pystachy 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- _pystachy_source/VERSION +1 -0
- _pystachy_source/lib/_argparse_help.py +188 -0
- _pystachy_source/lib/_markupbase.py +399 -0
- _pystachy_source/lib/_pyrandom.py +272 -0
- _pystachy_source/lib/_pystachy__io.py +43 -0
- _pystachy_source/lib/_pystachy_abc.py +105 -0
- _pystachy_source/lib/_pystachy_atexit.py +76 -0
- _pystachy_source/lib/_pystachy_bfile.py +245 -0
- _pystachy_source/lib/_pystachy_binascii.py +412 -0
- _pystachy_source/lib/_pystachy_bytescan.py +28 -0
- _pystachy_source/lib/_pystachy_codecs.py +524 -0
- _pystachy_source/lib/_pystachy_copy.py +43 -0
- _pystachy_source/lib/_pystachy_iterators.py +207 -0
- _pystachy_source/lib/_pystachy_itertools.py +996 -0
- _pystachy_source/lib/_pystachy_json_any.py +271 -0
- _pystachy_source/lib/_pystachy_json_int.py +6 -0
- _pystachy_source/lib/_pystachy_mappingproxy.py +94 -0
- _pystachy_source/lib/_pystachy_object.py +13 -0
- _pystachy_source/lib/_pystachy_percent.py +343 -0
- _pystachy_source/lib/_pystachy_range.py +139 -0
- _pystachy_source/lib/_pystachy_re_specialized.py +33 -0
- _pystachy_source/lib/_pystachy_string.py +175 -0
- _pystachy_source/lib/_pystachy_struct.py +447 -0
- _pystachy_source/lib/_pystachy_thread.py +433 -0
- _pystachy_source/lib/_pystachy_time.py +15 -0
- _pystachy_source/lib/_pystachy_types.py +13 -0
- _pystachy_source/lib/_pystachy_unicodedata.py +873 -0
- _pystachy_source/lib/_pystachy_unicodedata_db.py +1371 -0
- _pystachy_source/lib/_pystachy_unicodedata_names.py +7634 -0
- _pystachy_source/lib/_pystachy_weakref.py +111 -0
- _pystachy_source/lib/_weakrefset.py +205 -0
- _pystachy_source/lib/argparse.py +315 -0
- _pystachy_source/lib/bisect.py +118 -0
- _pystachy_source/lib/codecs.py +1135 -0
- _pystachy_source/lib/collections/__init__.py +1282 -0
- _pystachy_source/lib/colorsys.py +166 -0
- _pystachy_source/lib/contextlib.py +300 -0
- _pystachy_source/lib/copy.py +213 -0
- _pystachy_source/lib/csv.py +1039 -0
- _pystachy_source/lib/curses/__init__.py +4 -0
- _pystachy_source/lib/curses/ascii.py +99 -0
- _pystachy_source/lib/datetime.py +3044 -0
- _pystachy_source/lib/difflib.py +2083 -0
- _pystachy_source/lib/enum.py +854 -0
- _pystachy_source/lib/fnmatch.py +249 -0
- _pystachy_source/lib/functools.py +407 -0
- _pystachy_source/lib/genericpath.py +200 -0
- _pystachy_source/lib/getopt.py +214 -0
- _pystachy_source/lib/gettext.py +657 -0
- _pystachy_source/lib/glob.py +224 -0
- _pystachy_source/lib/heapq.py +636 -0
- _pystachy_source/lib/html/__init__.py +149 -0
- _pystachy_source/lib/html/entities.py +2514 -0
- _pystachy_source/lib/html/parser.py +602 -0
- _pystachy_source/lib/io.py +1183 -0
- _pystachy_source/lib/json.py +843 -0
- _pystachy_source/lib/keyword.py +74 -0
- _pystachy_source/lib/logging/__init__.py +2506 -0
- _pystachy_source/lib/mpz.py +127 -0
- _pystachy_source/lib/operator.py +455 -0
- _pystachy_source/lib/pathlib.py +739 -0
- _pystachy_source/lib/posixpath.py +578 -0
- _pystachy_source/lib/pyobj.py +475 -0
- _pystachy_source/lib/random.py +1174 -0
- _pystachy_source/lib/re/__init__.py +2516 -0
- _pystachy_source/lib/re/_constants.py +111 -0
- _pystachy_source/lib/re/_sre.py +2108 -0
- _pystachy_source/lib/re/_unicode.py +304 -0
- _pystachy_source/lib/shlex.py +381 -0
- _pystachy_source/lib/shutil.py +205 -0
- _pystachy_source/lib/stat.py +212 -0
- _pystachy_source/lib/statistics.py +1954 -0
- _pystachy_source/lib/string.py +352 -0
- _pystachy_source/lib/struct.py +15 -0
- _pystachy_source/lib/textwrap.py +520 -0
- _pystachy_source/lib/this.py +28 -0
- _pystachy_source/lib/threading.py +1674 -0
- _pystachy_source/lib/token.py +166 -0
- _pystachy_source/lib/tomllib/__init__.py +10 -0
- _pystachy_source/lib/tomllib/_parser.py +732 -0
- _pystachy_source/lib/tomllib/_re.py +114 -0
- _pystachy_source/lib/tomllib/_types.py +13 -0
- _pystachy_source/lib/traceback.py +184 -0
- _pystachy_source/lib/types.py +49 -0
- _pystachy_source/lib/urllib/__init__.py +0 -0
- _pystachy_source/lib/urllib/parse.py +1713 -0
- _pystachy_source/lib/warnings.py +764 -0
- _pystachy_source/lib/weakref.py +539 -0
- _pystachy_source/mpz/mpz.c +463 -0
- _pystachy_source/pyembed.c +373 -0
- _pystachy_source/pyext.c +266 -0
- _pystachy_source/pystachy.py +34 -0
- _pystachy_source/pystachy_cli.py +31 -0
- _pystachy_source/pystachy_toolchain.py +152 -0
- _pystachy_source/runtime.c +8564 -0
- _pystachy_source/runtime.py +2276 -0
- _pystachy_source/ryu/common.h +114 -0
- _pystachy_source/ryu/d2s.c +509 -0
- _pystachy_source/ryu/d2s_intrinsics.h +357 -0
- _pystachy_source/ryu/d2s_small_table.h +186 -0
- _pystachy_source/ryu/digit_table.h +35 -0
- _pystachy_source/ryu/ryu.h +46 -0
- _pystachy_source/src/__init__.py +1 -0
- _pystachy_source/src/pystachy_compiler/__init__.py +1 -0
- _pystachy_source/src/pystachy_compiler/analysis.py +2105 -0
- _pystachy_source/src/pystachy_compiler/argparse_schema.py +393 -0
- _pystachy_source/src/pystachy_compiler/bigints.py +1498 -0
- _pystachy_source/src/pystachy_compiler/builtins.py +3026 -0
- _pystachy_source/src/pystachy_compiler/calls.py +1698 -0
- _pystachy_source/src/pystachy_compiler/containers.py +1256 -0
- _pystachy_source/src/pystachy_compiler/conversions.py +399 -0
- _pystachy_source/src/pystachy_compiler/declarations.py +3000 -0
- _pystachy_source/src/pystachy_compiler/diagnostics.py +176 -0
- _pystachy_source/src/pystachy_compiler/driver.py +921 -0
- _pystachy_source/src/pystachy_compiler/dynamic.py +4513 -0
- _pystachy_source/src/pystachy_compiler/emission.py +666 -0
- _pystachy_source/src/pystachy_compiler/exceptions.py +1642 -0
- _pystachy_source/src/pystachy_compiler/expressions.py +5153 -0
- _pystachy_source/src/pystachy_compiler/flow.py +972 -0
- _pystachy_source/src/pystachy_compiler/functions.py +523 -0
- _pystachy_source/src/pystachy_compiler/gen.py +5142 -0
- _pystachy_source/src/pystachy_compiler/generators.py +1361 -0
- _pystachy_source/src/pystachy_compiler/ir.py +579 -0
- _pystachy_source/src/pystachy_compiler/ircheck.py +503 -0
- _pystachy_source/src/pystachy_compiler/lexer.py +788 -0
- _pystachy_source/src/pystachy_compiler/llvm_abi.py +19 -0
- _pystachy_source/src/pystachy_compiler/loader.py +3787 -0
- _pystachy_source/src/pystachy_compiler/local_versions.py +57 -0
- _pystachy_source/src/pystachy_compiler/lower_module.py +754 -0
- _pystachy_source/src/pystachy_compiler/lowering.py +625 -0
- _pystachy_source/src/pystachy_compiler/memory_ir.py +28 -0
- _pystachy_source/src/pystachy_compiler/module.py +55 -0
- _pystachy_source/src/pystachy_compiler/names.py +55 -0
- _pystachy_source/src/pystachy_compiler/optimizations.py +1445 -0
- _pystachy_source/src/pystachy_compiler/parser.py +2465 -0
- _pystachy_source/src/pystachy_compiler/program.py +1296 -0
- _pystachy_source/src/pystachy_compiler/reflection.py +3073 -0
- _pystachy_source/src/pystachy_compiler/scalar_ir.py +61 -0
- _pystachy_source/src/pystachy_compiler/scope.py +619 -0
- _pystachy_source/src/pystachy_compiler/specs.py +1102 -0
- _pystachy_source/src/pystachy_compiler/statements.py +2126 -0
- _pystachy_source/src/pystachy_compiler/structs.py +271 -0
- _pystachy_source/src/pystachy_compiler/syntax.py +245 -0
- _pystachy_source/src/pystachy_compiler/templates.py +998 -0
- _pystachy_source/src/pystachy_compiler/union_arithmetic.py +161 -0
- _pystachy_source/src/pystachy_compiler/union_proof.py +891 -0
- _pystachy_source/src/pystachy_compiler/union_state.py +251 -0
- _pystachy_source/src/pystachy_compiler/unions.py +591 -0
- _pystachy_source/src/pystachy_compiler/utils.py +1124 -0
- _pystachy_source/src/pystachy_compiler/variables.py +2323 -0
- pystachy-0.2.0.dist-info/METADATA +93 -0
- pystachy-0.2.0.dist-info/RECORD +158 -0
- pystachy-0.2.0.dist-info/WHEEL +5 -0
- pystachy-0.2.0.dist-info/entry_points.txt +2 -0
- pystachy-0.2.0.dist-info/licenses/LICENSE +21 -0
- pystachy-0.2.0.dist-info/licenses/THIRD_PARTY_NOTICES +1051 -0
- pystachy-0.2.0.dist-info/licenses/ryu/LICENSE-Boost +23 -0
- pystachy-0.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
"""The _random module's Mersenne Twister generator, written for Pystachy.
|
|
2
|
+
|
|
3
|
+
CPython's _random is a C module, Modules/_randommodule.c; this one follows that file of CPython
|
|
4
|
+
3.13.16 (lib/provenance.md): init_genrand(), init_by_array(), genrand_uint32() and the methods of
|
|
5
|
+
_random.Random, with the C code's operations in its order, so a seeded generator gives the values
|
|
6
|
+
CPython's does. Its uint32_t arithmetic is done in checked 64-bit ints: each product of two 32-bit
|
|
7
|
+
words has a factor below 2**31, and stays below 2**63, and each result is masked to 32 bits.
|
|
8
|
+
|
|
9
|
+
lib/random.py's Random derives from this Random, as CPython's derives from the C type.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
# The generator follows the MT19937 reference code, whose comments CPython's _randommodule.c keeps:
|
|
13
|
+
#
|
|
14
|
+
# A C-program for MT19937, with initialization improved 2002/1/26.
|
|
15
|
+
# Coded by Takuji Nishimura and Makoto Matsumoto.
|
|
16
|
+
#
|
|
17
|
+
# Before using, initialize the state by using init_genrand(seed)
|
|
18
|
+
# or init_by_array(init_key, key_length).
|
|
19
|
+
#
|
|
20
|
+
# Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
|
|
21
|
+
# All rights reserved.
|
|
22
|
+
#
|
|
23
|
+
# Redistribution and use in source and binary forms, with or without
|
|
24
|
+
# modification, are permitted provided that the following conditions
|
|
25
|
+
# are met:
|
|
26
|
+
#
|
|
27
|
+
# 1. Redistributions of source code must retain the above copyright
|
|
28
|
+
# notice, this list of conditions and the following disclaimer.
|
|
29
|
+
#
|
|
30
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
|
31
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
32
|
+
# documentation and/or other materials provided with the distribution.
|
|
33
|
+
#
|
|
34
|
+
# 3. The names of its contributors may not be used to endorse or promote
|
|
35
|
+
# products derived from this software without specific prior written
|
|
36
|
+
# permission.
|
|
37
|
+
#
|
|
38
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
39
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
40
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
41
|
+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
42
|
+
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
43
|
+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
44
|
+
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
45
|
+
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
46
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
47
|
+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
48
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
49
|
+
|
|
50
|
+
from math import frexp as _frexp, isfinite as _isfinite, isinf as _isinf
|
|
51
|
+
import os as _os
|
|
52
|
+
import time as _time
|
|
53
|
+
|
|
54
|
+
# Period parameters
|
|
55
|
+
_N = 624
|
|
56
|
+
_M = 397
|
|
57
|
+
_MATRIX_A = 0x9908b0df # constant vector a
|
|
58
|
+
_UPPER_MASK = 0x80000000 # most significant w-r bits
|
|
59
|
+
_LOWER_MASK = 0x7fffffff # least significant r bits
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class Random:
|
|
63
|
+
"""Random() -> create a random number generator with its own internal state."""
|
|
64
|
+
|
|
65
|
+
_state: list[int] # the N words of uint32_t state
|
|
66
|
+
_index: int
|
|
67
|
+
|
|
68
|
+
def __init__(self, n: int | float | bool | None = None) -> None:
|
|
69
|
+
self._state = [0] * _N
|
|
70
|
+
self._index = 0
|
|
71
|
+
self.seed(n)
|
|
72
|
+
|
|
73
|
+
def _genrand_uint32(self) -> int:
|
|
74
|
+
# genrand_uint32(): generates a random number on [0,0xffffffff]-interval
|
|
75
|
+
mt = self._state
|
|
76
|
+
if self._index >= _N: # generate N words at one time
|
|
77
|
+
kk = 0
|
|
78
|
+
while kk < _N - _M:
|
|
79
|
+
y = (mt[kk] & _UPPER_MASK) | (mt[kk + 1] & _LOWER_MASK)
|
|
80
|
+
mt[kk] = mt[kk + _M] ^ (y >> 1) ^ (_MATRIX_A if y & 0x1 else 0)
|
|
81
|
+
kk += 1
|
|
82
|
+
while kk < _N - 1:
|
|
83
|
+
y = (mt[kk] & _UPPER_MASK) | (mt[kk + 1] & _LOWER_MASK)
|
|
84
|
+
mt[kk] = mt[kk + (_M - _N)] ^ (y >> 1) ^ (_MATRIX_A if y & 0x1 else 0)
|
|
85
|
+
kk += 1
|
|
86
|
+
y = (mt[_N - 1] & _UPPER_MASK) | (mt[0] & _LOWER_MASK)
|
|
87
|
+
mt[_N - 1] = mt[_M - 1] ^ (y >> 1) ^ (_MATRIX_A if y & 0x1 else 0)
|
|
88
|
+
self._index = 0
|
|
89
|
+
|
|
90
|
+
y = mt[self._index]
|
|
91
|
+
self._index += 1
|
|
92
|
+
y ^= y >> 11
|
|
93
|
+
y ^= (y << 7) & 0x9d2c5680
|
|
94
|
+
y ^= (y << 15) & 0xefc60000
|
|
95
|
+
y ^= y >> 18
|
|
96
|
+
return y
|
|
97
|
+
|
|
98
|
+
def random(self) -> float:
|
|
99
|
+
"""random() -> x in the interval [0, 1)."""
|
|
100
|
+
# random_random() is the same as genrand_res53() from the reference code
|
|
101
|
+
a = self._genrand_uint32() >> 5
|
|
102
|
+
b = self._genrand_uint32() >> 6
|
|
103
|
+
return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0)
|
|
104
|
+
|
|
105
|
+
def _init_genrand(self, s: int) -> None:
|
|
106
|
+
# initializes mt[N] with a seed: in a new list, as lib/random.py's Random.__init__() does
|
|
107
|
+
# not call this __init__() (the C type's state is made with the object)
|
|
108
|
+
mt = [0] * _N
|
|
109
|
+
self._state = mt
|
|
110
|
+
mt[0] = s
|
|
111
|
+
for mti in range(1, _N):
|
|
112
|
+
# 1812433253 * (2**32 - 1) + 623 < 2**63
|
|
113
|
+
mt[mti] = (1812433253 * (mt[mti - 1] ^ (mt[mti - 1] >> 30)) + mti) & 0xffffffff
|
|
114
|
+
self._index = _N
|
|
115
|
+
|
|
116
|
+
def _init_by_array(self, init_key: list[int]) -> None:
|
|
117
|
+
# initialize by an array: init_key is the array for initializing keys
|
|
118
|
+
key_length = len(init_key)
|
|
119
|
+
self._init_genrand(19650218)
|
|
120
|
+
mt = self._state
|
|
121
|
+
i = 1
|
|
122
|
+
j = 0
|
|
123
|
+
k = _N if _N > key_length else key_length
|
|
124
|
+
while k:
|
|
125
|
+
mt[i] = ((mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1664525))
|
|
126
|
+
+ init_key[j] + j) & 0xffffffff # non linear
|
|
127
|
+
i += 1
|
|
128
|
+
j += 1
|
|
129
|
+
if i >= _N:
|
|
130
|
+
mt[0] = mt[_N - 1]
|
|
131
|
+
i = 1
|
|
132
|
+
if j >= key_length:
|
|
133
|
+
j = 0
|
|
134
|
+
k -= 1
|
|
135
|
+
k = _N - 1
|
|
136
|
+
while k:
|
|
137
|
+
# (2**32 - 1) * 1566083941 < 2**63; a negative difference is masked as C wraps it
|
|
138
|
+
mt[i] = ((mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1566083941))
|
|
139
|
+
- i) & 0xffffffff # non linear
|
|
140
|
+
i += 1
|
|
141
|
+
if i >= _N:
|
|
142
|
+
mt[0] = mt[_N - 1]
|
|
143
|
+
i = 1
|
|
144
|
+
k -= 1
|
|
145
|
+
|
|
146
|
+
mt[0] = 0x80000000 # MSB is 1; assuring non-zero initial array
|
|
147
|
+
|
|
148
|
+
def _seed_time_pid(self) -> None:
|
|
149
|
+
# random_seed_time_pid(), C's fallback where the system's entropy cannot be read, as
|
|
150
|
+
# Pystachy's is not (it has no os.urandom()): the time, the process id and the
|
|
151
|
+
# monotonic clock, each in 32-bit words
|
|
152
|
+
now = _time.time_ns()
|
|
153
|
+
mono = _time.monotonic_ns()
|
|
154
|
+
self._init_by_array([now & 0xffffffff, (now >> 32) & 0xffffffff, _os.getpid() & 0xffffffff,
|
|
155
|
+
mono & 0xffffffff, (mono >> 32) & 0xffffffff])
|
|
156
|
+
|
|
157
|
+
def seed(self, n=None, /) -> None:
|
|
158
|
+
"""seed([n]) -> None.
|
|
159
|
+
|
|
160
|
+
Defaults to use urandom and falls back to a combination
|
|
161
|
+
of the current time and the process identifier.
|
|
162
|
+
"""
|
|
163
|
+
# random_seed(): None seeds from the time and process id (above); an int seeds with the
|
|
164
|
+
# 32-bit words of its absolute value, from the right, and a float with those of its
|
|
165
|
+
# hash, cast to an unsigned size_t
|
|
166
|
+
if n is None:
|
|
167
|
+
self._seed_time_pid()
|
|
168
|
+
return
|
|
169
|
+
if isinstance(n, float):
|
|
170
|
+
h = _hash_float(n)
|
|
171
|
+
if h < 0: # (size_t)hash: 64 bits
|
|
172
|
+
key = [h & 0xffffffff, (h >> 32) & 0xffffffff]
|
|
173
|
+
else:
|
|
174
|
+
key = _key_words(h)
|
|
175
|
+
elif isinstance(n, bool):
|
|
176
|
+
key = [1 if n else 0] # int.__abs__() of a bool
|
|
177
|
+
elif n < 0:
|
|
178
|
+
if n == -0x7fffffffffffffff - 1: # abs() of -2**63
|
|
179
|
+
key = [0, 0x80000000]
|
|
180
|
+
else:
|
|
181
|
+
key = _key_words(-n)
|
|
182
|
+
else:
|
|
183
|
+
key = _key_words(n)
|
|
184
|
+
self._init_by_array(key)
|
|
185
|
+
|
|
186
|
+
def getstate(self) -> tuple[int, ...]:
|
|
187
|
+
"""getstate() -> tuple containing the current state."""
|
|
188
|
+
state = self._state[:]
|
|
189
|
+
state.append(self._index)
|
|
190
|
+
return tuple(state)
|
|
191
|
+
|
|
192
|
+
def setstate(self, state: tuple[int, ...], /) -> None:
|
|
193
|
+
"""setstate(state) -> None. Restores generator state."""
|
|
194
|
+
if len(state) != _N + 1:
|
|
195
|
+
raise ValueError("state vector is the wrong size")
|
|
196
|
+
new_state = [0] * _N
|
|
197
|
+
for i in range(_N):
|
|
198
|
+
element = state[i]
|
|
199
|
+
if element < 0: # PyLong_AsUnsignedLong()
|
|
200
|
+
raise OverflowError("can't convert negative value to unsigned int")
|
|
201
|
+
new_state[i] = element & 0xffffffff
|
|
202
|
+
index = state[_N]
|
|
203
|
+
if index < 0 or index > _N:
|
|
204
|
+
raise ValueError("invalid state")
|
|
205
|
+
self._index = index
|
|
206
|
+
self._state = new_state
|
|
207
|
+
|
|
208
|
+
def getrandbits(self, k: int, /) -> int:
|
|
209
|
+
"""getrandbits(k) -> x. Generates an int with k random bits."""
|
|
210
|
+
if k < 0:
|
|
211
|
+
raise ValueError("number of bits must be non-negative")
|
|
212
|
+
|
|
213
|
+
if k == 0:
|
|
214
|
+
return 0
|
|
215
|
+
|
|
216
|
+
if k <= 32: # Fast path
|
|
217
|
+
return self._genrand_uint32() >> (32 - k)
|
|
218
|
+
|
|
219
|
+
# Pystachy's ints have 64 bits: two 32-bit words, from least significant to most
|
|
220
|
+
# significant, hold up to 63 random bits
|
|
221
|
+
if k > 63:
|
|
222
|
+
raise OverflowError("integer result does not fit in 64 bits")
|
|
223
|
+
r = self._genrand_uint32()
|
|
224
|
+
return r | ((self._genrand_uint32() >> (64 - k)) << 32)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def _key_words(n: int) -> list[int]:
|
|
228
|
+
# the 32-bit words of n >= 0, from the right: one word for 0
|
|
229
|
+
key = [n & 0xffffffff]
|
|
230
|
+
n >>= 32
|
|
231
|
+
while n:
|
|
232
|
+
key.append(n & 0xffffffff)
|
|
233
|
+
n >>= 32
|
|
234
|
+
return key
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
_PyHASH_BITS = 61
|
|
238
|
+
_PyHASH_MODULUS = (1 << _PyHASH_BITS) - 1
|
|
239
|
+
_PyHASH_INF = 314159
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def _hash_float(v: float) -> int:
|
|
243
|
+
# _Py_HashDouble() of Python/pyhash.c: hash(v), for a float v. Its unsigned operations are done
|
|
244
|
+
# below 2**61: a shift left first drops the bits the modulus mask would drop.
|
|
245
|
+
if not _isfinite(v):
|
|
246
|
+
if _isinf(v):
|
|
247
|
+
return _PyHASH_INF if v > 0 else -_PyHASH_INF
|
|
248
|
+
# a NaN's hash is its object's address, which a Pystachy float has not: 0 here
|
|
249
|
+
return 0
|
|
250
|
+
m, e = _frexp(v)
|
|
251
|
+
sign = 1
|
|
252
|
+
if m < 0:
|
|
253
|
+
sign = -1
|
|
254
|
+
m = -m
|
|
255
|
+
# process 28 bits at a time
|
|
256
|
+
x = 0
|
|
257
|
+
while m:
|
|
258
|
+
x = ((x & ((1 << (_PyHASH_BITS - 28)) - 1)) << 28) | x >> (_PyHASH_BITS - 28)
|
|
259
|
+
m *= 268435456.0 # 2**28
|
|
260
|
+
e -= 28
|
|
261
|
+
y = int(m) # pull out integer part
|
|
262
|
+
m -= y
|
|
263
|
+
x += y
|
|
264
|
+
if x >= _PyHASH_MODULUS:
|
|
265
|
+
x -= _PyHASH_MODULUS
|
|
266
|
+
# adjust for the exponent; first reduce it modulo _PyHASH_BITS
|
|
267
|
+
e = e % _PyHASH_BITS if e >= 0 else _PyHASH_BITS - 1 - ((-1 - e) % _PyHASH_BITS)
|
|
268
|
+
x = ((x & ((1 << (_PyHASH_BITS - e)) - 1)) << e) | x >> (_PyHASH_BITS - e)
|
|
269
|
+
x = x * sign
|
|
270
|
+
if x == -1:
|
|
271
|
+
x = -2
|
|
272
|
+
return x
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""The io module provides the Python interfaces to stream handling. The
|
|
2
|
+
builtin open function is defined in this module.
|
|
3
|
+
|
|
4
|
+
At the top of the I/O hierarchy is the abstract base class IOBase. It
|
|
5
|
+
defines the basic interface to a stream. Note, however, that there is no
|
|
6
|
+
separation between reading and writing to streams; implementations are
|
|
7
|
+
allowed to raise an OSError if they do not support a given operation.
|
|
8
|
+
|
|
9
|
+
Extending IOBase is RawIOBase which deals simply with the reading and
|
|
10
|
+
writing of raw bytes to a stream. FileIO subclasses RawIOBase to provide
|
|
11
|
+
an interface to OS files.
|
|
12
|
+
|
|
13
|
+
BufferedIOBase deals with buffering on a raw byte stream (RawIOBase). Its
|
|
14
|
+
subclasses, BufferedWriter, BufferedReader, and BufferedRWPair buffer
|
|
15
|
+
streams that are readable, writable, and both respectively.
|
|
16
|
+
BufferedRandom provides a buffered interface to random access
|
|
17
|
+
streams. BytesIO is a simple stream of in-memory bytes.
|
|
18
|
+
|
|
19
|
+
Another IOBase subclass, TextIOBase, deals with the encoding and decoding
|
|
20
|
+
of streams into text. TextIOWrapper, which extends it, is a buffered text
|
|
21
|
+
interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO
|
|
22
|
+
is an in-memory stream for text.
|
|
23
|
+
|
|
24
|
+
Argument names are not part of the specification, and only the arguments
|
|
25
|
+
of open() are intended to be used as keyword arguments.
|
|
26
|
+
|
|
27
|
+
data:
|
|
28
|
+
|
|
29
|
+
DEFAULT_BUFFER_SIZE
|
|
30
|
+
|
|
31
|
+
An int containing the default buffer size used by the module's buffered
|
|
32
|
+
I/O classes. open() uses the file's blksize (as obtained by os.stat) if
|
|
33
|
+
possible.
|
|
34
|
+
"""
|
|
35
|
+
# _io for Pystachy: CPython builds _io into its interpreter (Modules/_io), and its io module is a
|
|
36
|
+
# Python layer over it. Pystachy's io (lib/io.py) is the implementation itself, so this file, which
|
|
37
|
+
# Pystachy loads for import _io (specs.STANDINS), gives io's classes and functions under _io's
|
|
38
|
+
# names. Not here: FileIO, the Buffered* classes and open_code(), which need binary files that
|
|
39
|
+
# open() does not make (#493); the _IOBase, _RawIOBase, _BufferedIOBase and _TextIOBase base
|
|
40
|
+
# classes, which io's classes do not derive from; and UnsupportedOperation, which, as io's, a
|
|
41
|
+
# program cannot name (lib/compatibility.md). The docstring is CPython 3.13.16's.
|
|
42
|
+
from io import (DEFAULT_BUFFER_SIZE, BlockingIOError, open, text_encoding, StringIO, BytesIO, TextIOWrapper,
|
|
43
|
+
IncrementalNewlineDecoder)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""Abstract Base Classes (ABCs) according to PEP 3119."""
|
|
2
|
+
# abc for Pystachy: CPython imports abc as it starts, so a program's own abc.py is never imported
|
|
3
|
+
# there, and Pystachy loads this module for import abc (specs.STANDINS). Its classes are known as
|
|
4
|
+
# the program compiles, so the compiler applies what CPython's ABCMeta does at run time: a method
|
|
5
|
+
# decorated with abstractmethod in a class that derives from ABC, or whose class statement passes
|
|
6
|
+
# metaclass=ABCMeta, is abstract until a subclass defines it again, and making an object of a
|
|
7
|
+
# class that has an abstract method raises CPython's TypeError (Gen.abstracts). The docstrings
|
|
8
|
+
# are CPython 3.13.16's.
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def abstractmethod(funcobj):
|
|
12
|
+
"""A decorator indicating abstract methods.
|
|
13
|
+
|
|
14
|
+
Requires that the metaclass is ABCMeta or derived from it. A
|
|
15
|
+
class that has a metaclass derived from ABCMeta cannot be
|
|
16
|
+
instantiated unless all of its abstract methods are overridden.
|
|
17
|
+
The abstract methods can be called using any of the normal
|
|
18
|
+
'super' call mechanisms. abstractmethod() may be used to declare
|
|
19
|
+
abstract methods for properties and descriptors.
|
|
20
|
+
|
|
21
|
+
Usage:
|
|
22
|
+
|
|
23
|
+
class C(metaclass=ABCMeta):
|
|
24
|
+
@abstractmethod
|
|
25
|
+
def my_abstract_method(self, arg1, arg2, argN):
|
|
26
|
+
...
|
|
27
|
+
"""
|
|
28
|
+
return funcobj
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def abstractclassmethod(callable):
|
|
32
|
+
"""A decorator indicating abstract classmethods.
|
|
33
|
+
|
|
34
|
+
Deprecated, use 'classmethod' with 'abstractmethod' instead:
|
|
35
|
+
|
|
36
|
+
class C(ABC):
|
|
37
|
+
@classmethod
|
|
38
|
+
@abstractmethod
|
|
39
|
+
def my_abstract_classmethod(cls, ...):
|
|
40
|
+
...
|
|
41
|
+
|
|
42
|
+
"""
|
|
43
|
+
return callable # (a method's is @classmethod @abstractmethod, which the compiler applies)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def abstractstaticmethod(callable):
|
|
47
|
+
"""A decorator indicating abstract staticmethods.
|
|
48
|
+
|
|
49
|
+
Deprecated, use 'staticmethod' with 'abstractmethod' instead:
|
|
50
|
+
|
|
51
|
+
class C(ABC):
|
|
52
|
+
@staticmethod
|
|
53
|
+
@abstractmethod
|
|
54
|
+
def my_abstract_staticmethod(...):
|
|
55
|
+
...
|
|
56
|
+
|
|
57
|
+
"""
|
|
58
|
+
return callable # (a method's is @staticmethod @abstractmethod)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def abstractproperty(fget):
|
|
62
|
+
"""A decorator indicating abstract properties.
|
|
63
|
+
|
|
64
|
+
Deprecated, use 'property' with 'abstractmethod' instead:
|
|
65
|
+
|
|
66
|
+
class C(ABC):
|
|
67
|
+
@property
|
|
68
|
+
@abstractmethod
|
|
69
|
+
def my_abstract_property(self):
|
|
70
|
+
...
|
|
71
|
+
|
|
72
|
+
"""
|
|
73
|
+
return fget # (a method's is @property @abstractmethod)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class ABCMeta:
|
|
77
|
+
"""Metaclass for defining Abstract Base Classes (ABCs).
|
|
78
|
+
|
|
79
|
+
Use this metaclass to create an ABC. An ABC can be subclassed
|
|
80
|
+
directly, and then acts as a mix-in class. You can also register
|
|
81
|
+
unrelated concrete classes (even built-in classes) and unrelated
|
|
82
|
+
ABCs as 'virtual subclasses' -- these and their descendants will
|
|
83
|
+
be considered subclasses of the registering ABC by the built-in
|
|
84
|
+
issubclass() function, but the registering ABC won't show up in
|
|
85
|
+
their MRO (Method Resolution Order) nor will method
|
|
86
|
+
implementations defined by the registering ABC be callable (not
|
|
87
|
+
even via super()).
|
|
88
|
+
"""
|
|
89
|
+
__slots__ = ()
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def get_cache_token() -> int:
|
|
93
|
+
"""Returns the current ABC cache token.
|
|
94
|
+
|
|
95
|
+
The token is an opaque object (supporting equality testing) identifying
|
|
96
|
+
the current version of the ABC cache for virtual subclasses. The token
|
|
97
|
+
changes with every call to register() on any ABC."""
|
|
98
|
+
return 0 # (no class is registered: register() is not supported)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class ABC:
|
|
102
|
+
"""Helper class that provides a standard way to create an ABC using
|
|
103
|
+
inheritance.
|
|
104
|
+
"""
|
|
105
|
+
__slots__ = ()
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""allow programmer to define multiple exit functions to be executed
|
|
2
|
+
upon normal program termination.
|
|
3
|
+
|
|
4
|
+
Two public functions, register and unregister, are defined.
|
|
5
|
+
"""
|
|
6
|
+
# atexit for Pystachy: CPython builds atexit into its interpreter (Modules/atexitmodule.c), so
|
|
7
|
+
# Pystachy loads this port of it for import atexit (specs.STANDINS). The callbacks are Callables,
|
|
8
|
+
# each a closure that calls a registered function with its arguments. The program's main
|
|
9
|
+
# function gives the runtime the address of _hook (Gen.lower_module), and pys_finish calls it at the
|
|
10
|
+
# end of the program, as CPython's finalization calls the callbacks: after the program's code,
|
|
11
|
+
# also where it ends with sys.exit() or an exception that nothing catches, whose message comes
|
|
12
|
+
# first. The docstrings are CPython 3.13.16's.
|
|
13
|
+
import sys
|
|
14
|
+
from typing import Callable
|
|
15
|
+
|
|
16
|
+
__all__ = ["register", "unregister", "_clear", "_run_exitfuncs", "_ncallbacks"]
|
|
17
|
+
|
|
18
|
+
_callbacks: list[Callable[[], None]] = []
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def register(func, /, *args, **kwargs):
|
|
22
|
+
"""Register a function to be executed upon normal program termination
|
|
23
|
+
|
|
24
|
+
func - function to be called at exit
|
|
25
|
+
args - optional arguments to pass to func
|
|
26
|
+
kwargs - optional keyword arguments to pass to func
|
|
27
|
+
|
|
28
|
+
func is returned to facilitate usage as a decorator."""
|
|
29
|
+
def call() -> None:
|
|
30
|
+
func(*args, **kwargs)
|
|
31
|
+
_callbacks.append(call)
|
|
32
|
+
return func
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def unregister(func, /) -> None:
|
|
36
|
+
"""Unregister an exit function which was previously registered using
|
|
37
|
+
atexit.register
|
|
38
|
+
|
|
39
|
+
func - function to be unregistered"""
|
|
40
|
+
raise NotImplementedError("atexit.unregister() is not supported: Pystachy keeps the callbacks as closures, which no function compares equal to")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _clear() -> None:
|
|
44
|
+
"""Clear the list of previously registered exit functions."""
|
|
45
|
+
_callbacks.clear()
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _run_exitfuncs() -> None:
|
|
49
|
+
"""Run all registered exit functions.
|
|
50
|
+
|
|
51
|
+
If a callback raises an exception, it is logged with sys.unraisablehook."""
|
|
52
|
+
# the last registered first, as CPython's, which leaves out those registered meanwhile and
|
|
53
|
+
# stops where a callback clears the list; an exception is reported and the next one runs
|
|
54
|
+
i = len(_callbacks) - 1
|
|
55
|
+
while i >= 0:
|
|
56
|
+
if i < len(_callbacks):
|
|
57
|
+
cb = _callbacks[i]
|
|
58
|
+
try:
|
|
59
|
+
cb()
|
|
60
|
+
except BaseException as e:
|
|
61
|
+
# (CPython's report names the function and shows the traceback; this shows the
|
|
62
|
+
# exception's last line, as Pystachy shows an exception that nothing catches)
|
|
63
|
+
m = str(e)
|
|
64
|
+
print("Exception ignored in atexit callback:", file=sys.stderr)
|
|
65
|
+
print(type(e).__name__ + (": " + m if m != "" else ""), file=sys.stderr)
|
|
66
|
+
i -= 1
|
|
67
|
+
_callbacks.clear()
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _ncallbacks() -> int:
|
|
71
|
+
"""Return the number of registered exit functions."""
|
|
72
|
+
return len(_callbacks)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
# (what the runtime calls at the end of the program: Gen.lower_module)
|
|
76
|
+
_hook: Callable[[], None] = _run_exitfuncs
|