[Python-ideas] With expressions

Abe Dillon abedillon at gmail.com
Fri Aug 3 19:57:40 EDT 2018


[Benedikt Werner]

> As the with-expression mimics the with-statement I would say this is
> similar to:
> with supress(AttributeError):
>     tmp = person.name[0]
> initial = tmp # Error on assignment wouldn't get suppressed. Not relevant
> for this case but still.


Ah, yes. That makes much more sense now. I would say the error on
assignment IS relevant for that case and it's not clear to me how you would
present that error to the user without causing a lot of confusion.

If it were implemented as:

tmp = None
with suppress(AttributeError):
    tmp = person.name[0]
initial = tmp

Then it would solve many of the common use cases for the None-aware
operators proposed in PEP 505, especially if we made it easy to filter out
None-specific errors:

class NoneError(BaseException):
    pass

class NoneAttributeError(AttributeError, NoneError):
    pass

... code to make erroneous attribute access on NoneType objects throw
NoneAttributeErrors ...
... shouldn't break much code other than maybe some doc-string tests ...

initial = person.name[0] with suppress(NoneError)

[Robert Vanden Eynde]

> With implementation details? The highest value is there, the alg is
> clear., one fetches the filename, one preprocess the lines, then parse the
> data.


Yes. Sorry for using confusing language. I was trying to say that I like
your proposed syntax (for both with and except) because it follows the same
principal. At the same time, I was trying to demonstrate part of the value
of expression-ized statements to everyone else. Since Python is strictly
evaluated statement by statement, there is no notion of looking ahead and
re-ordering code. You can't use a variable in one statement then define
that variable later on (like you do in comprehensions). Expressions, on the
other hand; are parsed in a more complex way, so you can do things like put
the relevant logic up front and move all the book-keeping to the end.

[Robert Vanden Eynde]

> About if elif elif else, ternary if does have that:
> y = (x+1 if x < 0 else
>      x-1 if x > 0 else
>      0)


True, and your except syntax could chain in a similar manner. In-fact it
might be possible to make a separate "finally" operator that executes the
left side then executes the right side no matter what:

y = ((x[0] except InxexError: x.default) except AttributeError: None)
finally print("hello!")

[Robert Vanden Eynde]

> Limiting the scope is interesting, for "with" the only limitation in that
> the body must have exactly one assignment, like in the ternary if case?
> a = ([l.strip() for l in f.readlines()] with open ('name') as f)
> By cutting the edge cases, "with something():" is not possible, only "with
> ... as" being possible?


I think it's better to forget what I said about limiting the scope of the
operator. It was a half-baked thought.

As for assignment expressions, they're already on their way thanks to PEP
572. I like the "where" version you proposed because it places the logic
first, but unfortunately PEP 572 (4th alternate spelling
<https://www.python.org/dev/peps/pep-0572/#alternative-spellings>) states
that they had considered that version and rejected it because "where" is a
pretty common variable name. From the PEP:

SQLAlchemy and numpy have where methods, as does tkinter.dnd.Icon in the
> standard library


So adding a new "where" keyword would break backwards compatibility in a
major way.

On Fri, Aug 3, 2018 at 5:40 PM, Benedikt Werner <1benediktwerner at gmail.com>
wrote:

> For instance, what would the following do?
>
> initial = person.name[0] with suppress(AttributeError)  # Hangover from
> PEP 505 discussion...
>
> As the with-expression mimics the with-statement I would say this is
> similar to:
>
> with supress(AttributeError):
>     tmp = person.name[0]
> initial = tmp			# Error on assignment wouldn't get suppressed. Not relevant for this case but still.
>
> I don't understand where this is ambigous?
>
> So maybe it only makes sense to use expression assignment (PEP 572):
>
> data = (d := file.read() with open(...) as file)
>
> To which I say, "Eww..."
>
> I definitely agree that this looks a bit bad but I don't get why you would
> consider using an expression assignment there.
>
> data = file.read with open(...) as file
>
> works perfectly fine so why would you want to additonaly assign it to
> another variable "d"?
>
>
> Overall I like the idea of the with-expression as it allows you to make
> some common use cases like the open/read example more readable. It's clear
> at first sight that what is actually done is reading the file. While it's
> true that it's usually easy to write a simple function to do the job that
> still isn't as simple to understand and in most cases when reading the code
> you then have to look at the function to see if anything else is done
> there. Also what if you then do readlines somewhere? Then you need another
> function.
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20180803/048fba49/attachment.html>


More information about the Python-ideas mailing list