From a171a4413c96e82c941aec0800ef7b23659d397c Mon Sep 17 00:00:00 2001 From: Elvis Pranskevichus Date: Sun, 10 Nov 2019 13:44:41 -0500 Subject: [PATCH] Handle IP values with prefix in "inet" type as IPvXInterface Currently we treat values with network prefix in `inet` values as `IPvXNetwork`, instead of `IPvXInterface` which is wrong. Fixes: #497 --- asyncpg/pgproto | 2 +- asyncpg/protocol/codecs/pgproto.pyx | 4 ++-- docs/usage.rst | 17 ++++++++++------- tests/test_codecs.py | 12 ++++++------ 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/asyncpg/pgproto b/asyncpg/pgproto index 6079e5b2..c6491237 160000 --- a/asyncpg/pgproto +++ b/asyncpg/pgproto @@ -1 +1 @@ -Subproject commit 6079e5b2addf7717aabbdcdb7825d6b68c731409 +Subproject commit c64912370b8532df7a561389f139f838b3681670 diff --git a/asyncpg/protocol/codecs/pgproto.pyx b/asyncpg/protocol/codecs/pgproto.pyx index ea9c15ac..accebcd2 100644 --- a/asyncpg/protocol/codecs/pgproto.pyx +++ b/asyncpg/protocol/codecs/pgproto.pyx @@ -382,12 +382,12 @@ cdef init_numeric_codecs(): cdef init_network_codecs(): register_core_codec(CIDROID, pgproto.cidr_encode, - pgproto.net_decode, + pgproto.cidr_decode, PG_FORMAT_BINARY) register_core_codec(INETOID, pgproto.inet_encode, - pgproto.net_decode, + pgproto.inet_decode, PG_FORMAT_BINARY) register_core_codec(MACADDROID, diff --git a/docs/usage.rst b/docs/usage.rst index 64dbb409..20da9d00 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -97,14 +97,14 @@ The table below shows the correspondence between PostgreSQL and Python types. | | :class:`ipaddress.IPv6Network\ | | | ` | +----------------------+-----------------------------------------------------+ -| ``inet`` | :class:`ipaddress.IPv4Network\ | -| | `, | -| | :class:`ipaddress.IPv6Network\ | -| | `, | +| ``inet`` | :class:`ipaddress.IPv4Interface\ | +| | `, | +| | :class:`ipaddress.IPv6Interface\ | +| | `, | | | :class:`ipaddress.IPv4Address\ | | | `, | | | :class:`ipaddress.IPv6Address\ | -| | ` | +| | ` [#f1]_ | +----------------------+-----------------------------------------------------+ | ``macaddr`` | :class:`str ` | +----------------------+-----------------------------------------------------+ @@ -127,7 +127,7 @@ The table below shows the correspondence between PostgreSQL and Python types. | ``interval`` | :class:`datetime.timedelta \ | | | ` | +----------------------+-----------------------------------------------------+ -| ``float``, | :class:`float ` [#f1]_ | +| ``float``, | :class:`float ` [#f2]_ | | ``double precision`` | | +----------------------+-----------------------------------------------------+ | ``smallint``, | :class:`int ` | @@ -158,7 +158,10 @@ The table below shows the correspondence between PostgreSQL and Python types. All other types are encoded and decoded as text by default. -.. [#f1] Inexact single-precision ``float`` values may have a different +.. [#f1] Prior to version 0.20.0, asyncpg erroneously treated ``inet`` values + with prefix as ``IPvXNetwork`` instead of ``IPvXInterface``. + +.. [#f2] Inexact single-precision ``float`` values may have a different representation when decoded into a Python float. This is inherent to the implementation of limited-precision floating point types. If you need the decimal representation to match, cast the expression diff --git a/tests/test_codecs.py b/tests/test_codecs.py index 5498b40f..1299f2bd 100644 --- a/tests/test_codecs.py +++ b/tests/test_codecs.py @@ -341,9 +341,12 @@ def _system_timezone(): ipaddress.IPv6Address('ffff' + ':ffff' * 7), ipaddress.IPv6Address('::1'), ipaddress.IPv6Address('::'), + ipaddress.IPv4Interface('10.0.0.1/30'), + ipaddress.IPv4Interface('0.0.0.0/0'), + ipaddress.IPv4Interface('255.255.255.255/31'), dict( input='127.0.0.0/8', - output=ipaddress.IPv4Network('127.0.0.0/8')), + output=ipaddress.IPv4Interface('127.0.0.0/8')), dict( input='127.0.0.1/32', output=ipaddress.IPv4Address('127.0.0.1')), @@ -358,7 +361,7 @@ def _system_timezone(): textoutput='10.11.12.13/32' ), dict( - input=ipaddress.IPv4Network('10.11.12.13'), + input=ipaddress.IPv4Interface('10.11.12.13'), textoutput='10.11.12.13/32' ), dict( @@ -366,11 +369,8 @@ def _system_timezone(): output=ipaddress.IPv4Address('10.11.12.13'), ), dict( - # Non-zero address bits after the network prefix are permitted - # by postgres, but are invalid in Python - # (and zeroed out by supernet()). textinput='10.11.12.13/0', - output=ipaddress.IPv4Network('0.0.0.0/0'), + output=ipaddress.IPv4Interface('10.11.12.13/0'), ), ]), ('macaddr', 'macaddr', [