How can I tell what pragmas from '__future__' have been enabled at runtime in a Python program?

Viewed 61

When I enable an interpreter feature in Python 2 with a from __future__ import X statement (e.g. from __future__ import unicode_literals), the interpreter behavior changes from there on out.

Is there a way, at runtime, to determine what __future__ pragmas have been enabled at a given point in execution?

The reason I want to do this is that some legacy code I maintain conditionally enables some __future__ pragmas before evaling/runtime-importing other arbitrary code. When debugging behavior issues in that code, I want to check whether it's because some of those conditional __future__ imports have been triggered or not. I know that conditionally importing __future__ (or importing it at anything other than the top of an entry point) is an antipattern and have no plans of spreading it; I just want to debug code that does this.

I've tried checking sys.modules, and using that I can tell that something from __future__ has been imported because the __future__ module shows up in the already-imported list. However, that's just the __future__ module, and the interpreter-behavior changes are not implemented as submodules, so I can't see which have been enabled or not.

1 Answers

You can just look at the top of the file, because __future__ imports are defined there, they can't be anywhere else.

Also the interpreter is not changed globally as you imply. The __future__ changes are only for the modules that have the actual __future__ import in them. So if you have two .py files in your project, and only one of them has the from __future__ import unicode_literals, then only that file will have unicode literals. The other file will still have normal literals.

The test below has been executed in python 2.7:

file1.py:

from __future__ import unicode_literals
x = 'This is unicode'

file2.py

y = 'This is NOT unicode'

Testing:

>>> import file1
>>> import file2
>>> file1.x, type(file1.x)
(u'This is unicode', <type 'unicode'>)
>>> file2.y, type(file2.y)
('This is NOT unicode', <type 'str'>)

That means the features are stored per module and not globally. You can check the module object for the feature attribute:

>>> file1.unicode_literals
_Feature((2, 6, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 131072)
>>> file2.unicode_literals
AttributeError: 'module' object has no attribute 'unicode_literals'
Related