diff --git a/src/pyscript-stubs/js/__init__.pyi b/src/pyscript-stubs/js/__init__.pyi new file mode 100644 index 0000000..7c2b9db --- /dev/null +++ b/src/pyscript-stubs/js/__init__.pyi @@ -0,0 +1,53 @@ +from __future__ import annotations + +from collections.abc import Buffer, Iterable +from typing import Any + +from typing import ClassVar + +class Blob: + @classmethod + def new(cls, blobParts: Iterable[Any], options: Any) -> Blob: ... + async def arrayBuffer(self) -> int: ... + +class CSSStyleSheet: + @classmethod + def new(cls) -> CSSStyleSheet: ... + def replaceSync(self, text: str) -> None: ... + +class Event: + @classmethod + def new(cls, name: str) -> Event: ... + +class File(Blob): + name: str = ... + +class FileList: + length: int = ... + def item(self, index: int) -> File: ... + +class Node: + TEXT_NODE: ClassVar[int] = ... + nodeType: int + nodeValue: str + def append(self, *args: Node | str) -> None: ... + +class NodeFilter: + SHOW_TEXT: ClassVar[int] = ... + +class Text(Node): ... + +class Uint8Array: + @classmethod + def new(cls, bytes_: Buffer) -> Uint8Array: ... + +class URL: + @classmethod + def createObjectURL(cls, object: Any) -> str: ... + @classmethod + def revokeObjectURL(cls, url: str) -> None: ... + +class Location: + def reload(self) -> None: ... + +location: Location diff --git a/src/pyscript-stubs/pre-existing/py.typed b/src/pyscript-stubs/js/py.typed similarity index 100% rename from src/pyscript-stubs/pre-existing/py.typed rename to src/pyscript-stubs/js/py.typed diff --git a/src/pyscript-stubs/pre-existing/__init__.pyi b/src/pyscript-stubs/pre-existing/__init__.pyi deleted file mode 100644 index 75e46cb..0000000 --- a/src/pyscript-stubs/pre-existing/__init__.pyi +++ /dev/null @@ -1,7 +0,0 @@ -from .document_class import Document -from .window_class import Window - -window = Window() -document = Document() - -def display(info: str): ... diff --git a/src/pyscript-stubs/pre-existing/base.pyi b/src/pyscript-stubs/pre-existing/base.pyi deleted file mode 100644 index 7607ef6..0000000 --- a/src/pyscript-stubs/pre-existing/base.pyi +++ /dev/null @@ -1,7 +0,0 @@ -class CSSStyleDeclaration: - display: str - -class EventTarget: - def addEventListener(self): ... - def removeEventListener(self): ... - def dispatchEvent(self): ... diff --git a/src/pyscript-stubs/pre-existing/document_class.pyi b/src/pyscript-stubs/pre-existing/document_class.pyi deleted file mode 100644 index 304be94..0000000 --- a/src/pyscript-stubs/pre-existing/document_class.pyi +++ /dev/null @@ -1,7 +0,0 @@ -from typing import Optional -from node import Node -from element import Element, HTMLElement - -class Document(Node): - def getElementsByClassName(self, names: str) -> list[Element]: ... - def createElement(self, localName: str, options: Optional[any] = None) -> HTMLElement: ... diff --git a/src/pyscript-stubs/pre-existing/element.pyi b/src/pyscript-stubs/pre-existing/element.pyi deleted file mode 100644 index 07a03ee..0000000 --- a/src/pyscript-stubs/pre-existing/element.pyi +++ /dev/null @@ -1,9 +0,0 @@ -from . import CSSStyleDeclaration -from node import Node - -class Element(Node): - classList: list[str] - onclick: callable - -class HTMLElement(Element): - style: CSSStyleDeclaration diff --git a/src/pyscript-stubs/pre-existing/node.pyi b/src/pyscript-stubs/pre-existing/node.pyi deleted file mode 100644 index 15f9f2c..0000000 --- a/src/pyscript-stubs/pre-existing/node.pyi +++ /dev/null @@ -1,23 +0,0 @@ -from typing import Optional -from .base import EventTarget -from .document_class import Document -from .element import Element - -class Node(EventTarget): - baseURI: str - childNodes: list["Node"] - firstChild: "Node" - isConnected: bool - lastChild: "Node" - nextSibling: "Node" - nodeName: str - nodeType: int - nodeValue: any - ownerDocument: "Document" - parentNode: Optional["Node"] - parentElement: Optional["Element"] - previousSibling: Optional["Node"] - textContent: str - - def appendChild(self, childNode: "Node"): ... - def cloneNode(self) -> "Node": ... diff --git a/src/pyscript-stubs/pre-existing/window_class.pyi b/src/pyscript-stubs/pre-existing/window_class.pyi deleted file mode 100644 index 862f8e5..0000000 --- a/src/pyscript-stubs/pre-existing/window_class.pyi +++ /dev/null @@ -1,16 +0,0 @@ -from .base import EventTarget - -class Location: - hostname: str - -class Console: - def log(self, output: any): ... - -class FileReader(EventTarget): - @classmethod - def new(cls): ... - -class Window(EventTarget): - console: Console - FileReader: FileReader - location: Location diff --git a/src/pyscript-stubs/pyodide/__init__.pyi b/src/pyscript-stubs/pyodide/__init__.pyi new file mode 100644 index 0000000..e69de29 diff --git a/src/pyscript-stubs/pyodide/ffi.pyi b/src/pyscript-stubs/pyodide/ffi.pyi new file mode 100644 index 0000000..98db708 --- /dev/null +++ b/src/pyscript-stubs/pyodide/ffi.pyi @@ -0,0 +1,14 @@ +from __future__ import annotations + +from js import Node + +class ArrayBuffer: + def to_bytes(self) -> bytes: ... + +class JsNull: ... + +class JsProxy: + nodeType: int + nodeValue: str + def append(self, *args: Node | str) -> None: ... + async def arrayBuffer(self) -> ArrayBuffer: ... diff --git a/src/pyscript-stubs/pyodide/py.typed b/src/pyscript-stubs/pyodide/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/pyscript-stubs/pyscript/__init__.pyi b/src/pyscript-stubs/pyscript/__init__.pyi index 4e7a204..0fca02b 100644 --- a/src/pyscript-stubs/pyscript/__init__.pyi +++ b/src/pyscript-stubs/pyscript/__init__.pyi @@ -3,8 +3,8 @@ PyScript makes available convenience objects, functions and attributes. These APIs will work with both Pyodide and MicroPython in exactly the same way. -PyScript can run in two contexts: the main browser thread, or on a web worker. T -he following three categories of API functionality explain features that are common for: +PyScript can run in two contexts: the main browser thread, or on a web worker. +The following three categories of API functionality explain features that are common for: - both main thread and worker, - main thread only, - and worker only. @@ -16,32 +16,13 @@ he following three categories of API functionality explain features that are com # Copyright (c) 2020-2025 Jos Verlinde # MIT Licensed -__all__ = [ - "PyWorker", - "config", - "current_target", - "display", - "document", - "fetch", - "js_import", - "js_modules", - "py_import", - "storage", - "sync", - "window", - "workers", - "HTML", - "Event", - "WebSocket", - "create_named_worker" -] +from __future__ import annotations - -from polyscript import lazy_py_modules as py_import # type: ignore -from pyscript.display import HTML as HTML, display as display -from pyscript.events import Event as Event, when as when -from pyscript.fetch import fetch as fetch -from pyscript.magic_js import ( +from .polyscript import lazy_py_modules as py_import +from .display import HTML as HTML, display as display +from .events import Event as Event, when as when +from .fetch import fetch as fetch +from .magic_js import ( RUNNING_IN_WORKER as RUNNING_IN_WORKER, PyWorker as PyWorker, config as config, @@ -50,12 +31,13 @@ from pyscript.magic_js import ( js_import as js_import, sync as sync, window as window, - js_modules as js_modules + js_modules as js_modules, + TreeWalker as TreeWalker, ) -from pyscript.storage import Storage as Storage, storage as storage -from pyscript.websocket import WebSocket as WebSocket -from pyscript.workers import create_named_worker as create_named_worker, workers as workers +from .storage import Storage as Storage, storage as storage +from .websocket import WebSocket as WebSocket +from .workers import create_named_worker as create_named_worker, workers as workers if not RUNNING_IN_WORKER: ... diff --git a/src/pyscript-stubs/pyscript/_pyscript.pyi b/src/pyscript-stubs/pyscript/_pyscript.pyi index b47d1aa..7af9246 100644 --- a/src/pyscript-stubs/pyscript/_pyscript.pyi +++ b/src/pyscript-stubs/pyscript/_pyscript.pyi @@ -1,7 +1,11 @@ # Copyright (c) 2020-2025 Jos Verlinde # MIT Licensed -from typing import Any, Callable +from __future__ import annotations + +from collections.abc import Callable +from typing import Any + from _typeshed import Incomplete def js_import(name: str) -> JSModule: @@ -9,11 +13,11 @@ def js_import(name: str) -> JSModule: ... class JSModule: - def __init__(self, name) -> None: ... - def __getattr__(self, field) -> Any | None: ... + def __init__(self, name: str) -> None: ... + def __getattr__(self, field: str) -> Any | None: ... class Worker: - async def sync(self) -> Callable: ... + async def sync(self) -> Callable[[Any], Any]: ... class XWorker(Worker): # https://pyscript.github.io/polyscript/#xworker-options @@ -24,9 +28,9 @@ class XWorker(Worker): def __init__( self, file: str, - a_sync: bool = True, - config: str = "", - type: str = "pyodide", # pyodide, micropython, ruby-wasm-wasi, wasmoon, webr + a_sync: bool = ..., + config: str = ..., + type: str = ..., # pyodide, micropython, ruby-wasm-wasi, wasmoon, webr version: str = ..., serviceWorker: str = ..., ) -> None: ... @@ -34,6 +38,6 @@ class XWorker(Worker): # def isWindowProxy(self, ref:Incomplete) -> bool: ... class PyWorker(XWorker): - def __init__(self, name) -> None: ... + def __init__(self, name: str) -> None: ... xworker: XWorker = ... diff --git a/src/pyscript-stubs/pyscript/_typeshed.pyi b/src/pyscript-stubs/pyscript/_typeshed.pyi new file mode 100644 index 0000000..e20170b --- /dev/null +++ b/src/pyscript-stubs/pyscript/_typeshed.pyi @@ -0,0 +1,2 @@ + +class Incomplete: ... diff --git a/src/pyscript-stubs/pyscript/display.pyi b/src/pyscript-stubs/pyscript/display.pyi index 474f646..1759b55 100644 --- a/src/pyscript-stubs/pyscript/display.pyi +++ b/src/pyscript-stubs/pyscript/display.pyi @@ -5,6 +5,12 @@ see: https://docs.pyscript.net/2025.2.3/api/ # Copyright (c) 2020-2025 Jos Verlinde # MIT Licensed +from __future__ import annotations + +from typing import Any + +from .web import Element + _MIME_METHODS = ... _MIME_RENDERERS = ... @@ -12,9 +18,9 @@ class HTML: """ Wrap a string so that display() can render it as plain HTML """ - def __init__(self, html) -> None: ... + def __init__(self, html: str) -> None: ... -def display(*values, target=None, append: bool = True) -> None: +def display(*values: Any, target: Element | None = ..., append: bool = True) -> None: """ A function used to display content. The function is intelligent enough to introspect the object[s] it is passed and work out how to correctly display the object[s] in the web page based on the following mime types:: diff --git a/src/pyscript-stubs/pyscript/events.pyi b/src/pyscript-stubs/pyscript/events.pyi index 1ebd542..c201f5f 100644 --- a/src/pyscript-stubs/pyscript/events.pyi +++ b/src/pyscript-stubs/pyscript/events.pyi @@ -5,25 +5,30 @@ see: https://docs.pyscript.net/2025.2.3/api/ # Copyright (c) 2020-2025 Jos Verlinde # MIT Licensed +from __future__ import annotations + +from collections.abc import Callable +from typing import Any + class Event: """ Represents something that may happen at some point in the future. """ def __init__(self) -> None: ... - def trigger(self, result) -> None: + def trigger(self, result: Any) -> None: """ Trigger the event with a result to pass into the handlers. """ ... - def add_listener(self, listener) -> None: + def add_listener(self, listener: Callable[[Event], Any]) -> None: """ Add a callable/awaitable to listen to when this event is triggered. """ ... - def remove_listener(self, *args) -> None: + def remove_listener(self, *args: Callable[[Event], Any]) -> None: """ Clear the specified handler functions in *args. If no handlers provided, clear all handlers. @@ -31,8 +36,8 @@ class Event: ... def when( - target, *args, **kwargs -): # -> _Wrapped[Callable[..., Any], Any, Callable[..., Any], CoroutineType[Any, Any, Any]] | Callable[..., _Wrapped[Callable[..., Any], Any, Callable[..., Any], CoroutineType[Any, Any, Any]]]: + target: str, *args: Any, **kwargs: Any +) -> Callable[..., Any]: # -> _Wrapped[Callable[..., Any], Any, Callable[..., Any], CoroutineType[Any, Any, Any]] | Callable[..., _Wrapped[Callable[..., Any], Any, Callable[..., Any], CoroutineType[Any, Any, Any]]]: """ Add an event listener to the target element(s) for the specified event type. diff --git a/src/pyscript-stubs/pyscript/fetch.pyi b/src/pyscript-stubs/pyscript/fetch.pyi index 563a8aa..3bda5c6 100644 --- a/src/pyscript-stubs/pyscript/fetch.pyi +++ b/src/pyscript-stubs/pyscript/fetch.pyi @@ -5,7 +5,12 @@ see: https://docs.pyscript.net/2025.2.3/api/ # Copyright (c) 2020-2025 Jos Verlinde # MIT Licensed -from typing import Any, Awaitable +from __future__ import annotations + +from builtins import bytearray + +from collections.abc import Awaitable +from typing import Any class _Response: """ diff --git a/src/pyscript-stubs/pyscript/ffi.pyi b/src/pyscript-stubs/pyscript/ffi.pyi index c313a99..9f095e1 100644 --- a/src/pyscript-stubs/pyscript/ffi.pyi +++ b/src/pyscript-stubs/pyscript/ffi.pyi @@ -5,7 +5,10 @@ see: https://docs.pyscript.net/2025.2.3/api/ # Copyright (c) 2020-2025 Jos Verlinde # MIT Licensed -from typing import Any, Callable, Iterable, Mapping +from __future__ import annotations + +from collections.abc import Callable, Iterable, Mapping +from typing import Any def from_entries(iterable: Iterable[tuple[str, Any]]) -> Any: """ diff --git a/src/pyscript-stubs/pyscript/flatted.pyi b/src/pyscript-stubs/pyscript/flatted.pyi index 4d7121f..2752736 100644 --- a/src/pyscript-stubs/pyscript/flatted.pyi +++ b/src/pyscript-stubs/pyscript/flatted.pyi @@ -5,7 +5,10 @@ see: https://docs.pyscript.net/2025.2.3/api/ # Copyright (c) 2020-2025 Jos Verlinde # MIT Licensed -from typing import Any, Callable +from __future__ import annotations + +from collections.abc import Callable +from typing import Any class _Known: """ diff --git a/src/pyscript-stubs/pyscript/fs.pyi b/src/pyscript-stubs/pyscript/fs.pyi index 886d5a4..0d4b9d6 100644 --- a/src/pyscript-stubs/pyscript/fs.pyi +++ b/src/pyscript-stubs/pyscript/fs.pyi @@ -8,9 +8,11 @@ allowing mounting, syncing, and unmounting of virtual filesystems. # Copyright (c) 2020-2025 Jos Verlinde # MIT Licensed -from typing import Any, Dict, Literal +from __future__ import annotations -mounted: Dict[str, Dict[str, Any]] +from typing import Any, Literal + +mounted: dict[str, dict[str, Any]] """Dictionary mapping mount points to filesystem information""" async def mount( diff --git a/src/pyscript-stubs/pyscript/magic_js.pyi b/src/pyscript-stubs/pyscript/magic_js.pyi index 9dadf63..5457179 100644 --- a/src/pyscript-stubs/pyscript/magic_js.pyi +++ b/src/pyscript-stubs/pyscript/magic_js.pyi @@ -7,24 +7,30 @@ see: https://docs.pyscript.net/2025.2.3/api/ from __future__ import annotations -import sys -from typing import Any, Callable +from collections.abc import Callable +from types import ModuleType +from typing import Any -from _pyscript import PyWorker as PyWorker -from _pyscript import js_import as js_import -from libcst import Not -from typing_extensions import Incomplete +from .web import Element +from ._pyscript import PyWorker as PyWorker +from ._pyscript import js_import as js_import +from ._typeshed import Incomplete -RUNNING_IN_WORKER: bool +from pyodide.ffi import JsProxy + +from js import CSSStyleSheet, Node + +RUNNING_IN_WORKER: bool = ... """True if code is running in a web worker, False if in main thread.""" -config: dict[str, Any] +config: dict[str, Any] = ... """PyScript configuration object containing runtime settings.""" # generate N modules in the system that will proxy the real value # for name in globalThis.Reflect.ownKeys(js_modules): # sys.modules[f"pyscript.js_modules.{name}"] = JSModule(name) # sys.modules["pyscript.js_modules"] = js_modules +js_modules: ModuleType = ... class JSModule: """ @@ -45,7 +51,19 @@ class JSModule: def __getattr__(self, field: str) -> Any | None: ... -PyWorker: None +class _Stylesheets(list[CSSStyleSheet]): + def push(self, value: CSSStyleSheet) -> None: ... + +class TreeWalker: + currentNode: Node = ... + def nextNode(self) -> Node: ... + +class Document: + adoptedStyleSheets: _Stylesheets = ... + + @classmethod + def createTreeWalker(cls, root: Element | JsProxy, whatToShow: int | None = ..., filter: Any | None = ...) -> TreeWalker: ... + """Not available in worker context (None).""" window: Incomplete | None @@ -58,7 +76,7 @@ and methods when running in the main thread. Not available in worker context (None). """ -document: Incomplete | None +document: Document = ... """ The browser's document object. diff --git a/src/pyscript-stubs/pyscript/media.pyi b/src/pyscript-stubs/pyscript/media.pyi index fbdfa7e..073efa3 100644 --- a/src/pyscript-stubs/pyscript/media.pyi +++ b/src/pyscript-stubs/pyscript/media.pyi @@ -5,6 +5,8 @@ see: https://docs.pyscript.net/2025.2.3/api/ # Copyright (c) 2020-2025 Jos Verlinde # MIT Licensed +from __future__ import annotations + from typing import Any, Literal class Device: diff --git a/src/pyscript-stubs/pyscript/polyscript.pyi b/src/pyscript-stubs/pyscript/polyscript.pyi index 3359b2a..58d5783 100644 --- a/src/pyscript-stubs/pyscript/polyscript.pyi +++ b/src/pyscript-stubs/pyscript/polyscript.pyi @@ -6,6 +6,10 @@ https://pyscript.github.io/polyscript/#the-polyscript-module # Copyright (c) 2020-2025 Jos Verlinde # MIT Licensed +from __future__ import annotations + +from types import ModuleType + # https://github.com/pyscript/polyscript # XWorker from polyscript import XWorker described in the XWorker part. @@ -16,14 +20,7 @@ https://pyscript.github.io/polyscript/#the-polyscript-module # storage from polyscript import storage a utility to instantiate a named idb-map that can be consumed synchronously. # JSON from polyscript import JSON a utility to stringify/parse more complex or recursive data via -from typing import Tuple - -# avoid name collisions -import storage as _storage - -storage = _storage.storage - -async def lazy_py_modules(*args: str) -> Tuple: +async def lazy_py_modules(*args: str) -> tuple[ModuleType, ...]: """ allows, only in Python related interpreters, and without needing static config entries, to import lazily any available module. diff --git a/src/pyscript-stubs/pyscript/py.typed b/src/pyscript-stubs/pyscript/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/pyscript-stubs/pyscript/storage.pyi b/src/pyscript-stubs/pyscript/storage.pyi index 20c4f12..7f6f699 100644 --- a/src/pyscript-stubs/pyscript/storage.pyi +++ b/src/pyscript-stubs/pyscript/storage.pyi @@ -5,7 +5,9 @@ see: https://docs.pyscript.net/2025.2.3/api/ # Copyright (c) 2020-2025 Jos Verlinde # MIT Licensed -from typing import Any, Type +from __future__ import annotations + +from typing import Any class Storage(dict[str, Any]): """ @@ -51,7 +53,7 @@ class Storage(dict[str, Any]): async def storage( name: str = "pyscript", - storage_class: Type[Storage] = Storage, + storage_class: type[Storage] = Storage, ) -> Storage: """ Create or access a named storage instance. diff --git a/src/pyscript-stubs/pyscript/util.pyi b/src/pyscript-stubs/pyscript/util.pyi index 7219d29..00a4798 100644 --- a/src/pyscript-stubs/pyscript/util.pyi +++ b/src/pyscript-stubs/pyscript/util.pyi @@ -5,7 +5,11 @@ see: https://docs.pyscript.net/2025.2.3/api/ # Copyright (c) 2020-2025 Jos Verlinde # MIT Licensed -def as_bytearray(buffer) -> bytearray: +from __future__ import annotations + +from typing import Any + +def as_bytearray(buffer: Any) -> bytearray: """ Given a JavaScript ArrayBuffer, convert it to a Python bytearray in a MicroPython friendly manner. @@ -18,13 +22,13 @@ class NotSupported: it. """ - def __init__(self, name, error) -> None: ... + def __init__(self, name: str, error: BaseException) -> None: ... def __repr__(self) -> str: ... - def __getattr__(self, attr): ... - def __setattr__(self, attr, value): ... - def __call__(self, *args): ... + def __getattr__(self, attr: str) -> Any: ... + def __setattr__(self, attr: str, value: Any) -> None: ... + def __call__(self, *args: Any) -> None: ... -def is_awaitable(obj) -> bool: +def is_awaitable(obj: Any) -> bool: """ Returns a boolean indication if the passed in obj is an awaitable function. (MicroPython treats awaitables as generator functions, and if diff --git a/src/pyscript-stubs/pyscript/web.pyi b/src/pyscript-stubs/pyscript/web.pyi index 7917c65..4caab85 100644 --- a/src/pyscript-stubs/pyscript/web.pyi +++ b/src/pyscript-stubs/pyscript/web.pyi @@ -6,7 +6,7 @@ As a convenience, and to ensure backwards compatibility, PyScript allows the use Warning: This classic pattern of coding (inline event handlers) is no longer considered good practice in web development circles. -We include this behaviour for historic reasons, but the folks at Mozilla have a good explanation of why this is currently considered bad practice. +We include this behavior for historic reasons, but the folks at Mozilla have a good explanation of why this is currently considered bad practice. These attributes, expressed as py-* or mpy-* attributes of an HTML element, reference the name of a Python function to run when the event is fired. You should replace the * with the actual name of an event (e.g. py-click or mpy-click). This is similar to how all event handlers on elements start @@ -18,18 +18,19 @@ with on in standard HTML (e.g. onclick). The rule of thumb is to simply replace from __future__ import annotations -from typing import Any, Generator, List +from collections.abc import Generator, Iterable, Iterator +from typing import Any, Self -from _typeshed import Incomplete -from pyscript import Event, document -from pyscript import when as when -from pyscript.ffi import create_proxy -from typing_extensions import Self +from js import Event as JsEvent, FileList + +from .events import Event +from ._typeshed import Incomplete ELEMENT_CLASSES: ElementCollection = ... + page: Page = ... -def wrap_dom_element(dom_element): +def wrap_dom_element(dom_element: Element) -> Element: """Wrap an existing DOM element in an instance of a subclass of `Element`. This is just a convenience function to avoid having to import the `Element` class @@ -51,17 +52,17 @@ class Element: ... @classmethod - def register_element_classes(cls, element_classes) -> None: + def register_element_classes(cls, element_classes: Iterable[type[Element]]) -> None: """Register an iterable of element classes.""" ... @classmethod - def unregister_element_classes(cls, element_classes) -> None: + def unregister_element_classes(cls, element_classes: Iterable[type[Element]]) -> None: """Unregister an iterable of element classes.""" ... @classmethod - def wrap_dom_element(cls, dom_element): + def wrap_dom_element(cls, dom_element: Element) -> Element: """Wrap an existing DOM element in an instance of a subclass of `Element`. We look up the `Element` subclass by the DOM element's tag name. For any unknown @@ -69,7 +70,7 @@ class Element: """ ... - def __init__(self, dom_element=..., classes=..., style=..., **kwargs) -> None: + def __init__(self, dom_element: Element =..., classes: Iterable[type[Element]] = ..., style: str = ..., **kwargs: Any) -> None: """Create a new, or wrap an existing DOM element. If `dom_element` is None we are being called to *create* a new element. @@ -77,11 +78,11 @@ class Element: """ ... - def __eq__(self, obj) -> bool: + def __eq__(self, obj: Any) -> bool: """Check for equality by comparing the underlying DOM element.""" ... - def __getitem__(self, key) -> ElementCollection: + def __getitem__(self, key: str) -> ElementCollection: """Get an item within the element's children. If `key` is an integer or a slice we use it to index/slice the element's @@ -89,7 +90,7 @@ class Element: """ ... - def __getattr__(self, name) -> Event | Any: + def __getattr__(self, name: str) -> Event | str | Any: """ Get an attribute from the element. @@ -99,8 +100,9 @@ class Element: """ ... - def __setattr__(self, name, value) -> None: ... - def get_event(self, name) -> Event: + def __setattr__(self, name: str, value: Any) -> None: ... + + def get_event(self, name: str) -> Event: """ Get an `Event` instance for the specified event name. """ @@ -126,15 +128,56 @@ class Element: """Return the element's `style` attribute as a `Style` instance.""" ... - def append(self, *items) -> None: + @property + def textContent(self) -> str: + ... + + @textContent.setter + def textContent(self, value: str) -> None: + ... + + @property + def tagName(self) -> str: + ... + + @property + def value(self) -> Any: + ... + + @value.setter + def value(self, value: Any) -> None: + ... + + @property + def checked(self) -> bool: + ... + + @checked.setter + def checked(self, value: bool) -> None: + ... + + @property + def files(self) -> FileList: + ... + + def getAttribute(self, name: str) -> str | None: + ... + + def setAttribute(self, name: str, value: Any) -> None: + ... + + def dispatchEvent(self, event: Event | JsEvent) -> None: + ... + + def append(self, *items: Element) -> None: """Append the specified items to the element.""" ... - def clone(self, clone_id=...): + def clone(self, clone_id: str | None = ...) -> Element: """Make a clone of the element (clones the underlying DOM object too).""" ... - def find(self, selector) -> ElementCollection: + def find(self, selector: str) -> ElementCollection: """Find all elements that match the specified selector. Return the results as a (possibly empty) `ElementCollection`. @@ -145,37 +188,43 @@ class Element: """Convenience method for 'element.scrollIntoView()'.""" ... - def update(self, classes=..., style=..., **kwargs) -> None: + def update(self, classes: Iterable[type[Element]] = ..., style: str = ..., **kwargs: Any) -> None: """Update the element with the specified classes, styles, and DOM properties.""" ... + def checkValidity(self) -> bool: + ... + + def click(self) -> None: + ... + class Classes: """A set-like interface to an element's `classList`.""" def __init__(self, element: Element) -> None: ... - def __contains__(self, item) -> bool: ... - def __eq__(self, other) -> bool: ... - def __iter__(self): ... + def __contains__(self, item: type[Element]) -> bool: ... + def __eq__(self, other: Any) -> bool: ... + def __iter__(self) -> Iterator[str]: ... def __len__(self) -> int: ... def __repr__(self) -> str: ... def __str__(self) -> str: ... - def add(self, *class_names) -> None: + def add(self, *class_names: str) -> None: """Add one or more classes to the element.""" ... - def contains(self, class_name) -> bool: + def contains(self, class_name: str) -> bool: """Check if the element has the specified class.""" ... - def remove(self, *class_names) -> None: + def remove(self, *class_names: str) -> None: """Remove one or more classes from the element.""" ... - def replace(self, old_class, new_class) -> None: + def replace(self, old_class: str, new_class: str) -> None: """Replace one of the element's classes with another.""" ... - def toggle(self, *class_names) -> None: + def toggle(self, *class_names: str) -> None: """Toggle one or more of the element's classes.""" ... @@ -197,8 +246,8 @@ class Options: `clear` methods. """ - def __init__(self, element) -> None: ... - def __getitem__(self, key): ... + def __init__(self, element: Element) -> None: ... + def __getitem__(self, key: str) -> Element: ... def __iter__(self) -> Generator[Any, Any, None]: ... def __len__(self) -> int: ... def __repr__(self) -> str: ... @@ -208,11 +257,11 @@ class Options: ... @property - def selected(self): + def selected(self) -> Any: """Return the selected option.""" ... - def add(self, value=..., html=..., text=..., before=..., **kwargs) -> None: + def add(self, value: str = ..., html: str = ..., text: str = ..., before: str = ..., **kwargs: Any) -> None: """Add a new option to the element""" ... @@ -220,7 +269,7 @@ class Options: """Remove all options.""" ... - def remove(self, index) -> None: + def remove(self, index: int) -> None: """Remove the option at the specified index.""" ... @@ -228,80 +277,80 @@ class Style: """A dict-like interface to an element's `style` attribute.""" def __init__(self, element: Element) -> None: ... - def __getitem__(self, key) -> Element: ... - def __setitem__(self, key, value) -> None: ... - def remove(self, key) -> None: + def __getitem__(self, key: str) -> Element: ... + def __setitem__(self, key: str, value: Any) -> None: ... + def remove(self, key: str) -> None: """Remove a CSS property from the element.""" ... - def set(self, **kwargs) -> None: + def set(self, **kwargs: Any) -> None: """Set one or more CSS properties on the element.""" ... @property def visible(self) -> Incomplete: ... @visible.setter - def visible(self, value) -> None: ... + def visible(self, value: Any) -> None: ... class ContainerElement(Element): """Base class for elements that can contain other elements.""" - def __init__(self, *args, children=..., dom_element=..., style=..., classes=..., **kwargs) -> None: ... + def __init__(self, *args: Any, children: Iterable[Element] = ..., dom_element: Element = ..., style: str = ..., classes: str = ..., **kwargs: Any) -> None: ... def __iter__(self) -> Generator[Any, Any, None]: ... class ClassesCollection: """A set-like interface to the classes of the elements in a collection.""" - def __init__(self, collection) -> None: ... - def __contains__(self, class_name) -> bool: ... - def __eq__(self, other) -> bool: ... + def __init__(self, collection: Iterable[str]) -> None: ... + def __contains__(self, class_name: str) -> bool: ... + def __eq__(self, other: Any) -> bool: ... def __iter__(self) -> Generator[Any, Any, None]: ... def __len__(self) -> int: ... def __repr__(self) -> str: ... def __str__(self) -> str: ... - def add(self, *class_names) -> None: + def add(self, *class_names: str) -> None: """Add one or more classes to the elements in the collection.""" ... - def contains(self, class_name) -> bool: + def contains(self, class_name: str) -> bool: """Check if any element in the collection has the specified class.""" ... - def remove(self, *class_names) -> None: + def remove(self, *class_names: str) -> None: """Remove one or more classes from the elements in the collection.""" ... - def replace(self, old_class, new_class) -> None: + def replace(self, old_class: str, new_class: str) -> None: """Replace one of the classes in the elements in the collection with another.""" ... - def toggle(self, *class_names) -> None: + def toggle(self, *class_names: str) -> None: """Toggle one or more classes on the elements in the collection.""" ... class StyleCollection: """A dict-like interface to the styles of the elements in a collection.""" - def __init__(self, collection) -> None: ... - def __getitem__(self, key) -> list[Any]: ... - def __setitem__(self, key, value) -> None: ... + def __init__(self, collection: Iterable[str]) -> None: ... + def __getitem__(self, key: str) -> list[Any]: ... + def __setitem__(self, key: str, value: Any) -> None: ... def __repr__(self) -> str: ... - def remove(self, key) -> None: + def remove(self, key: str) -> None: """Remove a CSS property from the elements in the collection.""" ... class ElementCollection: @classmethod - def wrap_dom_elements(cls, dom_elements) -> Self: + def wrap_dom_elements(cls, dom_elements: Iterable[Element]) -> Self: """Wrap an iterable of dom_elements in an `ElementCollection`.""" ... - def __init__(self, elements: List[Element]) -> None: ... - def __eq__(self, obj) -> bool: + def __init__(self, elements: list[Element]) -> None: ... + def __eq__(self, obj: Any) -> bool: """Check for equality by comparing the underlying DOM elements.""" ... - def __getitem__(self, key) -> ElementCollection: + def __getitem__(self, key: int | str) -> Element: """Get an item in the collection. If `key` is an integer or a slice we use it to index/slice the collection. @@ -312,16 +361,16 @@ class ElementCollection: def __iter__(self) -> Generator[Any, Any, None]: ... def __len__(self) -> int: ... def __repr__(self) -> str: ... - def __getattr__(self, name) -> list[Any]: ... - def __setattr__(self, name, value) -> None: ... + def __getattr__(self, name: str) -> list[Any]: ... + def __setattr__(self, name: str, value: Any) -> None: ... @property def classes(self) -> ClassesCollection: """Return the classes of the elements in the collection as a `ClassesCollection`.""" ... @property - def elements(self): - """Return the elements in the collection as a list.""" + def elements(self) -> ElementCollection: + """Return the elements in the collection as a `ElementCollection`.""" ... @property @@ -329,7 +378,7 @@ class ElementCollection: """""" ... - def find(self, selector) -> ElementCollection: + def find(self, selector: str) -> ElementCollection: """Find all elements that match the specified selector. Return the results as a (possibly empty) `ElementCollection`. @@ -415,7 +464,7 @@ class canvas(ContainerElement): """ ... - def draw(self, what, width=..., height=...) -> None: + def draw(self, what: Element, width: int = ..., height: int = ...) -> None: """Draw `what` on the current element Inputs: @@ -890,7 +939,7 @@ class Page: """Represents the whole page.""" def __init__(self) -> None: ... - def __getitem__(self, selector) -> ElementCollection: + def __getitem__(self, selector: str) -> ElementCollection: """Get an item on the page. We don't index/slice the page like we do with `Element` and `ElementCollection` @@ -905,17 +954,29 @@ class Page: ... @title.setter - def title(self, value) -> None: + def title(self, value: str) -> None: """Set the page title.""" ... - def append(self, *items) -> None: + def append(self, *items: Element) -> None: """Shortcut for `page.body.append`.""" ... - def find(self, selector) -> ElementCollection: + def find(self, selector: str) -> ElementCollection: """Find all elements that match the specified selector. Return the results as a (possibly empty) `ElementCollection`. """ ... + + @property + def html(self) -> html: + ... + + @property + def head(self) -> head: + ... + + @property + def body(self) -> body: + ... diff --git a/src/pyscript-stubs/pyscript/websocket.pyi b/src/pyscript-stubs/pyscript/websocket.pyi index d7f6b5a..2180ebd 100644 --- a/src/pyscript-stubs/pyscript/websocket.pyi +++ b/src/pyscript-stubs/pyscript/websocket.pyi @@ -5,6 +5,8 @@ see: https://docs.pyscript.net/2025.2.3/api/ # Copyright (c) 2020-2025 Jos Verlinde # MIT Licensed +from __future__ import annotations + from typing import Any, Literal code: dict[str, int] diff --git a/src/pyscript-stubs/pyscript/workers.pyi b/src/pyscript-stubs/pyscript/workers.pyi index de7bb2d..0f4678d 100644 --- a/src/pyscript-stubs/pyscript/workers.pyi +++ b/src/pyscript-stubs/pyscript/workers.pyi @@ -5,6 +5,8 @@ see: https://docs.pyscript.net/2025.2.3/api/ # Copyright (c) 2020-2025 Jos Verlinde # MIT Licensed +from __future__ import annotations + from typing import Any def _get(name: str) -> Any: @@ -40,8 +42,8 @@ Provides access to workers created with create_named_worker() by their names. async def create_named_worker( src: str = "", name: str = "", - config: dict[str, Any] | None = None, - type: str = "micropython", + config: dict[str, Any] | None = ..., + type: str = ..., ) -> Any: """ Create a named web worker for parallel execution.