58 lines
1.9 KiB
Plaintext
58 lines
1.9 KiB
Plaintext
The special method https://docs.python.org/3/reference/datamodel.html?highlight=__exit__%20special#object.__exit__[<code>\_\_exit\_\_</code>] 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 <code>\_\_exit\_\_</code> method can filter passed-in exceptions by simply returning True or False.
|
||
|
||
This rule raises an issue when:
|
||
|
||
* an <code>\_\_exit\_\_</code> method has a bare <code>raise</code> outside of an <code>except</code> block.
|
||
* an <code>\_\_exit\_\_</code> method raises the exception provided as parameter.
|
||
|
||
|
||
== Noncompliant Code Example
|
||
|
||
----
|
||
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
|
||
|
||
----
|
||
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.
|
||
----
|
||
|
||
|
||
== See
|
||
|
||
* Python documentation – https://docs.python.org/3/reference/datamodel.html?highlight=__exit__%20special#object.__exit__[The <code>\_\_exit\_\_</code> special method]
|
||
* PEP 343 – https://www.python.org/dev/peps/pep-0343/[The "with" Statement]
|
||
|