Nymbo/self-hosted-python
1
1/**2 * Is the argument a :any:`PyProxy`?3 * @param jsobj {any} Object to test.4 * @returns {jsobj is PyProxy} Is ``jsobj`` a :any:`PyProxy`?5 */6export function isPyProxy(jsobj: any): jsobj is PyProxy;7/**8 * @typedef {Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array} TypedArray;9 */10/**11 * A class to allow access to a Python data buffers from JavaScript. These are12 * produced by :any:`PyProxy.getBuffer` and cannot be constructed directly.13 * When you are done, release it with the :any:`release <PyBuffer.release>`14 * method. See15 * `Python buffer protocol documentation16 * <https://docs.python.org/3/c-api/buffer.html>`_ for more information.17 *18 * To find the element ``x[a_1, ..., a_n]``, you could use the following code:19 *20 * .. code-block:: js21 *22 * function multiIndexToIndex(pybuff, multiIndex){23 * if(multindex.length !==pybuff.ndim){24 * throw new Error("Wrong length index");25 * }26 * let idx = pybuff.offset;27 * for(let i = 0; i < pybuff.ndim; i++){28 * if(multiIndex[i] < 0){29 * multiIndex[i] = pybuff.shape[i] - multiIndex[i];30 * }31 * if(multiIndex[i] < 0 || multiIndex[i] >= pybuff.shape[i]){32 * throw new Error("Index out of range");33 * }34 * idx += multiIndex[i] * pybuff.stride[i];35 * }36 * return idx;37 * }38 * console.log("entry is", pybuff.data[multiIndexToIndex(pybuff, [2, 0, -1])]);39 *40 * .. admonition:: Contiguity41 * :class: warning42 *43 * If the buffer is not contiguous, the ``data`` TypedArray will contain44 * data that is not part of the buffer. Modifying this data may lead to45 * undefined behavior.46 *47 * .. admonition:: Readonly buffers48 * :class: warning49 *50 * If ``buffer.readonly`` is ``true``, you should not modify the buffer.51 * Modifying a readonly buffer may lead to undefined behavior.52 *53 * .. admonition:: Converting between TypedArray types54 * :class: warning55 *56 * The following naive code to change the type of a typed array does not57 * work:58 *59 * .. code-block:: js60 *61 * // Incorrectly convert a TypedArray.62 * // Produces a Uint16Array that points to the entire WASM memory!63 * let myarray = new Uint16Array(buffer.data.buffer);64 *65 * Instead, if you want to convert the output TypedArray, you need to say:66 *67 * .. code-block:: js68 *69 * // Correctly convert a TypedArray.70 * let myarray = new Uint16Array(71 * buffer.data.buffer,72 * buffer.data.byteOffset,73 * buffer.data.byteLength74 * );75 */76export class PyBuffer {77 /**78 * The offset of the first entry of the array. For instance if our array79 * is 3d, then you will find ``array[0,0,0]`` at80 * ``pybuf.data[pybuf.offset]``81 * @type {number}82 */83 offset: number;84 /**85 * If the data is readonly, you should not modify it. There is no way86 * for us to enforce this, but it may cause very weird behavior.87 * @type {boolean}88 */89 readonly: boolean;90 /**91 * The format string for the buffer. See `the Python documentation on92 * format strings93 * <https://docs.python.org/3/library/struct.html#format-strings>`_.94 * @type {string}95 */96 format: string;97 /**98 * How large is each entry (in bytes)?99 * @type {number}100 */101 itemsize: number;102 /**103 * The number of dimensions of the buffer. If ``ndim`` is 0, the buffer104 * represents a single scalar or struct. Otherwise, it represents an105 * array.106 * @type {number}107 */108 ndim: number;109 /**110 * The total number of bytes the buffer takes up. This is equal to111 * ``buff.data.byteLength``.112 * @type {number}113 */114 nbytes: number;115 /**116 * The shape of the buffer, that is how long it is in each dimension.117 * The length will be equal to ``ndim``. For instance, a 2x3x4 array118 * would have shape ``[2, 3, 4]``.119 * @type {number[]}120 */121 shape: number[];122 /**123 * An array of of length ``ndim`` giving the number of elements to skip124 * to get to a new element in each dimension. See the example definition125 * of a ``multiIndexToIndex`` function above.126 * @type {number[]}127 */128 strides: number[];129 /**130 * The actual data. A typed array of an appropriate size backed by a131 * segment of the WASM memory.132 *133 * The ``type`` argument of :any:`PyProxy.getBuffer`134 * determines which sort of ``TypedArray`` this is. By default135 * :any:`PyProxy.getBuffer` will look at the format string to determine the most136 * appropriate option.137 * @type {TypedArray}138 */139 data: TypedArray;140 /**141 * Is it C contiguous?142 * @type {boolean}143 */144 c_contiguous: boolean;145 /**146 * Is it Fortran contiguous?147 * @type {boolean}148 */149 f_contiguous: boolean;150 /**151 * Release the buffer. This allows the memory to be reclaimed.152 */153 release(): void;154 _released: boolean;155}156export type PyProxy = PyProxyClass & {157 [x: string]: Py2JsResult;158};159export type Py2JsResult = PyProxy | number | bigint | string | boolean | undefined;160export type PyProxyWithLength = PyProxy & PyProxyLengthMethods;161export type PyProxyWithGet = PyProxy & PyProxyGetItemMethods;162export type PyProxyWithSet = PyProxy & PyProxySetItemMethods;163export type PyProxyWithHas = PyProxy & PyProxyContainsMethods;164export type PyProxyIterable = PyProxy & PyProxyIterableMethods;165export type PyProxyIterator = PyProxy & PyProxyIteratorMethods;166export type PyProxyAwaitable = PyProxy & Promise<Py2JsResult>;167export type PyProxyCallable = PyProxyClass & {168 [x: string]: Py2JsResult;169} & PyProxyCallableMethods & ((...args: any[]) => Py2JsResult);170export type PyProxyBuffer = PyProxy & PyProxyBufferMethods;171/**172 * ;173 */174export type TypedArray = Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array;175/**176 * @typedef {(PyProxyClass & {[x : string] : Py2JsResult})} PyProxy177 * @typedef { PyProxy | number | bigint | string | boolean | undefined } Py2JsResult178 */179declare class PyProxyClass {180 /**181 * The name of the type of the object.182 *183 * Usually the value is ``"module.name"`` but for builtins or184 * interpreter-defined types it is just ``"name"``. As pseudocode this is:185 *186 * .. code-block:: python187 *188 * ty = type(x)189 * if ty.__module__ == 'builtins' or ty.__module__ == "__main__":190 * return ty.__name__191 * else:192 * ty.__module__ + "." + ty.__name__193 *194 * @type {string}195 */196 get type(): string;197 /**198 * @returns {string}199 */200 toString(): string;201 /**202 * Destroy the ``PyProxy``. This will release the memory. Any further203 * attempt to use the object will raise an error.204 *205 * In a browser supporting `FinalizationRegistry206 * <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry>`_207 * Pyodide will automatically destroy the ``PyProxy`` when it is garbage208 * collected, however there is no guarantee that the finalizer will be run209 * in a timely manner so it is better to ``destroy`` the proxy explicitly.210 *211 * @param {string} [destroyed_msg] The error message to print if use is212 * attempted after destroying. Defaults to "Object has already been213 * destroyed".214 */215 destroy(destroyed_msg?: string): void;216 /**217 * Make a new PyProxy pointing to the same Python object.218 * Useful if the PyProxy is destroyed somewhere else.219 * @returns {PyProxy}220 */221 copy(): PyProxy;222 /**223 * Converts the ``PyProxy`` into a JavaScript object as best as possible. By224 * default does a deep conversion, if a shallow conversion is desired, you can225 * use ``proxy.toJs({depth : 1})``. See :ref:`Explicit Conversion of PyProxy226 * <type-translations-pyproxy-to-js>` for more info.227 *228 * @param {object} options229 * @param {number} [options.depth] How many layers deep to perform the230 * conversion. Defaults to infinite.231 * @param {array} [options.pyproxies] If provided, ``toJs`` will store all232 * PyProxies created in this list. This allows you to easily destroy all the233 * PyProxies by iterating the list without having to recurse over the234 * generated structure. The most common use case is to create a new empty235 * list, pass the list as `pyproxies`, and then later iterate over `pyproxies`236 * to destroy all of created proxies.237 * @param {boolean} [options.create_pyproxies] If false, ``toJs`` will throw a238 * ``ConversionError`` rather than producing a ``PyProxy``.239 * @param {boolean} [options.dict_converter] A function to be called on an240 * iterable of pairs ``[key, value]``. Convert this iterable of pairs to the241 * desired output. For instance, ``Object.fromEntries`` would convert the dict242 * to an object, ``Array.from`` converts it to an array of entries, and ``(it) =>243 * new Map(it)`` converts it to a ``Map`` (which is the default behavior).244 * @return {any} The JavaScript object resulting from the conversion.245 */246 toJs({ depth, pyproxies, create_pyproxies, dict_converter, }?: {247 depth?: number;248 pyproxies?: any[];249 create_pyproxies?: boolean;250 dict_converter?: boolean;251 }): any;252 /**253 * Check whether the :any:`PyProxy.length` getter is available on this PyProxy. A254 * Typescript type guard.255 * @returns {this is PyProxyWithLength}256 */257 supportsLength(): this is PyProxyWithLength;258 /**259 * Check whether the :any:`PyProxy.get` method is available on this PyProxy. A260 * Typescript type guard.261 * @returns {this is PyProxyWithGet}262 */263 supportsGet(): this is PyProxyWithGet;264 /**265 * Check whether the :any:`PyProxy.set` method is available on this PyProxy. A266 * Typescript type guard.267 * @returns {this is PyProxyWithSet}268 */269 supportsSet(): this is PyProxyWithSet;270 /**271 * Check whether the :any:`PyProxy.has` method is available on this PyProxy. A272 * Typescript type guard.273 * @returns {this is PyProxyWithHas}274 */275 supportsHas(): this is PyProxyWithHas;276 /**277 * Check whether the PyProxy is iterable. A Typescript type guard for278 * :any:`PyProxy.[Symbol.iterator]`.279 * @returns {this is PyProxyIterable}280 */281 isIterable(): this is PyProxyIterable;282 /**283 * Check whether the PyProxy is iterable. A Typescript type guard for284 * :any:`PyProxy.next`.285 * @returns {this is PyProxyIterator}286 */287 isIterator(): this is PyProxyIterator;288 /**289 * Check whether the PyProxy is awaitable. A Typescript type guard, if this290 * function returns true Typescript considers the PyProxy to be a ``Promise``.291 * @returns {this is PyProxyAwaitable}292 */293 isAwaitable(): this is PyProxyAwaitable;294 /**295 * Check whether the PyProxy is a buffer. A Typescript type guard for296 * :any:`PyProxy.getBuffer`.297 * @returns {this is PyProxyBuffer}298 */299 isBuffer(): this is PyProxyBuffer;300 /**301 * Check whether the PyProxy is a Callable. A Typescript type guard, if this302 * returns true then Typescript considers the Proxy to be callable of303 * signature ``(args... : any[]) => PyProxy | number | bigint | string |304 * boolean | undefined``.305 * @returns {this is PyProxyCallable}306 */307 isCallable(): this is PyProxyCallable;308 get [Symbol.toStringTag](): string;309}310/**311 * @typedef { PyProxy & PyProxyLengthMethods } PyProxyWithLength312 */313declare class PyProxyLengthMethods {314 /**315 * The length of the object.316 *317 * Present only if the proxied Python object has a ``__len__`` method.318 * @returns {number}319 */320 get length(): number;321}322/**323 * @typedef {PyProxy & PyProxyGetItemMethods} PyProxyWithGet324 */325/**326 * @interface327 */328declare class PyProxyGetItemMethods {329 /**330 * This translates to the Python code ``obj[key]``.331 *332 * Present only if the proxied Python object has a ``__getitem__`` method.333 *334 * @param {any} key The key to look up.335 * @returns {Py2JsResult} The corresponding value.336 */337 get(key: any): Py2JsResult;338}339/**340 * @typedef {PyProxy & PyProxySetItemMethods} PyProxyWithSet341 */342declare class PyProxySetItemMethods {343 /**344 * This translates to the Python code ``obj[key] = value``.345 *346 * Present only if the proxied Python object has a ``__setitem__`` method.347 *348 * @param {any} key The key to set.349 * @param {any} value The value to set it to.350 */351 set(key: any, value: any): void;352 /**353 * This translates to the Python code ``del obj[key]``.354 *355 * Present only if the proxied Python object has a ``__delitem__`` method.356 *357 * @param {any} key The key to delete.358 */359 delete(key: any): void;360}361/**362 * @typedef {PyProxy & PyProxyContainsMethods} PyProxyWithHas363 */364declare class PyProxyContainsMethods {365 /**366 * This translates to the Python code ``key in obj``.367 *368 * Present only if the proxied Python object has a ``__contains__`` method.369 *370 * @param {*} key The key to check for.371 * @returns {boolean} Is ``key`` present?372 */373 has(key: any): boolean;374}375/**376 * @typedef {PyProxy & PyProxyIterableMethods} PyProxyIterable377 */378declare class PyProxyIterableMethods {379 /**380 * This translates to the Python code ``iter(obj)``. Return an iterator381 * associated to the proxy. See the documentation for `Symbol.iterator382 * <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator>`_.383 *384 * Present only if the proxied Python object is iterable (i.e., has an385 * ``__iter__`` method).386 *387 * This will be used implicitly by ``for(let x of proxy){}``.388 *389 * @returns {Iterator<Py2JsResult, Py2JsResult, any>} An iterator for the proxied Python object.390 */391 [Symbol.iterator](): Iterator<Py2JsResult, Py2JsResult, any>;392}393/**394 * @typedef {PyProxy & PyProxyIteratorMethods} PyProxyIterator395 */396declare class PyProxyIteratorMethods {397 /**398 * This translates to the Python code ``next(obj)``. Returns the next value399 * of the generator. See the documentation for `Generator.prototype.next400 * <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator/next>`_.401 * The argument will be sent to the Python generator.402 *403 * This will be used implicitly by ``for(let x of proxy){}``.404 *405 * Present only if the proxied Python object is a generator or iterator406 * (i.e., has a ``send`` or ``__next__`` method).407 *408 * @param {any=} [value] The value to send to the generator. The value will be409 * assigned as a result of a yield expression.410 * @returns {IteratorResult<Py2JsResult, Py2JsResult>} An Object with two properties: ``done`` and ``value``.411 * When the generator yields ``some_value``, ``next`` returns ``{done :412 * false, value : some_value}``. When the generator raises a413 * ``StopIteration(result_value)`` exception, ``next`` returns ``{done :414 * true, value : result_value}``.415 */416 next(arg?: any): IteratorResult<Py2JsResult, Py2JsResult>;417 [Symbol.iterator](): PyProxyIteratorMethods;418}419/**420 * @typedef { PyProxy & PyProxyCallableMethods & ((...args : any[]) => Py2JsResult) } PyProxyCallable421 */422declare class PyProxyCallableMethods {423 apply(jsthis: any, jsargs: any): any;424 call(jsthis: any, ...jsargs: any[]): any;425 /**426 * Call the function with key word arguments.427 * The last argument must be an object with the keyword arguments.428 */429 callKwargs(...jsargs: any[]): any;430 prototype: Function;431}432/**433 * @typedef {PyProxy & PyProxyBufferMethods} PyProxyBuffer434 */435declare class PyProxyBufferMethods {436 /**437 * Get a view of the buffer data which is usable from JavaScript. No copy is438 * ever performed.439 *440 * Present only if the proxied Python object supports the `Python Buffer441 * Protocol <https://docs.python.org/3/c-api/buffer.html>`_.442 *443 * We do not support suboffsets, if the buffer requires suboffsets we will444 * throw an error. JavaScript nd array libraries can't handle suboffsets445 * anyways. In this case, you should use the :any:`toJs` api or copy the446 * buffer to one that doesn't use suboffets (using e.g.,447 * `numpy.ascontiguousarray448 * <https://numpy.org/doc/stable/reference/generated/numpy.ascontiguousarray.html>`_).449 *450 * If the buffer stores big endian data or half floats, this function will451 * fail without an explicit type argument. For big endian data you can use452 * ``toJs``. `DataViews453 * <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView>`_454 * have support for big endian data, so you might want to pass455 * ``'dataview'`` as the type argument in that case.456 *457 * @param {string=} [type] The type of the :any:`PyBuffer.data <pyodide.PyBuffer.data>` field in the458 * output. Should be one of: ``"i8"``, ``"u8"``, ``"u8clamped"``, ``"i16"``,459 * ``"u16"``, ``"i32"``, ``"u32"``, ``"i32"``, ``"u32"``, ``"i64"``,460 * ``"u64"``, ``"f32"``, ``"f64``, or ``"dataview"``. This argument is461 * optional, if absent ``getBuffer`` will try to determine the appropriate462 * output type based on the buffer `format string463 * <https://docs.python.org/3/library/struct.html#format-strings>`_.464 * @returns {PyBuffer} :any:`PyBuffer <pyodide.PyBuffer>`465 */466 getBuffer(type?: string | undefined): PyBuffer;467}468export {};469 