From 2ee0e8eaec7f6e87664c2c9297633623cbd28868 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 23 May 2008 05:03:59 +0000 Subject: Revert the renaming of repr to reprlib. --- Demo/pdist/cmptree.py | 2 +- Demo/pdist/server.py | 2 +- Doc/library/datatypes.rst | 2 +- Doc/library/repr.rst | 139 ++++++++++++++++++ Doc/library/reprlib.rst | 143 ------------------- Doc/tutorial/stdlib2.rst | 6 +- Lib/bdb.py | 6 +- Lib/copy.py | 19 +-- Lib/idlelib/Debugger.py | 4 +- Lib/idlelib/ObjectBrowser.py | 2 +- Lib/pdb.py | 2 +- Lib/pydoc.py | 2 +- Lib/repr.py | 132 +++++++++++++++++ Lib/reprlib.py | 132 ----------------- Lib/test/test___all__.py | 2 +- Lib/test/test_py3kwarn.py | 2 +- Lib/test/test_repr.py | 327 +++++++++++++++++++++++++++++++++++++++++++ Lib/test/test_reprlib.py | 327 ------------------------------------------- Misc/NEWS | 3 - 19 files changed, 624 insertions(+), 630 deletions(-) create mode 100644 Doc/library/repr.rst delete mode 100644 Doc/library/reprlib.rst create mode 100644 Lib/repr.py delete mode 100644 Lib/reprlib.py create mode 100644 Lib/test/test_repr.py delete mode 100644 Lib/test/test_reprlib.py diff --git a/Demo/pdist/cmptree.py b/Demo/pdist/cmptree.py index dccd3ae..f6c611f 100755 --- a/Demo/pdist/cmptree.py +++ b/Demo/pdist/cmptree.py @@ -1,7 +1,7 @@ """Compare local and remote dictionaries and transfer differing files -- like rdist.""" import sys -from reprlib import repr +from repr import repr import FSProxy import time import os diff --git a/Demo/pdist/server.py b/Demo/pdist/server.py index ea70e71..e692eea 100755 --- a/Demo/pdist/server.py +++ b/Demo/pdist/server.py @@ -4,7 +4,7 @@ import sys import socket import pickle from fnmatch import fnmatch -from reprlib import repr +from repr import repr # Default verbosity (0 = silent, 1 = print connections, 2 = print requests too) diff --git a/Doc/library/datatypes.rst b/Doc/library/datatypes.rst index b6b37ab..4ebaa6c 100644 --- a/Doc/library/datatypes.rst +++ b/Doc/library/datatypes.rst @@ -36,4 +36,4 @@ The following modules are documented in this chapter: new.rst copy.rst pprint.rst - reprlib.rst + repr.rst diff --git a/Doc/library/repr.rst b/Doc/library/repr.rst new file mode 100644 index 0000000..bd9743d --- /dev/null +++ b/Doc/library/repr.rst @@ -0,0 +1,139 @@ + +:mod:`repr` --- Alternate :func:`repr` implementation +===================================================== + +.. module:: repr + :synopsis: Alternate repr() implementation with size limits. +.. sectionauthor:: Fred L. Drake, Jr. + +.. note:: + The :mod:`repr` module has been renamed to :mod:`reprlib` in + Python 3.0. + +The :mod:`repr` module provides a means for producing object representations +with limits on the size of the resulting strings. This is used in the Python +debugger and may be useful in other contexts as well. + +This module provides a class, an instance, and a function: + + +.. class:: Repr() + + Class which provides formatting services useful in implementing functions + similar to the built-in :func:`repr`; size limits for different object types + are added to avoid the generation of representations which are excessively long. + + +.. data:: aRepr + + This is an instance of :class:`Repr` which is used to provide the :func:`repr` + function described below. Changing the attributes of this object will affect + the size limits used by :func:`repr` and the Python debugger. + + +.. function:: repr(obj) + + This is the :meth:`repr` method of ``aRepr``. It returns a string similar to + that returned by the built-in function of the same name, but with limits on + most sizes. + + +.. _repr-objects: + +Repr Objects +------------ + +:class:`Repr` instances provide several members which can be used to provide +size limits for the representations of different object types, and methods +which format specific object types. + + +.. attribute:: Repr.maxlevel + + Depth limit on the creation of recursive representations. The default is ``6``. + + +.. attribute:: Repr.maxdict + Repr.maxlist + Repr.maxtuple + Repr.maxset + Repr.maxfrozenset + Repr.maxdeque + Repr.maxarray + + Limits on the number of entries represented for the named object type. The + default is ``4`` for :attr:`maxdict`, ``5`` for :attr:`maxarray`, and ``6`` for + the others. + + .. versionadded:: 2.4 + :attr:`maxset`, :attr:`maxfrozenset`, and :attr:`set`. + + +.. attribute:: Repr.maxlong + + Maximum number of characters in the representation for a long integer. Digits + are dropped from the middle. The default is ``40``. + + +.. attribute:: Repr.maxstring + + Limit on the number of characters in the representation of the string. Note + that the "normal" representation of the string is used as the character source: + if escape sequences are needed in the representation, these may be mangled when + the representation is shortened. The default is ``30``. + + +.. attribute:: Repr.maxother + + This limit is used to control the size of object types for which no specific + formatting method is available on the :class:`Repr` object. It is applied in a + similar manner as :attr:`maxstring`. The default is ``20``. + + +.. method:: Repr.repr(obj) + + The equivalent to the built-in :func:`repr` that uses the formatting imposed by + the instance. + + +.. method:: Repr.repr1(obj, level) + + Recursive implementation used by :meth:`repr`. This uses the type of *obj* to + determine which formatting method to call, passing it *obj* and *level*. The + type-specific methods should call :meth:`repr1` to perform recursive formatting, + with ``level - 1`` for the value of *level* in the recursive call. + + +.. method:: Repr.repr_TYPE(obj, level) + :noindex: + + Formatting methods for specific types are implemented as methods with a name + based on the type name. In the method name, **TYPE** is replaced by + ``string.join(string.split(type(obj).__name__, '_'))``. Dispatch to these + methods is handled by :meth:`repr1`. Type-specific methods which need to + recursively format a value should call ``self.repr1(subobj, level - 1)``. + + +.. _subclassing-reprs: + +Subclassing Repr Objects +------------------------ + +The use of dynamic dispatching by :meth:`Repr.repr1` allows subclasses of +:class:`Repr` to add support for additional built-in object types or to modify +the handling of types already supported. This example shows how special support +for file objects could be added:: + + import repr + import sys + + class MyRepr(repr.Repr): + def repr_file(self, obj, level): + if obj.name in ['', '', '']: + return obj.name + else: + return `obj` + + aRepr = MyRepr() + print aRepr.repr(sys.stdin) # prints '' + diff --git a/Doc/library/reprlib.rst b/Doc/library/reprlib.rst deleted file mode 100644 index c4859be..0000000 --- a/Doc/library/reprlib.rst +++ /dev/null @@ -1,143 +0,0 @@ -:mod:`reprlib` --- Alternate :func:`repr` implementation -======================================================== - -.. module:: repr - :synopsis: Old name for the reprlib module. - -.. module:: reprlib - :synopsis: Alternate repr() implementation with size limits. -.. sectionauthor:: Fred L. Drake, Jr. - -.. note:: - The :mod:`repr` module has been renamed to :mod:`reprlib` in - Python 3.0. It is importable under both names in Python 2.6 - and the rest of the 2.x series. - - -The :mod:`reprlib` module provides a means for producing object representations -with limits on the size of the resulting strings. This is used in the Python -debugger and may be useful in other contexts as well. - -This module provides a class, an instance, and a function: - - -.. class:: Repr() - - Class which provides formatting services useful in implementing functions - similar to the built-in :func:`repr`; size limits for different object types - are added to avoid the generation of representations which are excessively long. - - -.. data:: aRepr - - This is an instance of :class:`Repr` which is used to provide the :func:`repr` - function described below. Changing the attributes of this object will affect - the size limits used by :func:`repr` and the Python debugger. - - -.. function:: repr(obj) - - This is the :meth:`repr` method of ``aRepr``. It returns a string similar to - that returned by the built-in function of the same name, but with limits on - most sizes. - - -.. _repr-objects: - -Repr Objects ------------- - -:class:`Repr` instances provide several members which can be used to provide -size limits for the representations of different object types, and methods -which format specific object types. - - -.. attribute:: Repr.maxlevel - - Depth limit on the creation of recursive representations. The default is ``6``. - - -.. attribute:: Repr.maxdict - Repr.maxlist - Repr.maxtuple - Repr.maxset - Repr.maxfrozenset - Repr.maxdeque - Repr.maxarray - - Limits on the number of entries represented for the named object type. The - default is ``4`` for :attr:`maxdict`, ``5`` for :attr:`maxarray`, and ``6`` for - the others. - - .. versionadded:: 2.4 - :attr:`maxset`, :attr:`maxfrozenset`, and :attr:`set`. - - -.. attribute:: Repr.maxlong - - Maximum number of characters in the representation for a long integer. Digits - are dropped from the middle. The default is ``40``. - - -.. attribute:: Repr.maxstring - - Limit on the number of characters in the representation of the string. Note - that the "normal" representation of the string is used as the character source: - if escape sequences are needed in the representation, these may be mangled when - the representation is shortened. The default is ``30``. - - -.. attribute:: Repr.maxother - - This limit is used to control the size of object types for which no specific - formatting method is available on the :class:`Repr` object. It is applied in a - similar manner as :attr:`maxstring`. The default is ``20``. - - -.. method:: Repr.repr(obj) - - The equivalent to the built-in :func:`repr` that uses the formatting imposed by - the instance. - - -.. method:: Repr.repr1(obj, level) - - Recursive implementation used by :meth:`repr`. This uses the type of *obj* to - determine which formatting method to call, passing it *obj* and *level*. The - type-specific methods should call :meth:`repr1` to perform recursive formatting, - with ``level - 1`` for the value of *level* in the recursive call. - - -.. method:: Repr.repr_TYPE(obj, level) - :noindex: - - Formatting methods for specific types are implemented as methods with a name - based on the type name. In the method name, **TYPE** is replaced by - ``string.join(string.split(type(obj).__name__, '_'))``. Dispatch to these - methods is handled by :meth:`repr1`. Type-specific methods which need to - recursively format a value should call ``self.repr1(subobj, level - 1)``. - - -.. _subclassing-reprs: - -Subclassing Repr Objects ------------------------- - -The use of dynamic dispatching by :meth:`Repr.repr1` allows subclasses of -:class:`Repr` to add support for additional built-in object types or to modify -the handling of types already supported. This example shows how special support -for file objects could be added:: - - import repr - import sys - - class MyRepr(repr.Repr): - def repr_file(self, obj, level): - if obj.name in ['', '', '']: - return obj.name - else: - return `obj` - - aRepr = MyRepr() - print aRepr.repr(sys.stdin) # prints '' - diff --git a/Doc/tutorial/stdlib2.rst b/Doc/tutorial/stdlib2.rst index 79044f9..9da5213 100644 --- a/Doc/tutorial/stdlib2.rst +++ b/Doc/tutorial/stdlib2.rst @@ -13,11 +13,11 @@ programming needs. These modules rarely occur in small scripts. Output Formatting ================= -The :mod:`reprlib` module provides a version of :func:`repr` customized for +The :mod:`repr` module provides a version of :func:`repr` customized for abbreviated displays of large or deeply nested containers:: - >>> import reprlib - >>> reprlib.repr(set('supercalifragilisticexpialidocious')) + >>> import repr + >>> repr.repr(set('supercalifragilisticexpialidocious')) "set(['a', 'c', 'd', 'e', 'f', 'g', ...])" The :mod:`pprint` module offers more sophisticated control over printing both diff --git a/Lib/bdb.py b/Lib/bdb.py index 5e4d7b4..74870e3 100644 --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -325,7 +325,7 @@ class Bdb: # def format_stack_entry(self, frame_lineno, lprefix=': '): - import linecache, reprlib + import linecache, repr frame, lineno = frame_lineno filename = self.canonic(frame.f_code.co_filename) s = '%s(%r)' % (filename, lineno) @@ -338,13 +338,13 @@ class Bdb: else: args = None if args: - s = s + reprlib.repr(args) + s = s + repr.repr(args) else: s = s + '()' if '__return__' in frame.f_locals: rv = frame.f_locals['__return__'] s = s + '->' - s = s + reprlib.repr(rv) + s = s + repr.repr(rv) line = linecache.getline(filename, lineno) if line: s = s + lprefix + line.strip() return s diff --git a/Lib/copy.py b/Lib/copy.py index f3871e5..3f2033f 100644 --- a/Lib/copy.py +++ b/Lib/copy.py @@ -399,16 +399,17 @@ def _test(): print l2 l.append({l[1]: l, 'xyz': l[2]}) l3 = copy(l) - import reprlib - print map(reprlib.repr, l) - print map(reprlib.repr, l1) - print map(reprlib.repr, l2) - print map(reprlib.repr, l3) + import repr + print map(repr.repr, l) + print map(repr.repr, l1) + print map(repr.repr, l2) + print map(repr.repr, l3) l3 = deepcopy(l) - print map(reprlib.repr, l) - print map(reprlib.repr, l1) - print map(reprlib.repr, l2) - print map(reprlib.repr, l3) + import repr + print map(repr.repr, l) + print map(repr.repr, l1) + print map(repr.repr, l2) + print map(repr.repr, l3) if __name__ == '__main__': _test() diff --git a/Lib/idlelib/Debugger.py b/Lib/idlelib/Debugger.py index a56c224..f56460a 100644 --- a/Lib/idlelib/Debugger.py +++ b/Lib/idlelib/Debugger.py @@ -413,8 +413,8 @@ class NamespaceViewer: height = 20*len(dict) # XXX 20 == observed height of Entry widget self.master = master self.title = title - import reprlib - self.repr = reprlib.Repr() + import repr + self.repr = repr.Repr() self.repr.maxstring = 60 self.repr.maxother = 60 self.frame = frame = Frame(master) diff --git a/Lib/idlelib/ObjectBrowser.py b/Lib/idlelib/ObjectBrowser.py index 8ff0041..a2a6cee 100644 --- a/Lib/idlelib/ObjectBrowser.py +++ b/Lib/idlelib/ObjectBrowser.py @@ -11,7 +11,7 @@ from TreeWidget import TreeItem, TreeNode, ScrolledCanvas -from reprlib import Repr +from repr import Repr myrepr = Repr() myrepr.maxstring = 100 diff --git a/Lib/pdb.py b/Lib/pdb.py index 3ed7a2f..8616202 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -8,7 +8,7 @@ import sys import linecache import cmd import bdb -from reprlib import Repr +from repr import Repr import os import re import pprint diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 987d213..8007ed0 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -53,7 +53,7 @@ Richard Chamberlain, for the first implementation of textdoc. # path will be displayed. import sys, imp, os, re, types, inspect, __builtin__, pkgutil -from reprlib import Repr +from repr import Repr from string import expandtabs, find, join, lower, split, strip, rfind, rstrip try: from collections import deque diff --git a/Lib/repr.py b/Lib/repr.py new file mode 100644 index 0000000..3c26cc3 --- /dev/null +++ b/Lib/repr.py @@ -0,0 +1,132 @@ +"""Redo the builtin repr() (representation) but with limits on most sizes.""" + +__all__ = ["Repr","repr"] + +import __builtin__ +from itertools import islice + +class Repr: + + def __init__(self): + self.maxlevel = 6 + self.maxtuple = 6 + self.maxlist = 6 + self.maxarray = 5 + self.maxdict = 4 + self.maxset = 6 + self.maxfrozenset = 6 + self.maxdeque = 6 + self.maxstring = 30 + self.maxlong = 40 + self.maxother = 20 + + def repr(self, x): + return self.repr1(x, self.maxlevel) + + def repr1(self, x, level): + typename = type(x).__name__ + if ' ' in typename: + parts = typename.split() + typename = '_'.join(parts) + if hasattr(self, 'repr_' + typename): + return getattr(self, 'repr_' + typename)(x, level) + else: + s = __builtin__.repr(x) + if len(s) > self.maxother: + i = max(0, (self.maxother-3)//2) + j = max(0, self.maxother-3-i) + s = s[:i] + '...' + s[len(s)-j:] + return s + + def _repr_iterable(self, x, level, left, right, maxiter, trail=''): + n = len(x) + if level <= 0 and n: + s = '...' + else: + newlevel = level - 1 + repr1 = self.repr1 + pieces = [repr1(elem, newlevel) for elem in islice(x, maxiter)] + if n > maxiter: pieces.append('...') + s = ', '.join(pieces) + if n == 1 and trail: right = trail + right + return '%s%s%s' % (left, s, right) + + def repr_tuple(self, x, level): + return self._repr_iterable(x, level, '(', ')', self.maxtuple, ',') + + def repr_list(self, x, level): + return self._repr_iterable(x, level, '[', ']', self.maxlist) + + def repr_array(self, x, level): + header = "array('%s', [" % x.typecode + return self._repr_iterable(x, level, header, '])', self.maxarray) + + def repr_set(self, x, level): + x = _possibly_sorted(x) + return self._repr_iterable(x, level, 'set([', '])', self.maxset) + + def repr_frozenset(self, x, level): + x = _possibly_sorted(x) + return self._repr_iterable(x, level, 'frozenset([', '])', + self.maxfrozenset) + + def repr_deque(self, x, level): + return self._repr_iterable(x, level, 'deque([', '])', self.maxdeque) + + def repr_dict(self, x, level): + n = len(x) + if n == 0: return '{}' + if level <= 0: return '{...}' + newlevel = level - 1 + repr1 = self.repr1 + pieces = [] + for key in islice(_possibly_sorted(x), self.maxdict): + keyrepr = repr1(key, newlevel) + valrepr = repr1(x[key], newlevel) + pieces.append('%s: %s' % (keyrepr, valrepr)) + if n > self.maxdict: pieces.append('...') + s = ', '.join(pieces) + return '{%s}' % (s,) + + def repr_str(self, x, level): + s = __builtin__.repr(x[:self.maxstring]) + if len(s) > self.maxstring: + i = max(0, (self.maxstring-3)//2) + j = max(0, self.maxstring-3-i) + s = __builtin__.repr(x[:i] + x[len(x)-j:]) + s = s[:i] + '...' + s[len(s)-j:] + return s + + def repr_long(self, x, level): + s = __builtin__.repr(x) # XXX Hope this isn't too slow... + if len(s) > self.maxlong: + i = max(0, (self.maxlong-3)//2) + j = max(0, self.maxlong-3-i) + s = s[:i] + '...' + s[len(s)-j:] + return s + + def repr_instance(self, x, level): + try: + s = __builtin__.repr(x) + # Bugs in x.__repr__() can cause arbitrary + # exceptions -- then make up something + except Exception: + return '<%s instance at %x>' % (x.__class__.__name__, id(x)) + if len(s) > self.maxstring: + i = max(0, (self.maxstring-3)//2) + j = max(0, self.maxstring-3-i) + s = s[:i] + '...' + s[len(s)-j:] + return s + + +def _possibly_sorted(x): + # Since not all sequences of items can be sorted and comparison + # functions may raise arbitrary exceptions, return an unsorted + # sequence in that case. + try: + return sorted(x) + except Exception: + return list(x) + +aRepr = Repr() +repr = aRepr.repr diff --git a/Lib/reprlib.py b/Lib/reprlib.py deleted file mode 100644 index 3c26cc3..0000000 --- a/Lib/reprlib.py +++ /dev/null @@ -1,132 +0,0 @@ -"""Redo the builtin repr() (representation) but with limits on most sizes.""" - -__all__ = ["Repr","repr"] - -import __builtin__ -from itertools import islice - -class Repr: - - def __init__(self): - self.maxlevel = 6 - self.maxtuple = 6 - self.maxlist = 6 - self.maxarray = 5 - self.maxdict = 4 - self.maxset = 6 - self.maxfrozenset = 6 - self.maxdeque = 6 - self.maxstring = 30 - self.maxlong = 40 - self.maxother = 20 - - def repr(self, x): - return self.repr1(x, self.maxlevel) - - def repr1(self, x, level): - typename = type(x).__name__ - if ' ' in typename: - parts = typename.split() - typename = '_'.join(parts) - if hasattr(self, 'repr_' + typename): - return getattr(self, 'repr_' + typename)(x, level) - else: - s = __builtin__.repr(x) - if len(s) > self.maxother: - i = max(0, (self.maxother-3)//2) - j = max(0, self.maxother-3-i) - s = s[:i] + '...' + s[len(s)-j:] - return s - - def _repr_iterable(self, x, level, left, right, maxiter, trail=''): - n = len(x) - if level <= 0 and n: - s = '...' - else: - newlevel = level - 1 - repr1 = self.repr1 - pieces = [repr1(elem, newlevel) for elem in islice(x, maxiter)] - if n > maxiter: pieces.append('...') - s = ', '.join(pieces) - if n == 1 and trail: right = trail + right - return '%s%s%s' % (left, s, right) - - def repr_tuple(self, x, level): - return self._repr_iterable(x, level, '(', ')', self.maxtuple, ',') - - def repr_list(self, x, level): - return self._repr_iterable(x, level, '[', ']', self.maxlist) - - def repr_array(self, x, level): - header = "array('%s', [" % x.typecode - return self._repr_iterable(x, level, header, '])', self.maxarray) - - def repr_set(self, x, level): - x = _possibly_sorted(x) - return self._repr_iterable(x, level, 'set([', '])', self.maxset) - - def repr_frozenset(self, x, level): - x = _possibly_sorted(x) - return self._repr_iterable(x, level, 'frozenset([', '])', - self.maxfrozenset) - - def repr_deque(self, x, level): - return self._repr_iterable(x, level, 'deque([', '])', self.maxdeque) - - def repr_dict(self, x, level): - n = len(x) - if n == 0: return '{}' - if level <= 0: return '{...}' - newlevel = level - 1 - repr1 = self.repr1 - pieces = [] - for key in islice(_possibly_sorted(x), self.maxdict): - keyrepr = repr1(key, newlevel) - valrepr = repr1(x[key], newlevel) - pieces.append('%s: %s' % (keyrepr, valrepr)) - if n > self.maxdict: pieces.append('...') - s = ', '.join(pieces) - return '{%s}' % (s,) - - def repr_str(self, x, level): - s = __builtin__.repr(x[:self.maxstring]) - if len(s) > self.maxstring: - i = max(0, (self.maxstring-3)//2) - j = max(0, self.maxstring-3-i) - s = __builtin__.repr(x[:i] + x[len(x)-j:]) - s = s[:i] + '...' + s[len(s)-j:] - return s - - def repr_long(self, x, level): - s = __builtin__.repr(x) # XXX Hope this isn't too slow... - if len(s) > self.maxlong: - i = max(0, (self.maxlong-3)//2) - j = max(0, self.maxlong-3-i) - s = s[:i] + '...' + s[len(s)-j:] - return s - - def repr_instance(self, x, level): - try: - s = __builtin__.repr(x) - # Bugs in x.__repr__() can cause arbitrary - # exceptions -- then make up something - except Exception: - return '<%s instance at %x>' % (x.__class__.__name__, id(x)) - if len(s) > self.maxstring: - i = max(0, (self.maxstring-3)//2) - j = max(0, self.maxstring-3-i) - s = s[:i] + '...' + s[len(s)-j:] - return s - - -def _possibly_sorted(x): - # Since not all sequences of items can be sorted and comparison - # functions may raise arbitrary exceptions, return an unsorted - # sequence in that case. - try: - return sorted(x) - except Exception: - return list(x) - -aRepr = Repr() -repr = aRepr.repr diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py index 466d921..846a2f6 100644 --- a/Lib/test/test___all__.py +++ b/Lib/test/test___all__.py @@ -123,7 +123,7 @@ class AllTest(unittest.TestCase): self.check_all("quopri") self.check_all("random") self.check_all("re") - self.check_all("reprlib") + self.check_all("repr") self.check_all("rexec") self.check_all("rfc822") self.check_all("rlcompleter") diff --git a/Lib/test/test_py3kwarn.py b/Lib/test/test_py3kwarn.py index ece38ec..b12d14d 100644 --- a/Lib/test/test_py3kwarn.py +++ b/Lib/test/test_py3kwarn.py @@ -218,7 +218,7 @@ class TestStdlibRenames(unittest.TestCase): renames = {'Queue': 'queue', 'SocketServer': 'socketserver', 'ConfigParser': 'configparser', - 'repr': 'reprlib'} + } def check_rename(self, module_name, new_module_name): """Make sure that: diff --git a/Lib/test/test_repr.py b/Lib/test/test_repr.py new file mode 100644 index 0000000..1094816 --- /dev/null +++ b/Lib/test/test_repr.py @@ -0,0 +1,327 @@ +""" + Test cases for the repr module + Nick Mathewson +""" + +import sys +import os +import shutil +import unittest + +from test.test_support import run_unittest +from repr import repr as r # Don't shadow builtin repr +from repr import Repr + + +def nestedTuple(nesting): + t = () + for i in range(nesting): + t = (t,) + return t + +class ReprTests(unittest.TestCase): + + def test_string(self): + eq = self.assertEquals + eq(r("abc"), "'abc'") + eq(r("abcdefghijklmnop"),"'abcdefghijklmnop'") + + s = "a"*30+"b"*30 + expected = repr(s)[:13] + "..." + repr(s)[-14:] + eq(r(s), expected) + + eq(r("\"'"), repr("\"'")) + s = "\""*30+"'"*100 + expected = repr(s)[:13] + "..." + repr(s)[-14:] + eq(r(s), expected) + + def test_tuple(self): + eq = self.assertEquals + eq(r((1,)), "(1,)") + + t3 = (1, 2, 3) + eq(r(t3), "(1, 2, 3)") + + r2 = Repr() + r2.maxtuple = 2 + expected = repr(t3)[:-2] + "...)" + eq(r2.repr(t3), expected) + + def test_container(self): + from array import array + from collections import deque + + eq = self.assertEquals + # Tuples give up after 6 elements + eq(r(()), "()") + eq(r((1,)), "(1,)") + eq(r((1, 2, 3)), "(1, 2, 3)") + eq(r((1, 2, 3, 4, 5, 6)), "(1, 2, 3, 4, 5, 6)") + eq(r((1, 2, 3, 4, 5, 6, 7)), "(1, 2, 3, 4, 5, 6, ...)") + + # Lists give up after 6 as well + eq(r([]), "[]") + eq(r([1]), "[1]") + eq(r([1, 2, 3]), "[1, 2, 3]") + eq(r([1, 2, 3, 4, 5, 6]), "[1, 2, 3, 4, 5, 6]") + eq(r([1, 2, 3, 4, 5, 6, 7]), "[1, 2, 3, 4, 5, 6, ...]") + + # Sets give up after 6 as well + eq(r(set([])), "set([])") + eq(r(set([1])), "set([1])") + eq(r(set([1, 2, 3])), "set([1, 2, 3])") + eq(r(set([1, 2, 3, 4, 5, 6])), "set([1, 2, 3, 4, 5, 6])") + eq(r(set([1, 2, 3, 4, 5, 6, 7])), "set([1, 2, 3, 4, 5, 6, ...])") + + # Frozensets give up after 6 as well + eq(r(frozenset([])), "frozenset([])") + eq(r(frozenset([1])), "frozenset([1])") + eq(r(frozenset([1, 2, 3])), "frozenset([1, 2, 3])") + eq(r(frozenset([1, 2, 3, 4, 5, 6])), "frozenset([1, 2, 3, 4, 5, 6])") + eq(r(frozenset([1, 2, 3, 4, 5, 6, 7])), "frozenset([1, 2, 3, 4, 5, 6, ...])") + + # collections.deque after 6 + eq(r(deque([1, 2, 3, 4, 5, 6, 7])), "deque([1, 2, 3, 4, 5, 6, ...])") + + # Dictionaries give up after 4. + eq(r({}), "{}") + d = {'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4} + eq(r(d), "{'alice': 1, 'bob': 2, 'charles': 3, 'dave': 4}") + d['arthur'] = 1 + eq(r(d), "{'alice': 1, 'arthur': 1, 'bob': 2, 'charles': 3, ...}") + + # array.array after 5. + eq(r(array('i')), "array('i', [])") + eq(r(array('i', [1])), "array('i', [1])") + eq(r(array('i', [1, 2])), "array('i', [1, 2])") + eq(r(array('i', [1, 2, 3])), "array('i', [1, 2, 3])") + eq(r(array('i', [1, 2, 3, 4])), "array('i', [1, 2, 3, 4])") + eq(r(array('i', [1, 2, 3, 4, 5])), "array('i', [1, 2, 3, 4, 5])") + eq(r(array('i', [1, 2, 3, 4, 5, 6])), + "array('i', [1, 2, 3, 4, 5, ...])") + + def test_numbers(self): + eq = self.assertEquals + eq(r(123), repr(123)) + eq(r(123L), repr(123L)) + eq(r(1.0/3), repr(1.0/3)) + + n = 10L**100 + expected = repr(n)[:18] + "..." + repr(n)[-19:] + eq(r(n), expected) + + def test_instance(self): + eq = self.assertEquals + i1 = ClassWithRepr("a") + eq(r(i1), repr(i1)) + + i2 = ClassWithRepr("x"*1000) + expected = repr(i2)[:13] + "..." + repr(i2)[-14:] + eq(r(i2), expected) + + i3 = ClassWithFailingRepr() + eq(r(i3), (""%id(i3))) + + s = r(ClassWithFailingRepr) + self.failUnless(s.startswith("")) + self.failUnless(s.find("...") == 8) + + def test_file(self): + fp = open(unittest.__file__) + self.failUnless(repr(fp).startswith( + "') + # Methods + self.failUnless(repr(''.split).startswith( + '") + # XXX member descriptors + # XXX attribute descriptors + # XXX slot descriptors + # static and class methods + class C: + def foo(cls): pass + x = staticmethod(C.foo) + self.failUnless(repr(x).startswith('" % (areallylongpackageandmodulenametotestreprtruncation.__name__, areallylongpackageandmodulenametotestreprtruncation.__file__)) + eq(repr(sys), "") + + def test_type(self): + eq = self.assertEquals + touch(os.path.join(self.subpkgname, 'foo'+os.extsep+'py'), '''\ +class foo(object): + pass +''') + from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo + eq(repr(foo.foo), + "" % foo.__name__) + + def test_object(self): + # XXX Test the repr of a type with a really long tp_name but with no + # tp_repr. WIBNI we had ::Inline? :) + pass + + def test_class(self): + touch(os.path.join(self.subpkgname, 'bar'+os.extsep+'py'), '''\ +class bar: + pass +''') + from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import bar + # Module name may be prefixed with "test.", depending on how run. + self.failUnless(repr(bar.bar).startswith( + "') + # Bound method next + iqux = qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa() + self.failUnless(repr(iqux.amethod).startswith( + '"%id(i3))) - - s = r(ClassWithFailingRepr) - self.failUnless(s.startswith("")) - self.failUnless(s.find("...") == 8) - - def test_file(self): - fp = open(unittest.__file__) - self.failUnless(repr(fp).startswith( - "') - # Methods - self.failUnless(repr(''.split).startswith( - '") - # XXX member descriptors - # XXX attribute descriptors - # XXX slot descriptors - # static and class methods - class C: - def foo(cls): pass - x = staticmethod(C.foo) - self.failUnless(repr(x).startswith('" % (areallylongpackageandmodulenametotestreprtruncation.__name__, areallylongpackageandmodulenametotestreprtruncation.__file__)) - eq(repr(sys), "") - - def test_type(self): - eq = self.assertEquals - touch(os.path.join(self.subpkgname, 'foo'+os.extsep+'py'), '''\ -class foo(object): - pass -''') - from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo - eq(repr(foo.foo), - "" % foo.__name__) - - def test_object(self): - # XXX Test the repr of a type with a really long tp_name but with no - # tp_repr. WIBNI we had ::Inline? :) - pass - - def test_class(self): - touch(os.path.join(self.subpkgname, 'bar'+os.extsep+'py'), '''\ -class bar: - pass -''') - from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import bar - # Module name may be prefixed with "test.", depending on how run. - self.failUnless(repr(bar.bar).startswith( - "') - # Bound method next - iqux = qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa() - self.failUnless(repr(iqux.amethod).startswith( - '