Skip to content

Commit 9cb67a2

Browse files
committed
Correctly retrieve forward referenced annotations from typed dictionaries
1 parent b7e9f60 commit 9cb67a2

File tree

4 files changed

+40
-1
lines changed

4 files changed

+40
-1
lines changed

AUTHORS.rst

+1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ their individual contributions.
7878
* `jwg4 <https://www.github.com/jwg4>`_
7979
* `Kai Chen <https://www.github.com/kx-chen>`_ ([email protected])
8080
* `Karthikeyan Singaravelan <https://www.github.com/tirkarthi>`_ ([email protected])
81+
* `Katelyn Gigante <https://github.com/silasary>`_
8182
* `Katrina Durance <https://github.com/kdurance>`_
8283
* `kbara <https://www.github.com/kbara>`_
8384
* `Kristian Glass <https://www.github.com/doismellburning>`_

hypothesis-python/RELEASE.rst

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
RELEASE_TYPE: patch
2+
3+
This patch fixes :func:`~hypothesis.strategies.from_type` on a :class:`~python:typing.TypedDict`
4+
with complex annotations, defined in a file using ``from __future__ import annotations``.
5+
Thanks to Katelyn Gigante for identifying and fixing this bug!

hypothesis-python/src/hypothesis/strategies/_internal/core.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1076,7 +1076,7 @@ def as_strategy(strat_or_callable, thing, final=True):
10761076
# way to tell and we just have to assume that everything is required.
10771077
# See https://github.com/python/cpython/pull/17214 for details.
10781078
optional = getattr(thing, "__optional_keys__", ())
1079-
anns = {k: from_type(v) for k, v in thing.__annotations__.items()}
1079+
anns = {k: from_type(v) for k, v in get_type_hints(thing).items()}
10801080
return fixed_dictionaries( # type: ignore
10811081
mapping={k: v for k, v in anns.items() if k not in optional},
10821082
optional={k: v for k, v in anns.items() if k in optional},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# This file is part of Hypothesis, which may be found at
2+
# https://github.com/HypothesisWorks/hypothesis/
3+
#
4+
# Copyright the Hypothesis Authors.
5+
# Individual contributors are listed in AUTHORS.rst and the git log.
6+
#
7+
# This Source Code Form is subject to the terms of the Mozilla Public License,
8+
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
9+
# obtain one at https://mozilla.org/MPL/2.0/.
10+
11+
from __future__ import annotations
12+
13+
from typing import TypedDict, Union
14+
15+
from hypothesis import given, strategies as st
16+
17+
18+
@given(st.data())
19+
def test_complex_forward_ref_in_typed_dict(data):
20+
alias = Union[int, bool]
21+
22+
class A(TypedDict):
23+
a: int
24+
25+
class B(TypedDict):
26+
a: A
27+
b: alias
28+
29+
b_strategy = st.from_type(B)
30+
d = data.draw(b_strategy)
31+
assert isinstance(d["a"], dict)
32+
assert isinstance(d["a"]["a"], int)
33+
assert isinstance(d["b"], (int, bool))

0 commit comments

Comments
 (0)