compatibility 2.3.0__tar.gz → 2.4.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.3.0 → compatibility-2.4.0}/PKG-INFO +175 -20
- {compatibility-2.3.0 → compatibility-2.4.0}/README.md +169 -14
- {compatibility-2.3.0 → compatibility-2.4.0}/compatibility/core.py +152 -52
- {compatibility-2.3.0 → compatibility-2.4.0}/compatibility/locales/compatibility.pot +55 -37
- compatibility-2.4.0/compatibility/locales/de/LC_MESSAGES/compatibility.mo +0 -0
- {compatibility-2.3.0 → compatibility-2.4.0}/compatibility/locales/de/LC_MESSAGES/compatibility.po +13 -0
- compatibility-2.4.0/compatibility/locales/es/LC_MESSAGES/compatibility.mo +0 -0
- {compatibility-2.3.0 → compatibility-2.4.0}/compatibility/locales/es/LC_MESSAGES/compatibility.po +13 -0
- compatibility-2.4.0/compatibility/locales/fr/LC_MESSAGES/compatibility.mo +0 -0
- {compatibility-2.3.0 → compatibility-2.4.0}/compatibility/locales/fr/LC_MESSAGES/compatibility.po +13 -0
- compatibility-2.4.0/compatibility/locales/nl/LC_MESSAGES/compatibility.mo +0 -0
- {compatibility-2.3.0 → compatibility-2.4.0}/compatibility/locales/nl/LC_MESSAGES/compatibility.po +13 -0
- {compatibility-2.3.0 → compatibility-2.4.0}/pyproject.toml +7 -9
- compatibility-2.3.0/compatibility/locales/de/LC_MESSAGES/compatibility.mo +0 -0
- compatibility-2.3.0/compatibility/locales/es/LC_MESSAGES/compatibility.mo +0 -0
- compatibility-2.3.0/compatibility/locales/fr/LC_MESSAGES/compatibility.mo +0 -0
- compatibility-2.3.0/compatibility/locales/nl/LC_MESSAGES/compatibility.mo +0 -0
- {compatibility-2.3.0 → compatibility-2.4.0}/LICENSE +0 -0
- {compatibility-2.3.0 → compatibility-2.4.0}/compatibility/__init__.py +0 -0
- {compatibility-2.3.0 → compatibility-2.4.0}/compatibility/__main__.py +0 -0
- {compatibility-2.3.0 → compatibility-2.4.0}/compatibility/err.py +0 -0
- {compatibility-2.3.0 → compatibility-2.4.0}/compatibility/py.typed +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: compatibility
|
|
3
|
-
Version: 2.
|
|
4
|
-
Summary: A library that checks whether the running version of Python is compatible and tested.
|
|
3
|
+
Version: 2.4.0
|
|
4
|
+
Summary: A library that checks whether the running version of Python is compatible and tested. Can remind the user to check for updates of the library.
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Keywords: compatibility,version-check,python-version,cross-platform,update-notifier
|
|
@@ -27,11 +27,11 @@ Classifier: Topic :: Software Development :: Quality Assurance
|
|
|
27
27
|
Classifier: Topic :: Utilities
|
|
28
28
|
Classifier: Typing :: Typed
|
|
29
29
|
Provides-Extra: dev
|
|
30
|
-
Requires-Dist: coverage[toml] (>=7.16.
|
|
31
|
-
Requires-Dist: mypy (>=2.
|
|
32
|
-
Requires-Dist: pytest (>=9.
|
|
30
|
+
Requires-Dist: coverage[toml] (>=7.16.2,<8) ; extra == "dev"
|
|
31
|
+
Requires-Dist: mypy (>=2.4.0,<3) ; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest (>=9.2.0,<10) ; extra == "dev"
|
|
33
33
|
Requires-Dist: pytest-cov (>=7.1.0,<8) ; extra == "dev"
|
|
34
|
-
Requires-Dist: ruff (>=0.
|
|
34
|
+
Requires-Dist: ruff (>=0.17.3,<0.18) ; extra == "dev"
|
|
35
35
|
Project-URL: Bug Tracker, https://github.com/RuedigerVoigt/compatibility/issues
|
|
36
36
|
Project-URL: Changelog, https://github.com/RuedigerVoigt/compatibility/blob/main/CHANGELOG.md
|
|
37
37
|
Project-URL: Documentation, https://github.com/RuedigerVoigt/compatibility
|
|
@@ -51,11 +51,11 @@ Description-Content-Type: text/markdown
|
|
|
51
51
|
|
|
52
52
|
Ensure your Python package runs on the right versions, warn users about untested versions, and gracefully handle incompatible environments.
|
|
53
53
|
|
|
54
|
-
Compatibility is a lightweight, zero-dependency library that helps Python package authors and library developers provide a better user experience by checking Python version compatibility, operating system compatibility (Linux, macOS, Windows), and gently reminding users to update. Uses Python's standard `gettext` for translations and follows PEP 561 (typed package). Perfect for PyPI package maintainers who want to
|
|
54
|
+
Compatibility is a lightweight, zero-dependency library that helps Python package authors and library developers provide a better user experience by checking Python version compatibility, operating system compatibility (Linux, macOS, Windows), and gently reminding users to update. Uses Python's standard `gettext` for translations and follows PEP 561 (typed package). Perfect for PyPI package maintainers who want to replace cryptic errors with helpful guidance to users.
|
|
55
55
|
|
|
56
56
|
## Why Use This Library?
|
|
57
57
|
|
|
58
|
-
- **
|
|
58
|
+
- **Clear messages instead of cryptic errors** - Tell users when they run your package on an incompatible Python version
|
|
59
59
|
- **Zero dependencies** - Uses only Python's standard library
|
|
60
60
|
- **Fully typed** - Complete type hints (PEP 484) for better IDE support
|
|
61
61
|
- **Multilingual** - Built-in English and German messages, plus AI-translated French, Dutch, and Spanish
|
|
@@ -67,12 +67,17 @@ Compatibility is a lightweight, zero-dependency library that helps Python packag
|
|
|
67
67
|
## Table of Contents
|
|
68
68
|
|
|
69
69
|
- [What It Does](#what-it-does)
|
|
70
|
+
- [What It Does Not Do](#what-it-does-not-do)
|
|
70
71
|
- [Key Features](#key-features)
|
|
71
72
|
- [Installation](#installation)
|
|
72
73
|
- [Quick Start](#quick-start)
|
|
73
74
|
- [Detailed Usage](#detailed-usage)
|
|
74
75
|
- [⚠️ Important: Where to Call Compatibility](#️-important-where-to-call-compatibility)
|
|
75
76
|
- [Complete Example](#complete-example)
|
|
77
|
+
- [Recipes](#recipes)
|
|
78
|
+
- [Command-Line Tool: Configure Logging First](#command-line-tool-configure-logging-first)
|
|
79
|
+
- [Warn Instead of Raising](#warn-instead-of-raising)
|
|
80
|
+
- [Typed Configuration](#typed-configuration)
|
|
76
81
|
- [Parameters](#parameters)
|
|
77
82
|
- [Required Parameters](#required-parameters)
|
|
78
83
|
- [Optional Parameters](#optional-parameters)
|
|
@@ -86,12 +91,21 @@ Compatibility is a lightweight, zero-dependency library that helps Python packag
|
|
|
86
91
|
|
|
87
92
|
1. **Python Version Validation** - Check if the running Python interpreter meets minimum requirements and isn't in your list of incompatible versions. Raises `RuntimeError` for incompatible versions.
|
|
88
93
|
2. **Untested Version Warnings** - Warn users when running your package on Python versions newer than you've tested.
|
|
89
|
-
3. **
|
|
90
|
-
4. **
|
|
91
|
-
5. **
|
|
94
|
+
3. **End-of-Life Warnings** - Optionally warn users whose Python version has reached its end of life and no longer receives security updates (built-in dates, no network access).
|
|
95
|
+
4. **Package Version Logging** - Log package name, version, and release date for better debugging.
|
|
96
|
+
5. **Privacy-Friendly Update Reminders** - Optionally remind users to check for updates after N days (without phoning home or checking if updates exist).
|
|
97
|
+
6. **Operating System Compatibility** - Validate whether the OS (Linux, macOS, Windows) is fully supported, partially supported, or incompatible.
|
|
92
98
|
|
|
93
99
|
All messages are available in English and German (plus AI-translated French, Dutch, and Spanish), selectable per-instance. See [Translations](#translations).
|
|
94
100
|
|
|
101
|
+
## What It Does Not Do
|
|
102
|
+
|
|
103
|
+
- **No update lookup** - The update reminder only counts the days since your release date. It never contacts PyPI or any other server, so it cannot tell whether a newer version exists.
|
|
104
|
+
- **No dependency checks** - It checks the Python interpreter and the operating system, not the versions of other installed packages. Declare those as dependencies in your `pyproject.toml`, so `pip` resolves them.
|
|
105
|
+
- **No patch versions** - Python versions are matched on major and minor version, optionally with the release level (like `'3.12'` or `'3.12.beta'`). You cannot target a single patch release such as 3.12.1.
|
|
106
|
+
- **No OS versions or distributions** - Operating systems are only distinguished as Linux, MacOS, and Windows.
|
|
107
|
+
- **No protection before your code is imported** - The check runs in your constructor. An error while Python imports your modules comes first (see [Avoid running your package with an incompatible version of Python](#avoid-running-your-package-with-an-incompatible-version-of-python)).
|
|
108
|
+
|
|
95
109
|
## Key Features
|
|
96
110
|
|
|
97
111
|
- **Zero Dependencies**: Pure Python stdlib - no external packages required
|
|
@@ -118,6 +132,7 @@ logging.basicConfig(level=logging.INFO)
|
|
|
118
132
|
|
|
119
133
|
Here's a minimal example to get started:
|
|
120
134
|
|
|
135
|
+
<!-- tested -->
|
|
121
136
|
```python
|
|
122
137
|
from datetime import date
|
|
123
138
|
import logging
|
|
@@ -138,12 +153,21 @@ class MyPackage:
|
|
|
138
153
|
'max_tested_version': '3.15'
|
|
139
154
|
}
|
|
140
155
|
)
|
|
156
|
+
|
|
157
|
+
MyPackage() # The check runs when the class is instantiated
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Output:
|
|
161
|
+
|
|
162
|
+
```text
|
|
163
|
+
INFO:compatibility:You are using my_package 1.0.0 (released: 2025-01-01)
|
|
141
164
|
```
|
|
142
165
|
|
|
143
166
|
### Extended Example
|
|
144
167
|
|
|
145
168
|
Here's a more complete example using all optional features:
|
|
146
169
|
|
|
170
|
+
<!-- tested -->
|
|
147
171
|
```python
|
|
148
172
|
from datetime import date
|
|
149
173
|
import logging
|
|
@@ -159,7 +183,7 @@ class MyAdvancedPackage:
|
|
|
159
183
|
release_date=date(2025, 1, 15),
|
|
160
184
|
python_version_support={
|
|
161
185
|
'min_version': '3.10',
|
|
162
|
-
'incompatible_versions': ['3.
|
|
186
|
+
'incompatible_versions': ['3.13.alpha'], # e.g. a pre-release with a known bug
|
|
163
187
|
'max_tested_version': '3.15'
|
|
164
188
|
},
|
|
165
189
|
nag_over_update={
|
|
@@ -171,8 +195,11 @@ class MyAdvancedPackage:
|
|
|
171
195
|
'full': {'Linux', 'MacOS'}, # Fully tested
|
|
172
196
|
'partial': {'Windows'}, # Should work, less tested
|
|
173
197
|
'incompatible': set() # No known incompatibilities
|
|
174
|
-
}
|
|
198
|
+
},
|
|
199
|
+
warn_eol=True # Warn if the running Python has reached its end of life
|
|
175
200
|
)
|
|
201
|
+
|
|
202
|
+
MyAdvancedPackage()
|
|
176
203
|
```
|
|
177
204
|
|
|
178
205
|
## Detailed Usage
|
|
@@ -192,7 +219,7 @@ class MyClass:
|
|
|
192
219
|
compatibility.Check(...) # Runs when instantiated, after logging is configured
|
|
193
220
|
```
|
|
194
221
|
|
|
195
|
-
**Why?** If you call it in `__init__.py`, it runs immediately on import before
|
|
222
|
+
**Why?** If you call it in `__init__.py`, it runs immediately on import, usually before the application has configured logging. Its messages are then lost: the `compatibility` logger has no handler of its own, so nothing is shown until logging is set up. Calling it in the class constructor lets users set up logging first. It also keeps your package importable on an incompatible system (for example for documentation tools), as the `RuntimeError` is only raised when your class is used.
|
|
196
223
|
|
|
197
224
|
### Complete Example
|
|
198
225
|
|
|
@@ -236,16 +263,132 @@ class Salted:
|
|
|
236
263
|
These settings ensure the package runs on Python 3.10 or higher, with testing confirmed through Python 3.15.
|
|
237
264
|
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.
|
|
238
265
|
|
|
266
|
+
## Recipes
|
|
267
|
+
|
|
268
|
+
The test suite runs every example in this section, as well as the Quick Start and the Extended Example.
|
|
269
|
+
|
|
270
|
+
### Command-Line Tool: Configure Logging First
|
|
271
|
+
|
|
272
|
+
In a command-line tool, configure logging first and create the class that runs the check afterwards. Otherwise the messages are lost:
|
|
273
|
+
|
|
274
|
+
<!-- tested -->
|
|
275
|
+
```python
|
|
276
|
+
import argparse
|
|
277
|
+
from datetime import date
|
|
278
|
+
import logging
|
|
279
|
+
|
|
280
|
+
import compatibility
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
class MyTool:
|
|
284
|
+
def __init__(self):
|
|
285
|
+
compatibility.Check(
|
|
286
|
+
package_name='my_tool',
|
|
287
|
+
package_version='1.0.0',
|
|
288
|
+
release_date=date(2025, 1, 1))
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def main(argv=None):
|
|
292
|
+
parser = argparse.ArgumentParser(prog='my_tool')
|
|
293
|
+
parser.add_argument('--verbose', action='store_true')
|
|
294
|
+
args = parser.parse_args(argv)
|
|
295
|
+
# Configure logging before anything creates MyTool:
|
|
296
|
+
logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO)
|
|
297
|
+
MyTool()
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
if __name__ == '__main__':
|
|
301
|
+
main()
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Output:
|
|
305
|
+
|
|
306
|
+
```text
|
|
307
|
+
INFO:compatibility:You are using my_tool 1.0.0 (released: 2025-01-01)
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Warn Instead of Raising
|
|
311
|
+
|
|
312
|
+
By default an incompatible Python version or operating system raises `RuntimeError`. With `on_incompatible='warn'` it only logs a warning, and your package keeps running. Use this if your users should decide whether to continue:
|
|
313
|
+
|
|
314
|
+
<!-- tested -->
|
|
315
|
+
```python
|
|
316
|
+
from datetime import date
|
|
317
|
+
import logging
|
|
318
|
+
|
|
319
|
+
import compatibility
|
|
320
|
+
|
|
321
|
+
logging.basicConfig(level=logging.INFO)
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
class MyPackage:
|
|
325
|
+
def __init__(self):
|
|
326
|
+
compatibility.Check(
|
|
327
|
+
package_name='my_package',
|
|
328
|
+
package_version='1.0.0',
|
|
329
|
+
release_date=date(2025, 1, 1),
|
|
330
|
+
python_version_support={
|
|
331
|
+
'min_version': '3.10',
|
|
332
|
+
'incompatible_versions': [],
|
|
333
|
+
'max_tested_version': '3.15'},
|
|
334
|
+
system_support={'full': {'Linux', 'MacOS', 'Windows'}},
|
|
335
|
+
on_incompatible='warn')
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
MyPackage()
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
With `on_incompatible='ignore'` the message is only logged at DEBUG level.
|
|
342
|
+
|
|
343
|
+
### Typed Configuration
|
|
344
|
+
|
|
345
|
+
The parameter dictionaries have matching `TypedDict` types: `PythonVersionSupport`, `SystemSupport`, and `NagOverUpdate`. Annotate your configuration with them, and a type checker such as mypy reports a misspelled or missing key before your code runs:
|
|
346
|
+
|
|
347
|
+
<!-- tested -->
|
|
348
|
+
```python
|
|
349
|
+
from datetime import date
|
|
350
|
+
import logging
|
|
351
|
+
|
|
352
|
+
import compatibility
|
|
353
|
+
from compatibility import NagOverUpdate, PythonVersionSupport, SystemSupport
|
|
354
|
+
|
|
355
|
+
logging.basicConfig(level=logging.INFO)
|
|
356
|
+
|
|
357
|
+
PYTHON_SUPPORT: PythonVersionSupport = {
|
|
358
|
+
'min_version': '3.10',
|
|
359
|
+
'incompatible_versions': [],
|
|
360
|
+
'max_tested_version': '3.15',
|
|
361
|
+
}
|
|
362
|
+
SYSTEM_SUPPORT: SystemSupport = {'full': {'Linux', 'MacOS', 'Windows'}}
|
|
363
|
+
NAG: NagOverUpdate = {'nag_days_after_release': 90, 'nag_in_hundred': 25}
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
class MyPackage:
|
|
367
|
+
def __init__(self) -> None:
|
|
368
|
+
compatibility.Check(
|
|
369
|
+
package_name='my_package',
|
|
370
|
+
package_version='1.0.0',
|
|
371
|
+
release_date=date(2025, 1, 1),
|
|
372
|
+
python_version_support=PYTHON_SUPPORT,
|
|
373
|
+
system_support=SYSTEM_SUPPORT,
|
|
374
|
+
nag_over_update=NAG)
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
MyPackage()
|
|
378
|
+
```
|
|
379
|
+
|
|
239
380
|
## Parameters
|
|
240
381
|
|
|
241
382
|
### Required Parameters
|
|
242
383
|
|
|
243
384
|
* `package_name`: the name of your package.
|
|
244
385
|
* `package_version`: the version number of your package as a string.
|
|
245
|
-
* `release_date`:
|
|
386
|
+
* `release_date`: a `datetime.date` (like `date(2021, 1, 1)`), or a string in the format `YYYY-MM-DD` (like `'2021-01-01'`; leading zeros are optional). A `datetime.datetime` is accepted too; its time is ignored.
|
|
246
387
|
|
|
247
388
|
### Optional Parameters
|
|
248
389
|
|
|
390
|
+
For `python_version_support`, `nag_over_update`, and `system_support`, leaving the parameter out, passing `None`, or passing an empty dictionary `{}` all skip that check. Any other value that is not a dictionary raises a `ValueError`.
|
|
391
|
+
|
|
249
392
|
* `python_version_support`: requires a dictionary with the three following keys:
|
|
250
393
|
* `min_version`: a string with the number of the oldest supported version (like `'3.10'`).
|
|
251
394
|
* `incompatible_versions`: a list of incompatible versions that, by default, raise the `RuntimeError` exception if they try to run your package (configurable with `on_incompatible`).
|
|
@@ -258,10 +401,13 @@ Salted in that specific version is a relatively young package that will receive
|
|
|
258
401
|
* `full`: The set of operating systems that are tested on production level.
|
|
259
402
|
* `partial`: The set of systems that should work, but are not as rigorously tested as those with full support. A system found running here logs a warning.
|
|
260
403
|
* `incompatible`: The set of systems of which you know they will fail to run the code properly. By default, if an OS in this set tries to run the code, this will yield a `RuntimeError` exception (configurable with `on_incompatible`).
|
|
404
|
+
|
|
405
|
+
An operating system may appear in only one of the three sets; listing it in two raises `ParameterContradiction`.
|
|
261
406
|
* `on_incompatible` (optional): what to do when the running Python version or operating system is incompatible. One of:
|
|
262
407
|
* `'raise'` (default): raise a `RuntimeError` — the current behaviour.
|
|
263
408
|
* `'warn'`: log a warning and continue.
|
|
264
409
|
* `'ignore'`: continue silently (logged at DEBUG only). You take responsibility for running in an unsupported environment.
|
|
410
|
+
* `warn_eol` (optional): set to `True` to log a warning if the running Python version has reached its [end of life](https://devguide.python.org/versions/) and no longer receives security updates. Defaults to `False`. The end-of-life dates are built in, so the check works offline; a Python version newer than the installed release of this library is not reported.
|
|
265
411
|
|
|
266
412
|
**System Support Behavior:**
|
|
267
413
|
|
|
@@ -288,10 +434,15 @@ However, `min_version` and `max_tested_version` ignore the release level part.
|
|
|
288
434
|
|
|
289
435
|
## Avoid running your package with an incompatible version of Python
|
|
290
436
|
|
|
291
|
-
In the `pyproject.toml` file of your package
|
|
437
|
+
In the `pyproject.toml` file of your package, set [`requires-python`](https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#python-requires) in the `[project]` table (for example `requires-python = ">=3.10"`) to tell `pip` about the supported versions of the interpreter. This blocks installation on incompatible systems. However, users can circumvent this with pip's `--ignore-requires-python` flag. More likely is a system upgrade that replaces the interpreter with an incompatible version through the system's package manager.
|
|
292
438
|
|
|
293
439
|
If you define incompatible versions while initializing the `compatibility` package, you add another layer of control. Even if your user ended up with an incompatible interpreter, that will trigger a `RuntimeError` exception once the user tries to run your package.
|
|
294
440
|
|
|
441
|
+
This works only if Python gets as far as running the check:
|
|
442
|
+
|
|
443
|
+
* `compatibility` itself runs on Python 3.10 or newer. On an older interpreter it cannot import, so it cannot show any message.
|
|
444
|
+
* Your package's modules are imported before your constructor runs. If one of them uses syntax or a feature that the running Python lacks, the user gets a `SyntaxError` or `ImportError` before the check. For example, `except*` and `typing.Self` need Python 3.11 and `class C[T]:` needs Python 3.12.
|
|
445
|
+
|
|
295
446
|
## Logging
|
|
296
447
|
|
|
297
448
|
The `compatibility` package uses Python's standard logging module with a dedicated logger named `'compatibility'`. This allows you to control the verbosity of compatibility messages independently from your application's logging.
|
|
@@ -329,7 +480,7 @@ logging.getLogger('compatibility').setLevel(logging.DEBUG)
|
|
|
329
480
|
The compatibility package logs at different levels:
|
|
330
481
|
* **DEBUG**: Informational messages about full platform support
|
|
331
482
|
* **INFO**: Package version information and update reminders
|
|
332
|
-
* **WARNING**: Running newer Python than tested, or partial platform support
|
|
483
|
+
* **WARNING**: Running newer Python than tested, a Python past its end of life (with `warn_eol=True`), or partial platform support
|
|
333
484
|
* **ERROR**: Incompatible Python version or operating system (also raises exceptions)
|
|
334
485
|
|
|
335
486
|
### Example Messages
|
|
@@ -343,6 +494,7 @@ INFO:compatibility:You are using my_package 1.0.0 (released: 2025-01-01)
|
|
|
343
494
|
INFO:compatibility:Your version of my_package was released 120 days ago. Please check for updates.
|
|
344
495
|
WARNING:compatibility:my_package has only partial support on Windows.
|
|
345
496
|
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.
|
|
497
|
+
WARNING:compatibility:Python 3.10 reached its end of life (2026-10-01) and no longer receives security updates. Please upgrade to a newer version of Python.
|
|
346
498
|
ERROR:compatibility:This version of my_package is incompatible with Windows!
|
|
347
499
|
```
|
|
348
500
|
|
|
@@ -351,7 +503,7 @@ An incompatible Python version (below `min_version`, or listed in
|
|
|
351
503
|
`on_incompatible='raise'`, additionally raises `RuntimeError`:
|
|
352
504
|
|
|
353
505
|
```text
|
|
354
|
-
ERROR:compatibility:You use Python 3.
|
|
506
|
+
ERROR:compatibility:You use Python 3.10.final, but need at least Python 3.11 to run my_package.
|
|
355
507
|
```
|
|
356
508
|
|
|
357
509
|
The same messages appear translated when you select another language (for
|
|
@@ -388,7 +540,7 @@ The `compatibility` package may raise the following exceptions:
|
|
|
388
540
|
## Use Cases
|
|
389
541
|
|
|
390
542
|
### When Your Package Requires Specific Python Versions
|
|
391
|
-
Use `min_version` to
|
|
543
|
+
Use `min_version` to stop your package from running on older Python versions that lack features it relies on at runtime, for example a standard library function or behavior added in a later version. A check in your constructor cannot catch syntax your modules use, as that fails on import (see [Avoid running your package with an incompatible version of Python](#avoid-running-your-package-with-an-incompatible-version-of-python)).
|
|
392
544
|
|
|
393
545
|
### When You Know Specific Python Versions Are Broken
|
|
394
546
|
Use `incompatible_versions` to block specific Python versions where your package has known issues (e.g., bugs in Python itself, or dependencies that break on certain versions).
|
|
@@ -396,8 +548,11 @@ Use `incompatible_versions` to block specific Python versions where your package
|
|
|
396
548
|
### When Users Report Bugs on Untested Python Versions
|
|
397
549
|
Use `max_tested_version` to warn users when they're running your package on newer Python versions you haven't tested yet. This helps manage expectations and reduces false bug reports.
|
|
398
550
|
|
|
551
|
+
### When Your Users Still Run an Unmaintained Python
|
|
552
|
+
Set `warn_eol=True` to warn users whose Python version has reached its end of life. Such a version gets no security fixes anymore, even if your package still supports it. The warning is opt-in, so it never surprises users of a package that did not ask for it.
|
|
553
|
+
|
|
399
554
|
### When You Drop Support for Old Python Versions
|
|
400
|
-
After dropping (for example) Python 3.
|
|
555
|
+
After dropping (for example) Python 3.10 support, set `min_version` to `'3.11'`. Users who still end up on 3.10 get a clear error message instead of a cryptic runtime failure, as long as your package still imports on 3.10.
|
|
401
556
|
|
|
402
557
|
### When Your Package Only Works on Certain Operating Systems
|
|
403
558
|
Use `system_support` to declare which operating systems (Linux, macOS, Windows) are fully supported, partially supported, or incompatible. For example, if your package uses Linux-specific system calls.
|