Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update "install_requires vs. requirements files" discussion #1427

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
85 changes: 43 additions & 42 deletions source/discussions/install-requires-vs-requirements.rst
webknjaz marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,89 +1,90 @@
.. _`install_requires vs requirements files`:
jeanas marked this conversation as resolved.
Show resolved Hide resolved
==========================================
Package dependencies vs requirements files
jeanas marked this conversation as resolved.
Show resolved Hide resolved
==========================================

======================================
install_requires vs requirements files
======================================

Package dependencies
====================

install_requires
----------------
Packages can declare dependencies, i.e., other packages that they need
to function. The standard method to do so is to set the
:ref:`dependencies key <writing-pyproject-toml-dependencies>` in the
``[project]`` section of a ``pyproject.toml`` file. When installing a
package, installers like :ref:`pip` will automatically install the
dependencies. This should be used for packages that the project
jeanas marked this conversation as resolved.
Show resolved Hide resolved
**minimally** needs to run correctly.

``install_requires`` is a :ref:`setuptools` :file:`setup.py` keyword that
should be used to specify what a project **minimally** needs to run correctly.
When the project is installed by :ref:`pip`, this is the specification that is
used to install its dependencies.

For example, if the project requires A and B, your ``install_requires`` would be
For example, if the project requires A and B, your ``dependencies`` would be
like so:

::
.. code-block:: toml

install_requires=[
'A',
'B'
]
[project]
dependencies = ["A", "B"]

Additionally, it's best practice to indicate any known lower or upper bounds.

For example, it may be known, that your project requires at least v1 of 'A', and
v2 of 'B', so it would be like so:

::
.. code-block:: toml

install_requires=[
'A>=1',
'B>=2'
]
[project]
dependencies = [
"A>=1",
"B>=2"
jeanas marked this conversation as resolved.
Show resolved Hide resolved
]

It may also be known that project 'A' introduced a change in its v2
that breaks the compatibility of your project with v2 of 'A' and later,
so it makes sense to not allow v2:

::
.. code-block:: toml

install_requires=[
'A>=1,<2',
'B>=2'
]
[project]
dependencies = [
"A>=1,<2",
"B>=2"
jeanas marked this conversation as resolved.
Show resolved Hide resolved
]

It is not considered best practice to use ``install_requires`` to pin
dependencies to specific versions, or to specify sub-dependencies
It is not considered best practice to use ``dependencies`` to pin
dependencies to specific versions, or to specify transitive dependencies
(i.e. dependencies of your dependencies). This is overly-restrictive, and
prevents the user from gaining the benefit of dependency upgrades.

Lastly, it's important to understand that ``install_requires`` is a listing of
"Abstract" requirements, i.e just names and version restrictions that don't
determine where the dependencies will be fulfilled from (i.e. from what
index or source). The where (i.e. how they are to be made "Concrete") is to
be determined at install time using :ref:`pip` options. [1]_
Lastly, it's important to understand that ``dependencies`` is a listing of
jeanas marked this conversation as resolved.
Show resolved Hide resolved
"abstract" requirements, i.e, it just names and version restrictions, but doesn't
jeanas marked this conversation as resolved.
Show resolved Hide resolved
determine where the dependencies will be fulfilled from (from what package
index or source). The where (i.e. how they are to be made "concrete") is to
be determined at install time, e.g., using :ref:`pip` options. [1]_


Requirements files
------------------
==================

:ref:`Requirements Files <pip:Requirements Files>` described most simply, are
:ref:`Requirements Files <pip:Requirements Files>`, described most simply, are
just a list of :ref:`pip:pip install` arguments placed into a file.

Whereas ``install_requires`` defines the dependencies for a single project,
Whereas ``dependencies`` defines the dependencies for a single project,
:ref:`Requirements Files <pip:Requirements Files>` are often used to define
the requirements for a complete Python environment.

Whereas ``install_requires`` requirements are minimal, requirements files
Whereas ``dependencies`` requirements are minimal, requirements files
often contain an exhaustive listing of pinned versions for the purpose of
jeanas marked this conversation as resolved.
Show resolved Hide resolved
achieving :ref:`repeatable installations <pip:Repeatability>` of a complete
environment.

Whereas ``install_requires`` requirements are "Abstract", i.e. not associated
Whereas ``dependencies`` requirements are "abstract", i.e., not associated
with any particular index, requirements files often contain pip
options like ``--index-url`` or ``--find-links`` to make requirements
"Concrete", i.e. associated with a particular index or directory of
"concrete", i.e., associated with a particular index or directory of
packages. [1]_

Whereas ``install_requires`` metadata is automatically analyzed by pip during an
Whereas ``dependencies`` metadata is automatically analyzed by pip during an
install, requirements files are not, and only are used when a user specifically
installs them using ``python -m pip install -r``.

----

.. [1] For more on "Abstract" vs "Concrete" requirements, see
.. [1] For more on "abstract" vs "concrete" requirements, see
https://caremad.io/posts/2013/07/setup-vs-requirement/.
2 changes: 0 additions & 2 deletions source/guides/distributing-packages-using-setuptools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -394,8 +394,6 @@ package, set ``py_modules`` to a list of the names of the modules (minus the
minimally needs to run. When the project is installed by :ref:`pip`, this is the
specification that is used to install its dependencies.

For more on using "install_requires" see :ref:`install_requires vs Requirements files`.


.. _python_requires:

Expand Down
2 changes: 2 additions & 0 deletions source/guides/writing-pyproject-toml.rst
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ This field is required, although it is often marked as dynamic using
Dependencies and requirements
=============================

.. _writing-pyproject-toml-dependencies:

``dependencies``/``optional-dependencies``
------------------------------------------

Expand Down