Skip to content

gh-91002: Support __annotate__ for functools.partial and functools.partialmethod#139753

Open
Zheaoli wants to merge 26 commits intopython:mainfrom
Zheaoli:manjusaka/gh91002
Open

gh-91002: Support __annotate__ for functools.partial and functools.partialmethod#139753
Zheaoli wants to merge 26 commits intopython:mainfrom
Zheaoli:manjusaka/gh91002

Conversation

@Zheaoli
Copy link
Copy Markdown
Contributor

@Zheaoli Zheaoli commented Oct 8, 2025

… inspect in annotationlib.get_annotations

Signed-off-by: Manjusaka <me@manjusaka.me>
Signed-off-by: Manjusaka <me@manjusaka.me>
Signed-off-by: Manjusaka <me@manjusaka.me>
Signed-off-by: Manjusaka <me@manjusaka.me>
Signed-off-by: Manjusaka <me@manjusaka.me>
Signed-off-by: Manjusaka <me@manjusaka.me>
Comment thread Doc/library/annotationlib.rst Outdated
Copy link
Copy Markdown
Member

@JelleZijlstra JelleZijlstra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this instead be implemented with a custom __annotate__ function on partial objects, so annotationlib itself doesn't need to change?

Comment thread Lib/annotationlib.py Outdated
Comment thread Lib/annotationlib.py Outdated
Comment thread Lib/annotationlib.py Outdated
Comment thread Lib/test/test_annotationlib.py
@bedevere-app
Copy link
Copy Markdown

bedevere-app Bot commented Oct 10, 2025

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@Zheaoli
Copy link
Copy Markdown
Contributor Author

Zheaoli commented Oct 12, 2025

Could this instead be implemented with a custom __annotate__ function on partial objects, so annotationlib itself doesn't need to change?

Hi @JelleZijlstra , thank you for your time.
From my personal perspective, I would actually prefer to make the modifications in the partial C module, as this would allow us to obtain the most original information. However, I have some concerns:

Currently, the partial C API doesn't have the relevant interfaces reserved. Adding them would be relatively more complex than the Python version.
If we add the information from functools, we may need to synchronously modify the inspect library to avoid circular dependencies (note: inspect has special handling for functools.partial).

In short, if we solve this problem from functools, it would indeed be the optimal choice in terms of effect, but it would increase complexity.
Do you think this PR needs to open a discussion on discuss.python.org?

@JelleZijlstra
Copy link
Copy Markdown
Member

I'd strongly prefer if this is done in functools, not annotationlib. This sets a good example where objects can support annotation introspection themselves through overriding __annotate__, instead of through special cases in annotationlib itself.

To make the implementation simpler, we can make the C code delegate to Python code, similar to how typevarobject.c invokes the Python typing module in some cases. So partial would gain an __annotate__ descriptor implemented in C, but that descriptor would just invoke some Python code.

@Zheaoli
Copy link
Copy Markdown
Contributor Author

Zheaoli commented Oct 13, 2025

To make the implementation simpler, we can make the C code delegate to Python code, similar to how typevarobject.c

Nice, this is better than my original thought. I'll make a try

Signed-off-by: Manjusaka <me@manjusaka.me>
@Zheaoli Zheaoli requested a review from rhettinger as a code owner October 15, 2025 14:02
Comment thread Doc/library/annotationlib.rst Outdated
Comment thread Doc/library/annotationlib.rst Outdated
Signed-off-by: Manjusaka <me@manjusaka.me>
@Zheaoli Zheaoli changed the title gh-91002: Support functools.partial and functools.partialmethod inspect in annotationlib.get_annotations gh-91002: Support __annotate__ for functools.partial and functools.partialmethod Oct 15, 2025
Signed-off-by: Manjusaka <me@manjusaka.me>
@Zheaoli
Copy link
Copy Markdown
Contributor Author

Zheaoli commented Oct 15, 2025

I have made the requested changes; please review again

@bedevere-app
Copy link
Copy Markdown

bedevere-app Bot commented Oct 15, 2025

Thanks for making the requested changes!

@JelleZijlstra: please review the changes made to this pull request.

@bedevere-app bedevere-app Bot requested a review from JelleZijlstra October 15, 2025 14:31
Signed-off-by: Manjusaka <me@manjusaka.me>
Signed-off-by: Manjusaka <me@manjusaka.me>
Signed-off-by: Manjusaka <me@manjusaka.me>
Signed-off-by: Manjusaka <me@manjusaka.me>
@Zheaoli
Copy link
Copy Markdown
Contributor Author

Zheaoli commented Nov 22, 2025

I have made the requested changes; please review again

@bedevere-app
Copy link
Copy Markdown

bedevere-app Bot commented Nov 22, 2025

Thanks for making the requested changes!

@JelleZijlstra: please review the changes made to this pull request.

@bedevere-app bedevere-app Bot requested a review from JelleZijlstra November 22, 2025 17:36
@Zheaoli Zheaoli requested a review from merwok November 22, 2025 17:37
Comment thread Doc/library/annotationlib.rst
Comment thread Doc/library/annotationlib.rst Outdated
-------------------------------------------

Objects can support annotation introspection by implementing the :attr:`~object.__annotate__`
protocol. When an object provides an :attr:`!__annotate__` attribute, :func:`get_annotations`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More accurately: when an object’s class provides __annotate__, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I think for now is right, consider the code following below

import annotationlib
class A():
    pass
a=A()
def demo(a):
    return {"annotate": 42}
a.__annotate__=demo
print(annotationlib.get_annotation(a))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That’s not how special methods work in Python.
There used to be a bug about that with the context manager protocol and __enter__, which was fixed.
There is an explicit exception for __class_getitem__ used to implement type hints like list[str] without needed a metaclass.
But otherwise dunder methods are looked up on the class of an object.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making sense. fixed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well I was wrong. __annotate__ is not defined as a special method, but a data descriptor. It’s not looked up on the class.

Comment thread Lib/functools.py
merwok and others added 2 commits November 22, 2025 13:30
Signed-off-by: Manjusaka <me@manjusaka.me>
@Zheaoli Zheaoli requested a review from merwok November 24, 2025 06:50
@Zheaoli
Copy link
Copy Markdown
Contributor Author

Zheaoli commented Dec 12, 2025

@JelleZijlstra PTAL when you got time

Copy link
Copy Markdown
Member

@merwok merwok left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, I had draft comment which were not submitted

Comment thread Doc/library/annotationlib.rst Outdated
Comment thread Doc/library/annotationlib.rst Outdated
@bedevere-app
Copy link
Copy Markdown

bedevere-app Bot commented Dec 12, 2025

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

Zheaoli and others added 4 commits December 14, 2025 03:27
Co-authored-by: Éric <merwok@netwok.org>
Co-authored-by: Éric <merwok@netwok.org>
Signed-off-by: Manjusaka <me@manjusaka.me>
Signed-off-by: Manjusaka <me@manjusaka.me>
@Zheaoli
Copy link
Copy Markdown
Contributor Author

Zheaoli commented Dec 13, 2025

@merwok Thanks for your time, PTAL when you got time

@Zheaoli Zheaoli requested a review from merwok December 13, 2025 19:37
Other examples of objects that implement :attr:`!__annotate__` include:

* :class:`typing.TypedDict` classes created through the functional syntax
* Generic classes and functions with type parameters
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a strange example; whether or not they are generic has no bearing on __annotate__.

@github-actions
Copy link
Copy Markdown

This PR is stale because it has been open for 30 days with no activity.

@github-actions github-actions Bot added the stale Stale PR or inactive for long period of time. label Apr 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting changes stale Stale PR or inactive for long period of time.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants