Skip to content

gh-124652: partialmethod simplifications #124788

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

Open
wants to merge 18 commits into
base: main
Choose a base branch
from

Conversation

dg-pb
Copy link
Contributor

@dg-pb dg-pb commented Sep 30, 2024

  1. it is now untangled from partial (makes use of partial instead of containing any complexities of partial)
  2. it has no need for any special-casing in inspect
  3. its performance is now reasonable (for standard methods and partial objects)

partialmethod Benchmarks:

Setup

S="
from functools import partialmethod, Placeholder

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

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

class A:
    @staticmethod
    def s(a, b):
        pass
    @classmethod
    def c(self, a, b):
        pass
    def m(self, a, b):
        pass
    d = D()

    ps = partialmethod(s, 1)
    pc = partialmethod(c, 1)
    pm = partialmethod(m, 1)
    pd = partialmethod(d, 1)

a = A()
"

C1='partialmethod(s, 1)'    # staticmethod
C2='partialmethod(c, 1)'    # classmethod
C3='partialmethod(m, 1)'    # instance method
C4='partialmethod(d, 1)'    # unknown descriptor

C5='A.ps(2)'
C6='A.pc(2)'
C7='a.pm(2)'
C8='a.pd(2)'

NOTE: construction cost for standard methods is obfuscated 
      as they are constructed and cached on 1st call.

                            #  BEFORE | AFTER
--------------------------- #-----------------
$PYEXE -m timeit -s $S $C1  #  920 ns |  390 ns
$PYEXE -m timeit -s $S $C2  # 1000 ns |  420 ns
$PYEXE -m timeit -s $S $C3  #  900 ns |  440 ns
$PYEXE -m timeit -s $S $C4  # 1000 ns |  600 ns
--------------------------- #-----------------
$PYEXE -m timeit -s $S $C5  # 1300 ns |  330 ns
$PYEXE -m timeit -s $S $C6  #  830 ns |  390 ns
$PYEXE -m timeit -s $S $C7  #  800 ns |  390 ns
$PYEXE -m timeit -s $S $C8  # 1300 ns |  890 ns

@rhettinger rhettinger removed their request for review September 30, 2024 16:31
@dg-pb dg-pb force-pushed the gh-124652-partialmethod branch from a04c14f to d217592 Compare October 6, 2024 16:56
@dg-pb
Copy link
Contributor Author

dg-pb commented Oct 6, 2024

Removed keyword Placeholder restriction from this and will issue a separate PR after. Felt like too much is packed into 1 PR.

@eendebakpt
Copy link
Contributor

@dg-pb Is this PR still relevant or have you opened PRs for the different components? If so, can we close this one?

@dg-pb
Copy link
Contributor Author

dg-pb commented Jan 4, 2025

It is still relevant.
On my part this is ready for review.
Given partial.Placeholder has been merged recently and not in production I wasn't sure if splitting is necessary.

I could factor "allowing trailing placeholders" into a separate one if it is preferred.

@eendebakpt
Copy link
Contributor

It is still relevant. On my part this is ready for review. Given partial.Placeholder has been merged recently and not in production I wasn't sure if splitting is necessary.

I could factor "allowing trailing placeholders" into a separate one if it is preferred.

I have not looked at all the changes in detail, but the PR seems big and that could be a reason this PR has not yet been reviewed. In the description at least 3 changes are mentioned (allowing placeholders, performance, refactor for partialmethod). If possible, I would advice to split the PR into multiple PRs.

@dg-pb
Copy link
Contributor Author

dg-pb commented Jan 4, 2025

at least 3 changes are mentioned

There are 2 really.

Performance benefit is a consequence of "allowing trailing placeholders".

I don't mind making changes, splitting as desired etc, but I would like these to be called by reviewer. Otherwise, I already have experience by trying to guess what reviewer might prefer, making changes per suggestions of others, etc and when final reviewer comes he desires to be different again and I need to keep changing things more times than necessary.

And either way these would need to be considered at the same time. I.e. allowing or not allowing trailing placeholders are both ok. There is a slight advantage for allowing them as it makes it a bit more flexible and explicit. While looking at partial from the POV of using it on methods, the advantages and rationale for allowing them can be seen more clearly putting it on a favourable side (at least this is my conclusion).

Also, if I split now, then I have PRs hanging on unmerged code.

the PR seems big

It isn't that big. Most of it is Pure Python rewrite of partialmethod and the implementation is much simpler to follow than the previous one.

@dg-pb
Copy link
Contributor Author

dg-pb commented Jan 8, 2025

As this series of partial related PRs started slowly moving, the path became a bit clearer and splitting this into 2 seems to be the best option to me now. Will do that shortly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants