-
Notifications
You must be signed in to change notification settings - Fork 4k
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
THRIFT-4002: Make generated exception classes immutable by default #1835
Conversation
return ttype->annotations_.find("python.immutable") != ttype->annotations_.end(); | ||
std::map<std::string, std::string>::iterator it = ttype->annotations_.find("python.immutable"); | ||
|
||
if (it == ttype->annotations_.end()) { |
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'm confused as to how ttype->annotations_ would get populated with the correct data. Below in DebugProtoTest.thrift containing MutableException, it says (python.immutable = "false"). Wouldn't that populate ttype->annotations with an entry where the key is "python.immutable" and the value is "false"? The code here assumes if an entry is found then it is immutable and does not check the value.
Also if someone is going to set an attribute like "python.immutable" to false, that would mean the default without an attribute means it is immutable. That is what the code does here. So wouldn't it be better to look for an attribute of "python.mutable" = and if it is there, it is not immutable?
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.
The code here assumes if an entry is found then it is immutable and does not check the value.
But it does: else if (it->second == "false")
Also if someone is going to set an attribute like "python.immutable" to false, that would mean the default without an attribute means it is immutable.
Only for exceptions.
So wouldn't it be better to look for an attribute of "python.mutable"
Those annotations are already "boolean" flags, so I see no benefit of adding a reverse spelling as opposed to setting a boolean to "false"
This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions. |
This is still important to me. Is there anything that I can help with to move this along? |
This issue is no longer stale. Thank you for your contributions. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions. |
This is still important to me. Is there anything that I can help with to move this along? |
This issue is no longer stale. Thank you for your contributions. |
LGTM, but I don't personally use the Python library, so I'll leave this open for comments from other maintainers for 24 hours before merging. @elprans can you please rebase from master? |
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.
Reverted due to failing tests https://travis-ci.org/apache/thrift/builds/623369529
@elprans One of these failures is very easy to fix:
The other is a little more complex because it depends on the mutability of the exceptions. So, does anyone know if this test is accurate in what it tests? I ask because it appears that the two tests (here and here) are the ones modifying the exception, not any underlying Thrift code. @dcelasun do you know anything about this?
|
Unfortunately no, I'm not really familiar with the Python library. Judging by But first I need confirmation from someone familiar with the code. |
@bufferoverflow It appears that you and @cpiro may have originally written these tests. Would either of you happen to know why this test modifies an exception? Or, perhaps shed light on what is being tested here (maybe we don't even need theses tests anymore)? |
As you've guessed, I ripped off that test code (and large chunks of the rest of - x = Xception()
- x.errorCode = 1001
- x.message = s
- raise x
+ raise Xception(1001, s) The original |
@cjbarth I'm very sorry, no clue. |
4934e56
to
fa7f74e
Compare
Thank you @elprans for pushing those changes. That seems to correct the previous problems. Now there appears to be a problem with the CI build itself. It says it can't open a file that clearly exists. @dcelasun Would you happen to know what might cause this sort of error, given that the file exists and wasn't modified by this PR?
|
Appveyor builds for thrift are highly unstable and we don't really block merges if they fail. Since Travis is green, I'll merge this shortly. |
In Python 3.11 exceptions generated by the compiler can't be used with a context manager because they are immutable. As of Python 3.11 `contextlib.contextmanager` sets `exc.__stacktrace__` in the event that the code in the context manager errors. As of Thrift v0.18.1 exceptions are generated as immutable by default. See [PR#1835](apache#1835) for more information about why exceptions were made immutable by default. This change adds a compiler flag, `py:immutible_exc` that generates all exceptions as mutable so they can be used with a context manager. When the flag is used with the `python.immutable = "true"` annotation, the exception is treated as immutable. I tested this change by generating the tutorial and comparing the outputs with and without the new flag. I also copied [tutorial.thrift](tutorial/tutorial.thrift) and added the `python.immutable` annotation to ensure that the annotation always overrides the flag. Where do I go to update documentation?
In Python 3.11 exceptions generated by the compiler can't be used with a context manager because they are immutable. As of Python 3.11 `contextlib.contextmanager` sets `exc.__stacktrace__` in the event that the code in the context manager errors. As of Thrift v0.18.1 exceptions are generated as immutable by default. See [PR#1835](apache#1835) for more information about why exceptions were made immutable by default. This change adds a compiler flag, `py:immutible_exc` that generates all exceptions as mutable so they can be used with a context manager. When the flag is used with the `python.immutable = "true"` annotation, the exception is treated as immutable. I tested this change by generating the tutorial and comparing the outputs with and without the new flag. I also copied [tutorial.thrift](tutorial/tutorial.thrift) and added the `python.immutable` annotation to ensure that the annotation always overrides the flag. Where do I go to update documentation?
In Python 3.11 exceptions generated by the compiler can't be used with a context manager because they are immutable. As of Python 3.11 `contextlib.contextmanager` sets `exc.__stacktrace__` in the event that the code in the context manager errors. As of Thrift v0.18.1 exceptions are generated as immutable by default. See [PR#1835](apache#1835) for more information about why exceptions were made immutable by default. This change makes it so only fields listed in `__dict__` or `__slots__` are considerd immutable. Other fields are considred writable. I added a test that ensure that a client raising an exception can be used in a context manager.
In Python 3.11 exceptions generated by the compiler can't be used with a context manager because they are immutable. As of Python 3.11 `contextlib.contextmanager` sets `exc.__stacktrace__` in the event that the code in the context manager errors. As of Thrift v0.18.1 exceptions are generated as immutable by default. See [PR#1835](apache#1835) for more information about why exceptions were made immutable by default. This change adds a compiler flag, `py:immutible_exc` that generates all exceptions as mutable so they can be used with a context manager. When the flag is used with the `python.immutable = "true"` annotation, the exception is treated as immutable. I tested this change by generating the tutorial and comparing the outputs with and without the new flag. I also copied [tutorial.thrift](tutorial/tutorial.thrift) and added the `python.immutable` annotation to ensure that the annotation always overrides the flag. Where do I go to update documentation?
In Python 3.11 exceptions generated by the compiler can't be used with a context manager because they are immutable. As of Python 3.11 `contextlib.contextmanager` sets `exc.__traceback__` in the event that the code in the context manager errors. As of Thrift v0.18.1 exceptions are generated as immutable by default. See [PR#1835](apache#1835) for more information about why exceptions were made immutable by default. This change makes all non-Thrift fields mutable when slots is used. This will allow exceptions to be re-raised properly by the contextmanager in Python 3.11.
In Python 3.11 exceptions generated by the compiler can't be used with a context manager because they are immutable. As of Python 3.11 `contextlib.contextmanager` sets `exc.__traceback__` in the event that the code in the context manager errors. As of Thrift v0.18.1 exceptions are generated as immutable by default. See [PR#1835](apache#1835) for more information about why exceptions were made immutable by default. This change makes all non-Thrift fields mutable when slots is used without dynamic. This will allow exceptions to be re-raised properly by the contextmanager in Python 3.11.
In Python 3.11 exceptions generated by the compiler can't be used with a context manager because they are immutable. As of Python 3.11 `contextlib.contextmanager` sets `exc.__traceback__` in the event that the code in the context manager errors. As of Thrift v0.18.1 exceptions are generated as immutable by default. See [PR#1835](apache#1835) for more information about why exceptions were made immutable by default. This change makes all non-Thrift fields mutable when slots is used without dynamic. This will allow exceptions to be re-raised properly by the contextmanager in Python 3.11.
In Python 3.11 exceptions generated by the compiler can't be used with a context manager because they are immutable. As of Python 3.11 `contextlib.contextmanager` sets `exc.__traceback__` in the event that the code in the context manager errors. As of Thrift v0.18.1 exceptions are generated as immutable by default. See [PR#1835](#1835) for more information about why exceptions were made immutable by default. This change makes all non-Thrift fields mutable when slots is used without dynamic. This will allow exceptions to be re-raised properly by the contextmanager in Python 3.11.
Currently, the generated exception classes are not hashable under Python 3
because of the generated
__eq__
method. Exception objects are generallyexpected to be hashable by the Python standard library. Post-construction
mutation of an exception object seems like a very unlikely case, so enable
hashing for all exceptions by making them immutable by default. This also
adds a way to opt-out of immutability by setting the
python.immutable
annotation to
"false"
.