0

I'm writing a script that includes printing a 10 second countdown without a newline, and I want it to be compatible with both Python2 and Python3.

This is what I've tried:

for sec in range(10, 0, -1):
    try:
        print(" %d \r" % sec, end="")
    except SyntaxError:
        subprocess.call("printf \" %d \\r\"" % sec, shell=True)

    time.sleep(1)

And I'm getting this error:

    print(" %d \r" % sec, end="")
                             ^
SyntaxError: invalid syntax

It seems to me that SyntaxError should be getting caught.

I've tried researching the topic, and read the documentation on SyntaxError, but can't find anything that suggests why this is happening.

John B
  • 3,566
  • 1
  • 16
  • 20
  • 1
    A syntax error is not an exception that you can catch, it means that the whole program is ill-formed. Now, I guess that you are running Python 2.x, where `print` is not a function that supports keyword arguments. Try upgrading or `from __future__ import printf_function`. – Ulrich Eckhardt Aug 29 '14 at 05:25

2 Answers2

2

As the documentation says:

This may occur in an import statement, in an exec statement, in a call to the built-in function eval() or input(), or when reading the initial script or standard input (also interactively).

The syntax of the entire file is parsed when your program is read, before any of your code is executed. Python can't even begin to run the code if the syntax is invalid. So you can't catch a SyntaxError that occurs inside your module.

For this particular case, there is an alternative, namely from __future__ import print_function.

BrenBarn
  • 242,874
  • 37
  • 412
  • 384
  • Unfortunately, I tried that and it waits until the countdown is complete before printing all the numbers as it would if I did `print(...),` in `python2`. Hence, why I use `subprocess` with `printf`. – John B Aug 29 '14 at 05:27
  • 1
    @JohnB: That is probably a buffering issue. See [this question](http://stackoverflow.com/questions/107705/python-output-buffering). – BrenBarn Aug 29 '14 at 05:36
  • Thanks, you answered the question. However, it seems that the documentation could be clearer. After all, it does say `This may occur...when reading the initial script`. Also, the solution in the question you linked worked for my script. – John B Aug 29 '14 at 05:53
0

This should help you.

from __future__ import print_function

import time;

for sec in range(2):
    print(sec, end='')
    time.sleep(1)
Kannan Mohan
  • 1,810
  • 12
  • 15
  • This waits until the final iteration of the loop to print everything. – John B Aug 29 '14 at 05:33
  • 1
    This seems to be a buffering issue. Using -u as an argument to python interpreter solved the issue. But there is still some inconsistency between 2.x and 3.x. – Kannan Mohan Aug 29 '14 at 06:29