Home > other >  What does a "with" statement do without the "as"?
What does a "with" statement do without the "as"?

Time:06-10

with dpg.window(label="Window"):
    dpg.add_text("Hello, world")
    dpg.add_button(label="Save")
    dpg.add_input_text(label="string", default_value="Quick brown fox")
    dpg.add_slider_float(label="float", default_value=0.273, max_value=1)
    dpg.add_color_picker(label="Pick", default_value=(0, 0, 0))

This code runs without error (given the correct imports and setup)

dpg.window(label="Window")
dpg.add_text("Hello, world")
dpg.add_button(label="Save")
dpg.add_input_text(label="string", default_value="Quick brown fox")
dpg.add_slider_float(label="float", default_value=0.273, max_value=1)
dpg.add_color_picker(label="Pick", default_value=(0, 0, 0))

This code does not. A runtime error occurs on line 2. I do not understand how a with statement with no as affects the contents of the with. I've seen another similar post, but I can't understand how the explanation answers my question.

Here is the stacktrace for the error:

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\18328\PycharmProjects\sandbox\main.py", line 10, in <module>
    dpg.add_text("Hello, world")
  File "C:\Users\18328\AppData\Local\Programs\Python\Python39\lib\site-packages\dearpygui\dearpygui.py", line 7019, in add_text
    return internal_dpg.add_text(default_value, label=label, user_data=user_data, use_internal_label=use_internal_label, tag=tag, indent=indent, parent=parent, before=before, source=source, payload_type=payload_type, drag_callback=drag_callback, drop_callback=drop_callback, show=show, pos=pos, filter_key=filter_key, tracked=tracked, track_offset=track_offset, wrap=wrap, bullet=bullet, color=color, show_label=show_label, **kwargs)
SystemError: <built-in function add_text> returned a result with an error set

CodePudding user response:

On the Python side: Context managers run completely arbitrary code on enter and exit. Python doesn't force that code to do things "behind your back", but neither does it present them from doing so; so the implementation of the specific context manager at hand needs to be inspected to know why it's modifying behavior.

From a DearPyGui perspective: The C library that dpg backends into maintains a "container stack". Entering a container as a context manager ensures that it's on the top of your stack. When you create a new DearPyGui object that needs to be attached to a container, it refers to that stack, and attaches itself to the thing that is currently on top.

CodePudding user response:

Using the translation provided by PEP-343, you can see that

with dpg.window(label="Window"):
    ...

is equivalent to

mgr = dpg.window(label="Window")
exit = type(mgr.__exit__)
value = type(mgr).__enter__(mgr)
exc = True
try:
    try:
        ...
    except:
        exc = False
        if not exit(mgr, *sys.exc_info()):
            raise
finally:
    if exc:
        exit(mgr, None, None, None)

You can compare the above to the fuller translation in PEP-343 to see the single line I omitted that results from the use of as.


In your examples, dpg.window(label="Window").__enter__ is called in the first example, but not in the second.

  • Related