Context and rationale behind deprecated lenient handling of dash-separated and uppercase terms in setup.cfg
#5011
Locked
abravalheri
started this conversation in
Dev
Replies: 1 comment
-
The primary purpose for this text is to be informative (and to be used as a link in the deprecation warnings), not necessarily reincite a heated debate. So I am considering to lock the conversation. Users can continue to provide feedback and debate via the existing issues and PRs, for example #4920, #4921, #4923, or open new ones. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
This post aims to clarify the context and rationale behind the deprecated features in
setuptools
related to configuration parsing insetup.cfg
.As with many long-standing open-source projects, setuptools is maintained by an ever-changing group of volunteers and contributors. While every effort is made to document decisions, reconstructing the full reasoning behind changes introduced years ago can be challenging. This post reflects the best understanding available, based on public discussions, issue history, and code contributions.
Deprecations and removals are a necessary part of maintaining a sustainable and reliable codebase. While such transitions can be disruptive, they are part of the ongoing effort to reduce technical debt, improve maintainability, and ensure long-term project health. An initial high-level overview of
setuptools
support policy can be seen in https://setuptools.pypa.io/en/latest/userguide/interfaces.html.Why Dash-Separated and Uppercase Options Were Deprecated
The deprecation of dash-separated and uppercase options in
setup.cfg
was primarily driven by the high maintenance burden, implementation complexity, and performance costs associated with supporting them. Historically, the complex logic required to normalize configuration keys - such as selectively replacing dashes with underscores and converting to lowercase - introduced inconsistencies, oversights, and bugs.In particular, a generalized normalization proved to be unreliable and was identified as the root cause of several issues. As a result, the implementation had to rely on special-casing specific options based on heuristics1 deriving from
importlib.metadata.entry_points
, a process that is both resource-intensive and difficult to maintain2. The relevant code paths have also shown to be unstable over time, requiring significant ongoing maintenance, as documented in the feature’s development history (summarised below).The overarching goal of this deprecation is to simplify the codebase, reduce technical debt, and improve performance by removing fragile and error-prone logic — rather than merely enforcing a stylistic preference in configuration formatting.
Users interested in revisiting the deprecation and the plans for removal
It is understandable that some users may prefer to retain support for dash-separated and uppercase options in
setup.cfg
. While the current direction ofsetuptools
is to deprecate and eventually remove this behaviour, the project remains open to community contributed alternative solutions — especially if they offer innovative approaches that address the underlying challenges (a fresh pair of eyes can reveal solutions that have not been devised before).The core issue is not simply about accepting dashes or uppercase letters; it’s about the complexity, fragility, maintenance and performance costs introduced by the current implementation. Any proposal to retain or reintroduce this functionality would need to address these concerns constructively.
If you’re interested in having
setuptools
revisit this deprecation, please submit contributions in the form of pull request (PR) that tackle the concerns above. Here are some guiding questions and expectations:setuptools.dist
?importlib
without introducing double-bookkeeping or hardcoded lists?An acceptable implementation should be able to respond affirmatively to the questions above. We're particularly interested in solutions that:
setuptools.config.setupcfg
to avoid scattered logic and reduce the "shotgun surgery" code smell.Setuptools have continuously considered community feedback and are actively working to improve the visibility and clarity of deprecation warnings, as well as to extend deprecation timelines where appropriate. These efforts reflect our commitment to minimizing disruption while still moving the project forward.
That said, backwards compatibility also requires shared effort. It is unrealistic to assume that
setuptools
will never introduce deprecations. If you believe this deprecation should be reconsidered, please consider contributing — not just feedback, but mainly via pull requests.Advice for end users that indirectly depend on
setuptools
Mission-critical systems and environments that cannot afford unforeseen/unintended interruptions should not rely on source distributions (sdists).
If your project or product requires high reliability and minimal disruption, please make sure to install packages exclusively via wheels (
.whl
)3 or other pre-built binary distributions (e.g. OS-provided). For packages that do not publish wheels on PyPI, you can explore alternatives such as:To further improve build stability and predictability, you can pin the version of setuptools using mechanisms like constraint files specified via:
PIP_CONSTRAINT
environment variable forpip
--build-constraint
CLI option foruv
.However, please avoid pre-emptively adding version constraints unless necessary. For a thoughtful discussion on this topic, see https://iscinumpy.dev/post/bound-version-constraints/.
For additional tips on how to stay informed and prepare for upcoming changes, please refer to the Setuptools User Guide.
Summarised history of the "accept dashes/uppercase in
setup.cfg
" feature and related changesThis timeline outlines the evolution of setuptools handling of dashes (-) and uppercase characters in
setup.cfg
, highlighting key issues, community contributions, and implementation decisions.08 Dec 2016,
setup.cfg
was introduced in setuptools for metadata and build settings (v30.3.0
), relying on the legacydistutils
implementation for command options, which silently replaced dashes with underscores.14 Dec 2018, extras_require in setup.cfg doesn't allow hyphen in extras name #1608
Users reported that the automatic dash-to-underscore conversion in
distutils
was breaking configurations. While initially observed withextras
, the issue also affected package names, data files, and entry points.08 Jan 2019, extras_require in setup.cfg doesn't allow hyphen in extras name #1608 (comment)
It was noted that the implementation was tightly coupled with
distutils
, making the codebase difficult to maintain.25 Jan 2019, 24be5ab
To improve
setup.cfg
parsing, significant complexity was introduced into thesetuptools
codebase.10 Dec 2019, setup.cfg: entry_points keys are made lowercase #1937
The default lenient behavior of
ConfigParser
was found to interfere with case-sensitive entry points.10 Dec 2020, target directories in data_files are incorrectly changed to lowercase #2480
Additional bugs related to lenient parsing of
setup.cfg
were reported.24 Feb 2021, Fix case sensitivity of entry point names and keys in setup.cfg. Fixes #1937 #2580
A community contribution modified the parser to bypass
ConfigParser.optionxform
, preserving original casing and dashes.01 Mar 2021, extras_require in setup.cfg doesn't allow hyphen in extras name #1608 (comment)
It was proposed that
setuptools
should discontinue automatic dash-to-underscore conversion.05 Mar 2021,
v54.1.0
, Provide support for dash-separated keys in setup.cfg, warns for future incompatibility of certain keys #2588A community contribution attempts to fix the bug previously identified and introduces the deprecation warning.
The fix attempt needs conditional logic to work properly because on extras and file naming users should
be able to use dashes freely.
05 Mar 2021, "Name" metadata keyword not recognized #2592
Backward compatibility issues were reported regarding capitalized options in
setup.cfg
.06 Mar 2021, Warn for uppercase key usage in metadata in setup.cfg, provides compatibility. Fixes #2592 #2593
A partial rollback of Fix case sensitivity of entry point names and keys in setup.cfg. Fixes #1937 #2580 was implemented to restore compatibility, introducing conditional logic and deprecation warnings for capitalized options.
06 Mar 2021, Provide support for dash-separated keys in setup.cfg, warns for future incompatibility of certain keys #2588 (comment) followed by Deprecation of dashes affects other project settings #2595
A bug was identified where unjustified deprecation warnings were issued for unrelated third-party configurations, highlighting the need for more nuanced logic.
14 Mar 2021, Reduce scope of dash deprecation warning. Fixes #2595 #2600
A fix was contributed to suppress deprecation warnings for sections unrelated to
setuptools
, adding more precise handling of deprecated paths.20 Mar 2021, Move distutils command names into package metadata and declare entry points using static config. #2678
To reduce redundancy and improve maintenance, hardcoded command names were moved to runtime metadata introspection.
12 Feb 2022, Remove reliance on pkg_resources for entry points #3087
Runtime introspection was migrated from the deprecated
pkg_resources
toimportlib.metadata
.07 Mar 2023, Overhaul for better visibility of warnings #3849
Deprecation warnings were made more informative and visually prominent, incorporating URLs and due dates based on community feedback.
01 May 2024, Using
setuptools.extern.importlib_metadata.EntryPoints.names
is incompatible with older versions ofimportlib_metadata
and/orimportlib.metadata
#4338An incompatibility was identified between
importlib.metadata
andimportlib_metadata
.Follow-up fix: Don't call
setuptools.extern.importlib_metadata.EntryPoints.names
for better backwards compatibility. #433915 Oct 2024, Temporary workaround for disruptive due deprecations #4679
Deprecation warnings were temporarily postponed.
23 Mar 2025,
v78.0.0
, Disallow deprecated dash-separated and uppercase options in setup.cfg #4870An initial attempt was made to remove the lenient handling of dashes and uppercase characters in
setup.cfg
as a scheduled follow up on the maintenance activities. As part of this broader effort, the release introduced the first step towards that goal. During the deprecation review, it became evident that some valid use cases — such as package names likehello-stubs
(per PEP 561) — were not properly accounted for. The removal was intentionally partial: the update focused on delivering a detailed and actionable error message to help users resolve issues in affected packages. Complete removal of the associated code complexity was deferred to a future version, to allow time for the community to adapt based on the provided guidance.24 Mar 2025,
v78.0.2
, Revert removals introduced inv78.0.0
#4911The deprecation warnings are reinstated in the code base with partial reversal of the previous changes.
The change was not a simple reversal of the changes in
v78.0.0
, in order to preserve fixes/improvements.Footnotes
This heuristic to determine when automatic normalization was applicable introduced ambiguity and potential for error. The deprecation aims to eliminate this guesswork by relying solely on explicit, user-provided configuration keys. ↩
A hard-coded allowlist was initially implemented as a workaround to support known options names. However, this approach proved fragile and difficult to maintain. It was also not able to handle projects with custom user-defined commands or build steps. It was later replaced by a more dynamic solution based on
importlib.metadata.entry_points
, which offered greater flexibility and reduced the need for manual updates. ↩See https://pip.pypa.io/en/stable/cli/pip_install/#cmdoption-only-binary or https://docs.astral.sh/uv/reference/settings/#pip_only-binary. ↩
Beta Was this translation helpful? Give feedback.
All reactions