summaryrefslogtreecommitdiff
path: root/lib/python2.7/test/test_descrtut.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python2.7/test/test_descrtut.py')
-rw-r--r--lib/python2.7/test/test_descrtut.py497
1 files changed, 0 insertions, 497 deletions
diff --git a/lib/python2.7/test/test_descrtut.py b/lib/python2.7/test/test_descrtut.py
deleted file mode 100644
index 33ff0c8..0000000
--- a/lib/python2.7/test/test_descrtut.py
+++ /dev/null
@@ -1,497 +0,0 @@
-# This contains most of the executable examples from Guido's descr
-# tutorial, once at
-#
-# http://www.python.org/2.2/descrintro.html
-#
-# A few examples left implicit in the writeup were fleshed out, a few were
-# skipped due to lack of interest (e.g., faking super() by hand isn't
-# of much interest anymore), and a few were fiddled to make the output
-# deterministic.
-
-from test.test_support import sortdict
-import pprint
-
-class defaultdict(dict):
- def __init__(self, default=None):
- dict.__init__(self)
- self.default = default
-
- def __getitem__(self, key):
- try:
- return dict.__getitem__(self, key)
- except KeyError:
- return self.default
-
- def get(self, key, *args):
- if not args:
- args = (self.default,)
- return dict.get(self, key, *args)
-
- def merge(self, other):
- for key in other:
- if key not in self:
- self[key] = other[key]
-
-test_1 = """
-
-Here's the new type at work:
-
- >>> print defaultdict # show our type
- <class 'test.test_descrtut.defaultdict'>
- >>> print type(defaultdict) # its metatype
- <type 'type'>
- >>> a = defaultdict(default=0.0) # create an instance
- >>> print a # show the instance
- {}
- >>> print type(a) # show its type
- <class 'test.test_descrtut.defaultdict'>
- >>> print a.__class__ # show its class
- <class 'test.test_descrtut.defaultdict'>
- >>> print type(a) is a.__class__ # its type is its class
- True
- >>> a[1] = 3.25 # modify the instance
- >>> print a # show the new value
- {1: 3.25}
- >>> print a[1] # show the new item
- 3.25
- >>> print a[0] # a non-existent item
- 0.0
- >>> a.merge({1:100, 2:200}) # use a dict method
- >>> print sortdict(a) # show the result
- {1: 3.25, 2: 200}
- >>>
-
-We can also use the new type in contexts where classic only allows "real"
-dictionaries, such as the locals/globals dictionaries for the exec
-statement or the built-in function eval():
-
- >>> def sorted(seq):
- ... seq.sort(key=str)
- ... return seq
- >>> print sorted(a.keys())
- [1, 2]
- >>> exec "x = 3; print x" in a
- 3
- >>> print sorted(a.keys())
- [1, 2, '__builtins__', 'x']
- >>> print a['x']
- 3
- >>>
-
-Now I'll show that defaultdict instances have dynamic instance variables,
-just like classic classes:
-
- >>> a.default = -1
- >>> print a["noway"]
- -1
- >>> a.default = -1000
- >>> print a["noway"]
- -1000
- >>> 'default' in dir(a)
- True
- >>> a.x1 = 100
- >>> a.x2 = 200
- >>> print a.x1
- 100
- >>> d = dir(a)
- >>> 'default' in d and 'x1' in d and 'x2' in d
- True
- >>> print sortdict(a.__dict__)
- {'default': -1000, 'x1': 100, 'x2': 200}
- >>>
-"""
-
-class defaultdict2(dict):
- __slots__ = ['default']
-
- def __init__(self, default=None):
- dict.__init__(self)
- self.default = default
-
- def __getitem__(self, key):
- try:
- return dict.__getitem__(self, key)
- except KeyError:
- return self.default
-
- def get(self, key, *args):
- if not args:
- args = (self.default,)
- return dict.get(self, key, *args)
-
- def merge(self, other):
- for key in other:
- if key not in self:
- self[key] = other[key]
-
-test_2 = """
-
-The __slots__ declaration takes a list of instance variables, and reserves
-space for exactly these in the instance. When __slots__ is used, other
-instance variables cannot be assigned to:
-
- >>> a = defaultdict2(default=0.0)
- >>> a[1]
- 0.0
- >>> a.default = -1
- >>> a[1]
- -1
- >>> a.x1 = 1
- Traceback (most recent call last):
- File "<stdin>", line 1, in ?
- AttributeError: 'defaultdict2' object has no attribute 'x1'
- >>>
-
-"""
-
-test_3 = """
-
-Introspecting instances of built-in types
-
-For instance of built-in types, x.__class__ is now the same as type(x):
-
- >>> type([])
- <type 'list'>
- >>> [].__class__
- <type 'list'>
- >>> list
- <type 'list'>
- >>> isinstance([], list)
- True
- >>> isinstance([], dict)
- False
- >>> isinstance([], object)
- True
- >>>
-
-Under the new proposal, the __methods__ attribute no longer exists:
-
- >>> [].__methods__
- Traceback (most recent call last):
- File "<stdin>", line 1, in ?
- AttributeError: 'list' object has no attribute '__methods__'
- >>>
-
-Instead, you can get the same information from the list type:
-
- >>> pprint.pprint(dir(list)) # like list.__dict__.keys(), but sorted
- ['__add__',
- '__class__',
- '__contains__',
- '__delattr__',
- '__delitem__',
- '__delslice__',
- '__doc__',
- '__eq__',
- '__format__',
- '__ge__',
- '__getattribute__',
- '__getitem__',
- '__getslice__',
- '__gt__',
- '__hash__',
- '__iadd__',
- '__imul__',
- '__init__',
- '__iter__',
- '__le__',
- '__len__',
- '__lt__',
- '__mul__',
- '__ne__',
- '__new__',
- '__reduce__',
- '__reduce_ex__',
- '__repr__',
- '__reversed__',
- '__rmul__',
- '__setattr__',
- '__setitem__',
- '__setslice__',
- '__sizeof__',
- '__str__',
- '__subclasshook__',
- 'append',
- 'count',
- 'extend',
- 'index',
- 'insert',
- 'pop',
- 'remove',
- 'reverse',
- 'sort']
-
-The new introspection API gives more information than the old one: in
-addition to the regular methods, it also shows the methods that are
-normally invoked through special notations, e.g. __iadd__ (+=), __len__
-(len), __ne__ (!=). You can invoke any method from this list directly:
-
- >>> a = ['tic', 'tac']
- >>> list.__len__(a) # same as len(a)
- 2
- >>> a.__len__() # ditto
- 2
- >>> list.append(a, 'toe') # same as a.append('toe')
- >>> a
- ['tic', 'tac', 'toe']
- >>>
-
-This is just like it is for user-defined classes.
-"""
-
-test_4 = """
-
-Static methods and class methods
-
-The new introspection API makes it possible to add static methods and class
-methods. Static methods are easy to describe: they behave pretty much like
-static methods in C++ or Java. Here's an example:
-
- >>> class C:
- ...
- ... @staticmethod
- ... def foo(x, y):
- ... print "staticmethod", x, y
-
- >>> C.foo(1, 2)
- staticmethod 1 2
- >>> c = C()
- >>> c.foo(1, 2)
- staticmethod 1 2
-
-Class methods use a similar pattern to declare methods that receive an
-implicit first argument that is the *class* for which they are invoked.
-
- >>> class C:
- ... @classmethod
- ... def foo(cls, y):
- ... print "classmethod", cls, y
-
- >>> C.foo(1)
- classmethod test.test_descrtut.C 1
- >>> c = C()
- >>> c.foo(1)
- classmethod test.test_descrtut.C 1
-
- >>> class D(C):
- ... pass
-
- >>> D.foo(1)
- classmethod test.test_descrtut.D 1
- >>> d = D()
- >>> d.foo(1)
- classmethod test.test_descrtut.D 1
-
-This prints "classmethod __main__.D 1" both times; in other words, the
-class passed as the first argument of foo() is the class involved in the
-call, not the class involved in the definition of foo().
-
-But notice this:
-
- >>> class E(C):
- ... @classmethod
- ... def foo(cls, y): # override C.foo
- ... print "E.foo() called"
- ... C.foo(y)
-
- >>> E.foo(1)
- E.foo() called
- classmethod test.test_descrtut.C 1
- >>> e = E()
- >>> e.foo(1)
- E.foo() called
- classmethod test.test_descrtut.C 1
-
-In this example, the call to C.foo() from E.foo() will see class C as its
-first argument, not class E. This is to be expected, since the call
-specifies the class C. But it stresses the difference between these class
-methods and methods defined in metaclasses (where an upcall to a metamethod
-would pass the target class as an explicit first argument).
-"""
-
-test_5 = """
-
-Attributes defined by get/set methods
-
-
- >>> class property(object):
- ...
- ... def __init__(self, get, set=None):
- ... self.__get = get
- ... self.__set = set
- ...
- ... def __get__(self, inst, type=None):
- ... return self.__get(inst)
- ...
- ... def __set__(self, inst, value):
- ... if self.__set is None:
- ... raise AttributeError, "this attribute is read-only"
- ... return self.__set(inst, value)
-
-Now let's define a class with an attribute x defined by a pair of methods,
-getx() and setx():
-
- >>> class C(object):
- ...
- ... def __init__(self):
- ... self.__x = 0
- ...
- ... def getx(self):
- ... return self.__x
- ...
- ... def setx(self, x):
- ... if x < 0: x = 0
- ... self.__x = x
- ...
- ... x = property(getx, setx)
-
-Here's a small demonstration:
-
- >>> a = C()
- >>> a.x = 10
- >>> print a.x
- 10
- >>> a.x = -10
- >>> print a.x
- 0
- >>>
-
-Hmm -- property is builtin now, so let's try it that way too.
-
- >>> del property # unmask the builtin
- >>> property
- <type 'property'>
-
- >>> class C(object):
- ... def __init__(self):
- ... self.__x = 0
- ... def getx(self):
- ... return self.__x
- ... def setx(self, x):
- ... if x < 0: x = 0
- ... self.__x = x
- ... x = property(getx, setx)
-
-
- >>> a = C()
- >>> a.x = 10
- >>> print a.x
- 10
- >>> a.x = -10
- >>> print a.x
- 0
- >>>
-"""
-
-test_6 = """
-
-Method resolution order
-
-This example is implicit in the writeup.
-
->>> class A: # classic class
-... def save(self):
-... print "called A.save()"
->>> class B(A):
-... pass
->>> class C(A):
-... def save(self):
-... print "called C.save()"
->>> class D(B, C):
-... pass
-
->>> D().save()
-called A.save()
-
->>> class A(object): # new class
-... def save(self):
-... print "called A.save()"
->>> class B(A):
-... pass
->>> class C(A):
-... def save(self):
-... print "called C.save()"
->>> class D(B, C):
-... pass
-
->>> D().save()
-called C.save()
-"""
-
-class A(object):
- def m(self):
- return "A"
-
-class B(A):
- def m(self):
- return "B" + super(B, self).m()
-
-class C(A):
- def m(self):
- return "C" + super(C, self).m()
-
-class D(C, B):
- def m(self):
- return "D" + super(D, self).m()
-
-
-test_7 = """
-
-Cooperative methods and "super"
-
->>> print D().m() # "DCBA"
-DCBA
-"""
-
-test_8 = """
-
-Backwards incompatibilities
-
->>> class A:
-... def foo(self):
-... print "called A.foo()"
-
->>> class B(A):
-... pass
-
->>> class C(A):
-... def foo(self):
-... B.foo(self)
-
->>> C().foo()
-Traceback (most recent call last):
- ...
-TypeError: unbound method foo() must be called with B instance as first argument (got C instance instead)
-
->>> class C(A):
-... def foo(self):
-... A.foo(self)
->>> C().foo()
-called A.foo()
-"""
-
-__test__ = {"tut1": test_1,
- "tut2": test_2,
- "tut3": test_3,
- "tut4": test_4,
- "tut5": test_5,
- "tut6": test_6,
- "tut7": test_7,
- "tut8": test_8}
-
-# Magic test name that regrtest.py invokes *after* importing this module.
-# This worms around a bootstrap problem.
-# Note that doctest and regrtest both look in sys.argv for a "-v" argument,
-# so this works as expected in both ways of running regrtest.
-def test_main(verbose=None):
- # Obscure: import this module as test.test_descrtut instead of as
- # plain test_descrtut because the name of this module works its way
- # into the doctest examples, and unless the full test.test_descrtut
- # business is used the name can change depending on how the test is
- # invoked.
- from test import test_support, test_descrtut
- test_support.run_doctest(test_descrtut, verbose)
-
-# This part isn't needed for regrtest, but for running the test directly.
-if __name__ == "__main__":
- test_main(1)