PEP 508 specifies a mini-language fordeclaring package dependencies. One feature of this language is the ability tospecifyextras, which are optional components of a distribution that, whenused, install additional dependencies. This PEP proposes a mechanism to allowone or more extras to be installed by default if none are provided explicitly.
Various use cases for default extras and possible solutions in this PEP were discussedextensively onthis DPO thread.These fall into two broad cases that provide themotivation for the present PEP.
Package maintainers often use extras to declare optional dependencies thatextend the functionality or performance of a package. In some cases, it can bedifficult to determine which dependencies should be required and which should becategorized as extras. A balance must be struck between the needs of typicalusers, who may prefer most features to be available by default, and users whowant minimal installations without large, optional dependencies. One solutionwith existing Python packaging infrastructure is for package maintainers todefine an extra called, for example,recommended, whichincludes all non-essential but suggested dependencies. Users are then instructed toinstall the package usingpackage[recommended], while those who prefer morecontrol can usepackage. However, in practice, many users are unawareof the[recommended] syntax, placing the burden on them to know this for atypical installation. Having a way to have recommended dependencies be installedby default while providing a way for users to request a more minimal installationwould satisfy this use case, and this PEP describes a solution to this.
Examples of packages that demonstrate this pattern by encouraging users toinclude extra dependencies by default include:
Another common use case for using extras is to define different backends orfrontends and dependencies that need to be installed for each backend orfrontend. A package might need at least one backend or frontend to be installedin order to be functional, but may be flexible on which backend or frontend thisis. Concrete examples of such frontends or backends include:
With current packaging standards, maintainers have to eitherrequire one of the backends or frontends or require usersto always specify extras, e.g.,package[backend], and therefore risk usershaving an unusable installation if they only installpackage. Having away to specify one or more default backend or frontend and providing a way tooverride these defaults would provide a much better experience for users, andthe approach described in this PEP will allow this.
Note that this PEP does not aim to address the issue of disallowing conflictingor incompatible extras, for example if a package requires exactly one frontendor backend package. There is currently no mechanism in Python packaginginfrastructure to disallow conflicting or incompatible extras to be installed,and this PEP does not change that.
Examples of packages that require at least one backend or frontend to work andrecommend a default extra to install a backend or frontend include:
In all three cases, installing the package without any extras results in abroken installation, and this is a commonly reported support issue for some of thesepackages.
A number of possible solutions have been discussed extensively bythe community for several years, including inthis DPO threadas well as in numerous issues and pull requests. The solution that ispresented below:
It is the only solution, out of all those discussed, that meets all three criteria.
Default-Extra Metadata FieldA new multiple-use metadata field,Default-Extra, will be added to thecore packagemetadata.For this field, each entry must be a string specifying an extra that will beautomatically included when the package is installed without any extras being specified explicitly.
Only entries already specified in aProvides-Extraentry can be used in aDefault-Extra entry.
Examples:
Default-Extra:recommendedDefault-Extra:backend1Default-Extra:backend2Default-Extra:backend3
Since this introduces a new field in the core package metadata, this will requireMetadata-Versionto be bumped to the next minor version (2.5 at the time of writing).
[project] metadata tableA new key will be added to the[project] table in project metadata asoriginally defined inPEP 621 and now defined in thePyPA specifications. This key will be nameddefault-optional-dependency-keys with the following description:
Default-ExtraEach string indefault-optional-dependency-keys must be the name of an extradefined inoptional-dependencies,and each extra in this array will be converted to a matchingDefault-Extraentry in the core package metadata. Examples of valid usage which wouldproduce the exampleDefault-Extra entries presented in the previous section are:
[project]default-optional-dependency-keys=["recommended",]
and:
[project]default-optional-dependency-keys=["backend1","backend2","backend3"]
If extras are explicitly given in a dependency specification, the defaultextras are ignored. Otherwise, the default extras are installed.
For example, if a package defines anextra1 default extra as well as anon-defaultextra2 extra, then if a user were to install the package with:
$pipinstallpackagethe defaultextra1 dependency would be included. If the user insteadinstalls the package with:
$pipinstallpackage[extra2]
then theextra2 extra would be installed but the defaultextra1 extrawould be ignored.
If the same package is specified multiple times in an installation command ordependency tree, the default extras must be installed if any of the instances ofthe package are specified without extras. For instance, if one installs apackagespam wherepackage appears several times in the dependencytree:
spam├── tomato│ ├── package[extra2]└── egg └── package
then the default extra should be installed becausepackage appears at leastonce with no extras specified.
An empty set of extras, such aspackage[] should be interpreted as meaningthat the package should be installedwithout any default extras (unlesspackage appears elsewhere in the dependency tree, in which case, the defaultextrawould be installed as mentioned above). Thiswould provide a universal way of obtaining a minimal installation of a package.
We also note that some tools such aspip currently ignore unrecognizedextras, and emit a warning to the user to indicate that the extra has not beenrecognized, e.g:
$pipinstallpackage[non-existent-extra]WARNING: package 3.0.0 does not provide the extra 'non-existent-extra'...
For tools that behave like this (rather than raising an error), if an extra isrecognized as invalid in a dependency specification, it should be ignored, andif all specified extras are invalid, then this should be considered equivalenttopackage[] (rather thanpackage) andnot install any default extras.
Finally, we note (as also discussed inRelying on tooling to deselectany default extras) that package installers are allowed to implement theirown options to control the above behavior, for example implementing an optionthat disables default extras for some or all packages regardless of where thesepackages appear in the dependency tree. If such tool-specific options areimplemented, tool developers should make these opt-in,and users should experience the above PEP 771 behavior as default.
In this section we take a look at the use cases described in theMotivationsection and how these can now be addressed by using the specification outlinedabove.
First, we consider the case of packages that want recommended but not strictlyrequired dependencies installed by default, while also providing a way to onlyinstall the required dependencies.
In order to do this, a package maintainer would define an extra calledrecommended containing the recommended but not required dependencies, andwould choose to have this be included as a default extra:
[project]default-optional-dependency-keys=["recommended"][project.optional-dependencies]recommended=["package1","package2"]
If this package was calledpackage, users installingpackage wouldthen get the equivalent ofpackage[recommended]. Users could alternativelyinstallpackage[] which would install the package without the default extras.
To take a one of the concrete examples of package from theMotivationsection, theastropy package defines arecommended extra that users arecurrently instructed to install in the default installation instructions.With this PEP, therecommended extra could be declared as being a defaultextra:
[project]default-optional-dependency-keys=["recommended"][project.optional-dependencies]recommended=["scipy","..."]
meaning that installing:
$pipinstallastropywould then install optional but recommended dependencies such asscipy. Advanced users who want a minimal installcould then use:
$pipinstallastropy[]
As described inMotivation, some packages may support multiple backendsand/or frontends, and in some cases it may be desirable to ensure that thereis always at least one backend or frontend package installed, as the packagewould be unusable otherwise. Concrete examples of this might include a GUIapplication that needs a GUI library to be present to be usable but is ableto support different ones, or a package that can rely on different computationalbackends but needs at least one to be installed.
In this case, package maintainers could make the choice to define an extrafor each backend or frontend, and provide a default, e.g.:
[project]default-optional-dependency-keys=["backend1"][project.optional-dependencies]backend1=["package1","package2"]backend2=["package3"]
If packages can support e.g. multiple backends at the same time, and some ofthe backends should always be installed, then the dependencies for these must be givenas required dependencies rather than using the default extras mechanism.
To take one of the concrete examples mentioned inMotivation, thenapari packagecan make use of one ofPyQt5,PyQt6,PySide2, orPySide6, and users currentlyneed to explicitly specifynapari[all] in order to have one of these be installed,or e.g.,napari[pyqt5] to explicitly specify one of the frontend packages. Installingnapari with no extras results in a non-functional package. With this PEP,naparicould define the following configuration:
[project]default-optional-dependency-keys=["pyqt5"][project.optional-dependencies]pyqt5=["PyQt5","..."]pyside2=["PySide2","..."]pyqt6=["PyQt6","..."]pyside6=["PySide6","..."]
meaning that:
$pipinstallnapariwould work out-of-the-box, but there would still be a mechanism for users toexplicitly specify a frontend, e.g.:
$pipinstallnapari[pyside6]
An additional case we consider here is where a package maintainer wants tosupport the ability for users to opt-in to non-default extras, without removingdefault extras. Essentially, they might want:
package[] to give an installation without any extraspackage to install recommended dependencies (in arecommended extra)package[alternative] to not install default extras, but to install an alternative set of optional dependencies (in analternative extra)package[additional] to install both recommended and additional dependencies (in anadditional extra)This could be achieved with e.g:
[project]default-optional-dependency-keys=["recommended"][project.optional-dependencies]recommended=["package1","package2"]alternative=["package3"]additional=["package[recommended]","package4"]
The ability for a package to reference itself in the extras is supported byexisting Python packaging tools.
Once again considering a concrete example,astropy could with this PEP define arecommended extra (as described inRecommended dependencies and minimalinstallations). However, it also defines other extras, including for examplejupyter, which adds packages thatenhance the user experience insideJupyter-basedenvironments. It is possible that users opting in to this extra would still wantrecommended dependencies to be installed. In this case, the followingconfiguration would solve this case:
[project]default-optional-dependency-keys=["recommended"][project.optional-dependencies]recommended=["scipy","..."]jupyter=["astropy[recommended]","ipywidgets","..."]
Users installing:
$pipinstallastropy[jupyter]
would then get the same as:
$pipinstallastropy[recommended,jupyter]
In some cases, it may be that packages need multiple kinds of defaults. As an example,inPackages requiring at least one backend or frontend, we considered the case of packagesthat haveeither backends or frontends, but in some cases, packages may have to supportbackendsand frontends, and want to specify one or more default frontend and one ormore default backend.
Ideally, one may want the following behavior:
$pipinstallpackage# installs default backend and frontend$pipinstallpackage[]# installs no backends or frontends$pipinstallpackage[backend1]# installs backend1 and default frontend$pipinstallpackage[frontend2]# installs frontend2 and default backend$pipinstallpackage[backend1,frontend2]# installs backend1 and frontend2
However, this PEP chooses not to provide a mechanism for making it so that e.g., ifbackend1 is specified, the default backend would be disabled, but thedefault frontend would be enabled, since this adds complexity.
Maintainers should instead for now document that if a backend or frontend isexplicitly specified, both backend and frontend need to be specified.Discoverability for users who want to do this should not be an issue however since usersneed to read the documentation in any case to find out what backends or frontends areavailable, so they can be shown at the same time how to properly use the extras forbackends and frontends.
One option to increase user friendliness is that maintainers can create extrascalled for exampledefaultbackend anddefaultfrontend which do installthe default backend and frontend. They can then recommend that users do:
$pipinstallpackage# installs default backend and frontend$pipinstallpackage[]# installs no backends or frontends$pipinstallpackage[backend1,defaultfrontend]# installs backend1 and default frontend$pipinstallpackage[defaultbackend,frontend2]# installs frontend2 and default backend$pipinstallpackage[backend1,frontend2]# installs backend1 and frontend2
This would allow (if desired) users to then get whatever the recommended backendis, even if that default changes in time.
If there is a desire to implement a better solution in future, we believe thisPEP should not preclude this. For example, one could imagine in future addingthe ability for an extra to specifywhich default extras it disables, and ifthis is not specified then explicitly specified extras would disable all defaultextras (consistent with the present PEP).
Once support for this PEP is added to tools in the packaging ecosystem, packagesthat do not make use of default extras will continue to work as-is and thereshould be no break in compatibility.
Once packages start defining default extras, those defaults will only be honoredwith recent versions of packaging tools which implement this PEP, but thosepackages will remain installable with older packaging tools – with the maindifference being that the default extras will not be installed automaticallywhen older packaging tools are used.
As described inHow to teach this,package authors need to carefully evaluate when and how they adoptthe default extra feature depending on their user base, as some actions (such asmoving a required dependency to a default extra) will likely result in breakagefor users if a significant fraction of them are still using older packageinstallers that do not support default extras. In this sense, package authorsshould be aware that this feature, if used in certain ways, can causebackward-compatibility issues for users, and they are thus responsible forensuring that they minimize the impact to users.
The most significant backward-compatibility aspect is related to assumptionspackaging tools make about extras – specifically, this PEP changes theassumption that extras are no longer exclusively additive in terms of addingdependencies to the dependency tree, and specifying some extras can result infewer dependencies being installed.
A specific example of change in behavior can be seen withpip: consider apackagepackage which has a required dependency ofnumpy, and a defaultextra calledrecommended which includesscipy. If a user installspackage[], onlypackage andnumpy will be installed. If a user thendoes:
$pipfreeze>requirements.txtthenrequirements.txt will contain e.g.:
package==1.0.2numpy==2.1.0
However, if the user then installs the requirements from this file using:
$pipinstall-rrequirements.txtthen pip will installpackage (which will include the default extra) as wellasnumpy, so the final environment will containscipy. A solution in thisspecific case is for the user to pass--no-deps topipinstall to avoidresolving the dependency tree, but the point here is to illustrate that theremay be changes in behavior in packaging tools due to the change in theassumption about what impact an extra can have.
It is worth noting that the recently-acceptedPEP 751 defines a new fileformat which is intended to replace alternatives such as thepipfreezeoutput and other tools in future. The new file format is designed so that thepackages in the file are installedwithout resolving dependencies, which meansthat it will be fully compatible with default extras as specified in this PEP,and will avoid the issue withpipfreeze/pipinstall-r mentioned above.
There are no known security implications for this PEP.
This section outlines information that should be made available to people indifferent groups in the community in relation to the implementation of this PEP.Some aspects described below will be relevant even before the PEP is fullyimplemented in packaging tools as there are some preparations that can be donein advance of this implementation to facilitate any potential transition lateron. The groups covered below are:
Package users should be provided with clear installation instructions that showwhat extras are available for packages and how they behave, for exampleexplaining that by default some recommended dependencies or a given frontend orbackend will be installed, and how to opt out of this or override defaults,depending what is available.
While the mechanism used to define extras and the associated rule about when touse it are clear, package authors need to carefully consider several pointsbefore adopting this capability in their packages, to avoid inadvertently breakingbackward-compatibility.
Package installers such aspip oruv will notnecessarily implement support for default extras at the same time, and once theydo it is likely that package authors will want to keep supporting users who donot have the most recent version of a package installer. In this case, thefollowing recommendations would apply:
recommended inastropy be a default extra, but in order to support userswith older versions of package installers, the documentation should still mentionthe extra explicitly as long as possible (until it is clear that most/all usersare using package installers that implement this PEP). There is no downside tokeeping the extra be explicitly mentioned, but this will ensure that users withmodern tooling who do not read documentation (which may be a non-negligiblefraction of the user community) will start getting the recommendeddependencies by default.package[] was equivalent topackage,authors will be able to documentpackage[] as a backward-compatibleuniversal way of getting a minimal installation. For packages that definedefault extras, installingpackage[] will always give a minimalinstallation even with older versions of packaging tools such aspip, andreleases of this package that pre-date the introduction of default extras fora specific package will also be installable withpackage[] (although inthese cases this will be equivalent topackage). For packages that do notdefine default extras,package[] will continue to be equivalent topackage.One temptation for authors might be to include many dependencies by default sincethey can provide a way to opt out from these. We recommend however that authorscarefully consider what is included by default to avoid unnecessarily bloatinginstallations and complicating dependency trees. Using default extras does notmean that all extras need to be defaults, and there is still scope for users toexplicitly opt in to non-default extras.
Default extras should generally be treated with the same “weight” as requireddependencies. When a package is widely used, introducing a default extra willresult in that extra’s dependencies being transitively included – unless alldownstream packages are updated to explicitly opt out using minimal installationspecifications.
As an example, thepytest package currently has nearly 1,500 plugins that depend on it. If pytest were to add a default extra and those plugins were not updated accordingly, installing a plugin would include the default extras’ dependencies. This doesn’t preclude the use of default extras, but addition of default extras requires careful evaluation of its downstream effects.
If package authors choose to make an extra be installed by default, it is importantthat they are aware that if users explicitly specify another extra, the default maynot be installed, unless they use the approach described inSupporting extrasthat should not remove default extras.
There are cases, such as the interchangeable backends,where ignoring the default if an extra is explicitly specified is the rightthing to do. However, for other cases, such as using default extras to includerecommended dependencies while still providing a way to do minimal installs, itmay be that many of the other extrasshould explicitly ‘inherit’ the defaultextra(s), so package authors should carefully consider in which cases they wantthe default extras to be installed.
In some cases, it may be that packages have extras that are mutuallyincompatible. In this case, we recommend against using the default extrafeature for any extra that contains a dependency that could be incompatible withanother.
Consider a package that has extraspackage[A] andpackage[B]. Userscould already currently try and installpackage[A] andpackage[B] orpackage[A,B] which would result in a broken installation, however it wouldat least be explicit that both extras were being installed. MakingA into adefault extra however could lead to unintuitive issues. A user could do:
$pipinstallpackage# this installs package[A]$pipinstallpackage[B]
and end up with a broken installation, even though A and B were never explicitlyboth installed. For this reason, we recommend against using default extrasfor dependencies where this is likely to be an issue.
Authors need to take special care when circular dependencies are present. For instance,consider the following dependency tree:
package1└── package2 └── package1
Ifpackage1 has a default extra namedrecommended then:
$pipinstallpackage1[]
will still result in therecommended extra being installed ifpackage2continues to depend onpackage1 (with no extras specified). This could besolved by changing the dependency tree to instead be:
package1└── package2 └── package1[]
assuming that indeedpackage2 does not depend on any features provided bythe extra dependencies ofpackage1. Authors therefore need to carefullyconsider a migration plan, coordinating with the authors ofpackage2.
Regardless of how default extras are used, package authors should aim to ensurethat their package’s documentation makes it clear how extras are to beused. ‘Best practices’ documentation should mention:
package will be equivalent topackage[<defaultextras>]package[] will include only minimal/required dependencies,but that this will not guarantee that optional dependencies do not get installedifpackage appears anywhere else in the dependency treeThe impact on individuals who repackage Python libraries for differentdistributions, such asconda,Homebrew, linux package installers (such asapt andyum) andso on, needs to be considered. Not all package distributions have mechanismsthat would line up with the approach described. In fact, some distributions suchas conda, do not even have the concept of extras.
There are two cases to consider here:
recommended dependencies by default sincethere is no way for users to explicitly request them otherwise).It is impossible for a PEP such as this to exhaustively consider each of thedifferent package distributions. However, ultimately, default extras should beunderstood as how package authors would like their package to be installed forthe majority of users, and this should inform decisions about how default extrasshould be handled, whether manually or automatically.
The following repository contains a fully functional demo packagethat makes use of default extras:
https://github.com/wheel-next/pep_771
This makes use of modified branches of several packages, and the followinglinks are to these branches:
In addition,this branchcontains a modified version of theFlit package.
The implementations above are proofs-of-concept at this time and the existing changes havenot yet been reviewed by the relevant maintainers. Nevertheless, they arefunctional enough to allow for interested maintainers to try these out.
Using existing packaging tools and infrastructure, package maintainers who wantto provide a minimal installation for some users and a default non-minimalinstallation for regular users (e.g. with recommended dependencies or a defaultbackend) can technically already achieve this if they are willing to distributetwo packages instead of one – for examplepackage-core which would be the main packagewith minimal dependencies, andpackage which would be a metapackage thatwould depend onpackage-core with optional dependencies enabled.
Taking once again a concrete example from theMotivationsection, theastropy package defines arecommended extra that users arecurrently instructed to install in the default installation instructions.In principle, one could rename the existingastropy package to e.g.astropy-coreand then create a newastropy package which would be a metapackage that wouldcontain the following dependencies section:
dependencies=["astropy-core[recommended]"]
Since users may want to pin or place version constraints on theastropymeta-package (e.g.astropy>5.0), the metapackage would need to followthe same versions as the core package, and would need to use strict pinningin the dependency section, e.g.:
version="7.1.0"dependencies=["astropy-core[recommended]==7.1.0"]
This idea may seem appealing because it is technically already feasible. However, inpractice, many projects have opted not to do this, for a number of reasons, whichwe now take a look at. Some of these may not be applicable to future new projects,but some of them apply to all projects, old and new.
In terms of naming, there are two main options for a package that wants to use the metapackageapproach:
package would provide the minimal installation, and to then create anew metapackage with a different name, such aspackage-all. However, thissuffers from one of the problems that motivated this PEP in the first place -users are often not aware that they can do e.g.package[recommended], soin the same way, they might not realise thatpackage-all exists. This onceagain places the burden on the average user to discover this, rather thenshifting some of the burden to more advanced users.package-core, andfor the new meta-package to be calledpackage. This is a better optionthan the first one, but is not ideal, as it then introduces a non-intuitivemismatch between the package name and module name, in thatpackage-core providesthepackage module, andpackage does not provide any module. An example of whythis would lead to confusion is that an average user might think that uninstallingthepackage module would be done with e.g.:$pipuninstallpackage
but this would not be the case (thepackage module would still work), andit may not be obvious to this user that thepackage-core package evenexists.
This approach requires either maintaining two repositories instead of one, orswitching to using a monorepo which would contain both packages. Neither optionis ideal:
package repository will need toupdate their remote URLs or any git clone URLs to point to thepackage-core repository. The alternative is to preserve thepackagerepository to contain thepackage-core package, and have a different namefor the meta-package, but this could lead to confusion.subdirectory= tothe repo URL), and any existing workflows that clone the repository and assumethe previous layout would break.Packages that need to depend on package versions that are older than the firstversion where the split was done will not easily be able to depend on theminimal package. Whereas with the main proposal in this PEP, downstream userswill be able to depend on e.g.package[]>version whereversion pre-datesthe introduction of default extras, with the splitting approach it will not bepossible for downstream users to depend on e.g.package-core>version, sincepackage-core did not previously exist.
A possible solution to this is for developers to release no-op metadata packagesfor all old versions of a package, but this is a significant additional burdenon the maintainers.
As alluded to when referring to naming issues inMismatch between package andmodule name, uninstalling packages will no longer work the way users expect. Auser doing:
$pipuninstallpackage
will still be left withpackage-core, but may not realise it. This isnot just confusing, but is in effect a breaking change that may impact a numberof existing workflows.
Having two packages instead of one would increase the long-term maintenance costof package distributions simply by virtue of the fact that two packages wouldhave to be released instead of one, and in some cases this would introduce extramanual work at each release.
The main metadata that would be important to keep synchronized between the mainpackage and the metapackage is the version. Anytime a new release of the corepackage is done, the metapackage would need to have its version updated as wellas the version pinning for the core package in the dependencies.
In addition, all extras defined in the core package would need to be redefinedand kept in sync in the metapackage. For example, ifpackage defines aadditional extra, users should still be able to installpackage[additional], but users installing thepackage-core package shouldalso have the option of doingpackage-core[additional].
Other metadata that would need to be kept in sync includes for example authorinformation and project URLs.
Overall, this solution would imply a significantly higher maintenance burden,not just in terms of initial set-up and transition (which could already beprohibitive for large established projects), but also in terms of long-termmaintenance. This also has the potential for breaking user workflows (inparticular around the issue of repositories, and e.g. uninstallation). For allthese reasons, we do not consider it a compelling alternative to the present PEP.
One of the main competing approaches was as follows: instead of having defaultsbe unselected if any extras were explicitly provided, default extras would needto be explicitly unselected.
In this picture, a new syntax for unselecting extras would be introduced as anextension of the mini-language defined inPEP 508. If a package defineddefault extras, users could opt out of these defaults by using a minus sign(-) before the extra name. The proposed syntax update would have been as follows:
extras_list = (-)?identifier (wsp* ',' wsp* (-)?identifier)*
Valid examples of this new syntax would have included, e.g.:
package[-recommended]package[-backend1,backend2]package[pdf,-svg]However, there are two main issues with this approach:
package[pdf,-pdf]) or if a dependencytree included bothpackage[pdf] andpackage[-pdf], and the rules wouldnot be intuitive to users.For these reasons, this alternative was not included in the final proposal.
extras_requireA potential solution that has been explored as an alternative to introducing thenewDefault-Extra metadata field would be to make use of an extra with a‘special’ name.
One example would be to use an empty string:
Provides-Extra:Requires-Dist:numpy;extra==''
The idea would be that dependencies installed as part of the ‘empty’ extraswould only get installed if another extra was not specified. An implementationof this was proposed inhttps://github.com/pypa/setuptools/pull/1503, but itwas found that there would be no way to make this work without breakingcompatibility with existing usage. For example, packages using Setuptools viaasetup.py file can do:
setup(...extras_require={'':['package_a']},)
which is valid and equivalent to havingpackage_a being defined ininstall_requires, so changing the meaning of the empty string wouldbreak compatibility.
In addition, no other string (such as'default') can be used as a specialstring since all strings that would be a backward-compatible valid extras namemay already be used in existing packages.
There have been suggestions of using the specialNone Python variable, butagain this is not possible, because even though one can useNone in asetup.py file,this is not possible in declarative files such assetup.cfg orpyproject.toml, and furthermore ultimately extras names have to be convertedto strings in the package metadata. Having:
Provides-Extra:None
would be indistinguishable from the string ‘None’ which may already be used asan extra name in a Python package. If we were to modify the core metadatasyntax to allow non-string ‘special’ extras names, then we would be back tomodifying the core metadata specification, which is no better thanintroducingDefault-Extra.
Another option to unselect extras would be to implement this at thelevel of packaging tools. For instance, pip could include an option such as:
$pipinstallpackage--no-default-extrasThis option could apply to all or specific packages, similar tothe--no-binary option, e.g.,:
$pipinstallpackage--no-default-extras:all:The advantage of this approach is that tools supporting default extras couldalso support unselecting them. This approach would be similar to the--no-install-recommendsoption for theapt tool.
However, this solution is not ideal on its own because it would not allow packages tospecify themselves that they do not need some of the default extras of adependency. It would also carry risks for users who might disable all defaultextras in a big dependency tree, potentially breaking packages in the tree thatrely on default extras at any point.
Nevertheless, this PEP does not disallow this approach and it is up to themaintainers of different packaging tools to decide if they want to support thiskind of option. It is a flag that could at the very least be useful for packagemaintainers who want to identify places in dependency trees where default extrasare being relied on. However, if it is supported, it should be made clear thatusing this flag does not guarantee a functional environment.
This document is placed in the public domain or under theCC0-1.0-Universal license, whichever is more permissive.
Source:https://github.com/python/peps/blob/main/peps/pep-0771.rst
Last modified:2025-06-09 11:29:19 GMT