check-python-versions 0.23.0__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.
@@ -0,0 +1,434 @@
1
+ Metadata-Version: 2.4
2
+ Name: check-python-versions
3
+ Version: 0.23.0
4
+ Summary: Compare supported Python versions in setup.py vs tox.ini et al.
5
+ Home-page: https://github.com/mgedmin/check-python-versions
6
+ Author: Marius Gedminas
7
+ Author-email: marius@gedmin.as
8
+ License: GPL
9
+ Project-URL: Changelog, https://github.com/mgedmin/check-python-versions/blob/master/CHANGES.rst
10
+ Project-URL: Issues, https://github.com/mgedmin/check-python-versions/issues
11
+ Project-URL: Source Code, https://github.com/mgedmin/check-python-versions
12
+ Keywords: python packaging version checker linter setup.py tox travis appveyor
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: GNU General Public License (GPL)
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Programming Language :: Python :: 3.14
25
+ Classifier: Programming Language :: Python :: Implementation :: CPython
26
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
27
+ Requires-Python: >=3.8
28
+ Description-Content-Type: text/x-rst
29
+ License-File: LICENSE
30
+ Requires-Dist: pyyaml
31
+ Requires-Dist: tomlkit
32
+ Dynamic: author
33
+ Dynamic: author-email
34
+ Dynamic: classifier
35
+ Dynamic: description
36
+ Dynamic: description-content-type
37
+ Dynamic: home-page
38
+ Dynamic: keywords
39
+ Dynamic: license
40
+ Dynamic: license-file
41
+ Dynamic: project-url
42
+ Dynamic: requires-dist
43
+ Dynamic: requires-python
44
+ Dynamic: summary
45
+
46
+ check-python-versions
47
+ =====================
48
+
49
+ .. image:: https://img.shields.io/pypi/v/check-python-versions.svg
50
+ :target: https://pypi.org/project/check-python-versions/
51
+ :alt: Latest release
52
+
53
+ .. image:: https://img.shields.io/pypi/pyversions/check-python-versions.svg
54
+ :target: https://pypi.org/project/check-python-versions/
55
+ :alt: Supported Python versions
56
+
57
+ .. image:: https://github.com/mgedmin/check-python-versions/actions/workflows/build.yml/badge.svg?branch=master
58
+ :target: https://github.com/mgedmin/check-python-versions/actions
59
+ :alt: Build status
60
+
61
+ .. image:: https://coveralls.io/repos/mgedmin/check-python-versions/badge.svg?branch=master
62
+ :target: https://coveralls.io/r/mgedmin/check-python-versions
63
+ :alt: Test coverage
64
+
65
+
66
+ This is a tool for Python package maintainers who want to explicitly state
67
+ which Python versions they support.
68
+
69
+
70
+ **The problem**: to properly support e.g. Python 2.7 and 3.6+ you have to
71
+ run tests with these Pythons. This means
72
+
73
+ - you need a tox.ini with envlist = py27, py36, py37, py38, py39
74
+ - you need a .travis.yml with python: [ 2.7, 3.6, 3.7, 3.8, 3.9 ]
75
+ - if you support Windows, you need an appveyor.yml with %PYTHON% set to
76
+ C:\\Python2.7, C:\\Python3.5, and so on
77
+ - if you're building manylinux wheels you need to ... you get the idea
78
+ - you have to tell the users which Python versions you support by specifying
79
+ trove classifiers like "Programming Language :: Python :: 2.7"
80
+ - you probably also want to tell pip which versions you support by specifying
81
+ python_requires=">= 2.7, !=3.0.* ..." because AFAIU PyPI classifiers are
82
+ not fine-grained enough
83
+
84
+ Keeping all these lists consistent is a pain.
85
+
86
+ **The solution**: ``check-python-versions`` will compare these lists and warn
87
+ you if they don't match ::
88
+
89
+ $ check-python-versions ~/projects/*
90
+ /home/mg/projects/check-manifest:
91
+
92
+ setup.py says: 2.7, 3.6, 3.7, 3.8, 3.9, PyPy
93
+ - python_requires says: 2.7, 3.6, 3.7, 3.8, 3.9
94
+ tox.ini says: 2.7, 3.6, 3.7, 3.8, 3.9, PyPy, PyPy3
95
+ .travis.yml says: 2.7, 3.6, 3.7, 3.8, 3.9, PyPy, PyPy3
96
+ appveyor.yml says: 2.7, 3.6, 3.7, 3.8, 3.9
97
+
98
+
99
+ /home/mg/projects/dozer:
100
+
101
+ setup.py says: 2.7, 3.6, 3.7, 3.8, 3.9
102
+ tox.ini says: 2.7, 3.6, 3.7, 3.8, 3.9
103
+ .travis.yml says: 2.7, 3.6, 3.7, 3.8, 3.9
104
+ appveyor.yml says: 2.7, 3.6, 3.7, 3.8, 3.9
105
+
106
+
107
+ /home/mg/projects/eazysvn:
108
+
109
+ setup.py says: 2.7, 3.6, 3.7, 3.8, 3.9, PyPy
110
+ tox.ini says: 2.7, 3.6, 3.7, 3.8, 3.9, PyPy, PyPy3
111
+ .travis.yml says: 2.7, 3.6, 3.7, 3.8, 3.9, PyPy, PyPy3
112
+ appveyor.yml says: 2.7, 3.6, 3.7, 3.8, 3.9
113
+
114
+ ...
115
+
116
+ all ok!
117
+
118
+
119
+ Installation
120
+ ------------
121
+
122
+ You need Python 3.6 or newer (f-strings!) to run check-python-versions.
123
+ Install it with ::
124
+
125
+ python3 -m pip install check-python-versions
126
+
127
+
128
+ Usage
129
+ -----
130
+
131
+ ::
132
+
133
+ $ check-python-versions --help
134
+ usage: check-python-versions [-h] [--version] [--expect VERSIONS]
135
+ [--skip-non-packages] [--only FILES]
136
+ [--add VERSIONS] [--drop VERSIONS]
137
+ [--update VERSIONS] [--diff] [--dry-run]
138
+ [where [where ...]]
139
+
140
+ verify that supported Python versions are the same in setup.py, tox.ini,
141
+ .travis.yml and appveyor.yml
142
+
143
+ positional arguments:
144
+ where directory where a Python package with a setup.py and
145
+ other files is located
146
+
147
+ optional arguments:
148
+ -h, --help show this help message and exit
149
+ --version show program's version number and exit
150
+ --expect VERSIONS expect these versions to be supported, e.g. --expect
151
+ 2.7,3.5-3.8
152
+ --skip-non-packages skip arguments that are not Python packages without
153
+ warning about them
154
+ --only FILES check only the specified files (comma-separated list,
155
+ e.g. --only tox.ini,appveyor.yml)
156
+
157
+ updating supported version lists (EXPERIMENTAL):
158
+ --add VERSIONS add these versions to supported ones, e.g --add 3.9
159
+ --drop VERSIONS drop these versions from supported ones, e.g --drop
160
+ 2.6,3.4
161
+ --update VERSIONS update the set of supported versions, e.g. --update
162
+ 2.7,3.5-3.9
163
+ --diff show a diff of proposed changes
164
+ --dry-run verify proposed changes without writing them to disk
165
+
166
+ If run without any arguments, check-python-versions will look for a setup.py in
167
+ the current working directory.
168
+
169
+ Exit status is 0 if all Python packages had consistent version numbers (and, if
170
+ --expect is specified, those numbers match your stated expectations).
171
+
172
+ If you specify multiple directories on the command line, then all packages
173
+ that failed a check will be listed at the end of the run, separated with
174
+ spaces, for easier copying and pasting onto shell command lines. This is
175
+ helpful when, e.g. you want to run ::
176
+
177
+ check-python-versions ~/src/zopefoundation/*
178
+
179
+ to check all 380+ packages, and then want re-run the checks only on the failed
180
+ ones, for a faster turnabout.
181
+
182
+ There's also experimental support for updating supported Python versions
183
+ so you can do things like ::
184
+
185
+ check-python-versions ~/projects/* --add 3.9 --dry-run --expect 2.7,3.6-3.9
186
+ check-python-versions ~/projects/* --drop 3.4 --diff
187
+ check-python-versions ~/projects/* --update 2.7,3.6- --dry-run --diff
188
+ check-python-versions ~/projects/* --add 3.9 --drop=-2.6,-3.5
189
+
190
+ (the last one will show a diff for each file and ask for interactive
191
+ confirmation before making any changes.)
192
+
193
+ Programmatically updating human-writable files is difficult, so expect
194
+ bugs (and please file issues).
195
+
196
+
197
+ Files
198
+ -----
199
+
200
+ **setup.py** or **pyproject.toml** is the only required file; if any of the
201
+ others are missing, they'll be ignored (and this will not be considered a
202
+ failure).
203
+
204
+ - **setup.py**: the ``classifiers`` argument passed to ``setup()`` is expected
205
+ to have classifiers of the form::
206
+
207
+ classifiers=[
208
+ ...
209
+ "Programming Language :: Python :: x.y",
210
+ ...
211
+ ],
212
+
213
+ check-python-versions will attempt to parse the file and walk the AST to
214
+ extract classifiers, but if that fails, it'll execute
215
+ ``python setup.py --classifiers`` and parse the output.
216
+
217
+ There's rudimentary support for dynamically-computed classifiers if at
218
+ least one part is a list literal, e.g. this can work and can even be
219
+ updated ::
220
+
221
+ classifiers=[
222
+ ...
223
+ "Programming Language :: Python :: x.y",
224
+ ...
225
+ ] + ... expression that computes extra classifiers ...,
226
+
227
+ - **setup.py**: the ``python_requires`` argument passed to ``setup()``, if
228
+ present::
229
+
230
+ python_requires=">=2.7, !=3.0.*, !=3.1.*",
231
+
232
+ check-python-versions will attempt to parse the file and walk the AST to
233
+ extract the ``python_requires`` value. It expects to find a string literal
234
+ or a simple expression of the form ``"literal".join(["...", "..."])``.
235
+
236
+ - **pyproject.toml**: can have any of these::
237
+
238
+ # PEP 621 static metadata
239
+
240
+ [project]
241
+ classifiers = [
242
+ ...
243
+ "Programming Language :: Python :: 3.8",
244
+ ...
245
+ ]
246
+ requires-python = ">= 3.8"
247
+
248
+ # old-style Flit metadata
249
+
250
+ [tool.flit.metadata]
251
+ classifiers = [
252
+ ...
253
+ "Programming Language :: Python :: 3.8",
254
+ ...
255
+ ]
256
+ requires-python = ">= 3.8"
257
+
258
+ # Poetry metadata
259
+
260
+ [tool.poetry]
261
+ classifiers = [
262
+ ...
263
+ "Programming Language :: Python :: 3.8",
264
+ ...
265
+ ]
266
+
267
+ [tool.poetry.dependencies]
268
+ python = "^3.8"
269
+
270
+ - **tox.ini**: if present, it's expected to have ::
271
+
272
+ [tox]
273
+ envlist = pyXY, ...
274
+
275
+ Environment names like pyXY-ZZZ are also accepted; the suffix is ignored.
276
+
277
+ - **.travis.yml**: if present, it's expected to have ::
278
+
279
+ python:
280
+ - X.Y
281
+ - ...
282
+
283
+ and/or ::
284
+
285
+ matrix:
286
+ include:
287
+ - python: X.Y
288
+ ...
289
+ - ...
290
+
291
+ and/or ::
292
+
293
+ jobs:
294
+ include:
295
+ - python: X.Y
296
+ ...
297
+ - ...
298
+
299
+ and/or ::
300
+
301
+ env:
302
+ - TOXENV=...
303
+
304
+ (but not all of these forms are supported for updates)
305
+
306
+ - **appveyor.yml**: if present, it's expected to have ::
307
+
308
+ environment:
309
+ matrix:
310
+ - PYTHON: C:\\PythonX.Y
311
+ - ...
312
+
313
+ The environment variable name is assumed to be ``PYTHON`` (case-insensitive).
314
+ The values should be one of
315
+
316
+ - ``X.Y``
317
+ - ``C:\\PythonX.Y`` (case-insensitive)
318
+ - ``C:\\PythonX.Y-x64`` (case-insensitive)
319
+
320
+ Alternatively, you can use ``TOXENV`` with the usual values (pyXY).
321
+
322
+ (``TOXENV`` is currently not supported for updates.)
323
+
324
+ - **.manylinux-install.sh**: if present, it's expected to contain a loop like
325
+ ::
326
+
327
+ for PYBIN in /opt/python/*/bin; do
328
+ if [[ "${PYBIN}" == *"cp27"* ]] || \
329
+ [[ "${PYBIN}" == *"cp35"* ]] || \
330
+ [[ "${PYBIN}" == *"cp36"* ]] || \
331
+ [[ "${PYBIN}" == *"cp37"* ]] || \
332
+ [[ "${PYBIN}" == *"cp38"* ]]; then
333
+ "${PYBIN}/pip" install -e /io/
334
+ "${PYBIN}/pip" wheel /io/ -w wheelhouse/
335
+ rm -rf /io/build /io/*.egg-info
336
+ fi
337
+ done
338
+
339
+ check-python-versions will look for $PYBIN tests of the form ::
340
+
341
+ [[ "${PYBIN}" == *"cpXY"* ]]
342
+
343
+ where X and Y are arbitrary digits.
344
+
345
+ These scripts are used in several zopefoundation repositories like
346
+ zopefoundation/zope.interface. It's the least standartized format.
347
+
348
+ - **.github/workflows/*.yml**: if present, it's expected to have ::
349
+
350
+ jobs:
351
+ (anything):
352
+ strategy:
353
+ matrix:
354
+ python-version:
355
+ - X.Y
356
+ - ...
357
+
358
+ or ::
359
+
360
+ jobs:
361
+ (anything):
362
+ strategy:
363
+ matrix:
364
+ config
365
+ - [ X.Y, "pyXY" ]
366
+ - ...
367
+
368
+
369
+ Python versions
370
+ ---------------
371
+
372
+ In addition to CPython X.Y, check-python-versions will recognize PyPy and PyPy3
373
+ in some of the files:
374
+
375
+ - **setup.py** or **pyproject.toml** may have a ::
376
+
377
+ 'Programming Language :: Python :: Implementation :: PyPy',
378
+
379
+ classifier
380
+
381
+ - **tox.ini** may have pypy[-suffix] and pypy3[-suffix] environments
382
+
383
+ - **.travis.yml** may have pypy and pypy3 jobs with optional version suffixes
384
+ (e.g. pypy2.7-6.0.0, pypy3.5-6.0.0)
385
+
386
+ - **.github/workflows/*.yml**: may have pypy/pypy3/pypy-N.M/pypy-N.M-vX.Y.Z
387
+ jobs.
388
+
389
+ - **appveyor.yml** and **.manylinux-install.sh** do not usually have pypy tests,
390
+ so check-python-versions cannot recognize them, and these files are excluded
391
+ from PyPy support consistency checks.
392
+
393
+ Upcoming Python releases (such as 3.12 in setup.py or 3.12-dev in a .travis.yml)
394
+ are also shown but do not cause mismatch errors.
395
+
396
+ In addition, ``python_requires`` in setup.py or ``requires-python`` in
397
+ pyproject.toml usually has a lower limit, but no upper limit.
398
+ check-python-versions will assume this means support up to
399
+ whatever's the latest Python 3.x release mentioned in other data sources, or
400
+ the current 3.x release (3.11 at the moment), whichever is lower. This means
401
+ that new Python 3 releases don't suddenly cause all your lint checks to fail
402
+ if you use python_requires '>= 3.6' and such.
403
+
404
+ When you're specifying Python version ranges for --expect, --add, --drop or
405
+ --update, you can use
406
+
407
+ - ``X.Y`` (e.g. ``--add 3.8``)
408
+ - ``X.Y-U.V`` for an inclusive range (e.g. ``--add 3.5-3.8``)
409
+ - ``X.Y-``, which means from X.Y until the latest known release from the X
410
+ series (e.g. ``--add 3.5-`` is equivalent to ``--add 3.5-3.7``)
411
+ - ``-X.Y``, which is the same as ``X.0-X.Y``
412
+ (e.g. ``--drop -3.4`` is equivalent to ``--drop 3.0-3.4``)
413
+
414
+ or a comma-separated list of the above (e.g. ``--expect 2.7,3.5-``,
415
+ ``--drop -2.6,-3.4``).
416
+
417
+ --expect/--add/--drop/--update currently do not allow specifying alternative
418
+ implementations (such as pypy).
419
+
420
+
421
+ pre-commit integration
422
+ ----------------------
423
+
424
+ With `pre-commit <https://pre-commit.com>`_,
425
+ ``check-python-versions`` can be part of your git-workflow.
426
+ Add the following snippet to your ``.pre-commit-config.yaml``.
427
+
428
+ .. code-block:: yaml
429
+
430
+ repos:
431
+ - repo: https://github.com/mgedmin/check-python-versions
432
+ rev: "0.23.0"
433
+ hooks:
434
+ - id: check-python-versions
@@ -0,0 +1,28 @@
1
+ check_python_versions/__init__.py,sha256=YCUn2caSB3U4ZSb_qU50AkLP4aHAnUz33_HCXpPqeJw,401
2
+ check_python_versions/__main__.py,sha256=3S4LJTimwAmcTUOog4Fh6c9wt96rHti9Bw93cj0KliI,110
3
+ check_python_versions/cli.py,sha256=k-NCatswL_4LxBw9xXuP6bT5LO9L89YOm9gjFmdxFiM,17259
4
+ check_python_versions/utils.py,sha256=oECHZ5TX7UW73ZZTU39d7xNC-RFaOlIUCIknyHVUEJM,3991
5
+ check_python_versions/versions.py,sha256=a2cGVQy7qDVqfDQcRFBFmOHUno8tHSSGpt8dmD8rIXA,5063
6
+ check_python_versions/parsers/__init__.py,sha256=k8XlWs_u7oqjp67dtu-22dP7Hxn1eOP7wUUPck-JUAM,50
7
+ check_python_versions/parsers/classifiers.py,sha256=HDIOMqTkz-n9rSQ3BTpLdcB_jAb2jTGV2-ZNxgZVel4,2508
8
+ check_python_versions/parsers/ini.py,sha256=MtKyt-Mg_ABXHhcg3D82uzJfT4g4giEHu84JQiODOSo,2178
9
+ check_python_versions/parsers/poetry_version_spec.py,sha256=YnnUZPvu9HGoNE2k-y5_lx8hd9mnL3kbrqGw0e2RRqo,10309
10
+ check_python_versions/parsers/python.py,sha256=SQOb00cgqw1JeX1GDYrIxfW-d-lv70cQTXwCrk3awGU,8717
11
+ check_python_versions/parsers/requires_python.py,sha256=0lGre_We78--Cn3RqQpjz-fnEraTNijLpJLA8W0T0dk,8963
12
+ check_python_versions/parsers/yaml.py,sha256=ZCHgkWMDuDWtQGzeOaux7lzpmfY_GTtgmo0LHjg45jk,6886
13
+ check_python_versions/sources/__init__.py,sha256=HDKHKaRDZarfDweJFXgCoUPW2g5VCu4-yyW4Q9mtTnE,53
14
+ check_python_versions/sources/all.py,sha256=NPBGmVIFCNPIb3zsLpDAkp5AN-Z500ShugMsBMiEvDs,607
15
+ check_python_versions/sources/appveyor.py,sha256=35le4a3ctPruM-pop9gFvCaEnYUDcH6IpRukvQn6W-c,6370
16
+ check_python_versions/sources/base.py,sha256=W3ziK_jkqs_vX1WuP4TFSYGrOZ4C6eBk-Mi-mk6lrqQ,2688
17
+ check_python_versions/sources/github.py,sha256=td_haNnzacpIUL-Kk36AfRdFxDN3PXEQXuP0g_ltm5g,5582
18
+ check_python_versions/sources/manylinux.py,sha256=Qj5aEBc50Pp5tFrYB0D3bzTLyr5d2Apc73LfwBaojDU,2900
19
+ check_python_versions/sources/pyproject.py,sha256=Q7aztzjvO1R5zQD1dfv2uLTx81B8VdKa7Ss-2N2DvjU,7053
20
+ check_python_versions/sources/setup_py.py,sha256=mg85K98zKRpzZhy1cve-2Z_pdrElaGqYbLefhXsfL0A,6353
21
+ check_python_versions/sources/tox.py,sha256=HHOO_bSy704POHA9Di7vL_eSdVtMEJkpopZMMg-2bzc,8343
22
+ check_python_versions/sources/travis.py,sha256=jzlPbFBUU4MPrSP8S6HbKsQsQ7YSb-HYI-XEWGaerwc,7317
23
+ check_python_versions-0.23.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
24
+ check_python_versions-0.23.0.dist-info/METADATA,sha256=-eL5TVFwCpVoEsLiOxXfdUF-5NFIOR9otCeMEUTgq0s,14055
25
+ check_python_versions-0.23.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
+ check_python_versions-0.23.0.dist-info/entry_points.txt,sha256=x9xSZ-bykDb8Fdbn5dveeKR_FremlF7LtoleDZsc6HY,73
27
+ check_python_versions-0.23.0.dist-info/top_level.txt,sha256=EXCdlUG8MIX0NEzRDdG7u2SBhm5v15MNVPO5RrOxkHQ,22
28
+ check_python_versions-0.23.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ check-python-versions = check_python_versions.cli:main