diff options
Diffstat (limited to 'Lib')
-rwxr-xr-x | Lib/pdb.py | 4 | ||||
-rwxr-xr-x | Lib/pydoc.py | 12 | ||||
-rw-r--r-- | Lib/test/test_funcattrs.py | 125 | ||||
-rw-r--r-- | Lib/test/test_pdb.py | 88 |
4 files changed, 158 insertions, 71 deletions
@@ -208,7 +208,9 @@ class Pdb(bdb.Bdb, cmd.Cmd): """Custom displayhook for the exec in default(), which prevents assignment of the _ variable in the builtins. """ - print(repr(obj)) + # reproduce the behavior of the standard displayhook, not printing None + if obj is not None: + print(repr(obj)) def default(self, line): if line[:1] == '!': line = line[1:] diff --git a/Lib/pydoc.py b/Lib/pydoc.py index fe439c2..68771c9 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -1557,7 +1557,7 @@ class Helper: 'global': ('global', 'NAMESPACES'), 'if': ('if', 'TRUTHVALUE'), 'import': ('import', 'MODULES'), - 'in': ('in', 'SEQUENCEMETHODS2'), + 'in': ('in', 'SEQUENCEMETHODS'), 'is': 'COMPARISON', 'lambda': ('lambda', 'FUNCTIONS'), 'not': 'BOOLEAN', @@ -1643,12 +1643,12 @@ class Helper: 'PRECEDENCE': 'EXPRESSIONS', 'OBJECTS': ('objects', 'TYPES'), 'SPECIALMETHODS': ('specialnames', 'BASICMETHODS ATTRIBUTEMETHODS ' - 'CALLABLEMETHODS SEQUENCEMETHODS1 MAPPINGMETHODS ' - 'SEQUENCEMETHODS2 NUMBERMETHODS CLASSES'), + 'CALLABLEMETHODS SEQUENCEMETHODS MAPPINGMETHODS ' + 'NUMBERMETHODS CLASSES'), 'BASICMETHODS': ('customization', 'hash repr str SPECIALMETHODS'), 'ATTRIBUTEMETHODS': ('attribute-access', 'ATTRIBUTES SPECIALMETHODS'), 'CALLABLEMETHODS': ('callable-types', 'CALLS SPECIALMETHODS'), - 'SEQUENCEMETHODS': ('sequence-types', 'SEQUENCES SEQUENCEMETHODS2 ' + 'SEQUENCEMETHODS': ('sequence-types', 'SEQUENCES SEQUENCEMETHODS ' 'SPECIALMETHODS'), 'MAPPINGMETHODS': ('sequence-types', 'MAPPINGS SPECIALMETHODS'), 'NUMBERMETHODS': ('numeric-types', 'NUMBERS AUGMENTEDASSIGNMENT ' @@ -1672,8 +1672,8 @@ class Helper: 'DICTIONARIES': ('typesmapping', 'DICTIONARYLITERALS'), 'DICTIONARYLITERALS': ('dict', 'DICTIONARIES LITERALS'), 'ATTRIBUTES': ('attribute-references', 'getattr hasattr setattr ATTRIBUTEMETHODS'), - 'SUBSCRIPTS': ('subscriptions', 'SEQUENCEMETHODS1'), - 'SLICINGS': ('slicings', 'SEQUENCEMETHODS2'), + 'SUBSCRIPTS': ('subscriptions', 'SEQUENCEMETHODS'), + 'SLICINGS': ('slicings', 'SEQUENCEMETHODS'), 'CALLS': ('calls', 'EXPRESSIONS'), 'POWER': ('power', 'EXPRESSIONS'), 'UNARY': ('unary', 'EXPRESSIONS'), diff --git a/Lib/test/test_funcattrs.py b/Lib/test/test_funcattrs.py index 5765b4e..d1d03a3 100644 --- a/Lib/test/test_funcattrs.py +++ b/Lib/test/test_funcattrs.py @@ -56,8 +56,29 @@ class FunctionPropertiesTest(FuncAttrsTest): self.assertEqual(test(), 3) # self.b always returns 3, arbitrarily def test___globals__(self): - self.assertEqual(self.b.__globals__, globals()) - self.cannot_set_attr(self.b, '__globals__', 2, (AttributeError, TypeError)) + self.assertIs(self.b.__globals__, globals()) + self.cannot_set_attr(self.b, '__globals__', 2, + (AttributeError, TypeError)) + + def test___closure__(self): + a = 12 + def f(): print(a) + c = f.__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, "__closure__", c, AttributeError) + + def test_empty_cell(self): + def f(): print(a) + try: + f.__closure__[0].cell_contents + except ValueError: + pass + else: + self.fail("shouldn't be able to read an empty cell") + a = 12 def test___name__(self): self.assertEqual(self.b.__name__, 'b') @@ -90,16 +111,20 @@ class FunctionPropertiesTest(FuncAttrsTest): self.assertEqual(c.__code__, d.__code__) self.assertEqual(c(), 7) # self.assertEqual(d(), 7) - try: b.__code__ = c.__code__ - except ValueError: pass - else: self.fail( - "__code__ with different numbers of free vars should not be " - "possible") - try: e.__code__ = d.__code__ - except ValueError: pass - else: self.fail( - "__code__ with different numbers of free vars should not be " - "possible") + try: + b.__code__ = c.__code__ + except ValueError: + pass + else: + self.fail("__code__ with different numbers of free vars should " + "not be possible") + try: + e.__code__ = d.__code__ + except ValueError: + pass + else: + self.fail("__code__ with different numbers of free vars should " + "not be possible") def test_blank_func_defaults(self): self.assertEqual(self.b.__defaults__, None) @@ -120,13 +145,16 @@ class FunctionPropertiesTest(FuncAttrsTest): self.assertEqual(first_func(3, 5), 8) del second_func.__defaults__ self.assertEqual(second_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("__defaults__ does not update; deleting it does not " + "remove requirement") -class ImplicitReferencesTest(FuncAttrsTest): + +class InstancemethodAttrTest(FuncAttrsTest): def test___class__(self): self.assertEqual(self.fi.a.__self__.__class__, self.F) @@ -146,31 +174,45 @@ class ImplicitReferencesTest(FuncAttrsTest): self.fi.id = types.MethodType(id, self.fi) self.assertEqual(self.fi.id(), id(self.fi)) # Test usage - try: self.fi.id.unknown_attr - except AttributeError: pass - else: self.fail("using unknown attributes should raise AttributeError") + try: + self.fi.id.unknown_attr + except AttributeError: + pass + else: + self.fail("using unknown attributes should raise AttributeError") # Test assignment and deletion self.cannot_set_attr(self.fi.id, 'unknown_attr', 2, AttributeError) + class ArbitraryFunctionAttrTest(FuncAttrsTest): def test_set_attr(self): self.b.known_attr = 7 self.assertEqual(self.b.known_attr, 7) - try: self.fi.a.known_attr = 7 - except AttributeError: pass - else: self.fail("setting attributes on methods should raise error") + try: + self.fi.a.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_unset_attr(self): for func in [self.b, 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): @@ -183,11 +225,11 @@ class FunctionDictsTest(FuncAttrsTest): d = {'known_attr': 7} self.b.__dict__ = d # Test assignment - self.assertEqual(d, self.b.__dict__) + self.assertIs(d, self.b.__dict__) # ... and on all the different ways of referencing the method's func self.F.a.__dict__ = d - self.assertEqual(d, self.fi.a.__func__.__dict__) - self.assertEqual(d, self.fi.a.__dict__) + self.assertIs(d, self.fi.a.__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) @@ -196,9 +238,12 @@ class FunctionDictsTest(FuncAttrsTest): self.assertEqual(self.fi.a.known_attr, 7) def test_delete___dict__(self): - try: del self.b.__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") def test_unassigned_dict(self): self.assertEqual(self.b.__dict__, {}) @@ -209,6 +254,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) @@ -224,6 +270,7 @@ class FunctionDocstringTest(FuncAttrsTest): del self.b.__doc__ self.assertEqual(self.b.__doc__, None) + def cell(value): """Create a cell containing the given value.""" def f(): @@ -242,6 +289,7 @@ def empty_cell(empty=True): a = 1729 return f.__closure__[0] + class CellTest(unittest.TestCase): def test_comparison(self): # These tests are here simply to exercise the comparison code; @@ -254,6 +302,7 @@ class CellTest(unittest.TestCase): self.assertTrue(cell(-36) == cell(-36.0)) self.assertTrue(cell(True) > empty_cell()) + class StaticMethodAttrsTest(unittest.TestCase): def test_func_attribute(self): def f(): @@ -267,7 +316,7 @@ class StaticMethodAttrsTest(unittest.TestCase): def test_main(): - support.run_unittest(FunctionPropertiesTest, ImplicitReferencesTest, + support.run_unittest(FunctionPropertiesTest, InstancemethodAttrTest, ArbitraryFunctionAttrTest, FunctionDictsTest, FunctionDocstringTest, CellTest, StaticMethodAttrsTest) diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index bcd4853..5d52707 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -12,6 +12,49 @@ from test import support from test.test_doctest import _FakeInput +class PdbTestInput(object): + """Context manager that makes testing Pdb in doctests easier.""" + + def __init__(self, input): + self.input = input + + def __enter__(self): + self.real_stdin = sys.stdin + sys.stdin = _FakeInput(self.input) + + def __exit__(self, *exc): + sys.stdin = self.real_stdin + + +def test_pdb_displayhook(): + """This tests the custom displayhook for pdb. + + >>> def test_function(foo, bar): + ... import pdb; pdb.Pdb().set_trace() + ... pass + + >>> with PdbTestInput([ + ... 'foo', + ... 'bar', + ... 'for i in range(5): print(i)', + ... 'continue', + ... ]): + ... test_function(1, None) + > <doctest test.test_pdb.test_pdb_displayhook[0]>(3)test_function() + -> pass + (Pdb) foo + 1 + (Pdb) bar + (Pdb) for i in range(5): print(i) + 0 + 1 + 2 + 3 + 4 + (Pdb) continue + """ + + def test_pdb_skip_modules(): """This illustrates the simple case of module skipping. @@ -19,16 +62,12 @@ def test_pdb_skip_modules(): ... import string ... import pdb; pdb.Pdb(skip=['stri*']).set_trace() ... string.capwords('FOO') - >>> real_stdin = sys.stdin - >>> sys.stdin = _FakeInput([ - ... 'step', - ... 'continue', - ... ]) - >>> try: + >>> with PdbTestInput([ + ... 'step', + ... 'continue', + ... ]): ... skip_module() - ... finally: - ... sys.stdin = real_stdin > <doctest test.test_pdb.test_pdb_skip_modules[0]>(4)skip_module() -> string.capwords('FOO') (Pdb) step @@ -36,7 +75,7 @@ def test_pdb_skip_modules(): > <doctest test.test_pdb.test_pdb_skip_modules[0]>(4)skip_module()->None -> string.capwords('FOO') (Pdb) continue -""" + """ # Module for testing skipping of module that makes a callback @@ -50,22 +89,19 @@ def test_pdb_skip_modules_with_callback(): >>> def skip_module(): ... def callback(): ... return None - ... import pdb;pdb.Pdb(skip=['module_to_skip*']).set_trace() + ... import pdb; pdb.Pdb(skip=['module_to_skip*']).set_trace() ... mod.foo_pony(callback) - >>> real_stdin = sys.stdin - >>> sys.stdin = _FakeInput([ - ... 'step', - ... 'step', - ... 'step', - ... 'step', - ... 'step', - ... 'continue', - ... ]) - - >>> try: + + >>> with PdbTestInput([ + ... 'step', + ... 'step', + ... 'step', + ... 'step', + ... 'step', + ... 'continue', + ... ]): ... skip_module() - ... finally: - ... sys.stdin = real_stdin + ... pass # provides something to "step" to > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(5)skip_module() -> mod.foo_pony(callback) (Pdb) step @@ -84,10 +120,10 @@ def test_pdb_skip_modules_with_callback(): > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(5)skip_module()->None -> mod.foo_pony(callback) (Pdb) step - > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[3]>(4)<module>() - -> sys.stdin = real_stdin + > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[1]>(10)<module>() + -> pass # provides something to "step" to (Pdb) continue -""" + """ def test_main(): |