33

I have the following Python code to write dependency files of a project. It works fine with Python 2.x, but while testing it with Python 3 it reports an error.

depend = None
if not nmake:
    depend = open(".depend", "a")
dependmak = open(".depend.mak", "a")
depend = open(".depend", "a")
print >>depend, s,

Here is the error:

Traceback (most recent call last):
  File "../../../../config/makedepend.py", line 121, in <module>
    print >>depend, s,
    TypeError: unsupported operand type(s) for >>:
      'builtin_function_or_method' and '_io.TextIOWrapper'

What is the best way to get this working with Python 2.x and 3.x?

Martin Thoma
  • 124,992
  • 159
  • 614
  • 958
José
  • 3,041
  • 8
  • 37
  • 58
  • "with python2.x and 3.x"? You cannot have the same code in both versions. Usually, you use the `2to3` tool to convert working Python 2 into Python 3. – S.Lott Feb 10 '12 at 23:31
  • 3
    You can use `from __future__ import print_function` to get the Python 3 print() function into Python 2. See also http://python3porting.com – Lennart Regebro Feb 11 '12 at 19:22

4 Answers4

47

In Python 3 the print statement has become a function. The new syntax looks like this:

print(s, end="", file=depend)

This breaking change in Python 3 means that it is not possible to use the same code in Python 2 and 3 when writing to a file using the print statement/function. One possible option would be to use depend.write(s) instead of print.

Update: J.F. Sebastian correctly points out that you can use from __future__ import print_function in your Python 2 code to enable the Python 3 syntax. That would be an excellent way to use the same code across different Python versions.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 3
    you could use `from __future__ import print_function` to use `print()` function in Python 2.x. btw, `end=""` is not the same as comma in a `print` statement. Compare [`print'a',;print'b'`](http://ideone.com/ogwCh) and [`print('a',end=''); print('b')`](http://ideone.com/py5k7) (note: no space between `a` and `b` in the latter case). ` – jfs Feb 11 '12 at 04:09
12

print() is a function in Python 3.

Change your code to print(s, end="", file=depend), or let the 2to3 tool do it for you.

Amber
  • 507,862
  • 82
  • 626
  • 550
3

Note that starting in Python 3.6.3 (September 2017), the error message for this case will be changing to recommend the Python 3 spelling:

>>> print >> sys.stderr
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for >>:
    'builtin_function_or_method' and '_io.TextIOWrapper'.
    Did you mean "print(<message>, file=<output_stream>)"?

(Explicit line breaks added to avoid side-scrolling - the actual error message just wraps at the width of your terminal window)

ncoghlan
  • 40,168
  • 10
  • 71
  • 80
0

I can propose at least two ways.

1 - if-else way with eval() trick (works with stdout as well as with a file).

import sys
def println(s, f=sys.stdout):
    if sys.version_info[0] < 3:
        print >>f, s
    else:
        func = eval('print')
        func(s, end='\n', file=f)

f = open('file.txt', 'a')
println('msg') # print to stdout
println('msg', f) # print to file
f.close()

2 - Use write() instead of print().

f = open('file.txt', 'a')
f.write("%s\n" % 'msg')
f.close()

Tested both scripts on Python 2.7.17 and 3.6.9.

Alexander Samoylov
  • 2,358
  • 2
  • 25
  • 28