diff options
-rw-r--r-- | Lib/test/test_funcattrs.py | 180 |
1 files changed, 119 insertions, 61 deletions
diff --git a/Lib/test/test_funcattrs.py b/Lib/test/test_funcattrs.py index 6350aad0cb..9e526af5b3 100644 --- a/Lib/test/test_funcattrs.py +++ b/Lib/test/test_funcattrs.py @@ -13,15 +13,20 @@ class FuncAttrsTest(unittest.TestCase): self.fi = F() self.b = b - def cannot_set_attr(self,obj, name, value, exceptions): - # This method is not called as a test (name doesn't start with 'test'), - # but may be used by other tests. - try: setattr(obj, name, value) - except exceptions: pass - else: self.fail("shouldn't be able to set %s to %r" % (name, value)) - try: delattr(obj, name) - except exceptions: pass - else: self.fail("shouldn't be able to del %s" % name) + def cannot_set_attr(self, obj, name, value, exceptions): + # Helper method for other tests. + try: + setattr(obj, name, value) + except exceptions: + pass + else: + self.fail("shouldn't be able to set %s to %r" % (name, value)) + try: + delattr(obj, name) + except exceptions: + pass + else: + self.fail("shouldn't be able to del %s" % name) class FunctionPropertiesTest(FuncAttrsTest): @@ -32,15 +37,15 @@ class FunctionPropertiesTest(FuncAttrsTest): def test_dir_includes_correct_attrs(self): self.b.known_attr = 7 self.assertTrue('known_attr' in dir(self.b), - "set attributes not in dir listing of method") + "set attributes not in dir listing of method") # Test on underlying function object of method self.f.a.im_func.known_attr = 7 self.assertTrue('known_attr' in dir(self.f.a), - "set attribute on unbound method implementation in class not in " - "dir") + "set attribute on unbound method implementation in " + "class not in dir") self.assertTrue('known_attr' in dir(self.fi.a), - "set attribute on unbound method implementations, should show up" - " in next dir") + "set attribute on unbound method implementations, " + "should show up in next dir") def test_duplicate_function_equality(self): # Body of `duplicate' is the exact same as self.b @@ -56,9 +61,29 @@ class FunctionPropertiesTest(FuncAttrsTest): self.assertEqual(test(), 3) # self.b always returns 3, arbitrarily def test_func_globals(self): - self.assertEqual(self.b.func_globals, globals()) + self.assertIs(self.b.func_globals, globals()) self.cannot_set_attr(self.b, 'func_globals', 2, TypeError) + def test_func_closure(self): + a = 12 + def f(): print a + c = f.func_closure + self.assertTrue(isinstance(c, tuple)) + self.assertEqual(len(c), 1) + # don't have a type object handy + self.assertEqual(c[0].__class__.__name__, "cell") + self.cannot_set_attr(f, "func_closure", c, TypeError) + + def test_empty_cell(self): + def f(): print a + try: + f.func_closure[0].cell_contents + except ValueError: + pass + else: + self.fail("shouldn't be able to read an empty cell") + a = 12 + def test_func_name(self): self.assertEqual(self.b.__name__, 'b') self.assertEqual(self.b.func_name, 'b') @@ -96,16 +121,20 @@ class FunctionPropertiesTest(FuncAttrsTest): self.assertEqual(c.func_code, d.func_code) self.assertEqual(c(), 7) # self.assertEqual(d(), 7) - try: b.func_code = c.func_code - except ValueError: pass - else: self.fail( - "func_code with different numbers of free vars should not be " - "possible") - try: e.func_code = d.func_code - except ValueError: pass - else: self.fail( - "func_code with different numbers of free vars should not be " - "possible") + try: + b.func_code = c.func_code + except ValueError: + pass + else: + self.fail("func_code with different numbers of free vars should " + "not be possible") + try: + e.func_code = d.func_code + except ValueError: + pass + else: + self.fail("func_code with different numbers of free vars should " + "not be possible") def test_blank_func_defaults(self): self.assertEqual(self.b.func_defaults, None) @@ -126,13 +155,16 @@ class FunctionPropertiesTest(FuncAttrsTest): self.assertEqual(first_func(3, 5), 8) del second_func.func_defaults self.assertEqual(second_func.func_defaults, None) - try: second_func() - except TypeError: pass - else: self.fail( - "func_defaults does not update; deleting it does not remove " - "requirement") + try: + second_func() + except TypeError: + pass + else: + self.fail("func_defaults does not update; deleting it does not " + "remove requirement") + -class ImplicitReferencesTest(FuncAttrsTest): +class InstancemethodAttrTest(FuncAttrsTest): def test_im_class(self): self.assertEqual(self.f.a.im_class, self.f) self.assertEqual(self.fi.a.im_class, self.f) @@ -159,9 +191,12 @@ class ImplicitReferencesTest(FuncAttrsTest): self.assertEqual(self.fi.id(), id(self.fi)) self.assertNotEqual(self.fi.id(), id(self.f)) # Test usage - try: self.f.id.unknown_attr - except AttributeError: pass - else: self.fail("using unknown attributes should raise AttributeError") + try: + self.f.id.unknown_attr + except AttributeError: + pass + else: + self.fail("using unknown attributes should raise AttributeError") # Test assignment and deletion self.cannot_set_attr(self.f.id, 'unknown_attr', 2, AttributeError) self.cannot_set_attr(self.fi.id, 'unknown_attr', 2, AttributeError) @@ -171,35 +206,50 @@ class ImplicitReferencesTest(FuncAttrsTest): self.assertEqual(self.f.a.known_attr, 7) self.assertEqual(self.fi.a.known_attr, 7) + class ArbitraryFunctionAttrTest(FuncAttrsTest): def test_set_attr(self): + # setting attributes only works on function objects self.b.known_attr = 7 self.assertEqual(self.b.known_attr, 7) for func in [self.f.a, self.fi.a]: - try: func.known_attr = 7 - except AttributeError: pass - else: self.fail("setting attributes on methods should raise error") + try: + func.known_attr = 7 + except AttributeError: + pass + else: + self.fail("setting attributes on methods should raise error") def test_delete_unknown_attr(self): - try: del self.b.unknown_attr - except AttributeError: pass - else: self.fail("deleting unknown attribute should raise TypeError") + try: + del self.b.unknown_attr + except AttributeError: + pass + else: + self.fail("deleting unknown attribute should raise TypeError") def test_setting_attrs_duplicates(self): - try: self.f.a.klass = self.f - except AttributeError: pass - else: self.fail("setting arbitrary attribute in unbound function " - " should raise AttributeError") + try: + self.f.a.klass = self.f + except AttributeError: + pass + else: + self.fail("setting arbitrary attribute in unbound function " + " should raise AttributeError") self.f.a.im_func.klass = self.f for method in [self.f.a, self.fi.a, self.fi.a.im_func]: self.assertEqual(method.klass, self.f) def test_unset_attr(self): for func in [self.b, self.f.a, self.fi.a]: - try: func.non_existent_attr - except AttributeError: pass - else: self.fail("using unknown attributes should raise " - "AttributeError") + try: + func.non_existent_attr + except AttributeError: + pass + else: + self.fail("using unknown attributes should raise " + "AttributeError") + class FunctionDictsTest(FuncAttrsTest): def test_setting_dict_to_invalid(self): @@ -216,13 +266,13 @@ class FunctionDictsTest(FuncAttrsTest): # Setting dict is only possible on the underlying function objects self.f.a.im_func.__dict__ = d # Test assignment - self.assertEqual(d, self.b.__dict__) - self.assertEqual(d, self.b.func_dict) + self.assertIs(d, self.b.__dict__) + self.assertIs(d, self.b.func_dict) # ... and on all the different ways of referencing the method's func - self.assertEqual(d, self.f.a.im_func.__dict__) - self.assertEqual(d, self.f.a.__dict__) - self.assertEqual(d, self.fi.a.im_func.__dict__) - self.assertEqual(d, self.fi.a.__dict__) + self.assertIs(d, self.f.a.im_func.__dict__) + self.assertIs(d, self.f.a.__dict__) + self.assertIs(d, self.fi.a.im_func.__dict__) + self.assertIs(d, self.fi.a.__dict__) # Test value self.assertEqual(self.b.known_attr, 7) self.assertEqual(self.b.__dict__['known_attr'], 7) @@ -234,12 +284,18 @@ class FunctionDictsTest(FuncAttrsTest): self.assertEqual(self.fi.a.known_attr, 7) def test_delete_func_dict(self): - try: del self.b.__dict__ - except TypeError: pass - else: self.fail("deleting function dictionary should raise TypeError") - try: del self.b.func_dict - except TypeError: pass - else: self.fail("deleting function dictionary should raise TypeError") + try: + del self.b.__dict__ + except TypeError: + pass + else: + self.fail("deleting function dictionary should raise TypeError") + try: + del self.b.func_dict + except TypeError: + pass + else: + self.fail("deleting function dictionary should raise TypeError") def test_unassigned_dict(self): self.assertEqual(self.b.__dict__, {}) @@ -250,6 +306,7 @@ class FunctionDictsTest(FuncAttrsTest): d[self.b] = value self.assertEqual(d[self.b], value) + class FunctionDocstringTest(FuncAttrsTest): def test_set_docstring_attr(self): self.assertEqual(self.b.__doc__, None) @@ -273,6 +330,7 @@ class FunctionDocstringTest(FuncAttrsTest): self.assertEqual(self.b.__doc__, None) self.assertEqual(self.b.func_doc, None) + class StaticMethodAttrsTest(unittest.TestCase): def test_func_attribute(self): def f(): @@ -286,7 +344,7 @@ class StaticMethodAttrsTest(unittest.TestCase): def test_main(): - test_support.run_unittest(FunctionPropertiesTest, ImplicitReferencesTest, + test_support.run_unittest(FunctionPropertiesTest, InstancemethodAttrTest, ArbitraryFunctionAttrTest, FunctionDictsTest, FunctionDocstringTest, StaticMethodAttrsTest) |