mirror of https://github.com/pyodide/pyodide.git
Switch to using sphinx-js fork (#4193)
This commit is contained in:
parent
53744b4906
commit
2bcd48c4c2
|
@ -18,4 +18,4 @@ build:
|
|||
os: ubuntu-20.04
|
||||
tools:
|
||||
python: "3.11"
|
||||
nodejs: "14"
|
||||
nodejs: "20"
|
||||
|
|
|
@ -21,7 +21,7 @@ issues and that future releases will have fewer breaking changes.
|
|||
We added full support for asyncio, including a new Python event loop that
|
||||
schedules tasks on the browser event loop, support for top level await in
|
||||
{any}`pyodide.runPythonAsync`, and implementations of `await` for {any}`JsProxy <pyodide.ffi.JsProxy>`
|
||||
and {js:class}`PyProxy`, so that it is possible to await a Python awaitable from
|
||||
and `PyProxy`, so that it is possible to await a Python awaitable from
|
||||
JavaScript and a JavaScript thenable from Python. This allows seamless
|
||||
interoperability:
|
||||
|
||||
|
@ -99,7 +99,7 @@ We added several new conversion APIs to give more explicit control over the
|
|||
foreign function interface. In particular, the goal was to make it easier for
|
||||
users to avoid leaking memory.
|
||||
|
||||
For the basic use cases, we have {js:meth}`PyProxy.toJs` and `JsProxy.to_py`
|
||||
For the basic use cases, we have `PyProxy.toJs` and `JsProxy.to_py`
|
||||
which respectively convert Python objects to JavaScript objects and JavaScript
|
||||
objects to Python objects. We also added also "wrong-way" conversion functions
|
||||
{any}`pyodide.to_js <pyodide.ffi.to_js>` and {any}`pyodide.toPy` which are particularly helpful for
|
||||
|
@ -110,7 +110,7 @@ The promise handler methods `JsProxy.then`, `JsProxy.catch`, and
|
|||
`JsProxy.finally_` were particularly hard to use without leaking memory so
|
||||
they have been updated with internal magic to automatically manage the memory.
|
||||
|
||||
For more advanced use cases where control over the life cycle of a {js:class}`PyProxy` is
|
||||
For more advanced use cases where control over the life cycle of a `PyProxy` is
|
||||
needed, there are {any}`create_proxy` and {any}`create_once_callable`.
|
||||
|
||||
(Added in PRs {pr}`1186`, {pr}`1244`, {pr}`1344`, {pr}`1436`)
|
||||
|
@ -150,7 +150,7 @@ The buffer translation code in previous versions was less flexible, leaked memor
|
|||
and had serious bugs including use after free ({issue}`749`) and buffer overflow errors.
|
||||
|
||||
We completely reworked these: buffers are now proxied like most other objects.
|
||||
In simple use cases they can be converted with a copy using {js:meth}`PyProxy.toJs`
|
||||
In simple use cases they can be converted with a copy using `PyProxy.toJs`
|
||||
and `JsProxy.to_py`. We added new APIs `PyProxy.getBuffer`,
|
||||
`JsProxy.assign`, and `JsProxy.assign_to` which give more fine-grained
|
||||
control, though they are not yet as ergonomic as they could be.
|
||||
|
|
|
@ -8,7 +8,6 @@ sphinx_book_theme>=0.4.0rc1
|
|||
# A dependency of the above theme, which had some breaking changes in 0.13.2
|
||||
pydata_sphinx_theme < 0.13.2
|
||||
sphinx-issues
|
||||
sphinx-js>=3.2.1
|
||||
sphinx-click
|
||||
sphinx-autodoc-typehints>=1.21.7
|
||||
sphinx-design>=0.3.0
|
||||
|
@ -19,3 +18,4 @@ pydantic
|
|||
micropip==0.2.2
|
||||
jinja2>=3.0
|
||||
ruamel.yaml
|
||||
sphinx-js @ git+https://github.com/pyodide/sphinx-js-fork@3c02e364d3444c9c75ca68419d71237b61f3f5d8
|
||||
|
|
|
@ -2,6 +2,9 @@ from .jsdoc import (
|
|||
PyodideAnalyzer,
|
||||
get_jsdoc_content_directive,
|
||||
get_jsdoc_summary_directive,
|
||||
ts_post_convert,
|
||||
ts_should_destructure_arg,
|
||||
ts_xref_formatter,
|
||||
)
|
||||
from .lexers import HtmlPyodideLexer, PyodideLexer
|
||||
from .mdn_xrefs import add_mdn_xrefs
|
||||
|
@ -12,36 +15,6 @@ def wrap_analyzer(app):
|
|||
app._sphinxjs_analyzer = PyodideAnalyzer(app._sphinxjs_analyzer)
|
||||
|
||||
|
||||
def patch_templates():
|
||||
"""Patch in a different jinja2 loader so we can override templates with our
|
||||
own versions.
|
||||
"""
|
||||
from pathlib import Path
|
||||
|
||||
from jinja2 import ChoiceLoader, Environment, FileSystemLoader, PackageLoader
|
||||
from sphinx_js.analyzer_utils import dotted_path
|
||||
from sphinx_js.renderers import JsRenderer
|
||||
|
||||
loader = ChoiceLoader(
|
||||
[
|
||||
FileSystemLoader(Path(__file__).parent / "templates"),
|
||||
PackageLoader("sphinx_js", "templates"),
|
||||
]
|
||||
)
|
||||
env = Environment(loader=loader)
|
||||
|
||||
def patched_rst_method(self, partial_path, obj, use_short_name=False):
|
||||
"""Return rendered RST about an entity with the given name and IR
|
||||
object."""
|
||||
dotted_name = partial_path[-1] if use_short_name else dotted_path(partial_path)
|
||||
|
||||
# Render to RST using Jinja:
|
||||
template = env.get_template(self._template)
|
||||
return template.render(**self._template_vars(dotted_name, obj))
|
||||
|
||||
JsRenderer.rst = patched_rst_method
|
||||
|
||||
|
||||
def fix_pyodide_ffi_path():
|
||||
"""
|
||||
The `pyodide.ffi` stuff is defined in `_pyodide._core_docs`. We don't want
|
||||
|
@ -80,7 +53,6 @@ def remove_property_prefix():
|
|||
|
||||
|
||||
def setup(app):
|
||||
patch_templates()
|
||||
fix_pyodide_ffi_path()
|
||||
remove_property_prefix()
|
||||
app.add_lexer("pyodide", PyodideLexer)
|
||||
|
@ -91,3 +63,7 @@ def setup(app):
|
|||
app.add_directive("js-doc-content", get_jsdoc_content_directive(app))
|
||||
app.add_directive("pyodide-package-list", get_packages_summary_directive(app))
|
||||
app.connect("builder-inited", add_mdn_xrefs)
|
||||
app.config.ts_post_convert = ts_post_convert
|
||||
app.config.ts_should_destructure_arg = ts_should_destructure_arg
|
||||
app.config.ts_type_xref_formatter = ts_xref_formatter
|
||||
app.config.ts_type_bold = True
|
||||
|
|
|
@ -1,20 +1,17 @@
|
|||
import re
|
||||
from collections import OrderedDict
|
||||
from typing import Any
|
||||
|
||||
import docutils.parsers.rst.directives as directives
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import Directive
|
||||
from docutils.parsers.rst import Parser as RstParser
|
||||
from docutils.statemachine import StringList
|
||||
from docutils.utils import new_document
|
||||
from sphinx import addnodes
|
||||
from sphinx.domains.javascript import JavaScriptDomain, JSCallable
|
||||
from sphinx.ext.autosummary import autosummary_table, extract_summary
|
||||
from sphinx.util import rst
|
||||
from sphinx.util.docutils import switch_source_input
|
||||
from sphinx_js.ir import Class, Function, Interface, Pathname
|
||||
from sphinx_js.parsers import PathVisitor, path_and_formal_params
|
||||
from sphinx_js import ir, typedoc
|
||||
from sphinx_js.ir import Class, Function, Interface
|
||||
from sphinx_js.renderers import (
|
||||
AutoAttributeRenderer,
|
||||
AutoClassRenderer,
|
||||
|
@ -22,412 +19,118 @@ from sphinx_js.renderers import (
|
|||
JsRenderer,
|
||||
)
|
||||
from sphinx_js.typedoc import Analyzer as TsAnalyzer
|
||||
from sphinx_js.typedoc import make_path_segments
|
||||
from sphinx_js.typedoc import Base, Callable, Converter, ReflectionType
|
||||
|
||||
_orig_convert_node = TsAnalyzer._convert_node
|
||||
_orig_constructor_and_members = TsAnalyzer._constructor_and_members
|
||||
_orig_top_level_properties = TsAnalyzer._top_level_properties
|
||||
_orig_convert_all_nodes = TsAnalyzer._convert_all_nodes
|
||||
|
||||
|
||||
def _constructor_and_members(self, cls):
|
||||
result = _orig_constructor_and_members(self, cls)
|
||||
for tag in cls.get("comment", {}).get("tags", []):
|
||||
if tag["tag"] == "hideconstructor":
|
||||
return (None, result[1])
|
||||
return result
|
||||
|
||||
|
||||
TsAnalyzer._constructor_and_members = _constructor_and_members
|
||||
|
||||
commentdict = {}
|
||||
|
||||
FFI_FIELDS: set[str] = set()
|
||||
|
||||
|
||||
def _convert_all_nodes(self, root):
|
||||
for node in root.get("children", []):
|
||||
if node["name"] == "ffi":
|
||||
FFI_FIELDS.update(x["name"] for x in node["children"])
|
||||
FFI_FIELDS.remove("ffi")
|
||||
break
|
||||
return _orig_convert_all_nodes(self, root)
|
||||
|
||||
|
||||
TsAnalyzer._convert_all_nodes = _convert_all_nodes
|
||||
|
||||
|
||||
def _top_level_properties(self, node):
|
||||
if "comment" not in node:
|
||||
sig = {}
|
||||
if "getSignature" in node:
|
||||
sig = node["getSignature"][0]
|
||||
elif "signatures" in node:
|
||||
sig = node["signatures"][0]
|
||||
node["comment"] = sig.get("comment", {})
|
||||
path = str(Pathname(make_path_segments(node, self._base_dir)))
|
||||
commentdict[path] = node.get("comment") or {}
|
||||
result = _orig_top_level_properties(self, node)
|
||||
return result
|
||||
|
||||
|
||||
def get_tag(doclet, tag):
|
||||
tags = commentdict[str(doclet.path)].get("tags", [])
|
||||
for t in tags:
|
||||
if t["tag"] == tag:
|
||||
return True, t["text"]
|
||||
return False, None
|
||||
# Custom tags are a great way of conveniently passing information from the
|
||||
# source code to this file. No custom tags will be seen by this code unless they
|
||||
# are registered in src/js/tsdoc.json
|
||||
#
|
||||
# Modifier tags act like a flag, block tags have content.
|
||||
|
||||
|
||||
def has_tag(doclet, tag):
|
||||
return get_tag(doclet, tag)[0]
|
||||
|
||||
|
||||
TsAnalyzer._top_level_properties = _top_level_properties
|
||||
|
||||
orig_JsRenderer_rst_ = JsRenderer.rst
|
||||
|
||||
|
||||
def JsRenderer_rst(self, partial_path, obj, use_short_name=False):
|
||||
match get_tag(obj, "deprecated"):
|
||||
case (True, text):
|
||||
# This is definitely not unreachable...
|
||||
if not text.strip(): # type: ignore[unreachable]
|
||||
obj.deprecated = True
|
||||
else:
|
||||
obj.deprecated = text
|
||||
if has_tag(obj, "hidetype"):
|
||||
obj.type = ""
|
||||
return orig_JsRenderer_rst_(self, partial_path, obj, use_short_name)
|
||||
|
||||
|
||||
for cls in [AutoAttributeRenderer, AutoFunctionRenderer, AutoClassRenderer]:
|
||||
cls.rst = JsRenderer_rst
|
||||
|
||||
|
||||
def destructure_param(param: dict[str, Any]) -> list[dict[str, Any]]:
|
||||
"""We want to document a destructured argument as if it were several
|
||||
separate arguments. This finds complex inline object types in the arguments
|
||||
list of a function and "destructures" them into separately documented arguments.
|
||||
|
||||
E.g., a function
|
||||
|
||||
/**
|
||||
* @param options
|
||||
*/
|
||||
function f({x , y } : {
|
||||
/** The x value */
|
||||
x : number,
|
||||
/** The y value */
|
||||
y : string
|
||||
}){ ... }
|
||||
|
||||
should be documented like:
|
||||
|
||||
options.x (number) The x value
|
||||
options.y (number) The y value
|
||||
"""Detects whether the doclet comes from a node that has the given modifier
|
||||
tag.
|
||||
"""
|
||||
decl = param["type"]["declaration"]
|
||||
result = []
|
||||
for child in decl["children"]:
|
||||
child = dict(child)
|
||||
if "type" not in child:
|
||||
if "signatures" in child:
|
||||
try:
|
||||
child["comment"] = child["signatures"][0]["comment"]
|
||||
except KeyError:
|
||||
# TODO: handle no comment case
|
||||
pass
|
||||
child["type"] = {
|
||||
"type": "reflection",
|
||||
"declaration": dict(child),
|
||||
}
|
||||
else:
|
||||
raise AssertionError("Didn't expect to get here...")
|
||||
child["name"] = param["name"] + "." + child["name"]
|
||||
result.append(child)
|
||||
return result
|
||||
return ("@" + tag) in doclet.modifier_tags
|
||||
|
||||
|
||||
def fix_up_inline_object_signature(self: TsAnalyzer, node: dict[str, Any]) -> None:
|
||||
"""Calls get_destructured_children on inline object types"""
|
||||
kind = node.get("kindString")
|
||||
if kind not in ["Call signature", "Constructor signature"]:
|
||||
return
|
||||
params = node.get("parameters", [])
|
||||
new_params = []
|
||||
for param in params:
|
||||
if "@ignore" in param.get("comment", {}).get("shortText", ""):
|
||||
if not param.get("flags", {}).get("isOptional"):
|
||||
print("sphinx-pyodide warning: Hiding mandatory argument!")
|
||||
continue
|
||||
param_type = param["type"]
|
||||
if (
|
||||
param_type["type"] != "reflection"
|
||||
or "children" not in param_type["declaration"]
|
||||
):
|
||||
new_params.append(param)
|
||||
else:
|
||||
new_params.extend(destructure_param(param))
|
||||
node["parameters"] = new_params
|
||||
def member_properties(self):
|
||||
return dict(
|
||||
is_abstract=self.flags.isAbstract,
|
||||
is_optional=self.flags.isOptional,
|
||||
is_static=self.flags.isStatic,
|
||||
is_private=self.flags.isPrivate or self.flags.isExternal,
|
||||
)
|
||||
|
||||
|
||||
def _convert_node(self: TsAnalyzer, node: dict[str, Any]) -> Any:
|
||||
"""Monkey patch for TsAnalyzer._convert_node.
|
||||
|
||||
Fixes two crashes and separates documentation for destructured object
|
||||
arguments into a series of separate argument entries.
|
||||
"""
|
||||
kind = node.get("kindString")
|
||||
# if a class has no documented constructor, don't crash
|
||||
if kind in ["Function", "Constructor", "Method"] and not node.get("sources"):
|
||||
return None, []
|
||||
# This fixes a crash, not really sure what it means.
|
||||
node["extendedTypes"] = [t for t in node.get("extendedTypes", []) if "id" in t]
|
||||
# See docstring for destructure_param
|
||||
fix_up_inline_object_signature(self, node)
|
||||
converted, more_todo = _orig_convert_node(self, node)
|
||||
if not converted:
|
||||
return converted, more_todo
|
||||
converted.is_private = node.get("flags", {}).get("isPrivate", False)
|
||||
if kind in ["Call signature", "Constructor signature"]:
|
||||
tags = node.get("comment", {}).get("tags", [])
|
||||
converted.examples = [tag["text"] for tag in tags if tag["tag"] == "example"]
|
||||
return converted, more_todo
|
||||
Base.member_properties = member_properties
|
||||
|
||||
|
||||
TsAnalyzer._convert_node = _convert_node
|
||||
|
||||
from os.path import relpath
|
||||
def ts_should_destructure_arg(sig, param):
|
||||
return param.name == "options"
|
||||
|
||||
|
||||
def _containing_deppath(self, node):
|
||||
"""Return the path pointing to the module containing the given node.
|
||||
The path is absolute or relative to `root_for_relative_js_paths`.
|
||||
Raises ValueError if one isn't found.
|
||||
def ts_post_convert(converter, node, doclet):
|
||||
doclet.exported_from = None
|
||||
doclet.name = doclet.name.replace("Symbol․Symbol․", "Symbol․")
|
||||
|
||||
"""
|
||||
from pathlib import Path
|
||||
if has_tag(doclet, "hidetype"):
|
||||
doclet.type = ""
|
||||
if isinstance(node, typedoc.Callable):
|
||||
node.signatures[0].type = ""
|
||||
|
||||
filename = node["sources"][0]["fileName"].replace(".gen", "")
|
||||
deppath = next(Path(self._base_dir).glob("**/" + filename), None)
|
||||
if deppath:
|
||||
return relpath(deppath, self._base_dir)
|
||||
return ""
|
||||
if isinstance(doclet, ir.Class) and has_tag(doclet, "hideconstructor"):
|
||||
doclet.constructor = None
|
||||
|
||||
if node.name == "setStdin":
|
||||
fix_set_stdin(converter, node, doclet)
|
||||
|
||||
if node.name == "mountNativeFS":
|
||||
fix_native_fs(converter, node, doclet)
|
||||
|
||||
|
||||
TsAnalyzer._containing_deppath = _containing_deppath
|
||||
def fix_set_stdin(converter, node, doclet):
|
||||
assert isinstance(node, Callable)
|
||||
options = node.signatures[0].parameters[0]
|
||||
assert isinstance(options.type, ReflectionType)
|
||||
for param in options.type.declaration.children:
|
||||
if param.name == "stdin":
|
||||
break
|
||||
target = converter.index[param.type.target]
|
||||
for docparam in doclet.params:
|
||||
if docparam.name == "stdin":
|
||||
break
|
||||
docparam.type = target.type.render_name(converter)
|
||||
|
||||
|
||||
def _add_type_role(self, name):
|
||||
def fix_native_fs(converter, node, doclet):
|
||||
assert isinstance(node, Callable)
|
||||
ty = node.signatures[0].type
|
||||
target = converter.index[ty.typeArguments[0].target]
|
||||
ty.typeArguments[0] = target.type
|
||||
doclet.returns[0].type = ty.render_name(converter)
|
||||
|
||||
|
||||
orig_convert_all_nodes = Converter.convert_all_nodes
|
||||
|
||||
|
||||
def locate_ffi_fields(root):
|
||||
for node in root.children:
|
||||
if node.name == "js/ffi":
|
||||
break
|
||||
for child in node.children:
|
||||
if child.name == "ffi":
|
||||
break
|
||||
fields = child.type.declaration.children
|
||||
FFI_FIELDS.update(x.name for x in fields)
|
||||
|
||||
|
||||
# locate the ffi fields
|
||||
FFI_FIELDS: set[str] = set()
|
||||
|
||||
|
||||
def convert_all_nodes(self, root):
|
||||
locate_ffi_fields(root)
|
||||
return orig_convert_all_nodes(self, root)
|
||||
|
||||
|
||||
Converter.convert_all_nodes = convert_all_nodes
|
||||
|
||||
|
||||
def ts_xref_formatter(self, xref):
|
||||
from sphinx_pyodide.mdn_xrefs import JSDATA
|
||||
|
||||
name = xref.name
|
||||
if name == "PyodideInterface":
|
||||
return ":ref:`PyodideInterface <js-api-pyodide>`"
|
||||
if name in JSDATA:
|
||||
return f":js:data:`{name}`"
|
||||
if name in FFI_FIELDS:
|
||||
return f":js:class:`~pyodide.ffi.{name}`"
|
||||
return f":js:class:`{name}`"
|
||||
|
||||
|
||||
def object_literal_type_name(self, decl):
|
||||
"""This renders the names of object literal types.
|
||||
|
||||
They have zero or more "children" and zero or one "indexSignatures".
|
||||
For example:
|
||||
|
||||
{
|
||||
[key: string]: string,
|
||||
name : string,
|
||||
id : string
|
||||
}
|
||||
|
||||
has children "name" and "id" and an indexSignature "[key: string]: string"
|
||||
"""
|
||||
children = []
|
||||
if "indexSignature" in decl:
|
||||
index_sig = decl["indexSignature"]
|
||||
assert len(index_sig["parameters"]) == 1
|
||||
key = index_sig["parameters"][0]
|
||||
keyname = key["name"]
|
||||
keytype = self._type_name(key["type"])
|
||||
valuetype = self._type_name(index_sig["type"])
|
||||
children.append(rf"\ **[{keyname}:** {keytype}\ **]:** {valuetype}")
|
||||
if "children" in decl:
|
||||
for child in decl["children"]:
|
||||
maybe_optional = ""
|
||||
if child["flags"].get("isOptional"):
|
||||
maybe_optional = "?"
|
||||
if child["kindString"] == "Method":
|
||||
child_type_name = self.function_type_name(child)
|
||||
else:
|
||||
child_type_name = self._type_name(child["type"])
|
||||
children.append(
|
||||
r"\ **" + child["name"] + maybe_optional + ":** " + child_type_name
|
||||
)
|
||||
|
||||
return r"\ **{**\ " + r"\ **,** ".join(children) + r"\ **}**\ "
|
||||
|
||||
|
||||
def function_type_name(self, decl):
|
||||
decl_sig = None
|
||||
if "signatures" in decl:
|
||||
decl_sig = decl["signatures"][0]
|
||||
elif decl["kindString"] == "Call signature":
|
||||
decl_sig = decl
|
||||
assert decl_sig
|
||||
params = [
|
||||
rf'\ **{ty["name"]}:** {self._type_name(ty["type"])}'
|
||||
for ty in decl_sig.get("parameters", [])
|
||||
]
|
||||
params_str = r"\ **,** ".join(params)
|
||||
ret_str = self._type_name(decl_sig["type"])
|
||||
return rf"\ **(**\ {params_str}\ **) =>** {ret_str}"
|
||||
|
||||
|
||||
def reflection_type_name(self, type):
|
||||
"""Fill in the type names for type_of_type == "reflection"
|
||||
|
||||
This is left as a TODO in sphinx-js.
|
||||
|
||||
There are a couple of options: if
|
||||
|
||||
decl["kindString"] == "Type Literal"
|
||||
|
||||
then this is a literal object type. At least we assume it's a literal object
|
||||
type, maybe there are other ways for that to happen.
|
||||
|
||||
Otherwise, we assume that it's a function type, which we want to format
|
||||
like:
|
||||
|
||||
(a : string, b : number) => string
|
||||
"""
|
||||
decl = type["declaration"]
|
||||
if decl["kindString"] == "Type literal" and "signatures" not in decl:
|
||||
return self.object_literal_type_name(decl)
|
||||
return self.function_type_name(decl)
|
||||
|
||||
|
||||
def _type_name_root(self, type):
|
||||
type_of_type = type.get("type")
|
||||
|
||||
if type_of_type == "reference" and type.get("id"):
|
||||
node = self._index[type["id"]]
|
||||
name = node["name"]
|
||||
if node.get("flags", {}).get("isPrivate") and "type" in node:
|
||||
return self._type_name(node["type"])
|
||||
return self._add_type_role(name)
|
||||
if type_of_type == "unknown":
|
||||
if re.match(r"-?\d*(\.\d+)?", type["name"]): # It's a number.
|
||||
# TypeDoc apparently sticks numeric constants' values into
|
||||
# the type name. String constants? Nope. Function ones? Nope.
|
||||
return "number"
|
||||
return self._add_type_role(type["name"])
|
||||
if type_of_type in ["intrinsic", "reference"]:
|
||||
return self._add_type_role(type["name"])
|
||||
if type_of_type == "stringLiteral":
|
||||
return '"' + type["value"] + '"'
|
||||
if type_of_type == "array":
|
||||
return self._type_name(type["elementType"]) + r"\ **[]**"
|
||||
if type_of_type == "tuple" and type.get("elements"):
|
||||
types = [self._type_name(t) for t in type["elements"]]
|
||||
return r"\ **[**\ " + r"\ **,** ".join(types) + r"\ **]** "
|
||||
if type_of_type == "union":
|
||||
return r" **|** ".join(self._type_name(t) for t in type["types"])
|
||||
if type_of_type == "intersection":
|
||||
return " **&** ".join(self._type_name(t) for t in type["types"])
|
||||
if type_of_type == "typeOperator":
|
||||
return type["operator"] + " " + self._type_name(type["target"])
|
||||
# e.g. "keyof T"
|
||||
if type_of_type == "typeParameter":
|
||||
name = type["name"]
|
||||
constraint = type.get("constraint")
|
||||
if constraint is not None:
|
||||
name += " extends " + self._type_name(constraint)
|
||||
# e.g. K += extends + keyof T
|
||||
return name
|
||||
if type_of_type == "reflection":
|
||||
return self.reflection_type_name(type)
|
||||
if type_of_type == "named-tuple-member":
|
||||
name = type["name"]
|
||||
type = self._type_name(type["element"])
|
||||
return rf"\ **{name}:** {type}"
|
||||
if type_of_type == "predicate":
|
||||
return (
|
||||
f":js:data:`boolean` (typeguard for {self._type_name(type['targetType'])})"
|
||||
)
|
||||
if type_of_type == "literal" and type["value"] is None:
|
||||
return ":js:data:`null`"
|
||||
if type_of_type == "query":
|
||||
return f"``typeof {type['queryType']['name']}``"
|
||||
return "<TODO: other type>"
|
||||
|
||||
|
||||
def _type_name(self, type):
|
||||
"""Return a string description of a type.
|
||||
|
||||
:arg type: A TypeDoc-emitted type node
|
||||
|
||||
"""
|
||||
name = self._type_name_root(type)
|
||||
|
||||
type_args = type.get("typeArguments")
|
||||
if type_args:
|
||||
arg_names = ", ".join(self._type_name(arg) for arg in type_args)
|
||||
name += rf"\ **<**\ {arg_names}\ **>** "
|
||||
return name
|
||||
|
||||
|
||||
for obj in [
|
||||
_add_type_role,
|
||||
object_literal_type_name,
|
||||
reflection_type_name,
|
||||
_type_name_root,
|
||||
_type_name,
|
||||
function_type_name,
|
||||
]:
|
||||
setattr(TsAnalyzer, obj.__name__, obj)
|
||||
|
||||
|
||||
def _param_type_formatter(param):
|
||||
"""Generate types for function parameters specified in field."""
|
||||
if not param.type:
|
||||
return None
|
||||
heads = ["type", param.name]
|
||||
tail = param.type
|
||||
return heads, tail
|
||||
|
||||
|
||||
def _return_formatter(return_):
|
||||
"""Derive heads and tail from ``@returns`` blocks."""
|
||||
tail = ("%s -- " % return_.type) if return_.type else ""
|
||||
tail += return_.description
|
||||
return ["returns"], tail
|
||||
|
||||
|
||||
import sphinx_js.renderers
|
||||
|
||||
for obj in [_param_type_formatter, _return_formatter]: # type:ignore[assignment]
|
||||
setattr(sphinx_js.renderers, obj.__name__, obj)
|
||||
|
||||
|
||||
class JSFuncMaybeAsync(JSCallable):
|
||||
option_spec = {
|
||||
**JSCallable.option_spec,
|
||||
"async": directives.flag,
|
||||
}
|
||||
|
||||
def get_display_prefix(
|
||||
self,
|
||||
):
|
||||
if "async" in self.options:
|
||||
return [
|
||||
addnodes.desc_sig_keyword("async", "async"),
|
||||
addnodes.desc_sig_space(),
|
||||
]
|
||||
return []
|
||||
|
||||
|
||||
JavaScriptDomain.directives["function"] = JSFuncMaybeAsync
|
||||
result = f":js:data:`{name}`"
|
||||
elif name in FFI_FIELDS:
|
||||
result = f":js:class:`~pyodide.ffi.{name}`"
|
||||
else:
|
||||
result = f":js:class:`{name}`"
|
||||
return result
|
||||
|
||||
|
||||
def flatten_suffix_tree(tree):
|
||||
|
@ -478,13 +181,6 @@ class PyodideAnalyzer:
|
|||
def __getattr__(self, key):
|
||||
return getattr(self.inner, key)
|
||||
|
||||
def longname_to_path(self, name):
|
||||
"""Convert the longname field produced by jsdoc to a path appropriate to use
|
||||
with _sphinxjs_analyzer.get_object. Based on:
|
||||
https://github.com/mozilla/sphinx-js/blob/3.1/sphinx_js/jsdoc.py#L181
|
||||
"""
|
||||
return PathVisitor().visit(path_and_formal_params["path"].parse(name))
|
||||
|
||||
def set_doclet_is_private(self, key, doclet):
|
||||
if getattr(doclet, "is_private", False):
|
||||
return
|
||||
|
@ -493,6 +189,10 @@ class PyodideAnalyzer:
|
|||
key = [x for x in key if "/" not in x]
|
||||
filename = key[0]
|
||||
toplevelname = key[1]
|
||||
if doclet.name == "PyodideAPI":
|
||||
doclet.is_private = True
|
||||
return
|
||||
|
||||
if key[-1].startswith("$"):
|
||||
doclet.is_private = True
|
||||
return
|
||||
|
@ -536,14 +236,10 @@ class PyodideAnalyzer:
|
|||
if doclet.is_private:
|
||||
continue
|
||||
|
||||
key = [x for x in key if "/" not in x]
|
||||
filename = key[0]
|
||||
toplevelname = key[1]
|
||||
doclet.name = doclet.name.rpartition(".")[2]
|
||||
if doclet.name.startswith("["):
|
||||
# a symbol.
|
||||
# \u2024 looks like a period but is not a period.
|
||||
# This isn't ideal, but otherwise the coloring is weird.
|
||||
doclet.name = "[Symbol\u2024" + doclet.name[1:]
|
||||
|
||||
if filename == "pyodide.":
|
||||
items["globalThis"].append(doclet)
|
||||
|
@ -594,21 +290,15 @@ class PyodideAnalyzer:
|
|||
|
||||
for key, value in items.items():
|
||||
for obj in sorted(value, key=attrgetter("name")):
|
||||
_, kind = get_tag(obj, "dockind")
|
||||
kind = obj.block_tags.get("dockind", [None])[0]
|
||||
if kind:
|
||||
obj.kind = kind
|
||||
obj.kind = kind[0].text
|
||||
elif isinstance(obj, Class):
|
||||
obj.kind = "class"
|
||||
elif isinstance(obj, Function):
|
||||
obj.kind = "function"
|
||||
else:
|
||||
obj.kind = "attribute"
|
||||
|
||||
obj.async_ = False
|
||||
if isinstance(obj, Function):
|
||||
obj.async_ = obj.returns and obj.returns[0].type.startswith(
|
||||
":js:class:`Promise`"
|
||||
)
|
||||
self.js_docs[key][obj.kind].append(obj)
|
||||
|
||||
|
||||
|
@ -635,19 +325,8 @@ def get_jsdoc_content_directive(app):
|
|||
cls = AutoAttributeRenderer
|
||||
renderer = cls(self, app, arguments=["dummy"], options={"members": ["*"]})
|
||||
rst = renderer.rst([obj.name], obj, use_short_name=False)
|
||||
if obj.async_:
|
||||
rst = self.add_async_option_to_rst(rst)
|
||||
return rst
|
||||
|
||||
def add_async_option_to_rst(self, rst: str) -> str:
|
||||
rst_lines = rst.split("\n")
|
||||
try:
|
||||
index = next(i for i, ln in enumerate(rst_lines) if ln.startswith(".."))
|
||||
except StopIteration:
|
||||
index = len(rst_lines) - 1
|
||||
rst_lines.insert(index + 1, " :async:")
|
||||
return "\n".join(rst_lines)
|
||||
|
||||
def get_rst_for_group(self, objects):
|
||||
return [self.get_rst(obj) for obj in objects]
|
||||
|
||||
|
@ -739,10 +418,16 @@ def get_jsdoc_summary_directive(app):
|
|||
"""
|
||||
sig = self.get_sig(obj)
|
||||
display_name = obj.name
|
||||
prefix = "**async** " if obj.async_ else ""
|
||||
summary = self.extract_summary(obj.description)
|
||||
prefix = "**async** " if getattr(obj, "is_async", False) else ""
|
||||
qualifier = "any"
|
||||
if obj.name == "ffi":
|
||||
qualifier = "js:mod"
|
||||
|
||||
summary = self.extract_summary(
|
||||
JsRenderer.render_description(None, obj.description)
|
||||
)
|
||||
link_name = pkgname + "." + display_name
|
||||
return (prefix, display_name, sig, summary, link_name)
|
||||
return (prefix, qualifier, display_name, sig, summary, link_name)
|
||||
|
||||
def get_summary_table(self, pkgname, group):
|
||||
"""Get the data for a summary tget_summary_tableable. Return value
|
||||
|
@ -791,9 +476,8 @@ def get_jsdoc_summary_directive(app):
|
|||
row.append(nodes.entry("", node))
|
||||
body.append(row)
|
||||
|
||||
for prefix, name, sig, summary, real_name in items:
|
||||
for prefix, qualifier, name, sig, summary, real_name in items:
|
||||
# The body of this loop is changed from copied code.
|
||||
qualifier = "any"
|
||||
sig = rst.escape(sig)
|
||||
if sig:
|
||||
sig = f"**{sig}**"
|
||||
|
@ -824,7 +508,7 @@ def get_jsdoc_summary_directive(app):
|
|||
name = name.removeprefix("~")
|
||||
_, obj, *_ = self.import_by_name(name, prefixes=prefixes)
|
||||
prefix = "**async** " if iscoroutinefunction(obj) else ""
|
||||
new_items.append((prefix, *item))
|
||||
new_items.append((prefix, "any", *item))
|
||||
return new_items
|
||||
|
||||
Autosummary.get_items = get_items
|
||||
|
|
|
@ -13,11 +13,14 @@ DATA = {
|
|||
"Reflect.ownKeys": "$global/",
|
||||
"Array.from": "$global/",
|
||||
"Atomics.wait": "$global/",
|
||||
"getDirectory": "API/StorageManager/",
|
||||
"showDirectoryPicker": "API/Window/",
|
||||
},
|
||||
"js:class": {
|
||||
"Array": "$global/",
|
||||
"NodeList": "API/",
|
||||
"HTMLCollection": "API/",
|
||||
"HTMLCanvasElement": "API/",
|
||||
"Generator": "$global/",
|
||||
"AsyncGenerator": "$global/",
|
||||
"Date": "$global/",
|
||||
|
@ -56,6 +59,15 @@ DATA = {
|
|||
"Function.bind": "$global/",
|
||||
"Function.call": "$global/",
|
||||
"Array.join": "$global/",
|
||||
"Array.copyWithin": "$global/",
|
||||
"Array.fill": "$global/",
|
||||
"Array.pop": "$global/",
|
||||
"Array.push": "$global/",
|
||||
"Array.reverse": "$global/",
|
||||
"Array.shift": "$global/",
|
||||
"Array.sort": "$global/",
|
||||
"Array.splice": "$global/",
|
||||
"Array.unshift": "$global/",
|
||||
"Array.slice": "$global/",
|
||||
"Array.lastIndexOf": "$global/",
|
||||
"Array.indexOf": "$global/",
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
{% import 'common.rst' as common %}
|
||||
|
||||
.. js:attribute:: {{ name }}{{ '?' if is_optional else '' }}
|
||||
|
||||
{{ common.deprecated(deprecated)|indent(3) }}
|
||||
|
||||
{% if type -%}
|
||||
.. rst-class:: js attribute type
|
||||
|
||||
type: {{ type|indent(3) }}
|
||||
{%- endif %}
|
||||
|
||||
{% if description -%}
|
||||
{{ description|indent(3) }}
|
||||
{%- endif %}
|
||||
|
||||
{{ common.examples(examples)|indent(3) }}
|
||||
|
||||
{{ content|indent(3) }}
|
||||
|
||||
{{ common.see_also(see_also)|indent(3) }}
|
|
@ -13,6 +13,7 @@ if not hasattr(inspect, "getargspec"):
|
|||
|
||||
from sphinx_js.suffix_tree import SuffixTree
|
||||
from sphinx_js.typedoc import Analyzer as TsAnalyzer
|
||||
from sphinx_js.typedoc import Project
|
||||
|
||||
test_directory = Path(__file__).resolve().parent
|
||||
sys.path.append(str(test_directory.parent))
|
||||
|
@ -25,18 +26,28 @@ src_dir = test_directory.parents[2] / "src"
|
|||
# typedoc src/js/*.ts --tsconfig src/js/tsconfig.json --json docs/sphinx_pyodide/tests/tsdoc_dump.json
|
||||
# gzip docs/sphinx_pyodide/tests/tsdoc_dump.json
|
||||
# rm src/js/pyproxy.gen.ts
|
||||
with gzip.open(test_directory / "tsdoc_dump.json.gz") as fh:
|
||||
jsdoc_json = json.load(fh)
|
||||
settings_json = json.loads((test_directory / "app_settings.json").read_text())
|
||||
|
||||
|
||||
from sphinx_pyodide.jsdoc import (
|
||||
PyodideAnalyzer,
|
||||
flatten_suffix_tree,
|
||||
get_jsdoc_content_directive,
|
||||
get_jsdoc_summary_directive,
|
||||
ts_post_convert,
|
||||
ts_should_destructure_arg,
|
||||
ts_xref_formatter,
|
||||
)
|
||||
|
||||
inner_analyzer = TsAnalyzer(jsdoc_json, str(src_dir))
|
||||
with gzip.open(test_directory / "tsdoc_dump.json.gz") as fh:
|
||||
jsdoc_json = Project.parse_raw(fh.read())
|
||||
settings_json = json.loads((test_directory / "app_settings.json").read_text())
|
||||
|
||||
inner_analyzer = TsAnalyzer(
|
||||
jsdoc_json,
|
||||
str(src_dir),
|
||||
post_convert=ts_post_convert,
|
||||
should_destructure_arg=ts_should_destructure_arg,
|
||||
)
|
||||
settings = OptionParser().get_default_values()
|
||||
settings.update(settings_json, OptionParser())
|
||||
|
||||
|
@ -60,9 +71,14 @@ def test_flatten_suffix_tree():
|
|||
assert d == r
|
||||
|
||||
|
||||
class dummy_config:
|
||||
ts_type_xref_formatter = ts_xref_formatter
|
||||
|
||||
|
||||
class dummy_app:
|
||||
_sphinxjs_analyzer = pyodide_analyzer
|
||||
document = document
|
||||
config = dummy_config
|
||||
|
||||
|
||||
class dummy_state:
|
||||
|
@ -83,7 +99,7 @@ def test_pyodide_analyzer():
|
|||
"registerJsModule",
|
||||
"runPython",
|
||||
"runPythonAsync",
|
||||
"setDefaultStdout",
|
||||
"setDebug",
|
||||
"setInterruptBuffer",
|
||||
"setStderr",
|
||||
"setStdin",
|
||||
|
@ -97,6 +113,8 @@ def test_pyodide_analyzer():
|
|||
"ERRNO_CODES",
|
||||
"FS",
|
||||
"PATH",
|
||||
"canvas",
|
||||
"ffi",
|
||||
"version",
|
||||
"globals",
|
||||
"loadedPackages",
|
||||
|
@ -171,11 +189,12 @@ def test_summary():
|
|||
functions = jsdoc_summary.get_summary_table(
|
||||
"pyodide", dummy_app._sphinxjs_analyzer.js_docs["pyodide"]["function"]
|
||||
)
|
||||
globals = {t[1]: t for t in globals}
|
||||
attributes = {t[1]: t for t in attributes}
|
||||
functions = {t[1]: t for t in functions}
|
||||
globals = {t[2]: t for t in globals}
|
||||
attributes = {t[2]: t for t in attributes}
|
||||
functions = {t[2]: t for t in functions}
|
||||
assert globals["loadPyodide"] == (
|
||||
"**async** ",
|
||||
"any",
|
||||
"loadPyodide",
|
||||
"(options)",
|
||||
"Load the main Pyodide wasm module and initialize it.",
|
||||
|
@ -184,13 +203,15 @@ def test_summary():
|
|||
|
||||
assert attributes["pyodide_py"] == (
|
||||
"",
|
||||
"any",
|
||||
"pyodide_py",
|
||||
"",
|
||||
"An alias to the Python :py:mod:`pyodide` package.",
|
||||
"An alias to the Python :ref:`pyodide <python-api>` package.",
|
||||
"pyodide.pyodide_py",
|
||||
)
|
||||
assert attributes["version"] == (
|
||||
"",
|
||||
"any",
|
||||
"version",
|
||||
"",
|
||||
"The Pyodide version.",
|
||||
|
@ -198,6 +219,7 @@ def test_summary():
|
|||
)
|
||||
assert attributes["loadedPackages"] == (
|
||||
"",
|
||||
"any",
|
||||
"loadedPackages",
|
||||
"",
|
||||
"The list of packages that Pyodide has loaded.",
|
||||
|
@ -206,149 +228,7 @@ def test_summary():
|
|||
|
||||
assert functions["loadPackagesFromImports"][:-2] == (
|
||||
"**async** ",
|
||||
"any",
|
||||
"loadPackagesFromImports",
|
||||
"(code, options)",
|
||||
)
|
||||
|
||||
|
||||
def test_type_name():
|
||||
tn = inner_analyzer._type_name
|
||||
assert tn({"name": "void", "type": "intrinsic"}) == ":js:data:`void`"
|
||||
assert tn({"value": None, "type": "literal"}) == ":js:data:`null`"
|
||||
assert (
|
||||
tn(
|
||||
{
|
||||
"name": "Promise",
|
||||
"type": "reference",
|
||||
"typeArguments": [{"name": "string", "type": "intrinsic"}],
|
||||
}
|
||||
).strip()
|
||||
== r":js:class:`Promise`\ **<**\ :js:data:`string`\ **>**"
|
||||
)
|
||||
|
||||
assert (
|
||||
tn(
|
||||
{
|
||||
"asserts": False,
|
||||
"name": "jsobj",
|
||||
"targetType": {"name": "PyProxy", "type": "reference"},
|
||||
"type": "predicate",
|
||||
}
|
||||
).strip()
|
||||
== ":js:data:`boolean` (typeguard for :js:class:`PyProxy`)"
|
||||
)
|
||||
|
||||
assert (
|
||||
tn(
|
||||
{
|
||||
"declaration": {
|
||||
"kindString": "Method",
|
||||
"name": "messageCallback",
|
||||
"signatures": [
|
||||
{
|
||||
"kindString": "Call signature",
|
||||
"name": "messageCallback",
|
||||
"parameters": [
|
||||
{
|
||||
"flags": {},
|
||||
"kindString": "Parameter",
|
||||
"name": "message",
|
||||
"type": {"name": "string", "type": "intrinsic"},
|
||||
}
|
||||
],
|
||||
"type": {"name": "void", "type": "intrinsic"},
|
||||
}
|
||||
],
|
||||
},
|
||||
"type": "reflection",
|
||||
}
|
||||
).strip()
|
||||
== r"\ **(**\ \ **message:** :js:data:`string`\ **) =>** :js:data:`void`"
|
||||
)
|
||||
|
||||
assert (
|
||||
tn(
|
||||
{
|
||||
"name": "Iterable",
|
||||
"type": "reference",
|
||||
"typeArguments": [
|
||||
{
|
||||
"elements": [
|
||||
{
|
||||
"element": {"name": "string", "type": "intrinsic"},
|
||||
"isOptional": False,
|
||||
"name": "key",
|
||||
"type": "named-tuple-member",
|
||||
},
|
||||
{
|
||||
"element": {"name": "any", "type": "intrinsic"},
|
||||
"isOptional": False,
|
||||
"name": "value",
|
||||
"type": "named-tuple-member",
|
||||
},
|
||||
],
|
||||
"type": "tuple",
|
||||
}
|
||||
],
|
||||
}
|
||||
).strip()
|
||||
== r":js:data:`Iterable`\ **<**\ \ **[**\ \ **key:** :js:data:`string`\ **,** \ **value:** :js:data:`any`\ **]** \ **>**"
|
||||
)
|
||||
|
||||
assert (
|
||||
tn(
|
||||
{
|
||||
"declaration": {
|
||||
"flags": {},
|
||||
"indexSignature": {
|
||||
"flags": {},
|
||||
"kindString": "Index signature",
|
||||
"parameters": [
|
||||
{
|
||||
"flags": {},
|
||||
"name": "key",
|
||||
"type": {"name": "string", "type": "intrinsic"},
|
||||
}
|
||||
],
|
||||
"type": {"name": "string", "type": "intrinsic"},
|
||||
},
|
||||
"kindString": "Type literal",
|
||||
},
|
||||
"type": "reflection",
|
||||
}
|
||||
).strip()
|
||||
== r"""\ **{**\ \ **[key:** :js:data:`string`\ **]:** :js:data:`string`\ **}**\ """.strip()
|
||||
)
|
||||
|
||||
assert (
|
||||
tn(
|
||||
{
|
||||
"declaration": {
|
||||
"children": [
|
||||
{
|
||||
"flags": {},
|
||||
"kindString": "Property",
|
||||
"name": "cache",
|
||||
"type": {"name": "PyProxyCache", "type": "reference"},
|
||||
},
|
||||
{
|
||||
"flags": {"isOptional": True},
|
||||
"kindString": "Property",
|
||||
"name": "destroyed_msg",
|
||||
"type": {"name": "string", "type": "intrinsic"},
|
||||
},
|
||||
{
|
||||
"flags": {},
|
||||
"kindString": "Property",
|
||||
"name": "ptr",
|
||||
"type": {"name": "number", "type": "intrinsic"},
|
||||
},
|
||||
],
|
||||
"flags": {},
|
||||
"kindString": "Type literal",
|
||||
},
|
||||
"type": "reflection",
|
||||
}
|
||||
).strip()
|
||||
== r"""\ **{**\ \ **cache:** :js:class:`PyProxyCache`\ **,** \ **destroyed_msg?:** :js:data:`string`\ **,** \ **ptr:** :js:data:`number`\ **}**\ """.strip()
|
||||
)
|
||||
|
|
Binary file not shown.
|
@ -43,7 +43,7 @@ import type { PyProxy } from "pyodide/ffi";
|
|||
This provides APIs to set a canvas for rendering graphics.
|
||||
|
||||
For example, you need to set a canvas if you want to use the SDL library. See
|
||||
:ref:`using-sdl` for more information.
|
||||
{ref}`using-sdl` for more information.
|
||||
|
||||
```{eval-rst}
|
||||
.. js-doc-summary:: pyodide.canvas
|
||||
|
|
|
@ -571,12 +571,12 @@ An example of a case where you would not want to use the
|
|||
{js:func}`~pyodide.ffi.PyProxy.toJs` method is when the buffer is bitmapped
|
||||
image data. If for instance you have a 3d buffer shaped 1920 x 1080 x 4, then
|
||||
{js:func}`~pyodide.ffi.PyProxy.toJs` will be extremely slow. In this case you
|
||||
could use {js:func}`~pyodide.ffi.PyProxy.getBuffer`. On the other hand, if you
|
||||
could use {js:func}`~pyodide.ffi.PyBuffer.getBuffer`. On the other hand, if you
|
||||
have a 3d buffer shaped 1920 x 4 x 1080, the performance of
|
||||
{js:func}`~pyodide.ffi.PyProxy.toJs` will most likely be satisfactory.
|
||||
Typically, the innermost dimension won't matter for performance.
|
||||
|
||||
The {js:func}`~pyodide.ffi.PyProxy.getBuffer` method can be used to retrieve a reference to
|
||||
The {js:func}`~pyodide.ffi.PyBuffer.getBuffer` method can be used to retrieve a reference to
|
||||
a JavaScript typed array that points to the data backing the Python object,
|
||||
combined with other metadata about the buffer format. The metadata is suitable
|
||||
for use with a JavaScript ndarray library if one is present. For instance, if
|
||||
|
|
|
@ -10,12 +10,12 @@ from ..logger import logger
|
|||
|
||||
def recipe(
|
||||
packages: list[str] = typer.Argument(
|
||||
..., help="Packages to build, or * for all packages in recipe directory"
|
||||
..., help="Packages to build, or ``*`` for all packages in recipe directory"
|
||||
),
|
||||
recipe_dir: str = typer.Option(
|
||||
None,
|
||||
help="The directory containing the recipe of packages. "
|
||||
"If not specified, the default is `./packages`",
|
||||
"If not specified, the default is ``./packages``",
|
||||
),
|
||||
no_deps: bool = typer.Option(
|
||||
False, help="If true, do not build dependencies of the specified packages. "
|
||||
|
@ -28,13 +28,13 @@ def recipe(
|
|||
install_dir: str = typer.Option(
|
||||
None,
|
||||
help="Path to install built packages and pyodide-lock.json. "
|
||||
"If not specified, the default is `./dist`.",
|
||||
"If not specified, the default is ``./dist``.",
|
||||
),
|
||||
metadata_files: bool = typer.Option(
|
||||
False,
|
||||
help="If true, extract the METADATA file from the built wheels "
|
||||
"to a matching *.whl.metadata file. "
|
||||
"If false, no *.whl.metadata file is produced.",
|
||||
"to a matching ``*.whl.metadata`` file. "
|
||||
"If false, no ``*.whl.metadata`` file is produced.",
|
||||
),
|
||||
cflags: str = typer.Option(
|
||||
None, help="Extra compiling flags. Default: SIDE_MODULE_CFLAGS"
|
||||
|
|
|
@ -44,7 +44,7 @@ def new_recipe_pypi(
|
|||
recipe_dir: str = typer.Option(
|
||||
None,
|
||||
help="The directory containing the recipe of packages."
|
||||
"If not specified, the default is `<cwd>/packages`.",
|
||||
"If not specified, the default is ``<cwd>/packages``.",
|
||||
),
|
||||
) -> None:
|
||||
"""
|
||||
|
|
|
@ -280,7 +280,7 @@ Module.handle_js_error = function (e: any) {
|
|||
/**
|
||||
* A JavaScript error caused by a Python exception.
|
||||
*
|
||||
* In order to reduce the risk of large memory leaks, the :py:exc:`PythonError`
|
||||
* In order to reduce the risk of large memory leaks, the :js:class:`PythonError`
|
||||
* contains no reference to the Python exception that caused it. You can find
|
||||
* the actual Python exception that caused this error as
|
||||
* :py:data:`sys.last_value`.
|
||||
|
|
|
@ -192,7 +192,6 @@ const pyproxyAttrsSymbol = Symbol("pyproxy.attrs");
|
|||
* Function so that PyProxy objects can be callable. In that case we MUST expose
|
||||
* certain properties inherited from Function, but we do our best to remove as
|
||||
* many as possible.
|
||||
* @private
|
||||
*/
|
||||
function pyproxy_new(
|
||||
ptr: number,
|
||||
|
@ -344,7 +343,6 @@ let pyproxyClassMap = new Map();
|
|||
* pyproxy_getflags. Multiple PyProxies with the same set of feature flags
|
||||
* will share the same prototype, so the memory footprint of each individual
|
||||
* PyProxy is minimal.
|
||||
* @private
|
||||
*/
|
||||
Module.getPyProxyClass = function (flags: number) {
|
||||
const FLAG_TYPE_PAIRS: [number, any][] = [
|
||||
|
@ -556,14 +554,13 @@ export class PyProxy {
|
|||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @hideconstructor
|
||||
*/
|
||||
constructor() {
|
||||
throw new TypeError("PyProxy is not a constructor");
|
||||
}
|
||||
|
||||
/** @private */
|
||||
/** @hidden */
|
||||
get [Symbol.toStringTag]() {
|
||||
return "PyProxy";
|
||||
}
|
||||
|
@ -1033,7 +1030,6 @@ export class PyContainsMethods {
|
|||
* Quote from:
|
||||
* https://hacks.mozilla.org/2015/07/es6-in-depth-generators-continued/
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function* iter_helper(iterptr: number, token: {}): Generator<any> {
|
||||
try {
|
||||
|
@ -1122,7 +1118,6 @@ export class PyIterableMethods {
|
|||
* Quote from:
|
||||
* https://hacks.mozilla.org/2015/07/es6-in-depth-generators-continued/
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
async function* aiter_helper(iterptr: number, token: {}): AsyncGenerator<any> {
|
||||
try {
|
||||
|
@ -1573,6 +1568,7 @@ function defaultCompareFunc(a: any, b: any): number {
|
|||
// Missing:
|
||||
// flatMap, flat,
|
||||
export class PySequenceMethods {
|
||||
/** @hidden */
|
||||
get [Symbol.isConcatSpreadable]() {
|
||||
return true;
|
||||
}
|
||||
|
@ -1645,10 +1641,11 @@ export class PySequenceMethods {
|
|||
* return value is added as a single element in the new array.
|
||||
* @param thisArg A value to use as ``this`` when executing ``callbackFn``.
|
||||
*/
|
||||
map(
|
||||
callbackfn: (elt: any, index: number, array: any) => void,
|
||||
map<U>(
|
||||
callbackfn: (elt: any, index: number, array: any) => U,
|
||||
thisArg?: any,
|
||||
) {
|
||||
): U[] {
|
||||
// @ts-ignore
|
||||
return Array.prototype.map.call(this, callbackfn, thisArg);
|
||||
}
|
||||
/**
|
||||
|
@ -1842,22 +1839,23 @@ export interface PyMutableSequence extends PyMutableSequenceMethods {}
|
|||
|
||||
export class PyMutableSequenceMethods {
|
||||
/**
|
||||
* The :js:meth:`Array.reverse` method reverses a ``MutableSequence`` in
|
||||
* The :js:meth:`Array.reverse` method reverses a :js:class:`PyMutableSequence` in
|
||||
* place.
|
||||
* @returns A reference to the same ``MutableSequence``
|
||||
* @returns A reference to the same :js:class:`PyMutableSequence`
|
||||
*/
|
||||
reverse() {
|
||||
reverse(): PyMutableSequence {
|
||||
// @ts-ignore
|
||||
this.$reverse();
|
||||
// @ts-ignore
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* The :js:meth:`Array.sort` method sorts the elements of a
|
||||
* ``MutableSequence`` in place.
|
||||
* :js:class:`PyMutableSequence` in place.
|
||||
* @param compareFn A function that defines the sort order.
|
||||
* @returns A reference to the same ``MutableSequence``
|
||||
* @returns A reference to the same :js:class:`PyMutableSequence`
|
||||
*/
|
||||
sort(compareFn?: (a: any, b: any) => number) {
|
||||
sort(compareFn?: (a: any, b: any) => number): PyMutableSequence {
|
||||
// Copy the behavior of sort described here:
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#creating_displaying_and_sorting_an_array
|
||||
// Yes JS sort is weird.
|
||||
|
@ -1897,17 +1895,18 @@ export class PyMutableSequenceMethods {
|
|||
cmp_to_key.destroy();
|
||||
functools.destroy();
|
||||
}
|
||||
// @ts-ignore
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* The :js:meth:`Array.splice` method changes the contents of a
|
||||
* ``MutableSequence`` by removing or replacing existing elements and/or
|
||||
* :js:class:`PyMutableSequence` by removing or replacing existing elements and/or
|
||||
* adding new elements in place.
|
||||
* @param start Zero-based index at which to start changing the
|
||||
* ``MutableSequence``.
|
||||
* :js:class:`PyMutableSequence`.
|
||||
* @param deleteCount An integer indicating the number of elements in the
|
||||
* ``MutableSequence`` to remove from ``start``.
|
||||
* @param items The elements to add to the ``MutableSequence``, beginning from
|
||||
* :js:class:`PyMutableSequence` to remove from ``start``.
|
||||
* @param items The elements to add to the :js:class:`PyMutableSequence`, beginning from
|
||||
* ``start``.
|
||||
* @returns An array containing the deleted elements.
|
||||
*/
|
||||
|
@ -1920,8 +1919,8 @@ export class PyMutableSequenceMethods {
|
|||
}
|
||||
/**
|
||||
* The :js:meth:`Array.push` method adds the specified elements to the end of
|
||||
* a ``MutableSequence``.
|
||||
* @param elts The element(s) to add to the end of the ``MutableSequence``.
|
||||
* a :js:class:`PyMutableSequence`.
|
||||
* @param elts The element(s) to add to the end of the :js:class:`PyMutableSequence`.
|
||||
* @returns The new length property of the object upon which the method was
|
||||
* called.
|
||||
*/
|
||||
|
@ -1935,27 +1934,27 @@ export class PyMutableSequenceMethods {
|
|||
}
|
||||
/**
|
||||
* The :js:meth:`Array.pop` method removes the last element from a
|
||||
* ``MutableSequence``.
|
||||
* @returns The removed element from the ``MutableSequence``; undefined if the
|
||||
* ``MutableSequence`` is empty.
|
||||
* :js:class:`PyMutableSequence`.
|
||||
* @returns The removed element from the :js:class:`PyMutableSequence`; undefined if the
|
||||
* :js:class:`PyMutableSequence` is empty.
|
||||
*/
|
||||
pop() {
|
||||
return python_pop(this, false);
|
||||
}
|
||||
/**
|
||||
* The :js:meth:`Array.shift` method removes the first element from a
|
||||
* ``MutableSequence``.
|
||||
* @returns The removed element from the ``MutableSequence``; undefined if the
|
||||
* ``MutableSequence`` is empty.
|
||||
* :js:class:`PyMutableSequence`.
|
||||
* @returns The removed element from the :js:class:`PyMutableSequence`; undefined if the
|
||||
* :js:class:`PyMutableSequence` is empty.
|
||||
*/
|
||||
shift() {
|
||||
return python_pop(this, true);
|
||||
}
|
||||
/**
|
||||
* The :js:meth:`Array.unshift` method adds the specified elements to the
|
||||
* beginning of a ``MutableSequence``.
|
||||
* @param elts The elements to add to the front of the ``MutableSequence``.
|
||||
* @returns The new length of the ``MutableSequence``.
|
||||
* beginning of a :js:class:`PyMutableSequence`.
|
||||
* @param elts The elements to add to the front of the :js:class:`PyMutableSequence`.
|
||||
* @returns The new length of the :js:class:`PyMutableSequence`.
|
||||
*/
|
||||
unshift(...elts: any[]) {
|
||||
elts.forEach((elt, idx) => {
|
||||
|
@ -1967,12 +1966,12 @@ export class PyMutableSequenceMethods {
|
|||
}
|
||||
/**
|
||||
* The :js:meth:`Array.copyWithin` method shallow copies part of a
|
||||
* ``MutableSequence`` to another location in the same ``MutableSequence``
|
||||
* :js:class:`PyMutableSequence` to another location in the same :js:class:`PyMutableSequence`
|
||||
* without modifying its length.
|
||||
* @param target Zero-based index at which to copy the sequence to.
|
||||
* @param start Zero-based index at which to start copying elements from.
|
||||
* @param end Zero-based index at which to end copying elements from.
|
||||
* @returns The modified ``MutableSequence``.
|
||||
* @returns The modified :js:class:`PyMutableSequence`.
|
||||
*/
|
||||
copyWithin(target: number, start?: number, end?: number): any;
|
||||
copyWithin(...args: number[]): any {
|
||||
|
@ -2339,7 +2338,6 @@ export type PyProxyAwaitable = PyAwaitable;
|
|||
|
||||
/**
|
||||
* The Promise / JavaScript awaitable API.
|
||||
* @private
|
||||
*/
|
||||
export class PyAwaitableMethods {
|
||||
$$: any;
|
||||
|
@ -2444,7 +2442,7 @@ export class PyAwaitableMethods {
|
|||
|
||||
/**
|
||||
* A :js:class:`~pyodide.ffi.PyProxy` whose proxied Python object is
|
||||
* :std:term:`callable` (i.e., has an :py:meth:`~operator.__call__` method).
|
||||
* :std:term:`callable` (i.e., has an :py:meth:`~object.__call__` method).
|
||||
*/
|
||||
export class PyCallable extends PyProxy {
|
||||
/** @private */
|
||||
|
@ -2958,10 +2956,8 @@ export class PyBufferView {
|
|||
*/
|
||||
f_contiguous: boolean;
|
||||
|
||||
/** @private */
|
||||
_released: boolean;
|
||||
|
||||
/** @private */
|
||||
_view_ptr: number;
|
||||
|
||||
/** @private */
|
||||
|
|
|
@ -470,8 +470,8 @@ export class PyodideAPI {
|
|||
* @param path The absolute path in the Emscripten file system to mount the
|
||||
* native directory. If the directory does not exist, it will be created. If it
|
||||
* does exist, it must be empty.
|
||||
* @param fileSystemHandle A handle returned by ``navigator.storage.getDirectory()``
|
||||
* or ``window.showDirectoryPicker()``.
|
||||
* @param fileSystemHandle A handle returned by :js:func:`navigator.storage.getDirectory() <getDirectory>`
|
||||
* or :js:func:`window.showDirectoryPicker() <showDirectoryPicker>`.
|
||||
*/
|
||||
static async mountNativeFS(
|
||||
path: string,
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
"@types/emscripten": "^1.39.5",
|
||||
"@types/expect": "^24.3.0",
|
||||
"@types/mocha": "^9.1.0",
|
||||
"@types/node": "^17.0.25",
|
||||
"@types/node": "^17.0.45",
|
||||
"@types/ws": "^8.5.3",
|
||||
"chai": "^4.3.6",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
|
@ -32,7 +32,7 @@
|
|||
"prettier": "^2.2.1",
|
||||
"ts-mocha": "^9.0.2",
|
||||
"tsd": "^0.24.1",
|
||||
"typedoc": "^0.22.15",
|
||||
"typedoc": "^0.25.1",
|
||||
"typescript": "^4.6.4"
|
||||
}
|
||||
},
|
||||
|
@ -1262,6 +1262,12 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-sequence-parser": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz",
|
||||
"integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
|
@ -3559,9 +3565,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/marked": {
|
||||
"version": "4.2.12",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.2.12.tgz",
|
||||
"integrity": "sha512-yr8hSKa3Fv4D3jdZmtMMPghgVt6TWbk86WQaWhDloQjRSQhMMYCAro7jP7VDJrjjdV8pxVxMssXS8B8Y5DZ5aw==",
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
|
||||
"integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"marked": "bin/marked.js"
|
||||
|
@ -5229,14 +5235,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/shiki": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz",
|
||||
"integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==",
|
||||
"version": "0.14.4",
|
||||
"resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.4.tgz",
|
||||
"integrity": "sha512-IXCRip2IQzKwxArNNq1S+On4KPML3Yyn8Zzs/xRgcgOWIr8ntIK3IKzjFPfjy/7kt9ZMjc+FItfqHRBg8b6tNQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"jsonc-parser": "^3.0.0",
|
||||
"vscode-oniguruma": "^1.6.1",
|
||||
"vscode-textmate": "5.2.0"
|
||||
"ansi-sequence-parser": "^1.1.0",
|
||||
"jsonc-parser": "^3.2.0",
|
||||
"vscode-oniguruma": "^1.7.0",
|
||||
"vscode-textmate": "^8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/side-channel": {
|
||||
|
@ -5764,25 +5771,24 @@
|
|||
}
|
||||
},
|
||||
"node_modules/typedoc": {
|
||||
"version": "0.22.18",
|
||||
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.18.tgz",
|
||||
"integrity": "sha512-NK9RlLhRUGMvc6Rw5USEYgT4DVAUFk7IF7Q6MYfpJ88KnTZP7EneEa4RcP+tX1auAcz7QT1Iy0bUSZBYYHdoyA==",
|
||||
"version": "0.25.1",
|
||||
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.1.tgz",
|
||||
"integrity": "sha512-c2ye3YUtGIadxN2O6YwPEXgrZcvhlZ6HlhWZ8jQRNzwLPn2ylhdGqdR8HbyDRyALP8J6lmSANILCkkIdNPFxqA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"glob": "^8.0.3",
|
||||
"lunr": "^2.3.9",
|
||||
"marked": "^4.0.16",
|
||||
"minimatch": "^5.1.0",
|
||||
"shiki": "^0.10.1"
|
||||
"marked": "^4.3.0",
|
||||
"minimatch": "^9.0.3",
|
||||
"shiki": "^0.14.1"
|
||||
},
|
||||
"bin": {
|
||||
"typedoc": "bin/typedoc"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12.10.0"
|
||||
"node": ">= 16"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x || 4.5.x || 4.6.x || 4.7.x"
|
||||
"typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x"
|
||||
}
|
||||
},
|
||||
"node_modules/typedoc/node_modules/brace-expansion": {
|
||||
|
@ -5794,35 +5800,19 @@
|
|||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/typedoc/node_modules/glob": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
|
||||
"integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^5.0.1",
|
||||
"once": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/typedoc/node_modules/minimatch": {
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
|
||||
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
|
||||
"version": "9.0.3",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
|
||||
"integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
|
@ -5932,9 +5922,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/vscode-textmate": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz",
|
||||
"integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==",
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz",
|
||||
"integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/which": {
|
||||
|
@ -7031,6 +7021,12 @@
|
|||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-sequence-parser": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz",
|
||||
"integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
|
@ -8704,9 +8700,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"marked": {
|
||||
"version": "4.2.12",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.2.12.tgz",
|
||||
"integrity": "sha512-yr8hSKa3Fv4D3jdZmtMMPghgVt6TWbk86WQaWhDloQjRSQhMMYCAro7jP7VDJrjjdV8pxVxMssXS8B8Y5DZ5aw==",
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
|
||||
"integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==",
|
||||
"dev": true
|
||||
},
|
||||
"media-typer": {
|
||||
|
@ -9930,14 +9926,15 @@
|
|||
"dev": true
|
||||
},
|
||||
"shiki": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz",
|
||||
"integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==",
|
||||
"version": "0.14.4",
|
||||
"resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.4.tgz",
|
||||
"integrity": "sha512-IXCRip2IQzKwxArNNq1S+On4KPML3Yyn8Zzs/xRgcgOWIr8ntIK3IKzjFPfjy/7kt9ZMjc+FItfqHRBg8b6tNQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"jsonc-parser": "^3.0.0",
|
||||
"vscode-oniguruma": "^1.6.1",
|
||||
"vscode-textmate": "5.2.0"
|
||||
"ansi-sequence-parser": "^1.1.0",
|
||||
"jsonc-parser": "^3.2.0",
|
||||
"vscode-oniguruma": "^1.7.0",
|
||||
"vscode-textmate": "^8.0.0"
|
||||
}
|
||||
},
|
||||
"side-channel": {
|
||||
|
@ -10342,16 +10339,15 @@
|
|||
}
|
||||
},
|
||||
"typedoc": {
|
||||
"version": "0.22.18",
|
||||
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.18.tgz",
|
||||
"integrity": "sha512-NK9RlLhRUGMvc6Rw5USEYgT4DVAUFk7IF7Q6MYfpJ88KnTZP7EneEa4RcP+tX1auAcz7QT1Iy0bUSZBYYHdoyA==",
|
||||
"version": "0.25.1",
|
||||
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.1.tgz",
|
||||
"integrity": "sha512-c2ye3YUtGIadxN2O6YwPEXgrZcvhlZ6HlhWZ8jQRNzwLPn2ylhdGqdR8HbyDRyALP8J6lmSANILCkkIdNPFxqA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "^8.0.3",
|
||||
"lunr": "^2.3.9",
|
||||
"marked": "^4.0.16",
|
||||
"minimatch": "^5.1.0",
|
||||
"shiki": "^0.10.1"
|
||||
"marked": "^4.3.0",
|
||||
"minimatch": "^9.0.3",
|
||||
"shiki": "^0.14.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"brace-expansion": {
|
||||
|
@ -10363,23 +10359,10 @@
|
|||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"glob": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
|
||||
"integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^5.0.1",
|
||||
"once": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
|
||||
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
|
||||
"version": "9.0.3",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
|
||||
"integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
|
@ -10456,9 +10439,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"vscode-textmate": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz",
|
||||
"integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==",
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz",
|
||||
"integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==",
|
||||
"dev": true
|
||||
},
|
||||
"which": {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
"@types/emscripten": "^1.39.5",
|
||||
"@types/expect": "^24.3.0",
|
||||
"@types/mocha": "^9.1.0",
|
||||
"@types/node": "^17.0.25",
|
||||
"@types/node": "^17.0.45",
|
||||
"@types/ws": "^8.5.3",
|
||||
"chai": "^4.3.6",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
|
@ -35,7 +35,7 @@
|
|||
"prettier": "^2.2.1",
|
||||
"ts-mocha": "^9.0.2",
|
||||
"tsd": "^0.24.1",
|
||||
"typedoc": "^0.22.15",
|
||||
"typedoc": "^0.25.1",
|
||||
"typescript": "^4.6.4"
|
||||
},
|
||||
"main": "pyodide.js",
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/en-us/json-schemas/tsdoc/v0/tsdoc.schema.json",
|
||||
"extends": ["typedoc/tsdoc.json"],
|
||||
"noStandardTags": false,
|
||||
"tagDefinitions": [
|
||||
{
|
||||
"tagName": "@alias",
|
||||
"syntaxKind": "modifier"
|
||||
},
|
||||
{
|
||||
"tagName": "@hidetype",
|
||||
"syntaxKind": "modifier"
|
||||
},
|
||||
{
|
||||
"tagName": "@hideconstructor",
|
||||
"syntaxKind": "modifier"
|
||||
},
|
||||
{
|
||||
"tagName": "@dockind",
|
||||
"syntaxKind": "block"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -252,7 +252,7 @@ class JsProxy(metaclass=_JsProxyMetaClass):
|
|||
--------
|
||||
|
||||
Here are a couple examples of converter functions. In addition to the
|
||||
normal conversions, convert :js:class:`Date`` to :py:class:`~datetime.datetime`:
|
||||
normal conversions, convert :js:class:`Date` to :py:class:`~datetime.datetime`:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
|
Loading…
Reference in New Issue