-
-
Notifications
You must be signed in to change notification settings - Fork 30.3k
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
Argument clinic: add support for creating method aliases #113270
Comments
How about a
|
Alternatively:
|
Possibly this is a dumb question -- how would this differ from the existing clone feature? |
It only creates a new |
Got it. That'll be something to make sure we're explicit about in the devguide docs. It is a similar concept to cloning though, so I guess I lean towards something like @eltoder's proposed syntax (something involving an assignment) rather than an |
Yeah, absolutely.
Yes, it is similar to cloning. No matter what syntax we land on, I think we need to be able to support the
... or a variant of #113270 (comment). |
I think the decorator syntax could work and be a very compact and readable notation: /*[clinic input]
@alias("datetime.date.__replace__")
datetime.date.replace as datetime_replace
args
...
[clinic start generated code]*/ To be honest, I think the ideal syntax is just the assignment like in Python: /*[clinic input]
datetime.date.__replace__ = datetime.date.replace
[clinic start generated code]*/ and the cloning feature would be something like: /*[clinic input]
datetime.date.bar from datetime.date.foo
[clinic start generated code]*/ since it isn't an assignment. But that's probably too late to change. We can go with something like this instead: /*[clinic input]
datetime.date.__replace__ alias datetime.date.replace
[clinic start generated code]*/ In this case, we do not need to support |
Actually, I take it back about /*[clinic input]
alias datetime.date.__replace__ as date___replace__ = datetime.date.replace
[clinic start generated code]*/ or /*[clinic input]
datetime.date.__replace__ as date___replace__ alias datetime.date.replace
[clinic start generated code]*/ |
Yeah, I think we need to support custom macro names with the Let's compare alternatives proposed so far: Syntax
I find 2. hard to read, and I dare not to think of how hard it would be to interpret such a line if you involve cloning as well 😄 Implementation
I believe 3. will be easiest to implement, but I may be wrong. |
Proof-of-concept implementation of 3.: https://github.com/erlend-aasland/cpython/pull/new/clinic/alias |
I agree that 2 seems hard to read, so 1 or 3 are better options. 3 seems like the most compact syntax and easier to implement. The only thing to note is that if you use short names instead of qualified names (i.e. class Base:
def foo(self): ...
class Derived(Base):
base_foo = Base.foo
@override
def foo(self): ... However, I don't currently have a case like this for argument clinic. |
This would require the base class and the target method to be declared using Argument Clinic. It would also require that the base class and the derived class is implemented in the same file. |
This is the case, for example, in the datetime module, so it is not unrealistic. But I don't have a use case for cross-class aliases at the moment.
You can make |
I thought about that, but let's not over-design this from the start. If the need arises, it is fairly trivial to allow multiple aliases as a future enhancement. We developed the keyword-only/positional-only deprecation system in Argument Clinic with similar enhancement iterations.
If there is no use-case, we don't need to implement support for it :) If the need arises, we can deal with it in a follow-up issue. |
Sure, but seems like an odd limitation. Having a list will actually make the code simpler since you can remove the |
I suggest to wait with that statement until tests have been added ;) |
You'll have to write a test for using two alias directives either way :) |
I forgot one thing: we need to generate a new docstring signature for the alias, which means we need to duplicate the docstring definition as well. |
^^ @AlexWaygood: this implies we need to bring back our old plan of refactoring the docstring generation. In our previous attempt, we moved the complete docstring generation to the |
@erlend-aasland looks like github is missing a yak-shaving emoji :-) |
You could also just use |
Thanks for chiming in, Larry. Yeah, that's probably the best option. |
Compilers will optimize it by just inlining the static function. This leads to code bloat as the argument parsing code, which can be substantial, and the function implementation will be duplicated in the executable. You can see this for yourself, for example: https://godbolt.org/z/GfMjfes8c. Notice how The alias feature itself seems very simple. @erlend-aasland had most of it implemented in less than a day. |
@erlend-aasland Are you still working on this? |
Not actively, so feel free to pick it up. But I do think we need to do more refactorings (as previously mentioned) in order to pull this off nicely. My branch is a very limited variant of this feature. |
Feature or enhancement
Proposal:
Before argument clinic, creating method aliases in C extension classes was very easy: simply add another MethodDef for the same function:
This is very cheap and convenient. However, with argument clinic we cannot quite do this. If I do
I have to manually copy the flags from the generated MethodDef into the one I wrote myself. This works now, but can break later if clinic generates a MethodDef with different flags. It is possible to work-around by copying the function, but this adds a maintenance burden and generates argument parsing twice, leading to code bloat.
It would be nice to have some syntax to tell argument clinic to generate the alias MethodDef. It could look like this:
which would generate:
that can then be used as usual:
This is presently a problem for
code.__replace__
, which is an alias for generatedcode.replace
1. I also ran into this in #112921, where I convert datetime.*.replace methods to use argument clinic.CC @AlexWaygood @larryhastings @erlend-aasland
Has this already been discussed elsewhere?
No response given
Links to previous discussion of this feature:
No response
Footnotes
https://github.com/python/cpython/blob/893c9ccf48eacb02fa6ae93632f2d0cb6778dbb6/Objects/codeobject.c#L2180 ↩
The text was updated successfully, but these errors were encountered: