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

Add more internal type hints #4105

Merged
merged 12 commits into from
Nov 9, 2024
Merged

Conversation

tybug
Copy link
Member

@tybug tybug commented Sep 13, 2024

Largely focused on non-conjecture this time. There are some source changes here as I tightened things up while typing, like no longer passing length-one strings or None to as_general_categories.

@tybug tybug requested a review from Zac-HD as a code owner September 13, 2024 18:42
@cacheable
@defines_strategy(force_reusable_values=True)
def characters(
*,
codec: Optional[str] = None,
min_codepoint: Optional[int] = None,
max_codepoint: Optional[int] = None,
categories: Optional[Collection[CategoryName]] = None,
exclude_categories: Optional[Collection[CategoryName]] = None,
categories: Optional[Categories] = None,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

notably this is a loosening of the type, from Collection[CategoryName] to Iterable[CategoryName].

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, not sure about this - it works, but non-collection iterables seem like a real footgun for our users!

Copy link
Member Author

@tybug tybug Sep 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something something hyrum's Law / may as well type what works? I think typing as Iterable doesn't push the footgun up to the user, so to speak – they would have to be shooting themselves already. More like Collection forces them to "fix" what in our determination is a "footgun" (but maybe they have a valid-but-cursed custom iterable type that doesn't implement e.g. __contains__).

But I am very unexperienced in maintaining forward-facing types, so I'm happy to defer this decision.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's stick with the status quo (Collection) here, and get the rest in 🙂

@tybug
Copy link
Member Author

tybug commented Sep 13, 2024

hmm, I've been testing locally with --allow-redefinition, which is the source of some of the mypy ci errors. Do we want to enable this in hypothesis? I find it ergonomic and dislike the alternative of arbitrary new names solely for uniqueness.

Copy link
Member

@Zac-HD Zac-HD left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--allow-redefinition seems fine to me

hypothesis-python/src/hypothesis/configuration.py Outdated Show resolved Hide resolved
hypothesis-python/src/hypothesis/internal/charmap.py Outdated Show resolved Hide resolved
@@ -206,14 +218,14 @@ def get_type_hints(thing):
# We still use the same trick on Python 3, because Numpy values and other
# custom __floor__ or __ceil__ methods may convert via floats.
# See issue #1667, Numpy issue 9068.
def floor(x):
def floor(x: float) -> int:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's broader than this though; essentially typing.SupportsInt (& Number, except no intersection types)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we defer this until a usage site requires it? I don't want to write a type which is subtly an overapproximation, whereas I am confident that float is an underapproximation.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we do use this on Numpy scalars, so maybe we already need it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking a type-checked usage site. I did just look into typing this though and it's a rabbit hole of defining a custom protocol inheriting SupportsInt and from _typeshed import SupportsAllComparisons except then mypy errors with Non-overlapping equality check and I gave up. Let's revert and come back another day?

Comment on lines 28 to 30
# we can't use this at runtime until from_type supports
# protocols -- breaks ghostwriter tests
class RandomLike(Protocol):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for me, later: maybe all this takes is to mark this protocol as runtime_checkable?

hypothesis-python/src/hypothesis/internal/intervalsets.py Outdated Show resolved Hide resolved
hypothesis-python/src/hypothesis/internal/scrutineer.py Outdated Show resolved Hide resolved
@cacheable
@defines_strategy(force_reusable_values=True)
def characters(
*,
codec: Optional[str] = None,
min_codepoint: Optional[int] = None,
max_codepoint: Optional[int] = None,
categories: Optional[Collection[CategoryName]] = None,
exclude_categories: Optional[Collection[CategoryName]] = None,
categories: Optional[Categories] = None,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, not sure about this - it works, but non-collection iterables seem like a real footgun for our users!

@Zac-HD
Copy link
Member

Zac-HD commented Oct 5, 2024

Looking at the CI failures and typing improvements in python 3.9, I suggest we revisit this after #4125.

I've also pulled out some of the easy bits in #4126 to simplify future reviews 🙂

@tybug
Copy link
Member Author

tybug commented Oct 5, 2024

yeah, sorry, I haven't had time to finish this pr up. Happy to do whatever's most efficient here.

@Zac-HD
Copy link
Member

Zac-HD commented Oct 5, 2024

oh, no worries at all about dropping stuff, just look at how old some of my PRs are getting! If working on Hypothesis would feel like an obligation instead of a fun hobby, that's a good time to go do something else instead 🙂

@tybug
Copy link
Member Author

tybug commented Oct 5, 2024

I can't even tell you how much I enjoy + wish I had time to work on hypothesis 😄 But, the paper takes priority for the moment.

@tybug
Copy link
Member Author

tybug commented Nov 9, 2024

I've brought this branch up to date, and removed some overcomplicated typing in validation.py in the interest of moving things along. I'm happy for you to make a final decision on the st.characters typing either way Zac 🙂

Copy link
Member

@Zac-HD Zac-HD left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Comments below, then merge at will.

(unfortunately I just watched that no-longer-xfailed mypy test flake, so maybe we need to revert 😭)

hypothesis-python/src/hypothesis/errors.py Outdated Show resolved Hide resolved
@@ -206,14 +218,14 @@ def get_type_hints(thing):
# We still use the same trick on Python 3, because Numpy values and other
# custom __floor__ or __ceil__ methods may convert via floats.
# See issue #1667, Numpy issue 9068.
def floor(x):
def floor(x: float) -> int:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we do use this on Numpy scalars, so maybe we already need it?

@cacheable
@defines_strategy(force_reusable_values=True)
def characters(
*,
codec: Optional[str] = None,
min_codepoint: Optional[int] = None,
max_codepoint: Optional[int] = None,
categories: Optional[Collection[CategoryName]] = None,
exclude_categories: Optional[Collection[CategoryName]] = None,
categories: Optional[Categories] = None,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's stick with the status quo (Collection) here, and get the rest in 🙂

@tybug tybug enabled auto-merge November 9, 2024 22:52
@tybug
Copy link
Member Author

tybug commented Nov 9, 2024

Saw the same mypy flake in #4163, so I've put back the xfail here

@tybug tybug disabled auto-merge November 9, 2024 23:02
@tybug tybug force-pushed the conjecture-typing branch 2 times, most recently from 26e0a0b to ba09d86 Compare November 9, 2024 23:08
@tybug tybug enabled auto-merge November 9, 2024 23:16
@tybug tybug merged commit f2b3500 into HypothesisWorks:master Nov 9, 2024
48 checks passed
@tybug tybug deleted the conjecture-typing branch November 9, 2024 23:59
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 this pull request may close these issues.

2 participants