84 lines
2.3 KiB
Plaintext
84 lines
2.3 KiB
Plaintext
:link-with-uscores1: https://docs.python.org/3/reference/datamodel.html?highlight=__exit__%20special#object.__exit__
|
||
|
||
The special method {link-with-uscores1}[``++__exit__++``] should only raise an exception when it fails. It should never raise the provided exception, it is the caller's responsibility.
|
||
|
||
Raising this exception will make the stack trace difficult to understand.
|
||
|
||
|
||
The ``++__exit__++`` method can filter passed-in exceptions by simply returning True or False.
|
||
|
||
|
||
This rule raises an issue when:
|
||
|
||
* an ``++__exit__++`` method has a bare ``++raise++`` outside of an ``++except++`` block.
|
||
* an ``++__exit__++`` method raises the exception provided as parameter.
|
||
|
||
|
||
== Noncompliant Code Example
|
||
|
||
[source,python]
|
||
----
|
||
class MyContextManager:
|
||
def __enter__(self):
|
||
return self
|
||
def __exit__(self, *args):
|
||
raise # Noncompliant
|
||
raise args[2] # Noncompliant
|
||
|
||
class MyContextManager:
|
||
def __enter__(self):
|
||
return self
|
||
def __exit__(self, exc_type, exc_value, traceback):
|
||
raise exc_value # Noncompliant
|
||
----
|
||
|
||
|
||
== Compliant Solution
|
||
|
||
[source,python]
|
||
----
|
||
class MyContextManager:
|
||
def __enter__(self):
|
||
return self
|
||
def __exit__(self, exc_type, exc_value, traceback):
|
||
# by default the function will return None, which is always False, and the exc_value will naturally raise.
|
||
pass
|
||
|
||
class MyContextManager:
|
||
def __enter__(self, stop_exceptions):
|
||
return self
|
||
def __exit__(self, *args):
|
||
try:
|
||
print("42")
|
||
except:
|
||
print("exception")
|
||
raise # No issue when raising another exception. The __exit__ method can fail and raise an exception
|
||
raise MemoryError("No more memory") # This is ok too.
|
||
----
|
||
|
||
|
||
:link-with-uscores1: https://docs.python.org/3/reference/datamodel.html?highlight=__exit__%20special#object.__exit__
|
||
|
||
== See
|
||
|
||
* Python documentation – {link-with-uscores1}[The ``++__exit__++`` special method]
|
||
* PEP 343 – https://www.python.org/dev/peps/pep-0343/[The "with" Statement]
|
||
|
||
|
||
ifdef::env-github,rspecator-view[]
|
||
|
||
'''
|
||
== Implementation Specification
|
||
(visible only on this page)
|
||
|
||
include::message.adoc[]
|
||
|
||
include::highlighting.adoc[]
|
||
|
||
'''
|
||
== Comments And Links
|
||
(visible only on this page)
|
||
|
||
include::comments-and-links.adoc[]
|
||
endif::env-github,rspecator-view[]
|