[Python-ideas] import features; if "print_function" in features.data

Steven D'Aprano steve at pearwood.info
Sun May 31 01:32:26 CEST 2015


On Sat, May 30, 2015 at 07:54:35AM -0500, Wes Turner wrote:
> Would it be useful to have one Python source file with an OrderedDict of
> (API_feat_lbl, [(start, None)]) mappings
> and a lookup?

Why an OrderedDict?

This already exists for __future__ features:

py> import __future__
py> __future__.all_feature_names
['nested_scopes', 'generators', 'division', 'absolute_import', 
'with_statement', 'print_function', 'unicode_literals', 
'barry_as_FLUFL']



> * [ ] feat/version segments/rays map
> * [ ] .lookup("print[_function]")

I don't know what this means.



> Syntax ideas:
> 
> * has("print[_function]")

Why does it need a new function instead of just this?

    "print" in featureset


> Advantages
> 
> * More pythonic to check for features than capabilities

I think that is wrong. I think that Look Before You Leap is generally 
considered *less* Pythonic.



> * Forward maintainability

Not when it comes to syntax changes. You can't write:

if has("print"):
    print "Hello world"
else:
    print("Hello world")

because *it won't compile* if print_function is in effect.

For non-syntax changes, it's not backwards compatible:

if not has("enumerate takes a start argument"):
    def enumerate(values, start):
        for i, x in builtins.enumerate(values):
            yield i+start, x

doesn't work for anything older than 3.6 (at the earliest). It's better 
to check for the feature directly, which always work:

try:
    enumerate([], 1)
except TypeError:
    ...

> Disadvantages:
> 
> *

* It's ugly, especially for small changes to features, such as when a 
function started to accept an optional argument.

* It requires more work: you have to duplicate the information 
about every feature in at least three places, not just two (the code 
itself, the documentation, plus the "features" database).

* It's hard to use.

* Bootstrapping problem: how do you check for the "has" feature 
itself?

     if has("has"): ... # obviously cannot work

* Doesn't help with writing hybrid 2+3 code, as it doesn't exist in 2.



> Alternatives:
> 
> * six, nine, future
> * try/import ENOENT

I don't understand this.




-- 
Steve


More information about the Python-ideas mailing list