Please help 'with' 'as' compound statements

Hi all. I’m on ex37.

https://docs.python.org/3/reference/compound_stmts.html#with

I’m trying to understand compound statement ‘with A as B’

There is example code provided in the docs, but I think I need to see some application of the code for it to start making sense to me.

My (mis-)understanding is that it seems to ‘wrap’ a block of code with two functions. Is that like a decorator? Let me know if I’m totally lost here.

A

Hello.

I have used “with A as B:” in a test code (Pytest) for ex 49.

def test_Parser_Error_msg():
    """test that the error message when a exception is raised is correct"""
    with pytest.raises(ParserError) as excinfo: 
        x = parse_sentence([('noun','princess'),('verbs', 'go'),('direction','away')])
    assert str(excinfo.value) == 'expected a verb next'

As you see on third row it starts as “excinfo”. Then it is resused again on last row as “(excinfo.value)” to get the string I wanted to test.
I hope this will make some sence.

I have no deeper understanding in this.
I am much better in finding examples on google and after a lot of work manage to use in my own code.

I’m trying to understand your application of ‘with’. It looks like you’re using it as a ‘try’ block, and the assert is some kind of ‘except’. ?

Or is it evaluating the exception messages themselves? Under what circumstances would this be helpful? I’m assuming it has something to do with debugging.

Hello.
Yes. The function is from a pytest code I did for parser.py (ex49).
I use Pytest instead of nosetest.
Here is the whole code on Github [https://github.com/ulfsjodin/ex49].
The code I wrote as an example for you is the last function in test_parser.py
I hope it becomes easier to see how one can use this code when you got both files.

As I mentioned. I have not got any deeper knowledge about this.
I just wanted to share one way to use it. Perhaps there are many more.
It worked well for me when testing code with pytest.

That is nice code man

 def test_Parser_Error_msg():
    """test that the error message when a exception is raised is correct"""
    with pytest.raises(ParserError) as excinfo: 
        x = parse_sentence([('noun','princess'),('verbs', 'go'),('direction','away')])
    assert str(excinfo.value) == 'expected a verb next'

So you could use it instead of say:

def sentences():
    pass
    y = parse_sentence([('noun','princess'),('verb','run'),('direction','away')])
return y

Fricken awesome, I just realised why you shared, you did the “Study” and figured out the accept raises usage. definitely three space invaders for that. :space_invader: :space_invader: :space_invader: Love your work

1 Like

Thanks for your feedback.
I supprice my self now and then.
But there is a lot of failures before.
I am working to reduce them before getting a useful code.

The purpose of with is to help with cleaning up resources when there’s an error or when you’re done with them. Let’s say I open a file like this:

myfile = open('stuff.txt')
while True:
    line = myfile.readline()
    dodangerousthing(line)
myfile.close()

Now let’s say dangerousthing() can throw an error that will abort this whole while loop. In this case, the myfile.close() will never happen and, if this code runs frequently enough, you’ll run out of available open files you can have.

Using with you can easily solve this:

with open('stuff.txt') as myfile:
    while True:
        line = myfile.readline()
        dodangerousthing(line)

The with basically says “open this file, then inside the with name the result myfile”. Inside the with-block if everything is good OR bad, the with will make sure the file gets closed. No matter what, that file will close. That means you don’t have to worry about cleaning it up anymore.