RedFox
RedFox

Reputation: 141

"AttributeError: 'NoneType' object has no attribute 'test'" using context manager

I have this class:

class Tess:
    def __init__(self, **kwargs):
        self.kwargs = kwargs

    def __enter__(self):
        print('fire away!')
        for key, value in self.kwargs.items():
            print(f"{key} and {value}")

    def __exit__(self):
        print('the end.')

    def test(self, **kwargs):        # This takes in a different dict independent of __init__
        # Also tried self.kwargs = kwargs here but doesn't change anything
        for key, value in self.kwargs.items():
            print(f"The end of {key} and {value}")
        

Then I used it within the context-manager.

with Tess(foo='bar') as t:
    t.test(foo_bar='baz')

I expected the output to be:

fire away!
foo and bar
The end of foo_bar and baz
the end.

It instead gives:

Traceback (most recent call last):
  File "/...", line 145, in <module>
    t.test(foo_bar='baz')
AttributeError: 'dict' object has no attribute 'test'

How do I rectify this? Thanks.

Upvotes: 1

Views: 1051

Answers (1)

S.B
S.B

Reputation: 16526

Check this :

class Tess:
    def __init__(self, **kwargs):
        self.kwargs = kwargs

    def __enter__(self):
        print('fire away!')
        for key, value in self.kwargs.items():
            print(f"{key} and {value}")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('the end')

    def test(self, **kwargs):  # This takes in a different dict independent of __init__
        # Also tried self.kwargs = kwargs here but doesn't change anything
        for key, value in self.kwargs.items():
            print(f"The end of {key} and {value}")


with Tess(foo='bar') as t:
    t.test(foo_bar='baz')

output :

fire away!
foo and bar
The end of foo and bar
the end

I made two changes :

1- In order to access t in as t statement, you should put return self in your __enter__. t is going to be whatever you return from __enter__

2- Python passes exc_type, exc_val, exc_tb (type, value, traceback) to __exit__ method, so you should change your signature to accept those parameters.

Upvotes: 2

Related Questions