`Optional` default-parsing fails for C-based callables
BvB93 opened this issue · comments
Bas van Beek commented
The changes introduced in #268 include a call to inspect.signature
, which was done under the assuption that this function could parse all callables. Unfortunetly this is not correct, as inspect.signature
will raise for callables that are defined in C (float
, int
, dict
, etc.) and those are therefore no longer usable as Optional
defaults.
Examples
In [1]: from schema import Schema, Optional
In [2]: dict_schema = Schema({
...: Optional('foo', default=dict): dict,
...: })
in [3]: dict_schema.validate({})
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-8-d42ec1bc3a4c> in <module>
----> 1 DictSchema.validate({})
~/opt/anaconda3/envs/test/lib/python3.9/site-packages/schema.py in validate(self, data, **kwargs)
429 defaults = set(k for k in s if isinstance(k, Optional) and hasattr(k, "default")) - coverage
430 for default in defaults:
--> 431 new[default.key] = _invoke_with_optional_kwargs(default.default, **kwargs) if callable(default.default) else default.default
432
433 return new
~/opt/anaconda3/envs/test/lib/python3.9/site-packages/schema.py in _invoke_with_optional_kwargs(f, **kwargs)
275
276 def _invoke_with_optional_kwargs(f, **kwargs):
--> 277 s = inspect.signature(f)
278 if len(s.parameters) == 0:
279 return f()
~/opt/anaconda3/envs/test/lib/python3.9/inspect.py in signature(obj, follow_wrapped)
3109 def signature(obj, *, follow_wrapped=True):
3110 """Get a signature object for the passed callable."""
-> 3111 return Signature.from_callable(obj, follow_wrapped=follow_wrapped)
3112
3113
~/opt/anaconda3/envs/test/lib/python3.9/inspect.py in from_callable(cls, obj, follow_wrapped)
2858 def from_callable(cls, obj, *, follow_wrapped=True):
2859 """Constructs Signature for the given callable object."""
-> 2860 return _signature_from_callable(obj, sigcls=cls,
2861 follow_wrapper_chains=follow_wrapped)
2862
~/opt/anaconda3/envs/test/lib/python3.9/inspect.py in _signature_from_callable(obj, follow_wrapper_chains, skip_bound_arg, sigcls)
2393 return sigcls.from_callable(object)
2394 else:
-> 2395 raise ValueError(
2396 'no signature found for builtin type {!r}'.format(obj))
2397
ValueError: no signature found for builtin type <class 'dict'>
Info
schema version: 0.7.5
python version: 3.9.7
Alex Robbins commented
If we can't merge that PR can we at least yank release 0.7.5? This bug seems pretty intrusive but 0.7.4 works fine.
(Or, if this project is unmaintained, it would be good to have that in the README.)