我正在尝试在一段代码中跟踪问题。一个简短的样本是:
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
这对我来说毫无意义,可以用我的怀疑来解释。