libres 0.7.3__tar.gz → 0.8.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.
- {libres-0.7.3 → libres-0.8.0}/HISTORY.rst +12 -0
- {libres-0.7.3/src/libres.egg-info → libres-0.8.0}/PKG-INFO +26 -9
- {libres-0.7.3 → libres-0.8.0}/README.rst +4 -4
- libres-0.8.0/pyproject.toml +285 -0
- {libres-0.7.3 → libres-0.8.0}/setup.cfg +13 -6
- {libres-0.7.3 → libres-0.8.0}/src/libres/__init__.py +3 -1
- {libres-0.7.3 → libres-0.8.0}/src/libres/context/core.py +32 -26
- libres-0.8.0/src/libres/context/exposure.py +13 -0
- {libres-0.7.3 → libres-0.8.0}/src/libres/context/registry.py +14 -10
- {libres-0.7.3 → libres-0.8.0}/src/libres/context/session.py +8 -6
- {libres-0.7.3 → libres-0.8.0}/src/libres/context/settings.py +9 -6
- libres-0.8.0/src/libres/db/__init__.py +7 -0
- {libres-0.7.3 → libres-0.8.0}/src/libres/db/models/__init__.py +2 -0
- {libres-0.7.3 → libres-0.8.0}/src/libres/db/models/allocation.py +60 -56
- {libres-0.7.3 → libres-0.8.0}/src/libres/db/models/base.py +2 -0
- {libres-0.7.3 → libres-0.8.0}/src/libres/db/models/other.py +12 -7
- {libres-0.7.3 → libres-0.8.0}/src/libres/db/models/reservation.py +28 -23
- {libres-0.7.3 → libres-0.8.0}/src/libres/db/models/reserved_slot.py +12 -10
- {libres-0.7.3 → libres-0.8.0}/src/libres/db/models/timestamp.py +9 -7
- {libres-0.7.3 → libres-0.8.0}/src/libres/db/models/types/__init__.py +2 -0
- {libres-0.7.3 → libres-0.8.0}/src/libres/db/models/types/json_type.py +12 -9
- {libres-0.7.3 → libres-0.8.0}/src/libres/db/models/types/utcdatetime.py +10 -8
- {libres-0.7.3 → libres-0.8.0}/src/libres/db/models/types/uuid_type.py +10 -8
- {libres-0.7.3 → libres-0.8.0}/src/libres/db/queries.py +32 -27
- {libres-0.7.3 → libres-0.8.0}/src/libres/db/scheduler.py +133 -127
- {libres-0.7.3 → libres-0.8.0}/src/libres/modules/errors.py +9 -7
- {libres-0.7.3 → libres-0.8.0}/src/libres/modules/events.py +57 -56
- {libres-0.7.3 → libres-0.8.0}/src/libres/modules/rasterizer.py +11 -7
- {libres-0.7.3 → libres-0.8.0}/src/libres/modules/utils.py +16 -14
- libres-0.8.0/src/libres/py.typed +0 -0
- {libres-0.7.3 → libres-0.8.0/src/libres.egg-info}/PKG-INFO +26 -9
- {libres-0.7.3 → libres-0.8.0}/src/libres.egg-info/requires.txt +6 -1
- {libres-0.7.3 → libres-0.8.0}/tests/test_allocation.py +1 -1
- libres-0.7.3/pyproject.toml +0 -82
- libres-0.7.3/src/libres/context/exposure.py +0 -9
- libres-0.7.3/src/libres/db/__init__.py +0 -5
- libres-0.7.3/src/libres/modules/__init__.py +0 -1
- {libres-0.7.3 → libres-0.8.0}/LICENSE +0 -0
- {libres-0.7.3 → libres-0.8.0}/MANIFEST.in +0 -0
- {libres-0.7.3 → libres-0.8.0}/docs/Makefile +0 -0
- {libres-0.7.3 → libres-0.8.0}/docs/_static/custom.css +0 -0
- {libres-0.7.3 → libres-0.8.0}/docs/_static/favicon.ico +0 -0
- {libres-0.7.3 → libres-0.8.0}/docs/_static/logo.svg +0 -0
- {libres-0.7.3 → libres-0.8.0}/docs/api.rst +0 -0
- {libres-0.7.3 → libres-0.8.0}/docs/concepts.rst +0 -0
- {libres-0.7.3 → libres-0.8.0}/docs/conf.py +0 -0
- {libres-0.7.3 → libres-0.8.0}/docs/customizations.rst +0 -0
- {libres-0.7.3 → libres-0.8.0}/docs/faq.rst +0 -0
- {libres-0.7.3 → libres-0.8.0}/docs/index.rst +0 -0
- {libres-0.7.3 → libres-0.8.0}/docs/requirements.txt +0 -0
- {libres-0.7.3 → libres-0.8.0}/docs/under_the_hood.rst +0 -0
- {libres-0.7.3 → libres-0.8.0}/src/libres/.gitignore +0 -0
- {libres-0.7.3 → libres-0.8.0}/src/libres/context/__init__.py +0 -0
- /libres-0.7.3/src/libres/py.typed → /libres-0.8.0/src/libres/modules/__init__.py +0 -0
- {libres-0.7.3 → libres-0.8.0}/src/libres.egg-info/SOURCES.txt +0 -0
- {libres-0.7.3 → libres-0.8.0}/src/libres.egg-info/dependency_links.txt +0 -0
- {libres-0.7.3 → libres-0.8.0}/src/libres.egg-info/not-zip-safe +0 -0
- {libres-0.7.3 → libres-0.8.0}/src/libres.egg-info/top_level.txt +0 -0
- {libres-0.7.3 → libres-0.8.0}/tests/test_registry.py +0 -0
- {libres-0.7.3 → libres-0.8.0}/tests/test_reservation.py +0 -0
- {libres-0.7.3 → libres-0.8.0}/tests/test_reserved_slot.py +0 -0
- {libres-0.7.3 → libres-0.8.0}/tests/test_scheduler.py +0 -0
- {libres-0.7.3 → libres-0.8.0}/tests/test_session.py +0 -0
- {libres-0.7.3 → libres-0.8.0}/tests/test_test.py +0 -0
- {libres-0.7.3 → libres-0.8.0}/tests/test_types.py +0 -0
- {libres-0.7.3 → libres-0.8.0}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
---------
|
|
3
3
|
|
|
4
|
+
0.8.0 (15.01.2025)
|
|
5
|
+
~~~~~~~~~~~~~~~~~~~
|
|
6
|
+
|
|
7
|
+
- Adds support for Python 3.13
|
|
8
|
+
[Daverball]
|
|
9
|
+
|
|
10
|
+
- Drops support for Python 3.8
|
|
11
|
+
[Daverball]
|
|
12
|
+
|
|
13
|
+
- Modernizes type hints
|
|
14
|
+
[Daverball]
|
|
15
|
+
|
|
4
16
|
0.7.3 (2024-08-21)
|
|
5
17
|
~~~~~~~~~~~~~~~~~~~
|
|
6
18
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: libres
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.0
|
|
4
4
|
Summary: A library to reserve things
|
|
5
5
|
Home-page: http://github.com/seantis/libres/
|
|
6
6
|
Author: Denis Krienbühl
|
|
@@ -14,13 +14,13 @@ Classifier: License :: OSI Approved :: BSD License
|
|
|
14
14
|
Classifier: Operating System :: OS Independent
|
|
15
15
|
Classifier: Programming Language :: Python
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.9
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
22
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
-
Requires-Python: >=3.
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
24
|
Description-Content-Type: text/x-rst
|
|
25
25
|
License-File: LICENSE
|
|
26
26
|
Requires-Dist: python-dateutil
|
|
@@ -30,10 +30,15 @@ Requires-Dist: sedate>=1.0.0
|
|
|
30
30
|
Requires-Dist: SQLAlchemy<2,>=0.9
|
|
31
31
|
Provides-Extra: dev
|
|
32
32
|
Requires-Dist: bandit[toml]; extra == "dev"
|
|
33
|
+
Requires-Dist: bump-my-version; extra == "dev"
|
|
33
34
|
Requires-Dist: flake8; extra == "dev"
|
|
34
|
-
Requires-Dist: flake8-
|
|
35
|
+
Requires-Dist: flake8-type-checking; extra == "dev"
|
|
35
36
|
Requires-Dist: pre-commit; extra == "dev"
|
|
37
|
+
Requires-Dist: pre-commit-uv; extra == "dev"
|
|
38
|
+
Requires-Dist: ruff; extra == "dev"
|
|
39
|
+
Requires-Dist: uv; extra == "dev"
|
|
36
40
|
Requires-Dist: tox; extra == "dev"
|
|
41
|
+
Requires-Dist: tox-uv; extra == "dev"
|
|
37
42
|
Provides-Extra: test
|
|
38
43
|
Requires-Dist: jsonpickle; extra == "test"
|
|
39
44
|
Requires-Dist: pytest; extra == "test"
|
|
@@ -91,19 +96,19 @@ Run the Tests
|
|
|
91
96
|
|
|
92
97
|
Install tox and run it::
|
|
93
98
|
|
|
94
|
-
pip install tox
|
|
99
|
+
pip install tox tox-uv
|
|
95
100
|
tox
|
|
96
101
|
|
|
97
102
|
Limit the tests to a specific python version::
|
|
98
103
|
|
|
99
|
-
tox -e
|
|
104
|
+
tox -e py311
|
|
100
105
|
|
|
101
106
|
Conventions
|
|
102
107
|
-----------
|
|
103
108
|
|
|
104
109
|
Libres follows PEP8 as close as possible. To test for it run::
|
|
105
110
|
|
|
106
|
-
tox -e
|
|
111
|
+
tox -e ruff,flake8
|
|
107
112
|
|
|
108
113
|
Libres uses `Semantic Versioning <http://semver.org/>`_
|
|
109
114
|
|
|
@@ -128,7 +133,7 @@ Making a new Release
|
|
|
128
133
|
|
|
129
134
|
Make sure all changes are in the HISTORY.rst, then bump the version::
|
|
130
135
|
|
|
131
|
-
|
|
136
|
+
bump-my-version bump major|minor|patch
|
|
132
137
|
git push && git push --tags
|
|
133
138
|
|
|
134
139
|
After this, create a new release on Github.
|
|
@@ -136,6 +141,18 @@ After this, create a new release on Github.
|
|
|
136
141
|
Changelog
|
|
137
142
|
---------
|
|
138
143
|
|
|
144
|
+
0.8.0 (15.01.2025)
|
|
145
|
+
~~~~~~~~~~~~~~~~~~~
|
|
146
|
+
|
|
147
|
+
- Adds support for Python 3.13
|
|
148
|
+
[Daverball]
|
|
149
|
+
|
|
150
|
+
- Drops support for Python 3.8
|
|
151
|
+
[Daverball]
|
|
152
|
+
|
|
153
|
+
- Modernizes type hints
|
|
154
|
+
[Daverball]
|
|
155
|
+
|
|
139
156
|
0.7.3 (2024-08-21)
|
|
140
157
|
~~~~~~~~~~~~~~~~~~~
|
|
141
158
|
|
|
@@ -42,19 +42,19 @@ Run the Tests
|
|
|
42
42
|
|
|
43
43
|
Install tox and run it::
|
|
44
44
|
|
|
45
|
-
pip install tox
|
|
45
|
+
pip install tox tox-uv
|
|
46
46
|
tox
|
|
47
47
|
|
|
48
48
|
Limit the tests to a specific python version::
|
|
49
49
|
|
|
50
|
-
tox -e
|
|
50
|
+
tox -e py311
|
|
51
51
|
|
|
52
52
|
Conventions
|
|
53
53
|
-----------
|
|
54
54
|
|
|
55
55
|
Libres follows PEP8 as close as possible. To test for it run::
|
|
56
56
|
|
|
57
|
-
tox -e
|
|
57
|
+
tox -e ruff,flake8
|
|
58
58
|
|
|
59
59
|
Libres uses `Semantic Versioning <http://semver.org/>`_
|
|
60
60
|
|
|
@@ -79,7 +79,7 @@ Making a new Release
|
|
|
79
79
|
|
|
80
80
|
Make sure all changes are in the HISTORY.rst, then bump the version::
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
bump-my-version bump major|minor|patch
|
|
83
83
|
git push && git push --tags
|
|
84
84
|
|
|
85
85
|
After this, create a new release on Github.
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=42", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[tool.pytest.ini_options]
|
|
6
|
+
log_level = "INFO"
|
|
7
|
+
testpaths = ["tests"]
|
|
8
|
+
|
|
9
|
+
[tool.coverage.run]
|
|
10
|
+
branch = true
|
|
11
|
+
source = ["src"]
|
|
12
|
+
|
|
13
|
+
[tool.bumpversion]
|
|
14
|
+
current_version = "0.8.0"
|
|
15
|
+
commit = true
|
|
16
|
+
message = "Release {new_version}"
|
|
17
|
+
tag = true
|
|
18
|
+
tag_message = "Release {new_version}"
|
|
19
|
+
|
|
20
|
+
[[tool.bumpversion.files]]
|
|
21
|
+
filename = "src/libres/__init__.py"
|
|
22
|
+
search= "__version__ = '{current_version}'"
|
|
23
|
+
replace= "__version__ = '{new_version}'"
|
|
24
|
+
|
|
25
|
+
[[tool.bumpversion.files]]
|
|
26
|
+
filename = "HISTORY.rst"
|
|
27
|
+
search = """
|
|
28
|
+
---------
|
|
29
|
+
"""
|
|
30
|
+
replace = """
|
|
31
|
+
---------
|
|
32
|
+
|
|
33
|
+
{new_version} ({now:%d.%m.%Y})
|
|
34
|
+
~~~~~~~~~~~~~~~~~~~
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
[tool.mypy]
|
|
38
|
+
python_version = "3.9"
|
|
39
|
+
follow_imports = "silent"
|
|
40
|
+
namespace_packages = true
|
|
41
|
+
explicit_package_bases = true
|
|
42
|
+
warn_unused_ignores = true
|
|
43
|
+
warn_redundant_casts = true
|
|
44
|
+
warn_unreachable = true
|
|
45
|
+
disallow_any_generics = true
|
|
46
|
+
disallow_untyped_defs = true
|
|
47
|
+
plugins = "sqlmypy"
|
|
48
|
+
mypy_path = "$MYPY_CONFIG_FILE_DIR/src"
|
|
49
|
+
|
|
50
|
+
[tool.bandit]
|
|
51
|
+
exclude_dirs = ["tests"]
|
|
52
|
+
skips = ["B101"]
|
|
53
|
+
|
|
54
|
+
[tool.ruff]
|
|
55
|
+
exclude = [
|
|
56
|
+
".bzr",
|
|
57
|
+
".direnv",
|
|
58
|
+
".eggs",
|
|
59
|
+
".git",
|
|
60
|
+
".git-rewrite",
|
|
61
|
+
".hg",
|
|
62
|
+
".ipynb_checkpoints",
|
|
63
|
+
".mypy_cache",
|
|
64
|
+
".nox",
|
|
65
|
+
".pants.d",
|
|
66
|
+
".pyenv",
|
|
67
|
+
".pytest_cache",
|
|
68
|
+
".pytype",
|
|
69
|
+
".ruff_cache",
|
|
70
|
+
".svn",
|
|
71
|
+
".tox",
|
|
72
|
+
".venv",
|
|
73
|
+
".vscode",
|
|
74
|
+
"__pypackages__",
|
|
75
|
+
"_build",
|
|
76
|
+
"buck-out",
|
|
77
|
+
"build",
|
|
78
|
+
"dist",
|
|
79
|
+
"node_modules",
|
|
80
|
+
"site-packages",
|
|
81
|
+
"venv",
|
|
82
|
+
]
|
|
83
|
+
src = ["src", "tests"]
|
|
84
|
+
include = [
|
|
85
|
+
"pyproject.toml",
|
|
86
|
+
"src/**/*.py",
|
|
87
|
+
"tests/**/*.py",
|
|
88
|
+
"stubs/**/*.pyi"
|
|
89
|
+
]
|
|
90
|
+
line-length = 79
|
|
91
|
+
indent-width = 4
|
|
92
|
+
target-version = "py39"
|
|
93
|
+
|
|
94
|
+
[tool.ruff.lint]
|
|
95
|
+
select = [
|
|
96
|
+
"B0",
|
|
97
|
+
"B904",
|
|
98
|
+
"B909",
|
|
99
|
+
"C4",
|
|
100
|
+
"COM818",
|
|
101
|
+
"D2",
|
|
102
|
+
"D301",
|
|
103
|
+
"D4",
|
|
104
|
+
"E",
|
|
105
|
+
"F",
|
|
106
|
+
"FLY002",
|
|
107
|
+
"I002",
|
|
108
|
+
"ISC",
|
|
109
|
+
"N",
|
|
110
|
+
"PERF",
|
|
111
|
+
"PGH004",
|
|
112
|
+
"PIE",
|
|
113
|
+
"PYI",
|
|
114
|
+
"Q",
|
|
115
|
+
"RUF",
|
|
116
|
+
"SIM",
|
|
117
|
+
"SLOT",
|
|
118
|
+
"UP",
|
|
119
|
+
"W"
|
|
120
|
+
]
|
|
121
|
+
ignore = [
|
|
122
|
+
"B007",
|
|
123
|
+
"C420",
|
|
124
|
+
"D200",
|
|
125
|
+
"D201",
|
|
126
|
+
"D202",
|
|
127
|
+
"D204",
|
|
128
|
+
"D205",
|
|
129
|
+
"D209",
|
|
130
|
+
"D210",
|
|
131
|
+
"D211",
|
|
132
|
+
"D400",
|
|
133
|
+
"D401",
|
|
134
|
+
"D412",
|
|
135
|
+
"E226",
|
|
136
|
+
"E402",
|
|
137
|
+
"E711",
|
|
138
|
+
"E712",
|
|
139
|
+
"E741",
|
|
140
|
+
"N818",
|
|
141
|
+
"PYI019",
|
|
142
|
+
"PYI041",
|
|
143
|
+
"RUF012",
|
|
144
|
+
"RUF013",
|
|
145
|
+
"RUF021",
|
|
146
|
+
"RUF022",
|
|
147
|
+
"RUF023",
|
|
148
|
+
"RUF031",
|
|
149
|
+
"RUF052",
|
|
150
|
+
"RUF056",
|
|
151
|
+
"SIM103",
|
|
152
|
+
"SIM105",
|
|
153
|
+
"SIM108",
|
|
154
|
+
"SIM110",
|
|
155
|
+
"SIM118",
|
|
156
|
+
"SIM210",
|
|
157
|
+
"SIM910",
|
|
158
|
+
"UP009",
|
|
159
|
+
"UP012",
|
|
160
|
+
"UP032",
|
|
161
|
+
"UP038",
|
|
162
|
+
]
|
|
163
|
+
unfixable = []
|
|
164
|
+
external = ["TC"]
|
|
165
|
+
allowed-confusables = ["×"]
|
|
166
|
+
preview = true
|
|
167
|
+
|
|
168
|
+
[tool.ruff.lint.extend-per-file-ignores]
|
|
169
|
+
"tests/**/*.py" = [
|
|
170
|
+
"C4",
|
|
171
|
+
"D",
|
|
172
|
+
"FLY002",
|
|
173
|
+
"I002",
|
|
174
|
+
"ISC",
|
|
175
|
+
"N",
|
|
176
|
+
"Q",
|
|
177
|
+
"PERF",
|
|
178
|
+
"PGH",
|
|
179
|
+
"PIE",
|
|
180
|
+
"PYI",
|
|
181
|
+
"RUF",
|
|
182
|
+
"SIM",
|
|
183
|
+
"UP",
|
|
184
|
+
]
|
|
185
|
+
|
|
186
|
+
[tool.ruff.lint.isort]
|
|
187
|
+
required-imports = ["from __future__ import annotations"]
|
|
188
|
+
|
|
189
|
+
[tool.ruff.lint.pep8-naming]
|
|
190
|
+
extend-ignore-names = [
|
|
191
|
+
"afterFlowable",
|
|
192
|
+
"HSTORE",
|
|
193
|
+
"sortKey",
|
|
194
|
+
"URL",
|
|
195
|
+
"UUID"
|
|
196
|
+
]
|
|
197
|
+
classmethod-decorators = [
|
|
198
|
+
# NOTE: We can potentially get rid some of these with SQLAlchemy 2.0
|
|
199
|
+
# since they should cleanly combine with classmethod
|
|
200
|
+
"declared_attr",
|
|
201
|
+
"expression",
|
|
202
|
+
"comparator",
|
|
203
|
+
]
|
|
204
|
+
|
|
205
|
+
[tool.ruff.lint.pydocstyle]
|
|
206
|
+
convention = "pep257"
|
|
207
|
+
ignore-decorators = ["typing.overload"]
|
|
208
|
+
|
|
209
|
+
[tool.ruff.lint.flake8-quotes]
|
|
210
|
+
avoid-escape = true
|
|
211
|
+
docstring-quotes = "double"
|
|
212
|
+
inline-quotes = "single"
|
|
213
|
+
multiline-quotes = "double"
|
|
214
|
+
|
|
215
|
+
[tool.ruff.format]
|
|
216
|
+
quote-style = "single"
|
|
217
|
+
indent-style = "space"
|
|
218
|
+
skip-magic-trailing-comma = false
|
|
219
|
+
line-ending = "lf"
|
|
220
|
+
docstring-code-format = true
|
|
221
|
+
docstring-code-line-length = "dynamic"
|
|
222
|
+
|
|
223
|
+
[tool.tox]
|
|
224
|
+
legacy_tox_ini = """
|
|
225
|
+
[tox]
|
|
226
|
+
envlist = py39,py310,py311,flake8,bandit,mypy,report
|
|
227
|
+
|
|
228
|
+
[gh-actions]
|
|
229
|
+
python =
|
|
230
|
+
3.9: py39
|
|
231
|
+
3.10: py310
|
|
232
|
+
3.11: py311,flake8,bandit,mypy
|
|
233
|
+
3.12: py312
|
|
234
|
+
3.13: py313
|
|
235
|
+
|
|
236
|
+
[testenv]
|
|
237
|
+
usedevelop = true
|
|
238
|
+
setenv =
|
|
239
|
+
py{39,310,311,312,313}: COVERAGE_FILE = .coverage.{envname}
|
|
240
|
+
deps =
|
|
241
|
+
-e{toxinidir}[test]
|
|
242
|
+
commands = pytest --cov --cov-report= {posargs}
|
|
243
|
+
|
|
244
|
+
[testenv:ruff]
|
|
245
|
+
basepython = python3.11
|
|
246
|
+
skip_install = true
|
|
247
|
+
deps =
|
|
248
|
+
ruff
|
|
249
|
+
commands = ruff check
|
|
250
|
+
|
|
251
|
+
[testenv:flake8]
|
|
252
|
+
basepython = python3.11
|
|
253
|
+
skip_install = true
|
|
254
|
+
deps =
|
|
255
|
+
flake8
|
|
256
|
+
flake8-type-checking
|
|
257
|
+
commands = flake8 src/ tests/
|
|
258
|
+
|
|
259
|
+
[testenv:bandit]
|
|
260
|
+
basepython = python3.11
|
|
261
|
+
skip_install = true
|
|
262
|
+
deps =
|
|
263
|
+
bandit[toml]
|
|
264
|
+
commands = bandit -q -c pyproject.toml -r src
|
|
265
|
+
|
|
266
|
+
[testenv:mypy]
|
|
267
|
+
basepython = python3.11
|
|
268
|
+
deps =
|
|
269
|
+
-e{toxinidir}[mypy]
|
|
270
|
+
commands =
|
|
271
|
+
mypy -p libres --python-version 3.9
|
|
272
|
+
mypy -p libres --python-version 3.10
|
|
273
|
+
mypy -p libres --python-version 3.11
|
|
274
|
+
mypy -p libres --python-version 3.12
|
|
275
|
+
mypy -p libres --python-version 3.13
|
|
276
|
+
|
|
277
|
+
[testenv:report]
|
|
278
|
+
deps =
|
|
279
|
+
coverage
|
|
280
|
+
skip_install = true
|
|
281
|
+
commands =
|
|
282
|
+
coverage combine
|
|
283
|
+
coverage report -m
|
|
284
|
+
|
|
285
|
+
"""
|
|
@@ -18,15 +18,15 @@ classifiers =
|
|
|
18
18
|
Operating System :: OS Independent
|
|
19
19
|
Programming Language :: Python
|
|
20
20
|
Programming Language :: Python :: 3
|
|
21
|
-
Programming Language :: Python :: 3.8
|
|
22
21
|
Programming Language :: Python :: 3.9
|
|
23
22
|
Programming Language :: Python :: 3.10
|
|
24
23
|
Programming Language :: Python :: 3.11
|
|
25
24
|
Programming Language :: Python :: 3.12
|
|
25
|
+
Programming Language :: Python :: 3.13
|
|
26
26
|
Topic :: Software Development :: Libraries :: Python Modules
|
|
27
27
|
|
|
28
28
|
[options]
|
|
29
|
-
python_requires = >= 3.
|
|
29
|
+
python_requires = >= 3.9
|
|
30
30
|
include_package_data = True
|
|
31
31
|
package_dir =
|
|
32
32
|
= src
|
|
@@ -47,10 +47,15 @@ libres =
|
|
|
47
47
|
[options.extras_require]
|
|
48
48
|
dev =
|
|
49
49
|
bandit[toml]
|
|
50
|
+
bump-my-version
|
|
50
51
|
flake8
|
|
51
|
-
flake8-
|
|
52
|
+
flake8-type-checking
|
|
52
53
|
pre-commit
|
|
54
|
+
pre-commit-uv
|
|
55
|
+
ruff
|
|
56
|
+
uv
|
|
53
57
|
tox
|
|
58
|
+
tox-uv
|
|
54
59
|
test =
|
|
55
60
|
jsonpickle
|
|
56
61
|
pytest
|
|
@@ -65,9 +70,11 @@ mypy =
|
|
|
65
70
|
typing-extensions
|
|
66
71
|
|
|
67
72
|
[flake8]
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
select = TC0,TC1
|
|
74
|
+
per_file_ignores =
|
|
75
|
+
*.pyi: TC
|
|
76
|
+
tests/**.py: TC
|
|
77
|
+
exclude = .venv,venv,.git,.tox,dist,docs,*lib/python*,*egg,build
|
|
71
78
|
|
|
72
79
|
[egg_info]
|
|
73
80
|
tag_build =
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from libres.context.registry import create_default_registry
|
|
2
4
|
from libres.db import new_scheduler
|
|
3
5
|
|
|
4
6
|
registry = create_default_registry()
|
|
5
7
|
|
|
6
|
-
__version__ = '0.
|
|
8
|
+
__version__ = '0.8.0'
|
|
7
9
|
__all__ = (
|
|
8
10
|
'new_scheduler',
|
|
9
11
|
'registry'
|
|
@@ -1,17 +1,23 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import enum
|
|
2
4
|
import libres
|
|
3
5
|
import threading
|
|
4
|
-
|
|
5
6
|
from contextlib import contextmanager
|
|
6
7
|
from functools import cached_property
|
|
7
8
|
|
|
8
9
|
from libres.modules import errors
|
|
9
10
|
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
from typing import Any
|
|
13
|
+
from typing import Literal
|
|
14
|
+
from typing import TYPE_CHECKING
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from collections.abc import Callable
|
|
17
|
+
from collections.abc import Iterator
|
|
13
18
|
from sqlalchemy.orm import Session
|
|
14
19
|
from sqlalchemy.orm.session import SessionTransaction
|
|
20
|
+
from typing_extensions import TypeAlias
|
|
15
21
|
from uuid import UUID
|
|
16
22
|
|
|
17
23
|
from libres.context.registry import Registry
|
|
@@ -24,8 +30,8 @@ class _Marker(enum.Enum):
|
|
|
24
30
|
required = enum.auto()
|
|
25
31
|
|
|
26
32
|
|
|
27
|
-
missing_t =
|
|
28
|
-
required_t =
|
|
33
|
+
missing_t: TypeAlias = Literal[_Marker.missing] # noqa: PYI042
|
|
34
|
+
required_t: TypeAlias = Literal[_Marker.required] # noqa: PYI042
|
|
29
35
|
missing: missing_t = _Marker.missing
|
|
30
36
|
required: required_t = _Marker.required
|
|
31
37
|
|
|
@@ -51,18 +57,18 @@ class ContextServicesMixin:
|
|
|
51
57
|
|
|
52
58
|
"""
|
|
53
59
|
|
|
54
|
-
context:
|
|
60
|
+
context: Context
|
|
55
61
|
|
|
56
62
|
@cached_property
|
|
57
|
-
def is_allocation_exposed(self) ->
|
|
63
|
+
def is_allocation_exposed(self) -> Callable[[Allocation], bool]:
|
|
58
64
|
return self.context.get_service('exposure').is_allocation_exposed
|
|
59
65
|
|
|
60
66
|
@cached_property
|
|
61
|
-
def generate_uuid(self) ->
|
|
67
|
+
def generate_uuid(self) -> Callable[[str], UUID]:
|
|
62
68
|
return self.context.get_service('uuid_generator')
|
|
63
69
|
|
|
64
70
|
@cached_property
|
|
65
|
-
def validate_email(self) ->
|
|
71
|
+
def validate_email(self) -> Callable[[str], bool]:
|
|
66
72
|
return self.context.get_service('email_validator')
|
|
67
73
|
|
|
68
74
|
def clear_cache(self) -> None:
|
|
@@ -84,11 +90,11 @@ class ContextServicesMixin:
|
|
|
84
90
|
pass
|
|
85
91
|
|
|
86
92
|
@property
|
|
87
|
-
def session_provider(self) ->
|
|
93
|
+
def session_provider(self) -> SessionProvider:
|
|
88
94
|
return self.context.get_service('session_provider')
|
|
89
95
|
|
|
90
96
|
@property
|
|
91
|
-
def session(self) ->
|
|
97
|
+
def session(self) -> Session:
|
|
92
98
|
""" Returns the current session. """
|
|
93
99
|
return self.session_provider.session()
|
|
94
100
|
|
|
@@ -97,7 +103,7 @@ class ContextServicesMixin:
|
|
|
97
103
|
self.session.close()
|
|
98
104
|
|
|
99
105
|
@property
|
|
100
|
-
def begin_nested(self) ->
|
|
106
|
+
def begin_nested(self) -> Callable[[], SessionTransaction]:
|
|
101
107
|
return self.session.begin_nested
|
|
102
108
|
|
|
103
109
|
def commit(self) -> None:
|
|
@@ -143,13 +149,13 @@ class Context:
|
|
|
143
149
|
def __init__(
|
|
144
150
|
self,
|
|
145
151
|
name: str,
|
|
146
|
-
registry:
|
|
147
|
-
parent:
|
|
152
|
+
registry: Registry | None = None,
|
|
153
|
+
parent: Context | None = None,
|
|
148
154
|
locked: bool = False
|
|
149
155
|
):
|
|
150
156
|
self.name = name
|
|
151
157
|
self.registry = registry or libres.registry
|
|
152
|
-
self.values:
|
|
158
|
+
self.values: dict[str, Any] = {}
|
|
153
159
|
self.parent = parent
|
|
154
160
|
self.locked = False
|
|
155
161
|
self.thread_lock = threading.RLock()
|
|
@@ -158,7 +164,7 @@ class Context:
|
|
|
158
164
|
return f"<Libres Context(name='{self.name}')>"
|
|
159
165
|
|
|
160
166
|
@contextmanager
|
|
161
|
-
def as_current_context(self) ->
|
|
167
|
+
def as_current_context(self) -> Iterator[None]:
|
|
162
168
|
with self.registry.context(self.name):
|
|
163
169
|
yield
|
|
164
170
|
|
|
@@ -173,7 +179,7 @@ class Context:
|
|
|
173
179
|
with self.thread_lock:
|
|
174
180
|
self.locked = False
|
|
175
181
|
|
|
176
|
-
def get(self, key: str) ->
|
|
182
|
+
def get(self, key: str) -> Any | missing_t:
|
|
177
183
|
if key in self.values:
|
|
178
184
|
return self.values[key]
|
|
179
185
|
elif self.parent:
|
|
@@ -181,7 +187,7 @@ class Context:
|
|
|
181
187
|
else:
|
|
182
188
|
return missing
|
|
183
189
|
|
|
184
|
-
def set(self, key: str, value:
|
|
190
|
+
def set(self, key: str, value: Any) -> None:
|
|
185
191
|
if self.locked:
|
|
186
192
|
raise errors.ContextIsLocked
|
|
187
193
|
|
|
@@ -195,21 +201,21 @@ class Context:
|
|
|
195
201
|
|
|
196
202
|
self.values[key] = value
|
|
197
203
|
|
|
198
|
-
def get_setting(self, name: str) ->
|
|
204
|
+
def get_setting(self, name: str) -> Any:
|
|
199
205
|
return self.get(f'settings.{name}')
|
|
200
206
|
|
|
201
|
-
def set_setting(self, name: str, value:
|
|
207
|
+
def set_setting(self, name: str, value: Any) -> None:
|
|
202
208
|
with self.thread_lock:
|
|
203
209
|
self.set(f'settings.{name}', value)
|
|
204
210
|
|
|
205
|
-
def get_service(self, name: str) ->
|
|
206
|
-
service_id = '/'
|
|
211
|
+
def get_service(self, name: str) -> Any:
|
|
212
|
+
service_id = f'service/{name}'
|
|
207
213
|
service = self.get(service_id)
|
|
208
214
|
|
|
209
215
|
if service is missing:
|
|
210
216
|
raise errors.UnknownService(service_id)
|
|
211
217
|
|
|
212
|
-
cache_id = '/
|
|
218
|
+
cache_id = f'service/{name}/cache'
|
|
213
219
|
cache = self.get(cache_id)
|
|
214
220
|
|
|
215
221
|
# no cache
|
|
@@ -226,13 +232,13 @@ class Context:
|
|
|
226
232
|
def set_service(
|
|
227
233
|
self,
|
|
228
234
|
name: str,
|
|
229
|
-
factory:
|
|
235
|
+
factory: Callable[..., Any],
|
|
230
236
|
cache: bool = False
|
|
231
237
|
) -> None:
|
|
232
238
|
with self.thread_lock:
|
|
233
|
-
service_id = '/'
|
|
239
|
+
service_id = f'service/{name}'
|
|
234
240
|
self.set(service_id, factory)
|
|
235
241
|
|
|
236
242
|
if cache:
|
|
237
|
-
cache_id = '/
|
|
243
|
+
cache_id = f'service/{name}/cache'
|
|
238
244
|
self.set(cache_id, required)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
from typing import Literal
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from libres.db.models import Allocation
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Exposure:
|
|
11
|
+
@staticmethod
|
|
12
|
+
def is_allocation_exposed(allocation: Allocation) -> Literal[True]:
|
|
13
|
+
return True
|