[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