Skip to content

Commit

Permalink
Added def-time check for disallowed override on __init__
Browse files Browse the repository at this point in the history
  • Loading branch information
Stewori committed Dec 12, 2016
1 parent 875a90e commit 11cf05b
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 8 deletions.
14 changes: 12 additions & 2 deletions src/test_typechecker.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,10 @@ def testmeth7(self, a):
# type:(int) -> testClass2
pass


class testClass2(testClass2Base):
@override
def __repr__(self, a): # Should fail because of arg-mismatch
def __repr__(self, a): # Should fail because of arg-count mismatch
return super(testClass2, self).__repr__()

def testmeth0(self,
Expand Down Expand Up @@ -350,7 +351,7 @@ def testmeth_err(self, a, b):
# type: (int, Real) -> int
return '-'.join((str(a), str(b), self))

return testClass2b('blah')
return testClass2b()

def testClass2_defTimeCheck2():
class testClass2b(testClass2Base):
Expand Down Expand Up @@ -384,6 +385,12 @@ class testClass3b(testClass3Base):
def testmeth(self, a, b):
return '-'.join((str(a), str(b), str(type(self))))

def testClass2_defTimeCheck_init_ov():
class testClass2_defTime_init_ov(testClass2Base):
@override
def __init__(self): # should fail because of invalid use of @override
pass


@typechecked
def testfunc(a, # type: int
Expand Down Expand Up @@ -564,9 +571,12 @@ def test_override_at_definition_time(self):
self.assertRaises(OverrideError, lambda: testClass2_defTimeCheck3())
self.assertRaises(OverrideError, lambda: testClass2_defTimeCheck4())
testClass3_defTimeCheck()
self.assertRaises(OverrideError, lambda: testClass2_defTimeCheck_init_ov())
typechecker.check_override_at_class_definition_time = tmp

def test_override_at_definition_time_with_forward_decl(self):
# This can only be sufficiently tested at import-time, so
# we import helper-modules during this test.
tmp = typechecker.check_override_at_class_definition_time
typechecker.check_override_at_class_definition_time = True
import override_testhelper # shall not raise error
Expand Down
8 changes: 2 additions & 6 deletions src/typechecker.py
Original file line number Diff line number Diff line change
Expand Up @@ -573,8 +573,8 @@ def _check_override_types(method, meth_types, class_name, base_method, base_clas

raise OverrideError('%s cannot override %s.\n'
% (fq_name_child, fq_name_parent)
+ 'Incompatible argument types: %s is not a subtype of %s.'
% (_type_str(base_types[0]), _type_str(meth_types[0])))
+ 'Incompatible argument types: %s is not a supertype of %s.'
% (_type_str(meth_types[0]), _type_str(base_types[0])))
if not issubclass(meth_types[1], base_types[1]):
fq_name_child = _fully_qualified_func_name(method, True, None, class_name)
fq_name_parent = _fully_qualified_func_name(base_method, True, base_class)
Expand Down Expand Up @@ -666,10 +666,6 @@ def override(func):

mro_set = set() # contains everything in would-be-mro, however in unspecified order
mro_pool = [base_classes]
# for base_cls in base_classes:
# if not is_builtin_type(base_cls):
# mro_set.add(base_cls)
# mro_pool.append(base_cls.__bases__)
while len(mro_pool) > 0:
lst = mro_pool.pop()
for base_cls in lst:
Expand Down

0 comments on commit 11cf05b

Please sign in to comment.