symbian-qemu-0.9.1-12/python-2.6.1/Lib/test/test_descrtut.py
changeset 1 2fb8b9db1c86
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/symbian-qemu-0.9.1-12/python-2.6.1/Lib/test/test_descrtut.py	Fri Jul 31 15:01:17 2009 +0100
@@ -0,0 +1,497 @@
+# 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-existant 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()
+    ...     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 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)