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