20460239 decorator should have some master test results to compare against
authorJohn Beck <John.Beck@Oracle.COM>
Wed, 18 Feb 2015 13:49:02 -0800
changeset 3840 39959a8e7a76
parent 3839 dece34b8bbeb
child 3841 073301957a1a
20460239 decorator should have some master test results to compare against
components/python/decorator/Makefile
components/python/decorator/test/results-2.6-32.master
components/python/decorator/test/results-2.7-32.master
components/python/decorator/test/results-3.4-32.master
--- a/components/python/decorator/Makefile	Fri Feb 20 11:48:36 2015 -0800
+++ b/components/python/decorator/Makefile	Wed Feb 18 13:49:02 2015 -0800
@@ -42,8 +42,11 @@
 
 ASLR_MODE = $(ASLR_NOT_APPLICABLE)
 
-COMPONENT_TEST_ARGS=	documentation.py -v
-COMPONENT_TEST_DIR=	$(SOURCE_DIR)
+COMPONENT_TEST_ARGS.2.6=	documentation.py -v
+COMPONENT_TEST_ARGS.2.7=	documentation.py -v
+COMPONENT_TEST_ARGS.3.4=	documentation3.py -v
+COMPONENT_TEST_ARGS=		$(COMPONENT_TEST_ARGS.$(PYTHON_VERSION))
+COMPONENT_TEST_DIR=		$(SOURCE_DIR)
 
 # common targets
 build:		$(BUILD_NO_ARCH)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/decorator/test/results-2.6-32.master	Wed Feb 18 13:49:02 2015 -0800
@@ -0,0 +1,436 @@
+[?1034hTrying:
+    @memoize_uw
+    def f1(x):
+        time.sleep(1) # simulate some long computation
+        return x
+Expecting nothing
+ok
+Trying:
+    from inspect import getargspec 
+Expecting nothing
+ok
+Trying:
+    print getargspec(f1) # I am using Python 2.6+ here
+Expecting:
+    ArgSpec(args=[], varargs='args', keywords='kw', defaults=None)
+ok
+Trying:
+    f1(0, 1)
+Expecting:
+    Traceback (most recent call last):
+       ...
+    TypeError: f1() takes exactly 1 argument (2 given)
+ok
+Trying:
+    from decorator import decorator
+Expecting nothing
+ok
+Trying:
+    @memoize
+    def heavy_computation():
+        time.sleep(2)
+        return "done"
+Expecting nothing
+ok
+Trying:
+    print heavy_computation() # the first time it will take 2 seconds
+Expecting:
+    done
+ok
+Trying:
+    print heavy_computation() # the second time it will be instantaneous
+Expecting:
+    done
+ok
+Trying:
+    print getargspec(heavy_computation) 
+Expecting:
+    ArgSpec(args=[], varargs=None, keywords=None, defaults=None)
+ok
+Trying:
+    @trace
+    def f1(x):
+        pass
+Expecting nothing
+ok
+Trying:
+    f1(0)
+Expecting:
+    calling f1 with args (0,), {}
+ok
+Trying:
+    print getargspec(f1) 
+Expecting:
+    ArgSpec(args=['x'], varargs=None, keywords=None, defaults=None)
+ok
+Trying:
+    @trace
+    def f(x, y=1, z=2, *args, **kw):
+        pass
+Expecting nothing
+ok
+Trying:
+    f(0, 3)
+Expecting:
+    calling f with args (0, 3, 2), {}
+ok
+Trying:
+    print getargspec(f) 
+Expecting:
+    ArgSpec(args=['x', 'y', 'z'], varargs='args', keywords='kw', defaults=(1, 2))
+ok
+Trying:
+    @trace
+    def exotic_signature((x, y)=(1,2)): return x+y
+Expecting nothing
+ok
+Trying:
+    print getargspec(exotic_signature)
+Expecting:
+    ArgSpec(args=[['x', 'y']], varargs=None, keywords=None, defaults=((1, 2),))
+ok
+Trying:
+    exotic_signature() 
+Expecting:
+    calling exotic_signature with args ((1, 2),), {}
+    3
+ok
+Trying:
+    @decorator
+    def trace(f, *args, **kw):
+        print "calling %s with args %s, %s" % (f.func_name, args, kw)
+        return f(*args, **kw)
+Expecting nothing
+ok
+Trying:
+    trace # doctest: +ELLIPSIS
+Expecting:
+    <function trace at 0x...>
+ok
+Trying:
+    @trace
+    def func(): pass
+Expecting nothing
+ok
+Trying:
+    func()
+Expecting:
+    calling func with args (), {}
+ok
+Trying:
+    @blocking("Please wait ...")
+    def read_data():
+        time.sleep(3) # simulate a blocking resource
+        return "some data"
+Expecting nothing
+ok
+Trying:
+    print read_data() # data is not available yet
+Expecting:
+    Please wait ...
+ok
+Trying:
+    time.sleep(1)  
+Expecting nothing
+ok
+Trying:
+    print read_data() # data is not available yet
+Expecting:
+    Please wait ...
+ok
+Trying:
+    time.sleep(1)
+Expecting nothing
+ok
+Trying:
+    print read_data() # data is not available yet
+Expecting:
+    Please wait ...
+ok
+Trying:
+    time.sleep(1.1) # after 3.1 seconds, data is available
+Expecting nothing
+ok
+Trying:
+    print read_data()
+Expecting:
+    some data
+ok
+Trying:
+    async = decorator(Async(threading.Thread))
+Expecting nothing
+ok
+Trying:
+    datalist = [] # for simplicity the written data are stored into a list.
+Expecting nothing
+ok
+Trying:
+    @async
+    def write(data):
+        # append data to the datalist by locking
+        with threading.Lock():
+            time.sleep(1) # emulate some long running operation
+            datalist.append(data)
+        # other operations not requiring a lock here
+Expecting nothing
+ok
+Trying:
+    write("data1") # doctest: +ELLIPSIS
+Expecting:
+    <Thread(write-1, started...)>
+ok
+Trying:
+    time.sleep(.1) # wait a bit, so we are sure data2 is written after data1
+Expecting nothing
+ok
+Trying:
+    write("data2") # doctest: +ELLIPSIS
+Expecting:
+    <Thread(write-2, started...)>
+ok
+Trying:
+    time.sleep(2) # wait for the writers to complete
+Expecting nothing
+ok
+Trying:
+    print datalist
+Expecting:
+    ['data1', 'data2']
+ok
+Trying:
+    from contextlib import contextmanager
+Expecting nothing
+ok
+Trying:
+    @contextmanager
+    def before_after(before, after):
+        print(before)
+        yield
+        print(after)
+Expecting nothing
+ok
+Trying:
+    ba = before_after('BEFORE', 'AFTER')
+Expecting nothing
+ok
+Trying:
+    type(ba)
+Expecting:
+    <class 'contextlib.GeneratorContextManager'>
+ok
+Trying:
+    with ba:
+        print 'hello'
+Expecting:
+    BEFORE
+    hello
+    AFTER
+ok
+Trying:
+    def f(*args, **kw): # a function with a generic signature
+        print args, kw
+Expecting nothing
+ok
+Trying:
+    f1 = FunctionMaker.create('f1(a, b)', 'f(a, b)', dict(f=f))
+Expecting nothing
+ok
+Trying:
+    f1(1,2)
+Expecting:
+    (1, 2) {}
+ok
+Trying:
+    f1 = FunctionMaker.create(
+        'f1(a, b)', 'f(a, b)', dict(f=f), addsource=True)
+Expecting nothing
+ok
+Trying:
+    print f1.__source__
+Expecting:
+    def f1(a, b):
+        f(a, b)
+    <BLANKLINE>
+ok
+Trying:
+    print inspect.getsource(example)
+Expecting:
+        def wrapper(*args, **kw):
+            return func(*args, **kw)
+    <BLANKLINE>
+ok
+Trying:
+    print inspect.getsource(factorial.__wrapped__)
+Expecting:
+    @tail_recursive
+    def factorial(n, acc=1):
+        "The good old factorial"
+        if n == 0: return acc
+        return factorial(n-1, n*acc)
+    <BLANKLINE>
+ok
+Trying:
+    print factorial(4) 
+Expecting:
+    24
+ok
+Trying:
+    @trace
+    def f():
+        1/0
+Expecting nothing
+ok
+Trying:
+    f()
+Expecting:
+    Traceback (most recent call last):
+      ...
+         File "<string>", line 2, in f
+         File "<doctest __main__[18]>", line 4, in trace
+           return f(*args, **kw)
+         File "<doctest __main__[47]>", line 3, in f
+           1/0
+    ZeroDivisionError: integer division or modulo by zero
+ok
+Trying:
+    class C(object): 
+         @trace
+         def meth(self):
+             pass
+Expecting nothing
+ok
+Trying:
+    class C(object):
+         def meth(self):
+             pass
+Expecting nothing
+ok
+Trying:
+    trace(C.meth)
+Expecting:
+    Traceback (most recent call last):
+      ...
+    TypeError: You are decorating a non function: <unbound method C.meth>
+ok
+Trying:
+    trace(C.meth.im_func) # doctest: +ELLIPSIS
+Expecting:
+    <function meth at 0x...>
+ok
+Trying:
+    @trace
+    def f(_func_): print f
+Expecting:
+    Traceback (most recent call last):
+      ...
+    NameError: _func_ is overridden in
+    def f(_func_):
+        return _call_(_func_, _func_)
+ok
+Trying:
+    def f(): pass # the original function
+Expecting nothing
+ok
+Trying:
+    f.attr1 = "something" # setting an attribute
+Expecting nothing
+ok
+Trying:
+    f.attr2 = "something else" # setting another attribute
+Expecting nothing
+ok
+Trying:
+    traced_f = trace(f) # the decorated function
+Expecting nothing
+ok
+Trying:
+    traced_f.attr1
+Expecting:
+    'something'
+ok
+Trying:
+    traced_f.attr2 = "something different" # setting attr
+Expecting nothing
+ok
+Trying:
+    f.attr2 # the original attribute did not change
+Expecting:
+    'something else'
+ok
+Trying:
+    a = Action()
+Expecting nothing
+ok
+Trying:
+    a.view() # ok
+Expecting nothing
+ok
+Trying:
+    a.insert() # err
+Expecting:
+    Traceback (most recent call last):
+       ...
+    PermissionError: User does not have the permission to run insert!
+ok
+Trying:
+    decorator(_memoize).__name__
+Expecting:
+    '_memoize'
+ok
+Trying:
+    factorial.__doc__
+Expecting:
+    'The good old factorial'
+ok
+Trying:
+    ba.__class__.__name__
+Expecting:
+    'ContextManager'
+ok
+Trying:
+    hello('michele')
+Expecting:
+    BEFORE
+    hello michele
+    AFTER
+ok
+31 items had no tests:
+    __main__.Action.delete
+    __main__.Action.insert
+    __main__.Action.view
+    __main__.Admin
+    __main__.Async
+    __main__.Async.__call__
+    __main__.Async.__init__
+    __main__.PermissionError
+    __main__.PowerUser
+    __main__.TailRecursive
+    __main__.TailRecursive.__call__
+    __main__.TailRecursive.__init__
+    __main__.User
+    __main__._memoize
+    __main__._trace
+    __main__.before_after
+    __main__.blocking
+    __main__.decorator_apply
+    __main__.example
+    __main__.fact
+    __main__.factorial
+    __main__.get_userclass
+    __main__.identity_dec
+    __main__.memoize
+    __main__.memoize_uw
+    __main__.on_closing
+    __main__.on_failure
+    __main__.on_success
+    __main__.restricted
+    __main__.tail_recursive
+    __main__.trace
+4 items passed all tests:
+  65 tests in __main__
+   3 tests in __main__.Action
+   2 tests in __main__.a_test_for_pylons
+   2 tests in __main__.hello
+72 tests in 35 items.
+72 passed and 0 failed.
+Test passed.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/decorator/test/results-2.7-32.master	Wed Feb 18 13:49:02 2015 -0800
@@ -0,0 +1,436 @@
+[?1034hTrying:
+    @memoize_uw
+    def f1(x):
+        time.sleep(1) # simulate some long computation
+        return x
+Expecting nothing
+ok
+Trying:
+    from inspect import getargspec 
+Expecting nothing
+ok
+Trying:
+    print getargspec(f1) # I am using Python 2.6+ here
+Expecting:
+    ArgSpec(args=[], varargs='args', keywords='kw', defaults=None)
+ok
+Trying:
+    f1(0, 1)
+Expecting:
+    Traceback (most recent call last):
+       ...
+    TypeError: f1() takes exactly 1 argument (2 given)
+ok
+Trying:
+    from decorator import decorator
+Expecting nothing
+ok
+Trying:
+    @memoize
+    def heavy_computation():
+        time.sleep(2)
+        return "done"
+Expecting nothing
+ok
+Trying:
+    print heavy_computation() # the first time it will take 2 seconds
+Expecting:
+    done
+ok
+Trying:
+    print heavy_computation() # the second time it will be instantaneous
+Expecting:
+    done
+ok
+Trying:
+    print getargspec(heavy_computation) 
+Expecting:
+    ArgSpec(args=[], varargs=None, keywords=None, defaults=None)
+ok
+Trying:
+    @trace
+    def f1(x):
+        pass
+Expecting nothing
+ok
+Trying:
+    f1(0)
+Expecting:
+    calling f1 with args (0,), {}
+ok
+Trying:
+    print getargspec(f1) 
+Expecting:
+    ArgSpec(args=['x'], varargs=None, keywords=None, defaults=None)
+ok
+Trying:
+    @trace
+    def f(x, y=1, z=2, *args, **kw):
+        pass
+Expecting nothing
+ok
+Trying:
+    f(0, 3)
+Expecting:
+    calling f with args (0, 3, 2), {}
+ok
+Trying:
+    print getargspec(f) 
+Expecting:
+    ArgSpec(args=['x', 'y', 'z'], varargs='args', keywords='kw', defaults=(1, 2))
+ok
+Trying:
+    @trace
+    def exotic_signature((x, y)=(1,2)): return x+y
+Expecting nothing
+ok
+Trying:
+    print getargspec(exotic_signature)
+Expecting:
+    ArgSpec(args=[['x', 'y']], varargs=None, keywords=None, defaults=((1, 2),))
+ok
+Trying:
+    exotic_signature() 
+Expecting:
+    calling exotic_signature with args ((1, 2),), {}
+    3
+ok
+Trying:
+    @decorator
+    def trace(f, *args, **kw):
+        print "calling %s with args %s, %s" % (f.func_name, args, kw)
+        return f(*args, **kw)
+Expecting nothing
+ok
+Trying:
+    trace # doctest: +ELLIPSIS
+Expecting:
+    <function trace at 0x...>
+ok
+Trying:
+    @trace
+    def func(): pass
+Expecting nothing
+ok
+Trying:
+    func()
+Expecting:
+    calling func with args (), {}
+ok
+Trying:
+    @blocking("Please wait ...")
+    def read_data():
+        time.sleep(3) # simulate a blocking resource
+        return "some data"
+Expecting nothing
+ok
+Trying:
+    print read_data() # data is not available yet
+Expecting:
+    Please wait ...
+ok
+Trying:
+    time.sleep(1)  
+Expecting nothing
+ok
+Trying:
+    print read_data() # data is not available yet
+Expecting:
+    Please wait ...
+ok
+Trying:
+    time.sleep(1)
+Expecting nothing
+ok
+Trying:
+    print read_data() # data is not available yet
+Expecting:
+    Please wait ...
+ok
+Trying:
+    time.sleep(1.1) # after 3.1 seconds, data is available
+Expecting nothing
+ok
+Trying:
+    print read_data()
+Expecting:
+    some data
+ok
+Trying:
+    async = decorator(Async(threading.Thread))
+Expecting nothing
+ok
+Trying:
+    datalist = [] # for simplicity the written data are stored into a list.
+Expecting nothing
+ok
+Trying:
+    @async
+    def write(data):
+        # append data to the datalist by locking
+        with threading.Lock():
+            time.sleep(1) # emulate some long running operation
+            datalist.append(data)
+        # other operations not requiring a lock here
+Expecting nothing
+ok
+Trying:
+    write("data1") # doctest: +ELLIPSIS
+Expecting:
+    <Thread(write-1, started...)>
+ok
+Trying:
+    time.sleep(.1) # wait a bit, so we are sure data2 is written after data1
+Expecting nothing
+ok
+Trying:
+    write("data2") # doctest: +ELLIPSIS
+Expecting:
+    <Thread(write-2, started...)>
+ok
+Trying:
+    time.sleep(2) # wait for the writers to complete
+Expecting nothing
+ok
+Trying:
+    print datalist
+Expecting:
+    ['data1', 'data2']
+ok
+Trying:
+    from contextlib import contextmanager
+Expecting nothing
+ok
+Trying:
+    @contextmanager
+    def before_after(before, after):
+        print(before)
+        yield
+        print(after)
+Expecting nothing
+ok
+Trying:
+    ba = before_after('BEFORE', 'AFTER')
+Expecting nothing
+ok
+Trying:
+    type(ba)
+Expecting:
+    <class 'contextlib.GeneratorContextManager'>
+ok
+Trying:
+    with ba:
+        print 'hello'
+Expecting:
+    BEFORE
+    hello
+    AFTER
+ok
+Trying:
+    def f(*args, **kw): # a function with a generic signature
+        print args, kw
+Expecting nothing
+ok
+Trying:
+    f1 = FunctionMaker.create('f1(a, b)', 'f(a, b)', dict(f=f))
+Expecting nothing
+ok
+Trying:
+    f1(1,2)
+Expecting:
+    (1, 2) {}
+ok
+Trying:
+    f1 = FunctionMaker.create(
+        'f1(a, b)', 'f(a, b)', dict(f=f), addsource=True)
+Expecting nothing
+ok
+Trying:
+    print f1.__source__
+Expecting:
+    def f1(a, b):
+        f(a, b)
+    <BLANKLINE>
+ok
+Trying:
+    print inspect.getsource(example)
+Expecting:
+        def wrapper(*args, **kw):
+            return func(*args, **kw)
+    <BLANKLINE>
+ok
+Trying:
+    print inspect.getsource(factorial.__wrapped__)
+Expecting:
+    @tail_recursive
+    def factorial(n, acc=1):
+        "The good old factorial"
+        if n == 0: return acc
+        return factorial(n-1, n*acc)
+    <BLANKLINE>
+ok
+Trying:
+    print factorial(4) 
+Expecting:
+    24
+ok
+Trying:
+    @trace
+    def f():
+        1/0
+Expecting nothing
+ok
+Trying:
+    f()
+Expecting:
+    Traceback (most recent call last):
+      ...
+         File "<string>", line 2, in f
+         File "<doctest __main__[18]>", line 4, in trace
+           return f(*args, **kw)
+         File "<doctest __main__[47]>", line 3, in f
+           1/0
+    ZeroDivisionError: integer division or modulo by zero
+ok
+Trying:
+    class C(object): 
+         @trace
+         def meth(self):
+             pass
+Expecting nothing
+ok
+Trying:
+    class C(object):
+         def meth(self):
+             pass
+Expecting nothing
+ok
+Trying:
+    trace(C.meth)
+Expecting:
+    Traceback (most recent call last):
+      ...
+    TypeError: You are decorating a non function: <unbound method C.meth>
+ok
+Trying:
+    trace(C.meth.im_func) # doctest: +ELLIPSIS
+Expecting:
+    <function meth at 0x...>
+ok
+Trying:
+    @trace
+    def f(_func_): print f
+Expecting:
+    Traceback (most recent call last):
+      ...
+    NameError: _func_ is overridden in
+    def f(_func_):
+        return _call_(_func_, _func_)
+ok
+Trying:
+    def f(): pass # the original function
+Expecting nothing
+ok
+Trying:
+    f.attr1 = "something" # setting an attribute
+Expecting nothing
+ok
+Trying:
+    f.attr2 = "something else" # setting another attribute
+Expecting nothing
+ok
+Trying:
+    traced_f = trace(f) # the decorated function
+Expecting nothing
+ok
+Trying:
+    traced_f.attr1
+Expecting:
+    'something'
+ok
+Trying:
+    traced_f.attr2 = "something different" # setting attr
+Expecting nothing
+ok
+Trying:
+    f.attr2 # the original attribute did not change
+Expecting:
+    'something else'
+ok
+Trying:
+    a = Action()
+Expecting nothing
+ok
+Trying:
+    a.view() # ok
+Expecting nothing
+ok
+Trying:
+    a.insert() # err
+Expecting:
+    Traceback (most recent call last):
+       ...
+    PermissionError: User does not have the permission to run insert!
+ok
+Trying:
+    decorator(_memoize).__name__
+Expecting:
+    '_memoize'
+ok
+Trying:
+    factorial.__doc__
+Expecting:
+    'The good old factorial'
+ok
+Trying:
+    ba.__class__.__name__
+Expecting:
+    'ContextManager'
+ok
+Trying:
+    hello('michele')
+Expecting:
+    BEFORE
+    hello michele
+    AFTER
+ok
+31 items had no tests:
+    __main__.Action.delete
+    __main__.Action.insert
+    __main__.Action.view
+    __main__.Admin
+    __main__.Async
+    __main__.Async.__call__
+    __main__.Async.__init__
+    __main__.PermissionError
+    __main__.PowerUser
+    __main__.TailRecursive
+    __main__.TailRecursive.__call__
+    __main__.TailRecursive.__init__
+    __main__.User
+    __main__._memoize
+    __main__._trace
+    __main__.before_after
+    __main__.blocking
+    __main__.decorator_apply
+    __main__.example
+    __main__.fact
+    __main__.factorial
+    __main__.get_userclass
+    __main__.identity_dec
+    __main__.memoize
+    __main__.memoize_uw
+    __main__.on_closing
+    __main__.on_failure
+    __main__.on_success
+    __main__.restricted
+    __main__.tail_recursive
+    __main__.trace
+4 items passed all tests:
+  65 tests in __main__
+   3 tests in __main__.Action
+   2 tests in __main__.a_test_for_pylons
+   2 tests in __main__.hello
+72 tests in 35 items.
+72 passed and 0 failed.
+Test passed.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/decorator/test/results-3.4-32.master	Wed Feb 18 13:49:02 2015 -0800
@@ -0,0 +1,492 @@
+Trying:
+    @memoize_uw
+    def f1(x):
+        time.sleep(1) # simulate some long computation
+        return x
+Expecting nothing
+ok
+Trying:
+    from inspect import getargspec 
+Expecting nothing
+ok
+Trying:
+    print(getargspec(f1))
+Expecting:
+    ArgSpec(args=[], varargs='args', keywords='kw', defaults=None)
+ok
+Trying:
+    f1(0, 1) # doctest: +IGNORE_EXCEPTION_DETAIL
+Expecting:
+    Traceback (most recent call last):
+       ...
+    TypeError: f1() takes exactly 1 positional argument (2 given)
+ok
+Trying:
+    from decorator import decorator
+Expecting nothing
+ok
+Trying:
+    @memoize
+    def heavy_computation():
+        time.sleep(2)
+        return "done"
+Expecting nothing
+ok
+Trying:
+    print(heavy_computation()) # the first time it will take 2 seconds
+Expecting:
+    done
+ok
+Trying:
+    print(heavy_computation()) # the second time it will be instantaneous
+Expecting:
+    done
+ok
+Trying:
+    print(getargspec(heavy_computation)) 
+Expecting:
+    ArgSpec(args=[], varargs=None, keywords=None, defaults=None)
+ok
+Trying:
+    @trace
+    def f1(x):
+        pass
+Expecting nothing
+ok
+Trying:
+    f1(0)
+Expecting:
+    calling f1 with args (0,), {}
+ok
+Trying:
+    print(getargspec(f1)) 
+Expecting:
+    ArgSpec(args=['x'], varargs=None, keywords=None, defaults=None)
+ok
+Trying:
+    @trace
+    def f(x, y=1, z=2, *args, **kw):
+        pass
+Expecting nothing
+ok
+Trying:
+    f(0, 3)
+Expecting:
+    calling f with args (0, 3, 2), {}
+ok
+Trying:
+    print(getargspec(f)) 
+Expecting:
+    ArgSpec(args=['x', 'y', 'z'], varargs='args', keywords='kw', defaults=(1, 2))
+ok
+Trying:
+    @trace
+    def f(x: 'the first argument', y: 'default argument'=1, z=2,
+          *args: 'varargs', **kw: 'kwargs'):
+        pass
+Expecting nothing
+ok
+Trying:
+    from inspect import getfullargspec 
+Expecting nothing
+ok
+Trying:
+    argspec = getfullargspec(f)
+Expecting nothing
+ok
+Trying:
+    argspec.args
+Expecting:
+    ['x', 'y', 'z']
+ok
+Trying:
+    argspec.varargs
+Expecting:
+    'args'
+ok
+Trying:
+    argspec.varkw
+Expecting:
+    'kw'
+ok
+Trying:
+    argspec.defaults
+Expecting:
+    (1, 2)
+ok
+Trying:
+    argspec.kwonlyargs
+Expecting:
+    []
+ok
+Trying:
+    argspec.kwonlydefaults
+Expecting nothing
+ok
+Trying:
+    f.__annotations__ == f.__wrapped__.__annotations__
+Expecting:
+    True
+ok
+Trying:
+    @decorator
+    def trace(f, *args, **kw):
+        kwstr = ', '.join('%r: %r' % (k, kw[k]) for k in sorted(kw))
+        print("calling %s with args %s, {%s}" % (f.__name__, args, kwstr))
+        return f(*args, **kw)
+Expecting nothing
+ok
+Trying:
+    trace # doctest: +ELLIPSIS
+Expecting:
+    <function trace at 0x...>
+ok
+Trying:
+    @trace
+    def func(): pass
+Expecting nothing
+ok
+Trying:
+    func()
+Expecting:
+    calling func with args (), {}
+ok
+Trying:
+    @blocking("Please wait ...")
+    def read_data():
+        time.sleep(3) # simulate a blocking resource
+        return "some data"
+Expecting nothing
+ok
+Trying:
+    print(read_data()) # data is not available yet
+Expecting:
+    Please wait ...
+ok
+Trying:
+    time.sleep(1)  
+Expecting nothing
+ok
+Trying:
+    print(read_data()) # data is not available yet
+Expecting:
+    Please wait ...
+ok
+Trying:
+    time.sleep(1)
+Expecting nothing
+ok
+Trying:
+    print(read_data()) # data is not available yet
+Expecting:
+    Please wait ...
+ok
+Trying:
+    time.sleep(1.1) # after 3.1 seconds, data is available
+Expecting nothing
+ok
+Trying:
+    print(read_data())
+Expecting:
+    some data
+ok
+Trying:
+    async = decorator(Async(threading.Thread))
+Expecting nothing
+ok
+Trying:
+    datalist = [] # for simplicity the written data are stored into a list.
+Expecting nothing
+ok
+Trying:
+    @async
+    def write(data):
+        # append data to the datalist by locking
+        with threading.Lock():
+            time.sleep(1) # emulate some long running operation
+            datalist.append(data)
+        # other operations not requiring a lock here
+Expecting nothing
+ok
+Trying:
+    write("data1") # doctest: +ELLIPSIS
+Expecting:
+    <Thread(write-1, started...)>
+ok
+Trying:
+    time.sleep(.1) # wait a bit, so we are sure data2 is written after data1
+Expecting nothing
+ok
+Trying:
+    write("data2") # doctest: +ELLIPSIS
+Expecting:
+    <Thread(write-2, started...)>
+ok
+Trying:
+    time.sleep(2) # wait for the writers to complete
+Expecting nothing
+ok
+Trying:
+    print(datalist)
+Expecting:
+    ['data1', 'data2']
+ok
+Trying:
+    from contextlib import contextmanager
+Expecting nothing
+ok
+Trying:
+    @contextmanager
+    def before_after(before, after):
+        print(before)
+        yield
+        print(after)
+Expecting nothing
+ok
+Trying:
+    ba = before_after('BEFORE', 'AFTER')
+Expecting nothing
+ok
+Trying:
+    type(ba)
+Expecting:
+    <class 'contextlib._GeneratorContextManager'>
+ok
+Trying:
+    with ba:
+        print('hello')
+Expecting:
+    BEFORE
+    hello
+    AFTER
+ok
+Trying:
+    def f(*args, **kw): # a function with a generic signature
+        print(args, kw)
+Expecting nothing
+ok
+Trying:
+    f1 = FunctionMaker.create('f1(a, b)', 'f(a, b)', dict(f=f))
+Expecting nothing
+ok
+Trying:
+    f1(1,2)
+Expecting:
+    (1, 2) {}
+ok
+Trying:
+    f1 = FunctionMaker.create(
+        'f1(a, b)', 'f(a, b)', dict(f=f), addsource=True)
+Expecting nothing
+ok
+Trying:
+    print(f1.__source__)
+Expecting:
+    def f1(a, b):
+        f(a, b)
+    <BLANKLINE>
+ok
+Trying:
+    print(inspect.getsource(example))
+Expecting:
+        def wrapper(*args, **kw):
+            return func(*args, **kw)
+    <BLANKLINE>
+ok
+Trying:
+    print(inspect.getsource(factorial.__wrapped__))
+Expecting:
+    @tail_recursive
+    def factorial(n, acc=1):
+        "The good old factorial"
+        if n == 0: return acc
+        return factorial(n-1, n*acc)
+    <BLANKLINE>
+ok
+Trying:
+    print(factorial(4))
+Expecting:
+    24
+ok
+Trying:
+    @trace
+    def f():
+        1/0
+Expecting nothing
+ok
+Trying:
+    f() # doctest: +ELLIPSIS
+Expecting:
+    Traceback (most recent call last):
+      ...
+         File "<string>", line 2, in f
+         File "<doctest __main__[22]>", line 4, in trace
+           return f(*args, **kw)
+         File "<doctest __main__[51]>", line 3, in f
+           1/0
+    ZeroDivisionError: ...
+ok
+Trying:
+    @trace
+    def f(_func_): print(f)
+Expecting:
+    Traceback (most recent call last):
+      ...
+    NameError: _func_ is overridden in
+    def f(_func_):
+        return _call_(_func_, _func_)
+ok
+Trying:
+    def f(): pass # the original function
+Expecting nothing
+ok
+Trying:
+    f.attr1 = "something" # setting an attribute
+Expecting nothing
+ok
+Trying:
+    f.attr2 = "something else" # setting another attribute
+Expecting nothing
+ok
+Trying:
+    traced_f = trace(f) # the decorated function
+Expecting nothing
+ok
+Trying:
+    traced_f.attr1
+Expecting:
+    'something'
+ok
+Trying:
+    traced_f.attr2 = "something different" # setting attr
+Expecting nothing
+ok
+Trying:
+    f.attr2 # the original attribute did not change
+Expecting:
+    'something else'
+ok
+Trying:
+    a = Action()
+Expecting nothing
+ok
+Trying:
+    a.view() # ok
+Expecting nothing
+ok
+Trying:
+    a.insert() # err
+Expecting:
+    Traceback (most recent call last):
+       ...
+    PermissionError: User does not have the permission to run insert!
+ok
+Trying:
+    decorator(_memoize).__name__
+Expecting:
+    '_memoize'
+ok
+Trying:
+    factorial.__doc__
+Expecting:
+    'The good old factorial'
+ok
+Trying:
+    ba.__class__.__name__
+Expecting:
+    'ContextManager'
+ok
+Trying:
+    hello('michele')
+Expecting:
+    BEFORE
+    hello michele
+    AFTER
+ok
+Trying:
+    @trace
+    def f(**kw): pass
+Expecting nothing
+ok
+Trying:
+    f()
+Expecting:
+    calling f with args (), {}
+ok
+Trying:
+    @trace
+    def f(*, a=1, **kw): pass
+Expecting nothing
+ok
+Trying:
+    inspect.getfullargspec(f)
+Expecting:
+    FullArgSpec(args=[], varargs=None, varkw='kw', defaults=None, kwonlyargs=['a'], kwonlydefaults={'a': 1}, annotations={})
+ok
+Trying:
+    @trace
+    def func(a, b, *args, y=2, z=3, **kwargs):
+        return y, z
+Expecting nothing
+ok
+Trying:
+    func('a', 'b', 'c', 'd', 'e', y='y', z='z', cat='dog')
+Expecting:
+    calling func with args ('a', 'b', 'c', 'd', 'e'), {'cat': 'dog', 'y': 'y', 'z': 'z'}
+    ('y', 'z')
+ok
+Trying:
+    @trace
+    def f(arg, defarg=1, *args, kwonly=2): pass
+Expecting nothing
+ok
+Trying:
+    f.__kwdefaults__ 
+Expecting:
+    {'kwonly': 2}
+ok
+31 items had no tests:
+    __main__.Action.delete
+    __main__.Action.insert
+    __main__.Action.view
+    __main__.Admin
+    __main__.Async
+    __main__.Async.__call__
+    __main__.Async.__init__
+    __main__.PermissionError
+    __main__.PowerUser
+    __main__.TailRecursive
+    __main__.TailRecursive.__call__
+    __main__.TailRecursive.__init__
+    __main__.User
+    __main__._memoize
+    __main__._trace
+    __main__.before_after
+    __main__.blocking
+    __main__.decorator_apply
+    __main__.example
+    __main__.fact
+    __main__.factorial
+    __main__.get_userclass
+    __main__.identity_dec
+    __main__.memoize
+    __main__.memoize_uw
+    __main__.on_closing
+    __main__.on_failure
+    __main__.on_success
+    __main__.restricted
+    __main__.tail_recursive
+    __main__.trace
+8 items passed all tests:
+  68 tests in __main__
+   3 tests in __main__.Action
+   2 tests in __main__.a_test_for_pylons
+   2 tests in __main__.hello
+   2 tests in __main__.test_kwonly_no_args
+   2 tests in __main__.test_kwonly_star_notation
+   2 tests in __main__.test_kwonlyargs
+   2 tests in __main__.test_kwonlydefaults
+83 tests in 39 items.
+83 passed and 0 failed.
+Test passed.
+[?1034h
\ No newline at end of file