# This contains most of the executable examples from Guido's descr
# tutorial, once at
#
#     https://www.python.org/download/releases/2.2.3/descrintro/
#
# 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.support import sortdict
import doctest
import unittest


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
    <class '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():

    >>> print(sorted(a.keys()))
    [1, 2]
    >>> a['print'] = print              # need the print function here
    >>> exec("x = 3; print(x)", a)
    3
    >>> print(sorted(a.keys(), key=lambda x: (str(type(x)), x)))
    [1, 2, '__builtins__', 'print', '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([])
    <class 'list'>
    >>> [].__class__
    <class 'list'>
    >>> list
    <class 'list'>
    >>> isinstance([], list)
    True
    >>> isinstance([], dict)
    False
    >>> isinstance([], object)
    True
    >>>

You can get the information from the list type:

    >>> import pprint
    >>> pprint.pprint(dir(list))    # like list.__dict__.keys(), but sorted
    ['__add__',
     '__class__',
     '__class_getitem__',
     '__contains__',
     '__delattr__',
     '__delitem__',
     '__dir__',
     '__doc__',
     '__eq__',
     '__format__',
     '__ge__',
     '__getattribute__',
     '__getitem__',
     '__getstate__',
     '__gt__',
     '__hash__',
     '__iadd__',
     '__imul__',
     '__init__',
     '__init_subclass__',
     '__iter__',
     '__le__',
     '__len__',
     '__lt__',
     '__mul__',
     '__ne__',
     '__new__',
     '__reduce__',
     '__reduce_ex__',
     '__repr__',
     '__reversed__',
     '__rmul__',
     '__setattr__',
     '__setitem__',
     '__sizeof__',
     '__str__',
     '__subclasshook__',
     'append',
     'clear',
     'copy',
     '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 <class 'test.test_descrtut.C'> 1
    >>> c = C()
    >>> c.foo(1)
    classmethod <class 'test.test_descrtut.C'> 1

    >>> class D(C):
    ...     pass

    >>> D.foo(1)
    classmethod <class 'test.test_descrtut.D'> 1
    >>> d = D()
    >>> d.foo(1)
    classmethod <class '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 <class 'test.test_descrtut.C'> 1
    >>> e = E()
    >>> e.foo(1)
    E.foo() called
    classmethod <class '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
    <class '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:    # implicit new-style 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):  # explicit new-style 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()
called A.foo()

>>> 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}

def load_tests(loader, tests, pattern):
    tests.addTest(doctest.DocTestSuite())
    return tests


if __name__ == "__main__":
    unittest.main()
