Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests fail with python 3.12 #32

Open
keszybz opened this issue May 29, 2023 · 1 comment
Open

tests fail with python 3.12 #32

keszybz opened this issue May 29, 2023 · 1 comment

Comments

@keszybz
Copy link
Contributor

keszybz commented May 29, 2023

Hi! I'm the maintainer of the python-decopath package in Fedora. The tests fail with python 3.12 (currently beta1). It seems to be minor stuff, some whitespace formatting changes:

=================================== FAILURES ===================================
__________________________ test_doc_say_hello[nested] __________________________

capsys = <_pytest.capture.CaptureFixture object at 0x7fdf0d78bd40>
mode = 'nested'

    @pytest.mark.parametrize('mode', ['nested', 'flat', 'double-flat'])
    def test_doc_say_hello(capsys, mode):
        """ Tests that the @say_hello example from doc works """
    
        with capsys.disabled():
            if mode == 'nested':
                @function_decorator
                def say_hello(person="world", f=DECORATED):
                    """
                    This decorator wraps the decorated function so that a nice hello
                    message is printed before each call.
    
                    :param person: the person name in the print message. Default = "world"
                    """
    
                    # create a wrapper of f that will do the print before call
                    # we rely on `makefun.wraps` to preserve signature
                    @wraps(f)
                    def new_f(*args, **kwargs):
                        print("hello, %s !" % person)  # say hello
                        return f(*args, **kwargs)  # call f
    
                    # return the new function
                    return new_f
            elif mode == 'flat':
                @function_decorator
                def say_hello(person="world", f=DECORATED):
                    """
                    This decorator wraps the decorated function so that a nice hello
                    message is printed before each call.
    
                    :param person: the person name in the print message. Default = "world"
                    """
    
                    # create a wrapper of f that will do the print before call
                    # we rely on `makefun.wraps` to preserve signature
                    @wraps(f)
                    def new_f(*args, **kwargs):
                        print("hello, %s !" % person)  # say hello
                        return f(*args, **kwargs)  # call f
    
                    # return the new function
                    return new_f
    
            elif mode == 'double-flat':
                @function_decorator
                def say_hello(person="world", f=WRAPPED, f_args=F_ARGS, f_kwargs=F_KWARGS):
                    """
                    This decorator wraps the decorated function so that a nice hello
                    message is printed before each call.
    
                    :param person: the person name in the print message. Default = "world"
                    """
                    print("hello, %s !" % person)  # say hello
                    return f(*f_args, **f_kwargs)  # call f
    
            else:
                raise ValueError("unsupported mode : %s" % mode)
    
        # for debug..
        with capsys.disabled():
            @say_hello  # no parenthesis
            def foo():
                print("<executing foo>")
    
        # for debug..
        with capsys.disabled():
            foo()
    
        foo()
    
        @say_hello()  # empty parenthesis
        def bar():
            print("<executing bar>")
    
        bar()
    
        @say_hello("you")  # arg
        def custom():
            print("<executing custom>")
    
        custom()
    
        # manual decoration
        def custom2():
            print("<executing custom2>")
    
        custom2 = say_hello()(custom2)
        custom2()
    
        help(say_hello)
    
        assert str(signature(say_hello)) == "(person='world')"
    
        print("Signature: %s" % signature(say_hello))
    
        @say_hello  # no parenthesis
        def add_ints(a, b):
            return a + b
    
        assert add_ints(1, 3) == 4
    
        captured = capsys.readouterr()
        with capsys.disabled():
            print(captured.out)
    
>       assert captured.out == """hello, world !
    <executing foo>
    hello, world !
    <executing bar>
    hello, you !
    <executing custom>
    hello, world !
    <executing custom2>
    Help on function say_hello in module tests.test_doc:
    
    say_hello(person='world')
        This decorator wraps the decorated function so that a nice hello
        message is printed before each call.
    
        :param person: the person name in the print message. Default = "world"
    
    Signature: (person='world')
    hello, world !
    """
E       assert 'hello, world !\n<executing foo>\nhello, world !\n<executing bar>\nhello, you !\n<executing custom>\nhello, world !\n<executing custom2>\nHelp on function say_hello in module tests.test_doc:\n\nsay_hello(person=\'world\')\n    This decorator wraps the decorated function so that a nice hello\n    message is printed before each call.\n\n    :param person: the person name in the print message. Default = "world"\n\nSignature: (person=\'world\')\nhello, world !\n' == 'hello, world !\n<executing foo>\nhello, world !\n<executing bar>\nhello, you !\n<executing custom>\nhello, world !\n<executing custom2>\nHelp on function say_hello in module tests.test_doc:\n\nsay_hello(person=\'world\')\n    This decorator wraps the decorated function so that a nice hello\n    message is printed before each call.\n    \n    :param person: the person name in the print message. Default = "world"\n\nSignature: (person=\'world\')\nhello, world !\n'
E           hello, world !
E           <executing foo>
E           hello, world !
E           <executing bar>
E           hello, you !
E           <executing custom>
E           hello, world !
E           <executing custom2>
E           Help on function say_hello in module tests.test_doc:
E           
E           say_hello(person='world')
E               This decorator wraps the decorated function so that a nice hello
E               message is printed before each call.
E         -     
E         + 
E               :param person: the person name in the print message. Default = "world"
E           
E           Signature: (person='world')
E           hello, world !

tests/test_doc.py:185: AssertionError
___________________________ test_doc_say_hello[flat] ___________________________

capsys = <_pytest.capture.CaptureFixture object at 0x7fdf0d44d7f0>
mode = 'flat'

    @pytest.mark.parametrize('mode', ['nested', 'flat', 'double-flat'])
    def test_doc_say_hello(capsys, mode):
        """ Tests that the @say_hello example from doc works """
    
        with capsys.disabled():
            if mode == 'nested':
                @function_decorator
                def say_hello(person="world", f=DECORATED):
                    """
                    This decorator wraps the decorated function so that a nice hello
                    message is printed before each call.
    
                    :param person: the person name in the print message. Default = "world"
                    """
    
                    # create a wrapper of f that will do the print before call
                    # we rely on `makefun.wraps` to preserve signature
                    @wraps(f)
                    def new_f(*args, **kwargs):
                        print("hello, %s !" % person)  # say hello
                        return f(*args, **kwargs)  # call f
    
                    # return the new function
                    return new_f
            elif mode == 'flat':
                @function_decorator
                def say_hello(person="world", f=DECORATED):
                    """
                    This decorator wraps the decorated function so that a nice hello
                    message is printed before each call.
    
                    :param person: the person name in the print message. Default = "world"
                    """
    
                    # create a wrapper of f that will do the print before call
                    # we rely on `makefun.wraps` to preserve signature
                    @wraps(f)
                    def new_f(*args, **kwargs):
                        print("hello, %s !" % person)  # say hello
                        return f(*args, **kwargs)  # call f
    
                    # return the new function
                    return new_f
    
            elif mode == 'double-flat':
                @function_decorator
                def say_hello(person="world", f=WRAPPED, f_args=F_ARGS, f_kwargs=F_KWARGS):
                    """
                    This decorator wraps the decorated function so that a nice hello
                    message is printed before each call.
    
                    :param person: the person name in the print message. Default = "world"
                    """
                    print("hello, %s !" % person)  # say hello
                    return f(*f_args, **f_kwargs)  # call f
    
            else:
                raise ValueError("unsupported mode : %s" % mode)
    
        # for debug..
        with capsys.disabled():
            @say_hello  # no parenthesis
            def foo():
                print("<executing foo>")
    
        # for debug..
        with capsys.disabled():
            foo()
    
        foo()
    
        @say_hello()  # empty parenthesis
        def bar():
            print("<executing bar>")
    
        bar()
    
        @say_hello("you")  # arg
        def custom():
            print("<executing custom>")
    
        custom()
    
        # manual decoration
        def custom2():
            print("<executing custom2>")
    
        custom2 = say_hello()(custom2)
        custom2()
    
        help(say_hello)
    
        assert str(signature(say_hello)) == "(person='world')"
    
        print("Signature: %s" % signature(say_hello))
    
        @say_hello  # no parenthesis
        def add_ints(a, b):
            return a + b
    
        assert add_ints(1, 3) == 4
    
        captured = capsys.readouterr()
        with capsys.disabled():
            print(captured.out)
    
>       assert captured.out == """hello, world !
    <executing foo>
    hello, world !
    <executing bar>
    hello, you !
    <executing custom>
    hello, world !
    <executing custom2>
    Help on function say_hello in module tests.test_doc:
    
    say_hello(person='world')
        This decorator wraps the decorated function so that a nice hello
        message is printed before each call.
    
        :param person: the person name in the print message. Default = "world"
    
    Signature: (person='world')
    hello, world !
    """
E       assert 'hello, world !\n<executing foo>\nhello, world !\n<executing bar>\nhello, you !\n<executing custom>\nhello, world !\n<executing custom2>\nHelp on function say_hello in module tests.test_doc:\n\nsay_hello(person=\'world\')\n    This decorator wraps the decorated function so that a nice hello\n    message is printed before each call.\n\n    :param person: the person name in the print message. Default = "world"\n\nSignature: (person=\'world\')\nhello, world !\n' == 'hello, world !\n<executing foo>\nhello, world !\n<executing bar>\nhello, you !\n<executing custom>\nhello, world !\n<executing custom2>\nHelp on function say_hello in module tests.test_doc:\n\nsay_hello(person=\'world\')\n    This decorator wraps the decorated function so that a nice hello\n    message is printed before each call.\n    \n    :param person: the person name in the print message. Default = "world"\n\nSignature: (person=\'world\')\nhello, world !\n'
E           hello, world !
E           <executing foo>
E           hello, world !
E           <executing bar>
E           hello, you !
E           <executing custom>
E           hello, world !
E           <executing custom2>
E           Help on function say_hello in module tests.test_doc:
E           
E           say_hello(person='world')
E               This decorator wraps the decorated function so that a nice hello
E               message is printed before each call.
E         -     
E         + 
E               :param person: the person name in the print message. Default = "world"
E           
E           Signature: (person='world')
E           hello, world !

tests/test_doc.py:185: AssertionError
_______________________ test_doc_say_hello[double-flat] ________________________

capsys = <_pytest.capture.CaptureFixture object at 0x7fdf0d43bd40>
mode = 'double-flat'

    @pytest.mark.parametrize('mode', ['nested', 'flat', 'double-flat'])
    def test_doc_say_hello(capsys, mode):
        """ Tests that the @say_hello example from doc works """
    
        with capsys.disabled():
            if mode == 'nested':
                @function_decorator
                def say_hello(person="world", f=DECORATED):
                    """
                    This decorator wraps the decorated function so that a nice hello
                    message is printed before each call.
    
                    :param person: the person name in the print message. Default = "world"
                    """
    
                    # create a wrapper of f that will do the print before call
                    # we rely on `makefun.wraps` to preserve signature
                    @wraps(f)
                    def new_f(*args, **kwargs):
                        print("hello, %s !" % person)  # say hello
                        return f(*args, **kwargs)  # call f
    
                    # return the new function
                    return new_f
            elif mode == 'flat':
                @function_decorator
                def say_hello(person="world", f=DECORATED):
                    """
                    This decorator wraps the decorated function so that a nice hello
                    message is printed before each call.
    
                    :param person: the person name in the print message. Default = "world"
                    """
    
                    # create a wrapper of f that will do the print before call
                    # we rely on `makefun.wraps` to preserve signature
                    @wraps(f)
                    def new_f(*args, **kwargs):
                        print("hello, %s !" % person)  # say hello
                        return f(*args, **kwargs)  # call f
    
                    # return the new function
                    return new_f
    
            elif mode == 'double-flat':
                @function_decorator
                def say_hello(person="world", f=WRAPPED, f_args=F_ARGS, f_kwargs=F_KWARGS):
                    """
                    This decorator wraps the decorated function so that a nice hello
                    message is printed before each call.
    
                    :param person: the person name in the print message. Default = "world"
                    """
                    print("hello, %s !" % person)  # say hello
                    return f(*f_args, **f_kwargs)  # call f
    
            else:
                raise ValueError("unsupported mode : %s" % mode)
    
        # for debug..
        with capsys.disabled():
            @say_hello  # no parenthesis
            def foo():
                print("<executing foo>")
    
        # for debug..
        with capsys.disabled():
            foo()
    
        foo()
    
        @say_hello()  # empty parenthesis
        def bar():
            print("<executing bar>")
    
        bar()
    
        @say_hello("you")  # arg
        def custom():
            print("<executing custom>")
    
        custom()
    
        # manual decoration
        def custom2():
            print("<executing custom2>")
    
        custom2 = say_hello()(custom2)
        custom2()
    
        help(say_hello)
    
        assert str(signature(say_hello)) == "(person='world')"
    
        print("Signature: %s" % signature(say_hello))
    
        @say_hello  # no parenthesis
        def add_ints(a, b):
            return a + b
    
        assert add_ints(1, 3) == 4
    
        captured = capsys.readouterr()
        with capsys.disabled():
            print(captured.out)
    
>       assert captured.out == """hello, world !
    <executing foo>
    hello, world !
    <executing bar>
    hello, you !
    <executing custom>
    hello, world !
    <executing custom2>
    Help on function say_hello in module tests.test_doc:
    
    say_hello(person='world')
        This decorator wraps the decorated function so that a nice hello
        message is printed before each call.
    
        :param person: the person name in the print message. Default = "world"
    
    Signature: (person='world')
    hello, world !
    """
E       assert 'hello, world !\n<executing foo>\nhello, world !\n<executing bar>\nhello, you !\n<executing custom>\nhello, world !\n<executing custom2>\nHelp on function say_hello in module tests.test_doc:\n\nsay_hello(person=\'world\')\n    This decorator wraps the decorated function so that a nice hello\n    message is printed before each call.\n\n    :param person: the person name in the print message. Default = "world"\n\nSignature: (person=\'world\')\nhello, world !\n' == 'hello, world !\n<executing foo>\nhello, world !\n<executing bar>\nhello, you !\n<executing custom>\nhello, world !\n<executing custom2>\nHelp on function say_hello in module tests.test_doc:\n\nsay_hello(person=\'world\')\n    This decorator wraps the decorated function so that a nice hello\n    message is printed before each call.\n    \n    :param person: the person name in the print message. Default = "world"\n\nSignature: (person=\'world\')\nhello, world !\n'
E           hello, world !
E           <executing foo>
E           hello, world !
E           <executing bar>
E           hello, you !
E           <executing custom>
E           hello, world !
E           <executing custom2>
E           Help on function say_hello in module tests.test_doc:
E           
E           say_hello(person='world')
E               This decorator wraps the decorated function so that a nice hello
E               message is printed before each call.
E         -     
E         + 
E               :param person: the person name in the print message. Default = "world"
E           
E           Signature: (person='world')
E           hello, world !

tests/test_doc.py:185: AssertionError
________________________ test_doc_impl_first_say_hello _________________________

capsys = <_pytest.capture.CaptureFixture object at 0x7fdf0d44fc50>

    def test_doc_impl_first_say_hello(capsys):
        """The second implementation-first example in the doc"""
    
        @function_decorator
        def say_hello(person='world', f=DECORATED):
            """
            This decorator modifies the decorated function so that a nice hello
            message is printed before the call.
    
            :param person: the person name in the print message. Default = "world"
            :param f: represents the decorated item. Automatically injected.
            :return: a modified version of `f` that will print a hello message before executing
            """
    
            # create a wrapper of f that will do the print before call
            # we rely on `makefun.wraps` to preserve signature
            @wraps(f)
            def new_f(*args, **kwargs):
                # nonlocal person
                person = new_f.person
                print("hello, %s !" % person)  # say hello
                return f(*args, **kwargs)  # call f
    
            # we use the trick at https://stackoverflow.com/a/16032631/7262247
            # to access the nonlocal 'person' variable in python 2 and 3
            # for python 3 only you can use 'nonlocal' https://www.python.org/dev/peps/pep-3104/
            new_f.person = person
    
            # return the wrapper
            return new_f
    
        @say_hello
        def foo(a, b):
            return a + b
    
        @say_hello()
        def bar(a, b):
            return a + b
    
        @say_hello("you")
        def custom(a, b):
            return a + b
    
        assert foo(1, 3) == 4
        assert bar(1, 3) == 4
        assert custom(1, 3) == 4
    
        help(say_hello)
    
        print("Signature: %s" % signature(say_hello))
    
        captured = capsys.readouterr()
        with capsys.disabled():
            print(captured.out)
    
>       assert captured.out == """hello, world !
    hello, world !
    hello, you !
    Help on function say_hello in module tests.test_doc_advanced:
    
    say_hello(person='world')
        This decorator modifies the decorated function so that a nice hello
        message is printed before the call.
    
        :param person: the person name in the print message. Default = "world"
        :param f: represents the decorated item. Automatically injected.
        :return: a modified version of `f` that will print a hello message before executing
    
    Signature: (person='world')
    """
E       assert 'hello, world !\nhello, world !\nhello, you !\nHelp on function say_hello in module tests.test_doc_advanced:\n\nsay_hello(person=\'world\')\n    This decorator modifies the decorated function so that a nice hello\n    message is printed before the call.\n\n    :param person: the person name in the print message. Default = "world"\n    :param f: represents the decorated item. Automatically injected.\n    :return: a modified version of `f` that will print a hello message before executing\n\nSignature: (person=\'world\')\n' == 'hello, world !\nhello, world !\nhello, you !\nHelp on function say_hello in module tests.test_doc_advanced:\n\nsay_hello(person=\'world\')\n    This decorator modifies the decorated function so that a nice hello\n    message is printed before the call.\n    \n    :param person: the person name in the print message. Default = "world"\n    :param f: represents the decorated item. Automatically injected.\n    :return: a modified version of `f` that will print a hello message before executing\n\nSignature: (person=\'world\')\n'
E           hello, world !
E           hello, world !
E           hello, you !
E           Help on function say_hello in module tests.test_doc_advanced:
E           
E           say_hello(person='world')
E               This decorator modifies the decorated function so that a nice hello
E               message is printed before the call.
E         -     
E         + 
E               :param person: the person name in the print message. Default = "world"
E               :param f: represents the decorated item. Automatically injected.
E               :return: a modified version of `f` that will print a hello message before executing
E           
E           Signature: (person='world')

tests/test_doc_advanced.py:203: AssertionError
=========================== short test summary info ============================
FAILED tests/test_doc.py::test_doc_say_hello[nested] - assert 'hello, world !...
FAILED tests/test_doc.py::test_doc_say_hello[flat] - assert 'hello, world !\n...
FAILED tests/test_doc.py::test_doc_say_hello[double-flat] - assert 'hello, wo...
FAILED tests/test_doc_advanced.py::test_doc_impl_first_say_hello - assert 'he...
================== 4 failed, 182 passed, 80 skipped in 0.58s ===================

Downstream bug report: https://bugzilla.redhat.com/show_bug.cgi?id=2196785
It also has instructions how to get a test environment with python 3.12 on Fedora.

@smarie
Copy link
Owner

smarie commented May 30, 2023

Thanks @keszybz ! I'll investigate when I find a bit of time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants