When creating a list of packages and their requirements (e.g. for a dependency graph), extras (as in extras_require property in setuptools.setup) are ignored. This results in missing package requirements.
Example of the problem
A project has pkga with pkgc extra as a requirement in requirements.txt:
The (simplified) setup.py of pkga would be following:
setup(
name="pkga",
version="1.0.0",
install_requires=["pkgb"],
extras_require={
"pkgc": ["pkgc"]
}
)
This means that pkga requires pkgb but if installed as pkga[pkgc] it also requires pkgc.
Dante ignores the extras and compiles the requirements as:
...while the expected result would be:
pkga
|-> pkgb
|-> ...
|-> pkgc
|-> ...
However, this a simple example because there might be multiple extras (e.g. pkga[pkgc,pkgz]) so gathering all the requirements gets more complex.
Suggestions
Getting the extras is not difficult. dante.core.models.Dependency could have extras property so at blocks like dante.core.models.Package.requirements you could pass the extras around and get correct requirements:
return RequirementCollection(sorted([
Requirement(
key=requirement.key.lower(),
name=requirement.name,
obj=requirement,
version=RequiredVersion(obj=requirement.specifier),
extras=requirement.extras,
_ignore_list=self._ignore_list
)
for requirement in self.obj.requires(extras=self.extras)
if requirement.key.lower() not in self._ignore_list
]))
However, it seems to me that creation of a graph starts with pkg_resources.working_set which is a set of packages that doesn't contain the information on which extras were used for each package.
When creating a list of packages and their requirements (e.g. for a dependency graph),
extras(as inextras_requireproperty insetuptools.setup) are ignored. This results in missing package requirements.Example of the problem
A project has pkga with pkgc extra as a requirement in requirements.txt:
The (simplified) setup.py of pkga would be following:
This means that pkga requires pkgb but if installed as pkga[pkgc] it also requires pkgc.
Dante ignores the extras and compiles the requirements as:
...while the expected result would be:
However, this a simple example because there might be multiple
extras(e.g. pkga[pkgc,pkgz]) so gathering all the requirements gets more complex.Suggestions
Getting the extras is not difficult.
dante.core.models.Dependencycould haveextrasproperty so at blocks likedante.core.models.Package.requirementsyou could pass theextrasaround and get correct requirements:However, it seems to me that creation of a graph starts with
pkg_resources.working_setwhich is a set of packages that doesn't contain the information on which extras were used for each package.