8000 bpo-35381 Remove all static state from posixmodule by eduardo-elizondo · Pull Request #15892 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

bpo-35381 Remove all static state from posixmodule #15892

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 45 commits into from
Nov 5, 2019

Conversation

eduardo-elizondo
Copy link
Contributor
@eduardo-elizondo eduardo-elizondo commented Sep 11, 2019

After #9665, this moves the remaining types in posixmodule to be heap-allocated to make it compatible with PEP384 as well as modifying all the type accessors to fully make the type opaque.

The original PR that got messed up a rebase: #10854. All the issues in that commit have now been addressed since #11661 got committed.

This change also removes any state from the data segment and onto the module state itself.

https://bugs.python.org/issue35381

Automerge-Triggered-By: @encukou

@eduardo-elizondo eduardo-elizondo changed the title bpo-35381 Make all posixmodule types heap-allocated [WIP] bpo-35381 Make all posixmodule types heap-allocated Sep 11, 2019
Copy link
Member
@encukou encukou left a comment

Choose a reason for hiding this comment

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

As Jeroen pointed out in the issue, PEP 384 (Stable ABI) isn't very relevant to the standard library. PEP 489 (Multi-phase init) would bring benefits (better subinterpreter support), but this isn't quite there.
Is there a practical benefit to this change?

@encukou
Copy link
Member
encukou commented Sep 11, 2019

I pushed a few changes directly rather than writing a comment about them. Hope that's OK with you :)

I'm proposing a PyState_AddModule doc update to make things clearer:
python#16101
@encukou
Copy link
Member
encukou commented Sep 13, 2019

I added some commits here. The core dev sprint is ending, and I won't have time to look at this issue for the next few days (or weeks, unfortunately, depending on work load).
Please take these as comments/conversation starters, rather than the one true way of doing things. Feel free to rebase/modify them.

@eduardo-elizondo
Copy link
Contributor Author

@encukou thanks for all the reviews! I'll update this to address all the comments

@eduardo-elizondo
Copy link
Contributor Author
eduardo-elizondo commented Sep 17, 2019

Module-level constant strings should use PyUnicode_InternFromString rather than PyUnicode_FromString

Agreed, thanks for the fix!

I'd rather bring _Py_IDENTIFIER(fspath) back (for now) than reimplement _PyObject_LookupSpecial.

I think there's two options: 1) Solve this by creating a new C-API that handles this without a _Py_IDENTIFIER. Unfortunately, this will add yet another C-API function. 2) Not expand the C-API and fix the pattern at the extension level. There's only 2 C Extensions in the stdlib that use this pattern.
Given that this is not a very common pattern, I think it's best to go for approach # 2. I didn't modify anything just yet but I'd like to hear your thoughts!

A more systematic solution would be to implement another C-API to hide the abstraction there. That being said, I rather not expand the C-API given that this pattern is barely present in the stdlib. I've kept the change for now to

In the stdlib, I'd prefer using tp_free and tp_new directly rather than using the workarounds here.

Unfortunately, under PEP384, tp_free and tp_new are not public api so they can't be used 😞
Also, with the introduced changes, os.stat_result now fails. I will revert this change to be compliant with PEP384 and make all tests pass.

ScandirIterator_new and DirEntry_new are the same function.

Thanks for merging them!

@encukou
Copy link
Member
encukou commented Oct 8, 2019

I think there's two options: 1) Solve this by creating a new C-API that handles this without a _Py_IDENTIFIER. Unfortunately, this will add yet another C-API function. 2) Not expand the C-API and fix the pattern at the extension level. There's only 2 C Extensions in the stdlib that use this pattern.
Given that this is not a very common pattern, I think it's best to go for approach # 2. I didn't modify anything just yet but I'd like to hear your thoughts!

As we remove statics, there will need to be a generic solution for _Py_IDENTIFIER. Eric & the team are thinking about how to handle them.
Let's not change things in a single module.

Unfortunately, under PEP384, tp_free and tp_new are not public api so they can't be used

PEP 384, the stable ABI, is not relevant to the standard library.
It is good to „dogfood“ the stable ABI in the stdlib, to make sure the ABI is usable – and to catch places where it can be improved, like this. We should definitely expand the stable ABI to allow handling slots more elegantly.
But I don't want to work around the stable ABI limitations.

@eduardo-elizondo
Copy link
Contributor Author
eduardo-elizondo commented Oct 9, 2019

Hey Petr, good to hear back from you!

As we remove statics, there will need to be a generic solution for _Py_IDENTIFIER. Eric & the team are thinking about how to handle them. Let's not change things in a single module.

Outside of the special case of _PyObject_LookupSpecial , we solved the _Py_IDENTIFIER problem by setting a unicode object in the module state and using it with non _Py_IDENTIFIER C-APIs. I.e. PyObject_GetAttr instead of _PyObject_GetAttrId.

PEP 384, the stable ABI, is not relevant to the standard library.

It is very relevant to any C Extension Module! That's something that I've been trying to get across but I'm probably not doing a good job at it 😛

The really nice benefit of PEP384 is that it hides all the implementation details of CPython. This allows any other implementation to use these modules as well. So adding these changes here allows 1) to set a pattern for other C Extensions to use PEP384, and 2) enables these extensions to be used by any other implementation.

Let me know if it makes sense and/or if you have other questions/concerns!

We should definitely expand the stable ABI to allow handling slots more elegantly.

Agreed! Any suggestions on the proper avenues to do that?

@encukou
Copy link
Member
encukou commented Oct 22, 2019

Sorry for the delay – I needed to cancel my CPython day last week :(

The really nice benefit of PEP384 is that it hides all the implementation details of CPython. This allows any other implementation to use these modules as well. So adding these changes here allows 1) to set a pattern for other C Extensions to use PEP384, and 2) enables these extensions to be used by any other implementation.

Agreed. However, the set a pattern for other C Extensions is an issue here.
I find this PR quite elegant, and I'm happy that the stable ABI is nice to use – with one exception, the setting of structseq slots via PyDescr_NewClassMethod and PyObject_SetAttrString. All the other pieces set a good example, but this one is an example of how to get around a limited API.
I want to find a better API before this is in the standard library and sets an example for everyone else.

Can we merge this PR with commit c1a6d03 reverted, and leave that bit for future work?
It's a big PR and I think it would help to have the majority of it merged.

We should definitely expand the stable ABI to allow handling slots more elegantly.

Agreed! Any suggestions on the proper avenues to do that?

Brainstorming ideas:

  • Add a new version of PyStructSequence_NewType that would take additional slot information (setting a precedent for other *_NewType functions)
  • Add a "set" counterpart to PyType_GetSlot (and think through the implications & limitations of that)

@eduardo-elizondo
Copy link
Contributor Author

Can we merge this PR with commit c1a6d03 reverted, and leave that bit for future work?

Sounds like a plan! I'll update this PR in a bit :)

@eduardo-elizondo
Copy link
Contributor Author

@encukou done!

Copy link
Member
@encukou encukou left a comment

Choose a reason for hiding this comment

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

I had a few cosmetic nitpicks, but I don't think they need a review round-trip, so I'll just merge with them.

Thank you very much for this change!

@@ -537,7 +538,7 @@ _Py_Uid_Converter(PyObject *obj, void *p)
if (index == NULL) {
PyErr_Format(PyExc_TypeError,
"uid should be integer, not %.200s",
Py_TYPE(obj)->tp_name);
_PyType_Name(Py_TYPE(obj)));
Copy link
Member

Choose a reason for hiding this comment

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

tp_name and _PyType_Name() are not the same. There were some discussions between fully qualified names (module.name1.name2.name3) vs short name (name3), but no consensus was found. Well, I should reopen a discussion ;-) I prefer to provide longest names in error messages to ease debug.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@vstinner I actually debated over that for a bit! I think we are missing something like: PyType_QualName. I can do a quick PR for that but I don't know if there will be push back from other devs. Thoughts?

Copy link
Member

Choose a reason for hiding this comment

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

Reopening the discussion sounds like a good idea.

Copy link
Member

Choose a reason for hiding this comment

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

Was it reopened? A discussion could be useful in https://bugs.python.org/issue42035.

jacobneiltaylor pushed a commit to jacobneiltaylor/cpython that referenced this pull request Dec 5, 2019
After python#9665, this moves the remaining types in posixmodule to be heap-allocated to make it compatible with PEP384 as well as modifying all the type accessors to fully make the type opaque.

The original PR that got messed up a rebase: python#10854. All the issues in that commit have now been addressed since python#11661 got committed.

This change also removes any state from the data segment and onto the module state itself.


https://bugs.python.org/issue35381



Automerge-Triggered-By: @encukou
shihai1991 pushed a commit to shihai1991/cpython that referenced this pull request Jan 31, 2020
After python#9665, this moves the remaining types in posixmodule to be heap-allocated to make it compatible with PEP384 as well as modifying all the type accessors to fully make the type opaque.

The original PR that got messed up a rebase: python#10854. All the issues in that commit have now been addressed since python#11661 got committed.

This change also removes any state from the data segment and onto the module state itself.


https://bugs.python.org/issue35381



Automerge-Triggered-By: @encukou
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.

6 participants
0