]> git.proxmox.com Git - ceph.git/blame - ceph/src/arrow/python/pyarrow/util.py
import quincy 17.2.0
[ceph.git] / ceph / src / arrow / python / pyarrow / util.py
CommitLineData
1d09f67e
TL
1# Licensed to the Apache Software Foundation (ASF) under one
2# or more contributor license agreements. See the NOTICE file
3# distributed with this work for additional information
4# regarding copyright ownership. The ASF licenses this file
5# to you under the Apache License, Version 2.0 (the
6# "License"); you may not use this file except in compliance
7# with the License. You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing,
12# software distributed under the License is distributed on an
13# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14# KIND, either express or implied. See the License for the
15# specific language governing permissions and limitations
16# under the License.
17
18# Miscellaneous utility code
19
20import contextlib
21import functools
22import gc
23import pathlib
24import socket
25import sys
26import types
27import warnings
28
29
30_DEPR_MSG = (
31 "pyarrow.{} is deprecated as of {}, please use pyarrow.{} instead."
32)
33
34
35def implements(f):
36 def decorator(g):
37 g.__doc__ = f.__doc__
38 return g
39 return decorator
40
41
42def _deprecate_api(old_name, new_name, api, next_version):
43 msg = _DEPR_MSG.format(old_name, next_version, new_name)
44
45 def wrapper(*args, **kwargs):
46 warnings.warn(msg, FutureWarning)
47 return api(*args, **kwargs)
48 return wrapper
49
50
51def _deprecate_class(old_name, new_class, next_version,
52 instancecheck=True):
53 """
54 Raise warning if a deprecated class is used in an isinstance check.
55 """
56 class _DeprecatedMeta(type):
57 def __instancecheck__(self, other):
58 warnings.warn(
59 _DEPR_MSG.format(old_name, next_version, new_class.__name__),
60 FutureWarning,
61 stacklevel=2
62 )
63 return isinstance(other, new_class)
64
65 return _DeprecatedMeta(old_name, (new_class,), {})
66
67
68def _is_iterable(obj):
69 try:
70 iter(obj)
71 return True
72 except TypeError:
73 return False
74
75
76def _is_path_like(path):
77 # PEP519 filesystem path protocol is available from python 3.6, so pathlib
78 # doesn't implement __fspath__ for earlier versions
79 return (isinstance(path, str) or
80 hasattr(path, '__fspath__') or
81 isinstance(path, pathlib.Path))
82
83
84def _stringify_path(path):
85 """
86 Convert *path* to a string or unicode path if possible.
87 """
88 if isinstance(path, str):
89 return path
90
91 # checking whether path implements the filesystem protocol
92 try:
93 return path.__fspath__() # new in python 3.6
94 except AttributeError:
95 # fallback pathlib ckeck for earlier python versions than 3.6
96 if isinstance(path, pathlib.Path):
97 return str(path)
98
99 raise TypeError("not a path-like object")
100
101
102def product(seq):
103 """
104 Return a product of sequence items.
105 """
106 return functools.reduce(lambda a, b: a*b, seq, 1)
107
108
109def get_contiguous_span(shape, strides, itemsize):
110 """
111 Return a contiguous span of N-D array data.
112
113 Parameters
114 ----------
115 shape : tuple
116 strides : tuple
117 itemsize : int
118 Specify array shape data
119
120 Returns
121 -------
122 start, end : int
123 The span end points.
124 """
125 if not strides:
126 start = 0
127 end = itemsize * product(shape)
128 else:
129 start = 0
130 end = itemsize
131 for i, dim in enumerate(shape):
132 if dim == 0:
133 start = end = 0
134 break
135 stride = strides[i]
136 if stride > 0:
137 end += stride * (dim - 1)
138 elif stride < 0:
139 start += stride * (dim - 1)
140 if end - start != itemsize * product(shape):
141 raise ValueError('array data is non-contiguous')
142 return start, end
143
144
145def find_free_port():
146 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
147 with contextlib.closing(sock) as sock:
148 sock.bind(('', 0))
149 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
150 return sock.getsockname()[1]
151
152
153def guid():
154 from uuid import uuid4
155 return uuid4().hex
156
157
158def _break_traceback_cycle_from_frame(frame):
159 # Clear local variables in all inner frames, so as to break the
160 # reference cycle.
161 this_frame = sys._getframe(0)
162 refs = gc.get_referrers(frame)
163 while refs:
164 for frame in refs:
165 if frame is not this_frame and isinstance(frame, types.FrameType):
166 break
167 else:
168 # No frame found in referrers (finished?)
169 break
170 refs = None
171 # Clear the frame locals, to try and break the cycle (it is
172 # somewhere along the chain of execution frames).
173 frame.clear()
174 # To visit the inner frame, we need to find it among the
175 # referers of this frame (while `frame.f_back` would let
176 # us visit the outer frame).
177 refs = gc.get_referrers(frame)
178 refs = frame = this_frame = None