Why does the python interpreter prompt with ... for a comment "#"? - python

In the Python interpreter, if I put in a # for a comment, why does it prompt with ...? I expected a >>> prompt.
e.g.,
>>> # my comment
... x = 4
>>> x
4
>>> # my comment
... foo
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
NameError: name 'foo' is not defined

Here's my educated guess about what is going on; I haven't actually looked at Python's REPL code. As you know, the Python interactive shell uses the ... prompt when it is expecting further input based on having parsed the contents of the preceding line(s).
For example:
>>> if True:
...
... because if ... :<newline> must be followed by an indented block according to the lexical structure of Python.
Notice that you can trigger the same slightly odd behavior with a line that is empty except for whitespace, e.g.:
>>> <space><enter>
...
According to the lexical rules of Python, in most contexts a line that contains only whitespace should not be treated as a pass statement, or an empty block, but it should be handled as if it didn't appear at all. Take this example (with | to emphasize the lack of whitespace at the end of each line):
if False:|
|
print "Foo"|
# comment|
print "Bar"|
|
print "Baz"|
If you run this code, it will print only Baz. The first two print statements are treated as part of the same block despite the fact that there are non-indented empty or comment-only lines before, after, and in the middle of them.
Basically, when the Python interpreter reads a line that is blank or contains only a comment, it pretends it didn't read any line at all. The interactive interpreter basically follows this behavior: it's waiting for input, and if it gets no input, it asks for more input. Hence the ... continued input prompt.
It appears that the case of a totally blank line (line=='' after chopping off the EOL character(s)) is special-cased into the interactive interpreter, but that this special-casing is not extended to lines which contain only comments and/or whitespace.

It is the prompt, just like when you type in def foo () : and press enter, it puts an ellipsis (...) and with some prompts automatically tabs for you. It's just it's way of saying that it is accepting that you are doing something over multiple lines.

Related

Why does command line Python require an empty line separating an "if" statement that follows a "while" statement?

I am running Python3 in terminal, copy/pasting my code line by line. In the follow code chunk example (finds median of two sorted arrays):
nums1=[1,2]
nums2=[3,4]
output_list = []
while(nums1 and nums2):
if nums1[0] <= nums2[0]:
output_list.append(nums1.pop(0))
else:
output_list.append(nums2.pop(0))
if nums1:
output_list.append(nums1.pop(0))
if nums2:
output_list.append(nums2.pop(0))
Upon copy/pasting this into terminal, I get
>>> nums1=[1,2]
>>> nums2=[3,4]
>>> output_list = []
>>> while(nums1 and nums2):
... if nums1[0] <= nums2[0]:
... output_list.append(nums1.pop(0))
... else:
... output_list.append(nums2.pop(0))
... if nums1:
File "<stdin>", line 6
if nums1:
^
SyntaxError: invalid syntax
>>> output_list.append(nums1.pop(0))
File "<stdin>", line 1
output_list.append(nums1.pop(0))
^
IndentationError: unexpected indent
>>> if nums2:
... output_list.append(nums2.pop(0))
This disappears if I have an empty line between the while, and two if statements. Why is this?
According to PEP8: https://www.python.org/dev/peps/pep-0008/#blank-lines
Blank Lines
Separate top-level function and class definitions with two blank lines. Method definitions inside a class are separated by a single blank line.
Extra blank lines may be used (sparingly) to separate groups of related functions. Blank lines may be omitted between a bunch of related one-liners (e.g. a set of dummy implementations).
Use blank lines in functions, sparingly, to indicate logical sections.
Python accepts the control-L (i.e. ^L) form feed character as whitespace; Many tools treat these characters as page separators, so you may use them to separate pages of related sections of your file. Note, some editors and web-based code viewers may not recognize control-L as a form feed and will show another glyph in its place.
A blank line signifies the end of a loop on then interactive window
For more reference: Blank line rule at interactive prompt
This is likely due to the IDE that you're using. I would try to replace the indentation with 4 spaces in terminal, or save the python file to your computer, cd to it's location and run a python3 (put file name ending in .py here) command.

Python unit-test assertions are being joined by newlines

While using unittest.TestCase.run(test_class(test)), the correct errors are being reported but they are being joined by \n.
AssertionError: False is not true : Failures: [], Errors: [(<module1 testMethod=method1>, 'Traceback (most recent call last):\n File "<file_name>", line 20, in method1\n \'resource_partitions\')\n File "error_source_file_path", line 23, in error_function\n error_line_statement\nKeyError: \'gen_data\'\n')]
How can these be removed and replaced with actual newlines instead?
Has it got something to do with line-endings on my machine (currently set to \n)
That is an intended behaviour.
The string is being displayed as a part an object. Such displays always print escape sequences rather to convert them to their specific char.
Look in this short example with string in interpreter:
>>> "spam\neggs"
'spam\neggs'
>>> print("spam\neggs")
spam
eggs
The first one gets displayed because it's an interactive console, in normal code it would never happen. But that's also how string in other object behave.
Printing list containing a string vs printing each element separately:
>>> print(["spam\neggs"])
['spam\neggs']
>>> for element in ["spam\neggs"]: print(element)
...
spam
eggs

How to tell if a single line of python is syntactically valid?

It is very similar to this:
How to tell if a string contains valid Python code
The only difference being instead of the entire program being given altogether, I am interested in a single line of code at a time.
Formally, we say a line of python is "syntactically valid" if there exists any syntactically valid python program that uses that particular line.
For instance, I would like to identify these as syntactically valid lines:
for i in range(10):
x = 1
Because one can use these lines in some syntactically valid python programs.
I would like to identify these lines as syntactically invalid lines:
for j in range(10 in range(10(
x =++-+ 1+-
Because no syntactically correct python programs could ever use these lines
The check does not need to be too strict, it just need to be good enough to filter out obviously bogus statements (like the ones shown above). The line is given as a string, of course.
This uses codeop.compile_command to attempt to compile the code. This is the same logic that the code module does to determine whether to ask for another line or immediately fail with a syntax error.
import codeop
def is_valid_code(line):
try:
codeop.compile_command(line)
except SyntaxError:
return False
else:
return True
It can be used as follows:
>>> is_valid_code('for i in range(10):')
True
>>> is_valid_code('')
True
>>> is_valid_code('x = 1')
True
>>> is_valid_code('for j in range(10 in range(10(')
True
>>> is_valid_code('x = ++-+ 1+-')
False
I'm sure at this point, you're saying "what gives? for j in range(10 in range(10( was supposed to be invalid!" The problem with this line is that 10() is technically syntactically valid, at least according to the Python interpreter. In the REPL, you get this:
>>> 10()
Traceback (most recent call last):
File "<pyshell#22>", line 1, in <module>
10()
TypeError: 'int' object is not callable
Notice how this is a TypeError, not a SyntaxError. ast.parse says it is valid as well, and just treats it as a call with the function being an ast.Num.
These kinds of things can't easily be caught until they actually run.
If some kind of monster managed to modify the value of the cached 10 value (which would technically be possible), you might be able to do 10(). It's still allowed by the syntax.
What about the unbalanced parentheses? This fits the same bill as for i in range(10):. This line is invalid on its own, but may be the first line in a multi-line expression. For example, see the following:
>>> is_valid_code('if x ==')
False
>>> is_valid_code('if (x ==')
True
The second line is True because the expression could continue like this:
if (x ==
3):
print('x is 3!')
and the expression would be complete. In fact, codeop.compile_command distinguishes between these different situations by returning a code object if it's a valid self-contained line, None if the line is expected to continue for a full expression, and throwing a SyntaxError on an invalid line.
However, you can also get into a much more complicated problem than initially stated. For example, consider the line ). If it's the start of the module, or the previous line is {, then it's invalid. However, if the previous line is (1,2,, it's completely valid.
The solution given here will work if you only work forward, and append previous lines as context, which is what the code module does for an interactive session. Creating something that can always accurately identify whether a single line could possibly exist in a Python file without considering surrounding lines is going to be extremely difficult, as the Python grammar interacts with newlines in non-trivial ways. This answer responds with whether a given line could be at the beginning of a module and continue on to the next line without failing.
It would be better to identify what the purpose of recognizing single lines is and solve that problem in a different way than trying to solve this for every case.
I am just suggesting, not sure if going to work... But maybe something with exec and try-except?
code_line += "\n" + ("\t" if code_line[-1] == ":" else "") + "pass"
try:
exec code_line
except SyntaxError:
print "Oops! Wrong syntax..."
except:
print "Syntax all right"
else:
print "Syntax all right"
Simple lines should cause an appropriate answer

Syntax error with exec call in Python

Quick python question about the exec command. I'm have Python 2.7.6 and am trying to make use of the exec to run some code stored in a .txt file. I've run into a syntax error and am not entirely sure what is causing it.
Traceback (most recent call last):
File "/Users/XYZ/Desktop/parser.py", line 46, in <module>
try_code(block)
File "<string>", line 1
x = 'Hello World!'
^
SyntaxError: invalid syntax
I initially thought it was complaining about carriage returns, but when I tried to edit them .replace them with ' ' I still received this error message. I've tried variations to see what appears to be the issue and it always declares the error as the first ' or " the program encounters when it runs exec.
Here is the try_code(block) method
def try_code(block):
exec block
And the main body of the program
inputFile = open('/Users/XYZ/Desktop/test.txt', 'r+')
starter = False
finished = False
check = 1
block = ""
for val in inputFile:
starter = lookForStart(val)
finished = lookForEnd(val)
if lookForStart:
check = 1
elif finished:
try_code(block)
if check == 1:
check = 0
elif finished == False:
block = block + val
Basically I'm trying to import a file (test.txt) and then look for some embedded code in it. To make it easier I surrounded it with indicators, thus starter and finished. Then I concatenate all the hidden code into one string and call try_code on it. Then try_code attempts to execute it (it does make it there, check with print statements) and fails with the Syntax error.
As a note it works fine if I have hidden something like...
x = 5
print x
so whatever the problem is appears to be dealing with strings for some reason.
EDIT
It would appear that textedit includes some extra characters that aren't displayed normally. I rewrote the test file in a different text editor (text wrangler) and it would seem that the characters have disappeared. Thank you all very much for helping me solve my problem, I appreciate it.
It is a character encoding issue. Unless you've explicitly declared character encoding of your Python source code at the top of the file; it is 'ascii' by default on Python 2.
The code that you're trying to execute contains non-ascii quotes:
>>> print b'\xe2\x80\x98Hello World\xe2\x80\x99'.decode('utf-8')
‘Hello World’
To fix it; use ordinary single quotes instead: 'Hello World'.
You can check that block doesn't contain non-ascii characters using decode method: block.decode('ascii') it raises an exception if there are.
A gentle introduction into the topic: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)
by Joel Spolsky.

Comments compared to string in python

I am just new to python.
as i know in python multi-line comments are made like this
"""
this is a comments
"""
but consider this code
somevariable="""this is a variable"""
print somevariable
it prints this is a variable
are comments and strings are same in python or they are different?
The first one isn't a comment, it's a string. But since you're not doing anything with that string (printing it, assigning it to a variable etc.) all the interpreter does is say "Yup, that's a string alright!" and ignore it entirely. Effectively making it the same as a comment, since it's an arbitrary bunch of text that's ignored by the interpreter.
There are no multi-line comments in Python. They're both just strings. The former is typically used as a docstring and will be associated with the function/class/module, while the other gets assigned to a variable.
Yes, they are the same
It is called a docstring
You can find more information about this type of string here:
http://www.pythonforbeginners.com/basics/python-docstrings/
are comments and strings the same in python?
Strictly speaking, they are not the same. But in your question, what you refer to as "a comment" is actually a string. A comment is everything appearing in the same line after the # character.
a.py:
"""
comment1
"""
# comment2
Now:
% strings a.pyc | grep comment
comment1
As you can see, comment2 is not part of the compiled byte code, while comment1 is -- because it's not a comment, it's a string.
As others pointed out, the string is considered a docstring. docstrings are conventionally used for documenting your code, while comments are used, well, for commenting, and are not included in the documentation.
Yes, they are the same. It is a convention to include a comment string as the first statement of the function or a class.
See PEP 257 -- Docstring Conventions.
The first snippet is not a comment. It is a string. Comments in Python are prefixed by the # character.
>>> somevariable="""
... this is not a comment
... """
>>> print(somevariable)
this is not a comment
The confusion comes through docstrings.
This is actually not a comment, but a way to make a string with multiple lines:
>>> """This is a string
... with line breaks"""
'This is a string\nwith line breaks'
The same notation is used in classes and functions to document them:
>>> def my_function():
... """This function does stupid things."""
... return 1/0
...
>>> my_function.__doc__
'This function does stupid things.'
>>> my_function()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in my_function
ZeroDivisionError: division by zero
So your code:
somevariable = """this is a variable"""
is really just equal to:
somevariable = "this is a variable"

Categories