rspec/rules/S5650/python/rule.adoc

71 lines
1.6 KiB
Plaintext
Raw Normal View History

2021-04-28 16:49:39 +02:00
The https://docs.python.org/3/reference/compound_stmts.html#the-with-statement[``++with++`` statement] should only be used with https://docs.python.org/3/reference/datamodel.html#context-managers[context managers]. A context manager should have an ``++__enter__++`` and an ``++__exit__++`` method.
Note that only ``++async with++`` statements should be used on https://docs.python.org/3/reference/datamodel.html#async-context-managers[asynchronous context managers].
This rule raises an issue when a ``++with++`` statement is used on something else than a context manager.
2021-04-28 16:49:39 +02:00
== Noncompliant Code Example
----
from contextlib import contextmanager, asynccontextmanager
def generator():
yield 42
with generator() as e: # Noncompliant
print(e)
class Empty:
pass
with Empty(): # Noncompliant
pass
@asynccontextmanager
async def async_context_manager():
yield 42
with async_context_manager() as context: # Noncompliant Missing "async"
print(context)
----
2021-04-28 16:49:39 +02:00
== Compliant Solution
----
from contextlib import contextmanager, asynccontextmanager
@contextmanager
def simple_contextmanager():
print("enter")
yield
print("exit")
with simple_contextmanager() as e:
print(e)
class SimpleContextManager:
def __enter__(self):
print("enter")
def __exit__(self, type_, value, traceback):
print("exit")
with SimpleContextManager():
pass
@asynccontextmanager
async def async_context_manager():
yield 42
async def call_async_context_manager():
async with async_context_manager() as context:
print(context)
asyncio.run(call_async_context_manager())
----