keleshev / schema

Schema validation just got Pythonic

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`Optional` default-parsing fails for C-based callables

BvB93 opened this issue · comments

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

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.)