Skip to content

Commit 9d406c8

Browse files
committed
Stop generating nan values in tests to work with latest attrs (#576)
1 parent a3773b2 commit 9d406c8

7 files changed

+176
-123
lines changed

pdm.lock

+96-76
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+4-4
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ lint = [
77
"ruff>=0.0.277",
88
]
99
test = [
10-
"hypothesis>=6.79.4",
11-
"pytest>=7.4.0",
10+
"hypothesis>=6.111.2",
11+
"pytest>=8.3.2",
1212
"pytest-benchmark>=4.0.0",
1313
"immutables>=0.20",
1414
"typing-extensions>=4.7.1",
15-
"coverage>=7.4.0",
16-
"pytest-xdist>=3.4.0",
15+
"coverage>=7.6.1",
16+
"pytest-xdist>=3.6.1",
1717
]
1818
docs = [
1919
"sphinx>=5.3.0",

tests/test_baseconverter.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
unstructure_strats = one_of(just(s) for s in UnstructureStrategy)
1616

1717

18-
@given(simple_typed_classes(newtypes=False), unstructure_strats)
18+
@given(simple_typed_classes(newtypes=False, allow_nan=False), unstructure_strats)
1919
def test_simple_roundtrip(cls_and_vals, strat):
2020
"""
2121
Simple classes with metadata can be unstructured and restructured.
@@ -43,7 +43,7 @@ def test_simple_roundtrip_defaults(attr_and_strat, strat):
4343
assert inst == converter.structure(converter.unstructure(inst), cl)
4444

4545

46-
@given(nested_typed_classes(newtypes=False))
46+
@given(nested_typed_classes(newtypes=False, allow_nan=False))
4747
def test_nested_roundtrip(cls_and_vals):
4848
"""
4949
Nested classes with metadata can be unstructured and restructured.
@@ -55,7 +55,7 @@ def test_nested_roundtrip(cls_and_vals):
5555
assert inst == converter.structure(converter.unstructure(inst), cl)
5656

5757

58-
@given(nested_typed_classes(kw_only=False, newtypes=False))
58+
@given(nested_typed_classes(kw_only=False, newtypes=False, allow_nan=False))
5959
def test_nested_roundtrip_tuple(cls_and_vals):
6060
"""
6161
Nested classes with metadata can be unstructured and restructured.
@@ -70,8 +70,8 @@ def test_nested_roundtrip_tuple(cls_and_vals):
7070

7171
@settings(suppress_health_check=[HealthCheck.filter_too_much, HealthCheck.too_slow])
7272
@given(
73-
simple_typed_classes(defaults=False, newtypes=False),
74-
simple_typed_classes(defaults=False, newtypes=False),
73+
simple_typed_classes(defaults=False, newtypes=False, allow_nan=False),
74+
simple_typed_classes(defaults=False, newtypes=False, allow_nan=False),
7575
unstructure_strats,
7676
)
7777
def test_union_field_roundtrip(cl_and_vals_a, cl_and_vals_b, strat):
@@ -113,8 +113,8 @@ def handler(obj, _):
113113
@pytest.mark.skipif(not is_py310_plus, reason="3.10+ union syntax")
114114
@settings(suppress_health_check=[HealthCheck.filter_too_much, HealthCheck.too_slow])
115115
@given(
116-
simple_typed_classes(defaults=False, newtypes=False),
117-
simple_typed_classes(defaults=False, newtypes=False),
116+
simple_typed_classes(defaults=False, newtypes=False, allow_nan=False),
117+
simple_typed_classes(defaults=False, newtypes=False, allow_nan=False),
118118
unstructure_strats,
119119
)
120120
def test_310_union_field_roundtrip(cl_and_vals_a, cl_and_vals_b, strat):
@@ -153,7 +153,7 @@ def handler(obj, _):
153153
assert inst == converter.structure(converter.unstructure(inst), C)
154154

155155

156-
@given(simple_typed_classes(defaults=False, newtypes=False))
156+
@given(simple_typed_classes(defaults=False, newtypes=False, allow_nan=False))
157157
def test_optional_field_roundtrip(cl_and_vals):
158158
"""
159159
Classes with optional fields can be unstructured and structured.
@@ -175,7 +175,7 @@ class C:
175175

176176

177177
@pytest.mark.skipif(not is_py310_plus, reason="3.10+ union syntax")
178-
@given(simple_typed_classes(defaults=False, newtypes=False))
178+
@given(simple_typed_classes(defaults=False, newtypes=False, allow_nan=False))
179179
def test_310_optional_field_roundtrip(cl_and_vals):
180180
"""
181181
Classes with optional fields can be unstructured and structured.

tests/test_converter.py

+23-15
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@
4040
unstructure_strats = one_of(just(s) for s in UnstructureStrategy)
4141

4242

43-
@given(simple_typed_classes() | simple_typed_dataclasses(), booleans())
43+
@given(
44+
simple_typed_classes(allow_nan=False) | simple_typed_dataclasses(allow_nan=False),
45+
booleans(),
46+
)
4447
def test_simple_roundtrip(cls_and_vals, detailed_validation):
4548
"""
4649
Simple classes with metadata can be unstructured and restructured.
@@ -54,8 +57,8 @@ def test_simple_roundtrip(cls_and_vals, detailed_validation):
5457

5558

5659
@given(
57-
simple_typed_classes(kw_only=False, newtypes=False)
58-
| simple_typed_dataclasses(newtypes=False),
60+
simple_typed_classes(kw_only=False, newtypes=False, allow_nan=False)
61+
| simple_typed_dataclasses(newtypes=False, allow_nan=False),
5962
booleans(),
6063
)
6164
def test_simple_roundtrip_tuple(cls_and_vals, dv: bool):
@@ -72,7 +75,7 @@ def test_simple_roundtrip_tuple(cls_and_vals, dv: bool):
7275
assert inst == converter.structure(unstructured, cl)
7376

7477

75-
@given(simple_typed_attrs(defaults=True))
78+
@given(simple_typed_attrs(defaults=True, allow_nan=False))
7679
def test_simple_roundtrip_defaults(attr_and_vals):
7780
"""
7881
Simple classes with metadata can be unstructured and restructured.
@@ -87,7 +90,9 @@ def test_simple_roundtrip_defaults(attr_and_vals):
8790
assert inst == converter.structure(converter.unstructure(inst), cl)
8891

8992

90-
@given(simple_typed_attrs(defaults=True, kw_only=False, newtypes=False))
93+
@given(
94+
simple_typed_attrs(defaults=True, kw_only=False, newtypes=False, allow_nan=False)
95+
)
9196
def test_simple_roundtrip_defaults_tuple(attr_and_vals):
9297
"""
9398
Simple classes with metadata can be unstructured and restructured.
@@ -103,7 +108,8 @@ def test_simple_roundtrip_defaults_tuple(attr_and_vals):
103108

104109

105110
@given(
106-
simple_typed_classes(newtypes=False) | simple_typed_dataclasses(newtypes=False),
111+
simple_typed_classes(newtypes=False, allow_nan=False)
112+
| simple_typed_dataclasses(newtypes=False, allow_nan=False),
107113
unstructure_strats,
108114
)
109115
def test_simple_roundtrip_with_extra_keys_forbidden(cls_and_vals, strat):
@@ -200,7 +206,7 @@ class A:
200206
assert cve.value.exceptions[0].extra_fields == {"b"}
201207

202208

203-
@given(nested_typed_classes(defaults=True, min_attrs=1), booleans())
209+
@given(nested_typed_classes(defaults=True, min_attrs=1, allow_nan=False), booleans())
204210
def test_nested_roundtrip(cls_and_vals, omit_if_default):
205211
"""
206212
Nested classes with metadata can be unstructured and restructured.
@@ -214,7 +220,9 @@ def test_nested_roundtrip(cls_and_vals, omit_if_default):
214220

215221

216222
@given(
217-
nested_typed_classes(defaults=True, min_attrs=1, kw_only=False, newtypes=False),
223+
nested_typed_classes(
224+
defaults=True, min_attrs=1, kw_only=False, newtypes=False, allow_nan=False
225+
),
218226
booleans(),
219227
)
220228
def test_nested_roundtrip_tuple(cls_and_vals, omit_if_default: bool):
@@ -233,8 +241,8 @@ def test_nested_roundtrip_tuple(cls_and_vals, omit_if_default: bool):
233241

234242
@settings(suppress_health_check=[HealthCheck.filter_too_much, HealthCheck.too_slow])
235243
@given(
236-
simple_typed_classes(defaults=False, newtypes=False),
237-
simple_typed_classes(defaults=False, newtypes=False),
244+
simple_typed_classes(defaults=False, newtypes=False, allow_nan=False),
245+
simple_typed_classes(defaults=False, newtypes=False, allow_nan=False),
238246
unstructure_strats,
239247
)
240248
def test_union_field_roundtrip(cl_and_vals_a, cl_and_vals_b, strat):
@@ -278,8 +286,8 @@ def handler(obj, _):
278286
@pytest.mark.skipif(not is_py310_plus, reason="3.10+ union syntax")
279287
@settings(suppress_health_check=[HealthCheck.filter_too_much, HealthCheck.too_slow])
280288
@given(
281-
simple_typed_classes(defaults=False, newtypes=False),
282-
simple_typed_classes(defaults=False, newtypes=False),
289+
simple_typed_classes(defaults=False, newtypes=False, allow_nan=False),
290+
simple_typed_classes(defaults=False, newtypes=False, allow_nan=False),
283291
unstructure_strats,
284292
)
285293
def test_310_union_field_roundtrip(cl_and_vals_a, cl_and_vals_b, strat):
@@ -320,7 +328,7 @@ def handler(obj, _):
320328
assert inst == converter.structure(unstructured, C)
321329

322330

323-
@given(simple_typed_classes(defaults=False))
331+
@given(simple_typed_classes(defaults=False, allow_nan=False))
324332
def test_optional_field_roundtrip(cl_and_vals):
325333
"""
326334
Classes with optional fields can be unstructured and structured.
@@ -342,7 +350,7 @@ class C:
342350

343351

344352
@pytest.mark.skipif(not is_py310_plus, reason="3.10+ union syntax")
345-
@given(simple_typed_classes(defaults=False))
353+
@given(simple_typed_classes(defaults=False, allow_nan=False))
346354
def test_310_optional_field_roundtrip(cl_and_vals):
347355
"""
348356
Classes with optional fields can be unstructured and structured.
@@ -363,7 +371,7 @@ class C:
363371
assert inst == converter.structure(unstructured, C)
364372

365373

366-
@given(simple_typed_classes(defaults=True))
374+
@given(simple_typed_classes(defaults=True, allow_nan=False))
367375
def test_omit_default_roundtrip(cl_and_vals):
368376
"""
369377
Omit default on the converter works.

tests/test_gen_dict.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,9 @@ def test_individual_overrides(converter_cls, cl_and_vals):
160160

161161

162162
@given(
163-
cl_and_vals=nested_typed_classes()
164-
| simple_typed_classes()
165-
| simple_typed_dataclasses(),
163+
cl_and_vals=nested_typed_classes(allow_nan=False)
164+
| simple_typed_classes(allow_nan=False)
165+
| simple_typed_dataclasses(allow_nan=False),
166166
dv=...,
167167
)
168168
def test_unmodified_generated_structuring(cl_and_vals, dv: bool):
@@ -185,7 +185,9 @@ def test_unmodified_generated_structuring(cl_and_vals, dv: bool):
185185

186186

187187
@given(
188-
simple_typed_classes(min_attrs=1) | simple_typed_dataclasses(min_attrs=1), data()
188+
simple_typed_classes(min_attrs=1, allow_nan=False)
189+
| simple_typed_dataclasses(min_attrs=1, allow_nan=False),
190+
data(),
189191
)
190192
def test_renaming(cl_and_vals, data):
191193
converter = Converter()

tests/typed.py

+37-14
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def simple_typed_classes(
6767
newtypes=True,
6868
text_codec: str = "utf8",
6969
allow_infinity=None,
70-
allow_nan=None,
70+
allow_nan=True,
7171
) -> SearchStrategy[Tuple[Type, PosArgs, KwArgs]]:
7272
"""Yield tuples of (class, values)."""
7373
return lists_of_typed_attrs(
@@ -82,23 +82,30 @@ def simple_typed_classes(
8282
).flatmap(partial(_create_hyp_class, frozen=frozen))
8383

8484

85-
def simple_typed_dataclasses(defaults=None, min_attrs=0, frozen=False, newtypes=True):
85+
def simple_typed_dataclasses(
86+
defaults=None, min_attrs=0, frozen=False, newtypes=True, allow_nan=True
87+
):
8688
"""Yield tuples of (class, values)."""
8789
return lists_of_typed_attrs(
8890
defaults,
8991
min_size=min_attrs,
9092
for_frozen=frozen,
9193
allow_mutable_defaults=False,
9294
newtypes=newtypes,
95+
allow_nan=allow_nan,
9396
).flatmap(partial(_create_dataclass, frozen=frozen))
9497

9598

9699
def simple_typed_classes_and_strats(
97-
defaults=None, min_attrs=0, kw_only=None, newtypes=True
100+
defaults=None, min_attrs=0, kw_only=None, newtypes=True, allow_nan=True
98101
) -> SearchStrategy[Tuple[Type, SearchStrategy[PosArgs], SearchStrategy[KwArgs]]]:
99102
"""Yield tuples of (class, (strategies))."""
100103
return lists_of_typed_attrs(
101-
defaults, min_size=min_attrs, kw_only=kw_only, newtypes=newtypes
104+
defaults,
105+
min_size=min_attrs,
106+
kw_only=kw_only,
107+
newtypes=newtypes,
108+
allow_nan=allow_nan,
102109
).flatmap(_create_hyp_class_and_strat)
103110

104111

@@ -111,7 +118,7 @@ def lists_of_typed_attrs(
111118
newtypes=True,
112119
text_codec="utf8",
113120
allow_infinity=None,
114-
allow_nan=None,
121+
allow_nan=True,
115122
) -> SearchStrategy[List[Tuple[_CountingAttr, SearchStrategy[PosArg]]]]:
116123
# Python functions support up to 255 arguments.
117124
return lists(
@@ -142,7 +149,7 @@ def simple_typed_attrs(
142149
newtypes=True,
143150
text_codec="utf8",
144151
allow_infinity=None,
145-
allow_nan=None,
152+
allow_nan=True,
146153
) -> SearchStrategy[Tuple[_CountingAttr, SearchStrategy[PosArgs]]]:
147154
if not is_39_or_later:
148155
res = (
@@ -400,7 +407,7 @@ def str_typed_attrs(draw, defaults=None, kw_only=None, codec: str = "utf8"):
400407

401408
@composite
402409
def float_typed_attrs(
403-
draw, defaults=None, kw_only=None, allow_infinity=None, allow_nan=None
410+
draw, defaults=None, kw_only=None, allow_infinity=None, allow_nan=True
404411
):
405412
"""
406413
Generate a tuple of an attribute and a strategy that yields floats for that
@@ -832,7 +839,7 @@ def dict_of_class(
832839

833840

834841
def _create_hyp_nested_strategy(
835-
simple_class_strategy: SearchStrategy, kw_only=None, newtypes=True
842+
simple_class_strategy: SearchStrategy, kw_only=None, newtypes=True, allow_nan=True
836843
) -> SearchStrategy[Tuple[Type, SearchStrategy[PosArgs], SearchStrategy[KwArgs]]]:
837844
"""
838845
Create a recursive attrs class.
@@ -847,7 +854,8 @@ def _create_hyp_nested_strategy(
847854
attrs_and_classes: SearchStrategy[
848855
Tuple[List[Tuple[_CountingAttr, PosArgs]], Tuple[Type, SearchStrategy[PosArgs]]]
849856
] = tuples(
850-
lists_of_typed_attrs(kw_only=kw_only, newtypes=newtypes), simple_class_strategy
857+
lists_of_typed_attrs(kw_only=kw_only, newtypes=newtypes, allow_nan=allow_nan),
858+
simple_class_strategy,
851859
)
852860

853861
return nested_classes(attrs_and_classes)
@@ -891,22 +899,37 @@ def nested_classes(
891899

892900

893901
def nested_typed_classes_and_strat(
894-
defaults=None, min_attrs=0, kw_only=None, newtypes=True
902+
defaults=None, min_attrs=0, kw_only=None, newtypes=True, allow_nan=True
895903
) -> SearchStrategy[Tuple[Type, SearchStrategy[PosArgs]]]:
896904
return recursive(
897905
simple_typed_classes_and_strats(
898-
defaults=defaults, min_attrs=min_attrs, kw_only=kw_only, newtypes=newtypes
906+
defaults=defaults,
907+
min_attrs=min_attrs,
908+
kw_only=kw_only,
909+
newtypes=newtypes,
910+
allow_nan=allow_nan,
911+
),
912+
partial(
913+
_create_hyp_nested_strategy,
914+
kw_only=kw_only,
915+
newtypes=newtypes,
916+
allow_nan=allow_nan,
899917
),
900-
partial(_create_hyp_nested_strategy, kw_only=kw_only, newtypes=newtypes),
901918
max_leaves=20,
902919
)
903920

904921

905922
@composite
906-
def nested_typed_classes(draw, defaults=None, min_attrs=0, kw_only=None, newtypes=True):
923+
def nested_typed_classes(
924+
draw, defaults=None, min_attrs=0, kw_only=None, newtypes=True, allow_nan=True
925+
):
907926
cl, strat, kwarg_strat = draw(
908927
nested_typed_classes_and_strat(
909-
defaults=defaults, min_attrs=min_attrs, kw_only=kw_only, newtypes=newtypes
928+
defaults=defaults,
929+
min_attrs=min_attrs,
930+
kw_only=kw_only,
931+
newtypes=newtypes,
932+
allow_nan=allow_nan,
910933
)
911934
)
912935
return cl, draw(strat), draw(kwarg_strat)

tests/untyped.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ def float_attrs(draw, defaults=None, kw_only=None):
356356
"""
357357
default = NOTHING
358358
if defaults is True or (defaults is None and draw(st.booleans())):
359-
default = draw(st.floats())
359+
default = draw(st.floats(allow_nan=False))
360360
return (
361361
attr.ib(
362362
default=default, kw_only=draw(st.booleans()) if kw_only is None else kw_only

0 commit comments

Comments
 (0)