1010
1111from __future__ import annotations
1212
13+ import collections
14+ import os
1315import re
1416import sys
1517from typing import Any
1618from typing import Callable
19+ from typing import List
1720from typing import Optional
1821from typing import Sequence
22+ from typing import Tuple
1923
2024import nox
2125
@@ -48,11 +52,12 @@ def tox_parameters(
4852 joined by ``-``, as well as combinations that include a subset of those
4953 values, where the omitted elements of the tag are implicitly considered to
5054 match the "default" value, indicated by them being first in their
51- collection. Additionally, values that start with an underscore are omitted
52- from all ids and tags. Values that refer to Python versions wlil be
53- expanded to the full Python executable name when passed as arguments to
54- the session function, which is currently a workaround to allow
55- free-threaded python interpreters to be located.
55+ collection (with the exception of "python", where the current python in
56+ use is the default). Additionally, values that start with an underscore
57+ are omitted from all ids and tags. Values that refer to Python versions
58+ wlil be expanded to the full Python executable name when passed as
59+ arguments to the session function, which is currently a workaround to
60+ allow free-threaded python interpreters to be located.
5661 :param base_tag: optional tag that will be appended to all tags generated,
5762 e.g. if the decorator yields tags like ``python314-x86-windows``, a
5863 ``basetag`` value of ``all`` would yield the
@@ -67,7 +72,7 @@ def tox_parameters(
6772
6873 """
6974
70- PY_RE = re .compile (r"(?:python)?([234]\.\d+t? )" )
75+ PY_RE = re .compile (r"(?:python)?([234]\.\d+(t?) )" )
7176
7277 def _is_py_version (token ):
7378 return bool (PY_RE .match (token ))
@@ -80,8 +85,15 @@ def _expand_python_version(token):
8085 name
8186
8287 """
88+ if sys .platform == "win32" :
89+ return token
90+
8391 m = PY_RE .match (token )
84- if m :
92+
93+ # do this matching minimally so that it only happens for the
94+ # free-threaded versions. on windows, the "pythonx.y" syntax doesn't
95+ # work due to the use of the "py" tool
96+ if m and m .group (2 ) == "t" :
8597 return f"python{ m .group (1 )} "
8698 else :
8799 return token
@@ -181,7 +193,36 @@ def _recur_param(prevtokens, prevtags, token_lists):
181193 ]
182194
183195 # for p in params:
184- # print(f"PARAM {'-'.join(p.args)} TAGS {p.tags}")
185- # breakpoint()
196+ # print(f"PARAM {'-'.join(p.args)} TAGS {p.tags}")
186197
187198 return nox .parametrize (names , params )
199+
200+
201+ def extract_opts (posargs : List [str ], * args : str ) -> Tuple [List [str ], Any ]:
202+
203+ underscore_args = [arg .replace ("-" , "_" ) for arg in args ]
204+ return_tuple = collections .namedtuple ("options" , underscore_args )
205+
206+ look_for_args = {f"--{ arg } " : idx for idx , arg in enumerate (args )}
207+ return_args = [False for arg in args ]
208+
209+ def extract (arg : str ):
210+ if arg in look_for_args :
211+ return_args [look_for_args [arg ]] = True
212+ return True
213+ else :
214+ return False
215+
216+ return [arg for arg in posargs if not extract (arg )], return_tuple (
217+ * return_args
218+ )
219+
220+
221+ def move_junit_file (tmpfilename : str , newname : str , suite_name : str ):
222+ import junitparser
223+
224+ xml = junitparser .JUnitXml .fromfile (tmpfilename )
225+ for suite in xml :
226+ suite .name = suite_name
227+ xml .write (newname )
228+ os .unlink (tmpfilename )
0 commit comments