def test_annotate_without_annotations(self): # This instrumentation works in both Python 2 & Python 3. def fn(hello): "unused" fn.__annotations__ = {'hello': 'hello:world'} jeni.annotate(fn) self.assertTrue(jeni.annotate.has_annotations(fn))
def test_annotate_without_annotations(self): def fn(hello): "unused" self.assertRaises(AttributeError, jeni.annotate, fn) fn.__annotations__ = {} self.assertRaises(AttributeError, jeni.annotate, fn) fn.__annotations__ = {'hello': 'hello:world'} jeni.annotate(fn) self.assertTrue(jeni.annotate.has_annotations(fn))
def test_multiple_annotations(self): @jeni.annotate('foo', 'bar') def fn(foo, bar): "unused" decorator = jeni.annotate('baz', 'quux') self.assertRaises(AttributeError, decorator, fn)
def test_annotate_without_dunder_annotations(self): # Unclear when this would come up; testing it given Python 2 support. class NoDunderAnnotations(object): def __getattr__(self, name): if name == '__annotations__': raise AttributeError() return super().__getattr__(name) def __call__(self): "unused" fn = NoDunderAnnotations() self.assertTrue(hasattr(fn, '__call__')) self.assertFalse(hasattr(fn, '__annotations__')) self.assertFalse(hasattr(fn, 'fake')) # coverage with self.assertRaises(AttributeError): jeni.annotate(fn)
def test_annotate_fn_name_keyword(self): # Test that annotation of 'fn' is not accidentally reserved by jeni. def foo(fn=None): "unused" decorator = jeni.annotate(fn='function') try: decorator(foo) raise TypeError('code coverage support') except TypeError: _, err, _ = sys.exc_info() msg = "Annotation cannot support argument named 'fn'." if 'coverage' not in str(err): self.fail(msg)
def test_annotate_without_annotations(self): def fn(hello): "unused" jeni.annotate(fn) self.assertTrue(jeni.annotate.has_annotations(fn))