Tuesday, August 27, 2019 10:25 PM
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
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
- Six: Python 2 and 3 Compatibility Library
- Building a Python 2/3 compatible Unicode Sandwich
- Strings, Bytes, and Unicode in Python 2 and 3