compatibility 2.1.0__tar.gz → 2.3.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.
- {compatibility-2.1.0 → compatibility-2.3.0}/PKG-INFO +16 -13
- {compatibility-2.1.0 → compatibility-2.3.0}/README.md +9 -7
- {compatibility-2.1.0 → compatibility-2.3.0}/compatibility/__init__.py +1 -1
- compatibility-2.3.0/compatibility/__main__.py +33 -0
- compatibility-2.1.0/compatibility/__main__.py → compatibility-2.3.0/compatibility/core.py +75 -19
- compatibility-2.3.0/compatibility/locales/compatibility.pot +179 -0
- compatibility-2.3.0/compatibility/locales/de/LC_MESSAGES/compatibility.mo +0 -0
- {compatibility-2.1.0 → compatibility-2.3.0}/compatibility/locales/de/LC_MESSAGES/compatibility.po +52 -32
- compatibility-2.3.0/compatibility/locales/es/LC_MESSAGES/compatibility.mo +0 -0
- {compatibility-2.1.0 → compatibility-2.3.0}/compatibility/locales/es/LC_MESSAGES/compatibility.po +52 -32
- compatibility-2.3.0/compatibility/locales/fr/LC_MESSAGES/compatibility.mo +0 -0
- {compatibility-2.1.0 → compatibility-2.3.0}/compatibility/locales/fr/LC_MESSAGES/compatibility.po +52 -32
- compatibility-2.3.0/compatibility/locales/nl/LC_MESSAGES/compatibility.mo +0 -0
- {compatibility-2.1.0 → compatibility-2.3.0}/compatibility/locales/nl/LC_MESSAGES/compatibility.po +52 -32
- {compatibility-2.1.0 → compatibility-2.3.0}/pyproject.toml +8 -7
- compatibility-2.1.0/compatibility/locales/de/LC_MESSAGES/compatibility.mo +0 -0
- compatibility-2.1.0/compatibility/locales/es/LC_MESSAGES/compatibility.mo +0 -0
- compatibility-2.1.0/compatibility/locales/fr/LC_MESSAGES/compatibility.mo +0 -0
- compatibility-2.1.0/compatibility/locales/nl/LC_MESSAGES/compatibility.mo +0 -0
- {compatibility-2.1.0 → compatibility-2.3.0}/LICENSE +0 -0
- {compatibility-2.1.0 → compatibility-2.3.0}/compatibility/err.py +0 -0
- {compatibility-2.1.0 → compatibility-2.3.0}/compatibility/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: compatibility
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: A library that checks whether the running version of Python is compatible and tested. Remind the user to check for updates of the library.
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
License-File: LICENSE
|
|
@@ -14,6 +14,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.13
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
17
18
|
Classifier: Operating System :: OS Independent
|
|
18
19
|
Classifier: Operating System :: POSIX :: Linux
|
|
19
20
|
Classifier: Operating System :: Microsoft :: Windows
|
|
@@ -26,11 +27,11 @@ Classifier: Topic :: Software Development :: Quality Assurance
|
|
|
26
27
|
Classifier: Topic :: Utilities
|
|
27
28
|
Classifier: Typing :: Typed
|
|
28
29
|
Provides-Extra: dev
|
|
29
|
-
Requires-Dist: coverage[toml] (>=7.
|
|
30
|
-
Requires-Dist: mypy (>=2.1,<3) ; extra == "dev"
|
|
31
|
-
Requires-Dist: pytest (>=9.
|
|
32
|
-
Requires-Dist: pytest-cov (>=7.1,<8) ; extra == "dev"
|
|
33
|
-
Requires-Dist: ruff (>=0.
|
|
30
|
+
Requires-Dist: coverage[toml] (>=7.16.1,<8) ; extra == "dev"
|
|
31
|
+
Requires-Dist: mypy (>=2.3.1,<3) ; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest (>=9.1.1,<10) ; extra == "dev"
|
|
33
|
+
Requires-Dist: pytest-cov (>=7.1.0,<8) ; extra == "dev"
|
|
34
|
+
Requires-Dist: ruff (>=0.16.8,<0.17) ; extra == "dev"
|
|
34
35
|
Project-URL: Bug Tracker, https://github.com/RuedigerVoigt/compatibility/issues
|
|
35
36
|
Project-URL: Changelog, https://github.com/RuedigerVoigt/compatibility/blob/main/CHANGELOG.md
|
|
36
37
|
Project-URL: Documentation, https://github.com/RuedigerVoigt/compatibility
|
|
@@ -41,7 +42,7 @@ Description-Content-Type: text/markdown
|
|
|
41
42
|

|
|
42
43
|

|
|
43
44
|

|
|
44
|
-
|
|
45
|
+

|
|
45
46
|
[](https://pepy.tech/project/compatibility)
|
|
46
47
|
|
|
47
48
|
# Python Compatibility Checker for Package Authors
|
|
@@ -96,7 +97,7 @@ All messages are available in English and German (plus AI-translated French, Dut
|
|
|
96
97
|
- **Zero Dependencies**: Pure Python stdlib - no external packages required
|
|
97
98
|
- **Type Safe**: Full type hints ([PEP 484](https://www.python.org/dev/peps/pep-0484/)) for excellent IDE integration
|
|
98
99
|
- **Well Tested**: 100% coverage (statements and branches), enforced in CI
|
|
99
|
-
- **Python 3.10+**: Supports Python 3.10 through 3.
|
|
100
|
+
- **Python 3.10+**: Supports Python 3.10 through 3.15.
|
|
100
101
|
|
|
101
102
|
## Installation
|
|
102
103
|
|
|
@@ -134,7 +135,7 @@ class MyPackage:
|
|
|
134
135
|
python_version_support={
|
|
135
136
|
'min_version': '3.10',
|
|
136
137
|
'incompatible_versions': [],
|
|
137
|
-
'max_tested_version': '3.
|
|
138
|
+
'max_tested_version': '3.15'
|
|
138
139
|
}
|
|
139
140
|
)
|
|
140
141
|
```
|
|
@@ -159,7 +160,7 @@ class MyAdvancedPackage:
|
|
|
159
160
|
python_version_support={
|
|
160
161
|
'min_version': '3.10',
|
|
161
162
|
'incompatible_versions': ['3.9'],
|
|
162
|
-
'max_tested_version': '3.
|
|
163
|
+
'max_tested_version': '3.15'
|
|
163
164
|
},
|
|
164
165
|
nag_over_update={
|
|
165
166
|
'nag_days_after_release': 90, # Start reminding after 90 days
|
|
@@ -223,7 +224,7 @@ class Salted:
|
|
|
223
224
|
python_version_support={
|
|
224
225
|
'min_version': '3.10',
|
|
225
226
|
'incompatible_versions': [],
|
|
226
|
-
'max_tested_version': '3.
|
|
227
|
+
'max_tested_version': '3.15'},
|
|
227
228
|
nag_over_update={
|
|
228
229
|
'nag_days_after_release': 30,
|
|
229
230
|
'nag_in_hundred': 50},
|
|
@@ -232,7 +233,7 @@ class Salted:
|
|
|
232
233
|
'full': {'Linux', 'MacOS', 'Windows'}
|
|
233
234
|
})
|
|
234
235
|
```
|
|
235
|
-
These settings ensure the package runs on Python 3.10 or higher, with testing confirmed through Python 3.
|
|
236
|
+
These settings ensure the package runs on Python 3.10 or higher, with testing confirmed through Python 3.15.
|
|
236
237
|
Salted in that specific version is a relatively young package that will receive frequent updates. So beginning a month after the release this will nag the user over looking for an update every second time - provided the user activated logging.
|
|
237
238
|
|
|
238
239
|
## Parameters
|
|
@@ -341,7 +342,7 @@ DEBUG:compatibility:my_package fully supports Linux.
|
|
|
341
342
|
INFO:compatibility:You are using my_package 1.0.0 (released: 2025-01-01)
|
|
342
343
|
INFO:compatibility:Your version of my_package was released 120 days ago. Please check for updates.
|
|
343
344
|
WARNING:compatibility:my_package has only partial support on Windows.
|
|
344
|
-
WARNING:compatibility:You are running Python 3.
|
|
345
|
+
WARNING:compatibility:You are running Python 3.16.final, but your version of my_package is only tested up to 3.15. Please check for updates.
|
|
345
346
|
ERROR:compatibility:This version of my_package is incompatible with Windows!
|
|
346
347
|
```
|
|
347
348
|
|
|
@@ -370,6 +371,8 @@ Each available language has one of the following quality levels:
|
|
|
370
371
|
|
|
371
372
|
The AI-translated languages are marked as such in the message catalog (`.po`) header until a native speaker has reviewed them. Corrections and reviews from native speakers are very welcome.
|
|
372
373
|
|
|
374
|
+
To add a new language, start from the template `compatibility/locales/compatibility.pot`, which lists every message.
|
|
375
|
+
|
|
373
376
|
Set `language_messages='auto'` to follow the user's environment locale (`LANGUAGE`/`LC_ALL`/`LC_MESSAGES`/`LANG`); if no matching catalog is available, messages fall back to English.
|
|
374
377
|
|
|
375
378
|
## Exceptions
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|

|
|
2
2
|

|
|
3
3
|

|
|
4
|
-
|
|
4
|
+

|
|
5
5
|
[](https://pepy.tech/project/compatibility)
|
|
6
6
|
|
|
7
7
|
# Python Compatibility Checker for Package Authors
|
|
@@ -56,7 +56,7 @@ All messages are available in English and German (plus AI-translated French, Dut
|
|
|
56
56
|
- **Zero Dependencies**: Pure Python stdlib - no external packages required
|
|
57
57
|
- **Type Safe**: Full type hints ([PEP 484](https://www.python.org/dev/peps/pep-0484/)) for excellent IDE integration
|
|
58
58
|
- **Well Tested**: 100% coverage (statements and branches), enforced in CI
|
|
59
|
-
- **Python 3.10+**: Supports Python 3.10 through 3.
|
|
59
|
+
- **Python 3.10+**: Supports Python 3.10 through 3.15.
|
|
60
60
|
|
|
61
61
|
## Installation
|
|
62
62
|
|
|
@@ -94,7 +94,7 @@ class MyPackage:
|
|
|
94
94
|
python_version_support={
|
|
95
95
|
'min_version': '3.10',
|
|
96
96
|
'incompatible_versions': [],
|
|
97
|
-
'max_tested_version': '3.
|
|
97
|
+
'max_tested_version': '3.15'
|
|
98
98
|
}
|
|
99
99
|
)
|
|
100
100
|
```
|
|
@@ -119,7 +119,7 @@ class MyAdvancedPackage:
|
|
|
119
119
|
python_version_support={
|
|
120
120
|
'min_version': '3.10',
|
|
121
121
|
'incompatible_versions': ['3.9'],
|
|
122
|
-
'max_tested_version': '3.
|
|
122
|
+
'max_tested_version': '3.15'
|
|
123
123
|
},
|
|
124
124
|
nag_over_update={
|
|
125
125
|
'nag_days_after_release': 90, # Start reminding after 90 days
|
|
@@ -183,7 +183,7 @@ class Salted:
|
|
|
183
183
|
python_version_support={
|
|
184
184
|
'min_version': '3.10',
|
|
185
185
|
'incompatible_versions': [],
|
|
186
|
-
'max_tested_version': '3.
|
|
186
|
+
'max_tested_version': '3.15'},
|
|
187
187
|
nag_over_update={
|
|
188
188
|
'nag_days_after_release': 30,
|
|
189
189
|
'nag_in_hundred': 50},
|
|
@@ -192,7 +192,7 @@ class Salted:
|
|
|
192
192
|
'full': {'Linux', 'MacOS', 'Windows'}
|
|
193
193
|
})
|
|
194
194
|
```
|
|
195
|
-
These settings ensure the package runs on Python 3.10 or higher, with testing confirmed through Python 3.
|
|
195
|
+
These settings ensure the package runs on Python 3.10 or higher, with testing confirmed through Python 3.15.
|
|
196
196
|
Salted in that specific version is a relatively young package that will receive frequent updates. So beginning a month after the release this will nag the user over looking for an update every second time - provided the user activated logging.
|
|
197
197
|
|
|
198
198
|
## Parameters
|
|
@@ -301,7 +301,7 @@ DEBUG:compatibility:my_package fully supports Linux.
|
|
|
301
301
|
INFO:compatibility:You are using my_package 1.0.0 (released: 2025-01-01)
|
|
302
302
|
INFO:compatibility:Your version of my_package was released 120 days ago. Please check for updates.
|
|
303
303
|
WARNING:compatibility:my_package has only partial support on Windows.
|
|
304
|
-
WARNING:compatibility:You are running Python 3.
|
|
304
|
+
WARNING:compatibility:You are running Python 3.16.final, but your version of my_package is only tested up to 3.15. Please check for updates.
|
|
305
305
|
ERROR:compatibility:This version of my_package is incompatible with Windows!
|
|
306
306
|
```
|
|
307
307
|
|
|
@@ -330,6 +330,8 @@ Each available language has one of the following quality levels:
|
|
|
330
330
|
|
|
331
331
|
The AI-translated languages are marked as such in the message catalog (`.po`) header until a native speaker has reviewed them. Corrections and reviews from native speakers are very welcome.
|
|
332
332
|
|
|
333
|
+
To add a new language, start from the template `compatibility/locales/compatibility.pot`, which lists every message.
|
|
334
|
+
|
|
333
335
|
Set `language_messages='auto'` to follow the user's environment locale (`LANGUAGE`/`LC_ALL`/`LC_MESSAGES`/`LANG`); if no matching catalog is available, messages fall back to English.
|
|
334
336
|
|
|
335
337
|
## Exceptions
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Entry point for `python -m compatibility` and a deprecated import alias.
|
|
3
|
+
|
|
4
|
+
The library code lives in `compatibility.core`. This module used to hold it,
|
|
5
|
+
so its public names are re-exported here to keep old imports such as
|
|
6
|
+
`from compatibility.__main__ import Check` working. Importing this module
|
|
7
|
+
emits a DeprecationWarning; import from `compatibility` instead.
|
|
8
|
+
|
|
9
|
+
Copyright (c) 2021-2026 Rüdiger Voigt and contributors
|
|
10
|
+
Released under the Apache License 2.0
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import warnings
|
|
14
|
+
|
|
15
|
+
from compatibility import NAME, __version__
|
|
16
|
+
from compatibility.core import ( # noqa: F401 (re-exported for old imports)
|
|
17
|
+
SUPPORTED_LANGUAGES,
|
|
18
|
+
Check,
|
|
19
|
+
NagOverUpdate,
|
|
20
|
+
PythonVersionSupport,
|
|
21
|
+
SystemSupport,
|
|
22
|
+
logger,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
if __name__ == '__main__':
|
|
26
|
+
print(f'{NAME} {__version__}')
|
|
27
|
+
else:
|
|
28
|
+
warnings.warn(
|
|
29
|
+
'Importing from compatibility.__main__ is deprecated and will be '
|
|
30
|
+
'removed in version 3. Import from compatibility instead '
|
|
31
|
+
'(e.g. "from compatibility import Check").',
|
|
32
|
+
DeprecationWarning,
|
|
33
|
+
stacklevel=2)
|
|
@@ -20,7 +20,7 @@ import platform
|
|
|
20
20
|
import random
|
|
21
21
|
import re
|
|
22
22
|
import sys
|
|
23
|
-
from typing import Literal,
|
|
23
|
+
from typing import Literal, TypedDict
|
|
24
24
|
|
|
25
25
|
from compatibility import err
|
|
26
26
|
|
|
@@ -54,7 +54,7 @@ class SystemSupport(TypedDict, total=False):
|
|
|
54
54
|
incompatible: set[str]
|
|
55
55
|
|
|
56
56
|
|
|
57
|
-
class Check
|
|
57
|
+
class Check:
|
|
58
58
|
"""Main Class of the compatibility package: check Python version
|
|
59
59
|
and time since release."""
|
|
60
60
|
|
|
@@ -63,14 +63,21 @@ class Check():
|
|
|
63
63
|
VERSION_REGEX = re.compile(
|
|
64
64
|
r"(?P<major>\d+)\.(?P<minor>\d+)(\.(?P<releaselevel>\b(alpha|beta|candidate|final)\b))?")
|
|
65
65
|
|
|
66
|
+
# Plausibility bounds for release_date. A date well into the future is
|
|
67
|
+
# almost always a typo (e.g. a wrong year); a very old date suggests
|
|
68
|
+
# release_date was never updated. Both only warn -- a near-future date is
|
|
69
|
+
# legitimate while developing toward a planned release.
|
|
70
|
+
FUTURE_LIMIT_DAYS = 60
|
|
71
|
+
PAST_LIMIT_YEARS = 8
|
|
72
|
+
|
|
66
73
|
def __init__(self,
|
|
67
74
|
package_name: str,
|
|
68
75
|
package_version: str,
|
|
69
|
-
release_date:
|
|
70
|
-
python_version_support:
|
|
71
|
-
nag_over_update:
|
|
76
|
+
release_date: datetime.date | str,
|
|
77
|
+
python_version_support: PythonVersionSupport | None = None,
|
|
78
|
+
nag_over_update: NagOverUpdate | None = None,
|
|
72
79
|
language_messages: str = 'en',
|
|
73
|
-
system_support:
|
|
80
|
+
system_support: SystemSupport | None = None,
|
|
74
81
|
on_incompatible: Literal['raise', 'warn', 'ignore'] = 'raise'):
|
|
75
82
|
"""Initialize compatibility checker and perform all validation checks.
|
|
76
83
|
|
|
@@ -103,6 +110,8 @@ class Check():
|
|
|
103
110
|
(log a warning and continue), or 'ignore' (continue silently).
|
|
104
111
|
|
|
105
112
|
Raises:
|
|
113
|
+
TypeError: If package_name, package_version, or
|
|
114
|
+
language_messages is not a string.
|
|
106
115
|
ValueError: If package_name or package_version is empty, if
|
|
107
116
|
language_messages or on_incompatible is invalid, or if
|
|
108
117
|
parameters are malformed.
|
|
@@ -113,6 +122,17 @@ class Check():
|
|
|
113
122
|
contradictory entries, or if min_version is higher than
|
|
114
123
|
max_tested_version.
|
|
115
124
|
"""
|
|
125
|
+
# Guard clause: .strip() below only works on strings, so reject other
|
|
126
|
+
# types with a clear error instead of a raw AttributeError. This runs
|
|
127
|
+
# before the translation is set up (which depends on
|
|
128
|
+
# language_messages), so the message is not localized.
|
|
129
|
+
for name, value in (('package_name', package_name),
|
|
130
|
+
('package_version', package_version),
|
|
131
|
+
('language_messages', language_messages)):
|
|
132
|
+
if not isinstance(value, str):
|
|
133
|
+
raise TypeError(
|
|
134
|
+
f'Parameter {name} must be a string, '
|
|
135
|
+
f'not {type(value).__name__}.')
|
|
116
136
|
self.package_name = package_name.strip()
|
|
117
137
|
self.package_version = package_version.strip()
|
|
118
138
|
self.language_messages = language_messages.strip()
|
|
@@ -134,6 +154,7 @@ class Check():
|
|
|
134
154
|
self._ = self._translation.gettext
|
|
135
155
|
self.release_date = self.__coerce_date(release_date)
|
|
136
156
|
self.check_params()
|
|
157
|
+
self.__warn_implausible_release_date()
|
|
137
158
|
self.check_python_version(python_version_support)
|
|
138
159
|
self.check_system(system_support)
|
|
139
160
|
self.log_version_info()
|
|
@@ -141,7 +162,7 @@ class Check():
|
|
|
141
162
|
self.check_version_age(nag_over_update)
|
|
142
163
|
|
|
143
164
|
def __coerce_date(
|
|
144
|
-
self, date_to_coerce:
|
|
165
|
+
self, date_to_coerce: str | datetime.date) -> datetime.date:
|
|
145
166
|
"""Convert a string to datetime.date and validate.
|
|
146
167
|
|
|
147
168
|
Accepts either a datetime.date object (returned as-is) or a string
|
|
@@ -172,6 +193,25 @@ class Check():
|
|
|
172
193
|
raise err.BadDateType(
|
|
173
194
|
self._('date_to_coerce must be either string or datetime.date'))
|
|
174
195
|
|
|
196
|
+
def __warn_implausible_release_date(self) -> None:
|
|
197
|
+
"""Warn (never raise) if release_date is implausibly far off.
|
|
198
|
+
|
|
199
|
+
A date more than ``FUTURE_LIMIT_DAYS`` ahead is almost always a typo
|
|
200
|
+
(e.g. a wrong year), and a date more than ``PAST_LIMIT_YEARS`` old
|
|
201
|
+
suggests release_date was not updated. Neither is fatal: a near-future
|
|
202
|
+
date is legitimate while developing toward a planned release, so both
|
|
203
|
+
cases only log a warning and leave the date usable.
|
|
204
|
+
"""
|
|
205
|
+
days_from_today = (self.release_date - datetime.date.today()).days
|
|
206
|
+
if days_from_today > self.FUTURE_LIMIT_DAYS:
|
|
207
|
+
logger.warning(
|
|
208
|
+
self._("The release_date %s is more than %s days in the future. Please check it is correct."),
|
|
209
|
+
self.release_date, self.FUTURE_LIMIT_DAYS)
|
|
210
|
+
elif days_from_today < -(self.PAST_LIMIT_YEARS * 365):
|
|
211
|
+
logger.warning(
|
|
212
|
+
self._("The release_date %s is more than %s years in the past. Please check it is correct."),
|
|
213
|
+
self.release_date, self.PAST_LIMIT_YEARS)
|
|
214
|
+
|
|
175
215
|
def check_params(self) -> None:
|
|
176
216
|
"""Validate that required parameters are non-empty and valid.
|
|
177
217
|
|
|
@@ -199,7 +239,7 @@ class Check():
|
|
|
199
239
|
raise ValueError(self._('Invalid value for on_incompatible!'))
|
|
200
240
|
|
|
201
241
|
def check_python_version(self,
|
|
202
|
-
python_version_support:
|
|
242
|
+
python_version_support: PythonVersionSupport | None = None
|
|
203
243
|
) -> None:
|
|
204
244
|
"""Validate that the running Python version is supported.
|
|
205
245
|
|
|
@@ -213,8 +253,8 @@ class Check():
|
|
|
213
253
|
no version checking is performed.
|
|
214
254
|
|
|
215
255
|
Raises:
|
|
216
|
-
ValueError: If python_version_support dict is malformed
|
|
217
|
-
contains invalid version strings.
|
|
256
|
+
ValueError: If python_version_support is not a dict, is malformed,
|
|
257
|
+
or contains invalid version strings.
|
|
218
258
|
err.ParameterContradiction: If 'min_version' is higher than
|
|
219
259
|
'max_tested_version'.
|
|
220
260
|
RuntimeError: If running Python version is below minimum or is
|
|
@@ -224,6 +264,9 @@ class Check():
|
|
|
224
264
|
if not python_version_support:
|
|
225
265
|
# Setting python_version_support is not required
|
|
226
266
|
return None
|
|
267
|
+
if not isinstance(python_version_support, dict):
|
|
268
|
+
raise ValueError(
|
|
269
|
+
self._('Parameter python_version_support must be a dictionary'))
|
|
227
270
|
|
|
228
271
|
min_version, max_version = self.__validate_python_version_support(
|
|
229
272
|
python_version_support)
|
|
@@ -256,7 +299,8 @@ class Check():
|
|
|
256
299
|
re-parse (and assert-guard) the strings in the comparison helpers.
|
|
257
300
|
|
|
258
301
|
Raises:
|
|
259
|
-
ValueError: If the dict has the wrong keys,
|
|
302
|
+
ValueError: If the dict has the wrong keys, if
|
|
303
|
+
'incompatible_versions' is not a list, or any of the version
|
|
260
304
|
strings ('min_version', 'max_tested_version', or any entry of
|
|
261
305
|
'incompatible_versions') cannot be parsed.
|
|
262
306
|
err.ParameterContradiction: If 'min_version' is higher than
|
|
@@ -287,6 +331,12 @@ class Check():
|
|
|
287
331
|
python_version_support['max_tested_version'])
|
|
288
332
|
if not max_match:
|
|
289
333
|
raise ValueError(self._('Value for key max_tested_version incorrect.'))
|
|
334
|
+
# A bare string here would otherwise be iterated character by character
|
|
335
|
+
# (yielding a misleading "cannot be parsed" error), and an empty string
|
|
336
|
+
# would pass silently. Require an actual list.
|
|
337
|
+
if not isinstance(python_version_support['incompatible_versions'], list):
|
|
338
|
+
raise ValueError(
|
|
339
|
+
self._('Value for key incompatible_versions must be a list.'))
|
|
290
340
|
for version_string in python_version_support['incompatible_versions']:
|
|
291
341
|
if not re.fullmatch(self.VERSION_REGEX, version_string):
|
|
292
342
|
raise ValueError(
|
|
@@ -368,7 +418,7 @@ class Check():
|
|
|
368
418
|
)
|
|
369
419
|
|
|
370
420
|
def check_system(self,
|
|
371
|
-
system_support:
|
|
421
|
+
system_support: SystemSupport | None) -> None:
|
|
372
422
|
"""Validate operating system compatibility.
|
|
373
423
|
|
|
374
424
|
Checks whether the current OS (Linux, MacOS, or Windows) is fully
|
|
@@ -527,10 +577,13 @@ class Check():
|
|
|
527
577
|
(int 0-100, percentage chance of showing nag message).
|
|
528
578
|
|
|
529
579
|
Raises:
|
|
530
|
-
ValueError: If
|
|
531
|
-
nag_days_after_release is negative, or
|
|
532
|
-
not between 0 and 100.
|
|
580
|
+
ValueError: If nag_over_update is not a dict, a key is missing, a
|
|
581
|
+
value is not an int, nag_days_after_release is negative, or
|
|
582
|
+
nag_in_hundred is not between 0 and 100.
|
|
533
583
|
"""
|
|
584
|
+
if not isinstance(nag_over_update, dict):
|
|
585
|
+
raise ValueError(
|
|
586
|
+
self._('Parameter nag_over_update must be a dictionary'))
|
|
534
587
|
nag_days_after_release, nag_in_hundred = self.__validate_nag_over_update(
|
|
535
588
|
nag_over_update)
|
|
536
589
|
if nag_in_hundred == 0:
|
|
@@ -557,8 +610,8 @@ class Check():
|
|
|
557
610
|
A tuple of (nag_days_after_release, nag_in_hundred).
|
|
558
611
|
|
|
559
612
|
Raises:
|
|
560
|
-
ValueError: If a key is missing, if a value is not an int (
|
|
561
|
-
and strings are rejected rather than coerced), if
|
|
613
|
+
ValueError: If a key is missing, if a value is not an int (bool,
|
|
614
|
+
floats, and strings are rejected rather than coerced), if
|
|
562
615
|
nag_days_after_release is negative, or if nag_in_hundred is
|
|
563
616
|
not between 0 and 100.
|
|
564
617
|
"""
|
|
@@ -568,8 +621,11 @@ class Check():
|
|
|
568
621
|
nag_days_after_release = nag_over_update['nag_days_after_release']
|
|
569
622
|
nag_in_hundred = nag_over_update['nag_in_hundred']
|
|
570
623
|
# Reject non-int values explicitly: int() would silently truncate a
|
|
571
|
-
# float (3.7 -> 3) or accept a numeric string.
|
|
572
|
-
|
|
624
|
+
# float (3.7 -> 3) or accept a numeric string. bool is checked first
|
|
625
|
+
# because it is a subclass of int (True would otherwise pass as 1).
|
|
626
|
+
if (isinstance(nag_days_after_release, bool)
|
|
627
|
+
or isinstance(nag_in_hundred, bool)
|
|
628
|
+
or not isinstance(nag_days_after_release, int)
|
|
573
629
|
or not isinstance(nag_in_hundred, int)):
|
|
574
630
|
raise ValueError(self._('Some key in nag_over_update has wrong type!'))
|
|
575
631
|
if nag_days_after_release < 0:
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# Translation template for the compatibility package.
|
|
2
|
+
# Copyright (c) 2021-2026 Rüdiger Voigt and contributors
|
|
3
|
+
# This file is distributed under the same license as the compatibility package.
|
|
4
|
+
# Generated by `python compile_translations.py --extract`. Do not edit by hand.
|
|
5
|
+
#
|
|
6
|
+
#, fuzzy
|
|
7
|
+
msgid ""
|
|
8
|
+
msgstr ""
|
|
9
|
+
"Project-Id-Version: compatibility\n"
|
|
10
|
+
"Report-Msgid-Bugs-To: \n"
|
|
11
|
+
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
12
|
+
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
13
|
+
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
14
|
+
"Language: \n"
|
|
15
|
+
"MIME-Version: 1.0\n"
|
|
16
|
+
"Content-Type: text/plain; charset=UTF-8\n"
|
|
17
|
+
"Content-Transfer-Encoding: 8bit\n"
|
|
18
|
+
|
|
19
|
+
#: compatibility/core.py:191
|
|
20
|
+
msgid "Non-existing or incomplete date!"
|
|
21
|
+
msgstr ""
|
|
22
|
+
|
|
23
|
+
#: compatibility/core.py:194
|
|
24
|
+
msgid "date_to_coerce must be either string or datetime.date"
|
|
25
|
+
msgstr ""
|
|
26
|
+
|
|
27
|
+
#: compatibility/core.py:208
|
|
28
|
+
#, python-format
|
|
29
|
+
msgid "The release_date %s is more than %s days in the future. Please check it is correct."
|
|
30
|
+
msgstr ""
|
|
31
|
+
|
|
32
|
+
#: compatibility/core.py:212
|
|
33
|
+
#, python-format
|
|
34
|
+
msgid "The release_date %s is more than %s years in the past. Please check it is correct."
|
|
35
|
+
msgstr ""
|
|
36
|
+
|
|
37
|
+
#: compatibility/core.py:229
|
|
38
|
+
msgid "Missing package name!"
|
|
39
|
+
msgstr ""
|
|
40
|
+
|
|
41
|
+
#: compatibility/core.py:231
|
|
42
|
+
msgid "Missing package version!"
|
|
43
|
+
msgstr ""
|
|
44
|
+
|
|
45
|
+
#: compatibility/core.py:236
|
|
46
|
+
msgid "Invalid value for language_messages!"
|
|
47
|
+
msgstr ""
|
|
48
|
+
|
|
49
|
+
#: compatibility/core.py:239
|
|
50
|
+
msgid "Invalid value for on_incompatible!"
|
|
51
|
+
msgstr ""
|
|
52
|
+
|
|
53
|
+
#: compatibility/core.py:269
|
|
54
|
+
msgid "Parameter python_version_support must be a dictionary"
|
|
55
|
+
msgstr ""
|
|
56
|
+
|
|
57
|
+
#: compatibility/core.py:311
|
|
58
|
+
msgid "Parameter python_version_support incomplete!"
|
|
59
|
+
msgstr ""
|
|
60
|
+
|
|
61
|
+
#: compatibility/core.py:314
|
|
62
|
+
msgid "Parameter python_version_support: too many keys!"
|
|
63
|
+
msgstr ""
|
|
64
|
+
|
|
65
|
+
#: compatibility/core.py:322
|
|
66
|
+
msgid "Parameter python_version_support contains unknown keys."
|
|
67
|
+
msgstr ""
|
|
68
|
+
|
|
69
|
+
#: compatibility/core.py:329
|
|
70
|
+
msgid "Value for key min_version is incorrect."
|
|
71
|
+
msgstr ""
|
|
72
|
+
|
|
73
|
+
#: compatibility/core.py:333
|
|
74
|
+
msgid "Value for key max_tested_version incorrect."
|
|
75
|
+
msgstr ""
|
|
76
|
+
|
|
77
|
+
#: compatibility/core.py:339
|
|
78
|
+
msgid "Value for key incompatible_versions must be a list."
|
|
79
|
+
msgstr ""
|
|
80
|
+
|
|
81
|
+
#: compatibility/core.py:343
|
|
82
|
+
msgid "Some string in incompatible_versions cannot be parsed."
|
|
83
|
+
msgstr ""
|
|
84
|
+
|
|
85
|
+
#: compatibility/core.py:351
|
|
86
|
+
#, python-format
|
|
87
|
+
msgid "min_version (%(min)s) is higher than max_tested_version (%(max)s)."
|
|
88
|
+
msgstr ""
|
|
89
|
+
|
|
90
|
+
#: compatibility/core.py:382
|
|
91
|
+
#, python-format
|
|
92
|
+
msgid "You use %(running)s, but need at least %(required)s to run %(package)s."
|
|
93
|
+
msgstr ""
|
|
94
|
+
|
|
95
|
+
#: compatibility/core.py:391
|
|
96
|
+
#, python-format
|
|
97
|
+
msgid "Your version of Python is not compatible with this version of %(package)s. Please check for updates."
|
|
98
|
+
msgstr ""
|
|
99
|
+
|
|
100
|
+
#: compatibility/core.py:414
|
|
101
|
+
#, python-format
|
|
102
|
+
msgid "You are running Python %s, but your version of %s is only tested up to %s. Please check for updates."
|
|
103
|
+
msgstr ""
|
|
104
|
+
|
|
105
|
+
#: compatibility/core.py:444
|
|
106
|
+
msgid "Parameter system_support must be a dictionary"
|
|
107
|
+
msgstr ""
|
|
108
|
+
|
|
109
|
+
#: compatibility/core.py:471
|
|
110
|
+
msgid "Unknown key in dictionary system_support"
|
|
111
|
+
msgstr ""
|
|
112
|
+
|
|
113
|
+
#: compatibility/core.py:473
|
|
114
|
+
#, python-format
|
|
115
|
+
msgid "Use a set to hold values for %s."
|
|
116
|
+
msgstr ""
|
|
117
|
+
|
|
118
|
+
#: compatibility/core.py:477
|
|
119
|
+
#, python-format
|
|
120
|
+
msgid "Invalid system in %s. Allowed: %s"
|
|
121
|
+
msgstr ""
|
|
122
|
+
|
|
123
|
+
#: compatibility/core.py:494
|
|
124
|
+
msgid "Contradiction: System cannot simultaneously be fully AND only partially supported."
|
|
125
|
+
msgstr ""
|
|
126
|
+
|
|
127
|
+
#: compatibility/core.py:500
|
|
128
|
+
msgid "Contradiction: System cannot have full support AND be incompatible!"
|
|
129
|
+
msgstr ""
|
|
130
|
+
|
|
131
|
+
#: compatibility/core.py:516
|
|
132
|
+
#, python-format
|
|
133
|
+
msgid "%s fully supports %s."
|
|
134
|
+
msgstr ""
|
|
135
|
+
|
|
136
|
+
#: compatibility/core.py:520
|
|
137
|
+
#, python-format
|
|
138
|
+
msgid "%s has only partial support on %s."
|
|
139
|
+
msgstr ""
|
|
140
|
+
|
|
141
|
+
#: compatibility/core.py:525
|
|
142
|
+
#, python-format
|
|
143
|
+
msgid "This version of %s is incompatible with %s!"
|
|
144
|
+
msgstr ""
|
|
145
|
+
|
|
146
|
+
#: compatibility/core.py:530
|
|
147
|
+
#, python-format
|
|
148
|
+
msgid "%s's support for %s is unknown!"
|
|
149
|
+
msgstr ""
|
|
150
|
+
|
|
151
|
+
#: compatibility/core.py:561
|
|
152
|
+
#, python-format
|
|
153
|
+
msgid "You are using %(package)s %(version)s (released: %(date)s)"
|
|
154
|
+
msgstr ""
|
|
155
|
+
|
|
156
|
+
#: compatibility/core.py:586
|
|
157
|
+
msgid "Parameter nag_over_update must be a dictionary"
|
|
158
|
+
msgstr ""
|
|
159
|
+
|
|
160
|
+
#: compatibility/core.py:597
|
|
161
|
+
#, python-format
|
|
162
|
+
msgid "Your version of %s was released %s days ago. Please check for updates."
|
|
163
|
+
msgstr ""
|
|
164
|
+
|
|
165
|
+
#: compatibility/core.py:620
|
|
166
|
+
msgid "A key in nag_over_update is missing."
|
|
167
|
+
msgstr ""
|
|
168
|
+
|
|
169
|
+
#: compatibility/core.py:630
|
|
170
|
+
msgid "Some key in nag_over_update has wrong type!"
|
|
171
|
+
msgstr ""
|
|
172
|
+
|
|
173
|
+
#: compatibility/core.py:632
|
|
174
|
+
msgid "nag_days_after_release must not be negative."
|
|
175
|
+
msgstr ""
|
|
176
|
+
|
|
177
|
+
#: compatibility/core.py:634
|
|
178
|
+
msgid "nag_in_hundred must be int between 0 and 100."
|
|
179
|
+
msgstr ""
|