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
>Solution :
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()