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 — gh-106915: Add PyImport_ImportOrAddModule() function by vstinner · Pull Request #111559 · python/cpython

Conversation

@vstinner

@vstinner vstinner commented Oct 31, 2023 •
edited by github-actions Bot
Loading

Uh oh!

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

Copy link
Copy Markdown
Member

Remove PyImport_AddModuleRef() function.

  • Issue: PyImport_AddModuleRef is questionable  #106915

📚 Documentation preview 📚: https://cpython-previews--111559.org.readthedocs.build/

Sorry, something went wrong.

Uh oh!

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

All reactions
@vstinner
vstinner requested review from a team, brettcannon, encukou, ericsnowcurrently, kumaraditya303, ncoghlan and warsaw as code owners October 31, 2023 16:43
@bedevere-app bedevere-app Bot mentioned this pull request Oct 31, 2023
PyImport_AddModuleRef is questionable #106915
Closed
@bedevere-app bedevere-app Bot added the awaiting core review label Oct 31, 2023
@vstinner

vstinner commented Oct 31, 2023

Copy link
Copy Markdown
Member Author

cc @encukou @serhiy-storchaka

All reactions

Sorry, something went wrong.

Uh oh!

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

@kumaraditya303
kumaraditya303 removed their request for review November 1, 2023 13:16
@vstinner
pythongh-106915: Add PyImport_ImportOrAddModule() function
2f3cc67
Remove PyImport_AddModuleRef() function.
@vstinner
vstinner force-pushed the pyimport_createmodule branch from b6f8588 to 2f3cc67 Compare November 7, 2023 09:22
@vstinner

vstinner commented Nov 7, 2023

Copy link
Copy Markdown
Member Author

@encukou proposes PyImport_ImportOrAddModule(), nobody proposes better name. I abandon my PyImport_CreateModule() name: I renamed the function to PyImport_ImportOrAddModule().

All reactions

Sorry, something went wrong.

Uh oh!

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

@vstinner vstinner changed the title gh-106915: Add PyImport_CreateModule() function gh-106915: Add PyImport_ImportOrAddModule() function Nov 7, 2023
vstinner added 2 commits November 7, 2023 10:30
@vstinner
Rephrase the doc
390fa73
@vstinner
Add import_import_or_add_module() helper function
ac91bea
@vstinner

vstinner commented Nov 7, 2023

Copy link
Copy Markdown
Member Author

Oh, if PyImport_AddModuleRef() is removed, I should update pythoncapi-compat as well: https://pythoncapi-compat.readthedocs.io/en/latest/api.html#c.PyImport_AddModuleRef

All reactions

Sorry, something went wrong.

Uh oh!

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

encukou
encukou reviewed Nov 7, 2023
View reviewed changes

@encukou encukou 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.

API-wise, this looks good to me, thank you! We should of course wait if the C-API WG is approved.

In the docs, I'd mention creating a new (empty) module more prominently, to make extra sure people don't assume the module is imported if missing.

Sorry, something went wrong.

Uh oh!

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

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

Uh oh!

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

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

Uh oh!

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

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

Uh oh!

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

@vstinner
Address Petr's review
35f862a
@vstinner

vstinner commented Nov 8, 2023

Copy link
Copy Markdown
Member Author

I applied your suggestions manually to also update the doc in Include/import.h at the same time.

All reactions

Sorry, something went wrong.

Uh oh!

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

@vstinner

vstinner commented Nov 8, 2023

Copy link
Copy Markdown
Member Author

We should of course wait if the C-API WG is approved.

The working group doesn't exist yet.

Maybe @gvanrossum @zooba and @iritkatriel want to review this PR?

All reactions

Sorry, something went wrong.

Uh oh!

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

@vstinner

vstinner commented Nov 8, 2023

Copy link
Copy Markdown
Member Author

@encukou: Would you mind to review the updated PR?

All reactions

Sorry, something went wrong.

Uh oh!

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

@brettcannon
brettcannon removed their request for review November 8, 2023 22:02
@encukou

encukou commented Nov 9, 2023

Copy link
Copy Markdown
Member

I'll get to it next week.

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.

encukou
encukou reviewed Nov 9, 2023
View reviewed changes

@encukou encukou left a comment •
edited
Loading

Uh oh!

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

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.

(Got to it sooner!)

+1 from me on the functionality. Thank you!

It looks OK API-wise, too. I recommend checking with the other CAPI-workgroup-to-be members if it fits the direction they want.

One thing to note is the allocation of the “lesser” and “greater” result (0 or 1) for this kind of “setdefault”-style API: should 1 mean “created/assigned” like here, or “found” like in “getitem”-style API?
As far as I'm concerned, it could go either way, but some people might have a strong opinion. And this could become a precedent.

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Modules/_testcapimodule.c Resolved

Uh oh!

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

vstinner added 2 commits November 9, 2023 16:58
@vstinner
Remove outdated comment
c12b080
@vstinner
Return 1 if exists, 0 if created
af8a9df
@vstinner

vstinner commented Nov 9, 2023 •
edited
Loading

Uh oh!

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

Copy link
Copy Markdown
Member Author

One thing to note is the allocation of the “lesser” and “greater” result (0 or 1) for this kind of “setdefault”-style API: should 1 mean “created/assigned” like here, or “found” like in “getitem”-style API?

Aha. The function is called import or add: add comes second, so I suppose that it should return success (1) if import is successful. Also, I think that returning 1 if the module exists in sys.modules which be consistent with PyDict_GetItemRef() API.

I modified the PR to return 1 if the module is found in sys.modules, or 0 if the module was created (and then added to sys.modules).

All reactions

Sorry, something went wrong.

Uh oh!

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

@vstinner

vstinner commented Nov 13, 2023

Copy link
Copy Markdown
Member Author

I modified the PR to return 1 if the module is found in sys.modules, or 0 if the module was created (and then added to sys.modules).

@encukou: Would you mind to review the updated PR?

All reactions

Sorry, something went wrong.

Uh oh!

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

@encukou

encukou commented Nov 13, 2023

Copy link
Copy Markdown
Member

I like this better, thanks!
Again, it would be nice if the other candidates for C-API WG confirmed that this matches the direction they want to take.

All reactions

Sorry, something went wrong.

Uh oh!

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

@encukou encukou mentioned this pull request Nov 13, 2023
API pattern for “setdefault”-like operations capi-workgroup/api-evolution#40
Open
@zooba

zooba commented Nov 13, 2023

Copy link
Copy Markdown
Member

I think we've still got to thoroughly discuss the return value convention, and personally in this case I'd prefer to see PyObject *PyImport_ImportOrAddModule(const char *name, int *was_created) where the second parameter can be NULL if you don't care.

Right now it isn't immediately obvious whether the existing value of the module argument is what is going to be added, or whether a new one will be created (ImportOrCreateModule might be enough to clarify, but as it's a "get the object" type API, and the object knows how to alloc/dealloc itself, I'd prefer the return value to be the object rather than the disposition of the object).

If there's a need to hurry this API in, then I won't block it, but I would ask that it not be used as precedent when we come to deciding the guideline. If we decide to go the other way, it can just be an exception/wart, but we shouldn't rush an API and then use that to determine the guideline.

All reactions

Sorry, something went wrong.

Uh oh!

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

@vstinner

vstinner commented Nov 13, 2023

Copy link
Copy Markdown
Member Author

@zooba:

personally in this case I'd prefer to see PyObject *PyImport_ImportOrAddModule(const char *name, int *was_created) where the second parameter can be NULL if you don't care.

Well, I added PyImport_AddModuleRef() to Python 3.13 in replacement of PyImport_AddModuleObject() to avoid borrowed references (the implementation uses a strange hack using a weakref). Then @encukou created issue gh-106915 since he considers that we should provide the information to the caller if the module was get from sys.modules or if a new empty main was created. Currently, the information is not provided, and I don't recall previous request to get it.

@encukou: So, which API do you prefer?

  • Keep PyObject* PyImport_AddModuleRef(const char *name) as it is?
  • int PyImport_ImportOrAddModule(const char *name, PyObject **module) (module cannot be NULL)
  • PyObject *PyImport_ImportOrAddModule(const char *name, int *was_created) where was_created can be NULL
All reactions

Sorry, something went wrong.

Uh oh!

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

@encukou

encukou commented Nov 13, 2023

Copy link
Copy Markdown
Member

I think we've still got to thoroughly discuss the return value convention

Please add your proposal/ideas there. New API is being added without waiting for that discussion...

Well, I added PyImport_AddModuleRef() to Python 3.13 in replacement of PyImport_AddModuleObject() to avoid borrowed references (the implementation uses a strange hack using a weakref). Then @encukou created issue #106915 since he considers that we should provide the information to the caller if the module was get from sys.modules or if a new empty main was created. Currently, the information is not provided, and I don't recall previous request to get it.

As always with new API, I'd prefer waiting until the WG can discuss it.
I think there are multiple issues with PyImport_AddModuleRef. I'd prefer to get a proper design before adding API, but I feel rushed in this case -- if we don't solve it for 3.13, we'll be stuck with PyImport_AddModuleRef.
Also, I don't think this function is particularly important, and it would be fine to keep things as they were in 3.12. The borrowed reference is just one of the warts.

@encukou: So, which API do you prefer?

What I prefer now, in the middle of the discussions?

  1. For importing stdlib or other stuff import can handle, PyImport_ImportModule, which exists already
  2. For a new empty module, something like PyObject *PyImport_AddNew(char *name)
  3. For a new “namespace” module or one shared with other extensions: the thread-safe getdefault pattern I proposed above.

For 3., the PyImport_ImportOrCreate is OK, except for that thread-safety issue when users need to initialize the module.
For 2., PyImport_ImportOrCreate is also OK, provided that the user handles the case where the module already existed -- then they'd want to do one of two things:

  • raise an error. Perhaps it would, in general, be good to provide API that raises errors, in order to have consistent exceptions.
  • skip any initialization & reuse the module. But in case they needed initialization, there's a race condition again.
All reactions

Sorry, something went wrong.

Uh oh!

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

@vstinner vstinner mentioned this pull request Nov 13, 2023
Return value conventions capi-workgroup/api-evolution#13
Open
@vstinner

vstinner commented Dec 20, 2023

Copy link
Copy Markdown
Member Author

This PR implements what @encukou proposed there: #106915 (comment) But apparently, @encukou now dislikes the API.

I don't have the bandwidth to dig into the issue. @encukou: if you're motivated, please go ahead. For now, I prefer to close this PR.

All reactions

Sorry, something went wrong.

Uh oh!

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

@vstinner vstinner closed this Dec 20, 2023
@vstinner
vstinner deleted the pyimport_createmodule branch January 14, 2025 08:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@encukou encukou encukou left review comments
@ericsnowcurrently ericsnowcurrently Awaiting requested review from ericsnowcurrently ericsnowcurrently is a code owner
@ncoghlan ncoghlan Awaiting requested review from ncoghlan ncoghlan is a code owner
@warsaw warsaw Awaiting requested review from warsaw warsaw is a code owner

Uh oh!

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

Assignees

No one assigned

Labels

awaiting core review

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.

3 participants

@vstinner @encukou @zooba
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.