-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
Fix Stubgen's behavior for Instance Variables in C extensions #12524
Fix Stubgen's behavior for Instance Variables in C extensions #12524
Conversation
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.
Thanks for your contribution! Is it possible to add a unit test for this change?
Also, please give a more precise title than "Fix stubgen".
It is not necessary for instance variables to have the fget attrbute (e.g. instance variable in a C class in an extension) but inspect.isdatadescriptor return True as expected, hence we update the 'is_c_property' check. Since special attributes (like __dict__ etc) also passes 'is_c_property' check, we ignore all such special attributes in 'generate_c_property_stub' while creating the contents of stub file. Also, 'is_c_property_readonly' assumed that the property would always have 'fset' attribute which again is not true for instance variables in C extension. Hence make the check defensive by first checking if 'fset' attribute even exists or not. This fixes python#12150.
db4be74
to
cc739fb
Compare
|
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.
If the fix changes behavior that can be observed in the test suite, then there should be a new test or a change in the tests.
And indeed tests are currently failing. |
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.
If the fix changes behavior that can be observed in the test suite, then there should be a new test or a change in the tests.
Makes sense. Apologies that I missed.
However, I'll note that test in $REPO_DIR/misc/test-stubgenc.sh
is not run when running tests via python3 runtests.py
is run (and hence I missed this).
@@ -5,8 +5,6 @@ PI: float | |||
|
|||
class Point: | |||
class AngleUnit: | |||
__doc__: ClassVar[str] = ... # read-only |
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.
Since stubs for special dunder attributes is not expected to be generated, we remove these from the test files.
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.
But we had tests explicitly adding them, so I'd like to make sure these aren't important for pybind11 users.
@sizmailov added these tests in #9903; could you comment on whether removing these attributes from the docs is desirable?
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.
I agree, annotation of most of dunder attributes makes a little sense and probably utilized only by few people if any, but I cannot speak for whole pybind11 community.
At the time I've added all the attributes to test just because it was generated by the stubgen and I saw no harm in leaving them.
It looks like dunder attributes hiding is orthogonal to the objectives of #12150.
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.
It looks like dunder attributes hiding is orthogonal to the objectives of #12150.
I agree on this, I had added this change to be in-line with stub generation logic for python files where we ignore special dunder methods (Ref).
We can also choose to not ignore dunder methods in generate_c_property_stub
, in that case, we would have to update the below two tests since these will now generate stubs for dunder attributes:
-
test_generate_c_type_stub_variable_type_annotation
AssertionError: ['class C(KeyError):', ' __weakref__: Any'] != ['class C(KeyError): ...']
-
test_generate_c_type_inheritance
AssertionError: ['class C:', ' x: ClassVar[int] = ...', ' __dict__: Any', ' __weakref__: Any'] != ['class C:', ' x: ClassVar[int] = ...']
@sizmailov Let me know if this sounds fine to you and I would then go ahead with the change.
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.
I think your change is OK as is. It is definitely an improvement.
My perception is that stubgen
is still in the 0.x
release state, therefore minor "breaking" changes are totally fine.
Last time I checked, stubgen
had little or no configuration options, which results in many hardcoded decisions such as "no dunder attributes". But this problem is definitely out of the scope of this PR.
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.
There are still no tests for the is_c_property
and is_c_property_readonly
changes, only for the dunder change.
@@ -5,8 +5,6 @@ PI: float | |||
|
|||
class Point: | |||
class AngleUnit: | |||
__doc__: ClassVar[str] = ... # read-only |
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.
But we had tests explicitly adding them, so I'd like to make sure these aren't important for pybind11 users.
@sizmailov added these tests in #9903; could you comment on whether removing these attributes from the docs is desirable?
Thanks @sizmailov for your thoughts.
@JelleZijlstra, I see there exist a test |
This comment has been minimized.
This comment has been minimized.
Tests are failing. |
Oops, somehow missed this earlier, fixed now. All tests should run fine now. |
According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉 |
One quick question: Will this change be included in the next mypy release ? |
It will be in the next release but I don't know when that will be. See #12210. |
It looks like this change has caused the regression #12717
This is not such a good idea. In many cases, special dunder attributes are just part of the officially interface. For instance |
Description
It is not necessary for instance variables to have the fget attribute (e.g. instance variable in a C class in an extension) but
inspect.isdatadescriptor return True as expected, hence we update the 'is_c_property' check.
Since special attributes (like __dict__ etc) also passes 'is_c_property' check, we ignore all such special attributes in
'generate_c_property_stub' while creating the contents of stub file.
Also, 'is_c_property_readonly' assumed that the property would always have 'fset' attribute which again is not true for instance variables in C extension. Hence make the check defensive by first checking if 'fset' attribute even exists or not.
Fixes #12150.
Test Plan
Ran the test suite as described in Contributing-Running tests. All tests are running fine.
Ran stubgen on a C extension and verified that instance variables are correctly typed now. The C extension is the same as present on Issue#12150.
C extension source code (only relevant part is present here, refer the Issue#12150 for the complete source code.:
Generated
extension.pyi
file prior to this change: (Note that the instance variables are incorrectly marked as ClassVar)Generated
extension.pyi
file after this change: