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

H2 and Python 3.10a7: test failures due to changes in repr() #1253

Closed
eclipseo opened this issue Apr 13, 2021 · 2 comments
Closed

H2 and Python 3.10a7: test failures due to changes in repr() #1253

eclipseo opened this issue Apr 13, 2021 · 2 comments

Comments

@eclipseo
Copy link

There were some changes in repr() in latest alpha of Python 3.10.
https://docs.python.org/3.10/whatsnew/changelog.html#python-3-10-0-alpha-7

bpo-40066: Enum: adjust repr() to show only enum and member name (not value, nor angle brackets) and str() to show only member name. Update and improve documentation to match.

bpo-40066: Enum’s repr() and str() have changed: repr() is now EnumClass.MemberName and str() is MemberName. Additionally, stdlib Enum’s whose contents are available as module attributes, such as RegexFlag.IGNORECASE, have their repr() as module.name, e.g. re.IGNORECASE.

https://bugs.python.org/issue40066

This causes multiple test failures:

============================= test session starts ==============================
platform linux -- Python 3.10.0a7, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
rootdir: /builddir/build/BUILD/h2-4.0.0, configfile: setup.cfg, testpaths: test
plugins: hypothesis-6.6.0
collected 1414 items

test/test_basic_logic.py ............................................... [  3%]
........................................................................ [  8%]
........................................................................ [ 13%]
........................................................................ [ 18%]
........................................................................ [ 23%]
................................................F                        [ 27%]
test/test_closed_streams.py .....................                        [ 28%]
test/test_complex_logic.py .................                             [ 29%]
test/test_config.py .................................................... [ 33%]
............                                                             [ 34%]
test/test_events.py .........F...F.F.FF.........................         [ 37%]
test/test_exceptions.py .                                                [ 37%]
test/test_flow_control_window.py ....................................... [ 40%]
......                                                                   [ 40%]
test/test_h2_upgrade.py .............                                    [ 41%]
test/test_head_request.py ..                                             [ 41%]
test/test_header_indexing.py ........................................... [ 44%]
........................................................................ [ 49%]
........................................................................ [ 55%]
........................................................................ [ 60%]
.........................................                                [ 63%]
test/test_informational_responses.py ..............................      [ 65%]
test/test_interacting_stacks.py .                                        [ 65%]
test/test_invalid_content_lengths.py ...                                 [ 65%]
test/test_invalid_frame_sequences.py .......................             [ 67%]
test/test_invalid_headers.py ........................................... [ 70%]
........................................................................ [ 75%]
........................................................................ [ 80%]
........................................................................ [ 85%]
........................................................................ [ 90%]
................                                                         [ 91%]
test/test_priority.py .......................                            [ 93%]
test/test_related_events.py .............                                [ 94%]
test/test_rfc7838.py ...................                                 [ 95%]
test/test_rfc8441.py .                                                   [ 95%]
test/test_settings.py ................................                   [ 97%]
test/test_state_machines.py ..................                           [ 99%]
test/test_stream_reset.py .....                                          [ 99%]
test/test_utility_functions.py ........                                  [100%]

=================================== FAILURES ===================================
_______________________ TestBasicServer.test_stream_repr _______________________

self = <test.test_basic_logic.TestBasicServer object at 0x7f305f7bfe20>

    def test_stream_repr(self):
        """
        Ensure stream string representation is appropriate.
        """
        s = h2.stream.H2Stream(4, None, 12, 14)
>       assert repr(s) == "<H2Stream id:4 state:<StreamState.IDLE: 0>>"
E       AssertionError: assert '<H2Stream id...amState.IDLE>' == '<H2Stream id...ate.IDLE: 0>>'
E         - <H2Stream id:4 state:<StreamState.IDLE: 0>>
E         ?                      -                --- -
E         + <H2Stream id:4 state:StreamState.IDLE>

test/test_basic_logic.py:1849: AssertionError
________________ TestEventReprs.test_remotesettingschanged_repr ________________

self = <test.test_events.TestEventReprs object at 0x7f305f335900>

    def test_remotesettingschanged_repr(self):
        """
        RemoteSettingsChanged has a useful debug representation.
        """
        e = h2.events.RemoteSettingsChanged()
        e.changed_settings = {
            h2.settings.SettingCodes.INITIAL_WINDOW_SIZE:
                h2.settings.ChangedSetting(
                    h2.settings.SettingCodes.INITIAL_WINDOW_SIZE, 2**16, 2**15
                ),
        }
    
>       assert repr(e) == (
            "<RemoteSettingsChanged changed_settings:{ChangedSetting("
            "setting=SettingCodes.INITIAL_WINDOW_SIZE, original_value=65536, "
            "new_value=32768)}>"
        )
E       AssertionError: assert '<RemoteSetti...alue=32768)}>' == '<RemoteSetti...alue=32768)}>'
E         Skipping 54 identical leading characters in diff, use -v to show
E         - g(setting=SettingCodes.INITIAL_WINDOW_SIZE, original_value=65536, new_value=32768)}>
E         ?           -------------
E         + g(setting=INITIAL_WINDOW_SIZE, original_value=65536, new_value=32768)}>

test/test_events.py:210: AssertionError
_____________________ TestEventReprs.test_streamreset_repr _____________________

self = <test.test_events.TestEventReprs object at 0x7f305f56c340>

    def test_streamreset_repr(self):
        """
        StreamEnded has a useful debug representation.
        """
        e = h2.events.StreamReset()
        e.stream_id = 919
        e.error_code = h2.errors.ErrorCodes.ENHANCE_YOUR_CALM
        e.remote_reset = False
    
>       assert repr(e) == (
            "<StreamReset stream_id:919, "
            "error_code:ErrorCodes.ENHANCE_YOUR_CALM, remote_reset:False>"
        )
E       AssertionError: assert '<StreamReset..._reset:False>' == '<StreamReset..._reset:False>'
E         - <StreamReset stream_id:919, error_code:ErrorCodes.ENHANCE_YOUR_CALM, remote_reset:False>
E         ?                                        -----------
E         + <StreamReset stream_id:919, error_code:ENHANCE_YOUR_CALM, remote_reset:False>

test/test_events.py:252: AssertionError
________________ TestEventReprs.test_settingsacknowledged_repr _________________

self = <test.test_events.TestEventReprs object at 0x7f305f334e80>

    def test_settingsacknowledged_repr(self):
        """
        SettingsAcknowledged has a useful debug representation.
        """
        e = h2.events.SettingsAcknowledged()
        e.changed_settings = {
            h2.settings.SettingCodes.INITIAL_WINDOW_SIZE:
                h2.settings.ChangedSetting(
                    h2.settings.SettingCodes.INITIAL_WINDOW_SIZE, 2**16, 2**15
                ),
        }
    
>       assert repr(e) == (
            "<SettingsAcknowledged changed_settings:{ChangedSetting("
            "setting=SettingCodes.INITIAL_WINDOW_SIZE, original_value=65536, "
            "new_value=32768)}>"
        )
E       AssertionError: assert '<SettingsAck...alue=32768)}>' == '<SettingsAck...alue=32768)}>'
E         Skipping 53 identical leading characters in diff, use -v to show
E         - g(setting=SettingCodes.INITIAL_WINDOW_SIZE, original_value=65536, new_value=32768)}>
E         ?           -------------
E         + g(setting=INITIAL_WINDOW_SIZE, original_value=65536, new_value=32768)}>

test/test_events.py:287: AssertionError
___________ TestEventReprs.test_connectionterminated_repr[None-None] ___________

self = <test.test_events.TestEventReprs object at 0x7f305f5d41f0>
additional_data = None, data_repr = 'None'

    @pytest.mark.parametrize("additional_data,data_repr", [
        (None, "None"),
        (b'some data', "736f6d652064617461")
    ])
    def test_connectionterminated_repr(self, additional_data, data_repr):
        """
        ConnectionTerminated has a useful debug representation.
        """
        e = h2.events.ConnectionTerminated()
        e.error_code = h2.errors.ErrorCodes.INADEQUATE_SECURITY
        e.last_stream_id = 33
        e.additional_data = additional_data
    
>       assert repr(e) == (
            "<ConnectionTerminated error_code:ErrorCodes.INADEQUATE_SECURITY, "
            "last_stream_id:33, additional_data:%s>" % data_repr
        )
E       AssertionError: assert '<ConnectionT...al_data:None>' == '<ConnectionT...al_data:None>'
E         - <ConnectionTerminated error_code:ErrorCodes.INADEQUATE_SECURITY, last_stream_id:33, additional_data:None>
E         ?                                  -----------
E         + <ConnectionTerminated error_code:INADEQUATE_SECURITY, last_stream_id:33, additional_data:None>

test/test_events.py:321: AssertionError
_ TestEventReprs.test_connectionterminated_repr[some data-736f6d652064617461] __

self = <test.test_events.TestEventReprs object at 0x7f305f336f50>
additional_data = b'some data', data_repr = '736f6d652064617461'

    @pytest.mark.parametrize("additional_data,data_repr", [
        (None, "None"),
        (b'some data', "736f6d652064617461")
    ])
    def test_connectionterminated_repr(self, additional_data, data_repr):
        """
        ConnectionTerminated has a useful debug representation.
        """
        e = h2.events.ConnectionTerminated()
        e.error_code = h2.errors.ErrorCodes.INADEQUATE_SECURITY
        e.last_stream_id = 33
        e.additional_data = additional_data
    
>       assert repr(e) == (
            "<ConnectionTerminated error_code:ErrorCodes.INADEQUATE_SECURITY, "
            "last_stream_id:33, additional_data:%s>" % data_repr
        )
E       AssertionError: assert '<ConnectionT...652064617461>' == '<ConnectionT...652064617461>'
E         - <ConnectionTerminated error_code:ErrorCodes.INADEQUATE_SECURITY, last_stream_id:33, additional_data:736f6d652064617461>
E         ?                                  -----------
E         + <ConnectionTerminated error_code:INADEQUATE_SECURITY, last_stream_id:33, additional_data:736f6d652064617461>

test/test_events.py:321: AssertionError
=========================== short test summary info ============================
FAILED test/test_basic_logic.py::TestBasicServer::test_stream_repr - Assertio...
FAILED test/test_events.py::TestEventReprs::test_remotesettingschanged_repr
FAILED test/test_events.py::TestEventReprs::test_streamreset_repr - Assertion...
FAILED test/test_events.py::TestEventReprs::test_settingsacknowledged_repr - ...
FAILED test/test_events.py::TestEventReprs::test_connectionterminated_repr[None-None]
FAILED test/test_events.py::TestEventReprs::test_connectionterminated_repr[some data-736f6d652064617461]
======================= 6 failed, 1408 passed in 33.81s ========================
eclipseo pushed a commit to eclipseo/h2 that referenced this issue Apr 13, 2021
Stating Python 3.10 alpha 7, repr() was modified as follow:

bpo-40066: Enum: adjust repr() to show only enum and member name
(not value, nor angle brackets) and str() to show only member name.
Update and improve documentation to match.

bpo-40066: Enum’s repr() and str() have changed: repr() is
now EnumClass.MemberName and str() is MemberName. Additionally,
stdlib Enum’s whose contents are available as module attributes,
such as RegexFlag.IGNORECASE, have their repr() as module.name,
e.g. re.IGNORECASE.

See https://bugs.python.org/issue40066

This commit fixes the assertions to match the new repr() behavior.

Fix python-hyper#1253
@musicinmybrain
Copy link

The CPython changes were reverted for Python 3.10.0b4 (full thread) and will not be present in Python 3.10. It does look like these changes are coming back in some form for Python 3.11.

@Kriechi
Copy link
Member

Kriechi commented Mar 26, 2022

Closing as 3.10 is stable released and this is not an issue any more.

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

Successfully merging a pull request may close this issue.

3 participants