Private helper: constructs Signature for the given python function.
(cls, func, skip_bound_arg=True,
globals=None, locals=None, eval_str=False,
*, annotation_format=Format.VALUE)
| 2311 | |
| 2312 | |
| 2313 | def _signature_from_function(cls, func, skip_bound_arg=True, |
| 2314 | globals=None, locals=None, eval_str=False, |
| 2315 | *, annotation_format=Format.VALUE): |
| 2316 | """Private helper: constructs Signature for the given python function.""" |
| 2317 | |
| 2318 | is_duck_function = False |
| 2319 | if not isfunction(func): |
| 2320 | if _signature_is_functionlike(func): |
| 2321 | is_duck_function = True |
| 2322 | else: |
| 2323 | # If it's not a pure Python function, and not a duck type |
| 2324 | # of pure function: |
| 2325 | raise TypeError('{!r} is not a Python function'.format(func)) |
| 2326 | |
| 2327 | s = getattr(func, "__text_signature__", None) |
| 2328 | if s: |
| 2329 | return _signature_fromstr(cls, func, s, skip_bound_arg) |
| 2330 | |
| 2331 | Parameter = cls._parameter_cls |
| 2332 | |
| 2333 | # Parameter information. |
| 2334 | func_code = func.__code__ |
| 2335 | pos_count = func_code.co_argcount |
| 2336 | arg_names = func_code.co_varnames |
| 2337 | posonly_count = func_code.co_posonlyargcount |
| 2338 | positional = arg_names[:pos_count] |
| 2339 | keyword_only_count = func_code.co_kwonlyargcount |
| 2340 | keyword_only = arg_names[pos_count:pos_count + keyword_only_count] |
| 2341 | annotations = get_annotations(func, globals=globals, locals=locals, eval_str=eval_str, |
| 2342 | format=annotation_format) |
| 2343 | defaults = func.__defaults__ |
| 2344 | kwdefaults = func.__kwdefaults__ |
| 2345 | |
| 2346 | if defaults: |
| 2347 | pos_default_count = len(defaults) |
| 2348 | else: |
| 2349 | pos_default_count = 0 |
| 2350 | |
| 2351 | parameters = [] |
| 2352 | |
| 2353 | non_default_count = pos_count - pos_default_count |
| 2354 | posonly_left = posonly_count |
| 2355 | |
| 2356 | # Non-keyword-only parameters w/o defaults. |
| 2357 | for name in positional[:non_default_count]: |
| 2358 | kind = _POSITIONAL_ONLY if posonly_left else _POSITIONAL_OR_KEYWORD |
| 2359 | annotation = annotations.get(name, _empty) |
| 2360 | parameters.append(Parameter(name, annotation=annotation, |
| 2361 | kind=kind)) |
| 2362 | if posonly_left: |
| 2363 | posonly_left -= 1 |
| 2364 | |
| 2365 | # ... w/ defaults. |
| 2366 | for offset, name in enumerate(positional[non_default_count:]): |
| 2367 | kind = _POSITIONAL_ONLY if posonly_left else _POSITIONAL_OR_KEYWORD |
| 2368 | annotation = annotations.get(name, _empty) |
| 2369 | parameters.append(Parameter(name, annotation=annotation, |
| 2370 | kind=kind, |
no test coverage detected
searching dependent graphs…