Source code for hoft.core.sigs
#!/usr/bin/env python
# -*- coding: latin-1 -*-
#
# HOFT signatures.
# @module hoft.core.sigs
# @version 0.1
# @copyright (c) 2017-present Francis Horsman.
from inspect import getargspec
from hoft.core.utils import NoDefaultError, Signature
__all__ = [
'num_keywords',
'num_positionals',
'get_keywords',
'get_positionals',
'get_default_value',
'get_signature',
'signature',
]
[docs]def num_keywords(argspec):
"""
Determine the number of keyword arguments (eg: `def func(name=value)`).
:param inspect.ArgSpec argspec:
A previously obtained argspec.
:return:
Number of positional arguments.
:rtype: int
"""
return len(argspec.defaults or [])
[docs]def num_positionals(argspec, num_keyword_args=None):
"""
Determine the number of positional arguments (eg: `def func(name)`).
:param inspect.ArgSpec argspec:
A previously obtained argspec.
:param int num_keyword_args:
Number of keyword arguments already known (if any, if not then they will be calculated).
:return:
Number of positional arguments.
:rtype: int
"""
return len(argspec.args) - num_keyword_args if num_keyword_args is not None else num_keywords(
argspec)
[docs]def get_positionals(argspec, num_positional_args=None):
"""
Get all positional arguments.
:param inspect.ArgSpec argspec:
A previously obtained argspec.
:param int num_positional_args:
Number of positional arguments already known (if any, if not then they will be calculated).
:return:
A list containing the positional arguments in declaration order.
:rtype:
List[str]
"""
num_positional_args = num_positional_args if num_positional_args is not None else \
num_positionals(argspec)
return argspec.args[:num_positional_args]
[docs]def get_keywords(argspec, num_positional_args=None):
"""
Get all keyword arguments and their associated default values.
:param inspect.ArgSpec argspec:
A previously obtained argspec.
:param int num_positional_args:
Number of positional arguments already known (if any, if not then they will be calculated).
:return:
A dictionary containing the keyword names and their associated default values.
:rtype:
Dict[str, int]
"""
num_positional_args = num_positional_args if num_positional_args is not None else \
num_positionals(argspec)
return {
name: default_value
for name, default_value in zip(argspec.args[num_positional_args:], argspec.defaults or [])
}
[docs]def get_default_value(name, argspec):
"""
Get the default value for the keyword argument of name.
:param str name:
The name to get the default keyword argument value for.
:param inspect.ArgSpec argspec:
A previously obtained argspec.
:return:
The default_value present in the method's signature.
:raises:
NoDefaultError When no default value can or does exist fo the name.
"""
try:
default_index = argspec.args.index(name) - len(argspec.args)
except ValueError:
raise NoDefaultError(name, argspec)
try:
return argspec.defaults[default_index]
except (IndexError, TypeError):
raise NoDefaultError(name, argspec)
[docs]def get_signature(argspec):
"""
Obtain a Signature from an argspec
:param inspect.ArgSpec argspec:
A previously obtained argspec.
:return:
The signature.
:rtype:
Signature
"""
num_keyword_args = num_keywords(argspec)
num_positional_args = num_positionals(argspec, num_keyword_args=num_keyword_args)
positionals = get_positionals(argspec, num_positional_args=num_positional_args)
keywords = get_keywords(argspec, num_positional_args=num_positional_args)
return Signature(positionals, argspec.varargs, keywords, argspec.keywords or None)
[docs]def signature(func):
"""
Obtain a method's Signature.
:param callable func:
Method to obtain the signature for.
:return:
The method's signature.
:rtype:
Signature
"""
return get_signature(getargspec(func))