Add support for Python 3.11 (#33505)
Argparse started raising ArgumentError exceptions when the same parser is added twice. Therefore, we perform the addition only if the parser is not there already Port match syntax to our unparser
This commit is contained in:
parent
c9fcb8aadc
commit
5558940ce6
2
.github/workflows/audit.yaml
vendored
2
.github/workflows/audit.yaml
vendored
@ -25,7 +25,7 @@ jobs:
|
||||
python-version: ${{inputs.python_version}}
|
||||
- name: Install Python packages
|
||||
run: |
|
||||
pip install --upgrade pip six setuptools pytest codecov 'coverage[toml]<=6.2'
|
||||
pip install --upgrade pip six setuptools pytest codecov coverage[toml]
|
||||
- name: Package audits (with coverage)
|
||||
if: ${{ inputs.with_coverage == 'true' }}
|
||||
run: |
|
||||
|
15
.github/workflows/unit_tests.yaml
vendored
15
.github/workflows/unit_tests.yaml
vendored
@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['2.7', '3.6', '3.7', '3.8', '3.9', '3.10']
|
||||
python-version: ['2.7', '3.6', '3.7', '3.8', '3.9', '3.10', '3.11']
|
||||
concretizer: ['clingo']
|
||||
on_develop:
|
||||
- ${{ github.ref == 'refs/heads/develop' }}
|
||||
@ -22,7 +22,7 @@ jobs:
|
||||
- python-version: 2.7
|
||||
concretizer: original
|
||||
on_develop: ${{ github.ref == 'refs/heads/develop' }}
|
||||
- python-version: '3.10'
|
||||
- python-version: '3.11'
|
||||
concretizer: original
|
||||
on_develop: ${{ github.ref == 'refs/heads/develop' }}
|
||||
exclude:
|
||||
@ -35,6 +35,9 @@ jobs:
|
||||
- python-version: '3.9'
|
||||
concretizer: 'clingo'
|
||||
on_develop: false
|
||||
- python-version: '3.10'
|
||||
concretizer: 'clingo'
|
||||
on_develop: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # @v2
|
||||
@ -86,7 +89,7 @@ jobs:
|
||||
SPACK_TEST_SOLVER: ${{ matrix.concretizer }}
|
||||
SPACK_TEST_PARALLEL: 2
|
||||
COVERAGE: true
|
||||
UNIT_TEST_COVERAGE: ${{ (matrix.python-version == '3.10') }}
|
||||
UNIT_TEST_COVERAGE: ${{ (matrix.python-version == '3.11') }}
|
||||
run: |
|
||||
share/spack/qa/run-unit-tests
|
||||
- uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70
|
||||
@ -101,7 +104,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@13ae5bb136fac2878aff31522b9efb785519f984 # @v2
|
||||
with:
|
||||
python-version: '3.10'
|
||||
python-version: '3.11'
|
||||
- name: Install System packages
|
||||
run: |
|
||||
sudo apt-get -y update
|
||||
@ -109,7 +112,7 @@ jobs:
|
||||
sudo apt-get install -y coreutils kcov csh zsh tcsh fish dash bash
|
||||
- name: Install Python packages
|
||||
run: |
|
||||
pip install --upgrade pip six setuptools pytest codecov coverage[toml]==6.2 pytest-xdist
|
||||
pip install --upgrade pip six setuptools pytest codecov coverage[toml] pytest-xdist
|
||||
- name: Setup git configuration
|
||||
run: |
|
||||
# Need this for the git tests to succeed.
|
||||
@ -158,7 +161,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@13ae5bb136fac2878aff31522b9efb785519f984 # @v2
|
||||
with:
|
||||
python-version: '3.10'
|
||||
python-version: '3.11'
|
||||
- name: Install System packages
|
||||
run: |
|
||||
sudo apt-get -y update
|
||||
|
6
.github/workflows/valid-style.yml
vendored
6
.github/workflows/valid-style.yml
vendored
@ -21,7 +21,7 @@ jobs:
|
||||
- uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # @v2
|
||||
- uses: actions/setup-python@13ae5bb136fac2878aff31522b9efb785519f984 # @v2
|
||||
with:
|
||||
python-version: '3.10'
|
||||
python-version: '3.11'
|
||||
cache: 'pip'
|
||||
- name: Install Python Packages
|
||||
run: |
|
||||
@ -40,7 +40,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@13ae5bb136fac2878aff31522b9efb785519f984 # @v2
|
||||
with:
|
||||
python-version: '3.10'
|
||||
python-version: '3.11'
|
||||
cache: 'pip'
|
||||
- name: Install Python packages
|
||||
run: |
|
||||
@ -57,4 +57,4 @@ jobs:
|
||||
uses: ./.github/workflows/audit.yaml
|
||||
with:
|
||||
with_coverage: ${{ inputs.with_coverage }}
|
||||
python_version: '3.10'
|
||||
python_version: '3.11'
|
||||
|
@ -1,5 +1,5 @@
|
||||
Name, Supported Versions, Notes, Requirement Reason
|
||||
Python, 2.7/3.6-3.10, , Interpreter for Spack
|
||||
Python, 2.7/3.6-3.11, , Interpreter for Spack
|
||||
C/C++ Compilers, , , Building software
|
||||
make, , , Build software
|
||||
patch, , , Build software
|
||||
|
|
@ -343,17 +343,21 @@ def add_command(self, cmd_name):
|
||||
self._remove_action(self._actions[-1])
|
||||
self.subparsers = self.add_subparsers(metavar="COMMAND", dest="command")
|
||||
|
||||
# each command module implements a parser() function, to which we
|
||||
# pass its subparser for setup.
|
||||
module = spack.cmd.get_module(cmd_name)
|
||||
if cmd_name not in self.subparsers._name_parser_map:
|
||||
# each command module implements a parser() function, to which we
|
||||
# pass its subparser for setup.
|
||||
module = spack.cmd.get_module(cmd_name)
|
||||
|
||||
# build a list of aliases
|
||||
alias_list = [k for k, v in aliases.items() if v == cmd_name]
|
||||
# build a list of aliases
|
||||
alias_list = [k for k, v in aliases.items() if v == cmd_name]
|
||||
|
||||
subparser = self.subparsers.add_parser(
|
||||
cmd_name, aliases=alias_list, help=module.description, description=module.description
|
||||
)
|
||||
module.setup_parser(subparser)
|
||||
subparser = self.subparsers.add_parser(
|
||||
cmd_name,
|
||||
aliases=alias_list,
|
||||
help=module.description,
|
||||
description=module.description,
|
||||
)
|
||||
module.setup_parser(subparser)
|
||||
|
||||
# return the callable function for the command
|
||||
return spack.cmd.get_command(cmd_name)
|
||||
|
@ -178,6 +178,71 @@ async def f():
|
||||
"""
|
||||
|
||||
|
||||
match_literal = """\
|
||||
match status:
|
||||
case 400:
|
||||
return "Bad request"
|
||||
case 404 | 418:
|
||||
return "Not found"
|
||||
case _:
|
||||
return "Something's wrong with the internet"
|
||||
"""
|
||||
|
||||
match_with_noop = """\
|
||||
match status:
|
||||
case 400:
|
||||
return "Bad request"
|
||||
"""
|
||||
|
||||
match_literal_and_variable = """\
|
||||
match point:
|
||||
case (0, 0):
|
||||
print("Origin")
|
||||
case (0, y):
|
||||
print(f"Y={y}")
|
||||
case (x, 0):
|
||||
print(f"X={x}")
|
||||
case (x, y):
|
||||
print(f"X={x}, Y={y}")
|
||||
case _:
|
||||
raise ValueError("Not a point")
|
||||
"""
|
||||
|
||||
|
||||
match_classes = """\
|
||||
class Point:
|
||||
x: int
|
||||
y: int
|
||||
|
||||
def location(point):
|
||||
match point:
|
||||
case Point(x=0, y=0):
|
||||
print("Origin is the point's location.")
|
||||
case Point(x=0, y=y):
|
||||
print(f"Y={y} and the point is on the y-axis.")
|
||||
case Point(x=x, y=0):
|
||||
print(f"X={x} and the point is on the x-axis.")
|
||||
case Point():
|
||||
print("The point is located somewhere else on the plane.")
|
||||
case _:
|
||||
print("Not a point")
|
||||
"""
|
||||
|
||||
match_nested = """\
|
||||
match points:
|
||||
case []:
|
||||
print("No points in the list.")
|
||||
case [Point(0, 0)]:
|
||||
print("The origin is the only point in the list.")
|
||||
case [Point(x, y)]:
|
||||
print(f"A single point {x}, {y} is in the list.")
|
||||
case [Point(0, y1), Point(0, y2)]:
|
||||
print(f"Two points on the Y axis at {y1}, {y2} are in the list.")
|
||||
case _:
|
||||
print("Something else is found in the list.")
|
||||
"""
|
||||
|
||||
|
||||
def check_ast_roundtrip(code1, filename="internal", mode="exec"):
|
||||
ast1 = compile(str(code1), filename, mode, ast.PyCF_ONLY_AST)
|
||||
code2 = spack.util.unparse.unparse(ast1)
|
||||
@ -512,3 +577,12 @@ def test_async_with():
|
||||
@pytest.mark.skipif(sys.version_info < (3, 5), reason="Not supported < 3.5")
|
||||
def test_async_with_as():
|
||||
check_ast_roundtrip(async_with_as)
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.version_info < (3, 10), reason="Not supported < 3.10")
|
||||
@pytest.mark.parametrize(
|
||||
"literal",
|
||||
[match_literal, match_with_noop, match_literal_and_variable, match_classes, match_nested],
|
||||
)
|
||||
def test_match_literal(literal):
|
||||
check_ast_roundtrip(literal)
|
||||
|
@ -1243,3 +1243,95 @@ def visit_withitem(self, node):
|
||||
if node.optional_vars:
|
||||
self.write(" as ")
|
||||
self.dispatch(node.optional_vars)
|
||||
|
||||
def visit_Match(self, node):
|
||||
self.fill("match ")
|
||||
self.dispatch(node.subject)
|
||||
with self.block():
|
||||
for case in node.cases:
|
||||
self.dispatch(case)
|
||||
|
||||
def visit_match_case(self, node):
|
||||
self.fill("case ")
|
||||
self.dispatch(node.pattern)
|
||||
if node.guard:
|
||||
self.write(" if ")
|
||||
self.dispatch(node.guard)
|
||||
with self.block():
|
||||
self.dispatch(node.body)
|
||||
|
||||
def visit_MatchValue(self, node):
|
||||
self.dispatch(node.value)
|
||||
|
||||
def visit_MatchSingleton(self, node):
|
||||
self._write_constant(node.value)
|
||||
|
||||
def visit_MatchSequence(self, node):
|
||||
with self.delimit("[", "]"):
|
||||
interleave(lambda: self.write(", "), self.dispatch, node.patterns)
|
||||
|
||||
def visit_MatchStar(self, node):
|
||||
name = node.name
|
||||
if name is None:
|
||||
name = "_"
|
||||
self.write("*{}".format(name))
|
||||
|
||||
def visit_MatchMapping(self, node):
|
||||
def write_key_pattern_pair(pair):
|
||||
k, p = pair
|
||||
self.dispatch(k)
|
||||
self.write(": ")
|
||||
self.dispatch(p)
|
||||
|
||||
with self.delimit("{", "}"):
|
||||
keys = node.keys
|
||||
interleave(
|
||||
lambda: self.write(", "),
|
||||
write_key_pattern_pair,
|
||||
zip(keys, node.patterns),
|
||||
)
|
||||
rest = node.rest
|
||||
if rest is not None:
|
||||
if keys:
|
||||
self.write(", ")
|
||||
self.write("**{}".format(rest))
|
||||
|
||||
def visit_MatchClass(self, node):
|
||||
self.set_precedence(_Precedence.ATOM, node.cls)
|
||||
self.dispatch(node.cls)
|
||||
with self.delimit("(", ")"):
|
||||
patterns = node.patterns
|
||||
interleave(lambda: self.write(", "), self.dispatch, patterns)
|
||||
attrs = node.kwd_attrs
|
||||
if attrs:
|
||||
|
||||
def write_attr_pattern(pair):
|
||||
attr, pattern = pair
|
||||
self.write("{}=".format(attr))
|
||||
self.dispatch(pattern)
|
||||
|
||||
if patterns:
|
||||
self.write(", ")
|
||||
interleave(
|
||||
lambda: self.write(", "),
|
||||
write_attr_pattern,
|
||||
zip(attrs, node.kwd_patterns),
|
||||
)
|
||||
|
||||
def visit_MatchAs(self, node):
|
||||
name = node.name
|
||||
pattern = node.pattern
|
||||
if name is None:
|
||||
self.write("_")
|
||||
elif pattern is None:
|
||||
self.write(node.name)
|
||||
else:
|
||||
with self.require_parens(_Precedence.TEST, node):
|
||||
self.set_precedence(_Precedence.BOR, node.pattern)
|
||||
self.dispatch(node.pattern)
|
||||
self.write(" as {}".format(node.name))
|
||||
|
||||
def visit_MatchOr(self, node):
|
||||
with self.require_parens(_Precedence.BOR, node):
|
||||
self.set_precedence(pnext(_Precedence.BOR), *node.patterns)
|
||||
interleave(lambda: self.write(" | "), self.dispatch, node.patterns)
|
||||
|
Loading…
Reference in New Issue
Block a user