I have a question about how the context manager fo...
# questions
m
I have a question about how the context manager for the
kedroSession
works. Specifically I would have expected that something like the code snippet below fails because the session object is already closed when I call it, but it seems to work nevertheless. Why is that? And what is the point of using a context manager if the session object persists outside of the
with
statement?
Copy code
bootstrap_project(Path("<project_root>"))
with KedroSession.create() as session:
    pass
session.run()
l
Hey @Mirko, if I understand correctly this is because of the way Python itself handles references in memory. Python’s garbage collector automatically destroys objects when they’re no longer referenced. Until that happens, the object persists. Because the
close()
method in the
KedroSession
class does not explicitly destroy the session object, you can still access it while there are still references to it. You can try the same thing with a similar operation like:
Copy code
with open("example.txt") as f:
    pass
print(type(f))
You can still check the type of
f
after
with
resolves because it still being referenced, so it still exists. You cannot read the contents of the file outside of the
with
block, if you try you'll get a
Error: I/O operation on closed file.
, but
f
itself still exists. Another example, if you have a little class like this and run it:
Copy code
class TestClass:
    def __init__(self, name):
        self.name = name

    def __enter__(self):
        print(f"Hello, my name is {self.name}!")
        return self.name

    def __exit__(self, exc_type, exc_value, traceback):
        print(f"Goodbye, {self.name}!")

with TestClass("Laura") as test:
    print(f"Inside the with block: {test}")
print(f"Outside the with block: {test}")
You will get the following output:
Copy code
Hello, my name is Laura!
Inside the with block: Laura
Goodbye, Laura!
Outside the with block: Laura
m
Thanks @Laura Couto for the detailed reply. So what actually happens in the
kedroSession.__exit__
method? I am trying to understand what it means for a session to be closed and whether it is bad practice to use the session or its attributes outside of the with block? For example, I have code which uses the kedro context like this
Copy code
bootstrap_project(Path("<project_root>"))
with KedroSession.create() as session:
    context = session.load_context()
# Do something with context outside of the with block
Is this pattern OK or is it not recommended? When I first wrote that piece of code I thought that it would be similar to doing something like the code snippet below, but now I'm not sure anymore.
Copy code
import json
with open("some_file.json", "r") as fp:
    json_data = json.load(fp)
# Do something with json_data outside the with block
l
It is generally safer to work everything inside the
with
block if an object comes from a context manager. But on the specific case of the
KedroSession
object, what the exit method does is just to call
close()
to save the store to disk if the option is set to True and log exceptions if there are any, so it shouldn't give you too much trouble.
Copy code
def close(self) -> None:
        """Close the current session and save its store to disk
        if save_on_close attribute is True.
        """
        if self.save_on_close:
            self._store.save()
...

def exit(self, exc_type: Any, excvalue: Any, tb: Any) -> None:
        if exc_type:
            self._log_exception(exc_type, excvalue, tb)
        self.close()
Still, for Python and this specific implementation it's OK, but in general it's a bit of a strange use of the scope.
👍 1
m
Thanks for the explanation.