declaring a python variable in a list [data] = self.read()? - python-3.x

while studying the open source repo of Odoo I found a line of code that I don't understand like the following
[data] = self.read()
found there https://github.com/odoo/odoo/blob/8f297c9d5f6d31370797d64fee5ca9d779f14b81/addons/hr_holidays/wizard/hr_holidays_summary_department.py#L25
I really would like to know why would you put the variable in a list

It seems to ensure that [data] is an iterable of one item and therefore unpacks the first value from self.read()
It cannot be assigned to a non-iterable
>>> [data] = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot unpack non-iterable int object
Works for iterable types, though must have a length equal to one
>>> [data] = {'some':2}
>>> data
'some'
>>> [data] = {'foo':2, 'bar':3}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 1)
>>> [data] = [1]
>>> data
1
>>> [data] = [[1]]
>>> data
[1]
>>> [data] = [1, 2]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 1)
>>> [data] = []
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: not enough values to unpack (expected 1, got 0)

Related

TypeError: 'tuple' object is not callable when converting a list to tuple as return value

I want to convert the final list as tuple. However i am receiving an error.How can i get rid of this?
li= [(19343160,),(39343169,)]
def render_list_sql(li):
l = []
for index, tuple in enumerate(li):
idd = str(tuple[0])
l.append(idd)
return tuple(l)
print(render_list_sql(li))
Expected value to be returned is:
(19343160,39343169)
Error
Traceback (most recent call last):
File "test.py", line 20, in <module>
print(render_list_sql(list))
File "test.py", line 14, in render_list_sql
return tuple(l)
TypeError: 'tuple' object is not callable
As commented, don't use names for variables that mean other things to Python. This is called "shadowing" and you lose the meaning of the original name.
Example:
>>> tuple # This is the class used to create tuples.
<class 'tuple'>
>>> for index,tuple in enumerate([1,2,3]): # This is similar to your code
... print(index,tuple)
...
0 1
1 2
2 3
>>> tuple # tuple is no longer a class, but an instance of an integer.
3
>>> tuple([1,2,3]) # so this fails
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
TypeError: 'int' object is not callable
>>> 3([1,2,3]) # You are basically doing this:
<interactive input>:1: SyntaxWarning: 'int' object is not callable; perhaps you missed a comma?
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
TypeError: 'int' object is not callable
So don't do that:
li = [(19343160,),(39343169,)] # don't reassign list
def render_list_sql(li):
l = []
for index, tup in enumerate(li): # don't reassign tuple
idd = str(tup[0])
l.append(idd)
return tuple(l) # now this will work
print(render_list_sql(li))
Output:
('19343160', '39343169')
FYI, a shorter version using a generator:
li = [(19343160,),(39343169,)]
tup = tuple(str(i[0]) for i in li)
print(tup)

How to get a useful exception message from decimal in python 3?

With Python 2, creating a Decimal with an invalid string produces a useful error message:
>>> import decimal
>>> decimal.Decimal('spam')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/decimal.py", line 547, in __new__
"Invalid literal for Decimal: %r" % value)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/decimal.py", line 3872, in _raise_error
raise error(explanation)
decimal.InvalidOperation: Invalid literal for Decimal: 'spam'
While Python 3 produces a not-so-helpful message:
>>> import decimal
>>> decimal.Decimal('spam')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
decimal.InvalidOperation: [<class 'decimal.ConversionSyntax'>]
Is there any way to get a useful message like "Invalid literal for Decimal: 'spam'" from the exception in Python 3?
I'm using Python 2.7.15 and Python 3.7.2, both on darwin.
Addenda:
It looks like Python 2 once had a not-very-helpful message for decimal.InvalidOperation: https://bugs.python.org/issue1770009
This situation looks analogous but most of it goes over my head: https://bugs.python.org/issue21227
You could monkey-patch the decimal module.
import decimal
def safe_decimal(something):
try:
funct_holder(something)
except Exception as e:
new_errror = Exception("Hey silly that's not a decimal, what should I do with this? {}".format(something))
raise new_errror from None
funct_holder = decimal.Decimal
decimal.Decimal = safe_decimal
Then you could use the monkey patched version as so
>>> decimal.Decimal('hello')
Traceback (most recent call last):
File "<input>", line 12, in <module>
File "<input>", line 6, in safe_decimal
Exception: Hey silly that's not a decimal, what should I do with this? hello

convert pypng to numpy array

I'm trying to convert pypng data struct to a numpy array (with PIL, you can just call numpy.array(img) and it works), but I'm not sure how to do it with pypng. I need to work with 48 bit images, so I need to use pypng.
I've adapted the method suggested in the docs to python3, but it seems to give me the wrong type.
There are my attempts:
>>> import png
>>> reader = png.Reader('encoded_0000000.png')
>>> pngdata = reader.read()
>>> import numpy
>>> nparr = numpy.asarray(map(np.uint16, pngdata[2]))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'np' is not defined
>>> nparr = numpy.asarray(map(numpy.uint16, pngdata[2]))
>>> nparr.shape
()
>>> nparr
array(<map object at 0x0000015F758F8DD8>, dtype=object)
>>># ^ This seems to be an incorrect object type, not a 3D array
>>> nparr = numpy.asarray(numpy.uint16, pngdata[2])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "D:\Miniconda3\envs\base\lib\site-packages\numpy\core\numeric.py", line 492, in asarray
return array(a, dtype, copy=False, order=order)
TypeError: data type not understood
>>>
>>> nparr = numpy.asarray(pngdata[2], type=numpy.uint16)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: asarray() got an unexpected keyword argument 'type'
>>> nparr = numpy.asarray(pngdata[2], dtype=numpy.uint16)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "D:\Miniconda3\envs\base\lib\site-packages\numpy\core\numeric.py", line 492, in asarray
return array(a, dtype, copy=False, order=order)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'generator'
>>> nparr = numpy.asarray(pngdata[2], dtype=numpy.uint16)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "D:\Miniconda3\envs\base\lib\site-packages\numpy\core\numeric.py", line 492, in asarray
return array(a, dtype, copy=False, order=order)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'generator'
>>> nparr = numpy.asarray(pngdata, dtype=numpy.uint16)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "D:\Miniconda3\envs\base\lib\site-packages\numpy\core\numeric.py", line 492, in asarray
return array(a, dtype, copy=False, order=order)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'generator'
>>> pngdata
(512, 256, <generator object Reader.iter_bytes_to_values at 0x0000015F758DBAF0>, {'greyscale': False, 'planes': 3, 'bitdepth': 16, 'alpha': False, 'interlace': 0, 'size': (512, 256)})

AttributeError: module 'readline' has no attribute 'set_completer_delims'

>>> import pdb
>>> x = [1,2,3,4,5]
>>> y = 6
>>> z = 7
>>> r1 = y+z
>>> r1
13
>>> r2 = x+y
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "int") to list
>>> pdb.set_trace()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.6/pdb.py", line 1585, in set_trace
Pdb().set_trace(sys._getframe().f_back)
File "/usr/lib/python3.6/pdb.py", line 156, in __init__
readline.set_completer_delims(' \t\n`##$%^&*()=+[{]}\\|;:\'",<>?')
AttributeError: module 'readline' has no attribute 'set_completer_delims'
>>>
Whats problem? run python3.6 an error occurred
I just try to pdb on Cygwin.
(Note that other lib is okay)
In my case the problem was fixed by installing pyreadline:
pip install pyreadline
Please try it.
More info: https://github.com/winpython/winpython/issues/544

How to use urllib.request.DataHandler in Python 3.6?

I want to open a datauri in Python 3.6
It is described here: https://docs.python.org/3/library/urllib.request.html
But there's really no practical example of how to use it.
I've tried the following without luck. Can anyone suggest the right way to get the data from a datauri using urllib.request.DataHandler?
>>> req = urllib.request.Request("data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E")
>>> with urllib.request.DataHandler.data_open(req) as response:
... data = response.read()
File "<stdin>", line 2
data = response.read()
^
IndentationError: expected an indented block
>>> data = response.read()
File "<stdin>", line 1
data = response.read()
^
IndentationError: unexpected indent
>>> with urllib.request.DataHandler.data_open(req) as response:
... data = response.read()
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: data_open() missing 1 required positional argument: 'req'
>>> with urllib.request.DataHandler.data_open(req) as response:
... data = response.read()
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: data_open() missing 1 required positional argument: 'req'
>>>
You could pass data URI to urlopen():
#!/usr/bin/env python3
from urllib.request import urlopen
url = "data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E"
with urlopen(url) as response:
data = response.read()
print(data.decode())

Resources