Can the following __future__
statements be removed from source code, without affecting its functionality if I am using python 3.7.1?
from __future__ import nested_scopes
from __future__ import generators
from __future__ import division
from __future__ import absolute_import
from __future__ import with_statement
from __future__ import print_function
from __future__ import unicode_literals
__future__ module is a built-in module in Python that is used to inherit new features that will be available in the new Python versions.. This module includes all the latest functions which were not present in the previous version in Python. And we can use this by importing the __future__ module.
The from __future__ import division directive forces the use of Python 3.0 style division.
from __future__ import absolute_import means that if you import string , Python will always look for a top-level string module, rather than current_package.string . However, it does not affect the logic Python uses to decide what file is the string module.
This is documented in the lib/python3.7/__future__.py
file. Each future import (here called _Feature
) is given two 5-tuples, specifying optional and mandatory releases, respectively. Here, "mandatory release" means which version of Python includes the feature by default. As you can see by following the link above, all mandatory versions are < 3.7.1 except two, namely barry_as_FLUFL
(mandatory in version 3.9.0) and annotations
(mandatory in version 4.0.0), the first of which is just an Easter egg.
All future imports on your list can then indeed be removed if using Python 3.7.1 or newer, with the exact same code execution guaranteed. As others have commented, this might not be a good idea though, as this reduces code compatibility.
You could remove those __future__
imports without impacting functionality, but removing them is not necessary and stops compatibility with earlier python versions.
Moreover, as @deceze alludes to in his comment, other imports may be different. For example, from __future__ import annotations
is only enabled in Python <= 4.0 via the import, so adding/removing that line would impact the functionality:
Since this change breaks compatibility, the new behavior needs to be enabled on a per-module basis in Python 3.7 using a
__future__
import:
from __future__ import annotations
It will become the default in Python 4.0.
As @jmd_dk points out, you can actually find this information in the __future__
module. I wrote a short script to extract it:
import __future__
import ast
import sys
print('Python version:', sys.version_info)
sys_t = sys.version_info[:3]
s = '__future__ import {} {} for you; the version: {} vs. your version: {}'
for name in __future__.all_feature_names:
optional, mandatory, _ = ast.literal_eval(str(getattr(__future__, name)).lstrip('_Featur'))
optional, mandatory = optional[:3], mandatory[:3]
print('\nName: {}'.format(name))
tmp = [None, None, optional, sys_t]
if optional <= sys_t:
tmp[:2] = 'is', 'included'
else:
tmp[:2] = 'not', 'included'
print(s.format(*tmp))
tmp[2] = mandatory
if mandatory <= sys_t:
tmp[:2] = 'is', 'fixed'
else:
tmp[:2] = 'not', 'fixed'
print(s.format(*tmp))
On my system this outputs:
Python version: sys.version_info(major=3, minor=7, micro=1, releaselevel='final', serial=0)
Name: nested_scopes
__future__ import is included for you; the version: (2, 1, 0) vs. your version: (3, 7, 1)
__future__ import is fixed for you; the version: (2, 2, 0) vs. your version: (3, 7, 1)
Name: generators
__future__ import is included for you; the version: (2, 2, 0) vs. your version: (3, 7, 1)
__future__ import is fixed for you; the version: (2, 3, 0) vs. your version: (3, 7, 1)
Name: division
__future__ import is included for you; the version: (2, 2, 0) vs. your version: (3, 7, 1)
__future__ import is fixed for you; the version: (3, 0, 0) vs. your version: (3, 7, 1)
Name: absolute_import
__future__ import is included for you; the version: (2, 5, 0) vs. your version: (3, 7, 1)
__future__ import is fixed for you; the version: (3, 0, 0) vs. your version: (3, 7, 1)
Name: with_statement
__future__ import is included for you; the version: (2, 5, 0) vs. your version: (3, 7, 1)
__future__ import is fixed for you; the version: (2, 6, 0) vs. your version: (3, 7, 1)
Name: print_function
__future__ import is included for you; the version: (2, 6, 0) vs. your version: (3, 7, 1)
__future__ import is fixed for you; the version: (3, 0, 0) vs. your version: (3, 7, 1)
Name: unicode_literals
__future__ import is included for you; the version: (2, 6, 0) vs. your version: (3, 7, 1)
__future__ import is fixed for you; the version: (3, 0, 0) vs. your version: (3, 7, 1)
Name: barry_as_FLUFL
__future__ import is included for you; the version: (3, 1, 0) vs. your version: (3, 7, 1)
__future__ import not fixed for you; the version: (3, 9, 0) vs. your version: (3, 7, 1)
Name: generator_stop
__future__ import is included for you; the version: (3, 5, 0) vs. your version: (3, 7, 1)
__future__ import is fixed for you; the version: (3, 7, 0) vs. your version: (3, 7, 1)
Name: annotations
__future__ import is included for you; the version: (3, 7, 0) vs. your version: (3, 7, 1)
__future__ import not fixed for you; the version: (4, 0, 0) vs. your version: (3, 7, 1)
When Python >= 3.8 introduces __future__
imports (there are none yet as I write this), removing these and running on Python 3.7 obviously would impact the functionality.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With