pyTooling.Sphinx.DependencyTable
A Sphinx directive rendering a project’s dependencies as a table, from the requirements rather than by hand.
A dependency table states, per package, which version is required, what it is licensed under, and what it drags in.
Written by hand it is wrong within a release or two: pyTooling’s own documentation table was missing four of the
packages doc/requirements.txt requires, listed one that isn’t required at all, and called Sphinx BSD-3-Clause
when it is BSD-2-Clause.
The entrypoints are declared in conf.py and named by the documents, the way
sphinx_reports declares its reports:
# doc/conf.py
pyTooling_Dependency_PackageOverrides = "Dependency.PackageOverrides.yaml"
pyTooling_Dependency_Requirements = {
"package": {"file": "../requirements.txt"},
"documentation": {"file": "requirements.txt"},
"yaml": {"package": "pyTooling[yaml]"}
}
.. dependency-table:: documentation
:caption: Documentation dependencies
A requirements file is read - with its -r includes followed - while conf.py is being processed, so a
path that doesn’t exist ends the build with one clear message instead of an error box in the middle of a page.
The data is fetched live from the package index, once per build and shared between every table of that build:
requirements.txt, tests/requirements.txt and doc/requirements.txt overlap heavily, and a
package they share is downloaded once. That still costs real time, so every table reports what it spent, measured
with a Stopwatch, and the build ends with the total.
Variables
Functions
readEntrypoints(): TurnpyTooling_Dependency_Requirementsinto entrypoints, reading every requirements file it names.prepareEntrypoints(): Call-back for Sphinx’config-initedevent, reading the entrypoints and the license overrides.formatUnresolvedLicenses(): Describe the packages needing a license override, grouped by what the package index published for them.
Classes
Entrypoint: One entry ofpyTooling_Dependency_Requirements: an identifier and the requirements it stands for.DependencyCollector: The entrypoints a build declared, the package index it queries, and what querying it cost.DependencyTable: Thedependency-tabledirective: an entrypoint’s dependencies, rendered from the requirements.
Variables
- pyTooling.Sphinx.DependencyTable.DEFAULT_INDEX_URL
URL of the package index the tables are built from, unless
conf.pynames another.'https://pypi.org'
- pyTooling.Sphinx.DependencyTable.DEFAULT_API_URL
URL of that index’s JSON API.
'https://pypi.org/pypi/'
- pyTooling.Sphinx.DependencyTable.DEFAULT_DEPTH
Levels of sub-dependencies rendered when nothing says otherwise;
0expands until the tree ends.0
- pyTooling.Sphinx.DependencyTable.DEFAULT_SIMPLIFIED_VERSIONS
Whether a version constraint is reduced to its lower bound when the document doesn’t say.
True
- pyTooling.Sphinx.DependencyTable.OPERATOR_SYMBOLS
Comparison operators as a reader writes them. Order matters - the two-character forms have to be tried first.
(('<=', '≤'), ('>=', '≥'), ('!=', '≠'), ('==', '='))
- pyTooling.Sphinx.DependencyTable.TABLE_COLUMNS
The table’s columns, as
(title, relative width).(('Package', 3), ('Version', 1), ('License', 2), ('Dependencies', 4))
- pyTooling.Sphinx.DependencyTable.ENTRYPOINT_FIELDS
The fields one entrypoint may state in
conf.py, exactly one of them.The singular forms take a string and the plural forms an iterable of strings; they are otherwise the same statement, and a project writes whichever reads better where it stands.
('file', 'files', 'package', 'packages')
- pyTooling.Sphinx.DependencyTable.CONFIG_PREFIX
Prefix every configuration value of this extension carries in
conf.py.'pyTooling_Dependency'
- pyTooling.Sphinx.DependencyTable.DEFAULT_VERSION_FORMAT
How many parts of a version number a table prints when the document doesn’t say.
<VersionFormat.MajorMinor: 2>
- pyTooling.Sphinx.DependencyTable.DEFAULT_DEPENDENCY_FORMAT
What a line of a dependency tree states when the document doesn’t say.
<DependencyFormat.PackageVersionLicense: 4>
Functions
- pyTooling.Sphinx.DependencyTable.readEntrypoints(configuration, confDirectory)[source]
Turn
pyTooling_Dependency_Requirementsinto entrypoints, reading every requirements file it names.A requirements file is read here rather than when a table is built, so a path that doesn’t exist ends the build with one message naming the identifier instead of an error box in the middle of a page - and so two tables naming the same file read it once.
- Parameters:
- Return type:
- Returns:
Every declared entrypoint, by its identifier.
- Raises:
MissingDependencyError – If the ‘pypi’ extra isn’t installed.
SphinxExtensionError – If the configuration is malformed, or a requirements file can’t be read.
- pyTooling.Sphinx.DependencyTable.prepareEntrypoints(sphinx, config)[source]
Call-back for Sphinx’
config-initedevent, reading the entrypoints and the license overrides.A build declaring no entrypoint does nothing here - not even import
pyTooling.Dependency.Python, so a project using only this extension’s roles doesn’t need thepypiextra.
- pyTooling.Sphinx.DependencyTable.formatUnresolvedLicenses(unresolved)[source]
Describe the packages needing a license override, grouped by what the package index published for them.
Grouped rather than listed one per line, because one ambiguous statement usually accounts for most of the list:
License :: OSI Approved :: BSD Licensenames three licenses, so every package whose only license information is that classifier lands here for the same reason and is worth reading as one group.
Classes
- class pyTooling.Sphinx.DependencyTable.Entrypoint(identifier, files=(), packages=(), requirements=None)[source]
One entry of
pyTooling_Dependency_Requirements: an identifier and the requirements it stands for.A file entrypoint is read while
conf.pyis being processed and carries its requirements from then on. A package entrypoint can only be resolved by asking the package index, so it carries the package’s name and extra and is resolved the first time a table names it.Inheritance
- Parameters:
- __init__(identifier, files=(), packages=(), requirements=None)[source]
Describe one entrypoint.
- Parameters:
identifier (
str) – Name the documents refer to this entrypoint by.files (
tuple[Path,...]) – Optional, every requirements file read, for a file entrypoint. Default:().packages (
tuple[tuple[str,str|None],...]) – Optional, the packages and their extras, for a package entrypoint. Default:().requirements (
dict[str,Requirement] |None) – Optional, the requirements, if they are known already. Default:None.
- Return type:
None
- property Files: tuple[Path, ...]
The requirements file and every file it includes.
- Returns:
The files this entrypoint was read from; empty for a package entrypoint.
- property Packages: tuple[tuple[str, str | None], ...]
The packages this entrypoint reads the requirements of, as
(name, extra)pairs.- Returns:
The packages, or an empty tuple for a file entrypoint.
- property Requirements: dict[str, Requirement] | None
The requirements this entrypoint stands for.
- Returns:
Every required package by its canonical name, or
Noneif they weren’t resolved yet.
- CacheRequirements(requirements)[source]
Remember the requirements the package index answered with.
A package entrypoint can only be resolved by asking the index; remembering the answer is what keeps a second table naming the same entrypoint from asking again.
- __repr__()[source]
Return a representation naming what this entrypoint reads.
- Return type:
- Returns:
The identifier and its source.
- classmethod GetMethodsWithAttributes(predicate: Nullable[TAttributeFilter[TAttr]] = None) dict[Callable[..., Any], tuple[Attribute, ...]]
Return the class’ methods that carry at least one matching attribute.
- Parameters:
predicate (Nullable[TAttributeFilter[TAttr]]) – Optional, an attribute class, an iterable of attribute classes, or
Noneto accept every attribute.- Return type:
dict[Callable[…, Any], tuple[Attribute, …]]
- Returns:
Dictionary of methods and the matching attributes attached to them.
- Raises:
ValueError – If an element of parameter ‘predicate’ is not a sub-class of
Attribute.ValueError – If parameter ‘predicate’ is neither an attribute class nor an iterable of those.
- __getstate__() dict[str, Any]
Return the object’s state for pickling, collecting every slot of the class hierarchy.
- class pyTooling.Sphinx.DependencyTable.DependencyCollector(entrypoints, indexURL, apiURL, overrides)[source]
The entrypoints a build declared, the package index it queries, and what querying it cost.
One collector is shared by every table of a build: a package required by two entrypoints is downloaded once, and the time is accumulated so the build can report a total. It exists because the alternative - a table that queries the index for itself - multiplies a documentation build’s runtime by however many tables it has, and
requirements.txt,tests/requirements.txtanddoc/requirements.txtshare most of what they require.The index is opened the first time a table asks for a package, not when the collector is created: a project may declare its entrypoints and then build a document that shows none of them, and that build should not open an HTTP session.
Inheritance
- Parameters:
entrypoints (dict[str, Entrypoint])
indexURL (str)
apiURL (str)
overrides (LicenseOverrides)
- __init__(entrypoints, indexURL, apiURL, overrides)[source]
Collect what a build declared, without opening the package index yet.
- Parameters:
entrypoints (
dict[str,Entrypoint]) – The entrypoints declared inconf.py, by identifier.indexURL (
str) – URL of the package index’s website.apiURL (
str) – URL of the package index’s JSON API.overrides (
LicenseOverrides) – Licenses stated by hand.
- Return type:
None
- _entrypoints: dict[str, Entrypoint]
The entrypoints declared in
conf.py.
- _overrides: LicenseOverrides
Licenses stated by hand, where the index can’t.
- _graph: PythonPackageDependencyGraph | None
Graph the downloaded packages are collected in.
- _index: PythonPackageIndex | None
The package index this build queries, once opened.
- property Entrypoints: dict[str, Entrypoint]
The entrypoints declared in
conf.py.- Returns:
Every entrypoint by its identifier.
- property Index: PythonPackageIndex
The package index this build queries, opened the first time it is asked for.
- Returns:
The package index.
- property RequestCount: int
Number of requests sent to the package index.
The stopwatch runs for exactly one span per request, so this is its
ActiveCount- counting them a second time in a field of our own would be a second answer to one question.- Returns:
Number of requests sent.
- property Seconds: float
Time spent waiting for the package index, in seconds.
This is the stopwatch’s
Activity- the sum of the intervals it ran - not its duration, because it is paused between requests and everything the build does in between is not time this collector spent.- Returns:
Seconds spent on the index.
- property UnresolvedLicenses: dict[str, tuple[str, ...]]
Packages whose license the index couldn’t answer for, and what it published instead.
The published fields are what the override file has to answer for, so they are kept rather than only the package’s name:
License :: OSI Approved :: BSD Licensenames three licenses and is never guessed at, and alicensefield holding a license’s title instead of its SPDX identifier doesn’t parse.- Returns:
Names of the packages needing a license override, mapped to what the index published for them.
- Project(packageName)[source]
Return a project, downloading it the first time it is asked for.
A package the index doesn’t know is remembered as unknown, so a table naming it doesn’t ask again for every row that mentions it.
- Details(release)[source]
Make sure a release knows its own requirements and its license.
A release the index lists but can’t describe - a yanked one, or a version its release endpoint spells differently - is remembered as unusable and answered with
None. Handing back the release itself would be worse than useless: its lazily loaded properties would each retry the download and raise.
- classmethod GetMethodsWithAttributes(predicate: Nullable[TAttributeFilter[TAttr]] = None) dict[Callable[..., Any], tuple[Attribute, ...]]
Return the class’ methods that carry at least one matching attribute.
- Parameters:
predicate (Nullable[TAttributeFilter[TAttr]]) – Optional, an attribute class, an iterable of attribute classes, or
Noneto accept every attribute.- Return type:
dict[Callable[…, Any], tuple[Attribute, …]]
- Returns:
Dictionary of methods and the matching attributes attached to them.
- Raises:
ValueError – If an element of parameter ‘predicate’ is not a sub-class of
Attribute.ValueError – If parameter ‘predicate’ is neither an attribute class nor an iterable of those.
- __getstate__() dict[str, Any]
Return the object’s state for pickling, collecting every slot of the class hierarchy.
- class pyTooling.Sphinx.DependencyTable.DependencyTable(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)[source]
The
dependency-tabledirective: an entrypoint’s dependencies, rendered from the requirements.One argument, the identifier of an entrypoint declared in
pyTooling_Dependency_Requirements.:depth:says how many levels of sub-dependencies to expand,:simplified-versions:whether a constraint is reduced to its lower bound, and:caption:puts a caption under the table; which package index is queried and which licenses are stated by hand are build-wide and configured inconf.py.Inheritance
- configValues: ClassVar[dict[str, tuple[Any, Literal['env'], Any]]] = {'APIURL': ('https://pypi.org/pypi/', 'env', <class 'str'>), 'IndexURL': ('https://pypi.org', 'env', <class 'str'>), 'PackageOverrides': (None, 'env', (<class 'str'>, <class 'pathlib.Path'>)), 'Requirements': ({}, 'env', <class 'dict'>)}
The configuration values this directive adds to
conf.py, asname: (default, rebuild, types). Each is registered withCONFIG_PREFIXas prefix, e.g.pyTooling_Dependency_Requirements.Requirementsmaps an identifier to what it names - a file, files, a package or packages. The other three are build-wide, because one package index is queried per build and one override file answers for it. All four are"env"-rebuilt: changing any of them changes every table.
- _versionFormat: VersionFormat
How many parts of a version number this table prints.
- _dependencyFormat: DependencyFormat
What a line of this table’s dependency trees states.
- has_content = False
A boolean;
Trueif content is allowed.
- required_arguments = 1
Number of required directive arguments: the entrypoint’s identifier.
- optional_arguments = 0
Number of optional arguments after the required ones.
- final_argument_whitespace = False
A boolean;
Trueif the last argument may contain spaces.
- option_spec: dict[str, Any] = {'caption': <function strip>, 'dependency-format': <function stripAndNormalize>, 'depth': <function nonnegative_int>, 'simplified-versions': <function stripAndNormalize>, 'version-format': <function stripAndNormalize>}
Mapping of option names to validator functions.
- run()[source]
Resolve the named entrypoint against the package index and return its requirements as a table.
- Return type:
list[Node]- Returns:
A
tablenode, or an error node when the entrypoint couldn’t be resolved.
- _ParseFormatOption(optionName, enumType, default)[source]
Read an option naming a member of an enumeration, or fall back to its default.
_ParseEnumOptionrequires the option and lower-cases what it reads; these two have a default and are written the way the members are spelled, so a document says:version-format: MajorMinorrather thanmajor_minor.- Parameters:
- Return type:
TypeVar(_FormatType,VersionFormat,DependencyFormat)- Returns:
The named member.
- Raises:
SphinxExtensionError – If the value names no member.
- _Collector()[source]
Return the build’s collector, which
prepareEntrypoints()created whenconf.pywas read.The collector belongs to the running application rather than to the directive, because a document with three tables would otherwise open three indexes and download the same packages three times. It deliberately does not live on the build environment: Sphinx pickles that between runs, and neither an open HTTP session nor a cached view of a package index survives being pickled - or should.
- Return type:
- Returns:
The collector shared by every table of this build.
- Raises:
SphinxExtensionError – If no entrypoint was configured.
- _Resolve(identifier, collector)[source]
Return what the named entrypoint requires.
A file entrypoint was read when
conf.pywas processed and answers immediately; a package entrypoint is resolved against the package index the first time a table names it, and remembers the answer.- Parameters:
identifier (
str) – Identifier the document names.collector (
DependencyCollector) – The build’s collector.
- Return type:
- Returns:
Every required package, by its canonical name.
- Raises:
MissingDependencyError – If the ‘pypi’ extra isn’t installed.
SphinxExtensionError – If the identifier is unknown, or the package index can’t answer for the entrypoint’s package.
- _PublishedRequirements(packageName, extra, collector)[source]
Ask the package index what a package’s latest release requires.
- Parameters:
packageName (
str) – Name of the package to ask about.extra (
str|None) – Extra whose requirements are wanted, orNonefor the package’s own.collector (
DependencyCollector) – The build’s collector.
- Return type:
list[Requirement]- Returns:
What that release requires.
- Raises:
SphinxExtensionError – If the index doesn’t know the package, can’t describe its latest release, or the package has no such extra.
- _CreateTable(identifier, requirements, collector)[source]
Render the requirements as a four-column table.
- Parameters:
identifier (
str) – Identifier of the entrypoint, used as the table’s identifier.requirements (
dict[str,Requirement]) – Every required package, by its canonical name.collector (
DependencyCollector) – The build’s collector.
- Return type:
table- Returns:
The finished table.
- static _CreateEmptyRow(columnCount)[source]
Render the one row a table with no requirements gets: a single cell spanning every column.
A table showing nothing but its header reads as a defect. pyTooling’s own
requirements.txtis empty - the package has no mandatory dependencies - and that is a statement worth printing.- Parameters:
columnCount (
int) – Number of columns the cell has to span.- Return type:
row- Returns:
The table row.
- _CreateDoubleRowTableHeader(columns, identifier, classes)
Create a table whose header spans two rows, so a column can group sub-columns.
A column’s
subColumnsisNonewhen it spans both header rows, and otherwise holds the(title, width)pairs below it.- Parameters:
- Return type:
tgroup- Returns:
The table’s column group, with both header rows already in it.
- _CreateRotatedTableHeader(columns, identifier, classes)
Create a table whose header titles are rotated, for many narrow columns.
- Parameters:
- Return type:
tgroup- Returns:
The table’s column group, with the header row already in it.
- _CreateRow(requirement, collector, depth)[source]
Render one required package as a table row.
A package the index doesn’t know, or one with no release matching the requirement, still gets a row - the specifier the entrypoint states is worth showing even when nothing else could be resolved.
- Parameters:
requirement (
Requirement) – The requirement to render.collector (
DependencyCollector) – The build’s collector.depth (
int|None) – Levels of sub-dependencies still to expand.
- Return type:
row- Returns:
The table row.
- _CreateSingleRowTableHeader(columns, identifier, classes)
Create a table with a single header row.
- Parameters:
- Return type:
tgroup- Returns:
The table’s column group, with the header row already in it.
- _ParseBooleanOption(optionName, default=None)
Read an option written as
yes/trueorno/false.- Parameters:
- Return type:
- Returns:
The option’s value.
- Raises:
SphinxExtensionError – If the option wasn’t given and has no default.
SphinxExtensionError – If the option’s value is neither of the two accepted spellings.
- _ParseEnumOption(optionName, enumType, default=None)
Read an option naming a member of an enumeration.
The written value is lowered and its dashes become underscores, so
horizontal-tablein a document selects thehorizontal_tablemember - a document reads in the spelling documents use, and the enumeration keeps the spelling Python uses.- Parameters:
- Return type:
- Returns:
The named member of the enumeration.
- Raises:
SphinxExtensionError – If the option wasn’t given and has no default.
SphinxExtensionError – If the value names no member of the enumeration.
- _ParseStringOption(optionName, default=None, regexp='\\\\w+')
Read an option that has to match a regular expression.
The pattern defaults to one or more word characters.
- Parameters:
- Return type:
- Returns:
The option’s value.
- Raises:
SphinxExtensionError – If the option wasn’t given and has no default.
SphinxExtensionError – If the option’s value doesn’t match the pattern.
- __annotate_func__()
The type of the None singleton.
- __init__(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)
- Return type:
None
- _internalError(container, location, message, exception)
Report an exception a directive couldn’t recover from, in the log and on the page.
A directive that fails silently leaves a hole in the documentation that nobody notices. This puts the message where a reader sees it and the traceback where a maintainer does.
- Parameters:
- Return type:
list[Node]- Returns:
The container, as the list a directive’s
runreturns.
- _object_hierarchy_parts(sig_node)
Returns a tuple of strings, one entry for each part of the object’s hierarchy (e.g.
('module', 'submodule', 'Class', 'method')). The returned tuple is used to properly nest children within parents in the table of contents, and can also be used within the_toc_entry_name()method.This method must not be used outwith table of contents generation.
- _toc_entry_name(sig_node)
Returns the text of the table of contents entry for the object.
This function is called once, in
run(), to set the name for the table of contents entry (a special attribute_toc_nameis set on the object node, later used inenvironment.collectors.toctree.TocTreeCollector.process_doc().build_toc()when the table of contents entries are collected).To support table of contents entries for their objects, domains must override this method, also respecting the configuration setting
toc_object_entries_show_parents. Domains must also override_object_hierarchy_parts(), with one (string) entry for each part of the object’s hierarchy. The result of this method is set on the signature node, and can be accessed assig_node['_toc_parts']for use within this method. The resulting tuple is also used to properly nest children within parents in the table of contents.An example implementations of this method is within the python domain (
PyObject._toc_entry_name()). The python domain sets the_toc_partsattribute within thehandle_signature()method.- Return type:
- Parameters:
sig_node (desc_signature)
- add_name(node)
Append self.options[‘name’] to node[‘names’] if it exists.
Also normalize the name string and register it as explicit target.
- Return type:
- add_target_and_index(name, sig, signode)
Add cross-reference IDs and entries to self.indexnode, if applicable.
name is whatever
handle_signature()returned.
- after_content()
Called after parsing content.
Used to reset information about the current directive context on the build environment.
- Return type:
- assert_has_content()
Throw an ERROR-level DirectiveError if the directive doesn’t have contents.
- before_content()
Called before parsing content.
Used to set information about the current directive context on the build environment.
- Return type:
- property config: Config
Reference to the
Configobject.Added in version 1.8.
- directive_error(level, message)
Return a DirectiveError suitable for being thrown as an exception.
Call “raise self.directive_error(level, message)” from within a directive implementation to return one single system message at level level, which automatically gets the directive block and the line number added.
Preferably use the debug, info, warning, error, or severe wrapper methods, e.g.
self.error(message)to generate an ERROR-level directive error.
- property env: BuildEnvironment
Reference to the
BuildEnvironmentobject.Added in version 1.8.
- get_signatures()
Retrieve the signatures to document from the directive arguments.
By default, signatures are given as arguments, one per line.
- get_source_info()
Get source and line number.
Added in version 3.0.
- handle_signature(sig, signode)
Parse the signature sig.
The individual nodes are then appended to signode. If ValueError is raised, parsing is aborted and the whole sig is put into a single desc_name node.
The return value should be a value that identifies the object. It is passed to
add_target_and_index()unchanged, and otherwise only used to skip duplicates.
- parse_content_to_nodes(allow_section_headings=False)
Parse the directive’s content into nodes.
- Parameters:
allow_section_headings (
bool) – Are titles (sections) allowed in the directive’s content? Note that this option bypasses Docutils’ usual checks on doctree structure, and misuse of this option can lead to an incoherent doctree. In Docutils, section nodes should only be children ofStructuralnodes, which includesdocument,section, andsidebarnodes.- Return type:
list[Node]
Added in version 7.4.
- parse_inline(text, *, lineno=-1)
Parse text as inline elements.
- Parameters:
- Return type:
- Returns:
A list of nodes (text and inline elements) and a list of system_messages.
Added in version 7.4.
- parse_text_to_nodes(text='', /, *, offset=-1, allow_section_headings=False)
Parse text into nodes.
- Parameters:
text (
str) – Text, in string form.StringListis also accepted.allow_section_headings (
bool) – Are titles (sections) allowed in text? Note that this option bypasses Docutils’ usual checks on doctree structure, and misuse of this option can lead to an incoherent doctree. In Docutils, section nodes should only be children ofStructuralnodes, which includesdocument,section, andsidebarnodes.offset (
int) – The offset of the content.
- Return type:
list[Node]
Added in version 7.4.
- set_source_info(node)
Set source and line number to the node.
Added in version 2.1.
- Return type:
- Parameters:
node (Node)
- transform_content(content_node)
Can be used to manipulate the content.
Called after creating the content through nested parsing, but before the
object-description-transformevent is emitted, and before the info-fields are transformed.- Return type:
- Parameters:
content_node (desc_content)
- _SelectRelease(project, requirement, collector)[source]
Return the newest release satisfying a requirement.
Pre-releases are skipped unless the specifier asks for them, because that is what an installer would resolve to and the table describes what would be installed.
- Parameters:
project (
Project|None) – The project to pick a release of, orNoneif the index doesn’t know it.requirement (
Requirement) – The requirement to satisfy.collector (
DependencyCollector) – The build’s collector.
- Return type:
- Returns:
The newest matching release, or
Noneif nothing matches.
- static _FormatVersion(version, versionFormat)[source]
Shorten a version number to the parts a table prints.
≥0.4.6says more than a reader of a dependency table needs; the parts that matter are the ones a constraint is usually written against. A version with fewer parts than asked for is left as it is -≥9does not become≥9.0- because padding would state a precision the requirement didn’t.
- static _FormatSpecifier(specifier, simplify, versionFormat)[source]
Render a version constraint the way a reader writes one.
The comparison operators become their mathematical symbols and the versions are shortened to
versionFormat. A simplified constraint keeps only what a package has to be at least: an upper bound and an exclusion say what a release must not be, which is the packaging problem rather than the reader’s, and~=is written as the lower bound it implies. Simplifying everything away leaves the constraint as it was written -<4.0alone is still the whole statement.
- static _PackageURL(project)[source]
Return the page a package’s name should link to, most useful first.
A project states none of these reliably, so there are three chances at one: its documentation answers what is this, its repository answers where does it come from, and its page on the package index is what the index itself can always answer. Only a package the index doesn’t know at all goes unlinked.
- classmethod _PackageEntry(requirement, project)[source]
Render the package’s name, linked to where a reader can find out about it.
- static _LicenseEntry(release)[source]
Render a release’s license, linked to its text where one is known.
The license’ name is shown rather than its SPDX identifier -
Apache License 2.0, notApache-2.0- because the table is read by a person and the identifier is what an expression writes.A license that didn’t resolve is an
UnknownLicense, never a blank cell, and it is shown as the index published it - in italics, so it reads as a quotation rather than as an identifier. The reader should see that the index said something, and what it was.
- static _LicenseName(release)[source]
Return the name(s) of the licenses a release is published under.
- static _PublishedLicense(release)[source]
Return what the package index published, for a license that didn’t resolve.
- static _LicenseURL(release)[source]
Return the page a license should link to, most specific first.
The project’s own
LICENSEfile wins: it is the license as this project publishes it, which is the document a reader auditing a dependency actually wants. Most projects don’t state one, though - it comes fromproject_urlsor from the override file - so a license on the SPDX List falls back to its own published pages, in the order of who is speaking: the licensor’s own page, then OSI’s entry, then SPDX’s. ALicenseRef-has none of those and stays unlinked, because nothing published it.
- _DependenciesEntry(release, collector, depth, visited)[source]
Render a release’s own requirements as a nested bullet list.
Only the unconditional requirements are listed - what an extra pulls in is that extra’s table, not this one. A package already on the path is not expanded again, so a dependency cycle terminates.
- Parameters:
- Return type:
entry- Returns:
The table entry.
- _CreateBulletList(requirements, collector, depth, visited)[source]
Render requirements as a bullet list, each item expanded by one more level.
- Parameters:
- Return type:
bullet_list- Returns:
The bullet list.
- _RequirementParagraph(requirement, project, release)[source]
Render one line of a dependency tree: the package, what is required of it, and what it is licensed under.
The license is the reason a dependency tree is in this table at all - a package pulls in what its own dependencies are licensed under, and reading that off the tree is the point. It is linked and parenthesised so the line still reads as one requirement.