Python 3 operator >> to print to file - python

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?

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.

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.

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)

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.

Related

Python 3.10.6: Syntax error and Name error when calling a user defined function

I'm using Python IDLE Shell 3.10.6, and this happens:
def math(x,y):
return x*y
math(1,2)
SyntaxError: invalid syntax
math(1,2)
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
math(1,2)
NameError: name 'math' is not defined
Is this because Python 3.10.6 has a different syntax? I've tried the same thing in Jupyter notebook and it worked perfectly.
Can anyone help me out please? Thank you in advance!
This hasn't got anything to do with Python syntax, but quirks of the IDLE interactive shell.
In the interactive shell, you'll want to separate the definition of the function and the call into separate entries with an ENTER press, i.e. not so it reads
>>> def math(x,y):
return x*y
math(1,2)
SyntaxError: invalid syntax
(as it's attempting to parse the function to contain a trailing, unindented line)
but instead so it reads
>>> def math(x,y):
return x*y
>>> math(1, 2)
2

I'm trying to use imapgrab to imap gmail, but I can't because of the following error. imapgrab error DEBUG_000 [duplicate]

When I try to use a print statement in Python, it gives me this error:
>>> print "Hello, World!"
File "<stdin>", line 1
print "Hello, World!"
^
SyntaxError: Missing parentheses in call to 'print'
What does that mean?
This error message means that you are attempting to use Python 3 to follow an example or run a program that uses the Python 2 print statement:
print "Hello, World!"
The statement above does not work in Python 3. In Python 3 you need to add parentheses around the value to be printed:
print("Hello, World!")
“SyntaxError: Missing parentheses in call to 'print'” is a new error message that was added in Python 3.4.2 primarily to help users that are trying to follow a Python 2 tutorial while running Python 3.
In Python 3, printing values changed from being a distinct statement to being an ordinary function call, so it now needs parentheses:
>>> print("Hello, World!")
Hello, World!
In earlier versions of Python 3, the interpreter just reports a generic syntax error, without providing any useful hints as to what might be going wrong:
>>> print "Hello, World!"
File "<stdin>", line 1
print "Hello, World!"
^
SyntaxError: invalid syntax
As for why print became an ordinary function in Python 3, that didn't relate to the basic form of the statement, but rather to how you did more complicated things like printing multiple items to stderr with a trailing space rather than ending the line.
In Python 2:
>>> import sys
>>> print >> sys.stderr, 1, 2, 3,; print >> sys.stderr, 4, 5, 6
1 2 3 4 5 6
In Python 3:
>>> import sys
>>> print(1, 2, 3, file=sys.stderr, end=" "); print(4, 5, 6, file=sys.stderr)
1 2 3 4 5 6
Starting with the Python 3.6.3 release in September 2017, some error messages related to the Python 2.x print syntax have been updated to recommend their Python 3.x counterparts:
>>> print "Hello!"
File "<stdin>", line 1
print "Hello!"
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print("Hello!")?
Since the "Missing parentheses in call to print" case is a compile time syntax error and hence has access to the raw source code, it's able to include the full text on the rest of the line in the suggested replacement. However, it doesn't currently try to work out the appropriate quotes to place around that expression (that's not impossible, just sufficiently complicated that it hasn't been done).
The TypeError raised for the right shift operator has also been customised:
>>> 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>)"?
Since this error is raised when the code runs, rather than when it is compiled, it doesn't have access to the raw source code, and hence uses meta-variables (<message> and <output_stream>) in the suggested replacement expression instead of whatever the user actually typed. Unlike the syntax error case, it's straightforward to place quotes around the Python expression in the custom right shift error message.
Unfortunately, the old xkcd comic isn't completely up to date anymore.
Since Python 3.0 you have to write:
print("Hello, World!")
And someone has still to write that antigravity library :(
There is a change in syntax from Python 2 to Python 3.
In Python 2,
print "Hello, World!"
will work but in Python 3, use parentheses as
print("Hello, World!")
This is equivalent syntax to Scala and near to Java.
Basically, since Python 3.x you need to use print with parenthesis.
Python 2.x: print "Lord of the Rings"
Python 3.x: print("Lord of the Rings")
Explanation
print was a statement in 2.x, but it's a function in 3.x. Now, there are a number of good reasons for this.
With function format of Python 3.x, more flexibility comes when printing multiple items with comma separated.
You can't use argument splatting with a statement. In 3.x if you have a list of items that you want to print with a separator, you can do this:
>>> items = ['foo', 'bar', 'baz']
>>> print(*items, sep='+')
foo+bar+baz
You can't override a statement. If you want to change the behavior of print, you can do that when it's a function but not when it's a statement.
If your code should work in both Python 2 and 3, you can achieve this by loading this at the beginning of your program:
from __future__ import print_function # If code has to work in Python 2 and 3!
Then you can print in the Python 3 way:
print("python")
If you want to print something without creating a new line - you can do this:
for number in range(0, 10):
print(number, end=', ')
In Python 3, you can only print as:
print("STRING")
But in Python 2, the parentheses are not necessary.
I could also just add that I knew everything about the syntax change between Python2.7 and Python3, and my code was correctly written as print("string") and even
print(f"string")...
But after some time of debugging I realized that my bash script was calling python like:
python file_name.py
which had the effect of calling my python script by default using python2.7 which gave the error. So I changed my bash script to:
python3 file_name.py
which of coarse uses python3 to run the script which fixed the error.
print('Hello, World!')
You're using python 3, where you need brackets when printing.
Outside of the direct answers here, one should note the other key difference between python 2 and 3. The official python wiki goes into almost all of the major differences and focuses on when you should use either of the versions. This blog post also does a fine job of explaining the current python universe and the somehow unsolved puzzle of moving to python 3.
As far as I can tell, you are beginning to learn the python language. You should consider the aforementioned articles before you continue down the python 3 route. Not only will you have to change some of your syntax, you will also need to think about which packages will be available to you (an advantage of python 2) and potential optimizations that could be made in your code (an advantage of python 3).
So I was getting this error
from trp import BoundingBox, Document
File "C:\Users\Kshitij Agarwal\AppData\Roaming\Python\Python39\site-packages\trp\__init__.py", line 31
print ip
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(ip)?
This is a Python package error, in which Python2 has been used and you are probably running this on Python3.
One solution could be to convert Python2 print something to Python3 print(something) for every line in each file in the package folder, which is not a good idea😅. I mean, you can do it but still there are better ways.
To perform the same task, there is a package named 2to3 in Python which converts Python2 scripts to Python3 scripts. To install it, execute the 👇 command in terminal..
pip install 2to3
Then change the directory in terminal to the location where the package files are present, in my case - C:\Users\Kshitij Agarwal\AppData\Roaming\Python\Python39\site-packages\trp
Now execute the command 👇
2to3 . -w
and voila, all the Python2 files in that directory will be converted to Python3.
Note:- The above commands hold true for other operating systems as well. Only Python package path will vary as per the system.
print "text" is not the way of printing text in python as this won't work
print("text") will print said text on your screen in the command line

Can't redirect standard input to Python script

I want to redirect a file as standard input to my Python script but I get some errors as soon as it tries to collect the input. A simple MWE would be:
A script like this:
T = int(input())
for i in range(T):
stack = input()
And a command like this in the Window's cmd:
script.py > someOut.out < someIn.in
And my input file is going to have contents like:
[Int]
[String]
[String]
...
It gets the number of tests right but as soon as it spots a string, it always throws some exception. For example, for a file like:
1
kdjddhs
I get NameError: name 'kdjddhs' is not defined. At the same time, file:
1
+-=
throws:
File "<string>", line 1
+-=
^
SyntaxError: unexpected EOF while parsing
Why is that so? When I start the script through the interpreter, everything works fine. How can I handle input in such a way so that I can redirect standard input through command line as opposed to handling the actual text file through the script itself?
You are using wrong interpreter on the SheBang. I have tested the following code with both python version 2 and 3 (Note the shebang specifies the version):
#!/usr/bin/env python3
import sys
print(sys.version)
T = int(input())
for i in range(T):
stack = input()
print(stack)
Now, on python 2 nothing works. Both using the interpreter python2 ./test.py < data.in and invoking the file directly results in error:
Data:
1
stack-123
Output:
2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2]
Traceback (most recent call last):
File "./test.py", line 9, in <module>
stack = input()
File "<string>", line 1, in <module>
NameError: name 'stack' is not defined
Using python3 both python3 ./test.py < data.in and ./test.py < ./data.in work as expected. Changing the shebang to #!/usr/bin/env python which does not specify the interpreter, the system's default python is used which in your case is python 2.x and results in error
I cannot really tell you why python 2 does not work - it seems it tries to evaluate stack-123 as a variable called "stack" and drops the -123 part... I will do some research on this and update the answer if I figure it out, but using the correct shebang will solve your problem.
Update: As #GurgenHovhannisyan says (+1 from me), which I completely forgot, in python2 you have to use raw_input() instead to achieve the same behavior. If you want this to work in both versions, define and use the following function:
def myInput():
try:
# this will fail in python 3
return raw_input()
except:
return input()
Hope it helps
First of all it doesn't matter through the interpreter or not . The python version here makes sense.
If you work with Python version 2., above mentioned input will work. If you are in Python 3., will not.
Because input() function works in different way depending of Python version
Python version 2:
input() - read input and evaluates
raw_input() - read input as a raw string
Python version 3:
input() - works as raw_input() in 2
raw_input() - there is not this function
So simple change your input to raw_input if you are in Python 2.
This should work the same for Python 2.x and Python 3.x:
from __future__ import print_function
import sys
stdin_reader = None
# python version check determines our choice of input function
try:
if (sys.version_info > (3, 0)):
stdin_reader = input
else:
stdin_reader = raw_input
# Yes yes, I know - don't catch all exceptions
# but here we want to quit if anything fails regardless of the error.
except:
print("Failed to determine Python version")
def echo_stdin():
""" Reads stdin and prints it back in upper case """
r = stdin_reader()
print(r.upper())
echo_stdin()
Output:
$ python3 echo_stdin.py < data_stdin
SOME INPUT LALALA
$ python echo_stdin.py < data_stdin
SOME INPUT LALALA

Can't read from tempfile in Python

I am trying to use some temporary files in an little python script and running into problems while using the tempfile-module:
test-code
import tempfile
with tempfile.NamedTemporaryFile() as temp:
print temp.name
temp.write('Some data')
print temp.seek(0).read()
output
s$ python tmpFileTester.py
/var/folders/cp/8kmr4fhs4l94y8fdc6g_84lw0000gn/T/tmpcDgrzF
Traceback
(most recent call last): File "tmpFileTester.py", line 5, in
print temp.seek(0).read() AttributeError: 'NoneType' object has no attribute 'read'
--> This happens on my MacBook with MacOS 10.9 and Python 2.7.5, it also happens with "delete=False".
Any ideas? It's probably a noob-error, but I can't find the problem...
Whenever you are chaining methods in Python and you get this, you can bet that one of them returns None (even if implicitly by not returning at all). The solution is generally to split up the chain over multiple lines.
temp.seek(0)
print temp.read()
file.seek returns None.
You should separated following statement:
print temp.seek(0).read()
into two statements:
temp.seek(0)
print temp.read()

Python: Use of Input() method for debug

My application (C#/WPF) creates Python code for users who are not programmers - they have a selection of drag & drop items and so they create a sequence that the app translates to Python.
That being said, they'd like to add debug capabilities - the option to inject inputs into their sequence during execution (for example, change myVar's value from 1 to 2). From what I understand, I should be able to translate that into Python's input(). I've been trying to understand how it works and got the following error(using PythonWin):
>>> a = 1
>>> input('--:)')
--:)>>> a=2
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
File "<string>", line 1
a=2
^
SyntaxError: invalid syntax
What am I doing wrong?
(Also, some tutorial for debugging capabilities in Python - including input() will be appreciated.)
Edit
We're working with Python 2.6.6. No need for IronPython - it's executed in Python environment.
According to python documentation, input() method is equivalent to eval(raw_input(prompt)) and eval() can be used to evaluate expressions only.
So for example this code is valid:
>>> a=1
>>> input('--:)')
--:) a+1
2
but a=2 is a statement so you have to use exec() method to execute it, here is an example:
>>> exec(raw_input())
a=2
>>> a
2

Categories

Resources