Python Dependency Administration: Which Software Ought to You Select? | by Khuyen Tran | Jun, 2023

An in-depth comparability between Poetry, Pip, and Conda

Picture by Creator

Initially printed at on June 13, 2023.

As your information science venture expands, the variety of dependencies additionally will increase. To maintain the venture’s atmosphere reproducible and maintainable, it’s vital to make use of an environment friendly dependency administration instrument.

Thus, I made a decision to match three fashionable instruments for dependency administration: Pip, Conda, and Poetry. After cautious analysis, I’m satisfied that Poetry surpasses the opposite two choices by way of effectiveness and efficiency.

On this article, we’ll delve into the benefits of Poetry and spotlight its key distinctions from Pip and Conda.

Having a broad number of packages makes it simpler for builders to seek out the particular package deal and model that most accurately fits their wants.


Some packages, like “snscrape,” can’t be put in with conda. Moreover, sure variations, reminiscent of Pandas 2.0, won’t be out there for set up via Conda.

Whereas you should use pip inside a conda digital atmosphere to deal with package deal limitations, conda can’t observe dependencies put in with pip, making dependency administration difficult.

$ conda checklist
# packages in atmosphere at /Customers/khuyentran/miniconda3/envs/test-conda:
# Title Model Construct Channel$ conda checklist # packages in atmosphere at /Customers/khuyentran/miniconda3/envs/test-conda: # # Title Model Construct Channel


Pip can set up any packages from the Python Bundle Index (PyPI) and different repositories.


Poetry additionally permits the set up of packages from the Python Bundle Index (PyPI) and different repositories.

Decreasing the variety of dependencies in an atmosphere simplifies the event course of.


Conda gives full atmosphere isolation, managing each Python packages and system-level dependencies. This can lead to bigger package deal sizes in comparison with different package deal managers, doubtlessly consuming extra space for storing throughout set up and distribution.

$ conda set up pandas

$ conda checklist

# packages in atmosphere at /Customers/khuyentran/miniconda3/envs/test-conda:
# Title Model Construct Channel
blas 1.0 openblas
bottleneck 1.3.5 py311ha0d4635_0
bzip2 1.0.8 h620ffc9_4
ca-certificates 2023.05.30 hca03da5_0
libcxx 14.0.6 h848a8c0_0
libffi 3.4.4 hca03da5_0
libgfortran 5.0.0 11_3_0_hca03da5_28
libgfortran5 11.3.0 h009349e_28
libopenblas 0.3.21 h269037a_0
llvm-openmp 14.0.6 hc6e5704_0
ncurses 6.4 h313beb8_0
numexpr 2.8.4 py311h6dc990b_1
numpy 1.24.3 py311hb57d4eb_0
numpy-base 1.24.3 py311h1d85a46_0
openssl 3.0.8 h1a28f6b_0
pandas 1.5.3 py311h6956b77_0
pip 23.0.1 py311hca03da5_0
python 3.11.3 hb885b13_1
python-dateutil 2.8.2 pyhd3eb1b0_0
pytz 2022.7 py311hca03da5_0
readline 8.2 h1a28f6b_0
setuptools 67.8.0 py311hca03da5_0
six 1.16.0 pyhd3eb1b0_1
sqlite 3.41.2 h80987f9_0
tk 8.6.12 hb8d0fd4_0
tzdata 2023c h04d1e81_0
wheel 0.38.4 py311hca03da5_0
xz 5.4.2 h80987f9_0
zlib 1.2.13 h5a0b063_0


Pip installs solely the dependencies required by a package deal.

$ pip set up pandas

$ pip checklist

Bundle Model
--------------- -------
numpy 1.24.3
pandas 2.0.2
pip 22.3.1
python-dateutil 2.8.2
pytz 2023.3
setuptools 65.5.0
six 1.16.0
tzdata 2023.3


Poetry additionally installs solely the dependencies required by a package deal.

$ poetry add pandas

$ poetry present

numpy 1.24.3 Basic package deal for array computing in Python
pandas 2.0.2 Highly effective information buildings for information evaluation, time...
python-dateutil 2.8.2 Extensions to the usual Python datetime module
pytz 2023.3 World timezone definitions, fashionable and historic
six 1.16.0 Python 2 and three compatibility utilities
tzdata 2023.3 Supplier of IANA time zone information

Uninstalling packages and their dependencies frees up disk house, prevents pointless litter, and optimizes storage useful resource utilization.


Pip removes solely the desired package deal, not its dependencies, doubtlessly resulting in the buildup of unused dependencies over time. This can lead to elevated space for storing utilization and potential conflicts.

$ pip set up pandas

$ pip uninstall pandas

$ pip checklist

Bundle Model
--------------- -------
numpy 1.24.3
pip 22.0.4
python-dateutil 2.8.2
pytz 2023.3
setuptools 56.0.0
six 1.16.0
tzdata 2023.3


Conda removes the package deal and its dependencies.

$ conda set up -c conda pandas

$ conda uninstall -c conda pandas

Accumulating package deal metadata (repodata.json): carried out
Fixing atmosphere: carried out

## Bundle Plan ##

atmosphere location: /Customers/khuyentran/miniconda3/envs/test-conda

eliminated specs:
- pandas

The next packages will likely be REMOVED:


Proceed ([y]/n)?

Making ready transaction: carried out
Verifying transaction: carried out
Executing transaction: donePoetry


Poetry additionally removes the package deal and its dependencies.

$ poetry add pandas

$ poetry take away pandas

• Eradicating numpy (1.24.3)
• Eradicating pandas (2.0.2)
• Eradicating python-dateutil (2.8.2)
• Eradicating pytz (2023.3)
• Eradicating six (1.16.0)
• Eradicating tzdata (2023.3)

Dependency recordsdata make sure the reproducibility of a software program venture’s atmosphere by specifying the precise variations or model ranges of required packages.

This helps recreate the identical atmosphere throughout totally different techniques or at totally different deadlines, making certain collaboration amongst builders with the identical set of dependencies.


To avoid wasting dependencies in a Conda atmosphere, it’s good to manually write them to a file. Model ranges laid out in an atmosphere.yml file can lead to totally different variations being put in, doubtlessly introducing compatibility points when reproducing the atmosphere.

Let’s assume that we have now put in pandas model 1.5.3 for instance. Right here is an instance atmosphere.yml file that specifies the dependencies:

# atmosphere.yml
title: test-conda
- defaults
- python=3.8
- pandas>=1.5

If a brand new person tries to breed the atmosphere when the newest model of pandas is 2.0, pandas 2.0 will likely be put in as a substitute.

# Create and activate a digital atmosphere
$ conda env create -n env
$ conda activate env

# Record packages within the present atmosphere
$ conda checklist
pandas 2.0

If the codebase depends on syntax or habits particular to pandas model 1.5.3 and the syntax has modified in model 2.0, operating the code with pandas 2.0 might introduce bugs.


The identical downside can happen with pip.

# necessities.txt 
# Create and activate a digital atmosphere
$ python3 -m venv venv
$ supply venv/bin/activate

# Set up dependencies
$ pip set up -r necessities.txt

# Record packages
$ pip checklist
Bundle Model
---------- -------
pandas 2.0

You possibly can pin down the model by freezing them in a necessities.txt file:

$ pip freeze > necessities.txt
# necessities.txt


Nevertheless, this makes the code atmosphere much less versatile and doubtlessly more durable to take care of in the long term. Any adjustments to the dependencies would require handbook modifications to the necessities.txt file, which might be time-consuming and error-prone.


Poetry routinely updates the pyproject.toml file when putting in a package deal.

Within the following instance, the “pandas” package deal is added with the model constraint ^1.5. This versatile versioning method ensures that your venture can adapt to newer releases with out handbook changes.

$ poetry add 'pandas=^1.5'
# pyproject.toml

python = "^3.8"
pandas = "^1.5"

The poetry.lock file shops the exact model numbers for every package deal and its dependencies.

# poetry.lock
title = "pandas"
model = "1.5.3"
description = "Highly effective information buildings for information evaluation, time sequence, and statistics"
class = "foremost"
optionally available = false
python-versions = ">=3.8"

numpy = [
{version = ">=1.20.3", markers = "python_version < "3.10""},
{version = ">=1.21.0", markers = "python_version >= "3.10""},
{version = ">=1.23.2", markers = "python_version >= "3.11""},
python-dateutil = ">=2.8.2"
pytz = ">=2020.1"
tzdata = ">=2022.1"

This ensures consistency within the put in packages, even when a package deal has a model vary specified within the pyproject.toml file. Right here, we are able to see that pandas 1.5.3 is put in as a substitute of pandas 2.0

$ poetry set up

$ poetry present pandas

title : pandas
model : 1.5.3
description : Highly effective information buildings for information evaluation, time sequence, and statistics

- numpy >=1.20.3
- numpy >=1.21.0
- numpy >=1.23.2
- python-dateutil >=2.8.1
- pytz >=2020.1

By separating the dependencies, you possibly can clearly distinguish between the packages required for growth functions, reminiscent of testing frameworks and code high quality instruments, from the packages wanted for the manufacturing atmosphere, which usually embody the core dependencies.


Conda doesn’t inherently help separate dependencies for various environments, however a workaround entails creating two atmosphere recordsdata: one for the event atmosphere and one for manufacturing. The event file incorporates each manufacturing and growth dependencies.

# atmosphere.yml
title: test-conda
- defaults
# Manufacturing packages
- numpy
- pandas
# environment-dev.yml
title: test-conda-dev
- defaults
# Manufacturing packages
- numpy
- pandas
# Improvement packages
- pytest
- pre-commit


Pip additionally doesn’t straight help separate dependencies, however an analogous method can be utilized with separate requirement recordsdata.

# necessities.txt
# requirements-dev.txt
-r necessities.txt
# Set up prod
$ pip set up -r necessities.txt

# Set up each dev and prod
$ pip set up -r requirements-dev.txt


Poetry simplifies managing dependencies by supporting teams inside one file. This lets you hold observe of all dependencies in a single place.

$ poetry add numpy pandas
$ poetry add --group dev pytest pre-commit
# pyproject.toml
python = "^3.8"
pandas = "^2.0"
numpy = "^1.24.3"

pytest = "^7.3.2"
pre-commit = "^3.3.2"

To put in solely manufacturing dependencies:

$ poetry set up --only foremost

To put in each growth and manufacturing dependencies:

$ poetry set up

Updating dependencies is crucial to learn from bug fixes, efficiency enhancements, and new options launched in newer package deal variations.


Conda permits you to replace solely a specified package deal.

$ conda set up -c conda pandas
$ conda set up -c anaconda scikit-learn
# New variations out there
$ conda replace pandas
$ conda replace scikit-learn

Afterward, it’s good to manually replace the atmosphere.yaml file to maintain it in sync with the up to date dependencies.

$ conda env export > atmosphere.yml


Pip additionally solely permits you to replace a specified package deal and requires you to manually replace the necessities.txt file.

$ pip set up -U pandas
$ pip freeze > necessities.txt


Utilizing Poetry, you should use the replace command to improve all packages specified within the pyproject.toml file. This motion routinely updates the poetry.lock file, making certain consistency between the package deal specs and the lock file.

$ poetry add pandas scikit-learn

# New verisons out there
poetry replace

Updating dependencies
Resolving dependencies... (0.3s)

Writing lock file

Bundle operations: 0 installs, 2 updates, 0 removals

• Updating pandas (2.0.0 -> 2.0.2)
• Updating scikit-learn (1.2.0 -> 1.2.2)

Dependency conflicts happen when packages or libraries required by a venture have conflicting variations or incompatible dependencies. Correctly resolving conflicts is essential to keep away from errors, runtime points, or venture failures.


pip installs packages sequentially, which implies it installs every package deal one after the other, following the desired order. This sequential method can typically result in conflicts when packages have incompatible dependencies or model necessities.

For instance, suppose you put in pandas==2.0.2 first, which requires numpy>=1.20.3. Later, you put in numpy==1.20.2 utilizing pip. Regardless that this may create dependency conflicts, pip will proceed to replace the model of numpy.

$ pip set up pandas==2.0.2

$ pip set up numpy==1.22.2
Accumulating numpy=1.20.2
Trying uninstall: numpy
Discovered current set up: numpy 1.24.3
Uninstalling numpy-1.24.3:
Efficiently uninstalled numpy-1.24.3
ERROR: pip's dependency resolver doesn't at the moment take note of all of the packages which are put in. This behaviour is the supply of the next dependency conflicts.
pandas 2.0.2 requires numpy>=1.20.3; python_version < "3.10", however you've gotten numpy 1.20.2 which is incompatible.
Efficiently put in numpy-1.20.2


Conda makes use of a SAT solver to discover all combos of package deal variations and dependencies to discover a suitable set.

As an example, if an current package deal has a selected constraint for its dependency (e.g., statsmodels==0.13.2 requires numpy>=1.21.2,<2.0a0), and the package deal you need to set up doesn’t meet that requirement (e.g., numpy<1.21.2), conda gained’t instantly increase an error. As a substitute, it is going to diligently seek for suitable variations of all of the required packages and their dependencies, solely reporting an error if no appropriate resolution is discovered.

$ conda set up 'statsmodels==0.13.2'

$ conda search 'statsmodels==0.13.2' --info
- numpy >=1.21.2,<2.0a0
- packaging >=21.3
- pandas >=1.0
- patsy >=0.5.2
- python >=3.9,<3.10.0a0
- scipy >=1.3

$ conda set up 'numpy<1.21.2'

Bundle ca-certificates conflicts for:
python=3.8 -> openssl[version='>=1.1.1t,<1.1.2a'] -> ca-certificates
openssl -> ca-certificates
cryptography -> openssl[version='>1.1.0,<3.1.0'] -> ca-certificates

Bundle idna conflicts for:
requests -> urllib3[version='>=1.21.1,<1.27'] -> idna[version='>=2.0.0']
requests -> idna[version='>=2.5,<3|>=2.5,<4']
pooch -> requests -> idna[version='>=2.5,<3|>=2.5,<4']
urllib3 -> idna[version='>=2.0.0']

Bundle numexpr conflicts for:
statsmodels==0.13.2 -> pandas[version='>=1.0'] -> numexpr[version='>=2.7.0|>=2.7.1|>=2.7.3']
pandas==1.5.3 -> numexpr[version='>=2.7.3']

Bundle patsy conflicts for:
statsmodels==0.13.2 -> patsy[version='>=0.5.2']

Bundle chardet conflicts for:
requests -> chardet[version='>=3.0.2,<4|>=3.0.2,<5']
pooch -> requests -> chardet[version='>=3.0.2,<4|>=3.0.2,<5']

Bundle python-dateutil conflicts for:
statsmodels==0.13.2 -> pandas[version='>=1.0'] -> python-dateutil[version='>=2.7.3|>=2.8.1']
pandas==1.5.3 -> python-dateutil[version='>=2.8.1']

Bundle setuptools conflicts for:
numexpr -> setuptools
pip -> setuptools
wheel -> setuptools
python=3.8 -> pip -> setuptools
pandas==1.5.3 -> numexpr[version='>=2.7.3'] -> setuptools

Bundle brotlipy conflicts for:
urllib3 -> brotlipy[version='>=0.6.0']
requests -> urllib3[version='>=1.21.1,<1.27'] -> brotlipy[version='>=0.6.0']

Bundle pytz conflicts for:
pandas==1.5.3 -> pytz[version='>=2020.1']
statsmodels==0.13.2 -> pandas[version='>=1.0'] -> pytz[version='>=2017.3|>=2020.1']

Whereas this method enhances the probabilities of discovering a decision, it may be computationally intensive, significantly when coping with in depth environments.


By specializing in the direct dependencies of the venture, Poetry’s deterministic resolver narrows down the search house, making the decision course of extra environment friendly. It evaluates the desired constraints, reminiscent of model ranges or particular variations, and instantly identifies any conflicts.

$ poetry add 'seaborn==0.12.2'
$ poetry add 'matplotlib<3.1'

As a result of poetry shell depends upon seaborn (0.12.2) which depends upon matplotlib (>=3.1,<3.6.1 || >3.6.1), matplotlib is required.
So, as a result of poetry shell depends upon matplotlib (<3.1), model fixing failed.

This rapid suggestions helps stop potential points from escalating and permits builders to deal with the issue early within the growth course of. For instance, within the following code, we are able to loosen up the necessities for seaborn to allow the set up of a selected model of matplotlib:

poetry add 'seaborn<=0.12.2'  'matplotlib<3.1' 

Bundle operations: 1 set up, 2 updates, 4 removals

• Eradicating contourpy (1.0.7)
• Eradicating fonttools (4.40.0)
• Eradicating packaging (23.1)
• Eradicating pillow (9.5.0)
• Updating matplotlib (3.7.1 -> 3.0.3)
• Putting in scipy (1.9.3)
• Updating seaborn (0.12.2 -> 0.11.2)

In abstract, Poetry gives a number of benefits over pip and conda:

  1. Broad Bundle Choice: Poetry gives entry to a variety of packages out there on PyPI, permitting you to leverage a various ecosystem to your venture.
  2. Environment friendly Dependency Administration: Poetry installs solely the mandatory dependencies for a specified package deal, lowering the variety of extraneous packages in your atmosphere.
  3. Streamlined Bundle Removing: Poetry simplifies the removing of packages and their related dependencies, making it simple to take care of a clear and environment friendly venture atmosphere.
  4. Dependency Decision: Poetry’s deterministic resolver effectively resolves dependencies, figuring out and addressing any inconsistencies or conflicts promptly.

Whereas Poetry might require some extra effort and time to your teammates to study and adapt to, utilizing a instrument like Poetry can prevent effort and time in the long term.

GPT vs BERT: Which is Higher?. Evaluating two large-language fashions… | by Pranay Dave | Jun, 2023

Understanding Bayesian Advertising Combine Modeling: A Deep Dive into Prior Specs | by Slava Kisilevich | Jun, 2023