{"id":47940,"date":"2023-08-28T10:55:14","date_gmt":"2023-08-28T08:55:14","guid":{"rendered":"https:\/\/www.inovex.de\/?p=47940"},"modified":"2024-01-23T09:28:42","modified_gmt":"2024-01-23T08:28:42","slug":"an-unbiased-evaluation-of-environment-management-and-packaging-tools-in-python","status":"publish","type":"post","link":"https:\/\/www.inovex.de\/de\/blog\/an-unbiased-evaluation-of-environment-management-and-packaging-tools-in-python\/","title":{"rendered":"An unbiased evaluation of environment management and packaging tools in Python"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_79_2 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\"><p class=\"ez-toc-title\" style=\"cursor:inherit\"><\/p>\n<\/div><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.inovex.de\/de\/blog\/an-unbiased-evaluation-of-environment-management-and-packaging-tools-in-python\/#Motivation\" >Motivation<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.inovex.de\/de\/blog\/an-unbiased-evaluation-of-environment-management-and-packaging-tools-in-python\/#Categorization\" >Categorization<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.inovex.de\/de\/blog\/an-unbiased-evaluation-of-environment-management-and-packaging-tools-in-python\/#Python-version-management\" >Python version management<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.inovex.de\/de\/blog\/an-unbiased-evaluation-of-environment-management-and-packaging-tools-in-python\/#Virtual-environment-management\" >(Virtual) environment management<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.inovex.de\/de\/blog\/an-unbiased-evaluation-of-environment-management-and-packaging-tools-in-python\/#Recap-I-%E2%80%93-pyprojecttoml\" >Recap I &#8211; pyproject.toml<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.inovex.de\/de\/blog\/an-unbiased-evaluation-of-environment-management-and-packaging-tools-in-python\/#Package-management\" >Package management<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/www.inovex.de\/de\/blog\/an-unbiased-evaluation-of-environment-management-and-packaging-tools-in-python\/#Recap-II-%E2%80%93-Lock-file\" >Recap II &#8211; Lock file<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/www.inovex.de\/de\/blog\/an-unbiased-evaluation-of-environment-management-and-packaging-tools-in-python\/#Multi-purpose-tools\" >Multi-purpose tools<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/www.inovex.de\/de\/blog\/an-unbiased-evaluation-of-environment-management-and-packaging-tools-in-python\/#Tools-that-do-not-fit-the-categories\" >Tools that do not fit the categories<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Motivation\"><\/span>Motivation<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>When I started with Python and created my first package I was confused. Creating and managing a package seemed much harder than I expected. In addition, multiple tools existed and I wasn&#8217;t sure which one to use. I&#8217;m sure most of you had the very same problem in the past. Python has a zillion tools to manage virtual environments and create packages and it can be hard (or almost impossible) to understand which one fits your needs. Several talks and blog post on the topic exist, but none of them gives a complete overview or evaluates the tools in a structured fashion. This is what this post is about. I want to give you a truly unbiased evaluation of existing packaging and environment management tools. In case you&#8217;d rather watch a talk, take a look at the recording of <a href=\"https:\/\/www.youtube.com\/watch?v=MsJjzVIVs6M\">PyCon DE 2023<\/a>.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Categorization\"><\/span>Categorization<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>For the purpose of this article I identified five main categories that are important when it comes to environment and package management:<\/p>\n<ul>\n<li>Environment management (which is mostly concerned with virtual environments)<\/li>\n<li>Package management<\/li>\n<li>Python version management<\/li>\n<li>Package building<\/li>\n<li>Package publishing<\/li>\n<\/ul>\n<p>As you can see in the Venn diagram below, lots of tools exist. Some can do a single thing (i.e. they are single-purpose), others can perform multiple tasks (hence I call them multi-purpose tools).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-47992 \" src=\"https:\/\/www.inovex.de\/wp-content\/uploads\/venn_diagram.png\" alt=\"\" width=\"697\" height=\"574\" srcset=\"https:\/\/www.inovex.de\/wp-content\/uploads\/venn_diagram.png 921w, https:\/\/www.inovex.de\/wp-content\/uploads\/venn_diagram-300x247.png 300w, https:\/\/www.inovex.de\/wp-content\/uploads\/venn_diagram-768x632.png 768w, https:\/\/www.inovex.de\/wp-content\/uploads\/venn_diagram-400x329.png 400w, https:\/\/www.inovex.de\/wp-content\/uploads\/venn_diagram-360x296.png 360w\" sizes=\"auto, (max-width: 697px) 100vw, 697px\" \/><\/p>\n<p>Let&#8217;s walk through the categories keeping a developers perspective in mind. Let&#8217;s say you are working on a personal project alongside your work projects. At work you&#8217;re using Python 3.7 whereas your personal project should be using the newest Python version (currently 3.11). In other words: you want to be able to install different Python versions and switch between them. That&#8217;s what our first category, <strong>Python version management<\/strong> is about.<br \/>\nWithin your projects you are using other packages (e.g. `pandas` or `sklearn` for data science). These are dependencies of your project that you have to install and manage (e.g. upgrade when new versions are released). This is what <strong>package management<\/strong> is about.<br \/>\nBecause different projects might require different versions of the same package you need to create (and manage) virtual environments to avoid dependency conflicts. Tools for this are collected in the category <strong>environment management<\/strong>. Most tools use virtual environments, but some use another concept called &#8222;local packages&#8220; which we will look at later.<br \/>\nOnce your code is in a proper state you might want to share it with fellow developers. For this you first have to build your package (<strong>package building<\/strong>) before you can publish it to PyPI or another index (<strong>package publishing<\/strong>).<\/p>\n<p>In the following we will look at each of the categories in more detail, including a short definition, motivation and the available tools. I will present some single-purpose tools in more detail and several multi-purpose tools in a separate section at the end. Let&#8217;s get started with the first category:<strong> Python version management<\/strong>.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Python-version-management\"><\/span>Python version management<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3>Definition<\/h3>\n<p>A tool that can perform Python version management allows you to install Python versions and switch between them easily.<\/p>\n<h3>Motivation<\/h3>\n<p>Why would we want to use different Python versions? There are several reasons. For example, you might be working of several projects where each projects requires a different Python version. Or you might develop a project that supports several Python versions and you want to test all of them. Besides that it can be nice to check out what the newest Python version has to offer, or test a pre-release version of Python for bugs.<\/p>\n<h3>Tools<\/h3>\n<p>Our Venn diagram displays the available tools for Python version management: `pyenv, conda, rye` and `PyFlow`. We will first look at `pyenv` and consider the multi-purpose tools in a separate section.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-48018 \" src=\"https:\/\/www.inovex.de\/wp-content\/uploads\/python_version_management.png\" alt=\"\" width=\"661\" height=\"537\" srcset=\"https:\/\/www.inovex.de\/wp-content\/uploads\/python_version_management.png 936w, https:\/\/www.inovex.de\/wp-content\/uploads\/python_version_management-300x244.png 300w, https:\/\/www.inovex.de\/wp-content\/uploads\/python_version_management-768x624.png 768w, https:\/\/www.inovex.de\/wp-content\/uploads\/python_version_management-400x325.png 400w, https:\/\/www.inovex.de\/wp-content\/uploads\/python_version_management-360x293.png 360w\" sizes=\"auto, (max-width: 661px) 100vw, 661px\" \/><\/p>\n<h3>pyenv<\/h3>\n<p>Python has one single-purpose tool that lets you install and manage Python versions: <a href=\"https:\/\/github.com\/pyenv\/pyenv\">pyenv<\/a>! Pyenv is easy to use. The most important commands are the following:<\/p>\n<pre># Install specific Python version\r\npyenv install 3.11\r\n\r\n# Switch between Python versions\r\npyenv shell 3.11 # select version just for current shell session\r\npyenv local 3.11 # automatically select version whenever you are in the current directory\r\npyenv global 3.11 # select version globally for your user account<\/pre>\n<h2><span class=\"ez-toc-section\" id=\"Virtual-environment-management\"><\/span>(Virtual) environment management<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3>Definition<\/h3>\n<p>A tool that can perform environment management allows you to create and manage (virtual) environments.<\/p>\n<h3>Motivation<\/h3>\n<p>Why do we want to use environments in the first place? As mentioned in the beginning, projects have specific requirements (i.e. they depend on other packages). It&#8217;s often the case that different projects require different versions of the same package. This can cause dependency conflicts. In addition, problems can occur when using `pip install` to install a package because the package is placed with your system-wide Python installation. Some of these problems can be solved by using the `&#8211;user` flag in the `pip` command. However, this option might not be known to everyone, especially beginners.<\/p>\n<h3>Tools<\/h3>\n<p>Many tools allow users to create and manage environments. These are: venv, virtualenv, pipenv, conda, pdm, poetry, hatch, rye and `PyFlow`. Only two of them are single-purpose tools: `venv` and `virtualenv`. Let&#8217;s look at both of them in more detail.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-47996 \" src=\"https:\/\/www.inovex.de\/wp-content\/uploads\/env_management.png\" alt=\"\" width=\"650\" height=\"530\" srcset=\"https:\/\/www.inovex.de\/wp-content\/uploads\/env_management.png 925w, https:\/\/www.inovex.de\/wp-content\/uploads\/env_management-300x245.png 300w, https:\/\/www.inovex.de\/wp-content\/uploads\/env_management-768x626.png 768w, https:\/\/www.inovex.de\/wp-content\/uploads\/env_management-400x326.png 400w, https:\/\/www.inovex.de\/wp-content\/uploads\/env_management-360x293.png 360w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<h3>venv<\/h3>\n<p><a href=\"https:\/\/docs.python.org\/3\/library\/venv.html\">Venv<\/a> is the built-in Python package for creating virtual environments. This means that it is shipped with Python and does not have to be installed by the user. The most important commands are the following:<\/p>\n<pre># Create new environment\r\npython3 -m venv\r\n\r\n# Activate an environment\r\nsource \/bin\/activate\r\n\r\n# Deactivate an active environment\r\ndeactivate<\/pre>\n<h3>virtualenv<\/h3>\n<p><a href=\"https:\/\/virtualenv.pypa.io\/en\/latest\/\">Virtualenv<\/a> tries to improve `venv`. It offers more features than `venv` and is faster and more powerful. The most important commands are similar to the ones of `venv`, only creating a new environment is cleaner:<\/p>\n<pre># Create new environment\r\nvirtualenv\r\n\r\n# Activate an environment\r\nsource \/bin\/activate\r\n\r\n# Deactivate an active environment\r\ndeactivate<\/pre>\n<h2><span class=\"ez-toc-section\" id=\"Recap-I-%E2%80%93-pyprojecttoml\"><\/span>Recap I &#8211; <em>pyproject.toml<\/em><span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Before we can talk about packaging I want to make sure that you are aware of the most important file for packaging: `pyproject.toml`.<\/p>\n<p>Packaging in Python has come a long way. Until <a href=\"https:\/\/peps.python.org\/pep-0518\/\">PEP 518<\/a> `setup.py` files where used for packaging, using `setuptools` as a build tool. <a href=\"https:\/\/peps.python.org\/pep-0518\/\">PEP 518<\/a> introduced the usage of a `pyproject.toml` file. As a consequence, you always need a `pyproject.toml` file when creating a package. `pyproject.toml` is used to define the settings of a project, define metadata and lots of other things. If you would like to see an example check out the <a href=\"https:\/\/github.com\/pandas-dev\/pandas\/blob\/main\/pyproject.toml\">`pyproject.toml` file of the pandas library<\/a>. With the knowledge on `pyproject.toml` we can go on at take a look at package management.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Package-management\"><\/span>Package management<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3>Definition<\/h3>\n<p>A tool that can perform package management is able to download and install libraries and their dependencies.<\/p>\n<h3>Motivation<\/h3>\n<p>Why do we care about packages? Packages allow us to define a hierarchy of modules and to access modules easily using the dot-syntax (`from package.module import my_function`). In addition, they make it easy to share code with other developers. Since each package contains a `pyproject.toml` file which defines its dependencies, other developers don\u2019t have to install the required packages separately but can simply install the package from its `pyproject.toml` file.<\/p>\n<h3>Tools<\/h3>\n<p>Lots of tools can perform package management: `pip, pipx, pipenv, conda, pdm, poetry, rye` and `PyFlow`. The single-purpose tool for package management is `pip` which is well known in the Python community.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-48004 \" src=\"https:\/\/www.inovex.de\/wp-content\/uploads\/package_management.png\" alt=\"\" width=\"642\" height=\"516\" srcset=\"https:\/\/www.inovex.de\/wp-content\/uploads\/package_management.png 947w, https:\/\/www.inovex.de\/wp-content\/uploads\/package_management-300x241.png 300w, https:\/\/www.inovex.de\/wp-content\/uploads\/package_management-768x617.png 768w, https:\/\/www.inovex.de\/wp-content\/uploads\/package_management-400x321.png 400w, https:\/\/www.inovex.de\/wp-content\/uploads\/package_management-360x289.png 360w\" sizes=\"auto, (max-width: 642px) 100vw, 642px\" \/><\/p>\n<h3>pip<\/h3>\n<p>The standard package manager for Python is <a href=\"https:\/\/pip.pypa.io\/en\/stable\/\">pip<\/a>. It&#8217;s shipped with Python and allows you to install packages from PyPI and other indexes. The main command (probably one of the first commands a Python developer learns) is `pip install `. Of course, `pip` offers lots of other options. Check out the <a href=\"https:\/\/pip.pypa.io\/en\/stable\/\">documentation<\/a> for more information about available flags, etc.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Recap-II-%E2%80%93-Lock-file\"><\/span>Recap II &#8211; Lock file<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Before we go on to the multi-purpose tools, there is one more file that&#8217;s important for packaging: the lock file. While `pyproject.toml` contains abstract dependencies, a lock file contains concrete dependencies. It records exact versions of all dependencies installed for a project (e.g. `pandas==2.0.3`). This enables reproducibility of projects across multiple platforms. If you have never seen a lock file before, take a look at <a href=\"https:\/\/github.com\/python-poetry\/poetry\/blob\/master\/poetry.lock\">this one from poetry<\/a>:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-48016 size-full\" src=\"https:\/\/www.inovex.de\/wp-content\/uploads\/poetry_lock.png\" alt=\"\" width=\"1293\" height=\"746\" srcset=\"https:\/\/www.inovex.de\/wp-content\/uploads\/poetry_lock.png 1293w, https:\/\/www.inovex.de\/wp-content\/uploads\/poetry_lock-300x173.png 300w, https:\/\/www.inovex.de\/wp-content\/uploads\/poetry_lock-1024x591.png 1024w, https:\/\/www.inovex.de\/wp-content\/uploads\/poetry_lock-768x443.png 768w, https:\/\/www.inovex.de\/wp-content\/uploads\/poetry_lock-400x231.png 400w, https:\/\/www.inovex.de\/wp-content\/uploads\/poetry_lock-360x208.png 360w\" sizes=\"auto, (max-width: 1293px) 100vw, 1293px\" \/><\/p>\n<h2><span class=\"ez-toc-section\" id=\"Multi-purpose-tools\"><\/span>Multi-purpose tools<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Knowing about lock files we can start looking at tools that perform several tasks. We will start with `pipenv` and `conda` before we transition to packaging tools like `poetry` and `pdm`.<\/p>\n<h3>Pipenv<\/h3>\n<p>As the name suggests, <a href=\"https:\/\/pipenv.pypa.io\/en\/latest\/\">`pipenv`<\/a> combines `pip` and `virtualenv`. It allows you to perform virtual environment management and package management as we can see in our Venn diagram:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-48012 \" src=\"https:\/\/www.inovex.de\/wp-content\/uploads\/pipenv.png\" alt=\"\" width=\"636\" height=\"494\" srcset=\"https:\/\/www.inovex.de\/wp-content\/uploads\/pipenv.png 970w, https:\/\/www.inovex.de\/wp-content\/uploads\/pipenv-300x233.png 300w, https:\/\/www.inovex.de\/wp-content\/uploads\/pipenv-768x597.png 768w, https:\/\/www.inovex.de\/wp-content\/uploads\/pipenv-400x311.png 400w, https:\/\/www.inovex.de\/wp-content\/uploads\/pipenv-360x280.png 360w\" sizes=\"auto, (max-width: 636px) 100vw, 636px\" \/><\/p>\n<p>`pipenv` introduces two additional files:<br \/>\n&#8211; `Pipfile`<br \/>\n&#8211; `Pipfile.lock`<\/p>\n<p>`Pipfile` is a TOML file (similar to `pyproject.toml`) used to define project dependencies. It is managed by the developer when she invokes `pipenv` commands (like `pipenv install`). `Pipfile.lock` allows for deterministic builds. It eliminates the need for a `requirements.txt` file and is managed automatically through locking actions .<\/p>\n<p>The most important `pipenv` commands are:<\/p>\n<pre># Install package\r\npipenv install\r\n\r\n# Run Python script within virtual env\r\npipenv run\r\n\r\n# Activate virtual env\r\npipenv shell<\/pre>\n<h3>Conda<\/h3>\n<p><a href=\"https:\/\/conda.io\/projects\/conda\/en\/latest\/index.html\">Conda<\/a> is a general-purpose package management system. That means that it&#8217;s not limited to Python packages. Conda is a huge tool with lots of capabilities. Lot&#8217;s of tutorials and blog posts exist (for example <a href=\"https:\/\/conda.io\/projects\/conda\/en\/latest\/user-guide\/getting-started.html#managing-python\">the official one<\/a>) so I won&#8217;t go into more detail here. However, I want to mention one thing: while it is possible to build and publish a package with <em>conda<\/em> I did not include the tool in the appropriate categories. That&#8217;s because packaging with <em>conda<\/em> works a little differently and the resulting packages will be <em>conda<\/em> packages.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-47994 \" src=\"https:\/\/www.inovex.de\/wp-content\/uploads\/conda.png\" alt=\"\" width=\"595\" height=\"475\" srcset=\"https:\/\/www.inovex.de\/wp-content\/uploads\/conda.png 942w, https:\/\/www.inovex.de\/wp-content\/uploads\/conda-300x239.png 300w, https:\/\/www.inovex.de\/wp-content\/uploads\/conda-768x612.png 768w, https:\/\/www.inovex.de\/wp-content\/uploads\/conda-400x319.png 400w, https:\/\/www.inovex.de\/wp-content\/uploads\/conda-360x287.png 360w\" sizes=\"auto, (max-width: 595px) 100vw, 595px\" \/><\/p>\n<h3>Feature evaluation<\/h3>\n<p>Last but not least I want to present multi-purpose tools for packaging. I promised an unbiased evaluation. For this purpose I created a list of features that I consider important when comparing different tools. The features are:<\/p>\n\n<table id=\"tablepress-74\" class=\"tablepress tablepress-id-74\">\n<thead>\n<tr class=\"row-1\">\n\t<th class=\"column-1\">Feature<\/th><td class=\"column-2\"><\/td>\n<\/tr>\n<\/thead>\n<tbody class=\"row-striping row-hover\">\n<tr class=\"row-2\">\n\t<td class=\"column-1\">Does the tool manage dependencies?<\/td><td class=\"column-2\">?<\/td>\n<\/tr>\n<tr class=\"row-3\">\n\t<td class=\"column-1\">Does it resolve\/lock dependencies?<\/td><td class=\"column-2\">?<\/td>\n<\/tr>\n<tr class=\"row-4\">\n\t<td class=\"column-1\">Is there a clean build\/publish flow?<\/td><td class=\"column-2\">?<\/td>\n<\/tr>\n<tr class=\"row-5\">\n\t<td class=\"column-1\">Does it allow to use plugins?<\/td><td class=\"column-2\">?<\/td>\n<\/tr>\n<tr class=\"row-6\">\n\t<td class=\"column-1\">Does it support PEP 660 (editable installs)?<\/td><td class=\"column-2\">?<\/td>\n<\/tr>\n<tr class=\"row-7\">\n\t<td class=\"column-1\">Does it support PEP 621 (project metadata)?<\/td><td class=\"column-2\">?<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n\n<p>Regarding the two PEPs: Python has a lot of open and closed PEPs on packaging. For a full overview take a look at <a href=\"https:\/\/peps.python.org\/topic\/packaging\/\">this page<\/a>. I only included PEP 660 and PEP 621 for specific reasons:<\/p>\n<ul>\n<li><a href=\"https:\/\/peps.python.org\/pep-0660\/\">PEP 660<\/a> is about editable installs for `pyproject.toml` based builds. When you install a package using `pip` you have the option to install it in editable mode using `pip install -e package_name`. This is an important features to have when you are developing a package and want your changes to be directly reflected in your environment.<\/li>\n<li><a href=\"https:\/\/peps.python.org\/pep-0621\/\">PEP 621<\/a> specifies how to write a project\u2019s core metadata in a `pyproject.toml` file. I added it because one package (spoiler: it&#8217;s `poetry`) currently does not support this PEP but uses its own way for declaring metadata.<\/li>\n<\/ul>\n<h3>Flit<\/h3>\n<p><a href=\"https:\/\/flit.pypa.io\/en\/stable\/\">Flit<\/a> tries to create a simple way to put Python packages and modules on PyPI. It has a very specific use case: it&#8217;s meant to be used for packaging pure Python packages (that is, packages without a build step). It doesn&#8217;t care about any of the other tasks:<br \/>\n&#8211; Python version management: \u274c<br \/>\n&#8211; Package management: \u274c<br \/>\n&#8211; Environment management: \u274c<br \/>\n&#8211; Building a package: \u2705<br \/>\n&#8211; Publishing a package: \u2705<\/p>\n<p>This is also reflected in our Venn diagram:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-47998 \" src=\"https:\/\/www.inovex.de\/wp-content\/uploads\/flit.png\" alt=\"\" width=\"577\" height=\"470\" srcset=\"https:\/\/www.inovex.de\/wp-content\/uploads\/flit.png 943w, https:\/\/www.inovex.de\/wp-content\/uploads\/flit-300x244.png 300w, https:\/\/www.inovex.de\/wp-content\/uploads\/flit-768x625.png 768w, https:\/\/www.inovex.de\/wp-content\/uploads\/flit-400x326.png 400w, https:\/\/www.inovex.de\/wp-content\/uploads\/flit-360x293.png 360w\" sizes=\"auto, (max-width: 577px) 100vw, 577px\" \/><\/p>\n<h4>Feature evaluation<\/h4>\n\n<table id=\"tablepress-75\" class=\"tablepress tablepress-id-75\">\n<thead>\n<tr class=\"row-1\">\n\t<th class=\"column-1\">Feature<\/th><td class=\"column-2\"><\/td>\n<\/tr>\n<\/thead>\n<tbody class=\"row-striping row-hover\">\n<tr class=\"row-2\">\n\t<td class=\"column-1\">Does the tool manage dependencies?<\/td><td class=\"column-2\">\u274c<\/td>\n<\/tr>\n<tr class=\"row-3\">\n\t<td class=\"column-1\">Does it resolve\/lock dependencies?<\/td><td class=\"column-2\">\u274c<\/td>\n<\/tr>\n<tr class=\"row-4\">\n\t<td class=\"column-1\">Is there a clean build\/publish flow?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-5\">\n\t<td class=\"column-1\">Does it allow to use plugins?<\/td><td class=\"column-2\">\u274c<\/td>\n<\/tr>\n<tr class=\"row-6\">\n\t<td class=\"column-1\">Does it support PEP 660 (editable installs)?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-7\">\n\t<td class=\"column-1\">Does it support PEP 621 (project metadata)?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n\n<h4>Main commands<\/h4>\n<pre># Create new pyproject.toml\r\nflit init\r\n\r\n# Build and publish\r\nflit publish<\/pre>\n<h3>Poetry<\/h3>\n<p><a href=\"https:\/\/python-poetry.org\/\">Poetry<\/a> is a well known tool in the packaging world. As visible in the Venn diagram it can do everything except for Python version management:<br \/>\n&#8211; Python version management: \u274c<br \/>\n&#8211; Package management: \u2705<br \/>\n&#8211; Environment management: \u2705<br \/>\n&#8211; Building a package: \u2705<br \/>\n&#8211; Publishing a package: \u2705<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-48014 \" src=\"https:\/\/www.inovex.de\/wp-content\/uploads\/poetry.png\" alt=\"\" width=\"615\" height=\"492\" srcset=\"https:\/\/www.inovex.de\/wp-content\/uploads\/poetry.png 884w, https:\/\/www.inovex.de\/wp-content\/uploads\/poetry-300x240.png 300w, https:\/\/www.inovex.de\/wp-content\/uploads\/poetry-768x614.png 768w, https:\/\/www.inovex.de\/wp-content\/uploads\/poetry-400x320.png 400w, https:\/\/www.inovex.de\/wp-content\/uploads\/poetry-360x288.png 360w\" sizes=\"auto, (max-width: 615px) 100vw, 615px\" \/><\/p>\n<p>Taking a look at the feature evaluation below you will see than Poetry does <strong>not<\/strong> support PEP 621. There has been an open issue about this on GitHub for about 1.5 years, but it hasn&#8217;t been integrated into the main code base (yet).<\/p>\n<h4>Feature evaluation<\/h4>\n\n<table id=\"tablepress-76\" class=\"tablepress tablepress-id-76\">\n<thead>\n<tr class=\"row-1\">\n\t<th class=\"column-1\">Feature<\/th><td class=\"column-2\"><\/td>\n<\/tr>\n<\/thead>\n<tbody class=\"row-striping row-hover\">\n<tr class=\"row-2\">\n\t<td class=\"column-1\">Does the tool manage dependencies?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-3\">\n\t<td class=\"column-1\">Does it resolve\/lock dependencies?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-4\">\n\t<td class=\"column-1\">Is there a clean build\/publish flow?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-5\">\n\t<td class=\"column-1\">Does it allow to use plugins?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-6\">\n\t<td class=\"column-1\">Does it support PEP 660 (editable installs)?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-7\">\n\t<td class=\"column-1\">Does it support PEP 621 (project metadata)?<\/td><td class=\"column-2\">\u274c<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n\n<h4>Main commands<\/h4>\n<pre># Create directory structure and pyproject.toml\r\npoetry new\r\n\r\n# Create pyproject.toml interactively\r\npoetry init\r\n\r\n# Install package from pyproject.toml\r\npoetry install<\/pre>\n<h4>Dependency management<\/h4>\n<pre># Add dependency\r\npoetry add\r\n\r\n# Display all dependencies\r\npoetry show --tree<\/pre>\n<h4>Running code<\/h4>\n<pre># Activate virtual env\r\npoetry shell\r\n\r\n# Run script within virtual env\r\npoetry run python\r\n\r\n<\/pre>\n<h4>Lock file<\/h4>\n<p>When installing a package for the first time, Poetry resolves all dependencies listed in your `pyproject.toml` file and downloads the latest version of the packages. Once Poetry has finished installing, it writes all the packages and the exact versions that it downloaded to a `poetry.lock` file, locking the project to those specific versions. It&#8217;s recommended to commit the lock file to your project repository so that all people working on the project are locked to the same versions of dependencies. To update your dependencies to the latest versions, use the `poetry update` command.<\/p>\n<h4>Build\/publish flow<\/h4>\n<pre># Package code (creates `.tar.gz` and `.whl` files)\r\npoetry build\r\n\r\n# Publish to PyPI\r\npoetry publish<\/pre>\n<h3>PDM<\/h3>\n<p><a href=\"https:\/\/pdm.fming.dev\/latest\/\">PDM<\/a> is a relatively new package and dependency manager (started in 2019) that is strongly inspired by Poetry and PyFlow. You will notice that I&#8217;m not talking about PyFlow in this article. That&#8217;s because PyFlow is not actively developed anymore &#8211; a must in the quickly evolving landscape of packaging. Being a new(er) tool, PDM requires Python 3.7 or higher. Another difference to other tools is that PDM allows users to choose a build backend.<br \/>\nPDM is the only tool (apart from PyFlow) that implements <a href=\"https:\/\/peps.python.org\/pep-0582\/\">PEP 582<\/a> on local packages, an alternative way of implementing environment management. Note that this PEP was recently rejected.<\/p>\n<p>As visible in the Venn diagram, PDM sits right next to Poetry. That means that it can do everything except for Python version management:<br \/>\n&#8211; Python version management: \u274c<br \/>\n&#8211; Package management: \u2705<br \/>\n&#8211; Environment management: \u2705<br \/>\n&#8211; Building a package: \u2705<br \/>\n&#8211; Publishing a package: \u2705<\/p>\n<p>The main commands of PDM are similar to Poetry. However, less commands exist. For example, there is no `pdm shell` or `pdm new` at the moment.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-48010 \" src=\"https:\/\/www.inovex.de\/wp-content\/uploads\/pdm.png\" alt=\"\" width=\"599\" height=\"473\" srcset=\"https:\/\/www.inovex.de\/wp-content\/uploads\/pdm.png 952w, https:\/\/www.inovex.de\/wp-content\/uploads\/pdm-300x237.png 300w, https:\/\/www.inovex.de\/wp-content\/uploads\/pdm-768x607.png 768w, https:\/\/www.inovex.de\/wp-content\/uploads\/pdm-400x316.png 400w, https:\/\/www.inovex.de\/wp-content\/uploads\/pdm-360x284.png 360w\" sizes=\"auto, (max-width: 599px) 100vw, 599px\" \/><\/p>\n<h4>Feature evaluation<\/h4>\n\n<table id=\"tablepress-77\" class=\"tablepress tablepress-id-77\">\n<thead>\n<tr class=\"row-1\">\n\t<th class=\"column-1\">Feature<\/th><td class=\"column-2\"><\/td>\n<\/tr>\n<\/thead>\n<tbody class=\"row-striping row-hover\">\n<tr class=\"row-2\">\n\t<td class=\"column-1\">Does the tool manage dependencies?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-3\">\n\t<td class=\"column-1\">Does it resolve\/lock dependencies?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-4\">\n\t<td class=\"column-1\">Is there a clean build\/publish flow?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-5\">\n\t<td class=\"column-1\">Does it allow to use plugins?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-6\">\n\t<td class=\"column-1\">Does it support PEP 660 (editable installs)?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-7\">\n\t<td class=\"column-1\">Does it support PEP 621 (project metadata)?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n\n<h4>Creating a new project<\/h4>\n<pre># Create pyproject.toml interactively\r\npdm init\r\n\r\n# Install package from pyproject.toml\r\npdm install<\/pre>\n<h4>Dependency management<\/h4>\n<pre># Add dependency\r\npdm add\r\n\r\n# Display all dependencies\r\npdm list --graph<\/pre>\n<h4>Running code<\/h4>\n<pre># No pdm shell command\r\n\r\n# Run script within env\r\npdm run python<\/pre>\n<h4>Lock file<\/h4>\n<p>The locking functionality of PDM is similar to Poetry. When installing a package for the first time, PDM resolves all dependencies listed in your `pyproject.toml` file and downloads the latest version of the packages. Once PDM has finished installing, it writes all packages and the exact versions that it downloaded to a `pdm.lock` file, locking the project to those specific versions. It&#8217;s recommended to commit the lock file to your project repo so that all people working on the project are locked to the same versions of dependencies. To update your dependencies to the latest versions, use the `pdm update` command.<\/p>\n<h4>Build\/publish flow<\/h4>\n<pre># Package code (creates `.tar.gz` and `.whl` files)\r\npdm build\r\n\r\n# Publish to PyPI\r\npdm publish<\/pre>\n<h3>Hatch<\/h3>\n<p><a href=\"https:\/\/hatch.pypa.io\/latest\/\">Hatch<\/a> can perform the following tasks:<br \/>\n&#8211; Python version management: \u2705<br \/>\n&#8211; Package management: \u274c<br \/>\n&#8211; Environment management: \u2705<br \/>\n&#8211; Building a package: \u2705<br \/>\n&#8211; Publishing a package: \u2705<\/p>\n<p>It should be noted that the author of Hatch promised that locking functionality will be added soon, which should also enable package management. Please make sure to check the latest version of Hatch to see if this has been implemented when you read this article.<\/p>\n<p>Update: Since version 1.8.0, Hatch provides the ability to manage Python installations, e.g. using `hatch python install`. Currently, only major.minor versions can be installed like 3.7 or 3.8, but not specific patches like 3.7.4.<\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-48000 \" src=\"https:\/\/www.inovex.de\/wp-content\/uploads\/hatch.png\" alt=\"\" width=\"633\" height=\"514\" srcset=\"https:\/\/www.inovex.de\/wp-content\/uploads\/hatch.png 935w, https:\/\/www.inovex.de\/wp-content\/uploads\/hatch-300x244.png 300w, https:\/\/www.inovex.de\/wp-content\/uploads\/hatch-768x623.png 768w, https:\/\/www.inovex.de\/wp-content\/uploads\/hatch-400x325.png 400w, https:\/\/www.inovex.de\/wp-content\/uploads\/hatch-360x292.png 360w\" sizes=\"auto, (max-width: 633px) 100vw, 633px\" \/><\/p>\n<h4>Feature evaluation<\/h4>\n\n<table id=\"tablepress-78\" class=\"tablepress tablepress-id-78\">\n<thead>\n<tr class=\"row-1\">\n\t<th class=\"column-1\">Feature<\/th><td class=\"column-2\"><\/td>\n<\/tr>\n<\/thead>\n<tbody class=\"row-striping row-hover\">\n<tr class=\"row-2\">\n\t<td class=\"column-1\">Does the tool manage dependencies?<\/td><td class=\"column-2\">\u274c<\/td>\n<\/tr>\n<tr class=\"row-3\">\n\t<td class=\"column-1\">Does it resolve\/lock dependencies?<\/td><td class=\"column-2\">\u274c<\/td>\n<\/tr>\n<tr class=\"row-4\">\n\t<td class=\"column-1\">Is there a clean build\/publish flow?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-5\">\n\t<td class=\"column-1\">Does it allow to use plugins?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-6\">\n\t<td class=\"column-1\">Does it support PEP 660 (editable installs)?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-7\">\n\t<td class=\"column-1\">Does it support PEP 621 (project metadata)?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n\n<h4>Creating a new project<\/h4>\n<pre># Create directory structure and pyproject.toml\r\nhatch new\r\n\r\n# Interactive mode\r\nhatch new -i\r\n\r\n# Initialize existing project \/ create pyproject.toml\r\nhatch new --init<\/pre>\n<h4>Dependency management<\/h4>\n<pre># Packages are added manually to pyproject.toml\r\nhatch add # This command doesn't exist!\r\n\r\n# Display dependencies\r\nhatch dep show table<\/pre>\n<h4>Running code<\/h4>\n<pre># Activate virtual env\r\nhatch shell\r\n\r\n# Run script within virtual env\r\nhatch run python<\/pre>\n<h4>Build\/publish flow<\/h4>\n<pre># Package code (creates `.tar.gz` and `.whl` files)\r\nhatch build\r\n\r\n# Publish to PyPI\r\nhatch publish<\/pre>\n<h4>Declarative environment management<\/h4>\n<p>Special about Hatch is that it allows you to configure your virtual environments within the `pyproject.toml` file. In addition if lets you define scripts specifically for an environment. And example use case for this is <a href=\"https:\/\/hatch.pypa.io\/1.1\/config\/environment\/#scripts\">code formatting<\/a>.<\/p>\n<h3>Rye<\/h3>\n<p><a href=\"https:\/\/rye-up.com\/\">Rye<\/a> was recently developed by Armin Ronacher (first release May 2023), the creator of the Flask framework. It is strongly inspired by `rustup` and `cargo`, the packaging tools of the programming language Rust. Rye is written in Rust and is able to perform all tasks in our Venn diagram:<\/p>\n<p>&#8211; Python version management: \u2705<br \/>\n&#8211; Package management: \u2705<br \/>\n&#8211; Environment management: \u2705<br \/>\n&#8211; Building a package: \u2705<br \/>\n&#8211; Publishing a package: \u2705<\/p>\n<p>Currently, Rye does not have a plugin interface. However, since new releases are published on a regular basis, this might be added in the future.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-48020 \" src=\"https:\/\/www.inovex.de\/wp-content\/uploads\/rye.png\" alt=\"\" width=\"620\" height=\"494\" srcset=\"https:\/\/www.inovex.de\/wp-content\/uploads\/rye.png 960w, https:\/\/www.inovex.de\/wp-content\/uploads\/rye-300x239.png 300w, https:\/\/www.inovex.de\/wp-content\/uploads\/rye-768x613.png 768w, https:\/\/www.inovex.de\/wp-content\/uploads\/rye-400x319.png 400w, https:\/\/www.inovex.de\/wp-content\/uploads\/rye-360x287.png 360w\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" \/><\/p>\n<h4>Feature evaluation<\/h4>\n\n<table id=\"tablepress-79\" class=\"tablepress tablepress-id-79\">\n<thead>\n<tr class=\"row-1\">\n\t<th class=\"column-1\">Feature<\/th><td class=\"column-2\"><\/td>\n<\/tr>\n<\/thead>\n<tbody class=\"row-striping row-hover\">\n<tr class=\"row-2\">\n\t<td class=\"column-1\">Does the tool manage dependencies?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-3\">\n\t<td class=\"column-1\">Does it resolve\/lock dependencies?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-4\">\n\t<td class=\"column-1\">Is there a clean build\/publish flow?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-5\">\n\t<td class=\"column-1\">Does it allow to use plugins?<\/td><td class=\"column-2\">\u274c<\/td>\n<\/tr>\n<tr class=\"row-6\">\n\t<td class=\"column-1\">Does it support PEP 660 (editable installs)?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-7\">\n\t<td class=\"column-1\">Does it support PEP 621 (project metadata)?<\/td><td class=\"column-2\">\u2705<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n\n<h4>Creating a new project<\/h4>\n<pre># Create directory structure and pyproject.toml\r\nrye init\r\n\r\n# Pin a Python version\r\nrye pin 3.10<\/pre>\n<h4>Dependency management<\/h4>\n<pre># Add dependency - this does not install the package!\r\nrye add\r\n\r\n# Synchronize virtual envs, lock file, etc.\r\n# This install packages and Python versions\r\nrye sync<\/pre>\n<h4>Running code<\/h4>\n<pre># Activate virtual env\r\nrye shell\r\n\r\n# Run script within virtual env\r\nrye run python<\/pre>\n<h4>Build\/publish flow<\/h4>\n<pre># Package code (creates `.tar.gz` and `.whl` files)\r\nrye build\r\n\r\n# Publish to PyPI\r\nrye publish<\/pre>\n<h3>Final overview<\/h3>\n\n<table id=\"tablepress-80\" class=\"tablepress tablepress-id-80\">\n<thead>\n<tr class=\"row-1\">\n\t<th class=\"column-1\">Feature<\/th><th class=\"column-2\">Flit<\/th><th class=\"column-3\">Poetry<\/th><th class=\"column-4\">PDM<\/th><th class=\"column-5\">Hatch<\/th><th class=\"column-6\">Rye<\/th>\n<\/tr>\n<\/thead>\n<tbody class=\"row-striping row-hover\">\n<tr class=\"row-2\">\n\t<td class=\"column-1\">Does the tool manage dependencies?<\/td><td class=\"column-2\">\u274c<\/td><td class=\"column-3\">\u2705<\/td><td class=\"column-4\">\u2705<\/td><td class=\"column-5\">\u274c<\/td><td class=\"column-6\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-3\">\n\t<td class=\"column-1\">Does it resolve\/lock dependencies?<\/td><td class=\"column-2\">\u274c<\/td><td class=\"column-3\">\u2705<\/td><td class=\"column-4\">\u2705<\/td><td class=\"column-5\">\u274c<\/td><td class=\"column-6\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-4\">\n\t<td class=\"column-1\">Is there a clean build\/publish flow?<\/td><td class=\"column-2\">\u2705<\/td><td class=\"column-3\">\u2705<\/td><td class=\"column-4\">\u2705<\/td><td class=\"column-5\">\u2705<\/td><td class=\"column-6\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-5\">\n\t<td class=\"column-1\">Does it allow to use plugins?<\/td><td class=\"column-2\">\u274c<\/td><td class=\"column-3\">\u2705<\/td><td class=\"column-4\">\u2705<\/td><td class=\"column-5\">\u2705<\/td><td class=\"column-6\">\u274c<\/td>\n<\/tr>\n<tr class=\"row-6\">\n\t<td class=\"column-1\">Does it support PEP 660 (editable installs)?<\/td><td class=\"column-2\">\u2705<\/td><td class=\"column-3\">\u2705<\/td><td class=\"column-4\">\u2705<\/td><td class=\"column-5\">\u2705<\/td><td class=\"column-6\">\u2705<\/td>\n<\/tr>\n<tr class=\"row-7\">\n\t<td class=\"column-1\">Does it support PEP 621 (project metadata)?<\/td><td class=\"column-2\">\u2705<\/td><td class=\"column-3\">\u274c<\/td><td class=\"column-4\">\u2705<\/td><td class=\"column-5\">\u2705<\/td><td class=\"column-6\">\u2705<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n\n<h2><span class=\"ez-toc-section\" id=\"Tools-that-do-not-fit-the-categories\"><\/span>Tools that do not fit the categories<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Some tools exist which don&#8217;t fit into any of my categories. These are:<br \/>\n&#8211; <a href=\"https:\/\/pip-tools.readthedocs.io\/en\/latest\/\">pip-tools<\/a> which helps to keep the versions of your `pip`-based packages up-to-date.<br \/>\n&#8211; <a href=\"https:\/\/tox.wiki\/en\/4.10.0\/\">tox<\/a> which is mainly used for testing but also handles virtual environments.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Motivation When I started with Python and created my first package I was confused. Creating and managing a package seemed much harder than I expected. In addition, multiple tools existed and I wasn&#8217;t sure which one to use. I&#8217;m sure most of you had the very same problem in the past. Python has a zillion [&hellip;]<\/p>\n","protected":false},"author":194,"featured_media":48212,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"ep_exclude_from_search":false,"footnotes":""},"tags":[],"service":[411,431],"coauthors":[{"id":194,"display_name":"Anna-Lena Popkes","user_nicename":"apopkes"}],"class_list":["post-47940","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","service-data-engineering","service-data-science"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>An unbiased evaluation of environment management and packaging tools in Python - inovex GmbH<\/title>\n<meta name=\"description\" content=\"Confused by Python package and environment management? Learn about tools for Python version management, environment management, package management, building, and publishing.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"An unbiased evaluation of environment management and packaging tools in Python - inovex GmbH\" \/>\n<meta property=\"og:description\" content=\"Confused by Python package and environment management? Learn about tools for Python version management, environment management, package management, building, and publishing.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/\" \/>\n<meta property=\"og:site_name\" content=\"inovex GmbH\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/inovexde\" \/>\n<meta property=\"article:published_time\" content=\"2023-08-28T08:55:14+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-01-23T08:28:42+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.inovex.de\/wp-content\/uploads\/python-tools-evaluation.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1500\" \/>\n\t<meta property=\"og:image:height\" content=\"880\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Anna-Lena Popkes\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.inovex.de\/wp-content\/uploads\/python-tools-evaluation-1024x601.jpg\" \/>\n<meta name=\"twitter:creator\" content=\"@inovexgmbh\" \/>\n<meta name=\"twitter:site\" content=\"@inovexgmbh\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Anna-Lena Popkes\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"14\u00a0Minuten\" \/>\n\t<meta name=\"twitter:label3\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data3\" content=\"Anna-Lena Popkes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/an-unbiased-evaluation-of-environment-management-and-packaging-tools-in-python\/\"},\"author\":{\"name\":\"Anna-Lena Popkes\",\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/person\/3df260d7f75d6a1efd09edc3741c0fdf\"},\"headline\":\"An unbiased evaluation of environment management and packaging tools in Python\",\"datePublished\":\"2023-08-28T08:55:14+00:00\",\"dateModified\":\"2024-01-23T08:28:42+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/an-unbiased-evaluation-of-environment-management-and-packaging-tools-in-python\/\"},\"wordCount\":2564,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.inovex.de\/de\/#organization\"},\"image\":{\"@id\":\"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/python-tools-evaluation.jpg\",\"articleSection\":[\"General\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/an-unbiased-evaluation-of-environment-management-and-packaging-tools-in-python\/\",\"url\":\"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/\",\"name\":\"An unbiased evaluation of environment management and packaging tools in Python - inovex GmbH\",\"isPartOf\":{\"@id\":\"https:\/\/www.inovex.de\/de\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/python-tools-evaluation.jpg\",\"datePublished\":\"2023-08-28T08:55:14+00:00\",\"dateModified\":\"2024-01-23T08:28:42+00:00\",\"description\":\"Confused by Python package and environment management? Learn about tools for Python version management, environment management, package management, building, and publishing.\",\"breadcrumb\":{\"@id\":\"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/#primaryimage\",\"url\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/python-tools-evaluation.jpg\",\"contentUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/python-tools-evaluation.jpg\",\"width\":1500,\"height\":880,\"caption\":\"Illustration: Zwei Personen ber\u00fchren Venn-Diagramm mit Python-Logo in der Mitte\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.inovex.de\/de\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"An unbiased evaluation of environment management and packaging tools in Python\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.inovex.de\/de\/#website\",\"url\":\"https:\/\/www.inovex.de\/de\/\",\"name\":\"inovex GmbH\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/www.inovex.de\/de\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.inovex.de\/de\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.inovex.de\/de\/#organization\",\"name\":\"inovex GmbH\",\"url\":\"https:\/\/www.inovex.de\/de\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png\",\"contentUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png\",\"width\":1921,\"height\":1081,\"caption\":\"inovex GmbH\"},\"image\":{\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/inovexde\",\"https:\/\/x.com\/inovexgmbh\",\"https:\/\/www.instagram.com\/inovexlife\/\",\"https:\/\/www.linkedin.com\/company\/inovex\",\"https:\/\/www.youtube.com\/channel\/UC7r66GT14hROB_RQsQBAQUQ\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/person\/3df260d7f75d6a1efd09edc3741c0fdf\",\"name\":\"Anna-Lena Popkes\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/person\/image\/b761218ea0c3098c8e9b2c42d8b06a83\",\"url\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/cropped-lena-96x96.jpg\",\"contentUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/cropped-lena-96x96.jpg\",\"caption\":\"Anna-Lena Popkes\"},\"description\":\"Hi, I'm Anna-Lena, a senior machine learning engineer here at inovex. I am an enthusiastic learner always looking for new challenges to expand my knowledge and skills. I am deeply fascinated by machine learning and its applications to questions that affect and benefit society. This translates into a passion for teaching, where I can share my insights and contribute to the collective growth of the machine learning community.\",\"sameAs\":[\"https:\/\/alpopkes.com\/\",\"https:\/\/www.linkedin.com\/in\/anna-lena-popkes\"],\"url\":\"https:\/\/www.inovex.de\/de\/blog\/author\/apopkes\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"An unbiased evaluation of environment management and packaging tools in Python - inovex GmbH","description":"Confused by Python package and environment management? Learn about tools for Python version management, environment management, package management, building, and publishing.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/","og_locale":"de_DE","og_type":"article","og_title":"An unbiased evaluation of environment management and packaging tools in Python - inovex GmbH","og_description":"Confused by Python package and environment management? Learn about tools for Python version management, environment management, package management, building, and publishing.","og_url":"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/","og_site_name":"inovex GmbH","article_publisher":"https:\/\/www.facebook.com\/inovexde","article_published_time":"2023-08-28T08:55:14+00:00","article_modified_time":"2024-01-23T08:28:42+00:00","og_image":[{"width":1500,"height":880,"url":"https:\/\/www.inovex.de\/wp-content\/uploads\/python-tools-evaluation.jpg","type":"image\/jpeg"}],"author":"Anna-Lena Popkes","twitter_card":"summary_large_image","twitter_image":"https:\/\/www.inovex.de\/wp-content\/uploads\/python-tools-evaluation-1024x601.jpg","twitter_creator":"@inovexgmbh","twitter_site":"@inovexgmbh","twitter_misc":{"Verfasst von":"Anna-Lena Popkes","Gesch\u00e4tzte Lesezeit":"14\u00a0Minuten","Written by":"Anna-Lena Popkes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/#article","isPartOf":{"@id":"https:\/\/www.inovex.de\/de\/blog\/an-unbiased-evaluation-of-environment-management-and-packaging-tools-in-python\/"},"author":{"name":"Anna-Lena Popkes","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/person\/3df260d7f75d6a1efd09edc3741c0fdf"},"headline":"An unbiased evaluation of environment management and packaging tools in Python","datePublished":"2023-08-28T08:55:14+00:00","dateModified":"2024-01-23T08:28:42+00:00","mainEntityOfPage":{"@id":"https:\/\/www.inovex.de\/de\/blog\/an-unbiased-evaluation-of-environment-management-and-packaging-tools-in-python\/"},"wordCount":2564,"commentCount":0,"publisher":{"@id":"https:\/\/www.inovex.de\/de\/#organization"},"image":{"@id":"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/#primaryimage"},"thumbnailUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/python-tools-evaluation.jpg","articleSection":["General"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.inovex.de\/de\/blog\/an-unbiased-evaluation-of-environment-management-and-packaging-tools-in-python\/","url":"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/","name":"An unbiased evaluation of environment management and packaging tools in Python - inovex GmbH","isPartOf":{"@id":"https:\/\/www.inovex.de\/de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/#primaryimage"},"image":{"@id":"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/#primaryimage"},"thumbnailUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/python-tools-evaluation.jpg","datePublished":"2023-08-28T08:55:14+00:00","dateModified":"2024-01-23T08:28:42+00:00","description":"Confused by Python package and environment management? Learn about tools for Python version management, environment management, package management, building, and publishing.","breadcrumb":{"@id":"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/#primaryimage","url":"https:\/\/www.inovex.de\/wp-content\/uploads\/python-tools-evaluation.jpg","contentUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/python-tools-evaluation.jpg","width":1500,"height":880,"caption":"Illustration: Zwei Personen ber\u00fchren Venn-Diagramm mit Python-Logo in der Mitte"},{"@type":"BreadcrumbList","@id":"https:\/\/alpopkes.com\/posts\/python\/packaging_tools\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.inovex.de\/de\/"},{"@type":"ListItem","position":2,"name":"An unbiased evaluation of environment management and packaging tools in Python"}]},{"@type":"WebSite","@id":"https:\/\/www.inovex.de\/de\/#website","url":"https:\/\/www.inovex.de\/de\/","name":"inovex GmbH","description":"","publisher":{"@id":"https:\/\/www.inovex.de\/de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.inovex.de\/de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/www.inovex.de\/de\/#organization","name":"inovex GmbH","url":"https:\/\/www.inovex.de\/de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/","url":"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png","contentUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png","width":1921,"height":1081,"caption":"inovex GmbH"},"image":{"@id":"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/inovexde","https:\/\/x.com\/inovexgmbh","https:\/\/www.instagram.com\/inovexlife\/","https:\/\/www.linkedin.com\/company\/inovex","https:\/\/www.youtube.com\/channel\/UC7r66GT14hROB_RQsQBAQUQ"]},{"@type":"Person","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/person\/3df260d7f75d6a1efd09edc3741c0fdf","name":"Anna-Lena Popkes","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/person\/image\/b761218ea0c3098c8e9b2c42d8b06a83","url":"https:\/\/www.inovex.de\/wp-content\/uploads\/cropped-lena-96x96.jpg","contentUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/cropped-lena-96x96.jpg","caption":"Anna-Lena Popkes"},"description":"Hi, I'm Anna-Lena, a senior machine learning engineer here at inovex. I am an enthusiastic learner always looking for new challenges to expand my knowledge and skills. I am deeply fascinated by machine learning and its applications to questions that affect and benefit society. This translates into a passion for teaching, where I can share my insights and contribute to the collective growth of the machine learning community.","sameAs":["https:\/\/alpopkes.com\/","https:\/\/www.linkedin.com\/in\/anna-lena-popkes"],"url":"https:\/\/www.inovex.de\/de\/blog\/author\/apopkes\/"}]}},"_links":{"self":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts\/47940","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/users\/194"}],"replies":[{"embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/comments?post=47940"}],"version-history":[{"count":5,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts\/47940\/revisions"}],"predecessor-version":[{"id":51139,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts\/47940\/revisions\/51139"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/media\/48212"}],"wp:attachment":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/media?parent=47940"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/tags?post=47940"},{"taxonomy":"service","embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/service?post=47940"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/coauthors?post=47940"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}