Tuesday, August 27, 2019
The unicode() function and Python3
Recently I had to work with some Python code which needs to be compatible with both the hopefully-soon-to-be-finally-deprecated Python 2.7 and recent 3.x versions.
String handling can be a tricky issue, particularly if the string in question needs to be cast to a Unicode object. Take the following example:
#!/usr/bin/env python import ipaddress addresses = list(ipaddress.ip_network(unicode('192.168.1.0/24'))); for address in addresses: print(address)
This does of course fail in Python 3.x with an error like:
Traceback (most recent call last): File "./python.py", line 5, in addresses = list(ipaddress.ip_network(unicode('192.168.1.0/24'))); NameError: name 'unicode' is not defined
Remove the unicode()
wrapper and it fails in Python 2.x with:
ipaddress.AddressValueError: '192.168.1.0/24' does not appear to be an IPv4 or IPv6 network. Did you pass in a bytes (str in Python 2) instead of a unicode object?
The solution is to use the "six
" compatibility layer and add the following directive, which reassigns unicode()
to a mutually compatible function:
#!/usr/bin/env python import ipaddress from six import u as unicode addresses = list(ipaddress.ip_network(unicode('192.168.1.0/24'))); for address in addresses: print(address)
Note that the "six
" compatibility layer may need to be installed separately, in RedHat et al via the packages python2x-six
and python3x-six
respectively.
Useful links
- Six: Python 2 and 3 Compatibility Library
- Building a Python 2/3 compatible Unicode Sandwich
- Strings, Bytes, and Unicode in Python 2 and 3
Posted at 10:25 PM |Comments (0)