door module

The door module contains classes that represent interfaces to python functions. They are primarily used on functions that have been defined in pure python, but can be extended to include arbitrary callables.

Function adapter classes for callable Python objects.

This module contains definitions for BaseDoor, Door, and DynamicDoor. It also defines the DoorError exception and DoorWarning warning.

These objects all take a python callable object in some form, extract metadata from the object (if possible), and provide a calling interface with optional checks and actions (see individual descriptions).

class porchlight.door.BaseDoor(function: Callable, typecheck: bool = True, returned_def_to_door: bool = False)

Bases: object

Contains basic information about a function such as expected arguments, type annotations, and named return values.

arguments

Dictionary of all arguments taken as input when the BaseDoor object is called.

Type:
dict, str:

Type

positional_only

List of positional-only arguments accepted by the function.

Type:

list of str

keyword_args

Keyword arguments accepted by the BaseDoor as input when called. This includes all arguments that are not positional-only. Positional arguments without a default value are assigned a :class:~porchlight.param.Empty` value instead of their default value.

Type:

dict, str: Any

n_args

Number of arguments accepted by this BaseDoor

Type:

int

name

The name of the function as visible from the base function’s __name__.

Type:

str

return_types

Values returned by any return statements in the base function.

Type:

dict of str, Type pairs.

return_vals

Names of parameters returned by the base function. Any return statements in a Door much haveidentical return parameters. I.e., the following would fail if used to initialize a Door.

def fxn(x):
    if x < 1:
        y = x + 1
        return x, y

    return x
Type:

list of str

typecheck

If True, when arguments are passed to the BaseDoor’s base function the input types are checked against the types in BaseDoor.arguments. If there is a mismatch, a TypeError will be thrown.

Type:

bool

_base_function

This holds a reference to the function being managed by the BaseDoor instance.

Type:

~typing.Callable

Notes

  • In version 2.0, this class will be permanently renamed or refactored. It is strongly suggested you use Door or PorchlightAdapter unless absolutely necessary, as those will remain forward and backward compatible across the 2.0 update.

__call__(*args, **kwargs)

Calls the BaseDoor’s function as normal.

The keys of kwargs must be passed with the same name as variables within the BaseDoor. As of right now, if extra values are included, they are ignored.

__init__(function: Callable, typecheck: bool = True, returned_def_to_door: bool = False)

Initializes the BaseDoor class. It takes any callable (function, lambda, method…) and inspects it to get at its arguments and structure.

if typecheck is True (default True), the type of inputs passed to BaseDoor.__call__ will be checked for matches to known input Types.

Parameters:
  • function (typing.Callable) – The callable/function to be managed by the BaseDoor class.

  • typecheck (bool, optional) – If True, the BaseDoor object will assert that arguments passed to BaseDoor.__call__ (when the BaseDoor itself is called like a function) have the type expected by type annotations and any user specifications. By default, this is True.

  • returned_def_to_door (bool, optional) – Returns a Door generated from the output of the base function. Note, this is not the same as a DynamicDoor, and internal variables/updating is not handled as with a DynamicDoor. This just creates a new Door instance using the output of the base function.

static _can_inspect(f: Callable) bool

Returns True if f can be used with inspect.signature().

static _get_return_vals(function: Callable) List[str]

Gets the names of the return value variables for a given function.

For functions that wrap other functions (i.e., the return value is a function def’d in the function body), the return statements in the body are not parsed.

Parameters:

function (typing.Callable) – The function to retrieve the return values for.

_inspect_base_callable()

Inspect the BaseDoor’s baseline callable for primary attributes.

This checks for type annotations, return statements, and all information accessible to inspect.Signature relevant to BaseDoor.

class porchlight.door.Door(function: Callable | None = None, *, argument_mapping: dict = {}, wrapped: bool = False, arguments: dict = {}, keyword_args: dict = {}, return_vals: List = [], name: str = '', typecheck: bool = False)

Bases: BaseDoor

Extends BaseDoor with Neighborhood-specific methods and handling.

__call__(*args, **kwargs)

Calls the BaseDoor’s function as normal.

The keys of kwargs must be passed with the same name as variables within the BaseDoor. As of right now, if extra values are included, they are ignored.

__init__(function: Callable | None = None, *, argument_mapping: dict = {}, wrapped: bool = False, arguments: dict = {}, keyword_args: dict = {}, return_vals: List = [], name: str = '', typecheck: bool = False)

Initializes the Door object.

Parameters:
  • function (Callable) – A callable object to be parsed by BaseDoor.

  • argument_mapping (dict, keyword-only, optional) –

    Maps parameters automatically by name. For example, to have a Door accept “a” and “b” and arguments instead of “x” and “y”, one could use

    def fxn(x):
        y = 2 * x
        return y
    
    my_door = Door(fxn, argument_mapping={'x': 'a', 'y': 'b'})
    

    to accomplish what would otherwise require wrapping the function yourself.

  • wrapped (bool, keyword-only, optional) –

    If True, will not parse the function using BaseDoor. Instead, it will take user arguments and generate a function wrapper using the following keyword-only arguments:

    • arguments

    • keyword_args

    • return_vals

    And this wrapper will be used to initialize the BaseDoor properties.

  • arguments (dict, keyword-only, optional) – Arguments to be passed to the function if it is wrapped. Does not override BaseDoor if wrapped is False.

  • keyword_args (dict, keyword-only, optional) – Corresponds to keyword arguments that may be passed positionally. Only used when wrapped is True.

  • name (str, keyword-only, optional) – Overrides the default name for the Door if provided.

  • typecheck (bool, optional) – If True, the Door object will assert that arguments passed to __call__ (when the Door itself is called like a function) have the type expected by type annotations and any user specifications. By default, this is True.

_check_argmap()

Assesses if an argument mapping is valid, raises an appropriate exception if it is invalid. Will also raise warnings for certain non-fatal actions.

_initialize_wrapped_function(arguments, keyword_args, return_vals)

Initializes a function that is auto-wrapped by Door instead of being passed to BaseDoor.

map_arguments()

Maps arguments if self.argmap is not empty and the function has been initialized.

This is done by modifying the door arguments directly, and using the argument mapping as a converter between the two systems if the original arguments are needed. This makes the Door mimic the same arguments when accessed by a Neighborhood or when arguments are given to it.

Mapped arguments are overridden, meaning they will no longer be recognized by the Door as appropriate arguments passed through Door.__call__().

property original_arguments: dict[str, Type]

Returns a dict with original positional arguments required by the base function.

property original_kw_arguments: dict[str, Type]

Returns a dict with original keyword arguments required by the base function.

property original_return_vals: list[str]

Returns a list with original return values of the base function.

property required_arguments: List[str]

Returns a list of arguments with no default value.

property variables: List[str]

Returns a list of all known return values and input arguments as strs.

exception porchlight.door.DoorError

Bases: Exception

exception porchlight.door.DoorWarning

Bases: Warning

class porchlight.door.DynamicDoor(door_generator: Callable[[Any], Door], generator_args: List = [], generator_kwargs: Dict = {})

Bases: Door

A dynamic door takes a door-generating function as its initializer.

Unlike BaseDoor and Door, DynamicDoor will only parse the definition’s source once it is generated.

These objects a function that returns a Door. The DynamicDoor then contains identical attributes to the generated door. Once called again, all attributes update to match the most recent call.

_door_generator

A function returning a Door as its output.

Type:

Callable

generator_args

List of arguments to be passed as positional arguments to the DynamicDoor._door_generator function.

Type:

List

generator_kwards

Dict of key: value pairs representing keyword arguments to be passed as positional arguments to the DynamicDoor._door_generator function.

Type:

Dict

__call__(*args, **kwargs) Any

Executes the function stored in DynamicDoor._base_function once DynamicDoor.update() has executed.

Parameters:
  • *args (positional arguments) – Arguments directly passed to DynamicDoor._base_function.

  • **kwargs (keyword arguments) – Keyword arguments directly passed to DynamicDoor._base_function.

__init__(door_generator: Callable[[Any], Door], generator_args: List = [], generator_kwargs: Dict = {})

Initializes the DynamicDoor. When DynamicDoor.__call__() is invoked, the door generator is called.

Parameters:
  • _door_generator (~typing.Callable[Any, Door]) – A callable function that returns an initialized Door object.

  • generator_args (~typing.List) – List of positional arguments for the generator function.

  • generator_kwargs (~typing.Dict[str, Any]) – Dictionary of str/Any key/value pairs for keyword arguments passed to the generator function.

call_without_update(*args, **kwargs) Any

Executes the function stored in DynamicDoor._base_function WITHOUT executing update()

Parameters:
  • *args (positional arguments) – Arguments directly passed to DynamicDoor._base_function.

  • **kwargs (keyword arguments) – Keyword arguments directly passed to DynamicDoor._base_function.

update()

Updates the DynamicDoor using DynamicDoor._door_generator

This method is called when DynamicDoor.__call__() is invoked.