I want to create a class that makes use of requests.Session(). Because of this, I want to use a context manager. However, when I try to access any of the functions or variables of the class, the context manager replies:
exception type: <class 'AttributeError'>
exception value: type object 'NoneType' has no attribute 'user'
exception trace: <traceback object at 0x0000024CFAF30340>
My code:
Class request_session:
def __init__(self, user="rwelch"):
self.user = user
self.session = (
requests.Session()
)
def __enter__(self):
print("Creating a new connection...")
def __exit__(self, exception_type, exception_val, trace):
print("Closing connection...")
if exception_type:
print(
"exception type: ",
exception_type,
"\nexception value: ",
exception_val,
"\nexception trace: ",
trace,
)
response = True
else:
response = False
self.session.close()
return response
...
with request_session() as request_session_handler:
print(request_session_handler.user)
This type of implementation I got from examples using exclusively file management, so I'm sure there's something fundamental I'm missing here.
Thanks in advance
you should return
the value of the session handler, otherwise it'll return None
implicitly, leading to the error you see
>>> def test():
... """ implicitly returns None """
... pass # does nothing
...
>>> test().user
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'user'
alternatively, you can often avoid creating a custom context manager and decorate a function with @contextlib.contextmanager
and yield
from it
class Foo:
def __enter__(self):
self.managed_resource = bar()
return self.managed_resource
def __exit__(self):
self.managed_resource.close()
@contextlib.contextmanager
def my_contextmgr():
resource = bar()
try:
yield resource
finally:
resource.close()