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

gh-106307: Add PyMapping_GetOptionalItem()#106308

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

Conversation

serhiy-storchaka
Copy link
Member

@serhiy-storchakaserhiy-storchaka commentedJul 1, 2023
edited by bedevere-bot
Loading

Replacement of PyObject_GetItem() which doesn't raise KeyError.

int _PyMapping_LookupItem(PyObject *obj, PyObject *key, PyObject **result)

Return 1 and set *result != NULL if a key is found.
Return 0 and set *result == NULL if a key is not found; a KeyError is silenced.
Return -1 and set *result == NULL if an error other than KeyError is raised.

Replacement of PyObject_GetItem() which doesn't raise KeyError.  int _PyMapping_LookupItem(PyObject *obj, PyObject *key, PyObject **result)Return 1 and set *result != NULL if a key is found.Return 0 and set *result == NULL if a key is not found;a KeyError is silenced.Return -1 and set *result == NULL if an error other than KeyErroris raised.
_PyErr_Clear(tstate);
}
}
(void)_PyMapping_LookupItem(modules, name, &m);
Copy link
Contributor

Choose a reason for hiding this comment

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

Out of interest, why not explicitly_PyErr_Clear(tstate) if_PyMapping_LookupItem returns-1?

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Because the current code does not clear arbitrary errors (and doing this would be wrong). It only clearsKeyError, what is done internally by_PyMapping_LookupItem.

@serhiy-storchakaserhiy-storchaka requested review froma team andencukou ascode ownersJuly 7, 2023 17:15
@serhiy-storchakaserhiy-storchaka changed the titlegh-106307: Add _PyMapping_LookupItem()gh-106307: Add PyMapping_GetOptionalItem()Jul 7, 2023
Copy link
Member

@carljmcarljm left a comment

Choose a reason for hiding this comment

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

Thebytecodes.c cleanups alone (i.e. the existing cases where we cared enough about perf to special-case the exact-dict fast path) clearly show the value of this API! Now all call sites can get the same perf benefit, with much less verbosity.

erlend-aasland reacted with thumbs up emoji
Comment on lines 40 to 43
Return ``1`` and set ``*result != NULL`` if a key is found.
Return ``0`` and set ``*result == NULL`` if a key is not found;
a :exc:`KeyError` is silenced.
Return ``-1`` and set ``*result == NULL`` if an error other than
Copy link
Member

@carljmcarljmJul 7, 2023
edited by serhiy-storchaka
Loading

Choose a reason for hiding this comment

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

To me, "KeyError is silenced" suggests internal implementation details that the caller doesn't need to care about, and b) may or may not be true (in the exact-dict case, no KeyError is silenced because it isn't set in the first place). IMO "no KeyError is raised" is a clearer statement of the contract that is relevant to the caller.

Suggested change
Return ``1`` and set ``*result != NULL`` ifa key is found.
Return ``0`` and set ``*result == NULL`` ifa key is not found;
a:exc:`KeyError` is silenced.
Return ``-1`` and set ``*result == NULL`` if an error other than
Return ``1`` and set ``*result != NULL`` ifthe key is found.
Return ``0`` and set ``*result == NULL`` ifthe key is not found;
the:exc:`KeyError` is silenced.
Return ``-1`` and set ``*result == NULL`` if an error other than

Copy link
Member

Choose a reason for hiding this comment

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

On second thought, it may be important to specify "the KeyError is silenced" to clarify the behavior with a custom__getitem__ method that raisesKeyError explicitly. I take back that part of the suggestion; I would just replace all three instances ofa withthe.

Copy link
Member

Choose a reason for hiding this comment

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

I dislike specify that*pvalue is set to NULL on error. I would prefer to leave it undefined.

Code like(void)PyMapping_GetOptionalItem(modules, name, &m); would be unsafe: I prefer to handle explicitly the error case and no rely onm value.

In the implementation, I prefer to set it to NULL to avoid... the undefined behavior :-) Maybe in debug mode we could even set the value to a marker value to detect the usage of the undefined value.

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

I disagree. It will require explicitly settingresult = NULL before every call of this function, and if you forgot to do this, it will crash your code in rare case of error, which may be not covered by tests. The risk of writing errorenous code is too high even if there would be a benefit from not setting the result to NULL.

Also, it makes the code simpler. Instead of saving the return code into a variable and checking it in twoif\ s

intrc=PyMapping_GetOptionalItem(...);if (rc<0) {    gotoerror;}if (rc==0) {// handle default}

you can get rid of that variable and insert the call directly in theif.

if (PyMapping_GetOptionalItem(...)<0) {    gotoerror;}if (value==NULL) {// handle default}

And there are many other cases in which it is convenient that you have two ways to check for result. I suggest you to makePyMapping_GetOptionalItem() not setting the result to NULL on error and to look how much code it will require to rewrite and how much uglier it will become. It is the same forPyObject_GetOptionalAttr.

carljm reacted with thumbs up emoji
Copy link
Contributor

@erlend-aaslanderlend-aaslandJul 11, 2023
edited
Loading

Choose a reason for hiding this comment

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

I disagree. It will require explicitly setting result = NULL before every call of this function, and if you forgot to do this, it will crash your code in rare case of error, which may be not covered by tests.

+1 and slightly related, I have a PR for the devguide repo regarding explicitly clearing output parameters:python/devguide#1129python/devguide#1128

cc.@serhiy-storchaka,@carljm

Comment on lines 40 to 43
Return ``1`` and set ``*result != NULL`` if a key is found.
Return ``0`` and set ``*result == NULL`` if a key is not found;
a :exc:`KeyError` is silenced.
Return ``-1`` and set ``*result == NULL`` if an error other than
Copy link
Member

Choose a reason for hiding this comment

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

I dislike specify that*pvalue is set to NULL on error. I would prefer to leave it undefined.

Code like(void)PyMapping_GetOptionalItem(modules, name, &m); would be unsafe: I prefer to handle explicitly the error case and no rely onm value.

In the implementation, I prefer to set it to NULL to avoid... the undefined behavior :-) Maybe in debug mode we could even set the value to a marker value to detect the usage of the undefined value.

@brettcannonbrettcannon removed their request for reviewJuly 7, 2023 22:01
serhiy-storchakaand others added3 commitsJuly 8, 2023 11:45
Co-authored-by: Carl Meyer <carl@oddbird.net>Co-authored-by: Victor Stinner <vstinner@python.org>
Co-authored-by: Carl Meyer <carl@oddbird.net>
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

@serhiy-storchakaserhiy-storchaka merged commit4bf4371 intopython:mainJul 11, 2023
@serhiy-storchakaserhiy-storchaka deleted the _PyMapping_LookupItem branchJuly 11, 2023 20:04
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@carljmcarljmcarljm left review comments

@encukouencukouencukou left review comments

@erlend-aaslanderlend-aaslanderlend-aasland left review comments

@vstinnervstinnervstinner approved these changes

@ericsnowcurrentlyericsnowcurrentlyAwaiting requested review from ericsnowcurrently

@ncoghlanncoghlanAwaiting requested review from ncoghlan

@warsawwarsawAwaiting requested review from warsaw

@markshannonmarkshannonAwaiting requested review from markshannonmarkshannon 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.

6 participants
@serhiy-storchaka@carljm@vstinner@encukou@erlend-aasland@bedevere-bot

[8]ページ先頭

©2009-2025 Movatter.jp