From 301b55986f4aa0ef607f69f022484092341c57fc Mon Sep 17 00:00:00 2001 From: Jacob Walls Date: Tue, 10 May 2022 11:15:35 -0400 Subject: [PATCH] Require Python 3.7.2 (#1542) --- .github/workflows/ci.yaml | 6 +- .pre-commit-config.yaml | 2 +- ChangeLog | 2 + astroid/brain/brain_crypt.py | 31 ++++---- astroid/brain/brain_dataclasses.py | 29 ++++---- astroid/brain/brain_re.py | 9 ++- astroid/brain/brain_subprocess.py | 82 +++++++--------------- astroid/brain/brain_typing.py | 37 ++++------ astroid/const.py | 2 - astroid/nodes/scoped_nodes/scoped_nodes.py | 18 +++-- astroid/rebuilder.py | 20 +----- setup.cfg | 3 +- tests/unittest_brain.py | 16 +---- tests/unittest_brain_dataclasses.py | 5 -- tests/unittest_scoped_nodes.py | 11 --- tox.ini | 2 +- 16 files changed, 96 insertions(+), 179 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9a115fe754..68bb87f36e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -81,7 +81,7 @@ jobs: strategy: fail-fast: true matrix: - python-version: [3.6, 3.7, 3.8, 3.9, "3.10"] + python-version: [3.7, 3.8, 3.9, "3.10"] outputs: python-key: ${{ steps.generate-python-key.outputs.key }} steps: @@ -233,7 +233,7 @@ jobs: strategy: fail-fast: true matrix: - python-version: [3.6, 3.7, 3.8, 3.9, "3.10"] + python-version: [3.7, 3.8, 3.9, "3.10"] steps: - name: Set temp directory run: echo "TEMP=$env:USERPROFILE\AppData\Local\Temp" >> $env:GITHUB_ENV @@ -282,7 +282,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["pypy-3.6", "pypy-3.7", "pypy-3.8"] + python-version: ["pypy-3.7", "pypy-3.8"] steps: - name: Check out code from GitHub uses: actions/checkout@v3.0.2 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8661d0d2ba..16ea6d30e3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -32,7 +32,7 @@ repos: hooks: - id: pyupgrade exclude: tests/testdata - args: [--py36-plus] + args: [--py37-plus] - repo: https://github.com/PyCQA/isort rev: 5.10.1 hooks: diff --git a/ChangeLog b/ChangeLog index cfbd305b77..a418b1b7af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,8 @@ What's New in astroid 2.12.0? ============================= Release date: TBA +* ``astroid`` now requires Python 3.7.2 to run. + * Fix ``re`` brain on Python ``3.11``. The flags now come from ``re._compile``. * Build ``nodes.Module`` for frozen modules which have location information in their diff --git a/astroid/brain/brain_crypt.py b/astroid/brain/brain_crypt.py index 45c305529b..312353c6aa 100644 --- a/astroid/brain/brain_crypt.py +++ b/astroid/brain/brain_crypt.py @@ -4,25 +4,22 @@ from astroid.brain.helpers import register_module_extender from astroid.builder import parse -from astroid.const import PY37_PLUS from astroid.manager import AstroidManager -if PY37_PLUS: - # Since Python 3.7 Hashing Methods are added - # dynamically to globals() - def _re_transform(): - return parse( - """ - from collections import namedtuple - _Method = namedtuple('_Method', 'name ident salt_chars total_size') - - METHOD_SHA512 = _Method('SHA512', '6', 16, 106) - METHOD_SHA256 = _Method('SHA256', '5', 16, 63) - METHOD_BLOWFISH = _Method('BLOWFISH', 2, 'b', 22) - METHOD_MD5 = _Method('MD5', '1', 8, 34) - METHOD_CRYPT = _Method('CRYPT', None, 2, 13) +def _re_transform(): + return parse( """ - ) + from collections import namedtuple + _Method = namedtuple('_Method', 'name ident salt_chars total_size') + + METHOD_SHA512 = _Method('SHA512', '6', 16, 106) + METHOD_SHA256 = _Method('SHA256', '5', 16, 63) + METHOD_BLOWFISH = _Method('BLOWFISH', 2, 'b', 22) + METHOD_MD5 = _Method('MD5', '1', 8, 34) + METHOD_CRYPT = _Method('CRYPT', None, 2, 13) + """ + ) + - register_module_extender(AstroidManager(), "crypt", _re_transform) +register_module_extender(AstroidManager(), "crypt", _re_transform) diff --git a/astroid/brain/brain_dataclasses.py b/astroid/brain/brain_dataclasses.py index 769d9ee9d3..8f21fd44dc 100644 --- a/astroid/brain/brain_dataclasses.py +++ b/astroid/brain/brain_dataclasses.py @@ -17,7 +17,7 @@ from astroid import context, inference_tip from astroid.builder import parse -from astroid.const import PY37_PLUS, PY39_PLUS +from astroid.const import PY39_PLUS from astroid.exceptions import ( AstroidSyntaxError, InferenceError, @@ -449,19 +449,18 @@ def _infer_instance_from_annotation( yield klass.instantiate_class() -if PY37_PLUS: - AstroidManager().register_transform( - ClassDef, dataclass_transform, is_decorated_with_dataclass - ) +AstroidManager().register_transform( + ClassDef, dataclass_transform, is_decorated_with_dataclass +) - AstroidManager().register_transform( - Call, - inference_tip(infer_dataclass_field_call, raise_on_overwrite=True), - _looks_like_dataclass_field_call, - ) +AstroidManager().register_transform( + Call, + inference_tip(infer_dataclass_field_call, raise_on_overwrite=True), + _looks_like_dataclass_field_call, +) - AstroidManager().register_transform( - Unknown, - inference_tip(infer_dataclass_attribute, raise_on_overwrite=True), - _looks_like_dataclass_attribute, - ) +AstroidManager().register_transform( + Unknown, + inference_tip(infer_dataclass_attribute, raise_on_overwrite=True), + _looks_like_dataclass_attribute, +) diff --git a/astroid/brain/brain_re.py b/astroid/brain/brain_re.py index a9f4686056..8e0d9d46ac 100644 --- a/astroid/brain/brain_re.py +++ b/astroid/brain/brain_re.py @@ -7,7 +7,7 @@ from astroid import context, inference_tip, nodes from astroid.brain.helpers import register_module_extender from astroid.builder import _extract_single_node, parse -from astroid.const import PY37_PLUS, PY39_PLUS, PY311_PLUS +from astroid.const import PY39_PLUS, PY311_PLUS from astroid.manager import AstroidManager @@ -90,7 +90,6 @@ def infer_pattern_match( return iter([class_def]) -if PY37_PLUS: - AstroidManager().register_transform( - nodes.Call, inference_tip(infer_pattern_match), _looks_like_pattern_or_match - ) +AstroidManager().register_transform( + nodes.Call, inference_tip(infer_pattern_match), _looks_like_pattern_or_match +) diff --git a/astroid/brain/brain_subprocess.py b/astroid/brain/brain_subprocess.py index ec52e0b3f9..1a409ba998 100644 --- a/astroid/brain/brain_subprocess.py +++ b/astroid/brain/brain_subprocess.py @@ -6,7 +6,7 @@ from astroid.brain.helpers import register_module_extender from astroid.builder import parse -from astroid.const import PY37_PLUS, PY39_PLUS +from astroid.const import PY39_PLUS from astroid.manager import AstroidManager @@ -17,9 +17,7 @@ def _subprocess_transform(): self, args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, restore_signals=True, - start_new_session=False, pass_fds=(), *, encoding=None, errors=None""" - if PY37_PLUS: - args += ", text=None" + start_new_session=False, pass_fds=(), *, encoding=None, errors=None, text=None""" init = f""" def __init__({args}): pass""" @@ -30,57 +28,31 @@ def __exit__(self, *args): pass """ py3_args = "args = []" - if PY37_PLUS: - check_output_signature = """ - check_output( - args, *, - stdin=None, - stderr=None, - shell=False, - cwd=None, - encoding=None, - errors=None, - universal_newlines=False, - timeout=None, - env=None, - text=None, - restore_signals=True, - preexec_fn=None, - pass_fds=(), - input=None, - bufsize=0, - executable=None, - close_fds=False, - startupinfo=None, - creationflags=0, - start_new_session=False - ): - """.strip() - else: - check_output_signature = """ - check_output( - args, *, - stdin=None, - stderr=None, - shell=False, - cwd=None, - encoding=None, - errors=None, - universal_newlines=False, - timeout=None, - env=None, - restore_signals=True, - preexec_fn=None, - pass_fds=(), - input=None, - bufsize=0, - executable=None, - close_fds=False, - startupinfo=None, - creationflags=0, - start_new_session=False - ): - """.strip() + check_output_signature = """ + check_output( + args, *, + stdin=None, + stderr=None, + shell=False, + cwd=None, + encoding=None, + errors=None, + universal_newlines=False, + timeout=None, + env=None, + text=None, + restore_signals=True, + preexec_fn=None, + pass_fds=(), + input=None, + bufsize=0, + executable=None, + close_fds=False, + startupinfo=None, + creationflags=0, + start_new_session=False + ): + """.strip() code = textwrap.dedent( f""" diff --git a/astroid/brain/brain_typing.py b/astroid/brain/brain_typing.py index 6077773f62..cc8b2a0af4 100644 --- a/astroid/brain/brain_typing.py +++ b/astroid/brain/brain_typing.py @@ -8,7 +8,7 @@ from astroid import context, extract_node, inference_tip from astroid.builder import _extract_single_node -from astroid.const import PY37_PLUS, PY38_PLUS, PY39_PLUS +from astroid.const import PY38_PLUS, PY39_PLUS from astroid.exceptions import ( AttributeInferenceError, InferenceError, @@ -148,22 +148,16 @@ def infer_typing_attr( except (InferenceError, StopIteration) as exc: raise UseInferenceDefault from exc - if ( - not value.qname().startswith("typing.") - or PY37_PLUS - and value.qname() in TYPING_ALIAS - ): - # If typing subscript belongs to an alias - # (PY37+) handle it separately. + if not value.qname().startswith("typing.") or value.qname() in TYPING_ALIAS: + # If typing subscript belongs to an alias handle it separately. raise UseInferenceDefault - if ( - PY37_PLUS - and isinstance(value, ClassDef) - and value.qname() - in {"typing.Generic", "typing.Annotated", "typing_extensions.Annotated"} - ): - # With PY37+ typing.Generic and typing.Annotated (PY39) are subscriptable + if isinstance(value, ClassDef) and value.qname() in { + "typing.Generic", + "typing.Annotated", + "typing_extensions.Annotated", + }: + # typing.Generic and typing.Annotated (PY39) are subscriptable # through __class_getitem__. Since astroid can't easily # infer the native methods, replace them for an easy inference tip func_to_add = _extract_single_node(CLASS_GETITEM_TEMPLATE) @@ -424,10 +418,9 @@ def infer_typing_cast( ClassDef, inference_tip(infer_old_typedDict), _looks_like_typedDict ) -if PY37_PLUS: - AstroidManager().register_transform( - Call, inference_tip(infer_typing_alias), _looks_like_typing_alias - ) - AstroidManager().register_transform( - Call, inference_tip(infer_special_alias), _looks_like_special_alias - ) +AstroidManager().register_transform( + Call, inference_tip(infer_typing_alias), _looks_like_typing_alias +) +AstroidManager().register_transform( + Call, inference_tip(infer_special_alias), _looks_like_special_alias +) diff --git a/astroid/const.py b/astroid/const.py index 375c03d076..87682c942f 100644 --- a/astroid/const.py +++ b/astroid/const.py @@ -6,9 +6,7 @@ import sys from pathlib import Path -PY36 = sys.version_info[:2] == (3, 6) PY38 = sys.version_info[:2] == (3, 8) -PY37_PLUS = sys.version_info >= (3, 7) PY38_PLUS = sys.version_info >= (3, 8) PY39_PLUS = sys.version_info >= (3, 9) PY310_PLUS = sys.version_info >= (3, 10) diff --git a/astroid/nodes/scoped_nodes/scoped_nodes.py b/astroid/nodes/scoped_nodes/scoped_nodes.py index 4762ed223d..ff14190258 100644 --- a/astroid/nodes/scoped_nodes/scoped_nodes.py +++ b/astroid/nodes/scoped_nodes/scoped_nodes.py @@ -13,7 +13,17 @@ import sys import typing import warnings -from typing import TYPE_CHECKING, Dict, List, Optional, Set, TypeVar, Union, overload +from typing import ( + TYPE_CHECKING, + Dict, + List, + NoReturn, + Optional, + Set, + TypeVar, + Union, + overload, +) from astroid import bases from astroid import decorators as decorators_mod @@ -44,12 +54,6 @@ from astroid.nodes.scoped_nodes.utils import builtin_lookup from astroid.nodes.utils import Position -if sys.version_info >= (3, 6, 2): - from typing import NoReturn -else: - from typing_extensions import NoReturn - - if sys.version_info >= (3, 8): from functools import cached_property from typing import Literal diff --git a/astroid/rebuilder.py b/astroid/rebuilder.py index 77ab10524a..e4c961b5c9 100644 --- a/astroid/rebuilder.py +++ b/astroid/rebuilder.py @@ -9,7 +9,6 @@ import ast import sys import token -import tokenize from io import StringIO from tokenize import TokenInfo, generate_tokens from typing import ( @@ -29,7 +28,7 @@ from astroid import nodes from astroid._ast import ParserModule, get_parser_module, parse_function_type_comment -from astroid.const import IS_PYPY, PY36, PY38, PY38_PLUS, PY39_PLUS, Context +from astroid.const import IS_PYPY, PY38, PY38_PLUS, PY39_PLUS, Context from astroid.manager import AstroidManager from astroid.nodes import NodeNG from astroid.nodes.utils import Position @@ -148,12 +147,6 @@ def _get_position_info( keyword_tokens: Tuple[int, ...] = (token.NAME,) if isinstance(parent, nodes.AsyncFunctionDef): search_token = "async" - if PY36: - # In Python 3.6, the token type for 'async' was 'ASYNC' - # In Python 3.7, the type was changed to 'NAME' and 'ASYNC' removed - # Python 3.8 added it back. However, if we use it unconditionally - # we would break 3.7. - keyword_tokens = (token.NAME, token.ASYNC) elif isinstance(parent, nodes.FunctionDef): search_token = "def" else: @@ -200,12 +193,7 @@ def _fix_doc_node_position(self, node: NodesWithDocsType) -> None: found_start, found_end = False, False open_brackets = 0 - skip_token: Set[int] = {token.NEWLINE, token.INDENT} - if PY36: - skip_token.update((tokenize.NL, tokenize.COMMENT)) - else: - # token.NL and token.COMMENT were added in 3.7 - skip_token.update((token.NL, token.COMMENT)) + skip_token: Set[int] = {token.NEWLINE, token.INDENT, token.NL, token.COMMENT} if isinstance(node, nodes.Module): found_end = True @@ -1294,10 +1282,6 @@ def _visit_functiondef( position=self._get_position_info(node, newnode), doc_node=self.visit(doc_ast_node, newnode), ) - if IS_PYPY and PY36 and newnode.position: - # PyPy: col_offset in Python 3.6 doesn't include 'async', - # use position.col_offset instead. - newnode.col_offset = newnode.position.col_offset self._fix_doc_node_position(newnode) self._global_names.pop() return newnode diff --git a/setup.cfg b/setup.cfg index e30d844d86..fa7c436e00 100644 --- a/setup.cfg +++ b/setup.cfg @@ -20,7 +20,6 @@ classifiers = Programming Language :: Python Programming Language :: Python :: 3 Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 @@ -43,7 +42,7 @@ install_requires = setuptools>=20.0 typed-ast>=1.4.0,<2.0;implementation_name=="cpython" and python_version<"3.8" typing-extensions>=3.10;python_version<"3.10" -python_requires = >=3.6.2 +python_requires = >=3.7.2 [options.packages.find] include = diff --git a/tests/unittest_brain.py b/tests/unittest_brain.py index 989cebda2f..3a15a89b18 100644 --- a/tests/unittest_brain.py +++ b/tests/unittest_brain.py @@ -15,7 +15,6 @@ import astroid from astroid import MANAGER, bases, builder, nodes, objects, test_utils, util from astroid.bases import Instance -from astroid.const import PY37_PLUS from astroid.exceptions import ( AttributeInferenceError, InferenceError, @@ -1659,7 +1658,6 @@ class Foo: attr = next(attr_def.infer()) self.assertEqual(attr.value, "bar") - @test_utils.require_version(minver="3.7") def test_tuple_type(self): node = builder.extract_node( """ @@ -1672,7 +1670,6 @@ def test_tuple_type(self): assert isinstance(inferred.getattr("__class_getitem__")[0], nodes.FunctionDef) assert inferred.qname() == "typing.Tuple" - @test_utils.require_version(minver="3.7") def test_callable_type(self): node = builder.extract_node( """ @@ -1685,7 +1682,6 @@ def test_callable_type(self): assert isinstance(inferred.getattr("__class_getitem__")[0], nodes.FunctionDef) assert inferred.qname() == "typing.Callable" - @test_utils.require_version(minver="3.7") def test_typing_generic_subscriptable(self): """Test typing.Generic is subscriptable with __class_getitem__ (added in PY37)""" node = builder.extract_node( @@ -1712,7 +1708,6 @@ def test_typing_annotated_subscriptable(self): assert isinstance(inferred, nodes.ClassDef) assert isinstance(inferred.getattr("__class_getitem__")[0], nodes.FunctionDef) - @test_utils.require_version(minver="3.7") def test_typing_generic_slots(self): """Test slots for Generic subclass.""" node = builder.extract_node( @@ -1779,7 +1774,6 @@ class CustomTD(TypedDict): #@ # Test TypedDict instance is callable assert next(code[1].infer()).callable() is True - @test_utils.require_version(minver="3.7") def test_typing_alias_type(self): """ Test that the type aliased thanks to typing._alias function are @@ -1813,7 +1807,6 @@ class Derived1(MutableSet[T]): ], ) - @test_utils.require_version(minver="3.7.2") def test_typing_alias_type_2(self): """ Test that the type aliased thanks to typing._alias function are @@ -1840,7 +1833,6 @@ class Derived2(typing.OrderedDict[int, str]): ], ) - @test_utils.require_version(minver="3.7") def test_typing_object_not_subscriptable(self): """Hashable is not subscriptable""" wrong_node = builder.extract_node( @@ -1869,7 +1861,6 @@ def test_typing_object_not_subscriptable(self): with self.assertRaises(AttributeInferenceError): inferred.getattr("__class_getitem__") - @test_utils.require_version(minver="3.7") def test_typing_object_subscriptable(self): """Test that MutableSet is subscriptable""" right_node = builder.extract_node( @@ -1896,7 +1887,6 @@ def test_typing_object_subscriptable(self): inferred.getattr("__class_getitem__")[0], nodes.FunctionDef ) - @test_utils.require_version(minver="3.7") def test_typing_object_subscriptable_2(self): """Multiple inheritance with subscriptable typing alias""" node = builder.extract_node( @@ -1920,7 +1910,6 @@ class Derived(typing.Hashable, typing.Iterator[int]): ], ) - @test_utils.require_version(minver="3.7") def test_typing_object_notsubscriptable_3(self): """Until python39 ByteString class of the typing module is not subscritable (whereas it is in the collections module)""" right_node = builder.extract_node( @@ -2006,11 +1995,10 @@ def test_regex_flags(self) -> None: self.assertIn(name, re_ast) self.assertEqual(next(re_ast[name].infer()).value, getattr(re, name)) - @test_utils.require_version(minver="3.7", maxver="3.9") + @test_utils.require_version(maxver="3.9") def test_re_pattern_unsubscriptable(self): """ re.Pattern and re.Match are unsubscriptable until PY39. - re.Pattern and re.Match were added in PY37. """ right_node1 = builder.extract_node( """ @@ -3110,7 +3098,6 @@ def test_http_client_brain() -> None: assert isinstance(inferred, astroid.Instance) -@pytest.mark.skipif(not PY37_PLUS, reason="Needs 3.7+") def test_http_status_brain() -> None: node = astroid.extract_node( """ @@ -3147,7 +3134,6 @@ def test_oserror_model() -> None: assert strerror.value == "" -@pytest.mark.skipif(not PY37_PLUS, reason="Dynamic module attributes since Python 3.7") def test_crypt_brain() -> None: module = MANAGER.ast_from_module_name("crypt") dynamic_attrs = [ diff --git a/tests/unittest_brain_dataclasses.py b/tests/unittest_brain_dataclasses.py index fa0a2047e8..6d45c0c7ec 100644 --- a/tests/unittest_brain_dataclasses.py +++ b/tests/unittest_brain_dataclasses.py @@ -6,14 +6,9 @@ import astroid from astroid import bases, nodes -from astroid.const import PY37_PLUS from astroid.exceptions import InferenceError from astroid.util import Uninferable -if not PY37_PLUS: - pytest.skip("Dataclasses were added in 3.7", allow_module_level=True) - - parametrize_module = pytest.mark.parametrize( ("module",), (["dataclasses"], ["pydantic.dataclasses"], ["marshmallow_dataclass"]) ) diff --git a/tests/unittest_scoped_nodes.py b/tests/unittest_scoped_nodes.py index cf01a5f7e4..0061399550 100644 --- a/tests/unittest_scoped_nodes.py +++ b/tests/unittest_scoped_nodes.py @@ -1724,7 +1724,6 @@ class C(scope.A, scope.B): assert isinstance(cls, nodes.ClassDef) self.assertEqualMro(cls, ["C", "A", "B", "object"]) - @test_utils.require_version(minver="3.7") def test_mro_generic_1(self): cls = builder.extract_node( """ @@ -1740,7 +1739,6 @@ class C(A[T], B): ... cls, [".C", ".A", "typing.Generic", ".B", "builtins.object"] ) - @test_utils.require_version(minver="3.7") def test_mro_generic_2(self): cls = builder.extract_node( """ @@ -1756,7 +1754,6 @@ class C(Generic[T], A, B[T]): ... cls, [".C", ".A", ".B", "typing.Generic", "builtins.object"] ) - @test_utils.require_version(minver="3.7") def test_mro_generic_3(self): cls = builder.extract_node( """ @@ -1773,7 +1770,6 @@ class D(B[T], C[T], Generic[T]): ... cls, [".D", ".B", ".A", ".C", "typing.Generic", "builtins.object"] ) - @test_utils.require_version(minver="3.7") def test_mro_generic_4(self): cls = builder.extract_node( """ @@ -1789,7 +1785,6 @@ class C(A, Generic[T], B[T]): ... cls, [".C", ".A", ".B", "typing.Generic", "builtins.object"] ) - @test_utils.require_version(minver="3.7") def test_mro_generic_5(self): cls = builder.extract_node( """ @@ -1806,7 +1801,6 @@ class C(A[T1], B[T2]): ... cls, [".C", ".A", ".B", "typing.Generic", "builtins.object"] ) - @test_utils.require_version(minver="3.7") def test_mro_generic_6(self): cls = builder.extract_node( """ @@ -1823,7 +1817,6 @@ class C(A, B[T]): ... cls, [".C", ".A", ".Generic", ".B", "typing.Generic", "builtins.object"] ) - @test_utils.require_version(minver="3.7") def test_mro_generic_7(self): cls = builder.extract_node( """ @@ -1841,7 +1834,6 @@ class E(C[str], D): ... cls, [".E", ".C", ".A", ".B", "typing.Generic", ".D", "builtins.object"] ) - @test_utils.require_version(minver="3.7") def test_mro_generic_error_1(self): cls = builder.extract_node( """ @@ -1855,7 +1847,6 @@ class A(Generic[T1], Generic[T2]): ... with self.assertRaises(DuplicateBasesError): cls.mro() - @test_utils.require_version(minver="3.7") def test_mro_generic_error_2(self): cls = builder.extract_node( """ @@ -1869,7 +1860,6 @@ class B(A[T], A[T]): ... with self.assertRaises(DuplicateBasesError): cls.mro() - @test_utils.require_version(minver="3.7") def test_mro_typing_extensions(self): """Regression test for mro() inference on typing_extesnions. @@ -2544,7 +2534,6 @@ def func(a, b=1, /, c=2): pass assert first_param.value == 1 -@test_utils.require_version(minver="3.7") def test_ancestor_with_generic() -> None: # https://github.com/PyCQA/astroid/issues/942 tree = builder.parse( diff --git a/tox.ini b/tox.ini index 64d30d7460..35e7d9e8dc 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py{36,37,38,39,310} +envlist = py{37,38,39,310} skip_missing_interpreters = true [testenv:pylint]