Triple quotation in python - python

So I understand that if I do the following
print """ Anything I
type in here
works. Multiple LINES woohoo!"""
But what if following is my python script
""" This is my python Script. Just this much """
What does the above thing do? Is it taken as comment? Why is it not a syntax error?
Similarly, if I do
"This is my Python Script. Just this. Even with single quotes."
How are the above two scripts interpreted?
Thanks

The triple quotes ''' or """ are just different ways of representing strings. The advantage of triple quotes is that it can span multiple lines and sometimes serve as docstrings.
The reason:
"hadfasdfas"
doesn't raise any error is because python simply creates the string and then doesn't assign it to anything. For the python interpreter, it is perfectly fine if you have a pointless statement in your code as long as there are no syntax or semantics errors
Hope that helps.

The string is just evaluated, and the interpreter noticing it wasn't assigned to anything, throws it away.
But in some special places, this string is actually assigned to the __doc__ property of the item:
def func(arg):
"""
Does stuff. This string will be evaluated and assigned to func.__doc__.
"""
pass
class Test:
"""
Same for Test.__doc__
"""
pass
At the top of module.py:
"""
module does stuff. this will be assigned to module.__doc__
"""
def func():
...

In addition to #sshashank124 answer I have to add that triple quoted strings are also used in testing https://docs.python.org/2/library/doctest.html
So consider this code snippet:
def some_function(x, y):
"""This function should simply return sum of arguments.
It should throw an error if you pass string as argument
>>> some_function(5, 4)
9
>>> some_function(-5, 4)
-1
>>> some_function("abc", 4)
Traceback (most recent call last):
...
ValueError: arguments must numbers
"""
if type(x, str) or type(y, str):
raise ValueError("arguments must numbers")
else:
return x + y
if __name__ == "__main__":
import doctest
doctest.testmod()
If you import this tiny module, you'll get the some_function function.
But if you invoke this script directly from shell, tests given in the triple quoted string will be evaluated and the report will be printed to the output.
So triple quoted strings can be treated as values of type string, as comment, as docstrings and as containers for unittests.

Related

Python doctest how to match single or double quote in output as opposed to only single quote

I commonly use the code auto-formatter Black, which has trained me to use double quotes.
It has become "muscle memory" for me to use double quotes.
The default repr for many classes prints from the Python interactive output with single quotes. I know doctest seeks to reproduce the Python interactive output.
Is there some simple way to have doctest match single or double quotes?
I know one option is to make a custom doctest.OutputChecker. I am wondering if there's a simpler option.
Code Sample
from dataclasses import dataclass
#dataclass
class SomeDataClass:
"""Contains a string."""
data: str
def get_some_dataclass(data: str) -> SomeDataClass:
"""Get a data class containing some specified data.
Returns:
Data class containing the data.
Examples:
>>> get_some_dataclass("hi")
SomeDataClass(data="hi")
"""
return SomeDataClass(data=data)
if __name__ == "__main__":
import doctest
doctest.testmod()
Output:
**********************************************************************
File "quote_or_apostrophe.py", line 23, in __main__.get_some_dataclass
Failed example:
get_some_dataclass("hi")
Expected:
SomeDataClass(data="hi")
Got:
SomeDataClass(data='hi')
**********************************************************************
Versions
I invoke doctest via pytest's doctest integration.
python==3.8.2
pytest==5.4.1
I imagine you could achieve this with blacken-docs but I haven't seen an example of this done yet...
Either the approach of:
Leave the strings in black standard (double quoted) and find a way to transform the expected output doctest so that it has double quotes (by running black on it somehow?)
Run blacken-docs with a single quote setting applied, which also avoids having to think about it yourself
I would instinctively go for the first option because it feels like it solves the problem better, but I expect it is easier to do the latter (and TBH not needing to think about this too much would be a plus).
Upon looking into it though, this doesn't seem supported at present according to this issue, and running blacken-docs on some code which prints a double-quoted __repr__ in a >>> doctest block does not affect said double quoting.
My interpretation of that issue and the other one it links to is that blacken-docs does not support code blocks in the format:
"""
Docstring starts here.
Code example comes next:
>>> from some_module import some_func
>>> some_func(1, 2)
"1+2"
"""
I've tried rewriting code in the suggested format:
"""
Docstring starts here.
Code example comes next:
.. code-block:: python
>>> from some_module import some_func
>>> some_func(1, 2)
"1+2"
"""
but this gives me
code block parse error Cannot parse: 1:0: >>> from some_module import some_func
So I'm not going to use blacken-docs or the more verbose .. code-block: python format, perhaps in time it'll be supported.

TypeError: sequence item 0: expected str instance, int found? [duplicate]

I have some code like:
def example(parameter):
global str
str = str(parameter)
print(str)
example(1)
example(2)
The first call to example works, but then the second time around I get an error like:
Traceback (most recent call last):
File "test.py", line 7, in <module>
example(2)
File "test.py", line 3, in example
str = str(parameter)
TypeError: 'str' object is not callable
Why does this happen, and how can I fix it?
If you are in an interactive session and encountered a problem like this, and you want to fix the problem without restarting the interpreter, see How to restore a builtin that I overwrote by accident?.
Where the code says:
global str
str = str(parameter)
You are redefining what str() means. str is the built-in Python name of the string type, and you don't want to change it.
Use a different name for the local variable, and remove the global statement.
Note that if you used code like this at the Python REPL, then the assignment to the global str will persist until you do something about it. You can restart the interpreter, or del str. The latter works because str is not actually a defined global variable by default - instead, it's normally found in a fallback (the builtins standard library module, which is specially imported at startup and given the global name __builtins__).
While not in your code, another hard-to-spot error is when the % character is missing in an attempt of string formatting:
"foo %s bar %s coffee"("blah","asdf")
but it should be:
"foo %s bar %s coffee"%("blah","asdf")
The missing % would result in the same TypeError: 'str' object is not callable.
In my case I had a class that had a method and a string property of the same name, I was trying to call the method but was getting the string property.
Note that TypeError: 'str' object is not callable means only that there is an attempt to call (i.e., use function-call syntax) a string (i.e., any name that previously had a string assigned to it). Using any other built-in method as variable name can cause the exact same error message.
You can get this error if you have variable str and trying to call str() function.
Whenever that happens, just issue the following ( it was also posted above)
>>> del str
That should fix it.
Another case of this: Messing with the __repr__ function of an object where a format() call fails non-transparently.
In our case, we used a #property decorator on the __repr__ and passed that object to a format(). The #property decorator causes the __repr__ object to be turned into a string, which then results in the str object is not callable error.
Check your input parameters, and make sure you don't have one named type. If so then you will have a clash and get this error.
str = 'Hello World String'
print(str(10)+' Good day!!')
Even I faced this issue with the above code as we are shadowing str() function.
Solution is:
string1 = 'Hello World String'
print(str(10)+' Good day!!')
I had the same error. In my case wasn't because of a variable named str. But because I named a function with a str parameter and the variable the same.
same_name = same_name(var_name: str)
I run it in a loop. The first time it run ok. The second time I got this error. Renaming the variable to a name different from the function name fixed this. So I think it's because Python once associate a function name in a scope, the second time tries to associate the left part (same_name =) as a call to the function and detects that the str parameter is not present, so it's missing, then it throws that error.
This error can also occur as a result of trying to call a property (as though it were a function):
class Example:
#property
def value():
return 'test'
e = Example()
print(e.value()) # should just be `e.value` to get the string
This problem can be caused by code like:
"Foo" ("Bar" if bar else "Baz")
You can concatenate string literals by putting them next to each other, like "Foo" "Bar". However, because of the open parenthesis, the code was interpreted as an attempt to call the string "Foo" as if it were a function.
it could be also you are trying to index in the wrong way:
a = 'apple'
a(3) ===> 'str' object is not callable
a[3] = l
it is recommended not to use str int list etc.. as variable names, even though python will allow it.
this is because it might create such accidents when trying to access reserved keywords that are named the same
This error could also occur with code like:
class Shape:
def __init__(self, colour):
self.colour = colour
def colour(self):
print("colour:", self.colour)
myShape = Shape("pink")
myShape.colour()
In the __init__ method, we assign an attribute colour, which has the same name as the method colour. When we later attempt to call the method, the instance's attribute is looked up instead. myShape.colour is the string "pink", which is not callable.
To fix this, change either the method name or the variable name.
I also got this error.
For me it was just a typo:
I wrote:
driver.find_element_by_id("swal2-content").text()
while it should have been:
driver.find_element_by_id("swal2-content").text
In my case, I had a Class with a method in it. The method did not have 'self' as the first parameter and the error was being thrown when I made a call to the method. Once I added 'self,' to the method's parameter list, it was fine.
FWIW I just hit this on a slightly different use case. I scoured and scoured my code looking for where I might've used a 'str' variable, but could not find it. I started to suspect that maybe one of the modules I imported was the culprit... but alas, it was a missing '%' character in a formatted print statement.
Here's an example:
x=5
y=6
print("x as a string is: %s. y as a string is: %s" (str(x) , str(y)) )
This will result in the output:
TypeError: 'str' object is not callable
The correction is:
x=5
y=6
print("x as a string is: %s. y as a string is: %s" % (str(x) , str(y)) )
Resulting in our expected output:
x as a string is: 5. y as a string is: 6
It also give same error if math library not imported,
import math
I realize this is not a runtime warning, but PyCharm gave me this similarly-worded IDE warning:
if hasattr(w, 'to_json'):
return w.to_json()
# warning, 'str' object is not callable
This was because the IDE assumed w.to_json was a string. The solution was to add a callable() check:
if hasattr(w, 'to_json') and callable(w.to_json):
return w.to_json()
Then the warning went away. This same check may also prevent the runtime exception in the original question.

Why are multiline comments allowed in empty functions but not single comments?

I am using python 2.7
My ide will display indent expected if I write a function like this
def foo():
#
but not if I write this
def foo():
'''
'''
Is there any reason why this happens?
A comment is something that's ignored by the compiler. When you put a comment on the line the compiler basically pretends it doesn't exist. But a multi-line string is a physical element of the code. Python recognizes its presence and makes no complaint.
If you want to write a function that doesn't do anything, at least for the moment, use pass.
def Foo():
#Comment goes here
pass
pass is a keyword that says 'something should go here, but I'm purposefully not putting anything here'.
''' is not actually a comment. It acts like one, but is, in fact, a string delimiter.
Try:
>>> s = '''
... '''
>>> print(s)
>>> repr(s)
"'\\n'"
>>> s = #
File "<stdin>", line 1
s = #
^
SyntaxError: invalid syntax
>>> s = '''foo'''
>>> print(s)
foo

Have Pycco recognize doctests as code?

Is there any way to have Pycco recognize doctests as code and render them appropriately?
E.g. the docstring of the following function
def fib(i):
""" Fibonacci number
>>> fib(10)
55
"""
if i < 2:
return i
else:
return fib(i-1) + fib(i-2)
Renders In Pycco like the following
Fibonacci number
fib(10) 5
Clearly the >>> was interpretted as indentation and code highlighting did not take effect. This seems like a common use case. is there a plugin somewhere that I'm missing?
Python doesn't mind if the doctest suite is indented an additional four characters compared to the rest of the docstring, as long as it's internally consistent, so the following will pass the tests just fine (tested in 2.7.9 and 3.4.2):
def test():
"""Doctest test
The following are doctests:
>>> test()
'foo'
That went well.
"""
return 'foo'
if __name__ == "__main__":
import doctest
doctest.testmod(verbose=True)
This additional indentation will be interpreted as a code block by pycco, just as it is in the Markdown here on SO. The above test renders in HTML as follows:

What is 'print' in Python?

I understand what print does, but of what "type" is that language element? I think it's a function, but why does this fail?
>>> print print
SyntaxError: invalid syntax
Isn't print a function? Shouldn't it print something like this?
>>> print print
<function print at ...>
In 2.7 and down, print is a statement. In python 3, print is a function. To use the print function in Python 2.6 or 2.7, you can do
>>> from __future__ import print_function
>>> print(print)
<built-in function print>
See this section from the Python Language Reference, as well as PEP 3105 for why it changed.
In Python 3, print() is a built-in function (object)
Before this, print was a statement. Demonstration...
Python 2.x:
% pydoc2.6 print
The ``print`` statement
***********************
print_stmt ::= "print" ([expression ("," expression)* [","]]
| ">>" expression [("," expression)+ [","]])
``print`` evaluates each expression in turn and writes the resulting
object to standard output (see below). If an object is not a string,
it is first converted to a string using the rules for string
conversions. The (resulting or original) string is then written. A
space is written before each object is (converted and) written, unless
the output system believes it is positioned at the beginning of a
line. This is the case (1) when no characters have yet been written
to standard output, (2) when the last character written to standard
output is a whitespace character except ``' '``, or (3) when the last
write operation on standard output was not a ``print`` statement. (In
some cases it may be functional to write an empty string to standard
output for this reason.)
-----8<-----
Python 3.x:
% pydoc3.1 print
Help on built-in function print in module builtins:
print(...)
print(value, ..., sep=' ', end='\n', file=sys.stdout)
Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
print is a mistake that has been rectified in Python 3. In Python 3 it is a function. In Python 1.x and 2.x it is not a function, it is a special form like if or while, but unlike those two it is not a control structure.
So, I guess the most accurate thing to call it is a statement.
In Python all statements (except assignment) are expressed with reserved words, not addressible objects. That is why you cannot simply print print and you get a SyntaxError for trying. It's a reserved word, not an object.
Confusingly, you can have a variable named print. You can't address it in the normal way, but you can setattr(locals(), 'print', somevalue) and then print locals()['print'].
Other reserved words that might be desirable as variable names but are nonetheless verboten:
class
import
return
raise
except
try
pass
lambda
In Python 2, print is a statement, which is a whole different kind of thing from a variable or function. Statements are not Python objects that can be passed to type(); they're just part of the language itself, even more so than built-in functions. For example, you could do sum = 5 (even though you shouldn't), but you can't do print = 5 or if = 7 because print and if are statements.
In Python 3, the print statement was replaced with the print() function. So if you do type(print), it'll return <class 'builtin_function_or_method'>.
BONUS:
In Python 2.6+, you can put from __future__ import print_function at the top of your script (as the first line of code), and the print statement will be replaced with the print() function.
>>> # Python 2
>>> from __future__ import print_function
>>> type(print)
<type 'builtin_function_or_method'>

Categories