Skip to content

Allow NULL value in pybind11_meta_setattro #2629

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

Merged
merged 1 commit into from
Nov 5, 2020

Conversation

bstaletic
Copy link
Collaborator

Description

Python says we have to handle NULL values in pybind11_meta_setattro as "delete property".

https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_setattro

However, pybind11 currently doesn't allow users to delete non-static properties. I'm not really sure what's the right course of action, this PR is just the first thing that worked, in the sense of not segfaulting as in #2009.

Fixes #2009

Suggested changelog entry:

Allows deleting of static properties.

@bstaletic bstaletic force-pushed the meta-setattro-null branch 2 times, most recently from 5c32889 to ceb2878 Compare October 29, 2020 17:52
@@ -171,6 +171,13 @@ def test_static_properties():
assert m.TestPropertiesOverride().def_readonly == 99
assert m.TestPropertiesOverride.def_readonly_static == 99

# Static attributes can be deleted
del m.TestPropertiesOverride.def_readonly_static
assert not hasattr(m.TestPropertiesOverride, "def_readonly_static")
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

So this check fails because:

>>> import pybind11_tests
>>> m = pybind11_tests.methods_and_attributes
>>> m.TestPropertiesOverride.def_readonly_static
99
>>> del m.TestPropertiesOverride.def_readonly_static
>>> hasattr(m.TestPropertiesOverride, 'def_readonly_static')
True
>>> m.TestPropertiesOverride.def_readonly_static
1
>>> del m.TestPropertiesOverride.def_readonly_static
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: def_readonly_static

Can anyone make sense of it?

Copy link
Collaborator

Choose a reason for hiding this comment

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

The latter value, 1, seems to come from m.TestProperties, a base class of m.TestPropertiesOverride?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That's right.

>>> m = pybind11_tests.methods_and_attributes
>>> del m.TestPropertiesOverride.def_readonly_static
>>> m.TestPropertiesOverride.def_readonly_static
1
>>> del m.TestProperties.def_readonly_static
>>> m.TestPropertiesOverride.def_readonly_static
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'pybind11_tests.methods_and_attributes.TestProperti' has no attribute 'def_readonly_static'

This makes me even less sure if this is the right course of action.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we see/mimic how this would react in Python?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Just tried this out:

>>> class Base:
...     answer = 6 * 9
... 
>>> class Derived(Base):
...     answer = 42
... 
>>> Derived.answer
42
>>> del Derived.answer
>>> Derived.answer
54
>>> del Derived.answer
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: answer
>>> del Base.answer
>>> Derived.answer
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'Derived' has no attribute 'answer'
>>> 

So even without any properties, static attributes in pure Python would match our behavior, no?

So ... not a bug, just counter-intuitive Python behaviour?

Copy link
Collaborator

@YannickJadoul YannickJadoul left a comment

Choose a reason for hiding this comment

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

Unless there's a reason to match non-static properties (or something that needs to be kept alive or so), I'm fine with this. It matches pure Python behavior, and as far as I know, that's what we most of the time aim for.

@henryiii
Copy link
Collaborator

henryiii commented Nov 2, 2020

2.6.1 or 2.7?

@YannickJadoul YannickJadoul added this to the v2.6.1 milestone Nov 2, 2020
@henryiii
Copy link
Collaborator

henryiii commented Nov 2, 2020

That was fast... :)

@YannickJadoul
Copy link
Collaborator

That was fast... :)

Hahahaha, I was just thinking I missed a PR or a few somewhere, and was already looking around ;-)
Do we need all PRs to be added to a milestone? I still haven't heard how we're going to manage versions.

Copy link
Collaborator

@rwgk rwgk left a comment

Choose a reason for hiding this comment

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

My vote is to include this one in 2.6.1.

@YannickJadoul YannickJadoul merged commit 06b673a into pybind:master Nov 5, 2020
@github-actions github-actions bot added the needs changelog Possibly needs a changelog entry label Nov 5, 2020
@YannickJadoul
Copy link
Collaborator

Merged! Good catch, @fried, and thanks for fixing, @bstaletic!

@bstaletic bstaletic deleted the meta-setattro-null branch November 6, 2020 10:46
@bstaletic bstaletic restored the meta-setattro-null branch November 6, 2020 10:46
@bstaletic bstaletic deleted the meta-setattro-null branch November 6, 2020 10:46
@bstaletic bstaletic restored the meta-setattro-null branch November 6, 2020 10:46
@bstaletic bstaletic deleted the meta-setattro-null branch November 6, 2020 10:46
@henryiii henryiii removed the needs changelog Possibly needs a changelog entry label Nov 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Calling del Class.field from python, when its a def_readonly_static segfaults
4 participants