错误导致`netaddr`的`IPRange .__ contains__`(`in`)运算符

时间:2017-03-21 13:58:25

标签: python python-2.7 python-2.x

我正在尝试在一段代码中跟踪问题。一个简短的样本是:

from netaddr import IPNetwork, IPRange
IPNetwork('127.0.0.4/32') in IPRange('127.0.0.1', '127.0.0.4')

令人惊讶地返回False

显然,网络包含在指定的范围内,但运营商返回的不是。

在调试后检查recent code for __contains__(我以为我现在可能已经修复了)我可以看到IPNetwork案例可能存在错误:

if isinstance(other, IPNetwork):
    shiftwidth = other._module.width - other._prefixlen
    other_start = (other._value >> shiftwidth) << shiftwidth
    # Start of the next network after other
    other_next_start = other_start + (1 << shiftwidth)
    return (self._start._value <= other_start and self._end._value > other_next_start)

鉴于设置,最后一行应该是:

return (self._start._value <= other_start and self._end._value >= other_next_start - 1)

还有一个更清洁的解决方案,在模块中的其他地方使用:

return self._start._value <= other.start and self._last._value >= other.last

似乎问题发生的原因是other_next_start被设置为第一个地址(作为int)网络的最后一个ip之后。

当尝试网络甚至不在范围的“边缘”的情况时,这已得到证实:

from netaddr import IPNetwork, IPRange
IPNetwork('127.0.0.3/32') in IPRange('127.0.0.1', '127.0.0.4')

再次,False

换句话说,这是错误的,因为它错误地将网络扩展到两个IP地址。

假设该模块被广泛使用,我想知道我的例子是否在概念上是错误的。

更新

运行此代码后,我已向netaddr发送了pull request

>>> net = IPNetwork('10.0.0.0/30')
>>> rng = IPRange(net.first, net.last)
>>> net in rng
False
>>> for ip in net:
...     print ip in rng
... 
True
True
True
True

这对我来说毫无意义,可以用我的怀疑来解释。

0 个答案:

没有答案