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

Run Python 3.12 beta in CI #3667

Merged
merged 5 commits into from
Jun 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ jobs:
- check-py311-cover
- check-py311-nocover
- check-py311-niche
# - check-py312-cover
# - check-py312-nocover
# - check-py312-niche
- check-py312-cover
- check-py312-nocover
- check-py312-niche
# - check-py313-cover
- check-quality
## Skip all the (inactive/old) Rust and Ruby tests pending fixes
Expand Down
4 changes: 4 additions & 0 deletions hypothesis-python/RELEASE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
RELEASE_TYPE: patch

We now test against Python 3.12 beta in CI, and this patch
fixes some new deprecations.
10 changes: 5 additions & 5 deletions hypothesis-python/src/hypothesis/strategies/_internal/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1123,6 +1123,11 @@ def from_type_guarded(thing):
if types.is_a_union(thing):
args = sorted(thing.__args__, key=types.type_sorting_key)
return one_of([_from_type(t, recurse_guard) for t in args])
# We also have a special case for TypeVars.
# They are represented as instances like `~T` when they come here.
# We need to work with their type instead.
if isinstance(thing, TypeVar) and type(thing) in types._global_type_lookup:
return as_strategy(types._global_type_lookup[type(thing)], thing)
if not types.is_a_type(thing):
if isinstance(thing, str):
# See https://github.com/HypothesisWorks/hypothesis/issues/3016
Expand Down Expand Up @@ -1190,11 +1195,6 @@ def from_type_guarded(thing):
mapping={k: v for k, v in anns.items() if k not in optional},
optional={k: v for k, v in anns.items() if k in optional},
)
# We also have a special case for TypeVars.
# They are represented as instances like `~T` when they come here.
# We need to work with their type instead.
if isinstance(thing, TypeVar) and type(thing) in types._global_type_lookup:
return as_strategy(types._global_type_lookup[type(thing)], thing)

# If there's no explicitly registered strategy, maybe a subtype of thing
# is registered - if so, we can resolve it to the subclass strategy.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ def from_typing_type(thing):
# Except for sequences of integers, or unions which include integer!
# See https://github.com/HypothesisWorks/hypothesis/issues/2257
#
# This block drops ByteString from the types that can be generated
# This block drops bytes from the types that can be generated
# if there is more than one allowed type, and the element type is
# not either `int` or a Union with `int` as one of its elements.
elem_type = (getattr(thing, "__args__", None) or ["not int"])[0]
Expand All @@ -450,7 +450,7 @@ def from_typing_type(thing):
and thing.__forward_arg__ in vars(builtins)
):
return st.from_type(getattr(builtins, thing.__forward_arg__))
# Before Python 3.9, we sometimes have e.g. ByteString from both the typing
# Before Python 3.9, we sometimes have e.g. Sequence from both the typing
# module, and collections.abc module. Discard any type which is not it's own
# origin, where the origin is also in the mapping.
for t in sorted(mapping, key=type_sorting_key):
Expand Down
14 changes: 10 additions & 4 deletions hypothesis-python/tests/cover/test_lookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@
t
for t in types._global_type_lookup
# We ignore TypeVar, because it is not a Generic type:
if isinstance(t, types.typing_root_type) and t != typing.TypeVar
if isinstance(t, types.typing_root_type)
and t != typing.TypeVar
and (sys.version_info[:2] <= (3, 11) or t != typing.ByteString)
),
key=str,
)
Expand Down Expand Up @@ -110,7 +112,11 @@ def test_typing_Type_Union(ex):
@given(data=st.data())
def test_rare_types(data, typ):
ex = data.draw(from_type(typ))
assert isinstance(ex, typ)
with warnings.catch_warnings():
if sys.version_info[:2] >= (3, 12):
warnings.simplefilter("ignore", DeprecationWarning)
# ByteString is deprecated in Python 3.12
assert isinstance(ex, typ)


class Elem:
Expand Down Expand Up @@ -752,7 +758,7 @@ def test_inference_on_generic_collections_abc_aliases(typ, data):
def test_bytestring_not_treated_as_generic_sequence(val):
# Check that we don't fall into the specific problem from
# https://github.com/HypothesisWorks/hypothesis/issues/2257
assert not isinstance(val, typing.ByteString)
assert not isinstance(val, bytes)
# Check it hasn't happened again from some other non-generic sequence type.
for x in val:
assert isinstance(x, set)
Expand All @@ -764,7 +770,7 @@ def test_bytestring_not_treated_as_generic_sequence(val):
def test_bytestring_is_valid_sequence_of_int_and_parent_classes(type_):
find_any(
st.from_type(typing.Sequence[type_]),
lambda val: isinstance(val, typing.ByteString),
lambda val: isinstance(val, bytes),
)


Expand Down
6 changes: 5 additions & 1 deletion hypothesis-python/tests/cover/test_type_lookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,11 @@ def test_uninspectable_from_type():

def _check_instances(t):
# See https://github.com/samuelcolvin/pydantic/discussions/2508
return t.__module__ != "typing" and not t.__module__.startswith("pydantic")
return (
t.__module__ != "typing"
and t.__name__ != "ByteString"
and not t.__module__.startswith("pydantic")
)


@pytest.mark.parametrize(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def test_bound_type_cheking_only_forward_ref():
st.builds(typechecking_only_fun).example()


def test_bound_type_cheking_only_forward_ref_wrong_type():
def test_bound_type_checking_only_forward_ref_wrong_type():
"""We should check ``ForwardRef`` parameter name correctly."""
with utils.temp_registered(ForwardRef("WrongType"), st.just(1)):
with pytest.raises(ResolutionFailed):
Expand Down
12 changes: 10 additions & 2 deletions hypothesis-python/tests/datetime/test_dateutil_timezones.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,27 @@
# obtain one at https://mozilla.org/MPL/2.0/.

import datetime as dt
import sys
import warnings

import pytest
from dateutil import tz, zoneinfo

from hypothesis import assume, given
from hypothesis.errors import FailedHealthCheck, InvalidArgument
from hypothesis.extra.dateutil import timezones
from hypothesis.strategies import data, datetimes, just, sampled_from, times
from hypothesis.strategies._internal.datetime import datetime_does_not_exist

from tests.common.debug import assert_all_examples, find_any, minimal
from tests.common.utils import fails_with

with warnings.catch_warnings():
if sys.version_info[:2] >= (3, 12):
# Prior to https://github.com/dateutil/dateutil/pull/1285/
warnings.simplefilter("ignore", DeprecationWarning)
from dateutil import tz, zoneinfo

from hypothesis.extra.dateutil import timezones


def test_utc_is_minimal():
assert tz.UTC is minimal(timezones())
Expand Down
15 changes: 12 additions & 3 deletions hypothesis-python/tests/datetime/test_pytz_timezones.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@
# obtain one at https://mozilla.org/MPL/2.0/.

import datetime as dt
import sys
import warnings

import pytest
import pytz
from dateutil.tz import datetime_exists

from hypothesis import assume, given
from hypothesis.errors import InvalidArgument
from hypothesis.extra.pytz import timezones
from hypothesis.strategies import data, datetimes, just, sampled_from, times
from hypothesis.strategies._internal.datetime import datetime_does_not_exist

Expand All @@ -27,6 +26,16 @@
minimal,
)

with warnings.catch_warnings():
if sys.version_info[:2] >= (3, 12):
# See https://github.com/stub42/pytz/issues/105 and
# https://github.com/dateutil/dateutil/pull/1285/
warnings.simplefilter("ignore", DeprecationWarning)
import pytz
from dateutil.tz import datetime_exists

from hypothesis.extra.pytz import timezones


def test_utc_is_minimal():
assert pytz.UTC is minimal(timezones())
Expand Down
9 changes: 8 additions & 1 deletion hypothesis-python/tests/nocover/test_from_type_recipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@
from hypothesis import given, strategies as st
from hypothesis.strategies._internal.types import _global_type_lookup

TYPES = sorted((x for x in _global_type_lookup if x.__module__ != "typing"), key=str)
TYPES = sorted(
(
x
for x in _global_type_lookup
if x.__module__ != "typing" and x.__name__ != "ByteString"
),
key=str,
)


def everything_except(excluded_types):
Expand Down