Skip to content

Commit

Permalink
Merge pull request #1668 from hynek/intro-standards
Browse files Browse the repository at this point in the history
Add pyproject.toml & modern packaging to introduction.
  • Loading branch information
webknjaz authored Aug 13, 2022
2 parents ae34c7f + 5b7d68b commit 9e6bd8e
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 25 deletions.
113 changes: 89 additions & 24 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ Example usage for ``pip-compile``
=================================

The ``pip-compile`` command lets you compile a ``requirements.txt`` file from
your dependencies, specified in either ``setup.py`` or ``requirements.in``.
your dependencies, specified in either ``pyproject.toml``, ``setup.cfg``,
``setup.py``, or ``requirements.in``.

Run it with ``pip-compile`` or ``python -m piptools compile``. If you use
multiple Python versions, you can also run ``py -X.Y -m piptools compile`` on
Expand All @@ -67,39 +68,105 @@ available. To compile from scratch, first delete the existing
``requirements.txt`` file, or see `Updating requirements`_ for alternative
approaches.

Requirements from ``setup.py``
------------------------------
Requirements from ``pyproject.toml``
------------------------------------

Suppose you have a Django project, and want to pin it for production.
If you have a ``setup.py`` with ``install_requires=['django']``, then run
``pip-compile`` without any arguments:
The ``pyproject.toml`` file is the
`latest standard <https://peps.python.org/pep-0621/>`_ for configuring
packages and applications, and is recommended for new projects. ``pip-compile``
supports both installing your ``project.dependencies`` as well as your
``project.optional-dependencies``. Thanks to the fact that this is an
official standard, you can use ``pip-compile`` to pin the dependencies
in projects that use modern standards-adhering packaging tools like
`Hatch <https://hatch.pypa.io/>`_ or `flit <https://flit.pypa.io/>`_.

.. code-block:: bash
Suppose you have a Django application that is packaged using ``Hatch``, and you
want to pin it for production. You also want to pin your development tools
in a separate pin file. You declare ``django`` as a dependency and create an
optional dependency ``dev`` that includes ``pytest``:

$ pip-compile
.. code-block:: toml
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "my-cool-django-app"
version = "42"
dependencies = ["django"]
[project.optional-dependencies]
dev = ["pytest"]
You can produce your pin files as easily as:

.. code-block:: console
$ pip-compile -o requirements.txt pyproject.toml
#
# This file is autogenerated by pip-compile
# This file is autogenerated by pip-compile with python 3.10
# To update, run:
#
# pip-compile
# pip-compile --output-file=requirements.txt pyproject.toml
#
asgiref==3.2.3
asgiref==3.5.2
# via django
django==4.1
# via my-cool-django-app (pyproject.toml)
sqlparse==0.4.2
# via django
django==3.0.3
# via my_django_project (setup.py)
pytz==2019.3
$ pip-compile --extra dev -o dev-requirements.txt pyproject.toml
#
# This file is autogenerated by pip-compile with python 3.10
# To update, run:
#
# pip-compile --extra=dev --output-file=dev-requirements.txt pyproject.toml
#
asgiref==3.5.2
# via django
sqlparse==0.3.0
attrs==22.1.0
# via pytest
django==4.1
# via my-cool-django-app (pyproject.toml)
iniconfig==1.1.1
# via pytest
packaging==21.3
# via pytest
pluggy==1.0.0
# via pytest
py==1.11.0
# via pytest
pyparsing==3.0.9
# via packaging
pytest==7.1.2
# via my-cool-django-app (pyproject.toml)
sqlparse==0.4.2
# via django
tomli==2.0.1
# via pytest
This is great for both pinning your applications, but also to keep the CI
of your open-source Python package stable.

Requirements from ``setup.py`` and ``setup.cfg``
------------------------------------------------

``pip-compile`` will produce your ``requirements.txt``, with all the Django
dependencies (and all underlying dependencies) pinned.
``pip-compile`` has also full support for ``setup.py``- and
``setup.cfg``-based projects that use ``setuptools``.

Without ``setup.py``
--------------------
Just define your dependencies and extras as usual and run
``pip-compile`` as above.

If you don't use ``setup.py`` (`it's easy to write one`_), you can create a
``requirements.in`` file to declare the Django dependency:
Requirements from ``requirements.in``
-------------------------------------

You can also use plain text files for your requirements (e.g. if you don't
want your application to be a package). To use a ``requirements.in`` file to
declare the Django dependency:

.. code-block:: ini
Expand Down Expand Up @@ -129,15 +196,13 @@ Now, run ``pip-compile requirements.in``:
And it will produce your ``requirements.txt``, with all the Django dependencies
(and all underlying dependencies) pinned.

.. _it's easy to write one: https://packaging.python.org/guides/distributing-packages-using-setuptools/#configuring-your-project

.. _Updating requirements:

Updating requirements
---------------------

``pip-compile`` generates a ``requirements.txt`` file using the latest versions
that fulfil the dependencies of ``setup.py`` or ``requirements.in``.
that fulfil the dependencies you specify in the supported files.

If ``pip-compile`` finds an existing ``requirements.txt`` file that fulfils the
dependencies then no changes will be made, even if updates are available.
Expand Down
5 changes: 4 additions & 1 deletion piptools/scripts/compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,10 @@ def cli(
emit_options: bool,
unsafe_package: Tuple[str, ...],
) -> None:
"""Compiles requirements.txt from requirements.in specs."""
"""
Compiles requirements.txt from requirements.in, pyproject.toml, setup.cfg,
or setup.py specs.
"""
log.verbosity = verbose - quiet

if len(src_files) == 0:
Expand Down

0 comments on commit 9e6bd8e

Please sign in to comment.