Skip to content

Add support for partialmethods and partial types #664

Open
@MiguelMonteiro

Description

@MiguelMonteiro

🚀 Feature request

Add support for objects created via functools.partial and functools.partialmethod

Motivation

Sometimes dynamically created classes and functions via partialmethod and partial are useful to prevent repeating code.

Pitch

I was able to implement this locally by changing the following:
Implement a function that checks if the method of class partial or partialmethod

from functools import partial, partialmethod
def is_partial_method(method):
    return isinstance(method, partialmethod) or isinstance(method, partial)

add another code path in get_component_and_parent in file _parameter_resolver.py:

def get_component_and_parent(
    function_or_class: Union[Callable, Type],
    method_or_property: Optional[Union[str, Callable]] = None,
):
    if is_subclass(function_or_class, ClassFromFunctionBase) and method_or_property in {None, "__init__"}:
        function_or_class = function_or_class.wrapped_function  # type: ignore[union-attr]
        if isinstance(function_or_class, MethodType):
            method_or_property = function_or_class.__name__
            function_or_class = function_or_class.__self__  # type: ignore[assignment]
        else:
            method_or_property = None
    elif inspect.isclass(get_generic_origin(function_or_class)) and method_or_property is None:
        method_or_property = "__init__"
    elif method_or_property and not isinstance(method_or_property, str):
        method_or_property = method_or_property.__name__
    parent = component = None
    if method_or_property:
        attr = inspect.getattr_static(get_generic_origin(function_or_class), method_or_property)
        if is_staticmethod(attr):
            component = getattr(function_or_class, method_or_property)
            return component, parent, method_or_property
        parent = function_or_class
        if has_dunder_new_method(function_or_class, method_or_property):
            component = getattr(function_or_class, "__new__")
        elif is_method(attr):
            component = attr
        elif is_partial_method(attr):
            component = getattr(function_or_class, method_or_property)
        elif is_property(attr):
            component = attr.fget
        elif isinstance(attr, classmethod):
            component = getattr(function_or_class, method_or_property)
        elif attr is not object.__init__:
            raise ValueError(
                f"Invalid or unsupported input: class={function_or_class}, method_or_property={method_or_property}"
            )
    else:
        if not callable(function_or_class):
            raise ValueError(f"Non-callable input: function={function_or_class}")
        component = function_or_class
    return component, parent, method_or_property

Just need to open and MR but thought I would create an issue first

Alternatives

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions