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

Call PyErr_NormalizeException for exceptions#1265

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
lostmsu merged 17 commits intopythonnet:masterfromslide:normalize_exceptions
Dec 21, 2020
Merged

Call PyErr_NormalizeException for exceptions#1265

lostmsu merged 17 commits intopythonnet:masterfromslide:normalize_exceptions
Dec 21, 2020

Conversation

slide
Copy link
Contributor

Seehttps://docs.python.org/3/c-api/exceptions.html#c.PyErr_NormalizeException

What does this implement/fix? Explain your changes.

This fixes cases where some exceptions are "unnormalized" (seehttps://docs.python.org/3/c-api/exceptions.html#c.PyErr_NormalizeException). Calling PyErr_NormalizeException will normalize the exception so that any calls to the traceback module functions correctly.

Does this close any currently open issues?

#1190

Checklist

Check all those that are applicable and complete.

  • Make sure to include one or more tests for your change
  • Add yourself toAUTHORS
  • Updated theCHANGELOG

@lostmsu
Copy link
Member

@slide tbh, I think it would be better to be fixed by checking if__cause__ attribute exists or available via some other means.

I am not sure if thePyErr_NormalizeException always does the right thing. I have two issues with it:

  1. What if the exception class has__init__ method, that performs something totally not expected when a value is passed to it? For example, tries to doint(val), and the exception value happens to be something, that causes that to raise another exception?
  2. If we doPyErr_NormalizeException, and completely discard the original values, subsequentPythonException.Restore would not return the error state to be exactly the same as beforePythonException.

@slide
Copy link
ContributorAuthor

This function is called in PyErr_Print, which is why I thought it would be safe. Would you rather the call be moved to the Format method itself?

@lostmsu
Copy link
Member

lostmsu commentedOct 15, 2020
edited
Loading

Can you clarify on behavior ofPyErr_NormalizeException in regards to reference counts? Does it decref objects passed to it? Do the objects it returns have their refcount > 0? For example, if it can under some circumstances decref the objects passed to it, then you have to ensure to incref them, otherwise pointers inPythonException will become invalid.

A test for scenario 1 is still required (e.g. when exception class has__init__ that throws an exception of its own). If that throws inFormat, what should we do in that case?

@codecov-io
Copy link

codecov-io commentedOct 15, 2020
edited
Loading

Codecov Report

Merging#1265 (04c8b66) intomaster (c81c3c3) willnot change coverage.
The diff coverage isn/a.

Impacted file tree graph

@@           Coverage Diff           @@##           master    #1265   +/-   ##=======================================  Coverage   87.97%   87.97%           =======================================  Files           1        1             Lines         291      291           =======================================  Hits          256      256             Misses         35       35
FlagCoverage Δ
setup_linux65.29% <ø> (ø)
setup_windows74.22% <ø> (ø)

Flags with carried forward coverage won't be shown.Click here to find out more.


Continue to review full report at Codecov.

Legend -Click here to learn more
Δ = absolute <relative> (impact),ø = not affected,? = missing data
Powered byCodecov. Last updatec81c3c3...04c8b66. Read thecomment docs.

@slide
Copy link
ContributorAuthor

The reference count stuff is something I tend to struggle with in regards to C# vs. Python stuff. :-) From looking at the source it looks like things would only be DECREF'd in case of an error or if the value is updated to be the correct value (https://github.com/python/cpython/blob/98c4433a81a4cd88c7438adbee1f2aa486188ca3/Python/errors.c#L353 andhttps://github.com/python/cpython/blob/98c4433a81a4cd88c7438adbee1f2aa486188ca3/Python/errors.c#L336).

In the case of an error, it looks like PyErr_NormalizeException will chain the new exception and try and normalize it.https://github.com/python/cpython/blob/98c4433a81a4cd88c7438adbee1f2aa486188ca3/Python/errors.c#L366. So, it seems like case 1 is covered internally in the normalization process. I can add something though just to make sure.

@lostmsu
Copy link
Member

lostmsu commentedOct 16, 2020
edited
Loading

From my reading the code you linked, it looks like you need to incref pointersbefore sending them to_PyErr_NormalizeException, and thenafter the function you will own whatever is returned, so no need to incref after.

For example, they decrefvaluehere, and then replace it withfixed_value, which is a new reference from_PyErr_CreateException.

@slide
Copy link
ContributorAuthor

I have NOT abandoned this PR, just had some work stuff come up. I will revisit for item 1 above shortly.

lostmsu reacted with thumbs up emoji

@slide
Copy link
ContributorAuthor

I ran the same code on C Python 3.7.7 interpreter and got this, so the behavior matches:

Python 3.7.7 (tags/v3.7.7:d7c567b08f, Mar 10 2020, 10:41:24) [MSC v.1900 64 bit (AMD64)] on win32Type "help", "copyright", "credits" or "license" for more information.>>> class TestException(NameError):...     def __init__(self, val):...             super().__init__(val)...             x = int(val)...>>> raise TestException('foo')Traceback (most recent call last):  File "<stdin>", line 1, in <module>  File "<stdin>", line 4, in __init__ValueError: invalid literal for int() with base 10: 'foo'

@lostmsu
Copy link
Member

@slide I don't think the new test with__init__ actually uses normalization. What you need is to doPyErr_NormalizeException(TestException, "hello", null).

@slide
Copy link
ContributorAuthor

You're absolutely right, I was thinking of something else, this makes complete sense.

@slide
Copy link
ContributorAuthor

closing and reopening to get a new build

@slideslide closed thisDec 21, 2020
@slideslide reopened thisDec 21, 2020
@lostmsulostmsu merged commita0d1a3d intopythonnet:masterDec 21, 2020
@slide
Copy link
ContributorAuthor

Thanks!

@slideslide deleted the normalize_exceptions branchDecember 21, 2020 21:05
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@lostmsulostmsulostmsu approved these changes

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

Successfully merging this pull request may close these issues.

4 participants
@slide@lostmsu@codecov-io@filmor

[8]ページ先頭

©2009-2025 Movatter.jp