This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author ncoghlan
Recipients abarry, kormat, ncoghlan, pitrou, r.david.murray, serhiy.storchaka, tklausmann
Date 2016-08-05.06:32:19
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1470378740.63.0.413028991819.issue27683@psf.upfronthosting.co.za>
In-reply-to
Content
As Stephen notes, the underlying problem appears to be a behavioural difference between two theoretically equivalent ways of defining a network:

>>> list(ipaddress.IPv4Network(('127.0.0.4', 31)).hosts())
[]
>>> list(ipaddress.IPv4Network(('127.0.0.4/31')).hosts())
[IPv4Address('127.0.0.4'), IPv4Address('127.0.0.5')]

Now, the first case is the documented behaviour: hosts() is *supposed to* exclude the network and broadcast address, and those are the only addresses in a /31.

If you want to iterate over all the *addresses* in a network (including the network and broadcast addresses) then you need to iterate over the network object directly:

>>> list(ipaddress.IPv4Network(('127.0.0.4', 31)))
[IPv4Address('127.0.0.4'), IPv4Address('127.0.0.5')]
>>> list(ipaddress.IPv4Network(('127.0.0.4/31')))
[IPv4Address('127.0.0.4'), IPv4Address('127.0.0.5')]

However, as Emanuel found when writing his patch, there's currently an undocumented special case for /31 networks: the definition of "hosts" is *implicitly changed* for such instances to include the nominal network and broadcast address (by setting "self.hosts = self.__iter__"), presumably on the assumption that such networks represent a point-to-point link between two hosts, so the concepts of "network address" and "broadcast address" don't really apply.

That special case seems pragmatically useful, so I think the right fix would be to:

- document the special case that for /31 networks, hosts() includes the network and broadcast addresses (on the assumption the "network" is actually a point-to-point link between two hosts)
- refactor IPv4Network.__init__ to first map the supplied input to a "candidate_address" and "candidate_netmask" and then use *common* validation logic to determine the actual network address and netmask (this will also address the "# fixme" comment for the int/bytes case)
- check whether or not IPv6Network is affected by the same behavioural discrepancy
History
Date User Action Args
2016-08-05 06:32:20ncoghlansetrecipients: + ncoghlan, pitrou, kormat, r.david.murray, serhiy.storchaka, abarry, tklausmann
2016-08-05 06:32:20ncoghlansetmessageid: <1470378740.63.0.413028991819.issue27683@psf.upfronthosting.co.za>
2016-08-05 06:32:20ncoghlanlinkissue27683 messages
2016-08-05 06:32:19ncoghlancreate