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

Merge PEP 660 implementation into main #3488

Merged
merged 145 commits into from Aug 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
145 commits
Select commit Hold shift + click to select a range
be3778e
include pep660 proof of concept
dholth Feb 4, 2022
2bddfdf
include pep660 proof of concept (#3082)
abravalheri Apr 11, 2022
c6106b7
Add dist_info_dir param to dist_info command
abravalheri Apr 13, 2022
ad803ae
Change dist_info to better control output directory
abravalheri Apr 3, 2022
e36951e
Merge branch 'upstream/main' into build-editable-aggregate
abravalheri May 19, 2022
e55e51d
Change build_meta to use --output-dir instead of --egg-base for dist-…
abravalheri Apr 3, 2022
1afb6c0
Make sure output_dir exists with dist_info
abravalheri Apr 4, 2022
0e6870b
Avoid creating dist_info_dir before the command runs
abravalheri Apr 13, 2022
da6dd05
Fix signature for build_editable according to PEP 660
abravalheri Apr 3, 2022
e7123c6
Fix flake8 errors with build_meta
abravalheri Apr 3, 2022
821d664
Add prepare_metadata_for_build_editable hook
abravalheri Apr 3, 2022
c642529
Editable rework dist_info to use --output-dir instead of --egg-base
abravalheri Jun 15, 2022
5bb97d0
Remove unecessary editable dependency
abravalheri Apr 3, 2022
3e9f441
Make sure setuptools itself can be installed with editable_wheel
abravalheri Apr 13, 2022
5866b85
Rely on wheel and bdist_wheel for editable_wheel
abravalheri Apr 4, 2022
aee3245
Re-use dist-info dir for build_editable
abravalheri Apr 4, 2022
33f2431
Always run editable install test
abravalheri Apr 4, 2022
06fbc36
Start adding APIs for handling multiple editable modes
abravalheri Apr 5, 2022
0bf1d4c
Rework PEP 660 PoC to re-use bdist_wheel
abravalheri Jun 15, 2022
7b402eb
Temporarily support deprecated namespace packages
abravalheri Apr 6, 2022
a31df2e
Remove unused function
abravalheri Apr 13, 2022
7ae5a69
Reorganise editable_wheel to allow different strategies
abravalheri Apr 9, 2022
a13adc8
Handle namespace_packages in editable_wheel
abravalheri Jun 15, 2022
14eb855
Rename variable for clarity
abravalheri Apr 9, 2022
8cb1344
Add namespace test
abravalheri Apr 9, 2022
f997500
Add initial implementation of editable strategy based on .pth file
abravalheri Jun 15, 2022
73c65b2
Move test from test_develop to test_editable_install
abravalheri Apr 9, 2022
59a39d9
Add test for PEP 420 packages
abravalheri Apr 9, 2022
a27b96b
Add tests for editable install focusing on namespaces
abravalheri Jun 15, 2022
1a531db
Add template for MetaPathFinder that can be used in editable mode
abravalheri Apr 9, 2022
dd9886c
Add test for namespaces created via package_dir
abravalheri Apr 9, 2022
f210f16
Relax file types in discovery
abravalheri Apr 9, 2022
994ca21
Add editable strategy with MetaPathFinder for top-level packages
abravalheri Apr 9, 2022
fba8717
Make sure top-level modules can be imported in editable install
abravalheri Apr 9, 2022
3ba7ec4
Add logging messages to editable install
abravalheri Apr 9, 2022
01ceef6
Fix error with Python 3.7
abravalheri Apr 10, 2022
55260a7
Prevent errors when __path__ is not set
abravalheri Apr 12, 2022
730b6e7
Prevent errors due to caching in sys.modules
abravalheri Apr 12, 2022
50afbf4
Add LinkTree strategy for build executable
abravalheri Apr 10, 2022
40f2f0f
Improve clarity of 'editable_wheel' code
abravalheri Apr 11, 2022
f5643f5
Initial editable MetaPathFinder for top-level pkgs
abravalheri Jun 15, 2022
4112379
Add more tests for editable install
abravalheri Apr 11, 2022
008a718
Add temporary workaround for packages.find.exclude
abravalheri Apr 22, 2022
f3786f3
Allow egg-info directory to be ignored in manifest
abravalheri Apr 11, 2022
06d52fe
Fix problems with link assertions on Windows
abravalheri Apr 12, 2022
9dc2588
Ignore transient warning
abravalheri May 19, 2022
92c90db
Add a better workaround for 3260 in tests for editable tree
abravalheri May 19, 2022
a4e16fe
Remove unnecessary fixture from tests
abravalheri Apr 17, 2022
99cf706
Test dynamic namespace path computation
abravalheri Apr 17, 2022
3c71c87
Correctly handle namespace spec via PathEntryFinder
abravalheri Apr 16, 2022
d9c4a41
Add editable strategy based on a link tree
abravalheri Jun 15, 2022
2ca60ad
Adequate tests to new internal API
abravalheri Apr 17, 2022
501aec9
Add missing methods to PathEntryFinder
abravalheri Apr 17, 2022
4687243
Avoid adding PathEntryFinder if not necessary
abravalheri Apr 17, 2022
daaf3ab
Ensure namespaces from ImportFinder handle additions to path
abravalheri Jun 15, 2022
ebf8369
Add translator for config_settings to build_meta
abravalheri Jun 15, 2022
6f680c9
Ensure new options for dist-info work
abravalheri Jun 16, 2022
da33c52
Make the dist info args translation private
abravalheri Jun 16, 2022
26f38a2
build_meta: Consider --global-option and --build-option
abravalheri Jun 16, 2022
c338f92
Support --build-option alongside --global-option
abravalheri Jun 16, 2022
4092e3b
Prefer 'verbose' and 'quiet' instead of 'log-level'
abravalheri Jun 16, 2022
46c1636
Consider config_settings in build_editable
abravalheri Jun 16, 2022
df44192
build_meta.build_editable: Add tests for config_settings
abravalheri Jun 16, 2022
01d961a
Add warning with information for the user about link tree
abravalheri Jun 16, 2022
57c863a
Add news fragment
abravalheri Jun 16, 2022
8db675d
Skip problematic test on macOS
abravalheri Jun 16, 2022
a19c4df
Address errors in tests for Windows
abravalheri Jun 17, 2022
66538d8
Handle `config_settings` as they would be passed by pip (#3380)
abravalheri Jun 17, 2022
ecdeb22
Add new item for PEP 660 implementation
abravalheri Jun 17, 2022
84d5133
build_py: Allow get_outputs() to work without re-running egg-info
abravalheri Jun 18, 2022
207da8c
Make it possible for build_py to export the output mapping
abravalheri Jun 19, 2022
075a3c8
Make it possible for build_ext to export the output mapping
abravalheri Jun 19, 2022
2be4465
Add news fragment
abravalheri Jun 19, 2022
64fdf11
Remove debugging code
abravalheri Jun 19, 2022
d019f49
Fix linting errors
abravalheri Jun 20, 2022
cdd12f3
Add get_output_mapping to build_py and build_ext (#3392)
abravalheri Jun 21, 2022
fd891af
Allow dist-info to keep original egg-info directory
abravalheri Jun 21, 2022
fd5fcbb
build_meta: Allow dist-info and egg-info to coexist
abravalheri Jun 21, 2022
90c3149
Fix problems with backup directory
abravalheri Jun 21, 2022
bd48c63
Allow dist_info to leave egg_info dir to be used by other steps of th…
abravalheri Jun 24, 2022
8832db2
Merge remote-tracking branch 'upstream/main' into feature/pep660
abravalheri Jun 24, 2022
f2da32f
Rely on get_outputs() and get_output_mapping() in editable_wheel
abravalheri Jun 24, 2022
7a9bc76
Remove unnecessary complexity
abravalheri Jun 24, 2022
5b7498b
editable_wheel: Move warnings/logging inside the strategy classes
abravalheri Jun 24, 2022
5f231b9
editable_wheel: simplify strategy instantiation
abravalheri Jun 24, 2022
a376bf9
editable_wheel: Improve strategy interface
abravalheri Jun 24, 2022
fdd9ab3
Add docstrings for command classes
abravalheri Jun 24, 2022
965458d
Revert addition of use_links to build_lib
abravalheri Jun 24, 2022
28f6f36
Merge 'upstream/main' into feature/pep660
abravalheri Jun 25, 2022
700237e
Update editable install to use get_output_mapping (#3409)
abravalheri Jun 25, 2022
c675d78
sdist: Add files from build subcommands (get_source_files)
abravalheri Jun 24, 2022
5479513
Add news fragment
abravalheri Jun 25, 2022
2ee94e7
sdist: Add files from build subcommands - get_source_files (#3412)
abravalheri Jun 25, 2022
0a82048
Test symlinks in the target directory
abravalheri Jun 24, 2022
2a9b06f
Update development mode docs
abravalheri Jun 25, 2022
1648318
Allow users to opt-into previous "develop" behavior
abravalheri Jun 25, 2022
a3e8d4d
Add help message to editable install exception
abravalheri Jun 25, 2022
6362056
Add news fragment
abravalheri Jun 25, 2022
d5b5f6b
Add note about using editable installs for test environments
abravalheri Jun 25, 2022
17311b1
Add interfaces to docs
abravalheri Jun 25, 2022
54935d6
Add notes about namespaces, tox + small fixes
abravalheri Jun 27, 2022
e7f351b
Improve docs and behaviour of editable installs (#3414)
abravalheri Jun 27, 2022
8bf3658
Fix header location
abravalheri Jun 27, 2022
85303e8
Temporarily bump beta version
abravalheri Jun 29, 2022
f3796a6
Document dir in strict editable installs
abravalheri Jun 29, 2022
156a75f
Document strict editable installs use the `build` directory (#3425)
abravalheri Jul 3, 2022
9d72045
Ensure members of the subcommand protocol are listed by autodoc
abravalheri Jul 3, 2022
b422ddc
Fix grammar problems with paragraph in docs
abravalheri Jul 3, 2022
233c986
[Doc] Ensure members of the build subcommand protocol are listed by a…
abravalheri Jul 4, 2022
618f4ef
Merge 'upstream/main' into feature/pep660
abravalheri Jul 4, 2022
2022949
Temporarily bump beta version
abravalheri Jul 4, 2022
49e2152
Fix outdated version number in docs
abravalheri Jul 4, 2022
d0d8b63
Merge 'upstream/main' into feature/pep660
abravalheri Jul 21, 2022
ab8e033
Merge branch 'main' into feature/pep660
abravalheri Aug 2, 2022
2b7c44f
Add prepare_metadata_for_build_editable to build_meta.__all__
abravalheri Aug 2, 2022
5e50139
Use set comparisson in test instead of list
abravalheri Aug 2, 2022
f4d411c
Add prepare_metadata_for_build_editable to build_meta.__all__ (#3477)
abravalheri Aug 2, 2022
38cf2d0
Use venv to isolate test_legacy_editable_install
abravalheri Aug 2, 2022
a703ff8
Use venv to isolate `test_legacy_editable_install` (#3478)
abravalheri Aug 2, 2022
7b2402a
Avoid using 'SETUPTOOLS_EDITABLE' env var in test
abravalheri Aug 2, 2022
4b8a6e0
Avoid using SETUPTOOLS_EDITABLE env var in test (#3479)
abravalheri Aug 3, 2022
0d3cf53
Merge branch 'main' into feature/pep660
abravalheri Aug 3, 2022
0ca171c
docs: Expand editable install limitations section
abravalheri Aug 3, 2022
fbd2530
docs: Mention 'compat' editable installation mode
abravalheri Aug 3, 2022
1d9ac32
doc: Add section explaining how editable installs work
abravalheri Aug 3, 2022
80311ab
docs: Improve developement_mode.rst
abravalheri Aug 3, 2022
da5af04
Add compat mode to editable install
abravalheri Aug 2, 2022
9e99099
Adapt test_build_meta to the new format of editable_wheel options
abravalheri Aug 2, 2022
266c38d
Make editable mode nomenclature homogeneous
abravalheri Aug 2, 2022
d57e68b
Add deprecation warning for compat editable mode
abravalheri Aug 2, 2022
498fb5c
Add test for 'compat' editable mode
abravalheri Aug 2, 2022
eb363c3
Use better wording in description of 'compat' editable mode
abravalheri Aug 2, 2022
4f4c6ac
Improve editable_wheel command help
abravalheri Aug 2, 2022
f3e11d7
Add news fragment
abravalheri Aug 3, 2022
4c2611b
Prevent test errors on Windows due to path sep
abravalheri Aug 4, 2022
da4249d
Merge branch 'main' into feature/pep660
abravalheri Aug 4, 2022
2f06393
Add transitional compat editable install (#3484)
abravalheri Aug 4, 2022
90c29d9
Update docs on the development_mode page (#3485)
abravalheri Aug 4, 2022
3f49880
docs: Fix link display text
abravalheri Aug 4, 2022
4a37623
docs: Fix phrases in userguide/development_mode
abravalheri Aug 5, 2022
b0b9420
docs: Fix incorrect syntax
abravalheri Aug 5, 2022
ccca622
Merge branch 'main' into feature/pep660
abravalheri Aug 5, 2022
5aa389c
Merge 'main' into feature/pep660
abravalheri Aug 6, 2022
228f3e9
Update docs to reflect the implementation of PEP 660
abravalheri Aug 6, 2022
707f953
Update docs to better reflect the implementation of PEP 660 (#3490)
abravalheri Aug 8, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions bootstrap.egg-info/entry_points.txt
Expand Up @@ -2,6 +2,7 @@
egg_info = setuptools.command.egg_info:egg_info
build_py = setuptools.command.build_py:build_py
sdist = setuptools.command.sdist:sdist
editable_wheel = setuptools.command.editable_wheel:editable_wheel

[distutils.setup_keywords]
include_package_data = setuptools.dist:assert_bool
Expand Down
17 changes: 17 additions & 0 deletions changelog.d/3265.change.rst
@@ -0,0 +1,17 @@
Added implementation for *editable install* hooks (PEP 660) - **beta** stage.

- The user will be able select between two distinct behaviors:

- *lenient*, which prioritises the ability of the users of changing the
distributed packages (e.g. adding new files or removing old ones)

- *strict*, which will try to replicate as much as possible the behavior of
the package as if it would be normally installed by end users.
The *strict* editable installation is not able to detect if files are
added or removed from the project (a new installation is required).

.. important::
The *editable* aspect of the *editable install* supported this implementation
is restricted to the Python modules contained in the distributed package.
Changes in binary extensions (e.g. C/C++), entry-point definitions,
dependencies, metadata, datafiles, etc require a new installation.
10 changes: 10 additions & 0 deletions changelog.d/3380.change.rst
@@ -0,0 +1,10 @@
Improved the handling of the ``config_settings`` parameter in both PEP 517 and
PEP 660 interfaces:

- It is possible now to pass both ``--global-option`` and ``--build-option``.
As discussed in #1928, arbitrary arguments passed via ``--global-option``
should be placed before the name of the setuptools' internal command, while
``--build-option`` should come after.

- Users can pass ``editable-mode=strict`` to select a strict behaviour for the
editable installation.
7 changes: 7 additions & 0 deletions changelog.d/3380.deprecation.rst
@@ -0,0 +1,7 @@
Passing some types of parameters via ``--global-option`` to setuptools PEP 517/PEP 660 backend
is now considered deprecated. The user can pass the same arbitrary parameter
via ``--build-option`` (``--global-option`` is now reserved for flags like
``--verbose`` or ``--quiet``).

Both ``--build-option`` and ``--global-option`` are supported as a **transitional** effort (a.k.a. "escape hatch").
In the future a proper list of allowed ``config_settings`` may be created.
5 changes: 5 additions & 0 deletions changelog.d/3392.change.rst
@@ -0,0 +1,5 @@
Exposed ``get_output_mapping()`` from ``build_py`` and ``build_ext``
subcommands. This interface is reserved for the use of ``setuptools``
Extensions and third part packages are explicitly disallowed to calling it.
However, any implementation overwriting ``build_py`` or ``build_ext`` are
required to honour this interface.
3 changes: 3 additions & 0 deletions changelog.d/3412.change.rst
@@ -0,0 +1,3 @@
Added ability of collecting source files from custom build sub-commands to
``sdist``. This allows plugins and customization scripts to automatically
add required source files in the source distribution.
4 changes: 4 additions & 0 deletions changelog.d/3414.change.rst
@@ -0,0 +1,4 @@
Users can *temporarily* specify an environment variable
``SETUPTOOLS_ENABLE_FEATURE=legacy-editable`` as a escape hatch for the
:pep:`660` behavior. This setting is **transitional** and may be removed in the
future.
2 changes: 2 additions & 0 deletions changelog.d/3414.doc.rst
@@ -0,0 +1,2 @@
Updated :doc:`Development Mode </userguide/development_mode>` to reflect on the
implementation of :pep:`660`.
6 changes: 6 additions & 0 deletions changelog.d/3484.change.rst
@@ -0,0 +1,6 @@
Added *transient* ``compat`` mode to editable installs.
This more will be temporarily available (to facilitate the transition period)
for those that want to emulate the behavior of the ``develop`` command
(in terms of what is added to ``sys.path``).
This mode is provided "as is", with limited support, and will be removed in
future versions of ``setuptools``.
287 changes: 256 additions & 31 deletions docs/userguide/development_mode.rst
@@ -1,34 +1,259 @@
Development Mode
================

Under normal circumstances, the ``setuptools`` assume that you are going to
build a distribution of your project, not use it in its "raw" or "unbuilt"
form. However, if you were to use the ``setuptools`` to build a distribution,
you would have to rebuild and reinstall your project every time you made a
change to it during development.

Another problem that sometimes comes is that you may
need to do development on two related projects at the same time. You may need
to put both projects' packages in the same directory to run them, but need to
keep them separate for revision control purposes. How can you do this?

Setuptools allows you to deploy your projects for use in a common directory or
staging area, but without copying any files. Thus, you can edit each project's
code in its checkout directory, and only need to run build commands when you
change files that need to be compiled or the provided metadata and setuptools configuration.

You can perform a ``pip`` installation passing the ``-e/--editable``
flag (e.g., ``pip install -e .``). It works very similarly to
``pip install .``, except that it doesn't actually install anything.
Instead, it creates a special ``.egg-link`` file in the target directory
(usually ``site-packages``) that links to your project's source code.
It may also update an existing ``easy-install.pth`` file
to include your project's source code, thereby making
it available on ``sys.path`` for all programs using that Python installation.

You can deploy the same project to multiple staging areas, e.g., if you have
multiple projects on the same machine that are sharing the same project you're
doing development work.
Development Mode (a.k.a. "Editable Installs")
=============================================

When creating a Python project, developers usually want to implement and test
changes iteratively, before cutting a release and preparing a distribution archive.

In normal circumstances this can be quite cumbersome and require the developers
to manipulate the ``PATHONPATH`` environment variable or to continuous re-build
and re-install the project.

To facilitate iterative exploration and experimentation, setuptools allows
users to instruct the Python interpreter and its import machinery to load the
code under development directly from the project folder without having to
copy the files to a different location in the disk.
This means that changes in the Python source code can immediately take place
without requiring a new installation.

You can enter this "development mode" by performing an :doc:`editable installation
<pip:topics/local-project-installs>` inside of a :term:`virtual environment`,
using :doc:`pip's <pip:cli/pip_install>` ``-e/--editable`` flag, as shown bellow:

.. code-block:: bash
$ cd your-python-project
$ python -m venv .venv
# Activate your environemt with:
# `source .venv/bin/activate` on Unix/macOS
# or `.venv\Scripts\activate` on Windows
$ pip install --editable .
# Now you have access to your package
# as if it was installed in .venv
$ python -c "import your_python_project"
An "editable installation" works very similarly to a regular install with
``pip install .``, except that it only installs your package dependencies,
metadata and wrappers for :ref:`console and GUI scripts <console-scripts>`.
Under the hood, setuptools will try to create a special :mod:`.pth file <site>`
in the target directory (usually ``site-packages``) that extends the
``PYTHONPATH`` or install a custom :doc:`import hook <python:reference/import>`.

When you're done with a given development task, you can simply uninstall your
package (as you would normally do with ``pip uninstall <package name>``).

Please note that, by default an editable install will expose at least all the
files that would be available in a regular installation. However, depending on
the file and directory organization in your project, it might also expose
as a side effect files that would not be normally available.
This is allowed so you can iteratively create new Python modules.
Please have a look on the following section if you are looking for a different behaviour.

.. admonition:: Virtual Environments

You can think about virtual environments as "isolated Python runtime deployments"
that allow users to install different sets of libraries and tools without
messing with the global behaviour of the system.

They are a safe way of testing new projects and can be created easily
with the :mod:`venv` module from the standard library.

Please note however that depending on your operating system or distribution,
``venv`` might not come installed by default with Python. For those cases,
you might need to use the OS package manager to install it.
For example, in Debian/Ubuntu-based systems you can obtain it via:

.. code-block:: bash
sudo apt install python3-venv
Alternatively, you can also try installing :pypi:`virtualenᴠ`.
More information is available on the Python Packaging User Guide on
:doc:`PyPUG:guides/installing-using-pip-and-virtual-environments`.

.. note::
.. versionchanged:: v64.0.0
Editable installation hooks implemented according to :pep:`660`.
Support for :pep:`namespace packages <420>` is still **EXPERIMENTAL**.


"Strict" editable installs
--------------------------

When thinking about editable installations, users might have the following
expectations:

1. It should allow developers to add new files (or split/rename existing ones)
and have them automatically exposed.
2. It should behave as close as possible to a regular installation and help
users to detect problems (e.g. new files not being included in the distribution).

Unfortunately these expectations are in conflict with each other.
To solve this problem ``setuptools`` allows developers to choose a more
*"strict"* mode for the editable installation. This can be done by passing
a special *configuration setting* via :pypi:`pip`, as indicated bellow:

.. code-block:: bash
pip install -e . --config-settings editable_mode=strict
In this mode, new files **won't** be exposed and the editable installs will
try to mimic as much as possible the behavior of a regular install.
Under the hood, ``setuptools`` will create a tree of file links in an auxiliary
directory (``$your_project_dir/build``) and add it to ``PYTHONPATH`` via a
:mod:`.pth file <site>`. (Please be careful to not delete this repository
by mistake otherwise your files may stop being accessible).

.. warning::
Strict editable installs require auxiliary files to be placed in a
``build/__editable__.*`` directory (relative to your project root).

Please be careful to not remove this directory while testing your project,
otherwise your editable installation may be compromised.

You can remove the ``build/__editable__.*`` directory after uninstalling.


.. note::
.. versionadded:: v64.0.0
*Strict* mode implemented as **EXPERIMENTAL**.


Limitations
-----------

- The *editable* term is used to refer only to Python modules
inside the package directories. Non-Python files, external (data) files,
executable script files, binary extensions, headers and metadata may be
exposed as a *snapshot* of the version they were at the moment of the
installation.
- Adding new dependencies, entry-points or changing your project's metadata
require a fresh "editable" re-installation.
- Console scripts and GUI scripts **MUST** be specified via :doc:`entry-points
</userguide/entry_point>` to work properly.
- *Strict* editable installs require the file system to support
either :wiki:`symbolic <symbolic link>` or :wiki:`hard links <hard link>`.
This installation mode might also generate auxiliary files under the project directory.
- There is *no guarantee* that the editable installation will be performed
using a specific technique. Depending on each project, ``setuptools`` may
select a different approach to ensure the package is importable at runtime.
- There is *no guarantee* that files outside the top-level package directory
will be accessible after an editable install.
- There is *no guarantee* that attributes like ``__path__`` or ``__file__``
will correspond to the exact location of the original files (e.g.,
``setuptools`` might employ file links to perform the editable installation).
Users are encouraged to use tools like :mod:`importlib.resources` or
:mod:`importlib.metadata` when trying to access package files directly.
- Editable installations may not work with
:doc:`namespaces created with pkgutil or pkg_resouces
<PyPUG:guides/packaging-namespace-packages>`.
Please use :pep:`420`-style implicit namespaces [#namespaces]_.
- Support for :pep:`420`-style implicit namespace packages for
projects structured using :ref:`flat-layout` is still **experimental**.
If you experience problems, you can try converting your package structure
to the :ref:`src-layout`.

.. attention::
Editable installs are **not a perfect replacement for regular installs**
in a test environment. When in doubt, please test your projects as
installed via a regular wheel. There are tools in the Python ecosystem,
like :pypi:`tox` or :pypi:`nox`, that can help you with that
(when used with appropriate configuration).


Legacy Behavior
---------------

If your project is not compatible with the new "editable installs" or you wish
to replicate the legacy behavior, for the time being you can also perform the
installation in the ``compat`` mode:

.. code-block:: bash
pip install -e . --config-settings editable_mode=compat
This installation mode will try to emulate how ``python setup.py develop``
works (still within the context of :pep:`660`).

.. warning::
The ``compat`` mode is *transitional* and will be removed in
future versions of ``setuptools``, it exists only to help during the
migration period.
Also note that support for this mode is limited:
it is safe to assume that the ``compat`` mode is offered "as is", and
improvements are unlikely to be implemented.
Users are encouraged to try out the new editable installation techniques
and make the necessary adaptations.

If the ``compat`` mode does not work for you, you can also disable the
:pep:`editable install <660>` hooks in ``setuptools`` by setting an environment
variable:

.. code-block::
SETUPTOOLS_USE_FEATURE="legacy-editable"
This *may* cause the installer (e.g. ``pip``) to effectively run the "legacy"
installation command: ``python setup.py develop`` [#installer]_.


How editable installations work?
--------------------------------

*Advanced topic*

There are many techniques that can be used to expose packages under development
in such a way that they are available as if they were installed.
Depending on the project file structure and the selected mode, ``setuptools``
will choose one of these approaches for the editable installation [#criteria]_.

A non-exhaustive list of implementation mechanisms is presented below.
More information is available on the text of :pep:`PEP 660 <660#what-to-put-in-the-wheel>`.

- A static ``.pth`` file [#static_pth]_ can be added to one of the directories
listed in :func:`site.getsitepackages` or :func:`site.getusersitepackages` to
extend :obj:`sys.path`.
- A directory containing a *farm of file links* that mimic the
project structure and point to the original files can be employed.
This directory can then be added to :obj:`sys.path` using a static ``.pth`` file.
- A dynamic ``.pth`` file [#dynamic_pth]_ can also be used to install an
"import :term:`finder`" (:obj:`~importlib.abc.MetaPathFinder` or
:obj:`~importlib.abc.PathEntryFinder`) that will hook into Python's
:doc:`import system <python:reference/import>` machinery.

.. attention::
``Setuptools`` offers **no guarantee** of which technique will be used to
perform an editable installation. This will vary from project to project
and may change depending on the specific version of ``setuptools`` being
used.


----

.. rubric:: Notes

.. [#namespaces]
You *may* be able to use *strict* editable installations with namespace
packages created with ``pkgutil`` or ``pkg_namespaces``, however this is not
officially supported.
.. [#installer]
For this workaround to work, the installer tool needs to support legacy
editable installations. (Future versions of ``pip``, for example, may drop
support for this feature).
.. [#criteria]
``setuptools`` strives to find a balance between allowing the user to see
the effects of project files being edited while still trying to keep the
editable installation as similar as possible to a regular installation.
.. [#static_pth]
i.e., a ``.pth`` file where each line correspond to a path that should be
added to :obj:`sys.path`. See :mod:`Site-specific configuration hook <site>`.
.. [#dynamic_pth]
i.e., a ``.pth`` file that starts where each line starts with an ``import``
statement and executes arbitrary Python code. See :mod:`Site-specific
configuration hook <site>`.
2 changes: 2 additions & 0 deletions docs/userguide/entry_point.rst
Expand Up @@ -21,6 +21,8 @@ highlighting tool :pypi:`pygments` allows specifying additional styles
using the entry point ``pygments.styles``.


.. _console-scripts:

Console Scripts
===============

Expand Down