| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| Expand Up | @@ -306,10 +306,28 @@ def isgeneratorfunction(obj): | |
| _is_coroutine_mark = object() | ||
|
|
||
| def _has_coroutine_mark(f): | ||
| while ismethod(f): | ||
| f = f.__func__ | ||
| f = functools._unwrap_partial(f) | ||
| return getattr(f, "_is_coroutine_marker", None) is _is_coroutine_mark | ||
| while True: | ||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityPlease:
Sorry, something went wrong.
All reactions
|
||
| # Methods: unwrap first (methods cannot be coroutine-marked) | ||
| if ismethod(f): | ||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityWhy not doing while ismethod(f): f = f.__func__ here?
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality>>> from functools import partialmethod
>>> class MyClass:
... def a(self): ...
... b = partialmethod(a)
>>> obj = MyClass()
>>> obj.b
functools.partial(<bound method MyClass.a of <__main__.MyClass object at 0x7fd343f4cc20>>)
>>> obj.b.func.__func__
<function MyClass.a at 0x7fd343f42cf0>When unwrapping the reference to obj.b, the functools.partial object comes before the method object, so the assumption that method objects always precede other objects is incorrect. >>> from functools import partialmethod
>>> class MyFirstClass:
... def f(self, other): ...
>>> first = MyFirstClass()
>>> class MySecondClass:
... g = partialmethod(first.f)
>>> second = MySecondClass()
>>> second.g
<bound method partialmethod._make_unbound_method.<locals>._method of <__main__.MySecondClass object at 0x7fd343f4d400>>
>>> second.g.__func__.__partialmethod__.func
<bound method MyFirstClass.f of <__main__.MyFirstClass object at 0x7fd343f4d2b0>>Well, it seems to me that the current implementation (in the main branch) is not very well thought out. Personally, I would not rely on it.
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityIf your comment is only about why there is if instead of while... why do we need a nested loop when we already have an outer one? Moreover, how often are methods that refer to other methods used? Does it even make sense to try to optimize this case? I think it is sufficient and simpler to rely on the outer loop. As you can easily see, the code in this PR is very similar to the one I attached to the original issue, except for the order of the blocks and some points borrowed from the original code (AI-generated or just copy-paste?). I use something similar in the implementation of similar functions in my library, although they are more general in nature.
Sorry, something went wrong.
All reactions
|
||
| f = f.__func__ | ||
| continue | ||
|
|
||
| # Direct marker check | ||
| if getattr(f, "_is_coroutine_marker", None) is _is_coroutine_mark: | ||
| return True | ||
|
|
||
| # Functions created by partialmethod descriptors keep a __partialmethod__ reference | ||
| pm = getattr(f, "__partialmethod__", None) | ||
| if isinstance(pm, functools.partialmethod): | ||
| f = pm | ||
| continue | ||
|
Comment thread
Comment on lines
+319
to
+323
Copy link
Copy Markdown
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityWell, this can also be moved forward by one block to avoid the time spent on obtaining the attribute when it is not necessary. I hope I have not bored you with these micro-optimizations.
Sorry, something went wrong.
All reactions
Comment thread
Comment on lines
+319
to
+323
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityI think you should use functools._unwrap_partialmethod which handles both partial methods and partial functions (first it unwraps partial methods then unwraps partial functions)
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityPlease read the discussion at #142505.
Sorry, something went wrong.
All reactions
|
||
|
|
||
| # partial and partialmethod share .func | ||
| if isinstance(f, (functools.partial, functools.partialmethod)): | ||
|
Comment thread
Copy link
Copy Markdown
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityI will also add, "for the record", why I do not handle partialmethod objects in this way in the code attached to the original issue. They are not callable, and therefore applying markcoroutinefunction() to them is incorrect, which means they should not be checked. Being defined as a class member, accessing the corresponding attribute will return a regular function object created by partialmethod (or a method object for such a function, if via an instance). Therefore, there is no point in unnecessary iteration, and you can go straight to pm.func (see the block above).
Sorry, something went wrong.
All reactions
|
||
| f = f.func | ||
| continue | ||
|
Comment thread
Joshua-Ward1 marked this conversation as resolved.
|
||
|
|
||
| return False | ||
|
|
||
| def markcoroutinefunction(func): | ||
| """ | ||
| Expand Down | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| Fix ``inspect.iscoroutinefunction()`` incorrectly returning ``False`` for | ||
| callables wrapped in ``functools.partial`` or ``functools.partialmethod`` when | ||
| explicitly marked with ``inspect.markcoroutinefunction()``. The function now | ||
| detects coroutine markers on wrappers at each unwrap stage. |
| Back | FazBrowse Home | New Git URL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityThis seems unrelated changes
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.