doctests = """

Basic class construction.

    >>> class C:
    ...     def meth(self): print("Hello")
    ...
    >>> C.__class__ is type
    True
    >>> a = C()
    >>> a.__class__ is C
    True
    >>> a.meth()
    Hello
    >>>

Use *args notation for the bases.

    >>> class A: pass
    >>> class B: pass
    >>> bases = (A, B)
    >>> class C(*bases): pass
    >>> C.__bases__ == bases
    True
    >>>

Use a trivial metaclass.

    >>> class M(type):
    ...     pass
    ...
    >>> class C(metaclass=M):
    ...    def meth(self): print("Hello")
    ...
    >>> C.__class__ is M
    True
    >>> a = C()
    >>> a.__class__ is C
    True
    >>> a.meth()
    Hello
    >>>

Use **kwds notation for the metaclass keyword.

    >>> kwds = {'metaclass': M}
    >>> class C(**kwds): pass
    ...
    >>> C.__class__ is M
    True
    >>> a = C()
    >>> a.__class__ is C
    True
    >>>

Use a metaclass with a __prepare__ static method.

    >>> class M(type):
    ...    @staticmethod
    ...    def __prepare__(*args, **kwds):
    ...        print("Prepare called:", args, kwds)
    ...        return dict()
    ...    def __new__(cls, name, bases, namespace, **kwds):
    ...        print("New called:", kwds)
    ...        return type.__new__(cls, name, bases, namespace)
    ...    def __init__(cls, *args, **kwds):
    ...        pass
    ...
    >>> class C(metaclass=M):
    ...     def meth(self): print("Hello")
    ...
    Prepare called: ('C', ()) {}
    New called: {}
    >>>

Also pass another keyword.

    >>> class C(object, metaclass=M, other="haha"):
    ...     pass
    ...
    Prepare called: ('C', (<class 'object'>,)) {'other': 'haha'}
    New called: {'other': 'haha'}
    >>> C.__class__ is M
    True
    >>> C.__bases__ == (object,)
    True
    >>> a = C()
    >>> a.__class__ is C
    True
    >>>

Check that build_class doesn't mutate the kwds dict.

    >>> kwds = {'metaclass': type}
    >>> class C(**kwds): pass
    ...
    >>> kwds == {'metaclass': type}
    True
    >>>

Use various combinations of explicit keywords and **kwds.

    >>> bases = (object,)
    >>> kwds = {'metaclass': M, 'other': 'haha'}
    >>> class C(*bases, **kwds): pass
    ...
    Prepare called: ('C', (<class 'object'>,)) {'other': 'haha'}
    New called: {'other': 'haha'}
    >>> C.__class__ is M
    True
    >>> C.__bases__ == (object,)
    True
    >>> class B: pass
    >>> kwds = {'other': 'haha'}
    >>> class C(B, metaclass=M, *bases, **kwds): pass
    ...
    Prepare called: ('C', (<class 'test.test_metaclass.B'>, <class 'object'>)) {'other': 'haha'}
    New called: {'other': 'haha'}
    >>> C.__class__ is M
    True
    >>> C.__bases__ == (B, object)
    True
    >>>

Check for duplicate keywords.

    >>> class C(metaclass=type, metaclass=type): pass
    ...
    Traceback (most recent call last):
    [...]
    SyntaxError: keyword argument repeated
    >>>

Another way.

    >>> kwds = {'metaclass': type}
    >>> class C(metaclass=type, **kwds): pass
    ...
    Traceback (most recent call last):
    [...]
    TypeError: __build_class__() got multiple values for keyword argument 'metaclass'
    >>>

Use a __prepare__ method that returns an instrumented dict.

    >>> class LoggingDict(dict):
    ...     def __setitem__(self, key, value):
    ...         print("d[%r] = %r" % (key, value))
    ...         dict.__setitem__(self, key, value)
    ...
    >>> class Meta(type):
    ...    @staticmethod
    ...    def __prepare__(name, bases):
    ...        return LoggingDict()
    ...
    >>> class C(metaclass=Meta):
    ...     foo = 2+2
    ...     foo = 42
    ...     bar = 123
    ...
    d['__module__'] = 'test.test_metaclass'
    d['__qualname__'] = 'C'
    d['foo'] = 4
    d['foo'] = 42
    d['bar'] = 123
    >>>

Use a metaclass that doesn't derive from type.

    >>> def meta(name, bases, namespace, **kwds):
    ...     print("meta:", name, bases)
    ...     print("ns:", sorted(namespace.items()))
    ...     print("kw:", sorted(kwds.items()))
    ...     return namespace
    ...
    >>> class C(metaclass=meta):
    ...     a = 42
    ...     b = 24
    ...
    meta: C ()
    ns: [('__module__', 'test.test_metaclass'), ('__qualname__', 'C'), ('a', 42), ('b', 24)]
    kw: []
    >>> type(C) is dict
    True
    >>> print(sorted(C.items()))
    [('__module__', 'test.test_metaclass'), ('__qualname__', 'C'), ('a', 42), ('b', 24)]
    >>>

And again, with a __prepare__ attribute.

    >>> def prepare(name, bases, **kwds):
    ...     print("prepare:", name, bases, sorted(kwds.items()))
    ...     return LoggingDict()
    ...
    >>> meta.__prepare__ = prepare
    >>> class C(metaclass=meta, other="booh"):
    ...    a = 1
    ...    a = 2
    ...    b = 3
    ...
    prepare: C () [('other', 'booh')]
    d['__module__'] = 'test.test_metaclass'
    d['__qualname__'] = 'C'
    d['a'] = 1
    d['a'] = 2
    d['b'] = 3
    meta: C ()
    ns: [('__module__', 'test.test_metaclass'), ('__qualname__', 'C'), ('a', 2), ('b', 3)]
    kw: [('other', 'booh')]
    >>>

The default metaclass must define a __prepare__() method.

    >>> type.__prepare__()
    {}
    >>>

Make sure it works with subclassing.

    >>> class M(type):
    ...     @classmethod
    ...     def __prepare__(cls, *args, **kwds):
    ...         d = super().__prepare__(*args, **kwds)
    ...         d["hello"] = 42
    ...         return d
    ...
    >>> class C(metaclass=M):
    ...     print(hello)
    ...
    42
    >>> print(C.hello)
    42
    >>>

Test failures in looking up the __prepare__ method work.
    >>> class ObscureException(Exception):
    ...     pass
    >>> class FailDescr:
    ...     def __get__(self, instance, owner):
    ...        raise ObscureException
    >>> class Meta(type):
    ...     __prepare__ = FailDescr()
    >>> class X(metaclass=Meta):
    ...     pass
    Traceback (most recent call last):
    [...]
    test.test_metaclass.ObscureException

"""

import sys

# Trace function introduces __locals__ which causes various tests to fail.
if hasattr(sys, 'gettrace') and sys.gettrace():
    __test__ = {}
else:
    __test__ = {'doctests' : doctests}

def test_main(verbose=False):
    from test import support
    from test import test_metaclass
    support.run_doctest(test_metaclass, verbose)

if __name__ == "__main__":
    test_main(verbose=True)
