Skip to content

Commit

Permalink
Fix required arg handling under Python2
Browse files Browse the repository at this point in the history
  • Loading branch information
Zac-HD committed Jul 18, 2017
1 parent 58ece74 commit 1299def
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 11 deletions.
3 changes: 2 additions & 1 deletion src/hypothesis/searchstrategy/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
def required_args(target, args=(), kwargs=()):
"""Return a set of required args to target."""
try:
spec = getfullargspec(target)
spec = getfullargspec(
target.__init__ if inspect.isclass(target) else target)
except TypeError:
return None
# For classes, self is present in the argspec but not really required
Expand Down
18 changes: 8 additions & 10 deletions src/hypothesis/strategies.py
Original file line number Diff line number Diff line change
Expand Up @@ -910,20 +910,18 @@ def from_type(thing):
elif strategies:
return one_of(strategies)
# If we don't have a strategy registered for this type or any subtype, we
# may be able to fall back on type annotations. If the constructor has
# an annotation for every required argument, we can (and do) use builds().
required = types.required_args(thing)
if not required or required.issubset(get_type_hints(thing.__init__)):
return builds(thing)
# The final special case is types created via typing.NamedTuple, which
# use a custom attribute but not annotations for their types. We can use
# builds() for this again, if we work out the right kwargs.
# may be able to fall back on type annotations.
# Types created via typing.NamedTuple use a custom attribute instead -
# but we can still use builds(), if we work out the right kwargs.
if issubclass(thing, tuple) and hasattr(thing, '_fields') \
and hasattr(thing, '_field_types'):
# Special handling for user-defined typing.NamedTuple
# collections.namedtuples can't be inferred; add then to lookup
kwargs = {k: from_type(thing._field_types[k]) for k in thing._fields}
return builds(thing, **kwargs)
# If the constructor has an annotation for every required argument,
# we can (and do) use builds() without supplying additional arguments.
required = types.required_args(thing)
if not required or required.issubset(get_type_hints(thing.__init__)):
return builds(thing)
# We have utterly failed, and might as well say so now.
raise ResolutionFailed('Could not resolve %r to a strategy; consider '
'using register_type_strategy' % (thing,))
Expand Down

0 comments on commit 1299def

Please sign in to comment.