To upgrade the custom code, we have summarised in this article the most common changes for moving from Python 2 to Python 3 in Athento SE:
has_key no longer exists and can be changed to an 'in'. Example:
- if isinstance(automation_result, dict) and automation_result.has_key(NuxeoConnector.EXCEPTION_MESSAGE):
+ if isinstance(automation_result, dict) and NuxeoConnector.EXCEPTION_MESSAGE in automation_result:
In python2 it returns a list, but in python3 it is a dict_keys object. The following considerations need to be taken into account:
The dict_keys class is iterable, and if it is used for traversal, then there is no problem.
However, if the old use was the index method, you have to convert it to a list:
>>> keys = codes.keys()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'dict_keys' object has no attribute 'index'
The python2 print is without parentheses, but in python3 it must have parentheses.
The unicode type no longer exists in python3. The str type is directly encoded in unicode. Make change to compare with str, but make sure the code makes sense:
- if isinstance(context_params, str) or isinstance(context_params, unicode):
+ if isinstance(context_params, str) or isinstance(context_params, str): # Borrar el segundo
Exceptions now have to use the "ace":
- except Exception, err:
+ except Exception as err:
The map() in Python2 returned a list. In Python3 this is no longer the case, they return a map object.
- categories = map(lambda x: x.category, queues)
+ categories = [x.category for x in queues]
Map in Python3:
>>> listado = ['1','2']
>>> map(lambda x: x, listado)
<map object at 0x7f83a3462e50>
The items() method returns a list of tuples in python2, while in python3 it returns a dict_items.
- Python2: [('romance', 'me before you'), ('fantasy', 'harrypotter'), ('fiction', 'divergent')]
- Python3: dict_items([('fantasy', 'harrypotter'), ('fiction', 'divergent'), ('romance', 'me before you')])
So the change to be made is:
- for key, val in groupase.items():
+ for key, val in list(groupase.items()):
- from StringIO import StringIO
+ from io import StringIO
2to3 does not recommend changing when you have a str object and decode it, but Python3 fails. It is probably because if that line is read from file it may come with some encoding. The proposed change is to leave it commented out.
In python 3 xrange no longer exists. Therefore, its equivalent is "range".
- for i in xrange(num_workers):
+ for i in range(num_workers):
In Python 2 files can be opened with open(filename, 'r') but in Python 3 they must be opened with open(filename, 'rb').