1# Copyright 2007 Google Inc.
2#  Licensed to PSF under a Contributor Agreement.
3
4"""Unittest for ipaddress module."""
5
6from __future__ import unicode_literals
7
8import contextlib
9import operator
10import pickle
11import re
12import sys
13import unittest
14import weakref
15
16import ipaddress
17
18# Compatibility function
19import binascii
20try:
21    _compat_bytes_fromhex = bytes.fromhex
22except AttributeError:
23    def _compat_bytes_fromhex(s):
24        return binascii.unhexlify(s)
25_compat_str = ipaddress._compat_str
26
27
28class BaseTestCase(unittest.TestCase):
29    # One big change in ipaddress over the original ipaddr module is
30    # error reporting that tries to assume users *don't know the rules*
31    # for what constitutes an RFC compliant IP address
32
33    # Ensuring these errors are emitted correctly in all relevant cases
34    # meant moving to a more systematic test structure that allows the
35    # test structure to map more directly to the module structure
36
37    # Note that if the constructors are refactored so that addresses with
38    # multiple problems get classified differently, that's OK - just
39    # move the affected examples to the newly appropriate test case.
40
41    # There is some duplication between the original relatively ad hoc
42    # test suite and the new systematic tests. While some redundancy in
43    # testing is considered preferable to accidentally deleting a valid
44    # test, the original test suite will likely be reduced over time as
45    # redundant tests are identified.
46
47    @property
48    def factory(self):
49        raise NotImplementedError
50
51    @contextlib.contextmanager
52    def assertCleanError(self, exc_type, details, *args):
53        """
54        Ensure exception does not display a context by default
55
56        Wraps unittest.TestCase.assertRaisesRegex
57        """
58        if args:
59            details = details % args
60        cm = self.assertRaisesRegex(exc_type, details)
61        with cm as exc:
62            yield exc
63
64        # Commented out - this is not easily possible in 2.x
65        # # Ensure we produce clean tracebacks on failure
66        # if exc.exception.__context__ is not None:
67        #     self.assertTrue(exc.exception.__suppress_context__)
68
69    def assertAddressError(self, details, *args):
70        """Ensure a clean AddressValueError"""
71        return self.assertCleanError(ipaddress.AddressValueError,
72                                     details, *args)
73
74    def assertNetmaskError(self, details, *args):
75        """Ensure a clean NetmaskValueError"""
76        return self.assertCleanError(ipaddress.NetmaskValueError,
77                                     details, *args)
78
79    def assertInstancesEqual(self, lhs, rhs):
80        """Check constructor arguments produce equivalent instances"""
81        self.assertEqual(self.factory(lhs), self.factory(rhs))
82
83
84class CommonTestMixin:
85
86    def test_empty_address(self):
87        with self.assertAddressError("Address cannot be empty"):
88            self.factory("")
89
90    def test_floats_rejected(self):
91        with self.assertAddressError(re.escape(repr("1.0"))):
92            self.factory(1.0)
93
94    def test_not_an_index_issue15559(self):
95        # Implementing __index__ makes for a very nasty interaction with the
96        # bytes constructor. Thus, we disallow implicit use as an integer
97        self.assertRaises(TypeError, operator.index, self.factory(1))
98        self.assertRaises(TypeError, hex, self.factory(1))
99        # Commented out: bytes semantics are different in 2.x
100        # self.assertRaises(TypeError, bytes, self.factory(1))
101
102    def pickle_test(self, addr):
103        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
104            with self.subTest(proto=proto):
105                x = self.factory(addr)
106                y = pickle.loads(pickle.dumps(x, proto))
107                self.assertEqual(y, x)
108
109
110class CommonTestMixin_v4(CommonTestMixin):
111
112    def test_leading_zeros(self):
113        self.assertInstancesEqual("000.000.000.000", "0.0.0.0")
114        self.assertInstancesEqual("192.168.000.001", "192.168.0.1")
115
116    def test_int(self):
117        self.assertInstancesEqual(0, "0.0.0.0")
118        self.assertInstancesEqual(3232235521, "192.168.0.1")
119
120    def test_packed(self):
121        self.assertInstancesEqual(
122            _compat_bytes_fromhex("00000000"), "0.0.0.0")
123        self.assertInstancesEqual(
124            _compat_bytes_fromhex("c0a80001"), "192.168.0.1")
125
126    def test_negative_ints_rejected(self):
127        msg = "-1 (< 0) is not permitted as an IPv4 address"
128        with self.assertAddressError(re.escape(msg)):
129            self.factory(-1)
130
131    def test_large_ints_rejected(self):
132        msg = "%d (>= 2**32) is not permitted as an IPv4 address"
133        with self.assertAddressError(re.escape(msg % (2 ** 32))):
134            self.factory(2 ** 32)
135
136    def test_bad_packed_length(self):
137        def assertBadLength(length):
138            addr = b'\0' * length
139            msg = "%r (len %d != 4) is not permitted as an IPv4 address"
140            with self.assertAddressError(re.escape(msg % (addr, length))):
141                self.factory(addr)
142
143        assertBadLength(3)
144        assertBadLength(5)
145
146
147class CommonTestMixin_v6(CommonTestMixin):
148
149    def test_leading_zeros(self):
150        self.assertInstancesEqual("0000::0000", "::")
151        self.assertInstancesEqual("000::c0a8:0001", "::c0a8:1")
152
153    def test_int(self):
154        self.assertInstancesEqual(0, "::")
155        self.assertInstancesEqual(3232235521, "::c0a8:1")
156
157    def test_packed(self):
158        addr = b'\0'*12 + _compat_bytes_fromhex("00000000")
159        self.assertInstancesEqual(addr, "::")
160        addr = b'\0'*12 + _compat_bytes_fromhex("c0a80001")
161        self.assertInstancesEqual(addr, "::c0a8:1")
162        addr = _compat_bytes_fromhex("c0a80001") + b'\0'*12
163        self.assertInstancesEqual(addr, "c0a8:1::")
164
165    def test_negative_ints_rejected(self):
166        msg = "-1 (< 0) is not permitted as an IPv6 address"
167        with self.assertAddressError(re.escape(msg)):
168            self.factory(-1)
169
170    def test_large_ints_rejected(self):
171        msg = "%d (>= 2**128) is not permitted as an IPv6 address"
172        with self.assertAddressError(re.escape(msg % 2 ** 128)):
173            self.factory(2 ** 128)
174
175    def test_bad_packed_length(self):
176        def assertBadLength(length):
177            addr = b'\0' * length
178            msg = "%r (len %d != 16) is not permitted as an IPv6 address"
179            with self.assertAddressError(re.escape(msg % (addr, length))):
180                self.factory(addr)
181                self.factory(addr)
182
183        assertBadLength(15)
184        assertBadLength(17)
185
186
187class AddressTestCase_v4(BaseTestCase, CommonTestMixin_v4):
188    factory = ipaddress.IPv4Address
189
190    def test_network_passed_as_address(self):
191        addr = "127.0.0.1/24"
192        with self.assertAddressError("Unexpected '/' in %r", addr):
193            ipaddress.IPv4Address(addr)
194
195    def test_bad_address_split(self):
196        def assertBadSplit(addr):
197            with self.assertAddressError("Expected 4 octets in %r", addr):
198                ipaddress.IPv4Address(addr)
199
200        assertBadSplit("127.0.1")
201        assertBadSplit("42.42.42.42.42")
202        assertBadSplit("42.42.42")
203        assertBadSplit("42.42")
204        assertBadSplit("42")
205        assertBadSplit("42..42.42.42")
206        assertBadSplit("42.42.42.42.")
207        assertBadSplit("42.42.42.42...")
208        assertBadSplit(".42.42.42.42")
209        assertBadSplit("...42.42.42.42")
210        assertBadSplit("016.016.016")
211        assertBadSplit("016.016")
212        assertBadSplit("016")
213        assertBadSplit("000")
214        assertBadSplit("0x0a.0x0a.0x0a")
215        assertBadSplit("0x0a.0x0a")
216        assertBadSplit("0x0a")
217        assertBadSplit(".")
218        assertBadSplit("bogus")
219        assertBadSplit("bogus.com")
220        assertBadSplit("1000")
221        assertBadSplit("1000000000000000")
222        assertBadSplit("192.168.0.1.com")
223
224    def test_empty_octet(self):
225        def assertBadOctet(addr):
226            with self.assertAddressError("Empty octet not permitted in %r",
227                                         addr):
228                ipaddress.IPv4Address(addr)
229
230        assertBadOctet("42..42.42")
231        assertBadOctet("...")
232
233    def test_invalid_characters(self):
234        def assertBadOctet(addr, octet):
235            msg = "Only decimal digits permitted in %r in %r" % (octet, addr)
236            with self.assertAddressError(re.escape(msg)):
237                ipaddress.IPv4Address(addr)
238
239        assertBadOctet("0x0a.0x0a.0x0a.0x0a", "0x0a")
240        assertBadOctet("0xa.0x0a.0x0a.0x0a", "0xa")
241        assertBadOctet("42.42.42.-0", "-0")
242        assertBadOctet("42.42.42.+0", "+0")
243        assertBadOctet("42.42.42.-42", "-42")
244        assertBadOctet("+1.+2.+3.4", "+1")
245        assertBadOctet("1.2.3.4e0", "4e0")
246        assertBadOctet("1.2.3.4::", "4::")
247        assertBadOctet("1.a.2.3", "a")
248
249    def test_octal_decimal_ambiguity(self):
250        def assertBadOctet(addr, octet):
251            msg = "Ambiguous (octal/decimal) value in %r not permitted in %r"
252            with self.assertAddressError(re.escape(msg % (octet, addr))):
253                ipaddress.IPv4Address(addr)
254
255        assertBadOctet("016.016.016.016", "016")
256        assertBadOctet("001.000.008.016", "008")
257
258    def test_octet_length(self):
259        def assertBadOctet(addr, octet):
260            msg = "At most 3 characters permitted in %r in %r"
261            with self.assertAddressError(re.escape(msg % (octet, addr))):
262                ipaddress.IPv4Address(addr)
263
264        assertBadOctet("0000.000.000.000", "0000")
265        assertBadOctet("12345.67899.-54321.-98765", "12345")
266
267    def test_octet_limit(self):
268        def assertBadOctet(addr, octet):
269            msg = "Octet %d (> 255) not permitted in %r" % (octet, addr)
270            with self.assertAddressError(re.escape(msg)):
271                ipaddress.IPv4Address(addr)
272
273        assertBadOctet("257.0.0.0", 257)
274        assertBadOctet("192.168.0.999", 999)
275
276    def test_pickle(self):
277        self.pickle_test('192.0.2.1')
278
279    def test_weakref(self):
280        weakref.ref(self.factory('192.0.2.1'))
281
282    def test_bytes_message(self):
283        with self.assertAddressError(r'bytes'):
284            ipaddress.IPv4Address(b'192.0.2.1')
285        with self.assertAddressError(r'bytes'):
286            ipaddress.ip_address(b'192.0.2.1')
287
288
289class AddressTestCase_v6(BaseTestCase, CommonTestMixin_v6):
290    factory = ipaddress.IPv6Address
291
292    def test_network_passed_as_address(self):
293        addr = "::1/24"
294        with self.assertAddressError("Unexpected '/' in %r", addr):
295            ipaddress.IPv6Address(addr)
296
297    def test_bad_address_split_v6_not_enough_parts(self):
298        def assertBadSplit(addr):
299            msg = "At least 3 parts expected in %r"
300            with self.assertAddressError(msg, addr):
301                ipaddress.IPv6Address(addr)
302
303        assertBadSplit(":")
304        assertBadSplit(":1")
305        assertBadSplit("FEDC:9878")
306
307    def test_bad_address_split_v6_too_many_colons(self):
308        def assertBadSplit(addr):
309            msg = "At most 8 colons permitted in %r"
310            with self.assertAddressError(msg, addr):
311                ipaddress.IPv6Address(addr)
312
313        assertBadSplit("9:8:7:6:5:4:3::2:1")
314        assertBadSplit("10:9:8:7:6:5:4:3:2:1")
315        assertBadSplit("::8:7:6:5:4:3:2:1")
316        assertBadSplit("8:7:6:5:4:3:2:1::")
317        # A trailing IPv4 address is two parts
318        assertBadSplit("10:9:8:7:6:5:4:3:42.42.42.42")
319
320    def test_bad_address_split_v6_too_many_parts(self):
321        def assertBadSplit(addr):
322            msg = "Exactly 8 parts expected without '::' in %r"
323            with self.assertAddressError(msg, addr):
324                ipaddress.IPv6Address(addr)
325
326        assertBadSplit("3ffe:0:0:0:0:0:0:0:1")
327        assertBadSplit("9:8:7:6:5:4:3:2:1")
328        assertBadSplit("7:6:5:4:3:2:1")
329        # A trailing IPv4 address is two parts
330        assertBadSplit("9:8:7:6:5:4:3:42.42.42.42")
331        assertBadSplit("7:6:5:4:3:42.42.42.42")
332
333    def test_bad_address_split_v6_too_many_parts_with_double_colon(self):
334        def assertBadSplit(addr):
335            msg = "Expected at most 7 other parts with '::' in %r"
336            with self.assertAddressError(msg, addr):
337                ipaddress.IPv6Address(addr)
338
339        assertBadSplit("1:2:3:4::5:6:7:8")
340
341    def test_bad_address_split_v6_repeated_double_colon(self):
342        def assertBadSplit(addr):
343            msg = "At most one '::' permitted in %r"
344            with self.assertAddressError(msg, addr):
345                ipaddress.IPv6Address(addr)
346
347        assertBadSplit("3ffe::1::1")
348        assertBadSplit("1::2::3::4:5")
349        assertBadSplit("2001::db:::1")
350        assertBadSplit("3ffe::1::")
351        assertBadSplit("::3ffe::1")
352        assertBadSplit(":3ffe::1::1")
353        assertBadSplit("3ffe::1::1:")
354        assertBadSplit(":3ffe::1::1:")
355        assertBadSplit(":::")
356        assertBadSplit('2001:db8:::1')
357
358    def test_bad_address_split_v6_leading_colon(self):
359        def assertBadSplit(addr):
360            msg = "Leading ':' only permitted as part of '::' in %r"
361            with self.assertAddressError(msg, addr):
362                ipaddress.IPv6Address(addr)
363
364        assertBadSplit(":2001:db8::1")
365        assertBadSplit(":1:2:3:4:5:6:7")
366        assertBadSplit(":1:2:3:4:5:6:")
367        assertBadSplit(":6:5:4:3:2:1::")
368
369    def test_bad_address_split_v6_trailing_colon(self):
370        def assertBadSplit(addr):
371            msg = "Trailing ':' only permitted as part of '::' in %r"
372            with self.assertAddressError(msg, addr):
373                ipaddress.IPv6Address(addr)
374
375        assertBadSplit("2001:db8::1:")
376        assertBadSplit("1:2:3:4:5:6:7:")
377        assertBadSplit("::1.2.3.4:")
378        assertBadSplit("::7:6:5:4:3:2:")
379
380    def test_bad_v4_part_in(self):
381        def assertBadAddressPart(addr, v4_error):
382            with self.assertAddressError("%s in %r", v4_error, addr):
383                ipaddress.IPv6Address(addr)
384
385        assertBadAddressPart("3ffe::1.net", "Expected 4 octets in u?'1.net'")
386        assertBadAddressPart("3ffe::127.0.1",
387                             "Expected 4 octets in u?'127.0.1'")
388        assertBadAddressPart("::1.2.3",
389                             "Expected 4 octets in u?'1.2.3'")
390        assertBadAddressPart("::1.2.3.4.5",
391                             "Expected 4 octets in u?'1.2.3.4.5'")
392        assertBadAddressPart("3ffe::1.1.1.net",
393                             "Only decimal digits permitted in u?'net' "
394                             "in u?'1.1.1.net'")
395
396    def test_invalid_characters(self):
397        def assertBadPart(addr, part):
398            msg = "Only hex digits permitted in %r in %r" % (part, addr)
399            with self.assertAddressError(re.escape(msg)):
400                ipaddress.IPv6Address(addr)
401
402        assertBadPart("3ffe::goog", "goog")
403        assertBadPart("3ffe::-0", "-0")
404        assertBadPart("3ffe::+0", "+0")
405        assertBadPart("3ffe::-1", "-1")
406        assertBadPart("1.2.3.4::", "1.2.3.4")
407        assertBadPart('1234:axy::b', "axy")
408
409    def test_part_length(self):
410        def assertBadPart(addr, part):
411            msg = "At most 4 characters permitted in %r in %r"
412            with self.assertAddressError(msg, part, addr):
413                ipaddress.IPv6Address(addr)
414
415        assertBadPart("::00000", "00000")
416        assertBadPart("3ffe::10000", "10000")
417        assertBadPart("02001:db8::", "02001")
418        assertBadPart('2001:888888::1', "888888")
419
420    def test_pickle(self):
421        self.pickle_test('2001:db8::')
422
423    def test_weakref(self):
424        weakref.ref(self.factory('2001:db8::'))
425
426    def test_bytes_message(self):
427        with self.assertAddressError(r'bytes'):
428            ipaddress.IPv6Address(b'::123')
429        with self.assertAddressError(r'bytes'):
430            ipaddress.ip_address(b'::123')
431
432
433class NetmaskTestMixin_v4(CommonTestMixin_v4):
434    """Input validation on interfaces and networks is very similar"""
435
436    def test_split_netmask(self):
437        addr = "1.2.3.4/32/24"
438        with self.assertAddressError("Only one '/' permitted in %r" % addr):
439            self.factory(addr)
440
441    def test_address_errors(self):
442        def assertBadAddress(addr, details):
443            with self.assertAddressError(details):
444                self.factory(addr)
445
446        assertBadAddress("/", "Address cannot be empty")
447        assertBadAddress("/8", "Address cannot be empty")
448        assertBadAddress("bogus", "Expected 4 octets")
449        assertBadAddress("google.com", "Expected 4 octets")
450        assertBadAddress("10/8", "Expected 4 octets")
451        assertBadAddress("::1.2.3.4", "Only decimal digits")
452        assertBadAddress("1.2.3.256", re.escape("256 (> 255)"))
453
454    def test_valid_netmask(self):
455        self.assertEqual(_compat_str(self.factory('192.0.2.0/255.255.255.0')),
456                         '192.0.2.0/24')
457        for i in range(0, 33):
458            # Generate and re-parse the CIDR format (trivial).
459            net_str = '0.0.0.0/%d' % i
460            net = self.factory(net_str)
461            self.assertEqual(_compat_str(net), net_str)
462            # Generate and re-parse the expanded netmask.
463            self.assertEqual(
464                _compat_str(self.factory('0.0.0.0/%s' % net.netmask)), net_str)
465            # Zero prefix is treated as decimal.
466            self.assertEqual(
467                _compat_str(self.factory('0.0.0.0/0%d' % i)),
468                net_str)
469            # Generate and re-parse the expanded hostmask.  The ambiguous
470            # cases (/0 and /32) are treated as netmasks.
471            if i in (32, 0):
472                net_str = '0.0.0.0/%d' % (32 - i)
473            self.assertEqual(
474                _compat_str(self.factory('0.0.0.0/%s' % net.hostmask)),
475                net_str)
476
477    def test_netmask_errors(self):
478        def assertBadNetmask(addr, netmask):
479            msg = "%r is not a valid netmask" % netmask
480            with self.assertNetmaskError(re.escape(msg)):
481                self.factory("%s/%s" % (addr, netmask))
482
483        assertBadNetmask("1.2.3.4", "")
484        assertBadNetmask("1.2.3.4", "-1")
485        assertBadNetmask("1.2.3.4", "+1")
486        assertBadNetmask("1.2.3.4", " 1 ")
487        assertBadNetmask("1.2.3.4", "0x1")
488        assertBadNetmask("1.2.3.4", "33")
489        assertBadNetmask("1.2.3.4", "254.254.255.256")
490        assertBadNetmask("1.2.3.4", "1.a.2.3")
491        assertBadNetmask("1.1.1.1", "254.xyz.2.3")
492        assertBadNetmask("1.1.1.1", "240.255.0.0")
493        assertBadNetmask("1.1.1.1", "255.254.128.0")
494        assertBadNetmask("1.1.1.1", "0.1.127.255")
495        assertBadNetmask("1.1.1.1", "pudding")
496        assertBadNetmask("1.1.1.1", "::")
497
498    def test_pickle(self):
499        self.pickle_test('192.0.2.0/27')
500        self.pickle_test('192.0.2.0/31')  # IPV4LENGTH - 1
501        self.pickle_test('192.0.2.0')     # IPV4LENGTH
502
503
504class InterfaceTestCase_v4(BaseTestCase, NetmaskTestMixin_v4):
505    factory = ipaddress.IPv4Interface
506
507
508class NetworkTestCase_v4(BaseTestCase, NetmaskTestMixin_v4):
509    factory = ipaddress.IPv4Network
510
511    def test_subnet_of(self):
512        # containee left of container
513        self.assertFalse(
514            self.factory('10.0.0.0/30').subnet_of(
515                self.factory('10.0.1.0/24')))
516        # containee inside container
517        self.assertTrue(
518            self.factory('10.0.0.0/30').subnet_of(
519                self.factory('10.0.0.0/24')))
520        # containee right of container
521        self.assertFalse(
522            self.factory('10.0.0.0/30').subnet_of(
523                self.factory('10.0.1.0/24')))
524        # containee larger than container
525        self.assertFalse(
526            self.factory('10.0.1.0/24').subnet_of(
527                self.factory('10.0.0.0/30')))
528
529    def test_supernet_of(self):
530        # containee left of container
531        self.assertFalse(
532            self.factory('10.0.0.0/30').supernet_of(
533                self.factory('10.0.1.0/24')))
534        # containee inside container
535        self.assertFalse(
536            self.factory('10.0.0.0/30').supernet_of(
537                self.factory('10.0.0.0/24')))
538        # containee right of container
539        self.assertFalse(
540            self.factory('10.0.0.0/30').supernet_of(
541                self.factory('10.0.1.0/24')))
542        # containee larger than container
543        self.assertTrue(
544            self.factory('10.0.0.0/24').supernet_of(
545                self.factory('10.0.0.0/30')))
546
547    def test_subnet_of_mixed_types(self):
548        self.assertRaises(
549            TypeError,
550            ipaddress.IPv4Network('10.0.0.0/30').supernet_of,
551            ipaddress.IPv6Network('::1/128'),
552        )
553        self.assertRaises(
554            TypeError,
555            ipaddress.IPv6Network('::1/128').subnet_of,
556            ipaddress.IPv4Network('10.0.0.0/30'),
557        )
558        self.assertRaises(
559            TypeError,
560            ipaddress.IPv4Network('10.0.0.0/30').subnet_of,
561            ipaddress.IPv6Network('::1/128'),
562        )
563        self.assertRaises(
564            TypeError,
565            ipaddress.IPv6Network('::1/128').subnet_of,
566            ipaddress.IPv4Network('10.0.0.0/30'),
567        )
568
569
570class NetmaskTestMixin_v6(CommonTestMixin_v6):
571    """Input validation on interfaces and networks is very similar"""
572
573    def test_split_netmask(self):
574        addr = "cafe:cafe::/128/190"
575        with self.assertAddressError("Only one '/' permitted in %r" % addr):
576            self.factory(addr)
577
578    def test_address_errors(self):
579        def assertBadAddress(addr, details):
580            with self.assertAddressError(details):
581                self.factory(addr)
582
583        assertBadAddress("/", "Address cannot be empty")
584        assertBadAddress("/8", "Address cannot be empty")
585        assertBadAddress("google.com", "At least 3 parts")
586        assertBadAddress("1.2.3.4", "At least 3 parts")
587        assertBadAddress("10/8", "At least 3 parts")
588        assertBadAddress("1234:axy::b", "Only hex digits")
589
590    def test_valid_netmask(self):
591        # We only support CIDR for IPv6, because expanded netmasks are not
592        # standard notation.
593        self.assertEqual(
594            _compat_str(self.factory('2001:db8::/32')),
595            '2001:db8::/32')
596        for i in range(0, 129):
597            # Generate and re-parse the CIDR format (trivial).
598            net_str = '::/%d' % i
599            self.assertEqual(_compat_str(self.factory(net_str)), net_str)
600            # Zero prefix is treated as decimal.
601            self.assertEqual(_compat_str(self.factory('::/0%d' % i)), net_str)
602
603    def test_netmask_errors(self):
604        def assertBadNetmask(addr, netmask):
605            msg = "%r is not a valid netmask" % netmask
606            with self.assertNetmaskError(re.escape(msg)):
607                self.factory("%s/%s" % (addr, netmask))
608
609        assertBadNetmask("::1", "")
610        assertBadNetmask("::1", "::1")
611        assertBadNetmask("::1", "1::")
612        assertBadNetmask("::1", "-1")
613        assertBadNetmask("::1", "+1")
614        assertBadNetmask("::1", " 1 ")
615        assertBadNetmask("::1", "0x1")
616        assertBadNetmask("::1", "129")
617        assertBadNetmask("::1", "1.2.3.4")
618        assertBadNetmask("::1", "pudding")
619        assertBadNetmask("::", "::")
620
621    def test_pickle(self):
622        self.pickle_test('2001:db8::1000/124')
623        self.pickle_test('2001:db8::1000/127')  # IPV6LENGTH - 1
624        self.pickle_test('2001:db8::1000')      # IPV6LENGTH
625
626
627class InterfaceTestCase_v6(BaseTestCase, NetmaskTestMixin_v6):
628    factory = ipaddress.IPv6Interface
629
630
631class NetworkTestCase_v6(BaseTestCase, NetmaskTestMixin_v6):
632    factory = ipaddress.IPv6Network
633
634    def test_subnet_of(self):
635        # containee left of container
636        self.assertFalse(
637            self.factory('2000:999::/56').subnet_of(
638                self.factory('2000:aaa::/48')))
639        # containee inside container
640        self.assertTrue(
641            self.factory('2000:aaa::/56').subnet_of(
642                self.factory('2000:aaa::/48')))
643        # containee right of container
644        self.assertFalse(
645            self.factory('2000:bbb::/56').subnet_of(
646                self.factory('2000:aaa::/48')))
647        # containee larger than container
648        self.assertFalse(
649            self.factory('2000:aaa::/48').subnet_of(
650                self.factory('2000:aaa::/56')))
651
652    def test_supernet_of(self):
653        # containee left of container
654        self.assertFalse(
655            self.factory('2000:999::/56').supernet_of(
656                self.factory('2000:aaa::/48')))
657        # containee inside container
658        self.assertFalse(
659            self.factory('2000:aaa::/56').supernet_of(
660                self.factory('2000:aaa::/48')))
661        # containee right of container
662        self.assertFalse(
663            self.factory('2000:bbb::/56').supernet_of(
664                self.factory('2000:aaa::/48')))
665        # containee larger than container
666        self.assertTrue(
667            self.factory('2000:aaa::/48').supernet_of(
668                self.factory('2000:aaa::/56')))
669
670
671class FactoryFunctionErrors(BaseTestCase):
672
673    def assertFactoryError(self, factory, kind):
674        """Ensure a clean ValueError with the expected message"""
675        addr = "camelot"
676        msg = '%r does not appear to be an IPv4 or IPv6 %s'
677        with self.assertCleanError(ValueError, msg, addr, kind):
678            factory(addr)
679
680    def test_ip_address(self):
681        self.assertFactoryError(ipaddress.ip_address, "address")
682
683    def test_ip_interface(self):
684        self.assertFactoryError(ipaddress.ip_interface, "interface")
685
686    def test_ip_network(self):
687        self.assertFactoryError(ipaddress.ip_network, "network")
688
689
690class LargestObject(ipaddress._TotalOrderingMixin):
691    def __eq__(self, other):
692        return isinstance(other, LargestObject)
693
694    def __lt__(self, other):
695        return False
696
697
698class SmallestObject(ipaddress._TotalOrderingMixin):
699    def __eq__(self, other):
700        return isinstance(other, SmallestObject)
701
702    def __lt__(self, other):
703        return True
704
705
706class ComparisonTests(unittest.TestCase):
707
708    v4addr = ipaddress.IPv4Address(1)
709    v4net = ipaddress.IPv4Network(1)
710    v4intf = ipaddress.IPv4Interface(1)
711    v6addr = ipaddress.IPv6Address(1)
712    v6net = ipaddress.IPv6Network(1)
713    v6intf = ipaddress.IPv6Interface(1)
714
715    v4_addresses = [v4addr, v4intf]
716    v4_objects = v4_addresses + [v4net]
717    v6_addresses = [v6addr, v6intf]
718    v6_objects = v6_addresses + [v6net]
719
720    objects = v4_objects + v6_objects
721
722    v4addr2 = ipaddress.IPv4Address(2)
723    v4net2 = ipaddress.IPv4Network(2)
724    v4intf2 = ipaddress.IPv4Interface(2)
725    v6addr2 = ipaddress.IPv6Address(2)
726    v6net2 = ipaddress.IPv6Network(2)
727    v6intf2 = ipaddress.IPv6Interface(2)
728
729    def test_foreign_type_equality(self):
730        # __eq__ should never raise TypeError directly
731        other = object()
732        for obj in self.objects:
733            self.assertNotEqual(obj, other)
734            self.assertFalse(obj == other)
735            self.assertEqual(obj.__eq__(other), NotImplemented)
736            self.assertEqual(obj.__ne__(other), NotImplemented)
737
738    def test_mixed_type_equality(self):
739        # Ensure none of the internal objects accidentally
740        # expose the right set of attributes to become "equal"
741        for lhs in self.objects:
742            for rhs in self.objects:
743                if lhs is rhs:
744                    continue
745                self.assertNotEqual(lhs, rhs)
746
747    def test_same_type_equality(self):
748        for obj in self.objects:
749            self.assertEqual(obj, obj)
750            self.assertTrue(obj <= obj)
751            self.assertTrue(obj >= obj)
752
753    def test_same_type_ordering(self):
754        for lhs, rhs in (
755            (self.v4addr, self.v4addr2),
756            (self.v4net, self.v4net2),
757            (self.v4intf, self.v4intf2),
758            (self.v6addr, self.v6addr2),
759            (self.v6net, self.v6net2),
760            (self.v6intf, self.v6intf2),
761        ):
762            self.assertNotEqual(lhs, rhs)
763            self.assertTrue(lhs < rhs)
764            self.assertTrue(lhs <= rhs)
765            self.assertTrue(rhs > lhs)
766            self.assertTrue(rhs >= lhs)
767            self.assertFalse(lhs > rhs)
768            self.assertFalse(rhs < lhs)
769            self.assertFalse(lhs >= rhs)
770            self.assertFalse(rhs <= lhs)
771
772    def test_containment(self):
773        for obj in self.v4_addresses:
774            self.assertIn(obj, self.v4net)
775        for obj in self.v6_addresses:
776            self.assertIn(obj, self.v6net)
777        for obj in self.v4_objects + [self.v6net]:
778            self.assertNotIn(obj, self.v6net)
779        for obj in self.v6_objects + [self.v4net]:
780            self.assertNotIn(obj, self.v4net)
781
782    def test_mixed_type_ordering(self):
783        for lhs in self.objects:
784            for rhs in self.objects:
785                if isinstance(lhs, type(rhs)) or isinstance(rhs, type(lhs)):
786                    continue
787                self.assertRaises(TypeError, lambda: lhs < rhs)
788                self.assertRaises(TypeError, lambda: lhs > rhs)
789                self.assertRaises(TypeError, lambda: lhs <= rhs)
790                self.assertRaises(TypeError, lambda: lhs >= rhs)
791
792    def test_foreign_type_ordering(self):
793        # In Python 2.x, the semantics are much less convenient, so skip all of
794        # these tests there.
795        if sys.version_info < (3, 0):
796            return
797
798        other = object()
799        smallest = SmallestObject()
800        largest = LargestObject()
801        for obj in self.objects:
802            with self.assertRaises(TypeError):
803                obj < other
804            with self.assertRaises(TypeError):
805                obj > other
806            with self.assertRaises(TypeError):
807                obj <= other
808            with self.assertRaises(TypeError):
809                obj >= other
810            self.assertTrue(obj < largest)
811            self.assertFalse(obj > largest)
812            self.assertTrue(obj <= largest)
813            self.assertFalse(obj >= largest)
814            self.assertFalse(obj < smallest)
815            self.assertTrue(obj > smallest)
816            self.assertFalse(obj <= smallest)
817            self.assertTrue(obj >= smallest)
818
819    def test_mixed_type_key(self):
820        # with get_mixed_type_key, you can sort addresses and network.
821        v4_ordered = [self.v4addr, self.v4net, self.v4intf]
822        v6_ordered = [self.v6addr, self.v6net, self.v6intf]
823        self.assertEqual(v4_ordered,
824                         sorted(self.v4_objects,
825                                key=ipaddress.get_mixed_type_key))
826        self.assertEqual(v6_ordered,
827                         sorted(self.v6_objects,
828                                key=ipaddress.get_mixed_type_key))
829        self.assertEqual(v4_ordered + v6_ordered,
830                         sorted(self.objects,
831                                key=ipaddress.get_mixed_type_key))
832        self.assertEqual(NotImplemented, ipaddress.get_mixed_type_key(object))
833
834    def test_incompatible_versions(self):
835        # These should always raise TypeError
836        v4addr = ipaddress.ip_address('1.1.1.1')
837        v4net = ipaddress.ip_network('1.1.1.1')
838        v6addr = ipaddress.ip_address('::1')
839        v6net = ipaddress.ip_network('::1')
840
841        self.assertRaises(TypeError, v4addr.__lt__, v6addr)
842        self.assertRaises(TypeError, v4addr.__gt__, v6addr)
843        self.assertRaises(TypeError, v4net.__lt__, v6net)
844        self.assertRaises(TypeError, v4net.__gt__, v6net)
845
846        self.assertRaises(TypeError, v6addr.__lt__, v4addr)
847        self.assertRaises(TypeError, v6addr.__gt__, v4addr)
848        self.assertRaises(TypeError, v6net.__lt__, v4net)
849        self.assertRaises(TypeError, v6net.__gt__, v4net)
850
851
852class IpaddrUnitTest(unittest.TestCase):
853
854    def setUp(self):
855        self.ipv4_address = ipaddress.IPv4Address('1.2.3.4')
856        self.ipv4_interface = ipaddress.IPv4Interface('1.2.3.4/24')
857        self.ipv4_network = ipaddress.IPv4Network('1.2.3.0/24')
858        self.ipv6_address = ipaddress.IPv6Interface(
859            '2001:658:22a:cafe:200:0:0:1')
860        self.ipv6_interface = ipaddress.IPv6Interface(
861            '2001:658:22a:cafe:200:0:0:1/64')
862        self.ipv6_network = ipaddress.IPv6Network('2001:658:22a:cafe::/64')
863
864    def testRepr(self):
865        self.assertTrue(re.match(r"IPv4Interface\(u?'1.2.3.4/32'\)",
866                        repr(ipaddress.IPv4Interface('1.2.3.4'))))
867        self.assertTrue(re.match(r"IPv6Interface\(u?'::1/128'\)",
868                        repr(ipaddress.IPv6Interface('::1'))))
869
870    # issue #16531: constructing IPv4Network from an (address, mask) tuple
871    def testIPv4Tuple(self):
872        # /32
873        ip = ipaddress.IPv4Address('192.0.2.1')
874        net = ipaddress.IPv4Network('192.0.2.1/32')
875        self.assertEqual(ipaddress.IPv4Network(('192.0.2.1', 32)), net)
876        self.assertEqual(ipaddress.IPv4Network((ip, 32)), net)
877        self.assertEqual(ipaddress.IPv4Network((3221225985, 32)), net)
878        self.assertEqual(ipaddress.IPv4Network(('192.0.2.1',
879                                                '255.255.255.255')), net)
880        self.assertEqual(ipaddress.IPv4Network((ip,
881                                                '255.255.255.255')), net)
882        self.assertEqual(ipaddress.IPv4Network((3221225985,
883                                                '255.255.255.255')), net)
884        # strict=True and host bits set
885        self.assertRaises(ValueError, ipaddress.IPv4Network, ('192.0.2.1', 24))
886        self.assertRaises(ValueError, ipaddress.IPv4Network, (ip, 24))
887        self.assertRaises(ValueError, ipaddress.IPv4Network, (3221225985, 24))
888        self.assertRaises(
889            ValueError, ipaddress.IPv4Network, ('192.0.2.1', '255.255.255.0'))
890        self.assertRaises(
891            ValueError, ipaddress.IPv4Network, (ip, '255.255.255.0'))
892        self.assertRaises(
893            ValueError, ipaddress.IPv4Network, (3221225985, '255.255.255.0'))
894        # strict=False and host bits set
895        net = ipaddress.IPv4Network('192.0.2.0/24')
896        self.assertEqual(ipaddress.IPv4Network(('192.0.2.1', 24),
897                                               strict=False), net)
898        self.assertEqual(ipaddress.IPv4Network((ip, 24),
899                                               strict=False), net)
900        self.assertEqual(ipaddress.IPv4Network((3221225985, 24),
901                                               strict=False), net)
902        self.assertEqual(ipaddress.IPv4Network(('192.0.2.1',
903                                                '255.255.255.0'),
904                                               strict=False), net)
905        self.assertEqual(ipaddress.IPv4Network((ip,
906                                                '255.255.255.0'),
907                                               strict=False), net)
908        self.assertEqual(ipaddress.IPv4Network((3221225985,
909                                                '255.255.255.0'),
910                                               strict=False), net)
911
912        # /24
913        ip = ipaddress.IPv4Address('192.0.2.0')
914        net = ipaddress.IPv4Network('192.0.2.0/24')
915        self.assertEqual(ipaddress.IPv4Network(('192.0.2.0',
916                                                '255.255.255.0')), net)
917        self.assertEqual(ipaddress.IPv4Network((ip,
918                                                '255.255.255.0')), net)
919        self.assertEqual(ipaddress.IPv4Network((3221225984,
920                                                '255.255.255.0')), net)
921        self.assertEqual(ipaddress.IPv4Network(('192.0.2.0', 24)), net)
922        self.assertEqual(ipaddress.IPv4Network((ip, 24)), net)
923        self.assertEqual(ipaddress.IPv4Network((3221225984, 24)), net)
924
925        self.assertEqual(ipaddress.IPv4Interface(('192.0.2.1', 24)),
926                         ipaddress.IPv4Interface('192.0.2.1/24'))
927        self.assertEqual(ipaddress.IPv4Interface((3221225985, 24)),
928                         ipaddress.IPv4Interface('192.0.2.1/24'))
929
930    # issue #16531: constructing IPv6Network from an (address, mask) tuple
931    def testIPv6Tuple(self):
932        # /128
933        ip = ipaddress.IPv6Address('2001:db8::')
934        net = ipaddress.IPv6Network('2001:db8::/128')
935        self.assertEqual(
936            ipaddress.IPv6Network(('2001:db8::', '128')),
937            net)
938        self.assertEqual(
939            ipaddress.IPv6Network(
940                (42540766411282592856903984951653826560, 128)),
941            net)
942        self.assertEqual(ipaddress.IPv6Network((ip, '128')),
943                         net)
944        ip = ipaddress.IPv6Address('2001:db8::')
945        net = ipaddress.IPv6Network('2001:db8::/96')
946        self.assertEqual(
947            ipaddress.IPv6Network(('2001:db8::', '96')),
948            net)
949        self.assertEqual(
950            ipaddress.IPv6Network(
951                (42540766411282592856903984951653826560, 96)),
952            net)
953        self.assertEqual(
954            ipaddress.IPv6Network((ip, '96')),
955            net)
956
957        # strict=True and host bits set
958        ip = ipaddress.IPv6Address('2001:db8::1')
959        self.assertRaises(
960            ValueError, ipaddress.IPv6Network, ('2001:db8::1', 96))
961        self.assertRaises(
962            ValueError, ipaddress.IPv6Network,
963            (42540766411282592856903984951653826561, 96))
964        self.assertRaises(ValueError, ipaddress.IPv6Network, (ip, 96))
965        # strict=False and host bits set
966        net = ipaddress.IPv6Network('2001:db8::/96')
967        self.assertEqual(ipaddress.IPv6Network(('2001:db8::1', 96),
968                                               strict=False),
969                         net)
970        self.assertEqual(
971            ipaddress.IPv6Network(
972                (42540766411282592856903984951653826561, 96), strict=False),
973            net)
974        self.assertEqual(
975            ipaddress.IPv6Network((ip, 96), strict=False),
976            net)
977
978        # /96
979        self.assertEqual(ipaddress.IPv6Interface(('2001:db8::1', '96')),
980                         ipaddress.IPv6Interface('2001:db8::1/96'))
981        self.assertEqual(
982            ipaddress.IPv6Interface(
983                (42540766411282592856903984951653826561, '96')),
984            ipaddress.IPv6Interface('2001:db8::1/96'))
985
986    # issue57
987    def testAddressIntMath(self):
988        self.assertEqual(ipaddress.IPv4Address('1.1.1.1') + 255,
989                         ipaddress.IPv4Address('1.1.2.0'))
990        self.assertEqual(ipaddress.IPv4Address('1.1.1.1') - 256,
991                         ipaddress.IPv4Address('1.1.0.1'))
992        self.assertEqual(ipaddress.IPv6Address('::1') + (2 ** 16 - 2),
993                         ipaddress.IPv6Address('::ffff'))
994        self.assertEqual(ipaddress.IPv6Address('::ffff') - (2 ** 16 - 2),
995                         ipaddress.IPv6Address('::1'))
996
997    def testInvalidIntToBytes(self):
998        self.assertRaises(ValueError, ipaddress.v4_int_to_packed, -1)
999        self.assertRaises(ValueError, ipaddress.v4_int_to_packed,
1000                          2 ** ipaddress.IPV4LENGTH)
1001        self.assertRaises(ValueError, ipaddress.v6_int_to_packed, -1)
1002        self.assertRaises(ValueError, ipaddress.v6_int_to_packed,
1003                          2 ** ipaddress.IPV6LENGTH)
1004
1005    def testInternals(self):
1006        ip1 = ipaddress.IPv4Address('10.10.10.10')
1007        ip2 = ipaddress.IPv4Address('10.10.10.11')
1008        ip3 = ipaddress.IPv4Address('10.10.10.12')
1009        self.assertEqual(list(ipaddress._find_address_range([ip1])),
1010                         [(ip1, ip1)])
1011        self.assertEqual(list(ipaddress._find_address_range([ip1, ip3])),
1012                         [(ip1, ip1), (ip3, ip3)])
1013        self.assertEqual(list(ipaddress._find_address_range([ip1, ip2, ip3])),
1014                         [(ip1, ip3)])
1015        self.assertEqual(128, ipaddress._count_righthand_zero_bits(0, 128))
1016        self.assertTrue(
1017            re.match(r"IPv4Network\(u?'1.2.3.0/24'\)",
1018                     repr(self.ipv4_network)))
1019
1020    def testMissingAddressVersion(self):
1021        class Broken(ipaddress._BaseAddress):
1022            pass
1023        broken = Broken()
1024        with self.assertRaisesRegex(NotImplementedError, "Broken.*version"):
1025            broken.version
1026
1027    def testMissingNetworkVersion(self):
1028        class Broken(ipaddress._BaseNetwork):
1029            pass
1030        broken = Broken('127.0.0.1')
1031        with self.assertRaisesRegex(NotImplementedError, "Broken.*version"):
1032            broken.version
1033
1034    def testMissingAddressClass(self):
1035        class Broken(ipaddress._BaseNetwork):
1036            pass
1037        broken = Broken('127.0.0.1')
1038        with self.assertRaisesRegex(NotImplementedError, "Broken.*address"):
1039            broken._address_class
1040
1041    def testGetNetwork(self):
1042        self.assertEqual(int(self.ipv4_network.network_address), 16909056)
1043        self.assertEqual(
1044            _compat_str(self.ipv4_network.network_address),
1045            '1.2.3.0')
1046
1047        self.assertEqual(int(self.ipv6_network.network_address),
1048                         42540616829182469433403647294022090752)
1049        self.assertEqual(_compat_str(self.ipv6_network.network_address),
1050                         '2001:658:22a:cafe::')
1051        self.assertEqual(_compat_str(self.ipv6_network.hostmask),
1052                         '::ffff:ffff:ffff:ffff')
1053
1054    def testIpFromInt(self):
1055        self.assertEqual(self.ipv4_interface._ip,
1056                         ipaddress.IPv4Interface(16909060)._ip)
1057
1058        ipv4 = ipaddress.ip_network('1.2.3.4')
1059        ipv6 = ipaddress.ip_network('2001:658:22a:cafe:200:0:0:1')
1060        self.assertEqual(ipv4, ipaddress.ip_network(int(ipv4.network_address)))
1061        self.assertEqual(ipv6, ipaddress.ip_network(int(ipv6.network_address)))
1062
1063        v6_int = 42540616829182469433547762482097946625
1064        self.assertEqual(self.ipv6_interface._ip,
1065                         ipaddress.IPv6Interface(v6_int)._ip)
1066
1067        self.assertEqual(ipaddress.ip_network(self.ipv4_address._ip).version,
1068                         4)
1069        self.assertEqual(ipaddress.ip_network(self.ipv6_address._ip).version,
1070                         6)
1071
1072    def testIpFromPacked(self):
1073        address = ipaddress.ip_address
1074        self.assertEqual(self.ipv4_interface._ip,
1075                         ipaddress.ip_interface(b'\x01\x02\x03\x04')._ip)
1076        self.assertEqual(address('255.254.253.252'),
1077                         address(b'\xff\xfe\xfd\xfc'))
1078        self.assertEqual(
1079            self.ipv6_interface.ip,
1080            ipaddress.ip_interface(
1081                b'\x20\x01\x06\x58\x02\x2a\xca\xfe'
1082                b'\x02\x00\x00\x00\x00\x00\x00\x01').ip)
1083        self.assertEqual(
1084            address('ffff:2:3:4:ffff::'),
1085            address(b'\xff\xff\x00\x02\x00\x03\x00\x04' +
1086                    b'\xff\xff' + b'\x00' * 6))
1087        self.assertEqual(address('::'),
1088                         address(b'\x00' * 16))
1089
1090    def testGetIp(self):
1091        self.assertEqual(int(self.ipv4_interface.ip), 16909060)
1092        self.assertEqual(_compat_str(self.ipv4_interface.ip), '1.2.3.4')
1093
1094        self.assertEqual(int(self.ipv6_interface.ip),
1095                         42540616829182469433547762482097946625)
1096        self.assertEqual(_compat_str(self.ipv6_interface.ip),
1097                         '2001:658:22a:cafe:200::1')
1098
1099    def testGetNetmask(self):
1100        self.assertEqual(int(self.ipv4_network.netmask), 4294967040)
1101        self.assertEqual(
1102            _compat_str(self.ipv4_network.netmask),
1103            '255.255.255.0')
1104        self.assertEqual(int(self.ipv6_network.netmask),
1105                         340282366920938463444927863358058659840)
1106        self.assertEqual(self.ipv6_network.prefixlen, 64)
1107
1108    def testZeroNetmask(self):
1109        ipv4_zero_netmask = ipaddress.IPv4Interface('1.2.3.4/0')
1110        self.assertEqual(int(ipv4_zero_netmask.network.netmask), 0)
1111        self.assertEqual(ipv4_zero_netmask._prefix_from_prefix_string('0'), 0)
1112        # Removed all _is_valid_netmask tests - the method was unused upstream
1113
1114        ipv6_zero_netmask = ipaddress.IPv6Interface('::1/0')
1115        self.assertEqual(int(ipv6_zero_netmask.network.netmask), 0)
1116        self.assertEqual(ipv6_zero_netmask._prefix_from_prefix_string('0'), 0)
1117
1118    def testIPv4NetAndHostmasks(self):
1119        net = self.ipv4_network
1120        # Removed all _is_valid_netmask tests - the method was unused upstream
1121        self.assertFalse(net._is_hostmask('invalid'))
1122        self.assertTrue(net._is_hostmask('128.255.255.255'))
1123        self.assertFalse(net._is_hostmask('255.255.255.255'))
1124        self.assertFalse(net._is_hostmask('1.2.3.4'))
1125
1126        net = ipaddress.IPv4Network('127.0.0.0/0.0.0.255')
1127        self.assertEqual(net.prefixlen, 24)
1128
1129    def testGetBroadcast(self):
1130        self.assertEqual(int(self.ipv4_network.broadcast_address), 16909311)
1131        self.assertEqual(
1132            _compat_str(self.ipv4_network.broadcast_address),
1133            '1.2.3.255')
1134
1135        self.assertEqual(int(self.ipv6_network.broadcast_address),
1136                         42540616829182469451850391367731642367)
1137        self.assertEqual(_compat_str(self.ipv6_network.broadcast_address),
1138                         '2001:658:22a:cafe:ffff:ffff:ffff:ffff')
1139
1140    def testGetPrefixlen(self):
1141        self.assertEqual(self.ipv4_interface.network.prefixlen, 24)
1142        self.assertEqual(self.ipv6_interface.network.prefixlen, 64)
1143
1144    def testGetSupernet(self):
1145        self.assertEqual(self.ipv4_network.supernet().prefixlen, 23)
1146        self.assertEqual(
1147            _compat_str(self.ipv4_network.supernet().network_address),
1148            '1.2.2.0')
1149        self.assertEqual(
1150            ipaddress.IPv4Interface('0.0.0.0/0').network.supernet(),
1151            ipaddress.IPv4Network('0.0.0.0/0'))
1152
1153        self.assertEqual(self.ipv6_network.supernet().prefixlen, 63)
1154        self.assertEqual(
1155            _compat_str(self.ipv6_network.supernet().network_address),
1156            '2001:658:22a:cafe::')
1157        self.assertEqual(
1158            ipaddress.IPv6Interface('::0/0').network.supernet(),
1159            ipaddress.IPv6Network('::0/0'))
1160
1161    def testGetSupernet3(self):
1162        self.assertEqual(self.ipv4_network.supernet(3).prefixlen, 21)
1163        self.assertEqual(
1164            _compat_str(self.ipv4_network.supernet(3).network_address),
1165            '1.2.0.0')
1166
1167        self.assertEqual(self.ipv6_network.supernet(3).prefixlen, 61)
1168        self.assertEqual(
1169            _compat_str(self.ipv6_network.supernet(3).network_address),
1170            '2001:658:22a:caf8::')
1171
1172    def testGetSupernet4(self):
1173        self.assertRaises(ValueError, self.ipv4_network.supernet,
1174                          prefixlen_diff=2, new_prefix=1)
1175        self.assertRaises(ValueError, self.ipv4_network.supernet,
1176                          new_prefix=25)
1177        self.assertEqual(self.ipv4_network.supernet(prefixlen_diff=2),
1178                         self.ipv4_network.supernet(new_prefix=22))
1179
1180        self.assertRaises(ValueError, self.ipv6_network.supernet,
1181                          prefixlen_diff=2, new_prefix=1)
1182        self.assertRaises(ValueError, self.ipv6_network.supernet,
1183                          new_prefix=65)
1184        self.assertEqual(self.ipv6_network.supernet(prefixlen_diff=2),
1185                         self.ipv6_network.supernet(new_prefix=62))
1186
1187    def testHosts(self):
1188        hosts = list(self.ipv4_network.hosts())
1189        self.assertEqual(254, len(hosts))
1190        self.assertEqual(ipaddress.IPv4Address('1.2.3.1'), hosts[0])
1191        self.assertEqual(ipaddress.IPv4Address('1.2.3.254'), hosts[-1])
1192
1193        # special case where only 1 bit is left for address
1194        self.assertEqual([ipaddress.IPv4Address('2.0.0.0'),
1195                          ipaddress.IPv4Address('2.0.0.1')],
1196                         list(ipaddress.ip_network('2.0.0.0/31').hosts()))
1197
1198    def testFancySubnetting(self):
1199        self.assertEqual(sorted(self.ipv4_network.subnets(prefixlen_diff=3)),
1200                         sorted(self.ipv4_network.subnets(new_prefix=27)))
1201        self.assertRaises(ValueError, list,
1202                          self.ipv4_network.subnets(new_prefix=23))
1203        self.assertRaises(ValueError, list,
1204                          self.ipv4_network.subnets(prefixlen_diff=3,
1205                                                    new_prefix=27))
1206        self.assertEqual(sorted(self.ipv6_network.subnets(prefixlen_diff=4)),
1207                         sorted(self.ipv6_network.subnets(new_prefix=68)))
1208        self.assertRaises(ValueError, list,
1209                          self.ipv6_network.subnets(new_prefix=63))
1210        self.assertRaises(ValueError, list,
1211                          self.ipv6_network.subnets(prefixlen_diff=4,
1212                                                    new_prefix=68))
1213
1214    def testGetSubnets(self):
1215        self.assertEqual(list(self.ipv4_network.subnets())[0].prefixlen, 25)
1216        self.assertEqual(
1217            _compat_str(list(self.ipv4_network.subnets())[0].network_address),
1218            '1.2.3.0')
1219        self.assertEqual(
1220            _compat_str(list(self.ipv4_network.subnets())[1].network_address),
1221            '1.2.3.128')
1222
1223        self.assertEqual(list(self.ipv6_network.subnets())[0].prefixlen, 65)
1224
1225    def testGetSubnetForSingle32(self):
1226        ip = ipaddress.IPv4Network('1.2.3.4/32')
1227        subnets1 = [_compat_str(x) for x in ip.subnets()]
1228        subnets2 = [_compat_str(x) for x in ip.subnets(2)]
1229        self.assertEqual(subnets1, ['1.2.3.4/32'])
1230        self.assertEqual(subnets1, subnets2)
1231
1232    def testGetSubnetForSingle128(self):
1233        ip = ipaddress.IPv6Network('::1/128')
1234        subnets1 = [_compat_str(x) for x in ip.subnets()]
1235        subnets2 = [_compat_str(x) for x in ip.subnets(2)]
1236        self.assertEqual(subnets1, ['::1/128'])
1237        self.assertEqual(subnets1, subnets2)
1238
1239    def testSubnet2(self):
1240        ips = [str(x) for x in self.ipv4_network.subnets(2)]
1241        self.assertEqual(
1242            ips,
1243            ['1.2.3.0/26', '1.2.3.64/26', '1.2.3.128/26', '1.2.3.192/26'])
1244
1245        ipsv6 = [str(x) for x in self.ipv6_network.subnets(2)]
1246        self.assertEqual(
1247            ipsv6,
1248            ['2001:658:22a:cafe::/66',
1249             '2001:658:22a:cafe:4000::/66',
1250             '2001:658:22a:cafe:8000::/66',
1251             '2001:658:22a:cafe:c000::/66'])
1252
1253    def testGetSubnets3(self):
1254        subnets = [str(x) for x in self.ipv4_network.subnets(8)]
1255        self.assertEqual(
1256            subnets[:3],
1257            ['1.2.3.0/32', '1.2.3.1/32', '1.2.3.2/32'])
1258        self.assertEqual(
1259            subnets[-3:],
1260            ['1.2.3.253/32', '1.2.3.254/32', '1.2.3.255/32'])
1261        self.assertEqual(len(subnets), 256)
1262
1263        ipv6_network = ipaddress.IPv6Network('2001:658:22a:cafe::/120')
1264        subnets = [str(x) for x in ipv6_network.subnets(8)]
1265        self.assertEqual(
1266            subnets[:3],
1267            ['2001:658:22a:cafe::/128',
1268             '2001:658:22a:cafe::1/128',
1269             '2001:658:22a:cafe::2/128'])
1270        self.assertEqual(
1271            subnets[-3:],
1272            ['2001:658:22a:cafe::fd/128',
1273             '2001:658:22a:cafe::fe/128',
1274             '2001:658:22a:cafe::ff/128'])
1275        self.assertEqual(len(subnets), 256)
1276
1277    def testSubnetFailsForLargeCidrDiff(self):
1278        self.assertRaises(ValueError, list,
1279                          self.ipv4_interface.network.subnets(9))
1280        self.assertRaises(ValueError, list,
1281                          self.ipv4_network.subnets(9))
1282        self.assertRaises(ValueError, list,
1283                          self.ipv6_interface.network.subnets(65))
1284        self.assertRaises(ValueError, list,
1285                          self.ipv6_network.subnets(65))
1286
1287    def testSupernetFailsForLargeCidrDiff(self):
1288        self.assertRaises(ValueError,
1289                          self.ipv4_interface.network.supernet, 25)
1290        self.assertRaises(ValueError,
1291                          self.ipv6_interface.network.supernet, 65)
1292
1293    def testSubnetFailsForNegativeCidrDiff(self):
1294        self.assertRaises(ValueError, list,
1295                          self.ipv4_interface.network.subnets(-1))
1296        self.assertRaises(ValueError, list,
1297                          self.ipv4_network.subnets(-1))
1298        self.assertRaises(ValueError, list,
1299                          self.ipv6_interface.network.subnets(-1))
1300        self.assertRaises(ValueError, list,
1301                          self.ipv6_network.subnets(-1))
1302
1303    def testGetNum_Addresses(self):
1304        self.assertEqual(self.ipv4_network.num_addresses, 256)
1305        self.assertEqual(list(self.ipv4_network.subnets())[0].num_addresses,
1306                         128)
1307        self.assertEqual(self.ipv4_network.supernet().num_addresses, 512)
1308
1309        self.assertEqual(self.ipv6_network.num_addresses, 18446744073709551616)
1310        self.assertEqual(list(self.ipv6_network.subnets())[0].num_addresses,
1311                         9223372036854775808)
1312        self.assertEqual(self.ipv6_network.supernet().num_addresses,
1313                         36893488147419103232)
1314
1315    def testContains(self):
1316        self.assertTrue(ipaddress.IPv4Interface('1.2.3.128/25') in
1317                        self.ipv4_network)
1318        self.assertFalse(ipaddress.IPv4Interface('1.2.4.1/24') in
1319                         self.ipv4_network)
1320        # We can test addresses and string as well.
1321        addr1 = ipaddress.IPv4Address('1.2.3.37')
1322        self.assertTrue(addr1 in self.ipv4_network)
1323        # issue 61, bad network comparison on like-ip'd network objects
1324        # with identical broadcast addresses.
1325        self.assertFalse(ipaddress.IPv4Network('1.1.0.0/16').__contains__(
1326            ipaddress.IPv4Network('1.0.0.0/15')))
1327
1328    def testNth(self):
1329        self.assertEqual(_compat_str(self.ipv4_network[5]), '1.2.3.5')
1330        self.assertRaises(IndexError, self.ipv4_network.__getitem__, 256)
1331
1332        self.assertEqual(_compat_str(self.ipv6_network[5]),
1333                         '2001:658:22a:cafe::5')
1334        self.assertRaises(IndexError, self.ipv6_network.__getitem__, 1 << 64)
1335
1336    def testGetitem(self):
1337        # http://code.google.com/p/ipaddr-py/issues/detail?id=15
1338        addr = ipaddress.IPv4Network('172.31.255.128/255.255.255.240')
1339        self.assertEqual(28, addr.prefixlen)
1340        addr_list = list(addr)
1341        self.assertEqual('172.31.255.128', str(addr_list[0]))
1342        self.assertEqual('172.31.255.128', str(addr[0]))
1343        self.assertEqual('172.31.255.143', str(addr_list[-1]))
1344        self.assertEqual('172.31.255.143', str(addr[-1]))
1345        self.assertEqual(addr_list[-1], addr[-1])
1346
1347    def testEqual(self):
1348        self.assertTrue(self.ipv4_interface ==
1349                        ipaddress.IPv4Interface('1.2.3.4/24'))
1350        self.assertFalse(self.ipv4_interface ==
1351                         ipaddress.IPv4Interface('1.2.3.4/23'))
1352        self.assertFalse(self.ipv4_interface ==
1353                         ipaddress.IPv6Interface('::1.2.3.4/24'))
1354        self.assertFalse(self.ipv4_interface == '')
1355        self.assertFalse(self.ipv4_interface == [])
1356        self.assertFalse(self.ipv4_interface == 2)
1357
1358        self.assertTrue(
1359            self.ipv6_interface ==
1360            ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/64'))
1361        self.assertFalse(
1362            self.ipv6_interface ==
1363            ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/63'))
1364        self.assertFalse(self.ipv6_interface ==
1365                         ipaddress.IPv4Interface('1.2.3.4/23'))
1366        self.assertFalse(self.ipv6_interface == '')
1367        self.assertFalse(self.ipv6_interface == [])
1368        self.assertFalse(self.ipv6_interface == 2)
1369
1370    def testNotEqual(self):
1371        self.assertFalse(self.ipv4_interface !=
1372                         ipaddress.IPv4Interface('1.2.3.4/24'))
1373        self.assertTrue(self.ipv4_interface !=
1374                        ipaddress.IPv4Interface('1.2.3.4/23'))
1375        self.assertTrue(self.ipv4_interface !=
1376                        ipaddress.IPv6Interface('::1.2.3.4/24'))
1377        self.assertTrue(self.ipv4_interface != '')
1378        self.assertTrue(self.ipv4_interface != [])
1379        self.assertTrue(self.ipv4_interface != 2)
1380
1381        self.assertTrue(self.ipv4_address !=
1382                        ipaddress.IPv4Address('1.2.3.5'))
1383        self.assertTrue(self.ipv4_address != '')
1384        self.assertTrue(self.ipv4_address != [])
1385        self.assertTrue(self.ipv4_address != 2)
1386
1387        self.assertFalse(
1388            self.ipv6_interface !=
1389            ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/64'))
1390        self.assertTrue(
1391            self.ipv6_interface !=
1392            ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/63'))
1393        self.assertTrue(self.ipv6_interface !=
1394                        ipaddress.IPv4Interface('1.2.3.4/23'))
1395        self.assertTrue(self.ipv6_interface != '')
1396        self.assertTrue(self.ipv6_interface != [])
1397        self.assertTrue(self.ipv6_interface != 2)
1398
1399        self.assertTrue(self.ipv6_address !=
1400                        ipaddress.IPv4Address('1.2.3.4'))
1401        self.assertTrue(self.ipv6_address != '')
1402        self.assertTrue(self.ipv6_address != [])
1403        self.assertTrue(self.ipv6_address != 2)
1404
1405    def testSlash32Constructor(self):
1406        self.assertEqual(
1407            _compat_str(ipaddress.IPv4Interface('1.2.3.4/255.255.255.255')),
1408            '1.2.3.4/32')
1409
1410    def testSlash128Constructor(self):
1411        self.assertEqual(
1412            _compat_str(ipaddress.IPv6Interface('::1/128')),
1413            '::1/128')
1414
1415    def testSlash0Constructor(self):
1416        self.assertEqual(
1417            _compat_str(ipaddress.IPv4Interface('1.2.3.4/0.0.0.0')),
1418            '1.2.3.4/0')
1419
1420    def testCollapsing(self):
1421        # test only IP addresses including some duplicates
1422        ip1 = ipaddress.IPv4Address('1.1.1.0')
1423        ip2 = ipaddress.IPv4Address('1.1.1.1')
1424        ip3 = ipaddress.IPv4Address('1.1.1.2')
1425        ip4 = ipaddress.IPv4Address('1.1.1.3')
1426        ip5 = ipaddress.IPv4Address('1.1.1.4')
1427        ip6 = ipaddress.IPv4Address('1.1.1.0')
1428        # check that addresses are subsumed properly.
1429        collapsed = ipaddress.collapse_addresses(
1430            [ip1, ip2, ip3, ip4, ip5, ip6])
1431        self.assertEqual(
1432            list(collapsed),
1433            [ipaddress.IPv4Network('1.1.1.0/30'),
1434             ipaddress.IPv4Network('1.1.1.4/32')])
1435
1436        # test a mix of IP addresses and networks including some duplicates
1437        ip1 = ipaddress.IPv4Address('1.1.1.0')
1438        ip2 = ipaddress.IPv4Address('1.1.1.1')
1439        ip3 = ipaddress.IPv4Address('1.1.1.2')
1440        ip4 = ipaddress.IPv4Address('1.1.1.3')
1441        # check that addreses are subsumed properly.
1442        collapsed = ipaddress.collapse_addresses([ip1, ip2, ip3, ip4])
1443        self.assertEqual(list(collapsed),
1444                         [ipaddress.IPv4Network('1.1.1.0/30')])
1445
1446        # test only IP networks
1447        ip1 = ipaddress.IPv4Network('1.1.0.0/24')
1448        ip2 = ipaddress.IPv4Network('1.1.1.0/24')
1449        ip3 = ipaddress.IPv4Network('1.1.2.0/24')
1450        ip4 = ipaddress.IPv4Network('1.1.3.0/24')
1451        ip5 = ipaddress.IPv4Network('1.1.4.0/24')
1452        # stored in no particular order b/c we want CollapseAddr to call
1453        # [].sort
1454        ip6 = ipaddress.IPv4Network('1.1.0.0/22')
1455
1456        # check that addreses are subsumed properly.
1457        collapsed = ipaddress.collapse_addresses(
1458            [ip1, ip2, ip3, ip4, ip5, ip6])
1459
1460        self.assertEqual(list(collapsed),
1461                         [ipaddress.IPv4Network('1.1.0.0/22'),
1462                          ipaddress.IPv4Network('1.1.4.0/24')])
1463
1464        # test that two addresses are supernet'ed properly
1465        collapsed = ipaddress.collapse_addresses([ip1, ip2])
1466        self.assertEqual(list(collapsed),
1467                         [ipaddress.IPv4Network('1.1.0.0/23')])
1468
1469        # test same IP networks
1470        ip_same1 = ip_same2 = ipaddress.IPv4Network('1.1.1.1/32')
1471        self.assertEqual(
1472            list(ipaddress.collapse_addresses([ip_same1, ip_same2])),
1473            [ip_same1])
1474
1475        # test same IP addresses
1476        ip_same1 = ip_same2 = ipaddress.IPv4Address('1.1.1.1')
1477        self.assertEqual(
1478            list(ipaddress.collapse_addresses([ip_same1, ip_same2])),
1479            [ipaddress.ip_network('1.1.1.1/32')])
1480        ip1 = ipaddress.IPv6Network('2001::/100')
1481        ip2 = ipaddress.IPv6Network('2001::/120')
1482        ip3 = ipaddress.IPv6Network('2001::/96')
1483        # test that ipv6 addresses are subsumed properly.
1484        collapsed = ipaddress.collapse_addresses([ip1, ip2, ip3])
1485        self.assertEqual(list(collapsed), [ip3])
1486
1487        # the toejam test
1488        addr_tuples = [
1489            (ipaddress.ip_address('1.1.1.1'),
1490             ipaddress.ip_address('::1')),
1491            (ipaddress.IPv4Network('1.1.0.0/24'),
1492             ipaddress.IPv6Network('2001::/120')),
1493            (ipaddress.IPv4Network('1.1.0.0/32'),
1494             ipaddress.IPv6Network('2001::/128')),
1495        ]
1496        for ip1, ip2 in addr_tuples:
1497            self.assertRaises(TypeError, ipaddress.collapse_addresses,
1498                              [ip1, ip2])
1499
1500    def testSummarizing(self):
1501        summarize = ipaddress.summarize_address_range
1502        ip1 = ipaddress.ip_address('1.1.1.0')
1503        ip2 = ipaddress.ip_address('1.1.1.255')
1504
1505        # summarize works only for IPv4 & IPv6
1506        class IPv7Address(ipaddress.IPv6Address):
1507            @property
1508            def version(self):
1509                return 7
1510        ip_invalid1 = IPv7Address('::1')
1511        ip_invalid2 = IPv7Address('::1')
1512        self.assertRaises(ValueError, list,
1513                          summarize(ip_invalid1, ip_invalid2))
1514        # test that a summary over ip4 & ip6 fails
1515        self.assertRaises(TypeError, list,
1516                          summarize(ip1, ipaddress.IPv6Address('::1')))
1517        # test a /24 is summarized properly
1518        self.assertEqual(list(summarize(ip1, ip2))[0],
1519                         ipaddress.ip_network('1.1.1.0/24'))
1520        # test an IPv4 range that isn't on a network byte boundary
1521        ip2 = ipaddress.ip_address('1.1.1.8')
1522        self.assertEqual(list(summarize(ip1, ip2)),
1523                         [ipaddress.ip_network('1.1.1.0/29'),
1524                          ipaddress.ip_network('1.1.1.8')])
1525        # all!
1526        ip1 = ipaddress.IPv4Address(0)
1527        ip2 = ipaddress.IPv4Address(ipaddress.IPv4Address._ALL_ONES)
1528        self.assertEqual([ipaddress.IPv4Network('0.0.0.0/0')],
1529                         list(summarize(ip1, ip2)))
1530
1531        ip1 = ipaddress.ip_address('1::')
1532        ip2 = ipaddress.ip_address('1:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
1533        # test an IPv6 is summarized properly
1534        self.assertEqual(list(summarize(ip1, ip2))[0],
1535                         ipaddress.ip_network('1::/16'))
1536        # test an IPv6 range that isn't on a network byte boundary
1537        ip2 = ipaddress.ip_address('2::')
1538        self.assertEqual(list(summarize(ip1, ip2)),
1539                         [ipaddress.ip_network('1::/16'),
1540                          ipaddress.ip_network('2::/128')])
1541
1542        # test exception raised when first is greater than last
1543        self.assertRaises(ValueError, list,
1544                          summarize(ipaddress.ip_address('1.1.1.0'),
1545                                    ipaddress.ip_address('1.1.0.0')))
1546        # test exception raised when first and last aren't IP addresses
1547        self.assertRaises(TypeError, list,
1548                          summarize(ipaddress.ip_network('1.1.1.0'),
1549                                    ipaddress.ip_network('1.1.0.0')))
1550        self.assertRaises(TypeError, list,
1551                          summarize(ipaddress.ip_network('1.1.1.0'),
1552                                    ipaddress.ip_network('1.1.0.0')))
1553        # test exception raised when first and last are not same version
1554        self.assertRaises(TypeError, list,
1555                          summarize(ipaddress.ip_address('::'),
1556                                    ipaddress.ip_network('1.1.0.0')))
1557
1558    def testAddressComparison(self):
1559        self.assertTrue(ipaddress.ip_address('1.1.1.1') <=
1560                        ipaddress.ip_address('1.1.1.1'))
1561        self.assertTrue(ipaddress.ip_address('1.1.1.1') <=
1562                        ipaddress.ip_address('1.1.1.2'))
1563        self.assertTrue(ipaddress.ip_address('::1') <=
1564                        ipaddress.ip_address('::1'))
1565        self.assertTrue(ipaddress.ip_address('::1') <=
1566                        ipaddress.ip_address('::2'))
1567
1568    def testInterfaceComparison(self):
1569        self.assertTrue(ipaddress.ip_interface('1.1.1.1/24') ==
1570                        ipaddress.ip_interface('1.1.1.1/24'))
1571        self.assertTrue(ipaddress.ip_interface('1.1.1.1/16') <
1572                        ipaddress.ip_interface('1.1.1.1/24'))
1573        self.assertTrue(ipaddress.ip_interface('1.1.1.1/24') <
1574                        ipaddress.ip_interface('1.1.1.2/24'))
1575        self.assertTrue(ipaddress.ip_interface('1.1.1.2/16') <
1576                        ipaddress.ip_interface('1.1.1.1/24'))
1577        self.assertTrue(ipaddress.ip_interface('1.1.1.1/24') >
1578                        ipaddress.ip_interface('1.1.1.1/16'))
1579        self.assertTrue(ipaddress.ip_interface('1.1.1.2/24') >
1580                        ipaddress.ip_interface('1.1.1.1/24'))
1581        self.assertTrue(ipaddress.ip_interface('1.1.1.1/24') >
1582                        ipaddress.ip_interface('1.1.1.2/16'))
1583
1584        self.assertTrue(ipaddress.ip_interface('::1/64') ==
1585                        ipaddress.ip_interface('::1/64'))
1586        self.assertTrue(ipaddress.ip_interface('::1/64') <
1587                        ipaddress.ip_interface('::1/80'))
1588        self.assertTrue(ipaddress.ip_interface('::1/64') <
1589                        ipaddress.ip_interface('::2/64'))
1590        self.assertTrue(ipaddress.ip_interface('::2/48') <
1591                        ipaddress.ip_interface('::1/64'))
1592        self.assertTrue(ipaddress.ip_interface('::1/80') >
1593                        ipaddress.ip_interface('::1/64'))
1594        self.assertTrue(ipaddress.ip_interface('::2/64') >
1595                        ipaddress.ip_interface('::1/64'))
1596        self.assertTrue(ipaddress.ip_interface('::1/64') >
1597                        ipaddress.ip_interface('::2/48'))
1598
1599    def testNetworkComparison(self):
1600        # ip1 and ip2 have the same network address
1601        ip1 = ipaddress.IPv4Network('1.1.1.0/24')
1602        ip2 = ipaddress.IPv4Network('1.1.1.0/32')
1603        ip3 = ipaddress.IPv4Network('1.1.2.0/24')
1604
1605        self.assertTrue(ip1 < ip3)
1606        self.assertTrue(ip3 > ip2)
1607
1608        self.assertEqual(ip1.compare_networks(ip1), 0)
1609
1610        # if addresses are the same, sort by netmask
1611        self.assertEqual(ip1.compare_networks(ip2), -1)
1612        self.assertEqual(ip2.compare_networks(ip1), 1)
1613
1614        self.assertEqual(ip1.compare_networks(ip3), -1)
1615        self.assertEqual(ip3.compare_networks(ip1), 1)
1616        self.assertTrue(ip1._get_networks_key() < ip3._get_networks_key())
1617
1618        ip1 = ipaddress.IPv6Network('2001:2000::/96')
1619        ip2 = ipaddress.IPv6Network('2001:2001::/96')
1620        ip3 = ipaddress.IPv6Network('2001:ffff:2000::/96')
1621
1622        self.assertTrue(ip1 < ip3)
1623        self.assertTrue(ip3 > ip2)
1624        self.assertEqual(ip1.compare_networks(ip3), -1)
1625        self.assertTrue(ip1._get_networks_key() < ip3._get_networks_key())
1626
1627        # Test comparing different protocols.
1628        # Should always raise a TypeError.
1629        self.assertRaises(TypeError,
1630                          self.ipv4_network.compare_networks,
1631                          self.ipv6_network)
1632        ipv6 = ipaddress.IPv6Interface('::/0')
1633        ipv4 = ipaddress.IPv4Interface('0.0.0.0/0')
1634        self.assertRaises(TypeError, ipv4.__lt__, ipv6)
1635        self.assertRaises(TypeError, ipv4.__gt__, ipv6)
1636        self.assertRaises(TypeError, ipv6.__lt__, ipv4)
1637        self.assertRaises(TypeError, ipv6.__gt__, ipv4)
1638
1639        # Regression test for issue 19.
1640        ip1 = ipaddress.ip_network('10.1.2.128/25')
1641        self.assertFalse(ip1 < ip1)
1642        self.assertFalse(ip1 > ip1)
1643        ip2 = ipaddress.ip_network('10.1.3.0/24')
1644        self.assertTrue(ip1 < ip2)
1645        self.assertFalse(ip2 < ip1)
1646        self.assertFalse(ip1 > ip2)
1647        self.assertTrue(ip2 > ip1)
1648        ip3 = ipaddress.ip_network('10.1.3.0/25')
1649        self.assertTrue(ip2 < ip3)
1650        self.assertFalse(ip3 < ip2)
1651        self.assertFalse(ip2 > ip3)
1652        self.assertTrue(ip3 > ip2)
1653
1654        # Regression test for issue 28.
1655        ip1 = ipaddress.ip_network('10.10.10.0/31')
1656        ip2 = ipaddress.ip_network('10.10.10.0')
1657        ip3 = ipaddress.ip_network('10.10.10.2/31')
1658        ip4 = ipaddress.ip_network('10.10.10.2')
1659        sorted = [ip1, ip2, ip3, ip4]
1660        unsorted = [ip2, ip4, ip1, ip3]
1661        unsorted.sort()
1662        self.assertEqual(sorted, unsorted)
1663        unsorted = [ip4, ip1, ip3, ip2]
1664        unsorted.sort()
1665        self.assertEqual(sorted, unsorted)
1666        self.assertRaises(TypeError, ip1.__lt__,
1667                          ipaddress.ip_address('10.10.10.0'))
1668        self.assertRaises(TypeError, ip2.__lt__,
1669                          ipaddress.ip_address('10.10.10.0'))
1670
1671        # <=, >=
1672        self.assertTrue(ipaddress.ip_network('1.1.1.1') <=
1673                        ipaddress.ip_network('1.1.1.1'))
1674        self.assertTrue(ipaddress.ip_network('1.1.1.1') <=
1675                        ipaddress.ip_network('1.1.1.2'))
1676        self.assertFalse(ipaddress.ip_network('1.1.1.2') <=
1677                         ipaddress.ip_network('1.1.1.1'))
1678        self.assertTrue(ipaddress.ip_network('::1') <=
1679                        ipaddress.ip_network('::1'))
1680        self.assertTrue(ipaddress.ip_network('::1') <=
1681                        ipaddress.ip_network('::2'))
1682        self.assertFalse(ipaddress.ip_network('::2') <=
1683                         ipaddress.ip_network('::1'))
1684
1685    def testStrictNetworks(self):
1686        self.assertRaises(ValueError, ipaddress.ip_network, '192.168.1.1/24')
1687        self.assertRaises(ValueError, ipaddress.ip_network, '::1/120')
1688
1689    def testOverlaps(self):
1690        other = ipaddress.IPv4Network('1.2.3.0/30')
1691        other2 = ipaddress.IPv4Network('1.2.2.0/24')
1692        other3 = ipaddress.IPv4Network('1.2.2.64/26')
1693        self.assertTrue(self.ipv4_network.overlaps(other))
1694        self.assertFalse(self.ipv4_network.overlaps(other2))
1695        self.assertTrue(other2.overlaps(other3))
1696
1697    def testEmbeddedIpv4(self):
1698        ipv4_string = '192.168.0.1'
1699        ipv4 = ipaddress.IPv4Interface(ipv4_string)
1700        v4compat_ipv6 = ipaddress.IPv6Interface('::%s' % ipv4_string)
1701        self.assertEqual(int(v4compat_ipv6.ip), int(ipv4.ip))
1702        v4mapped_ipv6 = ipaddress.IPv6Interface('::ffff:%s' % ipv4_string)
1703        self.assertNotEqual(v4mapped_ipv6.ip, ipv4.ip)
1704        self.assertRaises(ipaddress.AddressValueError, ipaddress.IPv6Interface,
1705                          '2001:1.1.1.1:1.1.1.1')
1706
1707    # Issue 67: IPv6 with embedded IPv4 address not recognized.
1708    def testIPv6AddressTooLarge(self):
1709        # RFC4291 2.5.5.2
1710        self.assertEqual(ipaddress.ip_address('::FFFF:192.0.2.1'),
1711                         ipaddress.ip_address('::FFFF:c000:201'))
1712        # RFC4291 2.2 (part 3) x::d.d.d.d
1713        self.assertEqual(ipaddress.ip_address('FFFF::192.0.2.1'),
1714                         ipaddress.ip_address('FFFF::c000:201'))
1715
1716    def testIPVersion(self):
1717        self.assertEqual(self.ipv4_address.version, 4)
1718        self.assertEqual(self.ipv6_address.version, 6)
1719
1720    def testMaxPrefixLength(self):
1721        self.assertEqual(self.ipv4_interface.max_prefixlen, 32)
1722        self.assertEqual(self.ipv6_interface.max_prefixlen, 128)
1723
1724    def testPacked(self):
1725        self.assertEqual(self.ipv4_address.packed,
1726                         b'\x01\x02\x03\x04')
1727        self.assertEqual(ipaddress.IPv4Interface('255.254.253.252').packed,
1728                         b'\xff\xfe\xfd\xfc')
1729        self.assertEqual(self.ipv6_address.packed,
1730                         b'\x20\x01\x06\x58\x02\x2a\xca\xfe'
1731                         b'\x02\x00\x00\x00\x00\x00\x00\x01')
1732        self.assertEqual(ipaddress.IPv6Interface('ffff:2:3:4:ffff::').packed,
1733                         b'\xff\xff\x00\x02\x00\x03\x00\x04\xff\xff' +
1734                         b'\x00' * 6)
1735        self.assertEqual(ipaddress.IPv6Interface('::1:0:0:0:0').packed,
1736                         b'\x00' * 6 + b'\x00\x01' + b'\x00' * 8)
1737
1738    def testIpType(self):
1739        ipv4net = ipaddress.ip_network('1.2.3.4')
1740        ipv4addr = ipaddress.ip_address('1.2.3.4')
1741        ipv6net = ipaddress.ip_network('::1.2.3.4')
1742        ipv6addr = ipaddress.ip_address('::1.2.3.4')
1743        self.assertEqual(ipaddress.IPv4Network, type(ipv4net))
1744        self.assertEqual(ipaddress.IPv4Address, type(ipv4addr))
1745        self.assertEqual(ipaddress.IPv6Network, type(ipv6net))
1746        self.assertEqual(ipaddress.IPv6Address, type(ipv6addr))
1747
1748    def testReservedIpv4(self):
1749        # test networks
1750        self.assertEqual(True, ipaddress.ip_interface(
1751            '224.1.1.1/31').is_multicast)
1752        self.assertEqual(False, ipaddress.ip_network('240.0.0.0').is_multicast)
1753        self.assertEqual(True, ipaddress.ip_network('240.0.0.0').is_reserved)
1754
1755        self.assertEqual(True, ipaddress.ip_interface(
1756            '192.168.1.1/17').is_private)
1757        self.assertEqual(False, ipaddress.ip_network('192.169.0.0').is_private)
1758        self.assertEqual(True, ipaddress.ip_network(
1759            '10.255.255.255').is_private)
1760        self.assertEqual(False, ipaddress.ip_network('11.0.0.0').is_private)
1761        self.assertEqual(False, ipaddress.ip_network('11.0.0.0').is_reserved)
1762        self.assertEqual(True, ipaddress.ip_network(
1763            '172.31.255.255').is_private)
1764        self.assertEqual(False, ipaddress.ip_network('172.32.0.0').is_private)
1765        self.assertEqual(True,
1766                         ipaddress.ip_network('169.254.1.0/24').is_link_local)
1767
1768        self.assertEqual(
1769            True,
1770            ipaddress.ip_interface('169.254.100.200/24').is_link_local)
1771        self.assertEqual(
1772            False,
1773            ipaddress.ip_interface('169.255.100.200/24').is_link_local)
1774
1775        self.assertEqual(
1776            True,
1777            ipaddress.ip_network('127.100.200.254/32').is_loopback)
1778        self.assertEqual(True, ipaddress.ip_network(
1779            '127.42.0.0/16').is_loopback)
1780        self.assertEqual(False, ipaddress.ip_network('128.0.0.0').is_loopback)
1781        self.assertEqual(False,
1782                         ipaddress.ip_network('100.64.0.0/10').is_private)
1783        self.assertEqual(
1784            False, ipaddress.ip_network('100.64.0.0/10').is_global)
1785
1786        self.assertEqual(True,
1787                         ipaddress.ip_network('192.0.2.128/25').is_private)
1788        self.assertEqual(True,
1789                         ipaddress.ip_network('192.0.3.0/24').is_global)
1790
1791        # test addresses
1792        self.assertEqual(True, ipaddress.ip_address('0.0.0.0').is_unspecified)
1793        self.assertEqual(True, ipaddress.ip_address('224.1.1.1').is_multicast)
1794        self.assertEqual(False, ipaddress.ip_address('240.0.0.0').is_multicast)
1795        self.assertEqual(True, ipaddress.ip_address('240.0.0.1').is_reserved)
1796        self.assertEqual(False,
1797                         ipaddress.ip_address('239.255.255.255').is_reserved)
1798
1799        self.assertEqual(True, ipaddress.ip_address('192.168.1.1').is_private)
1800        self.assertEqual(False, ipaddress.ip_address('192.169.0.0').is_private)
1801        self.assertEqual(True, ipaddress.ip_address(
1802            '10.255.255.255').is_private)
1803        self.assertEqual(False, ipaddress.ip_address('11.0.0.0').is_private)
1804        self.assertEqual(True, ipaddress.ip_address(
1805            '172.31.255.255').is_private)
1806        self.assertEqual(False, ipaddress.ip_address('172.32.0.0').is_private)
1807
1808        self.assertEqual(True,
1809                         ipaddress.ip_address('169.254.100.200').is_link_local)
1810        self.assertEqual(False,
1811                         ipaddress.ip_address('169.255.100.200').is_link_local)
1812
1813        self.assertTrue(ipaddress.ip_address('192.0.7.1').is_global)
1814        self.assertFalse(ipaddress.ip_address('203.0.113.1').is_global)
1815
1816        self.assertEqual(True,
1817                         ipaddress.ip_address('127.100.200.254').is_loopback)
1818        self.assertEqual(True, ipaddress.ip_address('127.42.0.0').is_loopback)
1819        self.assertEqual(False, ipaddress.ip_address('128.0.0.0').is_loopback)
1820        self.assertEqual(True, ipaddress.ip_network('0.0.0.0').is_unspecified)
1821
1822    def testReservedIpv6(self):
1823
1824        self.assertEqual(True, ipaddress.ip_network('ffff::').is_multicast)
1825        self.assertEqual(True, ipaddress.ip_network(2 ** 128 - 1).is_multicast)
1826        self.assertEqual(True, ipaddress.ip_network('ff00::').is_multicast)
1827        self.assertEqual(False, ipaddress.ip_network('fdff::').is_multicast)
1828
1829        self.assertEqual(True, ipaddress.ip_network('fecf::').is_site_local)
1830        self.assertEqual(True, ipaddress.ip_network(
1831            'feff:ffff:ffff:ffff::').is_site_local)
1832        self.assertEqual(False, ipaddress.ip_network(
1833            'fbf:ffff::').is_site_local)
1834        self.assertEqual(False, ipaddress.ip_network('ff00::').is_site_local)
1835
1836        self.assertEqual(True, ipaddress.ip_network('fc00::').is_private)
1837        self.assertEqual(True, ipaddress.ip_network(
1838            'fc00:ffff:ffff:ffff::').is_private)
1839        self.assertEqual(False, ipaddress.ip_network('fbff:ffff::').is_private)
1840        self.assertEqual(False, ipaddress.ip_network('fe00::').is_private)
1841
1842        self.assertEqual(True, ipaddress.ip_network('fea0::').is_link_local)
1843        self.assertEqual(True, ipaddress.ip_network(
1844            'febf:ffff::').is_link_local)
1845        self.assertEqual(False, ipaddress.ip_network(
1846            'fe7f:ffff::').is_link_local)
1847        self.assertEqual(False, ipaddress.ip_network('fec0::').is_link_local)
1848
1849        self.assertEqual(True, ipaddress.ip_interface('0:0::0:01').is_loopback)
1850        self.assertEqual(False, ipaddress.ip_interface('::1/127').is_loopback)
1851        self.assertEqual(False, ipaddress.ip_network('::').is_loopback)
1852        self.assertEqual(False, ipaddress.ip_network('::2').is_loopback)
1853
1854        self.assertEqual(True, ipaddress.ip_network('0::0').is_unspecified)
1855        self.assertEqual(False, ipaddress.ip_network('::1').is_unspecified)
1856        self.assertEqual(False, ipaddress.ip_network('::/127').is_unspecified)
1857
1858        self.assertEqual(True,
1859                         ipaddress.ip_network('2001::1/128').is_private)
1860        self.assertEqual(True,
1861                         ipaddress.ip_network('200::1/128').is_global)
1862        # test addresses
1863        self.assertEqual(True, ipaddress.ip_address('ffff::').is_multicast)
1864        self.assertEqual(True, ipaddress.ip_address(2 ** 128 - 1).is_multicast)
1865        self.assertEqual(True, ipaddress.ip_address('ff00::').is_multicast)
1866        self.assertEqual(False, ipaddress.ip_address('fdff::').is_multicast)
1867
1868        self.assertEqual(True, ipaddress.ip_address('fecf::').is_site_local)
1869        self.assertEqual(True, ipaddress.ip_address(
1870            'feff:ffff:ffff:ffff::').is_site_local)
1871        self.assertEqual(False, ipaddress.ip_address(
1872            'fbf:ffff::').is_site_local)
1873        self.assertEqual(False, ipaddress.ip_address('ff00::').is_site_local)
1874
1875        self.assertEqual(True, ipaddress.ip_address('fc00::').is_private)
1876        self.assertEqual(True, ipaddress.ip_address(
1877            'fc00:ffff:ffff:ffff::').is_private)
1878        self.assertEqual(False, ipaddress.ip_address('fbff:ffff::').is_private)
1879        self.assertEqual(False, ipaddress.ip_address('fe00::').is_private)
1880
1881        self.assertEqual(True, ipaddress.ip_address('fea0::').is_link_local)
1882        self.assertEqual(True, ipaddress.ip_address(
1883            'febf:ffff::').is_link_local)
1884        self.assertEqual(False, ipaddress.ip_address(
1885            'fe7f:ffff::').is_link_local)
1886        self.assertEqual(False, ipaddress.ip_address('fec0::').is_link_local)
1887
1888        self.assertEqual(True, ipaddress.ip_address('0:0::0:01').is_loopback)
1889        self.assertEqual(True, ipaddress.ip_address('::1').is_loopback)
1890        self.assertEqual(False, ipaddress.ip_address('::2').is_loopback)
1891
1892        self.assertEqual(True, ipaddress.ip_address('0::0').is_unspecified)
1893        self.assertEqual(False, ipaddress.ip_address('::1').is_unspecified)
1894
1895        # some generic IETF reserved addresses
1896        self.assertEqual(True, ipaddress.ip_address('100::').is_reserved)
1897        self.assertEqual(True, ipaddress.ip_network('4000::1/128').is_reserved)
1898
1899    def testIpv4Mapped(self):
1900        self.assertEqual(
1901            ipaddress.ip_address('::ffff:192.168.1.1').ipv4_mapped,
1902            ipaddress.ip_address('192.168.1.1'))
1903        self.assertEqual(ipaddress.ip_address('::c0a8:101').ipv4_mapped, None)
1904        self.assertEqual(ipaddress.ip_address('::ffff:c0a8:101').ipv4_mapped,
1905                         ipaddress.ip_address('192.168.1.1'))
1906
1907    def testAddrExclude(self):
1908        addr1 = ipaddress.ip_network('10.1.1.0/24')
1909        addr2 = ipaddress.ip_network('10.1.1.0/26')
1910        addr3 = ipaddress.ip_network('10.2.1.0/24')
1911        addr4 = ipaddress.ip_address('10.1.1.0')
1912        addr5 = ipaddress.ip_network('2001:db8::0/32')
1913        addr6 = ipaddress.ip_network('10.1.1.5/32')
1914        self.assertEqual(sorted(list(addr1.address_exclude(addr2))),
1915                         [ipaddress.ip_network('10.1.1.64/26'),
1916                          ipaddress.ip_network('10.1.1.128/25')])
1917        self.assertRaises(ValueError, list, addr1.address_exclude(addr3))
1918        self.assertRaises(TypeError, list, addr1.address_exclude(addr4))
1919        self.assertRaises(TypeError, list, addr1.address_exclude(addr5))
1920        self.assertEqual(list(addr1.address_exclude(addr1)), [])
1921        self.assertEqual(sorted(list(addr1.address_exclude(addr6))),
1922                         [ipaddress.ip_network('10.1.1.0/30'),
1923                          ipaddress.ip_network('10.1.1.4/32'),
1924                          ipaddress.ip_network('10.1.1.6/31'),
1925                          ipaddress.ip_network('10.1.1.8/29'),
1926                          ipaddress.ip_network('10.1.1.16/28'),
1927                          ipaddress.ip_network('10.1.1.32/27'),
1928                          ipaddress.ip_network('10.1.1.64/26'),
1929                          ipaddress.ip_network('10.1.1.128/25')])
1930
1931    def testHash(self):
1932        self.assertEqual(hash(ipaddress.ip_interface('10.1.1.0/24')),
1933                         hash(ipaddress.ip_interface('10.1.1.0/24')))
1934        self.assertEqual(hash(ipaddress.ip_network('10.1.1.0/24')),
1935                         hash(ipaddress.ip_network('10.1.1.0/24')))
1936        self.assertEqual(hash(ipaddress.ip_address('10.1.1.0')),
1937                         hash(ipaddress.ip_address('10.1.1.0')))
1938        # i70
1939        self.assertEqual(
1940            hash(ipaddress.ip_address('1.2.3.4')),
1941            hash(ipaddress.ip_address(
1942                int(ipaddress.ip_address('1.2.3.4')._ip))))
1943        ip1 = ipaddress.ip_address('10.1.1.0')
1944        ip2 = ipaddress.ip_address('1::')
1945        dummy = {}
1946        dummy[self.ipv4_address] = None
1947        dummy[self.ipv6_address] = None
1948        dummy[ip1] = None
1949        dummy[ip2] = None
1950        self.assertTrue(self.ipv4_address in dummy)
1951        self.assertTrue(ip2 in dummy)
1952
1953    def testIPBases(self):
1954        net = self.ipv4_network
1955        self.assertEqual('1.2.3.0/24', net.compressed)
1956        net = self.ipv6_network
1957        self.assertRaises(ValueError, net._string_from_ip_int, 2 ** 128 + 1)
1958
1959    def testIPv6NetworkHelpers(self):
1960        net = self.ipv6_network
1961        self.assertEqual('2001:658:22a:cafe::/64', net.with_prefixlen)
1962        self.assertEqual('2001:658:22a:cafe::/ffff:ffff:ffff:ffff::',
1963                         net.with_netmask)
1964        self.assertEqual('2001:658:22a:cafe::/::ffff:ffff:ffff:ffff',
1965                         net.with_hostmask)
1966        self.assertEqual('2001:658:22a:cafe::/64', str(net))
1967
1968    def testIPv4NetworkHelpers(self):
1969        net = self.ipv4_network
1970        self.assertEqual('1.2.3.0/24', net.with_prefixlen)
1971        self.assertEqual('1.2.3.0/255.255.255.0', net.with_netmask)
1972        self.assertEqual('1.2.3.0/0.0.0.255', net.with_hostmask)
1973        self.assertEqual('1.2.3.0/24', str(net))
1974
1975    def testCopyConstructor(self):
1976        addr1 = ipaddress.ip_network('10.1.1.0/24')
1977        addr2 = ipaddress.ip_network(addr1)
1978        addr3 = ipaddress.ip_interface('2001:658:22a:cafe:200::1/64')
1979        addr4 = ipaddress.ip_interface(addr3)
1980        addr5 = ipaddress.IPv4Address('1.1.1.1')
1981        addr6 = ipaddress.IPv6Address('2001:658:22a:cafe:200::1')
1982
1983        self.assertEqual(addr1, addr2)
1984        self.assertEqual(addr3, addr4)
1985        self.assertEqual(addr5, ipaddress.IPv4Address(addr5))
1986        self.assertEqual(addr6, ipaddress.IPv6Address(addr6))
1987
1988    def testCompressIPv6Address(self):
1989        test_addresses = {
1990            '1:2:3:4:5:6:7:8': '1:2:3:4:5:6:7:8/128',
1991            '2001:0:0:4:0:0:0:8': '2001:0:0:4::8/128',
1992            '2001:0:0:4:5:6:7:8': '2001::4:5:6:7:8/128',
1993            '2001:0:3:4:5:6:7:8': '2001:0:3:4:5:6:7:8/128',
1994            '0:0:3:0:0:0:0:ffff': '0:0:3::ffff/128',
1995            '0:0:0:4:0:0:0:ffff': '::4:0:0:0:ffff/128',
1996            '0:0:0:0:5:0:0:ffff': '::5:0:0:ffff/128',
1997            '1:0:0:4:0:0:7:8': '1::4:0:0:7:8/128',
1998            '0:0:0:0:0:0:0:0': '::/128',
1999            '0:0:0:0:0:0:0:0/0': '::/0',
2000            '0:0:0:0:0:0:0:1': '::1/128',
2001            '2001:0658:022a:cafe:0000:0000:0000:0000/66':
2002            '2001:658:22a:cafe::/66',
2003            '::1.2.3.4': '::102:304/128',
2004            '1:2:3:4:5:ffff:1.2.3.4': '1:2:3:4:5:ffff:102:304/128',
2005            '::7:6:5:4:3:2:1': '0:7:6:5:4:3:2:1/128',
2006            '::7:6:5:4:3:2:0': '0:7:6:5:4:3:2:0/128',
2007            '7:6:5:4:3:2:1::': '7:6:5:4:3:2:1:0/128',
2008            '0:6:5:4:3:2:1::': '0:6:5:4:3:2:1:0/128',
2009        }
2010        for uncompressed, compressed in list(test_addresses.items()):
2011            self.assertEqual(compressed, str(ipaddress.IPv6Interface(
2012                uncompressed)))
2013
2014    def testExplodeShortHandIpStr(self):
2015        addr1 = ipaddress.IPv6Interface('2001::1')
2016        addr2 = ipaddress.IPv6Address('2001:0:5ef5:79fd:0:59d:a0e5:ba1')
2017        addr3 = ipaddress.IPv6Network('2001::/96')
2018        addr4 = ipaddress.IPv4Address('192.168.178.1')
2019        self.assertEqual('2001:0000:0000:0000:0000:0000:0000:0001/128',
2020                         addr1.exploded)
2021        self.assertEqual('0000:0000:0000:0000:0000:0000:0000:0001/128',
2022                         ipaddress.IPv6Interface('::1/128').exploded)
2023        # issue 77
2024        self.assertEqual('2001:0000:5ef5:79fd:0000:059d:a0e5:0ba1',
2025                         addr2.exploded)
2026        self.assertEqual('2001:0000:0000:0000:0000:0000:0000:0000/96',
2027                         addr3.exploded)
2028        self.assertEqual('192.168.178.1', addr4.exploded)
2029
2030    def testReversePointer(self):
2031        addr1 = ipaddress.IPv4Address('127.0.0.1')
2032        addr2 = ipaddress.IPv6Address('2001:db8::1')
2033        self.assertEqual('1.0.0.127.in-addr.arpa', addr1.reverse_pointer)
2034        self.assertEqual('1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.' +
2035                         'b.d.0.1.0.0.2.ip6.arpa',
2036                         addr2.reverse_pointer)
2037
2038    def testIntRepresentation(self):
2039        self.assertEqual(16909060, int(self.ipv4_address))
2040        self.assertEqual(42540616829182469433547762482097946625,
2041                         int(self.ipv6_address))
2042
2043    def testForceVersion(self):
2044        self.assertEqual(ipaddress.ip_network(1).version, 4)
2045        self.assertEqual(ipaddress.IPv6Network(1).version, 6)
2046
2047    def testWithStar(self):
2048        self.assertEqual(self.ipv4_interface.with_prefixlen, "1.2.3.4/24")
2049        self.assertEqual(self.ipv4_interface.with_netmask,
2050                         "1.2.3.4/255.255.255.0")
2051        self.assertEqual(self.ipv4_interface.with_hostmask,
2052                         "1.2.3.4/0.0.0.255")
2053
2054        self.assertEqual(self.ipv6_interface.with_prefixlen,
2055                         '2001:658:22a:cafe:200::1/64')
2056        self.assertEqual(self.ipv6_interface.with_netmask,
2057                         '2001:658:22a:cafe:200::1/ffff:ffff:ffff:ffff::')
2058        # this probably don't make much sense, but it's included for
2059        # compatibility with ipv4
2060        self.assertEqual(self.ipv6_interface.with_hostmask,
2061                         '2001:658:22a:cafe:200::1/::ffff:ffff:ffff:ffff')
2062
2063    def testNetworkElementCaching(self):
2064        # V4 - make sure we're empty
2065        self.assertFalse('network_address' in self.ipv4_network._cache)
2066        self.assertFalse('broadcast_address' in self.ipv4_network._cache)
2067        self.assertFalse('hostmask' in self.ipv4_network._cache)
2068
2069        # V4 - populate and test
2070        self.assertEqual(self.ipv4_network.network_address,
2071                         ipaddress.IPv4Address('1.2.3.0'))
2072        self.assertEqual(self.ipv4_network.broadcast_address,
2073                         ipaddress.IPv4Address('1.2.3.255'))
2074        self.assertEqual(self.ipv4_network.hostmask,
2075                         ipaddress.IPv4Address('0.0.0.255'))
2076
2077        # V4 - check we're cached
2078        self.assertTrue('broadcast_address' in self.ipv4_network._cache)
2079        self.assertTrue('hostmask' in self.ipv4_network._cache)
2080
2081        # V6 - make sure we're empty
2082        self.assertFalse('broadcast_address' in self.ipv6_network._cache)
2083        self.assertFalse('hostmask' in self.ipv6_network._cache)
2084
2085        # V6 - populate and test
2086        self.assertEqual(self.ipv6_network.network_address,
2087                         ipaddress.IPv6Address('2001:658:22a:cafe::'))
2088        self.assertEqual(self.ipv6_interface.network.network_address,
2089                         ipaddress.IPv6Address('2001:658:22a:cafe::'))
2090
2091        self.assertEqual(
2092            self.ipv6_network.broadcast_address,
2093            ipaddress.IPv6Address('2001:658:22a:cafe:ffff:ffff:ffff:ffff'))
2094        self.assertEqual(self.ipv6_network.hostmask,
2095                         ipaddress.IPv6Address('::ffff:ffff:ffff:ffff'))
2096        self.assertEqual(
2097            self.ipv6_interface.network.broadcast_address,
2098            ipaddress.IPv6Address('2001:658:22a:cafe:ffff:ffff:ffff:ffff'))
2099        self.assertEqual(self.ipv6_interface.network.hostmask,
2100                         ipaddress.IPv6Address('::ffff:ffff:ffff:ffff'))
2101
2102        # V6 - check we're cached
2103        self.assertTrue('broadcast_address' in self.ipv6_network._cache)
2104        self.assertTrue('hostmask' in self.ipv6_network._cache)
2105        self.assertTrue(
2106            'broadcast_address' in self.ipv6_interface.network._cache)
2107        self.assertTrue('hostmask' in self.ipv6_interface.network._cache)
2108
2109    def testTeredo(self):
2110        # stolen from wikipedia
2111        server = ipaddress.IPv4Address('65.54.227.120')
2112        client = ipaddress.IPv4Address('192.0.2.45')
2113        teredo_addr = '2001:0000:4136:e378:8000:63bf:3fff:fdd2'
2114        self.assertEqual((server, client),
2115                         ipaddress.ip_address(teredo_addr).teredo)
2116        bad_addr = '2000::4136:e378:8000:63bf:3fff:fdd2'
2117        self.assertFalse(ipaddress.ip_address(bad_addr).teredo)
2118        bad_addr = '2001:0001:4136:e378:8000:63bf:3fff:fdd2'
2119        self.assertFalse(ipaddress.ip_address(bad_addr).teredo)
2120
2121        # i77
2122        teredo_addr = ipaddress.IPv6Address('2001:0:5ef5:79fd:0:59d:a0e5:ba1')
2123        self.assertEqual((ipaddress.IPv4Address('94.245.121.253'),
2124                          ipaddress.IPv4Address('95.26.244.94')),
2125                         teredo_addr.teredo)
2126
2127    def testsixtofour(self):
2128        sixtofouraddr = ipaddress.ip_address('2002:ac1d:2d64::1')
2129        bad_addr = ipaddress.ip_address('2000:ac1d:2d64::1')
2130        self.assertEqual(ipaddress.IPv4Address('172.29.45.100'),
2131                         sixtofouraddr.sixtofour)
2132        self.assertFalse(bad_addr.sixtofour)
2133
2134
2135# Monkey-patch test runner
2136if not hasattr(BaseTestCase, 'assertRaisesRegex'):
2137    class _AssertRaisesRegex(object):
2138        def __init__(self, expected_exception, expected_regex):
2139            self.expected = expected_exception
2140            self.expected_regex = re.compile(expected_regex)
2141
2142        def __enter__(self):
2143            return self
2144
2145        def __exit__(self, exc_type, exc_value, tb):
2146            if exc_type is None:
2147                try:
2148                    exc_name = self.expected.__name__
2149                except AttributeError:
2150                    exc_name = str(self.expected)
2151                if self.obj_name:
2152                    self._raiseFailure("{} not raised by {}".format(
2153                        exc_name, self.obj_name))
2154                else:
2155                    self._raiseFailure("{} not raised".format(exc_name))
2156            if not issubclass(exc_type, self.expected):
2157                # let unexpected exceptions pass through
2158                return False
2159            self.exception = exc_value
2160            if self.expected_regex is None:
2161                return True
2162
2163            expected_regex = self.expected_regex
2164            if not expected_regex.search(str(exc_value)):
2165                raise AssertionError('"{0}" does not match "{1}"'.format(
2166                    expected_regex.pattern, str(exc_value)))
2167            return True
2168
2169    BaseTestCase.assertRaisesRegex = _AssertRaisesRegex
2170    IpaddrUnitTest.assertRaisesRegex = _AssertRaisesRegex
2171if not hasattr(BaseTestCase, 'assertIn'):
2172    def _assertIn(self, o, iterable):
2173        self.assertTrue(o in iterable)
2174
2175    def _assertNotIn(self, o, iterable):
2176        self.assertFalse(o in iterable)
2177    BaseTestCase.assertIn = _assertIn
2178    BaseTestCase.assertNotIn = _assertNotIn
2179    IpaddrUnitTest.assertIn = _assertIn
2180    IpaddrUnitTest.assertNotIn = _assertNotIn
2181    ComparisonTests.assertIn = _assertIn
2182    ComparisonTests.assertNotIn = _assertNotIn
2183if not hasattr(BaseTestCase, 'subTest'):
2184    class _SubTest(object):
2185        def __init__(*a, **kw):
2186            pass
2187
2188        def __enter__(*a):
2189            pass
2190
2191        def __exit__(*a):
2192            pass
2193    BaseTestCase.subTest = _SubTest
2194
2195
2196# Test for https://github.com/phihag/ipaddress/pull/6
2197class Python2RangeTest(unittest.TestCase):
2198    def test_network_hosts(self):
2199        net = ipaddress.ip_network('::/0')
2200        next(net.hosts())  # This should not throw OverflowError
2201
2202    def test_network_iter(self):
2203        net = ipaddress.ip_network('::/0')
2204        next(iter(net))  # This should not throw OverflowError
2205
2206
2207class CompatTest(unittest.TestCase):
2208    def test_bit_length(self):
2209        self.assertEqual(ipaddress._compat_bit_length(0), 0)
2210        self.assertEqual(ipaddress._compat_bit_length(1), 1)
2211        self.assertEqual(ipaddress._compat_bit_length(2), 2)
2212        self.assertEqual(ipaddress._compat_bit_length(3), 2)
2213        self.assertEqual(ipaddress._compat_bit_length(4), 3)
2214
2215
2216class SingleIssuesTest(BaseTestCase):
2217    # https://github.com/phihag/ipaddress/issues/14
2218    def test_issue_14(self):
2219        self.assertTrue(ipaddress.ip_address('127.0.0.1').is_private)
2220
2221    def test_issue_18(self):
2222        net1 = ipaddress.ip_network("192.0.2.0/24")
2223        net2 = ipaddress.ip_network("192.0.2.112/29")
2224        self.assertFalse(net1.subnet_of(net2))
2225        self.assertTrue(net1.supernet_of(net2))
2226        self.assertTrue(net2.subnet_of(net1))
2227        self.assertFalse(net2.supernet_of(net1))
2228
2229    def test_issue_48(self):
2230        v6net = ipaddress.ip_network('::/0')
2231        v4net = ipaddress.ip_network('1.2.3.0/24')
2232        with self.assertRaisesRegex(TypeError, r'are not of the same version'):
2233            v6net.subnet_of(v4net)
2234
2235
2236if __name__ == '__main__':
2237    unittest.main()
2238