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 ADDED
@@ -0,0 +1,4 @@
1
+ from pyprojectr import pyproject
2
+ from pyprojectr.pyproject import Author, BuildSystem, License, Maintainer, PyProject, PyProjectFile, Readme
3
+
4
+ __all__ = ["Author", "BuildSystem", "License", "Maintainer", "PyProject", "PyProjectFile", "Readme", "pyproject"]
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)
@@ -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,3 @@
1
+ from .pytest import PytestTool
2
+
3
+ __all__ = ["PytestTool"]
@@ -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,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ pyprojectr