not compatible with pydantic.validate_arguments
A function with Field parameter wrapped by pydantic.validate_arguments, can not been exeuted from the command line.
from datetime import datetime
from pydantic import Field, validate_arguments
@validate_arguments()
def foo(dt: datetime = Field(default_factory=datetime.now)):
print(dt)
if __name__ == '__main__':
import fire
fire.Fire(foo)
run this code from command line with raise:
Traceback (most recent call last):
File "/home/xxx/repositories/others/test_fire.py", line 12, in <module>
fire.Fire(foo)
File "/home/xxx/.conda/envs/py39/lib/python3.9/site-packages/fire/core.py", line 141, in Fire
component_trace = _Fire(component, args, parsed_flag_args, context, name)
File "/home/xxx/.conda/envs/py39/lib/python3.9/site-packages/fire/core.py", line 466, in _Fire
component, remaining_args = _CallAndUpdateTrace(
File "/home/xxx/.conda/envs/py39/lib/python3.9/site-packages/fire/core.py", line 681, in _CallAndUpdateTrace
component = fn(*varargs, **kwargs)
File "pydantic/decorator.py", line 40, in pydantic.decorator.validate_arguments.validate.wrapper_function
from contextlib import _GeneratorContextManager
File "pydantic/decorator.py", line 133, in pydantic.decorator.ValidatedFunction.call
func.__dict__.update(kw)
File "pydantic/decorator.py", line 130, in pydantic.decorator.ValidatedFunction.init_model_instance
else:
File "pydantic/main.py", line 341, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for Foo
dt
invalid type; expected datetime, string, bytes, int or float (type=type_error)
Thanks for raising this. I'm marking it as a bug.
It looks like the call to foo is failing at https://github.com/google/python-fire/blob/37c4305194ff3d0a63f435f08a40e14b1978bd4e/fire/core.py#L475-L480
This is surprising, because calling foo without arguments normally (i.e. without _CallAndUpdateTrace) passes pydantic's validation, but making the call with _CallAndUpdateTrace fails validation.
Looking deeper, I see the arguments being used to call foo by _CallAndUpdateTrace are different than when calling foo directly. This is determined by these lines: https://github.com/google/python-fire/blob/37c4305194ff3d0a63f435f08a40e14b1978bd4e/fire/core.py#L682-L683
When this is run, varargs takes on the value [FieldInfo(default=PydanticUndefined, default_factory=<built-in method now of type object at 0x10292f978>, extra={})] rather than []. This seems problematic. The next steps are to investigate why this occurs and what the appropriate change to make is to resolve it.
See also #343 -- in that issue @melsabagh-kw shows a decorator he wrote to get typeguard typechecking with fire.
Can I look into this? @dbieber
Yes, just please be advised that we don't have any planned review time for accepting PRs right now, so it might be a while before we can provide feedback or accept your proposed change.