@@ -29,6 +29,7 @@ class IPv4v6Base(object):
29
29
IPv4v6Base .register (ipaddress .IPv6Address )
30
30
31
31
32
+ @pd .api .extensions .register_extension_dtype
32
33
class IPType (ExtensionDtype ):
33
34
name = 'ip'
34
35
type = IPv4v6Base
@@ -44,6 +45,11 @@ def construct_from_string(cls, string):
44
45
raise TypeError ("Cannot construct a '{}' from "
45
46
"'{}'" .format (cls , string ))
46
47
48
+ @classmethod
49
+ def construct_array_type (cls ):
50
+ return IPArray
51
+
52
+
47
53
# -----------------------------------------------------------------------------
48
54
# Extension Container
49
55
# -----------------------------------------------------------------------------
@@ -69,15 +75,17 @@ class IPArray(NumPyBackedExtensionArrayMixin):
69
75
ndim = 1
70
76
can_hold_na = True
71
77
72
- def __init__ (self , values ):
78
+ def __init__ (self , values , dtype = None , copy = False ):
73
79
from .parser import _to_ip_array
74
80
75
81
values = _to_ip_array (values ) # TODO: avoid potential copy
82
+ # TODO: dtype?
83
+ if copy :
84
+ values = values .copy ()
76
85
self .data = values
77
86
78
87
@classmethod
79
88
def from_pyints (cls , values ):
80
- # type: (T.Sequence[int]) -> 'IPArray'
81
89
"""Construct an IPArray from a sequence of Python integers.
82
90
83
91
This can be useful for representing IPv6 addresses, which may
@@ -97,7 +105,7 @@ def from_pyints(cls, values):
97
105
98
106
@classmethod
99
107
def from_bytes (cls , bytestring ):
100
- """Create an IPArray from a bytestring.
108
+ r """Create an IPArray from a bytestring.
101
109
102
110
Parameters
103
111
----------
@@ -295,7 +303,7 @@ def to_pyints(self):
295
303
return [combine (* map (int , x )) for x in self .data ]
296
304
297
305
def to_bytes (self ):
298
- """Serialize the IPArray as a Python bytestring.
306
+ r """Serialize the IPArray as a Python bytestring.
299
307
300
308
This and :meth:IPArray.from_bytes is the fastest way to roundtrip
301
309
serialize and de-serialize an IPArray.
@@ -312,6 +320,13 @@ def to_bytes(self):
312
320
"""
313
321
return self .data .tobytes ()
314
322
323
+ def astype (self , dtype , copy = True ):
324
+ if isinstance (dtype , IPType ):
325
+ if copy :
326
+ self = self .copy ()
327
+ return self
328
+ return super (IPArray , self ).astype (dtype )
329
+
315
330
# ------------------------------------------------------------------------
316
331
# Ops
317
332
# ------------------------------------------------------------------------
@@ -449,7 +464,6 @@ def isin(self, other):
449
464
return mask
450
465
451
466
def _isin_network (self , other ):
452
- # type: (Union[ipaddress.IPv4Network,ipaddress.IPv6Network]) -> ndarray
453
467
"""Check whether an array of addresses is contained in a network."""
454
468
# A network is bounded below by 'network_address' and
455
469
# above by 'broadcast_address'.
@@ -649,6 +663,7 @@ def mask(self, mask):
649
663
# Accessor
650
664
# -----------------------------------------------------------------------------
651
665
666
+
652
667
@pd .api .extensions .register_series_accessor ("ip" )
653
668
class IPAccessor :
654
669
0 commit comments