Comments (15)
running the same package just with pyodide works just fine. Additionally, with a local installation, replacing that unicode character in the pyscript files, the package also works as planned. Also an older version of pyscript works fine. In fact the same package on pyscript.com works as well:
https://frank_bergmann.pyscriptapps.com/copasi-test/latest/
from pyscript.
Pinging @fpliger then as we need to be careful with Unicode chars in comments, apparently, but I will also investigate why that breaks .. afaik we do test pymedia and we have no issue there
from pyscript.
thank you very much, I can confirm that the patched version linked above works fine.
from pyscript.
I think it comes from here:
from pyscript.
the issue happens only with that package
so it's definitively not an issue with our own code because it's tested and it works ... it is possible though that our packages to virtual FileSystem fails with some edge case but it's hard from this issue to understand what is it that is causing troubles.
from pyscript.
please also keep in mind packages are given directly to pyodide and its import mechanism so I think you'll have the same isseu in raw pyodide and, if that's the case, this issue should be filed in there.
from pyscript.
Mmmm
That's a weird one, definitely worth investing
from pyscript.
OK, I did investigate and I can't reproduce any issue there ... this is my current test page, it uses both the legacy way to write python code and the modern script
one, just to exclude possible shenanigans caused by browsers parsing the content of the <py-script>
custom tag and the result is the same ... I see those lines printed, including the incriminated char:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link
rel="stylesheet"
href="https://pyscript.net/releases/2024.1.3/core.css"
/>
<script
type="module"
src="https://pyscript.net/releases/2024.1.3/core.js"
></script>
</head>
<body>
<py-script>
from pyweb import media
print("from pyodide.ffi import to_js\nfrom pyscript import window\n\n\nclass Device:\n \"\"\"Device represents a media input or output device, such as a microphone,\n camera, or headset.\n \"\"\"\n\n def __init__(self, device):\n self._js = device\n\n @property\n def id(self):\n return self._js.deviceId\n\n @property\n def group(self):\n return self._js.groupId\n\n @property\n def kind(self):\n return self._js.kind\n\n @property\n def label(self):\n return self._js.label\n\n def __getitem__(self, key):\n return getattr(self, key)\n\n @classmethod\n async def load(cls, audio=False, video=True):\n \"\"\"Load the device stream.\"\"\"\n options = window.Object.new()\n options.audio = audio\n if isinstance(video, bool):\n options.video = video\n else:\n # TODO: Think this can be simplified but need to check it on the pyodide side\n\n # TODO: this is pyodide specific. shouldn't be!\n options.video = window.Object.new()\n for k in video:\n setattr(\n options.video,\n k,\n to_js(video[k], dict_converter=window.Object.fromEntries),\n )\n\n stream = await window.navigator.mediaDevices.getUserMedia(options)\n return stream\n\n async def get_stream(self):\n key = self.kind.replace(\"input\", \"\").replace(\"output\", \"\")\n options = {key: {\"deviceId\": {\"exact\": self.id}}}\n\n return await self.load(**options)\n\n\nasync def list_devices() -> list[dict]:\n \"\"\"\n Return the list of the currently available media input and output devices,\n such as microphones, cameras, headsets, and so forth.\n\n Output:\n\n list(dict) - list of dictionaries representing the available media devices.\n Each dictionary has the following keys:\n * deviceId: a string that is an identifier for the represented device\n that is persisted across sessions. It is un-guessable by other\n applications and unique to the origin of the calling application.\n It is reset when the user clears cookies (for Private Browsing, a\n different identifier is used that is not persisted across sessions).\n\n * groupId: a string that is a group identifier. Two devices have the same\n group identifier if they belong to the same physical device — for\n example a monitor with both a built-in camera and a microphone.\n\n * kind: an enumerated value that is either \"videoinput\", \"audioinput\"\n or \"audiooutput\".\n\n * label: a string describing this device (for example \"External USB\n Webcam\").\n\n Note: the returned list will omit any devices that are blocked by the document\n Permission Policy: microphone, camera, speaker-selection (for output devices),\n and so on. Access to particular non-default devices is also gated by the\n Permissions API, and the list will omit devices for which the user has not\n granted explicit permission.\n \"\"\"\n # https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices\n return [\n Device(obj) for obj in await window.navigator.mediaDevices.enumerateDevices()\n ]\n")
</py-script>
<script type="py">
from pyweb import media
print("from pyodide.ffi import to_js\nfrom pyscript import window\n\n\nclass Device:\n \"\"\"Device represents a media input or output device, such as a microphone,\n camera, or headset.\n \"\"\"\n\n def __init__(self, device):\n self._js = device\n\n @property\n def id(self):\n return self._js.deviceId\n\n @property\n def group(self):\n return self._js.groupId\n\n @property\n def kind(self):\n return self._js.kind\n\n @property\n def label(self):\n return self._js.label\n\n def __getitem__(self, key):\n return getattr(self, key)\n\n @classmethod\n async def load(cls, audio=False, video=True):\n \"\"\"Load the device stream.\"\"\"\n options = window.Object.new()\n options.audio = audio\n if isinstance(video, bool):\n options.video = video\n else:\n # TODO: Think this can be simplified but need to check it on the pyodide side\n\n # TODO: this is pyodide specific. shouldn't be!\n options.video = window.Object.new()\n for k in video:\n setattr(\n options.video,\n k,\n to_js(video[k], dict_converter=window.Object.fromEntries),\n )\n\n stream = await window.navigator.mediaDevices.getUserMedia(options)\n return stream\n\n async def get_stream(self):\n key = self.kind.replace(\"input\", \"\").replace(\"output\", \"\")\n options = {key: {\"deviceId\": {\"exact\": self.id}}}\n\n return await self.load(**options)\n\n\nasync def list_devices() -> list[dict]:\n \"\"\"\n Return the list of the currently available media input and output devices,\n such as microphones, cameras, headsets, and so forth.\n\n Output:\n\n list(dict) - list of dictionaries representing the available media devices.\n Each dictionary has the following keys:\n * deviceId: a string that is an identifier for the represented device\n that is persisted across sessions. It is un-guessable by other\n applications and unique to the origin of the calling application.\n It is reset when the user clears cookies (for Private Browsing, a\n different identifier is used that is not persisted across sessions).\n\n * groupId: a string that is a group identifier. Two devices have the same\n group identifier if they belong to the same physical device — for\n example a monitor with both a built-in camera and a microphone.\n\n * kind: an enumerated value that is either \"videoinput\", \"audioinput\"\n or \"audiooutput\".\n\n * label: a string describing this device (for example \"External USB\n Webcam\").\n\n Note: the returned list will omit any devices that are blocked by the document\n Permission Policy: microphone, camera, speaker-selection (for output devices),\n and so on. Access to particular non-default devices is also gated by the\n Permissions API, and the list will omit devices for which the user has not\n granted explicit permission.\n \"\"\"\n # https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices\n return [\n Device(obj) for obj in await window.navigator.mediaDevices.enumerateDevices()\n ]\n")
</script>
</body>
</html>
I did also manually changed that char with \u2014
directly in the comment and the result is the same: nothing breaks.
I am afraid being incapable to reproduce this issue makes it very hard to fix it ... what is happening in your package exactly and why would our otherwise-working code fail? 🤔
from pyscript.
P.S. also note that output
as attribute doesn't exist anymore ... it's eventually target
and it's an ID or a CSS selector.
edit same goes for py-env
that doesn't exist anymore
from pyscript.
I tracked it out to the boilerscript code generated, that includes _path.write_text statements without an encoding specified, and inside that string, there are those unicode characters.
about this ... I've tried to enforce latin-1 without success ... meaning: no errors.
I am struggling to understand in which circumstance you have issues because that is a valid JSON string and JSON is pretty universal. I understand that char in particular goes beyond ASCII table but I don't understand why you have such issue.
If enforcing utf-8
encoding instead would solve without affecting too much bootstrap performance, I might try to fix it but I still would love to understand the culprit of this issue as no browser I could try with no version could reproduce this issue.
from pyscript.
I'd be happy to change the wheel as well, but i fail to understand where the problem lies. I essentially built the package using pyodide build, tested it in pyodide (and jupyterlite), and then wanted to try it with pyscript, where it worked with the old version but not the new one.
The package itself is a scientific library, exposed via SWIG. I don't understand what would change the environment default encoding by just using the py-config
line with the package statement. If it helps, here is the __init__.py
script, though i'm not sure that would have executed at that point.
https://gist.github.com/fbergmann/48219beb795a42d2c17294c03d803fac
if there is any further information i could provide, please let me know.
from pyscript.
I am not sure I have resources to dig into a 21K lines of code but these lines got me thinking ... https://gist.github.com/fbergmann/48219beb795a42d2c17294c03d803fac#file-__init__-py-L100-L103
I have no idea what's going on in there but if comments are not dropped out of the equation that might be the issue ... I don't think with older PyScript we were sanitizing more than what JSON can produce, but again ... if you think the issue is in the write_text
not specifying any encoding, I am down to try a variant but without a minimal reproducible test, I can't just land that variant in production to let you test your module works ... I hope this makes sense.
from pyscript.
on a second thought, you @fbergmann could do that!
you clone this repo, run npm i
and eventually npm run build
... then you run npm run server
and you have all you need.
You can then add utf-8
encoding in this line https://github.com/pyscript/pyscript/blob/main/pyscript.core/src/stdlib.js#L24 as extra embedded argument, run npm run build
again, and test your stuff works.
I understand I am asking a lot from you but please try to realize without a minimal reproducible code, and to date tons of modules have been used without this issue, it's extremely hard to validate the workaround or fix.
I am here to help you forward with any local test, so please let me know if you need anything else.
P.S. any ./test/
file that is html likely gives you a template to bootstrap from there and see if latest built artifact satisfies your use-case.
from pyscript.
I can confirm that running with the patch, everything works as it should. While without it I still see the error.
diff --git a/pyscript.core/src/stdlib.js b/pyscript.core/src/stdlib.js
index 4818772..dc5d9da 100644
--- a/pyscript.core/src/stdlib.js
+++ b/pyscript.core/src/stdlib.js
@@ -21,7 +21,7 @@ const write = (base, literal) => {
python.push(`_path = _Path("${base}/${key}")`);
if (typeof value === "string") {
const code = JSON.stringify(value);
- python.push(`_path.write_text(${code})`);
+ python.push(`_path.write_text(${code}, encoding="utf-8")`);
} else {
// @see https://github.com/pyscript/pyscript/pull/1813#issuecomment-1781502909
python.push(`if not _os.path.exists("${base}/${key}"):`);
Not sure how to measure performance. I ran the tests using make test-integration
with the patch the runtime was:
============ 152 passed, 40 skipped, 6 xfailed in 203.21s (0:03:23) ============
without
============ 152 passed, 40 skipped, 6 xfailed in 211.59s (0:03:31) ============
but I'm not sure whether that difference is representative. You let me know what else you'd need from me.
from pyscript.
First of all, thank you a lot for helping out, really appreciated!
We have merged the patched version on main and published to npm (our "canary" distribution).
You can use these CDN links to try latest and re-confirm we're good now:
- the JS file: https://cdn.jsdelivr.net/npm/@pyscript/core/dist/core.js
- the CSS one: https://cdn.jsdelivr.net/npm/@pyscript/core/dist/core.css
from pyscript.
Related Issues (20)
- `PyDom[key: int]` raises `AttributeError: 'int' object has no attribute 'indices'`
- Terminal does not show error message when using workers HOT 2
- Py Terminal issues aggregation HOT 1
- PyScript pre-resolved config URL is not consistent
- the py-editor is created repeatedly HOT 13
- MicroPython doesn't support MethodType() from "types" module! HOT 1
- MicroPython doesn't support alternative syntax to create a tuple outta comprehension HOT 1
- MicroPython should provide better error messages for missing APIs HOT 8
- Alert box issue. HOT 3
- Error message not shown. HOT 6
- terminal with worker not working HOT 2
- Saved Image not Displayed. HOT 4
- Incorrect line number in exception tracebacks HOT 18
- nltk data download error HOT 1
- Unable to upload pdf file. HOT 1
- Unable to upload .mp4 file. HOT 1
- Cannot create a PyWorker from python using Pyodide HOT 8
- Improve either PyWorker documentation or internals in general HOT 11
- Trouble interacting with files in Pyscript (both virtual and local) HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pyscript.