Skip to content

Commit

Permalink
Fix crash caused by attr.s being passed a decorated class.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 309459874
  • Loading branch information
rchen152 committed May 5, 2020
1 parent 3b98201 commit ee90a8d
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 0 deletions.
4 changes: 4 additions & 0 deletions pytype/overlays/classgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ def get_class_locals(self, cls, allow_methods, ordering):
# TODO(rechen): Once we drop Python 2 support, either use a normal dict or
# replace key deletion with OrderedDict.move_to_end().
out = collections.OrderedDict()
if cls.name not in self.vm.local_ops:
# See TestAttribPy3.test_cannot_decorate in tests/py3/test_attr.py. The
# class will not be in local_ops if a previous decorator hides it.
return out
for op in self.vm.local_ops[cls.name]:
if is_dunder(op.name):
continue
Expand Down
1 change: 1 addition & 0 deletions pytype/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,7 @@ py_test(
test_attr.py
DEPS
.test_base
pytype.utils
)

py_test(
Expand Down
23 changes: 23 additions & 0 deletions pytype/tests/py3/test_attr.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Tests for attrs library in attr_overlay.py."""

from pytype import file_utils
from pytype.tests import test_base


Expand Down Expand Up @@ -104,6 +105,28 @@ class Foo(object):
def __init__(self, x: int = ..., y: str = ...) -> None: ...
""")

def test_cannot_decorate(self):
# Tests the attr.s decorator being passed an object it can't process.
with file_utils.Tempdir() as d:
d.create_file("foo.pyi", """
from typing import Type
class Foo: ...
def decorate(cls: Type[Foo]) -> Type[Foo]: ...
""")
ty = self.Infer("""
import attr
import foo
@attr.s
@foo.decorate
class Bar(foo.Foo): ...
""", pythonpath=[d.path])
self.assertTypesMatchPytd(ty, """
from typing import Type
attr: module
foo: module
Bar: Type[foo.Foo]
""")


class TestAttrs(test_base.TargetPython3FeatureTest):
"""Tests for attr.s."""
Expand Down

0 comments on commit ee90a8d

Please sign in to comment.