pyprojectr 0.0.1a2__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.
- pyprojectr/__init__.py +4 -0
- pyprojectr/core.py +40 -0
- pyprojectr/pyproject.py +123 -0
- pyprojectr/tools/__init__.py +3 -0
- pyprojectr/tools/pytest.py +17 -0
- pyprojectr/tools/setuptools_scm.py +0 -0
- pyprojectr-0.0.1a2.dist-info/METADATA +21 -0
- pyprojectr-0.0.1a2.dist-info/RECORD +10 -0
- pyprojectr-0.0.1a2.dist-info/WHEEL +5 -0
- pyprojectr-0.0.1a2.dist-info/top_level.txt +1 -0
pyprojectr/__init__.py
ADDED
pyprojectr/core.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Mapping
|
|
4
|
+
from typing import Any, TypeVar
|
|
5
|
+
|
|
6
|
+
import attrs
|
|
7
|
+
import cattrs
|
|
8
|
+
from cattrs.gen import make_dict_structure_fn
|
|
9
|
+
|
|
10
|
+
T = TypeVar("T")
|
|
11
|
+
D = TypeVar("D")
|
|
12
|
+
STRUCT_CONVERTER = cattrs.Converter()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def convert_underscores(cls: type[T]) -> cattrs.SimpleStructureHook[Mapping[str, Any], T]:
|
|
16
|
+
return make_dict_structure_fn(
|
|
17
|
+
cls,
|
|
18
|
+
STRUCT_CONVERTER,
|
|
19
|
+
**{a.name: cattrs.override(rename=_underscores_to_hyphen(a.name)) for a in attrs.fields(cls)},
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _underscores_to_hyphen(text: str, reverse: bool = False) -> str:
|
|
24
|
+
if not reverse:
|
|
25
|
+
return text.replace("_", "-")
|
|
26
|
+
return text.replace("-", "_")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@attrs.define
|
|
30
|
+
class BaseModel:
|
|
31
|
+
@classmethod
|
|
32
|
+
def converter(cls) -> cattrs.Converter:
|
|
33
|
+
return STRUCT_CONVERTER
|
|
34
|
+
|
|
35
|
+
@classmethod
|
|
36
|
+
def from_data(cls, data: D) -> BaseModel:
|
|
37
|
+
return cls.converter().structure(data, cls)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
STRUCT_CONVERTER.register_structure_hook_factory(attrs.has, convert_underscores)
|
pyprojectr/pyproject.py
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import pathlib
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
import attrs
|
|
5
|
+
import tomli
|
|
6
|
+
|
|
7
|
+
from pyprojectr import core
|
|
8
|
+
from pyprojectr.tools import PytestTool
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@attrs.define(frozen=True)
|
|
12
|
+
class BuildSystem(core.BaseModel):
|
|
13
|
+
requires: list[str]
|
|
14
|
+
build_backend: str | None = None
|
|
15
|
+
backend_path: list[str] | None = None
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@attrs.define(frozen=True)
|
|
19
|
+
class Author(core.BaseModel):
|
|
20
|
+
name: str | None = None
|
|
21
|
+
email: str | None = None
|
|
22
|
+
|
|
23
|
+
def __attrs_post_init__(self) -> None:
|
|
24
|
+
if not self.name and not self.email:
|
|
25
|
+
raise ValueError("Author must have a name or email")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@attrs.define(frozen=True)
|
|
29
|
+
class Maintainer(Author): ...
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@attrs.define(frozen=True, eq=False)
|
|
33
|
+
class Readme(core.BaseModel):
|
|
34
|
+
file: str | None = None
|
|
35
|
+
text: str | None = None
|
|
36
|
+
content_type: str | None = None
|
|
37
|
+
|
|
38
|
+
def __eq__(self, other) -> bool:
|
|
39
|
+
print(other, type(other), self)
|
|
40
|
+
if isinstance(other, str):
|
|
41
|
+
return self.file == other
|
|
42
|
+
return self.file == other.file
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@attrs.define(frozen=True)
|
|
46
|
+
class License(core.BaseModel):
|
|
47
|
+
file: str | None = None
|
|
48
|
+
text: str | None = None
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@attrs.define(frozen=True)
|
|
52
|
+
class PyProject(core.BaseModel):
|
|
53
|
+
name: str
|
|
54
|
+
version: str | None = None
|
|
55
|
+
description: str | None = None
|
|
56
|
+
readme: Readme | None = None
|
|
57
|
+
requires_python: str | None = None
|
|
58
|
+
license: License | None = None
|
|
59
|
+
authors: list[Author] = attrs.Factory(list)
|
|
60
|
+
maintainers: list[Maintainer] = attrs.Factory(list)
|
|
61
|
+
keywords: list[str] = attrs.Factory(list)
|
|
62
|
+
classifiers: list[str] = attrs.Factory(list)
|
|
63
|
+
urls: dict[str, str] = attrs.Factory(dict)
|
|
64
|
+
dependencies: list[str] = attrs.Factory(list)
|
|
65
|
+
optional_dependencies: dict[str, list[str]] = attrs.Factory(dict)
|
|
66
|
+
dynamic: list[str] = attrs.Factory(list)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@attrs.define(frozen=True)
|
|
70
|
+
class PyProjectScmTool(core.BaseModel):
|
|
71
|
+
version_scheme: str | None = None
|
|
72
|
+
local_scheme: str | None = None
|
|
73
|
+
write_to: str | None = None
|
|
74
|
+
write_to_template: str | None = None
|
|
75
|
+
relative_to: str | None = None
|
|
76
|
+
tag_regex: str | None = None
|
|
77
|
+
parentdir_prefix: str | None = None
|
|
78
|
+
fallback_version: str | None = None
|
|
79
|
+
parse: Any | None = None
|
|
80
|
+
git_describe_command: str | None = None
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@attrs.define(frozen=True)
|
|
84
|
+
class PyProjectScmxTool(core.BaseModel):
|
|
85
|
+
ci_version_variable: str
|
|
86
|
+
ci_main_branch_name: str
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
@attrs.define(frozen=True)
|
|
90
|
+
class PyProjectTool(core.BaseModel):
|
|
91
|
+
setuptools_scm: PyProjectScmTool | None = None
|
|
92
|
+
setuptools_scmx: PyProjectScmxTool | None = None
|
|
93
|
+
pytest: PytestTool | None = None
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
@attrs.define(frozen=True)
|
|
97
|
+
class PyProjectFile(core.BaseModel):
|
|
98
|
+
build_system: BuildSystem
|
|
99
|
+
project: PyProject
|
|
100
|
+
tool: PyProjectTool | None = None
|
|
101
|
+
dependency_groups: dict[str, list[str | dict[str, Any]]] = attrs.Factory(dict)
|
|
102
|
+
|
|
103
|
+
@property
|
|
104
|
+
def tools(self) -> PyProjectTool | None:
|
|
105
|
+
return self.tool
|
|
106
|
+
|
|
107
|
+
def get_tool_options(self, name: str) -> Any:
|
|
108
|
+
if self.tool and hasattr(self.tool, name):
|
|
109
|
+
return getattr(self.tool, name)
|
|
110
|
+
return None
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@core.STRUCT_CONVERTER.register_structure_hook
|
|
114
|
+
def register_readme_hook(value: dict[str, Any] | str, _) -> Readme:
|
|
115
|
+
if isinstance(value, str):
|
|
116
|
+
value = dict(file=value)
|
|
117
|
+
return core.convert_underscores(Readme)(value, Readme)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def from_file(path: pathlib.Path) -> PyProjectFile:
|
|
121
|
+
with path.open() as f:
|
|
122
|
+
toml = tomli.loads(f.read())
|
|
123
|
+
return core.BaseModel.converter().structure(toml, PyProjectFile)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import attrs
|
|
2
|
+
|
|
3
|
+
from pyprojectr.core import BaseModel
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@attrs.define(frozen=True)
|
|
7
|
+
class PytestTool(BaseModel):
|
|
8
|
+
"""Model for [tool.pytest.ini_options] in pyproject.toml."""
|
|
9
|
+
|
|
10
|
+
minversion: str | None = None
|
|
11
|
+
addopts: str | None = None
|
|
12
|
+
testpaths: list[str] = attrs.Factory(list)
|
|
13
|
+
python_files: list[str] = attrs.Factory(list)
|
|
14
|
+
python_classes: list[str] = attrs.Factory(list)
|
|
15
|
+
python_functions: list[str] = attrs.Factory(list)
|
|
16
|
+
markers: list[str] = attrs.Factory(list)
|
|
17
|
+
norecursedirs: list[str] = attrs.Factory(list)
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyprojectr
|
|
3
|
+
Version: 0.0.1a2
|
|
4
|
+
Summary: Add your description here
|
|
5
|
+
Author-email: Rowland Ogwara <r.ogwara@gmail.com>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Classifier: Intended Audience :: Developers
|
|
8
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
14
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
15
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
Requires-Dist: attrs>=26.1
|
|
20
|
+
Requires-Dist: cattrs>=26.1
|
|
21
|
+
Requires-Dist: tomli>=2.4.1
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
pyprojectr/__init__.py,sha256=WvhR2Dp_tcE60c9AnLRCne7gWmieEVbRSpN9trAc-o0,256
|
|
2
|
+
pyprojectr/core.py,sha256=TUgyDDwgfA9588NqEJz7BKNRa5iq-rDYtWGfFmYCUgU,1015
|
|
3
|
+
pyprojectr/pyproject.py,sha256=nLc-Is-eyEmdPTEaF3JZ79BVBLxVmrdagbGeGkgWh5I,3451
|
|
4
|
+
pyprojectr/tools/__init__.py,sha256=Yl7NLmzLE8VvVQ4XGSN0R0hTSyLg-nOG9vIXPvLdgYw,57
|
|
5
|
+
pyprojectr/tools/pytest.py,sha256=6Go0OAWHgEhQE_0caeF1VkP8XCGm-2Tf85LEVxj9AR0,540
|
|
6
|
+
pyprojectr/tools/setuptools_scm.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
pyprojectr-0.0.1a2.dist-info/METADATA,sha256=WAoh7gUqnLjfCw3mnEdr_cd-tQa6VxrJCl_mvzce1SM,888
|
|
8
|
+
pyprojectr-0.0.1a2.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
9
|
+
pyprojectr-0.0.1a2.dist-info/top_level.txt,sha256=tvJqvZyWkd9kKcsi8BrGnlp6nQzHdgRGOXUVHGaII1M,11
|
|
10
|
+
pyprojectr-0.0.1a2.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pyprojectr
|