Skip to content

Conversation

@abravalheri
Copy link
Contributor

The idea of this PR is to partially tackle #3780.

Summary of changes

  • Introduced a warning class hierarchy starting with setuptools.warnings.SetuptoolsWarning.
    • All warnings should use inherit from this class, this way users can set warning filters appropriately.
  • Create a special emit method in the warning classes that adds a lot of visual decorations for improving the visibility.
    • This method also accepts kwargs like due_date, see_docs, see_url to provide more information to the user, as requested in Better visibility to deprecations #3780 (fallback to the corresponding attributes in the warning class, e.g. _DUE_DATE, _SEE_DOCS, etc...).
    • This is done mostly in commits:
  • I also added a mechanism to enforce the deprecation warnings to be turned into errors after the due date
    • This is done via the env var SETUPTOOLS_ENFORCE_DEPRECATION=true.
    • I set this to true in tox.ini to remind us to act once the deprecation period is over.
  • Replaced all calls to warnings.warn with the new emit. I took this opportunity to re-visit some of the warning messages and try to assign a due date as requested in Better visibility to deprecations #3780. This might be the bulk of the change.
  • Other minor modifications in test and modules to adapt to the new system.

Other implications and open questions

In this PR, I tried to assign "due dates" for the deprecation warnings as it was originally requested in #3780.
If we actually try to enforce these deprecations, this might be too disruptive...
Moreover there is always the problem with old unmaintained projects that may stop working if they need to be installed from sdists/source...

So we have a few options here:

  1. Forget about enforcing due dates for all the warnings and concentrate in a few.
  2. Review the due dates I tried to assign (my methodology was to guess an estimation date that would "feel right" depending on the age of the warning, where it is issued and the guesstimated probability of old projects relying on it, then I tried to cluster them in a few dates).

Remarks

I did not try to apply this to pkg_resources only to setuptools...
The reasoning behind it that pkg_resources warnings are DeprecationWarnings invisible by default... So I don't know how much effective changing it would be.

Pull Request Checklist

The objective is to centralize all the warnings in a single module.
@abravalheri abravalheri marked this pull request as ready for review March 7, 2023 23:49
@abravalheri
Copy link
Contributor Author

The following is a list of "due dates" that I loosely proposed in this PR.
Please feel free to suggest different ones or to completely drop the concept of a "due date".

  • 2023-Jun-01:

    • setuptools.package_index:_download_svn
      • Warning initially introduced in 2018-Sep-23
    • "Fixing" invalid egg-info directory name
      • The warning message was introduced in 2005, however it was a log.warn... Not sure if we want this to be a real warning or just ignore for now.
    • "Handling" depends.txt in egg-info
      • The warning message was also introduced in 2005, however it was a log.warn... Not sure if we want this to be a real warning or just ignore for now.
    • get_pkg_info_revision
      • Warning introduced in 2015
    • setuptools.dist:_get_unpatched
      • Warning initially introduced in 2016
    • A few deprecated methods in the easy_install command class: get_script_args, get_script_header, get_writer
      • These have been deprecated for a while and are direct API calls to a command that has been deprecated for a while by itself...
    • Invalid pyproject.toml metadata
      • Warning initially introduced in 2022-Mar-26
  • 2023-Sep-26:

    • "Fixing" catch all --global-option in setuptools.build_meta
      • Warning initially introduced in 2022-Aug-11
      • --global-option and --build-option where changed to follow the corresponding legacy usage in pip.
    • Invalid versions (non-PEP 440)
      • Setuptools already adopted the latest version of packaging that dropped LegacyVersion.
    • --egg-base CLI option for dist_info
      • dist_info is an internal command, and since direct usage of python setup.py is deprecated, it should not be used outside of the setuptools code base.
    • dash-separated or uppercase options in setup.cfg
      • Warning initially introduced in 2021-Mar
    • upload_docs
      • Warning initialy introduced in 2022-Jul-27
  • 2023-Oct-30:

    • bdist_rpm:
      • Warning initially introduced in 2021-Oct-22
    • Usage of namespace_packages in pyproject.toml
      • Warning initially introduced in 2022-May, but I am assuming that projects that use pyproject.toml for metadata are recent and still maintained.
    • Non-dynamic fields in the context of pyproject.toml that are specified via setup.py
      • Warning initially introduced in 2022-May-27
      • PEP 621 is very pedantic about dynamic fields ebing listed in dynamic.
    • requires in setup.cfg (instead of install_requires)
      • Warning initially inroduced in 2018-Oct-27
    • license_File in setup.cfg (instead of install_requires)
      • Warning initially inroduced in 2021-May-23
  • 2023-Dec-13:

    • Prevent people from importing convert_path directly from setuptools:
      • Warning initially introduced in 2022-Mar-25.
      • convert_path is part of distutils and imported by setuptools, but by no means this mean it is part of setuptools API...
    • Support for overwriting build.sub_subcommands using distutils class instead of the setuptools class:
      • Warning initially introduced in 2022-Jun-22

Unspecified "due dates":

  • Ambiguous configuration with include_package_data=True and packages that does not include datafiles-only packages. Initially introduced in May 2022.
  • easy_install as a setup.py command.
  • editable_mode=compat for editable installs (might cause a lot of push-back because static analysis tools and code editors don't support MetaPathFinders).
  • Customized build steps/build_py/build_ext that where written considering setup.py develop and are not ready to interoperate with the new implementation for PEP 660.
  • build_py that does not inherit from setuptools class and therefore does not interoperate well with egg_info.
  • install command.
  • setuptools.config:read_configuration (with pyproject.toml it makes more sense to direct users to something like build.util.project_wheel_metadata)
  • namespace_packages in setup.cfg / setup.py, setuptools.dist.check_nsp(old packages might still define it, e.g. sphinxcontrib)
  • Ambiguos marker in install_requires/extras_require in setup.cfg
  • setuptools.dist:single_line (controversial, lots of push back)
  • setuptools.dist:invalid_unless_false
  • setuptools.installer
@abravalheri
Copy link
Contributor Author

Probably this idea of adding a due date to every single deprecation warning is a bit too excessive... and is likely to cause a lot of push back from the community.

@jaraco do you have any thoughts about how should we handle deprecations? (Should we enforce an 'end-date' for them?).

Copy link
Contributor

@edmorley edmorley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for working on improving deprecation warnings! :-)

Co-authored-by: Ed Morley <501702+edmorley@users.noreply.github.com>
@abravalheri
Copy link
Contributor Author

Thank you very much for the suggestions @edmorley.

@pypa pypa deleted a comment Apr 2, 2023
@jaraco
Copy link
Member

jaraco commented Apr 2, 2023

All warnings should use inherit from [SetuptoolsWarning], this way users can set warning filters appropriately.

I'm slightly opposed to this concept because it sidesteps the conventions established by Python, mainly the convention that DeprecationWarnings get a special treatment (invisible by default except under tests). The reason we created SetuptoolsDeprecationWarning was to bypass this convention in select circumstances where it's important for end users to see the warning outside of test environments. In practice, since Setuptools is moving away from being an API and instead focusing on being a build backend, it's going to be increasingly important for build backends to be able to surface warnings and errors through the frontends. To the extent this change achieves that goal, that's great, but I do worry about the potential to create a whole new convention/standard that users may need to honor... or perhaps it's already that way and this change just consolidates the ad-hoc approach.

In this PR, I tried to assign "due dates" for the deprecation warnings as it was originally requested in #3780.
If we actually try to enforce these deprecations, this might be too disruptive...

The CPython project has started using a methodology for due dates, based on the formalized deprecation policy. That policy makes it easier, because it treats all deprecations as more-or-less equal and gives them two governed major releases before removing.

The process we're talking about introducing here is much more flexible and thus nuanced, so would require more consideration for each incidence. I worry that approach could increase the maintenance burden and impede the ability to enact deprecations when appropriate.

I've been unwilling to try to manage this space so rigorously, but I'm glad to see Anderson tackling this issue. I'm supportive of creating a framework for managing deprecations especially if it limits the aforementioned concerns. I'm willing to try it out and see how it goes.

As far as due dates, there are two facets to consider: giving users a more predictable expectation and mechanically enforcing that expectation. I'm an enthusiastic +1 on the former, but -0 on the latter. My main concern with mechanically enforcing due dates is that users would then have less control over protecting against breaking changes - the "breaking" release would be the one where the due date was added and not the one where the behavior is actually removed, because once the due-date passes, that release is now breaking (depending on your perspective). Or maybe there are now two breaking releases for each breaking change.

So while I have some concerns, I appreciate all the effort that's gone into characterizing the deprecations and creating a framework for managing them, and I'm happy to try it out.

@abravalheri abravalheri merged commit 73b5c62 into pypa:main Apr 20, 2023
@abravalheri abravalheri deleted the warnings-visibility branch April 20, 2023 14:07
@abravalheri
Copy link
Contributor Author

Thank you very much @jaraco, I merged this and created a new release. If we have a push back we can revert.

The reason why I went with a due date instead of a "2 releases from now" policy is because setuptools does not work with a release calendar like CPython. I thought that using a due date would make things more predictable.

The enforcement should only be "opt-in", so when the due date arrives, the users will still be able to use the software in the same way there where using before, as long as they don't set SETUPTOOLS_ENFORCE_DEPRECATION=true as an environment variable.

I did set SETUPTOOLS_ENFORCE_DEPRECATION=true in the test suite, so we are reminded to actually remove the deprecated code (and avoid it lingering for ever in the code base). We can also push back the due date if we find out that the community is still not prepared for the change.

@mattclay
Copy link

Additional details for the failure can be found on #3898, including a simple reproducer.

pytorchmergebot pushed a commit to pytorch/pytorch that referenced this pull request Jul 9, 2025
…> `[uv ]pip install --no-build-isolation [-e ].` (#156027) Modernize the development installation: ```bash # python setup.py develop python -m pip install --no-build-isolation -e . # python setup.py install python -m pip install --no-build-isolation . ``` Now, the `python setup.py develop` is a wrapper around `python -m pip install -e .` since `setuptools>=80.0`: - pypa/setuptools#4955 `python setup.py install` is deprecated and will emit a warning during run. The warning will become an error on October 31, 2025. - https://github.com/pypa/setuptools/blob/9c4d383631d3951fcae0afd73b5d08ff5a262976/setuptools/command/install.py#L58-L67 > ```python > SetuptoolsDeprecationWarning.emit( > "setup.py install is deprecated.", > """ > Please avoid running ``setup.py`` directly. > Instead, use pypa/build, pypa/installer or other > standards-based tools. > """, > see_url="https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html", > due_date=(2025, 10, 31), > ) > ``` - pypa/setuptools#3849 Additional Resource: - [Why you shouldn't invoke setup.py directly](https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html) Pull Request resolved: #156027 Approved by: https://github.com/ezyang
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

5 participants