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

from_type on typing.Protocol without methods #3803

Closed
Rik-de-Kort opened this issue Nov 27, 2023 · 1 comment
Closed

from_type on typing.Protocol without methods #3803

Rik-de-Kort opened this issue Nov 27, 2023 · 1 comment

Comments

@Rik-de-Kort
Copy link

Rik-de-Kort commented Nov 27, 2023

I'm expecting a protocol without any methods to be able to passed in to from_type, but that doesn't work.
Additionally, a bare class with only class variables can also not be passed to from_type, but a dataclass can.

import typing

from hypothesis import given, strategies as st

@typing.runtime_checkable
class NoMethods(typing.Protocol):
    x: float

@given(st.from_type(NoMethods)
def test_can_handle_methodless_protocols(data):
    assert data.x is not None

Fails with message:
FAILED test.py::test_can_handle_methodless_protocols - TypeError: Protocols with non-method members don't support issubclass()

The bare class example:

from hypothesis import given, strategies as st

class NoMethods:
    x: float

@given(st.from_type(NoMethods))
def test_can_handle_methodless_protocols(no_methods):
    assert no_methods.x is not None

Fails with message:
FAILED test.py::test_can_handle_methodless_protocols - AttributeError: 'NoMethods' object has no attribute 'x'

The dataclass example:

from dataclasses import dataclass

from hypothesis import given, strategies as st

@dataclass
class NoMethods:
    x: float

@given(st.from_type(NoMethods))
def test_can_handle_methodless_protocols(no_methods):
    assert no_methods.x is not None

does pass. I would expect all of them to

On the other hand, a protocol is a non-runtime thing, so maybe there should be a separate strategy from_protocol?

@Zac-HD
Copy link
Member

Zac-HD commented Nov 27, 2023

  • Your NoMethods protocol is not actually runtime-checkable (because it has non-method attributes), so Hypothesis can't handle this at runtime. Unfortunate, but nothing we can do there.
  • from_type() successfully generates instances of the bare class - the fact that this doesn't actually ensure that the x attribute exists is not Hypothesis' problem.
  • @dataclass generates an __init__() method which takes a float x and assigns it to an attribute, so this works.

An internal _from_protocol() strategy to use for non-runtime-checkable protocols would be technically feasible, but providing objects with no useful behavior which technically satisfy the protocol just doesn't seem very useful to me.

@Zac-HD Zac-HD closed this as completed Nov 27, 2023
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