[Distutils] multiple backports of ipaddress and a world of pain

Chris Withers chris at simplistix.co.uk
Wed Feb 17 02:51:03 EST 2016

On 16/02/2016 22:31, Philipp Hagemeister wrote:
> Code that uses py2-ipaddress will break upon migrating to Python 3, and
> potentially in really subtle ways. For instance,
> import py2_ipaddress as ipaddress
> ipaddress.ip_address(b'\x3a\x3a\x31\x32')
> ipaddress.ip_address(open('file', 'rb').read(4))
> has different semantics in Python 2 and Python 3. Also note that if you
> actually want to generate an ipaddress object from a binary
> representation, py2-ipaddress' "solution"
> ipaddress.ip_address(bytearray(b'\xff\x00\x00\x01'))
> will break as well under Python 3, but at least it will throw an
> exception and not silently do something different.
> Therefore, code that uses py2-ipaddress needs to be fixed anyways in
> order to work correctly under Python 3 - might as well do it now.

Indeed, James has thankfully switched django-netfields to ipaddress...

> py2-ipaddress' API is incompatible with the ipaddress from the stdlib,
> so I don't think it should claim the module name ipaddress in the first
> place. Why one would actively introduce incompatibilities between Python
> 2 and Python 3 *after Python 3 has long been released* is beyond my
> understanding anyways.
> Specifically for django-netfields, a workaround is to always use
> character strings (unicode type in Python 2, str in Python 3).

The code James uses as a result isn't that pretty, multiple occurrences of:

     value = unicode(value)
except NameError:

What would you recommend instead? When I monkeypatched this yesterday, I 
went with:

if isinstance(value, bytes):
     value = value.decode('ascii')

...but I wonder if there's something better?

(The context here is data coming back from Postgres, which is always str 
in Python 2, and only contains ip or netmask, so really shouldn't have 
anything non-ascii in it!)



More information about the Distutils-SIG mailing list