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.
Files changed (158) hide show
  1. _pystachy_source/VERSION +1 -0
  2. _pystachy_source/lib/_argparse_help.py +188 -0
  3. _pystachy_source/lib/_markupbase.py +399 -0
  4. _pystachy_source/lib/_pyrandom.py +272 -0
  5. _pystachy_source/lib/_pystachy__io.py +43 -0
  6. _pystachy_source/lib/_pystachy_abc.py +105 -0
  7. _pystachy_source/lib/_pystachy_atexit.py +76 -0
  8. _pystachy_source/lib/_pystachy_bfile.py +245 -0
  9. _pystachy_source/lib/_pystachy_binascii.py +412 -0
  10. _pystachy_source/lib/_pystachy_bytescan.py +28 -0
  11. _pystachy_source/lib/_pystachy_codecs.py +524 -0
  12. _pystachy_source/lib/_pystachy_copy.py +43 -0
  13. _pystachy_source/lib/_pystachy_iterators.py +207 -0
  14. _pystachy_source/lib/_pystachy_itertools.py +996 -0
  15. _pystachy_source/lib/_pystachy_json_any.py +271 -0
  16. _pystachy_source/lib/_pystachy_json_int.py +6 -0
  17. _pystachy_source/lib/_pystachy_mappingproxy.py +94 -0
  18. _pystachy_source/lib/_pystachy_object.py +13 -0
  19. _pystachy_source/lib/_pystachy_percent.py +343 -0
  20. _pystachy_source/lib/_pystachy_range.py +139 -0
  21. _pystachy_source/lib/_pystachy_re_specialized.py +33 -0
  22. _pystachy_source/lib/_pystachy_string.py +175 -0
  23. _pystachy_source/lib/_pystachy_struct.py +447 -0
  24. _pystachy_source/lib/_pystachy_thread.py +433 -0
  25. _pystachy_source/lib/_pystachy_time.py +15 -0
  26. _pystachy_source/lib/_pystachy_types.py +13 -0
  27. _pystachy_source/lib/_pystachy_unicodedata.py +873 -0
  28. _pystachy_source/lib/_pystachy_unicodedata_db.py +1371 -0
  29. _pystachy_source/lib/_pystachy_unicodedata_names.py +7634 -0
  30. _pystachy_source/lib/_pystachy_weakref.py +111 -0
  31. _pystachy_source/lib/_weakrefset.py +205 -0
  32. _pystachy_source/lib/argparse.py +315 -0
  33. _pystachy_source/lib/bisect.py +118 -0
  34. _pystachy_source/lib/codecs.py +1135 -0
  35. _pystachy_source/lib/collections/__init__.py +1282 -0
  36. _pystachy_source/lib/colorsys.py +166 -0
  37. _pystachy_source/lib/contextlib.py +300 -0
  38. _pystachy_source/lib/copy.py +213 -0
  39. _pystachy_source/lib/csv.py +1039 -0
  40. _pystachy_source/lib/curses/__init__.py +4 -0
  41. _pystachy_source/lib/curses/ascii.py +99 -0
  42. _pystachy_source/lib/datetime.py +3044 -0
  43. _pystachy_source/lib/difflib.py +2083 -0
  44. _pystachy_source/lib/enum.py +854 -0
  45. _pystachy_source/lib/fnmatch.py +249 -0
  46. _pystachy_source/lib/functools.py +407 -0
  47. _pystachy_source/lib/genericpath.py +200 -0
  48. _pystachy_source/lib/getopt.py +214 -0
  49. _pystachy_source/lib/gettext.py +657 -0
  50. _pystachy_source/lib/glob.py +224 -0
  51. _pystachy_source/lib/heapq.py +636 -0
  52. _pystachy_source/lib/html/__init__.py +149 -0
  53. _pystachy_source/lib/html/entities.py +2514 -0
  54. _pystachy_source/lib/html/parser.py +602 -0
  55. _pystachy_source/lib/io.py +1183 -0
  56. _pystachy_source/lib/json.py +843 -0
  57. _pystachy_source/lib/keyword.py +74 -0
  58. _pystachy_source/lib/logging/__init__.py +2506 -0
  59. _pystachy_source/lib/mpz.py +127 -0
  60. _pystachy_source/lib/operator.py +455 -0
  61. _pystachy_source/lib/pathlib.py +739 -0
  62. _pystachy_source/lib/posixpath.py +578 -0
  63. _pystachy_source/lib/pyobj.py +475 -0
  64. _pystachy_source/lib/random.py +1174 -0
  65. _pystachy_source/lib/re/__init__.py +2516 -0
  66. _pystachy_source/lib/re/_constants.py +111 -0
  67. _pystachy_source/lib/re/_sre.py +2108 -0
  68. _pystachy_source/lib/re/_unicode.py +304 -0
  69. _pystachy_source/lib/shlex.py +381 -0
  70. _pystachy_source/lib/shutil.py +205 -0
  71. _pystachy_source/lib/stat.py +212 -0
  72. _pystachy_source/lib/statistics.py +1954 -0
  73. _pystachy_source/lib/string.py +352 -0
  74. _pystachy_source/lib/struct.py +15 -0
  75. _pystachy_source/lib/textwrap.py +520 -0
  76. _pystachy_source/lib/this.py +28 -0
  77. _pystachy_source/lib/threading.py +1674 -0
  78. _pystachy_source/lib/token.py +166 -0
  79. _pystachy_source/lib/tomllib/__init__.py +10 -0
  80. _pystachy_source/lib/tomllib/_parser.py +732 -0
  81. _pystachy_source/lib/tomllib/_re.py +114 -0
  82. _pystachy_source/lib/tomllib/_types.py +13 -0
  83. _pystachy_source/lib/traceback.py +184 -0
  84. _pystachy_source/lib/types.py +49 -0
  85. _pystachy_source/lib/urllib/__init__.py +0 -0
  86. _pystachy_source/lib/urllib/parse.py +1713 -0
  87. _pystachy_source/lib/warnings.py +764 -0
  88. _pystachy_source/lib/weakref.py +539 -0
  89. _pystachy_source/mpz/mpz.c +463 -0
  90. _pystachy_source/pyembed.c +373 -0
  91. _pystachy_source/pyext.c +266 -0
  92. _pystachy_source/pystachy.py +34 -0
  93. _pystachy_source/pystachy_cli.py +31 -0
  94. _pystachy_source/pystachy_toolchain.py +152 -0
  95. _pystachy_source/runtime.c +8564 -0
  96. _pystachy_source/runtime.py +2276 -0
  97. _pystachy_source/ryu/common.h +114 -0
  98. _pystachy_source/ryu/d2s.c +509 -0
  99. _pystachy_source/ryu/d2s_intrinsics.h +357 -0
  100. _pystachy_source/ryu/d2s_small_table.h +186 -0
  101. _pystachy_source/ryu/digit_table.h +35 -0
  102. _pystachy_source/ryu/ryu.h +46 -0
  103. _pystachy_source/src/__init__.py +1 -0
  104. _pystachy_source/src/pystachy_compiler/__init__.py +1 -0
  105. _pystachy_source/src/pystachy_compiler/analysis.py +2105 -0
  106. _pystachy_source/src/pystachy_compiler/argparse_schema.py +393 -0
  107. _pystachy_source/src/pystachy_compiler/bigints.py +1498 -0
  108. _pystachy_source/src/pystachy_compiler/builtins.py +3026 -0
  109. _pystachy_source/src/pystachy_compiler/calls.py +1698 -0
  110. _pystachy_source/src/pystachy_compiler/containers.py +1256 -0
  111. _pystachy_source/src/pystachy_compiler/conversions.py +399 -0
  112. _pystachy_source/src/pystachy_compiler/declarations.py +3000 -0
  113. _pystachy_source/src/pystachy_compiler/diagnostics.py +176 -0
  114. _pystachy_source/src/pystachy_compiler/driver.py +921 -0
  115. _pystachy_source/src/pystachy_compiler/dynamic.py +4513 -0
  116. _pystachy_source/src/pystachy_compiler/emission.py +666 -0
  117. _pystachy_source/src/pystachy_compiler/exceptions.py +1642 -0
  118. _pystachy_source/src/pystachy_compiler/expressions.py +5153 -0
  119. _pystachy_source/src/pystachy_compiler/flow.py +972 -0
  120. _pystachy_source/src/pystachy_compiler/functions.py +523 -0
  121. _pystachy_source/src/pystachy_compiler/gen.py +5142 -0
  122. _pystachy_source/src/pystachy_compiler/generators.py +1361 -0
  123. _pystachy_source/src/pystachy_compiler/ir.py +579 -0
  124. _pystachy_source/src/pystachy_compiler/ircheck.py +503 -0
  125. _pystachy_source/src/pystachy_compiler/lexer.py +788 -0
  126. _pystachy_source/src/pystachy_compiler/llvm_abi.py +19 -0
  127. _pystachy_source/src/pystachy_compiler/loader.py +3787 -0
  128. _pystachy_source/src/pystachy_compiler/local_versions.py +57 -0
  129. _pystachy_source/src/pystachy_compiler/lower_module.py +754 -0
  130. _pystachy_source/src/pystachy_compiler/lowering.py +625 -0
  131. _pystachy_source/src/pystachy_compiler/memory_ir.py +28 -0
  132. _pystachy_source/src/pystachy_compiler/module.py +55 -0
  133. _pystachy_source/src/pystachy_compiler/names.py +55 -0
  134. _pystachy_source/src/pystachy_compiler/optimizations.py +1445 -0
  135. _pystachy_source/src/pystachy_compiler/parser.py +2465 -0
  136. _pystachy_source/src/pystachy_compiler/program.py +1296 -0
  137. _pystachy_source/src/pystachy_compiler/reflection.py +3073 -0
  138. _pystachy_source/src/pystachy_compiler/scalar_ir.py +61 -0
  139. _pystachy_source/src/pystachy_compiler/scope.py +619 -0
  140. _pystachy_source/src/pystachy_compiler/specs.py +1102 -0
  141. _pystachy_source/src/pystachy_compiler/statements.py +2126 -0
  142. _pystachy_source/src/pystachy_compiler/structs.py +271 -0
  143. _pystachy_source/src/pystachy_compiler/syntax.py +245 -0
  144. _pystachy_source/src/pystachy_compiler/templates.py +998 -0
  145. _pystachy_source/src/pystachy_compiler/union_arithmetic.py +161 -0
  146. _pystachy_source/src/pystachy_compiler/union_proof.py +891 -0
  147. _pystachy_source/src/pystachy_compiler/union_state.py +251 -0
  148. _pystachy_source/src/pystachy_compiler/unions.py +591 -0
  149. _pystachy_source/src/pystachy_compiler/utils.py +1124 -0
  150. _pystachy_source/src/pystachy_compiler/variables.py +2323 -0
  151. pystachy-0.2.0.dist-info/METADATA +93 -0
  152. pystachy-0.2.0.dist-info/RECORD +158 -0
  153. pystachy-0.2.0.dist-info/WHEEL +5 -0
  154. pystachy-0.2.0.dist-info/entry_points.txt +2 -0
  155. pystachy-0.2.0.dist-info/licenses/LICENSE +21 -0
  156. pystachy-0.2.0.dist-info/licenses/THIRD_PARTY_NOTICES +1051 -0
  157. pystachy-0.2.0.dist-info/licenses/ryu/LICENSE-Boost +23 -0
  158. 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