Handle None default args in Cython methods

This commit is contained in:
Ines Montani 2020-09-29 18:08:02 +02:00
parent 9353a82076
commit dba26186ef
2 changed files with 24 additions and 2 deletions

View File

@ -11,6 +11,7 @@ import inspect
from .attrs import NAMES
from .lookups import Lookups
from .util import is_cython_func
if TYPE_CHECKING:
# This lets us add type hints for mypy etc. without causing circular imports
@ -93,8 +94,11 @@ def get_arg_model(
continue
# If no annotation is specified assume it's anything
annotation = param.annotation if param.annotation != param.empty else Any
# If no default value is specified assume that it's required
default = param.default if param.default != param.empty else ...
# If no default value is specified assume that it's required. Cython
# functions/methods will have param.empty for default value None so we
# need to treat them differently
default_empty = None if is_cython_func(func) else ...
default = param.default if param.default != param.empty else default_empty
sig_args[param.name] = (annotation, default)
is_strict = strict and not has_variable
sig_args["__config__"] = ArgSchemaConfig if is_strict else ArgSchemaConfigExtra

View File

@ -1310,3 +1310,21 @@ def minibatch(items, size):
if len(batch) == 0:
break
yield list(batch)
def is_cython_func(func: Callable) -> bool:
"""Slightly hacky check for whether a callable is implemented in Cython.
Can be used to implement slightly different behaviors, especially around
inspecting and parameter annotations.
func (Callable): The callable to check.
RETURNS (bool): Whether the callable is Cython (probably).
"""
attr = "__reduce_cython__"
if hasattr(func, attr): # function or class instance
return True
# https://stackoverflow.com/a/55767059
if hasattr(func, "__qualname__") and hasattr(func, "__module__"): # method
cls_func = vars(sys.modules[func.__module__])[func.__qualname__.split(".")[0]]
return hasattr(cls_func, attr)
return False