From c0304a74d99b596ad1d0df59d53c072652e75cf0 Mon Sep 17 00:00:00 2001 From: David Liu Date: Thu, 19 Aug 2021 08:32:06 -0400 Subject: [PATCH 1/2] Update test requirements to astroid 2.7.1 --- requirements_test_min.txt | 2 +- setup.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements_test_min.txt b/requirements_test_min.txt index 1a60d73840..7a9e7745bb 100644 --- a/requirements_test_min.txt +++ b/requirements_test_min.txt @@ -1,4 +1,4 @@ -e . -astroid==2.7.0 # Pinned to a specific version for tests +astroid==2.7.1 # Pinned to a specific version for tests pytest~=6.2 pytest-benchmark~=3.4 diff --git a/setup.cfg b/setup.cfg index 322d85ea31..28a8dda4ee 100644 --- a/setup.cfg +++ b/setup.cfg @@ -43,7 +43,7 @@ project_urls = packages = find: install_requires = appdirs>=1.4.0 - astroid>=2.7.0,<2.8 # (You should also upgrade requirements_test_min.txt) + astroid>=2.7.1,<2.8 # (You should also upgrade requirements_test_min.txt) isort>=4.2.5,<6 mccabe>=0.6,<0.7 toml>=0.7.1 From f1cba5050cb611e8cd9880aba3b47804fad00260 Mon Sep 17 00:00:00 2001 From: David Liu Date: Wed, 18 Aug 2021 21:16:45 -0400 Subject: [PATCH 2/2] Add typecheck tests for dataclass attributes --- .../d/deprecated/dataclass_typecheck.py | 115 ++++++++++++++++++ .../d/deprecated/dataclass_typecheck.rc | 2 + .../d/deprecated/dataclass_typecheck.txt | 12 ++ 3 files changed, 129 insertions(+) create mode 100644 tests/functional/d/deprecated/dataclass_typecheck.py create mode 100644 tests/functional/d/deprecated/dataclass_typecheck.rc create mode 100644 tests/functional/d/deprecated/dataclass_typecheck.txt diff --git a/tests/functional/d/deprecated/dataclass_typecheck.py b/tests/functional/d/deprecated/dataclass_typecheck.py new file mode 100644 index 0000000000..9a2be2fb86 --- /dev/null +++ b/tests/functional/d/deprecated/dataclass_typecheck.py @@ -0,0 +1,115 @@ +"""Tests for dataclass attributes with basic type annotations. + +Tests for regressions from https://github.com/PyCQA/astroid/pull/1126 +""" +# pylint: disable=missing-docstring,too-few-public-methods,pointless-statement,redefined-builtin, fixme +from dataclasses import dataclass +from typing import Callable, Dict, List, Optional + + +class Dummy: + pass + + +@dataclass +class MyClass: + # Attribute inference does not support Optional, so Uninferable is yielded + # This should not trigger any type errors from pylint + attr0: Optional[Dummy] + + attr1: int + attr2: str + attr3: Callable[[int], int] + attr4: List[int] + attr5: Dict[str, str] + + +obj = MyClass(None, 1, 'hi', lambda x: x, [], {}) + +lst = [0, 1, 2] +print(lst[obj.attr0]) +print(lst[obj.attr1]) +print(lst[obj.attr2]) # [invalid-sequence-index] + +print(lst[obj.attr0::]) +print(lst[obj.attr1::]) +print(lst[obj.attr2::]) # [invalid-slice-index] + +obj.attr0(100) +obj.attr1(100) # [not-callable] +obj.attr3(100) + +print(-obj.attr0) +print(-obj.attr1) +print(-obj.attr2) # [invalid-unary-operand-type] + +print(1 + obj.attr0) +print(1 + obj.attr1) +print(1 + obj.attr2) # Should be an error here once unsupported-binary-operation is enabled + +print(1 in obj.attr0) +print(1 in obj.attr1) # [unsupported-membership-test] +print(1 in obj.attr4) +print('hi' in obj.attr5) + +print(obj.attr0[1]) +print(obj.attr1[1]) # [unsubscriptable-object] +print(obj.attr4[1]) +print(obj.attr5['hi']) + +obj.attr0[1] = 1 +obj.attr1[1] = 1 # [unsupported-assignment-operation] +obj.attr4[1] = 1 +obj.attr5['hi'] = 'bye' + +del obj.attr0[1] +del obj.attr1[1] # [unsupported-delete-operation] +del obj.attr4[1] +del obj.attr5['hi'] + + +class Manager: + def __enter__(self): + pass + + def __exit__(self, type_, value, traceback): + pass + + +@dataclass +class MyClass2: + attr0: Optional[Dummy] + attr1: Manager + attr2: str + + +obj2 = MyClass2(None, Manager(), 'hi') +with obj2.attr0: + pass +with obj2.attr1: + pass +with obj2.attr2: # [not-context-manager] + pass + + +class Test1(metaclass=obj.attr0): + pass + + +class Test2(metaclass=obj.attr1): # [invalid-metaclass] + pass + + +{}[obj.attr0] = 1 +{}[obj.attr1] = 1 +{}[obj.attr5] = 1 # [unhashable-dict-key] + +for k, v in obj.attr5: # TODO: Should be an dict-iter-missing-items error + print(k, v) + +__name__ = obj.attr0 +__name__ = obj.attr1 # TODO: Should be a non-str-assignment-to-dunder-name error +__name__ = obj.attr2 + +print(isinstance(1, obj.attr0)) +print(isinstance(1, obj.attr1)) # [isinstance-second-argument-not-valid-type] diff --git a/tests/functional/d/deprecated/dataclass_typecheck.rc b/tests/functional/d/deprecated/dataclass_typecheck.rc new file mode 100644 index 0000000000..a17bb22daf --- /dev/null +++ b/tests/functional/d/deprecated/dataclass_typecheck.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.7 diff --git a/tests/functional/d/deprecated/dataclass_typecheck.txt b/tests/functional/d/deprecated/dataclass_typecheck.txt new file mode 100644 index 0000000000..529f4aab95 --- /dev/null +++ b/tests/functional/d/deprecated/dataclass_typecheck.txt @@ -0,0 +1,12 @@ +invalid-sequence-index:32:6::Sequence index is not an int, slice, or instance with __index__:HIGH +invalid-slice-index:36:0::Slice index is not an int, None, or instance with __index__:HIGH +not-callable:39:0::obj.attr1 is not callable:HIGH +invalid-unary-operand-type:44:6::"bad operand type for unary -: str":HIGH +unsupported-membership-test:51:11::Value 'obj.attr1' doesn't support membership test:HIGH +unsubscriptable-object:56:6::Value 'obj.attr1' is unsubscriptable:HIGH +unsupported-assignment-operation:61:0::'obj.attr1' does not support item assignment:HIGH +unsupported-delete-operation:66:4::'obj.attr1' does not support item deletion:HIGH +not-context-manager:91:0::Context manager 'str' doesn't implement __enter__ and __exit__.:HIGH +invalid-metaclass:99:0:Test2:Invalid metaclass 'Instance of builtins.int' used:HIGH +unhashable-dict-key:105:0::Dict key is unhashable:HIGH +isinstance-second-argument-not-valid-type:115:6::Second argument of isinstance is not a type:HIGH