bvz
bvz

Reputation: 879

python: from __future__ import print_function must be in every loaded module?

I'm not a professional programmer, so I have some big holes in my knowledge (just a heads up).

I have written a few libraries in python 3.7. But now I want to access them from a 3D app which uses python 2.7. The only real 3.7 specific features that they have (as far as I can tell at the moment) are configparser (vs. ConfigParser) and the print function.

I am handling the configparser issue by catching an importerror and then loading the 2.7 version instead.

I am trying to handle the print function by adding this line to the top of my script that is running in the 3D application:

from __future__ import print_function

But when I import a module that has a python 3 style print function in it I get a syntax error. If, however, I include the from __future__ statement in the loaded module, everything works. Clearly I am running into the limits of my knowledge here.

Here is the entire code for the module I am importing (called test.py):

import sys

def print_error():
    print("AND THIS IS?", file=sys.stderr)

And here is the code inside the 3D app (running python 2.7) that calls this code:

from __future__ import print_function
import sys
sys.path.append("/home/me/Documents/dev/")
print("WHY IS THIS NOT A SYNTAX ERROR?", file=sys.stderr)
from mylib import test

When I run this code, I get the following output:

WHY IS THIS NOT A SYNTAX ERROR?
00:00:08    Traceback (most recent call last):
00:00:08      File "<string>", line 7, in <module>
00:00:08      File "/home/me/Documents/dev/mylib/test.py", line 4
00:00:08        print("AND THIS IS?", file=sys.stderr)
00:00:08                                  ^
00:00:08    SyntaxError: invalid syntax
00:00:08 

But if I put the from __future__ line in the test.py module, everything runs correctly.

Am I doing something wrong? Or do I need to have this line in each module. And if so, how do I reconcile that with the times I will be calling these libraries from python 3.7 (where I do not want to load the print function from __future__)?

From my research it appears that the from __future__ is a compiler directive which controls how the script is compiled at run time? Maybe? I'm in over my head on this bit. But does that mean each time a module is loaded that the compiler has to be reminded to use from __future__?

Thanks for any and all help!

Upvotes: 1

Views: 7849

Answers (1)

lmiguelvargasf
lmiguelvargasf

Reputation: 69755

In Python 3, print is a function, and in Python 2 it is a keyword, so basically in Python 2, it is not expecting the parameter file.

You will have to add from __future__ import print_function at the top of each module, to disable the statement and use the print() function, use this future statement at the top of your module.

From the docs, __future__ serves 3 purposes:

  1. Avoid confusing existing tools that analyze import statements and to find the modules they’re importing.

  2. Ensure future statements run under releases prior to 2.1 at least yield runtime exceptions.

  3. Document when incompatible changes were introduced, and when they will be — or were — made mandatory.

Upvotes: 5

Related Questions