diff --git a/test/conftest.py b/test/conftest.py index 0d1da891..b24be32d 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -1,5 +1,6 @@ import os import shutil +import re import tempfile import pytest @@ -96,9 +97,9 @@ class StaticAnalysisCase(object): def collect_comparison(self): cases = [] for line_nr, line in enumerate(self._source.splitlines(), 1): - if line.startswith('#! '): - rest = line[3:] - cases.append((line_nr + 1, rest)) + match = re.match(r'\s*#! (.*)$', line) + if match is not None: + cases.append((line_nr + 1, match.group(1))) return cases def run(self, compare_cb): diff --git a/test/static_analysis/attribute_error.py b/test/static_analysis/attribute_error.py new file mode 100644 index 00000000..a5a243e1 --- /dev/null +++ b/test/static_analysis/attribute_error.py @@ -0,0 +1,39 @@ +class Cls(): + class_attr = '' + def __init__(self, input): + self.instance_attr = 3 + self.input = input + + def f(self): + #! attribute-error + return self.not_existing + + def undefined_object(self, obj): + """ + Uses an arbitrary object and performs an operation on it, shouldn't + be a problem. + """ + obj.arbitrary_lookup + + def defined_lookup(self, obj): + """ + Uses an arbitrary object and performs an operation on it, shouldn't + be a problem. + """ + obj.upper + #! attribute-error + obj.arbitrary_lookup + + #! attribute-error + class_attr = a + +Cls().defined_lookup('') + +c = Cls() +c.class_attr +Cls.class_attr +#! attribute-error +Cls.class_attr_error +c.instance_attr +#! attribute-error +c.instance_attr_error