Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

bpo-42327: Add PyModule_Add() (smaller).#23443

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
serhiy-storchaka merged 12 commits intopython:mainfromserhiy-storchaka:pymodule-add3
Jul 18, 2023

Conversation

serhiy-storchaka
Copy link
Member

@serhiy-storchakaserhiy-storchaka commentedNov 21, 2020
edited
Loading

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

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
Copy link
MemberAuthor

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.

@serhiy-storchakaserhiy-storchaka changed the titlebpo-42327: Add PyModule_Add().bpo-42327: Add PyModule_Add() (smaller).Nov 21, 2020
Copy link
Member

@vstinnervstinner left a 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 preferPyModule_AddObjectRef(obj) rather thanPy_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.

@vstinner
Copy link
Member

vstinner commentedNov 23, 2020
edited by bedevere-bot
Loading

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. Seebpo-40077 andbpo-1635741.

@tiran
Copy link
Member

I still preferhttps://github.com/python/cpython/pull/23286/files overPyModule_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 needPyModule_Add?

erlend-aasland and serhiy-storchaka reacted with thumbs up emoji

@github-actions
Copy link

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

@github-actionsgithub-actionsbot added the staleStale PR or inactive for long period of time. labelDec 24, 2020
@tirantiran removed their request for reviewApril 18, 2021 09:43
@github-actionsgithub-actionsbot removed the staleStale PR or inactive for long period of time. labelAug 1, 2022
@vstinner
Copy link
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.

@serhiy-storchaka
Copy link
MemberAuthor

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

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

returnPy_BuildValue("Nl",_PyLong_FromTime_t(sec),nsec);

instead of:

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

@rhettingerrhettinger removed their request for reviewJuly 10, 2023 14:41
@vstinner
Copy link
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

@serhiy-storchaka
Copy link
MemberAuthor

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 originalPyModule_AddObject() written right.

@serhiy-storchaka
Copy link
MemberAuthor

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 publicPyModule_AddNew(). But I think that it is better to havePyModule_AddNew() than not have neitherPyModule_AddNew() nor new module initialization API.

@encukou
Copy link
Member

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

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

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

@vstinner
Copy link
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 justone 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 ;-)

@vstinner
Copy link
Member

What does "New" stand for? This function does not create anew reference, butsteals 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().

@serhiy-storchaka
Copy link
MemberAuthor

It adds a newly created object.
I think that the format unit "N" inPy_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 namePyModule_AddNew(). Initially I named it simplyPyModule_Add(). I can rename it back.

Copy link
Member

@vstinnervstinner left a 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.

.. c:function:: int PyModule_Add(PyObject *module, const char *name, PyObject *value)

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

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.

Copy link
MemberAuthor

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 usePyModule_AddObjectRef() rely on this.

// 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'.
Copy link
Member

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".

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
Copy link
Member

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 toPyModule_AddObjectRef() andPyModule_Add() but steal
// Similar to PyModule_Add() but steal


// 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.
Copy link
Member

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.

Copy link
MemberAuthor

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 thenote block intodeprecated?

@serhiy-storchaka
Copy link
MemberAuthor

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.

@vstinner
Copy link
Member

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

Copy link
Member

@vstinnervstinner left a 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.

@serhiy-storchaka
Copy link
MemberAuthor

Thanks Victor.

vstinner reacted with thumbs up emoji

@vstinner
Copy link
Member

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

@vstinner
Copy link
Member

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

serhiy-storchaka reacted with thumbs up emoji

@vstinner
Copy link
Member

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

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

@vstinnervstinnervstinner approved these changes

@abalkinabalkinAwaiting requested review from abalkin

@pgansslepganssleAwaiting requested review from pganssle

@encukouencukouAwaiting requested review from encukouencukou is a code owner

Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

7 participants
@serhiy-storchaka@vstinner@tiran@encukou@the-knights-who-say-ni@ezio-melotti@bedevere-bot

[8]ページ先頭

©2009-2025 Movatter.jp