Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
91dc64ba
Commit
91dc64ba
authored
Oct 22, 2017
by
Cheryl Sabella
Committed by
Antoine Pitrou
Oct 22, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bpo-20825: Containment test for ip_network in ip_network.
parent
04e36af9
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
136 additions
and
7 deletions
+136
-7
Doc/library/ipaddress.rst
Doc/library/ipaddress.rst
+24
-0
Lib/ipaddress.py
Lib/ipaddress.py
+23
-6
Lib/test/test_ipaddress.py
Lib/test/test_ipaddress.py
+86
-1
Misc/NEWS.d/next/Library/2017-10-21-09-13-16.bpo-20825.-1MBEy.rst
...S.d/next/Library/2017-10-21-09-13-16.bpo-20825.-1MBEy.rst
+3
-0
No files found.
Doc/library/ipaddress.rst
View file @
91dc64ba
...
...
@@ -543,6 +543,28 @@ so to avoid duplication they are only documented for :class:`IPv4Network`.
>>> ip_network('192.0.2.0/24').supernet(new_prefix=20)
IPv4Network('192.0.0.0/20')
.. method:: subnet_of(other)
Returns *True* if this network is a subnet of *other*.
>>> a = ip_network('192.168.1.0/24')
>>> b = ip_network('192.168.1.128/30')
>>> b.subnet_of(a)
True
.. versionadded:: 3.7
.. method:: supernet_of(other)
Returns *True* if this network is a supernet of *other*.
>>> a = ip_network('192.168.1.0/24')
>>> b = ip_network('192.168.1.128/30')
>>> a.supernet_of(b)
True
.. versionadded:: 3.7
.. method:: compare_networks(other)
Compare this network to *other*. In this comparison only the network
...
...
@@ -621,6 +643,8 @@ so to avoid duplication they are only documented for :class:`IPv4Network`.
.. method:: address_exclude(network)
.. method:: subnets(prefixlen_diff=1, new_prefix=None)
.. method:: supernet(prefixlen_diff=1, new_prefix=None)
.. method:: subnet_of(other)
.. method:: supernet_of(other)
.. method:: compare_networks(other)
Refer to the corresponding attribute documentation in
...
...
Lib/ipaddress.py
View file @
91dc64ba
...
...
@@ -776,8 +776,7 @@ class _BaseNetwork(_IPAddressBase):
if
not
isinstance
(
other
,
_BaseNetwork
):
raise
TypeError
(
"%s is not a network object"
%
other
)
if
not
(
other
.
network_address
>=
self
.
network_address
and
other
.
broadcast_address
<=
self
.
broadcast_address
):
if
not
other
.
subnet_of
(
self
):
raise
ValueError
(
'%s not contained in %s'
%
(
other
,
self
))
if
other
==
self
:
return
...
...
@@ -788,12 +787,10 @@ class _BaseNetwork(_IPAddressBase):
s1
,
s2
=
self
.
subnets
()
while
s1
!=
other
and
s2
!=
other
:
if
(
other
.
network_address
>=
s1
.
network_address
and
other
.
broadcast_address
<=
s1
.
broadcast_address
):
if
other
.
subnet_of
(
s1
):
yield
s2
s1
,
s2
=
s1
.
subnets
()
elif
(
other
.
network_address
>=
s2
.
network_address
and
other
.
broadcast_address
<=
s2
.
broadcast_address
):
elif
other
.
subnet_of
(
s2
):
yield
s1
s1
,
s2
=
s2
.
subnets
()
else
:
...
...
@@ -975,6 +972,26 @@ class _BaseNetwork(_IPAddressBase):
return
(
self
.
network_address
.
is_multicast
and
self
.
broadcast_address
.
is_multicast
)
@
staticmethod
def
_is_subnet_of
(
a
,
b
):
try
:
# Always false if one is v4 and the other is v6.
if
a
.
_version
!=
b
.
_version
:
raise
TypeError
(
f"
{
a
}
and
{
b
}
are not of the same version"
)
return
(
b
.
network_address
<=
a
.
network_address
and
b
.
broadcast_address
>=
a
.
broadcast_address
)
except
AttributeError
:
raise
TypeError
(
f"Unable to test subnet containment "
f"between
{
a
}
and
{
b
}
"
)
def
subnet_of
(
self
,
other
):
"""Return True if this network is a subnet of other."""
return
self
.
_is_subnet_of
(
self
,
other
)
def
supernet_of
(
self
,
other
):
"""Return True if this network is a supernet of other."""
return
self
.
_is_subnet_of
(
other
,
self
)
@
property
def
is_reserved
(
self
):
"""Test if the address is otherwise IETF reserved.
...
...
Lib/test/test_ipaddress.py
View file @
91dc64ba
...
...
@@ -92,7 +92,6 @@ class CommonTestMixin:
y
=
pickle
.
loads
(
pickle
.
dumps
(
x
,
proto
))
self
.
assertEqual
(
y
,
x
)
class
CommonTestMixin_v4
(
CommonTestMixin
):
def
test_leading_zeros
(
self
):
...
...
@@ -477,6 +476,56 @@ class InterfaceTestCase_v4(BaseTestCase, NetmaskTestMixin_v4):
class
NetworkTestCase_v4
(
BaseTestCase
,
NetmaskTestMixin_v4
):
factory
=
ipaddress
.
IPv4Network
def
test_subnet_of
(
self
):
# containee left of container
self
.
assertFalse
(
self
.
factory
(
'10.0.0.0/30'
).
subnet_of
(
self
.
factory
(
'10.0.1.0/24'
)))
# containee inside container
self
.
assertTrue
(
self
.
factory
(
'10.0.0.0/30'
).
subnet_of
(
self
.
factory
(
'10.0.0.0/24'
)))
# containee right of container
self
.
assertFalse
(
self
.
factory
(
'10.0.0.0/30'
).
subnet_of
(
self
.
factory
(
'10.0.1.0/24'
)))
# containee larger than container
self
.
assertFalse
(
self
.
factory
(
'10.0.1.0/24'
).
subnet_of
(
self
.
factory
(
'10.0.0.0/30'
)))
def
test_supernet_of
(
self
):
# containee left of container
self
.
assertFalse
(
self
.
factory
(
'10.0.0.0/30'
).
supernet_of
(
self
.
factory
(
'10.0.1.0/24'
)))
# containee inside container
self
.
assertFalse
(
self
.
factory
(
'10.0.0.0/30'
).
supernet_of
(
self
.
factory
(
'10.0.0.0/24'
)))
# containee right of container
self
.
assertFalse
(
self
.
factory
(
'10.0.0.0/30'
).
supernet_of
(
self
.
factory
(
'10.0.1.0/24'
)))
# containee larger than container
self
.
assertTrue
(
self
.
factory
(
'10.0.0.0/24'
).
supernet_of
(
self
.
factory
(
'10.0.0.0/30'
)))
def
test_subnet_of_mixed_types
(
self
):
with
self
.
assertRaises
(
TypeError
):
ipaddress
.
IPv4Network
(
'10.0.0.0/30'
).
supernet_of
(
ipaddress
.
IPv6Network
(
'::1/128'
))
with
self
.
assertRaises
(
TypeError
):
ipaddress
.
IPv6Network
(
'::1/128'
).
supernet_of
(
ipaddress
.
IPv4Network
(
'10.0.0.0/30'
))
with
self
.
assertRaises
(
TypeError
):
ipaddress
.
IPv4Network
(
'10.0.0.0/30'
).
subnet_of
(
ipaddress
.
IPv6Network
(
'::1/128'
))
with
self
.
assertRaises
(
TypeError
):
ipaddress
.
IPv6Network
(
'::1/128'
).
subnet_of
(
ipaddress
.
IPv4Network
(
'10.0.0.0/30'
))
class
NetmaskTestMixin_v6
(
CommonTestMixin_v6
):
"""Input validation on interfaces and networks is very similar"""
...
...
@@ -540,6 +589,42 @@ class InterfaceTestCase_v6(BaseTestCase, NetmaskTestMixin_v6):
class
NetworkTestCase_v6
(
BaseTestCase
,
NetmaskTestMixin_v6
):
factory
=
ipaddress
.
IPv6Network
def
test_subnet_of
(
self
):
# containee left of container
self
.
assertFalse
(
self
.
factory
(
'2000:999::/56'
).
subnet_of
(
self
.
factory
(
'2000:aaa::/48'
)))
# containee inside container
self
.
assertTrue
(
self
.
factory
(
'2000:aaa::/56'
).
subnet_of
(
self
.
factory
(
'2000:aaa::/48'
)))
# containee right of container
self
.
assertFalse
(
self
.
factory
(
'2000:bbb::/56'
).
subnet_of
(
self
.
factory
(
'2000:aaa::/48'
)))
# containee larger than container
self
.
assertFalse
(
self
.
factory
(
'2000:aaa::/48'
).
subnet_of
(
self
.
factory
(
'2000:aaa::/56'
)))
def
test_supernet_of
(
self
):
# containee left of container
self
.
assertFalse
(
self
.
factory
(
'2000:999::/56'
).
supernet_of
(
self
.
factory
(
'2000:aaa::/48'
)))
# containee inside container
self
.
assertFalse
(
self
.
factory
(
'2000:aaa::/56'
).
supernet_of
(
self
.
factory
(
'2000:aaa::/48'
)))
# containee right of container
self
.
assertFalse
(
self
.
factory
(
'2000:bbb::/56'
).
supernet_of
(
self
.
factory
(
'2000:aaa::/48'
)))
# containee larger than container
self
.
assertTrue
(
self
.
factory
(
'2000:aaa::/48'
).
supernet_of
(
self
.
factory
(
'2000:aaa::/56'
)))
class
FactoryFunctionErrors
(
BaseTestCase
):
...
...
Misc/NEWS.d/next/Library/2017-10-21-09-13-16.bpo-20825.-1MBEy.rst
0 → 100644
View file @
91dc64ba
Add `subnet_of` and `superset_of` containment tests to
:class:`ipaddress.IPv6Network` and :class:`ipaddress.IPv4Network`.
Patch by Michel Albert and Cheryl Sabella.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment