JinghuiLuAstronaut commited on
Commit
44961a7
·
verified ·
1 Parent(s): 48de36d

Add files using upload-large-folder tool

Browse files
Files changed (20) hide show
  1. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/fsspec/__init__.py +71 -0
  2. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/fsspec/asyn.py +1127 -0
  3. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/fsspec/fuse.py +324 -0
  4. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/fsspec/generic.py +396 -0
  5. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/fsspec/mapping.py +251 -0
  6. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/fsspec/utils.py +748 -0
  7. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/API_CHANGES.txt +135 -0
  8. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/LICENSE +24 -0
  9. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/README.rst +236 -0
  10. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/__init__.py +54 -0
  11. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/__init__.pyi +234 -0
  12. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/core.py +0 -0
  13. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/core.pyi +471 -0
  14. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/extras.py +2133 -0
  15. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/extras.pyi +85 -0
  16. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/mrecords.py +783 -0
  17. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/mrecords.pyi +90 -0
  18. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/setup.py +12 -0
  19. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/qwen3_vl_moe/configuration_qwen3_vl_moe.py +194 -0
  20. LTA_openwebtext_dualt/mini_owt_logdirichlet/logs/infer_not5_bottleneck128_170k_decode32_ema_20260611/lr2e3.log +29 -0
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/fsspec/__init__.py ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from . import caching
2
+ from ._version import __version__ # noqa: F401
3
+ from .callbacks import Callback
4
+ from .compression import available_compressions
5
+ from .core import get_fs_token_paths, open, open_files, open_local, url_to_fs
6
+ from .exceptions import FSTimeoutError
7
+ from .mapping import FSMap, get_mapper
8
+ from .registry import (
9
+ available_protocols,
10
+ filesystem,
11
+ get_filesystem_class,
12
+ register_implementation,
13
+ registry,
14
+ )
15
+ from .spec import AbstractFileSystem
16
+
17
+ __all__ = [
18
+ "AbstractFileSystem",
19
+ "FSTimeoutError",
20
+ "FSMap",
21
+ "filesystem",
22
+ "register_implementation",
23
+ "get_filesystem_class",
24
+ "get_fs_token_paths",
25
+ "get_mapper",
26
+ "open",
27
+ "open_files",
28
+ "open_local",
29
+ "registry",
30
+ "caching",
31
+ "Callback",
32
+ "available_protocols",
33
+ "available_compressions",
34
+ "url_to_fs",
35
+ ]
36
+
37
+
38
+ def process_entries():
39
+ try:
40
+ from importlib.metadata import entry_points
41
+ except ImportError:
42
+ return
43
+ if entry_points is not None:
44
+ try:
45
+ eps = entry_points()
46
+ except TypeError:
47
+ pass # importlib-metadata < 0.8
48
+ else:
49
+ if hasattr(eps, "select"): # Python 3.10+ / importlib_metadata >= 3.9.0
50
+ specs = eps.select(group="fsspec.specs")
51
+ else:
52
+ specs = eps.get("fsspec.specs", [])
53
+ registered_names = {}
54
+ for spec in specs:
55
+ err_msg = f"Unable to load filesystem from {spec}"
56
+ name = spec.name
57
+ if name in registered_names:
58
+ continue
59
+ registered_names[name] = True
60
+ register_implementation(
61
+ name,
62
+ spec.value.replace(":", "."),
63
+ errtxt=err_msg,
64
+ # We take our implementations as the ones to overload with if
65
+ # for some reason we encounter some, may be the same, already
66
+ # registered
67
+ clobber=True,
68
+ )
69
+
70
+
71
+ process_entries()
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/fsspec/asyn.py ADDED
@@ -0,0 +1,1127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import asyncio.events
3
+ import functools
4
+ import inspect
5
+ import io
6
+ import numbers
7
+ import os
8
+ import re
9
+ import threading
10
+ from collections.abc import Iterable
11
+ from glob import has_magic
12
+ from typing import TYPE_CHECKING
13
+
14
+ from .callbacks import DEFAULT_CALLBACK
15
+ from .exceptions import FSTimeoutError
16
+ from .implementations.local import LocalFileSystem, make_path_posix, trailing_sep
17
+ from .spec import AbstractBufferedFile, AbstractFileSystem
18
+ from .utils import glob_translate, is_exception, other_paths
19
+
20
+ private = re.compile("_[^_]")
21
+ iothread = [None] # dedicated fsspec IO thread
22
+ loop = [None] # global event loop for any non-async instance
23
+ _lock = None # global lock placeholder
24
+ get_running_loop = asyncio.get_running_loop
25
+
26
+
27
+ def get_lock():
28
+ """Allocate or return a threading lock.
29
+
30
+ The lock is allocated on first use to allow setting one lock per forked process.
31
+ """
32
+ global _lock
33
+ if not _lock:
34
+ _lock = threading.Lock()
35
+ return _lock
36
+
37
+
38
+ def reset_lock():
39
+ """Reset the global lock.
40
+
41
+ This should be called only on the init of a forked process to reset the lock to
42
+ None, enabling the new forked process to get a new lock.
43
+ """
44
+ global _lock
45
+
46
+ iothread[0] = None
47
+ loop[0] = None
48
+ _lock = None
49
+
50
+
51
+ async def _runner(event, coro, result, timeout=None):
52
+ timeout = timeout if timeout else None # convert 0 or 0.0 to None
53
+ if timeout is not None:
54
+ coro = asyncio.wait_for(coro, timeout=timeout)
55
+ try:
56
+ result[0] = await coro
57
+ except Exception as ex:
58
+ result[0] = ex
59
+ finally:
60
+ event.set()
61
+
62
+
63
+ def sync(loop, func, *args, timeout=None, **kwargs):
64
+ """
65
+ Make loop run coroutine until it returns. Runs in other thread
66
+
67
+ Examples
68
+ --------
69
+ >>> fsspec.asyn.sync(fsspec.asyn.get_loop(), func, *args,
70
+ timeout=timeout, **kwargs)
71
+ """
72
+ timeout = timeout if timeout else None # convert 0 or 0.0 to None
73
+ # NB: if the loop is not running *yet*, it is OK to submit work
74
+ # and we will wait for it
75
+ if loop is None or loop.is_closed():
76
+ raise RuntimeError("Loop is not running")
77
+ try:
78
+ loop0 = asyncio.events.get_running_loop()
79
+ if loop0 is loop:
80
+ raise NotImplementedError("Calling sync() from within a running loop")
81
+ except NotImplementedError:
82
+ raise
83
+ except RuntimeError:
84
+ pass
85
+ coro = func(*args, **kwargs)
86
+ result = [None]
87
+ event = threading.Event()
88
+ asyncio.run_coroutine_threadsafe(_runner(event, coro, result, timeout), loop)
89
+ while True:
90
+ # this loops allows thread to get interrupted
91
+ if event.wait(1):
92
+ break
93
+ if timeout is not None:
94
+ timeout -= 1
95
+ if timeout < 0:
96
+ raise FSTimeoutError
97
+
98
+ return_result = result[0]
99
+ if isinstance(return_result, asyncio.TimeoutError):
100
+ # suppress asyncio.TimeoutError, raise FSTimeoutError
101
+ raise FSTimeoutError from return_result
102
+ elif isinstance(return_result, BaseException):
103
+ raise return_result
104
+ else:
105
+ return return_result
106
+
107
+
108
+ def sync_wrapper(func, obj=None):
109
+ """Given a function, make so can be called in blocking contexts
110
+
111
+ Leave obj=None if defining within a class. Pass the instance if attaching
112
+ as an attribute of the instance.
113
+ """
114
+
115
+ @functools.wraps(func)
116
+ def wrapper(*args, **kwargs):
117
+ self = obj or args[0]
118
+ return sync(self.loop, func, *args, **kwargs)
119
+
120
+ return wrapper
121
+
122
+
123
+ def get_loop():
124
+ """Create or return the default fsspec IO loop
125
+
126
+ The loop will be running on a separate thread.
127
+ """
128
+ if loop[0] is None:
129
+ with get_lock():
130
+ # repeat the check just in case the loop got filled between the
131
+ # previous two calls from another thread
132
+ if loop[0] is None:
133
+ loop[0] = asyncio.new_event_loop()
134
+ th = threading.Thread(target=loop[0].run_forever, name="fsspecIO")
135
+ th.daemon = True
136
+ th.start()
137
+ iothread[0] = th
138
+ return loop[0]
139
+
140
+
141
+ def reset_after_fork():
142
+ global lock
143
+ loop[0] = None
144
+ iothread[0] = None
145
+ lock = None
146
+
147
+
148
+ if hasattr(os, "register_at_fork"):
149
+ # should be posix; this will do nothing for spawn or forkserver subprocesses
150
+ os.register_at_fork(after_in_child=reset_after_fork)
151
+
152
+
153
+ if TYPE_CHECKING:
154
+ import resource
155
+
156
+ ResourceError = resource.error
157
+ else:
158
+ try:
159
+ import resource
160
+ except ImportError:
161
+ resource = None
162
+ ResourceError = OSError
163
+ else:
164
+ ResourceError = getattr(resource, "error", OSError)
165
+
166
+ _DEFAULT_BATCH_SIZE = 128
167
+ _NOFILES_DEFAULT_BATCH_SIZE = 1280
168
+
169
+
170
+ def _get_batch_size(nofiles=False):
171
+ from fsspec.config import conf
172
+
173
+ if nofiles:
174
+ if "nofiles_gather_batch_size" in conf:
175
+ return conf["nofiles_gather_batch_size"]
176
+ else:
177
+ if "gather_batch_size" in conf:
178
+ return conf["gather_batch_size"]
179
+ if nofiles:
180
+ return _NOFILES_DEFAULT_BATCH_SIZE
181
+ if resource is None:
182
+ return _DEFAULT_BATCH_SIZE
183
+
184
+ try:
185
+ soft_limit, _ = resource.getrlimit(resource.RLIMIT_NOFILE)
186
+ except (ImportError, ValueError, ResourceError):
187
+ return _DEFAULT_BATCH_SIZE
188
+
189
+ if soft_limit == resource.RLIM_INFINITY:
190
+ return -1
191
+ else:
192
+ return soft_limit // 8
193
+
194
+
195
+ def running_async() -> bool:
196
+ """Being executed by an event loop?"""
197
+ try:
198
+ asyncio.get_running_loop()
199
+ return True
200
+ except RuntimeError:
201
+ return False
202
+
203
+
204
+ async def _run_coros_in_chunks(
205
+ coros,
206
+ batch_size=None,
207
+ callback=DEFAULT_CALLBACK,
208
+ timeout=None,
209
+ return_exceptions=False,
210
+ nofiles=False,
211
+ ):
212
+ """Run the given coroutines in chunks.
213
+
214
+ Parameters
215
+ ----------
216
+ coros: list of coroutines to run
217
+ batch_size: int or None
218
+ Number of coroutines to submit/wait on simultaneously.
219
+ If -1, then it will not be any throttling. If
220
+ None, it will be inferred from _get_batch_size()
221
+ callback: fsspec.callbacks.Callback instance
222
+ Gets a relative_update when each coroutine completes
223
+ timeout: number or None
224
+ If given, each coroutine times out after this time. Note that, since
225
+ there are multiple batches, the total run time of this function will in
226
+ general be longer
227
+ return_exceptions: bool
228
+ Same meaning as in asyncio.gather
229
+ nofiles: bool
230
+ If inferring the batch_size, does this operation involve local files?
231
+ If yes, you normally expect smaller batches.
232
+ """
233
+
234
+ if batch_size is None:
235
+ batch_size = _get_batch_size(nofiles=nofiles)
236
+
237
+ if batch_size == -1:
238
+ batch_size = len(coros)
239
+
240
+ assert batch_size > 0
241
+
242
+ async def _run_coro(coro, i):
243
+ try:
244
+ return await asyncio.wait_for(coro, timeout=timeout), i
245
+ except Exception as e:
246
+ if not return_exceptions:
247
+ raise
248
+ return e, i
249
+ finally:
250
+ callback.relative_update(1)
251
+
252
+ i = 0
253
+ n = len(coros)
254
+ results = [None] * n
255
+ pending = set()
256
+
257
+ while pending or i < n:
258
+ while len(pending) < batch_size and i < n:
259
+ pending.add(asyncio.ensure_future(_run_coro(coros[i], i)))
260
+ i += 1
261
+
262
+ if not pending:
263
+ break
264
+
265
+ done, pending = await asyncio.wait(pending, return_when=asyncio.FIRST_COMPLETED)
266
+ first_exc = None
267
+ while done:
268
+ task = done.pop()
269
+ try:
270
+ result, k = await task
271
+ results[k] = result
272
+ except Exception as exc:
273
+ if first_exc is None:
274
+ first_exc = exc
275
+
276
+ if first_exc is not None:
277
+ for task in pending:
278
+ task.cancel()
279
+ if pending:
280
+ await asyncio.gather(*pending, return_exceptions=True)
281
+ raise first_exc
282
+
283
+ return results
284
+
285
+
286
+ # these methods should be implemented as async by any async-able backend
287
+ async_methods = [
288
+ "_ls",
289
+ "_cat_file",
290
+ "_get_file",
291
+ "_put_file",
292
+ "_rm_file",
293
+ "_cp_file",
294
+ "_pipe_file",
295
+ "_expand_path",
296
+ "_info",
297
+ "_isfile",
298
+ "_isdir",
299
+ "_exists",
300
+ "_walk",
301
+ "_glob",
302
+ "_find",
303
+ "_du",
304
+ "_size",
305
+ "_mkdir",
306
+ "_makedirs",
307
+ ]
308
+
309
+
310
+ class AsyncFileSystem(AbstractFileSystem):
311
+ """Async file operations, default implementations
312
+
313
+ Passes bulk operations to asyncio.gather for concurrent operation.
314
+
315
+ Implementations that have concurrent batch operations and/or async methods
316
+ should inherit from this class instead of AbstractFileSystem. Docstrings are
317
+ copied from the un-underscored method in AbstractFileSystem, if not given.
318
+ """
319
+
320
+ # note that methods do not have docstring here; they will be copied
321
+ # for _* methods and inferred for overridden methods.
322
+
323
+ async_impl = True
324
+ mirror_sync_methods = True
325
+ disable_throttling = False
326
+
327
+ def __init__(self, *args, asynchronous=False, loop=None, batch_size=None, **kwargs):
328
+ self.asynchronous = asynchronous
329
+ self._pid = os.getpid()
330
+ if not asynchronous:
331
+ self._loop = loop or get_loop()
332
+ else:
333
+ self._loop = None
334
+ self.batch_size = batch_size
335
+ super().__init__(*args, **kwargs)
336
+
337
+ @property
338
+ def loop(self):
339
+ if self._pid != os.getpid():
340
+ raise RuntimeError("This class is not fork-safe")
341
+ return self._loop
342
+
343
+ async def _rm_file(self, path, **kwargs):
344
+ if (
345
+ inspect.iscoroutinefunction(self._rm)
346
+ and type(self)._rm is not AsyncFileSystem._rm
347
+ ):
348
+ return await self._rm(path, recursive=False, batch_size=1, **kwargs)
349
+ raise NotImplementedError
350
+
351
+ async def _rm(self, path, recursive=False, batch_size=None, **kwargs):
352
+ # TODO: implement on_error
353
+ batch_size = batch_size or self.batch_size
354
+ path = await self._expand_path(path, recursive=recursive)
355
+ return await _run_coros_in_chunks(
356
+ [self._rm_file(p, **kwargs) for p in reversed(path)],
357
+ batch_size=batch_size,
358
+ nofiles=True,
359
+ )
360
+
361
+ async def _cp_file(self, path1, path2, **kwargs):
362
+ raise NotImplementedError
363
+
364
+ async def _mv_file(self, path1, path2):
365
+ await self._cp_file(path1, path2)
366
+ await self._rm_file(path1)
367
+
368
+ async def _copy(
369
+ self,
370
+ path1,
371
+ path2,
372
+ recursive=False,
373
+ on_error=None,
374
+ maxdepth=None,
375
+ batch_size=None,
376
+ **kwargs,
377
+ ):
378
+ if on_error is None and recursive:
379
+ on_error = "ignore"
380
+ elif on_error is None:
381
+ on_error = "raise"
382
+
383
+ if isinstance(path1, list) and isinstance(path2, list):
384
+ # No need to expand paths when both source and destination
385
+ # are provided as lists
386
+ paths1 = path1
387
+ paths2 = path2
388
+ else:
389
+ source_is_str = isinstance(path1, str)
390
+ paths1 = await self._expand_path(
391
+ path1, maxdepth=maxdepth, recursive=recursive
392
+ )
393
+ if source_is_str and (not recursive or maxdepth is not None):
394
+ # Non-recursive glob does not copy directories
395
+ paths1 = [
396
+ p for p in paths1 if not (trailing_sep(p) or await self._isdir(p))
397
+ ]
398
+ if not paths1:
399
+ return
400
+
401
+ source_is_file = len(paths1) == 1
402
+ dest_is_dir = isinstance(path2, str) and (
403
+ trailing_sep(path2) or await self._isdir(path2)
404
+ )
405
+
406
+ exists = source_is_str and (
407
+ (has_magic(path1) and source_is_file)
408
+ or (not has_magic(path1) and dest_is_dir and not trailing_sep(path1))
409
+ )
410
+ paths2 = other_paths(
411
+ paths1,
412
+ path2,
413
+ exists=exists,
414
+ flatten=not source_is_str,
415
+ )
416
+
417
+ batch_size = batch_size or self.batch_size
418
+ coros = [self._cp_file(p1, p2, **kwargs) for p1, p2 in zip(paths1, paths2)]
419
+ result = await _run_coros_in_chunks(
420
+ coros, batch_size=batch_size, return_exceptions=True, nofiles=True
421
+ )
422
+
423
+ for ex in filter(is_exception, result):
424
+ if on_error == "ignore" and isinstance(ex, FileNotFoundError):
425
+ continue
426
+ raise ex
427
+
428
+ async def _pipe_file(self, path, value, mode="overwrite", **kwargs):
429
+ raise NotImplementedError
430
+
431
+ async def _pipe(self, path, value=None, batch_size=None, **kwargs):
432
+ if isinstance(path, str):
433
+ path = {path: value}
434
+ batch_size = batch_size or self.batch_size
435
+ return await _run_coros_in_chunks(
436
+ [self._pipe_file(k, v, **kwargs) for k, v in path.items()],
437
+ batch_size=batch_size,
438
+ nofiles=True,
439
+ )
440
+
441
+ async def _process_limits(self, url, start, end):
442
+ """Helper for "Range"-based _cat_file"""
443
+ size = None
444
+ suff = False
445
+ if start is not None and start < 0:
446
+ # if start is negative and end None, end is the "suffix length"
447
+ if end is None:
448
+ end = -start
449
+ start = ""
450
+ suff = True
451
+ else:
452
+ size = size or (await self._info(url))["size"]
453
+ start = size + start
454
+ elif start is None:
455
+ start = 0
456
+ if not suff:
457
+ if end is not None and end < 0:
458
+ if start is not None:
459
+ size = size or (await self._info(url))["size"]
460
+ end = size + end
461
+ elif end is None:
462
+ end = ""
463
+ if isinstance(end, numbers.Integral):
464
+ end -= 1 # bytes range is inclusive
465
+ return f"bytes={start}-{end}"
466
+
467
+ async def _cat_file(self, path, start=None, end=None, **kwargs):
468
+ raise NotImplementedError
469
+
470
+ async def _cat(
471
+ self, path, recursive=False, on_error="raise", batch_size=None, **kwargs
472
+ ):
473
+ paths = await self._expand_path(path, recursive=recursive)
474
+ coros = [self._cat_file(path, **kwargs) for path in paths]
475
+ batch_size = batch_size or self.batch_size
476
+ out = await _run_coros_in_chunks(
477
+ coros, batch_size=batch_size, nofiles=True, return_exceptions=True
478
+ )
479
+ if on_error == "raise":
480
+ ex = next(filter(is_exception, out), False)
481
+ if ex:
482
+ raise ex
483
+ if (
484
+ len(paths) > 1
485
+ or isinstance(path, list)
486
+ or paths[0] != self._strip_protocol(path)
487
+ ):
488
+ return {
489
+ k: v
490
+ for k, v in zip(paths, out)
491
+ if on_error != "omit" or not is_exception(v)
492
+ }
493
+ else:
494
+ return out[0]
495
+
496
+ async def _cat_ranges(
497
+ self,
498
+ paths,
499
+ starts,
500
+ ends,
501
+ max_gap=None,
502
+ batch_size=None,
503
+ on_error="return",
504
+ **kwargs,
505
+ ):
506
+ """Get the contents of byte ranges from one or more files
507
+
508
+ Parameters
509
+ ----------
510
+ paths: list
511
+ A list of of filepaths on this filesystems
512
+ starts, ends: int or list
513
+ Bytes limits of the read. If using a single int, the same value will be
514
+ used to read all the specified files.
515
+ """
516
+ # TODO: on_error
517
+ if max_gap is not None:
518
+ # use utils.merge_offset_ranges
519
+ raise NotImplementedError
520
+ if not isinstance(paths, list):
521
+ raise TypeError
522
+ if not isinstance(starts, Iterable):
523
+ starts = [starts] * len(paths)
524
+ if not isinstance(ends, Iterable):
525
+ ends = [ends] * len(paths)
526
+ if len(starts) != len(paths) or len(ends) != len(paths):
527
+ raise ValueError
528
+ coros = [
529
+ self._cat_file(p, start=s, end=e, **kwargs)
530
+ for p, s, e in zip(paths, starts, ends)
531
+ ]
532
+ batch_size = batch_size or self.batch_size
533
+ return await _run_coros_in_chunks(
534
+ coros, batch_size=batch_size, nofiles=True, return_exceptions=True
535
+ )
536
+
537
+ async def _put_file(self, lpath, rpath, mode="overwrite", **kwargs):
538
+ raise NotImplementedError
539
+
540
+ async def _put(
541
+ self,
542
+ lpath,
543
+ rpath,
544
+ recursive=False,
545
+ callback=DEFAULT_CALLBACK,
546
+ batch_size=None,
547
+ maxdepth=None,
548
+ **kwargs,
549
+ ):
550
+ """Copy file(s) from local.
551
+
552
+ Copies a specific file or tree of files (if recursive=True). If rpath
553
+ ends with a "/", it will be assumed to be a directory, and target files
554
+ will go within.
555
+
556
+ The put_file method will be called concurrently on a batch of files. The
557
+ batch_size option can configure the amount of futures that can be executed
558
+ at the same time. If it is -1, then all the files will be uploaded concurrently.
559
+ The default can be set for this instance by passing "batch_size" in the
560
+ constructor, or for all instances by setting the "gather_batch_size" key
561
+ in ``fsspec.config.conf``, falling back to 1/8th of the system limit .
562
+ """
563
+ if isinstance(lpath, list) and isinstance(rpath, list):
564
+ # No need to expand paths when both source and destination
565
+ # are provided as lists
566
+ rpaths = rpath
567
+ lpaths = lpath
568
+ else:
569
+ source_is_str = isinstance(lpath, str)
570
+ if source_is_str:
571
+ lpath = make_path_posix(lpath)
572
+ fs = LocalFileSystem()
573
+ lpaths = fs.expand_path(lpath, recursive=recursive, maxdepth=maxdepth)
574
+ if source_is_str and (not recursive or maxdepth is not None):
575
+ # Non-recursive glob does not copy directories
576
+ lpaths = [p for p in lpaths if not (trailing_sep(p) or fs.isdir(p))]
577
+ if not lpaths:
578
+ return
579
+
580
+ source_is_file = len(lpaths) == 1
581
+ dest_is_dir = isinstance(rpath, str) and (
582
+ trailing_sep(rpath) or await self._isdir(rpath)
583
+ )
584
+
585
+ rpath = self._strip_protocol(rpath)
586
+ exists = source_is_str and (
587
+ (has_magic(lpath) and source_is_file)
588
+ or (not has_magic(lpath) and dest_is_dir and not trailing_sep(lpath))
589
+ )
590
+ rpaths = other_paths(
591
+ lpaths,
592
+ rpath,
593
+ exists=exists,
594
+ flatten=not source_is_str,
595
+ )
596
+
597
+ is_dir = {l: os.path.isdir(l) for l in lpaths}
598
+ rdirs = [r for l, r in zip(lpaths, rpaths) if is_dir[l]]
599
+ file_pairs = [(l, r) for l, r in zip(lpaths, rpaths) if not is_dir[l]]
600
+
601
+ await asyncio.gather(*[self._makedirs(d, exist_ok=True) for d in rdirs])
602
+ batch_size = batch_size or self.batch_size
603
+
604
+ coros = []
605
+ callback.set_size(len(file_pairs))
606
+ for lfile, rfile in file_pairs:
607
+ put_file = callback.branch_coro(self._put_file)
608
+ coros.append(put_file(lfile, rfile, **kwargs))
609
+
610
+ return await _run_coros_in_chunks(
611
+ coros, batch_size=batch_size, callback=callback
612
+ )
613
+
614
+ async def _get_file(self, rpath, lpath, **kwargs):
615
+ raise NotImplementedError
616
+
617
+ async def _get(
618
+ self,
619
+ rpath,
620
+ lpath,
621
+ recursive=False,
622
+ callback=DEFAULT_CALLBACK,
623
+ maxdepth=None,
624
+ **kwargs,
625
+ ):
626
+ """Copy file(s) to local.
627
+
628
+ Copies a specific file or tree of files (if recursive=True). If lpath
629
+ ends with a "/", it will be assumed to be a directory, and target files
630
+ will go within. Can submit a list of paths, which may be glob-patterns
631
+ and will be expanded.
632
+
633
+ The get_file method will be called concurrently on a batch of files. The
634
+ batch_size option can configure the amount of futures that can be executed
635
+ at the same time. If it is -1, then all the files will be uploaded concurrently.
636
+ The default can be set for this instance by passing "batch_size" in the
637
+ constructor, or for all instances by setting the "gather_batch_size" key
638
+ in ``fsspec.config.conf``, falling back to 1/8th of the system limit .
639
+ """
640
+ if isinstance(lpath, list) and isinstance(rpath, list):
641
+ # No need to expand paths when both source and destination
642
+ # are provided as lists
643
+ rpaths = rpath
644
+ lpaths = lpath
645
+ else:
646
+ source_is_str = isinstance(rpath, str)
647
+ # First check for rpath trailing slash as _strip_protocol removes it.
648
+ source_not_trailing_sep = source_is_str and not trailing_sep(rpath)
649
+ rpath = self._strip_protocol(rpath)
650
+ rpaths = await self._expand_path(
651
+ rpath, recursive=recursive, maxdepth=maxdepth
652
+ )
653
+ if source_is_str and (not recursive or maxdepth is not None):
654
+ # Non-recursive glob does not copy directories
655
+ rpaths = [
656
+ p for p in rpaths if not (trailing_sep(p) or await self._isdir(p))
657
+ ]
658
+ if not rpaths:
659
+ return
660
+
661
+ lpath = make_path_posix(lpath)
662
+ source_is_file = len(rpaths) == 1
663
+ dest_is_dir = isinstance(lpath, str) and (
664
+ trailing_sep(lpath) or LocalFileSystem().isdir(lpath)
665
+ )
666
+
667
+ exists = source_is_str and (
668
+ (has_magic(rpath) and source_is_file)
669
+ or (not has_magic(rpath) and dest_is_dir and source_not_trailing_sep)
670
+ )
671
+ lpaths = other_paths(
672
+ rpaths,
673
+ lpath,
674
+ exists=exists,
675
+ flatten=not source_is_str,
676
+ )
677
+
678
+ [os.makedirs(os.path.dirname(lp), exist_ok=True) for lp in lpaths]
679
+ batch_size = kwargs.pop("batch_size", self.batch_size)
680
+
681
+ coros = []
682
+ callback.set_size(len(lpaths))
683
+ for lpath, rpath in zip(lpaths, rpaths):
684
+ get_file = callback.branch_coro(self._get_file)
685
+ coros.append(get_file(rpath, lpath, **kwargs))
686
+ return await _run_coros_in_chunks(
687
+ coros, batch_size=batch_size, callback=callback
688
+ )
689
+
690
+ async def _isfile(self, path):
691
+ try:
692
+ return (await self._info(path))["type"] == "file"
693
+ except: # noqa: E722
694
+ return False
695
+
696
+ async def _isdir(self, path):
697
+ try:
698
+ return (await self._info(path))["type"] == "directory"
699
+ except OSError:
700
+ return False
701
+
702
+ async def _size(self, path):
703
+ return (await self._info(path)).get("size", None)
704
+
705
+ async def _sizes(self, paths, batch_size=None):
706
+ batch_size = batch_size or self.batch_size
707
+ return await _run_coros_in_chunks(
708
+ [self._size(p) for p in paths], batch_size=batch_size
709
+ )
710
+
711
+ async def _exists(self, path, **kwargs):
712
+ try:
713
+ await self._info(path, **kwargs)
714
+ return True
715
+ except FileNotFoundError:
716
+ return False
717
+
718
+ async def _info(self, path, **kwargs):
719
+ raise NotImplementedError
720
+
721
+ async def _ls(self, path, detail=True, **kwargs):
722
+ raise NotImplementedError
723
+
724
+ async def _walk(self, path, maxdepth=None, on_error="omit", **kwargs):
725
+ if maxdepth is not None and maxdepth < 1:
726
+ raise ValueError("maxdepth must be at least 1")
727
+
728
+ path = self._strip_protocol(path)
729
+ full_dirs = {}
730
+ dirs = {}
731
+ files = {}
732
+
733
+ detail = kwargs.pop("detail", False)
734
+ try:
735
+ listing = await self._ls(path, detail=True, **kwargs)
736
+ except (FileNotFoundError, OSError) as e:
737
+ if on_error == "raise":
738
+ raise
739
+ elif callable(on_error):
740
+ on_error(e)
741
+ if detail:
742
+ yield path, {}, {}
743
+ else:
744
+ yield path, [], []
745
+ return
746
+
747
+ for info in listing:
748
+ # each info name must be at least [path]/part , but here
749
+ # we check also for names like [path]/part/
750
+ pathname = info["name"].rstrip("/")
751
+ name = pathname.rsplit("/", 1)[-1]
752
+ if info["type"] == "directory" and pathname != path:
753
+ # do not include "self" path
754
+ full_dirs[name] = pathname
755
+ dirs[name] = info
756
+ elif pathname == path:
757
+ # file-like with same name as give path
758
+ files[""] = info
759
+ else:
760
+ files[name] = info
761
+
762
+ if detail:
763
+ yield path, dirs, files
764
+ else:
765
+ yield path, list(dirs), list(files)
766
+
767
+ if maxdepth is not None:
768
+ maxdepth -= 1
769
+ if maxdepth < 1:
770
+ return
771
+
772
+ for d in dirs:
773
+ async for _ in self._walk(
774
+ full_dirs[d], maxdepth=maxdepth, detail=detail, **kwargs
775
+ ):
776
+ yield _
777
+
778
+ async def _glob(self, path, maxdepth=None, **kwargs):
779
+ if maxdepth is not None and maxdepth < 1:
780
+ raise ValueError("maxdepth must be at least 1")
781
+
782
+ import re
783
+
784
+ seps = (os.path.sep, os.path.altsep) if os.path.altsep else (os.path.sep,)
785
+ ends_with_sep = path.endswith(seps) # _strip_protocol strips trailing slash
786
+ path = self._strip_protocol(path)
787
+ append_slash_to_dirname = ends_with_sep or path.endswith(
788
+ tuple(sep + "**" for sep in seps)
789
+ )
790
+ idx_star = path.find("*") if path.find("*") >= 0 else len(path)
791
+ idx_qmark = path.find("?") if path.find("?") >= 0 else len(path)
792
+ idx_brace = path.find("[") if path.find("[") >= 0 else len(path)
793
+
794
+ min_idx = min(idx_star, idx_qmark, idx_brace)
795
+
796
+ detail = kwargs.pop("detail", False)
797
+ withdirs = kwargs.pop("withdirs", True)
798
+
799
+ if not has_magic(path):
800
+ if await self._exists(path, **kwargs):
801
+ if not detail:
802
+ return [path]
803
+ else:
804
+ return {path: await self._info(path, **kwargs)}
805
+ else:
806
+ if not detail:
807
+ return [] # glob of non-existent returns empty
808
+ else:
809
+ return {}
810
+ elif "/" in path[:min_idx]:
811
+ first_wildcard_idx = min_idx
812
+ min_idx = path[:min_idx].rindex("/")
813
+ root = path[
814
+ : min_idx + 1
815
+ ] # everything up to the last / before the first wildcard
816
+ prefix = path[
817
+ min_idx + 1 : first_wildcard_idx
818
+ ] # stem between last "/" and first wildcard
819
+ depth = path[min_idx + 1 :].count("/") + 1
820
+ else:
821
+ root = ""
822
+ prefix = path[:min_idx] # stem up to the first wildcard
823
+ depth = path[min_idx + 1 :].count("/") + 1
824
+
825
+ if "**" in path:
826
+ if maxdepth is not None:
827
+ idx_double_stars = path.find("**")
828
+ depth_double_stars = path[idx_double_stars:].count("/") + 1
829
+ depth = depth - depth_double_stars + maxdepth
830
+ else:
831
+ depth = None
832
+
833
+ # Pass the filename stem as prefix= so backends that support it such as
834
+ # gcsfs, s3fs and adlfs can filter server-side up to the first wildcard.
835
+ if prefix:
836
+ kwargs["prefix"] = prefix
837
+ allpaths = await self._find(
838
+ root, maxdepth=depth, withdirs=withdirs, detail=True, **kwargs
839
+ )
840
+
841
+ pattern = glob_translate(path + ("/" if ends_with_sep else ""))
842
+ pattern = re.compile(pattern)
843
+
844
+ out = {
845
+ p: info
846
+ for p, info in sorted(allpaths.items())
847
+ if pattern.match(
848
+ p + "/"
849
+ if append_slash_to_dirname and info["type"] == "directory"
850
+ else p
851
+ )
852
+ }
853
+
854
+ if detail:
855
+ return out
856
+ else:
857
+ return list(out)
858
+
859
+ async def _du(self, path, total=True, maxdepth=None, **kwargs):
860
+ sizes = {}
861
+ # async for?
862
+ for f in await self._find(path, maxdepth=maxdepth, **kwargs):
863
+ info = await self._info(f)
864
+ sizes[info["name"]] = info["size"]
865
+ if total:
866
+ return sum(sizes.values())
867
+ else:
868
+ return sizes
869
+
870
+ async def _find(self, path, maxdepth=None, withdirs=False, **kwargs):
871
+ path = self._strip_protocol(path)
872
+ out = {}
873
+ detail = kwargs.pop("detail", False)
874
+
875
+ # Add the root directory if withdirs is requested
876
+ # This is needed for posix glob compliance
877
+ if withdirs and path != "" and await self._isdir(path):
878
+ out[path] = await self._info(path)
879
+
880
+ # async for?
881
+ async for _, dirs, files in self._walk(path, maxdepth, detail=True, **kwargs):
882
+ if withdirs:
883
+ files.update(dirs)
884
+ out.update({info["name"]: info for name, info in files.items()})
885
+ if not out and (await self._isfile(path)):
886
+ # walk works on directories, but find should also return [path]
887
+ # when path happens to be a file
888
+ out[path] = {}
889
+ names = sorted(out)
890
+ if not detail:
891
+ return names
892
+ else:
893
+ return {name: out[name] for name in names}
894
+
895
+ async def _expand_path(self, path, recursive=False, maxdepth=None):
896
+ if maxdepth is not None and maxdepth < 1:
897
+ raise ValueError("maxdepth must be at least 1")
898
+
899
+ if isinstance(path, str):
900
+ out = await self._expand_path([path], recursive, maxdepth)
901
+ else:
902
+ out = set()
903
+ path = [self._strip_protocol(p) for p in path]
904
+ for p in path: # can gather here
905
+ if has_magic(p):
906
+ bit = set(await self._glob(p, maxdepth=maxdepth))
907
+ out |= bit
908
+ if recursive:
909
+ # glob call above expanded one depth so if maxdepth is defined
910
+ # then decrement it in expand_path call below. If it is zero
911
+ # after decrementing then avoid expand_path call.
912
+ if maxdepth is not None and maxdepth <= 1:
913
+ continue
914
+ out |= set(
915
+ await self._expand_path(
916
+ list(bit),
917
+ recursive=recursive,
918
+ maxdepth=maxdepth - 1 if maxdepth is not None else None,
919
+ )
920
+ )
921
+ continue
922
+ elif recursive:
923
+ rec = set(await self._find(p, maxdepth=maxdepth, withdirs=True))
924
+ out |= rec
925
+ if p not in out and (recursive is False or (await self._exists(p))):
926
+ # should only check once, for the root
927
+ out.add(p)
928
+ if not out:
929
+ raise FileNotFoundError(path)
930
+ return sorted(out)
931
+
932
+ async def _mkdir(self, path, create_parents=True, **kwargs):
933
+ pass # not necessary to implement, may not have directories
934
+
935
+ async def _makedirs(self, path, exist_ok=False):
936
+ pass # not necessary to implement, may not have directories
937
+
938
+ async def open_async(self, path, mode="rb", **kwargs):
939
+ if "b" not in mode or kwargs.get("compression"):
940
+ raise ValueError
941
+ raise NotImplementedError
942
+
943
+
944
+ def mirror_sync_methods(obj):
945
+ """Populate sync and async methods for obj
946
+
947
+ For each method will create a sync version if the name refers to an async method
948
+ (coroutine) and there is no override in the child class; will create an async
949
+ method for the corresponding sync method if there is no implementation.
950
+
951
+ Uses the methods specified in
952
+ - async_methods: the set that an implementation is expected to provide
953
+ - default_async_methods: that can be derived from their sync version in
954
+ AbstractFileSystem
955
+ - AsyncFileSystem: async-specific default coroutines
956
+ """
957
+ from fsspec import AbstractFileSystem
958
+
959
+ for method in async_methods + dir(AsyncFileSystem):
960
+ if not method.startswith("_"):
961
+ continue
962
+ smethod = method[1:]
963
+ if private.match(method):
964
+ isco = inspect.iscoroutinefunction(getattr(obj, method, None))
965
+ unsync = getattr(getattr(obj, smethod, False), "__func__", None)
966
+ is_default = unsync is getattr(AbstractFileSystem, smethod, "")
967
+ if isco and is_default:
968
+ mth = sync_wrapper(getattr(obj, method), obj=obj)
969
+ setattr(obj, smethod, mth)
970
+ if not mth.__doc__:
971
+ mth.__doc__ = getattr(
972
+ getattr(AbstractFileSystem, smethod, None), "__doc__", ""
973
+ )
974
+
975
+
976
+ class FSSpecCoroutineCancel(Exception):
977
+ pass
978
+
979
+
980
+ def _dump_running_tasks(
981
+ printout=True, cancel=True, exc=FSSpecCoroutineCancel, with_task=False
982
+ ):
983
+ import traceback
984
+
985
+ tasks = [t for t in asyncio.tasks.all_tasks(loop[0]) if not t.done()]
986
+ if printout:
987
+ [task.print_stack() for task in tasks]
988
+ out = [
989
+ {
990
+ "locals": task._coro.cr_frame.f_locals,
991
+ "file": task._coro.cr_frame.f_code.co_filename,
992
+ "firstline": task._coro.cr_frame.f_code.co_firstlineno,
993
+ "linelo": task._coro.cr_frame.f_lineno,
994
+ "stack": traceback.format_stack(task._coro.cr_frame),
995
+ "task": task if with_task else None,
996
+ }
997
+ for task in tasks
998
+ ]
999
+ if cancel:
1000
+ for t in tasks:
1001
+ cbs = t._callbacks
1002
+ t.cancel()
1003
+ asyncio.futures.Future.set_exception(t, exc)
1004
+ asyncio.futures.Future.cancel(t)
1005
+ [cb[0](t) for cb in cbs] # cancels any dependent concurrent.futures
1006
+ try:
1007
+ t._coro.throw(exc) # exits coro, unless explicitly handled
1008
+ except exc:
1009
+ pass
1010
+ return out
1011
+
1012
+
1013
+ class AbstractAsyncStreamedFile(AbstractBufferedFile):
1014
+ # no read buffering, and always auto-commit
1015
+ # TODO: readahead might still be useful here, but needs async version
1016
+
1017
+ async def read(self, length=-1):
1018
+ """
1019
+ Return data from cache, or fetch pieces as necessary
1020
+
1021
+ Parameters
1022
+ ----------
1023
+ length: int (-1)
1024
+ Number of bytes to read; if <0, all remaining bytes.
1025
+ """
1026
+ length = -1 if length is None else int(length)
1027
+ if self.mode != "rb":
1028
+ raise ValueError("File not in read mode")
1029
+ if length < 0:
1030
+ length = self.size - self.loc
1031
+ if self.closed:
1032
+ raise ValueError("I/O operation on closed file.")
1033
+ if length == 0:
1034
+ # don't even bother calling fetch
1035
+ return b""
1036
+ out = await self._fetch_range(self.loc, self.loc + length)
1037
+ self.loc += len(out)
1038
+ return out
1039
+
1040
+ async def write(self, data):
1041
+ """
1042
+ Write data to buffer.
1043
+
1044
+ Buffer only sent on flush() or if buffer is greater than
1045
+ or equal to blocksize.
1046
+
1047
+ Parameters
1048
+ ----------
1049
+ data: bytes
1050
+ Set of bytes to be written.
1051
+ """
1052
+ if self.mode not in {"wb", "ab"}:
1053
+ raise ValueError("File not in write mode")
1054
+ if self.closed:
1055
+ raise ValueError("I/O operation on closed file.")
1056
+ if self.forced:
1057
+ raise ValueError("This file has been force-flushed, can only close")
1058
+ out = self.buffer.write(data)
1059
+ self.loc += out
1060
+ if self.buffer.tell() >= self.blocksize:
1061
+ await self.flush()
1062
+ return out
1063
+
1064
+ async def close(self):
1065
+ """Close file
1066
+
1067
+ Finalizes writes, discards cache
1068
+ """
1069
+ if getattr(self, "_unclosable", False):
1070
+ return
1071
+ if self.closed:
1072
+ return
1073
+ if self.mode == "rb":
1074
+ self.cache = None
1075
+ else:
1076
+ if not self.forced:
1077
+ await self.flush(force=True)
1078
+
1079
+ if self.fs is not None:
1080
+ self.fs.invalidate_cache(self.path)
1081
+ self.fs.invalidate_cache(self.fs._parent(self.path))
1082
+
1083
+ self.closed = True
1084
+
1085
+ async def flush(self, force=False):
1086
+ if self.closed:
1087
+ raise ValueError("Flush on closed file")
1088
+ if force and self.forced:
1089
+ raise ValueError("Force flush cannot be called more than once")
1090
+ if force:
1091
+ self.forced = True
1092
+
1093
+ if self.mode not in {"wb", "ab"}:
1094
+ # no-op to flush on read-mode
1095
+ return
1096
+
1097
+ if not force and self.buffer.tell() < self.blocksize:
1098
+ # Defer write on small block
1099
+ return
1100
+
1101
+ if self.offset is None:
1102
+ # Initialize a multipart upload
1103
+ self.offset = 0
1104
+ try:
1105
+ await self._initiate_upload()
1106
+ except:
1107
+ self.closed = True
1108
+ raise
1109
+
1110
+ if await self._upload_chunk(final=force) is not False:
1111
+ self.offset += self.buffer.seek(0, 2)
1112
+ self.buffer = io.BytesIO()
1113
+
1114
+ async def __aenter__(self):
1115
+ return self
1116
+
1117
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
1118
+ await self.close()
1119
+
1120
+ async def _fetch_range(self, start, end):
1121
+ raise NotImplementedError
1122
+
1123
+ async def _initiate_upload(self):
1124
+ pass
1125
+
1126
+ async def _upload_chunk(self, final=False):
1127
+ raise NotImplementedError
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/fsspec/fuse.py ADDED
@@ -0,0 +1,324 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import argparse
2
+ import logging
3
+ import os
4
+ import stat
5
+ import threading
6
+ import time
7
+ from errno import EIO, ENOENT
8
+
9
+ from fuse import FUSE, FuseOSError, LoggingMixIn, Operations
10
+
11
+ from fsspec import __version__
12
+ from fsspec.core import url_to_fs
13
+
14
+ logger = logging.getLogger("fsspec.fuse")
15
+
16
+
17
+ class FUSEr(Operations):
18
+ def __init__(self, fs, path, ready_file=False):
19
+ self.fs = fs
20
+ self.cache = {}
21
+ self.root = path.rstrip("/") + "/"
22
+ self.counter = 0
23
+ logger.info("Starting FUSE at %s", path)
24
+ self._ready_file = ready_file
25
+
26
+ def getattr(self, path, fh=None):
27
+ logger.debug("getattr %s", path)
28
+ if self._ready_file and path in ["/.fuse_ready", ".fuse_ready"]:
29
+ return {"type": "file", "st_size": 5}
30
+
31
+ path = "".join([self.root, path.lstrip("/")]).rstrip("/")
32
+ try:
33
+ info = self.fs.info(path)
34
+ except FileNotFoundError as exc:
35
+ raise FuseOSError(ENOENT) from exc
36
+
37
+ data = {"st_uid": info.get("uid", 1000), "st_gid": info.get("gid", 1000)}
38
+ perm = info.get("mode", 0o777)
39
+
40
+ if info["type"] != "file":
41
+ data["st_mode"] = stat.S_IFDIR | perm
42
+ data["st_size"] = 0
43
+ data["st_blksize"] = 0
44
+ else:
45
+ data["st_mode"] = stat.S_IFREG | perm
46
+ data["st_size"] = info["size"]
47
+ data["st_blksize"] = 5 * 2**20
48
+ data["st_nlink"] = 1
49
+ data["st_atime"] = info["atime"] if "atime" in info else time.time()
50
+ data["st_ctime"] = info["ctime"] if "ctime" in info else time.time()
51
+ data["st_mtime"] = info["mtime"] if "mtime" in info else time.time()
52
+ return data
53
+
54
+ def readdir(self, path, fh):
55
+ logger.debug("readdir %s", path)
56
+ path = "".join([self.root, path.lstrip("/")])
57
+ files = self.fs.ls(path, False)
58
+ files = [os.path.basename(f.rstrip("/")) for f in files]
59
+ return [".", ".."] + files
60
+
61
+ def mkdir(self, path, mode):
62
+ path = "".join([self.root, path.lstrip("/")])
63
+ self.fs.mkdir(path)
64
+ return 0
65
+
66
+ def rmdir(self, path):
67
+ path = "".join([self.root, path.lstrip("/")])
68
+ self.fs.rmdir(path)
69
+ return 0
70
+
71
+ def read(self, path, size, offset, fh):
72
+ logger.debug("read %s", (path, size, offset))
73
+ if self._ready_file and path in ["/.fuse_ready", ".fuse_ready"]:
74
+ # status indicator
75
+ return b"ready"
76
+
77
+ f = self.cache[fh]
78
+ f.seek(offset)
79
+ out = f.read(size)
80
+ return out
81
+
82
+ def write(self, path, data, offset, fh):
83
+ logger.debug("write %s", (path, offset))
84
+ f = self.cache[fh]
85
+ f.seek(offset)
86
+ f.write(data)
87
+ return len(data)
88
+
89
+ def create(self, path, flags, fi=None):
90
+ logger.debug("create %s", (path, flags))
91
+ fn = "".join([self.root, path.lstrip("/")])
92
+ self.fs.touch(fn) # OS will want to get attributes immediately
93
+ f = self.fs.open(fn, "wb")
94
+ self.cache[self.counter] = f
95
+ self.counter += 1
96
+ return self.counter - 1
97
+
98
+ def open(self, path, flags):
99
+ logger.debug("open %s", (path, flags))
100
+ fn = "".join([self.root, path.lstrip("/")])
101
+ if flags % 2 == 0:
102
+ # read
103
+ mode = "rb"
104
+ else:
105
+ # write/create
106
+ mode = "wb"
107
+ self.cache[self.counter] = self.fs.open(fn, mode)
108
+ self.counter += 1
109
+ return self.counter - 1
110
+
111
+ def truncate(self, path, length, fh=None):
112
+ fn = "".join([self.root, path.lstrip("/")])
113
+ if length != 0:
114
+ raise NotImplementedError
115
+ # maybe should be no-op since open with write sets size to zero anyway
116
+ self.fs.touch(fn)
117
+
118
+ def unlink(self, path):
119
+ fn = "".join([self.root, path.lstrip("/")])
120
+ try:
121
+ self.fs.rm(fn, False)
122
+ except (OSError, FileNotFoundError) as exc:
123
+ raise FuseOSError(EIO) from exc
124
+
125
+ def release(self, path, fh):
126
+ try:
127
+ if fh in self.cache:
128
+ f = self.cache[fh]
129
+ f.close()
130
+ self.cache.pop(fh)
131
+ except Exception as e:
132
+ print(e)
133
+ return 0
134
+
135
+ def chmod(self, path, mode):
136
+ if hasattr(self.fs, "chmod"):
137
+ path = "".join([self.root, path.lstrip("/")])
138
+ return self.fs.chmod(path, mode)
139
+ raise NotImplementedError
140
+
141
+
142
+ def run(
143
+ fs,
144
+ path,
145
+ mount_point,
146
+ foreground=True,
147
+ threads=False,
148
+ ready_file=False,
149
+ ops_class=FUSEr,
150
+ ):
151
+ """Mount stuff in a local directory
152
+
153
+ This uses fusepy to make it appear as if a given path on an fsspec
154
+ instance is in fact resident within the local file-system.
155
+
156
+ This requires that fusepy by installed, and that FUSE be available on
157
+ the system (typically requiring a package to be installed with
158
+ apt, yum, brew, etc.).
159
+
160
+ Parameters
161
+ ----------
162
+ fs: file-system instance
163
+ From one of the compatible implementations
164
+ path: str
165
+ Location on that file-system to regard as the root directory to
166
+ mount. Note that you typically should include the terminating "/"
167
+ character.
168
+ mount_point: str
169
+ An empty directory on the local file-system where the contents of
170
+ the remote path will appear.
171
+ foreground: bool
172
+ Whether or not calling this function will block. Operation will
173
+ typically be more stable if True.
174
+ threads: bool
175
+ Whether or not to create threads when responding to file operations
176
+ within the mounter directory. Operation will typically be more
177
+ stable if False.
178
+ ready_file: bool
179
+ Whether the FUSE process is ready. The ``.fuse_ready`` file will
180
+ exist in the ``mount_point`` directory if True. Debugging purpose.
181
+ ops_class: FUSEr or Subclass of FUSEr
182
+ To override the default behavior of FUSEr. For Example, logging
183
+ to file.
184
+
185
+ """
186
+ func = lambda: FUSE(
187
+ ops_class(fs, path, ready_file=ready_file),
188
+ mount_point,
189
+ nothreads=not threads,
190
+ foreground=foreground,
191
+ )
192
+ if not foreground:
193
+ th = threading.Thread(target=func)
194
+ th.daemon = True
195
+ th.start()
196
+ return th
197
+ else: # pragma: no cover
198
+ try:
199
+ func()
200
+ except KeyboardInterrupt:
201
+ pass
202
+
203
+
204
+ def main(args):
205
+ """Mount filesystem from chained URL to MOUNT_POINT.
206
+
207
+ Examples:
208
+
209
+ python3 -m fsspec.fuse memory /usr/share /tmp/mem
210
+
211
+ python3 -m fsspec.fuse local /tmp/source /tmp/local \\
212
+ -l /tmp/fsspecfuse.log
213
+
214
+ You can also mount chained-URLs and use special settings:
215
+
216
+ python3 -m fsspec.fuse 'filecache::zip::file://data.zip' \\
217
+ / /tmp/zip \\
218
+ -o 'filecache-cache_storage=/tmp/simplecache'
219
+
220
+ You can specify the type of the setting by using `[int]` or `[bool]`,
221
+ (`true`, `yes`, `1` represents the Boolean value `True`):
222
+
223
+ python3 -m fsspec.fuse 'simplecache::ftp://ftp1.at.proftpd.org' \\
224
+ /historic/packages/RPMS /tmp/ftp \\
225
+ -o 'simplecache-cache_storage=/tmp/simplecache' \\
226
+ -o 'simplecache-check_files=false[bool]' \\
227
+ -o 'ftp-listings_expiry_time=60[int]' \\
228
+ -o 'ftp-username=anonymous' \\
229
+ -o 'ftp-password=xieyanbo'
230
+ """
231
+
232
+ class RawDescriptionArgumentParser(argparse.ArgumentParser):
233
+ def format_help(self):
234
+ usage = super().format_help()
235
+ parts = usage.split("\n\n")
236
+ parts[1] = self.description.rstrip()
237
+ return "\n\n".join(parts)
238
+
239
+ parser = RawDescriptionArgumentParser(prog="fsspec.fuse", description=main.__doc__)
240
+ parser.add_argument("--version", action="version", version=__version__)
241
+ parser.add_argument("url", type=str, help="fs url")
242
+ parser.add_argument("source_path", type=str, help="source directory in fs")
243
+ parser.add_argument("mount_point", type=str, help="local directory")
244
+ parser.add_argument(
245
+ "-o",
246
+ "--option",
247
+ action="append",
248
+ help="Any options of protocol included in the chained URL",
249
+ )
250
+ parser.add_argument(
251
+ "-l", "--log-file", type=str, help="Logging FUSE debug info (Default: '')"
252
+ )
253
+ parser.add_argument(
254
+ "-f",
255
+ "--foreground",
256
+ action="store_false",
257
+ help="Running in foreground or not (Default: False)",
258
+ )
259
+ parser.add_argument(
260
+ "-t",
261
+ "--threads",
262
+ action="store_false",
263
+ help="Running with threads support (Default: False)",
264
+ )
265
+ parser.add_argument(
266
+ "-r",
267
+ "--ready-file",
268
+ action="store_false",
269
+ help="The `.fuse_ready` file will exist after FUSE is ready. "
270
+ "(Debugging purpose, Default: False)",
271
+ )
272
+ args = parser.parse_args(args)
273
+
274
+ kwargs = {}
275
+ for item in args.option or []:
276
+ key, sep, value = item.partition("=")
277
+ if not sep:
278
+ parser.error(message=f"Wrong option: {item!r}")
279
+ val = value.lower()
280
+ if val.endswith("[int]"):
281
+ value = int(value[: -len("[int]")])
282
+ elif val.endswith("[bool]"):
283
+ value = val[: -len("[bool]")] in ["1", "yes", "true"]
284
+
285
+ if "-" in key:
286
+ fs_name, setting_name = key.split("-", 1)
287
+ if fs_name in kwargs:
288
+ kwargs[fs_name][setting_name] = value
289
+ else:
290
+ kwargs[fs_name] = {setting_name: value}
291
+ else:
292
+ kwargs[key] = value
293
+
294
+ if args.log_file:
295
+ logging.basicConfig(
296
+ level=logging.DEBUG,
297
+ filename=args.log_file,
298
+ format="%(asctime)s %(message)s",
299
+ )
300
+
301
+ class LoggingFUSEr(FUSEr, LoggingMixIn):
302
+ pass
303
+
304
+ fuser = LoggingFUSEr
305
+ else:
306
+ fuser = FUSEr
307
+
308
+ fs, url_path = url_to_fs(args.url, **kwargs)
309
+ logger.debug("Mounting %s to %s", url_path, str(args.mount_point))
310
+ run(
311
+ fs,
312
+ args.source_path,
313
+ args.mount_point,
314
+ foreground=args.foreground,
315
+ threads=args.threads,
316
+ ready_file=args.ready_file,
317
+ ops_class=fuser,
318
+ )
319
+
320
+
321
+ if __name__ == "__main__":
322
+ import sys
323
+
324
+ main(sys.argv[1:])
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/fsspec/generic.py ADDED
@@ -0,0 +1,396 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import inspect
4
+ import logging
5
+ import os
6
+ import shutil
7
+ import uuid
8
+
9
+ from .asyn import AsyncFileSystem, _run_coros_in_chunks, sync_wrapper
10
+ from .callbacks import DEFAULT_CALLBACK
11
+ from .core import filesystem, get_filesystem_class, split_protocol, url_to_fs
12
+
13
+ _generic_fs = {}
14
+ logger = logging.getLogger("fsspec.generic")
15
+
16
+
17
+ def set_generic_fs(protocol, **storage_options):
18
+ """Populate the dict used for method=="generic" lookups"""
19
+ _generic_fs[protocol] = filesystem(protocol, **storage_options)
20
+
21
+
22
+ def _resolve_fs(url, method, protocol=None, storage_options=None):
23
+ """Pick instance of backend FS"""
24
+ url = url[0] if isinstance(url, (list, tuple)) else url
25
+ protocol = protocol or split_protocol(url)[0]
26
+ storage_options = storage_options or {}
27
+ if method == "default":
28
+ return filesystem(protocol)
29
+ if method == "generic":
30
+ return _generic_fs[protocol]
31
+ if method == "current":
32
+ cls = get_filesystem_class(protocol)
33
+ return cls.current()
34
+ if method == "options":
35
+ fs, _ = url_to_fs(url, **storage_options.get(protocol, {}))
36
+ return fs
37
+ raise ValueError(f"Unknown FS resolution method: {method}")
38
+
39
+
40
+ def rsync(
41
+ source,
42
+ destination,
43
+ delete_missing=False,
44
+ source_field="size",
45
+ dest_field="size",
46
+ update_cond="different",
47
+ inst_kwargs=None,
48
+ fs=None,
49
+ **kwargs,
50
+ ):
51
+ """Sync files between two directory trees
52
+
53
+ (experimental)
54
+
55
+ Parameters
56
+ ----------
57
+ source: str
58
+ Root of the directory tree to take files from. This must be a directory, but
59
+ do not include any terminating "/" character
60
+ destination: str
61
+ Root path to copy into. The contents of this location should be
62
+ identical to the contents of ``source`` when done. This will be made a
63
+ directory, and the terminal "/" should not be included.
64
+ delete_missing: bool
65
+ If there are paths in the destination that don't exist in the
66
+ source and this is True, delete them. Otherwise, leave them alone.
67
+ source_field: str | callable
68
+ If ``update_field`` is "different", this is the key in the info
69
+ of source files to consider for difference. Maybe a function of the
70
+ info dict.
71
+ dest_field: str | callable
72
+ If ``update_field`` is "different", this is the key in the info
73
+ of destination files to consider for difference. May be a function of
74
+ the info dict.
75
+ update_cond: "different"|"always"|"never"
76
+ If "always", every file is copied, regardless of whether it exists in
77
+ the destination. If "never", files that exist in the destination are
78
+ not copied again. If "different" (default), only copy if the info
79
+ fields given by ``source_field`` and ``dest_field`` (usually "size")
80
+ are different. Other comparisons may be added in the future.
81
+ inst_kwargs: dict|None
82
+ If ``fs`` is None, use this set of keyword arguments to make a
83
+ GenericFileSystem instance
84
+ fs: GenericFileSystem|None
85
+ Instance to use if explicitly given. The instance defines how to
86
+ to make downstream file system instances from paths.
87
+
88
+ Returns
89
+ -------
90
+ dict of the copy operations that were performed, {source: destination}
91
+ """
92
+ fs = fs or GenericFileSystem(**(inst_kwargs or {}))
93
+ source = fs._strip_protocol(source)
94
+ destination = fs._strip_protocol(destination)
95
+ allfiles = fs.find(source, withdirs=True, detail=True)
96
+ if not fs.isdir(source):
97
+ raise ValueError("Can only rsync on a directory")
98
+ otherfiles = fs.find(destination, withdirs=True, detail=True)
99
+ dirs = [
100
+ a
101
+ for a, v in allfiles.items()
102
+ if v["type"] == "directory" and a.replace(source, destination) not in otherfiles
103
+ ]
104
+ logger.debug(f"{len(dirs)} directories to create")
105
+ if dirs:
106
+ fs.make_many_dirs(
107
+ [dirn.replace(source, destination) for dirn in dirs], exist_ok=True
108
+ )
109
+ allfiles = {a: v for a, v in allfiles.items() if v["type"] == "file"}
110
+ logger.debug(f"{len(allfiles)} files to consider for copy")
111
+ to_delete = [
112
+ o
113
+ for o, v in otherfiles.items()
114
+ if o.replace(destination, source) not in allfiles and v["type"] == "file"
115
+ ]
116
+ for k, v in allfiles.copy().items():
117
+ otherfile = k.replace(source, destination)
118
+ if otherfile in otherfiles:
119
+ if update_cond == "always":
120
+ allfiles[k] = otherfile
121
+ elif update_cond == "never":
122
+ allfiles.pop(k)
123
+ elif update_cond == "different":
124
+ inf1 = source_field(v) if callable(source_field) else v[source_field]
125
+ v2 = otherfiles[otherfile]
126
+ inf2 = dest_field(v2) if callable(dest_field) else v2[dest_field]
127
+ if inf1 != inf2:
128
+ # details mismatch, make copy
129
+ allfiles[k] = otherfile
130
+ else:
131
+ # details match, don't copy
132
+ allfiles.pop(k)
133
+ else:
134
+ # file not in target yet
135
+ allfiles[k] = otherfile
136
+ logger.debug(f"{len(allfiles)} files to copy")
137
+ if allfiles:
138
+ source_files, target_files = zip(*allfiles.items())
139
+ fs.cp(source_files, target_files, **kwargs)
140
+ logger.debug(f"{len(to_delete)} files to delete")
141
+ if delete_missing and to_delete:
142
+ fs.rm(to_delete)
143
+ return allfiles
144
+
145
+
146
+ class GenericFileSystem(AsyncFileSystem):
147
+ """Wrapper over all other FS types
148
+
149
+ <experimental!>
150
+
151
+ This implementation is a single unified interface to be able to run FS operations
152
+ over generic URLs, and dispatch to the specific implementations using the URL
153
+ protocol prefix.
154
+
155
+ Note: instances of this FS are always async, even if you never use it with any async
156
+ backend.
157
+ """
158
+
159
+ protocol = "generic" # there is no real reason to ever use a protocol with this FS
160
+
161
+ def __init__(self, default_method="default", storage_options=None, **kwargs):
162
+ """
163
+
164
+ Parameters
165
+ ----------
166
+ default_method: str (optional)
167
+ Defines how to configure backend FS instances. Options are:
168
+ - "default": instantiate like FSClass(), with no
169
+ extra arguments; this is the default instance of that FS, and can be
170
+ configured via the config system
171
+ - "generic": takes instances from the `_generic_fs` dict in this module,
172
+ which you must populate before use. Keys are by protocol
173
+ - "options": expects storage_options, a dict mapping protocol to
174
+ kwargs to use when constructing the filesystem
175
+ - "current": takes the most recently instantiated version of each FS
176
+ """
177
+ self.method = default_method
178
+ self.st_opts = storage_options
179
+ super().__init__(**kwargs)
180
+
181
+ def _parent(self, path):
182
+ fs = _resolve_fs(path, self.method, storage_options=self.st_opts)
183
+ return fs.unstrip_protocol(fs._parent(path))
184
+
185
+ def _strip_protocol(self, path):
186
+ # normalization only
187
+ fs = _resolve_fs(path, self.method, storage_options=self.st_opts)
188
+ return fs.unstrip_protocol(fs._strip_protocol(path))
189
+
190
+ async def _find(self, path, maxdepth=None, withdirs=False, detail=False, **kwargs):
191
+ fs = _resolve_fs(path, self.method, storage_options=self.st_opts)
192
+ if fs.async_impl:
193
+ out = await fs._find(
194
+ path, maxdepth=maxdepth, withdirs=withdirs, detail=True, **kwargs
195
+ )
196
+ else:
197
+ out = fs.find(
198
+ path, maxdepth=maxdepth, withdirs=withdirs, detail=True, **kwargs
199
+ )
200
+ result = {}
201
+ for k, v in out.items():
202
+ v = v.copy() # don't corrupt target FS dircache
203
+ name = fs.unstrip_protocol(k)
204
+ v["name"] = name
205
+ result[name] = v
206
+ if detail:
207
+ return result
208
+ return list(result)
209
+
210
+ async def _info(self, url, **kwargs):
211
+ fs = _resolve_fs(url, self.method)
212
+ if fs.async_impl:
213
+ out = await fs._info(url, **kwargs)
214
+ else:
215
+ out = fs.info(url, **kwargs)
216
+ out = out.copy() # don't edit originals
217
+ out["name"] = fs.unstrip_protocol(out["name"])
218
+ return out
219
+
220
+ async def _ls(
221
+ self,
222
+ url,
223
+ detail=True,
224
+ **kwargs,
225
+ ):
226
+ fs = _resolve_fs(url, self.method)
227
+ if fs.async_impl:
228
+ out = await fs._ls(url, detail=True, **kwargs)
229
+ else:
230
+ out = fs.ls(url, detail=True, **kwargs)
231
+ out = [o.copy() for o in out] # don't edit originals
232
+ for o in out:
233
+ o["name"] = fs.unstrip_protocol(o["name"])
234
+ if detail:
235
+ return out
236
+ else:
237
+ return [o["name"] for o in out]
238
+
239
+ async def _cat_file(
240
+ self,
241
+ url,
242
+ **kwargs,
243
+ ):
244
+ fs = _resolve_fs(url, self.method)
245
+ if fs.async_impl:
246
+ return await fs._cat_file(url, **kwargs)
247
+ else:
248
+ return fs.cat_file(url, **kwargs)
249
+
250
+ async def _pipe_file(
251
+ self,
252
+ path,
253
+ value,
254
+ **kwargs,
255
+ ):
256
+ fs = _resolve_fs(path, self.method, storage_options=self.st_opts)
257
+ if fs.async_impl:
258
+ return await fs._pipe_file(path, value, **kwargs)
259
+ else:
260
+ return fs.pipe_file(path, value, **kwargs)
261
+
262
+ async def _rm(self, url, **kwargs):
263
+ urls = url
264
+ if isinstance(urls, str):
265
+ urls = [urls]
266
+ fs = _resolve_fs(urls[0], self.method)
267
+ if fs.async_impl:
268
+ await fs._rm(urls, **kwargs)
269
+ else:
270
+ fs.rm(url, **kwargs)
271
+
272
+ async def _makedirs(self, path, exist_ok=False):
273
+ logger.debug("Make dir %s", path)
274
+ fs = _resolve_fs(path, self.method, storage_options=self.st_opts)
275
+ if fs.async_impl:
276
+ await fs._makedirs(path, exist_ok=exist_ok)
277
+ else:
278
+ fs.makedirs(path, exist_ok=exist_ok)
279
+
280
+ def rsync(self, source, destination, **kwargs):
281
+ """Sync files between two directory trees
282
+
283
+ See `func:rsync` for more details.
284
+ """
285
+ rsync(source, destination, fs=self, **kwargs)
286
+
287
+ async def _cp_file(
288
+ self,
289
+ url,
290
+ url2,
291
+ blocksize=2**20,
292
+ callback=DEFAULT_CALLBACK,
293
+ tempdir: str | None = None,
294
+ **kwargs,
295
+ ):
296
+ fs = _resolve_fs(url, self.method)
297
+ fs2 = _resolve_fs(url2, self.method)
298
+ if fs is fs2:
299
+ # pure remote
300
+ if fs.async_impl:
301
+ return await fs._copy(url, url2, **kwargs)
302
+ else:
303
+ return fs.copy(url, url2, **kwargs)
304
+ await copy_file_op(fs, [url], fs2, [url2], tempdir, 1, on_error="raise")
305
+
306
+ async def _make_many_dirs(self, urls, exist_ok=True):
307
+ fs = _resolve_fs(urls[0], self.method)
308
+ if fs.async_impl:
309
+ coros = [fs._makedirs(u, exist_ok=exist_ok) for u in urls]
310
+ await _run_coros_in_chunks(coros)
311
+ else:
312
+ for u in urls:
313
+ fs.makedirs(u, exist_ok=exist_ok)
314
+
315
+ make_many_dirs = sync_wrapper(_make_many_dirs)
316
+
317
+ async def _copy(
318
+ self,
319
+ path1: list[str],
320
+ path2: list[str],
321
+ recursive: bool = False,
322
+ on_error: str = "ignore",
323
+ maxdepth: int | None = None,
324
+ batch_size: int | None = None,
325
+ tempdir: str | None = None,
326
+ **kwargs,
327
+ ):
328
+ # TODO: special case for one FS being local, which can use get/put
329
+ # TODO: special case for one being memFS, which can use cat/pipe
330
+ if recursive:
331
+ raise NotImplementedError("Please use fsspec.generic.rsync")
332
+ path1 = [path1] if isinstance(path1, str) else path1
333
+ path2 = [path2] if isinstance(path2, str) else path2
334
+
335
+ fs = _resolve_fs(path1, self.method)
336
+ fs2 = _resolve_fs(path2, self.method)
337
+
338
+ if fs is fs2:
339
+ if fs.async_impl:
340
+ return await fs._copy(path1, path2, **kwargs)
341
+ else:
342
+ return fs.copy(path1, path2, **kwargs)
343
+
344
+ await copy_file_op(
345
+ fs, path1, fs2, path2, tempdir, batch_size, on_error=on_error
346
+ )
347
+
348
+
349
+ async def copy_file_op(
350
+ fs1, url1, fs2, url2, tempdir=None, batch_size=20, on_error="ignore"
351
+ ):
352
+ import tempfile
353
+
354
+ tempdir = tempdir or tempfile.mkdtemp()
355
+ try:
356
+ coros = [
357
+ _copy_file_op(
358
+ fs1,
359
+ u1,
360
+ fs2,
361
+ u2,
362
+ os.path.join(tempdir, uuid.uuid4().hex),
363
+ )
364
+ for u1, u2 in zip(url1, url2)
365
+ ]
366
+ out = await _run_coros_in_chunks(
367
+ coros, batch_size=batch_size, return_exceptions=True
368
+ )
369
+ finally:
370
+ shutil.rmtree(tempdir)
371
+ if on_error == "return":
372
+ return out
373
+ elif on_error == "raise":
374
+ for o in out:
375
+ if isinstance(o, Exception):
376
+ raise o
377
+
378
+
379
+ async def _copy_file_op(fs1, url1, fs2, url2, local, on_error="ignore"):
380
+ if fs1.async_impl:
381
+ await fs1._get_file(url1, local)
382
+ else:
383
+ fs1.get_file(url1, local)
384
+ if fs2.async_impl:
385
+ await fs2._put_file(local, url2)
386
+ else:
387
+ fs2.put_file(local, url2)
388
+ os.unlink(local)
389
+ logger.debug("Copy %s -> %s; done", url1, url2)
390
+
391
+
392
+ async def maybe_await(cor):
393
+ if inspect.iscoroutine(cor):
394
+ return await cor
395
+ else:
396
+ return cor
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/fsspec/mapping.py ADDED
@@ -0,0 +1,251 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import array
2
+ import logging
3
+ import posixpath
4
+ import warnings
5
+ from collections.abc import MutableMapping
6
+ from functools import cached_property
7
+
8
+ from fsspec.core import url_to_fs
9
+
10
+ logger = logging.getLogger("fsspec.mapping")
11
+
12
+
13
+ class FSMap(MutableMapping):
14
+ """Wrap a FileSystem instance as a mutable wrapping.
15
+
16
+ The keys of the mapping become files under the given root, and the
17
+ values (which must be bytes) the contents of those files.
18
+
19
+ Parameters
20
+ ----------
21
+ root: string
22
+ prefix for all the files
23
+ fs: FileSystem instance
24
+ check: bool (=True)
25
+ performs a touch at the location, to check for write access.
26
+
27
+ Examples
28
+ --------
29
+ >>> fs = FileSystem(**parameters) # doctest: +SKIP
30
+ >>> d = FSMap('my-data/path/', fs) # doctest: +SKIP
31
+ or, more likely
32
+ >>> d = fs.get_mapper('my-data/path/')
33
+
34
+ >>> d['loc1'] = b'Hello World' # doctest: +SKIP
35
+ >>> list(d.keys()) # doctest: +SKIP
36
+ ['loc1']
37
+ >>> d['loc1'] # doctest: +SKIP
38
+ b'Hello World'
39
+ """
40
+
41
+ def __init__(self, root, fs, check=False, create=False, missing_exceptions=None):
42
+ self.fs = fs
43
+ self.root = fs._strip_protocol(root)
44
+ self._root_key_to_str = fs._strip_protocol(posixpath.join(root, "x"))[:-1]
45
+ if missing_exceptions is None:
46
+ missing_exceptions = (
47
+ FileNotFoundError,
48
+ IsADirectoryError,
49
+ NotADirectoryError,
50
+ )
51
+ self.missing_exceptions = missing_exceptions
52
+ self.check = check
53
+ self.create = create
54
+ if create:
55
+ if not self.fs.exists(root):
56
+ self.fs.mkdir(root)
57
+ if check:
58
+ if not self.fs.exists(root):
59
+ raise ValueError(
60
+ f"Path {root} does not exist. Create "
61
+ f" with the ``create=True`` keyword"
62
+ )
63
+ self.fs.touch(root + "/a")
64
+ self.fs.rm(root + "/a")
65
+
66
+ @cached_property
67
+ def dirfs(self):
68
+ """dirfs instance that can be used with the same keys as the mapper"""
69
+ from .implementations.dirfs import DirFileSystem
70
+
71
+ return DirFileSystem(path=self._root_key_to_str, fs=self.fs)
72
+
73
+ def clear(self):
74
+ """Remove all keys below root - empties out mapping"""
75
+ logger.info("Clear mapping at %s", self.root)
76
+ try:
77
+ self.fs.rm(self.root, True)
78
+ self.fs.mkdir(self.root)
79
+ except: # noqa: E722
80
+ pass
81
+
82
+ def getitems(self, keys, on_error="raise"):
83
+ """Fetch multiple items from the store
84
+
85
+ If the backend is async-able, this might proceed concurrently
86
+
87
+ Parameters
88
+ ----------
89
+ keys: list(str)
90
+ They keys to be fetched
91
+ on_error : "raise", "omit", "return"
92
+ If raise, an underlying exception will be raised (converted to KeyError
93
+ if the type is in self.missing_exceptions); if omit, keys with exception
94
+ will simply not be included in the output; if "return", all keys are
95
+ included in the output, but the value will be bytes or an exception
96
+ instance.
97
+
98
+ Returns
99
+ -------
100
+ dict(key, bytes|exception)
101
+ """
102
+ keys2 = [self._key_to_str(k) for k in keys]
103
+ oe = on_error if on_error == "raise" else "return"
104
+ try:
105
+ out = self.fs.cat(keys2, on_error=oe)
106
+ if isinstance(out, bytes):
107
+ out = {keys2[0]: out}
108
+ except self.missing_exceptions as e:
109
+ raise KeyError from e
110
+ out = {
111
+ k: (KeyError() if isinstance(v, self.missing_exceptions) else v)
112
+ for k, v in out.items()
113
+ }
114
+ return {
115
+ key: out[k2] if on_error == "raise" else out.get(k2, KeyError(k2))
116
+ for key, k2 in zip(keys, keys2)
117
+ if on_error == "return" or not isinstance(out[k2], BaseException)
118
+ }
119
+
120
+ def setitems(self, values_dict):
121
+ """Set the values of multiple items in the store
122
+
123
+ Parameters
124
+ ----------
125
+ values_dict: dict(str, bytes)
126
+ """
127
+ values = {self._key_to_str(k): maybe_convert(v) for k, v in values_dict.items()}
128
+ self.fs.pipe(values)
129
+
130
+ def delitems(self, keys):
131
+ """Remove multiple keys from the store"""
132
+ self.fs.rm([self._key_to_str(k) for k in keys])
133
+
134
+ def _key_to_str(self, key):
135
+ """Generate full path for the key"""
136
+ if not isinstance(key, str):
137
+ # raise TypeError("key must be of type `str`, got `{type(key).__name__}`"
138
+ warnings.warn(
139
+ "from fsspec 2023.5 onward FSMap non-str keys will raise TypeError",
140
+ DeprecationWarning,
141
+ )
142
+ if isinstance(key, list):
143
+ key = tuple(key)
144
+ key = str(key)
145
+ return f"{self._root_key_to_str}{key}".rstrip("/")
146
+
147
+ def _str_to_key(self, s):
148
+ """Strip path of to leave key name"""
149
+ return s[len(self.root) :].lstrip("/")
150
+
151
+ def __getitem__(self, key, default=None):
152
+ """Retrieve data"""
153
+ k = self._key_to_str(key)
154
+ try:
155
+ result = self.fs.cat(k)
156
+ except self.missing_exceptions as exc:
157
+ if default is not None:
158
+ return default
159
+ raise KeyError(key) from exc
160
+ return result
161
+
162
+ def pop(self, key, default=None):
163
+ """Pop data"""
164
+ result = self.__getitem__(key, default)
165
+ try:
166
+ del self[key]
167
+ except KeyError:
168
+ pass
169
+ return result
170
+
171
+ def __setitem__(self, key, value):
172
+ """Store value in key"""
173
+ key = self._key_to_str(key)
174
+ self.fs.mkdirs(self.fs._parent(key), exist_ok=True)
175
+ self.fs.pipe_file(key, maybe_convert(value))
176
+
177
+ def __iter__(self):
178
+ return (self._str_to_key(x) for x in self.fs.find(self.root))
179
+
180
+ def __len__(self):
181
+ return len(self.fs.find(self.root))
182
+
183
+ def __delitem__(self, key):
184
+ """Remove key"""
185
+ try:
186
+ self.fs.rm(self._key_to_str(key))
187
+ except Exception as exc:
188
+ raise KeyError from exc
189
+
190
+ def __contains__(self, key):
191
+ """Does key exist in mapping?"""
192
+ path = self._key_to_str(key)
193
+ return self.fs.isfile(path)
194
+
195
+ def __reduce__(self):
196
+ return FSMap, (self.root, self.fs, False, False, self.missing_exceptions)
197
+
198
+
199
+ def maybe_convert(value):
200
+ if isinstance(value, array.array) or hasattr(value, "__array__"):
201
+ # bytes-like things
202
+ if hasattr(value, "dtype") and value.dtype.kind in "Mm":
203
+ # The buffer interface doesn't support datetime64/timdelta64 numpy
204
+ # arrays
205
+ value = value.view("int64")
206
+ value = bytes(memoryview(value))
207
+ return value
208
+
209
+
210
+ def get_mapper(
211
+ url="",
212
+ check=False,
213
+ create=False,
214
+ missing_exceptions=None,
215
+ alternate_root=None,
216
+ **kwargs,
217
+ ):
218
+ """Create key-value interface for given URL and options
219
+
220
+ The URL will be of the form "protocol://location" and point to the root
221
+ of the mapper required. All keys will be file-names below this location,
222
+ and their values the contents of each key.
223
+
224
+ Also accepts compound URLs like zip::s3://bucket/file.zip , see ``fsspec.open``.
225
+
226
+ Parameters
227
+ ----------
228
+ url: str
229
+ Root URL of mapping
230
+ check: bool
231
+ Whether to attempt to read from the location before instantiation, to
232
+ check that the mapping does exist
233
+ create: bool
234
+ Whether to make the directory corresponding to the root before
235
+ instantiating
236
+ missing_exceptions: None or tuple
237
+ If given, these exception types will be regarded as missing keys and
238
+ return KeyError when trying to read data. By default, you get
239
+ (FileNotFoundError, IsADirectoryError, NotADirectoryError)
240
+ alternate_root: None or str
241
+ In cases of complex URLs, the parser may fail to pick the correct part
242
+ for the mapper root, so this arg can override
243
+
244
+ Returns
245
+ -------
246
+ ``FSMap`` instance, the dict-like key-value store.
247
+ """
248
+ # Removing protocol here - could defer to each open() on the backend
249
+ fs, urlpath = url_to_fs(url, **kwargs)
250
+ root = alternate_root if alternate_root is not None else urlpath
251
+ return FSMap(root, fs, check, create, missing_exceptions=missing_exceptions)
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/fsspec/utils.py ADDED
@@ -0,0 +1,748 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import contextlib
4
+ import logging
5
+ import math
6
+ import os
7
+ import re
8
+ import sys
9
+ import tempfile
10
+ from collections.abc import Callable, Iterable, Iterator, Sequence
11
+ from functools import partial
12
+ from hashlib import md5
13
+ from importlib.metadata import version
14
+ from typing import IO, TYPE_CHECKING, Any, TypeVar
15
+ from urllib.parse import urlsplit
16
+
17
+ if TYPE_CHECKING:
18
+ import pathlib
19
+ from typing import TypeGuard
20
+
21
+ from fsspec.spec import AbstractFileSystem
22
+
23
+
24
+ DEFAULT_BLOCK_SIZE = 5 * 2**20
25
+
26
+ T = TypeVar("T")
27
+
28
+
29
+ def infer_storage_options(
30
+ urlpath: str, inherit_storage_options: dict[str, Any] | None = None
31
+ ) -> dict[str, Any]:
32
+ """Infer storage options from URL path and merge it with existing storage
33
+ options.
34
+
35
+ Parameters
36
+ ----------
37
+ urlpath: str or unicode
38
+ Either local absolute file path or URL (hdfs://namenode:8020/file.csv)
39
+ inherit_storage_options: dict (optional)
40
+ Its contents will get merged with the inferred information from the
41
+ given path
42
+
43
+ Returns
44
+ -------
45
+ Storage options dict.
46
+
47
+ Examples
48
+ --------
49
+ >>> infer_storage_options('/mnt/datasets/test.csv') # doctest: +SKIP
50
+ {"protocol": "file", "path", "/mnt/datasets/test.csv"}
51
+ >>> infer_storage_options(
52
+ ... 'hdfs://username:pwd@node:123/mnt/datasets/test.csv?q=1',
53
+ ... inherit_storage_options={'extra': 'value'},
54
+ ... ) # doctest: +SKIP
55
+ {"protocol": "hdfs", "username": "username", "password": "pwd",
56
+ "host": "node", "port": 123, "path": "/mnt/datasets/test.csv",
57
+ "url_query": "q=1", "extra": "value"}
58
+ """
59
+ # Handle Windows paths including disk name in this special case
60
+ if (
61
+ re.match(r"^[a-zA-Z]:[\\/]", urlpath)
62
+ or re.match(r"^[a-zA-Z0-9]+://", urlpath) is None
63
+ ):
64
+ return {"protocol": "file", "path": urlpath}
65
+
66
+ parsed_path = urlsplit(urlpath)
67
+ protocol = parsed_path.scheme or "file"
68
+ if parsed_path.fragment:
69
+ path = "#".join([parsed_path.path, parsed_path.fragment])
70
+ else:
71
+ path = parsed_path.path
72
+ if protocol == "file":
73
+ # Special case parsing file protocol URL on Windows according to:
74
+ # https://msdn.microsoft.com/en-us/library/jj710207.aspx
75
+ windows_path = re.match(r"^/([a-zA-Z])[:|]([\\/].*)$", path)
76
+ if windows_path:
77
+ drive, path = windows_path.groups()
78
+ path = f"{drive}:{path}"
79
+
80
+ if protocol in ["http", "https"]:
81
+ # for HTTP, we don't want to parse, as requests will anyway
82
+ return {"protocol": protocol, "path": urlpath}
83
+
84
+ options: dict[str, Any] = {"protocol": protocol, "path": path}
85
+
86
+ if parsed_path.netloc:
87
+ # Parse `hostname` from netloc manually because `parsed_path.hostname`
88
+ # lowercases the hostname which is not always desirable (e.g. in S3):
89
+ # https://github.com/dask/dask/issues/1417
90
+ options["host"] = parsed_path.netloc.rsplit("@", 1)[-1].rsplit(":", 1)[0]
91
+
92
+ if protocol in ("s3", "s3a", "gcs", "gs"):
93
+ options["path"] = options["host"] + options["path"]
94
+ else:
95
+ options["host"] = options["host"]
96
+ if parsed_path.port:
97
+ options["port"] = parsed_path.port
98
+ if parsed_path.username:
99
+ options["username"] = parsed_path.username
100
+ if parsed_path.password:
101
+ options["password"] = parsed_path.password
102
+
103
+ if parsed_path.query:
104
+ options["url_query"] = parsed_path.query
105
+ if parsed_path.fragment:
106
+ options["url_fragment"] = parsed_path.fragment
107
+
108
+ if inherit_storage_options:
109
+ update_storage_options(options, inherit_storage_options)
110
+
111
+ return options
112
+
113
+
114
+ def update_storage_options(
115
+ options: dict[str, Any], inherited: dict[str, Any] | None = None
116
+ ) -> None:
117
+ if not inherited:
118
+ inherited = {}
119
+ collisions = set(options) & set(inherited)
120
+ if collisions:
121
+ for collision in collisions:
122
+ if options.get(collision) != inherited.get(collision):
123
+ raise KeyError(
124
+ f"Collision between inferred and specified storage "
125
+ f"option:\n{collision}"
126
+ )
127
+ options.update(inherited)
128
+
129
+
130
+ # Compression extensions registered via fsspec.compression.register_compression
131
+ compressions: dict[str, str] = {}
132
+
133
+
134
+ def infer_compression(filename: str) -> str | None:
135
+ """Infer compression, if available, from filename.
136
+
137
+ Infer a named compression type, if registered and available, from filename
138
+ extension. This includes builtin (gz, bz2, zip) compressions, as well as
139
+ optional compressions. See fsspec.compression.register_compression.
140
+ """
141
+ extension = os.path.splitext(filename)[-1].strip(".").lower()
142
+ if extension in compressions:
143
+ return compressions[extension]
144
+ return None
145
+
146
+
147
+ def build_name_function(max_int: float) -> Callable[[int], str]:
148
+ """Returns a function that receives a single integer
149
+ and returns it as a string padded by enough zero characters
150
+ to align with maximum possible integer
151
+
152
+ >>> name_f = build_name_function(57)
153
+
154
+ >>> name_f(7)
155
+ '07'
156
+ >>> name_f(31)
157
+ '31'
158
+ >>> build_name_function(1000)(42)
159
+ '0042'
160
+ >>> build_name_function(999)(42)
161
+ '042'
162
+ >>> build_name_function(0)(0)
163
+ '0'
164
+ """
165
+ # handle corner cases max_int is 0 or exact power of 10
166
+ max_int += 1e-8
167
+
168
+ pad_length = int(math.ceil(math.log10(max_int)))
169
+
170
+ def name_function(i: int) -> str:
171
+ return str(i).zfill(pad_length)
172
+
173
+ return name_function
174
+
175
+
176
+ def seek_delimiter(file: IO[bytes], delimiter: bytes, blocksize: int) -> bool:
177
+ r"""Seek current file to file start, file end, or byte after delimiter seq.
178
+
179
+ Seeks file to next chunk delimiter, where chunks are defined on file start,
180
+ a delimiting sequence, and file end. Use file.tell() to see location afterwards.
181
+ Note that file start is a valid split, so must be at offset > 0 to seek for
182
+ delimiter.
183
+
184
+ Parameters
185
+ ----------
186
+ file: a file
187
+ delimiter: bytes
188
+ a delimiter like ``b'\n'`` or message sentinel, matching file .read() type
189
+ blocksize: int
190
+ Number of bytes to read from the file at once.
191
+
192
+
193
+ Returns
194
+ -------
195
+ Returns True if a delimiter was found, False if at file start or end.
196
+
197
+ """
198
+
199
+ if file.tell() == 0:
200
+ # beginning-of-file, return without seek
201
+ return False
202
+
203
+ # Interface is for binary IO, with delimiter as bytes, but initialize last
204
+ # with result of file.read to preserve compatibility with text IO.
205
+ last: bytes | None = None
206
+ while True:
207
+ current = file.read(blocksize)
208
+ if not current:
209
+ # end-of-file without delimiter
210
+ return False
211
+ full = last + current if last else current
212
+ try:
213
+ if delimiter in full:
214
+ i = full.index(delimiter)
215
+ file.seek(file.tell() - (len(full) - i) + len(delimiter))
216
+ return True
217
+ elif len(current) < blocksize:
218
+ # end-of-file without delimiter
219
+ return False
220
+ except (OSError, ValueError):
221
+ pass
222
+ last = full[-len(delimiter) :]
223
+
224
+
225
+ def read_block(
226
+ f: IO[bytes],
227
+ offset: int,
228
+ length: int | None,
229
+ delimiter: bytes | None = None,
230
+ split_before: bool = False,
231
+ ) -> bytes:
232
+ """Read a block of bytes from a file
233
+
234
+ Parameters
235
+ ----------
236
+ f: File
237
+ Open file
238
+ offset: int
239
+ Byte offset to start read
240
+ length: int
241
+ Number of bytes to read, read through end of file if None
242
+ delimiter: bytes (optional)
243
+ Ensure reading starts and stops at delimiter bytestring
244
+ split_before: bool (optional)
245
+ Start/stop read *before* delimiter bytestring.
246
+
247
+
248
+ If using the ``delimiter=`` keyword argument we ensure that the read
249
+ starts and stops at delimiter boundaries that follow the locations
250
+ ``offset`` and ``offset + length``. If ``offset`` is zero then we
251
+ start at zero, regardless of delimiter. The bytestring returned WILL
252
+ include the terminating delimiter string.
253
+
254
+ Examples
255
+ --------
256
+
257
+ >>> from io import BytesIO # doctest: +SKIP
258
+ >>> f = BytesIO(b'Alice, 100\\nBob, 200\\nCharlie, 300') # doctest: +SKIP
259
+ >>> read_block(f, 0, 13) # doctest: +SKIP
260
+ b'Alice, 100\\nBo'
261
+
262
+ >>> read_block(f, 0, 13, delimiter=b'\\n') # doctest: +SKIP
263
+ b'Alice, 100\\nBob, 200\\n'
264
+
265
+ >>> read_block(f, 10, 10, delimiter=b'\\n') # doctest: +SKIP
266
+ b'Bob, 200\\nCharlie, 300'
267
+ """
268
+ if delimiter:
269
+ f.seek(offset)
270
+ found_start_delim = seek_delimiter(f, delimiter, 2**16)
271
+ if length is None:
272
+ return f.read()
273
+ start = f.tell()
274
+ length -= start - offset
275
+
276
+ f.seek(start + length)
277
+ found_end_delim = seek_delimiter(f, delimiter, 2**16)
278
+ end = f.tell()
279
+
280
+ # Adjust split location to before delimiter if seek found the
281
+ # delimiter sequence, not start or end of file.
282
+ if found_start_delim and split_before:
283
+ start -= len(delimiter)
284
+
285
+ if found_end_delim and split_before:
286
+ end -= len(delimiter)
287
+
288
+ offset = start
289
+ length = end - start
290
+
291
+ f.seek(offset)
292
+
293
+ # TODO: allow length to be None and read to the end of the file?
294
+ assert length is not None
295
+ b = f.read(length)
296
+ return b
297
+
298
+
299
+ def tokenize(*args: Any, **kwargs: Any) -> str:
300
+ """Deterministic token
301
+
302
+ (modified from dask.base)
303
+
304
+ >>> tokenize([1, 2, '3'])
305
+ '9d71491b50023b06fc76928e6eddb952'
306
+
307
+ >>> tokenize('Hello') == tokenize('Hello')
308
+ True
309
+ """
310
+ if kwargs:
311
+ args += (kwargs,)
312
+ try:
313
+ h = md5(str(args).encode())
314
+ except ValueError:
315
+ # FIPS systems: https://github.com/fsspec/filesystem_spec/issues/380
316
+ h = md5(str(args).encode(), usedforsecurity=False)
317
+ return h.hexdigest()
318
+
319
+
320
+ def stringify_path(filepath: str | os.PathLike[str] | pathlib.Path) -> str:
321
+ """Attempt to convert a path-like object to a string.
322
+
323
+ Parameters
324
+ ----------
325
+ filepath: object to be converted
326
+
327
+ Returns
328
+ -------
329
+ filepath_str: maybe a string version of the object
330
+
331
+ Notes
332
+ -----
333
+ Objects supporting the fspath protocol are coerced according to its
334
+ __fspath__ method.
335
+
336
+ For backwards compatibility with older Python version, pathlib.Path
337
+ objects are specially coerced.
338
+
339
+ Any other object is passed through unchanged, which includes bytes,
340
+ strings, buffers, or anything else that's not even path-like.
341
+ """
342
+ if isinstance(filepath, str):
343
+ return filepath
344
+ elif hasattr(filepath, "__fspath__"):
345
+ return filepath.__fspath__()
346
+ elif hasattr(filepath, "path"):
347
+ return filepath.path
348
+ else:
349
+ return filepath # type: ignore[return-value]
350
+
351
+
352
+ def make_instance(
353
+ cls: Callable[..., T], args: Sequence[Any], kwargs: dict[str, Any]
354
+ ) -> T:
355
+ inst = cls(*args, **kwargs)
356
+ inst._determine_worker() # type: ignore[attr-defined]
357
+ return inst
358
+
359
+
360
+ def common_prefix(paths: Iterable[str]) -> str:
361
+ """For a list of paths, find the shortest prefix common to all"""
362
+ parts = [p.split("/") for p in paths]
363
+ lmax = min(len(p) for p in parts)
364
+ end = 0
365
+ for i in range(lmax):
366
+ end = all(p[i] == parts[0][i] for p in parts)
367
+ if not end:
368
+ break
369
+ i += end
370
+ return "/".join(parts[0][:i])
371
+
372
+
373
+ def other_paths(
374
+ paths: list[str],
375
+ path2: str | list[str],
376
+ exists: bool = False,
377
+ flatten: bool = False,
378
+ ) -> list[str]:
379
+ """In bulk file operations, construct a new file tree from a list of files
380
+
381
+ Parameters
382
+ ----------
383
+ paths: list of str
384
+ The input file tree
385
+ path2: str or list of str
386
+ Root to construct the new list in. If this is already a list of str, we just
387
+ assert it has the right number of elements.
388
+ exists: bool (optional)
389
+ For a str destination, it is already exists (and is a dir), files should
390
+ end up inside.
391
+ flatten: bool (optional)
392
+ Whether to flatten the input directory tree structure so that the output files
393
+ are in the same directory.
394
+
395
+ Returns
396
+ -------
397
+ list of str
398
+ """
399
+
400
+ if isinstance(path2, str):
401
+ path2 = path2.rstrip("/")
402
+
403
+ if flatten:
404
+ path2 = ["/".join((path2, p.split("/")[-1])) for p in paths]
405
+ else:
406
+ cp = common_prefix(paths)
407
+ if exists:
408
+ cp = cp.rsplit("/", 1)[0]
409
+ if not cp and all(not s.startswith("/") for s in paths):
410
+ path2 = ["/".join([path2, p]) for p in paths]
411
+ else:
412
+ path2 = [p.replace(cp, path2, 1) for p in paths]
413
+ else:
414
+ assert len(paths) == len(path2)
415
+ return path2
416
+
417
+
418
+ def is_exception(obj: Any) -> bool:
419
+ return isinstance(obj, BaseException)
420
+
421
+
422
+ def isfilelike(f: Any) -> TypeGuard[IO[bytes]]:
423
+ return all(hasattr(f, attr) for attr in ["read", "close", "tell"])
424
+
425
+
426
+ def get_protocol(url: str) -> str:
427
+ url = stringify_path(url)
428
+ parts = re.split(r"(\:\:|\://)", url, maxsplit=1)
429
+ if len(parts) > 1:
430
+ return parts[0]
431
+ return "file"
432
+
433
+
434
+ def get_file_extension(url: str) -> str:
435
+ url = stringify_path(url)
436
+ ext_parts = url.rsplit(".", 1)
437
+ if len(ext_parts) > 1:
438
+ return ext_parts[-1]
439
+ return ""
440
+
441
+
442
+ def can_be_local(path: str) -> bool:
443
+ """Can the given URL be used with open_local?"""
444
+ from fsspec import get_filesystem_class
445
+
446
+ try:
447
+ return getattr(get_filesystem_class(get_protocol(path)), "local_file", False)
448
+ except (ValueError, ImportError):
449
+ # not in registry or import failed
450
+ return False
451
+
452
+
453
+ def get_package_version_without_import(name: str) -> str | None:
454
+ """For given package name, try to find the version without importing it
455
+
456
+ Import and package.__version__ is still the backup here, so an import
457
+ *might* happen.
458
+
459
+ Returns either the version string, or None if the package
460
+ or the version was not readily found.
461
+ """
462
+ if name in sys.modules:
463
+ mod = sys.modules[name]
464
+ if hasattr(mod, "__version__"):
465
+ return mod.__version__
466
+ try:
467
+ return version(name)
468
+ except: # noqa: E722
469
+ pass
470
+ try:
471
+ import importlib
472
+
473
+ mod = importlib.import_module(name)
474
+ return mod.__version__
475
+ except (ImportError, AttributeError):
476
+ return None
477
+
478
+
479
+ def setup_logging(
480
+ logger: logging.Logger | None = None,
481
+ logger_name: str | None = None,
482
+ level: str = "DEBUG",
483
+ clear: bool = True,
484
+ ) -> logging.Logger:
485
+ if logger is None and logger_name is None:
486
+ raise ValueError("Provide either logger object or logger name")
487
+ logger = logger or logging.getLogger(logger_name)
488
+ handle = logging.StreamHandler()
489
+ formatter = logging.Formatter(
490
+ "%(asctime)s - %(name)s - %(levelname)s - %(funcName)s -- %(message)s"
491
+ )
492
+ handle.setFormatter(formatter)
493
+ if clear:
494
+ logger.handlers.clear()
495
+ logger.addHandler(handle)
496
+ logger.setLevel(level)
497
+ return logger
498
+
499
+
500
+ def _unstrip_protocol(name: str, fs: AbstractFileSystem) -> str:
501
+ return fs.unstrip_protocol(name)
502
+
503
+
504
+ def mirror_from(
505
+ origin_name: str, methods: Iterable[str]
506
+ ) -> Callable[[type[T]], type[T]]:
507
+ """Mirror attributes and methods from the given
508
+ origin_name attribute of the instance to the
509
+ decorated class"""
510
+
511
+ def origin_getter(method: str, self: Any) -> Any:
512
+ origin = getattr(self, origin_name)
513
+ return getattr(origin, method)
514
+
515
+ def wrapper(cls: type[T]) -> type[T]:
516
+ for method in methods:
517
+ wrapped_method = partial(origin_getter, method)
518
+ setattr(cls, method, property(wrapped_method))
519
+ return cls
520
+
521
+ return wrapper
522
+
523
+
524
+ @contextlib.contextmanager
525
+ def nullcontext(obj: T) -> Iterator[T]:
526
+ yield obj
527
+
528
+
529
+ def merge_offset_ranges(
530
+ paths: list[str],
531
+ starts: list[int] | int,
532
+ ends: list[int] | int,
533
+ max_gap: int = 0,
534
+ max_block: int | None = None,
535
+ sort: bool = True,
536
+ ) -> tuple[list[str], list[int], list[int]]:
537
+ """Merge adjacent byte-offset ranges when the inter-range
538
+ gap is <= `max_gap`, and when the merged byte range does not
539
+ exceed `max_block` (if specified). By default, this function
540
+ will re-order the input paths and byte ranges to ensure sorted
541
+ order. If the user can guarantee that the inputs are already
542
+ sorted, passing `sort=False` will skip the re-ordering.
543
+ """
544
+ # Check input
545
+ if not isinstance(paths, list):
546
+ raise TypeError
547
+ if not isinstance(starts, list):
548
+ starts = [starts] * len(paths)
549
+ if not isinstance(ends, list):
550
+ ends = [ends] * len(paths)
551
+ if len(starts) != len(paths) or len(ends) != len(paths):
552
+ raise ValueError
553
+
554
+ # Early Return
555
+ if len(starts) <= 1:
556
+ return paths, starts, ends
557
+
558
+ starts = [s or 0 for s in starts]
559
+ # Sort by paths and then ranges if `sort=True`
560
+ if sort:
561
+ paths, starts, ends = (
562
+ list(v)
563
+ for v in zip(
564
+ *sorted(
565
+ zip(paths, starts, ends),
566
+ )
567
+ )
568
+ )
569
+ remove = []
570
+ for i, (path, start, end) in enumerate(zip(paths, starts, ends)):
571
+ if any(
572
+ e is not None and p == path and start >= s and end <= e and i != i2
573
+ for i2, (p, s, e) in enumerate(zip(paths, starts, ends))
574
+ ):
575
+ remove.append(i)
576
+ paths = [p for i, p in enumerate(paths) if i not in remove]
577
+ starts = [s for i, s in enumerate(starts) if i not in remove]
578
+ ends = [e for i, e in enumerate(ends) if i not in remove]
579
+
580
+ if paths:
581
+ # Loop through the coupled `paths`, `starts`, and
582
+ # `ends`, and merge adjacent blocks when appropriate
583
+ new_paths = paths[:1]
584
+ new_starts = starts[:1]
585
+ new_ends = ends[:1]
586
+ for i in range(1, len(paths)):
587
+ if paths[i] == paths[i - 1] and new_ends[-1] is None:
588
+ continue
589
+ elif (
590
+ paths[i] != paths[i - 1]
591
+ or ((starts[i] - new_ends[-1]) > max_gap)
592
+ or (max_block is not None and (ends[i] - new_starts[-1]) > max_block)
593
+ ):
594
+ # Cannot merge with previous block.
595
+ # Add new `paths`, `starts`, and `ends` elements
596
+ new_paths.append(paths[i])
597
+ new_starts.append(starts[i])
598
+ new_ends.append(ends[i])
599
+ else:
600
+ # Merge with the previous block by updating the
601
+ # last element of `ends`
602
+ new_ends[-1] = ends[i]
603
+ return new_paths, new_starts, new_ends
604
+
605
+ # `paths` is empty. Just return input lists
606
+ return paths, starts, ends
607
+
608
+
609
+ def file_size(filelike: IO[bytes]) -> int:
610
+ """Find length of any open read-mode file-like"""
611
+ pos = filelike.tell()
612
+ try:
613
+ return filelike.seek(0, 2)
614
+ finally:
615
+ filelike.seek(pos)
616
+
617
+
618
+ @contextlib.contextmanager
619
+ def atomic_write(path: str, mode: str = "wb"):
620
+ """
621
+ A context manager that opens a temporary file next to `path` and, on exit,
622
+ replaces `path` with the temporary file, thereby updating `path`
623
+ atomically.
624
+ """
625
+ fd, fn = tempfile.mkstemp(
626
+ dir=os.path.dirname(path), prefix=os.path.basename(path) + "-"
627
+ )
628
+ try:
629
+ with open(fd, mode) as fp:
630
+ yield fp
631
+ except BaseException:
632
+ with contextlib.suppress(FileNotFoundError):
633
+ os.unlink(fn)
634
+ raise
635
+ else:
636
+ os.replace(fn, path)
637
+
638
+
639
+ def _translate(pat, STAR, QUESTION_MARK):
640
+ # Copied from: https://github.com/python/cpython/pull/106703.
641
+ res: list[str] = []
642
+ add = res.append
643
+ i, n = 0, len(pat)
644
+ while i < n:
645
+ c = pat[i]
646
+ i = i + 1
647
+ if c == "*":
648
+ # compress consecutive `*` into one
649
+ if (not res) or res[-1] is not STAR:
650
+ add(STAR)
651
+ elif c == "?":
652
+ add(QUESTION_MARK)
653
+ elif c == "[":
654
+ j = i
655
+ if j < n and pat[j] == "!":
656
+ j = j + 1
657
+ if j < n and pat[j] == "]":
658
+ j = j + 1
659
+ while j < n and pat[j] != "]":
660
+ j = j + 1
661
+ if j >= n:
662
+ add("\\[")
663
+ else:
664
+ stuff = pat[i:j]
665
+ if "-" not in stuff:
666
+ stuff = stuff.replace("\\", r"\\")
667
+ else:
668
+ chunks = []
669
+ k = i + 2 if pat[i] == "!" else i + 1
670
+ while True:
671
+ k = pat.find("-", k, j)
672
+ if k < 0:
673
+ break
674
+ chunks.append(pat[i:k])
675
+ i = k + 1
676
+ k = k + 3
677
+ chunk = pat[i:j]
678
+ if chunk:
679
+ chunks.append(chunk)
680
+ else:
681
+ chunks[-1] += "-"
682
+ # Remove empty ranges -- invalid in RE.
683
+ for k in range(len(chunks) - 1, 0, -1):
684
+ if chunks[k - 1][-1] > chunks[k][0]:
685
+ chunks[k - 1] = chunks[k - 1][:-1] + chunks[k][1:]
686
+ del chunks[k]
687
+ # Escape backslashes and hyphens for set difference (--).
688
+ # Hyphens that create ranges shouldn't be escaped.
689
+ stuff = "-".join(
690
+ s.replace("\\", r"\\").replace("-", r"\-") for s in chunks
691
+ )
692
+ # Escape set operations (&&, ~~ and ||).
693
+ stuff = re.sub(r"([&~|])", r"\\\1", stuff)
694
+ i = j + 1
695
+ if not stuff:
696
+ # Empty range: never match.
697
+ add("(?!)")
698
+ elif stuff == "!":
699
+ # Negated empty range: match any character.
700
+ add(".")
701
+ else:
702
+ if stuff[0] == "!":
703
+ stuff = "^" + stuff[1:]
704
+ elif stuff[0] in ("^", "["):
705
+ stuff = "\\" + stuff
706
+ add(f"[{stuff}]")
707
+ else:
708
+ add(re.escape(c))
709
+ assert i == n
710
+ return res
711
+
712
+
713
+ def glob_translate(pat):
714
+ # Copied from: https://github.com/python/cpython/pull/106703.
715
+ # The keyword parameters' values are fixed to:
716
+ # recursive=True, include_hidden=True, seps=None
717
+ """Translate a pathname with shell wildcards to a regular expression."""
718
+ if os.path.altsep:
719
+ seps = os.path.sep + os.path.altsep
720
+ else:
721
+ seps = os.path.sep
722
+ escaped_seps = "".join(map(re.escape, seps))
723
+ any_sep = f"[{escaped_seps}]" if len(seps) > 1 else escaped_seps
724
+ not_sep = f"[^{escaped_seps}]"
725
+ one_last_segment = f"{not_sep}+"
726
+ one_segment = f"{one_last_segment}{any_sep}"
727
+ any_segments = f"(?:.+{any_sep})?"
728
+ any_last_segments = ".*"
729
+ results = []
730
+ parts = re.split(any_sep, pat)
731
+ last_part_idx = len(parts) - 1
732
+ for idx, part in enumerate(parts):
733
+ if part == "*":
734
+ results.append(one_segment if idx < last_part_idx else one_last_segment)
735
+ continue
736
+ if part == "**":
737
+ results.append(any_segments if idx < last_part_idx else any_last_segments)
738
+ continue
739
+ elif "**" in part:
740
+ raise ValueError(
741
+ "Invalid pattern: '**' can only be an entire path component"
742
+ )
743
+ if part:
744
+ results.extend(_translate(part, f"{not_sep}*", not_sep))
745
+ if idx < last_part_idx:
746
+ results.append(any_sep)
747
+ res = "".join(results)
748
+ return rf"(?s:{res})\Z"
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/API_CHANGES.txt ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .. -*- rest -*-
2
+
3
+ ==================================================
4
+ API changes in the new masked array implementation
5
+ ==================================================
6
+
7
+ Masked arrays are subclasses of ndarray
8
+ ---------------------------------------
9
+
10
+ Contrary to the original implementation, masked arrays are now regular
11
+ ndarrays::
12
+
13
+ >>> x = masked_array([1,2,3],mask=[0,0,1])
14
+ >>> print isinstance(x, numpy.ndarray)
15
+ True
16
+
17
+
18
+ ``_data`` returns a view of the masked array
19
+ --------------------------------------------
20
+
21
+ Masked arrays are composed of a ``_data`` part and a ``_mask``. Accessing the
22
+ ``_data`` part will return a regular ndarray or any of its subclass, depending
23
+ on the initial data::
24
+
25
+ >>> x = masked_array(numpy.matrix([[1,2],[3,4]]),mask=[[0,0],[0,1]])
26
+ >>> print x._data
27
+ [[1 2]
28
+ [3 4]]
29
+ >>> print type(x._data)
30
+ <class 'numpy.matrixlib.defmatrix.matrix'>
31
+
32
+
33
+ In practice, ``_data`` is implemented as a property, not as an attribute.
34
+ Therefore, you cannot access it directly, and some simple tests such as the
35
+ following one will fail::
36
+
37
+ >>>x._data is x._data
38
+ False
39
+
40
+
41
+ ``filled(x)`` can return a subclass of ndarray
42
+ ----------------------------------------------
43
+ The function ``filled(a)`` returns an array of the same type as ``a._data``::
44
+
45
+ >>> x = masked_array(numpy.matrix([[1,2],[3,4]]),mask=[[0,0],[0,1]])
46
+ >>> y = filled(x)
47
+ >>> print type(y)
48
+ <class 'numpy.matrixlib.defmatrix.matrix'>
49
+ >>> print y
50
+ matrix([[ 1, 2],
51
+ [ 3, 999999]])
52
+
53
+
54
+ ``put``, ``putmask`` behave like their ndarray counterparts
55
+ -----------------------------------------------------------
56
+
57
+ Previously, ``putmask`` was used like this::
58
+
59
+ mask = [False,True,True]
60
+ x = array([1,4,7],mask=mask)
61
+ putmask(x,mask,[3])
62
+
63
+ which translated to::
64
+
65
+ x[~mask] = [3]
66
+
67
+ (Note that a ``True``-value in a mask suppresses a value.)
68
+
69
+ In other words, the mask had the same length as ``x``, whereas
70
+ ``values`` had ``sum(~mask)`` elements.
71
+
72
+ Now, the behaviour is similar to that of ``ndarray.putmask``, where
73
+ the mask and the values are both the same length as ``x``, i.e.
74
+
75
+ ::
76
+
77
+ putmask(x,mask,[3,0,0])
78
+
79
+
80
+ ``fill_value`` is a property
81
+ ----------------------------
82
+
83
+ ``fill_value`` is no longer a method, but a property::
84
+
85
+ >>> print x.fill_value
86
+ 999999
87
+
88
+ ``cumsum`` and ``cumprod`` ignore missing values
89
+ ------------------------------------------------
90
+
91
+ Missing values are assumed to be the identity element, i.e. 0 for
92
+ ``cumsum`` and 1 for ``cumprod``::
93
+
94
+ >>> x = N.ma.array([1,2,3,4],mask=[False,True,False,False])
95
+ >>> print x
96
+ [1 -- 3 4]
97
+ >>> print x.cumsum()
98
+ [1 -- 4 8]
99
+ >> print x.cumprod()
100
+ [1 -- 3 12]
101
+
102
+ ``bool(x)`` raises a ValueError
103
+ -------------------------------
104
+
105
+ Masked arrays now behave like regular ``ndarrays``, in that they cannot be
106
+ converted to booleans:
107
+
108
+ ::
109
+
110
+ >>> x = N.ma.array([1,2,3])
111
+ >>> bool(x)
112
+ Traceback (most recent call last):
113
+ File "<stdin>", line 1, in <module>
114
+ ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
115
+
116
+
117
+ ==================================
118
+ New features (non exhaustive list)
119
+ ==================================
120
+
121
+ ``mr_``
122
+ -------
123
+
124
+ ``mr_`` mimics the behavior of ``r_`` for masked arrays::
125
+
126
+ >>> np.ma.mr_[3,4,5]
127
+ masked_array(data = [3 4 5],
128
+ mask = False,
129
+ fill_value=999999)
130
+
131
+
132
+ ``anom``
133
+ --------
134
+
135
+ The ``anom`` method returns the deviations from the average (anomalies).
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/LICENSE ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ * Copyright (c) 2006, University of Georgia and Pierre G.F. Gerard-Marchant
2
+ * All rights reserved.
3
+ * Redistribution and use in source and binary forms, with or without
4
+ * modification, are permitted provided that the following conditions are met:
5
+ *
6
+ * * Redistributions of source code must retain the above copyright
7
+ * notice, this list of conditions and the following disclaimer.
8
+ * * Redistributions in binary form must reproduce the above copyright
9
+ * notice, this list of conditions and the following disclaimer in the
10
+ * documentation and/or other materials provided with the distribution.
11
+ * * Neither the name of the University of Georgia nor the
12
+ * names of its contributors may be used to endorse or promote products
13
+ * derived from this software without specific prior written permission.
14
+ *
15
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
16
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
19
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/README.rst ADDED
@@ -0,0 +1,236 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ==================================
2
+ A Guide to Masked Arrays in NumPy
3
+ ==================================
4
+
5
+ .. Contents::
6
+
7
+ See http://www.scipy.org/scipy/numpy/wiki/MaskedArray (dead link)
8
+ for updates of this document.
9
+
10
+
11
+ History
12
+ -------
13
+
14
+ As a regular user of MaskedArray, I (Pierre G.F. Gerard-Marchant) became
15
+ increasingly frustrated with the subclassing of masked arrays (even if
16
+ I can only blame my inexperience). I needed to develop a class of arrays
17
+ that could store some additional information along with numerical values,
18
+ while keeping the possibility for missing data (picture storing a series
19
+ of dates along with measurements, what would later become the `TimeSeries
20
+ Scikit <http://projects.scipy.org/scipy/scikits/wiki/TimeSeries>`__
21
+ (dead link).
22
+
23
+ I started to implement such a class, but then quickly realized that
24
+ any additional information disappeared when processing these subarrays
25
+ (for example, adding a constant value to a subarray would erase its
26
+ dates). I ended up writing the equivalent of *numpy.core.ma* for my
27
+ particular class, ufuncs included. Everything went fine until I needed to
28
+ subclass my new class, when more problems showed up: some attributes of
29
+ the new subclass were lost during processing. I identified the culprit as
30
+ MaskedArray, which returns masked ndarrays when I expected masked
31
+ arrays of my class. I was preparing myself to rewrite *numpy.core.ma*
32
+ when I forced myself to learn how to subclass ndarrays. As I became more
33
+ familiar with the *__new__* and *__array_finalize__* methods,
34
+ I started to wonder why masked arrays were objects, and not ndarrays,
35
+ and whether it wouldn't be more convenient for subclassing if they did
36
+ behave like regular ndarrays.
37
+
38
+ The new *maskedarray* is what I eventually come up with. The
39
+ main differences with the initial *numpy.core.ma* package are
40
+ that MaskedArray is now a subclass of *ndarray* and that the
41
+ *_data* section can now be any subclass of *ndarray*. Apart from a
42
+ couple of issues listed below, the behavior of the new MaskedArray
43
+ class reproduces the old one. Initially the *maskedarray*
44
+ implementation was marginally slower than *numpy.ma* in some areas,
45
+ but work is underway to speed it up; the expectation is that it can be
46
+ made substantially faster than the present *numpy.ma*.
47
+
48
+
49
+ Note that if the subclass has some special methods and
50
+ attributes, they are not propagated to the masked version:
51
+ this would require a modification of the *__getattribute__*
52
+ method (first trying *ndarray.__getattribute__*, then trying
53
+ *self._data.__getattribute__* if an exception is raised in the first
54
+ place), which really slows things down.
55
+
56
+ Main differences
57
+ ----------------
58
+
59
+ * The *_data* part of the masked array can be any subclass of ndarray (but not recarray, cf below).
60
+ * *fill_value* is now a property, not a function.
61
+ * in the majority of cases, the mask is forced to *nomask* when no value is actually masked. A notable exception is when a masked array (with no masked values) has just been unpickled.
62
+ * I got rid of the *share_mask* flag, I never understood its purpose.
63
+ * *put*, *putmask* and *take* now mimic the ndarray methods, to avoid unpleasant surprises. Moreover, *put* and *putmask* both update the mask when needed. * if *a* is a masked array, *bool(a)* raises a *ValueError*, as it does with ndarrays.
64
+ * in the same way, the comparison of two masked arrays is a masked array, not a boolean
65
+ * *filled(a)* returns an array of the same subclass as *a._data*, and no test is performed on whether it is contiguous or not.
66
+ * the mask is always printed, even if it's *nomask*, which makes things easy (for me at least) to remember that a masked array is used.
67
+ * *cumsum* works as if the *_data* array was filled with 0. The mask is preserved, but not updated.
68
+ * *cumprod* works as if the *_data* array was filled with 1. The mask is preserved, but not updated.
69
+
70
+ New features
71
+ ------------
72
+
73
+ This list is non-exhaustive...
74
+
75
+ * the *mr_* function mimics *r_* for masked arrays.
76
+ * the *anom* method returns the anomalies (deviations from the average)
77
+
78
+ Using the new package with numpy.core.ma
79
+ ----------------------------------------
80
+
81
+ I tried to make sure that the new package can understand old masked
82
+ arrays. Unfortunately, there's no upward compatibility.
83
+
84
+ For example:
85
+
86
+ >>> import numpy.core.ma as old_ma
87
+ >>> import maskedarray as new_ma
88
+ >>> x = old_ma.array([1,2,3,4,5], mask=[0,0,1,0,0])
89
+ >>> x
90
+ array(data =
91
+ [ 1 2 999999 4 5],
92
+ mask =
93
+ [False False True False False],
94
+ fill_value=999999)
95
+ >>> y = new_ma.array([1,2,3,4,5], mask=[0,0,1,0,0])
96
+ >>> y
97
+ array(data = [1 2 -- 4 5],
98
+ mask = [False False True False False],
99
+ fill_value=999999)
100
+ >>> x==y
101
+ array(data =
102
+ [True True True True True],
103
+ mask =
104
+ [False False True False False],
105
+ fill_value=?)
106
+ >>> old_ma.getmask(x) == new_ma.getmask(x)
107
+ array([True, True, True, True, True])
108
+ >>> old_ma.getmask(y) == new_ma.getmask(y)
109
+ array([True, True, False, True, True])
110
+ >>> old_ma.getmask(y)
111
+ False
112
+
113
+
114
+ Using maskedarray with matplotlib
115
+ ---------------------------------
116
+
117
+ Starting with matplotlib 0.91.2, the masked array importing will work with
118
+ the maskedarray branch) as well as with earlier versions.
119
+
120
+ By default matplotlib still uses numpy.ma, but there is an rcParams setting
121
+ that you can use to select maskedarray instead. In the matplotlibrc file
122
+ you will find::
123
+
124
+ #maskedarray : False # True to use external maskedarray module
125
+ # instead of numpy.ma; this is a temporary #
126
+ setting for testing maskedarray.
127
+
128
+
129
+ Uncomment and set to True to select maskedarray everywhere.
130
+ Alternatively, you can test a script with maskedarray by using a
131
+ command-line option, e.g.::
132
+
133
+ python simple_plot.py --maskedarray
134
+
135
+
136
+ Masked records
137
+ --------------
138
+
139
+ Like *numpy.core.ma*, the *ndarray*-based implementation
140
+ of MaskedArray is limited when working with records: you can
141
+ mask any record of the array, but not a field in a record. If you
142
+ need this feature, you may want to give the *mrecords* package
143
+ a try (available in the *maskedarray* directory in the scipy
144
+ sandbox). This module defines a new class, *MaskedRecord*. An
145
+ instance of this class accepts a *recarray* as data, and uses two
146
+ masks: the *fieldmask* has as many entries as records in the array,
147
+ each entry with the same fields as a record, but of boolean types:
148
+ they indicate whether the field is masked or not; a record entry
149
+ is flagged as masked in the *mask* array if all the fields are
150
+ masked. A few examples in the file should give you an idea of what
151
+ can be done. Note that *mrecords* is still experimental...
152
+
153
+ Optimizing maskedarray
154
+ ----------------------
155
+
156
+ Should masked arrays be filled before processing or not?
157
+ --------------------------------------------------------
158
+
159
+ In the current implementation, most operations on masked arrays involve
160
+ the following steps:
161
+
162
+ * the input arrays are filled
163
+ * the operation is performed on the filled arrays
164
+ * the mask is set for the results, from the combination of the input masks and the mask corresponding to the domain of the operation.
165
+
166
+ For example, consider the division of two masked arrays::
167
+
168
+ import numpy
169
+ import maskedarray as ma
170
+ x = ma.array([1,2,3,4],mask=[1,0,0,0], dtype=numpy.float_)
171
+ y = ma.array([-1,0,1,2], mask=[0,0,0,1], dtype=numpy.float_)
172
+
173
+ The division of x by y is then computed as::
174
+
175
+ d1 = x.filled(0) # d1 = array([0., 2., 3., 4.])
176
+ d2 = y.filled(1) # array([-1., 0., 1., 1.])
177
+ m = ma.mask_or(ma.getmask(x), ma.getmask(y)) # m =
178
+ array([True,False,False,True])
179
+ dm = ma.divide.domain(d1,d2) # array([False, True, False, False])
180
+ result = (d1/d2).view(MaskedArray) # masked_array([-0. inf, 3., 4.])
181
+ result._mask = logical_or(m, dm)
182
+
183
+ Note that a division by zero takes place. To avoid it, we can consider
184
+ to fill the input arrays, taking the domain mask into account, so that::
185
+
186
+ d1 = x._data.copy() # d1 = array([1., 2., 3., 4.])
187
+ d2 = y._data.copy() # array([-1., 0., 1., 2.])
188
+ dm = ma.divide.domain(d1,d2) # array([False, True, False, False])
189
+ numpy.putmask(d2, dm, 1) # d2 = array([-1., 1., 1., 2.])
190
+ m = ma.mask_or(ma.getmask(x), ma.getmask(y)) # m =
191
+ array([True,False,False,True])
192
+ result = (d1/d2).view(MaskedArray) # masked_array([-1. 0., 3., 2.])
193
+ result._mask = logical_or(m, dm)
194
+
195
+ Note that the *.copy()* is required to avoid updating the inputs with
196
+ *putmask*. The *.filled()* method also involves a *.copy()*.
197
+
198
+ A third possibility consists in avoid filling the arrays::
199
+
200
+ d1 = x._data # d1 = array([1., 2., 3., 4.])
201
+ d2 = y._data # array([-1., 0., 1., 2.])
202
+ dm = ma.divide.domain(d1,d2) # array([False, True, False, False])
203
+ m = ma.mask_or(ma.getmask(x), ma.getmask(y)) # m =
204
+ array([True,False,False,True])
205
+ result = (d1/d2).view(MaskedArray) # masked_array([-1. inf, 3., 2.])
206
+ result._mask = logical_or(m, dm)
207
+
208
+ Note that here again the division by zero takes place.
209
+
210
+ A quick benchmark gives the following results:
211
+
212
+ * *numpy.ma.divide* : 2.69 ms per loop
213
+ * classical division : 2.21 ms per loop
214
+ * division w/ prefilling : 2.34 ms per loop
215
+ * division w/o filling : 1.55 ms per loop
216
+
217
+ So, is it worth filling the arrays beforehand ? Yes, if we are interested
218
+ in avoiding floating-point exceptions that may fill the result with infs
219
+ and nans. No, if we are only interested into speed...
220
+
221
+
222
+ Thanks
223
+ ------
224
+
225
+ I'd like to thank Paul Dubois, Travis Oliphant and Sasha for the
226
+ original masked array package: without you, I would never have started
227
+ that (it might be argued that I shouldn't have anyway, but that's
228
+ another story...). I also wish to extend these thanks to Reggie Dugard
229
+ and Eric Firing for their suggestions and numerous improvements.
230
+
231
+
232
+ Revision notes
233
+ --------------
234
+
235
+ * 08/25/2007 : Creation of this page
236
+ * 01/23/2007 : The package has been moved to the SciPy sandbox, and is regularly updated: please check out your SVN version!
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/__init__.py ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ =============
3
+ Masked Arrays
4
+ =============
5
+
6
+ Arrays sometimes contain invalid or missing data. When doing operations
7
+ on such arrays, we wish to suppress invalid values, which is the purpose masked
8
+ arrays fulfill (an example of typical use is given below).
9
+
10
+ For example, examine the following array:
11
+
12
+ >>> x = np.array([2, 1, 3, np.nan, 5, 2, 3, np.nan])
13
+
14
+ When we try to calculate the mean of the data, the result is undetermined:
15
+
16
+ >>> np.mean(x)
17
+ nan
18
+
19
+ The mean is calculated using roughly ``np.sum(x)/len(x)``, but since
20
+ any number added to ``NaN`` [1]_ produces ``NaN``, this doesn't work. Enter
21
+ masked arrays:
22
+
23
+ >>> m = np.ma.masked_array(x, np.isnan(x))
24
+ >>> m
25
+ masked_array(data = [2.0 1.0 3.0 -- 5.0 2.0 3.0 --],
26
+ mask = [False False False True False False False True],
27
+ fill_value=1e+20)
28
+
29
+ Here, we construct a masked array that suppress all ``NaN`` values. We
30
+ may now proceed to calculate the mean of the other values:
31
+
32
+ >>> np.mean(m)
33
+ 2.6666666666666665
34
+
35
+ .. [1] Not-a-Number, a floating point value that is the result of an
36
+ invalid operation.
37
+
38
+ .. moduleauthor:: Pierre Gerard-Marchant
39
+ .. moduleauthor:: Jarrod Millman
40
+
41
+ """
42
+ from . import core
43
+ from .core import *
44
+
45
+ from . import extras
46
+ from .extras import *
47
+
48
+ __all__ = ['core', 'extras']
49
+ __all__ += core.__all__
50
+ __all__ += extras.__all__
51
+
52
+ from numpy._pytesttester import PytestTester
53
+ test = PytestTester(__name__)
54
+ del PytestTester
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/__init__.pyi ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from numpy._pytesttester import PytestTester
2
+
3
+ from numpy.ma import extras as extras
4
+
5
+ from numpy.ma.core import (
6
+ MAError as MAError,
7
+ MaskError as MaskError,
8
+ MaskType as MaskType,
9
+ MaskedArray as MaskedArray,
10
+ abs as abs,
11
+ absolute as absolute,
12
+ add as add,
13
+ all as all,
14
+ allclose as allclose,
15
+ allequal as allequal,
16
+ alltrue as alltrue,
17
+ amax as amax,
18
+ amin as amin,
19
+ angle as angle,
20
+ anom as anom,
21
+ anomalies as anomalies,
22
+ any as any,
23
+ append as append,
24
+ arange as arange,
25
+ arccos as arccos,
26
+ arccosh as arccosh,
27
+ arcsin as arcsin,
28
+ arcsinh as arcsinh,
29
+ arctan as arctan,
30
+ arctan2 as arctan2,
31
+ arctanh as arctanh,
32
+ argmax as argmax,
33
+ argmin as argmin,
34
+ argsort as argsort,
35
+ around as around,
36
+ array as array,
37
+ asanyarray as asanyarray,
38
+ asarray as asarray,
39
+ bitwise_and as bitwise_and,
40
+ bitwise_or as bitwise_or,
41
+ bitwise_xor as bitwise_xor,
42
+ bool_ as bool_,
43
+ ceil as ceil,
44
+ choose as choose,
45
+ clip as clip,
46
+ common_fill_value as common_fill_value,
47
+ compress as compress,
48
+ compressed as compressed,
49
+ concatenate as concatenate,
50
+ conjugate as conjugate,
51
+ convolve as convolve,
52
+ copy as copy,
53
+ correlate as correlate,
54
+ cos as cos,
55
+ cosh as cosh,
56
+ count as count,
57
+ cumprod as cumprod,
58
+ cumsum as cumsum,
59
+ default_fill_value as default_fill_value,
60
+ diag as diag,
61
+ diagonal as diagonal,
62
+ diff as diff,
63
+ divide as divide,
64
+ empty as empty,
65
+ empty_like as empty_like,
66
+ equal as equal,
67
+ exp as exp,
68
+ expand_dims as expand_dims,
69
+ fabs as fabs,
70
+ filled as filled,
71
+ fix_invalid as fix_invalid,
72
+ flatten_mask as flatten_mask,
73
+ flatten_structured_array as flatten_structured_array,
74
+ floor as floor,
75
+ floor_divide as floor_divide,
76
+ fmod as fmod,
77
+ frombuffer as frombuffer,
78
+ fromflex as fromflex,
79
+ fromfunction as fromfunction,
80
+ getdata as getdata,
81
+ getmask as getmask,
82
+ getmaskarray as getmaskarray,
83
+ greater as greater,
84
+ greater_equal as greater_equal,
85
+ harden_mask as harden_mask,
86
+ hypot as hypot,
87
+ identity as identity,
88
+ ids as ids,
89
+ indices as indices,
90
+ inner as inner,
91
+ innerproduct as innerproduct,
92
+ isMA as isMA,
93
+ isMaskedArray as isMaskedArray,
94
+ is_mask as is_mask,
95
+ is_masked as is_masked,
96
+ isarray as isarray,
97
+ left_shift as left_shift,
98
+ less as less,
99
+ less_equal as less_equal,
100
+ log as log,
101
+ log10 as log10,
102
+ log2 as log2,
103
+ logical_and as logical_and,
104
+ logical_not as logical_not,
105
+ logical_or as logical_or,
106
+ logical_xor as logical_xor,
107
+ make_mask as make_mask,
108
+ make_mask_descr as make_mask_descr,
109
+ make_mask_none as make_mask_none,
110
+ mask_or as mask_or,
111
+ masked as masked,
112
+ masked_array as masked_array,
113
+ masked_equal as masked_equal,
114
+ masked_greater as masked_greater,
115
+ masked_greater_equal as masked_greater_equal,
116
+ masked_inside as masked_inside,
117
+ masked_invalid as masked_invalid,
118
+ masked_less as masked_less,
119
+ masked_less_equal as masked_less_equal,
120
+ masked_not_equal as masked_not_equal,
121
+ masked_object as masked_object,
122
+ masked_outside as masked_outside,
123
+ masked_print_option as masked_print_option,
124
+ masked_singleton as masked_singleton,
125
+ masked_values as masked_values,
126
+ masked_where as masked_where,
127
+ max as max,
128
+ maximum as maximum,
129
+ maximum_fill_value as maximum_fill_value,
130
+ mean as mean,
131
+ min as min,
132
+ minimum as minimum,
133
+ minimum_fill_value as minimum_fill_value,
134
+ mod as mod,
135
+ multiply as multiply,
136
+ mvoid as mvoid,
137
+ ndim as ndim,
138
+ negative as negative,
139
+ nomask as nomask,
140
+ nonzero as nonzero,
141
+ not_equal as not_equal,
142
+ ones as ones,
143
+ outer as outer,
144
+ outerproduct as outerproduct,
145
+ power as power,
146
+ prod as prod,
147
+ product as product,
148
+ ptp as ptp,
149
+ put as put,
150
+ putmask as putmask,
151
+ ravel as ravel,
152
+ remainder as remainder,
153
+ repeat as repeat,
154
+ reshape as reshape,
155
+ resize as resize,
156
+ right_shift as right_shift,
157
+ round as round,
158
+ set_fill_value as set_fill_value,
159
+ shape as shape,
160
+ sin as sin,
161
+ sinh as sinh,
162
+ size as size,
163
+ soften_mask as soften_mask,
164
+ sometrue as sometrue,
165
+ sort as sort,
166
+ sqrt as sqrt,
167
+ squeeze as squeeze,
168
+ std as std,
169
+ subtract as subtract,
170
+ sum as sum,
171
+ swapaxes as swapaxes,
172
+ take as take,
173
+ tan as tan,
174
+ tanh as tanh,
175
+ trace as trace,
176
+ transpose as transpose,
177
+ true_divide as true_divide,
178
+ var as var,
179
+ where as where,
180
+ zeros as zeros,
181
+ )
182
+
183
+ from numpy.ma.extras import (
184
+ apply_along_axis as apply_along_axis,
185
+ apply_over_axes as apply_over_axes,
186
+ atleast_1d as atleast_1d,
187
+ atleast_2d as atleast_2d,
188
+ atleast_3d as atleast_3d,
189
+ average as average,
190
+ clump_masked as clump_masked,
191
+ clump_unmasked as clump_unmasked,
192
+ column_stack as column_stack,
193
+ compress_cols as compress_cols,
194
+ compress_nd as compress_nd,
195
+ compress_rowcols as compress_rowcols,
196
+ compress_rows as compress_rows,
197
+ count_masked as count_masked,
198
+ corrcoef as corrcoef,
199
+ cov as cov,
200
+ diagflat as diagflat,
201
+ dot as dot,
202
+ dstack as dstack,
203
+ ediff1d as ediff1d,
204
+ flatnotmasked_contiguous as flatnotmasked_contiguous,
205
+ flatnotmasked_edges as flatnotmasked_edges,
206
+ hsplit as hsplit,
207
+ hstack as hstack,
208
+ isin as isin,
209
+ in1d as in1d,
210
+ intersect1d as intersect1d,
211
+ mask_cols as mask_cols,
212
+ mask_rowcols as mask_rowcols,
213
+ mask_rows as mask_rows,
214
+ masked_all as masked_all,
215
+ masked_all_like as masked_all_like,
216
+ median as median,
217
+ mr_ as mr_,
218
+ ndenumerate as ndenumerate,
219
+ notmasked_contiguous as notmasked_contiguous,
220
+ notmasked_edges as notmasked_edges,
221
+ polyfit as polyfit,
222
+ row_stack as row_stack,
223
+ setdiff1d as setdiff1d,
224
+ setxor1d as setxor1d,
225
+ stack as stack,
226
+ unique as unique,
227
+ union1d as union1d,
228
+ vander as vander,
229
+ vstack as vstack,
230
+ )
231
+
232
+ __all__: list[str]
233
+ __path__: list[str]
234
+ test: PytestTester
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/core.py ADDED
The diff for this file is too large to render. See raw diff
 
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/core.pyi ADDED
@@ -0,0 +1,471 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from collections.abc import Callable
2
+ from typing import Any, TypeVar
3
+ from numpy import ndarray, dtype, float64
4
+
5
+ from numpy import (
6
+ amax as amax,
7
+ amin as amin,
8
+ bool_ as bool_,
9
+ expand_dims as expand_dims,
10
+ clip as clip,
11
+ indices as indices,
12
+ ones_like as ones_like,
13
+ squeeze as squeeze,
14
+ zeros_like as zeros_like,
15
+ )
16
+
17
+ from numpy.lib.function_base import (
18
+ angle as angle,
19
+ )
20
+
21
+ # TODO: Set the `bound` to something more suitable once we
22
+ # have proper shape support
23
+ _ShapeType = TypeVar("_ShapeType", bound=Any)
24
+ _DType_co = TypeVar("_DType_co", bound=dtype[Any], covariant=True)
25
+
26
+ __all__: list[str]
27
+
28
+ MaskType = bool_
29
+ nomask: bool_
30
+
31
+ class MaskedArrayFutureWarning(FutureWarning): ...
32
+ class MAError(Exception): ...
33
+ class MaskError(MAError): ...
34
+
35
+ def default_fill_value(obj): ...
36
+ def minimum_fill_value(obj): ...
37
+ def maximum_fill_value(obj): ...
38
+ def set_fill_value(a, fill_value): ...
39
+ def common_fill_value(a, b): ...
40
+ def filled(a, fill_value=...): ...
41
+ def getdata(a, subok=...): ...
42
+ get_data = getdata
43
+
44
+ def fix_invalid(a, mask=..., copy=..., fill_value=...): ...
45
+
46
+ class _MaskedUFunc:
47
+ f: Any
48
+ __doc__: Any
49
+ __name__: Any
50
+ def __init__(self, ufunc): ...
51
+
52
+ class _MaskedUnaryOperation(_MaskedUFunc):
53
+ fill: Any
54
+ domain: Any
55
+ def __init__(self, mufunc, fill=..., domain=...): ...
56
+ def __call__(self, a, *args, **kwargs): ...
57
+
58
+ class _MaskedBinaryOperation(_MaskedUFunc):
59
+ fillx: Any
60
+ filly: Any
61
+ def __init__(self, mbfunc, fillx=..., filly=...): ...
62
+ def __call__(self, a, b, *args, **kwargs): ...
63
+ def reduce(self, target, axis=..., dtype=...): ...
64
+ def outer(self, a, b): ...
65
+ def accumulate(self, target, axis=...): ...
66
+
67
+ class _DomainedBinaryOperation(_MaskedUFunc):
68
+ domain: Any
69
+ fillx: Any
70
+ filly: Any
71
+ def __init__(self, dbfunc, domain, fillx=..., filly=...): ...
72
+ def __call__(self, a, b, *args, **kwargs): ...
73
+
74
+ exp: _MaskedUnaryOperation
75
+ conjugate: _MaskedUnaryOperation
76
+ sin: _MaskedUnaryOperation
77
+ cos: _MaskedUnaryOperation
78
+ arctan: _MaskedUnaryOperation
79
+ arcsinh: _MaskedUnaryOperation
80
+ sinh: _MaskedUnaryOperation
81
+ cosh: _MaskedUnaryOperation
82
+ tanh: _MaskedUnaryOperation
83
+ abs: _MaskedUnaryOperation
84
+ absolute: _MaskedUnaryOperation
85
+ fabs: _MaskedUnaryOperation
86
+ negative: _MaskedUnaryOperation
87
+ floor: _MaskedUnaryOperation
88
+ ceil: _MaskedUnaryOperation
89
+ around: _MaskedUnaryOperation
90
+ logical_not: _MaskedUnaryOperation
91
+ sqrt: _MaskedUnaryOperation
92
+ log: _MaskedUnaryOperation
93
+ log2: _MaskedUnaryOperation
94
+ log10: _MaskedUnaryOperation
95
+ tan: _MaskedUnaryOperation
96
+ arcsin: _MaskedUnaryOperation
97
+ arccos: _MaskedUnaryOperation
98
+ arccosh: _MaskedUnaryOperation
99
+ arctanh: _MaskedUnaryOperation
100
+
101
+ add: _MaskedBinaryOperation
102
+ subtract: _MaskedBinaryOperation
103
+ multiply: _MaskedBinaryOperation
104
+ arctan2: _MaskedBinaryOperation
105
+ equal: _MaskedBinaryOperation
106
+ not_equal: _MaskedBinaryOperation
107
+ less_equal: _MaskedBinaryOperation
108
+ greater_equal: _MaskedBinaryOperation
109
+ less: _MaskedBinaryOperation
110
+ greater: _MaskedBinaryOperation
111
+ logical_and: _MaskedBinaryOperation
112
+ alltrue: _MaskedBinaryOperation
113
+ logical_or: _MaskedBinaryOperation
114
+ sometrue: Callable[..., Any]
115
+ logical_xor: _MaskedBinaryOperation
116
+ bitwise_and: _MaskedBinaryOperation
117
+ bitwise_or: _MaskedBinaryOperation
118
+ bitwise_xor: _MaskedBinaryOperation
119
+ hypot: _MaskedBinaryOperation
120
+ divide: _MaskedBinaryOperation
121
+ true_divide: _MaskedBinaryOperation
122
+ floor_divide: _MaskedBinaryOperation
123
+ remainder: _MaskedBinaryOperation
124
+ fmod: _MaskedBinaryOperation
125
+ mod: _MaskedBinaryOperation
126
+
127
+ def make_mask_descr(ndtype): ...
128
+ def getmask(a): ...
129
+ get_mask = getmask
130
+
131
+ def getmaskarray(arr): ...
132
+ def is_mask(m): ...
133
+ def make_mask(m, copy=..., shrink=..., dtype=...): ...
134
+ def make_mask_none(newshape, dtype=...): ...
135
+ def mask_or(m1, m2, copy=..., shrink=...): ...
136
+ def flatten_mask(mask): ...
137
+ def masked_where(condition, a, copy=...): ...
138
+ def masked_greater(x, value, copy=...): ...
139
+ def masked_greater_equal(x, value, copy=...): ...
140
+ def masked_less(x, value, copy=...): ...
141
+ def masked_less_equal(x, value, copy=...): ...
142
+ def masked_not_equal(x, value, copy=...): ...
143
+ def masked_equal(x, value, copy=...): ...
144
+ def masked_inside(x, v1, v2, copy=...): ...
145
+ def masked_outside(x, v1, v2, copy=...): ...
146
+ def masked_object(x, value, copy=..., shrink=...): ...
147
+ def masked_values(x, value, rtol=..., atol=..., copy=..., shrink=...): ...
148
+ def masked_invalid(a, copy=...): ...
149
+
150
+ class _MaskedPrintOption:
151
+ def __init__(self, display): ...
152
+ def display(self): ...
153
+ def set_display(self, s): ...
154
+ def enabled(self): ...
155
+ def enable(self, shrink=...): ...
156
+
157
+ masked_print_option: _MaskedPrintOption
158
+
159
+ def flatten_structured_array(a): ...
160
+
161
+ class MaskedIterator:
162
+ ma: Any
163
+ dataiter: Any
164
+ maskiter: Any
165
+ def __init__(self, ma): ...
166
+ def __iter__(self): ...
167
+ def __getitem__(self, indx): ...
168
+ def __setitem__(self, index, value): ...
169
+ def __next__(self): ...
170
+
171
+ class MaskedArray(ndarray[_ShapeType, _DType_co]):
172
+ __array_priority__: Any
173
+ def __new__(cls, data=..., mask=..., dtype=..., copy=..., subok=..., ndmin=..., fill_value=..., keep_mask=..., hard_mask=..., shrink=..., order=...): ...
174
+ def __array_finalize__(self, obj): ...
175
+ def __array_wrap__(self, obj, context=...): ...
176
+ def view(self, dtype=..., type=..., fill_value=...): ...
177
+ def __getitem__(self, indx): ...
178
+ def __setitem__(self, indx, value): ...
179
+ @property
180
+ def dtype(self): ...
181
+ @dtype.setter
182
+ def dtype(self, dtype): ...
183
+ @property
184
+ def shape(self): ...
185
+ @shape.setter
186
+ def shape(self, shape): ...
187
+ def __setmask__(self, mask, copy=...): ...
188
+ @property
189
+ def mask(self): ...
190
+ @mask.setter
191
+ def mask(self, value): ...
192
+ @property
193
+ def recordmask(self): ...
194
+ @recordmask.setter
195
+ def recordmask(self, mask): ...
196
+ def harden_mask(self): ...
197
+ def soften_mask(self): ...
198
+ @property
199
+ def hardmask(self): ...
200
+ def unshare_mask(self): ...
201
+ @property
202
+ def sharedmask(self): ...
203
+ def shrink_mask(self): ...
204
+ @property
205
+ def baseclass(self): ...
206
+ data: Any
207
+ @property
208
+ def flat(self): ...
209
+ @flat.setter
210
+ def flat(self, value): ...
211
+ @property
212
+ def fill_value(self): ...
213
+ @fill_value.setter
214
+ def fill_value(self, value=...): ...
215
+ get_fill_value: Any
216
+ set_fill_value: Any
217
+ def filled(self, fill_value=...): ...
218
+ def compressed(self): ...
219
+ def compress(self, condition, axis=..., out=...): ...
220
+ def __eq__(self, other): ...
221
+ def __ne__(self, other): ...
222
+ def __ge__(self, other): ...
223
+ def __gt__(self, other): ...
224
+ def __le__(self, other): ...
225
+ def __lt__(self, other): ...
226
+ def __add__(self, other): ...
227
+ def __radd__(self, other): ...
228
+ def __sub__(self, other): ...
229
+ def __rsub__(self, other): ...
230
+ def __mul__(self, other): ...
231
+ def __rmul__(self, other): ...
232
+ def __div__(self, other): ...
233
+ def __truediv__(self, other): ...
234
+ def __rtruediv__(self, other): ...
235
+ def __floordiv__(self, other): ...
236
+ def __rfloordiv__(self, other): ...
237
+ def __pow__(self, other): ...
238
+ def __rpow__(self, other): ...
239
+ def __iadd__(self, other): ...
240
+ def __isub__(self, other): ...
241
+ def __imul__(self, other): ...
242
+ def __idiv__(self, other): ...
243
+ def __ifloordiv__(self, other): ...
244
+ def __itruediv__(self, other): ...
245
+ def __ipow__(self, other): ...
246
+ def __float__(self): ...
247
+ def __int__(self): ...
248
+ @property # type: ignore[misc]
249
+ def imag(self): ...
250
+ get_imag: Any
251
+ @property # type: ignore[misc]
252
+ def real(self): ...
253
+ get_real: Any
254
+ def count(self, axis=..., keepdims=...): ...
255
+ def ravel(self, order=...): ...
256
+ def reshape(self, *s, **kwargs): ...
257
+ def resize(self, newshape, refcheck=..., order=...): ...
258
+ def put(self, indices, values, mode=...): ...
259
+ def ids(self): ...
260
+ def iscontiguous(self): ...
261
+ def all(self, axis=..., out=..., keepdims=...): ...
262
+ def any(self, axis=..., out=..., keepdims=...): ...
263
+ def nonzero(self): ...
264
+ def trace(self, offset=..., axis1=..., axis2=..., dtype=..., out=...): ...
265
+ def dot(self, b, out=..., strict=...): ...
266
+ def sum(self, axis=..., dtype=..., out=..., keepdims=...): ...
267
+ def cumsum(self, axis=..., dtype=..., out=...): ...
268
+ def prod(self, axis=..., dtype=..., out=..., keepdims=...): ...
269
+ product: Any
270
+ def cumprod(self, axis=..., dtype=..., out=...): ...
271
+ def mean(self, axis=..., dtype=..., out=..., keepdims=...): ...
272
+ def anom(self, axis=..., dtype=...): ...
273
+ def var(self, axis=..., dtype=..., out=..., ddof=..., keepdims=...): ...
274
+ def std(self, axis=..., dtype=..., out=..., ddof=..., keepdims=...): ...
275
+ def round(self, decimals=..., out=...): ...
276
+ def argsort(self, axis=..., kind=..., order=..., endwith=..., fill_value=...): ...
277
+ def argmin(self, axis=..., fill_value=..., out=..., *, keepdims=...): ...
278
+ def argmax(self, axis=..., fill_value=..., out=..., *, keepdims=...): ...
279
+ def sort(self, axis=..., kind=..., order=..., endwith=..., fill_value=...): ...
280
+ def min(self, axis=..., out=..., fill_value=..., keepdims=...): ...
281
+ # NOTE: deprecated
282
+ # def tostring(self, fill_value=..., order=...): ...
283
+ def max(self, axis=..., out=..., fill_value=..., keepdims=...): ...
284
+ def ptp(self, axis=..., out=..., fill_value=..., keepdims=...): ...
285
+ def partition(self, *args, **kwargs): ...
286
+ def argpartition(self, *args, **kwargs): ...
287
+ def take(self, indices, axis=..., out=..., mode=...): ...
288
+ copy: Any
289
+ diagonal: Any
290
+ flatten: Any
291
+ repeat: Any
292
+ squeeze: Any
293
+ swapaxes: Any
294
+ T: Any
295
+ transpose: Any
296
+ def tolist(self, fill_value=...): ...
297
+ def tobytes(self, fill_value=..., order=...): ...
298
+ def tofile(self, fid, sep=..., format=...): ...
299
+ def toflex(self): ...
300
+ torecords: Any
301
+ def __reduce__(self): ...
302
+ def __deepcopy__(self, memo=...): ...
303
+
304
+ class mvoid(MaskedArray[_ShapeType, _DType_co]):
305
+ def __new__(
306
+ self,
307
+ data,
308
+ mask=...,
309
+ dtype=...,
310
+ fill_value=...,
311
+ hardmask=...,
312
+ copy=...,
313
+ subok=...,
314
+ ): ...
315
+ def __getitem__(self, indx): ...
316
+ def __setitem__(self, indx, value): ...
317
+ def __iter__(self): ...
318
+ def __len__(self): ...
319
+ def filled(self, fill_value=...): ...
320
+ def tolist(self): ...
321
+
322
+ def isMaskedArray(x): ...
323
+ isarray = isMaskedArray
324
+ isMA = isMaskedArray
325
+
326
+ # 0D float64 array
327
+ class MaskedConstant(MaskedArray[Any, dtype[float64]]):
328
+ def __new__(cls): ...
329
+ __class__: Any
330
+ def __array_finalize__(self, obj): ...
331
+ def __array_prepare__(self, obj, context=...): ...
332
+ def __array_wrap__(self, obj, context=...): ...
333
+ def __format__(self, format_spec): ...
334
+ def __reduce__(self): ...
335
+ def __iop__(self, other): ...
336
+ __iadd__: Any
337
+ __isub__: Any
338
+ __imul__: Any
339
+ __ifloordiv__: Any
340
+ __itruediv__: Any
341
+ __ipow__: Any
342
+ def copy(self, *args, **kwargs): ...
343
+ def __copy__(self): ...
344
+ def __deepcopy__(self, memo): ...
345
+ def __setattr__(self, attr, value): ...
346
+
347
+ masked: MaskedConstant
348
+ masked_singleton: MaskedConstant
349
+ masked_array = MaskedArray
350
+
351
+ def array(
352
+ data,
353
+ dtype=...,
354
+ copy=...,
355
+ order=...,
356
+ mask=...,
357
+ fill_value=...,
358
+ keep_mask=...,
359
+ hard_mask=...,
360
+ shrink=...,
361
+ subok=...,
362
+ ndmin=...,
363
+ ): ...
364
+ def is_masked(x): ...
365
+
366
+ class _extrema_operation(_MaskedUFunc):
367
+ compare: Any
368
+ fill_value_func: Any
369
+ def __init__(self, ufunc, compare, fill_value): ...
370
+ # NOTE: in practice `b` has a default value, but users should
371
+ # explicitly provide a value here as the default is deprecated
372
+ def __call__(self, a, b): ...
373
+ def reduce(self, target, axis=...): ...
374
+ def outer(self, a, b): ...
375
+
376
+ def min(obj, axis=..., out=..., fill_value=..., keepdims=...): ...
377
+ def max(obj, axis=..., out=..., fill_value=..., keepdims=...): ...
378
+ def ptp(obj, axis=..., out=..., fill_value=..., keepdims=...): ...
379
+
380
+ class _frommethod:
381
+ __name__: Any
382
+ __doc__: Any
383
+ reversed: Any
384
+ def __init__(self, methodname, reversed=...): ...
385
+ def getdoc(self): ...
386
+ def __call__(self, a, *args, **params): ...
387
+
388
+ all: _frommethod
389
+ anomalies: _frommethod
390
+ anom: _frommethod
391
+ any: _frommethod
392
+ compress: _frommethod
393
+ cumprod: _frommethod
394
+ cumsum: _frommethod
395
+ copy: _frommethod
396
+ diagonal: _frommethod
397
+ harden_mask: _frommethod
398
+ ids: _frommethod
399
+ mean: _frommethod
400
+ nonzero: _frommethod
401
+ prod: _frommethod
402
+ product: _frommethod
403
+ ravel: _frommethod
404
+ repeat: _frommethod
405
+ soften_mask: _frommethod
406
+ std: _frommethod
407
+ sum: _frommethod
408
+ swapaxes: _frommethod
409
+ trace: _frommethod
410
+ var: _frommethod
411
+ count: _frommethod
412
+ argmin: _frommethod
413
+ argmax: _frommethod
414
+
415
+ minimum: _extrema_operation
416
+ maximum: _extrema_operation
417
+
418
+ def take(a, indices, axis=..., out=..., mode=...): ...
419
+ def power(a, b, third=...): ...
420
+ def argsort(a, axis=..., kind=..., order=..., endwith=..., fill_value=...): ...
421
+ def sort(a, axis=..., kind=..., order=..., endwith=..., fill_value=...): ...
422
+ def compressed(x): ...
423
+ def concatenate(arrays, axis=...): ...
424
+ def diag(v, k=...): ...
425
+ def left_shift(a, n): ...
426
+ def right_shift(a, n): ...
427
+ def put(a, indices, values, mode=...): ...
428
+ def putmask(a, mask, values): ...
429
+ def transpose(a, axes=...): ...
430
+ def reshape(a, new_shape, order=...): ...
431
+ def resize(x, new_shape): ...
432
+ def ndim(obj): ...
433
+ def shape(obj): ...
434
+ def size(obj, axis=...): ...
435
+ def diff(a, /, n=..., axis=..., prepend=..., append=...): ...
436
+ def where(condition, x=..., y=...): ...
437
+ def choose(indices, choices, out=..., mode=...): ...
438
+ def round(a, decimals=..., out=...): ...
439
+
440
+ def inner(a, b): ...
441
+ innerproduct = inner
442
+
443
+ def outer(a, b): ...
444
+ outerproduct = outer
445
+
446
+ def correlate(a, v, mode=..., propagate_mask=...): ...
447
+ def convolve(a, v, mode=..., propagate_mask=...): ...
448
+ def allequal(a, b, fill_value=...): ...
449
+ def allclose(a, b, masked_equal=..., rtol=..., atol=...): ...
450
+ def asarray(a, dtype=..., order=...): ...
451
+ def asanyarray(a, dtype=...): ...
452
+ def fromflex(fxarray): ...
453
+
454
+ class _convert2ma:
455
+ __doc__: Any
456
+ def __init__(self, funcname, params=...): ...
457
+ def getdoc(self): ...
458
+ def __call__(self, *args, **params): ...
459
+
460
+ arange: _convert2ma
461
+ empty: _convert2ma
462
+ empty_like: _convert2ma
463
+ frombuffer: _convert2ma
464
+ fromfunction: _convert2ma
465
+ identity: _convert2ma
466
+ ones: _convert2ma
467
+ zeros: _convert2ma
468
+
469
+ def append(a, b, axis=...): ...
470
+ def dot(a, b, strict=..., out=...): ...
471
+ def mask_rowcols(a, axis=...): ...
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/extras.py ADDED
@@ -0,0 +1,2133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Masked arrays add-ons.
3
+
4
+ A collection of utilities for `numpy.ma`.
5
+
6
+ :author: Pierre Gerard-Marchant
7
+ :contact: pierregm_at_uga_dot_edu
8
+ :version: $Id: extras.py 3473 2007-10-29 15:18:13Z jarrod.millman $
9
+
10
+ """
11
+ __all__ = [
12
+ 'apply_along_axis', 'apply_over_axes', 'atleast_1d', 'atleast_2d',
13
+ 'atleast_3d', 'average', 'clump_masked', 'clump_unmasked', 'column_stack',
14
+ 'compress_cols', 'compress_nd', 'compress_rowcols', 'compress_rows',
15
+ 'count_masked', 'corrcoef', 'cov', 'diagflat', 'dot', 'dstack', 'ediff1d',
16
+ 'flatnotmasked_contiguous', 'flatnotmasked_edges', 'hsplit', 'hstack',
17
+ 'isin', 'in1d', 'intersect1d', 'mask_cols', 'mask_rowcols', 'mask_rows',
18
+ 'masked_all', 'masked_all_like', 'median', 'mr_', 'ndenumerate',
19
+ 'notmasked_contiguous', 'notmasked_edges', 'polyfit', 'row_stack',
20
+ 'setdiff1d', 'setxor1d', 'stack', 'unique', 'union1d', 'vander', 'vstack',
21
+ ]
22
+
23
+ import itertools
24
+ import warnings
25
+
26
+ from . import core as ma
27
+ from .core import (
28
+ MaskedArray, MAError, add, array, asarray, concatenate, filled, count,
29
+ getmask, getmaskarray, make_mask_descr, masked, masked_array, mask_or,
30
+ nomask, ones, sort, zeros, getdata, get_masked_subclass, dot
31
+ )
32
+
33
+ import numpy as np
34
+ from numpy import ndarray, array as nxarray
35
+ from numpy.core.multiarray import normalize_axis_index
36
+ from numpy.core.numeric import normalize_axis_tuple
37
+ from numpy.lib.function_base import _ureduce
38
+ from numpy.lib.index_tricks import AxisConcatenator
39
+
40
+
41
+ def issequence(seq):
42
+ """
43
+ Is seq a sequence (ndarray, list or tuple)?
44
+
45
+ """
46
+ return isinstance(seq, (ndarray, tuple, list))
47
+
48
+
49
+ def count_masked(arr, axis=None):
50
+ """
51
+ Count the number of masked elements along the given axis.
52
+
53
+ Parameters
54
+ ----------
55
+ arr : array_like
56
+ An array with (possibly) masked elements.
57
+ axis : int, optional
58
+ Axis along which to count. If None (default), a flattened
59
+ version of the array is used.
60
+
61
+ Returns
62
+ -------
63
+ count : int, ndarray
64
+ The total number of masked elements (axis=None) or the number
65
+ of masked elements along each slice of the given axis.
66
+
67
+ See Also
68
+ --------
69
+ MaskedArray.count : Count non-masked elements.
70
+
71
+ Examples
72
+ --------
73
+ >>> import numpy.ma as ma
74
+ >>> a = np.arange(9).reshape((3,3))
75
+ >>> a = ma.array(a)
76
+ >>> a[1, 0] = ma.masked
77
+ >>> a[1, 2] = ma.masked
78
+ >>> a[2, 1] = ma.masked
79
+ >>> a
80
+ masked_array(
81
+ data=[[0, 1, 2],
82
+ [--, 4, --],
83
+ [6, --, 8]],
84
+ mask=[[False, False, False],
85
+ [ True, False, True],
86
+ [False, True, False]],
87
+ fill_value=999999)
88
+ >>> ma.count_masked(a)
89
+ 3
90
+
91
+ When the `axis` keyword is used an array is returned.
92
+
93
+ >>> ma.count_masked(a, axis=0)
94
+ array([1, 1, 1])
95
+ >>> ma.count_masked(a, axis=1)
96
+ array([0, 2, 1])
97
+
98
+ """
99
+ m = getmaskarray(arr)
100
+ return m.sum(axis)
101
+
102
+
103
+ def masked_all(shape, dtype=float):
104
+ """
105
+ Empty masked array with all elements masked.
106
+
107
+ Return an empty masked array of the given shape and dtype, where all the
108
+ data are masked.
109
+
110
+ Parameters
111
+ ----------
112
+ shape : int or tuple of ints
113
+ Shape of the required MaskedArray, e.g., ``(2, 3)`` or ``2``.
114
+ dtype : dtype, optional
115
+ Data type of the output.
116
+
117
+ Returns
118
+ -------
119
+ a : MaskedArray
120
+ A masked array with all data masked.
121
+
122
+ See Also
123
+ --------
124
+ masked_all_like : Empty masked array modelled on an existing array.
125
+
126
+ Examples
127
+ --------
128
+ >>> import numpy.ma as ma
129
+ >>> ma.masked_all((3, 3))
130
+ masked_array(
131
+ data=[[--, --, --],
132
+ [--, --, --],
133
+ [--, --, --]],
134
+ mask=[[ True, True, True],
135
+ [ True, True, True],
136
+ [ True, True, True]],
137
+ fill_value=1e+20,
138
+ dtype=float64)
139
+
140
+ The `dtype` parameter defines the underlying data type.
141
+
142
+ >>> a = ma.masked_all((3, 3))
143
+ >>> a.dtype
144
+ dtype('float64')
145
+ >>> a = ma.masked_all((3, 3), dtype=np.int32)
146
+ >>> a.dtype
147
+ dtype('int32')
148
+
149
+ """
150
+ a = masked_array(np.empty(shape, dtype),
151
+ mask=np.ones(shape, make_mask_descr(dtype)))
152
+ return a
153
+
154
+
155
+ def masked_all_like(arr):
156
+ """
157
+ Empty masked array with the properties of an existing array.
158
+
159
+ Return an empty masked array of the same shape and dtype as
160
+ the array `arr`, where all the data are masked.
161
+
162
+ Parameters
163
+ ----------
164
+ arr : ndarray
165
+ An array describing the shape and dtype of the required MaskedArray.
166
+
167
+ Returns
168
+ -------
169
+ a : MaskedArray
170
+ A masked array with all data masked.
171
+
172
+ Raises
173
+ ------
174
+ AttributeError
175
+ If `arr` doesn't have a shape attribute (i.e. not an ndarray)
176
+
177
+ See Also
178
+ --------
179
+ masked_all : Empty masked array with all elements masked.
180
+
181
+ Examples
182
+ --------
183
+ >>> import numpy.ma as ma
184
+ >>> arr = np.zeros((2, 3), dtype=np.float32)
185
+ >>> arr
186
+ array([[0., 0., 0.],
187
+ [0., 0., 0.]], dtype=float32)
188
+ >>> ma.masked_all_like(arr)
189
+ masked_array(
190
+ data=[[--, --, --],
191
+ [--, --, --]],
192
+ mask=[[ True, True, True],
193
+ [ True, True, True]],
194
+ fill_value=1e+20,
195
+ dtype=float32)
196
+
197
+ The dtype of the masked array matches the dtype of `arr`.
198
+
199
+ >>> arr.dtype
200
+ dtype('float32')
201
+ >>> ma.masked_all_like(arr).dtype
202
+ dtype('float32')
203
+
204
+ """
205
+ a = np.empty_like(arr).view(MaskedArray)
206
+ a._mask = np.ones(a.shape, dtype=make_mask_descr(a.dtype))
207
+ return a
208
+
209
+
210
+ #####--------------------------------------------------------------------------
211
+ #---- --- Standard functions ---
212
+ #####--------------------------------------------------------------------------
213
+ class _fromnxfunction:
214
+ """
215
+ Defines a wrapper to adapt NumPy functions to masked arrays.
216
+
217
+
218
+ An instance of `_fromnxfunction` can be called with the same parameters
219
+ as the wrapped NumPy function. The docstring of `newfunc` is adapted from
220
+ the wrapped function as well, see `getdoc`.
221
+
222
+ This class should not be used directly. Instead, one of its extensions that
223
+ provides support for a specific type of input should be used.
224
+
225
+ Parameters
226
+ ----------
227
+ funcname : str
228
+ The name of the function to be adapted. The function should be
229
+ in the NumPy namespace (i.e. ``np.funcname``).
230
+
231
+ """
232
+
233
+ def __init__(self, funcname):
234
+ self.__name__ = funcname
235
+ self.__doc__ = self.getdoc()
236
+
237
+ def getdoc(self):
238
+ """
239
+ Retrieve the docstring and signature from the function.
240
+
241
+ The ``__doc__`` attribute of the function is used as the docstring for
242
+ the new masked array version of the function. A note on application
243
+ of the function to the mask is appended.
244
+
245
+ Parameters
246
+ ----------
247
+ None
248
+
249
+ """
250
+ npfunc = getattr(np, self.__name__, None)
251
+ doc = getattr(npfunc, '__doc__', None)
252
+ if doc:
253
+ sig = self.__name__ + ma.get_object_signature(npfunc)
254
+ doc = ma.doc_note(doc, "The function is applied to both the _data "
255
+ "and the _mask, if any.")
256
+ return '\n\n'.join((sig, doc))
257
+ return
258
+
259
+ def __call__(self, *args, **params):
260
+ pass
261
+
262
+
263
+ class _fromnxfunction_single(_fromnxfunction):
264
+ """
265
+ A version of `_fromnxfunction` that is called with a single array
266
+ argument followed by auxiliary args that are passed verbatim for
267
+ both the data and mask calls.
268
+ """
269
+ def __call__(self, x, *args, **params):
270
+ func = getattr(np, self.__name__)
271
+ if isinstance(x, ndarray):
272
+ _d = func(x.__array__(), *args, **params)
273
+ _m = func(getmaskarray(x), *args, **params)
274
+ return masked_array(_d, mask=_m)
275
+ else:
276
+ _d = func(np.asarray(x), *args, **params)
277
+ _m = func(getmaskarray(x), *args, **params)
278
+ return masked_array(_d, mask=_m)
279
+
280
+
281
+ class _fromnxfunction_seq(_fromnxfunction):
282
+ """
283
+ A version of `_fromnxfunction` that is called with a single sequence
284
+ of arrays followed by auxiliary args that are passed verbatim for
285
+ both the data and mask calls.
286
+ """
287
+ def __call__(self, x, *args, **params):
288
+ func = getattr(np, self.__name__)
289
+ _d = func(tuple([np.asarray(a) for a in x]), *args, **params)
290
+ _m = func(tuple([getmaskarray(a) for a in x]), *args, **params)
291
+ return masked_array(_d, mask=_m)
292
+
293
+
294
+ class _fromnxfunction_args(_fromnxfunction):
295
+ """
296
+ A version of `_fromnxfunction` that is called with multiple array
297
+ arguments. The first non-array-like input marks the beginning of the
298
+ arguments that are passed verbatim for both the data and mask calls.
299
+ Array arguments are processed independently and the results are
300
+ returned in a list. If only one array is found, the return value is
301
+ just the processed array instead of a list.
302
+ """
303
+ def __call__(self, *args, **params):
304
+ func = getattr(np, self.__name__)
305
+ arrays = []
306
+ args = list(args)
307
+ while len(args) > 0 and issequence(args[0]):
308
+ arrays.append(args.pop(0))
309
+ res = []
310
+ for x in arrays:
311
+ _d = func(np.asarray(x), *args, **params)
312
+ _m = func(getmaskarray(x), *args, **params)
313
+ res.append(masked_array(_d, mask=_m))
314
+ if len(arrays) == 1:
315
+ return res[0]
316
+ return res
317
+
318
+
319
+ class _fromnxfunction_allargs(_fromnxfunction):
320
+ """
321
+ A version of `_fromnxfunction` that is called with multiple array
322
+ arguments. Similar to `_fromnxfunction_args` except that all args
323
+ are converted to arrays even if they are not so already. This makes
324
+ it possible to process scalars as 1-D arrays. Only keyword arguments
325
+ are passed through verbatim for the data and mask calls. Arrays
326
+ arguments are processed independently and the results are returned
327
+ in a list. If only one arg is present, the return value is just the
328
+ processed array instead of a list.
329
+ """
330
+ def __call__(self, *args, **params):
331
+ func = getattr(np, self.__name__)
332
+ res = []
333
+ for x in args:
334
+ _d = func(np.asarray(x), **params)
335
+ _m = func(getmaskarray(x), **params)
336
+ res.append(masked_array(_d, mask=_m))
337
+ if len(args) == 1:
338
+ return res[0]
339
+ return res
340
+
341
+
342
+ atleast_1d = _fromnxfunction_allargs('atleast_1d')
343
+ atleast_2d = _fromnxfunction_allargs('atleast_2d')
344
+ atleast_3d = _fromnxfunction_allargs('atleast_3d')
345
+
346
+ vstack = row_stack = _fromnxfunction_seq('vstack')
347
+ hstack = _fromnxfunction_seq('hstack')
348
+ column_stack = _fromnxfunction_seq('column_stack')
349
+ dstack = _fromnxfunction_seq('dstack')
350
+ stack = _fromnxfunction_seq('stack')
351
+
352
+ hsplit = _fromnxfunction_single('hsplit')
353
+
354
+ diagflat = _fromnxfunction_single('diagflat')
355
+
356
+
357
+ #####--------------------------------------------------------------------------
358
+ #----
359
+ #####--------------------------------------------------------------------------
360
+ def flatten_inplace(seq):
361
+ """Flatten a sequence in place."""
362
+ k = 0
363
+ while (k != len(seq)):
364
+ while hasattr(seq[k], '__iter__'):
365
+ seq[k:(k + 1)] = seq[k]
366
+ k += 1
367
+ return seq
368
+
369
+
370
+ def apply_along_axis(func1d, axis, arr, *args, **kwargs):
371
+ """
372
+ (This docstring should be overwritten)
373
+ """
374
+ arr = array(arr, copy=False, subok=True)
375
+ nd = arr.ndim
376
+ axis = normalize_axis_index(axis, nd)
377
+ ind = [0] * (nd - 1)
378
+ i = np.zeros(nd, 'O')
379
+ indlist = list(range(nd))
380
+ indlist.remove(axis)
381
+ i[axis] = slice(None, None)
382
+ outshape = np.asarray(arr.shape).take(indlist)
383
+ i.put(indlist, ind)
384
+ res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
385
+ # if res is a number, then we have a smaller output array
386
+ asscalar = np.isscalar(res)
387
+ if not asscalar:
388
+ try:
389
+ len(res)
390
+ except TypeError:
391
+ asscalar = True
392
+ # Note: we shouldn't set the dtype of the output from the first result
393
+ # so we force the type to object, and build a list of dtypes. We'll
394
+ # just take the largest, to avoid some downcasting
395
+ dtypes = []
396
+ if asscalar:
397
+ dtypes.append(np.asarray(res).dtype)
398
+ outarr = zeros(outshape, object)
399
+ outarr[tuple(ind)] = res
400
+ Ntot = np.prod(outshape)
401
+ k = 1
402
+ while k < Ntot:
403
+ # increment the index
404
+ ind[-1] += 1
405
+ n = -1
406
+ while (ind[n] >= outshape[n]) and (n > (1 - nd)):
407
+ ind[n - 1] += 1
408
+ ind[n] = 0
409
+ n -= 1
410
+ i.put(indlist, ind)
411
+ res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
412
+ outarr[tuple(ind)] = res
413
+ dtypes.append(asarray(res).dtype)
414
+ k += 1
415
+ else:
416
+ res = array(res, copy=False, subok=True)
417
+ j = i.copy()
418
+ j[axis] = ([slice(None, None)] * res.ndim)
419
+ j.put(indlist, ind)
420
+ Ntot = np.prod(outshape)
421
+ holdshape = outshape
422
+ outshape = list(arr.shape)
423
+ outshape[axis] = res.shape
424
+ dtypes.append(asarray(res).dtype)
425
+ outshape = flatten_inplace(outshape)
426
+ outarr = zeros(outshape, object)
427
+ outarr[tuple(flatten_inplace(j.tolist()))] = res
428
+ k = 1
429
+ while k < Ntot:
430
+ # increment the index
431
+ ind[-1] += 1
432
+ n = -1
433
+ while (ind[n] >= holdshape[n]) and (n > (1 - nd)):
434
+ ind[n - 1] += 1
435
+ ind[n] = 0
436
+ n -= 1
437
+ i.put(indlist, ind)
438
+ j.put(indlist, ind)
439
+ res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
440
+ outarr[tuple(flatten_inplace(j.tolist()))] = res
441
+ dtypes.append(asarray(res).dtype)
442
+ k += 1
443
+ max_dtypes = np.dtype(np.asarray(dtypes).max())
444
+ if not hasattr(arr, '_mask'):
445
+ result = np.asarray(outarr, dtype=max_dtypes)
446
+ else:
447
+ result = asarray(outarr, dtype=max_dtypes)
448
+ result.fill_value = ma.default_fill_value(result)
449
+ return result
450
+ apply_along_axis.__doc__ = np.apply_along_axis.__doc__
451
+
452
+
453
+ def apply_over_axes(func, a, axes):
454
+ """
455
+ (This docstring will be overwritten)
456
+ """
457
+ val = asarray(a)
458
+ N = a.ndim
459
+ if array(axes).ndim == 0:
460
+ axes = (axes,)
461
+ for axis in axes:
462
+ if axis < 0:
463
+ axis = N + axis
464
+ args = (val, axis)
465
+ res = func(*args)
466
+ if res.ndim == val.ndim:
467
+ val = res
468
+ else:
469
+ res = ma.expand_dims(res, axis)
470
+ if res.ndim == val.ndim:
471
+ val = res
472
+ else:
473
+ raise ValueError("function is not returning "
474
+ "an array of the correct shape")
475
+ return val
476
+
477
+
478
+ if apply_over_axes.__doc__ is not None:
479
+ apply_over_axes.__doc__ = np.apply_over_axes.__doc__[
480
+ :np.apply_over_axes.__doc__.find('Notes')].rstrip() + \
481
+ """
482
+
483
+ Examples
484
+ --------
485
+ >>> a = np.ma.arange(24).reshape(2,3,4)
486
+ >>> a[:,0,1] = np.ma.masked
487
+ >>> a[:,1,:] = np.ma.masked
488
+ >>> a
489
+ masked_array(
490
+ data=[[[0, --, 2, 3],
491
+ [--, --, --, --],
492
+ [8, 9, 10, 11]],
493
+ [[12, --, 14, 15],
494
+ [--, --, --, --],
495
+ [20, 21, 22, 23]]],
496
+ mask=[[[False, True, False, False],
497
+ [ True, True, True, True],
498
+ [False, False, False, False]],
499
+ [[False, True, False, False],
500
+ [ True, True, True, True],
501
+ [False, False, False, False]]],
502
+ fill_value=999999)
503
+ >>> np.ma.apply_over_axes(np.ma.sum, a, [0,2])
504
+ masked_array(
505
+ data=[[[46],
506
+ [--],
507
+ [124]]],
508
+ mask=[[[False],
509
+ [ True],
510
+ [False]]],
511
+ fill_value=999999)
512
+
513
+ Tuple axis arguments to ufuncs are equivalent:
514
+
515
+ >>> np.ma.sum(a, axis=(0,2)).reshape((1,-1,1))
516
+ masked_array(
517
+ data=[[[46],
518
+ [--],
519
+ [124]]],
520
+ mask=[[[False],
521
+ [ True],
522
+ [False]]],
523
+ fill_value=999999)
524
+ """
525
+
526
+
527
+ def average(a, axis=None, weights=None, returned=False, *,
528
+ keepdims=np._NoValue):
529
+ """
530
+ Return the weighted average of array over the given axis.
531
+
532
+ Parameters
533
+ ----------
534
+ a : array_like
535
+ Data to be averaged.
536
+ Masked entries are not taken into account in the computation.
537
+ axis : int, optional
538
+ Axis along which to average `a`. If None, averaging is done over
539
+ the flattened array.
540
+ weights : array_like, optional
541
+ The importance that each element has in the computation of the average.
542
+ The weights array can either be 1-D (in which case its length must be
543
+ the size of `a` along the given axis) or of the same shape as `a`.
544
+ If ``weights=None``, then all data in `a` are assumed to have a
545
+ weight equal to one. The 1-D calculation is::
546
+
547
+ avg = sum(a * weights) / sum(weights)
548
+
549
+ The only constraint on `weights` is that `sum(weights)` must not be 0.
550
+ returned : bool, optional
551
+ Flag indicating whether a tuple ``(result, sum of weights)``
552
+ should be returned as output (True), or just the result (False).
553
+ Default is False.
554
+ keepdims : bool, optional
555
+ If this is set to True, the axes which are reduced are left
556
+ in the result as dimensions with size one. With this option,
557
+ the result will broadcast correctly against the original `a`.
558
+ *Note:* `keepdims` will not work with instances of `numpy.matrix`
559
+ or other classes whose methods do not support `keepdims`.
560
+
561
+ .. versionadded:: 1.23.0
562
+
563
+ Returns
564
+ -------
565
+ average, [sum_of_weights] : (tuple of) scalar or MaskedArray
566
+ The average along the specified axis. When returned is `True`,
567
+ return a tuple with the average as the first element and the sum
568
+ of the weights as the second element. The return type is `np.float64`
569
+ if `a` is of integer type and floats smaller than `float64`, or the
570
+ input data-type, otherwise. If returned, `sum_of_weights` is always
571
+ `float64`.
572
+
573
+ Examples
574
+ --------
575
+ >>> a = np.ma.array([1., 2., 3., 4.], mask=[False, False, True, True])
576
+ >>> np.ma.average(a, weights=[3, 1, 0, 0])
577
+ 1.25
578
+
579
+ >>> x = np.ma.arange(6.).reshape(3, 2)
580
+ >>> x
581
+ masked_array(
582
+ data=[[0., 1.],
583
+ [2., 3.],
584
+ [4., 5.]],
585
+ mask=False,
586
+ fill_value=1e+20)
587
+ >>> avg, sumweights = np.ma.average(x, axis=0, weights=[1, 2, 3],
588
+ ... returned=True)
589
+ >>> avg
590
+ masked_array(data=[2.6666666666666665, 3.6666666666666665],
591
+ mask=[False, False],
592
+ fill_value=1e+20)
593
+
594
+ With ``keepdims=True``, the following result has shape (3, 1).
595
+
596
+ >>> np.ma.average(x, axis=1, keepdims=True)
597
+ masked_array(
598
+ data=[[0.5],
599
+ [2.5],
600
+ [4.5]],
601
+ mask=False,
602
+ fill_value=1e+20)
603
+ """
604
+ a = asarray(a)
605
+ m = getmask(a)
606
+
607
+ # inspired by 'average' in numpy/lib/function_base.py
608
+
609
+ if keepdims is np._NoValue:
610
+ # Don't pass on the keepdims argument if one wasn't given.
611
+ keepdims_kw = {}
612
+ else:
613
+ keepdims_kw = {'keepdims': keepdims}
614
+
615
+ if weights is None:
616
+ avg = a.mean(axis, **keepdims_kw)
617
+ scl = avg.dtype.type(a.count(axis))
618
+ else:
619
+ wgt = asarray(weights)
620
+
621
+ if issubclass(a.dtype.type, (np.integer, np.bool_)):
622
+ result_dtype = np.result_type(a.dtype, wgt.dtype, 'f8')
623
+ else:
624
+ result_dtype = np.result_type(a.dtype, wgt.dtype)
625
+
626
+ # Sanity checks
627
+ if a.shape != wgt.shape:
628
+ if axis is None:
629
+ raise TypeError(
630
+ "Axis must be specified when shapes of a and weights "
631
+ "differ.")
632
+ if wgt.ndim != 1:
633
+ raise TypeError(
634
+ "1D weights expected when shapes of a and weights differ.")
635
+ if wgt.shape[0] != a.shape[axis]:
636
+ raise ValueError(
637
+ "Length of weights not compatible with specified axis.")
638
+
639
+ # setup wgt to broadcast along axis
640
+ wgt = np.broadcast_to(wgt, (a.ndim-1)*(1,) + wgt.shape, subok=True)
641
+ wgt = wgt.swapaxes(-1, axis)
642
+
643
+ if m is not nomask:
644
+ wgt = wgt*(~a.mask)
645
+ wgt.mask |= a.mask
646
+
647
+ scl = wgt.sum(axis=axis, dtype=result_dtype, **keepdims_kw)
648
+ avg = np.multiply(a, wgt,
649
+ dtype=result_dtype).sum(axis, **keepdims_kw) / scl
650
+
651
+ if returned:
652
+ if scl.shape != avg.shape:
653
+ scl = np.broadcast_to(scl, avg.shape).copy()
654
+ return avg, scl
655
+ else:
656
+ return avg
657
+
658
+
659
+ def median(a, axis=None, out=None, overwrite_input=False, keepdims=False):
660
+ """
661
+ Compute the median along the specified axis.
662
+
663
+ Returns the median of the array elements.
664
+
665
+ Parameters
666
+ ----------
667
+ a : array_like
668
+ Input array or object that can be converted to an array.
669
+ axis : int, optional
670
+ Axis along which the medians are computed. The default (None) is
671
+ to compute the median along a flattened version of the array.
672
+ out : ndarray, optional
673
+ Alternative output array in which to place the result. It must
674
+ have the same shape and buffer length as the expected output
675
+ but the type will be cast if necessary.
676
+ overwrite_input : bool, optional
677
+ If True, then allow use of memory of input array (a) for
678
+ calculations. The input array will be modified by the call to
679
+ median. This will save memory when you do not need to preserve
680
+ the contents of the input array. Treat the input as undefined,
681
+ but it will probably be fully or partially sorted. Default is
682
+ False. Note that, if `overwrite_input` is True, and the input
683
+ is not already an `ndarray`, an error will be raised.
684
+ keepdims : bool, optional
685
+ If this is set to True, the axes which are reduced are left
686
+ in the result as dimensions with size one. With this option,
687
+ the result will broadcast correctly against the input array.
688
+
689
+ .. versionadded:: 1.10.0
690
+
691
+ Returns
692
+ -------
693
+ median : ndarray
694
+ A new array holding the result is returned unless out is
695
+ specified, in which case a reference to out is returned.
696
+ Return data-type is `float64` for integers and floats smaller than
697
+ `float64`, or the input data-type, otherwise.
698
+
699
+ See Also
700
+ --------
701
+ mean
702
+
703
+ Notes
704
+ -----
705
+ Given a vector ``V`` with ``N`` non masked values, the median of ``V``
706
+ is the middle value of a sorted copy of ``V`` (``Vs``) - i.e.
707
+ ``Vs[(N-1)/2]``, when ``N`` is odd, or ``{Vs[N/2 - 1] + Vs[N/2]}/2``
708
+ when ``N`` is even.
709
+
710
+ Examples
711
+ --------
712
+ >>> x = np.ma.array(np.arange(8), mask=[0]*4 + [1]*4)
713
+ >>> np.ma.median(x)
714
+ 1.5
715
+
716
+ >>> x = np.ma.array(np.arange(10).reshape(2, 5), mask=[0]*6 + [1]*4)
717
+ >>> np.ma.median(x)
718
+ 2.5
719
+ >>> np.ma.median(x, axis=-1, overwrite_input=True)
720
+ masked_array(data=[2.0, 5.0],
721
+ mask=[False, False],
722
+ fill_value=1e+20)
723
+
724
+ """
725
+ if not hasattr(a, 'mask'):
726
+ m = np.median(getdata(a, subok=True), axis=axis,
727
+ out=out, overwrite_input=overwrite_input,
728
+ keepdims=keepdims)
729
+ if isinstance(m, np.ndarray) and 1 <= m.ndim:
730
+ return masked_array(m, copy=False)
731
+ else:
732
+ return m
733
+
734
+ return _ureduce(a, func=_median, keepdims=keepdims, axis=axis, out=out,
735
+ overwrite_input=overwrite_input)
736
+
737
+
738
+ def _median(a, axis=None, out=None, overwrite_input=False):
739
+ # when an unmasked NaN is present return it, so we need to sort the NaN
740
+ # values behind the mask
741
+ if np.issubdtype(a.dtype, np.inexact):
742
+ fill_value = np.inf
743
+ else:
744
+ fill_value = None
745
+ if overwrite_input:
746
+ if axis is None:
747
+ asorted = a.ravel()
748
+ asorted.sort(fill_value=fill_value)
749
+ else:
750
+ a.sort(axis=axis, fill_value=fill_value)
751
+ asorted = a
752
+ else:
753
+ asorted = sort(a, axis=axis, fill_value=fill_value)
754
+
755
+ if axis is None:
756
+ axis = 0
757
+ else:
758
+ axis = normalize_axis_index(axis, asorted.ndim)
759
+
760
+ if asorted.shape[axis] == 0:
761
+ # for empty axis integer indices fail so use slicing to get same result
762
+ # as median (which is mean of empty slice = nan)
763
+ indexer = [slice(None)] * asorted.ndim
764
+ indexer[axis] = slice(0, 0)
765
+ indexer = tuple(indexer)
766
+ return np.ma.mean(asorted[indexer], axis=axis, out=out)
767
+
768
+ if asorted.ndim == 1:
769
+ idx, odd = divmod(count(asorted), 2)
770
+ mid = asorted[idx + odd - 1:idx + 1]
771
+ if np.issubdtype(asorted.dtype, np.inexact) and asorted.size > 0:
772
+ # avoid inf / x = masked
773
+ s = mid.sum(out=out)
774
+ if not odd:
775
+ s = np.true_divide(s, 2., casting='safe', out=out)
776
+ s = np.lib.utils._median_nancheck(asorted, s, axis)
777
+ else:
778
+ s = mid.mean(out=out)
779
+
780
+ # if result is masked either the input contained enough
781
+ # minimum_fill_value so that it would be the median or all values
782
+ # masked
783
+ if np.ma.is_masked(s) and not np.all(asorted.mask):
784
+ return np.ma.minimum_fill_value(asorted)
785
+ return s
786
+
787
+ counts = count(asorted, axis=axis, keepdims=True)
788
+ h = counts // 2
789
+
790
+ # duplicate high if odd number of elements so mean does nothing
791
+ odd = counts % 2 == 1
792
+ l = np.where(odd, h, h-1)
793
+
794
+ lh = np.concatenate([l,h], axis=axis)
795
+
796
+ # get low and high median
797
+ low_high = np.take_along_axis(asorted, lh, axis=axis)
798
+
799
+ def replace_masked(s):
800
+ # Replace masked entries with minimum_full_value unless it all values
801
+ # are masked. This is required as the sort order of values equal or
802
+ # larger than the fill value is undefined and a valid value placed
803
+ # elsewhere, e.g. [4, --, inf].
804
+ if np.ma.is_masked(s):
805
+ rep = (~np.all(asorted.mask, axis=axis, keepdims=True)) & s.mask
806
+ s.data[rep] = np.ma.minimum_fill_value(asorted)
807
+ s.mask[rep] = False
808
+
809
+ replace_masked(low_high)
810
+
811
+ if np.issubdtype(asorted.dtype, np.inexact):
812
+ # avoid inf / x = masked
813
+ s = np.ma.sum(low_high, axis=axis, out=out)
814
+ np.true_divide(s.data, 2., casting='unsafe', out=s.data)
815
+
816
+ s = np.lib.utils._median_nancheck(asorted, s, axis)
817
+ else:
818
+ s = np.ma.mean(low_high, axis=axis, out=out)
819
+
820
+ return s
821
+
822
+
823
+ def compress_nd(x, axis=None):
824
+ """Suppress slices from multiple dimensions which contain masked values.
825
+
826
+ Parameters
827
+ ----------
828
+ x : array_like, MaskedArray
829
+ The array to operate on. If not a MaskedArray instance (or if no array
830
+ elements are masked), `x` is interpreted as a MaskedArray with `mask`
831
+ set to `nomask`.
832
+ axis : tuple of ints or int, optional
833
+ Which dimensions to suppress slices from can be configured with this
834
+ parameter.
835
+ - If axis is a tuple of ints, those are the axes to suppress slices from.
836
+ - If axis is an int, then that is the only axis to suppress slices from.
837
+ - If axis is None, all axis are selected.
838
+
839
+ Returns
840
+ -------
841
+ compress_array : ndarray
842
+ The compressed array.
843
+ """
844
+ x = asarray(x)
845
+ m = getmask(x)
846
+ # Set axis to tuple of ints
847
+ if axis is None:
848
+ axis = tuple(range(x.ndim))
849
+ else:
850
+ axis = normalize_axis_tuple(axis, x.ndim)
851
+
852
+ # Nothing is masked: return x
853
+ if m is nomask or not m.any():
854
+ return x._data
855
+ # All is masked: return empty
856
+ if m.all():
857
+ return nxarray([])
858
+ # Filter elements through boolean indexing
859
+ data = x._data
860
+ for ax in axis:
861
+ axes = tuple(list(range(ax)) + list(range(ax + 1, x.ndim)))
862
+ data = data[(slice(None),)*ax + (~m.any(axis=axes),)]
863
+ return data
864
+
865
+
866
+ def compress_rowcols(x, axis=None):
867
+ """
868
+ Suppress the rows and/or columns of a 2-D array that contain
869
+ masked values.
870
+
871
+ The suppression behavior is selected with the `axis` parameter.
872
+
873
+ - If axis is None, both rows and columns are suppressed.
874
+ - If axis is 0, only rows are suppressed.
875
+ - If axis is 1 or -1, only columns are suppressed.
876
+
877
+ Parameters
878
+ ----------
879
+ x : array_like, MaskedArray
880
+ The array to operate on. If not a MaskedArray instance (or if no array
881
+ elements are masked), `x` is interpreted as a MaskedArray with
882
+ `mask` set to `nomask`. Must be a 2D array.
883
+ axis : int, optional
884
+ Axis along which to perform the operation. Default is None.
885
+
886
+ Returns
887
+ -------
888
+ compressed_array : ndarray
889
+ The compressed array.
890
+
891
+ Examples
892
+ --------
893
+ >>> x = np.ma.array(np.arange(9).reshape(3, 3), mask=[[1, 0, 0],
894
+ ... [1, 0, 0],
895
+ ... [0, 0, 0]])
896
+ >>> x
897
+ masked_array(
898
+ data=[[--, 1, 2],
899
+ [--, 4, 5],
900
+ [6, 7, 8]],
901
+ mask=[[ True, False, False],
902
+ [ True, False, False],
903
+ [False, False, False]],
904
+ fill_value=999999)
905
+
906
+ >>> np.ma.compress_rowcols(x)
907
+ array([[7, 8]])
908
+ >>> np.ma.compress_rowcols(x, 0)
909
+ array([[6, 7, 8]])
910
+ >>> np.ma.compress_rowcols(x, 1)
911
+ array([[1, 2],
912
+ [4, 5],
913
+ [7, 8]])
914
+
915
+ """
916
+ if asarray(x).ndim != 2:
917
+ raise NotImplementedError("compress_rowcols works for 2D arrays only.")
918
+ return compress_nd(x, axis=axis)
919
+
920
+
921
+ def compress_rows(a):
922
+ """
923
+ Suppress whole rows of a 2-D array that contain masked values.
924
+
925
+ This is equivalent to ``np.ma.compress_rowcols(a, 0)``, see
926
+ `compress_rowcols` for details.
927
+
928
+ See Also
929
+ --------
930
+ compress_rowcols
931
+
932
+ """
933
+ a = asarray(a)
934
+ if a.ndim != 2:
935
+ raise NotImplementedError("compress_rows works for 2D arrays only.")
936
+ return compress_rowcols(a, 0)
937
+
938
+
939
+ def compress_cols(a):
940
+ """
941
+ Suppress whole columns of a 2-D array that contain masked values.
942
+
943
+ This is equivalent to ``np.ma.compress_rowcols(a, 1)``, see
944
+ `compress_rowcols` for details.
945
+
946
+ See Also
947
+ --------
948
+ compress_rowcols
949
+
950
+ """
951
+ a = asarray(a)
952
+ if a.ndim != 2:
953
+ raise NotImplementedError("compress_cols works for 2D arrays only.")
954
+ return compress_rowcols(a, 1)
955
+
956
+
957
+ def mask_rowcols(a, axis=None):
958
+ """
959
+ Mask rows and/or columns of a 2D array that contain masked values.
960
+
961
+ Mask whole rows and/or columns of a 2D array that contain
962
+ masked values. The masking behavior is selected using the
963
+ `axis` parameter.
964
+
965
+ - If `axis` is None, rows *and* columns are masked.
966
+ - If `axis` is 0, only rows are masked.
967
+ - If `axis` is 1 or -1, only columns are masked.
968
+
969
+ Parameters
970
+ ----------
971
+ a : array_like, MaskedArray
972
+ The array to mask. If not a MaskedArray instance (or if no array
973
+ elements are masked), the result is a MaskedArray with `mask` set
974
+ to `nomask` (False). Must be a 2D array.
975
+ axis : int, optional
976
+ Axis along which to perform the operation. If None, applies to a
977
+ flattened version of the array.
978
+
979
+ Returns
980
+ -------
981
+ a : MaskedArray
982
+ A modified version of the input array, masked depending on the value
983
+ of the `axis` parameter.
984
+
985
+ Raises
986
+ ------
987
+ NotImplementedError
988
+ If input array `a` is not 2D.
989
+
990
+ See Also
991
+ --------
992
+ mask_rows : Mask rows of a 2D array that contain masked values.
993
+ mask_cols : Mask cols of a 2D array that contain masked values.
994
+ masked_where : Mask where a condition is met.
995
+
996
+ Notes
997
+ -----
998
+ The input array's mask is modified by this function.
999
+
1000
+ Examples
1001
+ --------
1002
+ >>> import numpy.ma as ma
1003
+ >>> a = np.zeros((3, 3), dtype=int)
1004
+ >>> a[1, 1] = 1
1005
+ >>> a
1006
+ array([[0, 0, 0],
1007
+ [0, 1, 0],
1008
+ [0, 0, 0]])
1009
+ >>> a = ma.masked_equal(a, 1)
1010
+ >>> a
1011
+ masked_array(
1012
+ data=[[0, 0, 0],
1013
+ [0, --, 0],
1014
+ [0, 0, 0]],
1015
+ mask=[[False, False, False],
1016
+ [False, True, False],
1017
+ [False, False, False]],
1018
+ fill_value=1)
1019
+ >>> ma.mask_rowcols(a)
1020
+ masked_array(
1021
+ data=[[0, --, 0],
1022
+ [--, --, --],
1023
+ [0, --, 0]],
1024
+ mask=[[False, True, False],
1025
+ [ True, True, True],
1026
+ [False, True, False]],
1027
+ fill_value=1)
1028
+
1029
+ """
1030
+ a = array(a, subok=False)
1031
+ if a.ndim != 2:
1032
+ raise NotImplementedError("mask_rowcols works for 2D arrays only.")
1033
+ m = getmask(a)
1034
+ # Nothing is masked: return a
1035
+ if m is nomask or not m.any():
1036
+ return a
1037
+ maskedval = m.nonzero()
1038
+ a._mask = a._mask.copy()
1039
+ if not axis:
1040
+ a[np.unique(maskedval[0])] = masked
1041
+ if axis in [None, 1, -1]:
1042
+ a[:, np.unique(maskedval[1])] = masked
1043
+ return a
1044
+
1045
+
1046
+ def mask_rows(a, axis=np._NoValue):
1047
+ """
1048
+ Mask rows of a 2D array that contain masked values.
1049
+
1050
+ This function is a shortcut to ``mask_rowcols`` with `axis` equal to 0.
1051
+
1052
+ See Also
1053
+ --------
1054
+ mask_rowcols : Mask rows and/or columns of a 2D array.
1055
+ masked_where : Mask where a condition is met.
1056
+
1057
+ Examples
1058
+ --------
1059
+ >>> import numpy.ma as ma
1060
+ >>> a = np.zeros((3, 3), dtype=int)
1061
+ >>> a[1, 1] = 1
1062
+ >>> a
1063
+ array([[0, 0, 0],
1064
+ [0, 1, 0],
1065
+ [0, 0, 0]])
1066
+ >>> a = ma.masked_equal(a, 1)
1067
+ >>> a
1068
+ masked_array(
1069
+ data=[[0, 0, 0],
1070
+ [0, --, 0],
1071
+ [0, 0, 0]],
1072
+ mask=[[False, False, False],
1073
+ [False, True, False],
1074
+ [False, False, False]],
1075
+ fill_value=1)
1076
+
1077
+ >>> ma.mask_rows(a)
1078
+ masked_array(
1079
+ data=[[0, 0, 0],
1080
+ [--, --, --],
1081
+ [0, 0, 0]],
1082
+ mask=[[False, False, False],
1083
+ [ True, True, True],
1084
+ [False, False, False]],
1085
+ fill_value=1)
1086
+
1087
+ """
1088
+ if axis is not np._NoValue:
1089
+ # remove the axis argument when this deprecation expires
1090
+ # NumPy 1.18.0, 2019-11-28
1091
+ warnings.warn(
1092
+ "The axis argument has always been ignored, in future passing it "
1093
+ "will raise TypeError", DeprecationWarning, stacklevel=2)
1094
+ return mask_rowcols(a, 0)
1095
+
1096
+
1097
+ def mask_cols(a, axis=np._NoValue):
1098
+ """
1099
+ Mask columns of a 2D array that contain masked values.
1100
+
1101
+ This function is a shortcut to ``mask_rowcols`` with `axis` equal to 1.
1102
+
1103
+ See Also
1104
+ --------
1105
+ mask_rowcols : Mask rows and/or columns of a 2D array.
1106
+ masked_where : Mask where a condition is met.
1107
+
1108
+ Examples
1109
+ --------
1110
+ >>> import numpy.ma as ma
1111
+ >>> a = np.zeros((3, 3), dtype=int)
1112
+ >>> a[1, 1] = 1
1113
+ >>> a
1114
+ array([[0, 0, 0],
1115
+ [0, 1, 0],
1116
+ [0, 0, 0]])
1117
+ >>> a = ma.masked_equal(a, 1)
1118
+ >>> a
1119
+ masked_array(
1120
+ data=[[0, 0, 0],
1121
+ [0, --, 0],
1122
+ [0, 0, 0]],
1123
+ mask=[[False, False, False],
1124
+ [False, True, False],
1125
+ [False, False, False]],
1126
+ fill_value=1)
1127
+ >>> ma.mask_cols(a)
1128
+ masked_array(
1129
+ data=[[0, --, 0],
1130
+ [0, --, 0],
1131
+ [0, --, 0]],
1132
+ mask=[[False, True, False],
1133
+ [False, True, False],
1134
+ [False, True, False]],
1135
+ fill_value=1)
1136
+
1137
+ """
1138
+ if axis is not np._NoValue:
1139
+ # remove the axis argument when this deprecation expires
1140
+ # NumPy 1.18.0, 2019-11-28
1141
+ warnings.warn(
1142
+ "The axis argument has always been ignored, in future passing it "
1143
+ "will raise TypeError", DeprecationWarning, stacklevel=2)
1144
+ return mask_rowcols(a, 1)
1145
+
1146
+
1147
+ #####--------------------------------------------------------------------------
1148
+ #---- --- arraysetops ---
1149
+ #####--------------------------------------------------------------------------
1150
+
1151
+ def ediff1d(arr, to_end=None, to_begin=None):
1152
+ """
1153
+ Compute the differences between consecutive elements of an array.
1154
+
1155
+ This function is the equivalent of `numpy.ediff1d` that takes masked
1156
+ values into account, see `numpy.ediff1d` for details.
1157
+
1158
+ See Also
1159
+ --------
1160
+ numpy.ediff1d : Equivalent function for ndarrays.
1161
+
1162
+ """
1163
+ arr = ma.asanyarray(arr).flat
1164
+ ed = arr[1:] - arr[:-1]
1165
+ arrays = [ed]
1166
+ #
1167
+ if to_begin is not None:
1168
+ arrays.insert(0, to_begin)
1169
+ if to_end is not None:
1170
+ arrays.append(to_end)
1171
+ #
1172
+ if len(arrays) != 1:
1173
+ # We'll save ourselves a copy of a potentially large array in the common
1174
+ # case where neither to_begin or to_end was given.
1175
+ ed = hstack(arrays)
1176
+ #
1177
+ return ed
1178
+
1179
+
1180
+ def unique(ar1, return_index=False, return_inverse=False):
1181
+ """
1182
+ Finds the unique elements of an array.
1183
+
1184
+ Masked values are considered the same element (masked). The output array
1185
+ is always a masked array. See `numpy.unique` for more details.
1186
+
1187
+ See Also
1188
+ --------
1189
+ numpy.unique : Equivalent function for ndarrays.
1190
+
1191
+ Examples
1192
+ --------
1193
+ >>> import numpy.ma as ma
1194
+ >>> a = [1, 2, 1000, 2, 3]
1195
+ >>> mask = [0, 0, 1, 0, 0]
1196
+ >>> masked_a = ma.masked_array(a, mask)
1197
+ >>> masked_a
1198
+ masked_array(data=[1, 2, --, 2, 3],
1199
+ mask=[False, False, True, False, False],
1200
+ fill_value=999999)
1201
+ >>> ma.unique(masked_a)
1202
+ masked_array(data=[1, 2, 3, --],
1203
+ mask=[False, False, False, True],
1204
+ fill_value=999999)
1205
+ >>> ma.unique(masked_a, return_index=True)
1206
+ (masked_array(data=[1, 2, 3, --],
1207
+ mask=[False, False, False, True],
1208
+ fill_value=999999), array([0, 1, 4, 2]))
1209
+ >>> ma.unique(masked_a, return_inverse=True)
1210
+ (masked_array(data=[1, 2, 3, --],
1211
+ mask=[False, False, False, True],
1212
+ fill_value=999999), array([0, 1, 3, 1, 2]))
1213
+ >>> ma.unique(masked_a, return_index=True, return_inverse=True)
1214
+ (masked_array(data=[1, 2, 3, --],
1215
+ mask=[False, False, False, True],
1216
+ fill_value=999999), array([0, 1, 4, 2]), array([0, 1, 3, 1, 2]))
1217
+ """
1218
+ output = np.unique(ar1,
1219
+ return_index=return_index,
1220
+ return_inverse=return_inverse)
1221
+ if isinstance(output, tuple):
1222
+ output = list(output)
1223
+ output[0] = output[0].view(MaskedArray)
1224
+ output = tuple(output)
1225
+ else:
1226
+ output = output.view(MaskedArray)
1227
+ return output
1228
+
1229
+
1230
+ def intersect1d(ar1, ar2, assume_unique=False):
1231
+ """
1232
+ Returns the unique elements common to both arrays.
1233
+
1234
+ Masked values are considered equal one to the other.
1235
+ The output is always a masked array.
1236
+
1237
+ See `numpy.intersect1d` for more details.
1238
+
1239
+ See Also
1240
+ --------
1241
+ numpy.intersect1d : Equivalent function for ndarrays.
1242
+
1243
+ Examples
1244
+ --------
1245
+ >>> x = np.ma.array([1, 3, 3, 3], mask=[0, 0, 0, 1])
1246
+ >>> y = np.ma.array([3, 1, 1, 1], mask=[0, 0, 0, 1])
1247
+ >>> np.ma.intersect1d(x, y)
1248
+ masked_array(data=[1, 3, --],
1249
+ mask=[False, False, True],
1250
+ fill_value=999999)
1251
+
1252
+ """
1253
+ if assume_unique:
1254
+ aux = ma.concatenate((ar1, ar2))
1255
+ else:
1256
+ # Might be faster than unique( intersect1d( ar1, ar2 ) )?
1257
+ aux = ma.concatenate((unique(ar1), unique(ar2)))
1258
+ aux.sort()
1259
+ return aux[:-1][aux[1:] == aux[:-1]]
1260
+
1261
+
1262
+ def setxor1d(ar1, ar2, assume_unique=False):
1263
+ """
1264
+ Set exclusive-or of 1-D arrays with unique elements.
1265
+
1266
+ The output is always a masked array. See `numpy.setxor1d` for more details.
1267
+
1268
+ See Also
1269
+ --------
1270
+ numpy.setxor1d : Equivalent function for ndarrays.
1271
+
1272
+ """
1273
+ if not assume_unique:
1274
+ ar1 = unique(ar1)
1275
+ ar2 = unique(ar2)
1276
+
1277
+ aux = ma.concatenate((ar1, ar2))
1278
+ if aux.size == 0:
1279
+ return aux
1280
+ aux.sort()
1281
+ auxf = aux.filled()
1282
+ # flag = ediff1d( aux, to_end = 1, to_begin = 1 ) == 0
1283
+ flag = ma.concatenate(([True], (auxf[1:] != auxf[:-1]), [True]))
1284
+ # flag2 = ediff1d( flag ) == 0
1285
+ flag2 = (flag[1:] == flag[:-1])
1286
+ return aux[flag2]
1287
+
1288
+
1289
+ def in1d(ar1, ar2, assume_unique=False, invert=False):
1290
+ """
1291
+ Test whether each element of an array is also present in a second
1292
+ array.
1293
+
1294
+ The output is always a masked array. See `numpy.in1d` for more details.
1295
+
1296
+ We recommend using :func:`isin` instead of `in1d` for new code.
1297
+
1298
+ See Also
1299
+ --------
1300
+ isin : Version of this function that preserves the shape of ar1.
1301
+ numpy.in1d : Equivalent function for ndarrays.
1302
+
1303
+ Notes
1304
+ -----
1305
+ .. versionadded:: 1.4.0
1306
+
1307
+ """
1308
+ if not assume_unique:
1309
+ ar1, rev_idx = unique(ar1, return_inverse=True)
1310
+ ar2 = unique(ar2)
1311
+
1312
+ ar = ma.concatenate((ar1, ar2))
1313
+ # We need this to be a stable sort, so always use 'mergesort'
1314
+ # here. The values from the first array should always come before
1315
+ # the values from the second array.
1316
+ order = ar.argsort(kind='mergesort')
1317
+ sar = ar[order]
1318
+ if invert:
1319
+ bool_ar = (sar[1:] != sar[:-1])
1320
+ else:
1321
+ bool_ar = (sar[1:] == sar[:-1])
1322
+ flag = ma.concatenate((bool_ar, [invert]))
1323
+ indx = order.argsort(kind='mergesort')[:len(ar1)]
1324
+
1325
+ if assume_unique:
1326
+ return flag[indx]
1327
+ else:
1328
+ return flag[indx][rev_idx]
1329
+
1330
+
1331
+ def isin(element, test_elements, assume_unique=False, invert=False):
1332
+ """
1333
+ Calculates `element in test_elements`, broadcasting over
1334
+ `element` only.
1335
+
1336
+ The output is always a masked array of the same shape as `element`.
1337
+ See `numpy.isin` for more details.
1338
+
1339
+ See Also
1340
+ --------
1341
+ in1d : Flattened version of this function.
1342
+ numpy.isin : Equivalent function for ndarrays.
1343
+
1344
+ Notes
1345
+ -----
1346
+ .. versionadded:: 1.13.0
1347
+
1348
+ """
1349
+ element = ma.asarray(element)
1350
+ return in1d(element, test_elements, assume_unique=assume_unique,
1351
+ invert=invert).reshape(element.shape)
1352
+
1353
+
1354
+ def union1d(ar1, ar2):
1355
+ """
1356
+ Union of two arrays.
1357
+
1358
+ The output is always a masked array. See `numpy.union1d` for more details.
1359
+
1360
+ See Also
1361
+ --------
1362
+ numpy.union1d : Equivalent function for ndarrays.
1363
+
1364
+ """
1365
+ return unique(ma.concatenate((ar1, ar2), axis=None))
1366
+
1367
+
1368
+ def setdiff1d(ar1, ar2, assume_unique=False):
1369
+ """
1370
+ Set difference of 1D arrays with unique elements.
1371
+
1372
+ The output is always a masked array. See `numpy.setdiff1d` for more
1373
+ details.
1374
+
1375
+ See Also
1376
+ --------
1377
+ numpy.setdiff1d : Equivalent function for ndarrays.
1378
+
1379
+ Examples
1380
+ --------
1381
+ >>> x = np.ma.array([1, 2, 3, 4], mask=[0, 1, 0, 1])
1382
+ >>> np.ma.setdiff1d(x, [1, 2])
1383
+ masked_array(data=[3, --],
1384
+ mask=[False, True],
1385
+ fill_value=999999)
1386
+
1387
+ """
1388
+ if assume_unique:
1389
+ ar1 = ma.asarray(ar1).ravel()
1390
+ else:
1391
+ ar1 = unique(ar1)
1392
+ ar2 = unique(ar2)
1393
+ return ar1[in1d(ar1, ar2, assume_unique=True, invert=True)]
1394
+
1395
+
1396
+ ###############################################################################
1397
+ # Covariance #
1398
+ ###############################################################################
1399
+
1400
+
1401
+ def _covhelper(x, y=None, rowvar=True, allow_masked=True):
1402
+ """
1403
+ Private function for the computation of covariance and correlation
1404
+ coefficients.
1405
+
1406
+ """
1407
+ x = ma.array(x, ndmin=2, copy=True, dtype=float)
1408
+ xmask = ma.getmaskarray(x)
1409
+ # Quick exit if we can't process masked data
1410
+ if not allow_masked and xmask.any():
1411
+ raise ValueError("Cannot process masked data.")
1412
+ #
1413
+ if x.shape[0] == 1:
1414
+ rowvar = True
1415
+ # Make sure that rowvar is either 0 or 1
1416
+ rowvar = int(bool(rowvar))
1417
+ axis = 1 - rowvar
1418
+ if rowvar:
1419
+ tup = (slice(None), None)
1420
+ else:
1421
+ tup = (None, slice(None))
1422
+ #
1423
+ if y is None:
1424
+ xnotmask = np.logical_not(xmask).astype(int)
1425
+ else:
1426
+ y = array(y, copy=False, ndmin=2, dtype=float)
1427
+ ymask = ma.getmaskarray(y)
1428
+ if not allow_masked and ymask.any():
1429
+ raise ValueError("Cannot process masked data.")
1430
+ if xmask.any() or ymask.any():
1431
+ if y.shape == x.shape:
1432
+ # Define some common mask
1433
+ common_mask = np.logical_or(xmask, ymask)
1434
+ if common_mask is not nomask:
1435
+ xmask = x._mask = y._mask = ymask = common_mask
1436
+ x._sharedmask = False
1437
+ y._sharedmask = False
1438
+ x = ma.concatenate((x, y), axis)
1439
+ xnotmask = np.logical_not(np.concatenate((xmask, ymask), axis)).astype(int)
1440
+ x -= x.mean(axis=rowvar)[tup]
1441
+ return (x, xnotmask, rowvar)
1442
+
1443
+
1444
+ def cov(x, y=None, rowvar=True, bias=False, allow_masked=True, ddof=None):
1445
+ """
1446
+ Estimate the covariance matrix.
1447
+
1448
+ Except for the handling of missing data this function does the same as
1449
+ `numpy.cov`. For more details and examples, see `numpy.cov`.
1450
+
1451
+ By default, masked values are recognized as such. If `x` and `y` have the
1452
+ same shape, a common mask is allocated: if ``x[i,j]`` is masked, then
1453
+ ``y[i,j]`` will also be masked.
1454
+ Setting `allow_masked` to False will raise an exception if values are
1455
+ missing in either of the input arrays.
1456
+
1457
+ Parameters
1458
+ ----------
1459
+ x : array_like
1460
+ A 1-D or 2-D array containing multiple variables and observations.
1461
+ Each row of `x` represents a variable, and each column a single
1462
+ observation of all those variables. Also see `rowvar` below.
1463
+ y : array_like, optional
1464
+ An additional set of variables and observations. `y` has the same
1465
+ shape as `x`.
1466
+ rowvar : bool, optional
1467
+ If `rowvar` is True (default), then each row represents a
1468
+ variable, with observations in the columns. Otherwise, the relationship
1469
+ is transposed: each column represents a variable, while the rows
1470
+ contain observations.
1471
+ bias : bool, optional
1472
+ Default normalization (False) is by ``(N-1)``, where ``N`` is the
1473
+ number of observations given (unbiased estimate). If `bias` is True,
1474
+ then normalization is by ``N``. This keyword can be overridden by
1475
+ the keyword ``ddof`` in numpy versions >= 1.5.
1476
+ allow_masked : bool, optional
1477
+ If True, masked values are propagated pair-wise: if a value is masked
1478
+ in `x`, the corresponding value is masked in `y`.
1479
+ If False, raises a `ValueError` exception when some values are missing.
1480
+ ddof : {None, int}, optional
1481
+ If not ``None`` normalization is by ``(N - ddof)``, where ``N`` is
1482
+ the number of observations; this overrides the value implied by
1483
+ ``bias``. The default value is ``None``.
1484
+
1485
+ .. versionadded:: 1.5
1486
+
1487
+ Raises
1488
+ ------
1489
+ ValueError
1490
+ Raised if some values are missing and `allow_masked` is False.
1491
+
1492
+ See Also
1493
+ --------
1494
+ numpy.cov
1495
+
1496
+ """
1497
+ # Check inputs
1498
+ if ddof is not None and ddof != int(ddof):
1499
+ raise ValueError("ddof must be an integer")
1500
+ # Set up ddof
1501
+ if ddof is None:
1502
+ if bias:
1503
+ ddof = 0
1504
+ else:
1505
+ ddof = 1
1506
+
1507
+ (x, xnotmask, rowvar) = _covhelper(x, y, rowvar, allow_masked)
1508
+ if not rowvar:
1509
+ fact = np.dot(xnotmask.T, xnotmask) * 1. - ddof
1510
+ result = (dot(x.T, x.conj(), strict=False) / fact).squeeze()
1511
+ else:
1512
+ fact = np.dot(xnotmask, xnotmask.T) * 1. - ddof
1513
+ result = (dot(x, x.T.conj(), strict=False) / fact).squeeze()
1514
+ return result
1515
+
1516
+
1517
+ def corrcoef(x, y=None, rowvar=True, bias=np._NoValue, allow_masked=True,
1518
+ ddof=np._NoValue):
1519
+ """
1520
+ Return Pearson product-moment correlation coefficients.
1521
+
1522
+ Except for the handling of missing data this function does the same as
1523
+ `numpy.corrcoef`. For more details and examples, see `numpy.corrcoef`.
1524
+
1525
+ Parameters
1526
+ ----------
1527
+ x : array_like
1528
+ A 1-D or 2-D array containing multiple variables and observations.
1529
+ Each row of `x` represents a variable, and each column a single
1530
+ observation of all those variables. Also see `rowvar` below.
1531
+ y : array_like, optional
1532
+ An additional set of variables and observations. `y` has the same
1533
+ shape as `x`.
1534
+ rowvar : bool, optional
1535
+ If `rowvar` is True (default), then each row represents a
1536
+ variable, with observations in the columns. Otherwise, the relationship
1537
+ is transposed: each column represents a variable, while the rows
1538
+ contain observations.
1539
+ bias : _NoValue, optional
1540
+ Has no effect, do not use.
1541
+
1542
+ .. deprecated:: 1.10.0
1543
+ allow_masked : bool, optional
1544
+ If True, masked values are propagated pair-wise: if a value is masked
1545
+ in `x`, the corresponding value is masked in `y`.
1546
+ If False, raises an exception. Because `bias` is deprecated, this
1547
+ argument needs to be treated as keyword only to avoid a warning.
1548
+ ddof : _NoValue, optional
1549
+ Has no effect, do not use.
1550
+
1551
+ .. deprecated:: 1.10.0
1552
+
1553
+ See Also
1554
+ --------
1555
+ numpy.corrcoef : Equivalent function in top-level NumPy module.
1556
+ cov : Estimate the covariance matrix.
1557
+
1558
+ Notes
1559
+ -----
1560
+ This function accepts but discards arguments `bias` and `ddof`. This is
1561
+ for backwards compatibility with previous versions of this function. These
1562
+ arguments had no effect on the return values of the function and can be
1563
+ safely ignored in this and previous versions of numpy.
1564
+ """
1565
+ msg = 'bias and ddof have no effect and are deprecated'
1566
+ if bias is not np._NoValue or ddof is not np._NoValue:
1567
+ # 2015-03-15, 1.10
1568
+ warnings.warn(msg, DeprecationWarning, stacklevel=2)
1569
+ # Get the data
1570
+ (x, xnotmask, rowvar) = _covhelper(x, y, rowvar, allow_masked)
1571
+ # Compute the covariance matrix
1572
+ if not rowvar:
1573
+ fact = np.dot(xnotmask.T, xnotmask) * 1.
1574
+ c = (dot(x.T, x.conj(), strict=False) / fact).squeeze()
1575
+ else:
1576
+ fact = np.dot(xnotmask, xnotmask.T) * 1.
1577
+ c = (dot(x, x.T.conj(), strict=False) / fact).squeeze()
1578
+ # Check whether we have a scalar
1579
+ try:
1580
+ diag = ma.diagonal(c)
1581
+ except ValueError:
1582
+ return 1
1583
+ #
1584
+ if xnotmask.all():
1585
+ _denom = ma.sqrt(ma.multiply.outer(diag, diag))
1586
+ else:
1587
+ _denom = diagflat(diag)
1588
+ _denom._sharedmask = False # We know return is always a copy
1589
+ n = x.shape[1 - rowvar]
1590
+ if rowvar:
1591
+ for i in range(n - 1):
1592
+ for j in range(i + 1, n):
1593
+ _x = mask_cols(vstack((x[i], x[j]))).var(axis=1)
1594
+ _denom[i, j] = _denom[j, i] = ma.sqrt(ma.multiply.reduce(_x))
1595
+ else:
1596
+ for i in range(n - 1):
1597
+ for j in range(i + 1, n):
1598
+ _x = mask_cols(
1599
+ vstack((x[:, i], x[:, j]))).var(axis=1)
1600
+ _denom[i, j] = _denom[j, i] = ma.sqrt(ma.multiply.reduce(_x))
1601
+ return c / _denom
1602
+
1603
+ #####--------------------------------------------------------------------------
1604
+ #---- --- Concatenation helpers ---
1605
+ #####--------------------------------------------------------------------------
1606
+
1607
+ class MAxisConcatenator(AxisConcatenator):
1608
+ """
1609
+ Translate slice objects to concatenation along an axis.
1610
+
1611
+ For documentation on usage, see `mr_class`.
1612
+
1613
+ See Also
1614
+ --------
1615
+ mr_class
1616
+
1617
+ """
1618
+ concatenate = staticmethod(concatenate)
1619
+
1620
+ @classmethod
1621
+ def makemat(cls, arr):
1622
+ # There used to be a view as np.matrix here, but we may eventually
1623
+ # deprecate that class. In preparation, we use the unmasked version
1624
+ # to construct the matrix (with copy=False for backwards compatibility
1625
+ # with the .view)
1626
+ data = super().makemat(arr.data, copy=False)
1627
+ return array(data, mask=arr.mask)
1628
+
1629
+ def __getitem__(self, key):
1630
+ # matrix builder syntax, like 'a, b; c, d'
1631
+ if isinstance(key, str):
1632
+ raise MAError("Unavailable for masked array.")
1633
+
1634
+ return super().__getitem__(key)
1635
+
1636
+
1637
+ class mr_class(MAxisConcatenator):
1638
+ """
1639
+ Translate slice objects to concatenation along the first axis.
1640
+
1641
+ This is the masked array version of `lib.index_tricks.RClass`.
1642
+
1643
+ See Also
1644
+ --------
1645
+ lib.index_tricks.RClass
1646
+
1647
+ Examples
1648
+ --------
1649
+ >>> np.ma.mr_[np.ma.array([1,2,3]), 0, 0, np.ma.array([4,5,6])]
1650
+ masked_array(data=[1, 2, 3, ..., 4, 5, 6],
1651
+ mask=False,
1652
+ fill_value=999999)
1653
+
1654
+ """
1655
+ def __init__(self):
1656
+ MAxisConcatenator.__init__(self, 0)
1657
+
1658
+ mr_ = mr_class()
1659
+
1660
+
1661
+ #####--------------------------------------------------------------------------
1662
+ #---- Find unmasked data ---
1663
+ #####--------------------------------------------------------------------------
1664
+
1665
+ def ndenumerate(a, compressed=True):
1666
+ """
1667
+ Multidimensional index iterator.
1668
+
1669
+ Return an iterator yielding pairs of array coordinates and values,
1670
+ skipping elements that are masked. With `compressed=False`,
1671
+ `ma.masked` is yielded as the value of masked elements. This
1672
+ behavior differs from that of `numpy.ndenumerate`, which yields the
1673
+ value of the underlying data array.
1674
+
1675
+ Notes
1676
+ -----
1677
+ .. versionadded:: 1.23.0
1678
+
1679
+ Parameters
1680
+ ----------
1681
+ a : array_like
1682
+ An array with (possibly) masked elements.
1683
+ compressed : bool, optional
1684
+ If True (default), masked elements are skipped.
1685
+
1686
+ See Also
1687
+ --------
1688
+ numpy.ndenumerate : Equivalent function ignoring any mask.
1689
+
1690
+ Examples
1691
+ --------
1692
+ >>> a = np.ma.arange(9).reshape((3, 3))
1693
+ >>> a[1, 0] = np.ma.masked
1694
+ >>> a[1, 2] = np.ma.masked
1695
+ >>> a[2, 1] = np.ma.masked
1696
+ >>> a
1697
+ masked_array(
1698
+ data=[[0, 1, 2],
1699
+ [--, 4, --],
1700
+ [6, --, 8]],
1701
+ mask=[[False, False, False],
1702
+ [ True, False, True],
1703
+ [False, True, False]],
1704
+ fill_value=999999)
1705
+ >>> for index, x in np.ma.ndenumerate(a):
1706
+ ... print(index, x)
1707
+ (0, 0) 0
1708
+ (0, 1) 1
1709
+ (0, 2) 2
1710
+ (1, 1) 4
1711
+ (2, 0) 6
1712
+ (2, 2) 8
1713
+
1714
+ >>> for index, x in np.ma.ndenumerate(a, compressed=False):
1715
+ ... print(index, x)
1716
+ (0, 0) 0
1717
+ (0, 1) 1
1718
+ (0, 2) 2
1719
+ (1, 0) --
1720
+ (1, 1) 4
1721
+ (1, 2) --
1722
+ (2, 0) 6
1723
+ (2, 1) --
1724
+ (2, 2) 8
1725
+ """
1726
+ for it, mask in zip(np.ndenumerate(a), getmaskarray(a).flat):
1727
+ if not mask:
1728
+ yield it
1729
+ elif not compressed:
1730
+ yield it[0], masked
1731
+
1732
+
1733
+ def flatnotmasked_edges(a):
1734
+ """
1735
+ Find the indices of the first and last unmasked values.
1736
+
1737
+ Expects a 1-D `MaskedArray`, returns None if all values are masked.
1738
+
1739
+ Parameters
1740
+ ----------
1741
+ a : array_like
1742
+ Input 1-D `MaskedArray`
1743
+
1744
+ Returns
1745
+ -------
1746
+ edges : ndarray or None
1747
+ The indices of first and last non-masked value in the array.
1748
+ Returns None if all values are masked.
1749
+
1750
+ See Also
1751
+ --------
1752
+ flatnotmasked_contiguous, notmasked_contiguous, notmasked_edges
1753
+ clump_masked, clump_unmasked
1754
+
1755
+ Notes
1756
+ -----
1757
+ Only accepts 1-D arrays.
1758
+
1759
+ Examples
1760
+ --------
1761
+ >>> a = np.ma.arange(10)
1762
+ >>> np.ma.flatnotmasked_edges(a)
1763
+ array([0, 9])
1764
+
1765
+ >>> mask = (a < 3) | (a > 8) | (a == 5)
1766
+ >>> a[mask] = np.ma.masked
1767
+ >>> np.array(a[~a.mask])
1768
+ array([3, 4, 6, 7, 8])
1769
+
1770
+ >>> np.ma.flatnotmasked_edges(a)
1771
+ array([3, 8])
1772
+
1773
+ >>> a[:] = np.ma.masked
1774
+ >>> print(np.ma.flatnotmasked_edges(a))
1775
+ None
1776
+
1777
+ """
1778
+ m = getmask(a)
1779
+ if m is nomask or not np.any(m):
1780
+ return np.array([0, a.size - 1])
1781
+ unmasked = np.flatnonzero(~m)
1782
+ if len(unmasked) > 0:
1783
+ return unmasked[[0, -1]]
1784
+ else:
1785
+ return None
1786
+
1787
+
1788
+ def notmasked_edges(a, axis=None):
1789
+ """
1790
+ Find the indices of the first and last unmasked values along an axis.
1791
+
1792
+ If all values are masked, return None. Otherwise, return a list
1793
+ of two tuples, corresponding to the indices of the first and last
1794
+ unmasked values respectively.
1795
+
1796
+ Parameters
1797
+ ----------
1798
+ a : array_like
1799
+ The input array.
1800
+ axis : int, optional
1801
+ Axis along which to perform the operation.
1802
+ If None (default), applies to a flattened version of the array.
1803
+
1804
+ Returns
1805
+ -------
1806
+ edges : ndarray or list
1807
+ An array of start and end indexes if there are any masked data in
1808
+ the array. If there are no masked data in the array, `edges` is a
1809
+ list of the first and last index.
1810
+
1811
+ See Also
1812
+ --------
1813
+ flatnotmasked_contiguous, flatnotmasked_edges, notmasked_contiguous
1814
+ clump_masked, clump_unmasked
1815
+
1816
+ Examples
1817
+ --------
1818
+ >>> a = np.arange(9).reshape((3, 3))
1819
+ >>> m = np.zeros_like(a)
1820
+ >>> m[1:, 1:] = 1
1821
+
1822
+ >>> am = np.ma.array(a, mask=m)
1823
+ >>> np.array(am[~am.mask])
1824
+ array([0, 1, 2, 3, 6])
1825
+
1826
+ >>> np.ma.notmasked_edges(am)
1827
+ array([0, 6])
1828
+
1829
+ """
1830
+ a = asarray(a)
1831
+ if axis is None or a.ndim == 1:
1832
+ return flatnotmasked_edges(a)
1833
+ m = getmaskarray(a)
1834
+ idx = array(np.indices(a.shape), mask=np.asarray([m] * a.ndim))
1835
+ return [tuple([idx[i].min(axis).compressed() for i in range(a.ndim)]),
1836
+ tuple([idx[i].max(axis).compressed() for i in range(a.ndim)]), ]
1837
+
1838
+
1839
+ def flatnotmasked_contiguous(a):
1840
+ """
1841
+ Find contiguous unmasked data in a masked array.
1842
+
1843
+ Parameters
1844
+ ----------
1845
+ a : array_like
1846
+ The input array.
1847
+
1848
+ Returns
1849
+ -------
1850
+ slice_list : list
1851
+ A sorted sequence of `slice` objects (start index, end index).
1852
+
1853
+ .. versionchanged:: 1.15.0
1854
+ Now returns an empty list instead of None for a fully masked array
1855
+
1856
+ See Also
1857
+ --------
1858
+ flatnotmasked_edges, notmasked_contiguous, notmasked_edges
1859
+ clump_masked, clump_unmasked
1860
+
1861
+ Notes
1862
+ -----
1863
+ Only accepts 2-D arrays at most.
1864
+
1865
+ Examples
1866
+ --------
1867
+ >>> a = np.ma.arange(10)
1868
+ >>> np.ma.flatnotmasked_contiguous(a)
1869
+ [slice(0, 10, None)]
1870
+
1871
+ >>> mask = (a < 3) | (a > 8) | (a == 5)
1872
+ >>> a[mask] = np.ma.masked
1873
+ >>> np.array(a[~a.mask])
1874
+ array([3, 4, 6, 7, 8])
1875
+
1876
+ >>> np.ma.flatnotmasked_contiguous(a)
1877
+ [slice(3, 5, None), slice(6, 9, None)]
1878
+ >>> a[:] = np.ma.masked
1879
+ >>> np.ma.flatnotmasked_contiguous(a)
1880
+ []
1881
+
1882
+ """
1883
+ m = getmask(a)
1884
+ if m is nomask:
1885
+ return [slice(0, a.size)]
1886
+ i = 0
1887
+ result = []
1888
+ for (k, g) in itertools.groupby(m.ravel()):
1889
+ n = len(list(g))
1890
+ if not k:
1891
+ result.append(slice(i, i + n))
1892
+ i += n
1893
+ return result
1894
+
1895
+
1896
+ def notmasked_contiguous(a, axis=None):
1897
+ """
1898
+ Find contiguous unmasked data in a masked array along the given axis.
1899
+
1900
+ Parameters
1901
+ ----------
1902
+ a : array_like
1903
+ The input array.
1904
+ axis : int, optional
1905
+ Axis along which to perform the operation.
1906
+ If None (default), applies to a flattened version of the array, and this
1907
+ is the same as `flatnotmasked_contiguous`.
1908
+
1909
+ Returns
1910
+ -------
1911
+ endpoints : list
1912
+ A list of slices (start and end indexes) of unmasked indexes
1913
+ in the array.
1914
+
1915
+ If the input is 2d and axis is specified, the result is a list of lists.
1916
+
1917
+ See Also
1918
+ --------
1919
+ flatnotmasked_edges, flatnotmasked_contiguous, notmasked_edges
1920
+ clump_masked, clump_unmasked
1921
+
1922
+ Notes
1923
+ -----
1924
+ Only accepts 2-D arrays at most.
1925
+
1926
+ Examples
1927
+ --------
1928
+ >>> a = np.arange(12).reshape((3, 4))
1929
+ >>> mask = np.zeros_like(a)
1930
+ >>> mask[1:, :-1] = 1; mask[0, 1] = 1; mask[-1, 0] = 0
1931
+ >>> ma = np.ma.array(a, mask=mask)
1932
+ >>> ma
1933
+ masked_array(
1934
+ data=[[0, --, 2, 3],
1935
+ [--, --, --, 7],
1936
+ [8, --, --, 11]],
1937
+ mask=[[False, True, False, False],
1938
+ [ True, True, True, False],
1939
+ [False, True, True, False]],
1940
+ fill_value=999999)
1941
+ >>> np.array(ma[~ma.mask])
1942
+ array([ 0, 2, 3, 7, 8, 11])
1943
+
1944
+ >>> np.ma.notmasked_contiguous(ma)
1945
+ [slice(0, 1, None), slice(2, 4, None), slice(7, 9, None), slice(11, 12, None)]
1946
+
1947
+ >>> np.ma.notmasked_contiguous(ma, axis=0)
1948
+ [[slice(0, 1, None), slice(2, 3, None)], [], [slice(0, 1, None)], [slice(0, 3, None)]]
1949
+
1950
+ >>> np.ma.notmasked_contiguous(ma, axis=1)
1951
+ [[slice(0, 1, None), slice(2, 4, None)], [slice(3, 4, None)], [slice(0, 1, None), slice(3, 4, None)]]
1952
+
1953
+ """
1954
+ a = asarray(a)
1955
+ nd = a.ndim
1956
+ if nd > 2:
1957
+ raise NotImplementedError("Currently limited to at most 2D array.")
1958
+ if axis is None or nd == 1:
1959
+ return flatnotmasked_contiguous(a)
1960
+ #
1961
+ result = []
1962
+ #
1963
+ other = (axis + 1) % 2
1964
+ idx = [0, 0]
1965
+ idx[axis] = slice(None, None)
1966
+ #
1967
+ for i in range(a.shape[other]):
1968
+ idx[other] = i
1969
+ result.append(flatnotmasked_contiguous(a[tuple(idx)]))
1970
+ return result
1971
+
1972
+
1973
+ def _ezclump(mask):
1974
+ """
1975
+ Finds the clumps (groups of data with the same values) for a 1D bool array.
1976
+
1977
+ Returns a series of slices.
1978
+ """
1979
+ if mask.ndim > 1:
1980
+ mask = mask.ravel()
1981
+ idx = (mask[1:] ^ mask[:-1]).nonzero()
1982
+ idx = idx[0] + 1
1983
+
1984
+ if mask[0]:
1985
+ if len(idx) == 0:
1986
+ return [slice(0, mask.size)]
1987
+
1988
+ r = [slice(0, idx[0])]
1989
+ r.extend((slice(left, right)
1990
+ for left, right in zip(idx[1:-1:2], idx[2::2])))
1991
+ else:
1992
+ if len(idx) == 0:
1993
+ return []
1994
+
1995
+ r = [slice(left, right) for left, right in zip(idx[:-1:2], idx[1::2])]
1996
+
1997
+ if mask[-1]:
1998
+ r.append(slice(idx[-1], mask.size))
1999
+ return r
2000
+
2001
+
2002
+ def clump_unmasked(a):
2003
+ """
2004
+ Return list of slices corresponding to the unmasked clumps of a 1-D array.
2005
+ (A "clump" is defined as a contiguous region of the array).
2006
+
2007
+ Parameters
2008
+ ----------
2009
+ a : ndarray
2010
+ A one-dimensional masked array.
2011
+
2012
+ Returns
2013
+ -------
2014
+ slices : list of slice
2015
+ The list of slices, one for each continuous region of unmasked
2016
+ elements in `a`.
2017
+
2018
+ Notes
2019
+ -----
2020
+ .. versionadded:: 1.4.0
2021
+
2022
+ See Also
2023
+ --------
2024
+ flatnotmasked_edges, flatnotmasked_contiguous, notmasked_edges
2025
+ notmasked_contiguous, clump_masked
2026
+
2027
+ Examples
2028
+ --------
2029
+ >>> a = np.ma.masked_array(np.arange(10))
2030
+ >>> a[[0, 1, 2, 6, 8, 9]] = np.ma.masked
2031
+ >>> np.ma.clump_unmasked(a)
2032
+ [slice(3, 6, None), slice(7, 8, None)]
2033
+
2034
+ """
2035
+ mask = getattr(a, '_mask', nomask)
2036
+ if mask is nomask:
2037
+ return [slice(0, a.size)]
2038
+ return _ezclump(~mask)
2039
+
2040
+
2041
+ def clump_masked(a):
2042
+ """
2043
+ Returns a list of slices corresponding to the masked clumps of a 1-D array.
2044
+ (A "clump" is defined as a contiguous region of the array).
2045
+
2046
+ Parameters
2047
+ ----------
2048
+ a : ndarray
2049
+ A one-dimensional masked array.
2050
+
2051
+ Returns
2052
+ -------
2053
+ slices : list of slice
2054
+ The list of slices, one for each continuous region of masked elements
2055
+ in `a`.
2056
+
2057
+ Notes
2058
+ -----
2059
+ .. versionadded:: 1.4.0
2060
+
2061
+ See Also
2062
+ --------
2063
+ flatnotmasked_edges, flatnotmasked_contiguous, notmasked_edges
2064
+ notmasked_contiguous, clump_unmasked
2065
+
2066
+ Examples
2067
+ --------
2068
+ >>> a = np.ma.masked_array(np.arange(10))
2069
+ >>> a[[0, 1, 2, 6, 8, 9]] = np.ma.masked
2070
+ >>> np.ma.clump_masked(a)
2071
+ [slice(0, 3, None), slice(6, 7, None), slice(8, 10, None)]
2072
+
2073
+ """
2074
+ mask = ma.getmask(a)
2075
+ if mask is nomask:
2076
+ return []
2077
+ return _ezclump(mask)
2078
+
2079
+
2080
+ ###############################################################################
2081
+ # Polynomial fit #
2082
+ ###############################################################################
2083
+
2084
+
2085
+ def vander(x, n=None):
2086
+ """
2087
+ Masked values in the input array result in rows of zeros.
2088
+
2089
+ """
2090
+ _vander = np.vander(x, n)
2091
+ m = getmask(x)
2092
+ if m is not nomask:
2093
+ _vander[m] = 0
2094
+ return _vander
2095
+
2096
+ vander.__doc__ = ma.doc_note(np.vander.__doc__, vander.__doc__)
2097
+
2098
+
2099
+ def polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False):
2100
+ """
2101
+ Any masked values in x is propagated in y, and vice-versa.
2102
+
2103
+ """
2104
+ x = asarray(x)
2105
+ y = asarray(y)
2106
+
2107
+ m = getmask(x)
2108
+ if y.ndim == 1:
2109
+ m = mask_or(m, getmask(y))
2110
+ elif y.ndim == 2:
2111
+ my = getmask(mask_rows(y))
2112
+ if my is not nomask:
2113
+ m = mask_or(m, my[:, 0])
2114
+ else:
2115
+ raise TypeError("Expected a 1D or 2D array for y!")
2116
+
2117
+ if w is not None:
2118
+ w = asarray(w)
2119
+ if w.ndim != 1:
2120
+ raise TypeError("expected a 1-d array for weights")
2121
+ if w.shape[0] != y.shape[0]:
2122
+ raise TypeError("expected w and y to have the same length")
2123
+ m = mask_or(m, getmask(w))
2124
+
2125
+ if m is not nomask:
2126
+ not_m = ~m
2127
+ if w is not None:
2128
+ w = w[not_m]
2129
+ return np.polyfit(x[not_m], y[not_m], deg, rcond, full, w, cov)
2130
+ else:
2131
+ return np.polyfit(x, y, deg, rcond, full, w, cov)
2132
+
2133
+ polyfit.__doc__ = ma.doc_note(np.polyfit.__doc__, polyfit.__doc__)
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/extras.pyi ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any
2
+ from numpy.lib.index_tricks import AxisConcatenator
3
+
4
+ from numpy.ma.core import (
5
+ dot as dot,
6
+ mask_rowcols as mask_rowcols,
7
+ )
8
+
9
+ __all__: list[str]
10
+
11
+ def count_masked(arr, axis=...): ...
12
+ def masked_all(shape, dtype = ...): ...
13
+ def masked_all_like(arr): ...
14
+
15
+ class _fromnxfunction:
16
+ __name__: Any
17
+ __doc__: Any
18
+ def __init__(self, funcname): ...
19
+ def getdoc(self): ...
20
+ def __call__(self, *args, **params): ...
21
+
22
+ class _fromnxfunction_single(_fromnxfunction):
23
+ def __call__(self, x, *args, **params): ...
24
+
25
+ class _fromnxfunction_seq(_fromnxfunction):
26
+ def __call__(self, x, *args, **params): ...
27
+
28
+ class _fromnxfunction_allargs(_fromnxfunction):
29
+ def __call__(self, *args, **params): ...
30
+
31
+ atleast_1d: _fromnxfunction_allargs
32
+ atleast_2d: _fromnxfunction_allargs
33
+ atleast_3d: _fromnxfunction_allargs
34
+
35
+ vstack: _fromnxfunction_seq
36
+ row_stack: _fromnxfunction_seq
37
+ hstack: _fromnxfunction_seq
38
+ column_stack: _fromnxfunction_seq
39
+ dstack: _fromnxfunction_seq
40
+ stack: _fromnxfunction_seq
41
+
42
+ hsplit: _fromnxfunction_single
43
+ diagflat: _fromnxfunction_single
44
+
45
+ def apply_along_axis(func1d, axis, arr, *args, **kwargs): ...
46
+ def apply_over_axes(func, a, axes): ...
47
+ def average(a, axis=..., weights=..., returned=..., keepdims=...): ...
48
+ def median(a, axis=..., out=..., overwrite_input=..., keepdims=...): ...
49
+ def compress_nd(x, axis=...): ...
50
+ def compress_rowcols(x, axis=...): ...
51
+ def compress_rows(a): ...
52
+ def compress_cols(a): ...
53
+ def mask_rows(a, axis = ...): ...
54
+ def mask_cols(a, axis = ...): ...
55
+ def ediff1d(arr, to_end=..., to_begin=...): ...
56
+ def unique(ar1, return_index=..., return_inverse=...): ...
57
+ def intersect1d(ar1, ar2, assume_unique=...): ...
58
+ def setxor1d(ar1, ar2, assume_unique=...): ...
59
+ def in1d(ar1, ar2, assume_unique=..., invert=...): ...
60
+ def isin(element, test_elements, assume_unique=..., invert=...): ...
61
+ def union1d(ar1, ar2): ...
62
+ def setdiff1d(ar1, ar2, assume_unique=...): ...
63
+ def cov(x, y=..., rowvar=..., bias=..., allow_masked=..., ddof=...): ...
64
+ def corrcoef(x, y=..., rowvar=..., bias = ..., allow_masked=..., ddof = ...): ...
65
+
66
+ class MAxisConcatenator(AxisConcatenator):
67
+ concatenate: Any
68
+ @classmethod
69
+ def makemat(cls, arr): ...
70
+ def __getitem__(self, key): ...
71
+
72
+ class mr_class(MAxisConcatenator):
73
+ def __init__(self): ...
74
+
75
+ mr_: mr_class
76
+
77
+ def ndenumerate(a, compressed=...): ...
78
+ def flatnotmasked_edges(a): ...
79
+ def notmasked_edges(a, axis=...): ...
80
+ def flatnotmasked_contiguous(a): ...
81
+ def notmasked_contiguous(a, axis=...): ...
82
+ def clump_unmasked(a): ...
83
+ def clump_masked(a): ...
84
+ def vander(x, n=...): ...
85
+ def polyfit(x, y, deg, rcond=..., full=..., w=..., cov=...): ...
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/mrecords.py ADDED
@@ -0,0 +1,783 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """:mod:`numpy.ma..mrecords`
2
+
3
+ Defines the equivalent of :class:`numpy.recarrays` for masked arrays,
4
+ where fields can be accessed as attributes.
5
+ Note that :class:`numpy.ma.MaskedArray` already supports structured datatypes
6
+ and the masking of individual fields.
7
+
8
+ .. moduleauthor:: Pierre Gerard-Marchant
9
+
10
+ """
11
+ # We should make sure that no field is called '_mask','mask','_fieldmask',
12
+ # or whatever restricted keywords. An idea would be to no bother in the
13
+ # first place, and then rename the invalid fields with a trailing
14
+ # underscore. Maybe we could just overload the parser function ?
15
+
16
+ from numpy.ma import (
17
+ MAError, MaskedArray, masked, nomask, masked_array, getdata,
18
+ getmaskarray, filled
19
+ )
20
+ import numpy.ma as ma
21
+ import warnings
22
+
23
+ import numpy as np
24
+ from numpy import (
25
+ bool_, dtype, ndarray, recarray, array as narray
26
+ )
27
+ from numpy.core.records import (
28
+ fromarrays as recfromarrays, fromrecords as recfromrecords
29
+ )
30
+
31
+ _byteorderconv = np.core.records._byteorderconv
32
+
33
+
34
+ _check_fill_value = ma.core._check_fill_value
35
+
36
+
37
+ __all__ = [
38
+ 'MaskedRecords', 'mrecarray', 'fromarrays', 'fromrecords',
39
+ 'fromtextfile', 'addfield',
40
+ ]
41
+
42
+ reserved_fields = ['_data', '_mask', '_fieldmask', 'dtype']
43
+
44
+
45
+ def _checknames(descr, names=None):
46
+ """
47
+ Checks that field names ``descr`` are not reserved keywords.
48
+
49
+ If this is the case, a default 'f%i' is substituted. If the argument
50
+ `names` is not None, updates the field names to valid names.
51
+
52
+ """
53
+ ndescr = len(descr)
54
+ default_names = ['f%i' % i for i in range(ndescr)]
55
+ if names is None:
56
+ new_names = default_names
57
+ else:
58
+ if isinstance(names, (tuple, list)):
59
+ new_names = names
60
+ elif isinstance(names, str):
61
+ new_names = names.split(',')
62
+ else:
63
+ raise NameError(f'illegal input names {names!r}')
64
+ nnames = len(new_names)
65
+ if nnames < ndescr:
66
+ new_names += default_names[nnames:]
67
+ ndescr = []
68
+ for (n, d, t) in zip(new_names, default_names, descr.descr):
69
+ if n in reserved_fields:
70
+ if t[0] in reserved_fields:
71
+ ndescr.append((d, t[1]))
72
+ else:
73
+ ndescr.append(t)
74
+ else:
75
+ ndescr.append((n, t[1]))
76
+ return np.dtype(ndescr)
77
+
78
+
79
+ def _get_fieldmask(self):
80
+ mdescr = [(n, '|b1') for n in self.dtype.names]
81
+ fdmask = np.empty(self.shape, dtype=mdescr)
82
+ fdmask.flat = tuple([False] * len(mdescr))
83
+ return fdmask
84
+
85
+
86
+ class MaskedRecords(MaskedArray):
87
+ """
88
+
89
+ Attributes
90
+ ----------
91
+ _data : recarray
92
+ Underlying data, as a record array.
93
+ _mask : boolean array
94
+ Mask of the records. A record is masked when all its fields are
95
+ masked.
96
+ _fieldmask : boolean recarray
97
+ Record array of booleans, setting the mask of each individual field
98
+ of each record.
99
+ _fill_value : record
100
+ Filling values for each field.
101
+
102
+ """
103
+
104
+ def __new__(cls, shape, dtype=None, buf=None, offset=0, strides=None,
105
+ formats=None, names=None, titles=None,
106
+ byteorder=None, aligned=False,
107
+ mask=nomask, hard_mask=False, fill_value=None, keep_mask=True,
108
+ copy=False,
109
+ **options):
110
+
111
+ self = recarray.__new__(cls, shape, dtype=dtype, buf=buf, offset=offset,
112
+ strides=strides, formats=formats, names=names,
113
+ titles=titles, byteorder=byteorder,
114
+ aligned=aligned,)
115
+
116
+ mdtype = ma.make_mask_descr(self.dtype)
117
+ if mask is nomask or not np.size(mask):
118
+ if not keep_mask:
119
+ self._mask = tuple([False] * len(mdtype))
120
+ else:
121
+ mask = np.array(mask, copy=copy)
122
+ if mask.shape != self.shape:
123
+ (nd, nm) = (self.size, mask.size)
124
+ if nm == 1:
125
+ mask = np.resize(mask, self.shape)
126
+ elif nm == nd:
127
+ mask = np.reshape(mask, self.shape)
128
+ else:
129
+ msg = "Mask and data not compatible: data size is %i, " + \
130
+ "mask size is %i."
131
+ raise MAError(msg % (nd, nm))
132
+ if not keep_mask:
133
+ self.__setmask__(mask)
134
+ self._sharedmask = True
135
+ else:
136
+ if mask.dtype == mdtype:
137
+ _mask = mask
138
+ else:
139
+ _mask = np.array([tuple([m] * len(mdtype)) for m in mask],
140
+ dtype=mdtype)
141
+ self._mask = _mask
142
+ return self
143
+
144
+ def __array_finalize__(self, obj):
145
+ # Make sure we have a _fieldmask by default
146
+ _mask = getattr(obj, '_mask', None)
147
+ if _mask is None:
148
+ objmask = getattr(obj, '_mask', nomask)
149
+ _dtype = ndarray.__getattribute__(self, 'dtype')
150
+ if objmask is nomask:
151
+ _mask = ma.make_mask_none(self.shape, dtype=_dtype)
152
+ else:
153
+ mdescr = ma.make_mask_descr(_dtype)
154
+ _mask = narray([tuple([m] * len(mdescr)) for m in objmask],
155
+ dtype=mdescr).view(recarray)
156
+ # Update some of the attributes
157
+ _dict = self.__dict__
158
+ _dict.update(_mask=_mask)
159
+ self._update_from(obj)
160
+ if _dict['_baseclass'] == ndarray:
161
+ _dict['_baseclass'] = recarray
162
+ return
163
+
164
+ @property
165
+ def _data(self):
166
+ """
167
+ Returns the data as a recarray.
168
+
169
+ """
170
+ return ndarray.view(self, recarray)
171
+
172
+ @property
173
+ def _fieldmask(self):
174
+ """
175
+ Alias to mask.
176
+
177
+ """
178
+ return self._mask
179
+
180
+ def __len__(self):
181
+ """
182
+ Returns the length
183
+
184
+ """
185
+ # We have more than one record
186
+ if self.ndim:
187
+ return len(self._data)
188
+ # We have only one record: return the nb of fields
189
+ return len(self.dtype)
190
+
191
+ def __getattribute__(self, attr):
192
+ try:
193
+ return object.__getattribute__(self, attr)
194
+ except AttributeError:
195
+ # attr must be a fieldname
196
+ pass
197
+ fielddict = ndarray.__getattribute__(self, 'dtype').fields
198
+ try:
199
+ res = fielddict[attr][:2]
200
+ except (TypeError, KeyError) as e:
201
+ raise AttributeError(
202
+ f'record array has no attribute {attr}') from e
203
+ # So far, so good
204
+ _localdict = ndarray.__getattribute__(self, '__dict__')
205
+ _data = ndarray.view(self, _localdict['_baseclass'])
206
+ obj = _data.getfield(*res)
207
+ if obj.dtype.names is not None:
208
+ raise NotImplementedError("MaskedRecords is currently limited to"
209
+ "simple records.")
210
+ # Get some special attributes
211
+ # Reset the object's mask
212
+ hasmasked = False
213
+ _mask = _localdict.get('_mask', None)
214
+ if _mask is not None:
215
+ try:
216
+ _mask = _mask[attr]
217
+ except IndexError:
218
+ # Couldn't find a mask: use the default (nomask)
219
+ pass
220
+ tp_len = len(_mask.dtype)
221
+ hasmasked = _mask.view((bool, ((tp_len,) if tp_len else ()))).any()
222
+ if (obj.shape or hasmasked):
223
+ obj = obj.view(MaskedArray)
224
+ obj._baseclass = ndarray
225
+ obj._isfield = True
226
+ obj._mask = _mask
227
+ # Reset the field values
228
+ _fill_value = _localdict.get('_fill_value', None)
229
+ if _fill_value is not None:
230
+ try:
231
+ obj._fill_value = _fill_value[attr]
232
+ except ValueError:
233
+ obj._fill_value = None
234
+ else:
235
+ obj = obj.item()
236
+ return obj
237
+
238
+ def __setattr__(self, attr, val):
239
+ """
240
+ Sets the attribute attr to the value val.
241
+
242
+ """
243
+ # Should we call __setmask__ first ?
244
+ if attr in ['mask', 'fieldmask']:
245
+ self.__setmask__(val)
246
+ return
247
+ # Create a shortcut (so that we don't have to call getattr all the time)
248
+ _localdict = object.__getattribute__(self, '__dict__')
249
+ # Check whether we're creating a new field
250
+ newattr = attr not in _localdict
251
+ try:
252
+ # Is attr a generic attribute ?
253
+ ret = object.__setattr__(self, attr, val)
254
+ except Exception:
255
+ # Not a generic attribute: exit if it's not a valid field
256
+ fielddict = ndarray.__getattribute__(self, 'dtype').fields or {}
257
+ optinfo = ndarray.__getattribute__(self, '_optinfo') or {}
258
+ if not (attr in fielddict or attr in optinfo):
259
+ raise
260
+ else:
261
+ # Get the list of names
262
+ fielddict = ndarray.__getattribute__(self, 'dtype').fields or {}
263
+ # Check the attribute
264
+ if attr not in fielddict:
265
+ return ret
266
+ if newattr:
267
+ # We just added this one or this setattr worked on an
268
+ # internal attribute.
269
+ try:
270
+ object.__delattr__(self, attr)
271
+ except Exception:
272
+ return ret
273
+ # Let's try to set the field
274
+ try:
275
+ res = fielddict[attr][:2]
276
+ except (TypeError, KeyError) as e:
277
+ raise AttributeError(
278
+ f'record array has no attribute {attr}') from e
279
+
280
+ if val is masked:
281
+ _fill_value = _localdict['_fill_value']
282
+ if _fill_value is not None:
283
+ dval = _localdict['_fill_value'][attr]
284
+ else:
285
+ dval = val
286
+ mval = True
287
+ else:
288
+ dval = filled(val)
289
+ mval = getmaskarray(val)
290
+ obj = ndarray.__getattribute__(self, '_data').setfield(dval, *res)
291
+ _localdict['_mask'].__setitem__(attr, mval)
292
+ return obj
293
+
294
+ def __getitem__(self, indx):
295
+ """
296
+ Returns all the fields sharing the same fieldname base.
297
+
298
+ The fieldname base is either `_data` or `_mask`.
299
+
300
+ """
301
+ _localdict = self.__dict__
302
+ _mask = ndarray.__getattribute__(self, '_mask')
303
+ _data = ndarray.view(self, _localdict['_baseclass'])
304
+ # We want a field
305
+ if isinstance(indx, str):
306
+ # Make sure _sharedmask is True to propagate back to _fieldmask
307
+ # Don't use _set_mask, there are some copies being made that
308
+ # break propagation Don't force the mask to nomask, that wreaks
309
+ # easy masking
310
+ obj = _data[indx].view(MaskedArray)
311
+ obj._mask = _mask[indx]
312
+ obj._sharedmask = True
313
+ fval = _localdict['_fill_value']
314
+ if fval is not None:
315
+ obj._fill_value = fval[indx]
316
+ # Force to masked if the mask is True
317
+ if not obj.ndim and obj._mask:
318
+ return masked
319
+ return obj
320
+ # We want some elements.
321
+ # First, the data.
322
+ obj = np.array(_data[indx], copy=False).view(mrecarray)
323
+ obj._mask = np.array(_mask[indx], copy=False).view(recarray)
324
+ return obj
325
+
326
+ def __setitem__(self, indx, value):
327
+ """
328
+ Sets the given record to value.
329
+
330
+ """
331
+ MaskedArray.__setitem__(self, indx, value)
332
+ if isinstance(indx, str):
333
+ self._mask[indx] = ma.getmaskarray(value)
334
+
335
+ def __str__(self):
336
+ """
337
+ Calculates the string representation.
338
+
339
+ """
340
+ if self.size > 1:
341
+ mstr = [f"({','.join([str(i) for i in s])})"
342
+ for s in zip(*[getattr(self, f) for f in self.dtype.names])]
343
+ return f"[{', '.join(mstr)}]"
344
+ else:
345
+ mstr = [f"{','.join([str(i) for i in s])}"
346
+ for s in zip([getattr(self, f) for f in self.dtype.names])]
347
+ return f"({', '.join(mstr)})"
348
+
349
+ def __repr__(self):
350
+ """
351
+ Calculates the repr representation.
352
+
353
+ """
354
+ _names = self.dtype.names
355
+ fmt = "%%%is : %%s" % (max([len(n) for n in _names]) + 4,)
356
+ reprstr = [fmt % (f, getattr(self, f)) for f in self.dtype.names]
357
+ reprstr.insert(0, 'masked_records(')
358
+ reprstr.extend([fmt % (' fill_value', self.fill_value),
359
+ ' )'])
360
+ return str("\n".join(reprstr))
361
+
362
+ def view(self, dtype=None, type=None):
363
+ """
364
+ Returns a view of the mrecarray.
365
+
366
+ """
367
+ # OK, basic copy-paste from MaskedArray.view.
368
+ if dtype is None:
369
+ if type is None:
370
+ output = ndarray.view(self)
371
+ else:
372
+ output = ndarray.view(self, type)
373
+ # Here again.
374
+ elif type is None:
375
+ try:
376
+ if issubclass(dtype, ndarray):
377
+ output = ndarray.view(self, dtype)
378
+ else:
379
+ output = ndarray.view(self, dtype)
380
+ # OK, there's the change
381
+ except TypeError:
382
+ dtype = np.dtype(dtype)
383
+ # we need to revert to MaskedArray, but keeping the possibility
384
+ # of subclasses (eg, TimeSeriesRecords), so we'll force a type
385
+ # set to the first parent
386
+ if dtype.fields is None:
387
+ basetype = self.__class__.__bases__[0]
388
+ output = self.__array__().view(dtype, basetype)
389
+ output._update_from(self)
390
+ else:
391
+ output = ndarray.view(self, dtype)
392
+ output._fill_value = None
393
+ else:
394
+ output = ndarray.view(self, dtype, type)
395
+ # Update the mask, just like in MaskedArray.view
396
+ if (getattr(output, '_mask', nomask) is not nomask):
397
+ mdtype = ma.make_mask_descr(output.dtype)
398
+ output._mask = self._mask.view(mdtype, ndarray)
399
+ output._mask.shape = output.shape
400
+ return output
401
+
402
+ def harden_mask(self):
403
+ """
404
+ Forces the mask to hard.
405
+
406
+ """
407
+ self._hardmask = True
408
+
409
+ def soften_mask(self):
410
+ """
411
+ Forces the mask to soft
412
+
413
+ """
414
+ self._hardmask = False
415
+
416
+ def copy(self):
417
+ """
418
+ Returns a copy of the masked record.
419
+
420
+ """
421
+ copied = self._data.copy().view(type(self))
422
+ copied._mask = self._mask.copy()
423
+ return copied
424
+
425
+ def tolist(self, fill_value=None):
426
+ """
427
+ Return the data portion of the array as a list.
428
+
429
+ Data items are converted to the nearest compatible Python type.
430
+ Masked values are converted to fill_value. If fill_value is None,
431
+ the corresponding entries in the output list will be ``None``.
432
+
433
+ """
434
+ if fill_value is not None:
435
+ return self.filled(fill_value).tolist()
436
+ result = narray(self.filled().tolist(), dtype=object)
437
+ mask = narray(self._mask.tolist())
438
+ result[mask] = None
439
+ return result.tolist()
440
+
441
+ def __getstate__(self):
442
+ """Return the internal state of the masked array.
443
+
444
+ This is for pickling.
445
+
446
+ """
447
+ state = (1,
448
+ self.shape,
449
+ self.dtype,
450
+ self.flags.fnc,
451
+ self._data.tobytes(),
452
+ self._mask.tobytes(),
453
+ self._fill_value,
454
+ )
455
+ return state
456
+
457
+ def __setstate__(self, state):
458
+ """
459
+ Restore the internal state of the masked array.
460
+
461
+ This is for pickling. ``state`` is typically the output of the
462
+ ``__getstate__`` output, and is a 5-tuple:
463
+
464
+ - class name
465
+ - a tuple giving the shape of the data
466
+ - a typecode for the data
467
+ - a binary string for the data
468
+ - a binary string for the mask.
469
+
470
+ """
471
+ (ver, shp, typ, isf, raw, msk, flv) = state
472
+ ndarray.__setstate__(self, (shp, typ, isf, raw))
473
+ mdtype = dtype([(k, bool_) for (k, _) in self.dtype.descr])
474
+ self.__dict__['_mask'].__setstate__((shp, mdtype, isf, msk))
475
+ self.fill_value = flv
476
+
477
+ def __reduce__(self):
478
+ """
479
+ Return a 3-tuple for pickling a MaskedArray.
480
+
481
+ """
482
+ return (_mrreconstruct,
483
+ (self.__class__, self._baseclass, (0,), 'b',),
484
+ self.__getstate__())
485
+
486
+
487
+ def _mrreconstruct(subtype, baseclass, baseshape, basetype,):
488
+ """
489
+ Build a new MaskedArray from the information stored in a pickle.
490
+
491
+ """
492
+ _data = ndarray.__new__(baseclass, baseshape, basetype).view(subtype)
493
+ _mask = ndarray.__new__(ndarray, baseshape, 'b1')
494
+ return subtype.__new__(subtype, _data, mask=_mask, dtype=basetype,)
495
+
496
+ mrecarray = MaskedRecords
497
+
498
+
499
+ ###############################################################################
500
+ # Constructors #
501
+ ###############################################################################
502
+
503
+
504
+ def fromarrays(arraylist, dtype=None, shape=None, formats=None,
505
+ names=None, titles=None, aligned=False, byteorder=None,
506
+ fill_value=None):
507
+ """
508
+ Creates a mrecarray from a (flat) list of masked arrays.
509
+
510
+ Parameters
511
+ ----------
512
+ arraylist : sequence
513
+ A list of (masked) arrays. Each element of the sequence is first converted
514
+ to a masked array if needed. If a 2D array is passed as argument, it is
515
+ processed line by line
516
+ dtype : {None, dtype}, optional
517
+ Data type descriptor.
518
+ shape : {None, integer}, optional
519
+ Number of records. If None, shape is defined from the shape of the
520
+ first array in the list.
521
+ formats : {None, sequence}, optional
522
+ Sequence of formats for each individual field. If None, the formats will
523
+ be autodetected by inspecting the fields and selecting the highest dtype
524
+ possible.
525
+ names : {None, sequence}, optional
526
+ Sequence of the names of each field.
527
+ fill_value : {None, sequence}, optional
528
+ Sequence of data to be used as filling values.
529
+
530
+ Notes
531
+ -----
532
+ Lists of tuples should be preferred over lists of lists for faster processing.
533
+
534
+ """
535
+ datalist = [getdata(x) for x in arraylist]
536
+ masklist = [np.atleast_1d(getmaskarray(x)) for x in arraylist]
537
+ _array = recfromarrays(datalist,
538
+ dtype=dtype, shape=shape, formats=formats,
539
+ names=names, titles=titles, aligned=aligned,
540
+ byteorder=byteorder).view(mrecarray)
541
+ _array._mask.flat = list(zip(*masklist))
542
+ if fill_value is not None:
543
+ _array.fill_value = fill_value
544
+ return _array
545
+
546
+
547
+ def fromrecords(reclist, dtype=None, shape=None, formats=None, names=None,
548
+ titles=None, aligned=False, byteorder=None,
549
+ fill_value=None, mask=nomask):
550
+ """
551
+ Creates a MaskedRecords from a list of records.
552
+
553
+ Parameters
554
+ ----------
555
+ reclist : sequence
556
+ A list of records. Each element of the sequence is first converted
557
+ to a masked array if needed. If a 2D array is passed as argument, it is
558
+ processed line by line
559
+ dtype : {None, dtype}, optional
560
+ Data type descriptor.
561
+ shape : {None,int}, optional
562
+ Number of records. If None, ``shape`` is defined from the shape of the
563
+ first array in the list.
564
+ formats : {None, sequence}, optional
565
+ Sequence of formats for each individual field. If None, the formats will
566
+ be autodetected by inspecting the fields and selecting the highest dtype
567
+ possible.
568
+ names : {None, sequence}, optional
569
+ Sequence of the names of each field.
570
+ fill_value : {None, sequence}, optional
571
+ Sequence of data to be used as filling values.
572
+ mask : {nomask, sequence}, optional.
573
+ External mask to apply on the data.
574
+
575
+ Notes
576
+ -----
577
+ Lists of tuples should be preferred over lists of lists for faster processing.
578
+
579
+ """
580
+ # Grab the initial _fieldmask, if needed:
581
+ _mask = getattr(reclist, '_mask', None)
582
+ # Get the list of records.
583
+ if isinstance(reclist, ndarray):
584
+ # Make sure we don't have some hidden mask
585
+ if isinstance(reclist, MaskedArray):
586
+ reclist = reclist.filled().view(ndarray)
587
+ # Grab the initial dtype, just in case
588
+ if dtype is None:
589
+ dtype = reclist.dtype
590
+ reclist = reclist.tolist()
591
+ mrec = recfromrecords(reclist, dtype=dtype, shape=shape, formats=formats,
592
+ names=names, titles=titles,
593
+ aligned=aligned, byteorder=byteorder).view(mrecarray)
594
+ # Set the fill_value if needed
595
+ if fill_value is not None:
596
+ mrec.fill_value = fill_value
597
+ # Now, let's deal w/ the mask
598
+ if mask is not nomask:
599
+ mask = np.array(mask, copy=False)
600
+ maskrecordlength = len(mask.dtype)
601
+ if maskrecordlength:
602
+ mrec._mask.flat = mask
603
+ elif mask.ndim == 2:
604
+ mrec._mask.flat = [tuple(m) for m in mask]
605
+ else:
606
+ mrec.__setmask__(mask)
607
+ if _mask is not None:
608
+ mrec._mask[:] = _mask
609
+ return mrec
610
+
611
+
612
+ def _guessvartypes(arr):
613
+ """
614
+ Tries to guess the dtypes of the str_ ndarray `arr`.
615
+
616
+ Guesses by testing element-wise conversion. Returns a list of dtypes.
617
+ The array is first converted to ndarray. If the array is 2D, the test
618
+ is performed on the first line. An exception is raised if the file is
619
+ 3D or more.
620
+
621
+ """
622
+ vartypes = []
623
+ arr = np.asarray(arr)
624
+ if arr.ndim == 2:
625
+ arr = arr[0]
626
+ elif arr.ndim > 2:
627
+ raise ValueError("The array should be 2D at most!")
628
+ # Start the conversion loop.
629
+ for f in arr:
630
+ try:
631
+ int(f)
632
+ except (ValueError, TypeError):
633
+ try:
634
+ float(f)
635
+ except (ValueError, TypeError):
636
+ try:
637
+ complex(f)
638
+ except (ValueError, TypeError):
639
+ vartypes.append(arr.dtype)
640
+ else:
641
+ vartypes.append(np.dtype(complex))
642
+ else:
643
+ vartypes.append(np.dtype(float))
644
+ else:
645
+ vartypes.append(np.dtype(int))
646
+ return vartypes
647
+
648
+
649
+ def openfile(fname):
650
+ """
651
+ Opens the file handle of file `fname`.
652
+
653
+ """
654
+ # A file handle
655
+ if hasattr(fname, 'readline'):
656
+ return fname
657
+ # Try to open the file and guess its type
658
+ try:
659
+ f = open(fname)
660
+ except FileNotFoundError as e:
661
+ raise FileNotFoundError(f"No such file: '{fname}'") from e
662
+ if f.readline()[:2] != "\\x":
663
+ f.seek(0, 0)
664
+ return f
665
+ f.close()
666
+ raise NotImplementedError("Wow, binary file")
667
+
668
+
669
+ def fromtextfile(fname, delimiter=None, commentchar='#', missingchar='',
670
+ varnames=None, vartypes=None,
671
+ *, delimitor=np._NoValue): # backwards compatibility
672
+ """
673
+ Creates a mrecarray from data stored in the file `filename`.
674
+
675
+ Parameters
676
+ ----------
677
+ fname : {file name/handle}
678
+ Handle of an opened file.
679
+ delimiter : {None, string}, optional
680
+ Alphanumeric character used to separate columns in the file.
681
+ If None, any (group of) white spacestring(s) will be used.
682
+ commentchar : {'#', string}, optional
683
+ Alphanumeric character used to mark the start of a comment.
684
+ missingchar : {'', string}, optional
685
+ String indicating missing data, and used to create the masks.
686
+ varnames : {None, sequence}, optional
687
+ Sequence of the variable names. If None, a list will be created from
688
+ the first non empty line of the file.
689
+ vartypes : {None, sequence}, optional
690
+ Sequence of the variables dtypes. If None, it will be estimated from
691
+ the first non-commented line.
692
+
693
+
694
+ Ultra simple: the varnames are in the header, one line"""
695
+ if delimitor is not np._NoValue:
696
+ if delimiter is not None:
697
+ raise TypeError("fromtextfile() got multiple values for argument "
698
+ "'delimiter'")
699
+ # NumPy 1.22.0, 2021-09-23
700
+ warnings.warn("The 'delimitor' keyword argument of "
701
+ "numpy.ma.mrecords.fromtextfile() is deprecated "
702
+ "since NumPy 1.22.0, use 'delimiter' instead.",
703
+ DeprecationWarning, stacklevel=2)
704
+ delimiter = delimitor
705
+
706
+ # Try to open the file.
707
+ ftext = openfile(fname)
708
+
709
+ # Get the first non-empty line as the varnames
710
+ while True:
711
+ line = ftext.readline()
712
+ firstline = line[:line.find(commentchar)].strip()
713
+ _varnames = firstline.split(delimiter)
714
+ if len(_varnames) > 1:
715
+ break
716
+ if varnames is None:
717
+ varnames = _varnames
718
+
719
+ # Get the data.
720
+ _variables = masked_array([line.strip().split(delimiter) for line in ftext
721
+ if line[0] != commentchar and len(line) > 1])
722
+ (_, nfields) = _variables.shape
723
+ ftext.close()
724
+
725
+ # Try to guess the dtype.
726
+ if vartypes is None:
727
+ vartypes = _guessvartypes(_variables[0])
728
+ else:
729
+ vartypes = [np.dtype(v) for v in vartypes]
730
+ if len(vartypes) != nfields:
731
+ msg = "Attempting to %i dtypes for %i fields!"
732
+ msg += " Reverting to default."
733
+ warnings.warn(msg % (len(vartypes), nfields), stacklevel=2)
734
+ vartypes = _guessvartypes(_variables[0])
735
+
736
+ # Construct the descriptor.
737
+ mdescr = [(n, f) for (n, f) in zip(varnames, vartypes)]
738
+ mfillv = [ma.default_fill_value(f) for f in vartypes]
739
+
740
+ # Get the data and the mask.
741
+ # We just need a list of masked_arrays. It's easier to create it like that:
742
+ _mask = (_variables.T == missingchar)
743
+ _datalist = [masked_array(a, mask=m, dtype=t, fill_value=f)
744
+ for (a, m, t, f) in zip(_variables.T, _mask, vartypes, mfillv)]
745
+
746
+ return fromarrays(_datalist, dtype=mdescr)
747
+
748
+
749
+ def addfield(mrecord, newfield, newfieldname=None):
750
+ """Adds a new field to the masked record array
751
+
752
+ Uses `newfield` as data and `newfieldname` as name. If `newfieldname`
753
+ is None, the new field name is set to 'fi', where `i` is the number of
754
+ existing fields.
755
+
756
+ """
757
+ _data = mrecord._data
758
+ _mask = mrecord._mask
759
+ if newfieldname is None or newfieldname in reserved_fields:
760
+ newfieldname = 'f%i' % len(_data.dtype)
761
+ newfield = ma.array(newfield)
762
+ # Get the new data.
763
+ # Create a new empty recarray
764
+ newdtype = np.dtype(_data.dtype.descr + [(newfieldname, newfield.dtype)])
765
+ newdata = recarray(_data.shape, newdtype)
766
+ # Add the existing field
767
+ [newdata.setfield(_data.getfield(*f), *f)
768
+ for f in _data.dtype.fields.values()]
769
+ # Add the new field
770
+ newdata.setfield(newfield._data, *newdata.dtype.fields[newfieldname])
771
+ newdata = newdata.view(MaskedRecords)
772
+ # Get the new mask
773
+ # Create a new empty recarray
774
+ newmdtype = np.dtype([(n, bool_) for n in newdtype.names])
775
+ newmask = recarray(_data.shape, newmdtype)
776
+ # Add the old masks
777
+ [newmask.setfield(_mask.getfield(*f), *f)
778
+ for f in _mask.dtype.fields.values()]
779
+ # Add the mask of the new field
780
+ newmask.setfield(getmaskarray(newfield),
781
+ *newmask.dtype.fields[newfieldname])
782
+ newdata._mask = newmask
783
+ return newdata
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/mrecords.pyi ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, TypeVar
2
+
3
+ from numpy import dtype
4
+ from numpy.ma import MaskedArray
5
+
6
+ __all__: list[str]
7
+
8
+ # TODO: Set the `bound` to something more suitable once we
9
+ # have proper shape support
10
+ _ShapeType = TypeVar("_ShapeType", bound=Any)
11
+ _DType_co = TypeVar("_DType_co", bound=dtype[Any], covariant=True)
12
+
13
+ class MaskedRecords(MaskedArray[_ShapeType, _DType_co]):
14
+ def __new__(
15
+ cls,
16
+ shape,
17
+ dtype=...,
18
+ buf=...,
19
+ offset=...,
20
+ strides=...,
21
+ formats=...,
22
+ names=...,
23
+ titles=...,
24
+ byteorder=...,
25
+ aligned=...,
26
+ mask=...,
27
+ hard_mask=...,
28
+ fill_value=...,
29
+ keep_mask=...,
30
+ copy=...,
31
+ **options,
32
+ ): ...
33
+ _mask: Any
34
+ _fill_value: Any
35
+ @property
36
+ def _data(self): ...
37
+ @property
38
+ def _fieldmask(self): ...
39
+ def __array_finalize__(self, obj): ...
40
+ def __len__(self): ...
41
+ def __getattribute__(self, attr): ...
42
+ def __setattr__(self, attr, val): ...
43
+ def __getitem__(self, indx): ...
44
+ def __setitem__(self, indx, value): ...
45
+ def view(self, dtype=..., type=...): ...
46
+ def harden_mask(self): ...
47
+ def soften_mask(self): ...
48
+ def copy(self): ...
49
+ def tolist(self, fill_value=...): ...
50
+ def __reduce__(self): ...
51
+
52
+ mrecarray = MaskedRecords
53
+
54
+ def fromarrays(
55
+ arraylist,
56
+ dtype=...,
57
+ shape=...,
58
+ formats=...,
59
+ names=...,
60
+ titles=...,
61
+ aligned=...,
62
+ byteorder=...,
63
+ fill_value=...,
64
+ ): ...
65
+
66
+ def fromrecords(
67
+ reclist,
68
+ dtype=...,
69
+ shape=...,
70
+ formats=...,
71
+ names=...,
72
+ titles=...,
73
+ aligned=...,
74
+ byteorder=...,
75
+ fill_value=...,
76
+ mask=...,
77
+ ): ...
78
+
79
+ def fromtextfile(
80
+ fname,
81
+ delimiter=...,
82
+ commentchar=...,
83
+ missingchar=...,
84
+ varnames=...,
85
+ vartypes=...,
86
+ # NOTE: deprecated: NumPy 1.22.0, 2021-09-23
87
+ # delimitor=...,
88
+ ): ...
89
+
90
+ def addfield(mrecord, newfield, newfieldname=...): ...
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/numpy/ma/setup.py ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ def configuration(parent_package='',top_path=None):
3
+ from numpy.distutils.misc_util import Configuration
4
+ config = Configuration('ma', parent_package, top_path)
5
+ config.add_subpackage('tests')
6
+ config.add_data_files('*.pyi')
7
+ return config
8
+
9
+ if __name__ == "__main__":
10
+ from numpy.distutils.core import setup
11
+ config = configuration(top_path='').todict()
12
+ setup(**config)
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/qwen3_vl_moe/configuration_qwen3_vl_moe.py ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/qwen3_vl_moe/modular_qwen3_vl_moe.py.
3
+ # Do NOT edit this file manually as any edits will be overwritten by the generation of
4
+ # the file from the modular. If any change should be done, please apply the change to the
5
+ # modular_qwen3_vl_moe.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 The Qwen Team and The HuggingFace Inc. team. All rights reserved.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+ from huggingface_hub.dataclasses import strict
21
+
22
+ from ...configuration_utils import PreTrainedConfig
23
+ from ...modeling_rope_utils import RopeParameters
24
+ from ...utils import auto_docstring
25
+
26
+
27
+ @auto_docstring(checkpoint="Qwen/Qwen3-VL-30B-A3B-Instruct")
28
+ @strict
29
+ class Qwen3VLMoeTextConfig(PreTrainedConfig):
30
+ r"""
31
+ decoder_sparse_step (`int`, *optional*, defaults to 1):
32
+ The frequency of the MoE layer.
33
+ mlp_only_layers (`List[int]`, *optional*, defaults to `[]`):
34
+ Indicate which layers use Qwen3VLMoeMLP rather than Qwen3VLMoeSparseMoeBlock
35
+ The list contains layer index, from 0 to num_layers-1 if we have num_layers layers
36
+ If `mlp_only_layers` is empty, `decoder_sparse_step` is used to determine the sparsity.
37
+
38
+ ```python
39
+ >>> from transformers import Qwen3VLMoeForConditionalGeneration, Qwen3VLMoeConfig
40
+
41
+ >>> # Initializing a Qwen3VLMoe style configuration
42
+ >>> configuration = Qwen3VLMoeConfig()
43
+
44
+ >>> # Initializing a model from the Qwen3-VL-30B-A3B style configuration
45
+ >>> model = Qwen3VLMoeForConditionalGeneration(configuration)
46
+
47
+ >>> # Accessing the model configuration
48
+ >>> configuration = model.config
49
+ ```"""
50
+
51
+ model_type = "qwen3_vl_moe_text"
52
+ keys_to_ignore_at_inference = ["past_key_values"]
53
+
54
+ attribute_map = {
55
+ "num_experts": "num_local_experts",
56
+ }
57
+ # Default tensor parallel plan for base model `Qwen3VLMoe`
58
+ base_model_tp_plan = {
59
+ "layers.*.self_attn.q_proj": "colwise",
60
+ "layers.*.self_attn.k_proj": "colwise",
61
+ "layers.*.self_attn.v_proj": "colwise",
62
+ "layers.*.self_attn.o_proj": "rowwise",
63
+ "layers.*.mlp.gate_proj": "colwise",
64
+ "layers.*.mlp.up_proj": "colwise",
65
+ "layers.*.mlp.down_proj": "rowwise",
66
+ }
67
+ base_model_ep_plan = {
68
+ "layers.*.mlp.gate": "ep_router",
69
+ "layers.*.mlp.experts.gate_up_proj": "grouped_gemm",
70
+ "layers.*.mlp.experts.down_proj": "grouped_gemm",
71
+ "layers.*.mlp.experts": "moe_tp_experts",
72
+ }
73
+ base_model_pp_plan = {
74
+ "embed_tokens": (["input_ids"], ["inputs_embeds"]),
75
+ "layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
76
+ "norm": (["hidden_states"], ["hidden_states"]),
77
+ }
78
+
79
+ vocab_size: int = 151936
80
+ hidden_size: int = 2048
81
+
82
+ intermediate_size: int = 5632
83
+ num_hidden_layers: int = 24
84
+ num_attention_heads: int = 16
85
+ num_key_value_heads: int = 16
86
+ hidden_act: str = "silu"
87
+ max_position_embeddings: int = 128000
88
+ initializer_range: float = 0.02
89
+ rms_norm_eps: float = 1e-6
90
+ use_cache: bool = True
91
+ tie_word_embeddings: bool = True
92
+ rope_parameters: RopeParameters | dict | None = None
93
+ attention_bias: bool = False
94
+ attention_dropout: float | int = 0.0
95
+ decoder_sparse_step: int = 1
96
+ moe_intermediate_size: int = 1408
97
+ num_experts_per_tok: int = 4
98
+ num_experts: int = 60
99
+ router_aux_loss_coef: float = 0.001
100
+ mlp_only_layers: list[int] | None = None
101
+ pad_token_id: int | None = None
102
+ bos_token_id: int | None = None
103
+ eos_token_id: int | list[int] | None = None
104
+ base_config_key = "text_config"
105
+ default_theta = 500000.0
106
+ ignore_keys_at_rope_validation = {"mrope_section", "mrope_interleaved"}
107
+ head_dim: int | None = None
108
+
109
+ def __post_init__(self, **kwargs):
110
+ if self.num_key_value_heads is None:
111
+ self.num_key_value_heads = self.num_attention_heads
112
+
113
+ self.head_dim = self.head_dim or self.hidden_size // self.num_attention_heads
114
+ self.sliding_window = None
115
+ self.mlp_only_layers = [] if self.mlp_only_layers is None else self.mlp_only_layers
116
+ super().__post_init__(**kwargs)
117
+
118
+
119
+ @auto_docstring(checkpoint="Qwen/Qwen3-VL-30B-A3B-Instruct")
120
+ @strict
121
+ class Qwen3VLMoeVisionConfig(PreTrainedConfig):
122
+ r"""
123
+ out_hidden_size (`int`, *optional*, defaults to 3584):
124
+ The output hidden size of the vision model.
125
+ num_position_embeddings (`int`, *optional*, defaults to 2304):
126
+ The maximum sequence length that this model might ever be used with
127
+ deepstack_visual_indexes (`list[int]`, *optional*, defaults to `[8, 16, 24]`):
128
+ Indexed of layers for deepstack embeddings.
129
+ """
130
+
131
+ model_type = "qwen3_vl_moe_vision"
132
+ base_config_key = "vision_config"
133
+
134
+ depth: int = 27
135
+ hidden_size: int = 1152
136
+ hidden_act: str = "gelu_pytorch_tanh"
137
+ intermediate_size: int = 4304
138
+ num_heads: int = 16
139
+ in_channels: int = 3
140
+ patch_size: int | list[int] | tuple[int, int] = 16
141
+ spatial_merge_size: int = 2
142
+ temporal_patch_size: int | list[int] | tuple[int, int] = 2
143
+ out_hidden_size: int = 3584
144
+ num_position_embeddings: int = 2304
145
+ deepstack_visual_indexes: list[int] | tuple[int, ...] = (8, 16, 24)
146
+ initializer_range: float = 0.02
147
+
148
+
149
+ @auto_docstring(checkpoint="Qwen/Qwen3-VL-30B-A3B-Instruct")
150
+ @strict
151
+ class Qwen3VLMoeConfig(PreTrainedConfig):
152
+ r"""
153
+ Example:
154
+
155
+ ```python
156
+ >>> from transformers import Qwen3VLMoeForConditionalGeneration, Qwen3VLMoeConfig
157
+
158
+ >>> # Initializing a Qwen3-VL-MOE style configuration
159
+ >>> configuration = Qwen3VLMoeConfig()
160
+
161
+ >>> # Initializing a model from the Qwen3-VL-30B-A3B style configuration
162
+ >>> model = Qwen3VLMoeForConditionalGeneration(configuration)
163
+
164
+ >>> # Accessing the model configuration
165
+ >>> configuration = model.config
166
+ ```"""
167
+
168
+ model_type = "qwen3_vl_moe"
169
+ sub_configs = {"vision_config": Qwen3VLMoeVisionConfig, "text_config": Qwen3VLMoeTextConfig}
170
+ keys_to_ignore_at_inference = ["past_key_values"]
171
+
172
+ text_config: dict | PreTrainedConfig | None = None
173
+ vision_config: dict | PreTrainedConfig | None = None
174
+ image_token_id: int = 151655
175
+ video_token_id: int = 151656
176
+ vision_start_token_id: int = 151652
177
+ vision_end_token_id: int = 151653
178
+ tie_word_embeddings: bool = False
179
+
180
+ def __post_init__(self, **kwargs):
181
+ if isinstance(self.vision_config, dict):
182
+ self.vision_config = self.sub_configs["vision_config"](**self.vision_config)
183
+ elif self.vision_config is None:
184
+ self.vision_config = self.sub_configs["vision_config"]()
185
+
186
+ if isinstance(self.text_config, dict):
187
+ self.text_config = self.sub_configs["text_config"](**self.text_config)
188
+ elif self.text_config is None:
189
+ self.text_config = self.sub_configs["text_config"]()
190
+
191
+ super().__post_init__(**kwargs)
192
+
193
+
194
+ __all__ = ["Qwen3VLMoeConfig", "Qwen3VLMoeTextConfig", "Qwen3VLMoeVisionConfig"]
LTA_openwebtext_dualt/mini_owt_logdirichlet/logs/infer_not5_bottleneck128_170k_decode32_ema_20260611/lr2e3.log ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ checkpoint=runs/owt_t5_elftokenized_full_len1024_C1_to_1024_pow1_d768_l12_h12_gbs512_2x8gpu_50ep_lr2e3_ema0p9999_elfopt_not5_bottleneck128_unfixed_norm_stateprobadd_selfcond_ce_fast_20260609_150828/step_170000.pt
2
+ use_ema=1
3
+ step=170000
4
+ decode_steps=32
5
+ n=64 chunk_n=8 gpu=1
6
+ out_base=/e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt/docs/lta_samples/metrics_20260611
7
+ [2026-06-11T21:37:16+00:00] infer step=170000 decode=32 -> /e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt/docs/lta_samples/metrics_20260611/owt_t5_not5_bottleneck128_norm_stateprobadd_selfcond_ce_fast_lr2e3_ema0p9999_step170000_ema_sc1p0_decode32_n64
8
+ [2026-06-11T21:37:16+00:00] run decode=32 chunk=0 n=8 seed=123
9
+ [2026-06-11T21:37:23+00:00] done decode=32 chunk=0
10
+ [2026-06-11T21:37:23+00:00] run decode=32 chunk=1 n=8 seed=124
11
+ [2026-06-11T21:37:30+00:00] done decode=32 chunk=1
12
+ [2026-06-11T21:37:30+00:00] run decode=32 chunk=2 n=8 seed=125
13
+ [2026-06-11T21:37:37+00:00] done decode=32 chunk=2
14
+ [2026-06-11T21:37:37+00:00] run decode=32 chunk=3 n=8 seed=126
15
+ [2026-06-11T21:37:43+00:00] done decode=32 chunk=3
16
+ [2026-06-11T21:37:43+00:00] run decode=32 chunk=4 n=8 seed=127
17
+ [2026-06-11T21:37:50+00:00] done decode=32 chunk=4
18
+ [2026-06-11T21:37:50+00:00] run decode=32 chunk=5 n=8 seed=128
19
+ [2026-06-11T21:37:57+00:00] done decode=32 chunk=5
20
+ [2026-06-11T21:37:57+00:00] run decode=32 chunk=6 n=8 seed=129
21
+ [2026-06-11T21:38:04+00:00] done decode=32 chunk=6
22
+ [2026-06-11T21:38:04+00:00] run decode=32 chunk=7 n=8 seed=130
23
+ [2026-06-11T21:38:11+00:00] done decode=32 chunk=7
24
+ merged 64 samples -> /e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt/docs/lta_samples/metrics_20260611/owt_t5_not5_bottleneck128_norm_stateprobadd_selfcond_ce_fast_lr2e3_ema0p9999_step170000_ema_sc1p0_decode32_n64/sc1p0/samples64.txt
25
+ loading scorer /e2e-data/evad-tech-vla/wanghan58/models/flowtext_scorers/gpt2-large-standard dtype=fp32 device=cuda
26
+ run kind ppl mean_entropy distinct_1 distinct_2 top_token_mass eos_rows eos_total ppl_tokens t5_tokens path
27
+ sc1p0 raw_full 36.813703657387094 5.18392545332874 0.08469329900856587 0.5129332802108554 0.026417812102545242 62 63 60904 65259 /e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt/docs/lta_samples/metrics_20260611/owt_t5_not5_bottleneck128_norm_stateprobadd_selfcond_ce_fast_lr2e3_ema0p9999_step170000_ema_sc1p0_decode32_n64/sc1p0
28
+ sc1p0 pre_eos 40.30085154584371 5.192043916306752 0.08625290656845457 0.5223477636630357 0.02690429001701025 0 0 58501 64079 /e2e-data/evad-tech-vla/wanghan58/workspace/LTA_openwebtext_dualt/docs/lta_samples/metrics_20260611/owt_t5_not5_bottleneck128_norm_stateprobadd_selfcond_ce_fast_lr2e3_ema0p9999_step170000_ema_sc1p0_decode32_n64/sc1p0
29
+ [2026-06-11T21:38:24+00:00] done