livery-extensions-python 0.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. livery/extensions/python/__init__.py +51 -0
  2. livery/extensions/python/_answers.py +127 -0
  3. livery/extensions/python/_backend.py +1532 -0
  4. livery/extensions/python/_declared.py +252 -0
  5. livery/extensions/python/_docs/index.md +165 -0
  6. livery/extensions/python/_docs/nav.toml +14 -0
  7. livery/extensions/python/_installed.py +219 -0
  8. livery/extensions/python/_parse.py +324 -0
  9. livery/extensions/python/_reaches.py +165 -0
  10. livery/extensions/python/_steps.py +71 -0
  11. livery/extensions/python/_terminal.py +118 -0
  12. livery/extensions/python/_verify.py +112 -0
  13. livery/extensions/python/content/templates/python-library/LICENSE.jinja +21 -0
  14. livery/extensions/python/content/templates/python-library/README.md.jinja +7 -0
  15. livery/extensions/python/content/templates/python-library/pyproject.toml.jinja +43 -0
  16. livery/extensions/python/content/templates/python-library/src/{{ source_path }}/__init__.py.jinja +15 -0
  17. livery/extensions/python/content/templates/python-library/src/{{ source_path }}/__main__.py.jinja +30 -0
  18. livery/extensions/python/content/templates/python-library/src/{{ source_path }}/py.typed +0 -0
  19. livery/extensions/python/content/templates/python-library/tests/test_{{ project_slug }}_cli.py.jinja +39 -0
  20. livery/extensions/python/content/templates/python-library/tests/test_{{ project_slug }}_package.py.jinja +22 -0
  21. livery/extensions/python/content/templates/python-library/workshop.toml.jinja +10 -0
  22. livery/extensions/python/extension.toml +165 -0
  23. livery/extensions/python/py.typed +0 -0
  24. livery_extensions_python-0.0.0.dist-info/METADATA +31 -0
  25. livery_extensions_python-0.0.0.dist-info/RECORD +28 -0
  26. livery_extensions_python-0.0.0.dist-info/WHEEL +4 -0
  27. livery_extensions_python-0.0.0.dist-info/entry_points.txt +3 -0
  28. livery_extensions_python-0.0.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,51 @@
1
+ """The python extension's names another extension reads to build and test a wheel.
2
+
3
+ The python extension builds, versions, publishes and tests a package
4
+ whose set holds python. An extension that builds such a package's
5
+ wheels with a tool of its own, as nanobind builds them with
6
+ cibuildwheel, reads two of its functions.
7
+ [livery.extensions.python.module_docs][] copies the package's ``docs/``
8
+ into its source tree as the wheel's embedded ``_docs`` for one build,
9
+ and removes the copy after it. [livery.extensions.python.run_isolated_test][]
10
+ installs a built wheel into a fresh venv and runs the package's tests
11
+ against the installed copy.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ # The literal-False spelling the checkers honour without importing
17
+ # `typing`: the names below are what a checker sees, and at runtime
18
+ # `__getattr__` serves each from its module when it is read, so importing
19
+ # this module loads none of the extension's modules.
20
+ TYPE_CHECKING = False
21
+ if TYPE_CHECKING:
22
+ from livery.extensions.python._backend import module_docs as module_docs
23
+ from livery.extensions.python._backend import (
24
+ run_isolated_test as run_isolated_test,
25
+ )
26
+
27
+ __version__ = "0.0.0"
28
+
29
+ __all__ = ["__version__", "module_docs", "run_isolated_test"]
30
+
31
+ # The module each lazily served name lives in.
32
+ _EXPORTS: dict[str, str] = {
33
+ "module_docs": "livery.extensions.python._backend",
34
+ "run_isolated_test": "livery.extensions.python._backend",
35
+ }
36
+
37
+
38
+ def __getattr__(name: str) -> object:
39
+ """Serve a public name from its module, each time it is read.
40
+
41
+ The value is never kept here, so a test that patches the name in
42
+ its module is read through.
43
+ """
44
+ import importlib
45
+
46
+ module = _EXPORTS.get(name)
47
+ if module is None:
48
+ raise AttributeError(
49
+ f"module 'livery.extensions.python' has no attribute {name!r}"
50
+ )
51
+ return getattr(importlib.import_module(module), name)
@@ -0,0 +1,127 @@
1
+ """The python extension's answers: about a package, and about the workspace.
2
+
3
+ About a package, from its manifest and sources: its version, the files
4
+ a version is written into, its requirements, the names its code is
5
+ referenced by, its public modules and what each source references.
6
+ About the workspace, while pytest is listed: the functions that run
7
+ the python packages' suites and a package's documentation examples.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from typing import TYPE_CHECKING
13
+
14
+ from livery.extensions.python import _backend
15
+
16
+ if TYPE_CHECKING:
17
+ from collections.abc import Callable, Mapping
18
+ from pathlib import Path
19
+
20
+ from livery.forge import Registry
21
+ from livery.workshop import Package, RequirementWriter, SourceReferences
22
+
23
+
24
+ def current_version(package: Package) -> str:
25
+ """The version the package's ``pyproject.toml`` declares."""
26
+ return _backend.current_version(package)
27
+
28
+
29
+ def version_files(package: Package) -> tuple[Path, ...]:
30
+ """``pyproject.toml``, and every ``__init__.py`` that may carry ``__version__``."""
31
+ return tuple(_backend.stamp_version(package).homes())
32
+
33
+
34
+ def requirements(package: Package) -> Mapping[str, str]:
35
+ """The package's ``[project.dependencies]``, each name to its constraint."""
36
+ return _backend.declared_requirements(package)
37
+
38
+
39
+ def requirement_writers(package: Package) -> tuple[RequirementWriter, ...]:
40
+ """The pyproject's writer of a requirement on a sibling that holds python."""
41
+ del package
42
+ return (_backend.declare_requirement,)
43
+
44
+
45
+ def test_requirements(package: Package) -> Mapping[str, str]:
46
+ """The package's ``test`` extra, each name to its constraint."""
47
+ return _backend.declared_test_requirements(package)
48
+
49
+
50
+ def test_requirement_writers(package: Package) -> tuple[RequirementWriter, ...]:
51
+ """The pyproject's writer of a test requirement on a sibling that holds python."""
52
+ del package
53
+ return (_backend.declare_test_requirement,)
54
+
55
+
56
+ def module_roots(package: Package) -> tuple[str, ...]:
57
+ """The import prefixes the package's code is referenced by."""
58
+ return tuple(_backend.module_roots(package))
59
+
60
+
61
+ def public_modules(package: Package) -> tuple[str, ...]:
62
+ """The modules that declare the package's public API."""
63
+ return tuple(_backend.public_modules(package))
64
+
65
+
66
+ def references(package: Package) -> tuple[SourceReferences, ...]:
67
+ """What each python source under ``src`` and ``tests`` references, one per file."""
68
+ return _backend.references(package)
69
+
70
+
71
+ #: The ecosystem a python package is released to, as the ``distributions``
72
+ #: query names it, and the registry kind its target resolves by.
73
+ ECOSYSTEM = "python"
74
+
75
+
76
+ def distributions(package: Package) -> tuple[tuple[str, str], ...]:
77
+ """The distribution the package releases, as its ecosystem and its name."""
78
+ return ((ECOSYSTEM, package.name),)
79
+
80
+
81
+ def executables(package: Package) -> tuple[str, ...]:
82
+ """The scripts the package's ``pyproject.toml`` names in ``[project.scripts]``."""
83
+ return _backend.scripts(package)
84
+
85
+
86
+ def registry(package: Package) -> Registry:
87
+ """The simple index the package is released to, as a probe of its versions.
88
+
89
+ The index is the python target the registry ladder resolves for the
90
+ package's workspace ([livery.workshop.registry][]), and the probe
91
+ reads it with the target's credential: an authenticated index, a
92
+ forge's own registry or a private owner's, answers only with it, and
93
+ an anonymous probe would wait for a version the index already
94
+ serves.
95
+ """
96
+ from livery.forge import SimpleRegistry
97
+ from livery.workshop import registry as resolved
98
+
99
+ target = resolved(package.root, ECOSYSTEM)
100
+ return SimpleRegistry(target.url, token=target.token)
101
+
102
+
103
+ def suite_runner(root: Path) -> Callable[..., None]:
104
+ """Answer ``python.test.runner`` with the function that runs the suites.
105
+
106
+ pytest's test step asks with the workspace root, which the answer
107
+ does not depend on, and calls the answer with the words for pytest,
108
+ the packages whose suites run in one call, the root, the test files
109
+ that stand for each package's suite, the CI point and whether the
110
+ run is measured.
111
+ """
112
+ del root
113
+ return _backend.run_test
114
+
115
+
116
+ def examples_runner(
117
+ root: Path,
118
+ ) -> Callable[[Package, Path, tuple[str, ...], tuple[str, ...]], None]:
119
+ """Answer ``python.examples.runner`` with the function that runs examples.
120
+
121
+ pytest's examples step asks with the workspace root, which the
122
+ answer does not depend on, and calls the answer once per package
123
+ with the package, the root, the example files the run names (empty
124
+ for all of them) and the words for pytest.
125
+ """
126
+ del root
127
+ return _backend.run_examples