GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — bpo-42327: Add PyModule_Add() (smaller). by serhiy-storchaka · Pull Request #23443 · python/cpython

Conversation

@serhiy-storchaka

@serhiy-storchaka serhiy-storchaka commented Nov 21, 2020 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Also fix possible leaks in initialization of modules: _curses_panel, _decimal, _ssl, _stat, _testinternalcapi, _threadmodule, cmath, math, posix, time, xxsubtype.

https://bugs.python.org/issue42327

#86493

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@serhiy-storchaka
bpo-42327: Add PyModule_Add().
26e6d1c
Also fix possible leaks in initialization of modules:
_csv, _curses_panel, _elementtree, _io, _pickle, _stat,
_testinternalcapi, _threadmodule, _zoneinfo, _codecs_*,
cmath, math, ossaudiodev, time, xxlimited, xxmodule, xxsubtype.
@serhiy-storchaka
serhiy-storchaka requested review from a team, abalkin and pganssle as code owners November 21, 2020 12:23
@the-knights-who-say-ni the-knights-who-say-ni added the CLA signed label Nov 21, 2020
@bedevere-bot bedevere-bot added the awaiting core review label Nov 21, 2020
@serhiy-storchaka
serhiy-storchaka requested a review from tiran November 21, 2020 12:26
@serhiy-storchaka

serhiy-storchaka commented Nov 21, 2020

Copy link
Copy Markdown
Member Author

This is the same as #23240, but without large changes to modules _ssl, _testbuffer, _testcapi, posix, select, socket, _msi, msvcrt. They will be extracted to separate PRs.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@serhiy-storchaka serhiy-storchaka changed the title bpo-42327: Add PyModule_Add(). bpo-42327: Add PyModule_Add() (smaller). Nov 21, 2020
@serhiy-storchaka serhiy-storchaka mentioned this pull request Nov 21, 2020
bpo-42327: Add PyModule_Add(). #23240
Closed
vstinner
vstinner reviewed Nov 23, 2020
View reviewed changes

@vstinner vstinner left a comment

Copy link
Copy Markdown
Member

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 like the new functon, but I prefer PyModule_AddObjectRef(obj) rather than Py_INCREF(obj); PyModule_Add(obj). In some cases, you removed a test for NULL, but I don't think that it's worth it (I prefer an explicit test with PyModule_AddObjectRef, but that's a personal preference, I guess). At least, when not test for == NULL is needed, PyModule_AddObjectRef() should be preferred IMO.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Doc/c-api/module.rst Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Misc/NEWS.d/next/C API/2020-11-11-22-36-29.bpo-42327.ODSZBM.rst Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Modules/_csv.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Modules/_csv.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Modules/_curses_panel.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Modules/_threadmodule.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Modules/_threadmodule.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Modules/_threadmodule.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Modules/ossaudiodev.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Python/modsupport.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

@vstinner

vstinner commented Nov 23, 2020 •
edited by bedevere-bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Could you split this PR in two parts? The first uncontroversial PR which only adds the function, and then a second PR which modify PyInit functions to use it.

These days, there are dozens of PRs modifying PyInit functions which would be in conflict with the second part. See bpo-40077 and bpo-1635741.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@tiran

tiran commented Nov 23, 2020

Copy link
Copy Markdown
Member

I still prefer https://github.com/python/cpython/pull/23286/files over PyModule_Add. The three new APIs from my PR will simplify a lot of common cases:

  • initialize and add new type to module dict
  • initialize and add new exception to module dict
  • add int/str/float/bool constants from a static array

How about we land PR #23286 first, port more code to the new API, and then see if we still need PyModule_Add?

erlend-aasland and serhiy-storchaka reacted with thumbs up emoji
All reactions
  • 👍 2 reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions

github-actions Bot commented Dec 24, 2020

Copy link
Copy Markdown

This PR is stale because it has been open for 30 days with no activity.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions github-actions Bot added the stale Stale PR or inactive for long period of time. label Dec 24, 2020
@tiran
tiran removed their request for review April 18, 2021 09:43
@corona10 corona10 mentioned this pull request Jun 27, 2022
Convert static types to heap types: use PyType_FromSpec() #84258
Closed
@ezio-melotti ezio-melotti removed the CLA signed label Jul 13, 2022
@github-actions github-actions Bot removed the stale Stale PR or inactive for long period of time. label Aug 1, 2022
@kylotan kylotan mannequin mentioned this pull request Sep 19, 2022
Py_Finalize() doesn't clear all Python objects at exit #44470
Closed
@serhiy-storchaka serhiy-storchaka mentioned this pull request Nov 15, 2022
C API: Add PyModule_Add() function #86493
Closed
serhiy-storchaka added 5 commits July 10, 2023 12:09
@serhiy-storchaka
Merge branch 'main' into pymodule-add3
1dca02c
@serhiy-storchaka
Raname PyModule_Add to PyModule_AddNew.
5adebfe
@serhiy-storchaka
Cleanup and update docs.
37ff11b
@serhiy-storchaka
Regenerate the limited APthe I
952015c
@serhiy-storchaka
Fix more PyModule_AddObject usages.
2da12b0
@serhiy-storchaka
serhiy-storchaka requested review from encukou and rhettinger as code owners July 10, 2023 12:18
@vstinner

vstinner commented Jul 10, 2023

Copy link
Copy Markdown
Member

I dislike APIs stealing references. IMO we should stop adding such API. I would prefer regular (boring and verbose) reference counting to make the C API easier to understand. Currently, developers have to check the documentation of each function to check if it returns a borrowed or strong reference, if it adds or removes a reference (and leave the ref count unchanged), etc.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@serhiy-storchaka

serhiy-storchaka commented Jul 10, 2023

Copy link
Copy Markdown
Member Author

It is a convenient API. How else would you fix Modules/mathmodule.c, for example?

The "N" code in Py_BuildValue() serves the same purpose. It allows to write in one line the code which would require 7 lines otherwise:

return Py_BuildValue("Nl", _PyLong_FromTime_t(sec), nsec);

instead of:

PyObject *tmp = _PyLong_FromTime_t(sec);
if (tmp == NULL) {
    return NULL;
}
PyObject *res = Py_BuildValue("Ol", tmp, nsec);
Py_DECREF(tmp);
return res;
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@serhiy-storchaka
Merge branch 'main' into pymodule-add3
4ecdbe9
@rhettinger
rhettinger removed their request for review July 10, 2023 14:41
@vstinner

vstinner commented Jul 10, 2023

Copy link
Copy Markdown
Member

It is a convenient API. How else would you fix Modules/mathmodule.c, for example?

Usually, a macro is written to create a temporary object and add it to the module. If you use PyModule_AddObjectRef(), the macro would also clear the reference.

I dislike the fact that macro is "required" to write correct code.

In 2020, @tiran proposed designing a new API to make this work easier with a declarative syntax: https://discuss.python.org/t/define-module-constants-in-pymoduledef/5749

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@serhiy-storchaka

serhiy-storchaka commented Jul 11, 2023

Copy link
Copy Markdown
Member Author

Macro is convenient because it can include "goto error" or "return NULL". But having to write such macro in every module is tiring. PyModule_AddNew() does not need to be a macro, it can be a regular function. It is the original PyModule_AddObject() written right.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@serhiy-storchaka

serhiy-storchaka commented Jul 11, 2023

Copy link
Copy Markdown
Member Author

We can make it a private function at first if you so dislike adding it to the public API. Then we can add new @tiran's API and decide whether it is worth to add public PyModule_AddNew(). But I think that it is better to have PyModule_AddNew() than not have neither PyModule_AddNew() nor new module initialization API.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@encukou

encukou commented Jul 11, 2023

Copy link
Copy Markdown
Member

I dislike APIs stealing references. IMO we should stop adding such API.

IMO, that's a good guideline, but PyModule_AddNew is a great example of when we should break this guideline. (Doesn't beat Py_DecRef, but it's close!)

But it should be very clear from the name. I don't think New is clear enough, and would prefer to one of Steal, Consume, Take, Move (see this draft) -- but we should settle on one of those and use it consistently for new API of this kind.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vstinner

vstinner commented Jul 11, 2023

Copy link
Copy Markdown
Member

To be clear, I dislike APIs stealing references, but I don't plan to block this PR. I will just not endorse it :-)

If using PyModule_AddObjectRef() is not convenient, maybe we need to provide "something" to make it easier to use. Sadly, the C language is limited in terms of macros/templates :-( The approach based on a description is promising, but I also know that there are many technical challenges which may not be possible to be solved.

By the way, I'm really unhappy on the bad state of our PyInit functions: many of them simply have no error checking, or just one final PyErr_Occurred() check. That's bad. The trend is more to disallow calling functions with an exception set (it might be enforced later). If this new function makes the situation better: go ahead ;-)

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vstinner vstinner mentioned this pull request Jul 11, 2023
Irregular reference counting capi-workgroup/problems#8
Open
serhiy-storchaka added 2 commits July 13, 2023 17:14
@serhiy-storchaka
Merge branch 'main' into pymodule-add3
eac1730
@serhiy-storchaka
Address the last unresolved review comment.
9dc8cac
@vstinner

vstinner commented Jul 17, 2023

Copy link
Copy Markdown
Member

What does "New" stand for? This function does not create a new reference, but steals a reference. Is is "New" because its a new function replacing an old one? What if tomorrow, there is a newer function? Should we call it PyModule_AddNewer or PyModule_AddNewEx?

I suggest to just call it PyModule_Add().

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@serhiy-storchaka

serhiy-storchaka commented Jul 17, 2023

Copy link
Copy Markdown
Member Author

It adds a newly created object.
I think that the format unit "N" in Py_BuildValue() means "new", because it is purposed to add newly created object, for which we do not need to keep other reference. I was guided by the same reasons for choosing name PyModule_AddNew(). Initially I named it simply PyModule_Add(). I can rename it back.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@serhiy-storchaka
Rename PyModule_AddNew() back to PyModule_Add().
5be0f6a
vstinner
vstinner reviewed Jul 17, 2023
View reviewed changes

@vstinner vstinner left a comment

Copy link
Copy Markdown
Member

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 may be easier to review this big PR if you could move code fixing PyInit functions into a separated PR.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Doc/c-api/module.rst Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Doc/c-api/module.rst Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Doc/c-api/module.rst
.. c:function:: int PyModule_Add(PyObject *module, const char *name, PyObject *value)

Similar to :c:func:`PyModule_AddObjectRef`, but "steals" a reference
to *value*.

@vstinner vstinner Jul 17, 2023

Copy link
Copy Markdown
Member

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.

PyModule_AddObjectRef() must not be called with NULL. Can you please elaborate the behavior when value is NULL? Something like:

If value is NULL, just return -1.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@serhiy-storchaka serhiy-storchaka Jul 17, 2023

Copy link
Copy Markdown
Member Author

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.

PyModule_AddObjectRef() can be called with NULL if an exception is set. Actually, some of my fixes which use PyModule_AddObjectRef() rely on this.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Include/modsupport.h
// Similar to PyModule_AddObjectRef() but steal a reference to 'obj'
// (Py_DECREF(obj)) on success (if it returns 0).
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030d0000
// Similar to PyModule_AddObjectRef() but steal a reference to 'value'.

@vstinner vstinner Jul 17, 2023

Copy link
Copy Markdown
Member

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 suggest to add "and value can be NULL".

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Include/modsupport.h
PyAPI_FUNC(int) PyModule_Add(PyObject *mod, const char *name, PyObject *value);
#endif /* Py_LIMITED_API */

// Similar to PyModule_AddObjectRef() and PyModule_Add() but steal

@vstinner vstinner Jul 17, 2023

Copy link
Copy Markdown
Member

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's not similar to PyModule_AddObjectRef(): value can be NULL.

Suggested change
// Similar to PyModule_AddObjectRef() and PyModule_Add() but steal
// Similar to PyModule_Add() but steal

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Include/modsupport.h

// Similar to PyModule_AddObjectRef() and PyModule_Add() but steal
// a reference to 'value' on success and only on success.
// Errorprone. Should not be used in new code.

@vstinner vstinner Jul 17, 2023

Copy link
Copy Markdown
Member

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.

IMO it's important important to put it in the documentation. This kind of definition fits perfectly with the Soft Deprecated status. Maybe also soft deprecate this API, similar to getopt and optparse soft deprecation. Example with getopt:

.. deprecated:: 3.13
   The :mod:`getopt` module is :term:`soft deprecated` and will not be
   developed further; development will continue with the :mod:`argparse`
   module.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@serhiy-storchaka serhiy-storchaka Jul 17, 2023

Copy link
Copy Markdown
Member Author

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.

Do you suggest to convert the note block into deprecated?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@serhiy-storchaka

serhiy-storchaka commented Jul 17, 2023

Copy link
Copy Markdown
Member Author

It may be easier to review this big PR if you could move code fixing PyInit functions into a separated PR.

Already did this. #106767 and #106768.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vstinner

vstinner commented Jul 17, 2023

Copy link
Copy Markdown
Member

Ok, but this PR changes Modules/_curses_panel.c for example, and the change doesn't even use PyModule_Add(). Can you maybe revert these changes? If not, tell me, I will try to get more time to through the whole change.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

serhiy-storchaka added 2 commits July 17, 2023 22:32
@serhiy-storchaka
Remove fixes of module initializations.
f33c54a
@serhiy-storchaka
Update docs.
fdc7ece
vstinner
vstinner approved these changes Jul 17, 2023
View reviewed changes

@vstinner vstinner left a comment

Copy link
Copy Markdown
Member

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.

LGTM.

If I have further comments, I may propose them as a separated PR.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@bedevere-bot bedevere-bot added awaiting merge and removed awaiting core review labels Jul 17, 2023
@serhiy-storchaka
serhiy-storchaka merged commit 83ac128 into python:main Jul 18, 2023
@bedevere-bot bedevere-bot removed the awaiting merge label Jul 18, 2023
@serhiy-storchaka
serhiy-storchaka deleted the pymodule-add3 branch July 18, 2023 06:42
@serhiy-storchaka

serhiy-storchaka commented Jul 18, 2023

Copy link
Copy Markdown
Member Author

Thanks Victor.

vstinner reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vstinner

vstinner commented Jul 18, 2023

Copy link
Copy Markdown
Member

Even if I dislike stealing references, the API seems to help simplifying PyInit code a lot.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vstinner

vstinner commented Jul 18, 2023

Copy link
Copy Markdown
Member

I added the PyModule_Add() function to the pythoncapi-compat project: python/pythoncapi-compat@e3f0eba

serhiy-storchaka reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vstinner

vstinner commented Jul 18, 2023

Copy link
Copy Markdown
Member

I wrote PR #106859 to document PyModule_AddObject() soft deprecation in What's New in Python 3.13.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@vstinner vstinner vstinner approved these changes
@abalkin abalkin Awaiting requested review from abalkin
@pganssle pganssle Awaiting requested review from pganssle
@encukou encukou Awaiting requested review from encukou encukou is a code owner

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

7 participants

@serhiy-storchaka @vstinner @tiran @encukou @the-knights-who-say-ni @ezio-melotti @bedevere-bot
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.