No, "with" statements does not create a new scope.
The "With" statement is a resource developed by the Python Dev team to generalize a common (and heavily recommended) practice of closing opened resources even after an exception ocurred. Imagine the following situation:
try:
f = open('file.txt', 'w')
#Do some processing that can raise exceptions and leave 'f' open, eventually locking the file or having trash data loaded into RAM.
#To avoid this situation, a mindful developer will do the following:
finally:
f.close()
It gets verbose easily.
To solve the problem, python dev team proposed the use of some dunder methods which encapsule this process: __enter__() and __exit__() - these are invoked "under the hood" when you use a "with" statement.
You can even implement them in your own classes!
class controlled_execution:
def __enter__(self):
set things up
return thing
def __exit__(self, type, value, traceback):
tear things down
with controlled_execution() as thing:
some code
In the end, a with statement, even though there's identation, is not a separate block of code. It is just an ellegant try...finaly block. It abstracts a "contained" piece of code.
This can be easily comprehended by looking at a try...except statement with variables declared inside the try:
x = 10
try:
y = load_using_failable_function()
z = 5
except FunctionFailureException:
y = 10
#If you treat it properly, there's nothing wrong with doing:
x = x + y + z
I hope it is clear to anyone else looking for this reason.
Consulted websites:
https://www.geeksforgeeks.org/with-statement-in-python/
https://effbot.org/zone/python-with-statement.htm