Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

functools.partialmethod simplification #124652

Open
dg-pb opened this issue Sep 27, 2024 · 2 comments
Open

functools.partialmethod simplification #124652

dg-pb opened this issue Sep 27, 2024 · 2 comments
Labels
type-feature A feature request or enhancement

Comments

@dg-pb
Copy link
Contributor

dg-pb commented Sep 27, 2024

Feature or enhancement

Proposal:

Now, as partial has __get__ and Placeholder it is probably a good idea to simplify partialmethod.

So the mental model of partialmethod can simply be:

partial, which always has the first argument set to Placeholder.

So partialmethod could maybe be a subclass partial, which would potentially simplify things.

Also, maybe there is a way so that partialmethod can be made obsolete altogether.

Will see where I can get to with this.
Any ideas welcome.

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

#121027
#119827 (comment)

Linked PRs

@dg-pb dg-pb added the type-feature A feature request or enhancement label Sep 27, 2024
@rhettinger
Copy link
Contributor

Note that partialmethod also copies __isabstractmethod__ from the underlying callable.

@dg-pb
Copy link
Contributor Author

dg-pb commented Oct 2, 2024

PR is ready for review.

Quick summary of what I have done and thought of:

  1. Considered implementing __isabstractmethod__ property for partial so that it returns it from the wrapped function. However, this is not a good idea, because in this case it would be impossible to set __isabstractmethod__ property for it. Also, it would be a divergent behaviour from FunctionType. In short, I kept the same abstract method attribute logic for partial and partialmethod as before.
  2. Relaxed trailing placeholder restriction. This way the behaviour of object is more robust, more functional and behaves naturally given functionality definition. E.g. If I know that Placeholder is for positional arguments, then trailing placeholder will convert it to "positional only". And I can not see a good reason why trailing placeholders need to be prohibited. Also, such behaviour stems naturally from definition of functionality, while forbidding or automatically trimming trailing placeholders would require special mention in documentation.
  3. partialmethod could be made redundant for standard method cases. However, there is one case that it is able to handle that could not be done without it, which is "Unknown descriptor" case, where partial needs to be applied at runtime on callable which is returned from __get__ of wrapped function.

E.g.:

class D:
    def __get__(self, obj, cls):
        return (lambda a, b: None)

class A:
    d = D()

    @staticmethod
    def s(a, b):
        pass

    @classmethod
    def c(self, a, b):
        pass

    ps = staticmethod(partial(s.__wrapped__, 1))
    pc = classmethod(partial(c.__wrapped__, Placeholder, 1))
    pd = ?    # needs `partialmethod`

Thus, I have modified partialmethod so that it does not do any heavy partial-like logic itself, but instead passes all of it to partial.

This allowed removing partialmethod special casing from inspect.signature.

More details in description of PR.

dg-pb added a commit to dg-pb/cpython that referenced this issue Oct 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

2 participants