[Python-Dev] PEP 408 -- Standard library __preview__ package

Steven D'Aprano steve at pearwood.info
Mon Feb 6 01:33:58 CET 2012


Paul Moore wrote:
> On 4 February 2012 11:25, Steven D'Aprano <steve at pearwood.info> wrote:
>> It strikes me that it would be helpful sometimes to programmatically
>> recognise "preview" modules in the std lib. Could we have a recommendation
>> in PEP 8 that such modules should have a global variable called PREVIEW, and
>> non-preview modules should not, so that the recommended way of telling them
>> apart is with hasattr(module, "PREVIEW")?
> 
> In what situation would you want that when you weren't referring to a
> specific module? If you're referring to a specific module and you
> really care, just check sys.version. (That's annoying and ugly enough
> that it'd probably make you thing about why you are doing it - I
> cannot honestly think of a case where I'd actually want to check in
> code if a module is a preview - hence my question as to what your use
> case is).

What's the use-case for any sort of introspection functionality? I would say 
that the ability to perform introspection is valuable in and of itself, 
regardless of any other concrete benefits.

We expect that modules may change APIs between the preview and non-preview 
("stable") releases. I can see value in (say) being forewarned of API changes 
from the interactive interpreter, without having to troll through 
documentation looking for changes, or waiting for an exception. Or having to 
remember exactly which version modules were added in, and when they left 
preview. (Will this *always* be one release later? I doubt it.)

If you don't believe that preview modules will change APIs, or that it would 
be useful to detect this programmatically when using such a module, then 
there's probably nothing I can say to convince you otherwise. But I think it 
will be useful. Python itself has a sys.version so you can detect feature sets 
and changes in semantics; this is just the same thing, only milder.

The one obvious way[1] is to explicitly tag modules as preview, and the 
simplest way to do this is with an attribute. (Non-preview modules shouldn't 
have the attribute at all -- non-preview is the default state, averaged over 
the entire lifetime of a module in the standard library.)

It would be just nice to sit down at the interactive interpreter and see 
whether a module you just imported was preview or not, without having to look 
it up in the docs. I do nearly everything at the interpreter: I read docs 
using help(), I check where modules are located using module.__file__. This is 
just more of the same.

Some alternatives:

1) Don't try to detect whether it is a preview module, but use EAFP to detect 
features that have changed:

try:
     result = spam.foo(x, y)
except AttributeError:
     # Must be a preview release. Do something else.
     result = spam.bar(y, x)

This is preferred so long as the differences between preview and stable 
releases are big, obvious changes like a function being renamed. But if there 
are subtle changes that you care about, things get dicey. spam.foo may not 
raise an exception, but just do something completely unexpected.



2) As you suggest, write version-specific code:

if sys.version >= "3.4":
     result = spam.foo(x, y)
else:
     # Preview release.
     result = spam.bar(y, x)


This starts to get messy fast, particularly if (worst case, and I *really* 
hope this doesn't happen!) modules get put into preview, then get withdrawn, 
then a few releases later get put back in. This sort of mess shouldn't ever 
happen with non-preview modules, but preview modules explicitly have weaker 
guarantees.

And I can never remember when modules were added to the std lib.



> Feels like YAGNI to me.

When people talk about YAGNI, they are referring to the principle that you 
shouldn't waste time and effort over-engineering a complex solution or 
providing significant additional functionality for no obvious gain. I don't 
think that

     PREVIEW = True

in a module *quite* counts as over-engineered.


[1] Disclaimer: I am not Dutch.


-- 
Steven



More information about the Python-Dev mailing list