python-hyper / h2

HTTP/2 State-Machine based protocol implementation
https://h2.readthedocs.io/en/stable
MIT License
963 stars 151 forks source link

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

Closed eclipseo closed 2 years ago

eclipseo commented 3 years ago

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 ========================
musicinmybrain commented 3 years ago

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 commented 2 years ago

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