What Is _Future_ in Python Used for and How/When to Use It, and How It Works

What is __future__ in Python used for and how/when to use it, and how it works

With __future__ module's inclusion, you can slowly be accustomed to incompatible changes or to such ones introducing new keywords.

E.g., for using context managers, you had to do from __future__ import with_statement in 2.5, as the with keyword was new and shouldn't be used as variable names any longer. In order to use with as a Python keyword in Python 2.5 or older, you will need to use the import from above.

Another example is

from __future__ import division
print 8/7 # prints 1.1428571428571428
print 8//7 # prints 1

Without the __future__ stuff, both print statements would print 1.

The internal difference is that without that import, / is mapped to the __div__() method, while with it, __truediv__() is used. (In any case, // calls __floordiv__().)

Apropos print: print becomes a function in 3.x, losing its special property as a keyword. So it is the other way round.

>>> print

>>> from __future__ import print_function
>>> print
<built-in function print>
>>>

How does the __future__ module work in Python 2.7?

The __future__ module was introduced in Python 2.1 in order to have access to upcoming features/functions which will lead to incompatibilities with the current implementation and is extended with each version if needed.

So the module gives the possibility to use those incompatible functions of future versions in earlier versions. So you can make use of the upcoming advantages of those functions.

There are three main reasons for that module as stated in the docs:

__future__ is a real module, and serves three purposes:

  • To avoid confusing existing tools that analyze import statements and
    expect to find the modules they’re importing.
  • To ensure that future
    statements run under releases prior to 2.1 at least yield runtime
    exceptions (the import of __future__ will fail, because there was no
    module of that name prior to 2.1).
  • To document when incompatible
    changes were introduced, and when they will be — or were — made
    mandatory. This is a form of executable documentation, and can be
    inspected programmatically via importing __future__ and examining its
    contents.

Why does using from __future__ import print_function breaks Python2-style print?

First of all, from __future__ import print_function needs to be the first line of code in your script (aside from some exceptions mentioned below). Second of all, as other answers have said, you have to use print as a function now. That's the whole point of from __future__ import print_function; to bring the print function from Python 3 into Python 2.6+.

from __future__ import print_function

import sys, os, time

for x in range(0,10):
print(x, sep=' ', end='') # No need for sep here, but okay :)
time.sleep(1)

__future__ statements need to be near the top of the file because they change fundamental things about the language, and so the compiler needs to know about them from the beginning. From the documentation:

A future statement is recognized and treated specially at compile
time: Changes to the semantics of core constructs are often
implemented by generating different code. It may even be the case that
a new feature introduces new incompatible syntax (such as a new
reserved word), in which case the compiler may need to parse the
module differently. Such decisions cannot be pushed off until runtime.

The documentation also mentions that the only things that can precede a __future__ statement are the module docstring, comments, blank lines, and other future statements.

What is __future__ in Python used for and how/when to use it, and how it works

With __future__ module's inclusion, you can slowly be accustomed to incompatible changes or to such ones introducing new keywords.

E.g., for using context managers, you had to do from __future__ import with_statement in 2.5, as the with keyword was new and shouldn't be used as variable names any longer. In order to use with as a Python keyword in Python 2.5 or older, you will need to use the import from above.

Another example is

from __future__ import division
print 8/7 # prints 1.1428571428571428
print 8//7 # prints 1

Without the __future__ stuff, both print statements would print 1.

The internal difference is that without that import, / is mapped to the __div__() method, while with it, __truediv__() is used. (In any case, // calls __floordiv__().)

Apropos print: print becomes a function in 3.x, losing its special property as a keyword. So it is the other way round.

>>> print

>>> from __future__ import print_function
>>> print
<built-in function print>
>>>

How does __future__ statements know the syntax of new python versions?

from __future__ import ... is just an overly cute way of saying a feature is available now, but you have to opt in. In the future, it will be the default or required.

Each defined import comes with two pieces of information: the version in which the feature is made optionally available, and the version in which the feature will become mandatory. No feature is ever removed from the __future__ module.

As of Python 3.8, there are nine features available in __future__. All but one, annotations, are mandatory. New code that will never need to run in older versions of Python don't need to import them. Older code that uses them don't need to be updated, even though the imports are effectively no-ops. annotations will remain an optional feature until Python 4.0 is released; there's no date for that, but it is guaranteed that annotations will be part of that release, and not a mandatory part of any earlier release.

Is it preferable to use __future__ or future to write code compatible with python2 and python3?

The __future__ module is built-in to Python, and is provided to allow programmers to make advance use of feature sets which are not yet regarded as complete. Although some of the features (e.g., from __future__ import print_function) are provided specifically to assist with porting Python 2 programs to Python 3, it is also used to give early access to advance features of any release.

__future__ is unique, in that some imports such as the print_function can actually change the syntax accepted by the interpreter.

python-future is a third-party module, one of several to provide compatibility features. You could also take a look at six, though it's now somewhat long in the tooth, and python-modernize. It's quite likely you will find that you need to use both __future__ and future together.

Another strategy you may not have considered is to convert your source to Python 2 that can be translated automatically by the 2to3 utility. There is also a lib3to2 that will translate the other way, though I have no experience with it.

How __future__ imports work under the hood

from __future__ import print_function tells the parser to not treat print as a keyword (leaving it as a name instead). That way the compiler treats it as the function and not a statement.

To track this, the compiler struct has a c_future field that holds a PyFutureFeatures object that tracks which future directives have been enabled. Various parts of the parser and compiler check the flags and alter behaviour.

This is mostly handled in the future.c source file, which has a future_parse() function that checks for import from AST objects with the module parameter set to __future__, and sets flags based on what is found.

For example, for the barry_as_FLUFL 'feature', the parser refuses != as syntax but accepts <> instead:

if (type == NOTEQUAL) {
if (!(ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) &&
strcmp(str, "!=")) {
PyObject_FREE(str);
err_ret->error = E_SYNTAX;
break;
}
else if ((ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) &&
strcmp(str, "<>")) {
PyObject_FREE(str);
err_ret->text = "with Barry as BDFL, use '<>' "
"instead of '!='";
err_ret->error = E_SYNTAX;
break;
}
}

You can find the other examples by grepping for the FUTURE_* flags listed in compile.h.

Note that there is a __future__ Python module, but it is not directly involved in the parsing and compilation of code; it is merely there to give Python code easy access to metadata about directives (including bitfield values to pass to the flags argument of the compile() function), nothing more.

Is there any reason to use from __future__ import print_function in code that's fully Python 3 compatible?

The answer comes down to your audience. If there is a need to run this code in python2, you should leave them. But, if you're content with removing python2 support, go ahead and clean em up.

All the more reason to do so now sooner than later.
https://www.python.org/doc/sunset-python-2/

Call not recognised and use instead Future

You can just call self.on_response directly:

response = yield client.fetch('https://books.toscrape.com')
self.on_response(response)

Additional notes:

Make your life easier by ditching @gen.coroutine and yield and switching to async/await:

async def get(self):
#arg = self.get_argument('stock')
client = tornado.httpclient.AsyncHTTPClient()
response = await client.fetch('https://books.toscrape.com')
self.on_response(response)


Related Topics



Leave a reply



Submit