mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-19 18:27:29 -05:00
Re ruff (#2292)
* Ruff fixes * Ruff fixes * from __future__ import annotations breaks MicroPython * noqa: FURB188 because there is no str.replacesuffix() in MicroPython * Add ruff to pre-commit
This commit is contained in:
@@ -38,6 +38,11 @@ repos:
|
|||||||
additional_dependencies:
|
additional_dependencies:
|
||||||
- tomli
|
- tomli
|
||||||
|
|
||||||
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
|
rev: v0.9.6
|
||||||
|
hooks:
|
||||||
|
- id: ruff
|
||||||
|
|
||||||
- repo: https://github.com/hoodmane/pyscript-prettier-precommit
|
- repo: https://github.com/hoodmane/pyscript-prettier-precommit
|
||||||
rev: "v3.0.0-alpha.6"
|
rev: "v3.0.0-alpha.6"
|
||||||
hooks:
|
hooks:
|
||||||
|
|||||||
@@ -73,14 +73,14 @@ def _eval_formatter(obj, print_method):
|
|||||||
"""
|
"""
|
||||||
if print_method == "__repr__":
|
if print_method == "__repr__":
|
||||||
return repr(obj)
|
return repr(obj)
|
||||||
elif hasattr(obj, print_method):
|
if hasattr(obj, print_method):
|
||||||
if print_method == "savefig":
|
if print_method == "savefig":
|
||||||
buf = io.BytesIO()
|
buf = io.BytesIO()
|
||||||
obj.savefig(buf, format="png")
|
obj.savefig(buf, format="png")
|
||||||
buf.seek(0)
|
buf.seek(0)
|
||||||
return base64.b64encode(buf.read()).decode("utf-8")
|
return base64.b64encode(buf.read()).decode("utf-8")
|
||||||
return getattr(obj, print_method)()
|
return getattr(obj, print_method)()
|
||||||
elif print_method == "_repr_mimebundle_":
|
if print_method == "_repr_mimebundle_":
|
||||||
return {}, {}
|
return {}, {}
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ def _format_mime(obj):
|
|||||||
|
|
||||||
if output is None:
|
if output is None:
|
||||||
continue
|
continue
|
||||||
elif mime_type not in _MIME_RENDERERS:
|
if mime_type not in _MIME_RENDERERS:
|
||||||
not_available.append(mime_type)
|
not_available.append(mime_type)
|
||||||
continue
|
continue
|
||||||
break
|
break
|
||||||
@@ -149,9 +149,11 @@ def display(*values, target=None, append=True):
|
|||||||
if target is None:
|
if target is None:
|
||||||
target = current_target()
|
target = current_target()
|
||||||
elif not isinstance(target, str):
|
elif not isinstance(target, str):
|
||||||
raise TypeError(f"target must be str or None, not {target.__class__.__name__}")
|
msg = f"target must be str or None, not {target.__class__.__name__}"
|
||||||
|
raise TypeError(msg)
|
||||||
elif target == "":
|
elif target == "":
|
||||||
raise ValueError("Cannot have an empty target")
|
msg = "Cannot have an empty target"
|
||||||
|
raise ValueError(msg)
|
||||||
elif target.startswith("#"):
|
elif target.startswith("#"):
|
||||||
# note: here target is str and not None!
|
# note: here target is str and not None!
|
||||||
# align with @when behavior
|
# align with @when behavior
|
||||||
@@ -161,9 +163,8 @@ def display(*values, target=None, append=True):
|
|||||||
|
|
||||||
# If target cannot be found on the page, a ValueError is raised
|
# If target cannot be found on the page, a ValueError is raised
|
||||||
if element is None:
|
if element is None:
|
||||||
raise ValueError(
|
msg = f"Invalid selector with id={target}. Cannot be found in the page."
|
||||||
f"Invalid selector with id={target}. Cannot be found in the page."
|
raise ValueError(msg)
|
||||||
)
|
|
||||||
|
|
||||||
# if element is a <script type="py">, it has a 'target' attribute which
|
# if element is a <script type="py">, it has a 'target' attribute which
|
||||||
# points to the visual element holding the displayed values. In that case,
|
# points to the visual element holding the displayed values. In that case,
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ class Event:
|
|||||||
if listener not in self._listeners:
|
if listener not in self._listeners:
|
||||||
self._listeners.append(listener)
|
self._listeners.append(listener)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Listener must be callable or awaitable.")
|
msg = "Listener must be callable or awaitable."
|
||||||
|
raise ValueError(msg)
|
||||||
|
|
||||||
def remove_listener(self, *args):
|
def remove_listener(self, *args):
|
||||||
"""
|
"""
|
||||||
@@ -76,7 +77,8 @@ def when(target, *args, **kwargs):
|
|||||||
# Extract the selector from the arguments or keyword arguments.
|
# Extract the selector from the arguments or keyword arguments.
|
||||||
selector = args[0] if args else kwargs.pop("selector")
|
selector = args[0] if args else kwargs.pop("selector")
|
||||||
if not selector:
|
if not selector:
|
||||||
raise ValueError("No selector provided.")
|
msg = "No selector provided."
|
||||||
|
raise ValueError(msg)
|
||||||
# Grab the DOM elements to which the target event will be attached.
|
# Grab the DOM elements to which the target event will be attached.
|
||||||
from pyscript.web import Element, ElementCollection
|
from pyscript.web import Element, ElementCollection
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ def _object_keys(value):
|
|||||||
|
|
||||||
|
|
||||||
def _is_array(value):
|
def _is_array(value):
|
||||||
return isinstance(value, list) or isinstance(value, tuple)
|
return isinstance(value, (list, tuple))
|
||||||
|
|
||||||
|
|
||||||
def _is_object(value):
|
def _is_object(value):
|
||||||
@@ -60,10 +60,10 @@ def _loop(keys, input, known, output):
|
|||||||
|
|
||||||
|
|
||||||
def _ref(key, value, input, known, output):
|
def _ref(key, value, input, known, output):
|
||||||
if _is_array(value) and not value in known:
|
if _is_array(value) and value not in known:
|
||||||
known.append(value)
|
known.append(value)
|
||||||
value = _loop(_array_keys(value), input, known, value)
|
value = _loop(_array_keys(value), input, known, value)
|
||||||
elif _is_object(value) and not value in known:
|
elif _is_object(value) and value not in known:
|
||||||
known.append(value)
|
known.append(value)
|
||||||
value = _loop(_object_keys(value), input, known, value)
|
value = _loop(_object_keys(value), input, known, value)
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class JSModule:
|
|||||||
# avoid pyodide looking for non existent fields
|
# avoid pyodide looking for non existent fields
|
||||||
if not field.startswith("_"):
|
if not field.startswith("_"):
|
||||||
return getattr(getattr(js_modules, self.name), field)
|
return getattr(getattr(js_modules, self.name), field)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
# generate N modules in the system that will proxy the real value
|
# generate N modules in the system that will proxy the real value
|
||||||
|
|||||||
@@ -44,8 +44,7 @@ class Device:
|
|||||||
for k in video:
|
for k in video:
|
||||||
setattr(options.video, k, to_js(video[k]))
|
setattr(options.video, k, to_js(video[k]))
|
||||||
|
|
||||||
stream = await window.navigator.mediaDevices.getUserMedia(options)
|
return await window.navigator.mediaDevices.getUserMedia(options)
|
||||||
return stream
|
|
||||||
|
|
||||||
async def get_stream(self):
|
async def get_stream(self):
|
||||||
key = self.kind.replace("input", "").replace("output", "")
|
key = self.kind.replace("input", "").replace("output", "")
|
||||||
|
|||||||
@@ -10,10 +10,11 @@ def _to_idb(value):
|
|||||||
if isinstance(value, (bool, float, int, str, list, dict, tuple)):
|
if isinstance(value, (bool, float, int, str, list, dict, tuple)):
|
||||||
return _stringify(["generic", value])
|
return _stringify(["generic", value])
|
||||||
if isinstance(value, bytearray):
|
if isinstance(value, bytearray):
|
||||||
return _stringify(["bytearray", [v for v in value]])
|
return _stringify(["bytearray", list(value)])
|
||||||
if isinstance(value, memoryview):
|
if isinstance(value, memoryview):
|
||||||
return _stringify(["memoryview", [v for v in value]])
|
return _stringify(["memoryview", list(value)])
|
||||||
raise TypeError(f"Unexpected value: {value}")
|
msg = f"Unexpected value: {value}"
|
||||||
|
raise TypeError(msg)
|
||||||
|
|
||||||
|
|
||||||
# convert an IndexedDB compatible entry into a Python value
|
# convert an IndexedDB compatible entry into a Python value
|
||||||
@@ -56,5 +57,6 @@ class Storage(dict):
|
|||||||
|
|
||||||
async def storage(name="", storage_class=Storage):
|
async def storage(name="", storage_class=Storage):
|
||||||
if not name:
|
if not name:
|
||||||
raise ValueError("The storage name must be defined")
|
msg = "The storage name must be defined"
|
||||||
|
raise ValueError(msg)
|
||||||
return storage_class(await _storage(f"@pyscript/{name}"))
|
return storage_class(await _storage(f"@pyscript/{name}"))
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ def as_bytearray(buffer):
|
|||||||
ui8a = js.Uint8Array.new(buffer)
|
ui8a = js.Uint8Array.new(buffer)
|
||||||
size = ui8a.length
|
size = ui8a.length
|
||||||
ba = bytearray(size)
|
ba = bytearray(size)
|
||||||
for i in range(0, size):
|
for i in range(size):
|
||||||
ba[i] = ui8a[i]
|
ba[i] = ui8a[i]
|
||||||
return ba
|
return ba
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,10 @@
|
|||||||
|
|
||||||
# `when` is not used in this module. It is imported here save the user an additional
|
# `when` is not used in this module. It is imported here save the user an additional
|
||||||
# import (i.e. they can get what they need from `pyscript.web`).
|
# import (i.e. they can get what they need from `pyscript.web`).
|
||||||
from pyscript import document, when, Event # NOQA
|
|
||||||
|
# from __future__ import annotations # CAUTION: This is not supported in MicroPython.
|
||||||
|
|
||||||
|
from pyscript import document, when, Event # noqa: F401
|
||||||
from pyscript.ffi import create_proxy
|
from pyscript.ffi import create_proxy
|
||||||
|
|
||||||
|
|
||||||
@@ -100,7 +103,7 @@ class Element:
|
|||||||
If `key` is an integer or a slice we use it to index/slice the element's
|
If `key` is an integer or a slice we use it to index/slice the element's
|
||||||
children. Otherwise, we use `key` as a query selector.
|
children. Otherwise, we use `key` as a query selector.
|
||||||
"""
|
"""
|
||||||
if isinstance(key, int) or isinstance(key, slice):
|
if isinstance(key, (int, slice)):
|
||||||
return self.children[key]
|
return self.children[key]
|
||||||
|
|
||||||
return self.find(key)
|
return self.find(key)
|
||||||
@@ -120,7 +123,7 @@ class Element:
|
|||||||
# attribute `for` which is a Python keyword, so you can access it on the
|
# attribute `for` which is a Python keyword, so you can access it on the
|
||||||
# Element instance via `for_`).
|
# Element instance via `for_`).
|
||||||
if name.endswith("_"):
|
if name.endswith("_"):
|
||||||
name = name[:-1]
|
name = name[:-1] # noqa: FURB188 No str.removesuffix() in MicroPython.
|
||||||
return getattr(self._dom_element, name)
|
return getattr(self._dom_element, name)
|
||||||
|
|
||||||
def __setattr__(self, name, value):
|
def __setattr__(self, name, value):
|
||||||
@@ -138,7 +141,7 @@ class Element:
|
|||||||
# attribute `for` which is a Python keyword, so you can access it on the
|
# attribute `for` which is a Python keyword, so you can access it on the
|
||||||
# Element instance via `for_`).
|
# Element instance via `for_`).
|
||||||
if name.endswith("_"):
|
if name.endswith("_"):
|
||||||
name = name[:-1]
|
name = name[:-1] # noqa: FURB188 No str.removesuffix() in MicroPython.
|
||||||
|
|
||||||
if name.startswith("on_"):
|
if name.startswith("on_"):
|
||||||
# Ensure on-events are cached in the _on_events dict if the
|
# Ensure on-events are cached in the _on_events dict if the
|
||||||
@@ -152,10 +155,12 @@ class Element:
|
|||||||
Get an `Event` instance for the specified event name.
|
Get an `Event` instance for the specified event name.
|
||||||
"""
|
"""
|
||||||
if not name.startswith("on_"):
|
if not name.startswith("on_"):
|
||||||
raise ValueError("Event names must start with 'on_'.")
|
msg = "Event names must start with 'on_'."
|
||||||
|
raise ValueError(msg)
|
||||||
event_name = name[3:] # Remove the "on_" prefix.
|
event_name = name[3:] # Remove the "on_" prefix.
|
||||||
if not hasattr(self._dom_element, event_name):
|
if not hasattr(self._dom_element, event_name):
|
||||||
raise ValueError(f"Element has no '{event_name}' event.")
|
msg = f"Element has no '{event_name}' event."
|
||||||
|
raise ValueError(msg)
|
||||||
if name in self._on_events:
|
if name in self._on_events:
|
||||||
return self._on_events[name]
|
return self._on_events[name]
|
||||||
# Such an on-event exists in the DOM element, but we haven't yet
|
# Such an on-event exists in the DOM element, but we haven't yet
|
||||||
@@ -203,7 +208,7 @@ class Element:
|
|||||||
# We check for list/tuple here and NOT for any iterable as it will match
|
# We check for list/tuple here and NOT for any iterable as it will match
|
||||||
# a JS Nodelist which is handled explicitly below.
|
# a JS Nodelist which is handled explicitly below.
|
||||||
# NodeList.
|
# NodeList.
|
||||||
elif isinstance(item, list) or isinstance(item, tuple):
|
elif isinstance(item, (list, tuple)):
|
||||||
for child in item:
|
for child in item:
|
||||||
self.append(child)
|
self.append(child)
|
||||||
|
|
||||||
@@ -227,10 +232,11 @@ class Element:
|
|||||||
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# Nope! This is not an element or a NodeList.
|
# Nope! This is not an element or a NodeList.
|
||||||
raise TypeError(
|
msg = (
|
||||||
f'Element "{item}" is a proxy object, "'
|
f'Element "{item}" is a proxy object, "'
|
||||||
f"but not a valid element or a NodeList."
|
f"but not a valid element or a NodeList."
|
||||||
)
|
)
|
||||||
|
raise TypeError(msg)
|
||||||
|
|
||||||
def clone(self, clone_id=None):
|
def clone(self, clone_id=None):
|
||||||
"""Make a clone of the element (clones the underlying DOM object too)."""
|
"""Make a clone of the element (clones the underlying DOM object too)."""
|
||||||
@@ -401,9 +407,8 @@ class Options:
|
|||||||
|
|
||||||
new_option = option(**kwargs)
|
new_option = option(**kwargs)
|
||||||
|
|
||||||
if before:
|
if before and isinstance(before, Element):
|
||||||
if isinstance(before, Element):
|
before = before._dom_element
|
||||||
before = before._dom_element
|
|
||||||
|
|
||||||
self._element._dom_element.add(new_option._dom_element, before)
|
self._element._dom_element.add(new_option._dom_element, before)
|
||||||
|
|
||||||
@@ -463,7 +468,7 @@ class ContainerElement(Element):
|
|||||||
)
|
)
|
||||||
|
|
||||||
for child in list(args) + (children or []):
|
for child in list(args) + (children or []):
|
||||||
if isinstance(child, Element) or isinstance(child, ElementCollection):
|
if isinstance(child, (Element, ElementCollection)):
|
||||||
self.append(child)
|
self.append(child)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@@ -493,14 +498,13 @@ class ClassesCollection:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
for class_name in self._all_class_names():
|
yield from self._all_class_names()
|
||||||
yield class_name
|
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return len(self._all_class_names())
|
return len(self._all_class_names())
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"ClassesCollection({repr(self._collection)})"
|
return f"ClassesCollection({self._collection!r})"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return " ".join(self._all_class_names())
|
return " ".join(self._all_class_names())
|
||||||
@@ -553,7 +557,7 @@ class StyleCollection:
|
|||||||
element.style[key] = value
|
element.style[key] = value
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"StyleCollection({repr(self._collection)})"
|
return f"StyleCollection({self._collection!r})"
|
||||||
|
|
||||||
def remove(self, key):
|
def remove(self, key):
|
||||||
"""Remove a CSS property from the elements in the collection."""
|
"""Remove a CSS property from the elements in the collection."""
|
||||||
@@ -588,7 +592,7 @@ class ElementCollection:
|
|||||||
if isinstance(key, int):
|
if isinstance(key, int):
|
||||||
return self._elements[key]
|
return self._elements[key]
|
||||||
|
|
||||||
elif isinstance(key, slice):
|
if isinstance(key, slice):
|
||||||
return ElementCollection(self._elements[key])
|
return ElementCollection(self._elements[key])
|
||||||
|
|
||||||
return self.find(key)
|
return self.find(key)
|
||||||
@@ -1125,7 +1129,8 @@ class video(ContainerElement):
|
|||||||
|
|
||||||
elif isinstance(to, Element):
|
elif isinstance(to, Element):
|
||||||
if to.tag != "canvas":
|
if to.tag != "canvas":
|
||||||
raise TypeError("Element to snap to must be a canvas.")
|
msg = "Element to snap to must be a canvas."
|
||||||
|
raise TypeError(msg)
|
||||||
|
|
||||||
elif getattr(to, "tagName", "") == "CANVAS":
|
elif getattr(to, "tagName", "") == "CANVAS":
|
||||||
to = canvas(dom_element=to)
|
to = canvas(dom_element=to)
|
||||||
@@ -1134,10 +1139,12 @@ class video(ContainerElement):
|
|||||||
elif isinstance(to, str):
|
elif isinstance(to, str):
|
||||||
nodelist = document.querySelectorAll(to) # NOQA
|
nodelist = document.querySelectorAll(to) # NOQA
|
||||||
if nodelist.length == 0:
|
if nodelist.length == 0:
|
||||||
raise TypeError("No element with selector {to} to snap to.")
|
msg = "No element with selector {to} to snap to."
|
||||||
|
raise TypeError(msg)
|
||||||
|
|
||||||
if nodelist[0].tagName != "CANVAS":
|
if nodelist[0].tagName != "CANVAS":
|
||||||
raise TypeError("Element to snap to must be a canvas.")
|
msg = "Element to snap to must be a canvas."
|
||||||
|
raise TypeError(msg)
|
||||||
|
|
||||||
to = canvas(dom_element=nodelist[0])
|
to = canvas(dom_element=nodelist[0])
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class EventMessage:
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
class WebSocket(object):
|
class WebSocket:
|
||||||
CONNECTING = 0
|
CONNECTING = 0
|
||||||
OPEN = 1
|
OPEN = 1
|
||||||
CLOSING = 2
|
CLOSING = 2
|
||||||
|
|||||||
@@ -25,10 +25,12 @@ async def create_named_worker(src="", name="", config=None, type="py"):
|
|||||||
from json import dumps
|
from json import dumps
|
||||||
|
|
||||||
if not src:
|
if not src:
|
||||||
raise ValueError("Named workers require src")
|
msg = "Named workers require src"
|
||||||
|
raise ValueError(msg)
|
||||||
|
|
||||||
if not name:
|
if not name:
|
||||||
raise ValueError("Named workers require a name")
|
msg = "Named workers require a name"
|
||||||
|
raise ValueError(msg)
|
||||||
|
|
||||||
s = _js.document.createElement("script")
|
s = _js.document.createElement("script")
|
||||||
s.type = type
|
s.type = type
|
||||||
@@ -37,7 +39,7 @@ async def create_named_worker(src="", name="", config=None, type="py"):
|
|||||||
_set(s, "name", name)
|
_set(s, "name", name)
|
||||||
|
|
||||||
if config:
|
if config:
|
||||||
_set(s, "config", isinstance(config, str) and config or dumps(config))
|
_set(s, "config", (isinstance(config, str) and config) or dumps(config))
|
||||||
|
|
||||||
_js.document.body.append(s)
|
_js.document.body.append(s)
|
||||||
return await workers[name]
|
return await workers[name]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import numpy
|
import numpy as np
|
||||||
import matplotlib
|
import matplotlib as mpl
|
||||||
|
|
||||||
# just do something with the packages
|
# just do something with the packages
|
||||||
print(len(dir(numpy)))
|
print(len(dir(np)))
|
||||||
print(len(dir(matplotlib)))
|
print(len(dir(mpl)))
|
||||||
|
|||||||
@@ -4,4 +4,4 @@ def runtime_version():
|
|||||||
return sys.version
|
return sys.version
|
||||||
|
|
||||||
|
|
||||||
__export__ = ['runtime_version']
|
__export__ = ["runtime_version"]
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ if TEST == "implicit":
|
|||||||
await fs.mount("/persistent")
|
await fs.mount("/persistent")
|
||||||
|
|
||||||
print(
|
print(
|
||||||
RUNNING_IN_WORKER and "Worker" or "Main",
|
(RUNNING_IN_WORKER and "Worker") or "Main",
|
||||||
os.listdir("/persistent"),
|
os.listdir("/persistent"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ import pygame
|
|||||||
|
|
||||||
# see if we can load more than standard BMP
|
# see if we can load more than standard BMP
|
||||||
if not pygame.image.get_extended():
|
if not pygame.image.get_extended():
|
||||||
raise SystemExit("Sorry, extended image module required")
|
msg = "Sorry, extended image module required"
|
||||||
|
raise SystemExit(msg)
|
||||||
|
|
||||||
|
|
||||||
# game constants
|
# game constants
|
||||||
@@ -56,7 +57,8 @@ def load_image(file):
|
|||||||
try:
|
try:
|
||||||
surface = pygame.image.load(file)
|
surface = pygame.image.load(file)
|
||||||
except pygame.error:
|
except pygame.error:
|
||||||
raise SystemExit(f'Could not load image "{file}" {pygame.get_error()}')
|
msg = f'Could not load image "{file}" {pygame.get_error()}'
|
||||||
|
raise SystemExit(msg)
|
||||||
return surface.convert()
|
return surface.convert()
|
||||||
|
|
||||||
|
|
||||||
@@ -66,8 +68,7 @@ def load_sound(file):
|
|||||||
return None
|
return None
|
||||||
file = os.path.join(main_dir, "data", file)
|
file = os.path.join(main_dir, "data", file)
|
||||||
try:
|
try:
|
||||||
sound = pygame.mixer.Sound(file)
|
return pygame.mixer.Sound(file)
|
||||||
return sound
|
|
||||||
except pygame.error:
|
except pygame.error:
|
||||||
print(f"Warning, unable to load, {file}")
|
print(f"Warning, unable to load, {file}")
|
||||||
return None
|
return None
|
||||||
@@ -227,7 +228,7 @@ class Score(pygame.sprite.Sprite):
|
|||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
"""We only update the score in update() when it has changed."""
|
"""We only update the score in update() when it has changed."""
|
||||||
if SCORE != self.lastscore:
|
if self.lastscore != SCORE:
|
||||||
self.lastscore = SCORE
|
self.lastscore = SCORE
|
||||||
msg = "Score: %d" % SCORE
|
msg = "Score: %d" % SCORE
|
||||||
self.image = self.font.render(msg, 0, self.color)
|
self.image = self.font.render(msg, 0, self.color)
|
||||||
@@ -296,7 +297,7 @@ async def main(winstyle=0):
|
|||||||
# Create Some Starting Values
|
# Create Some Starting Values
|
||||||
global score
|
global score
|
||||||
alienreload = ALIEN_RELOAD
|
alienreload = ALIEN_RELOAD
|
||||||
clock = pygame.Clock()
|
_clock = pygame.Clock()
|
||||||
|
|
||||||
# initialize our starting sprites
|
# initialize our starting sprites
|
||||||
global SCORE
|
global SCORE
|
||||||
@@ -313,24 +314,23 @@ async def main(winstyle=0):
|
|||||||
return
|
return
|
||||||
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
|
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
|
||||||
return
|
return
|
||||||
elif event.type == pygame.KEYDOWN:
|
if event.type == pygame.KEYDOWN and event.key == pygame.K_f:
|
||||||
if event.key == pygame.K_f:
|
if not fullscreen:
|
||||||
if not fullscreen:
|
print("Changing to FULLSCREEN")
|
||||||
print("Changing to FULLSCREEN")
|
screen_backup = screen.copy()
|
||||||
screen_backup = screen.copy()
|
screen = pygame.display.set_mode(
|
||||||
screen = pygame.display.set_mode(
|
SCREENRECT.size, winstyle | pygame.FULLSCREEN, bestdepth
|
||||||
SCREENRECT.size, winstyle | pygame.FULLSCREEN, bestdepth
|
)
|
||||||
)
|
screen.blit(screen_backup, (0, 0))
|
||||||
screen.blit(screen_backup, (0, 0))
|
else:
|
||||||
else:
|
print("Changing to windowed mode")
|
||||||
print("Changing to windowed mode")
|
screen_backup = screen.copy()
|
||||||
screen_backup = screen.copy()
|
screen = pygame.display.set_mode(
|
||||||
screen = pygame.display.set_mode(
|
SCREENRECT.size, winstyle, bestdepth
|
||||||
SCREENRECT.size, winstyle, bestdepth
|
)
|
||||||
)
|
screen.blit(screen_backup, (0, 0))
|
||||||
screen.blit(screen_backup, (0, 0))
|
pygame.display.flip()
|
||||||
pygame.display.flip()
|
fullscreen = not fullscreen
|
||||||
fullscreen = not fullscreen
|
|
||||||
|
|
||||||
keystate = pygame.key.get_pressed()
|
keystate = pygame.key.get_pressed()
|
||||||
|
|
||||||
@@ -371,7 +371,7 @@ async def main(winstyle=0):
|
|||||||
player.kill()
|
player.kill()
|
||||||
|
|
||||||
# See if shots hit the aliens.
|
# See if shots hit the aliens.
|
||||||
for alien in pygame.sprite.groupcollide(aliens, shots, 1, 1).keys():
|
for alien in pygame.sprite.groupcollide(aliens, shots, 1, 1):
|
||||||
if pygame.mixer:
|
if pygame.mixer:
|
||||||
boom_sound.play()
|
boom_sound.play()
|
||||||
Explosion(alien)
|
Explosion(alien)
|
||||||
|
|||||||
@@ -13,10 +13,7 @@ def test_current_target():
|
|||||||
"""
|
"""
|
||||||
expected = "py-0"
|
expected = "py-0"
|
||||||
if is_micropython:
|
if is_micropython:
|
||||||
if RUNNING_IN_WORKER:
|
expected = "mpy-w0-target" if RUNNING_IN_WORKER else "mpy-0"
|
||||||
expected = "mpy-w0-target"
|
|
||||||
else:
|
|
||||||
expected = "mpy-0"
|
|
||||||
elif RUNNING_IN_WORKER:
|
elif RUNNING_IN_WORKER:
|
||||||
expected = "py-w0-target"
|
expected = "py-w0-target"
|
||||||
assert current_target() == expected, f"Expected {expected} got {current_target()}"
|
assert current_target() == expected, f"Expected {expected} got {current_target()}"
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ async def test_image_display():
|
|||||||
"""
|
"""
|
||||||
Check an image is displayed correctly.
|
Check an image is displayed correctly.
|
||||||
"""
|
"""
|
||||||
mpl = await py_import("matplotlib")
|
_mpl = await py_import("matplotlib")
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
xpoints = [3, 6, 9]
|
xpoints = [3, 6, 9]
|
||||||
|
|||||||
@@ -65,7 +65,6 @@ async def test_storage_types():
|
|||||||
assert test_store["string"] == "hello"
|
assert test_store["string"] == "hello"
|
||||||
assert isinstance(test_store["string"], str)
|
assert isinstance(test_store["string"], str)
|
||||||
assert test_store["none"] is None
|
assert test_store["none"] is None
|
||||||
assert isinstance(test_store["none"], type(None))
|
|
||||||
assert test_store["list"] == [1, 2, 3]
|
assert test_store["list"] == [1, 2, 3]
|
||||||
assert isinstance(test_store["list"], list)
|
assert isinstance(test_store["list"], list)
|
||||||
assert test_store["dict"] == {"a": 1, "b": 2}
|
assert test_store["dict"] == {"a": 1, "b": 2}
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ class TestCollection:
|
|||||||
|
|
||||||
def test_iter_eq_children(self):
|
def test_iter_eq_children(self):
|
||||||
elements = web.page.find(".multi-elems")
|
elements = web.page.find(".multi-elems")
|
||||||
assert [el for el in elements] == [el for el in elements.elements]
|
assert list(elements) == list(elements.elements)
|
||||||
assert len(elements) == 3
|
assert len(elements) == 3
|
||||||
|
|
||||||
def test_slices(self):
|
def test_slices(self):
|
||||||
@@ -427,18 +427,18 @@ class TestInput:
|
|||||||
class TestSelect:
|
class TestSelect:
|
||||||
|
|
||||||
def test_select_options_iter(self):
|
def test_select_options_iter(self):
|
||||||
select = web.page.find(f"#test_select_element_w_options")[0]
|
select = web.page.find("#test_select_element_w_options")[0]
|
||||||
|
|
||||||
for i, option in enumerate(select.options, 1):
|
for i, option in enumerate(select.options, 1):
|
||||||
assert option.value == f"{i}"
|
assert option.value == f"{i}"
|
||||||
assert option.innerHTML == f"Option {i}"
|
assert option.innerHTML == f"Option {i}"
|
||||||
|
|
||||||
def test_select_options_len(self):
|
def test_select_options_len(self):
|
||||||
select = web.page.find(f"#test_select_element_w_options")[0]
|
select = web.page.find("#test_select_element_w_options")[0]
|
||||||
assert len(select.options) == 2
|
assert len(select.options) == 2
|
||||||
|
|
||||||
def test_select_options_clear(self):
|
def test_select_options_clear(self):
|
||||||
select = web.page.find(f"#test_select_element_to_clear")[0]
|
select = web.page.find("#test_select_element_to_clear")[0]
|
||||||
assert len(select.options) == 3
|
assert len(select.options) == 3
|
||||||
|
|
||||||
select.options.clear()
|
select.options.clear()
|
||||||
@@ -447,7 +447,7 @@ class TestSelect:
|
|||||||
|
|
||||||
def test_select_element_add(self):
|
def test_select_element_add(self):
|
||||||
# GIVEN the existing select element with no options
|
# GIVEN the existing select element with no options
|
||||||
select = web.page.find(f"#test_select_element")[0]
|
select = web.page.find("#test_select_element")[0]
|
||||||
|
|
||||||
# EXPECT the select element to have no options
|
# EXPECT the select element to have no options
|
||||||
assert len(select.options) == 0
|
assert len(select.options) == 0
|
||||||
@@ -498,20 +498,14 @@ class TestSelect:
|
|||||||
# EXPECT the middle option to have the value and html we passed in
|
# EXPECT the middle option to have the value and html we passed in
|
||||||
assert select.options[0].value == "1"
|
assert select.options[0].value == "1"
|
||||||
assert select.options[0].innerHTML == "Option 1"
|
assert select.options[0].innerHTML == "Option 1"
|
||||||
assert (
|
assert select.options[0].selected == select.options[0]._dom_element.selected
|
||||||
select.options[0].selected
|
assert select.options[0].selected is False
|
||||||
== select.options[0]._dom_element.selected
|
|
||||||
== False
|
|
||||||
)
|
|
||||||
assert select.options[1].value == "2"
|
assert select.options[1].value == "2"
|
||||||
assert select.options[1].innerHTML == "Option 2"
|
assert select.options[1].innerHTML == "Option 2"
|
||||||
assert select.options[2].value == "3"
|
assert select.options[2].value == "3"
|
||||||
assert select.options[2].innerHTML == "Option 3"
|
assert select.options[2].innerHTML == "Option 3"
|
||||||
assert (
|
assert select.options[2].selected == select.options[2]._dom_element.selected
|
||||||
select.options[2].selected
|
assert select.options[2].selected is True
|
||||||
== select.options[2]._dom_element.selected
|
|
||||||
== True
|
|
||||||
)
|
|
||||||
assert select.options[3].value == ""
|
assert select.options[3].value == ""
|
||||||
assert select.options[3].innerHTML == ""
|
assert select.options[3].innerHTML == ""
|
||||||
|
|
||||||
@@ -538,7 +532,7 @@ class TestSelect:
|
|||||||
|
|
||||||
def test_select_options_remove(self):
|
def test_select_options_remove(self):
|
||||||
# GIVEN the existing select element with 3 options
|
# GIVEN the existing select element with 3 options
|
||||||
select = web.page.find(f"#test_select_element_to_remove")[0]
|
select = web.page.find("#test_select_element_to_remove")[0]
|
||||||
|
|
||||||
# EXPECT the select element to have 3 options
|
# EXPECT the select element to have 3 options
|
||||||
assert len(select.options) == 4
|
assert len(select.options) == 4
|
||||||
@@ -560,7 +554,7 @@ class TestSelect:
|
|||||||
|
|
||||||
def test_select_get_selected_option(self):
|
def test_select_get_selected_option(self):
|
||||||
# GIVEN the existing select element with one selected option
|
# GIVEN the existing select element with one selected option
|
||||||
select = web.page.find(f"#test_select_element_w_options")[0]
|
select = web.page.find("#test_select_element_w_options")[0]
|
||||||
|
|
||||||
# WHEN we get the selected option
|
# WHEN we get the selected option
|
||||||
selected_option = select.options.selected
|
selected_option = select.options.selected
|
||||||
@@ -568,7 +562,8 @@ class TestSelect:
|
|||||||
# EXPECT the selected option to be correct
|
# EXPECT the selected option to be correct
|
||||||
assert selected_option.value == "2"
|
assert selected_option.value == "2"
|
||||||
assert selected_option.innerHTML == "Option 2"
|
assert selected_option.innerHTML == "Option 2"
|
||||||
assert selected_option.selected == selected_option._dom_element.selected == True
|
assert selected_option.selected == selected_option._dom_element.selected
|
||||||
|
assert selected_option.selected is True
|
||||||
|
|
||||||
|
|
||||||
class TestElements:
|
class TestElements:
|
||||||
@@ -625,7 +620,8 @@ class TestElements:
|
|||||||
el = klass(*args, **kwargs)
|
el = klass(*args, **kwargs)
|
||||||
container.append(el)
|
container.append(el)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
assert False, f"Failed to create element {el_type}: {e}"
|
msg = f"Failed to create element {el_type}: {e}"
|
||||||
|
raise AssertionError(msg)
|
||||||
|
|
||||||
# Let's keep the tag in 2 variables, one for the selector and another to
|
# Let's keep the tag in 2 variables, one for the selector and another to
|
||||||
# check the return tag from the selector
|
# check the return tag from the selector
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
[tool.codespell]
|
[tool.codespell]
|
||||||
ignore-words-list = "afterall"
|
ignore-words-list = "afterall"
|
||||||
skip = "*.js,*.json"
|
skip = "*.js,*.json"
|
||||||
|
|
||||||
|
[tool.ruff]
|
||||||
|
line-length = 114
|
||||||
|
lint.select = ["C4", "C90", "E", "EM", "F", "PIE", "PYI", "PLC", "Q", "RET", "W"]
|
||||||
|
lint.ignore = ["E402", "E722", "E731", "E741", "F401", "F704", "F811", "F821"]
|
||||||
|
lint.mccabe.max-complexity = 27
|
||||||
|
|||||||
Reference in New Issue
Block a user