Question

More specifically, can I detect if a function is called as EXPR in with EXPR: BLOCK statement? I am trying to make myself familiar with the usage of with-statement in python. As a first step, I re-implemented an example, which generate marked up text, appeared in the reference of contextlib.contextmanager (ignoring exception handling for now).

class Markup(object):
    def __init__(self):
        self.tags = []
        self.append = self.tags.append
        self.pop = self.tags.pop

    def tag(self, name):
        self.append(name)
        return self

    def __enter__(self):
        print('<{}>'.format(self.tags[-1]))

    def __exit__(self, exc_type, exc_value, traceback):
        print('</{}>'.format(self.pop()))

>>> m = Markup()
>>> with m.tag('ELEMENT'):
...     print('sample text')
...
<ELEMENT>
sample text
</ELEMENT>

This works as expected. Then, I got to think if tag() can also generate empty elements:

>>> m = Markup()

# if a function appears as EXPR of "with EXPR: BLOCK", 'ELEMENT' is a container element. .
>>> with m.tag('ELEMENT'):
...     print('sample text')
...
<ELEMENT>
sample text
</ELEMENT> 

# in other cases, ELEMENT is an empty element.
>>> m.tag('ELEMENT')
<ELEMENT/>

To my naive eyes, it seems doable if callee can detect if it is called from with-statement or not. However, I do not know if this detection is possible or not. Is there such a way and, if there is, how?

Was it helpful?

Solution

You're not actually calling tag() "from" the with statement. You're calling tag(), then passing the return value from tag() to the with statement, which then calls __enter__ on that passed-in value, then runs the body, then calls __exit__.

So no, you can't detect the with statement before it's actually invoked (which is after tag() is called).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top