livery-extensions-python 0.0.0__tar.gz

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-0.0.0/LICENSE +21 -0
  2. livery_extensions_python-0.0.0/PKG-INFO +31 -0
  3. livery_extensions_python-0.0.0/README.md +11 -0
  4. livery_extensions_python-0.0.0/pyproject.toml +37 -0
  5. livery_extensions_python-0.0.0/pyproject.toml.orig +48 -0
  6. livery_extensions_python-0.0.0/src/livery/extensions/python/__init__.py +51 -0
  7. livery_extensions_python-0.0.0/src/livery/extensions/python/_answers.py +127 -0
  8. livery_extensions_python-0.0.0/src/livery/extensions/python/_backend.py +1532 -0
  9. livery_extensions_python-0.0.0/src/livery/extensions/python/_declared.py +252 -0
  10. livery_extensions_python-0.0.0/src/livery/extensions/python/_docs/index.md +165 -0
  11. livery_extensions_python-0.0.0/src/livery/extensions/python/_docs/nav.toml +14 -0
  12. livery_extensions_python-0.0.0/src/livery/extensions/python/_installed.py +219 -0
  13. livery_extensions_python-0.0.0/src/livery/extensions/python/_parse.py +324 -0
  14. livery_extensions_python-0.0.0/src/livery/extensions/python/_reaches.py +165 -0
  15. livery_extensions_python-0.0.0/src/livery/extensions/python/_steps.py +71 -0
  16. livery_extensions_python-0.0.0/src/livery/extensions/python/_terminal.py +118 -0
  17. livery_extensions_python-0.0.0/src/livery/extensions/python/_verify.py +112 -0
  18. livery_extensions_python-0.0.0/src/livery/extensions/python/content/templates/python-library/LICENSE.jinja +21 -0
  19. livery_extensions_python-0.0.0/src/livery/extensions/python/content/templates/python-library/README.md.jinja +7 -0
  20. livery_extensions_python-0.0.0/src/livery/extensions/python/content/templates/python-library/pyproject.toml.jinja +43 -0
  21. livery_extensions_python-0.0.0/src/livery/extensions/python/content/templates/python-library/src/{{ source_path }}/__init__.py.jinja +15 -0
  22. livery_extensions_python-0.0.0/src/livery/extensions/python/content/templates/python-library/src/{{ source_path }}/__main__.py.jinja +30 -0
  23. livery_extensions_python-0.0.0/src/livery/extensions/python/content/templates/python-library/src/{{ source_path }}/py.typed +0 -0
  24. livery_extensions_python-0.0.0/src/livery/extensions/python/content/templates/python-library/tests/test_{{ project_slug }}_cli.py.jinja +39 -0
  25. livery_extensions_python-0.0.0/src/livery/extensions/python/content/templates/python-library/tests/test_{{ project_slug }}_package.py.jinja +22 -0
  26. livery_extensions_python-0.0.0/src/livery/extensions/python/content/templates/python-library/workshop.toml.jinja +10 -0
  27. livery_extensions_python-0.0.0/src/livery/extensions/python/extension.toml +165 -0
  28. livery_extensions_python-0.0.0/src/livery/extensions/python/py.typed +0 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Willem Kokke
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,31 @@
1
+ Metadata-Version: 2.4
2
+ Name: livery-extensions-python
3
+ Version: 0.0.0
4
+ Summary: Python distributions, as an extension of the livery workshop: each package's version stamped, its wheel and sdist built, published and verified, its suite run against the installed wheel, and the layering rules over the python sources.
5
+ Author: Willem Kokke
6
+ Author-email: Willem Kokke <mail@willem.net>
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3 :: Only
12
+ Classifier: Typing :: Typed
13
+ Requires-Dist: livery-footman>=0.61.0
14
+ Requires-Dist: livery-forge>=0.8.0
15
+ Requires-Dist: livery-toolroom>=0.12.0
16
+ Requires-Dist: livery-workshop>=0.11.0
17
+ Requires-Python: >=3.11
18
+ Project-URL: Repository, https://github.com/willemkokke/livery
19
+ Description-Content-Type: text/markdown
20
+
21
+ # livery-extensions-python
22
+
23
+ Python distributions, as an extension of the livery workshop. Listed as
24
+ `python` in a package's `extensions`, it stamps the version in
25
+ `pyproject.toml`, builds the wheel and the sdist, publishes them to a
26
+ python index, and tests the installed wheel in a fresh environment for
27
+ a release. Its layering rules judge the python sources: no reach into
28
+ another distribution's private names, no import a package does not
29
+ declare, and no terminal check beside the runner's own.
30
+ `fm new.package.python-library <name>` creates a python package while a
31
+ workspace lists the extension.
@@ -0,0 +1,11 @@
1
+ # livery-extensions-python
2
+
3
+ Python distributions, as an extension of the livery workshop. Listed as
4
+ `python` in a package's `extensions`, it stamps the version in
5
+ `pyproject.toml`, builds the wheel and the sdist, publishes them to a
6
+ python index, and tests the installed wheel in a fresh environment for
7
+ a release. Its layering rules judge the python sources: no reach into
8
+ another distribution's private names, no import a package does not
9
+ declare, and no terminal check beside the runner's own.
10
+ `fm new.package.python-library <name>` creates a python package while a
11
+ workspace lists the extension.
@@ -0,0 +1,37 @@
1
+ [build-system]
2
+ requires = ["uv_build>=0.11,<0.13"]
3
+ build-backend = "uv_build"
4
+
5
+ [project]
6
+ name = "livery-extensions-python"
7
+ version = "0.0.0"
8
+ description = "Python distributions, as an extension of the livery workshop: each package's version stamped, its wheel and sdist built, published and verified, its suite run against the installed wheel, and the layering rules over the python sources."
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ requires-python = ">=3.11"
13
+ classifiers = [
14
+ "Development Status :: 3 - Alpha",
15
+ "Programming Language :: Python :: 3",
16
+ "Programming Language :: Python :: 3 :: Only",
17
+ "Typing :: Typed",
18
+ ]
19
+ dependencies = [
20
+ "livery-footman>=0.61.0",
21
+ "livery-forge>=0.8.0",
22
+ "livery-toolroom>=0.12.0",
23
+ "livery-workshop>=0.11.0",
24
+ ]
25
+
26
+ [[project.authors]]
27
+ name = "Willem Kokke"
28
+ email = "mail@willem.net"
29
+
30
+ [project.urls]
31
+ Repository = "https://github.com/willemkokke/livery"
32
+
33
+ [project.entry-points."workshop.extensions"]
34
+ python = "livery.extensions.python"
35
+
36
+ [tool.uv.build-backend]
37
+ module-name = "livery.extensions.python"
@@ -0,0 +1,48 @@
1
+ # The package's own: edit it directly, nothing rewrites it.
2
+ [build-system]
3
+ requires = ["uv_build>=0.11,<0.13"]
4
+ build-backend = "uv_build"
5
+
6
+ [project]
7
+ name = "livery-extensions-python"
8
+ version = "0.0.0"
9
+ description = "Python distributions, as an extension of the livery workshop: each package's version stamped, its wheel and sdist built, published and verified, its suite run against the installed wheel, and the layering rules over the python sources."
10
+ readme = "README.md"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ requires-python = ">=3.11"
14
+ authors = [{ name = "Willem Kokke", email = "mail@willem.net" }]
15
+ classifiers = [
16
+ "Development Status :: 3 - Alpha",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3 :: Only",
19
+ "Typing :: Typed",
20
+ ]
21
+ dependencies = [
22
+ "livery-footman>=0.61.0",
23
+ # The python index's simple API: the release train's probe of a
24
+ # version the index already serves.
25
+ "livery-forge>=0.8.0",
26
+ # The store's uv and pytest, through their toolroom handles, so the
27
+ # versions are the ones the checkout's lock pins.
28
+ "livery-toolroom>=0.12.0",
29
+ # The base.
30
+ "livery-workshop>=0.11.0",
31
+ ]
32
+
33
+ [project.urls]
34
+ Repository = "https://github.com/willemkokke/livery"
35
+
36
+ # The name a package lists in its extensions, and the package whose
37
+ # extension.toml the workshop mounts it from. Nothing else: the
38
+ # extension adds no verb of its own, and nothing activates by being
39
+ # installed.
40
+ [project.entry-points."workshop.extensions"]
41
+ python = "livery.extensions.python"
42
+
43
+ [tool.uv.build-backend]
44
+ # The importable package is livery.extensions.python, its entry module
45
+ # the root's __init__.py, which serves the names an extension that
46
+ # requires python reads; livery and livery.extensions are PEP 420
47
+ # namespaces with no __init__.py.
48
+ module-name = "livery.extensions.python"
@@ -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