[Python-Dev] PEP 550 v4

Yury Selivanov yselivanov.ml at gmail.com
Thu Sep 7 02:57:34 EDT 2017


On Wed, Sep 6, 2017 at 11:39 PM, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> Yury Selivanov wrote:
>>
>> It would be great if you or Greg could show a couple of real-world
>> examples showing the "issue" (with the current PEP 550
>> APIs/semantics).
>
>
> Here's one way that refactoring could trip you up.
> Start with this:
>
>    async def foo():
>       calculate_something()
>       #in a coroutine, so we can be lazy and not use a cm

Where exactly does PEP 550 encourage users to be "lazy and not use a
cm"?  PEP 550 provides a mechanism for implementing context managers!
What is this example supposed to show?

>       ctx = decimal.getcontext().copy()
>       ctx.prec = 5
>       decimal.setcontext(ctx)
>       calculate_something_else()
>
> And factor part of it out (into an *ordinary* function!)
>
>    async def foo():
>       calculate_something()
>       calculate_something_else_with_5_digits()
>
>    def calculate_something_else_with_5_digits():
>       ctx = decimal.getcontext().copy()
>       ctx.prec = 5
>       decimal.setcontext(ctx)
>       calculate_something_else()
>
> Now we add some more calculation to the end of foo():
>
>    async def foo():
>       calculate_something()
>       calculate_something_else_with_5_digits()
>       calculate_more_stuff()
>
> Here we didn't intend calculate_more_stuff() to be done
> with prec=5, but we forgot that calculate_something_else_
> with_5_digits() changes the precision and *doesn't restore
> it* because we didn't add a context manager to it.
>
> If we hadn't been lazy and had used a context manager in the
> first place, that wouldn't have happened.

How is PEP 550 is at fault of somebody being lazy and not using a
context manager?

PEP 550 has a hard requirement to make it possible for decimal/other
libraries to start using its APIs and stay backwards compatible, so it
allows `decimal.setcontext(ctx)` function to be implemented.  We are
fixing things here.

When you are designing a new library/API, you can use CMs and only
CMs.  It's up to you, as a library author, PEP 550 does not limit you.

And when you use CMs, there's no "problems" with 'yield from' or
anything in PEP 550.

>
> Summary: I think that skipping context managers in some
> circumstances is a bad habit that shouldn't be encouraged.

PEP 550 does not encourage coding without context managers.  It does,
in fact, solve the problem of reliably storing context to make writing
context managers possible.

To reiterate: it provides mechanism to set a variable within the
current logical thread, like storing a current request in an async
HTTP handler. Or to implement `decimal.setcontext`.  But you are free
to use it to only implement context managers in your library.

Yury


More information about the Python-Dev mailing list