tlsfuzzer / python-ecdsa

pure-python ECDSA signature/verification and ECDH key agreement
Other
906 stars 311 forks source link

pytest 8 failing tests #336

Closed jelly closed 3 months ago

jelly commented 3 months ago

Rebuilding against either 3.11 or 3.12 gives me test failures likely introduced by pytest 8 (as the tests succeed in Fedora with pytest 7).

=================================== FAILURES ===================================
________________ TestEncodeBitstring.test_implicit_unused_bits _________________

self = <ecdsa.test_der.TestEncodeBitstring testMethod=test_implicit_unused_bits>

    def test_implicit_unused_bits(self):
        """
        Writing bit string with already included the number of unused bits.
        """
        warnings.simplefilter("always")
>       with pytest.warns(None) as warns:

src/ecdsa/test_der.py:161:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = WarningsChecker(record=True), expected_warning = None, match_expr = None

    def __init__(
        self,
        expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]] = Warning,
        match_expr: Optional[Union[str, Pattern[str]]] = None,
        *,
        _ispytest: bool = False,
    ) -> None:
        check_ispytest(_ispytest)
        super().__init__(_ispytest=True)

        msg = "exceptions must be derived from Warning, not %s"
        if isinstance(expected_warning, tuple):
            for exc in expected_warning:
                if not issubclass(exc, Warning):
                    raise TypeError(msg % type(exc))
            expected_warning_tup = expected_warning
        elif isinstance(expected_warning, type) and issubclass(
            expected_warning, Warning
        ):
            expected_warning_tup = (expected_warning,)
        else:
>           raise TypeError(msg % type(expected_warning))
E           TypeError: exceptions must be derived from Warning, not <class 'NoneType'>

/usr/lib/python3.11/site-packages/_pytest/recwarn.py:285: TypeError
_________________ TestEncodeBitstring.test_new_call_convention _________________

self = <ecdsa.test_der.TestEncodeBitstring testMethod=test_new_call_convention>

    def test_new_call_convention(self):
        """This is how it should be called now."""
        warnings.simplefilter("always")
>       with pytest.warns(None) as warns:

src/ecdsa/test_der.py:148:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = WarningsChecker(record=True), expected_warning = None, match_expr = None

    def __init__(
        self,
        expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]] = Warning,
        match_expr: Optional[Union[str, Pattern[str]]] = None,
        *,
        _ispytest: bool = False,
    ) -> None:
        check_ispytest(_ispytest)
        super().__init__(_ispytest=True)

        msg = "exceptions must be derived from Warning, not %s"
        if isinstance(expected_warning, tuple):
            for exc in expected_warning:
                if not issubclass(exc, Warning):
                    raise TypeError(msg % type(exc))
            expected_warning_tup = expected_warning
        elif isinstance(expected_warning, type) and issubclass(
            expected_warning, Warning
        ):
            expected_warning_tup = (expected_warning,)
        else:
>           raise TypeError(msg % type(expected_warning))
E           TypeError: exceptions must be derived from Warning, not <class 'NoneType'>

/usr/lib/python3.11/site-packages/_pytest/recwarn.py:285: TypeError
_____________ TestRemoveBitstring.test_implicit_unexpected_unused ______________

self = <ecdsa.test_der.TestRemoveBitstring testMethod=test_implicit_unexpected_unused>

    def test_implicit_unexpected_unused(self):
        warnings.simplefilter("always")
>       with pytest.warns(None) as warns:

src/ecdsa/test_der.py:217:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = WarningsChecker(record=True), expected_warning = None, match_expr = None

    def __init__(
        self,
        expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]] = Warning,
        match_expr: Optional[Union[str, Pattern[str]]] = None,
        *,
        _ispytest: bool = False,
    ) -> None:
        check_ispytest(_ispytest)
        super().__init__(_ispytest=True)

        msg = "exceptions must be derived from Warning, not %s"
        if isinstance(expected_warning, tuple):
            for exc in expected_warning:
                if not issubclass(exc, Warning):
                    raise TypeError(msg % type(exc))
            expected_warning_tup = expected_warning
        elif isinstance(expected_warning, type) and issubclass(
            expected_warning, Warning
        ):
            expected_warning_tup = (expected_warning,)
        else:
>           raise TypeError(msg % type(expected_warning))
E           TypeError: exceptions must be derived from Warning, not <class 'NoneType'>

/usr/lib/python3.11/site-packages/_pytest/recwarn.py:285: TypeError
_________________ TestRemoveBitstring.test_new_call_convention _________________

self = <ecdsa.test_der.TestRemoveBitstring testMethod=test_new_call_convention>

    def test_new_call_convention(self):
        warnings.simplefilter("always")
>       with pytest.warns(None) as warns:

src/ecdsa/test_der.py:207:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = WarningsChecker(record=True), expected_warning = None, match_expr = None

    def __init__(
        self,
        expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]] = Warning,
        match_expr: Optional[Union[str, Pattern[str]]] = None,
        *,
        _ispytest: bool = False,
    ) -> None:
        check_ispytest(_ispytest)
        super().__init__(_ispytest=True)

        msg = "exceptions must be derived from Warning, not %s"
        if isinstance(expected_warning, tuple):
            for exc in expected_warning:
                if not issubclass(exc, Warning):
                    raise TypeError(msg % type(exc))
            expected_warning_tup = expected_warning
        elif isinstance(expected_warning, type) and issubclass(
            expected_warning, Warning
        ):
            expected_warning_tup = (expected_warning,)
        else:
>           raise TypeError(msg % type(expected_warning))
E           TypeError: exceptions must be derived from Warning, not <class 'NoneType'>

/usr/lib/python3.11/site-packages/_pytest/recwarn.py:285: TypeError
=============================== warnings summary ===============================
src/ecdsa/test_malformed_sigs.py::test_fuzzed_der_signatures
  /usr/lib/python3.11/site-packages/hypothesis/strategies/_internal/lazy.py:158: HypothesisWarning: Generating overly large repr. This is an expensive operation, and with a length of 68 kB is is unlikely to be useful. Use -Wignore to ignore the warning, or -Werror to get a traceback.
    self.__representation = repr_call(

src/ecdsa/test_malformed_sigs.py::test_fuzzed_string_signatures
  /usr/lib/python3.11/site-packages/hypothesis/strategies/_internal/lazy.py:158: HypothesisWarning: Generating overly large repr. This is an expensive operation, and with a length of 66 kB is is unlikely to be useful. Use -Wignore to ignore the warning, or -Werror to get a traceback.
    self.__representation = repr_call(

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
FAILED src/ecdsa/test_der.py::TestEncodeBitstring::test_implicit_unused_bits
FAILED src/ecdsa/test_der.py::TestEncodeBitstring::test_new_call_convention
FAILED src/ecdsa/test_der.py::TestRemoveBitstring::test_implicit_unexpected_unused
FAILED src/ecdsa/test_der.py::TestRemoveBitstring::test_new_call_convention
============ 4 failed, 1759 passed, 5 skipped, 2 warnings in 10.19s ============
tomato42 commented 3 months ago

Looks like it's already fixed in https://github.com/tlsfuzzer/python-ecdsa/pull/313, by 50c1fa44f35b9d38 more specifically.

Can you check current master for the issue?

tomato42 commented 3 months ago

(@jelly if you can confirm that master fixes the issue, then I can quickly release a new version, I wanted to do few more things before releasing 0.19, but if releasing it now helps packagers, I have no problem doing it now)

jelly commented 3 months ago

Thanks for the reply! That indeed fixes it and makes the tests pass. FYI I also had to apply https://github.com/tlsfuzzer/python-ecdsa/commit/87a1596b93f45f5b2ee484ca12a075365e67815a which the Fedora package also patches.

A new release is not required for now, I disabled those tests and release a new package. And with this patch the test suite now succeeds!

tomato42 commented 3 months ago

I really have no strict reason not to release a new version, and given that there was no release for close to two years now, it's probably good idea anyway.