mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-19 10:17:23 -05:00
* Revise display module. TODO: more comprehensive tests. Especially around mimebundles. * Markdown corrections in example code in display.py docstrings. * Minor adjustments and a much more comprehensive test-suite for the display module. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Updated docstring in __init__.py. * Remove unused imports and black-ify the source. * Refactor, docs and tests for the Event class in events.py. * Refactored, simplified and documented @when decorator. * Extensive test suite for @when decorator. * Documentation and minor refactoring of the fetch.py module. TODO: Check tests. * Refactored and more comprehensive tests for the fetch module. * Add/clarify Event related interactions. Thanks @Neon22 for the suggestion. * Refactor, document ffi.py module. * More complete passing tests for ffi.py. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Add docstrings to flatted.py. Since this is actually an external(ish) module, tests for it should be in the external repository from which this code is derived. * Minor docstring cleanup in ffi.py. * Added docstrings and clarifications to fs.py. * Add very limited test suite for fs.py. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Rename magic_js.py to context.py, add comprehensive docstrings, and rename certain internal things for readability and comprehension. * Fix dict check in ffi.py. * Rename test_js_modules to test_context. * Fix test configuration aftert rename. * Docs and refactor of media.py. * Comprehensive tests for media.py. * Refactor and docstrings for storage.py * Appease the ruff gods. * Further storage.py changes and a more complete test suite for storage. * Refactor and docstrings for the util.py module. Fixed a problem with is_awaitable not handling async bound methods. * More comprehensive test suite for util.py. Updated to latest upytest. * A major refactoring, documenting and simplification of the web.py module substantially reducing it in size and complexity with only a few minor (edge) behavioural changes. Softly breaking changes include: - An element's classes are just a set. - An element's styles are just a dict. - Explicitly use `update_all` with ElementCollections (simpler and greater flexibility). - Extract a child element by id with `my_container["#an-id"]` * Updates and additions for a more comprehensive test suite for the web.py module. All code paths are exercised and checked. * Black tidy-ups in test suite. * Refactor and documentation for websocket.py module. * Tests for websocket.py. Disabled due to playwright flakiness, but they all pass in a local browser. * Refactor and documentation of workers.py module. * Added tests for workers.py module. Updated related test suite to account for the new named worker in the test HTML. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Refactor away remaining "is not None" not caught before. * Remove check-docstring-first because it interferes with the auto-generated documentation (where triple quoted strings are used to document module attributes). * Careful Markdown changes so the docstrings render properly in the PyScript docs. * Typo correction. * More typo corrections and clarifications. * Add clarification about SVG handling to _render_image docstring. * Add DOM event options to the @when decorator (with new tests to exercise this functionality). * Fixes default value for options if no options passed into @when. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
20 lines
31 KiB
JavaScript
20 lines
31 KiB
JavaScript
// ⚠️ This file is an artifact: DO NOT MODIFY
|
|
export default {
|
|
"pyscript": {
|
|
"__init__.py": "from polyscript import lazy_py_modules as py_import\nfrom pyscript.context import RUNNING_IN_WORKER,PyWorker,config,current_target,document,js_import,js_modules,sync,window\nfrom pyscript.display import HTML,display\nfrom pyscript.fetch import fetch\nfrom pyscript.storage import Storage,storage\nfrom pyscript.websocket import WebSocket\nfrom pyscript.events import when,Event\nif not RUNNING_IN_WORKER:from pyscript.workers import create_named_worker,workers",
|
|
"context.py": "_A=None\nimport json,sys,js\nfrom polyscript import config as _polyscript_config,js_modules\nfrom pyscript.util import NotSupported\nRUNNING_IN_WORKER=not hasattr(js,'document')\nconfig=json.loads(js.JSON.stringify(_polyscript_config))\nif isinstance(config,str):config={}\njs_import=_A\nwindow=_A\ndocument=_A\nsync=_A\nif'MicroPython'in sys.version:config['type']='mpy'\nelse:config['type']='py'\nclass _JSModuleProxy:\n\tdef __init__(A,name):A.name=name\n\tdef __getattr__(B,field):\n\t\tA=field\n\t\tif not A.startswith('_'):return getattr(getattr(js_modules,B.name),A)\nfor module_name in js.Reflect.ownKeys(js_modules):sys.modules[f\"pyscript.js_modules.{module_name}\"]=_JSModuleProxy(module_name)\nsys.modules['pyscript.js_modules']=js_modules\nif RUNNING_IN_WORKER:\n\timport polyscript;PyWorker=NotSupported('pyscript.PyWorker','pyscript.PyWorker works only when running in the main thread')\n\ttry:window=polyscript.xworker.window;document=window.document;js.document=document;js_import=window.Function('return (...urls) => Promise.all(urls.map((url) => import(url)))')()\n\texcept:sab_error_message='Unable to use `window` or `document` in worker. This requires SharedArrayBuffer support. See: https://docs.pyscript.net/latest/faq/#sharedarraybuffer';js.console.warn(sab_error_message);window=NotSupported('pyscript.window',sab_error_message);document=NotSupported('pyscript.document',sab_error_message)\n\tsync=polyscript.xworker.sync\n\tdef current_target():return polyscript.target\nelse:\n\timport _pyscript;from _pyscript import PyWorker as _PyWorker;from pyscript.ffi import to_js;js_import=_pyscript.js_import\n\tdef PyWorker(url,**A):return _PyWorker(url,to_js(A))\n\twindow=js;document=js.document;sync=NotSupported('pyscript.sync','pyscript.sync works only when running in a worker')\n\tdef current_target():return _pyscript.target",
|
|
"display.py": "_I='__repr__'\n_H='savefig'\n_G='application/json'\n_F='image/svg+xml'\n_E='application/javascript'\n_D='image/jpeg'\n_C='text/html'\n_B='image/png'\n_A='text/plain'\nimport base64,html,io\nfrom collections import OrderedDict\nfrom pyscript.context import current_target,document,window\nfrom pyscript.ffi import is_none\ndef _render_image(mime,value,meta):\n\tA=value\n\tif isinstance(A,bytes):A=base64.b64encode(A).decode('utf-8')\n\tB=''.join([f' {A}=\"{B}\"'for(A,B)in meta.items()]);return f'<img src=\"data:{mime};base64,{A}\"{B}>'\n_MIME_TO_RENDERERS={_A:lambda v,m:html.escape(v),_C:lambda v,m:v,_B:lambda v,m:_render_image(_B,v,m),_D:lambda v,m:_render_image(_D,v,m),_F:lambda v,m:v,_G:lambda v,m:v,_E:lambda v,m:f\"<script>{v}<\\\\/script>\"}\n_METHOD_TO_MIME=OrderedDict([(_H,_B),('_repr_png_',_B),('_repr_jpeg_',_D),('_repr_svg_',_F),('_repr_html_',_C),('_repr_json_',_G),('_repr_javascript_',_E),(_I,_A)])\nclass HTML:\n\tdef __init__(A,html):A._html=html\n\tdef _repr_html_(A):return A._html\ndef _get_representation(obj,method):\n\tB=method;A=obj\n\tif B==_I:return repr(A)\n\tif not hasattr(A,B):return\n\tif B==_H:C=io.BytesIO();A.savefig(C,format='png');C.seek(0);return base64.b64encode(C.read()).decode('utf-8')\n\treturn getattr(A,B)()\ndef _get_content_and_mime(obj):\n\tC=obj\n\tif isinstance(C,str):return html.escape(C),_A\n\tE=_get_representation(C,'_repr_mimebundle_')\n\tif E:\n\t\tif isinstance(E,tuple):F,G=E\n\t\telse:F,G=E,{}\n\t\tfor(B,A)in F.items():\n\t\t\tif B in _MIME_TO_RENDERERS:\n\t\t\t\tD=G.get(B,{})\n\t\t\t\tif isinstance(A,tuple):A,H=A;D.update(H)\n\t\t\t\treturn _MIME_TO_RENDERERS[B](A,D),B\n\tfor(I,B)in _METHOD_TO_MIME.items():\n\t\tif B not in _MIME_TO_RENDERERS:continue\n\t\tA=_get_representation(C,I)\n\t\tif A is None:continue\n\t\tD={}\n\t\tif isinstance(A,tuple):A,D=A\n\t\treturn _MIME_TO_RENDERERS[B](A,D),B\n\twindow.console.warn(f\"Object {type(C).__name__} has no supported representation method. Using __repr__ as fallback.\");A=repr(C);return html.escape(A),_A\ndef _write_to_dom(element,value,append):\n\tC=element;B,D=_get_content_and_mime(value)\n\tif not B.strip():return\n\tif append:A=document.createElement('div');C.append(A)\n\telse:A=C\n\tif D in(_E,_C):A.append(document.createRange().createContextualFragment(B))\n\telse:A.innerHTML=B\ndef display(*D,target=None,append=True):\n\tC=append;A=target\n\tif isinstance(A,str):A=A[1:]if A.startswith('#')else A\n\telif is_none(A):A=current_target()\n\tB=document.getElementById(A)\n\tif is_none(B):raise ValueError(f\"Cannot find element with id='{A}' in the page.\")\n\tif B.tagName=='SCRIPT'and hasattr(B,'target'):B=B.target\n\tif not C:B.replaceChildren()\n\tfor E in D:_write_to_dom(B,E,C)",
|
|
"events.py": "import asyncio,inspect\nfrom functools import wraps\nfrom pyscript.context import document\nfrom pyscript.ffi import create_proxy,to_js\nfrom pyscript.util import is_awaitable\nclass Event:\n\tdef __init__(A):A._listeners=[]\n\tdef trigger(C,result):\n\t\tB=result\n\t\tfor A in C._listeners:\n\t\t\tif is_awaitable(A):asyncio.create_task(A(B))\n\t\t\telse:A(B)\n\tdef add_listener(B,listener):\n\t\tA=listener\n\t\tif not callable(A):C='Listener must be callable.';raise ValueError(C)\n\t\tif A not in B._listeners:B._listeners.append(A)\n\tdef remove_listener(A,*B):\n\t\tif B:\n\t\t\tfor C in B:\n\t\t\t\ttry:A._listeners.remove(C)\n\t\t\t\texcept ValueError:pass\n\t\telse:A._listeners=[]\ndef when(event_type,selector=None,**C):\n\tB=selector;A=event_type\n\tif isinstance(A,str):\n\t\tif not B:raise ValueError('Selector required for DOM event handling.')\n\t\tD=_get_elements(B)\n\t\tif not D:raise ValueError(f\"No elements found for selector: {B}\")\n\tdef E(func):\n\t\tB=_create_wrapper(func)\n\t\tif isinstance(A,Event):A.add_listener(B)\n\t\telif isinstance(A,list)and all(isinstance(A,Event)for A in A):\n\t\t\tfor E in A:E.add_listener(B)\n\t\telse:\n\t\t\tfor F in D:F.addEventListener(A,create_proxy(B),to_js(C)if C else False)\n\t\treturn B\n\treturn E\ndef _get_elements(selector):\n\tA=selector;from pyscript.web import Element as B,ElementCollection as C\n\tif isinstance(A,str):return list(document.querySelectorAll(A))\n\telif isinstance(A,B):return[A._dom_element]\n\telif isinstance(A,C):return[A._dom_element for A in A]\n\telif isinstance(A,list):return A\n\telse:return[A]\ndef _create_wrapper(func):\n\tA=func;B=A\n\twhile hasattr(B,'__wrapped__'):B=B.__wrapped__\n\tE=inspect.signature(B);D=bool(E.parameters)\n\tif is_awaitable(A):\n\t\tif D:\n\t\t\tasync def C(event):return await A(event)\n\t\telse:\n\t\t\tasync def C(*B,**C):return await A()\n\telif D:\n\t\tdef C(event):return A(event)\n\telse:\n\t\tdef C(*B,**C):return A()\n\treturn wraps(A)(C)",
|
|
"fetch.py": "import json,js\nfrom pyscript.util import as_bytearray\nclass _FetchResponse:\n\tdef __init__(A,response):A._response=response\n\tdef __getattr__(A,attr):return getattr(A._response,attr)\n\tasync def arrayBuffer(B):\n\t\tA=await B._response.arrayBuffer()\n\t\tif hasattr(A,'to_py'):return A.to_py()\n\t\treturn memoryview(as_bytearray(A))\n\tasync def blob(A):return await A._response.blob()\n\tasync def bytearray(A):B=await A._response.arrayBuffer();return as_bytearray(B)\n\tasync def json(A):return json.loads(await A.text())\n\tasync def text(A):return await A._response.text()\nclass _FetchPromise:\n\tdef __init__(B,promise):A=promise;B._promise=A;A._response=None;A.arrayBuffer=B.arrayBuffer;A.blob=B.blob;A.bytearray=B.bytearray;A.json=B.json;A.text=B.text\n\t@staticmethod\n\tdef setup(promise,response):A=promise;A._response=_FetchResponse(response);return A._response\n\tasync def _get_response(A):\n\t\tif not A._promise._response:await A._promise\n\t\treturn A._promise._response\n\tasync def arrayBuffer(A):B=await A._get_response();return await B.arrayBuffer()\n\tasync def blob(A):B=await A._get_response();return await B.blob()\n\tasync def bytearray(A):B=await A._get_response();return await B.bytearray()\n\tasync def json(A):B=await A._get_response();return await B.json()\n\tasync def text(A):B=await A._get_response();return await B.text()\ndef fetch(url,**B):\n\tC=js.JSON.parse(json.dumps(B))\n\tdef D(response,*B):return _FetchPromise.setup(A,response)\n\tA=js.fetch(url,C).then(D);_FetchPromise(A);return A",
|
|
"ffi.py": "try:\n\timport js;from pyodide.ffi import create_proxy as _cp,to_js as _py_tjs,jsnull;from_entries=js.Object.fromEntries\n\tdef _to_js_wrapper(value,**A):\n\t\tB='dict_converter'\n\t\tif B not in A:A[B]=from_entries\n\t\treturn _py_tjs(value,**A)\nexcept:from jsffi import create_proxy as _cp;from jsffi import to_js as _to_js_wrapper;import js;jsnull=js.Object.getPrototypeOf(js.Object.prototype)\ndef create_proxy(func):return _cp(func)\ndef to_js(value,**A):return _to_js_wrapper(value,**A)\ndef is_none(value):A=value;return A is None or A is jsnull\ntry:from polyscript import ffi as _ffi;_assign=_ffi.assign;direct=_ffi.direct;gather=_ffi.gather;query=_ffi.query\nexcept:import js;_assign=js.Object.assign;direct=lambda source:source\ndef assign(source,*B):\n\tA=source\n\tfor C in B:_assign(A,to_js(C))\n\treturn A",
|
|
"flatted.py": "import json as _json\nclass _Known:\n\tdef __init__(A):A.key=[];A.value=[]\nclass _String:\n\tdef __init__(A,value):A.value=value\ndef _array_keys(value):\n\tA=[];B=0\n\tfor C in value:A.append(B);B+=1\n\treturn A\ndef _object_keys(value):\n\tA=[]\n\tfor B in value:A.append(B)\n\treturn A\ndef _is_array(value):return isinstance(value,(list,tuple))\ndef _is_object(value):return isinstance(value,dict)\ndef _is_string(value):return isinstance(value,str)\ndef _index(known,input,value):B=value;A=known;input.append(B);C=str(len(input)-1);A.key.append(B);A.value.append(C);return C\ndef _loop(keys,input,known,output):\n\tA=output\n\tfor B in keys:\n\t\tC=A[B]\n\t\tif isinstance(C,_String):_ref(B,input[int(C.value)],input,known,A)\n\treturn A\ndef _ref(key,value,input,known,output):\n\tB=known;A=value\n\tif _is_array(A)and A not in B:B.append(A);A=_loop(_array_keys(A),input,B,A)\n\telif _is_object(A)and A not in B:B.append(A);A=_loop(_object_keys(A),input,B,A)\n\toutput[key]=A\ndef _relate(known,input,value):\n\tB=known;A=value\n\tif _is_string(A)or _is_array(A)or _is_object(A):\n\t\ttry:return B.value[B.key.index(A)]\n\t\texcept:return _index(B,input,A)\n\treturn A\ndef _transform(known,input,value):\n\tB=known;A=value\n\tif _is_array(A):\n\t\tC=[]\n\t\tfor F in A:C.append(_relate(B,input,F))\n\t\treturn C\n\tif _is_object(A):\n\t\tD={}\n\t\tfor E in A:D[E]=_relate(B,input,A[E])\n\t\treturn D\n\treturn A\ndef _wrap(value):\n\tA=value\n\tif _is_string(A):return _String(A)\n\tif _is_array(A):\n\t\tB=0\n\t\tfor D in A:A[B]=_wrap(D);B+=1\n\telif _is_object(A):\n\t\tfor C in A:A[C]=_wrap(A[C])\n\treturn A\ndef parse(value,*C,**D):\n\tA=value;E=_json.loads(A,*C,**D);B=[]\n\tfor A in E:B.append(_wrap(A))\n\tinput=[]\n\tfor A in B:\n\t\tif isinstance(A,_String):input.append(A.value)\n\t\telse:input.append(A)\n\tA=input[0]\n\tif _is_array(A):return _loop(_array_keys(A),input,[A],A)\n\tif _is_object(A):return _loop(_object_keys(A),input,[A],A)\n\treturn A\ndef stringify(value,*D,**E):\n\tB=_Known();input=[];C=[];A=int(_index(B,input,value))\n\twhile A<len(input):C.append(_transform(B,input,input[A]));A+=1\n\treturn _json.dumps(C,*D,**E)",
|
|
"fs.py": "_B='pyscript'\n_A=None\nimport js\nfrom _pyscript import fs as _fs,interpreter\nfrom pyscript import window\nfrom pyscript.ffi import to_js\nfrom pyscript.context import RUNNING_IN_WORKER\nif RUNNING_IN_WORKER:from pyscript.context import sync as sync_with_worker;from polyscript import IDBMap\nmounted={}\nasync def _check_permission(details):A=details;B=A.handler;C=A.options;D=await B.queryPermission(C);return B if D=='granted'else _A\nasync def mount(path,mode='readwrite',root='',id=_B):\n\tC=path;js.console.warn('experimental pyscript.fs ⚠️');D=f\"{C}@{id}\"\n\tif C in mounted:\n\t\tfor H in mounted.keys():\n\t\t\tif H.startswith(f\"{C}@\")and H!=D:raise ValueError(f\"Path '{C}' is already mounted with a different ID. Unmount it first or use a different path.\")\n\tA=_A;B=_A;F={'id':id,'mode':mode}\n\tif root!='':F['startIn']=root\n\tif RUNNING_IN_WORKER:\n\t\tG=sync_with_worker.storeFSHandler(D,to_js(F))\n\t\tif isinstance(G,bool):E=G\n\t\telse:E=await G\n\t\tif E:\n\t\t\tJ=IDBMap.new(_fs.NAMESPACE);A=await J.get(D);B=await _check_permission(A)\n\t\t\tif B is _A:await js.Promise.resolve(sync_with_worker.getFSHandler(A.options));B=A.handler\n\t\telse:raise RuntimeError(_fs.ERROR)\n\telse:\n\t\tE=await _fs.idb.has(D)\n\t\tif E:\n\t\t\tA=await _fs.idb.get(D);B=await _check_permission(A)\n\t\t\tif B is _A:B=await _fs.getFileSystemDirectoryHandle(A.options)\n\t\telse:I=to_js(F);B=await _fs.getFileSystemDirectoryHandle(I);A={'handler':B,'options':I};await _fs.idb.set(D,to_js(A))\n\tmounted[C]=await interpreter.mountNativeFS(C,B)\nasync def sync(path):\n\tA=path\n\tif A not in mounted:raise KeyError(f\"Path '{A}' is not mounted. Use fs.mount() to mount it first.\")\n\tawait mounted[A].syncfs()\nasync def unmount(path):\n\tA=path\n\tif A not in mounted:raise KeyError(f\"Path '{A}' is not mounted. Cannot unmount.\")\n\tawait sync(A);interpreter._module.FS.unmount(A);del mounted[A]\nasync def revoke(path,id=_B):\n\tB=path;C=f\"{B}@{id}\"\n\tif RUNNING_IN_WORKER:A=sync_with_worker.deleteFSHandler(C)\n\telse:\n\t\tA=await _fs.idb.has(C)\n\t\tif A:A=await _fs.idb.delete(C)\n\tif A:\n\t\tinterpreter._module.FS.unmount(B)\n\t\tif B in mounted:del mounted[B]\n\treturn A",
|
|
"media.py": "from pyscript import window\nfrom pyscript.ffi import to_js\nclass Device:\n\tdef __init__(A,device):A._device_info=device\n\t@property\n\tdef id(self):return self._device_info.deviceId\n\t@property\n\tdef group(self):return self._device_info.groupId\n\t@property\n\tdef kind(self):return self._device_info.kind\n\t@property\n\tdef label(self):return self._device_info.label\n\tdef __getitem__(A,key):return getattr(A,key)\n\t@classmethod\n\tasync def request_stream(F,audio=False,video=True):\n\t\tE='video';D='audio';C=video;B=audio;A={}\n\t\tif isinstance(B,bool):A[D]=B\n\t\telif isinstance(B,dict):A[D]=B\n\t\tif isinstance(C,bool):A[E]=C\n\t\telif isinstance(C,dict):A[E]=C\n\t\treturn await window.navigator.mediaDevices.getUserMedia(to_js(A))\n\t@classmethod\n\tasync def load(A,audio=False,video=True):return await A.request_stream(audio=audio,video=video)\n\tasync def get_stream(A):B=A.kind.replace('input','').replace('output','');C={B:{'deviceId':{'exact':A.id}}};return await A.request_stream(**C)\nasync def list_devices():A=await window.navigator.mediaDevices.enumerateDevices();return[Device(A)for A in A]",
|
|
"storage.py": "_C='memoryview'\n_B='bytearray'\n_A='generic'\nfrom polyscript import storage as _polyscript_storage\nfrom pyscript.flatted import parse as _parse\nfrom pyscript.flatted import stringify as _stringify\nfrom pyscript.ffi import is_none\ndef _convert_to_idb(value):\n\tA=value\n\tif is_none(A):return _stringify(['null',0])\n\tif isinstance(A,(bool,float,int,str,list,dict,tuple)):return _stringify([_A,A])\n\tif isinstance(A,bytearray):return _stringify([_B,list(A)])\n\tif isinstance(A,memoryview):return _stringify([_C,list(A)])\n\traise TypeError(f\"Cannot serialize type {type(A).__name__} for storage.\")\ndef _convert_from_idb(value):\n\tC=value;A,B=_parse(C)\n\tif A=='null':return\n\tif A==_A:return B\n\tif A==_B:return bytearray(B)\n\tif A==_C:return memoryview(bytearray(B))\n\treturn C\nclass Storage(dict):\n\tdef __init__(B,store):A=store;super().__init__({A:_convert_from_idb(B)for(A,B)in A.entries()});B._store=A\n\tdef __delitem__(A,key):A._store.delete(key);super().__delitem__(key)\n\tdef __setitem__(B,key,value):A=value;B._store.set(key,_convert_to_idb(A));super().__setitem__(key,A)\n\tdef clear(A):A._store.clear();super().clear()\n\tasync def sync(A):await A._store.sync()\nasync def storage(name='',storage_class=Storage):\n\tif not name:raise ValueError('Storage name must be a non-empty string')\n\tA=await _polyscript_storage(f\"@pyscript/{name}\");return storage_class(A)",
|
|
"util.py": "import js,inspect\ndef as_bytearray(buffer):\n\tA=js.Uint8Array.new(buffer);B=A.length;C=bytearray(B)\n\tfor D in range(B):C[D]=A[D]\n\treturn C\nclass NotSupported:\n\tdef __init__(A,name,error):object.__setattr__(A,'name',name);object.__setattr__(A,'error',error)\n\tdef __repr__(A):return f\"<NotSupported {A.name} [{A.error}]>\"\n\tdef __getattr__(A,attr):raise AttributeError(A.error)\n\tdef __setattr__(A,attr,value):raise AttributeError(A.error)\n\tdef __call__(A,*B):raise TypeError(A.error)\ndef is_awaitable(obj):\n\tA=obj;from pyscript import config as C\n\tif C['type']=='mpy':\n\t\tB=repr(A)\n\t\tif'<closure <generator>'in B:return True\n\t\tif'<bound_method'in B and'<generator>'in B:return True\n\t\treturn inspect.isgeneratorfunction(A)\n\treturn inspect.iscoroutinefunction(A)",
|
|
"web.py": "_D='object'\n_C='tagName'\n_B='on_'\n_A=None\nfrom pyscript import document,when,Event\nfrom pyscript.ffi import create_proxy,is_none\ndef _wrap_if_not_none(dom_element):return Element.wrap_dom_element(dom_element)if not is_none(dom_element)else _A\ndef _find_by_id(dom_node,target_id):element_id=target_id[1:]if target_id.startswith('#')else target_id;result=dom_node.querySelector(f\"#{element_id}\");return _wrap_if_not_none(result)\ndef _find_and_wrap(dom_node,selector):return ElementCollection.wrap_dom_elements(dom_node.querySelectorAll(selector))\nclass Element:\n\telement_classes_by_tag_name={}\n\t@classmethod\n\tdef get_tag_name(cls):return cls.__name__.replace('_','')\n\t@classmethod\n\tdef register_element_classes(cls,element_classes):\n\t\tfor element_class in element_classes:tag_name=element_class.get_tag_name();cls.element_classes_by_tag_name[tag_name]=element_class\n\t@classmethod\n\tdef unregister_element_classes(cls,element_classes):\n\t\tfor element_class in element_classes:tag_name=element_class.get_tag_name();cls.element_classes_by_tag_name.pop(tag_name,_A)\n\t@classmethod\n\tdef wrap_dom_element(cls,dom_element):element_cls=cls.element_classes_by_tag_name.get(dom_element.tagName.lower(),cls);return element_cls(dom_element=dom_element)\n\tdef __init__(self,dom_element=_A,classes=_A,style=_A,**kwargs):\n\t\tif is_none(dom_element):self._dom_element=document.createElement(type(self).get_tag_name())\n\t\telse:self._dom_element=dom_element\n\t\tself._on_events={};self.update(classes=classes,style=style,**kwargs)\n\tdef __eq__(self,obj):return isinstance(obj,Element)and obj._dom_element==self._dom_element\n\tdef __getitem__(self,key):\n\t\tif isinstance(key,(int,slice)):return self.children[key]\n\t\tif isinstance(key,str):return _find_by_id(self._dom_element,key)\n\t\traise TypeError(f\"Element indices must be integers, slices, or strings, not {type(key).__name__}.\")\n\tdef __getattr__(self,name):\n\t\tif name.startswith(_B):return self.get_event(name)\n\t\tdom_name=self._normalize_attribute_name(name);return getattr(self._dom_element,dom_name)\n\tdef __setattr__(self,name,value):\n\t\tif name.startswith('_'):super().__setattr__(name,value)\n\t\telif name.startswith(_B):self.get_event(name).add_listener(value)\n\t\telse:dom_name=self._normalize_attribute_name(name);setattr(self._dom_element,dom_name,value)\n\tdef _normalize_attribute_name(self,name):\n\t\tif name.endswith('_'):name=name[:-1]\n\t\tif name=='for':return'htmlFor'\n\t\tif name=='class':return'className'\n\t\treturn name\n\tdef get_event(self,name):\n\t\tif not name.startswith(_B):raise ValueError(\"Event names must start with 'on_'.\")\n\t\tevent_name=name[3:]\n\t\tif not hasattr(self._dom_element,event_name):raise ValueError(f\"Element has no '{event_name}' event.\")\n\t\tif name in self._on_events:return self._on_events[name]\n\t\tev=Event();self._on_events[name]=ev;self._dom_element.addEventListener(event_name,create_proxy(ev.trigger));return ev\n\t@property\n\tdef children(self):return ElementCollection.wrap_dom_elements(self._dom_element.children)\n\t@property\n\tdef classes(self):\n\t\tif not hasattr(self,'_classes'):self._classes=Classes(self)\n\t\treturn self._classes\n\t@property\n\tdef style(self):\n\t\tif not hasattr(self,'_style'):self._style=Style(self)\n\t\treturn self._style\n\t@property\n\tdef parent(self):\n\t\tif is_none(self._dom_element.parentElement):return\n\t\treturn Element.wrap_dom_element(self._dom_element.parentElement)\n\tdef append(self,*items):\n\t\tfor item in items:\n\t\t\tif isinstance(item,Element):self._dom_element.appendChild(item._dom_element)\n\t\t\telif isinstance(item,ElementCollection):\n\t\t\t\tfor element in item:self._dom_element.appendChild(element._dom_element)\n\t\t\telif isinstance(item,(list,tuple)):\n\t\t\t\tfor child in item:self.append(child)\n\t\t\telif hasattr(item,_C):self._dom_element.appendChild(item)\n\t\t\telif hasattr(item,'length'):\n\t\t\t\tfor element in item:self._dom_element.appendChild(element)\n\t\t\telse:raise TypeError(f\"Cannot append {type(item).__name__} to element.\")\n\tdef clone(self,clone_id=_A):clone=Element.wrap_dom_element(self._dom_element.cloneNode(True));clone.id=clone_id;return clone\n\tdef find(self,selector):return _find_and_wrap(self._dom_element,selector)\n\tdef show_me(self):self._dom_element.scrollIntoView()\n\tdef update(self,classes=_A,style=_A,**kwargs):\n\t\tif classes:\n\t\t\tif isinstance(classes,str):self.classes.add(classes)\n\t\t\telse:\n\t\t\t\tfor class_name in classes:self.classes.add(class_name)\n\t\tif style:\n\t\t\tfor(key,value)in style.items():self.style[key]=value\n\t\tfor(name,value)in kwargs.items():setattr(self,name,value)\nclass Classes(set):\n\tdef __init__(self,element):self._class_list=element._dom_element.classList;super().__init__(self._class_list)\n\tdef _extract_class_names(self,class_name):return[name for name in class_name.split()if name]if' 'in class_name else[class_name]\n\tdef add(self,class_name):\n\t\tfor name in self._extract_class_names(class_name):super().add(name);self._class_list.add(name)\n\tdef remove(self,class_name):\n\t\tfor name in self._extract_class_names(class_name):super().remove(name);self._class_list.remove(name)\n\tdef discard(self,class_name):\n\t\tfor name in self._extract_class_names(class_name):\n\t\t\tsuper().discard(name)\n\t\t\tif name in self._class_list:self._class_list.remove(name)\n\tdef clear(self):\n\t\tsuper().clear()\n\t\twhile self._class_list.length>0:self._class_list.remove(self._class_list.item(0))\nclass Style(dict):\n\tdef __init__(self,element):self._style=element._dom_element.style;super().__init__()\n\tdef __setitem__(self,key,value):super().__setitem__(key,value);self._style.setProperty(key,str(value))\n\tdef __delitem__(self,key):super().__delitem__(key);self._style.removeProperty(key)\nclass HasOptions:\n\t@property\n\tdef options(self):\n\t\tif not hasattr(self,'_options'):self._options=Options(self)\n\t\treturn self._options\nclass Options:\n\tdef __init__(self,element):self._element=element\n\tdef __getitem__(self,key):return self.options[key]\n\tdef __iter__(self):yield from self.options\n\tdef __len__(self):return len(self.options)\n\tdef __repr__(self):return f\"{self.__class__.__name__} (length: {len(self)}) {self.options}\"\n\t@property\n\tdef options(self):return[Element.wrap_dom_element(o)for o in self._element._dom_element.options]\n\t@property\n\tdef selected(self):return self.options[self._element._dom_element.selectedIndex]\n\tdef add(self,value=_A,html=_A,text=_A,before=_A,**kwargs):\n\t\tif value:kwargs['value']=value\n\t\tif html:kwargs['innerHTML']=html\n\t\tif text:kwargs['text']=text\n\t\tnew_option=option(**kwargs)\n\t\tif before and isinstance(before,Element):before=before._dom_element\n\t\tself._element._dom_element.add(new_option._dom_element,before)\n\tdef clear(self):self._element._dom_element.length=0\n\tdef remove(self,index):self._element._dom_element.remove(index)\nclass ContainerElement(Element):\n\tdef __init__(self,*args,children=_A,dom_element=_A,style=_A,classes=_A,**kwargs):\n\t\tsuper().__init__(dom_element=dom_element,style=style,classes=classes,**kwargs)\n\t\tfor child in list(args)+(children or[]):\n\t\t\tif isinstance(child,(Element,ElementCollection)):self.append(child)\n\t\t\telse:self._dom_element.insertAdjacentHTML('beforeend',child)\n\tdef __iter__(self):yield from self.children\nclass ElementCollection:\n\t@classmethod\n\tdef wrap_dom_elements(cls,dom_elements):return cls([Element.wrap_dom_element(dom_element)for dom_element in dom_elements])\n\tdef __init__(self,elements):self._elements=elements\n\tdef __eq__(self,obj):return isinstance(obj,ElementCollection)and obj._elements==self._elements\n\tdef __getitem__(self,key):\n\t\tif isinstance(key,int):return self._elements[key]\n\t\tif isinstance(key,slice):return ElementCollection(self._elements[key])\n\t\tif isinstance(key,str):\n\t\t\tfor element in self._elements:\n\t\t\t\tresult=_find_by_id(element._dom_element,key)\n\t\t\t\tif result:return result\n\t\t\treturn\n\t\traise TypeError(f\"Collection indices must be integers, slices, or strings, not {type(key).__name__}\")\n\tdef __iter__(self):yield from self._elements\n\tdef __len__(self):return len(self._elements)\n\tdef __repr__(self):return f\"{self.__class__.__name__} (length: {len(self._elements)}) {self._elements}\"\n\t@property\n\tdef elements(self):return self._elements\n\tdef find(self,selector):\n\t\telements=[]\n\t\tfor element in self._elements:elements.extend(_find_and_wrap(element._dom_element,selector))\n\t\treturn ElementCollection(elements)\n\tdef update_all(self,**kwargs):\n\t\tfor element in self._elements:\n\t\t\tfor(name,value)in kwargs.items():setattr(element,name,value)\nclass canvas(ContainerElement):\n\tdef download(self,filename='snapped.png'):download_link=a(download=filename,href=self._dom_element.toDataURL());self.append(download_link);download_link._dom_element.click()\n\tdef draw(self,what,width=_A,height=_A):\n\t\tif isinstance(what,Element):what=what._dom_element\n\t\tctx=self._dom_element.getContext('2d')\n\t\tif width or height:ctx.drawImage(what,0,0,width,height)\n\t\telse:ctx.drawImage(what,0,0)\nclass video(ContainerElement):\n\tdef snap(self,to=_A,width=_A,height=_A):\n\t\tB='CANVAS';A='Element to snap to must be a canvas.';width=width if width else self.videoWidth;height=height if height else self.videoHeight\n\t\tif is_none(to):to=canvas(width=width,height=height)\n\t\telif isinstance(to,Element):\n\t\t\tif to.tag!='canvas':raise TypeError(A)\n\t\telif getattr(to,_C,'')==B:to=canvas(dom_element=to)\n\t\telif isinstance(to,str):\n\t\t\tnodelist=document.querySelectorAll(to)\n\t\t\tif nodelist.length==0:raise TypeError(f\"No element with selector {to} to snap to.\")\n\t\t\tif nodelist[0].tagName!=B:raise TypeError(A)\n\t\t\tto=canvas(dom_element=nodelist[0])\n\t\tto.draw(self,width,height);return to\nclass datalist(ContainerElement,HasOptions):0\nclass optgroup(ContainerElement,HasOptions):0\nclass select(ContainerElement,HasOptions):0\nCONTAINER_TAGS=['a','abbr','address','article','aside','audio','b','blockquote','body','button','caption','cite','code','colgroup','data','dd','del','details','dialog','div','dl','dt','em','fieldset','figcaption','figure','footer','form','h1','h2','h3','h4','h5','h6','head','header','hgroup','html','i','iframe','ins','kbd','label','legend','li','main','map','mark','menu','meta','meter','nav',_D,'ol','option','output','p','param','picture','pre','progress','q','s','script','section','small','span','strong','style','sub','summary','sup','table','tbody','td','template','textarea','tfoot','th','thead','time','title','tr','u','ul','var','wbr']\nVOID_TAGS=['area','base','br','col','embed','hr','img','input','link','source','track']\ndef _create_element_classes():\n\tA='__doc__';classes=[canvas,video,datalist,optgroup,select]\n\tfor tag in CONTAINER_TAGS:class_name=f\"{tag}_\"if tag in('del','map',_D)else tag;doc=f\"HTML <{tag}> element. Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/{tag}\";cls=type(class_name,(ContainerElement,),{A:doc});globals()[class_name]=cls;classes.append(cls)\n\tfor tag in VOID_TAGS:class_name=f\"{tag}_\"if tag=='input'else tag;doc=f\"HTML <{tag}> element. Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/{tag}\";cls=type(class_name,(Element,),{A:doc});globals()[class_name]=cls;classes.append(cls)\n\tElement.register_element_classes(classes)\n_create_element_classes()\nclass Page:\n\tdef __init__(self):self.html=Element.wrap_dom_element(document.documentElement);self.body=Element.wrap_dom_element(document.body);self.head=Element.wrap_dom_element(document.head)\n\tdef __getitem__(self,key):return _find_by_id(document,key)\n\t@property\n\tdef title(self):return document.title\n\t@title.setter\n\tdef title(self,value):document.title=value\n\tdef append(self,*items):self.body.append(*items)\n\tdef find(self,selector):return _find_and_wrap(document,selector)\npage=Page()",
|
|
"websocket.py": "import js\nfrom pyscript.ffi import create_proxy\nfrom pyscript.util import as_bytearray,is_awaitable\ndef _attach_event_handler(websocket,handler_name,handler_function):\n\tA=handler_function\n\tif is_awaitable(A):\n\t\tasync def C(event):await A(WebSocketEvent(event))\n\t\tB=create_proxy(C)\n\telse:B=create_proxy(lambda event:A(WebSocketEvent(event)))\n\tsetattr(websocket,handler_name,B)\nclass WebSocketEvent:\n\tdef __init__(A,event):A._event=event\n\tdef __getattr__(B,attr):\n\t\tA=getattr(B._event,attr)\n\t\tif attr=='data'and not isinstance(A,str):\n\t\t\tif hasattr(A,'to_py'):return A.to_py()\n\t\t\telse:return memoryview(as_bytearray(A))\n\t\treturn A\nclass WebSocket:\n\tCONNECTING=0;OPEN=1;CLOSING=2;CLOSED=3\n\tdef __init__(B,url,protocols=None,**D):\n\t\tC=protocols\n\t\tif C:A=js.WebSocket.new(url,C)\n\t\telse:A=js.WebSocket.new(url)\n\t\tA.binaryType='arraybuffer';object.__setattr__(B,'_js_websocket',A)\n\t\tfor(E,F)in D.items():setattr(B,E,F)\n\tdef __getattr__(A,attr):return getattr(A._js_websocket,attr)\n\tdef __setattr__(B,attr,value):\n\t\tC=value;A=attr\n\t\tif A in['onclose','onerror','onmessage','onopen']:_attach_event_handler(B._js_websocket,A,C)\n\t\telse:setattr(B._js_websocket,A,C)\n\tdef send(B,data):\n\t\tA=data\n\t\tif isinstance(A,str):B._js_websocket.send(A)\n\t\telse:\n\t\t\tC=js.Uint8Array.new(len(A))\n\t\t\tfor(D,E)in enumerate(A):C[D]=E\n\t\t\tB._js_websocket.send(C)\n\tdef close(B,code=None,reason=None):\n\t\tC=reason;A=code\n\t\tif A and C:B._js_websocket.close(A,C)\n\t\telif A:B._js_websocket.close(A)\n\t\telse:B._js_websocket.close()",
|
|
"workers.py": "import js,json\nfrom polyscript import workers as _polyscript_workers\nclass _ReadOnlyWorkersProxy:\n\tdef __getitem__(A,name):return js.Reflect.get(_polyscript_workers,name)\n\tdef __getattr__(A,name):return js.Reflect.get(_polyscript_workers,name)\nworkers=_ReadOnlyWorkersProxy()\nasync def create_named_worker(src,name,config=None,type='py'):\n\tB=config;A=js.document.createElement('script');A.type=type;A.src=src;A.setAttribute('worker','');A.setAttribute('name',name)\n\tif B:\n\t\tif isinstance(B,str):C=B\n\t\telse:C=json.dumps(B)\n\t\tA.setAttribute('config',C)\n\tjs.document.body.append(A);return await workers[name]"
|
|
}
|
|
};
|