14
14
import subprocess
15
15
import sys
16
16
from glob import glob
17
- from urllib .parse import urlparse
18
17
19
18
import requests
20
19
from coverage .config import CoverageConfig
@@ -262,32 +261,33 @@ def compile_requirements(upgrade=False):
262
261
263
262
264
263
def update_python_versions ():
265
- install .ensure_python (PYMAIN ) # ensures pyenv is installed and up to date
264
+ install .ensure_python (PYTHONS [ ci_version ])
266
265
cmd = "~/.cache/hypothesis-build-runtimes/pyenv/bin/pyenv install --list"
267
266
result = subprocess .run (cmd , shell = True , stdout = subprocess .PIPE ).stdout .decode ()
268
267
# pyenv reports available versions in chronological order, so we keep the newest
269
268
# *unless* our current ends with a digit (is stable) and the candidate does not.
270
269
stable = re .compile (r".*3\.\d+.\d+$" )
271
270
best = {}
272
271
for line in map (str .strip , result .splitlines ()):
273
- if m := re .match (r"(?:pypy)?3\.(?:[6-9 ]|\d\d)" , line ):
272
+ if m := re .match (r"(?:pypy)?3\.(?:[789 ]|\d\d)" , line ):
274
273
key = m .group ()
275
274
if stable .match (line ) or not stable .match (best .get (key , line )):
276
275
best [key ] = line
277
- print (best )
276
+
277
+ if best == PYTHONS :
278
+ return
279
+
280
+ # Write the new mapping back to this file
278
281
thisfile = pathlib .Path (__file__ )
279
- before = after = thisfile .read_text ()
280
- for key , version in best .items ():
281
- var = key .upper ().replace ("." , "" )
282
- after = re .sub (rf'({ var } = .*?"){ key } [^"]+' , rf"\g<1>{ version } " , after )
283
- if before != after :
284
- thisfile .write_text (after )
285
-
286
- # Automatically sync PYMAIN with the version in build.sh
282
+ before = thisfile .read_text ()
283
+ after = re .sub (r"\nPYTHONS = \{[^{}]+\}" , f"\n PYTHONS = { best } " , before )
284
+ thisfile .write_text (after )
285
+ pip_tool ("shed" , str (thisfile ))
286
+
287
+ # Automatically sync ci_version with the version in build.sh
287
288
build_sh = pathlib .Path (tools .ROOT ) / "build.sh"
288
289
sh_before = build_sh .read_text ()
289
- new_pymain = re .search (r'PYMAIN = "(3\.\d\d?\.\d\d?)"' , after ).group (1 )
290
- sh_after = re .sub (r"3\.\d\d?\.\d\d?" , new_pymain , sh_before )
290
+ sh_after = re .sub (r"3\.\d\d?\.\d\d?" , best [ci_version ], sh_before )
291
291
if sh_before != sh_after :
292
292
build_sh .unlink () # so bash doesn't reload a modified file
293
293
build_sh .write_text (sh_after )
@@ -299,7 +299,7 @@ def update_vendored_files():
299
299
300
300
# Turns out that as well as adding new gTLDs, IANA can *terminate* old ones
301
301
url = "http://data.iana.org/TLD/tlds-alpha-by-domain.txt"
302
- fname = vendor / urlparse ( url ). path .split ("/" )[- 1 ]
302
+ fname = vendor / url .split ("/" )[- 1 ]
303
303
new = requests .get (url ).content
304
304
# If only the timestamp in the header comment has changed, skip the update.
305
305
if fname .read_bytes ().splitlines ()[1 :] != new .splitlines ()[1 :]:
@@ -376,28 +376,19 @@ def run_tox(task, version, *args):
376
376
pip_tool ("tox" , "-e" , task , * args , env = env , cwd = hp .HYPOTHESIS_PYTHON )
377
377
378
378
379
- # See update_python_versions() above
380
- # When adding or removing a version, also update the env lists in tox.ini and
381
- # workflows/main.yml, the `Programming Language ::` declaration(s) in setup.py,
382
- # and the corresponding @python_tests function below.
383
- PY37 = "3.7.13"
384
- PY38 = PYMAIN = "3.8.13" # Sync PYMAIN minor version with GH Actions main.yml
385
- PY39 = "3.9.12"
386
- PY310 = "3.10.4"
387
- PY311 = "3.11-dev"
388
- PYPY37 = "pypy3.7-7.3.9"
389
- PYPY38 = "pypy3.8-7.3.9"
390
-
391
-
392
- # ALIASES are the executable names for each Python version
393
- ALIASES = {}
394
- for name , value in list (globals ().items ()):
395
- if name .startswith ("PYPY" ):
396
- ALIASES [value ] = "pypy3"
397
- elif name .startswith ("PY" ):
398
- major , minor , patch = value .replace ("-dev" , "." ).split ("." )
399
- ALIASES [value ] = f"python{ major } .{ minor } "
400
-
379
+ # update_python_versions(), above, keeps the contents of this dict up to date.
380
+ # When a version is added or removed, manually update the env lists in tox.ini and
381
+ # workflows/main.yml, and the `Programming Language ::` specifiers in setup.py
382
+ PYTHONS = {
383
+ "3.7" : "3.7.13" ,
384
+ "3.8" : "3.8.13" ,
385
+ "3.9" : "3.9.12" ,
386
+ "3.10" : "3.10.4" ,
387
+ "3.11" : "3.11-dev" ,
388
+ "pypy3.7" : "pypy3.7-7.3.9" ,
389
+ "pypy3.8" : "pypy3.8-7.3.9" ,
390
+ }
391
+ ci_version = "3.8" # Keep this in sync with GH Actions main.yml
401
392
402
393
python_tests = task (
403
394
if_changed = (
@@ -409,44 +400,23 @@ def run_tox(task, version, *args):
409
400
)
410
401
411
402
412
- @python_tests
413
- def check_py37 ():
414
- run_tox ("py37-full" , PY37 )
415
-
416
-
417
- @python_tests
418
- def check_py38 ():
419
- run_tox ("py38-full" , PY38 )
420
-
421
-
422
- @python_tests
423
- def check_py39 ():
424
- run_tox ("py39-full" , PY39 )
425
-
426
-
427
- @python_tests
428
- def check_py310 ():
429
- run_tox ("py310-full" , PY310 )
430
-
431
-
432
- @python_tests
433
- def check_py311 ():
434
- run_tox ("py311-full" , PY311 )
403
+ # ALIASES are the executable names for each Python version
404
+ ALIASES = {}
405
+ for key , version in PYTHONS .items ():
406
+ if key .startswith ("pypy" ):
407
+ ALIASES [version ] = "pypy3"
408
+ name = key .replace ("." , "" )
409
+ else :
410
+ ALIASES [version ] = f"python{ key } "
411
+ name = f"py3{ key [2 :]} "
412
+ TASKS [f"check-{ name } " ] = python_tests (
413
+ lambda n = f"{ name } -full" , v = version : run_tox (n , v )
414
+ )
435
415
436
416
437
417
@python_tests
438
418
def check_py310_pyjion ():
439
- run_tox ("py310-pyjion" , PY310 )
440
-
441
-
442
- @python_tests
443
- def check_pypy37 ():
444
- run_tox ("pypy3-full" , PYPY37 )
445
-
446
-
447
- @python_tests
448
- def check_pypy38 ():
449
- run_tox ("pypy3-full" , PYPY38 )
419
+ run_tox ("py310-pyjion" , PYTHONS ["3.10" ])
450
420
451
421
452
422
@task ()
@@ -458,7 +428,7 @@ def tox(*args):
458
428
459
429
460
430
def standard_tox_task (name ):
461
- TASKS ["check-" + name ] = python_tests (lambda : run_tox (name , PYMAIN ))
431
+ TASKS ["check-" + name ] = python_tests (lambda : run_tox (name , PYTHONS [ ci_version ] ))
462
432
463
433
464
434
standard_tox_task ("nose" )
@@ -477,12 +447,12 @@ def standard_tox_task(name):
477
447
478
448
@task ()
479
449
def check_quality ():
480
- run_tox ("quality" , PYMAIN )
450
+ run_tox ("quality" , PYTHONS [ ci_version ] )
481
451
482
452
483
453
@task (if_changed = (hp .PYTHON_SRC , os .path .join (hp .HYPOTHESIS_PYTHON , "examples" )))
484
454
def check_examples3 ():
485
- run_tox ("examples3" , PYMAIN )
455
+ run_tox ("examples3" , PYTHONS [ ci_version ] )
486
456
487
457
488
458
@task ()
0 commit comments