10000 bpo-44263: Py_TPFLAGS_HAVE_GC requires tp_traverse by vstinner · Pull Request #26463 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

bpo-44263: 8000 Py_TPFLAGS_HAVE_GC requires tp_traverse #26463

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
Jun 1, 2021
Merged

bpo-44263: Py_TPFLAGS_HAVE_GC requires tp_traverse #26463

merged 1 commit into from
Jun 1, 2021

Conversation

vstinner
Copy link
Member
@vstinner vstinner commented May 31, 2021

The PyType_Ready() function now raises an error if a type is defined
with the Py_TPFLAGS_HAVE_GC flag set but has no traverse function
(PyTypeObject.tp_traverse).

https://bugs.python.org/issue44263

@vstinner
Copy link
Member Author

This change breaks C extensions which define types with Py_TPFLAGS_HAVE_GC but without tp_traverse, even if instances of the type are never tracked by the GC. Such extensions worked properly previously.

Maybe the check could be restricted to heap types?

If we don't want to break the backward compatibility, we should check in PyObject_GC_Track() if type->tp_traverse is not NULL.

Many instances are created by PyType_GenericAlloc() which calls _PyObject_GC_TRACK(). I tried to modify _PyObject_GC_TRACK() to ensure that it's possible to traverse the instance, as I did in PyObject_GC_Track(), but I got a lot of issues. Many types call _PyObject_GC_TRACK() too early, and it's really difficult to change that (it would require a lot of work).

cc @pablogsal @erlend-aasland @corona10

@vstinner
Copy link
Member Author

As I explained at https://bugs.python.org/issue44263#msg394799, this PR cannot be merged yet since _testcapi and _decimal don't respect the GC protocol. I chose to create a separated PR to fix them, so it can be backported (and review should be easier): #26464

@vstinner
Copy link
Member Author

Many instances are created by PyType_GenericAlloc() which calls _PyObject_GC_TRACK(). I tried to modify _PyObject_GC_TRACK() to ensure that it's possible to traverse the instance, as I did in PyObject_GC_Track(), but I got a lot of issues. Many types call _PyObject_GC_TRACK() too early, and it's really difficult to change that (it would require a lot of work).

My latest attempt in 2020: https://bugs.python.org/issue40142

Copy link
Contributor
@erlend-aasland erlend-aasland left a comment

Choose a reason for hiding this comment

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

LGTM. I leave it for Pablo and Dong-hee to decide if this should be restricted to heap types only.

(Contributed by Dong-hee Na and Serhiy Storchaka in :issue:`44235`.)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why this change? :)

Copy link
Member Author

Choose a reason for hiding this comment

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

Ask my text editor.

Copy link
Member Author

Choose a reason for hiding this comment

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

My text editor (vim) likes to add newline at the end of a file.

@pablogsal
Copy link
Member

@vstinner is the issue number correct?

The PyType_Ready() function now raises an error if a type is defined
with the Py_TPFLAGS_HAVE_GC flag set but has no traverse function
(PyTypeObject.tp_traverse).
@vstinner
Copy link
Member Author

@vstinner is the issue number correct?

I consider that it's to ok reuse https://bugs.python.org/issue44263 My change implements a runtime check for 8b55bc3 "... it must implement the GC protocol itself by at least including a slot".

@vstinner
Copy link
Member Author

PR rebased on top on the merged PR #26464 fix.

@pablogsal
Copy link
Member

I consider that it's to ok reuse https://bugs.python.org/issue44263

🤷‍♂️ I don't know about that, https://bugs.python.org/issue44263 is a bout a documentation change and this is a breaking change in the C-API, which probably requires its own issue. But I don't feel strongly so you don't need to change anything. I just want to note that I find it a bit odd.

Copy link
Member
@corona10 corona10 left a comment

Choose a reason for hi 8000 ding this comment

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

lgtm

@vstinner
Copy link
Member Author

For the risk of breaking C extensions with this PR: I documented the change in What's New in Python 3.11. It's the bare minimum change that I can do.

@pablogsal: Apart of the bpo number, are you ok with this change?

A GC type with NULL traverse function is likely to crash, but not always, as we saw with the broken _ssl.SSLError exception ;-) This change makes the code more deterministic, it always fail (but don't crash) ;-)

Copy link
Member
@shihai1991 shihai1991 left a comment

Choose a reason for hiding this comment

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

Nice improvement.

@shihai1991
Copy link
Member

For the risk of breaking C extensions with this PR: I documented the change in What's New in Python 3.11. It's the bare minimum change that I can do.

Hm. Ptr's pep-652 have redefined the lifetime of stable ABI, so it's not a big probleam, right?
refs: https://www.python.org/dev/peps/pep-0652/#stable-abi

@pablogsal
Copy link
Member

Hm. Ptr's pep-652 have redefined the lifetime of stable ABI, so it's not a big probleam, right?

This doesn't change the ABI, it just makes a bug break early :)

@shihai1991
Copy link
Member

This doesn't change the ABI, it just makes a bug break early :)

OK. It's make sense :)

@vstinner vstinner merged commit ee76375 into python:main Jun 1, 2021
@vstinner vstinner deleted the gc_type_traverse branch June 1, 2021 21:37
@vstinner
Copy link
Member Author
vstinner commented Jun 1, 2021

Ok, I merged my PR. If it breaks too many C extensions, we can revert it. I hope that it will detect more real bugs than it breaks C extensions for no good reasons :-D

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.

7 participants
0