88import sysconfig
99import tarfile
1010import tempfile
11+ from collections .abc import (
12+ Callable ,
13+ Iterable ,
14+ Iterator ,
15+ )
1116from contextlib import ExitStack , contextmanager
1217from functools import lru_cache
1318from glob import glob
1419from pathlib import Path
1520from typing import (
1621 Any ,
17- Callable ,
18- Dict ,
19- Iterable ,
20- Iterator ,
21- List ,
22- Optional ,
23- Tuple ,
22+ IO ,
2423)
2524
2625import nox .command
@@ -54,7 +53,7 @@ def _get_output(*args: str) -> str:
5453
5554def _parse_supported_interpreter_version (
5655 python_impl : str , # Literal["cpython", "pypy"], TODO update after 3.7 dropped
57- ) -> Tuple [str , str ]:
56+ ) -> tuple [str , str ]:
5857 output = _get_output ("cargo" , "metadata" , "--format-version=1" , "--no-deps" )
5958 cargo_packages = json .loads (output )["packages" ]
6059 # Check Python interpreter version support in package metadata
@@ -68,7 +67,7 @@ def _parse_supported_interpreter_version(
6867
6968def _supported_interpreter_versions (
7069 python_impl : str , # Literal["cpython", "pypy"], TODO update after 3.7 dropped
71- ) -> List [str ]:
70+ ) -> list [str ]:
7271 min_version , max_version = _parse_supported_interpreter_version (python_impl )
7372 major = int (min_version .split ("." )[0 ])
7473 assert major == 3 , f"unsupported Python major version { major } "
@@ -97,7 +96,7 @@ def test_rust(session: nox.Session):
9796 _run_cargo_test (session , package = "pyo3-macros-backend" )
9897 _run_cargo_test (session , package = "pyo3-macros" )
9998
100- extra_flags = []
99+ extra_flags : list [ str ] = []
101100 # pypy and graalpy don't have Py_Initialize APIs, so we can only
102101 # build the main tests, not run them
103102 if sys .implementation .name in ("pypy" , "graalpy" ):
@@ -214,14 +213,14 @@ def rumdl(session: nox.Session):
214213
215214
216215@nox .session (name = "clippy" , venv_backend = "none" )
217- def clippy (session : nox .Session ) -> bool :
216+ def clippy (session : nox .Session ) -> None :
218217 if not (_clippy (session ) and _clippy_additional_workspaces (session )):
219218 session .error ("one or more jobs failed" )
220219
221220
222- def _clippy (session : nox .Session , * , env : Dict [str , str ] = None ) -> bool :
221+ def _clippy (session : nox .Session , * , env : dict [str , str ] | None = None ) -> bool :
223222 success = True
224- env = env or os .environ
223+ env = env or dict ( os .environ )
225224 for feature_set in _get_feature_sets ():
226225 try :
227226 _run_cargo (
@@ -263,12 +262,12 @@ def _clippy_additional_workspaces(session: nox.Session) -> bool:
263262
264263
265264@nox .session (venv_backend = "none" )
266- def bench (session : nox .Session ) -> bool :
265+ def bench (session : nox .Session ) -> None :
267266 _run_cargo (session , "bench" , _BENCHES , * session .posargs )
268267
269268
270269@nox .session ()
271- def codspeed (session : nox .Session ) -> bool :
270+ def codspeed (session : nox .Session ) -> None :
272271 # rust benchmarks
273272 os .chdir (PYO3_DIR / "pyo3-benches" )
274273 _run_cargo (session , "codspeed" , "build" )
@@ -283,7 +282,7 @@ def codspeed(session: nox.Session) -> bool:
283282def clippy_all (session : nox .Session ) -> None :
284283 success = True
285284
286- def _clippy_with_config (env : Dict [str , str ]) -> None :
285+ def _clippy_with_config (env : dict [str , str ]) -> None :
287286 nonlocal success
288287 success &= _clippy (session , env = env )
289288
@@ -298,7 +297,7 @@ def _clippy_with_config(env: Dict[str, str]) -> None:
298297def check_all (session : nox .Session ) -> None :
299298 success = True
300299
301- def _check (env : Dict [str , str ]) -> None :
300+ def _check (env : dict [str , str ]) -> None :
302301 nonlocal success
303302 for feature_set in _get_feature_sets ():
304303 try :
@@ -347,7 +346,7 @@ def contributors(session: nox.Session) -> None:
347346 if len (session .posargs ) > 2 :
348347 raise Exception ("too many arguments" )
349348
350- authors = set ()
349+ authors : set [ str ] | list [ str ] = set ()
351350
352351 while True :
353352 resp = requests .get (
@@ -387,9 +386,10 @@ def __init__(self):
387386
388387 self .pyversion = sys .version .split ()[0 ]
389388 self .pymajor , self .pyminor , self .pymicro = self .pyversion .split ("." )
390- self .pymicro , self .pydev = re .match (
391- "([0-9]*)([^0-9].*)?" , self .pymicro
392- ).groups ()
389+ match = re .match ("([0-9]*)([^0-9].*)?" , self .pymicro )
390+ if match :
391+ self .pymicro , self .pydev = match .groups ()
392+
393393 if self .pydev is None :
394394 self .pydev = ""
395395
@@ -441,7 +441,7 @@ def test_emscripten(session: nox.Session):
441441 )
442442 session .env ["RUSTDOCFLAGS" ] = session .env ["RUSTFLAGS" ]
443443 session .env ["CARGO_BUILD_TARGET" ] = target
444- session .env ["PYO3_CROSS_LIB_DIR" ] = pythonlibdir
444+ session .env ["PYO3_CROSS_LIB_DIR" ] = str ( pythonlibdir )
445445 _run (session , "rustup" , "target" , "add" , target , "--toolchain" , "stable" )
446446 _run (
447447 session ,
@@ -517,8 +517,8 @@ def test_cross_compilation_windows(session: nox.Session):
517517@nox .session (venv_backend = "none" )
518518def docs (session : nox .Session , nightly : bool = False , internal : bool = False ) -> None :
519519 rustdoc_flags = ["-Dwarnings" ]
520- toolchain_flags = []
521- cargo_flags = []
520+ toolchain_flags : list [ str ] = []
521+ cargo_flags : list [ str ] = []
522522
523523 nightly = nightly or ("nightly" in session .posargs )
524524 internal = internal or ("internal" in session .posargs )
@@ -539,7 +539,7 @@ def docs(session: nox.Session, nightly: bool = False, internal: bool = False) ->
539539 else :
540540 cargo_flags .extend (["--exclude=pyo3-macros" , "--exclude=pyo3-macros-backend" ])
541541
542- rustdoc_flags .append (session .env .get ("RUSTDOCFLAGS" , "" ) )
542+ rustdoc_flags .append (session .env .get ("RUSTDOCFLAGS" ) or "" )
543543 session .env ["RUSTDOCFLAGS" ] = " " .join (rustdoc_flags )
544544
545545 features = "full"
@@ -579,6 +579,9 @@ def build_guide(session: nox.Session):
579579
580580@nox .session (name = "build-netlify-site" )
581581def build_netlify_site (session : nox .Session ):
582+ if requests is None :
583+ session .error ("requests library is required for this session" )
584+
582585 # Remove netlify_build directory if it exists
583586 netlify_build = Path ("netlify_build" )
584587 if netlify_build .exists ():
@@ -726,7 +729,7 @@ def check_guide(session: nox.Session):
726729 # rust docs
727730 "(https://docs.rs/[^#]+)#[a-zA-Z0-9._-]*" : "$1" ,
728731 }
729- remap_args = []
732+ remap_args : list [ str ] = []
730733 for key , value in remaps .items ():
731734 remap_args .extend (("--remap" , f"{ key } { value } " ))
732735
@@ -767,7 +770,7 @@ def format_guide(session: nox.Session):
767770 for path in Path ("guide" ).glob ("**/*.md" ):
768771 session .log ("Working on %s" , path )
769772 lines = iter (path .read_text ().splitlines (True ))
770- new_lines = []
773+ new_lines : list [ str ] = []
771774
772775 for line in lines :
773776 new_lines .append (line )
@@ -889,7 +892,7 @@ def set_msrv_package_versions(session: nox.Session):
889892 * (Path (p ).parent for p in glob ("examples/*/Cargo.toml" )),
890893 * (Path (p ).parent for p in glob ("pyo3-ffi/examples/*/Cargo.toml" )),
891894 )
892- min_pkg_versions = {}
895+ min_pkg_versions : dict [ str , str ] = {}
893896
894897 # run cargo update first to ensure that everything is at highest
895898 # possible version, so that this matches what CI will resolve to.
@@ -904,10 +907,12 @@ def set_msrv_package_versions(session: nox.Session):
904907
905908 lock_file = project / "Cargo.lock"
906909
907- def load_pkg_versions ():
910+ def load_pkg_versions ():
911+ if toml is None :
912+ session .error ("requires `toml` to be installed" )
908913 cargo_lock = toml .loads (lock_file .read_text ())
909914 # Cargo allows to depends on multiple versions of the same package
910- pkg_versions = defaultdict (list )
915+ pkg_versions : defaultdict [ str , list [ str ]] = defaultdict (list )
911916 for pkg in cargo_lock ["package" ]:
912917 name = pkg ["name" ]
913918 if name not in min_pkg_versions :
@@ -922,7 +927,7 @@ def load_pkg_versions():
922927 if version != min_version :
923928 pkg_id = pkg_name + ":" + version
924929 _run_cargo_set_package_version (
925- session , pkg_id , min_version , project = project
930+ session , pkg_id , min_version , project = str ( project )
926931 )
927932 # assume `_run_cargo_set_package_version` has changed something
928933 # and re-read `Cargo.lock`
@@ -1103,7 +1108,7 @@ def update_ui_tests(session: nox.Session):
11031108def test_introspection (session : nox .Session ):
11041109 session .install ("maturin" )
11051110 session .install ("ruff" )
1106- options = []
1111+ options : list [ str ] = []
11071112 target = os .environ .get ("CARGO_BUILD_TARGET" )
11081113 if target is not None :
11091114 options += ("--target" , target )
@@ -1124,6 +1129,8 @@ def test_introspection(session: nox.Session):
11241129 for file in Path (session .virtualenv .location ).rglob ("pyo3_pytests.*" ):
11251130 if file .is_file ():
11261131 lib_file = str (file .resolve ())
1132+ if lib_file is None :
1133+ session .error ("Could not find built pyo3_pytests" )
11271134 _run_cargo_test (
11281135 session ,
11291136 package = "pyo3-introspection" ,
@@ -1139,19 +1146,21 @@ def _build_docs_for_ffi_check(session: nox.Session) -> None:
11391146
11401147
11411148@lru_cache ()
1142- def _get_rust_info () -> Tuple [str , ...]:
1149+ def _get_rust_info () -> tuple [str , ...]:
11431150 output = _get_output ("rustc" , "-vV" )
11441151
11451152 return tuple (output .splitlines ())
11461153
11471154
1148- def get_rust_version () -> Tuple [int , int , int , List [str ]]:
1155+ def get_rust_version () -> tuple [int , int , int , list [str ]]:
11491156 for line in _get_rust_info ():
11501157 if line .startswith (_RELEASE_LINE_START ):
11511158 version = line [len (_RELEASE_LINE_START ) :].strip ()
11521159 # e.g. 1.67.0-beta.2
11531160 (version_number , * extra ) = version .split ("-" , maxsplit = 1 )
1154- return (* map (int , version_number .split ("." )), extra )
1161+ major , minor , patch = map (int , version_number .split ("." ))
1162+ return (major , minor , patch , extra )
1163+ raise RuntimeError ("Could not parse Rust version" )
11551164
11561165
11571166def is_rust_nightly () -> bool :
@@ -1165,10 +1174,11 @@ def _get_rust_default_target() -> str:
11651174 for line in _get_rust_info ():
11661175 if line .startswith (_HOST_LINE_START ):
11671176 return line [len (_HOST_LINE_START ) :].strip ()
1177+ raise RuntimeError ("Could not get Rust default target" )
11681178
11691179
11701180@lru_cache ()
1171- def _get_feature_sets () -> Tuple [ Optional [ str ] , ...]:
1181+ def _get_feature_sets () -> tuple [ str | None , ...]:
11721182 """Returns feature sets to use for Rust jobs"""
11731183 cargo_target = os .getenv ("CARGO_BUILD_TARGET" , "" )
11741184
@@ -1188,8 +1198,8 @@ def _get_feature_sets() -> Tuple[Optional[str], ...]:
11881198_HOST_LINE_START = "host: "
11891199
11901200
1191- def _get_coverage_env () -> Dict [str , str ]:
1192- env = {}
1201+ def _get_coverage_env () -> dict [str , str ]:
1202+ env : dict [ str , str ] = {}
11931203 output = _get_output ("cargo" , "llvm-cov" , "show-env" )
11941204
11951205 for line in output .strip ().splitlines ():
@@ -1242,10 +1252,10 @@ def _run_cargo(
12421252def _run_cargo_test (
12431253 session : nox .Session ,
12441254 * ,
1245- package : Optional [ str ] = None ,
1246- features : Optional [ str ] = None ,
1247- env : Optional [ Dict [ str , str ]] = None ,
1248- extra_flags : Optional [ List [ str ]] = None ,
1255+ package : str | None = None ,
1256+ features : str | None = None ,
1257+ env : dict [ str , str ] | None = None ,
1258+ extra_flags : list [ str ] | None = None ,
12491259) -> None :
12501260 command = ["cargo" ]
12511261 if "careful" in session .posargs :
@@ -1276,7 +1286,7 @@ def _run_cargo_set_package_version(
12761286 pkg_id : str ,
12771287 version : str ,
12781288 * ,
1279- project : Optional [ str ] = None ,
1289+ project : str | None = None ,
12801290) -> None :
12811291 command = ["cargo" , "update" , "-p" , pkg_id , "--precise" , version , "--workspace" ]
12821292 if project :
@@ -1285,13 +1295,13 @@ def _run_cargo_set_package_version(
12851295
12861296
12871297def _for_all_version_configs (
1288- session : nox .Session , job : Callable [[Dict [str , str ]], None ]
1298+ session : nox .Session , job : Callable [[dict [str , str ]], None ]
12891299) -> None :
12901300 env = os .environ .copy ()
12911301 with _config_file () as config_file :
12921302 env ["PYO3_CONFIG_FILE" ] = config_file .name
12931303
1294- def _job_with_config (implementation , version ) :
1304+ def _job_with_config (implementation : str , version : str ) -> None :
12951305 session .log (f"{ implementation } { version } " )
12961306 config_file .set (implementation , version )
12971307 job (env )
@@ -1304,7 +1314,7 @@ def _job_with_config(implementation, version):
13041314
13051315
13061316class _ConfigFile :
1307- def __init__ (self , config_file ) -> None :
1317+ def __init__ (self , config_file : IO [ str ] ) -> None :
13081318 self ._config_file = config_file
13091319
13101320 def set (
0 commit comments