diff --git a/modules/photons_app/collector.py b/modules/photons_app/collector.py index 335e37be..1818a5a5 100644 --- a/modules/photons_app/collector.py +++ b/modules/photons_app/collector.py @@ -10,12 +10,13 @@ from delfick_project.errors import DelfickError from delfick_project.norms import Meta, dictobj, sb from delfick_project.option_merge import Collector, MergedOptions +from photons_messages import protocol_register + from photons_app import helpers as hp from photons_app.errors import BadConfiguration, BadYaml, UserQuit from photons_app.formatter import MergedOptionStringFormatter from photons_app.photons_app import PhotonsAppSpec from photons_app.tasks.runner import Runner -from photons_messages import protocol_register log = logging.getLogger("photons_app.collector") @@ -73,9 +74,7 @@ def setup(self, source): self.extras_spec = Extras.FieldSpec() def normalise_filled(self, meta, val): - options_spec = sb.set_options( - filename=sb.required(sb.string_spec()), optional=sb.defaulted(sb.boolean(), False) - ) + options_spec = sb.set_options(filename=sb.required(sb.string_spec()), optional=sb.defaulted(sb.boolean(), False)) lst_spec = sb.listof(sb.or_spec(sb.string_spec(), options_spec)) if isinstance(val, list): @@ -156,8 +155,8 @@ def run_coro_as_main(self, coro, catch_delfick_error=True): print("") print("!" * 80) - print("Something went wrong! -- {0}".format(error.__class__.__name__)) - print("\t{0}".format(error)) + print(f"Something went wrong! -- {error.__class__.__name__}") + print(f"\t{error}") if conf["photons_app"].debug: raise sys.exit(1) @@ -210,7 +209,10 @@ def extra_prepare(self, configuration, args_dict): def find_photons_app_options(self, configuration, args_dict): """Return us all the photons_app options""" - d = lambda r: {} if r in (None, "", sb.NotSpecified) else r + + def d(r): + return {} if r in (None, "", sb.NotSpecified) else r + return MergedOptions.using( dict(d(configuration.get("photons_app")).items()), dict(d(args_dict.get("photons_app")).items()), @@ -225,13 +227,8 @@ def determine_mainline_module(self): except ImportError: pass else: - if any( - hasattr(getattr(__main__, attr, None), "_delfick_project_addon_entry") - for attr in dir(__main__) - ): - sys.meta_path = [ - thing for thing in sys.meta_path if not isinstance(thing, MainFinder) - ] + if any(hasattr(getattr(__main__, attr, None), "_delfick_project_addon_entry") for attr in dir(__main__)): + sys.meta_path = [thing for thing in sys.meta_path if not isinstance(thing, MainFinder)] sys.meta_path.append(MainFinder(__main__)) else: __main__ = None @@ -276,9 +273,7 @@ def extra_prepare_after_activation(self, configuration, args_dict): This will determine the target and artifact for you given the configuration in the collector. """ - configuration.update( - {"final_future": configuration["photons_app"].final_future}, source="" - ) + configuration.update({"final_future": configuration["photons_app"].final_future}, source="") # Post register our addons extra_args = {"lifx.photons": {}} @@ -314,7 +309,7 @@ def read_file(self, location): "Failed to read yaml", location=location, error_type=error.__class__.__name__, - error="{0}{1}".format(error.problem, error.problem_mark), + error=f"{error.problem}{error.problem_mark}", ) def add_configuration(self, configuration, collect_another_source, done, result, src): @@ -329,9 +324,7 @@ def add_configuration(self, configuration, collect_another_source, done, result, if "config_root" in configuration: # if we already have a config root then we only keep new config root if it's not the home location # i.e. if it is the home configuration, we don't delete the new config_root - if configuration["config_root"] != os.path.dirname( - self.home_dir_configuration_location() - ): + if configuration["config_root"] != os.path.dirname(self.home_dir_configuration_location()): if "config_root" in result: del result["config_root"] diff --git a/modules/photons_app/executor.py b/modules/photons_app/executor.py index 2c6e64b7..49bd196a 100644 --- a/modules/photons_app/executor.py +++ b/modules/photons_app/executor.py @@ -10,14 +10,13 @@ from delfick_project.app import App, OptionalFileType from delfick_project.norms import sb + from photons_app import VERSION from photons_app.collector import Collector from photons_app.tasks import task_register -def library_setup( - config_filename="lifx.yml", photons_modules=True, extra_files=None, photons_app_options=None -): +def library_setup(config_filename="lifx.yml", photons_modules=True, extra_files=None, photons_app_options=None): """ Get us a setup photons Collector instance. @@ -108,7 +107,7 @@ def mainline(self, argv=None, print_errors_to=sys.stdout, **execute_args): if task in ("list_tasks", "help"): os.environ["PHOTONS_SILENT_BY_DEFAULT"] = "1" - super(App, self).mainline(original_argv, print_errors_to, **execute_args) + super().mainline(original_argv, print_errors_to, **execute_args) def setup_collector(self, args_dict, logging_handler, extra_files): """Create and initialize a collector""" diff --git a/modules/photons_app/formatter.py b/modules/photons_app/formatter.py index a13fb69a..a01c968b 100644 --- a/modules/photons_app/formatter.py +++ b/modules/photons_app/formatter.py @@ -20,6 +20,7 @@ import operator from delfick_project.option_merge import MergedOptionStringFormatter + from photons_app import helpers as hp @@ -68,12 +69,6 @@ def special_format_field(self, obj, format_spec): """Know about any special formats""" if format_spec == "resource": parts = obj.split("/") - return str( - functools.reduce( - operator.truediv, [importlib.resources.files(parts[0]), *parts[1:]] - ).resolve() - ) - elif any( - isinstance(obj, f) for f in (asyncio.Future, hp.ChildOfFuture, hp.ResettableFuture) - ): + return str(functools.reduce(operator.truediv, [importlib.resources.files(parts[0]), *parts[1:]]).resolve()) + elif any(isinstance(obj, f) for f in (asyncio.Future, hp.ChildOfFuture, hp.ResettableFuture)): return obj diff --git a/modules/photons_app/helpers.py b/modules/photons_app/helpers.py index fa33ecf2..b54ebe87 100644 --- a/modules/photons_app/helpers.py +++ b/modules/photons_app/helpers.py @@ -13,9 +13,10 @@ from queue import Queue as NormalQueue from delfick_project.logging import lc -from photons_app.errors import PhotonsAppError from photons_messages import fields +from photons_app.errors import PhotonsAppError + log = logging.getLogger("photons_app.helpers") # Make vim be quiet @@ -69,7 +70,7 @@ def __eq__(self, other): other = Color(*other) - if not isinstance(other, (fields.Color, dict)) and not hasattr(other, "as_dict"): + if not isinstance(other, dict | fields.Color) and not hasattr(other, "as_dict"): return False if not isinstance(other, fields.Color): @@ -120,11 +121,7 @@ def __eq__(self, other): if isinstance(other, tuple) and len(other) == 2: return (self.major, self.minor) == other elif isinstance(other, Firmware): - return ( - self.major == other.major - and self.minor == other.minor - and self.build == other.build - ) + return self.major == other.major and self.minor == other.minor and self.build == other.build else: raise ValueError(f"Can't compare firmware with {type(other)}: {other}") @@ -181,7 +178,7 @@ async def ensure_aexit_cm(): exc_info = None try: yield - except: + except Exception: exc_info = sys.exc_info() if exc_info is not None: @@ -355,8 +352,7 @@ def __init__( self.waiter = ResettableFuture(name=f"ATicker({self.name})::__init__[waiter]") self.final_future = ChildOfFuture( - final_future - or create_future(name=f"ATicker({self.name})::__init__[owned_final_future]"), + final_future or create_future(name=f"ATicker({self.name})::__init__[owned_final_future]"), name=f"ATicker({self.name})::__init__[final_future]", ) @@ -366,17 +362,13 @@ async def start(self): def __aiter__(self): if not hasattr(self, "gen"): - raise Exception( - "The ticker must be used as a context manager before being used as an async iterator" - ) + raise Exception("The ticker must be used as a context manager before being used as an async iterator") return self.gen async def finish(self, exc_typ=None, exc=None, tb=None): if hasattr(self, "gen"): try: - await stop_async_generator( - self.gen, exc=exc or self.Stop(), name=f"ATicker({self.name})::stop[stop_gen]" - ) + await stop_async_generator(self.gen, exc=exc or self.Stop(), name=f"ATicker({self.name})::stop[stop_gen]") except self.Stop: pass @@ -440,9 +432,7 @@ async def pause(): async with self.pauser: pass - ts_final_future = ChildOfFuture( - self.final_future, name=f"ATicker({self.name})::_wait_for_next[with_pause]" - ) + ts_final_future = ChildOfFuture(self.final_future, name=f"ATicker({self.name})::_wait_for_next[with_pause]") async with TaskHolder(ts_final_future) as ts: ts.add(pause()) @@ -605,14 +595,10 @@ def __init__(self, final_future, *, name=None): self.name = name self.ts = [] - self.final_future = ChildOfFuture( - final_future, name=f"TaskHolder({self.name})::__init__[final_future]" - ) + self.final_future = ChildOfFuture(final_future, name=f"TaskHolder({self.name})::__init__[final_future]") self._cleaner = None - self._cleaner_waiter = ResettableFuture( - name=f"TaskHolder({self.name})::__init__[cleaner_waiter]" - ) + self._cleaner_waiter = ResettableFuture(name=f"TaskHolder({self.name})::__init__[cleaner_waiter]") def add(self, coro, *, silent=False): return self.add_task(async_as_background(coro, silent=silent)) @@ -674,9 +660,7 @@ async def finish(self, exc_typ=None, exc=None, tb=None): async def _final(self): if self._cleaner: self._cleaner.cancel() - await wait_for_all_futures( - self._cleaner, name=f"TaskHolder({self.name})::finish[finally_wait_for_cleaner]" - ) + await wait_for_all_futures(self._cleaner, name=f"TaskHolder({self.name})::finish[finally_wait_for_cleaner]") await wait_for_all_futures( async_as_background(self.clean()), @@ -708,9 +692,7 @@ async def clean(self): else: remaining.append(t) - await wait_for_all_futures( - *destroyed, name=f"TaskHolder({self.name})::clean[wait_for_destroyed]" - ) + await wait_for_all_futures(*destroyed, name=f"TaskHolder({self.name})::clean[wait_for_destroyed]") self.ts = remaining + [t for t in self.ts if t not in destroyed and t not in remaining] @@ -841,19 +823,13 @@ def __repr__(self): status = "success" if self.successful else "failed" return f"" - def __init__( - self, final_future, *, error_catcher=None, exceptions_only_to_error_catcher=False, name=None - ): + def __init__(self, final_future, *, error_catcher=None, exceptions_only_to_error_catcher=False, name=None): self.name = name - self.final_future = ChildOfFuture( - final_future, name=f"ResultStreamer({self.name})::__init__[final_future]" - ) + self.final_future = ChildOfFuture(final_future, name=f"ResultStreamer({self.name})::__init__[final_future]") self.error_catcher = error_catcher self.exceptions_only_to_error_catcher = exceptions_only_to_error_catcher - self.queue_future = ChildOfFuture( - final_future, name=f"ResultStreamer({self.name})::__init__[queue_future]" - ) + self.queue_future = ChildOfFuture(final_future, name=f"ResultStreamer({self.name})::__init__[queue_future]") self.queue = Queue( self.queue_future, empty_on_finished=True, @@ -896,9 +872,7 @@ async def run(): task.gen = gen if self.final_future.done(): - await cancel_futures_and_wait( - task, name=f"ResultStreamer({self.name})::add_generator[already_stopped_task]" - ) + await cancel_futures_and_wait(task, name=f"ResultStreamer({self.name})::add_generator[already_stopped_task]") await wait_for_first_future( async_as_background(gen.aclose()), name=f"ResultStreamer({self.name})::add_generator[already_stopped_gen]", @@ -924,13 +898,9 @@ async def return_value(): async def add_task(self, task, *, context=None, on_done=None, force=False): if self.final_future.done(): if force: - await wait_for_all_futures( - task, name=f"ResultStreamer({self.name})::add_task[force_already_stopped]" - ) + await wait_for_all_futures(task, name=f"ResultStreamer({self.name})::add_task[force_already_stopped]") else: - await cancel_futures_and_wait( - task, name=f"ResultStreamer({self.name})::add_task[already_stopped]" - ) + await cancel_futures_and_wait(task, name=f"ResultStreamer({self.name})::add_task[already_stopped]") return task def add_to_queue(res): @@ -1296,9 +1266,7 @@ async def cancel_futures_and_wait(*futs, name=None): fut.cancel() waiting.append(fut) - await wait_for_all_futures( - *waiting, name=f"||cancel_futures_and_wait({name})[wait_for_everything]" - ) + await wait_for_all_futures(*waiting, name=f"||cancel_futures_and_wait({name})[wait_for_everything]") class memoized_property(tp.Generic[T]): @@ -1339,7 +1307,7 @@ def __init__(self, func): self.func = func self.name = func.__name__ self.__doc__ = func.__doc__ - self.cache_name = "_{0}".format(self.name) + self.cache_name = f"_{self.name}" def __get__(self, instance: object = None, owner: object = None) -> T: if instance is None: @@ -1790,9 +1758,7 @@ def __init__(self, final_future, *, timeout=0.05, empty_on_finished=False, name= self.name = name self.timeout = timeout self.collection = NormalQueue() - self.final_future = ChildOfFuture( - final_future, name=f"SyncQueue({self.name})::__init__[final_future]" - ) + self.final_future = ChildOfFuture(final_future, name=f"SyncQueue({self.name})::__init__[final_future]") self.empty_on_finished = empty_on_finished def append(self, item): @@ -1865,9 +1831,7 @@ def __init__(self, final_future, *, empty_on_finished=False, name=None): self.name = name self.waiter = ResettableFuture(name=f"Queue({self.name})::__init__[waiter]") self.collection = deque() - self.final_future = ChildOfFuture( - final_future, name=f"Queue({self.name})::__init__[final_future]" - ) + self.final_future = ChildOfFuture(final_future, name=f"Queue({self.name})::__init__[final_future]") self.empty_on_finished = empty_on_finished self.stop = False diff --git a/modules/photons_app/mimic/__init__.py b/modules/photons_app/mimic/__init__.py index 50214e6f..42ce00c9 100644 --- a/modules/photons_app/mimic/__init__.py +++ b/modules/photons_app/mimic/__init__.py @@ -2,12 +2,13 @@ import os import sys +from photons_messages import Services, protocol_register +from photons_transport.targets import LanTarget + from photons_app import helpers as hp from photons_app.mimic.device import Device from photons_app.mimic.event import Events from photons_app.mimic.transport import MemoryTarget -from photons_messages import Services, protocol_register -from photons_transport.targets import LanTarget this_dir = os.path.dirname(__file__) for fle in os.listdir(os.path.join(this_dir, "operators")): @@ -296,9 +297,7 @@ async def for_test(self, final_future, udp=False): for session in sessions: tt.append(ts.add(session.start())) - await hp.wait_for_all_futures( - *tt, name="DeviceCollection::for_test[wait_for_start]" - ) + await hp.wait_for_all_futures(*tt, name="DeviceCollection::for_test[wait_for_start]") configuration = { "final_future": final_future, @@ -328,9 +327,7 @@ async def for_test(self, final_future, udp=False): ends = [] for session in sessions: ends.append(ts.add(session.finish(exc_typ=exc_typ, exc=exc, tb=tb))) - await hp.wait_for_all_futures( - *ends, name="DeviceCollection::for_test[wait_for_session_ends]" - ) + await hp.wait_for_all_futures(*ends, name="DeviceCollection::for_test[wait_for_session_ends]") __all__ = ["Device", "DeviceCollection"] diff --git a/modules/photons_app/mimic/attrs.py b/modules/photons_app/mimic/attrs.py index 279bc062..b3fc2cbf 100644 --- a/modules/photons_app/mimic/attrs.py +++ b/modules/photons_app/mimic/attrs.py @@ -1,6 +1,7 @@ import fnmatch from delfick_project.norms import sb + from photons_app.mimic.event import Events @@ -41,7 +42,7 @@ def retrieve(self, at, part, allow_missing=False): def retrieve_length(self, at, part): got = self.retrieve(at, part, allow_missing=False) - if not isinstance(got, (list, tuple)): + if not isinstance(got, list | tuple): return "" else: return len(got) @@ -68,12 +69,12 @@ async def reduce_length(self, at, part, new_length, event): current = at[part] if isinstance(current, list): - l = len(current) + length = len(current) while len(current) > new_length: current.pop() - if len(current) == l: + if len(current) == length: break - l = len(current) + length = len(current) elif isinstance(current, tuple): current = current[:new_length] @@ -294,9 +295,7 @@ def __setattr__(self, key, value): if key.startswith("_"): object.__setattr__(self, key, value) else: - raise AttributeError( - f"Use 'await attrs.attrs_apply(*changes)' to change attributes: Tried changing {key} to {value}" - ) + raise AttributeError(f"Use 'await attrs.attrs_apply(*changes)' to change attributes: Tried changing {key} to {value}") def __getitem__(self, key): return self._attrs[key] diff --git a/modules/photons_app/mimic/device.py b/modules/photons_app/mimic/device.py index 646c78d2..75637704 100644 --- a/modules/photons_app/mimic/device.py +++ b/modules/photons_app/mimic/device.py @@ -24,20 +24,14 @@ def __init__(self, final_future, device): async def start(self): await self.device.prepare() - self.parent_ts = hp.TaskHolder( - self.final_future, name=f"DeviceSession({self.device.serial})::start[parent]" - ) + self.parent_ts = hp.TaskHolder(self.final_future, name=f"DeviceSession({self.device.serial})::start[parent]") await self.parent_ts.start() made = [] - async with hp.TaskHolder( - self.final_future, name=f"DeviceSession({self.device.serial})::start[ts]" - ) as ts: + async with hp.TaskHolder(self.final_future, name=f"DeviceSession({self.device.serial})::start[ts]") as ts: for _, io in self.device.io.items(): self.managed.append(io) - made.append( - ts.add(io.start_session(self.final_future, self.parent_ts), silent=True) - ) + made.append(ts.add(io.start_session(self.final_future, self.parent_ts), silent=True)) # Raise any exceptions for t in made: @@ -52,18 +46,14 @@ async def finish(self, exc_typ=None, exc=None, tb=None): made = [] async def call_finishers(): - async with hp.TaskHolder( - self.final_future, name=f"DeviceSession({self.device.serial})::finish[ts]" - ) as ts: + async with hp.TaskHolder(self.final_future, name=f"DeviceSession({self.device.serial})::finish[ts]") as ts: made.append(ts.add(self.device.delete())) for io in self.managed: made.append(ts.add(io.finish_session(), silent=True)) self.managed = [] - await hp.wait_for_all_futures( - *made, name=f"DeviceSession({self.device.serial})::finish[all]" - ) + await hp.wait_for_all_futures(*made, name=f"DeviceSession({self.device.serial})::finish[all]") await hp.wait_for_all_futures( self.parent_ts.add(call_finishers()), @@ -131,20 +121,16 @@ async def annotate_error(self, *, executing): raise except Exception as error: try: - await self.annotate( - "ERROR", "Failed executing an event", error=error, executing=executing - ) + await self.annotate("ERROR", "Failed executing an event", error=error, executing=executing) except asyncio.CancelledError: raise - except: + except Exception: pass async def event(self, eventkls, *args, **kwargs): return await self.event_with_options(eventkls, args=args, kwargs=kwargs) - async def event_with_options( - self, eventkls, *, is_finished=None, visible=True, execute=True, args, kwargs - ): + async def event_with_options(self, eventkls, *, is_finished=None, visible=True, execute=True, args, kwargs): event = eventkls(self, *args, **kwargs) event._exclude_viewers = not visible @@ -208,10 +194,7 @@ async def change_one(self, key, value, *, event): async def change(self, *changes, event): await self.attrs.attrs_apply( - *[ - self.attrs.attrs_path(*((key,) if isinstance(key, str) else key)).changer_to(value) - for key, value in changes - ], + *[self.attrs.attrs_path(*((key,) if isinstance(key, str) else key)).changer_to(value) for key, value in changes], event=event, ) diff --git a/modules/photons_app/mimic/event.py b/modules/photons_app/mimic/event.py index e7d5bad9..526eae91 100644 --- a/modules/photons_app/mimic/event.py +++ b/modules/photons_app/mimic/event.py @@ -8,11 +8,12 @@ import dateutil.tz from delfick_project.norms import BadSpecValue, sb -from photons_app.errors import ProgrammerError from photons_messages import TileMessages from photons_protocol.errors import PhotonsProtocolError from photons_protocol.packets import dictobj, reprer +from photons_app.errors import ProgrammerError + class ConsoleFormat: @classmethod @@ -75,7 +76,6 @@ def t(o): continue val = payload[name] if isinstance(val, list): - length = len(val) length_name = f"{name}_count" if length_name in payload: @@ -173,9 +173,7 @@ def __eq__(self, other): raise ValueError("Can't compare against an empty tuple") if len(other) != 2 or not isinstance(other[0], type): - raise ValueError( - f"Can only compare against against a tuple of (EventKls, device): ({other})" - ) + raise ValueError(f"Can only compare against against a tuple of (EventKls, device): ({other})") return self | other[0] and other[1] is self.device @@ -189,11 +187,7 @@ def has_same_args(self, other): def for_console(self, time=True, show_set64_contents=False): if time is True: - time = ( - datetime.fromtimestamp(self.created) - .astimezone(self.LOCAL_TZ) - .strftime("%Y-%m-%d %H:%M:%S.%f%z") - ) + time = datetime.fromtimestamp(self.created).astimezone(self.LOCAL_TZ).strftime("%Y-%m-%d %H:%M:%S.%f%z") else: time = "TIME" @@ -220,9 +214,7 @@ def for_console(self, time=True, show_set64_contents=False): yield f" | {part}" elif isinstance(val, dictobj.PacketSpec) or getattr(val, "represents_ack", False): - lines = list( - ConsoleFormat.lines_from_packet(val, show_set64_contents=show_set64_contents) - ) + lines = list(ConsoleFormat.lines_from_packet(val, show_set64_contents=show_set64_contents)) if lines: yield f" || {key} = {lines.pop(0)}" for line in lines: @@ -240,7 +232,6 @@ def has_same_args(self, other): pkt_other = other.log_kwargs["packet"] if pkt_other is not mock.ANY: - if isinstance(pkt_other, type): if not pkt_have | pkt_other: return False @@ -418,11 +409,11 @@ def add_replies(self, *replies): self.replies = [] def flatten(lst): - for l in lst: - if isinstance(l, list): - yield from flatten(l) - elif l is not None: - yield l + for item in lst: + if isinstance(item, list): + yield from flatten(item) + elif item is not None: + yield item self.replies.extend(list(flatten(replies))) @@ -627,11 +618,7 @@ def setup(self, level, message, **details): self.log_kwargs = self.details def has_same_args(self, other): - return ( - super().has_same_args(other) - and self.level == other.level - and re.match(other.message, self.message) - ) + return super().has_same_args(other) and self.level == other.level and re.match(other.message, self.message) @Events.register("DISCOVERABLE") diff --git a/modules/photons_app/mimic/operator.py b/modules/photons_app/mimic/operator.py index 942ce83c..cbbb29c9 100644 --- a/modules/photons_app/mimic/operator.py +++ b/modules/photons_app/mimic/operator.py @@ -1,11 +1,12 @@ import asyncio from delfick_project.norms import Meta, dictobj +from photons_protocol.messages import Messages + from photons_app import helpers as hp from photons_app.errors import PhotonsAppError, ProgrammerError from photons_app.mimic.event import Events from photons_app.mimic.packet_filter import Filter, SendAck, SendReplies, SendUnhandled -from photons_protocol.messages import Messages register = [] @@ -75,9 +76,7 @@ def only_io_and_viewer_operators(kls, value_store): def __init__(self, device, options=None, *args, **kwargs): self.device = device self.device_attrs = device.attrs - self.options = self.Options.FieldSpec().normalise( - Meta.empty(), {} if options is None else options - ) + self.options = self.Options.FieldSpec().normalise(Meta.empty(), {} if options is None else options) self.setup(*args, **kwargs) def setup(self): @@ -170,9 +169,7 @@ async def start_session(self, final_future, parent_ts): async def restart_session(self): if self.last_final_future is None or self.last_final_future.done(): - raise PhotonsAppError( - "The IO does not have a valid final future to restart the session from" - ) + raise PhotonsAppError("The IO does not have a valid final future to restart the session from") await self.shutting_down(Events.SHUTTING_DOWN(self.device)) await self.start_session(self.last_final_future, self.parent_ts) await self.power_on(Events.POWER_ON(self.device)) @@ -227,19 +224,13 @@ async def process_incoming(self, bts, give_reply, addr): await self.process_instruction(SendAck(event), give_reply) if processed is False: - await self.device.event( - Events.IGNORED, self, pkt=event.pkt, bts=event.bts, addr=event.addr - ) + await self.device.event(Events.IGNORED, self, pkt=event.pkt, bts=event.bts, addr=event.addr) return if event.ignored: - await self.device.event( - Events.IGNORED, self, pkt=event.pkt, bts=event.bts, addr=event.addr - ) + await self.device.event(Events.IGNORED, self, pkt=event.pkt, bts=event.bts, addr=event.addr) elif not event.handled and not event.replies: - await self.device.event( - Events.UNHANDLED, self, pkt=event.pkt, bts=event.bts, addr=event.addr - ) + await self.device.event(Events.UNHANDLED, self, pkt=event.pkt, bts=event.bts, addr=event.addr) await self.process_instruction(SendUnhandled(event), give_reply) else: await self.process_instruction(SendReplies(event), give_reply) @@ -247,9 +238,7 @@ async def process_incoming(self, bts, give_reply, addr): async def process_instruction(self, instruction, give_reply): async for reply in instruction.process(): async for rr in self.packet_filter.outgoing(reply, instruction.event): - await self._send_reply( - rr, give_reply, instruction.event.addr, replying_to=instruction.event.pkt - ) + await self._send_reply(rr, give_reply, instruction.event.addr, replying_to=instruction.event.pkt) async def respond(self, event): pass diff --git a/modules/photons_app/mimic/operators/clean.py b/modules/photons_app/mimic/operators/clean.py index 26137873..7a2253c9 100644 --- a/modules/photons_app/mimic/operators/clean.py +++ b/modules/photons_app/mimic/operators/clean.py @@ -1,11 +1,12 @@ import time from delfick_project.norms import dictobj, sb +from photons_messages import DeviceMessages, LightLastHevCycleResult, LightMessages +from photons_protocol.types import enum_spec + from photons_app import helpers as hp from photons_app.mimic.event import Events from photons_app.mimic.operator import Operator, operator -from photons_messages import DeviceMessages, LightLastHevCycleResult, LightMessages -from photons_protocol.types import enum_spec # Ensure Device operator comes before this one __import__("photons_app.mimic.operators.device") @@ -59,9 +60,7 @@ async def set_cycle(self, event): self.last_trigger = None self.triggered_at = time.time() - self.last_trigger = hp.get_event_loop().call_later( - duration, lambda: self.device.io["MEMORY"].ts.add(self.stop_cycle(event)) - ) + self.last_trigger = hp.get_event_loop().call_later(duration, lambda: self.device.io["MEMORY"].ts.add(self.stop_cycle(event))) await self.device.change(*changes, event=event) diff --git a/modules/photons_app/mimic/operators/device.py b/modules/photons_app/mimic/operators/device.py index b2429cae..92c84a3a 100644 --- a/modules/photons_app/mimic/operators/device.py +++ b/modules/photons_app/mimic/operators/device.py @@ -1,8 +1,9 @@ from delfick_project.norms import BadSpecValue, dictobj, sb -from photons_app.mimic.operator import Operator, operator from photons_messages import DeviceMessages from photons_protocol.types import bytes_spec +from photons_app.mimic.operator import Operator, operator + class identity_spec(sb.Spec): def __init__(self): @@ -19,12 +20,8 @@ class Collection(dictobj.Spec): updated_at = dictobj.Field(sb.integer_spec, default=0) @classmethod - def create( - self, *, identity=sb.NotSpecified, label=sb.NotSpecified, updated_at=sb.NotSpecified - ): - return Collection.FieldSpec().empty_normalise( - identity=identity, label=label, updated_at=updated_at - ) + def create(self, *, identity=sb.NotSpecified, label=sb.NotSpecified, updated_at=sb.NotSpecified): + return Collection.FieldSpec().empty_normalise(identity=identity, label=label, updated_at=updated_at) class power_spec(sb.Spec): @@ -183,9 +180,7 @@ def make_state_for(self, kls, result): result.append(kls(build=0, version_major=0, version_minor=0)) elif kls | DeviceMessages.StateVersion: - result.append( - kls(vendor=self.device.cap.product.vendor.vid, product=self.device.cap.product.pid) - ) + result.append(kls(vendor=self.device.cap.product.vendor.vid, product=self.device.cap.product.pid)) elif kls | DeviceMessages.StateHostFirmware: result.append( diff --git a/modules/photons_app/mimic/operators/io.py b/modules/photons_app/mimic/operators/io.py index 105a56e0..bbdca956 100644 --- a/modules/photons_app/mimic/operators/io.py +++ b/modules/photons_app/mimic/operators/io.py @@ -3,11 +3,12 @@ import socket from delfick_project.norms import dictobj, sb +from photons_messages import DiscoveryMessages, Services + from photons_app import helpers as hp from photons_app.mimic.event import Events from photons_app.mimic.operator import IO, operator from photons_app.mimic.transport import MemoryService -from photons_messages import DiscoveryMessages, Services def make_port(): @@ -52,11 +53,7 @@ async def respond(self, event): if event | DiscoveryMessages.GetService and event.io is self: port = self.options.get("state_service_port", self.options.port) state_service_port = 0 if port is None else port - event.add_replies( - DiscoveryMessages.StateService( - service=self.options.state_service, port=state_service_port - ) - ) + event.add_replies(DiscoveryMessages.StateService(service=self.options.state_service, port=state_service_port)) @operator @@ -101,9 +98,7 @@ async def give_reply(bts, addr, replying_to, *, reply): port = make_port() try: - remote, _ = await hp.get_event_loop().create_datagram_endpoint( - ServerProtocol, local_addr=("0.0.0.0", port) - ) + remote, _ = await hp.get_event_loop().create_datagram_endpoint(ServerProtocol, local_addr=("0.0.0.0", port)) self.remote = remote except OSError as e: error = e @@ -119,11 +114,7 @@ async def give_reply(bts, addr, replying_to, *, reply): break if remote is None: - raise Exception( - "%" * 80 - + f"%%% Failed to bind to a udp socket: {port} ({error})\n" - + "You should stop whatever is using that port!" - ) + raise Exception("%" * 80 + f"%%% Failed to bind to a udp socket: {port} ({error})\n" + "You should stop whatever is using that port!") async def shutting_down(self, event): if hasattr(self, "remote"): diff --git a/modules/photons_app/mimic/operators/light.py b/modules/photons_app/mimic/operators/light.py index c02bf6a0..795d9af9 100644 --- a/modules/photons_app/mimic/operators/light.py +++ b/modules/photons_app/mimic/operators/light.py @@ -1,9 +1,10 @@ from delfick_project.norms import BadSpecValue, dictobj, sb -from photons_app import helpers as hp -from photons_app.mimic.operator import Operator, operator from photons_messages import DeviceMessages, LightMessages from photons_products import Family +from photons_app import helpers as hp +from photons_app.mimic.operator import Operator, operator + class color_spec(sb.Spec): def normalise(self, meta, val): @@ -12,7 +13,7 @@ def normalise(self, meta, val): keys = ("hue", "saturation", "brightness", "kelvin") - if isinstance(val, (list, tuple)): + if isinstance(val, list | tuple): while len(val) < 4: val = (*val, 0) elif isinstance(val, dict): @@ -88,9 +89,7 @@ async def respond(self, event): for k in ("hue", "saturation", "brightness", "kelvin"): if getattr(event.pkt, f"set_{k}"): - changes.append( - self.device.attrs.attrs_path("color", k).changer_to(event.pkt[k]) - ) + changes.append(self.device.attrs.attrs_path("color", k).changer_to(event.pkt[k])) if changes: await self.device.attrs.attrs_apply(*changes, event=event) diff --git a/modules/photons_app/mimic/operators/listener.py b/modules/photons_app/mimic/operators/listener.py index 6e10bcf8..2cbf4c05 100644 --- a/modules/photons_app/mimic/operators/listener.py +++ b/modules/photons_app/mimic/operators/listener.py @@ -1,4 +1,5 @@ from delfick_project.norms import dictobj, sb + from photons_app import helpers as hp from photons_app.mimic.event import Events from photons_app.mimic.operator import Viewer, operator @@ -120,11 +121,7 @@ def select(kls, device): if "make_packet_waiter" in device.value_store: return kls(device) - attrs = [ - Viewer.Attr.Lambda( - "event_waiter", from_zero=lambda event, options: EventWaiter(event.device) - ) - ] + attrs = [Viewer.Attr.Lambda("event_waiter", from_zero=lambda event, options: EventWaiter(event.device))] async def respond(self, event): if hasattr(self.device.attrs, "event_waiter"): diff --git a/modules/photons_app/mimic/operators/matrix.py b/modules/photons_app/mimic/operators/matrix.py index a3988fbc..05d115dd 100644 --- a/modules/photons_app/mimic/operators/matrix.py +++ b/modules/photons_app/mimic/operators/matrix.py @@ -1,9 +1,10 @@ from delfick_project.norms import dictobj, sb +from photons_messages import TileEffectType, TileMessages +from photons_protocol.types import enum_spec + from photons_app import helpers as hp from photons_app.mimic.operator import Operator, operator from photons_app.mimic.operators.light import color_spec -from photons_messages import TileEffectType, TileMessages -from photons_protocol.types import enum_spec class TileChild(dictobj.Spec): @@ -94,9 +95,7 @@ class Options(dictobj.Spec): palette = dictobj.Field(sb.listof(color_spec())) palette_count = dictobj.NullableField(sb.integer_spec) - matrix_effect = dictobj.Field( - enum_spec(None, TileEffectType, unpacking=True), default=TileEffectType.OFF - ) + matrix_effect = dictobj.Field(enum_spec(None, TileEffectType, unpacking=True), default=TileEffectType.OFF) @classmethod def select(kls, device): @@ -127,29 +126,17 @@ async def respond(self, event): changes = [] for i, palette in enumerate(self.device.attrs.palette): if i >= palette_count: - changes.append( - self.device.attrs.attrs_path("palette", i).changer_to(hp.Color(0, 0, 0, 0)) - ) + changes.append(self.device.attrs.attrs_path("palette", i).changer_to(hp.Color(0, 0, 0, 0))) else: if self.device.attrs.palette[i] != event.pkt.palette[i]: - changes.append( - self.device.attrs.attrs_path("palette", i).changer_to( - event.pkt.palette[i] - ) - ) + changes.append(self.device.attrs.attrs_path("palette", i).changer_to(event.pkt.palette[i])) for i in range(palette_count): if i >= len(self.device.attrs.palette): - changes.append( - self.device.attrs.attrs_path("palette", i).changer_to(event.pkt.palette[i]) - ) + changes.append(self.device.attrs.attrs_path("palette", i).changer_to(event.pkt.palette[i])) if event.pkt.palette_count > len(self.device.attrs.palette): - changes.append( - self.device.attrs.attrs_path("palette").reduce_length_to( - event.pkt.palette_count - ) - ) + changes.append(self.device.attrs.attrs_path("palette").reduce_length_to(event.pkt.palette_count)) changes.append(self.device.attrs.attrs_path("matrix_effect").changer_to(event.pkt.type)) await self.device.attrs.attrs_apply(*changes, event=event) @@ -159,9 +146,7 @@ async def respond(self, event): elif event | TileMessages.Get64: state = [] - res = { - ch.tile_index: ch for ch in self.state_for(TileMessages.State64, expect_one=False) - } + res = {ch.tile_index: ch for ch in self.state_for(TileMessages.State64, expect_one=False)} for i in range(event.pkt.tile_index, event.pkt.tile_index + event.pkt.length): if i in res: state.append(res[i]) @@ -177,11 +162,8 @@ async def respond(self, event): event.set_replies() elif event | TileMessages.Set64: - state = [] - res = { - ch.tile_index: ch for ch in self.state_for(TileMessages.State64, expect_one=False) - } + res = {ch.tile_index: ch for ch in self.state_for(TileMessages.State64, expect_one=False)} for i in range(event.pkt.tile_index, event.pkt.tile_index + event.pkt.length): if i in res: state.append(res[i]) @@ -192,12 +174,7 @@ async def respond(self, event): # For efficiency, not gonna make events for this chain = self.device.attrs.chain[i] chain.colors.clear() - chain.colors.extend( - [ - hp.Color(c.hue, c.saturation, c.brightness, c.kelvin) - for c in event.pkt.colors - ] - ) + chain.colors.extend([hp.Color(c.hue, c.saturation, c.brightness, c.kelvin) for c in event.pkt.colors]) def make_state_for(self, kls, result): if kls | TileMessages.StateTileEffect: diff --git a/modules/photons_app/mimic/operators/multizone.py b/modules/photons_app/mimic/operators/multizone.py index f1f697be..da6871c1 100644 --- a/modules/photons_app/mimic/operators/multizone.py +++ b/modules/photons_app/mimic/operators/multizone.py @@ -1,10 +1,11 @@ from delfick_project.norms import dictobj, sb +from photons_messages import MultiZoneEffectType, MultiZoneMessages +from photons_protocol.types import enum_spec + from photons_app import helpers as hp from photons_app.mimic.event import Event, Events from photons_app.mimic.operator import Operator, operator from photons_app.mimic.operators.light import color_spec -from photons_messages import MultiZoneEffectType, MultiZoneMessages -from photons_protocol.types import enum_spec class ZonesAttr: @@ -55,9 +56,7 @@ class Options(dictobj.Spec): zones = dictobj.Field(sb.listof(color_spec())) zones_count = dictobj.NullableField(sb.integer_spec) - zones_effect = dictobj.Field( - enum_spec(None, MultiZoneEffectType, unpacking=True), default=MultiZoneEffectType.OFF - ) + zones_effect = dictobj.Field(enum_spec(None, MultiZoneEffectType, unpacking=True), default=MultiZoneEffectType.OFF) @classmethod def select(kls, device): @@ -101,9 +100,7 @@ async def respond(self, event): event.add_replies(*state) zones = [] - color = hp.Color( - event.pkt.hue, event.pkt.saturation, event.pkt.brightness, event.pkt.kelvin - ) + color = hp.Color(event.pkt.hue, event.pkt.saturation, event.pkt.brightness, event.pkt.kelvin) for i in range(event.pkt.start_index, event.pkt.end_index + 1): zones.append((i, color)) await self.respond(Events.SET_ZONES(self.device, zones=zones)) @@ -170,9 +167,7 @@ async def respond(self, event): zones.append((i + event.pkt.zone_index, color)) zones = zones[: len(self.device.attrs.zones)] - await self.device.event_with_options( - Events.SET_ZONES, args=(), kwargs={"zones": zones}, visible=False - ) + await self.device.event_with_options(Events.SET_ZONES, args=(), kwargs={"zones": zones}, visible=False) def make_state_for(self, kls, result): if not self.device.cap.has_extended_multizone: diff --git a/modules/photons_app/mimic/operators/relays.py b/modules/photons_app/mimic/operators/relays.py index 9f7576c3..e6ca58a2 100644 --- a/modules/photons_app/mimic/operators/relays.py +++ b/modules/photons_app/mimic/operators/relays.py @@ -1,9 +1,8 @@ -import typing as tp - from delfick_project.norms import dictobj, sb +from photons_messages import DeviceMessages, RelayMessages + from photons_app.mimic.event import Event, Events from photons_app.mimic.operator import Operator, operator -from photons_messages import DeviceMessages, RelayMessages # Ensure Device operator comes before this one __import__("photons_app.mimic.operators.device") @@ -13,7 +12,7 @@ class SetRelaysPower(Event): """Used to change the power of zero or more relays""" - def setup(self, *, relays: tp.Dict[int, int]): + def setup(self, *, relays: dict[int, int]): self.relays = relays def __repr__(self): @@ -42,11 +41,7 @@ async def __call__(self, event, options): options = Relays.Options.FieldSpec().empty_normalise() relays = list(options.relays) if options.relays is not None else [] - relays_count = ( - options.relays_count - if isinstance(options.relays_count, int) and options.relays_count > 0 - else 4 - ) + relays_count = options.relays_count if isinstance(options.relays_count, int) and options.relays_count > 0 else 4 while len(relays) < relays_count: relays.append(Relay.FieldSpec().empty_normalise()) @@ -76,18 +71,14 @@ async def respond(self, event): elif event | RelayMessages.SetRPower: event.add_replies(self.state_for(RelayPowerGetter(event.pkt.relay_index))) - await self.respond( - SetRelaysPower(self.device, relays={event.pkt.relay_index: event.pkt.level}) - ) + await self.respond(SetRelaysPower(self.device, relays={event.pkt.relay_index: event.pkt.level})) elif event | DeviceMessages.SetPower: event.set_replies(self.state_for(DeviceMessages.StatePower)) await self.respond( SetRelaysPower( self.device, - relays={ - index: event.pkt.level for index in range(len(self.device.attrs.relays)) - }, + relays={index: event.pkt.level for index in range(len(self.device.attrs.relays))}, ) ) @@ -98,9 +89,7 @@ async def respond(self, event): for index, power in event.relays.items(): if 0 <= index < len(self.device.attrs.relays): new_power = 0 if power == 0 else 65535 - changes.append( - self.device.attrs.attrs_path("relays", index, "power").changer_to(new_power) - ) + changes.append(self.device.attrs.attrs_path("relays", index, "power").changer_to(new_power)) powers[index] = new_power # On a real switch this changes depending on how you've setup your switch @@ -115,8 +104,4 @@ async def respond(self, event): def make_state_for(self, kls, result): if kls | RelayPowerGetter: if 0 < kls.index < len(self.device.attrs.relays): - result.append( - RelayMessages.StateRPower( - relay_index=kls.index, level=self.device.attrs.relays[kls.index].power - ) - ) + result.append(RelayMessages.StateRPower(relay_index=kls.index, level=self.device.attrs.relays[kls.index].power)) diff --git a/modules/photons_app/mimic/packet_filter.py b/modules/photons_app/mimic/packet_filter.py index 7cc4d07b..342c0994 100644 --- a/modules/photons_app/mimic/packet_filter.py +++ b/modules/photons_app/mimic/packet_filter.py @@ -94,9 +94,7 @@ def lost_replies(self, *klses): self._lost_replies.add(kls) yield finally: - self._lost_replies = { - kls for kls in self._lost_replies if kls not in klses or kls in before - } + self._lost_replies = {kls for kls in self._lost_replies if kls not in klses or kls in before} @contextmanager def lost_request(self, *klses): @@ -106,9 +104,7 @@ def lost_request(self, *klses): self._lost_request.add(kls) yield finally: - self._lost_request = { - kls for kls in self._lost_request if kls not in klses or kls in before - } + self._lost_request = {kls for kls in self._lost_request if kls not in klses or kls in before} @contextmanager def intercept_see_request(self, func): @@ -191,11 +187,7 @@ async def outgoing(self, reply, request_event): else: return - if ( - not request_event.pkt.res_required - and not request_event.pkt.__class__.__name__.startswith("Get") - and not represents_ack - ): + if not request_event.pkt.res_required and not request_event.pkt.__class__.__name__.startswith("Get") and not represents_ack: return if not represents_ack and any(request_event.pkt | kls for kls in self._lost_replies): diff --git a/modules/photons_app/mimic/transport.py b/modules/photons_app/mimic/transport.py index cd042aba..d555ba7c 100644 --- a/modules/photons_app/mimic/transport.py +++ b/modules/photons_app/mimic/transport.py @@ -1,7 +1,6 @@ import time from delfick_project.norms import dictobj, sb -from photons_app.errors import PhotonsAppError from photons_messages import protocol_register from photons_protocol.messages import Messages from photons_transport.retry_options import Gaps @@ -9,6 +8,8 @@ from photons_transport.targets import LanTarget from photons_transport.transports.base import Transport +from photons_app.errors import PhotonsAppError + def make_message(bts): return Messages.create(bts, protocol_register=protocol_register) @@ -91,20 +92,15 @@ async def make_broadcast_transport(self, broadcast): broadcast = self.transport_target.default_broadcast if broadcast not in self.broadcast_transports: - io_service = self.transport_target.io_service async def writer(bts, received_data, addr): for device in self.transport_target.devices: self.record(device.serial, bts) - if io_service.name in device.io and await device.discoverable( - io_service, broadcast - ): + if io_service.name in device.io and await device.discoverable(io_service, broadcast): device.io[io_service.name].received(bts, received_data, addr) - self.broadcast_transports[broadcast] = self.transport_target.transport_kls( - self, self.record, writer - ) + self.broadcast_transports[broadcast] = self.transport_target.transport_kls(self, self.record, writer) return self.broadcast_transports[broadcast] return MemorySession @@ -115,9 +111,7 @@ class MemoryTarget(LanTarget): Knows how to talk to fake devices as if they were on the network. """ - gaps = dictobj.Field( - Gaps(gap_between_results=0.05, gap_between_ack_and_res=0.05, timeouts=[(0.2, 0.2)]) - ) + gaps = dictobj.Field(Gaps(gap_between_results=0.05, gap_between_ack_and_res=0.05, timeouts=[(0.2, 0.2)])) io_service = dictobj.Field(sb.any_spec, default=MemoryService) transport_kls = dictobj.Field(sb.any_spec, default=MemoryTransport) diff --git a/modules/photons_app/photons_app.py b/modules/photons_app/photons_app.py index 5ad10a63..170ee1ce 100644 --- a/modules/photons_app/photons_app.py +++ b/modules/photons_app/photons_app.py @@ -15,6 +15,7 @@ from urllib.parse import unquote, urlparse from delfick_project.norms import dictobj, sb, va + from photons_app import helpers as hp from photons_app.errors import ApplicationStopped, BadOption from photons_app.formatter import MergedOptionStringFormatter @@ -31,29 +32,17 @@ class PhotonsApp(dictobj.Spec): .. dictobj_params:: """ - config = dictobj.Field( - sb.file_spec, wrapper=sb.optional_spec, help="The root configuration file" - ) - extra = dictobj.Field( - sb.string_spec, default="", help="The arguments after the ``--`` in the commandline" - ) + config = dictobj.Field(sb.file_spec, wrapper=sb.optional_spec, help="The root configuration file") + extra = dictobj.Field(sb.string_spec, default="", help="The arguments after the ``--`` in the commandline") debug = dictobj.Field(sb.boolean, default=False, help="Whether we are in debug mode or not") - artifact = dictobj.Field( - default="", format_into=sb.string_spec, help="The artifact string from the commandline" - ) - reference = dictobj.Field( - default="", format_into=sb.string_spec, help="The device(s) to send commands to" - ) + artifact = dictobj.Field(default="", format_into=sb.string_spec, help="The artifact string from the commandline") + reference = dictobj.Field(default="", format_into=sb.string_spec, help="The device(s) to send commands to") cleaners = dictobj.Field( lambda: sb.overridden([]), help="A list of functions to call when cleaning up at the end of the program", ) - default_activate = dictobj.NullableField( - sb.listof(sb.string_spec()), help="A list of photons modules to load by default" - ) - task_specifier = dictobj.Field( - sb.delayed(task_specifier_spec()), help="Used to determine chosen task and target" - ) + default_activate = dictobj.NullableField(sb.listof(sb.string_spec()), help="A list of photons modules to load by default") + task_specifier = dictobj.Field(sb.delayed(task_specifier_spec()), help="Used to determine chosen task and target") @hp.memoized_property def final_future(self): @@ -85,7 +74,7 @@ def extra_as_json(self): if not os.path.exists(location): raise BadOption(f"The path {location} does not exist") - with open(location, "r") as fle: + with open(location) as fle: options = fle.read() try: @@ -144,9 +133,7 @@ def using_graceful_future(self): def stop(): if not graceful_future.done(): - hp.get_event_loop().call_soon_threadsafe( - graceful_future.set_exception, ApplicationStopped() - ) + hp.get_event_loop().call_soon_threadsafe(graceful_future.set_exception, ApplicationStopped()) reinstate_handler = self.loop.remove_signal_handler(signal.SIGTERM) self.loop.add_signal_handler(signal.SIGTERM, stop) @@ -160,9 +147,7 @@ def stop(): def stop(): if not final_future.done(): - hp.get_event_loop().call_soon_threadsafe( - final_future.set_exception, ApplicationStopped() - ) + hp.get_event_loop().call_soon_threadsafe(final_future.set_exception, ApplicationStopped()) self.loop.remove_signal_handler(signal.SIGTERM) self.loop.add_signal_handler(signal.SIGTERM, stop) @@ -226,6 +211,4 @@ def targets_spec(self): """ Get us a dictionary of target name to Target object """ - return sb.dictof( - self.target_name_spec, Target.FieldSpec(formatter=MergedOptionStringFormatter) - ) + return sb.dictof(self.target_name_spec, Target.FieldSpec(formatter=MergedOptionStringFormatter)) diff --git a/modules/photons_app/polyfill.py b/modules/photons_app/polyfill.py index 4677cc9c..ba757aef 100644 --- a/modules/photons_app/polyfill.py +++ b/modules/photons_app/polyfill.py @@ -2,11 +2,10 @@ Copied from python3.8 and python3.6 contextlib """ +import _collections_abc import abc from functools import wraps -import _collections_abc - class AbstractAsyncContextManager(abc.ABC): """An abstract base class for asynchronous context managers.""" @@ -81,7 +80,7 @@ async def __aexit__(self, typ, value, traceback): # have this behavior). But do this only if the exception wrapped # by the RuntimeError is actully Stop(Async)Iteration (see # issue29692). - if isinstance(value, (StopIteration, StopAsyncIteration)): + if isinstance(value, StopIteration | StopAsyncIteration): if exc.__cause__ is value: return False raise diff --git a/modules/photons_app/registers.py b/modules/photons_app/registers.py index c5986c0f..e9bb5456 100644 --- a/modules/photons_app/registers.py +++ b/modules/photons_app/registers.py @@ -5,6 +5,7 @@ """ from delfick_project.norms import dictobj, sb + from photons_app.errors import ( ProgrammerError, ResolverNotFound, @@ -146,13 +147,9 @@ def __repr__(self): restrictions = [] if self.target_types is not None: - restrictions.append( - f"restricted_types='{','.join(str(t) for t in self.target_types)}'" - ) + restrictions.append(f"restricted_types='{','.join(str(t) for t in self.target_types)}'") if self.target_names is not None: - restrictions.append( - f"restricted_names='{','.join(str(n) for n in self.target_names)}'" - ) + restrictions.append(f"restricted_names='{','.join(str(n) for n in self.target_names)}'") return f"" diff --git a/modules/photons_app/special.py b/modules/photons_app/special.py index c428fb62..40d1fb95 100644 --- a/modules/photons_app/special.py +++ b/modules/photons_app/special.py @@ -16,9 +16,7 @@ class SpecialReference: def __init__(self): self.found = hp.ResettableFuture(name=f"SpecialReference({self.__class__.__name__}.found)") - self.finding = hp.ResettableFuture( - name=f"SpecialReference({self.__class__.__name__}.finding" - ) + self.finding = hp.ResettableFuture(name=f"SpecialReference({self.__class__.__name__}.finding") async def find_serials(self, sender, *, timeout, broadcast=True): """Must be implemented by the subclass, return ``found`` from this function""" @@ -46,9 +44,7 @@ async def find(self, sender, *, timeout, broadcast=True): return await self.found self.finding.set_result(True) - t = hp.get_event_loop().create_task( - self.find_serials(sender, timeout=timeout, broadcast=broadcast) - ) + t = hp.get_event_loop().create_task(self.find_serials(sender, timeout=timeout, broadcast=broadcast)) def transfer(res): if res.cancelled(): @@ -113,15 +109,13 @@ def __init__(self, serials): self.serials = [binascii.hexlify(target).decode() for target in self.targets] - super(HardCodedSerials, self).__init__() + super().__init__() async def find_serials(self, sender, *, timeout, broadcast=True): found = getattr(sender, "found", {}) if not all(target in found for target in self.targets): - found, _ = await sender.find_specific_serials( - self.serials, broadcast=broadcast, raise_on_none=False, timeout=timeout - ) + found, _ = await sender.find_specific_serials(self.serials, broadcast=broadcast, raise_on_none=False, timeout=timeout) return {target: found[target] for target in self.targets if target in found} @@ -140,9 +134,7 @@ def __init__(self, filename): with open(self.filename) as fle: serials = [s.strip() for s in fle.readlines() if s.strip()] except OSError as error: - raise PhotonsAppError( - "Failed to read serials from a file", filename=self.filename, error=error - ) + raise PhotonsAppError("Failed to read serials from a file", filename=self.filename, error=error) if not serials: raise PhotonsAppError("Found no serials in file", filename=self.filename) diff --git a/modules/photons_app/tasks/default_tasks.py b/modules/photons_app/tasks/default_tasks.py index 3e776845..4f2ffb61 100644 --- a/modules/photons_app/tasks/default_tasks.py +++ b/modules/photons_app/tasks/default_tasks.py @@ -5,6 +5,7 @@ from delfick_project.norms import Meta, sb from delfick_project.option_merge import MergedOptions + from photons_app.errors import PhotonsAppError from photons_app.tasks.register import task_register from photons_app.tasks.specifier import task_specifier_spec @@ -52,9 +53,7 @@ async def execute_task(self, **kwargs): if self.reference is not sb.NotSpecified: if ":" in self.reference: - target_name, task_name = task_specifier_spec().normalise( - Meta.empty(), self.reference - ) + target_name, task_name = task_specifier_spec().normalise(Meta.empty(), self.reference) else: task_name = self.reference @@ -73,13 +72,8 @@ async def execute_task(self, **kwargs): if target_name in target_register.registered or target_name in target_register.types: kwargs["specific_target"] = target_name - if ( - target_name not in target_register.registered - and target_name not in target_register.types - ): - raise PhotonsAppError( - "Sorry, cannot find help for non existing target", wanted=target_name - ) + if target_name not in target_register.registered and target_name not in target_register.types: + raise PhotonsAppError("Sorry, cannot find help for non existing target", wanted=target_name) if task_name is not sb.NotSpecified: kwargs["specific_task"] = task_name @@ -90,9 +84,7 @@ async def execute_task(self, **kwargs): available=task_register.names, ) - await task_register.fill_task( - self.collector, list_tasks, specific_task_groups=self.specific_task_groups, **kwargs - ).run() + await task_register.fill_task(self.collector, list_tasks, specific_task_groups=self.specific_task_groups, **kwargs).run() @task @@ -129,10 +121,7 @@ async def execute_task(self, **kwargs): tasks = [] for task in task_register.registered: - if ( - self.specific_task_groups is not None - and task.task_group not in self.specific_task_groups - ): + if self.specific_task_groups is not None and task.task_group not in self.specific_task_groups: continue if self.specific_task is sb.NotSpecified or task.name == self.specific_task: @@ -182,19 +171,14 @@ def print_tasks(self, targets_by_name, tasks): doc = doc.split("\n")[0] o = StringIO() - task_register.fill_task( - self.collector, self.__class__, output=o - ).print_target_restrictions(targets_by_name, restriction) + task_register.fill_task(self.collector, self.__class__, output=o).print_target_restrictions(targets_by_name, restriction) o.flush() o.seek(0) by_restriction[o.read()].append((t.name, t.task_group, doc)) for show_those_without_restriction in (False, True): for restriction, tasks in by_restriction.items(): - if ( - restriction.startswith("- Can be used with any target") - ^ show_those_without_restriction - ): + if restriction.startswith("- Can be used with any target") ^ show_those_without_restriction: continue self("=" * 80) diff --git a/modules/photons_app/tasks/register.py b/modules/photons_app/tasks/register.py index 0fbf205a..7fb8adec 100644 --- a/modules/photons_app/tasks/register.py +++ b/modules/photons_app/tasks/register.py @@ -1,10 +1,13 @@ from collections import namedtuple from delfick_project.norms import dictobj, sb + from photons_app.errors import BadOption, BadTarget, BadTask from photons_app.tasks.tasks import GracefulTask, Task -artifact_spec = lambda: sb.optional_spec(sb.any_spec()) + +def artifact_spec(): + return sb.optional_spec(sb.any_spec()) class target_spec(sb.Spec): @@ -282,9 +285,7 @@ def find(self, target_register, task, target): raise BadTask( "Task was used with wrong type of target", wanted_task=task, - wanted_target=getattr( - target, "instantiated_name", getattr(target, "__name__", repr(target)) - ), + wanted_target=getattr(target, "instantiated_name", getattr(target, "__name__", repr(target))), available_targets=sorted(set(possible_targets)), **kw, ) diff --git a/modules/photons_app/tasks/runner.py b/modules/photons_app/tasks/runner.py index ef60a995..c941f82e 100644 --- a/modules/photons_app/tasks/runner.py +++ b/modules/photons_app/tasks/runner.py @@ -51,7 +51,7 @@ def run(self): override = self.got_keyboard_interrupt(error) except asyncio.CancelledError as error: override = self.got_cancelled(error) - except: + except Exception: override = sys.exc_info()[1] log.debug("CLEANING UP") @@ -72,9 +72,7 @@ def register_sigterm_handler(self, final_future): def stop_final_fut(): if not final_future.done(): - hp.get_event_loop().call_soon_threadsafe( - final_future.set_exception, ApplicationStopped() - ) + hp.get_event_loop().call_soon_threadsafe(final_future.set_exception, ApplicationStopped()) self.loop.add_signal_handler(signal.SIGTERM, stop_final_fut) @@ -166,7 +164,7 @@ def wait_for_main_task(self, task): self.loop.run_until_complete(asyncio.tasks.gather(task, return_exceptions=True)) except KeyboardInterrupt: pass - except: + except Exception: pass finally: task.cancel() @@ -176,7 +174,7 @@ def wait_for_waiter(self, waiter): waiter.cancel() try: self.loop.run_until_complete(asyncio.tasks.gather(waiter, return_exceptions=True)) - except: + except Exception: pass def run_cleanup(self): @@ -192,8 +190,7 @@ def ensure_finished_futures(self, task, waiter): if self.photons_app.graceful_final_future.setup: if self.significant_future.cancelled() or isinstance( - self.significant_future.exception(), - (UserQuit, ApplicationStopped, ApplicationCancelled), + self.significant_future.exception(), UserQuit | ApplicationStopped | ApplicationCancelled ): self.photons_app.final_future.cancel() @@ -251,12 +248,10 @@ async def shutdown_asyncgens(self): # the asyncio loop to think it's shutdown, so I have to do them one at a time for ag in closing_agens: try: - await hp.stop_async_generator( - ag, name="||shutdown_asyncgens[wait_for_closing_agens]" - ) + await hp.stop_async_generator(ag, name="||shutdown_asyncgens[wait_for_closing_agens]") except asyncio.CancelledError: pass - except: + except Exception: exc = sys.exc_info()[1] self.loop.call_exception_handler( { diff --git a/modules/photons_app/tasks/specifier.py b/modules/photons_app/tasks/specifier.py index 18dc420e..8838150f 100644 --- a/modules/photons_app/tasks/specifier.py +++ b/modules/photons_app/tasks/specifier.py @@ -3,6 +3,7 @@ import uuid from delfick_project.norms import BadSpecValue, sb + from photons_app.errors import TargetNotFound from photons_app.formatter import MergedOptionStringFormatter from photons_app.registers import Target @@ -20,9 +21,7 @@ def normalise_filled(self, meta, val): val = tuple(val) if isinstance(val, tuple): - return sb.tuple_spec( - sb.optional_spec(sb.string_spec()), sb.required(sb.string_spec()) - ).normalise(meta, val) + return sb.tuple_spec(sb.optional_spec(sb.string_spec()), sb.required(sb.string_spec())).normalise(meta, val) task = sb.or_spec(sb.string_spec(), sb.none_spec()).normalise(meta, val) if not task: @@ -44,14 +43,14 @@ def normalise_filled(self, meta, val): target_register = collector.configuration["target_register"] target_name = tokens.pop(0).string - target_name = self.parse_overridden_target( - meta, val, collector, target_register, target_name, tokens - ) + target_name = self.parse_overridden_target(meta, val, collector, target_register, target_name, tokens) return target_name, chosen_task def initial_parse(self, val): lines = [val.encode(), b""] - readline = lambda size=-1: lines.pop(0) + + def readline(size=-1): + return lines.pop(0) try: tokens = list(tokenize.tokenize(readline)) @@ -71,16 +70,12 @@ def initial_parse(self, val): def parse_overridden_target(self, meta, val, collector, target_register, target_name, tokens): if target_name not in target_register.registered: - raise TargetNotFound( - name=target_name, available=list(target_register.registered.keys()) - ) + raise TargetNotFound(name=target_name, available=list(target_register.registered.keys())) if tokens[0].string != "(" or tokens[-1].string != ")": raise BadSpecValue("target with options should have options in parenthesis", got=val) - parent_target_options = collector.configuration.get( - ["targets", target_name], ignore_converters=True - ).as_dict() + parent_target_options = collector.configuration.get(["targets", target_name], ignore_converters=True).as_dict() target = self.parse_target(meta, parent_target_options, target_name, tokens) @@ -101,9 +96,7 @@ def parse_target(self, meta, target_options, target_name, tokens): try: val = ast.parse(untokenized) except SyntaxError as e: - raise BadSpecValue( - "Target options must be valid dictionary syntax", error=e, got=untokenized - ) + raise BadSpecValue("Target options must be valid dictionary syntax", error=e, got=untokenized) else: for kw in val.body[0].value.keywords: try: diff --git a/modules/photons_app/tasks/tasks.py b/modules/photons_app/tasks/tasks.py index 795bfc9d..f8a65999 100644 --- a/modules/photons_app/tasks/tasks.py +++ b/modules/photons_app/tasks/tasks.py @@ -3,6 +3,7 @@ import typing as tp from delfick_project.norms import Meta, dictobj, sb + from photons_app import helpers as hp from photons_app.errors import ApplicationStopped from photons_app.formatter import MergedOptionStringFormatter @@ -65,9 +66,7 @@ def create(kls, collector, where=None, instantiated_name=None, **kwargs): @hp.memoized_property def task_holder(self): - return hp.TaskHolder( - self.photons_app.final_future, name=f"Task({self.__class__.__name__})::task_holder" - ) + return hp.TaskHolder(self.photons_app.final_future, name=f"Task({self.__class__.__name__})::task_holder") def run_loop(self, **kwargs): return Runner(self, kwargs).run_loop() @@ -78,7 +77,7 @@ async def run(self, **kwargs): async with self.task_holder: try: return await self.execute_task(**kwargs) - except: + except Exception: exc_info = sys.exc_info() if not self.hide_exception_from_task_holder(exc_info): raise diff --git a/modules/photons_canvas/addon.py b/modules/photons_canvas/addon.py index 1bb73c70..b0f8b336 100644 --- a/modules/photons_canvas/addon.py +++ b/modules/photons_canvas/addon.py @@ -5,6 +5,7 @@ from delfick_project.option_merge import MergedOptions from photons_app.errors import PhotonsAppError from photons_app.tasks import task_register as task + from photons_canvas.animations import AnimationRunner, print_help, register from photons_canvas.theme import ApplyTheme diff --git a/modules/photons_canvas/animations/action.py b/modules/photons_canvas/animations/action.py index 1010dbda..bd34f69d 100644 --- a/modules/photons_canvas/animations/action.py +++ b/modules/photons_canvas/animations/action.py @@ -4,6 +4,7 @@ from textwrap import dedent from photons_app.tasks import task_register as task + from photons_canvas.animations.infrastructure.finish import Finish from photons_canvas.animations.runner import AnimationRunner diff --git a/modules/photons_canvas/animations/infrastructure/animation.py b/modules/photons_canvas/animations/infrastructure/animation.py index 4b4f1c23..5f08f633 100644 --- a/modules/photons_canvas/animations/infrastructure/animation.py +++ b/modules/photons_canvas/animations/infrastructure/animation.py @@ -3,6 +3,7 @@ import time from photons_app import helpers as hp + from photons_canvas.animations.infrastructure.events import AnimationEvent from photons_canvas.points import rearrange @@ -79,9 +80,7 @@ def errors(e): name=f"Animation({self.__class__.__name__})", ) as streamer: await streamer.add_generator(tick(), context=AnimationEvent.Types.TICK) - await streamer.add_generator( - self.make_user_events(animation_state), context=AnimationEvent.Types.USER_EVENT - ) + await streamer.add_generator(self.make_user_events(animation_state), context=AnimationEvent.Types.USER_EVENT) streamer.no_more_work() async for result in streamer: diff --git a/modules/photons_canvas/animations/infrastructure/cannons.py b/modules/photons_canvas/animations/infrastructure/cannons.py index 4b47358b..4efcd7d7 100644 --- a/modules/photons_canvas/animations/infrastructure/cannons.py +++ b/modules/photons_canvas/animations/infrastructure/cannons.py @@ -49,11 +49,7 @@ def should_drop(self, serial): if not self.inflight_limit: return False - self.results[serial] = [ - (t, r) - for t, r in self.results[serial] - if not r.done() and time.time() - t < self.wait_timeout - ] + self.results[serial] = [(t, r) for t, r in self.results[serial] if not r.done() and time.time() - t < self.wait_timeout] if len(self.results[serial]) >= self.inflight_limit: return True diff --git a/modules/photons_canvas/animations/infrastructure/register.py b/modules/photons_canvas/animations/infrastructure/register.py index 1d3b9e55..f0ff3108 100644 --- a/modules/photons_canvas/animations/infrastructure/register.py +++ b/modules/photons_canvas/animations/infrastructure/register.py @@ -28,9 +28,7 @@ def resolver(self, options=None, background=None): if options is None: options = {} - background = ( - background if background in (True, False) else background in (sb.NotSpecified, None) - ) + background = background if background in (True, False) else background in (sb.NotSpecified, None) return self.Resolver(self, options, background) diff --git a/modules/photons_canvas/animations/infrastructure/state.py b/modules/photons_canvas/animations/infrastructure/state.py index 09da083f..c350f768 100644 --- a/modules/photons_canvas/animations/infrastructure/state.py +++ b/modules/photons_canvas/animations/infrastructure/state.py @@ -6,6 +6,7 @@ from photons_app import helpers as hp from photons_app.errors import PhotonsAppError + from photons_canvas import Canvas from photons_canvas.animations.infrastructure.events import AnimationEvent from photons_canvas.animations.infrastructure.finish import Finish @@ -25,7 +26,7 @@ def catch_finish(reraise_exceptions=True): raise except Finish: pass - except: + except Exception: if reraise_exceptions: raise log.exception("Unexpected error") @@ -51,7 +52,7 @@ async def ensure_error_event(self): yield except (Finish, asyncio.CancelledError): raise - except: + except Exception: exc_typ, exc, tb = sys.exc_info() handled = False @@ -60,7 +61,7 @@ async def ensure_error_event(self): handled = await self.process_event(AnimationEvent.Types.ERROR, exc) except asyncio.CancelledError: raise - except: + except Exception: log.exception("Failed to process event") raise Finish("Failed to process error") @@ -85,9 +86,7 @@ async def set_animation(self, animation, background): self.background = background self.canvas = Canvas() - await self.add_collected( - [[p.clone_real_part() for p in ps] for ps in self.by_device.values()] - ) + await self.add_collected([[p.clone_real_part() for p in ps] for ps in self.by_device.values()]) def add_parts(self, parts): for part in parts: @@ -122,9 +121,7 @@ async def messages(self, device=None): if result.context is AnimationEvent.Types.TICK: if not self: continue - async for messages in self.send_canvas( - await self.process_event(AnimationEvent.Types.TICK) - ): + async for messages in self.send_canvas(await self.process_event(AnimationEvent.Types.TICK)): yield messages else: @@ -133,9 +130,7 @@ async def messages(self, device=None): if started and not sys.exc_info()[0]: with catch_finish(reraise_exceptions=False): await asyncio.sleep(self.animation.every) - async for messages in self.send_canvas( - await self.process_event(AnimationEvent.Types.ENDED, force=True) - ): + async for messages in self.send_canvas(await self.process_event(AnimationEvent.Types.ENDED, force=True)): yield messages async def send_canvas(self, layer): @@ -173,9 +168,7 @@ async def process_event(self, typ, value=None, force=False): except Finish: raise except NotImplementedError: - log.error( - hp.lc("Animation does not implement process_event", animation=type(self.animation)) - ) + log.error(hp.lc("Animation does not implement process_event", animation=type(self.animation))) raise Finish("Animation does not implement process_event") except Exception as error: log.exception(error) diff --git a/modules/photons_canvas/animations/lines.py b/modules/photons_canvas/animations/lines.py index 62e2c1df..3a9b1366 100644 --- a/modules/photons_canvas/animations/lines.py +++ b/modules/photons_canvas/animations/lines.py @@ -1,6 +1,7 @@ import math from delfick_project.norms import dictobj, sb + from photons_canvas import point_helpers as php from photons_canvas.animations import options diff --git a/modules/photons_canvas/animations/options.py b/modules/photons_canvas/animations/options.py index e486b6e9..dee04781 100644 --- a/modules/photons_canvas/animations/options.py +++ b/modules/photons_canvas/animations/options.py @@ -130,7 +130,7 @@ def normalise_filled(self, meta, val): return ManyColor([c for c in colors if c is not None]) def interpret(self, meta, val): - if not isinstance(val, (tuple, list, str)): + if not isinstance(val, tuple | list | str): raise BadSpecValue("Each color specifier must be a list or string", got=val, meta=meta) if isinstance(val, str): @@ -153,7 +153,7 @@ def interpret(self, meta, val): for i, v in enumerate(val): m = meta.indexed_at(i) - if not isinstance(v, (tuple, list, str)): + if not isinstance(v, tuple | list | str): raise BadSpecValue("Each color specifier must be a list or string", got=val, meta=m) if i != 0 and v == "rainbow": @@ -166,7 +166,7 @@ def interpret(self, meta, val): if isinstance(v, str): v = v.split("-") - if isinstance(v, (int, float)): + if isinstance(v, int | float): v = [v] if len(v) > 2: @@ -260,10 +260,10 @@ def normalise_filled(self, meta, value): value = value.split("-") if len(value) == 1: value *= 2 - elif isinstance(value, (int, float)): + elif isinstance(value, int | float): value = (value, value) - if not isinstance(value, (list, tuple)): + if not isinstance(value, list | tuple): raise BadSpecValue("Speed option must be 'min-max' or [min, max]", got=value, meta=meta) kls = Rate if self.rate else Range diff --git a/modules/photons_canvas/animations/registered/balls.py b/modules/photons_canvas/animations/registered/balls.py index a807d2da..76d2c87a 100644 --- a/modules/photons_canvas/animations/registered/balls.py +++ b/modules/photons_canvas/animations/registered/balls.py @@ -3,6 +3,7 @@ import uuid from delfick_project.norms import dictobj, sb + from photons_canvas import point_helpers as php from photons_canvas.animations import Animation, an_animation, options @@ -111,9 +112,7 @@ def points(self, extra_col, extra_row, hor_direction, ver_direction): def move(self): extra_col = random.randrange(0, 5) / 10 extra_row = random.randrange(0, 5) / 10 - self.point, self.hor_direction, self.ver_direction, points = self.boundary.move( - self, extra_col, extra_row - ) + self.point, self.hor_direction, self.ver_direction, points = self.boundary.move(self, extra_col, extra_row) return points diff --git a/modules/photons_canvas/animations/registered/color_cycle.py b/modules/photons_canvas/animations/registered/color_cycle.py index 17d1fd93..3c256342 100644 --- a/modules/photons_canvas/animations/registered/color_cycle.py +++ b/modules/photons_canvas/animations/registered/color_cycle.py @@ -3,6 +3,7 @@ from collections import defaultdict from delfick_project.norms import dictobj, sb + from photons_canvas import point_helpers as php from photons_canvas.animations import Animation, an_animation @@ -218,9 +219,7 @@ def layer(self, point, canvas): c = self.event.state["colors"].get(key) if key is None or c is None: - c = self.event.state["colors"][key] = self.changer.color( - point, canvas, self.event, self.event.state["state"] - ) + c = self.event.state["colors"][key] = self.changer.color(point, canvas, self.event, self.event.state["state"]) return c diff --git a/modules/photons_canvas/animations/registered/dice.py b/modules/photons_canvas/animations/registered/dice.py index 4455cd6b..143a2b82 100644 --- a/modules/photons_canvas/animations/registered/dice.py +++ b/modules/photons_canvas/animations/registered/dice.py @@ -2,6 +2,7 @@ import random from delfick_project.norms import dictobj, sb + from photons_canvas import font from photons_canvas.animations import Animation, Finish, an_animation, options diff --git a/modules/photons_canvas/animations/registered/dots.py b/modules/photons_canvas/animations/registered/dots.py index 5d8029f6..6bc3948e 100644 --- a/modules/photons_canvas/animations/registered/dots.py +++ b/modules/photons_canvas/animations/registered/dots.py @@ -1,6 +1,7 @@ import random from delfick_project.norms import dictobj + from photons_canvas import point_helpers as php from photons_canvas.animations import Animation, Finish, an_animation, options diff --git a/modules/photons_canvas/animations/registered/falling.py b/modules/photons_canvas/animations/registered/falling.py index 98624f63..512605f3 100644 --- a/modules/photons_canvas/animations/registered/falling.py +++ b/modules/photons_canvas/animations/registered/falling.py @@ -1,6 +1,7 @@ import random from delfick_project.norms import dictobj + from photons_canvas import point_helpers as php from photons_canvas.animations import Animation, an_animation, options from photons_canvas.animations.lines import LineOptions @@ -82,7 +83,7 @@ def next_layer(self): if top < self.extreme_bottom: remove.append(line) - self.lines[col] = [l for l in self.lines[col] if l not in remove] + self.lines[col] = [bl for bl in self.lines[col] if bl not in remove] if most_top is None or self.extreme_top - most_top > random.randrange(3, 7): self.lines[col].append(Line.make(self.options, self.extreme_top)) diff --git a/modules/photons_canvas/animations/registered/marquee.py b/modules/photons_canvas/animations/registered/marquee.py index c980e21d..14a8536e 100644 --- a/modules/photons_canvas/animations/registered/marquee.py +++ b/modules/photons_canvas/animations/registered/marquee.py @@ -2,9 +2,10 @@ from delfick_project.norms import dictobj, sb from photons_app import helpers as hp +from photons_protocol.types import enum_spec + from photons_canvas.animations import Animation, Finish, an_animation, options from photons_canvas.font import Characters, alphabet_8 -from photons_protocol.types import enum_spec class MarqueeDirection(enum.Enum): @@ -157,11 +158,7 @@ async def process_event(self, event): event.state.bounds = event.canvas.bounds elif event.is_tick: - - if ( - self.options.num_iterations > 0 - and event.state.iteration >= self.options.num_iterations - ): + if self.options.num_iterations > 0 and event.state.iteration >= self.options.num_iterations: raise Finish("Reached maximum iterations") return event.state.next_layer diff --git a/modules/photons_canvas/animations/registered/nyan.py b/modules/photons_canvas/animations/registered/nyan.py index 71340cb7..1e2368b1 100644 --- a/modules/photons_canvas/animations/registered/nyan.py +++ b/modules/photons_canvas/animations/registered/nyan.py @@ -1,5 +1,6 @@ from delfick_project.norms import dictobj from photons_app import helpers as hp + from photons_canvas.animations import an_animation from photons_canvas.animations.registered.marquee import ( MarqueeAnimation, diff --git a/modules/photons_canvas/animations/registered/pacman.py b/modules/photons_canvas/animations/registered/pacman.py index 2c331657..e131035c 100644 --- a/modules/photons_canvas/animations/registered/pacman.py +++ b/modules/photons_canvas/animations/registered/pacman.py @@ -2,6 +2,7 @@ from delfick_project.norms import dictobj, sb from photons_app import helpers as hp + from photons_canvas.animations import an_animation from photons_canvas.animations.registered.marquee import ( MarqueeAnimation, diff --git a/modules/photons_canvas/animations/registered/skip.py b/modules/photons_canvas/animations/registered/skip.py index 4cfcdc52..d0ea780d 100644 --- a/modules/photons_canvas/animations/registered/skip.py +++ b/modules/photons_canvas/animations/registered/skip.py @@ -1,4 +1,5 @@ from delfick_project.norms import dictobj + from photons_canvas.animations import Animation, Finish, an_animation diff --git a/modules/photons_canvas/animations/registered/swipe.py b/modules/photons_canvas/animations/registered/swipe.py index d687599a..dc3e416d 100644 --- a/modules/photons_canvas/animations/registered/swipe.py +++ b/modules/photons_canvas/animations/registered/swipe.py @@ -1,6 +1,7 @@ import random from delfick_project.norms import dictobj + from photons_canvas import Canvas from photons_canvas import point_helpers as php from photons_canvas.animations import Animation, Finish, an_animation, options diff --git a/modules/photons_canvas/animations/registered/time.py b/modules/photons_canvas/animations/registered/time.py index 0fb49e52..37bbd866 100644 --- a/modules/photons_canvas/animations/registered/time.py +++ b/modules/photons_canvas/animations/registered/time.py @@ -2,6 +2,7 @@ import time from delfick_project.norms import dictobj, sb + from photons_canvas import font from photons_canvas import point_helpers as php from photons_canvas.animations import Animation, an_animation, options diff --git a/modules/photons_canvas/animations/registered/twinkles.py b/modules/photons_canvas/animations/registered/twinkles.py index 6a3e6961..bf459965 100644 --- a/modules/photons_canvas/animations/registered/twinkles.py +++ b/modules/photons_canvas/animations/registered/twinkles.py @@ -1,6 +1,7 @@ import random from delfick_project.norms import dictobj + from photons_canvas import point_helpers as php from photons_canvas.animations import Animation, an_animation, options @@ -23,9 +24,7 @@ def __init__(self, color, fade_in, fade_out): @property def color(self): - c = self._color = php.Color.adjust( - self._color, brightness_change=self.fades[self.direction] - ) + c = self._color = php.Color.adjust(self._color, brightness_change=self.fades[self.direction]) if c[2] >= 1: self.direction = 1 diff --git a/modules/photons_canvas/animations/run_options.py b/modules/photons_canvas/animations/run_options.py index 6db7076e..016375d8 100644 --- a/modules/photons_canvas/animations/run_options.py +++ b/modules/photons_canvas/animations/run_options.py @@ -4,6 +4,7 @@ from delfick_project.norms import BadSpecValue, Meta, dictobj, sb from photons_app.formatter import MergedOptionStringFormatter + from photons_canvas.animations.infrastructure.register import resolve @@ -37,9 +38,9 @@ def normalise_empty(self, meta): env = 0 return sb.integer_spec().normalise(meta, env) - animation_options = sb.set_options( - noisy_network_limit=sb.defaulted(sb.integer_spec(), 0) - ).normalise(meta, meta.everything.get("animation_options") or {}) + animation_options = sb.set_options(noisy_network_limit=sb.defaulted(sb.integer_spec(), 0)).normalise( + meta, meta.everything.get("animation_options") or {} + ) if animation_options["noisy_network_limit"]: return animation_options["noisy_network_limit"] @@ -58,13 +59,13 @@ def normalise_filled(self, meta, val): if isinstance(val, str): val = [val] - if isinstance(val, (list, tuple)) and hasattr(val[0], "resolve"): + if isinstance(val, list | tuple) and hasattr(val[0], "resolve"): val = val[0] if hasattr(val, "resolve"): return val - if isinstance(val, (list, tuple)): + if isinstance(val, list | tuple): if len(val) == 1: val = [val[0], sb.NotSpecified, sb.NotSpecified] @@ -80,9 +81,7 @@ def normalise_filled(self, meta, val): class TransitionOptions(dictobj.Spec): - run_first = dictobj.Field( - sb.boolean, default=True, help="Whether to run a transition before feature animations" - ) + run_first = dictobj.Field(sb.boolean, default=True, help="Whether to run a transition before feature animations") run_last = dictobj.Field( sb.boolean, @@ -90,9 +89,7 @@ class TransitionOptions(dictobj.Spec): help="Whether to run a transition after limit of feature animations", ) - run_between = dictobj.Field( - sb.boolean, default=True, help="Whether to run a transitions between animations" - ) + run_between = dictobj.Field(sb.boolean, default=True, help="Whether to run a transitions between animations") animations = dictobj.Field( sb.listof(animation_spec()), @@ -114,9 +111,7 @@ class RunOptions(dictobj.Spec): help="A semaphore that when set will pause the animation", ) - combined = dictobj.Field( - sb.boolean, default=True, help="Whether to join all found tiles into one animation" - ) + combined = dictobj.Field(sb.boolean, default=True, help="Whether to join all found tiles into one animation") reinstate_on_end = dictobj.Field( sb.boolean, @@ -124,9 +119,7 @@ class RunOptions(dictobj.Spec): help="Whether to return the tiles to how they were before the animation", ) - reinstate_duration = dictobj.Field( - sb.float_spec, default=1, help="The duration used when reinstating state" - ) + reinstate_duration = dictobj.Field(sb.float_spec, default=1, help="The duration used when reinstating state") noisy_network = dictobj.Field( noisy_network_spec(), diff --git a/modules/photons_canvas/animations/runner.py b/modules/photons_canvas/animations/runner.py index 3c70643e..f272a62d 100644 --- a/modules/photons_canvas/animations/runner.py +++ b/modules/photons_canvas/animations/runner.py @@ -6,27 +6,24 @@ from photons_app import helpers as hp from photons_app.errors import FoundNoDevices from photons_app.special import SpecialReference +from photons_messages import LightMessages + from photons_canvas import Canvas from photons_canvas.animations.infrastructure import cannons from photons_canvas.animations.infrastructure.finish import Finish from photons_canvas.animations.infrastructure.state import State from photons_canvas.animations.run_options import make_run_options -from photons_messages import LightMessages log = logging.getLogger("photons_canvas.animations.runner") class AnimationRunner(hp.AsyncCMMixin): - def __init__( - self, sender, reference, run_options, *, final_future, animation_options=None, **kwargs - ): + def __init__(self, sender, reference, run_options, *, final_future, animation_options=None, **kwargs): self.sender = sender self.kwargs = kwargs self.reference = reference self.run_options = make_run_options(run_options, animation_options) - self.final_future = hp.ChildOfFuture( - final_future, name="AnimationRunner::__init__[final_future]" - ) + self.final_future = hp.ChildOfFuture(final_future, name="AnimationRunner::__init__[final_future]") self.original_canvas = Canvas() self.started = None @@ -78,12 +75,8 @@ async def run(self): animations = self.run_options.animations_iter self.combined_state = State(self.final_future) - async with self.reinstate(), hp.TaskHolder( - self.final_future, name="AnimationRunner::run[task_holder]" - ) as ts: - self.transfer_error( - ts, ts.add(self.animate(ts, cannon, self.combined_state, animations)) - ) + async with self.reinstate(), hp.TaskHolder(self.final_future, name="AnimationRunner::run[task_holder]") as ts: + self.transfer_error(ts, ts.add(self.animate(ts, cannon, self.combined_state, animations))) async for collected in self.collect_parts(ts): try: @@ -106,9 +99,7 @@ def process(res, fut): fut.cancel() try: - t.add_done_callback( - hp.transfer_result(self.final_future, errors_only=True, process=process) - ) + t.add_done_callback(hp.transfer_result(self.final_future, errors_only=True, process=process)) except asyncio.CancelledError: raise except Exception as error: @@ -127,9 +118,7 @@ async def animate(self, ts, cannon, state, animations): except StopIteration: break - with hp.ChildOfFuture( - self.final_future, name="AnimationRunner::animate[animation_fut]" - ) as animation_fut: + with hp.ChildOfFuture(self.final_future, name="AnimationRunner::animate[animation_fut]") as animation_fut: animation = make_animation(animation_fut, self.run_options.pauser) self.current_animation = animation @@ -164,9 +153,7 @@ async def collect_parts(self, ts): elif isinstance(serials, SpecialReference): self.reference.reset() try: - _, serials = await self.reference.find( - self.sender, timeout=self.kwargs.get("find_timeout", 10) - ) + _, serials = await self.reference.find(self.sender, timeout=self.kwargs.get("find_timeout", 10)) except asyncio.CancelledError: raise except FoundNoDevices: @@ -206,9 +193,7 @@ async def reinstate(self): finally: if not self.run_options.reinstate_on_end: return - await self.sender( - list(self.original_canvas.restore_msgs()), message_timeout=1, errors=[] - ) + await self.sender(list(self.original_canvas.restore_msgs()), message_timeout=1, errors=[]) async def turn_on(self, serial): msg = LightMessages.SetLightPower(level=65535, duration=1) @@ -216,9 +201,7 @@ async def turn_on(self, serial): async def parts_from_serials(self, serials): plans = self.sender.make_plans("parts_and_colors") - async for serial, _, info in self.sender.gatherer.gather_per_serial( - plans, serials, **self.kwargs - ): + async for serial, _, info in self.sender.gatherer.gather_per_serial(plans, serials, **self.kwargs): self.seen_serials.add(serial) parts = info["parts_and_colors"] if parts: diff --git a/modules/photons_canvas/font/base.py b/modules/photons_canvas/font/base.py index f42a73ff..f8f78ab3 100644 --- a/modules/photons_canvas/font/base.py +++ b/modules/photons_canvas/font/base.py @@ -63,8 +63,7 @@ def pairs(self, left_x, top_y, fill_color): left_x = round(left_x) for character in self.characters: - for point, pixel in character.pairs(left_x, top_y, fill_color): - yield point, pixel + yield from character.pairs(left_x, top_y, fill_color) left_x += character.width diff --git a/modules/photons_canvas/points/canvas.py b/modules/photons_canvas/points/canvas.py index 62a1e6ba..77b20941 100644 --- a/modules/photons_canvas/points/canvas.py +++ b/modules/photons_canvas/points/canvas.py @@ -1,6 +1,7 @@ from collections import defaultdict from delfick_project.norms import sb + from photons_canvas.points import helpers as php @@ -149,9 +150,7 @@ def msgs(self, layer, acks=False, duration=1, randomize=False, onto=None): if onto is not None: onto[point] = c - for msg in part.msgs( - cs, acks=acks, duration=duration, randomize=randomize, force=False - ): + for msg in part.msgs(cs, acks=acks, duration=duration, randomize=randomize, force=False): msgs.append(msg) return msgs @@ -206,10 +205,10 @@ def _update_bounds(self, parts): else: bounds = part.bounds - (l, r), (t, b), _ = bounds + (bl, r), (t, b), _ = bounds top = top if top is not None and t < top else t - left = left if left is not None and l > left else l + left = left if left is not None and bl > left else bl right = right if right is not None and r < right else r bottom = bottom if bottom is not None and b > bottom else b diff --git a/modules/photons_canvas/points/containers.py b/modules/photons_canvas/points/containers.py index 04dc22ba..71328c27 100644 --- a/modules/photons_canvas/points/containers.py +++ b/modules/photons_canvas/points/containers.py @@ -2,10 +2,11 @@ import random import time +from photons_messages import LightMessages + from photons_canvas.orientation import Orientation, reorient, reverse_orientation from photons_canvas.points import helpers as php from photons_canvas.points.simple_messages import MultizoneMessagesMaker, Set64 -from photons_messages import LightMessages NO_MESSAGES = () @@ -89,9 +90,7 @@ def original_colors(self, value): def clone_real_part(self): return self.real_part.clone(real_part=self.real_part, frm=self) - def clone( - self, *, user_x=None, user_y=None, width=None, height=None, real_part=False, frm=None - ): + def clone(self, *, user_x=None, user_y=None, width=None, height=None, real_part=False, frm=None): if frm is None: frm = self @@ -100,7 +99,8 @@ def clone( w = self.width if width is None else width h = self.height if height is None else height - l = lambda ss: ss if ss is None else list(ss) + def listify(ss): + return ss if ss is None else list(ss) return Part( ux, @@ -110,9 +110,9 @@ def clone( self.part_number, self.orientation, self.device, - colors=l(getattr(frm, "colors")), + colors=listify(getattr(frm, "colors")), real_part=real_part if not getattr(self, "real_part", False) else self.real_part, - original_colors=l(getattr(frm, "original_colors")), + original_colors=listify(getattr(frm, "original_colors")), ) def update(self, user_x, user_y, width, height): @@ -183,9 +183,7 @@ def msgs(self, colors, *, acks=False, duration=1, randomize=False, force=True): def _msgs(self, colors, acks=False, duration=1, randomize=False): if self.device.cap.has_matrix: - colors = [ - c if c is not None else None for c in self.reorient(colors, randomize=randomize) - ] + colors = [c if c is not None else None for c in self.reorient(colors, randomize=randomize)] kwargs = {"colors": colors} if duration != 0: @@ -198,9 +196,7 @@ def _msgs(self, colors, acks=False, duration=1, randomize=False): return (msg,) elif self.device.cap.has_multizone: - return MultizoneMessagesMaker( - self.device.serial, self.device.cap, colors, duration=duration - ).msgs + return MultizoneMessagesMaker(self.device.serial, self.device.cap, colors, duration=duration).msgs elif colors: if isinstance(colors[0], tuple): diff --git a/modules/photons_canvas/points/helpers.py b/modules/photons_canvas/points/helpers.py index d7dfac84..6d7ed5c1 100644 --- a/modules/photons_canvas/points/helpers.py +++ b/modules/photons_canvas/points/helpers.py @@ -190,8 +190,8 @@ class Points: @classmethod @_points_bound_cache def cols(kls, bounds): - (l, r), _, _ = bounds - for col in range(l, r): + (left, r), _, _ = bounds + for col in range(left, r): yield kls.col(col, bounds) @classmethod @@ -215,8 +215,8 @@ def count_points(kls, bounds): @classmethod @_points_bound_cache def row(kls, row, bounds): - (l, r), _, _ = bounds - return [(col, row) for col in range(l, r)] + (left, r), _, _ = bounds + return [(col, row) for col in range(left, r)] @classmethod @_points_bound_cache @@ -226,13 +226,13 @@ def col(kls, col, bounds): @classmethod def expand(kls, bounds, amount): - (l, r), (t, b), (w, h) = bounds - return (l - amount, r + amount), (t + amount, b - amount), (w + amount * 2, h + amount * 2) + (left, r), (t, b), (w, h) = bounds + return (left - amount, r + amount), (t + amount, b - amount), (w + amount * 2, h + amount * 2) @classmethod def relative(kls, point, bounds): - (l, _), (t, _), _ = bounds - return point[0] - l, t - point[1] + (left, _), (t, _), _ = bounds + return point[0] - left, t - point[1] @classmethod def bottom_row(kls, bounds): diff --git a/modules/photons_canvas/points/rearrange.py b/modules/photons_canvas/points/rearrange.py index 724a8012..e45c5c03 100644 --- a/modules/photons_canvas/points/rearrange.py +++ b/modules/photons_canvas/points/rearrange.py @@ -12,9 +12,7 @@ def rearrange(self, canvas): class Straight: def rearrange(self, canvas): user_x = 0 - for part in sorted( - canvas.parts, key=lambda p: (p.real_part.user_x, p.device, p.part_number) - ): + for part in sorted(canvas.parts, key=lambda p: (p.real_part.user_x, p.device, p.part_number)): yield part.clone(user_x=user_x, user_y=0) user_x += part.width / 8 diff --git a/modules/photons_canvas/theme.py b/modules/photons_canvas/theme.py index c0c74224..1fd67779 100644 --- a/modules/photons_canvas/theme.py +++ b/modules/photons_canvas/theme.py @@ -4,12 +4,13 @@ import kdtree from delfick_project.norms import Meta, dictobj, sb from photons_app import helpers as hp -from photons_canvas import Canvas -from photons_canvas import point_helpers as php from photons_control.colour import make_hsbk from photons_control.script import FromGenerator from photons_messages import LightMessages +from photons_canvas import Canvas +from photons_canvas import point_helpers as php + log = logging.getLogger("photons_canvas.themes.addon") default_colors = [ @@ -177,9 +178,7 @@ async def gen(reference, sender, **kwargs): for canvas in canvases: Applier(canvas, options.colors).apply() - for msg in canvas.msgs( - options.override_layer, duration=options.duration, acks=True - ): + for msg in canvas.msgs(options.override_layer, duration=options.duration, acks=True): msgs.append(msg) yield msgs diff --git a/modules/photons_control/addon.py b/modules/photons_control/addon.py index 364e7306..3cc02911 100644 --- a/modules/photons_control/addon.py +++ b/modules/photons_control/addon.py @@ -6,9 +6,10 @@ from delfick_project.addons import addon_hook from delfick_project.norms import Meta, sb from photons_app.tasks import task_register as task -from photons_control.device_finder import DeviceFinder from photons_messages import Services +from photons_control.device_finder import DeviceFinder + # Get us our actions for filename in os.listdir(os.path.dirname(__file__)): if not filename.endswith(".py") or filename.startswith("_") or filename.startswith("."): diff --git a/modules/photons_control/attributes.py b/modules/photons_control/attributes.py index c0531986..92fd9b37 100644 --- a/modules/photons_control/attributes.py +++ b/modules/photons_control/attributes.py @@ -4,11 +4,12 @@ from delfick_project.norms import sb from photons_app.errors import BadOption, DeprecatedTask from photons_app.tasks import task_register as task +from photons_messages import LightMessages + from photons_control.multizone import SetZonesEffect from photons_control.planner import Skip from photons_control.script import FromGenerator from photons_control.tile import SetTileEffect -from photons_messages import LightMessages def find_packet(protocol_register, value, prefix): @@ -46,15 +47,11 @@ async def execute_task(self, **kwargs): protocol_register = self.collector.configuration["protocol_register"] if self.artifact is sb.NotSpecified: - raise BadOption( - f"Please specify what you want to get\nUsage: {sys.argv[0]} :attr " - ) + raise BadOption(f"Please specify what you want to get\nUsage: {sys.argv[0]} :attr ") kls = find_packet(protocol_register, self.artifact, "") if kls is None: - raise BadOption( - "Sorry, couldn't a class for this message", prefix="", want=self.artifact - ) + raise BadOption("Sorry, couldn't a class for this message", prefix="", want=self.artifact) extra = self.photons_app.extra_as_json @@ -88,15 +85,11 @@ async def execute_task(self, **kwargs): protocol_register = self.collector.configuration["protocol_register"] if self.artifact is sb.NotSpecified: - raise BadOption( - f"Please specify what you want to get\nUsage: {sys.argv[0]} :attr_actual " - ) + raise BadOption(f"Please specify what you want to get\nUsage: {sys.argv[0]} :attr_actual ") kls = find_packet(protocol_register, self.artifact, "") if kls is None: - raise BadOption( - "Sorry, couldn't a class for this message", prefix="", want=self.artifact - ) + raise BadOption("Sorry, couldn't a class for this message", prefix="", want=self.artifact) extra = self.photons_app.extra_as_json diff --git a/modules/photons_control/clean.py b/modules/photons_control/clean.py index d122a4f7..2185b9b2 100644 --- a/modules/photons_control/clean.py +++ b/modules/photons_control/clean.py @@ -3,9 +3,10 @@ from delfick_project.norms import Meta, sb from photons_app.errors import ProgrammerError from photons_app.tasks import task_register as task +from photons_messages import LightMessages + from photons_control.planner import Skip from photons_control.script import ForCapability -from photons_messages import LightMessages try: import humanize diff --git a/modules/photons_control/colour.py b/modules/photons_control/colour.py index 3c991e06..6fc807e5 100644 --- a/modules/photons_control/colour.py +++ b/modules/photons_control/colour.py @@ -89,7 +89,7 @@ def make_hsbk(specifier): if b is None: b = 1 - elif isinstance(specifier, (list, tuple)): + elif isinstance(specifier, list | tuple): h, s, b, k = 0, 0, 1, 3500 if len(specifier) > 0: h = specifier[0] @@ -299,7 +299,7 @@ def parse_color_component(self, color_string): if regex.endswith("_component"): m = regexes[regex].match(color_string) if m: - func_name = "parse_{0}_component".format(regex.split("_")[1]) + func_name = f"parse_{regex.split('_')[1]}_component" return getattr(self, func_name)((color_string,) + m.groups()) except PhotonsAppError as error: raise InvalidColor("Unable to parse color!", got=color_string, error=error.as_dict()) @@ -376,9 +376,7 @@ def parse_kelvin_component(self, groups): None, 0, None, - self.parse_decimal_string( - groups[1], label="kelvin", minimum=1500, maximum=9000, is_integer=True - ), + self.parse_decimal_string(groups[1], label="kelvin", minimum=1500, maximum=9000, is_integer=True), ] def parse_random_component(self, groups): @@ -528,9 +526,7 @@ def make(kls, effect=None, **kwargs): raise NoSuchEffect(effect=effect) func = getattr(kls, effect) if not getattr(func, "_is_effect", None): - log.warning( - "Trying to get an effect that's on Effect, but isn't an effect\teffect=%s", effect - ) + log.warning("Trying to get an effect that's on Effect, but isn't an effect\teffect=%s", effect) raise NoSuchEffect(effect=effect) return getattr(kls(), effect)(**kwargs) @@ -556,9 +552,7 @@ def pulse( ) @effect - def sine( - self, cycles=1, period=1.0, peak=0.5, transient=1, skew_ratio=sb.NotSpecified, **kwargs - ): + def sine(self, cycles=1, period=1.0, peak=0.5, transient=1, skew_ratio=sb.NotSpecified, **kwargs): """Options to make the light(s) transition to `color` and back in a smooth sine wave""" if skew_ratio is sb.NotSpecified: skew_ratio = peak @@ -576,9 +570,7 @@ def half_sine(self, cycles=1, period=1.0, transient=1, **kwargs): return dict(waveform=Waveform.HALF_SINE, cycles=cycles, transient=transient, period=period) @effect - def triangle( - self, cycles=1, period=1.0, peak=0.5, transient=1, skew_ratio=sb.NotSpecified, **kwargs - ): + def triangle(self, cycles=1, period=1.0, peak=0.5, transient=1, skew_ratio=sb.NotSpecified, **kwargs): """Options to make the light(s) transition to `color` linearly and back""" if skew_ratio is sb.NotSpecified: skew_ratio = peak @@ -596,9 +588,7 @@ def saw(self, cycles=1, period=1.0, transient=1, **kwargs): return dict(waveform=Waveform.SAW, cycles=cycles, transient=transient, period=period) @effect - def breathe( - self, cycles=1, period=1, peak=0.5, transient=1, skew_ratio=sb.NotSpecified, **kwargs - ): + def breathe(self, cycles=1, period=1, peak=0.5, transient=1, skew_ratio=sb.NotSpecified, **kwargs): """ Options to make the light(s) transition to `color` and back in a smooth sine wave diff --git a/modules/photons_control/device_finder.py b/modules/photons_control/device_finder.py index ee59302a..d2eb331d 100644 --- a/modules/photons_control/device_finder.py +++ b/modules/photons_control/device_finder.py @@ -17,10 +17,11 @@ from photons_app.errors import FoundNoDevices, PhotonsAppError, RunErrors from photons_app.special import FoundSerials, SpecialReference from photons_app.tasks import task_register as task -from photons_control.script import FromGenerator from photons_messages import CoreMessages, DeviceMessages, LightMessages from photons_products import Products +from photons_control.script import FromGenerator + log = logging.getLogger("photons_control.device_finder") @@ -105,12 +106,7 @@ async def execute_task(self, **kwargs): async for device in device_finder.info(sender): print(device.serial) - print( - "\n".join( - f" {line}" - for line in json.dumps(device.info, sort_keys=True, indent=" ").split("\n") - ) - ) + print("\n".join(f" {line}" for line in json.dumps(device.info, sort_keys=True, indent=" ").split("\n"))) regexes = {"key_value": re.compile(r"^(?P[\w_]+)=(?P.+)")} @@ -132,7 +128,7 @@ class Collection(dictobj.Spec): name = dictobj.Field(sb.string_spec, default="") def setup(self, *args, **kwargs): - super(Collection, self).setup(*args, **kwargs) + super().setup(*args, **kwargs) self.newest_timestamp = None def add_name(self, timestamp, name): @@ -305,9 +301,7 @@ def from_kwargs(kls, **kwargs): @classmethod def empty(kls, refresh_info=False, refresh_discovery=False): """Create an empty filter""" - return kls.from_options( - {"refresh_info": refresh_info, "refresh_discovery": refresh_discovery} - ) + return kls.from_options({"refresh_info": refresh_info, "refresh_discovery": refresh_discovery}) @classmethod def from_options(kls, options): @@ -516,13 +510,8 @@ class Device(dictobj.Spec): def setup(self, *args, **kwargs): super().setup(*args, **kwargs) - self.point_futures = { - e: hp.ResettableFuture(name=f"Device({self.serial})::setup[point_futures.{e.name}]") - for e in InfoPoints - } - self.point_futures[None] = hp.ResettableFuture( - name=f"Device::setup({self.serial})[point_futures.None]" - ) + self.point_futures = {e: hp.ResettableFuture(name=f"Device({self.serial})::setup[point_futures.{e.name}]") for e in InfoPoints} + self.point_futures[None] = hp.ResettableFuture(name=f"Device::setup({self.serial})[point_futures.None]") self.refreshing = hp.ResettableFuture(name=f"Device({self.serial})::[refreshing]") @hp.memoized_property @@ -573,7 +562,7 @@ def location_id(self): return self.location.uuid def as_dict(self): - actual = super(Device, self).as_dict() + actual = super().as_dict() del actual["group"] del actual["limit"] del actual["location"] @@ -839,14 +828,10 @@ def __init__( self.time_between_queries = time_between_queries final_future = final_future or sender.stop_fut - self.final_future = hp.ChildOfFuture( - final_future, name="DeviceFinderDaemon::__init__[final_future]" - ) + self.final_future = hp.ChildOfFuture(final_future, name="DeviceFinderDaemon::__init__[final_future]") self.own_finder = not bool(finder) - self.finder = finder or Finder( - self.sender, self.final_future, forget_after=forget_after, limit=limit - ) + self.finder = finder or Finder(self.sender, self.final_future, forget_after=forget_after, limit=limit) self.ts = hp.TaskHolder(self.final_future, name="DeviceFinderDaemon::__init__[ts]") self.hp_tick = hp.tick @@ -876,9 +861,7 @@ async def add(streamer): async for device in self.finder.find(refresh_discovery_fltr): await streamer.add_coroutine( - device.refresh_information_loop( - self.sender, self.time_between_queries, self.finder.collections - ), + device.refresh_information_loop(self.sender, self.time_between_queries, self.finder.collections), context=device, ) @@ -924,9 +907,7 @@ def __init__(self, sender, final_future=None, *, forget_after=30, limit=30): self.last_seen = {} self.searched = hp.ResettableFuture(name="Finder::__init__[searched]") self.collections = Collections() - self.final_future = hp.ChildOfFuture( - final_future or self.sender.stop_fut, name="Finder::__init__[final_future]" - ) + self.final_future = hp.ChildOfFuture(final_future or self.sender.stop_fut, name="Finder::__init__[final_future]") async def find(self, fltr): if self.final_future.done(): @@ -946,9 +927,7 @@ async def find(self, fltr): catcher = partial(log_errors, "Failed to determine if device matched filter") - async with hp.ResultStreamer( - self.final_future, name="Finder::find[streamer]", error_catcher=catcher - ) as streamer: + async with hp.ResultStreamer(self.final_future, name="Finder::find[streamer]", error_catcher=catcher) as streamer: for device in removed: await streamer.add_coroutine(device.finish()) @@ -958,9 +937,7 @@ async def find(self, fltr): fut.set_result(True) await streamer.add_task(fut, context=device) else: - await streamer.add_coroutine( - device.matches(self.sender, fltr, self.collections), context=device - ) + await streamer.add_coroutine(device.matches(self.sender, fltr, self.collections), context=device) streamer.no_more_work() @@ -975,15 +952,11 @@ async def info(self, fltr): async def find(): async for device in self.find(fltr): await streamer.add_coroutine( - device.matches( - self.sender, Filter.empty(refresh_info=fltr.refresh_info), self.collections - ), + device.matches(self.sender, Filter.empty(refresh_info=fltr.refresh_info), self.collections), context=device, ) - streamer = hp.ResultStreamer( - self.final_future, error_catcher=catcher, name="Finder::info[streamer]" - ) + streamer = hp.ResultStreamer(self.final_future, error_catcher=catcher, name="Finder::info[streamer]") async with streamer: await streamer.add_coroutine(find(), context=True) diff --git a/modules/photons_control/multizone.py b/modules/photons_control/multizone.py index e1a3bcf0..70b2696b 100644 --- a/modules/photons_control/multizone.py +++ b/modules/photons_control/multizone.py @@ -1,10 +1,6 @@ from delfick_project.norms import sb from photons_app.errors import PhotonsAppError from photons_app.tasks import task_register as task -from photons_control.colour import make_hsbks -from photons_control.planner import NoMessages, Plan, Skip -from photons_control.planner.plans import CapabilityPlan -from photons_control.script import FromGenerator from photons_messages import ( Direction, LightMessages, @@ -12,6 +8,11 @@ MultiZoneMessages, ) +from photons_control.colour import make_hsbks +from photons_control.planner import NoMessages, Plan, Skip +from photons_control.planner.plans import CapabilityPlan +from photons_control.script import FromGenerator + async def find_multizone(reference, sender, **kwargs): """ @@ -312,7 +313,7 @@ async def execute_task(self, **kwargs): async for serial, zones in zones_from_reference(self.reference, sender): print(serial) for zone, color in zones: - print("\tZone {0}: {1}".format(zone, repr(color))) + print(f"\tZone {zone}: {repr(color)}") @task @@ -335,9 +336,7 @@ async def execute_task(self, **kwargs): options = self.photons_app.extra_as_json if "colors" not in options: - raise PhotonsAppError( - """Say something like ` -- '{"colors": [["red", 10], ["blue", 3]]}'`""" - ) + raise PhotonsAppError("""Say something like ` -- '{"colors": [["red", 10], ["blue", 3]]}'`""") await self.target.send(SetZones(**options), self.reference) diff --git a/modules/photons_control/planner/gatherer.py b/modules/photons_control/planner/gatherer.py index a64212fc..ac4b0fbd 100644 --- a/modules/photons_control/planner/gatherer.py +++ b/modules/photons_control/planner/gatherer.py @@ -5,12 +5,13 @@ from photons_app import helpers as hp from photons_app.errors import BadRunWithResults, ProgrammerError, RunErrors -from photons_control.planner.plans import NoMessages, Skip -from photons_control.script import find_serials from photons_transport import catch_errors from photons_transport.errors import FailedToFindDevice from photons_transport.targets.base import Target +from photons_control.planner.plans import NoMessages, Skip +from photons_control.script import find_serials + class PlanInfo: """ @@ -385,9 +386,7 @@ class Gatherer: def __init__(self, sender): if isinstance(sender, Target): - raise ProgrammerError( - "The Gatherer no longer takes in target instances. Please pass in a target.session result instead" - ) + raise ProgrammerError("The Gatherer no longer takes in target instances. Please pass in a target.session result instead") self.sender = sender @hp.memoized_property @@ -415,9 +414,7 @@ async def gather(self, plans, reference, error_catcher=None, **kwargs): with catch_errors(error_catcher) as error_catcher: kwargs["error_catcher"] = error_catcher - serials, missing = await find_serials( - reference, self.sender, timeout=kwargs.get("find_timeout", 20) - ) + serials, missing = await find_serials(reference, self.sender, timeout=kwargs.get("find_timeout", 20)) for serial in missing: hp.add_error(error_catcher, FailedToFindDevice(serial=serial)) @@ -532,9 +529,9 @@ async def _deps(self, plans, serial, **kwargs): for _, plan in sorted(plans.items()): d = plan.dependant_info if d: - for l, p in d.items(): + for item, p in d.items(): uid = str(uuid.uuid4()) - deps[uid] = (plan, l) + deps[uid] = (plan, item) depplan[uid] = p depinfo[plan] = None @@ -545,9 +542,9 @@ async def _deps(self, plans, serial, **kwargs): if completed: for uid, info in i.items(): if uid in deps: - plan, l = deps[uid] + plan, item = deps[uid] if depinfo.get(plan) is None: depinfo[plan] = {} - depinfo[plan][l] = info + depinfo[plan][item] = info return depinfo diff --git a/modules/photons_control/planner/plans.py b/modules/photons_control/planner/plans.py index 58976cf6..de80ed90 100644 --- a/modules/photons_control/planner/plans.py +++ b/modules/photons_control/planner/plans.py @@ -70,19 +70,13 @@ def make_plans(*by_key, **plans): for key in by_key: count[key] += 1 if key in plans: - raise PhotonsAppError( - "Cannot specify plan by label and by Plan class", specified_twice=key - ) + raise PhotonsAppError("Cannot specify plan by label and by Plan class", specified_twice=key) if count[key] > 1: - raise PhotonsAppError( - "Cannot specify plan by label more than once", specified_multiple_times=key - ) + raise PhotonsAppError("Cannot specify plan by label more than once", specified_multiple_times=key) for key in by_key: if key not in plan_by_key: - raise PhotonsAppError( - "No default plan for key", wanted=key, available=list(plan_by_key) - ) + raise PhotonsAppError("No default plan for key", wanted=key, available=list(plan_by_key)) plans[key] = plan_by_key[key]() return plans @@ -474,11 +468,7 @@ def messages(self): return [LightMessages.GetColor()] elif self.zones is Zones.MATRIX: - return [ - TileMessages.Get64( - x=0, y=0, tile_index=0, length=255, width=self.deps["chain"]["width"] - ) - ] + return [TileMessages.Get64(x=0, y=0, tile_index=0, length=255, width=self.deps["chain"]["width"])] else: return [] @@ -547,10 +537,7 @@ def process(self, pkt): for tile in pkt.tile_devices[:amount]: self.chain.append(tile) - self.orientations = [ - nearest_orientation(tile.accel_meas_x, tile.accel_meas_y, tile.accel_meas_z) - for tile in self.chain - ] + self.orientations = [nearest_orientation(tile.accel_meas_x, tile.accel_meas_y, tile.accel_meas_z) for tile in self.chain] return True @@ -579,11 +566,7 @@ async def info(self): parts = [] for i, t in enumerate(self.chain): - parts.append( - cont.Part( - t.user_x, t.user_y, t.width, t.height, i, self.orientations[i], device - ) - ) + parts.append(cont.Part(t.user_x, t.user_y, t.width, t.height, i, self.orientations[i], device)) return parts @@ -608,10 +591,7 @@ def process(self, pkt): return True async def info(self): - colors = [ - [(color.hue, color.saturation, color.brightness, color.kelvin) for color in cs] - for cs in self.deps["colors"] - ] + colors = [[(color.hue, color.saturation, color.brightness, color.kelvin) for color in cs] for cs in self.deps["colors"]] for i, p in enumerate(self.deps["parts"]): p.original_colors = colors[i] @@ -741,9 +721,7 @@ def reorient(self, orientations, random_orientations, index, colors, randomize=F async def info(self): coords_and_sizes = [((t.user_x, t.user_y), (t.width, t.height)) for t in self.chain] - random_orientations = { - i: random.choice(list(self.Orien.__members__.values())) for i in self.orientations - } + random_orientations = {i: random.choice(list(self.Orien.__members__.values())) for i in self.orientations} reorient = partial(self.reorient, self.orientations, random_orientations) reverse_orient = partial(self.reverse_orient, self.orientations) @@ -796,9 +774,7 @@ async def info(self): "cap": cap, "product": product, "firmware": self.firmware, - "state_version": DeviceMessages.StateVersion.Payload.create( - self.version.payload.pack() - ), + "state_version": DeviceMessages.StateVersion.Payload.create(self.version.payload.pack()), } diff --git a/modules/photons_control/script.py b/modules/photons_control/script.py index 35417842..63da4b3e 100644 --- a/modules/photons_control/script.py +++ b/modules/photons_control/script.py @@ -266,16 +266,11 @@ def FromGeneratorPerSerial(inner_gen, **generator_kwargs): """ async def gen(reference, sender, **kwargs): - serials, missing = await find_serials( - reference, sender, timeout=kwargs.get("find_timeout", 20) - ) + serials, missing = await find_serials(reference, sender, timeout=kwargs.get("find_timeout", 20)) for serial in missing: yield FailedToFindDevice(serial=serial) - yield [ - FromGenerator(inner_gen, reference_override=serial, **generator_kwargs) - for serial in serials - ] + yield [FromGenerator(inner_gen, reference_override=serial, **generator_kwargs) for serial in serials] return FromGenerator(gen) @@ -417,9 +412,7 @@ def __init__(self, item, stop_fut, reference, sender, kwargs): self.reference = reference self.sender = sender - self.stop_fut = hp.ChildOfFuture( - stop_fut, name="FromGenerator>Runner::__init__[stop_fut]" - ) + self.stop_fut = hp.ChildOfFuture(stop_fut, name="FromGenerator>Runner::__init__[stop_fut]") self.streamer = hp.ResultStreamer( self.stop_fut, @@ -481,9 +474,7 @@ async def consume(self, gen, streamer): break complete = hp.create_future(name="FromGenerator>Runner::getter[complete]") - await streamer.add_generator( - self.retrieve_all(msg, complete), context=self.Value - ) + await streamer.add_generator(self.retrieve_all(msg, complete), context=self.Value) except StopAsyncIteration: break finally: diff --git a/modules/photons_control/tile.py b/modules/photons_control/tile.py index d4b6dd0d..e7cad6e3 100644 --- a/modules/photons_control/tile.py +++ b/modules/photons_control/tile.py @@ -4,8 +4,6 @@ from photons_app.errors import PhotonsAppError from photons_app.tasks import task_register as task from photons_canvas.orientation import nearest_orientation -from photons_control.colour import make_hsbks -from photons_control.script import FromGenerator from photons_messages import ( LightMessages, TileEffectSkyType, @@ -13,12 +11,12 @@ TileMessages, ) +from photons_control.colour import make_hsbks +from photons_control.script import FromGenerator + log = logging.getLogger(name="photons_control.tiles") -default_tile_palette = [ - {"hue": hue, "brightness": 1, "saturation": 1, "kelvin": 3500} - for hue in [0, 40, 60, 122, 239, 271, 294] -] +default_tile_palette = [{"hue": hue, "brightness": 1, "saturation": 1, "kelvin": 3500} for hue in [0, 40, 60, 122, 239, 271, 294]] default_sky_palette = [] @@ -37,9 +35,7 @@ def tiles_from(state_pkt): def orientations_from(pkt): orientations = {} for i, tile in enumerate(tiles_from(pkt)): - orientations[i] = nearest_orientation( - tile.accel_meas_x, tile.accel_meas_y, tile.accel_meas_z - ) + orientations[i] = nearest_orientation(tile.accel_meas_x, tile.accel_meas_y, tile.accel_meas_z) return orientations @@ -173,16 +169,13 @@ class get_chain_state(task.Task): reference = task.provides_reference(special=True) async def execute_task(self, **kwargs): - async with self.target.session() as sender: plans = sender.make_plans("parts_and_colors") def error(e): log.error(e) - async for serial, _, parts in sender.gatherer.gather( - plans, self.reference, error_catcher=error - ): + async for serial, _, parts in sender.gatherer.gather(plans, self.reference, error_catcher=error): if not parts or not parts[0].device.cap.has_matrix: continue @@ -299,20 +292,12 @@ async def execute_task(self, **kwargs): options["width"] = width if "colors" in options: - spec = sb.listof( - sb.listof( - list_spec( - sb.integer_spec(), sb.float_spec(), sb.float_spec(), sb.integer_spec() - ) - ) - ) + spec = sb.listof(sb.listof(list_spec(sb.integer_spec(), sb.float_spec(), sb.float_spec(), sb.integer_spec()))) colors = spec.normalise(Meta.empty().at("colors"), options["colors"]) row_lengths = [len(row) for row in colors] if len(set(row_lengths)) != 1: - raise PhotonsAppError( - "Please specify colors as a grid with the same length rows", got=row_lengths - ) + raise PhotonsAppError("Please specify colors as a grid with the same length rows", got=row_lengths) cells = [] for row in colors: @@ -335,9 +320,7 @@ async def execute_task(self, **kwargs): options["colors"] = cells else: - raise PhotonsAppError( - "Please specify colors in options after -- as a grid of [h, s, b, k]" - ) + raise PhotonsAppError("Please specify colors in options after -- as a grid of [h, s, b, k]") missing = [] for field in TileMessages.Set64.Payload.Meta.all_names: @@ -368,9 +351,7 @@ async def execute_task(self, **kwargs): positions = sb.listof(sb.listof(sb.float_spec())).normalise(Meta.empty(), extra) if any(len(position) != 2 for position in positions): - raise PhotonsAppError( - "Please enter positions as a list of two item lists of user_x, user_y" - ) + raise PhotonsAppError("Please enter positions as a list of two item lists of user_x, user_y") async def gen(reference, sender, **kwargs): ps = sender.make_plans("capability") diff --git a/modules/photons_control/transform.py b/modules/photons_control/transform.py index 69590430..92c19f98 100644 --- a/modules/photons_control/transform.py +++ b/modules/photons_control/transform.py @@ -1,9 +1,10 @@ from delfick_project.norms import Meta, sb from photons_app.errors import PhotonsAppError from photons_app.tasks import task_register as task +from photons_messages import DeviceMessages, LightMessages + from photons_control.colour import ColourParser from photons_control.script import FromGenerator, Pipeline -from photons_messages import DeviceMessages, LightMessages def PowerToggle(duration=1, group=False, **kwargs): @@ -28,13 +29,9 @@ async def gen(reference, sender, **kwargs): async for pkt in sender(get_power, reference, **kwargs): if pkt | DeviceMessages.StatePower: if pkt.level == 0: - yield LightMessages.SetLightPower( - level=65535, res_required=False, duration=duration, target=pkt.serial - ) + yield LightMessages.SetLightPower(level=65535, res_required=False, duration=duration, target=pkt.serial) else: - yield LightMessages.SetLightPower( - level=0, res_required=False, duration=duration, target=pkt.serial - ) + yield LightMessages.SetLightPower(level=0, res_required=False, duration=duration, target=pkt.serial) return FromGenerator(gen) @@ -112,9 +109,7 @@ def using(kls, state, keep_brightness=False, transition_color=False, **kwargs): return [] if state.get("power") == "on" and has_color_options: - return transformer.power_on_and_color( - state, keep_brightness=keep_brightness, transition_color=transition_color - ) + return transformer.power_on_and_color(state, keep_brightness=keep_brightness, transition_color=transition_color) msgs = [] if "power" in state: @@ -164,7 +159,6 @@ def receiver(serial, current_state): currently_off = current_state.power == 0 if currently_off: - clone = color_message.clone() clone.period = 0 clone.brightness = 0 @@ -185,9 +179,7 @@ def receiver(serial, current_state): set_color.target = serial if currently_off: - set_color.brightness = ( - current_state.brightness if want_brightness is None else want_brightness - ) + set_color.brightness = current_state.brightness if want_brightness is None else want_brightness set_color.set_brightness = True elif want_brightness is not None: set_color.brightness = want_brightness @@ -236,16 +228,12 @@ async def execute_task(self, **kwargs): extra = self.photons_app.extra_as_json extra = sb.dictionary_spec().normalise(Meta.empty(), extra) - transform_options = sb.set_options(transform_options=sb.dictionary_spec()).normalise( - Meta.empty(), extra - )["transform_options"] + transform_options = sb.set_options(transform_options=sb.dictionary_spec()).normalise(Meta.empty(), extra)["transform_options"] msg = Transformer.using(extra, **transform_options) if not msg: - raise PhotonsAppError( - 'Please specify valid options after --. For example ``transform -- \'{"power": "on", "color": "red"}\'``' - ) + raise PhotonsAppError('Please specify valid options after --. For example ``transform -- \'{"power": "on", "color": "red"}\'``') await self.target.send(msg, self.reference) diff --git a/modules/photons_core.py b/modules/photons_core.py index 49e3216e..f9ab6608 100644 --- a/modules/photons_core.py +++ b/modules/photons_core.py @@ -99,9 +99,7 @@ def special_format_field(self, obj, format_spec): name = parts[0] if len(parts) == 1: if name not in os.environ: - raise sys.exit( - f"This script requires you have a '{name}' variable in your environment" - ) + raise sys.exit(f"This script requires you have a '{name}' variable in your environment") return os.environ[name] or " " else: return os.environ.get(name, parts[1]) or " " diff --git a/modules/photons_messages/fields.py b/modules/photons_messages/fields.py index a832c3f5..ea27f14b 100644 --- a/modules/photons_messages/fields.py +++ b/modules/photons_messages/fields.py @@ -2,10 +2,11 @@ from delfick_project.norms import sb from lru import LRU -from photons_messages import enums from photons_protocol.messages import T from photons_protocol.packets import dictobj +from photons_messages import enums, fields + def tile_effect_parameters_for(typ): if typ is enums.TileEffectType.SKY: @@ -20,7 +21,7 @@ def tile_effect_parameters_for(typ): yield ("parameter6", T.Reserved(184)) else: for i in range(8): - yield ("parameter{0}".format(i), T.Reserved(32)) + yield (f"parameter{i}", T.Reserved(32)) def multizone_effect_parameters_for(typ): @@ -28,10 +29,10 @@ def multizone_effect_parameters_for(typ): yield ("parameter1", T.Reserved(32)) yield ("speed_direction", T.Uint32.enum(enums.Direction).default(enums.Direction.RIGHT)) for i in range(6): - yield ("parameter{0}".format(i + 2), T.Reserved(32)) + yield (f"parameter{i + 2}", T.Reserved(32)) else: for i in range(8): - yield ("parameter{0}".format(i), T.Reserved(32)) + yield (f"parameter{i}", T.Reserved(32)) # fmt: off diff --git a/modules/photons_messages/frame.py b/modules/photons_messages/frame.py index 030afc3b..98195e53 100644 --- a/modules/photons_messages/frame.py +++ b/modules/photons_messages/frame.py @@ -192,7 +192,7 @@ class MyMessages(Messages): def maker(name): Payload = type( - "{0}Payload".format(name), + f"{name}Payload", (dictobj.PacketSpec,), { "fields": list(payload_fields), diff --git a/modules/photons_messages/messages.py b/modules/photons_messages/messages.py index 95799de5..9665ee15 100644 --- a/modules/photons_messages/messages.py +++ b/modules/photons_messages/messages.py @@ -1,11 +1,12 @@ import math from delfick_project.norms import sb -from photons_messages import enums, fields -from photons_messages.frame import msg from photons_protocol.messages import Messages, MultiOptions, T from photons_protocol.types import Optional +from photons_messages import enums, fields +from photons_messages.frame import msg + def empty(pkt, attr): return pkt.actual(attr) in (Optional, sb.NotSpecified) diff --git a/modules/photons_products/base.py b/modules/photons_products/base.py index 9e014c26..82ff3659 100644 --- a/modules/photons_products/base.py +++ b/modules/photons_products/base.py @@ -1,4 +1,5 @@ from photons_app.errors import ProgrammerError + from photons_products.enums import Family, VendorRegistry from photons_products.errors import IncompleteProduct @@ -14,8 +15,7 @@ def __init__(self, value): def __repr__(self): upgrades = [ - f"({ma}, {mi}, {becomes}, conditions:({', '.join(repr(c) for c in conditions)}))" - for ma, mi, becomes, conditions in self.upgrades + f"({ma}, {mi}, {becomes}, conditions:({', '.join(repr(c) for c in conditions)}))" for ma, mi, becomes, conditions in self.upgrades ] if upgrades: return f" {' -> '.join(upgrades)}>" @@ -23,11 +23,7 @@ def __repr__(self): return f"" def __eq__(self, other): - return ( - isinstance(other, CapabilityValue) - and self._value == other._value - and self.upgrades == other.upgrades - ) + return isinstance(other, CapabilityValue) and self._value == other._value and self.upgrades == other.upgrades def value(self, cap): value = self._value @@ -41,9 +37,7 @@ def value(self, cap): return value def until(self, major, minor, *conditions, becomes): - if any( - (ma, mi) >= (major, minor) and conditions == conds for ma, mi, _, conds in self.upgrades - ): + if any((ma, mi) >= (major, minor) and conditions == conds for ma, mi, _, conds in self.upgrades): raise ProgrammerError("Each .until must be for a greater version number") self.upgrades.append((major, minor, becomes, conditions)) @@ -115,19 +109,13 @@ def __init__(self, product, firmware_major=0, firmware_minor=0): self.firmware_minor = firmware_minor def __call__(self, firmware_major, firmware_minor): - return self.__class__( - self.product, firmware_major=firmware_major, firmware_minor=firmware_minor - ) + return self.__class__(self.product, firmware_major=firmware_major, firmware_minor=firmware_minor) def __repr__(self): return f"" def __eq__(self, other): - return ( - self.product == other.product - and self.firmware_major == other.firmware_major - and self.firmware_minor == other.firmware_minor - ) + return self.product == other.product and self.firmware_major == other.firmware_major and self.firmware_minor == other.firmware_minor def items(self): for capability in sorted(list(self.Meta.capabilities) + self.Meta.properties): @@ -285,7 +273,7 @@ def __getattr__(self, name): return super().__getattribute__(name) def __getitem__(self, key): - if isinstance(key, (list, tuple)) and len(key) == 2: + if isinstance(key, list | tuple) and len(key) == 2: if key not in self.by_pair: vid, pid = key return make_unknown_product(vid, pid, self.default_capability_kls) diff --git a/modules/photons_products/registry.py b/modules/photons_products/registry.py index 8903d7fc..00a2960b 100644 --- a/modules/photons_products/registry.py +++ b/modules/photons_products/registry.py @@ -106,9 +106,7 @@ class LCM2_A19(lifx.Product): class cap(lifx.Capability): has_color = True - min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until( - 2, 80, becomes=(1500, 9000) - ) + min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until(2, 80, becomes=(1500, 9000)) class LCM2_BR30(lifx.Product): pid = 28 @@ -118,9 +116,7 @@ class LCM2_BR30(lifx.Product): class cap(lifx.Capability): has_color = True - min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until( - 2, 80, becomes=(1500, 9000) - ) + min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until(2, 80, becomes=(1500, 9000)) class LCM2_A19_PLUS(lifx.Product): pid = 29 @@ -131,9 +127,7 @@ class cap(lifx.Capability): has_ir = True has_color = True - min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until( - 2, 80, becomes=(1500, 9000) - ) + min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until(2, 80, becomes=(1500, 9000)) class LCM2_BR30_PLUS(lifx.Product): pid = 30 @@ -144,9 +138,7 @@ class cap(lifx.Capability): has_ir = True has_color = True - min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until( - 2, 80, becomes=(1500, 9000) - ) + min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until(2, 80, becomes=(1500, 9000)) class LCM1_Z(lifx.Product): pid = 31 @@ -168,9 +160,7 @@ class cap(lifx.Capability): zones = Zones.LINEAR has_color = True - min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until( - 2, 80, becomes=(1500, 9000) - ) + min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until(2, 80, becomes=(1500, 9000)) class LCM2_DOWNLIGHT_OL(lifx.Product): pid = 36 @@ -180,9 +170,7 @@ class LCM2_DOWNLIGHT_OL(lifx.Product): class cap(lifx.Capability): has_color = True - min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until( - 2, 80, becomes=(1500, 9000) - ) + min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until(2, 80, becomes=(1500, 9000)) class LCM2_DOWNLIGHT_NL(lifx.Product): pid = 37 @@ -192,9 +180,7 @@ class LCM2_DOWNLIGHT_NL(lifx.Product): class cap(lifx.Capability): has_color = True - min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until( - 2, 80, becomes=(1500, 9000) - ) + min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until(2, 80, becomes=(1500, 9000)) class LCM2_BEAM(lifx.Product): pid = 38 @@ -205,9 +191,7 @@ class cap(lifx.Capability): zones = Zones.LINEAR has_color = True - min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until( - 2, 80, becomes=(1500, 9000) - ) + min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until(2, 80, becomes=(1500, 9000)) class LCM2_DOWNLIGHT_WW_IC4(lifx.Product): pid = 39 @@ -218,9 +202,7 @@ class cap(lifx.Capability): has_color = False has_variable_color_temp = True - min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until( - 2, 80, becomes=(1500, 9000) - ) + min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until(2, 80, becomes=(1500, 9000)) class LCM2_DOWNLIGHT_COLOR_IC4(lifx.Product): pid = 40 @@ -230,9 +212,7 @@ class LCM2_DOWNLIGHT_COLOR_IC4(lifx.Product): class cap(lifx.Capability): has_color = True - min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until( - 2, 80, becomes=(1500, 9000) - ) + min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until(2, 80, becomes=(1500, 9000)) class LCM2_A19_HK(lifx.Product): pid = 43 @@ -242,9 +222,7 @@ class LCM2_A19_HK(lifx.Product): class cap(lifx.Capability): has_color = True - min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until( - 2, 80, becomes=(1500, 9000) - ) + min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until(2, 80, becomes=(1500, 9000)) class LCM2_BR30_HK(lifx.Product): pid = 44 @@ -254,9 +232,7 @@ class LCM2_BR30_HK(lifx.Product): class cap(lifx.Capability): has_color = True - min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until( - 2, 80, becomes=(1500, 9000) - ) + min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until(2, 80, becomes=(1500, 9000)) class LCM2_A19_PLUS_HK(lifx.Product): pid = 45 @@ -267,9 +243,7 @@ class cap(lifx.Capability): has_ir = True has_color = True - min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until( - 2, 80, becomes=(1500, 9000) - ) + min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until(2, 80, becomes=(1500, 9000)) class LCM2_BR30_PLUS_HK(lifx.Product): pid = 46 @@ -280,9 +254,7 @@ class cap(lifx.Capability): has_ir = True has_color = True - min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until( - 2, 80, becomes=(1500, 9000) - ) + min_kelvin, max_kelvin = CapabilityRange((2500, 9000)).until(2, 80, becomes=(1500, 9000)) class LCM3_MINI_COLOR(lifx.Product): pid = 49 @@ -303,9 +275,7 @@ class cap(lifx.Capability): has_color = False has_variable_color_temp = True - min_kelvin, max_kelvin = CapabilityRange((1500, 6500)).until( - 3, 70, becomes=(1500, 9000) - ) + min_kelvin, max_kelvin = CapabilityRange((1500, 6500)).until(3, 70, becomes=(1500, 9000)) class LCM3_MINI_WHITE(lifx.Product): pid = 51 @@ -381,9 +351,7 @@ class cap(lifx.Capability): has_color = False has_variable_color_temp = True - min_kelvin, max_kelvin = CapabilityRange((1500, 6500)).until( - 3, 70, becomes=(1500, 9000) - ) + min_kelvin, max_kelvin = CapabilityRange((1500, 6500)).until(3, 70, becomes=(1500, 9000)) class LCM3_MINI2_WHITE(lifx.Product): pid = 61 diff --git a/modules/photons_protocol/messages.py b/modules/photons_protocol/messages.py index dc8332b8..b71aed0a 100644 --- a/modules/photons_protocol/messages.py +++ b/modules/photons_protocol/messages.py @@ -15,6 +15,7 @@ from textwrap import dedent from bitarray import bitarray + from photons_protocol.errors import BadConversion from photons_protocol.types import MultiOptions, Type @@ -68,9 +69,7 @@ def packet_type_from_bitarray(kls, data): if protocol == 1024: if len(data) < 288: - raise BadConversion( - "Data is too small to be a LIFX packet", need_atleast=36, got=len(data) // 8 - ) + raise BadConversion("Data is too small to be a LIFX packet", need_atleast=36, got=len(data) // 8) ptbts = data[256 : 256 + 16].tobytes() pkt_type = ptbts[0] + (ptbts[1] << 8) @@ -91,9 +90,7 @@ def packet_type_from_bytes(kls, data): if protocol == 1024: if len(data) < 36: - raise BadConversion( - "Data is too small to be a LIFX packet", need_atleast=36, got=len(data) - ) + raise BadConversion("Data is too small to be a LIFX packet", need_atleast=36, got=len(data)) pkt_type = data[32] + (data[33] << 8) return protocol, pkt_type @@ -111,7 +108,7 @@ def sources_for(kls): return except OSError as error: if error.args and error.args[0] == "could not find class definition": - log.warning("Couldn't find source code for kls\tkls={0}".format(kls)) + log.warning(f"Couldn't find source code for kls\tkls={kls}") else: raise else: @@ -125,7 +122,6 @@ def sources_for(kls): in_kls = attr if not line.strip().startswith("#"): - buf.append(line) if buf and in_kls: @@ -174,9 +170,7 @@ def get_packet_type(kls, data, protocol_register): prot = protocol_register.get(protocol) if prot is None: - raise BadConversion( - "Unknown packet protocol", wanted=protocol, available=list(protocol_register) - ) + raise BadConversion("Unknown packet protocol", wanted=protocol, available=list(protocol_register)) Packet, messages_register = prot mkls = None @@ -199,9 +193,7 @@ def unpack_bytes(kls, data, protocol, pkt_type, protocol_register, unknown_ok=Fa prot = protocol_register.get(protocol) if prot is None: - raise BadConversion( - "Unknown packet protocol", wanted=protocol, available=list(protocol_register) - ) + raise BadConversion("Unknown packet protocol", wanted=protocol, available=list(protocol_register)) Packet, messages_register = prot mkls = None diff --git a/modules/photons_protocol/packets.py b/modules/photons_protocol/packets.py index ab4deae0..05f4ef75 100644 --- a/modules/photons_protocol/packets.py +++ b/modules/photons_protocol/packets.py @@ -31,6 +31,7 @@ class MyPacket(dictobj.PacketSpec): from bitarray import bitarray from delfick_project.norms import Meta, dictobj, sb from photons_app.errors import PhotonsAppError, ProgrammerError + from photons_protocol.packing import PacketPacking, val_to_bitarray from photons_protocol.types import Optional from photons_protocol.types import Type as T @@ -170,8 +171,7 @@ def __contains__(self, key): return any(k == key for k in self.Meta.all_names) or any(k == key for k in self.Meta.groups) def keys(self): - for k in dictobj.__iter__(self): - yield k + yield from dictobj.__iter__(self) def actual_items(self): for key in self.keys(): @@ -248,9 +248,7 @@ def __getitem__( if do_spec and key in M.all_names: typ = M.all_field_types_dict[key] - res = object.__getattribute__(self, "getitem_spec")( - typ, key, actual, parent, serial, do_transform, allow_bitarray, unpacking - ) + res = object.__getattribute__(self, "getitem_spec")(typ, key, actual, parent, serial, do_transform, allow_bitarray, unpacking) # Make it so if there isn't a list specified, but you access it, we store the list we return # So that if you modify that list, it modifies on the packet @@ -261,9 +259,7 @@ def __getitem__( return actual - def getitem_spec( - self, typ, key, actual, parent, serial, do_transform, allow_bitarray, unpacking - ): + def getitem_spec(self, typ, key, actual, parent, serial, do_transform, allow_bitarray, unpacking): """ Used by __getitem__ to use the spec on the type to transform the ``actual`` value """ @@ -350,7 +346,7 @@ def _set_group_item(self, key, val): # __getitem__ has the opposite logic to grab this group as is if type(val) not in (bytes, bitarray, str): msg = "Setting non bytes payload on a packet that doesn't know what fields it's payload has" - raise ValueError("{0}\tkey={1}\tgot={2}".format(msg, key, repr(val))) + raise ValueError(f"{msg}\tkey={key}\tgot={repr(val)}") dictobj.__setitem__(self, key, val) return @@ -373,7 +369,7 @@ def _set_group_item(self, key, val): # We're setting a group, we need to get things from the group via items if not hasattr(val, "items"): msg = "Setting a group on a packet must be done with a value that has an items() method" - raise ValueError("{0}\tkey={1}\tgot={2}".format(msg, key, repr(val))) + raise ValueError(f"{msg}\tkey={key}\tgot={repr(val)}") # Set from our value for field, v in val.items(): @@ -493,7 +489,7 @@ def create(kls, *args, **kwargs): if args: val = args[0] - if isinstance(val, (bitarray, bytes)): + if isinstance(val, bitarray | bytes): return PacketPacking.unpack(kls, val) return kls.spec().normalise(Meta.empty(), val) @@ -546,11 +542,11 @@ def __new__(metaname, classname, baseclasses, attrs): if fields is None: msg = "PacketSpecMixin expects a fields attribute on the class or a PacketSpec parent" - raise ProgrammerError("{0}\tcreating={1}".format(msg, classname)) + raise ProgrammerError(f"{msg}\tcreating={classname}") if type(fields) is dict: msg = "PacketSpecMixin expect fields to be a list of tuples, not a dictionary" - raise ProgrammerError("{0}\tcreating={1}".format(msg, classname)) + raise ProgrammerError(f"{msg}\tcreating={classname}") for name, typ in fields: if isinstance(typ, str): @@ -570,15 +566,11 @@ def __new__(metaname, classname, baseclasses, attrs): field_types.append((name, typ)) if len(set(all_names)) != len(all_names): - raise ProgrammerError( - "Duplicated names!\t{0}".format( - [name for name in all_names if all_names.count(name) > 1] - ) - ) + raise ProgrammerError(f"Duplicated names!\t{[name for name in all_names if all_names.count(name) > 1]}") class MetaRepr(type): def __repr__(self): - return "".format(classname) + return f"" Meta = type.__new__( MetaRepr, @@ -603,10 +595,7 @@ def __repr__(self): def dflt(in_group): return Initial if in_group else sb.NotSpecified - attrs["fields"] = [ - (name, partial(dflt, name in groups)) - for name in (list(all_names) + list(groups.keys())) - ] + attrs["fields"] = [(name, partial(dflt, name in groups)) for name in (list(all_names) + list(groups.keys()))] kls = type.__new__(metaname, classname, baseclasses, attrs) @@ -615,11 +604,7 @@ def dflt(in_group): if hasattr(kls, field): already_attributes.append(field) if already_attributes: - raise ProgrammerError( - "Can't override attributes with fields\talready_attributes={0}".format( - sorted(already_attributes) - ) - ) + raise ProgrammerError(f"Can't override attributes with fields\talready_attributes={sorted(already_attributes)}") return kls diff --git a/modules/photons_protocol/packing.py b/modules/photons_protocol/packing.py index 4c6480c9..89b90e2f 100644 --- a/modules/photons_protocol/packing.py +++ b/modules/photons_protocol/packing.py @@ -3,6 +3,7 @@ from bitarray import bitarray from delfick_project.norms import dictobj, sb + from photons_protocol.errors import BadConversion from photons_protocol.types import Optional @@ -118,9 +119,7 @@ def to_bitarray(self): group=self.group, field=self.name, ) - return ( - bitarray("0", endian="little") if val is False else bitarray("1", endian="little") - ) + return bitarray("0", endian="little") if val is False else bitarray("1", endian="little") else: b = bitarray(endian="little") @@ -173,9 +172,7 @@ def fields_in(kls, pkt, parent, serial): number = number(pkt) if len(val) != number: - raise BadConversion( - "Expected correct number of items", name=name, found=len(val), want=number - ) + raise BadConversion("Expected correct number of items", name=name, found=len(val), want=number) for v in val: yield FieldInfo(name, typ, v, size_bits, group) @@ -250,9 +247,7 @@ def pack(kls, pkt, payload=None, parent=None, serial=None): if getattr(pkt, "parent_packet", False) and pkt.Meta.field_types: name, typ = pkt.Meta.field_types[-1] if getattr(typ, "message_type", None) == 0: - final += val_to_bitarray( - payload or pkt[name], doing="Adding payload when packing a packet" - ) + final += val_to_bitarray(payload or pkt[name], doing="Adding payload when packing a packet") return final diff --git a/modules/photons_protocol/types.py b/modules/photons_protocol/types.py index 7d387cad..f425da75 100644 --- a/modules/photons_protocol/types.py +++ b/modules/photons_protocol/types.py @@ -11,6 +11,7 @@ from bitarray import bitarray from delfick_project.norms import sb from photons_app.errors import ProgrammerError + from photons_protocol.errors import BadConversion, BadSpecValue log = logging.getLogger("photons_protocol.packets.builder") @@ -220,9 +221,7 @@ def spec(self, pkt, unpacking=False, transform=True, multiple=True): * ``(list, str, ",")`` * json """ - spec = self._maybe_transform_spec( - pkt, self._spec(pkt, unpacking=unpacking), unpacking, transform=transform - ) + spec = self._maybe_transform_spec(pkt, self._spec(pkt, unpacking=unpacking), unpacking, transform=transform) if self._allow_callable: spec = callable_spec(spec) @@ -446,9 +445,7 @@ def unpack_bytes(self, meta, val, kls, number): def unpack_list(self, meta, val, kls, number): if len(val) > number: - raise BadSpecValue( - "Expected correct number of items", meta=meta, got=len(val), want=number - ) + raise BadSpecValue("Expected correct number of items", meta=meta, got=len(val), want=number) kls = self.kls if kls and not isinstance(kls, type): @@ -472,7 +469,7 @@ def val_to_kls(self, kls, meta, val): if isinstance(val, kls): return val - elif val is sb.NotSpecified or isinstance(val, (bytes, bitarray)): + elif val is sb.NotSpecified or isinstance(val, bytes | bitarray): if val is sb.NotSpecified: val = b"" return kls.create(self.spec.normalise(meta, val)) @@ -506,9 +503,7 @@ def pack(self, meta, val): number = self.number if len(val) > number: - raise BadSpecValue( - "Expected correct number of items", meta=meta, got=len(val), want=number - ) + raise BadSpecValue("Expected correct number of items", meta=meta, got=len(val), want=number) kls = self.kls if kls and not isinstance(kls, type): @@ -565,17 +560,13 @@ def normalise(self, meta, val): elif val is sb.NotSpecified: return self.kls.create() else: - raise BadSpecValue( - "Expected to unpack bytes", found=val, transforming_into=self.kls - ) + raise BadSpecValue("Expected to unpack bytes", found=val, transforming_into=self.kls) else: if type(val) not in (bytes, bitarray): try: fields = sb.dictionary_spec().normalise(meta, val) except BadSpecValue as error: - raise BadSpecValue( - "Sorry, dynamic fields only supports a dictionary of values", error=error - ) + raise BadSpecValue("Sorry, dynamic fields only supports a dictionary of values", error=error) else: val = self.kls.create(fields).pack() @@ -625,9 +616,7 @@ def normalise_filled(self, meta, val): val = sb.string_spec().normalise(meta, val) m = regexes["version_number"].match(val) if not m: - raise BadSpecValue( - r"Expected version string to match (\d+.\d+)", wanted=val, meta=meta - ) + raise BadSpecValue(r"Expected version string to match (\d+.\d+)", wanted=val, meta=meta) groups = m.groupdict() major = int(groups["major"]) @@ -642,9 +631,7 @@ class integer_spec(sb.Spec): Take into account whether we have ``enum`` or ``bitmask`` and ``allow_float`` """ - def setup( - self, pkt, enum, bitmask, unpacking=False, allow_float=False, unknown_enum_values=False - ): + def setup(self, pkt, enum, bitmask, unpacking=False, allow_float=False, unknown_enum_values=False): self.pkt = pkt self.enum = enum self.bitmask = bitmask @@ -676,9 +663,7 @@ def normalise_filled(self, meta, val): kwargs = dict(unpacking=self.unpacking, allow_unknown=self.unknown_enum_values) return enum_spec(self.pkt, self.enum, **kwargs).normalise(meta, val) else: - return bitmask_spec(self.pkt, self.bitmask, unpacking=self.unpacking).normalise( - meta, val - ) + return bitmask_spec(self.pkt, self.bitmask, unpacking=self.unpacking).normalise(meta, val) class bitmask_spec(sb.Spec): @@ -748,17 +733,13 @@ def determine_bitmask(self): try: if not issubclass(bitmask, enum.Enum): - raise ProgrammerError("Bitmask is not an enum! got {0}".format(repr(bitmask))) + raise ProgrammerError(f"Bitmask is not an enum! got {repr(bitmask)}") except TypeError: - raise ProgrammerError("Bitmask is not an enum! got {0}".format(repr(bitmask))) + raise ProgrammerError(f"Bitmask is not an enum! got {repr(bitmask)}") for name, member in bitmask.__members__.items(): if member.value == 0: - raise ProgrammerError( - "A bitmask with a zero value item makes no sense: {0} in {1}".format( - name, repr(bitmask) - ) - ) + raise ProgrammerError(f"A bitmask with a zero value item makes no sense: {name} in {repr(bitmask)}") return bitmask @@ -790,9 +771,7 @@ def unpack(self, bitmask, meta, val): break if not found: - raise BadConversion( - "Can't convert value into value from mask", val=v, wanted=bitmask - ) + raise BadConversion("Can't convert value into value from mask", val=v, wanted=bitmask) return set(result) @@ -859,9 +838,7 @@ def unpack(self, em, meta, val): if isinstance(val, em): return val elif isinstance(val, enum.Enum): - raise BadConversion( - "Can't convert value of wrong Enum", val=val, wanted=em, got=type(val), meta=meta - ) + raise BadConversion("Can't convert value of wrong Enum", val=val, wanted=em, got=type(val), meta=meta) available = [] for name, member in em.__members__.items(): @@ -907,13 +884,9 @@ def pack(self, em, meta, val): return int(m["value"]) if isinstance(val, enum.Enum): - raise BadConversion( - "Can't convert value of wrong Enum", val=val, wanted=em, got=type(val), meta=meta - ) + raise BadConversion("Can't convert value of wrong Enum", val=val, wanted=em, got=type(val), meta=meta) else: - raise BadConversion( - "Value wasn't a valid enum value", val=val, available=available, meta=meta - ) + raise BadConversion("Value wasn't a valid enum value", val=val, available=available, meta=meta) def determine_enum(self): """ @@ -929,9 +902,9 @@ def determine_enum(self): try: if not issubclass(em, enum.Enum): - raise ProgrammerError("Enum is not an enum! got {0}".format(repr(em))) + raise ProgrammerError(f"Enum is not an enum! got {repr(em)}") except TypeError: - raise ProgrammerError("Enum is not an enum! got {0}".format(repr(em))) + raise ProgrammerError(f"Enum is not an enum! got {repr(em)}") return em @@ -1032,17 +1005,13 @@ def normalise_filled(self, meta, val): if type(val) is bitarray: val = val.tobytes() if type(val) is bytes: - val = bytes_as_string_spec(self.pkt, self.size_bits, self.unpacking).normalise( - meta, val - ) + val = bytes_as_string_spec(self.pkt, self.size_bits, self.unpacking).normalise(meta, val) if type(val) is str: return val.split(",") else: if type(val) is list: val = ",".join(val) - return bytes_as_string_spec(self.pkt, self.size_bits, self.unpacking).normalise( - meta, val - ) + return bytes_as_string_spec(self.pkt, self.size_bits, self.unpacking).normalise(meta, val) class bytes_spec(sb.Spec): @@ -1104,9 +1073,7 @@ def to_bitarray(self, meta, val): try: b.frombytes(binascii.unhexlify(val)) except binascii.Error as error: - raise BadConversion( - "Failed to turn str into bytes", meta=meta, val=val, error=error - ) + raise BadConversion("Failed to turn str into bytes", meta=meta, val=val, error=error) else: try: b.frombytes(val) @@ -1148,16 +1115,10 @@ def normalise_filled(self, meta, val): try: return val.decode() except UnicodeDecodeError as error: - log.warning( - __import__("photons_app").helpers.lc( - "Can't turn bytes into string, so just returning bytes", error=error - ) - ) + log.warning(__import__("photons_app").helpers.lc("Can't turn bytes into string, so just returning bytes", error=error)) return val except Exception as error: - raise BadSpecValue( - "String before the null byte could not be decoded", val=val, erorr=error - ) + raise BadSpecValue("String before the null byte could not be decoded", val=val, erorr=error) else: if type(val) is str: val = val.encode() @@ -1171,16 +1132,12 @@ class float_spec(sb.Spec): def normalise_filled(self, meta, val): if type(val) is bool: - raise BadSpecValue( - "Converting a boolean into a float makes no sense", got=val, meta=meta - ) + raise BadSpecValue("Converting a boolean into a float makes no sense", got=val, meta=meta) try: return float(val) except (TypeError, ValueError) as error: - raise BadSpecValue( - "Failed to convert value into a float", got=val, error=error, meta=meta - ) + raise BadSpecValue("Failed to convert value into a float", got=val, error=error, meta=meta) class MultiOptions: diff --git a/modules/photons_pytest.py b/modules/photons_pytest.py index 4f219f5e..d0570c66 100644 --- a/modules/photons_pytest.py +++ b/modules/photons_pytest.py @@ -20,7 +20,7 @@ try: import pytest -except: +except ImportError: class FakePytest: class fixture: @@ -124,10 +124,7 @@ def pytest_cmdline_parse(pluginmanager, args): "-W", "ignore:Using or importing the ABCs:DeprecationWarning", "-W", - ( - "ignore:websockets.connection was renamed to websockets.protocol" - " and Connection was renamed to Protocol:DeprecationWarning" - ), + ("ignore:websockets.connection was renamed to websockets.protocol" " and Connection was renamed to Protocol:DeprecationWarning"), "-W", "ignore:ServerConnection was renamed to ServerProtocol:DeprecationWarning", "--log-level=INFO", @@ -545,17 +542,11 @@ def indented(v): @pytest.helpers.register def AsyncMock(*args, **kwargs): - if sys.version_info < (3, 8): - return __import__("mock").AsyncMock(*args, **kwargs) - else: - return mock.AsyncMock(*args, **kwargs) + return mock.AsyncMock(*args, **kwargs) @pytest.helpers.register def MagicAsyncMock(*args, **kwargs): - if sys.version_info < (3, 8): - return __import__("mock").MagicMock(*args, **kwargs) - else: - return mock.MagicMock(*args, **kwargs) + return mock.MagicMock(*args, **kwargs) @pytest.helpers.register def child_future_of(fut): @@ -646,9 +637,7 @@ def assertFutCallbacks(fut, *cbs, exhaustive=False): if Context is not None: if callbacks: assert len(callbacks) == 1, f"Expect only one context callback: got {callbacks}" - assert isinstance( - callbacks[0], Context - ), f"Expected just a context callback: got {callbacks}" + assert isinstance(callbacks[0], Context), f"Expected just a context callback: got {callbacks}" else: assert callbacks == [], f"Expected no callbacks, got {callbacks}" @@ -705,7 +694,6 @@ def print_packet_difference(one, two, ignore_unspecified_expected=True): print(f" GOT : {one.__class__}") print(f" WANT: {two.__class__}") if one.__class__ == two.__class__: - dictc = json.loads(json.dumps(dict(one), default=reprer)) dictw = json.loads(json.dumps(dict(two), default=reprer)) for k, v in dictc.items(): @@ -720,20 +708,14 @@ def print_packet_difference(one, two, ignore_unspecified_expected=True): if isinstance(v, list) and isinstance(dictw[k], list): for i, (g, w) in enumerate(zip(v, dictw[k])): if g != w: - print( - f" = || key {k}[{i}]\n = || GOT -> {g}\n = || WANT-> {w}" - ) + print(f" = || key {k}[{i}]\n = || GOT -> {g}\n = || WANT-> {w}") else: Reserved = __import__("photons_protocol.types").types.Type.Reserved if isinstance(one.Meta.all_field_types_dict[k], Reserved.__class__): - if v is sb.NotSpecified or ( - isinstance(v, str) and set(list(v)) == set(["0"]) - ): + if v is sb.NotSpecified or (isinstance(v, str) and set(list(v)) == set(["0"])): continue - print( - f" = || key {k}\n = || GOT -> {v}\n = || WANT-> {dictw[k]}" - ) + print(f" = || key {k}\n = || GOT -> {v}\n = || WANT-> {dictw[k]}") different = True for k in dictw: diff --git a/modules/photons_transport/__init__.py b/modules/photons_transport/__init__.py index 57ec1ccc..684f92e3 100644 --- a/modules/photons_transport/__init__.py +++ b/modules/photons_transport/__init__.py @@ -12,6 +12,7 @@ from photons_app import helpers as hp from photons_app.errors import PhotonsAppError, RunErrors, UserQuit + from photons_transport.errors import StopPacketStream from photons_transport.retry_options import Gaps, RetryTicker @@ -30,7 +31,7 @@ def catch_errors(error_catcher=None): except StopPacketStream: pass except Exception as error: - if not isinstance(error, (PhotonsAppError, UserQuit)): + if not isinstance(error, PhotonsAppError | UserQuit): log.exception(error) hp.add_error(error_catcher, error) diff --git a/modules/photons_transport/addon.py b/modules/photons_transport/addon.py index 53493dd8..ed1d39dc 100644 --- a/modules/photons_transport/addon.py +++ b/modules/photons_transport/addon.py @@ -1,5 +1,6 @@ from delfick_project.addons import addon_hook from photons_app.formatter import MergedOptionStringFormatter + from photons_transport.session.discovery_options import DiscoveryOptions from photons_transport.targets import LanTarget @@ -12,9 +13,5 @@ def __lifx__(collector, *args, **kwargs): @addon_hook(post_register=True) def __lifx_post__(collector, **kwargs): - collector.configuration["target_register"].register_type( - "lan", LanTarget.FieldSpec(formatter=MergedOptionStringFormatter) - ) - collector.register_converters( - {"discovery_options": DiscoveryOptions.FieldSpec(formatter=MergedOptionStringFormatter)} - ) + collector.configuration["target_register"].register_type("lan", LanTarget.FieldSpec(formatter=MergedOptionStringFormatter)) + collector.register_converters({"discovery_options": DiscoveryOptions.FieldSpec(formatter=MergedOptionStringFormatter)}) diff --git a/modules/photons_transport/comms/base.py b/modules/photons_transport/comms/base.py index 364322f8..7efe8ed9 100644 --- a/modules/photons_transport/comms/base.py +++ b/modules/photons_transport/comms/base.py @@ -9,6 +9,7 @@ from photons_app.errors import BadRunWithResults, FoundNoDevices, RunErrors, TimedOut from photons_protocol.messages import Messages from photons_protocol.packets import Information + from photons_transport import catch_errors from photons_transport.comms.receiver import Receiver from photons_transport.comms.writer import Writer @@ -106,12 +107,7 @@ def __iter__(self): return iter(self.found) def __repr__(self): - services = json.dumps( - { - binascii.hexlify(t).decode(): ",".join(repr(s) for s in services.keys()) - for t, services in self.found.items() - } - ) + services = json.dumps({binascii.hexlify(t).decode(): ",".join(repr(s) for s in services.keys()) for t, services in self.found.items()}) return f"" @@ -195,13 +191,9 @@ def __init__(self, target): self.transport_target = target self.found = Found() - self.stop_fut = hp.ChildOfFuture( - self.transport_target.final_future, name=f"{type(self).__name__}.__init__|stop_fut|" - ) + self.stop_fut = hp.ChildOfFuture(self.transport_target.final_future, name=f"{type(self).__name__}.__init__|stop_fut|") self.receiver = Receiver() - self.received_data_tasks = hp.TaskHolder( - self.stop_fut, name=f"{type(self).__name__}.__init__|received_data_tasks|" - ) + self.received_data_tasks = hp.TaskHolder(self.stop_fut, name=f"{type(self).__name__}.__init__|received_data_tasks|") self.make_plans = __import__("photons_control.planner").planner.make_plans @@ -254,9 +246,7 @@ async def forget(self, serial): except asyncio.CancelledError: raise except Exception as error: - log.exception( - hp.lc("Failed to close transport", service=service, error=error, serial=serial) - ) + log.exception(hp.lc("Failed to close transport", service=service, error=error, serial=serial)) async def add_service(self, serial, service, **kwargs): new = await self.make_transport(serial, service, kwargs) @@ -291,9 +281,7 @@ async def find_devices(self, *, ignore_lost=False, raise_on_none=False, **kwargs found, _ = await self.find_specific_serials(None, **kwargs) return found - async def find_specific_serials( - self, serials, ignore_lost=False, raise_on_none=False, **kwargs - ): + async def find_specific_serials(self, serials, ignore_lost=False, raise_on_none=False, **kwargs): kwargs["ignore_lost"] = ignore_lost kwargs["raise_on_none"] = raise_on_none found = await self._find_specific_serials(serials, **kwargs) @@ -304,9 +292,7 @@ async def find_specific_serials( return found, missing - async def _find_specific_serials( - self, serials, ignore_lost=False, raise_on_none=False, timeout=60, **kwargs - ): + async def _find_specific_serials(self, serials, ignore_lost=False, raise_on_none=False, timeout=60, **kwargs): found_now = await self._do_search(serials, timeout, **kwargs) if not ignore_lost: @@ -340,13 +326,8 @@ async def broadcast(self, packet, broadcast, **kwargs): kwargs["is_broadcast"] = True return await self.send_single(packet, **kwargs) - async def send_single( - self, original, packet, *, timeout, no_retry=False, broadcast=False, connect_timeout=10 - ): - - transport, is_broadcast = await self._transport_for_send( - None, packet, original, broadcast, connect_timeout - ) + async def send_single(self, original, packet, *, timeout, no_retry=False, broadcast=False, connect_timeout=10): + transport, is_broadcast = await self._transport_for_send(None, packet, original, broadcast, connect_timeout) retry_gaps = self.retry_gaps(original, transport) @@ -384,14 +365,10 @@ async def wait_for_remainders(tick_fut, streamer_fut): name=f"SendPacket({original.pkt_type, packet.serial})::send_single[streamer_fut]", ) - retry_ticker = retry_gaps.retry_ticker( - name=f"{type(self).__name__}({type(transport).__name__})::retry_ticker" - ) + retry_ticker = retry_gaps.retry_ticker(name=f"{type(self).__name__}({type(transport).__name__})::retry_ticker") with tick_fut, streamer_fut: - async with hp.ResultStreamer( - streamer_fut, name=f"SendPacket({original.pkt_type, packet.serial}).send_single" - ) as streamer: + async with hp.ResultStreamer(streamer_fut, name=f"SendPacket({original.pkt_type, packet.serial}).send_single") as streamer: await streamer.add_generator( retry_ticker.tick(tick_fut, timeout), context="tick", @@ -449,9 +426,7 @@ async def received_data(self, data, addr, allow_zero=False): try: protocol_register = self.transport_target.protocol_register - protocol, pkt_type, Packet, PacketKls, data = Messages.get_packet_type( - data, protocol_register - ) + protocol, pkt_type, Packet, PacketKls, data = Messages.get_packet_type(data, protocol_register) if protocol == 1024 and pkt_type == 45: if isinstance(data, bytes): diff --git a/modules/photons_transport/comms/receiver.py b/modules/photons_transport/comms/receiver.py index eb96691a..08f29fcc 100644 --- a/modules/photons_transport/comms/receiver.py +++ b/modules/photons_transport/comms/receiver.py @@ -61,9 +61,7 @@ async def recv(self, pkt, addr, allow_zero=False): # But gets a reply from multiple of these requests # The first one back will unregister the future # And so there's nothing to resolve with this newly received data - log.debug( - hp.lc("Received a message that wasn't expected", key=key, serial=pkt.serial) - ) + log.debug(hp.lc("Received a message that wasn't expected", key=key, serial=pkt.serial)) return if key not in self.results: diff --git a/modules/photons_transport/comms/result.py b/modules/photons_transport/comms/result.py index b818c714..47da5cb5 100644 --- a/modules/photons_transport/comms/result.py +++ b/modules/photons_transport/comms/result.py @@ -81,9 +81,7 @@ def schedule_finisher(self, attr): result """ current = getattr(self, attr) - hp.get_event_loop().call_later( - self.retry_gaps.finish_multi_gap, self.maybe_finish, current, attr - ) + hp.get_event_loop().call_later(self.retry_gaps.finish_multi_gap, self.maybe_finish, current, attr) def maybe_finish(self, last, attr): """ diff --git a/modules/photons_transport/comms/writer.py b/modules/photons_transport/comms/writer.py index 89164f3a..92b0eea2 100644 --- a/modules/photons_transport/comms/writer.py +++ b/modules/photons_transport/comms/writer.py @@ -2,6 +2,7 @@ import logging from photons_app import helpers as hp + from photons_transport.comms.result import Result log = logging.getLogger("photons_transport.comms.writer") diff --git a/modules/photons_transport/session/discovery_options.py b/modules/photons_transport/session/discovery_options.py index 6d4f6069..971f3ac7 100644 --- a/modules/photons_transport/session/discovery_options.py +++ b/modules/photons_transport/session/discovery_options.py @@ -72,9 +72,7 @@ def expand(self, meta, val): options = {"host": options, "port": 56700} elif isinstance(options, list): if len(options) not in (1, 2): - raise BadSpecValue( - "A list must be [host] or [host, port]", got=options, meta=meta.at(service) - ) + raise BadSpecValue("A list must be [host] or [host, port]", got=options, meta=meta.at(service)) if len(options) == 1: options = {"host": options[0], "port": 56700} else: @@ -91,9 +89,7 @@ def normalise_filled(self, meta, val): if not val.startswith("d073d5"): raise BadSpecValue("serials must start with d073d5", got=val, meta=meta) if len(val) != 12: - raise BadSpecValue( - "serials must be 12 characters long, like d073d5001337", got=val, meta=meta - ) + raise BadSpecValue("serials must be 12 characters long, like d073d5001337", got=val, meta=meta) try: binascii.unhexlify(val) diff --git a/modules/photons_transport/session/network.py b/modules/photons_transport/session/network.py index 347fba2e..d53f8638 100644 --- a/modules/photons_transport/session/network.py +++ b/modules/photons_transport/session/network.py @@ -3,6 +3,7 @@ from photons_app import helpers as hp from photons_messages import DiscoveryMessages, Services + from photons_transport.comms.base import Communication from photons_transport.errors import InvalidBroadcast, NoDesiredService, UnknownService from photons_transport.retry_options import RetryTicker @@ -26,9 +27,7 @@ async def finish(self, exc_typ=None, exc=None, tb=None): await super().finish(exc_typ, exc, tb) ts = [hp.async_as_background(t.close()) for t in self.broadcast_transports.values()] - await hp.cancel_futures_and_wait( - *ts, name=f"{type(self).__name__}::finish[wait_for_broadcast_transports]" - ) + await hp.cancel_futures_and_wait(*ts, name=f"{type(self).__name__}::finish[wait_for_broadcast_transports]") for t in ts: if not t.cancelled(): @@ -66,9 +65,7 @@ async def _do_search(self, serials, timeout, **kwargs): log.debug("Using hard coded discovery information") return await discovery_options.discover(self.add_service) - get_service = DiscoveryMessages.GetService( - target=None, tagged=True, addressable=True, res_required=True, ack_required=False - ) + get_service = DiscoveryMessages.GetService(target=None, tagged=True, addressable=True, res_required=True, ack_required=False) kwargs["no_retry"] = True kwargs["broadcast"] = kwargs.get("broadcast", True) or True @@ -95,9 +92,9 @@ async def _do_search(self, serials, timeout, **kwargs): async def _search_retry_iterator(self, end_after): timeouts = [(0.6, 1.8), (1, 2), (2, 6), (4, 10), (5, 20)] - async for info in RetryTicker( - timeouts=timeouts, name=f"{type(self).__name__}::_search_retry_iterator[retry_ticker]" - ).tick(self.stop_fut, end_after): + async for info in RetryTicker(timeouts=timeouts, name=f"{type(self).__name__}::_search_retry_iterator[retry_ticker]").tick( + self.stop_fut, end_after + ): yield info async def make_transport(self, serial, service, kwargs): @@ -116,9 +113,7 @@ async def make_broadcast_transport(self, broadcast): if isinstance(broadcast, str): broadcast = (broadcast, 56700) - if type(broadcast) is not str and not ( - isinstance(broadcast, tuple) and len(broadcast) == 2 - ): + if type(broadcast) is not str and not (isinstance(broadcast, tuple) and len(broadcast) == 2): raise InvalidBroadcast("Expect a string or (host, port) tuple", got=broadcast) if broadcast in self.broadcast_transports: diff --git a/modules/photons_transport/targets/__init__.py b/modules/photons_transport/targets/__init__.py index 427b5e19..84670c3b 100644 --- a/modules/photons_transport/targets/__init__.py +++ b/modules/photons_transport/targets/__init__.py @@ -4,6 +4,7 @@ """ from delfick_project.norms import dictobj, sb + from photons_transport.retry_options import Gaps from photons_transport.session.discovery_options import discovery_options_spec from photons_transport.session.network import NetworkSession diff --git a/modules/photons_transport/targets/base.py b/modules/photons_transport/targets/base.py index edd86193..649b5e85 100644 --- a/modules/photons_transport/targets/base.py +++ b/modules/photons_transport/targets/base.py @@ -4,6 +4,7 @@ from photons_app import helpers as hp from photons_app.formatter import MergedOptionStringFormatter from photons_control.script import FromGenerator + from photons_transport.targets.item import Item from photons_transport.targets.script import ScriptRunner diff --git a/modules/photons_transport/targets/item.py b/modules/photons_transport/targets/item.py index e753105a..d896da66 100644 --- a/modules/photons_transport/targets/item.py +++ b/modules/photons_transport/targets/item.py @@ -5,6 +5,7 @@ from photons_app import helpers as hp from photons_app.errors import DevicesNotFound, TimedOut from photons_app.special import SpecialReference + from photons_transport import catch_errors log = logging.getLogger("photons_transport.targets.item") @@ -130,9 +131,7 @@ async def run(self, reference, sender, **kwargs): broadcast = kwargs.get("broadcast", False) find_timeout = kwargs.get("find_timeout", 20) - found, serials, missing = await self._find( - kwargs.get("found"), reference, sender, broadcast, find_timeout - ) + found, serials, missing = await self._find(kwargs.get("found"), reference, sender, broadcast, find_timeout) # Work out what and where to send # All the packets from here have targets on them @@ -146,9 +145,7 @@ async def run(self, reference, sender, **kwargs): if missing is None and not broadcast: accept_found = kwargs.get("accept_found") or broadcast - found, missing = await self.search( - sender, found, accept_found, packets, broadcast, find_timeout, kwargs - ) + found, missing = await self.search(sender, found, accept_found, packets, broadcast, find_timeout, kwargs) # Complain if we care about having all wanted devices if not broadcast and kwargs.get("require_all_devices") and missing: @@ -222,9 +219,7 @@ def make_packets(self, sender, serials): packets.append((original, clone)) else: clone = p.clone() - clone.update( - dict(source=choose_source(clone, sender.source), sequence=sender.seq(p.serial)) - ) + clone.update(dict(source=choose_source(clone, sender.source), sequence=sender.seq(p.serial))) packets.append((original, clone)) return packets @@ -251,15 +246,11 @@ async def write_messages(self, sender, packets, kwargs): error_catcher = kwargs["error_catcher"] - async with hp.ResultStreamer( - sender.stop_fut, error_catcher=silence_errors, name="Item::write_messages[streamer]" - ) as streamer: + async with hp.ResultStreamer(sender.stop_fut, error_catcher=silence_errors, name="Item::write_messages[streamer]") as streamer: count = 0 for original, packet in packets: count += 1 - await streamer.add_coroutine( - self.do_send(sender, original, packet, kwargs), context=packet - ) + await streamer.add_coroutine(self.do_send(sender, original, packet, kwargs), context=packet) streamer.no_more_work() diff --git a/modules/photons_transport/transports/base.py b/modules/photons_transport/transports/base.py index 8617d113..377d7626 100644 --- a/modules/photons_transport/transports/base.py +++ b/modules/photons_transport/transports/base.py @@ -29,9 +29,7 @@ async def spawn(self, packet, *, timeout=10, create=True): return None if self.transport is None: - self.transport = hp.create_future( - name=f"Transport::{self.session.__class__.__name__}::spawn[transport]" - ) + self.transport = hp.create_future(name=f"Transport::{self.session.__class__.__name__}::spawn[transport]") t = hp.async_as_background(self.spawn_transport(timeout)) t.add_done_callback(hp.transfer_result(self.transport)) @@ -39,9 +37,7 @@ async def spawn(self, packet, *, timeout=10, create=True): async def close(self): if self.transport: - await hp.wait_for_all_futures( - self.transport, name=f"Transport::{self.session.__class__.__name__}::close" - ) + await hp.wait_for_all_futures(self.transport, name=f"Transport::{self.session.__class__.__name__}::close") t = self.transport self.transport = None diff --git a/modules/photons_transport/transports/socket.py b/modules/photons_transport/transports/socket.py index 5a2d69f7..e00f3f49 100644 --- a/modules/photons_transport/transports/socket.py +++ b/modules/photons_transport/transports/socket.py @@ -1,6 +1,7 @@ import logging from photons_app import helpers as hp + from photons_transport.transports.base import Transport log = logging.getLogger("photons_transport.transports.socket") @@ -40,11 +41,7 @@ def clone_for(self, session): return self.__class__(session, self.host, self.port, serial=self.serial) def __eq__(self, other): - return ( - isinstance(other, self.__class__) - and other.host == self.host - and other.port == self.port - ) + return isinstance(other, self.__class__) and other.host == self.host and other.port == self.port async def close(self): await super().close() @@ -52,9 +49,7 @@ async def close(self): for fut in self.socket_futs: close_existing(fut) - await hp.cancel_futures_and_wait( - *self.socket_futs, name=f"{type(self).__name__}::close[wait_for_sockets]" - ) + await hp.cancel_futures_and_wait(*self.socket_futs, name=f"{type(self).__name__}::close[wait_for_sockets]") async def close_transport(self, transport): close_socket(transport) diff --git a/modules/photons_transport/transports/udp.py b/modules/photons_transport/transports/udp.py index 763433f2..f94ed481 100644 --- a/modules/photons_transport/transports/udp.py +++ b/modules/photons_transport/transports/udp.py @@ -3,6 +3,7 @@ import socket from photons_app import helpers as hp + from photons_transport.transports.socket import Socket log = logging.getLogger("photons_transport.transports.udp") diff --git a/modules/photons_web_server/commander/__init__.py b/modules/photons_web_server/commander/__init__.py index 2862dca7..11d1b837 100644 --- a/modules/photons_web_server/commander/__init__.py +++ b/modules/photons_web_server/commander/__init__.py @@ -2,10 +2,9 @@ from sanic.response import BaseHTTPResponse as Response from .const import REQUEST_IDENTIFIER_HEADER -from .messages import MessageFromExc, ProgressMessageMaker +from .messages import MessageFromExc, ProgressMessageMaker, reprer from .messages import TProgressMessageMaker as Progress from .messages import TResponseMaker as Responder -from .messages import reprer from .routes import Route from .store import ( Command, diff --git a/modules/photons_web_server/commander/messages.py b/modules/photons_web_server/commander/messages.py index c69ff4bf..a67a2b79 100644 --- a/modules/photons_web_server/commander/messages.py +++ b/modules/photons_web_server/commander/messages.py @@ -16,16 +16,11 @@ log = logging.getLogger("photons_web_server.commander.messages") -ExcInfo: tp.TypeAlias = tp.Union[ - None, - bool, - tp.Tuple[None, None, None], - tp.Tuple[tp.Type[BaseException], BaseException, types.TracebackType | None], -] +type ExcInfo = None | bool | tuple[None, None, None] | tuple[type[BaseException], BaseException, types.TracebackType | None] -ExcTypO: tp.TypeAlias = tp.Union[tp.Type[BaseException], None] -ExcO: tp.TypeAlias = BaseException | None -TBO: tp.TypeAlias = types.TracebackType | None +type ExcTypO = type[BaseException] | None +type ExcO = BaseException | None +type TBO = types.TracebackType | None class WithAsDict(tp.Protocol): @@ -113,23 +108,15 @@ def process(self, exc_type: ExcTypO, exc: ExcO, tb: TBO) -> ErrorMessage: ) elif exc_type is asyncio.CancelledError: - return ErrorMessage( - status=500, error="Request was cancelled", error_code="RequestCancelled" - ) + return ErrorMessage(status=500, error="Request was cancelled", error_code="RequestCancelled") elif exc and exc_type: if self.see_exception is None and self.log_exceptions: - self.log.error( - self.lc(f"{type(exc).__name__}: {str(exc)}"), exc_info=(exc_type, exc, tb) - ) + self.log.error(self.lc(f"{type(exc).__name__}: {str(exc)}"), exc_info=(exc_type, exc, tb)) - return ErrorMessage( - status=500, error="Internal Server Error", error_code="InternalServerError" - ) + return ErrorMessage(status=500, error="Internal Server Error", error_code="InternalServerError") - def modify_error_dict( - self, exc_type: ExcTypO, exc: ExcO, tb: TBO, dct: dict[str, object] - ) -> dict[str, object]: + def modify_error_dict(self, exc_type: ExcTypO, exc: ExcO, tb: TBO, dct: dict[str, object]) -> dict[str, object]: return dct __call__ = process diff --git a/modules/photons_web_server/commander/store.py b/modules/photons_web_server/commander/store.py index 679ddd4d..d2057565 100644 --- a/modules/photons_web_server/commander/store.py +++ b/modules/photons_web_server/commander/store.py @@ -13,14 +13,15 @@ import strcs from delfick_project.logging import LogContext from photons_app import helpers as hp -from photons_web_server.commander.const import REQUEST_IDENTIFIER_HEADER -from photons_web_server.commander.messages import ExcInfo from sanic import Sanic from sanic.models.handler_types import RouteHandler from sanic.request import Request from sanic.response import BaseHTTPResponse as Response from strcs import Meta +from photons_web_server.commander.const import REQUEST_IDENTIFIER_HEADER +from photons_web_server.commander.messages import ExcInfo + from .messages import ( TBO, ErrorMessage, @@ -29,11 +30,13 @@ MessageFromExc, ProgressMessageMaker, TMessageFromExc, + TReprer, + get_logger, + get_logger_name, + reprer, ) from .messages import TProgressMessageMaker as Progress -from .messages import TReprer from .messages import TResponseMaker as Responder -from .messages import get_logger, get_logger_name, reprer from .routes import Route from .stream_wrap import ( Message, @@ -87,12 +90,8 @@ def setup(self, *, instance: "Command", message_from_exc_maker: type[TMessageFro self.instance = instance self.message_from_exc_maker = message_from_exc_maker - def message_from_exc( - self, message: Message, exc_type: ExcTypO, exc: ExcO, tb: TBO - ) -> ErrorMessage | Exception: - return self.message_from_exc_maker( - lc=self.instance.lc.using(message_id=message.id), logger_name=self.instance.logger_name - )(exc_type, exc, tb) + def message_from_exc(self, message: Message, exc_type: ExcTypO, exc: ExcO, tb: TBO) -> ErrorMessage | Exception: + return self.message_from_exc_maker(lc=self.instance.lc.using(message_id=message.id), logger_name=self.instance.logger_name)(exc_type, exc, tb) def make_responder( self, @@ -121,12 +120,8 @@ def setup(self, *, instance: "Command", message_from_exc_maker: type[TMessageFro self.instance = instance self.message_from_exc_maker = message_from_exc_maker - def message_from_exc( - self, message: Message, exc_type: ExcTypO, exc: ExcO, tb: TBO - ) -> ErrorMessage | Exception: - return self.message_from_exc_maker( - lc=self.instance.lc.using(message_id=message.id), logger_name=self.instance.logger_name - )(exc_type, exc, tb) + def message_from_exc(self, message: Message, exc_type: ExcTypO, exc: ExcO, tb: TBO) -> ErrorMessage | Exception: + return self.message_from_exc_maker(lc=self.instance.lc.using(message_id=message.id), logger_name=self.instance.logger_name)(exc_type, exc, tb) def make_responder( self, @@ -227,14 +222,10 @@ def ws( return self.app.add_websocket_route(self.wrap_ws(method), *args, **kwargs) def sio(self, event: str, method: WrappedSocketioHandlerOnClass) -> RouteHandler: - return self.store.sio.on(event)( - self.wrap_sio(method, specific_event=None if event == "*" else event) - ) + return self.store.sio.on(event)(self.wrap_sio(method, specific_event=None if event == "*" else event)) @contextmanager - def a_request_future( - self, request: Request, name: str - ) -> tp.Generator[asyncio.Future, None, None]: + def a_request_future(self, request: Request, name: str) -> tp.Generator[asyncio.Future, None, None]: if hasattr(request.ctx, "request_future"): yield request.ctx.request_future return @@ -259,9 +250,7 @@ async def handle(request: Request, ws: Websocket): return handle - def wrap_sio( - self, method: WrappedSocketioHandlerOnClass, specific_event: str | None - ) -> RouteHandler: + def wrap_sio(self, method: WrappedSocketioHandlerOnClass, specific_event: str | None) -> RouteHandler: @wraps(method) async def handle(sid: str, *data: object): if specific_event is None: @@ -275,9 +264,7 @@ async def handle(sid: str, *data: object): if "lock" not in session: session["lock"] = asyncio.Lock() - room = SocketioRoomEvent( - lock=session["lock"], sio=self.store.sio, sid=sid, data=data, event=event - ) + room = SocketioRoomEvent(lock=session["lock"], sio=self.store.sio, sid=sid, data=data, event=event) request = self.store.sio.get_environ(sid)["sanic.request"] with self._an_instance(request, method) as (_, instance): @@ -300,12 +287,8 @@ async def route(request: Request, *args: tp.Any, **kwargs: tp.Any) -> Response | ret = False try: route = partial(method, instance) - progress = instance.progress_message_maker( - lc=instance.lc, logger_name=instance.logger_name - ) - route_args = self.store.determine_http_args_and_kwargs( - instance.meta, route, progress, request, args, kwargs - ) + progress = instance.progress_message_maker(lc=instance.lc, logger_name=instance.logger_name) + route_args = self.store.determine_http_args_and_kwargs(instance.meta, route, progress, request, args, kwargs) if inspect.iscoroutinefunction(route): t = hp.async_as_background(route(*route_args)) @@ -324,9 +307,7 @@ async def route(request: Request, *args: tp.Any, **kwargs: tp.Any) -> Response | except (asyncio.CancelledError, Exception): exc_info = sys.exc_info() if ret or exc_info[0] is not asyncio.CancelledError: - raise self.message_from_exc_maker( - lc=instance.lc, logger_name=instance.logger_name - )(*exc_info) + raise self.message_from_exc_maker(lc=instance.lc, logger_name=instance.logger_name)(*exc_info) if exc_info[0] is asyncio.CancelledError: raise sanic.exceptions.ServiceUnavailable("Cancelled") @@ -337,9 +318,7 @@ async def route(request: Request, *args: tp.Any, **kwargs: tp.Any) -> Response | return tp.cast(RouteHandler, route) @contextmanager - def instantiate_route( - self, request: Request, kls: type["Command"], method: tp.Callable[P, R] - ) -> tp.Generator[tp.Callable[P, R], None, None]: + def instantiate_route(self, request: Request, kls: type["Command"], method: tp.Callable[P, R]) -> tp.Generator[tp.Callable[P, R], None, None]: with self._an_instance(request, method, kls=kls) as (_, instance): route = getattr(instance, method.__name__) route_name = f"{route.__func__.__module__}.{route.__func__.__qualname__}" @@ -355,9 +334,7 @@ def _an_instance( @tp.overload @contextmanager - def _an_instance( - self, request: Request, method: tp.Callable[..., object], kls: None - ) -> tp.Generator[tuple[str, C], None, None]: ... + def _an_instance(self, request: Request, method: tp.Callable[..., object], kls: None) -> tp.Generator[tuple[str, C], None, None]: ... @contextmanager def _an_instance( @@ -365,13 +342,7 @@ def _an_instance( ) -> tp.Generator[tuple[str, C], None, None]: name = f"RouteTransformer::__call__({self.kls.__name__}:{method.__name__})" - lc = hp.lc.using( - **( - {} - if not hasattr(request.ctx, "request_identifier") - else {"request_identifier": request.ctx.request_identifier} - ) - ) + lc = hp.lc.using(**({} if not hasattr(request.ctx, "request_identifier") else {"request_identifier": request.ctx.request_identifier})) logger_name = get_logger_name(method=method) logger = logging.getLogger(logger_name) @@ -444,9 +415,7 @@ def create( ) -> T: if meta is None: meta = self.meta - return self.store.strcs_register.create( - typ, value, meta=meta, once_only_creator=once_only_creator - ) + return self.store.strcs_register.create(typ, value, meta=meta, once_only_creator=once_only_creator) @classmethod def log_request_dict( @@ -604,28 +573,19 @@ def determine_http_args_and_kwargs( values = list(signature.parameters.values()) use: list[object] = [] - if ( - values - and values[0].kind is inspect.Parameter.POSITIONAL_ONLY - and values[0].name == "self" - and values[0].annotation is inspect._empty - ): + if values and values[0].kind is inspect.Parameter.POSITIONAL_ONLY and values[0].name == "self" and values[0].annotation is inspect._empty: values.pop(0) if values and values[0].kind is inspect.Parameter.POSITIONAL_ONLY: nxt = values.pop(0) if nxt.annotation not in (inspect._empty, Progress): - raise IncorrectPositionalArgument( - "First positional only argument must be a progress object" - ) + raise IncorrectPositionalArgument("First positional only argument must be a progress object") use.append(progress) if values and values[0].kind is inspect.Parameter.POSITIONAL_ONLY: nxt = values.pop(0) if nxt.annotation not in (inspect._empty, Request): - raise IncorrectPositionalArgument( - "Second positional only argument must be a request object" - ) + raise IncorrectPositionalArgument("Second positional only argument must be a request object") use.append(request) remaining_args = list(args) @@ -633,9 +593,7 @@ def determine_http_args_and_kwargs( while values: nxt = values.pop(0) if remaining_args: - use.append( - self.strcs_register.create(nxt.annotation, remaining_args.pop(0), meta=meta) - ) + use.append(self.strcs_register.create(nxt.annotation, remaining_args.pop(0), meta=meta)) continue if nxt.kind is not inspect.Parameter.POSITIONAL_ONLY: @@ -644,15 +602,9 @@ def determine_http_args_and_kwargs( if nxt.default is inspect._empty: try: - use.append( - self.strcs_register.create( - nxt.annotation, kwargs.pop(nxt.name, strcs.NotSpecified), meta=meta - ) - ) + use.append(self.strcs_register.create(nxt.annotation, kwargs.pop(nxt.name, strcs.NotSpecified), meta=meta)) except (TypeError, ValueError) as e: - raise NotEnoughArgs( - reason="request expected more positional arguments than it got" - ) from e + raise NotEnoughArgs(reason="request expected more positional arguments than it got") from e continue diff --git a/modules/photons_web_server/commander/stream_wrap.py b/modules/photons_web_server/commander/stream_wrap.py index 99295f80..a7ac9b38 100644 --- a/modules/photons_web_server/commander/stream_wrap.py +++ b/modules/photons_web_server/commander/stream_wrap.py @@ -7,6 +7,7 @@ from contextlib import contextmanager from functools import wraps from textwrap import dedent +from typing import Self import attrs import sanic.exceptions @@ -21,13 +22,10 @@ from sanic.response import BaseHTTPResponse as Response from sanic.response import HTTPResponse from sanic.response.types import json_dumps -from typing_extensions import Self -from .messages import TBO, ErrorMessage, ExcO, ExcTypO +from .messages import TBO, ErrorMessage, ExcO, ExcTypO, TReprer, reprer from .messages import TProgressMessageMaker as Progress -from .messages import TReprer from .messages import TResponseMaker as Responder -from .messages import reprer try: import ulid @@ -107,12 +105,8 @@ def stream_id(self) -> str: @classmethod @contextmanager - def unknown( - cls, request: Request, stream_fut: asyncio.Future, body: object - ) -> tp.Generator["Message", None, None]: - with hp.ChildOfFuture( - stream_fut, name="Message(unknown)::unknown[message_fut]" - ) as message_fut: + def unknown(cls, request: Request, stream_fut: asyncio.Future, body: object) -> tp.Generator["Message", None, None]: + with hp.ChildOfFuture(stream_fut, name="Message(unknown)::unknown[message_fut]") as message_fut: yield cls( id="unknown", body=tp.cast(dict, body), @@ -123,12 +117,8 @@ def unknown( @classmethod @contextmanager - def create( - cls, message_id: str, body: dict, request: Request, stream_fut: asyncio.Future - ) -> tp.Generator["Message", None, None]: - with hp.ChildOfFuture( - stream_fut, name=f"Message({message_id})::create[message_fut]" - ) as message_fut: + def create(cls, message_id: str, body: dict, request: Request, stream_fut: asyncio.Future) -> tp.Generator["Message", None, None]: + with hp.ChildOfFuture(stream_fut, name=f"Message({message_id})::create[message_fut]") as message_fut: yield cls( id=message_id, body=body, @@ -142,13 +132,9 @@ class WrappedWebsocketHandler(tp.Protocol): async def __call__(self, respond: Responder, message: Message) -> bool | None: ... -WrappedWebsocketHandlerOnClass: tp.TypeAlias = tp.Callable[ - [tp.Any, Responder, Message], tp.Coroutine[tp.Any, tp.Any, bool | None] -] +type WrappedWebsocketHandlerOnClass = tp.Callable[[tp.Any, Responder, Message], tp.Coroutine[tp.Any, tp.Any, bool | None]] -WrappedSocketioHandlerOnClass: tp.TypeAlias = tp.Callable[ - [tp.Any, Responder, Message], tp.Coroutine[tp.Any, tp.Any, bool | None] -] +type WrappedSocketioHandlerOnClass = tp.Callable[[tp.Any, Responder, Message], tp.Coroutine[tp.Any, tp.Any, bool | None]] T_Handler = tp.TypeVar("T_Handler", WrappedWebsocketHandlerOnClass, WrappedSocketioHandlerOnClass) T_Transport = tp.TypeVar("T_Transport") @@ -249,9 +235,7 @@ def __init__( self.setup(*args, **kwargs) @abc.abstractmethod - def message_from_exc( - self, message: Message, exc_type: ExcTypO, exc: ExcO, tb: TBO - ) -> ErrorMessage | Exception: ... + def message_from_exc(self, message: Message, exc_type: ExcTypO, exc: ExcO, tb: TBO) -> ErrorMessage | Exception: ... @abc.abstractmethod def make_responder( @@ -286,9 +270,7 @@ async def handle(request: Request, transport: T_Transport): request.ctx.__commander_class__ = handler.__commander_class__ with self.a_stream_fut(request) as stream_fut: - async with hp.TaskHolder( - stream_fut, name="WebsocketWrap::__call__[tasks]" - ) as tasks: + async with hp.TaskHolder(stream_fut, name="WebsocketWrap::__call__[tasks]") as tasks: await self.handle_request(handler, request, transport, tasks, stream_fut) return handle @@ -299,9 +281,7 @@ def a_stream_fut(self, request: Request) -> tp.Generator[asyncio.Future, None, N yield request.ctx.request_future return - with hp.ChildOfFuture( - self.final_future, name="WebsocketWrap::a_stream_fut[stream_fut]" - ) as stream_fut: + with hp.ChildOfFuture(self.final_future, name="WebsocketWrap::a_stream_fut[stream_fut]") as stream_fut: request.ctx.request_future = stream_fut yield stream_fut @@ -322,7 +302,7 @@ async def _process( result = await handler(respond=respond, message=message) status = 200 return result - except: + except Exception: request.ctx.exc_info = sys.exc_info() res = self.message_from_exc(message, *request.ctx.exc_info) if isinstance(res, ErrorMessage): @@ -334,9 +314,7 @@ async def _process( class WebsocketWrap(StreamWrap[WrappedWebsocketHandler, Websocket]): - def message_from_exc( - self, message: Message, exc_type: ExcTypO, exc: ExcO, tb: TBO - ) -> ErrorMessage | Exception: + def message_from_exc(self, message: Message, exc_type: ExcTypO, exc: ExcO, tb: TBO) -> ErrorMessage | Exception: return InternalServerError("Internal Server Error") def make_responder( @@ -364,9 +342,7 @@ async def handle_request( if loop_stop.done(): break - await self.handle_next( - loop_stop, tasks, handler, request, stream_fut, transport - ) + await self.handle_next(loop_stop, tasks, handler, request, stream_fut, transport) finally: await transport.close() @@ -380,9 +356,7 @@ async def handle_next( ws: T_Transport, ) -> None: get_nxt = tasks.add(ws.recv()) - await hp.wait_for_first_future( - get_nxt, loop_stop, name="WebsocketWrap::handle_next[wait_for_nxt]" - ) + await hp.wait_for_first_future(get_nxt, loop_stop, name="WebsocketWrap::handle_next[wait_for_nxt]") if loop_stop.done(): await ws.close() @@ -425,9 +399,7 @@ async def handle_next( async def process() -> None: try: - if ( - await self._process(handler, ws, message_id, body, request, stream_fut) - ) is False: + if (await self._process(handler, ws, message_id, body, request, stream_fut)) is False: loop_stop.cancel() except sanic.exceptions.WebsocketClosed: loop_stop.cancel() @@ -436,9 +408,7 @@ async def process() -> None: class SocketioWrap(StreamWrap[WrappedSocketioHandlerOnClass, str]): - def message_from_exc( - self, message: Message, exc_type: ExcTypO, exc: ExcO, tb: TBO - ) -> ErrorMessage | Exception: + def message_from_exc(self, message: Message, exc_type: ExcTypO, exc: ExcO, tb: TBO) -> ErrorMessage | Exception: return InternalServerError("Internal Server Error") def make_responder( diff --git a/modules/photons_web_server/pytest_helpers.py b/modules/photons_web_server/pytest_helpers.py index e0198000..32995a4f 100644 --- a/modules/photons_web_server/pytest_helpers.py +++ b/modules/photons_web_server/pytest_helpers.py @@ -9,6 +9,7 @@ import websockets import websockets.client from photons_app import helpers as hp + from photons_web_server.server import Server @@ -141,12 +142,8 @@ def __init__( if self.server_properties is None: self.server_properties = {} - self.task_holder = hp.TaskHolder( - self.final_future, name="WebServerRoutes::__init__[task_holder]" - ) - self.graceful_final_future = hp.create_future( - name="WebServerRoutes::__init__[graceful_final_future]" - ) + self.task_holder = hp.TaskHolder(self.final_future, name="WebServerRoutes::__init__[task_holder]") + self.graceful_final_future = hp.create_future(name="WebServerRoutes::__init__[graceful_final_future]") async def start(self, kls: type[Server] = Server) -> "WebServerRoutes": assert self.server_properties is not None @@ -177,14 +174,10 @@ async def setup_routes(s): def stop(self) -> None: self.graceful_final_future.cancel() - def start_request( - self, method: str, route: str, body: dict | None = None - ) -> asyncio.Task[aiohttp.ClientResponse]: + def start_request(self, method: str, route: str, body: dict | None = None) -> asyncio.Task[aiohttp.ClientResponse]: async def request() -> aiohttp.ClientResponse: async with aiohttp.ClientSession() as session: - return await getattr(session, method.lower())( - f"http://127.0.0.1:{self.port}{route}", json=body - ) + return await getattr(session, method.lower())(f"http://127.0.0.1:{self.port}{route}", json=body) return hp.get_event_loop().create_task(request()) @@ -205,6 +198,6 @@ async def finish( await hp.wait_for_all_futures(self.serve_task) try: await self.server.finished() - except: + except Exception: self.final_future.cancel() await self.task_holder.finish() diff --git a/modules/photons_web_server/server.py b/modules/photons_web_server/server.py index 0e678cbe..dd64216a 100644 --- a/modules/photons_web_server/server.py +++ b/modules/photons_web_server/server.py @@ -10,6 +10,12 @@ from photons_app import helpers as hp from photons_app.errors import PhotonsAppError from photons_app.tasks.tasks import GracefulTask +from sanic.models.handler_types import RouteHandler +from sanic.request import Request +from sanic.response import BaseHTTPResponse as Response +from sanic.server import AsyncioServer +from sanic.server.protocols.websocket_protocol import WebSocketProtocol + from photons_web_server.commander import ( REQUEST_IDENTIFIER_HEADER, Command, @@ -17,11 +23,6 @@ WrappedWebsocketHandler, ) from photons_web_server.commander.messages import ErrorMessage, catch_ErrorMessage -from sanic.models.handler_types import RouteHandler -from sanic.request import Request -from sanic.response import BaseHTTPResponse as Response -from sanic.server import AsyncioServer -from sanic.server.protocols.websocket_protocol import WebSocketProtocol try: import sanic @@ -152,9 +153,7 @@ async def serve(self, host, port, **kwargs) -> None: self.tasks.add(self.server.serve_forever()) self.tasks.add(self.after_start()) - await hp.wait_for_all_futures( - self.server_stop_future, name="Server::serve[wait_for_stop]" - ) + await hp.wait_for_all_futures(self.server_stop_future, name="Server::serve[wait_for_stop]") finally: exc_info = sys.exc_info() await self.finished() @@ -172,7 +171,6 @@ async def finished(self) -> None: await self.before_stop() if self.server.is_serving(): - for connection in self.connections: connection.close_if_idle() @@ -205,9 +203,7 @@ def create_request_id(self, request: Request) -> None: def attach_exception(self, request: Request, exception: BaseException) -> None: request.ctx.exc_info = (type(exception), exception, exception.__traceback__) - def log_request_dict( - self, request: Request, remote_addr: str, identifier: str - ) -> dict[str, tp.Any] | None: + def log_request_dict(self, request: Request, remote_addr: str, identifier: str) -> dict[str, tp.Any] | None: return dict( method=request.method, uri=request.path, @@ -238,9 +234,7 @@ def log_request(self, request: Request, **extra_lc_context) -> None: getattr(log, method)(lc("Request", **dct)) - def log_ws_request( - self, request: Request, first: tp.Any, title: str = "Websocket Request", **extra_lc_context - ) -> None: + def log_ws_request(self, request: Request, first: tp.Any, title: str = "Websocket Request", **extra_lc_context) -> None: remote_addr = request.remote_addr identifier = request.ctx.request_identifier diff --git a/modules/tests/photons_app_tests/helpers/test_futures.py b/modules/tests/photons_app_tests/helpers/test_futures.py index 501af930..e9c03ceb 100644 --- a/modules/tests/photons_app_tests/helpers/test_futures.py +++ b/modules/tests/photons_app_tests/helpers/test_futures.py @@ -35,7 +35,6 @@ def test_it_can_give_a_name_to_the_future(self): class TestFutHasCallback: async def test_it_says_no_if_fut_has_no_callbacks(self): - def func(): pass @@ -43,7 +42,6 @@ def func(): assert not hp.fut_has_callback(fut, func) async def test_it_says_no_if_it_has_other_callbacks(self): - def func1(): pass @@ -55,7 +53,6 @@ def func2(): assert not hp.fut_has_callback(fut, func2) async def test_it_says_yes_if_we_have_the_callback(self): - def func1(): pass @@ -82,7 +79,6 @@ async def func(): assert res == val async def test_it_cancels_the_coroutine_if_it_doesnt_respond(self): - async def func(): await asyncio.sleep(2) @@ -108,9 +104,8 @@ async def func(): class TestAsyncAsBackground: async def test_it_runs_the_coroutine_in_the_background(self): - async def func(one, two, three=None): - return "{0}.{1}.{2}".format(one, two, three) + return f"{one}.{two}.{three}" t = hp.async_as_background(func(6, 5, three=9)) pytest.helpers.assertFutCallbacks(t, hp.reporter) @@ -118,9 +113,8 @@ async def func(one, two, three=None): assert await t == "6.5.9" async def test_it_uses_silent_reporter_if_silent_is_True(self): - async def func(one, two, three=None): - return "{0}.{1}.{2}".format(one, two, three) + return f"{one}.{two}.{three}" t = hp.async_as_background(func(6, 5, three=9), silent=True) pytest.helpers.assertFutCallbacks(t, hp.silent_reporter) @@ -320,7 +314,6 @@ async def test_it_can_return_error_with_multiple_errors(self): class TestFindAndApplyResult: - @pytest.fixture() def V(self): class V: diff --git a/modules/tests/photons_app_tests/helpers/test_queue.py b/modules/tests/photons_app_tests/helpers/test_queue.py index 4354c3c1..2f7e87df 100644 --- a/modules/tests/photons_app_tests/helpers/test_queue.py +++ b/modules/tests/photons_app_tests/helpers/test_queue.py @@ -101,9 +101,7 @@ async def fill(): assert found == [1, 2, 3, 4, 5] assert list(queue.remaining()) == [6, 7] - async def test_it_ignores_results_added_after_final_future_is_done_if_still_waiting_for_results( - self, final_future - ): + async def test_it_ignores_results_added_after_final_future_is_done_if_still_waiting_for_results(self, final_future): wait = hp.create_future() queue = hp.Queue(final_future) @@ -196,9 +194,7 @@ async def fill(): assert found == [1, 2, 3, 4, 5, 6, 7] assert list(queue.remaining()) == [] - async def test_it_gets_results_added_after_final_future_is_done_if_still_waiting_for_results( - self, final_future - ): + async def test_it_gets_results_added_after_final_future_is_done_if_still_waiting_for_results(self, final_future): wait = hp.create_future() queue = hp.Queue(final_future, empty_on_finished=True) @@ -299,7 +295,6 @@ async def test_it_can_get_remaining_items(self, final_future): assert queue.collection.empty() class TestGettingAllResults: - async def test_it_can_get_results_until_final_future_is_done(self, final_future): wait = hp.create_future() @@ -338,9 +333,7 @@ async def fill(): assert found == [1, 2, 3, 4, 5] assert list(queue.remaining()) == [6, 7] - async def test_it_ignores_results_added_after_final_future_is_done_if_still_waiting_for_results( - self, final_future - ): + async def test_it_ignores_results_added_after_final_future_is_done_if_still_waiting_for_results(self, final_future): wait = hp.create_future() queue = hp.SyncQueue(final_future) @@ -399,7 +392,6 @@ async def test_it_is_re_entrant_if_we_break(self, final_future): assert found == list(range(10)) class TestGettingAllResultsWhenEmptyOnFinished: - async def test_it_can_get_results_until_final_future_is_done(self, final_future): wait = hp.create_future() @@ -438,9 +430,7 @@ async def fill(): assert found == [1, 2, 3, 4, 5, 6, 7] assert list(queue.remaining()) == [] - async def test_it_gets_results_added_after_final_future_is_done_if_still_waiting_for_results( - self, final_future - ): + async def test_it_gets_results_added_after_final_future_is_done_if_still_waiting_for_results(self, final_future): wait = hp.create_future() queue = hp.SyncQueue(final_future, empty_on_finished=True) diff --git a/modules/tests/photons_app_tests/helpers/test_resettable_future.py b/modules/tests/photons_app_tests/helpers/test_resettable_future.py index 6ae6581e..fb52e784 100644 --- a/modules/tests/photons_app_tests/helpers/test_resettable_future.py +++ b/modules/tests/photons_app_tests/helpers/test_resettable_future.py @@ -166,7 +166,9 @@ async def test_it_does_nothing_if_the_future_hasnt_been_resolved_yet(self): called = [] - cb = lambda res: called.append("DONE1") + def cb(res): + return called.append("DONE1") + fut.add_done_callback(cb) pytest.helpers.assertFutCallbacks(f, cb, hp.silent_reporter) pytest.helpers.assertFutCallbacks(fut, cb, hp.silent_reporter) @@ -191,7 +193,10 @@ async def test_it_can_force_the_future_to_be_closed(self): f = fut.fut called = [] - cb = lambda res: called.append("DONE1") + + def cb(res): + return called.append("DONE1") + fut.add_done_callback(cb) pytest.helpers.assertFutCallbacks(f, cb, hp.silent_reporter) pytest.helpers.assertFutCallbacks(fut, cb, hp.silent_reporter) diff --git a/modules/tests/photons_app_tests/helpers/test_rest.py b/modules/tests/photons_app_tests/helpers/test_rest.py index 610ca7ad..53980ec2 100644 --- a/modules/tests/photons_app_tests/helpers/test_rest.py +++ b/modules/tests/photons_app_tests/helpers/test_rest.py @@ -8,7 +8,6 @@ class TestFutureToString: def test_it_just_reprs_a_not_future(self): - class Thing: def __repr__(s): return "" @@ -94,9 +93,7 @@ def test_it_logs_exceptions(self): with hp.just_log_exceptions(log): raise error - log.error.assert_called_once_with( - "Unexpected error", exc_info=(ValueError, error, mock.ANY) - ) + log.error.assert_called_once_with("Unexpected error", exc_info=(ValueError, error, mock.ANY)) def test_it_can_be_given_a_different_message(self): log = mock.Mock(name="log") @@ -105,9 +102,7 @@ def test_it_can_be_given_a_different_message(self): with hp.just_log_exceptions(log, message="a different message"): raise error - log.error.assert_called_once_with( - "a different message", exc_info=(ValueError, error, mock.ANY) - ) + log.error.assert_called_once_with("a different message", exc_info=(ValueError, error, mock.ANY)) def test_it_can_reraise_particular_errors(self): log = mock.Mock(name="log") @@ -116,9 +111,7 @@ def test_it_can_reraise_particular_errors(self): with hp.just_log_exceptions(log, message="a different message", reraise=[TypeError]): raise error - log.error.assert_called_once_with( - "a different message", exc_info=(ValueError, error, mock.ANY) - ) + log.error.assert_called_once_with("a different message", exc_info=(ValueError, error, mock.ANY)) log.error.reset_mock() with assertRaises(TypeError, "wat"): @@ -337,22 +330,12 @@ def test_it_can_be_compared_with_another_hpColor(self): assert hp.Color(2, 0, 0, 3500) != hp.Color(2, 0, 0, 3700) def test_it_can_be_compared_with_a_real_fieldsColor(self): - assert hp.Color(2, 0, 0, 3500) == fields.Color( - hue=2, saturation=0, brightness=0, kelvin=3500 - ) + assert hp.Color(2, 0, 0, 3500) == fields.Color(hue=2, saturation=0, brightness=0, kelvin=3500) - assert hp.Color(2, 0, 0, 3500) != fields.Color( - hue=20, saturation=0, brightness=0, kelvin=3500 - ) - assert hp.Color(2, 0, 0, 3500) != fields.Color( - hue=2, saturation=1, brightness=0, kelvin=3500 - ) - assert hp.Color(2, 0, 0, 3500) != fields.Color( - hue=2, saturation=0, brightness=1, kelvin=3500 - ) - assert hp.Color(2, 0, 0, 3500) != fields.Color( - hue=2, saturation=0, brightness=0, kelvin=3700 - ) + assert hp.Color(2, 0, 0, 3500) != fields.Color(hue=20, saturation=0, brightness=0, kelvin=3500) + assert hp.Color(2, 0, 0, 3500) != fields.Color(hue=2, saturation=1, brightness=0, kelvin=3500) + assert hp.Color(2, 0, 0, 3500) != fields.Color(hue=2, saturation=0, brightness=1, kelvin=3500) + assert hp.Color(2, 0, 0, 3500) != fields.Color(hue=2, saturation=0, brightness=0, kelvin=3700) def test_it_compares_to_4_decimal_places(self): assert hp.Color(250.245677, 0.134577, 0.765477, 4568) == ( diff --git a/modules/tests/photons_app_tests/helpers/test_result_streamer.py b/modules/tests/photons_app_tests/helpers/test_result_streamer.py index eaee017b..efcb6c00 100644 --- a/modules/tests/photons_app_tests/helpers/test_result_streamer.py +++ b/modules/tests/photons_app_tests/helpers/test_result_streamer.py @@ -61,7 +61,6 @@ async def test_it_has_a_final_future_as_a_child_of_that_passed_in(self): assert streamer.final_future.cancelled() class TestAddGenerator: - @pytest.fixture() async def V(self): class V: @@ -90,7 +89,6 @@ async def retrieve(s): await v.streamer.finish(*exc_info) async def test_it_adds_it_as_a_coroutine(self, V): - async def gen(): yield 1 yield 2 @@ -150,9 +148,7 @@ async def gen(): assert [r.value for r in results] == [1] V.error_catcher.assert_not_called() - on_done.assert_called_once_with( - hp.ResultStreamer.Result(hp.ResultStreamer.GeneratorComplete, ctx, True) - ) + on_done.assert_called_once_with(hp.ResultStreamer.Result(hp.ResultStreamer.GeneratorComplete, ctx, True)) async def test_it_can_call_on_each_for_each_result(self, V): ctx = mock.NonCallableMock(name="context", spec=[]) @@ -171,9 +167,7 @@ async def gen(): yield 3 called.append("gen_finished") - task = await V.streamer.add_generator( - gen(), on_done=on_done, on_each=on_each, context=ctx - ) + task = await V.streamer.add_generator(gen(), on_done=on_done, on_each=on_each, context=ctx) assert task in V.streamer.ts results = await V.retrieve() @@ -192,7 +186,6 @@ async def gen(): ] class TestAddCoroutine: - @pytest.fixture() async def V(self): class V: @@ -245,7 +238,6 @@ async def func(): add_task.assert_called_once_with(mock.ANY, context=None, on_done=None, force=False) class TestAddValue: - @pytest.fixture() async def V(self): class V: @@ -305,7 +297,6 @@ async def adder(streamer): assert found == [(True, "ADDER", None), (True, 1, "adder"), (True, 2, "adder")] class TestAddTask: - @pytest.fixture() async def make_streamer(self): @hp.asynccontextmanager @@ -337,10 +328,7 @@ async def retrieve(): return started, hp.async_as_background(retrieve()) - async def test_it_calls_error_catcher_with_CancelledError_if_the_task_gets_cancelled( - self, make_streamer - ): - + async def test_it_calls_error_catcher_with_CancelledError_if_the_task_gets_cancelled(self, make_streamer): async def func(): await asyncio.sleep(20) @@ -402,9 +390,7 @@ async def func(): on_done.assert_called_once_with(result) error_catcher.assert_called_once_with(result) - async def test_it_Result_Streamer_only_gives_cancelled_errors_to_catcher_if_we_only_give_exceptions( - self, make_streamer - ): + async def test_it_Result_Streamer_only_gives_cancelled_errors_to_catcher_if_we_only_give_exceptions(self, make_streamer): error = AttributeError("nup") on_done = mock.Mock(name="on_done") @@ -416,9 +402,7 @@ async def func(sleeper_task): raise error error_catcher = mock.Mock(name="error_catcher") - async with make_streamer( - error_catcher=error_catcher, exceptions_only_to_error_catcher=True - ) as streamer: + async with make_streamer(error_catcher=error_catcher, exceptions_only_to_error_catcher=True) as streamer: sleeper_task = await streamer.add_coroutine(sleeper(), on_done=on_done) await streamer.add_coroutine(func(sleeper_task), on_done=on_done) @@ -466,9 +450,7 @@ async def func(sleeper_task): raise error error_catcher = mock.Mock(name="error_catcher") - async with make_streamer( - error_catcher=error_catcher, exceptions_only_to_error_catcher=True - ) as streamer: + async with make_streamer(error_catcher=error_catcher, exceptions_only_to_error_catcher=True) as streamer: sleeper_task = await streamer.add_coroutine(sleeper(), on_done=on_done) await streamer.add_coroutine(func(sleeper_task), on_done=on_done) @@ -523,9 +505,7 @@ async def func(): error_catcher.assert_not_called() on_done.assert_called_once_with(result) - async def test_it_doesnt_call_error_catcher_if_success_and_exceptions_only( - self, make_streamer - ): + async def test_it_doesnt_call_error_catcher_if_success_and_exceptions_only(self, make_streamer): make_return = hp.create_future() async def func(): @@ -533,9 +513,7 @@ async def func(): return 42 error_catcher = mock.Mock(name="error_catcher") - async with make_streamer( - error_catcher=error_catcher, exceptions_only_to_error_catcher=True - ) as streamer: + async with make_streamer(error_catcher=error_catcher, exceptions_only_to_error_catcher=True) as streamer: await streamer.add_task(hp.async_as_background(func())) started, runner = await self.retrieve(streamer) @@ -601,7 +579,6 @@ async def run_it(): finish.assert_called_once_with(asyncio.CancelledError, mock.ANY, mock.ANY) class TestFinishingByFinalFuture: - async def test_it_stops_retrieving_if_there_is_results_left_to_yield(self): called = [] @@ -649,9 +626,7 @@ def error_catcher(e): async with streamer: on_dones["gen"] = mock.Mock(name="on_done gen") - tasks["gen"] = await streamer.add_generator( - gen(), context="gen", on_done=on_dones["gen"] - ) + tasks["gen"] = await streamer.add_generator(gen(), context="gen", on_done=on_dones["gen"]) for name, coro in ( ("func", func()), @@ -659,9 +634,7 @@ def error_catcher(e): ("func3", func3()), ): on_dones[name] = mock.Mock(name=f"on_done {name}") - tasks[name] = await streamer.add_task( - hp.async_as_background(coro), context=name, on_done=on_dones[name] - ) + tasks[name] = await streamer.add_task(hp.async_as_background(coro), context=name, on_done=on_dones[name]) results = [] async for result in streamer: @@ -709,7 +682,6 @@ def error_catcher(e): class TestUsingResultStreamer: - @pytest.fixture() def final_future(self): fut = hp.create_future() @@ -817,9 +789,7 @@ async def gen1_for_gen1_of_gen2(): yield "r_g2g1g1_last" XS.g2_g1_g1 = CTX.Gen("gen1_for_gen1_of_gen2", 1) - await streamer.add_generator( - gen1_for_gen1_of_gen2(), context=XS.g2_g1_g1, on_done=make_on_done(2) - ) + await streamer.add_generator(gen1_for_gen1_of_gen2(), context=XS.g2_g1_g1, on_done=make_on_done(2)) ########## ## coro for generator 1 for Second generator @@ -831,9 +801,7 @@ async def coro_for_gen1_of_gen2(): raise ValueError("e_g2g1c") XS.g2_g1_c = CTX("coro_for_gen1_of_gen2") - await streamer.add_coroutine( - coro_for_gen1_of_gen2(), context=XS.g2_g1_c, on_done=make_on_done(5) - ) + await streamer.add_coroutine(coro_for_gen1_of_gen2(), context=XS.g2_g1_c, on_done=make_on_done(5)) ########## ## sub generator 1 for Second generator @@ -901,9 +869,7 @@ async def coro1_for_gen2(): return "r_g2c2" XS.g2_c2 = CTX("gen2_coro2") - await streamer.add_coroutine( - coro1_for_gen2(), context=XS.g2_c2, on_done=make_on_done(8) - ) + await streamer.add_coroutine(coro1_for_gen2(), context=XS.g2_c2, on_done=make_on_done(8)) ########## ## Second generator @@ -1032,9 +998,7 @@ def on_done(result): i += 1 key = result.context.key print() - print( - f"STREAMED: value:`{type(result.value)}`{result.value}`\tcontext:`{result.context}`\tkey:`{key}`" - ) + print(f"STREAMED: value:`{type(result.value)}`{result.value}`\tcontext:`{result.context}`\tkey:`{key}`") expectedi, r = expected["yielded"][i]() if not result.successful and r.successful: diff --git a/modules/tests/photons_app_tests/helpers/test_stop_async_generator.py b/modules/tests/photons_app_tests/helpers/test_stop_async_generator.py index 66f013b2..ecb2552d 100644 --- a/modules/tests/photons_app_tests/helpers/test_stop_async_generator.py +++ b/modules/tests/photons_app_tests/helpers/test_stop_async_generator.py @@ -67,7 +67,6 @@ async def d(): ] async def test_it_works_if_generator_is_already_complete(self): - async def d(): yield True @@ -78,7 +77,6 @@ async def d(): await hp.stop_async_generator(gen) async def test_it_works_if_generator_is_already_complete_by_cancellation(self): - async def d(): fut = hp.create_future() fut.cancel() @@ -93,7 +91,6 @@ async def d(): await hp.stop_async_generator(gen) async def test_it_works_if_generator_is_already_complete_by_exception(self): - async def d(): raise ValueError("NOPE") yield True @@ -106,7 +103,6 @@ async def d(): await hp.stop_async_generator(gen) async def test_it_works_if_generator_is_half_complete(self): - called = [] async def d(): diff --git a/modules/tests/photons_app_tests/helpers/test_task_holder.py b/modules/tests/photons_app_tests/helpers/test_task_holder.py index 8f89dcd0..9d0d7d9b 100644 --- a/modules/tests/photons_app_tests/helpers/test_task_holder.py +++ b/modules/tests/photons_app_tests/helpers/test_task_holder.py @@ -51,9 +51,7 @@ async def wait(amount): assert called == [0.05, 0.01] - async def test_it_can_wait_for_more_tasks_if_they_are_added_when_the_manager_has_left( - self, final_future - ): + async def test_it_can_wait_for_more_tasks_if_they_are_added_when_the_manager_has_left(self, final_future): called = [] async def wait(ts, amount): @@ -231,9 +229,7 @@ async def two(): await asyncio.sleep(0) assert called == ["ONE", "TWO", "CANC_ONE", "FIN_ONE", "DONE_TWO", "FIN_TWO"] - async def test_it_doesnt_lose_tasks_from_race_condition( - self, FakeTime, MockedCallLater, final_future - ): + async def test_it_doesnt_lose_tasks_from_race_condition(self, FakeTime, MockedCallLater, final_future): with FakeTime() as t: async with MockedCallLater(t): called = [] diff --git a/modules/tests/photons_app_tests/helpers/test_ticker.py b/modules/tests/photons_app_tests/helpers/test_ticker.py index ba84a0b2..314f0942 100644 --- a/modules/tests/photons_app_tests/helpers/test_ticker.py +++ b/modules/tests/photons_app_tests/helpers/test_ticker.py @@ -5,10 +5,7 @@ class TestTick: - - async def test_it_keeps_yielding_such_that_yields_are_every_apart( - self, FakeTime, MockedCallLater - ): + async def test_it_keeps_yielding_such_that_yields_are_every_apart(self, FakeTime, MockedCallLater): called = [] with FakeTime() as t: @@ -81,10 +78,7 @@ async def test_it_keeps_yielding_until_max_time(self, FakeTime, MockedCallLater) assert called == [(1, 0), (2, 3), (3, 6), (4, 9), (5, 12), (6, 15), (7, 18)] - async def test_it_keeps_yielding_until_max_time_or_max_iterations( - self, FakeTime, MockedCallLater - ): - + async def test_it_keeps_yielding_until_max_time_or_max_iterations(self, FakeTime, MockedCallLater): with FakeTime() as t: async with MockedCallLater(t): called = [] @@ -113,9 +107,7 @@ async def test_it_keeps_yielding_until_max_time_or_max_iterations( (7, 18), ] - async def test_it_keeps_yielding_such_that_yields_are_best_effort_every_apart_when_tasks_go_over( - self, FakeTime, MockedCallLater - ): + async def test_it_keeps_yielding_such_that_yields_are_best_effort_every_apart_when_tasks_go_over(self, FakeTime, MockedCallLater): called = [] with FakeTime() as t: @@ -157,7 +149,6 @@ async def test_it_stops_if_final_future_stops(self, FakeTime, MockedCallLater): class TestATicker: - async def test_it_can_change_the_after_permanently(self, FakeTime, MockedCallLater): called = [] @@ -286,9 +277,7 @@ async def test_it_can_be_paused(self, FakeTime, MockedCallLater): ] assert m.called_times == [5.0, 10.0, 33.0, 33.0, 35.0, 40.0, 45.0] - async def test_it_cancelled_final_future_not_stopped_by_pauser( - self, FakeTime, MockedCallLater - ): + async def test_it_cancelled_final_future_not_stopped_by_pauser(self, FakeTime, MockedCallLater): called = [] pauser = asyncio.Semaphore() diff --git a/modules/tests/photons_app_tests/mimic/test_attrs.py b/modules/tests/photons_app_tests/mimic/test_attrs.py index 800722fc..c2412f1d 100644 --- a/modules/tests/photons_app_tests/mimic/test_attrs.py +++ b/modules/tests/photons_app_tests/mimic/test_attrs.py @@ -23,7 +23,6 @@ def device(): class TestPath: - @pytest.fixture() def attrs(self, device): attrs = Attrs(device) @@ -37,9 +36,7 @@ class One(dictobj.Spec): thing3 = dictobj.Field(sb.string_spec()) # Bypass the change system cause the tests is testing that system! - attrs._attrs["one"] = One.FieldSpec().empty_normalise( - list1=[{"blah": True}, {"blah": False}], list2=[1, 2, 3], thing3="yeap" - ) + attrs._attrs["one"] = One.FieldSpec().empty_normalise(list1=[{"blah": True}, {"blah": False}], list2=[1, 2, 3], thing3="yeap") attrs._attrs["stuff"] = "things" attrs._attrs["many"] = ["yes", "yah", "yarp"] @@ -153,10 +150,7 @@ async def attr_change(self, part, value, event): called.clear() assert attrs.holder.my_property == 5 - async def test_it_has_a_repr_if_we_applied_to_a_path_but_the_value_didnt_change( - self, attrs - ): - + async def test_it_has_a_repr_if_we_applied_to_a_path_but_the_value_didnt_change(self, attrs): class Sticky(dictobj.Spec): @property def one(s): @@ -216,17 +210,13 @@ async def test_it_has_a_repr_if_we_applied_to_a_path(self, attrs): "many": ["yes", "yah", "nope"], } - async def test_it_can_add_attributes_that_dont_already_exist_to_the_base_of_attrs( - self, attrs - ): + async def test_it_can_add_attributes_that_dont_already_exist_to_the_base_of_attrs(self, attrs): changer = attrs.attrs_path("new").changer_to("newer") assert repr(changer) == " to newer>" await changer() assert repr(changer) == "" - async def test_it_can_not_add_attributes_that_dont_already_exist_to_after_base_of_attrs( - self, attrs - ): + async def test_it_can_not_add_attributes_that_dont_already_exist_to_after_base_of_attrs(self, attrs): changer = attrs.attrs_path("one", "list1", 0, "nope").changer_to("never") assert repr(changer) == "> to never>" await changer() @@ -291,10 +281,7 @@ async def attr_change(self, part, value, event): assert attrs.holder.a_list == (1, 2) assert called == [("attr_change", "a_list", (1, 2), None)] - async def test_it_has_a_repr_if_we_applied_to_a_path_but_the_value_didnt_change( - self, attrs - ): - + async def test_it_has_a_repr_if_we_applied_to_a_path_but_the_value_didnt_change(self, attrs): class Unpoppable(list): def __init__(self): super().__init__() @@ -353,7 +340,6 @@ async def test_it_has_a_repr_if_we_applied_to_a_path(self, attrs): class TestAttrs: - @pytest.fixture() def final_future(self): fut = hp.create_future() @@ -401,9 +387,7 @@ async def test_it_says_if_something_is_inside_attrs(self, attrs): assert attrs.one == 3 assert attrs["one"] == 3 - def test_it_complains_if_you_try_to_set_things_on_the_attrs_with_item_or_attr_syntax( - self, attrs - ): + def test_it_complains_if_you_try_to_set_things_on_the_attrs_with_item_or_attr_syntax(self, attrs): assert "nup" not in attrs with assertRaises(TypeError, "'Attrs' object does not support item assignment"): attrs["nup"] = 3 @@ -506,9 +490,7 @@ async def test_it_records_what_is_changed(self, device, attrs, record, final_fut "three": "blah", } - async def test_it_hides_changes_if_the_attrs_havent_started_yet( - self, device, attrs, record, final_future - ): + async def test_it_hides_changes_if_the_attrs_havent_started_yet(self, device, attrs, record, final_future): device.value_store["has_io"] = False device.value_store["test_console_record"] = record diff --git a/modules/tests/photons_app_tests/mimic/test_device.py b/modules/tests/photons_app_tests/mimic/test_device.py index b0f4c9ca..5e2b250c 100644 --- a/modules/tests/photons_app_tests/mimic/test_device.py +++ b/modules/tests/photons_app_tests/mimic/test_device.py @@ -27,9 +27,7 @@ def test_it_is_returned_from_the_sesion_on_the_device(self, device, final_future assert session.final_future is final_future assert session.device is device - async def test_it_follows_a_prepare_reset_delete_protocol_with_io_operators_started( - self, final_future, device - ): + async def test_it_follows_a_prepare_reset_delete_protocol_with_io_operators_started(self, final_future, device): called = [] async with pytest.helpers.FutureDominoes(expected=9) as futs: @@ -100,12 +98,9 @@ async def finish_session(s): "delete", ] - async def test_it_follows_a_prepare_reset_delete_protocol_even_if_io_operators_fail( - self, final_future, device - ): + async def test_it_follows_a_prepare_reset_delete_protocol_even_if_io_operators_fail(self, final_future, device): called = [] async with pytest.helpers.FutureDominoes(expected=8) as futs: - error1 = KeyError("nope") error2 = KeyError("nup") @@ -353,10 +348,7 @@ def make_state_for(self, kls, result): called.clear() # can be told to not care about getting nothing - assert ( - device.state_for(DeviceMessages.StateLocation, expect_any=False, expect_one=False) - == [] - ) + assert device.state_for(DeviceMessages.StateLocation, expect_any=False, expect_one=False) == [] assert called == [ ("io1", DeviceMessages.StateLocation, mock.ANY), ("io2", DeviceMessages.StateLocation, mock.ANY), @@ -408,7 +400,6 @@ def make_state_for(self, kls, result): called.clear() class TestPrepare: - async def test_it_instantiates_operator_collections_and_applies_options(self): info = {"device": None} @@ -503,7 +494,6 @@ def not_used(device): assert device.applied_options class TestEvents: - @pytest.fixture() def record(self): class Record: @@ -692,9 +682,7 @@ async def test_it_has_a_shortcut_to_event_with_options(self): kwarg4 = mock.Mock(name="kwarg4") ret = mock.Mock(name="ret") - event_with_options = pytest.helpers.AsyncMock( - name="event_with_options", return_value=ret - ) + event_with_options = pytest.helpers.AsyncMock(name="event_with_options", return_value=ret) device = Device("d073d5001337", Products.LCM2_A19, Device.Firmware(2, 80, 0)) @@ -702,37 +690,28 @@ async def test_it_has_a_shortcut_to_event_with_options(self): event = await device.event(Events.RESET, arg1, arg2, a=kwarg3, b=kwarg4) assert event is ret - event_with_options.assert_called_once_with( - Events.RESET, args=(arg1, arg2), kwargs={"a": kwarg3, "b": kwarg4} - ) + event_with_options.assert_called_once_with(Events.RESET, args=(arg1, arg2), kwargs={"a": kwarg3, "b": kwarg4}) class TestHelperForCreatingAndExecutingEvents: - @pytest.fixture() def mocked(self): class Mocked: def __init__(s): - s.device = Device( - "d073d5001337", Products.LCM2_A19, Device.Firmware(2, 80, 0) - ) + s.device = Device("d073d5001337", Products.LCM2_A19, Device.Firmware(2, 80, 0)) s.ret = mock.Mock(name="ret") async def execute_event(event, is_finished): return (s.ret, event, is_finished) - s.execute_event = pytest.helpers.AsyncMock( - name="execute_event", side_effect=execute_event - ) + s.execute_event = pytest.helpers.AsyncMock(name="execute_event", side_effect=execute_event) mocked = Mocked() with mock.patch.object(mocked.device, "execute_event", mocked.execute_event): yield mocked async def test_it_has_helper_for_creating_and_executing_events(self, mocked): - res = await mocked.device.event_with_options( - Events.RESET, args=(), kwargs={"old_attrs": {}} - ) + res = await mocked.device.event_with_options(Events.RESET, args=(), kwargs={"old_attrs": {}}) assert res == (mocked.ret, Events.RESET(mocked.device, old_attrs={}), None) mocked.execute_event.assert_called_once_with(res[1], res[2]) assert res[1]._exclude_viewers is False @@ -756,17 +735,13 @@ def __eq__(s, other): assert res[1]._exclude_viewers is False async def test_it_can_make_the_event_invisible_to_viewers(self, mocked): - res = await mocked.device.event_with_options( - Events.RESET, visible=False, args=(), kwargs={"old_attrs": {}} - ) + res = await mocked.device.event_with_options(Events.RESET, visible=False, args=(), kwargs={"old_attrs": {}}) assert res == (mocked.ret, Events.RESET(mocked.device, old_attrs={}), None) mocked.execute_event.assert_called_once_with(res[1], res[2]) assert res[1]._exclude_viewers is True async def test_it_can_not_execute(self, mocked): - res = await mocked.device.event_with_options( - Events.RESET, execute=False, args=(), kwargs={"old_attrs": {}} - ) + res = await mocked.device.event_with_options(Events.RESET, execute=False, args=(), kwargs={"old_attrs": {}}) assert res == Events.RESET(mocked.device, old_attrs={}) mocked.execute_event.assert_not_called() @@ -872,9 +847,7 @@ async def test_it_passes_reset_event_into_reset_functions_too(self, device, reco ("operator", event), ] - async def test_it_passes_on_invisible_reset_event_into_reset_functions_too( - self, device, record - ): + async def test_it_passes_on_invisible_reset_event_into_reset_functions_too(self, device, record): attr_change_event = Events.ATTRIBUTE_CHANGE( device, [ @@ -908,10 +881,7 @@ async def test_it_passes_on_invisible_reset_event_into_reset_functions_too( ("operator", event), ] - async def test_it_can_stop_going_through_operators_based_on_is_finished( - self, record, final_future - ): - + async def test_it_can_stop_going_through_operators_based_on_is_finished(self, record, final_future): class OO(Operator): def setup(s, i): s.i = i @@ -1056,7 +1026,6 @@ def intercept(operator, *v): ] async def test_it_can_temporarily_be_off(self, device, record): - def intercept(operator, *v): if operator is not None: return (operator, (*v, operator.device.has_power)) @@ -1291,9 +1260,7 @@ async def test_it_can_delete(self, device, record): async def test_it_can_annotate(self, device, record): await device.annotate("INFO", "hello there", one=1, two=2) - annotate_event = Events.ANNOTATION( - device, logging.INFO, "hello there", one=1, two=2 - ) + annotate_event = Events.ANNOTATION(device, logging.INFO, "hello there", one=1, two=2) assert record == [ ("execute_event", annotate_event, None), ("viewer", annotate_event), @@ -1303,9 +1270,7 @@ async def test_it_can_annotate(self, device, record): record.clear() await device.annotate(logging.ERROR, "hello there", one=1, two=2) - annotate_event = Events.ANNOTATION( - device, logging.ERROR, "hello there", one=1, two=2 - ) + annotate_event = Events.ANNOTATION(device, logging.ERROR, "hello there", one=1, two=2) assert record == [ ("execute_event", annotate_event, None), ("viewer", annotate_event), @@ -1325,9 +1290,7 @@ async def test_it_can_determine_if_the_device_is_discoverable(self, device, reco record.clear() assert await device.discoverable(Services.UDP, "255.255.255.255") - discoverable_event = Events.DISCOVERABLE( - device, service=Services.UDP, address="255.255.255.255" - ) + discoverable_event = Events.DISCOVERABLE(device, service=Services.UDP, address="255.255.255.255") assert record == [ ("execute_event", discoverable_event, None), ("viewer", discoverable_event), @@ -1344,9 +1307,7 @@ def intercept(operator, *v): record._intercept = intercept assert not await device.discoverable(Services.UDP, "255.255.0.255") - discoverable_event = Events.DISCOVERABLE( - device, service=Services.UDP, address="255.255.0.255" - ) + discoverable_event = Events.DISCOVERABLE(device, service=Services.UDP, address="255.255.0.255") assert record == [ ("execute_event", discoverable_event, None), ("viewer", discoverable_event), diff --git a/modules/tests/photons_app_tests/mimic/test_events.py b/modules/tests/photons_app_tests/mimic/test_events.py index e0c42391..a9c5e14c 100644 --- a/modules/tests/photons_app_tests/mimic/test_events.py +++ b/modules/tests/photons_app_tests/mimic/test_events.py @@ -72,7 +72,6 @@ def assertConsoleOutput(event, *lines): class TestConsoleFormat: class TestLinesFromError: - def assertLines(self, err, *lines): assertLines(ConsoleFormat.lines_from_error, err, *lines) @@ -88,7 +87,6 @@ def test_it_can_format_a_dictionary(self): ) def test_it_can_format_a_DelfickError(self): - class MyError(PhotonsAppError): desc = "oh noes" @@ -100,7 +98,6 @@ class MyError(PhotonsAppError): ) def test_it_can_see_an_expand_function(self): - class MyError(PhotonsAppError): desc = "oh noes" @@ -117,7 +114,6 @@ def expand(self): ) class TestLinesFromAPacket: - def assertLines(self, pkt, *lines): assertLines(ConsoleFormat.lines_from_packet, pkt, *lines) @@ -200,7 +196,6 @@ def test_it_has_or_comparison(self): assert not event.IncomingEvent | event.ResetEvent def test_it_has_a_name(self, device): - class MyEvent(Event): pass @@ -208,7 +203,6 @@ class MyEvent(Event): assert e.name == "d073d5001337(LCM2_A19:2,80) MyEvent" def test_it_has_a_repr(self, device): - class MyEvent(Event): pass @@ -216,7 +210,6 @@ class MyEvent(Event): assert repr(e) == "" def test_it_has_equality(self, device, device2): - class MyEvent(Event): pass @@ -236,7 +229,6 @@ class MyEvent2(Event): MyEvent(device) == (MyEvent2, device2) def test_it_has_equality_by_default_only_on_log_args_and_log_kwargs(self, device): - class MyEvent3(Event): def setup(self, *, one, two, three): self.one = one @@ -260,7 +252,6 @@ def has_same_args(self, other): MyEvent4(device, one=1, two=4, three=5) != MyEvent4(device, one=1, two=4, three=3) def test_it_has_setup(self, device, FakeTime): - got = [] with FakeTime() as t: @@ -291,7 +282,6 @@ def test_it_can_do_comparisons_with_events(self, device): assert not e | Events.POWER_OFF class TestFormattingForTheConsole: - def test_it_can_format_a_simple_event(self, device): assertConsoleOutput( Events.POWER_OFF(device), @@ -299,7 +289,6 @@ def test_it_can_format_a_simple_event(self, device): ) def test_it_can_format_an_event_with_arguments(self, device): - class Simple(Event): def setup(self): self.log_args = ("hello", "there") @@ -367,7 +356,6 @@ class Other: class TestIncomingEvent: - @pytest.fixture() def EKLS(self): return Events.INCOMING @@ -391,16 +379,13 @@ def test_it_can_do_comparisons_with_packets_and_events(self, EKLS, io, device): assert not e | Events.OUTGOING # Show doesn't apply to a different event - e = Events.OUTGOING( - device, io, pkt=DeviceMessages.GetPower(), addr="somewhere", replying_to="the test" - ) + e = Events.OUTGOING(device, io, pkt=DeviceMessages.GetPower(), addr="somewhere", replying_to="the test") assert not e | DeviceMessages.GetPower assert not e | DeviceMessages.SetPower assert not e | Events.INCOMING assert e | Events.OUTGOING def test_it_can_do_comparisons_on_the_io(self, EKLS, device): - class MyIO(Operator): io_source = "HIGHWAY_TO_INFO" @@ -504,7 +489,6 @@ def test_it_modifies_args_and_kwargs_for_console_output(self, EKLS, device, io): class TestOutgoingEvent: - @pytest.fixture() def EKLS(self): return Events.OUTGOING @@ -578,7 +562,6 @@ def test_it_modifies_args_and_kwargs_for_console_output(self, EKLS, device, io): class TestUnhandledEvent: - @pytest.fixture() def EKLS(self): return Events.UNHANDLED @@ -635,7 +618,6 @@ def test_it_modifies_args_and_kwargs_for_console_output(self, EKLS, device, io): class TestIgnoredEvent: - @pytest.fixture() def EKLS(self): return Events.IGNORED @@ -692,7 +674,6 @@ def test_it_modifies_args_and_kwargs_for_console_output(self, EKLS, device, io): class TestLostEvent: - @pytest.fixture() def EKLS(self): return Events.LOST @@ -749,7 +730,6 @@ def test_it_modifies_args_and_kwargs_for_console_output(self, EKLS, device, io): class TestAttributeChangeEvent: - @pytest.fixture() def EKLS(self): return Events.ATTRIBUTE_CHANGE @@ -792,7 +772,6 @@ def test_it_has_nicer_console_output(self, EKLS, device): class TestAnnotationEvent: - @pytest.fixture() def EKLS(self): return Events.ANNOTATION @@ -834,7 +813,6 @@ class AnError(PhotonsAppError): class TestDiscoverableEvent: - @pytest.fixture() def EKLS(self): return Events.DISCOVERABLE diff --git a/modules/tests/photons_app_tests/mimic/test_io_operator.py b/modules/tests/photons_app_tests/mimic/test_io_operator.py index ed601660..1d3f80a9 100644 --- a/modules/tests/photons_app_tests/mimic/test_io_operator.py +++ b/modules/tests/photons_app_tests/mimic/test_io_operator.py @@ -43,7 +43,6 @@ async def parent_ts(final_future): class TestIO: def test_it_has_a_packet_filter(self, device): - class IIO(IO): io_source = "iio" @@ -53,9 +52,7 @@ class IIO(IO): assert io.last_final_future is None class TestSession: - async def test_it_manages_a_queue_and_consumer_task_for_incoming_messages( - self, device, wrap_io, final_future, parent_ts - ): + async def test_it_manages_a_queue_and_consumer_task_for_incoming_messages(self, device, wrap_io, final_future, parent_ts): process = [] got = hp.ResettableFuture() @@ -95,7 +92,6 @@ async def process_incoming(s, bts, give_reply, addr): assert io.incoming.final_future.done() async def test_it_can_restart_a_session(self, device, wrap_io, final_future, parent_ts): - class IIO(IO): io_source = "iio" @@ -146,9 +142,7 @@ class IIO(IO): await queue.finish() class TestProcessInstruction: - async def test_it_puts_result_from_instruction_through_filter_and_sends_replies( - self, wrap_io, device, final_future - ): + async def test_it_puts_result_from_instruction_through_filter_and_sends_replies(self, wrap_io, device, final_future): got = [] class MyIO(IO): @@ -204,7 +198,6 @@ async def outgoing(r, e): ] class TestProcessIncoming: - @pytest.fixture() def record(self): rec = [] @@ -289,9 +282,7 @@ async def device(self, record, Responder, final_future, iokls, got_event): lambda d: iokls(d), lambda d: Listener(d), lambda d: Responder(d), - lambda d: RecordEvents( - d, {"record_events_store": record, "got_event_fut": got_event} - ), + lambda d: RecordEvents(d, {"record_events_store": record, "got_event_fut": got_event}), search_for_operators=False, ) async with device.session(final_future): @@ -307,9 +298,7 @@ async def switch(self, record, Responder, final_future, iokls, got_event): lambda d: iokls(d), lambda d: Listener(d), lambda d: Responder(d), - lambda d: RecordEvents( - d, {"record_events_store": record, "got_event_fut": got_event} - ), + lambda d: RecordEvents(d, {"record_events_store": record, "got_event_fut": got_event}), search_for_operators=False, ) async with device.session(final_future): @@ -317,9 +306,7 @@ async def switch(self, record, Responder, final_future, iokls, got_event): record.pop() yield device - async def test_it_does_nothing_if_the_device_is_offline( - self, device, sent, record, got_event - ): + async def test_it_does_nothing_if_the_device_is_offline(self, device, sent, record, got_event): io = device.io["TESTIO"] addr = ("memory", device.serial) @@ -352,9 +339,7 @@ async def test_it_can_get_and_send_back_messages(self, device, sent, record, got io = device.io["TESTIO"] addr = ("memory", device.serial) - pkt = make_packet( - DiscoveryMessages.GetService, source=3, sequence=3, target=device.serial - ) + pkt = make_packet(DiscoveryMessages.GetService, source=3, sequence=3, target=device.serial) io.received(pkt.pack().tobytes(), True, addr) while len(record) != 4: @@ -419,9 +404,7 @@ async def intercept(event, Cont): raise Cont() with intercept: - pkt = make_packet( - DeviceMessages.GetPower, source=3, sequence=3, target=device.serial - ) + pkt = make_packet(DeviceMessages.GetPower, source=3, sequence=3, target=device.serial) io.received(pkt.pack().tobytes(), True, addr) while len(record) != 4: @@ -442,9 +425,7 @@ async def intercept(event, Cont): ] record.clear() - async def test_it_can_have_unhandled_messages( - self, switch, device, sent, record, got_event - ): + async def test_it_can_have_unhandled_messages(self, switch, device, sent, record, got_event): io = device.io["TESTIO"] ioswitch = switch.io["TESTIO"] addr = ("memory", device.serial) @@ -494,9 +475,7 @@ async def test_it_can_have_unhandled_messages( ] record.clear() - async def test_it_can_not_send_replies_from_res_required_false_unless_is_a_get( - self, device, sent, record, got_event - ): + async def test_it_can_not_send_replies_from_res_required_false_unless_is_a_get(self, device, sent, record, got_event): io = device.io["TESTIO"] addr = ("memory", device.serial) @@ -549,9 +528,7 @@ async def test_it_can_lose_messages(self, device, sent, record, got_event): io = device.io["TESTIO"] addr = ("memory", device.serial) - pkt = make_packet( - DeviceMessages.SetPower, source=2, sequence=3, target=device.serial, level=65535 - ) + pkt = make_packet(DeviceMessages.SetPower, source=2, sequence=3, target=device.serial, level=65535) io.received(pkt.pack().tobytes(), True, addr) await sent sent.reset() @@ -619,9 +596,7 @@ async def test_it_can_lose_messages(self, device, sent, record, got_event): ] record.clear() - pkt = make_packet( - DeviceMessages.SetPower, source=2, sequence=5, target=device.serial, level=0 - ) + pkt = make_packet(DeviceMessages.SetPower, source=2, sequence=5, target=device.serial, level=0) with io.packet_filter.lost_replies(DeviceMessages.SetPower): io.received(pkt.pack().tobytes(), True, addr) diff --git a/modules/tests/photons_app_tests/mimic/test_operator.py b/modules/tests/photons_app_tests/mimic/test_operator.py index 02a57c1d..8dff6d1e 100644 --- a/modules/tests/photons_app_tests/mimic/test_operator.py +++ b/modules/tests/photons_app_tests/mimic/test_operator.py @@ -39,12 +39,7 @@ def assertEvents(events, *expected, ignore_annotations=True): same = nxt == ex - if ( - isinstance(ex, tuple) - and len(ex) == 2 - and isinstance(ex[1], tuple) - and isinstance(ex[1][1], Device) - ): + if isinstance(ex, tuple) and len(ex) == 2 and isinstance(ex[1], tuple) and isinstance(ex[1][1], Device): if nxtEvt.device is ex[1][1]: ex = (ex[0], (ex[1][0], "<>")) else: @@ -58,9 +53,7 @@ def assertEvents(events, *expected, ignore_annotations=True): try: if count != len(expected): - assert ( - False - ), f"Expected different number of events (expected {count} == {len(expected)})" + assert False, f"Expected different number of events (expected {count} == {len(expected)})" elif failed: assert False, "Expected correct events" finally: @@ -74,7 +67,6 @@ def test_it_can_be_got_from_the_Operator(self): assert Operator.Attr.Static is StaticSetter async def test_it_can_be_used_to_set_values_in_attrs(self, device, final_future): - class Op(Operator): attrs = [Operator.Attr.Static("three", 0), Operator.Attr.Static("two", "stuff")] @@ -101,7 +93,6 @@ def test_it_can_be_got_from_the_Operator(self): assert Operator.Attr.Lambda is LambdaSetter async def test_it_can_be_used_to_set_values_in_attrs(self, device, final_future): - class Op(Operator): class Options(dictobj.Spec): one = dictobj.Field(sb.string_spec()) @@ -134,10 +125,7 @@ class Options(dictobj.Spec): assert device.attrs.three == 1 assert device.attrs.four == 2 - async def test_it_can_default_to_use_zero_if_options_dont_determine_value( - self, device, final_future - ): - + async def test_it_can_default_to_use_zero_if_options_dont_determine_value(self, device, final_future): class Op(Operator): attrs = [ Operator.Attr.Lambda( @@ -151,9 +139,7 @@ class Op(Operator): async with device.session(final_future): assert device.attrs.thing == "stuff" - await device.attrs.attrs_apply( - device.attrs.attrs_path("thing").changer_to("yeap"), event=None - ) + await device.attrs.attrs_apply(device.attrs.attrs_path("thing").changer_to("yeap"), event=None) assert device.attrs.thing == "yeap" await device.reset(zerod=True) @@ -161,7 +147,6 @@ class Op(Operator): class TestAddingOperatorToADevice: async def test_it_adds_itself_to_the_operators_list(self, device, final_future): - class Op(Operator): pass @@ -177,7 +162,6 @@ class Op(Operator): assert not hasattr(device, "operators") async def test_it_can_be_a_viewer_instead(self, device, final_future): - class View(Viewer): pass @@ -214,7 +198,6 @@ async def apply(self): class TestCanHaveOptions: def test_it_complains_if_instantiated_with_bad_options(self, device): - class Op(Operator): class Options(Operator.Options): will_be_wrong = dictobj.Field(sb.integer_spec()) @@ -259,7 +242,6 @@ def setup(self): assert operator.device_attrs is device.attrs def test_it_defaults_to_providing_empty_dictionary_to_options(self, device): - class Op(Operator): class Options(Operator.Options): an_int = dictobj.NullableField(sb.integer_spec()) diff --git a/modules/tests/photons_app_tests/mimic/test_packet_filter.py b/modules/tests/photons_app_tests/mimic/test_packet_filter.py index e9464d90..2e7bd86c 100644 --- a/modules/tests/photons_app_tests/mimic/test_packet_filter.py +++ b/modules/tests/photons_app_tests/mimic/test_packet_filter.py @@ -22,9 +22,7 @@ def io(device): @pytest.fixture() def incoming_event(device, io): - return Events.INCOMING( - device, io, pkt=DeviceMessages.GetPower(source=20, sequence=34, target=device.serial) - ) + return Events.INCOMING(device, io, pkt=DeviceMessages.GetPower(source=20, sequence=34, target=device.serial)) class TestSendAck: @@ -58,9 +56,7 @@ class TestSendReplies: def test_it_takes_in_an_event(self, incoming_event): assert SendReplies(incoming_event).event is incoming_event - async def test_it_fills_out_each_reply_on_the_event_with_source_sequence_target_if_missing( - self, incoming_event, device - ): + async def test_it_fills_out_each_reply_on_the_event_with_source_sequence_target_if_missing(self, incoming_event, device): sr = SendReplies(incoming_event) replies = [] @@ -106,9 +102,7 @@ class TestSendUnhandled: def test_it_takes_in_an_event(self, incoming_event): assert SendUnhandled(incoming_event).event is incoming_event - async def test_it_does_not_send_a_StateUnhandled_if_firmware_doesnt_support_it( - self, device, incoming_event - ): + async def test_it_does_not_send_a_StateUnhandled_if_firmware_doesnt_support_it(self, device, incoming_event): assert not device.cap.has_unhandled su = SendUnhandled(incoming_event) @@ -143,13 +137,11 @@ async def test_it_sends_a_StateUnhandled_if_firmware_does_support_it(self, incom class TestFilter: - @pytest.fixture() def fltr(self): return Filter() class TestProcessRequest: - @pytest.fixture() def make_incoming(self, device, io): def make_incoming(serial, kls=DeviceMessages.GetPower): @@ -158,9 +150,7 @@ def make_incoming(serial, kls=DeviceMessages.GetPower): return make_incoming class TestDefaults: - async def test_it_says_yes_to_an_incoming_event_only_if_the_target_is_this_device_or_broadcast( - self, make_incoming, fltr, device - ): + async def test_it_says_yes_to_an_incoming_event_only_if_the_target_is_this_device_or_broadcast(self, make_incoming, fltr, device): assert await fltr.process_request(make_incoming("d073d5000000")) is False assert await fltr.process_request(make_incoming("d073d5000001")) is False @@ -168,9 +158,7 @@ async def test_it_says_yes_to_an_incoming_event_only_if_the_target_is_this_devic assert await fltr.process_request(make_incoming("0" * 12)) is True class TestSeeRequest: - async def test_it_looks_at_request_but_does_not_affect_outcome( - self, make_incoming, fltr, device - ): + async def test_it_looks_at_request_but_does_not_affect_outcome(self, make_incoming, fltr, device): got = [] async def intercept1(event): @@ -195,9 +183,7 @@ async def intercept2(event): assert got == [1, 2, 1, 1] class TestInterceptRequest: - async def test_it_looks_at_request_after_see_request_and_affects_outcome( - self, make_incoming, fltr, device - ): + async def test_it_looks_at_request_after_see_request_and_affects_outcome(self, make_incoming, fltr, device): got = [] async def see1(event): @@ -234,9 +220,7 @@ async def intercept2(event, Cont): assert got == ["s1", "i1", "s1", "i2", "s2", "i1", "i1"] - async def test_it_can_continue_as_normal_if_Cont_is_raised( - self, make_incoming, fltr, device - ): + async def test_it_can_continue_as_normal_if_Cont_is_raised(self, make_incoming, fltr, device): got = [] async def intercept(event, Cont): @@ -253,50 +237,29 @@ async def intercept(event, Cont): class TestLostRequest: async def test_it_causes_a_message_to_return_None(self, fltr, device, make_incoming): - await fltr.process_request( - make_incoming(device.serial, DeviceMessages.GetPower) - ) is True + await fltr.process_request(make_incoming(device.serial, DeviceMessages.GetPower)) is True with fltr.lost_request(DeviceMessages.GetPower, DeviceMessages.SetPower): - await fltr.process_request( - make_incoming(device.serial, DeviceMessages.GetPower) - ) is None - await fltr.process_request( - make_incoming("d073d5656565", DeviceMessages.GetPower) - ) is None + await fltr.process_request(make_incoming(device.serial, DeviceMessages.GetPower)) is None + await fltr.process_request(make_incoming("d073d5656565", DeviceMessages.GetPower)) is None - await fltr.process_request( - make_incoming(device.serial, DeviceMessages.SetPower) - ) is None + await fltr.process_request(make_incoming(device.serial, DeviceMessages.SetPower)) is None - await fltr.process_request( - make_incoming(device.serial, DeviceMessages.GetLabel) - ) is True + await fltr.process_request(make_incoming(device.serial, DeviceMessages.GetLabel)) is True with fltr.lost_request(DeviceMessages.SetGroup): - await fltr.process_request( - make_incoming(device.serial, DeviceMessages.GetPower) - ) is None - await fltr.process_request( - make_incoming(device.serial, DeviceMessages.GetGroup) - ) is None + await fltr.process_request(make_incoming(device.serial, DeviceMessages.GetPower)) is None + await fltr.process_request(make_incoming(device.serial, DeviceMessages.GetGroup)) is None - await fltr.process_request( - make_incoming(device.serial, DeviceMessages.GetGroup) - ) is True + await fltr.process_request(make_incoming(device.serial, DeviceMessages.GetGroup)) is True - await fltr.process_request( - make_incoming(device.serial, DeviceMessages.GetPower) - ) is True + await fltr.process_request(make_incoming(device.serial, DeviceMessages.GetPower)) is True class TestOutgoing: - @pytest.fixture() def make_incoming(self, device, io): def make_incoming(kls): - return Events.INCOMING( - device, io, pkt=kls(source=200, sequence=300, target=device.serial) - ) + return Events.INCOMING(device, io, pkt=kls(source=200, sequence=300, target=device.serial)) return make_incoming @@ -322,18 +285,14 @@ async def test_it_doesnt_give_replies_if_no_res_required(self, make_incoming, ou reply = DeviceMessages.StatePower() assert await outgoing(reply, request_event) == [] - async def test_it_doesnt_give_replies_if_no_res_required_unless_is_a_Get( - self, make_incoming, outgoing - ): + async def test_it_doesnt_give_replies_if_no_res_required_unless_is_a_Get(self, make_incoming, outgoing): request_event = make_incoming(DeviceMessages.GetPower) request_event.pkt.res_required = False reply = DeviceMessages.StatePower() assert await outgoing(reply, request_event) == [reply] class TestLostAcks: - async def test_it_can_ignore_acks_if_request_is_from_a_certain_class( - self, make_incoming, outgoing, fltr - ): + async def test_it_can_ignore_acks_if_request_is_from_a_certain_class(self, make_incoming, outgoing, fltr): request_event = make_incoming(DeviceMessages.GetPower) ack = CoreMessages.Acknowledgement() @@ -352,10 +311,7 @@ async def test_it_can_ignore_acks_if_request_is_from_a_certain_class( assert await outgoing(ack, request_event) == [ack] class TestLostReplies: - - async def test_it_can_ignore_replies_if_request_is_from_a_certain_class( - self, make_incoming, outgoing, fltr - ): + async def test_it_can_ignore_replies_if_request_is_from_a_certain_class(self, make_incoming, outgoing, fltr): request_event = make_incoming(DeviceMessages.GetPower) ack = CoreMessages.Acknowledgement() reply = DeviceMessages.StatePower() @@ -383,9 +339,7 @@ async def test_it_can_ignore_replies_if_request_is_from_a_certain_class( assert await outgoing(ack, request_event) == [ack] assert await outgoing(reply, request_event) == [reply] - async def test_it_can_ignore_replies_that_themselves_are_a_particular_class( - self, make_incoming, outgoing, fltr - ): + async def test_it_can_ignore_replies_that_themselves_are_a_particular_class(self, make_incoming, outgoing, fltr): request_event = make_incoming(DeviceMessages.GetPower) ack = CoreMessages.Acknowledgement() reply1 = DeviceMessages.StatePower() @@ -415,18 +369,14 @@ async def test_it_can_ignore_replies_that_themselves_are_a_particular_class( assert await outgoing(ack, make_incoming(DeviceMessages.SetPower)) == [ack] assert await outgoing(reply1, make_incoming(DeviceMessages.SetPower)) == [] - assert await outgoing(reply2, make_incoming(DeviceMessages.SetPower)) == [ - reply2 - ] + assert await outgoing(reply2, make_incoming(DeviceMessages.SetPower)) == [reply2] assert await outgoing(ack, request_event) == [ack] assert await outgoing(reply1, request_event) == [reply1] assert await outgoing(reply2, request_event) == [reply2] class TestSeeOutgoing: - async def test_it_looks_at_event_but_does_not_affect_outcome( - self, outgoing, make_incoming, fltr, device - ): + async def test_it_looks_at_event_but_does_not_affect_outcome(self, outgoing, make_incoming, fltr, device): request_event = make_incoming(DeviceMessages.GetPower) ack = CoreMessages.Acknowledgement() reply = DeviceMessages.StatePower() @@ -457,9 +407,7 @@ async def intercept2(rep, req_event): assert got == [1, 2, 1, 1] class TestInterceptOutgoing: - async def test_it_looks_at_outgoing_after_see_outgoing_and_affects_outcome( - self, outgoing, make_incoming, fltr, device - ): + async def test_it_looks_at_outgoing_after_see_outgoing_and_affects_outcome(self, outgoing, make_incoming, fltr, device): request_event = make_incoming(DeviceMessages.GetPower) reply1 = DeviceMessages.StatePower() reply2 = DeviceMessages.StateLabel() @@ -508,9 +456,7 @@ async def intercept2(rep, req_event, Cont): assert got == ["s1", "i1", "s1", "i2", "s2", "i1", "i1"] assert await outgoing(reply4, request_event) == [reply4] - async def test_it_can_continue_as_normal_if_Cont_is_raised( - self, make_incoming, outgoing, fltr, device - ): + async def test_it_can_continue_as_normal_if_Cont_is_raised(self, make_incoming, outgoing, fltr, device): got = [] request_event = make_incoming(DeviceMessages.GetPower) diff --git a/modules/tests/photons_app_tests/mimic/test_public_protocol.py b/modules/tests/photons_app_tests/mimic/test_public_protocol.py index 4978d0a3..40fa88d2 100644 --- a/modules/tests/photons_app_tests/mimic/test_public_protocol.py +++ b/modules/tests/photons_app_tests/mimic/test_public_protocol.py @@ -92,7 +92,6 @@ async def assertUnhandled(send): class TestLightDevice: - @pytest.fixture() def device(self): device = devices["a19"] @@ -110,22 +109,15 @@ async def test_it_responds_to_label_messages(self, device, assertResponse): [DeviceMessages.StateLabel(label="sam")], label="sam", ) - await assertResponse( - DeviceMessages.GetLabel(), [DeviceMessages.StateLabel(label="sam")], label="sam" - ) + await assertResponse(DeviceMessages.GetLabel(), [DeviceMessages.StateLabel(label="sam")], label="sam") async def test_it_responds_to_power_messages(self, device, assertResponse): await assertResponse(DeviceMessages.GetPower(), [DeviceMessages.StatePower(level=0)]) - await assertResponse( - DeviceMessages.SetPower(level=200), [DeviceMessages.StatePower(level=0)], power=200 - ) - await assertResponse( - DeviceMessages.GetPower(), [DeviceMessages.StatePower(level=200)], power=200 - ) + await assertResponse(DeviceMessages.SetPower(level=200), [DeviceMessages.StatePower(level=0)], power=200) + await assertResponse(DeviceMessages.GetPower(), [DeviceMessages.StatePower(level=200)], power=200) class TestSwitchDevice: - @pytest.fixture() def device(self): device = devices["switch"] @@ -153,19 +145,14 @@ async def test_it_responds_to_label_messages(self, device, assertResponse): [DeviceMessages.StateLabel(label="sam")], label="sam", ) - await assertResponse( - DeviceMessages.GetLabel(), [DeviceMessages.StateLabel(label="sam")], label="sam" - ) + await assertResponse(DeviceMessages.GetLabel(), [DeviceMessages.StateLabel(label="sam")], label="sam") - async def test_it_replies_to_light_messages_with_a_StateUnhandled_packet( - self, device, assertUnhandled - ): + async def test_it_replies_to_light_messages_with_a_StateUnhandled_packet(self, device, assertUnhandled): await assertUnhandled(LightMessages.GetColor()) await assertUnhandled(LightMessages.GetLightPower()) class TestLightState: - @pytest.fixture() def device(self): device = devices["a19"] @@ -183,15 +170,10 @@ async def test_it_responds_to_light_power_messages(self, device, assertResponse) [LightMessages.StateLightPower(level=0)], power=200, ) - await assertResponse( - DeviceMessages.GetPower(), [DeviceMessages.StatePower(level=200)], power=200 - ) - await assertResponse( - LightMessages.GetLightPower(), [DeviceMessages.StatePower(level=200)], power=200 - ) + await assertResponse(DeviceMessages.GetPower(), [DeviceMessages.StatePower(level=200)], power=200) + await assertResponse(LightMessages.GetLightPower(), [DeviceMessages.StatePower(level=200)], power=200) async def test_it_responds_to_Color_messages(self, async_timeout, device, assertResponse): - def light_state(label, power, hue, saturation, brightness, kelvin): return LightMessages.LightState.create( label=label, @@ -211,36 +193,26 @@ def light_state(label, power, hue, saturation, brightness, kelvin): ) await assertResponse(LightMessages.GetColor(), [light_state("bob", 0, 0, 0, 1, 3500)]) - await assertResponse( - DeviceMessages.SetPower(level=300), [DeviceMessages.StatePower(level=0)], power=300 - ) + await assertResponse(DeviceMessages.SetPower(level=300), [DeviceMessages.StatePower(level=0)], power=300) await assertResponse(LightMessages.GetColor(), [light_state("bob", 300, 0, 0, 1, 3500)]) await assertResponse( LightMessages.SetColor(hue=100, saturation=0.5, brightness=0.5, kelvin=4500), [light_state("bob", 300, 0, 0, 1, 3500)], ) - await assertResponse( - LightMessages.GetColor(), [light_state("bob", 300, 100, 0.5, 0.5, 4500)] - ) + await assertResponse(LightMessages.GetColor(), [light_state("bob", 300, 100, 0.5, 0.5, 4500)]) await assertResponse( - LightMessages.SetWaveform( - hue=200, saturation=0.6, brightness=0.4, kelvin=9000, waveform=Waveform.SAW - ), + LightMessages.SetWaveform(hue=200, saturation=0.6, brightness=0.4, kelvin=9000, waveform=Waveform.SAW), [light_state("bob", 300, 100, 0.5, 0.5, 4500)], ) - await assertResponse( - LightMessages.GetColor(), [light_state("bob", 300, 200, 0.6, 0.4, 9000)] - ) + await assertResponse(LightMessages.GetColor(), [light_state("bob", 300, 200, 0.6, 0.4, 9000)]) await assertResponse( LightMessages.SetWaveformOptional(hue=333), [light_state("bob", 300, 200, 0.6, 0.4, 9000)], ) - await assertResponse( - LightMessages.GetColor(), [light_state("bob", 300, 333, 0.6, 0.4, 9000)] - ) + await assertResponse(LightMessages.GetColor(), [light_state("bob", 300, 333, 0.6, 0.4, 9000)]) await assertResponse( LightMessages.SetWaveformOptional(saturation=0), @@ -262,7 +234,6 @@ def light_state(label, power, hue, saturation, brightness, kelvin): class TestInfrared: - @pytest.fixture() def device(self): device = devices["ir"] @@ -275,9 +246,7 @@ def assertResponse(self, device, **attrs): return makeAssertResponse(device, **attrs) async def test_it_responds_to_infrared_messages(self, device, assertResponse): - await assertResponse( - LightMessages.GetInfrared(), [LightMessages.StateInfrared(brightness=0)] - ) + await assertResponse(LightMessages.GetInfrared(), [LightMessages.StateInfrared(brightness=0)]) await assertResponse( LightMessages.SetInfrared(brightness=100), [LightMessages.StateInfrared(brightness=0)], @@ -310,9 +279,7 @@ async def test_it_does_respond_to_infrared_if_the_product_doesnt_have_infrared_b assertResponse = makeAssertResponse(device) - await assertResponse( - LightMessages.GetInfrared(), [LightMessages.StateInfrared(brightness=0)] - ) + await assertResponse(LightMessages.GetInfrared(), [LightMessages.StateInfrared(brightness=0)]) await assertResponse( LightMessages.SetInfrared(brightness=100), [LightMessages.StateInfrared(brightness=0)], @@ -326,7 +293,6 @@ async def test_it_does_respond_to_infrared_if_the_product_doesnt_have_infrared_b class TestMatrix: - @pytest.fixture def device(self): device = devices["tile"] @@ -368,11 +334,7 @@ async def test_it_responds_to_changing_user_position(self, device, assertRespons async def test_it_responds_to_tile_effect_messages(self, device, assertResponse): await assertResponse( TileMessages.GetTileEffect(), - [ - TileMessages.StateTileEffect.create( - type=TileEffectType.OFF, speed=0.005, palette_count=0, parameters={} - ) - ], + [TileMessages.StateTileEffect.create(type=TileEffectType.OFF, speed=0.005, palette_count=0, parameters={})], ) await assertResponse( TileMessages.SetTileEffect( @@ -380,11 +342,7 @@ async def test_it_responds_to_tile_effect_messages(self, device, assertResponse) palette_count=1, palette=[hp.Color(1, 0, 1, 3500)], ), - [ - TileMessages.StateTileEffect.create( - type=TileEffectType.OFF, speed=0.005, palette_count=0, parameters={}, palette=[] - ) - ], + [TileMessages.StateTileEffect.create(type=TileEffectType.OFF, speed=0.005, palette_count=0, parameters={}, palette=[])], matrix_effect=TileEffectType.FLAME, ) await assertResponse( @@ -408,15 +366,10 @@ async def test_it_doesnt_respond_to_tile_messages_if_the_product_doesnt_have_cha assertUnhandled = makeAssertUnhandled(device) await assertUnhandled(TileMessages.GetTileEffect()) - await assertUnhandled( - TileMessages.SetTileEffect.create( - type=TileEffectType.FLAME, parameters={}, palette=[hp.Color(0, 0, 0, 3500)] - ) - ) + await assertUnhandled(TileMessages.SetTileEffect.create(type=TileEffectType.FLAME, parameters={}, palette=[hp.Color(0, 0, 0, 3500)])) class TestZones: - async def make_device(self, name, zones=None): device = devices[name] if zones is not None: @@ -431,44 +384,28 @@ async def test_it_doesnt_respond_if_we_arent_a_multizone_device(self): assertUnhandled = makeAssertUnhandled(device) await assertUnhandled(MultiZoneMessages.GetMultiZoneEffect()) - await assertUnhandled( - MultiZoneMessages.SetMultiZoneEffect.create( - type=MultiZoneEffectType.MOVE, parameters={} - ) - ) + await assertUnhandled(MultiZoneMessages.SetMultiZoneEffect.create(type=MultiZoneEffectType.MOVE, parameters={})) await assertUnhandled(MultiZoneMessages.GetColorZones(start_index=0, end_index=255)) - await assertUnhandled( - MultiZoneMessages.SetColorZones( - start_index=0, end_index=1, hue=0, saturation=1, brightness=1, kelvin=3500 - ) - ) + await assertUnhandled(MultiZoneMessages.SetColorZones(start_index=0, end_index=1, hue=0, saturation=1, brightness=1, kelvin=3500)) await assertUnhandled(MultiZoneMessages.GetExtendedColorZones()) - await assertUnhandled( - MultiZoneMessages.SetExtendedColorZones(colors=[hp.Color(0, 0, 0, 0)], colors_count=1) - ) + await assertUnhandled(MultiZoneMessages.SetExtendedColorZones(colors=[hp.Color(0, 0, 0, 0)], colors_count=1)) async def test_it_doesnt_respond_to_extended_multizone_if_we_arent_extended_multizone(self): for case in ["striplcm1", "striplcm2noextended"]: device = await self.make_device(case, zones=[hp.Color(0, 0, 0, 0)]) - devices.store(device).assertAttrs( - zones_effect=MultiZoneEffectType.OFF, zones=[hp.Color(0, 0, 0, 0)] - ) + devices.store(device).assertAttrs(zones_effect=MultiZoneEffectType.OFF, zones=[hp.Color(0, 0, 0, 0)]) assertResponse = makeAssertResponse(device) await assertResponse(MultiZoneMessages.GetMultiZoneEffect(), True) await assertResponse( - MultiZoneMessages.SetMultiZoneEffect.create( - type=MultiZoneEffectType.MOVE, parameters={} - ), + MultiZoneMessages.SetMultiZoneEffect.create(type=MultiZoneEffectType.MOVE, parameters={}), True, ) - await assertResponse( - MultiZoneMessages.GetColorZones(start_index=0, end_index=255), True - ) + await assertResponse(MultiZoneMessages.GetColorZones(start_index=0, end_index=255), True) await assertResponse( MultiZoneMessages.SetColorZones( start_index=0, @@ -483,49 +420,35 @@ async def test_it_doesnt_respond_to_extended_multizone_if_we_arent_extended_mult assertUnhandled = makeAssertUnhandled(device) await assertUnhandled(MultiZoneMessages.GetExtendedColorZones()) - await assertUnhandled( - MultiZoneMessages.SetExtendedColorZones( - colors=[hp.Color(0, 0, 0, 0)], colors_count=1 - ) - ) + await assertUnhandled(MultiZoneMessages.SetExtendedColorZones(colors=[hp.Color(0, 0, 0, 0)], colors_count=1)) async def test_it_responds_to_all_messages_if_we_have_extended_multizone(self): device = await self.make_device("striplcm2extended", zones=[hp.Color(0, 0, 0, 0)]) - devices.store(device).assertAttrs( - zones_effect=MultiZoneEffectType.OFF, zones=[hp.Color(0, 0, 0, 0)] - ) + devices.store(device).assertAttrs(zones_effect=MultiZoneEffectType.OFF, zones=[hp.Color(0, 0, 0, 0)]) assertResponse = makeAssertResponse(device) await assertResponse(MultiZoneMessages.GetMultiZoneEffect(), True) await assertResponse( - MultiZoneMessages.SetMultiZoneEffect.create( - type=MultiZoneEffectType.MOVE, parameters={} - ), + MultiZoneMessages.SetMultiZoneEffect.create(type=MultiZoneEffectType.MOVE, parameters={}), True, ) await assertResponse(MultiZoneMessages.GetColorZones(start_index=0, end_index=255), True) await assertResponse( - MultiZoneMessages.SetColorZones( - start_index=0, end_index=1, hue=0, saturation=1, brightness=1, kelvin=3500 - ), + MultiZoneMessages.SetColorZones(start_index=0, end_index=1, hue=0, saturation=1, brightness=1, kelvin=3500), True, ) await assertResponse(MultiZoneMessages.GetExtendedColorZones(), True) await assertResponse( - MultiZoneMessages.SetExtendedColorZones( - colors_count=1, zone_index=0, colors=[hp.Color(0, 0, 0, 0)] - ), + MultiZoneMessages.SetExtendedColorZones(colors_count=1, zone_index=0, colors=[hp.Color(0, 0, 0, 0)]), True, ) async def test_it_responds_to_effect_messages(self): device = await self.make_device("striplcm2extended", zones=[hp.Color(0, 0, 0, 0)]) - devices.store(device).assertAttrs( - zones_effect=MultiZoneEffectType.OFF, zones=[hp.Color(0, 0, 0, 0)] - ) + devices.store(device).assertAttrs(zones_effect=MultiZoneEffectType.OFF, zones=[hp.Color(0, 0, 0, 0)]) assertResponse = makeAssertResponse(device) @@ -534,9 +457,7 @@ async def test_it_responds_to_effect_messages(self): [MultiZoneMessages.StateMultiZoneEffect(type=MultiZoneEffectType.OFF)], ) await assertResponse( - MultiZoneMessages.SetMultiZoneEffect.create( - type=MultiZoneEffectType.MOVE, parameters={} - ), + MultiZoneMessages.SetMultiZoneEffect.create(type=MultiZoneEffectType.MOVE, parameters={}), [MultiZoneMessages.StateMultiZoneEffect(type=MultiZoneEffectType.OFF)], zones_effect=MultiZoneEffectType.MOVE, ) @@ -632,11 +553,7 @@ async def test_it_responds_to_extended_multizone(self): await assertResponse( MultiZoneMessages.GetExtendedColorZones(), - [ - MultiZoneMessages.StateExtendedColorZones( - zones_count=11, zone_index=0, colors_count=11, colors=zones - ) - ], + [MultiZoneMessages.StateExtendedColorZones(zones_count=11, zone_index=0, colors_count=11, colors=zones)], ) new_colors = [ @@ -645,14 +562,8 @@ async def test_it_responds_to_extended_multizone(self): hp.Color(300, 0.5, 0.6, 7000), ] await assertResponse( - MultiZoneMessages.SetExtendedColorZones( - zone_index=3, colors_count=3, colors=new_colors - ), - [ - MultiZoneMessages.StateExtendedColorZones( - zones_count=11, zone_index=0, colors_count=11, colors=zones - ) - ], + MultiZoneMessages.SetExtendedColorZones(zone_index=3, colors_count=3, colors=new_colors), + [MultiZoneMessages.StateExtendedColorZones(zones_count=11, zone_index=0, colors_count=11, colors=zones)], ) zones[3] = new_colors[0] @@ -660,16 +571,11 @@ async def test_it_responds_to_extended_multizone(self): zones[5] = new_colors[2] await assertResponse( MultiZoneMessages.GetExtendedColorZones(), - [ - MultiZoneMessages.StateExtendedColorZones( - zones_count=11, zone_index=0, colors_count=11, colors=zones - ) - ], + [MultiZoneMessages.StateExtendedColorZones(zones_count=11, zone_index=0, colors_count=11, colors=zones)], ) class TestProduct: - def make_device(self, name, product, firmware): device = devices[name] assert device.cap.product is product @@ -690,9 +596,7 @@ async def test_it_responds_to_GetVersion(self): ) async def test_it_responds_to_GetHostFirmware(self): - device, assertResponse = self.make_device( - "color1000", Products.LCMV4_A19_COLOR, hp.Firmware(1, 23) - ) + device, assertResponse = self.make_device("color1000", Products.LCMV4_A19_COLOR, hp.Firmware(1, 23)) device.firmware.build = 2 await assertResponse( DeviceMessages.GetHostFirmware(), @@ -707,9 +611,7 @@ async def test_it_responds_to_GetHostFirmware(self): ) async def test_it_responds_to_GetWifiFirmware(self): - device, assertResponse = self.make_device( - "color1000", Products.LCMV4_A19_COLOR, hp.Firmware(1, 23) - ) + device, assertResponse = self.make_device("color1000", Products.LCMV4_A19_COLOR, hp.Firmware(1, 23)) await assertResponse( DeviceMessages.GetWifiFirmware(), [DeviceMessages.StateWifiFirmware(build=0, version_major=0, version_minor=0)], @@ -723,7 +625,6 @@ async def test_it_responds_to_GetWifiFirmware(self): class TestGrouping: - @pytest.fixture() def device(self): return devices["a19"] @@ -739,9 +640,7 @@ async def test_it_responds_to_group(self, device, assertResponse): setter = DeviceMessages.SetGroup.create(group="dcba", label="gl2", updated_at=3) state = DeviceMessages.StateGroup(group=setter.group, label="gl2", updated_at=3) - await assertResponse( - setter, [state], group=Collection(label="gl2", identity=setter.group, updated_at=3) - ) + await assertResponse(setter, [state], group=Collection(label="gl2", identity=setter.group, updated_at=3)) await assertResponse( setter, [state], @@ -765,7 +664,6 @@ async def test_it_responds_to_location(self, device, assertResponse): class TestClean: - @pytest.fixture() def device(self): return devices["clean"] @@ -784,9 +682,7 @@ async def fake_the_time(self, FakeTime, MockedCallLater): def m(self, fake_the_time): return fake_the_time[1] - async def test_it_responds_to_starting_a_cycle_when_light_is_off( - self, device, assertResponse, m - ): + async def test_it_responds_to_starting_a_cycle_when_light_is_off(self, device, assertResponse, m): await device.change_one("power", 0, event=None) assert device.attrs.clean_details.enabled is False @@ -865,9 +761,7 @@ async def test_it_responds_to_starting_a_cycle_when_light_is_off( await assertResponse(getter, [state]) assert device.attrs.power == 0 - async def test_it_responds_to_starting_a_cycle_when_light_is_on( - self, device, assertResponse, m - ): + async def test_it_responds_to_starting_a_cycle_when_light_is_on(self, device, assertResponse, m): await device.change_one("power", 0xFFFF, event=None) assert device.attrs.clean_details.enabled is False @@ -954,18 +848,13 @@ async def test_it_can_change_default_duration(self, device, assertResponse, m): assert device.attrs.clean_details.default_duration_s == 69420 async def test_it_can_interrupt_a_cycle(self, device, assertResponse, m): - async def start(enable, duration): - setter = LightMessages.SetHevCycle( - enable=enable, duration_s=duration, res_required=False - ) + setter = LightMessages.SetHevCycle(enable=enable, duration_s=duration, res_required=False) await assertResponse(setter, True) async def assertRemaining(duration, remaining, last_power, result): getter = LightMessages.GetHevCycle() - state = LightMessages.StateHevCycle( - duration_s=duration, remaining_s=remaining, last_power=last_power - ) + state = LightMessages.StateHevCycle(duration_s=duration, remaining_s=remaining, last_power=last_power) await assertResponse(getter, [state]) getter = LightMessages.GetLastHevCycleResult() diff --git a/modules/tests/photons_app_tests/mimic/test_relays.py b/modules/tests/photons_app_tests/mimic/test_relays.py index 559df5dc..64a199d7 100644 --- a/modules/tests/photons_app_tests/mimic/test_relays.py +++ b/modules/tests/photons_app_tests/mimic/test_relays.py @@ -71,7 +71,6 @@ async def assertState(question, expected): class TestRelays: - @pytest.fixture() def device(self): device = devices["switch"] @@ -90,9 +89,7 @@ def assertState(self, device, **attrs): def assertEvent(self, device, **attrs): return makeAssertEvent(device, **attrs) - async def test_it_can_change_the_power_of_all_the_relays( - self, device, assertResponse, assertEvent - ): + async def test_it_can_change_the_power_of_all_the_relays(self, device, assertResponse, assertEvent): await assertResponse( DeviceMessages.GetPower(), [DeviceMessages.StatePower(level=0)], @@ -249,9 +246,7 @@ async def test_it_can_change_the_power_of_the_specified_relay(self, device, asse [DeviceMessages.StatePower(level=0)], ) - async def test_it_can_change_the_power_of_the_multiple_relays( - self, device, assertResponse, assertEvent - ): + async def test_it_can_change_the_power_of_the_multiple_relays(self, device, assertResponse, assertEvent): await assertResponse( DeviceMessages.GetPower(), [DeviceMessages.StatePower(level=0)], @@ -300,9 +295,7 @@ async def test_it_can_change_the_power_of_the_multiple_relays( [DeviceMessages.StatePower(level=0)], ) - async def test_it_returns_the_power_level_of_the_specified_relay( - self, device, assertResponse, assertState - ): + async def test_it_returns_the_power_level_of_the_specified_relay(self, device, assertResponse, assertState): await assertResponse( RelayMessages.GetRPower(relay_index=1), [RelayMessages.StateRPower(relay_index=1, level=0)], diff --git a/modules/tests/photons_app_tests/mimic/test_sender_api.py b/modules/tests/photons_app_tests/mimic/test_sender_api.py index c96b9540..8554d64f 100644 --- a/modules/tests/photons_app_tests/mimic/test_sender_api.py +++ b/modules/tests/photons_app_tests/mimic/test_sender_api.py @@ -22,9 +22,7 @@ async def respond(s, event): event.set_replies(DeviceMessages.StatePower(level=s.device_attrs.power)) elif event | DeviceMessages.SetPower: event.set_replies(DeviceMessages.StatePower(level=s.device_attrs.power)) - await s.device_attrs.attrs_apply( - s.device_attrs.attrs_path("power").changer_to(event.pkt.level), event=event - ) + await s.device_attrs.attrs_apply(s.device_attrs.attrs_path("power").changer_to(event.pkt.level), event=event) @pytest.fixture() @@ -47,7 +45,6 @@ def make_device(has_memory=True, has_udp=False, value_store=None): class TestCanSendOverMemory: - @pytest.fixture() async def device(self, final_future, make_device): device = make_device() @@ -82,9 +79,7 @@ async def test_it_can_send_and_receive_messages_using_memory_target(self, sender assert pkt | DeviceMessages.StatePower assert pkt.level == 0 - async def test_it_times_out_if_the_device_is_offline( - self, sender, device, FakeTime, MockedCallLater - ): + async def test_it_times_out_if_the_device_is_offline(self, sender, device, FakeTime, MockedCallLater): pkts = await sender(DeviceMessages.GetPower(), device.serial) assert len(pkts) == 1 pkt = pkts[0] @@ -132,7 +127,6 @@ async def test_it_times_out_if_the_device_is_offline( class TestCanSendOverUdp: - @pytest.fixture() async def device(self, final_future, make_device): device = make_device(has_udp=True, value_store={"port": 56700}) @@ -149,10 +143,7 @@ async def test_it_can_send_and_receive_messages_using_lan_target_target(self, se reference = HardCodedSerials([device.serial]) found, serials = await reference.find(sender, timeout=1) assert serials == [device.serial] - assert ( - found[binascii.unhexlify(device.serial)][Services.UDP].port - == device.io[Services.UDP.name].options.port - ) + assert found[binascii.unhexlify(device.serial)][Services.UDP].port == device.io[Services.UDP.name].options.port pkts = await sender(DeviceMessages.SetPower(level=65535), device.serial) assert len(pkts) == 1 @@ -175,9 +166,7 @@ async def test_it_can_send_and_receive_messages_using_lan_target_target(self, se assert pkt | DeviceMessages.StatePower assert pkt.level == 0 - async def test_it_times_out_if_the_device_is_offline( - self, sender, device, FakeTime, MockedCallLater - ): + async def test_it_times_out_if_the_device_is_offline(self, sender, device, FakeTime, MockedCallLater): pkts = await sender(DeviceMessages.GetPower(), device.serial) assert len(pkts) == 1 pkt = pkts[0] diff --git a/modules/tests/photons_app_tests/running_main/example/runner.py b/modules/tests/photons_app_tests/running_main/example/runner.py index bd48daeb..f8547250 100644 --- a/modules/tests/photons_app_tests/running_main/example/runner.py +++ b/modules/tests/photons_app_tests/running_main/example/runner.py @@ -11,7 +11,7 @@ class Wat(dictobj.Spec): @property def thing(self): - return "{0}.{1}".format(self.one, self.two) + return f"{self.one}.{self.two}" @addon_hook() diff --git a/modules/tests/photons_app_tests/running_main/test_running_main.py b/modules/tests/photons_app_tests/running_main/test_running_main.py index f66fe55b..1af2f920 100644 --- a/modules/tests/photons_app_tests/running_main/test_running_main.py +++ b/modules/tests/photons_app_tests/running_main/test_running_main.py @@ -16,17 +16,11 @@ def test_it_works(self): "--config", os.path.join(example_dir, "config.yml"), ], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, + capture_output=True, ) - assert process.returncode == 0, "STDERR: {}\nSTDOUT:{}".format( - process.stderr, process.stdout - ) - assert ( - process.stdout.decode().strip() - == "8AC5B50C-7278-46F8-A164-9A75E310A466.39786789-9B56-475C-8F26-D04CE48EB206" - ) + assert process.returncode == 0, f"STDERR: {process.stderr}\nSTDOUT:{process.stdout}" + assert process.stdout.decode().strip() == "8AC5B50C-7278-46F8-A164-9A75E310A466.39786789-9B56-475C-8F26-D04CE48EB206" def test_it_works_with_old_an_action(self): process = subprocess.run( @@ -37,14 +31,8 @@ def test_it_works_with_old_an_action(self): "--config", os.path.join(example_dir, "config.yml"), ], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, + capture_output=True, ) - assert process.returncode == 0, "STDERR: {}\nSTDOUT:{}".format( - process.stderr, process.stdout - ) - assert ( - process.stdout.decode().strip() - == "8AC5B50C-7278-46F8-A164-9A75E310A466.39786789-9B56-475C-8F26-D04CE48EB206" - ) + assert process.returncode == 0, f"STDERR: {process.stderr}\nSTDOUT:{process.stdout}" + assert process.stdout.decode().strip() == "8AC5B50C-7278-46F8-A164-9A75E310A466.39786789-9B56-475C-8F26-D04CE48EB206" diff --git a/modules/tests/photons_app_tests/tasks/test_register.py b/modules/tests/photons_app_tests/tasks/test_register.py index 1f70a7a7..e14c0db0 100644 --- a/modules/tests/photons_app_tests/tasks/test_register.py +++ b/modules/tests/photons_app_tests/tasks/test_register.py @@ -65,7 +65,6 @@ def test_it_returns_if_we_contain_a_task_with_a_particular_name(self, register): assert t2 not in register def test_it_can_give_specs_to_a_class(self, register): - class T(register.Task): req_targ1 = register.requires_target() req_targ2 = register.requires_target(target_types=["lan"]) @@ -88,13 +87,9 @@ def assertField(got, want, **attrs): assert getattr(got.spec, n) == v assertField(T.req_targ1, specs.target_spec, mandatory=True) - assertField( - T.req_targ2, specs.target_spec, mandatory=True, restrictions={"target_types": ["lan"]} - ) + assertField(T.req_targ2, specs.target_spec, mandatory=True, restrictions={"target_types": ["lan"]}) assertField(T.prov_targ1, specs.target_spec, mandatory=False) - assertField( - T.prov_targ2, specs.target_spec, mandatory=False, restrictions={"target_names": ["bob"]} - ) + assertField(T.prov_targ2, specs.target_spec, mandatory=False, restrictions={"target_names": ["bob"]}) assertField(T.req_ref1, specs.reference_spec, mandatory=True, special=False) assertField(T.req_ref2, specs.reference_spec, mandatory=True, special=True) @@ -106,7 +101,6 @@ def assertField(got, want, **attrs): assert isinstance(T.art.spec.spec, sb.any_spec) class TestTaskFromAFunction: - @pytest.fixture() def collector(self): with alt_pytest_asyncio.Loop(new_loop=False): @@ -127,12 +121,8 @@ async def test_it_works(self, register, collector): herotarget = Target.FieldSpec().empty_normalise(type="hero") target_register.register_type("hero", HeroTarget) - road = mock.Mock( - name="resolvedroad", instantiated_name="road", spec=["instantiated_name"] - ) - batman = mock.Mock( - name="resolvedbatman", instantiated_name="batman", spec=["instantiated_name"] - ) + road = mock.Mock(name="resolvedroad", instantiated_name="road", spec=["instantiated_name"]) + batman = mock.Mock(name="resolvedbatman", instantiated_name="batman", spec=["instantiated_name"]) roadcreator = mock.Mock(name="roadcreator", return_value=road) batmancreator = mock.Mock(name="batmancreator", return_value=batman) @@ -185,9 +175,7 @@ async def task6(**kwargs): t6 = register.registered[0].task assert t6._original is task6 - @register.from_function( - needs_target=True, needs_reference=True, special_reference=True, label="Stuff" - ) + @register.from_function(needs_target=True, needs_reference=True, special_reference=True, label="Stuff") async def task7(**kwargs): ran["task7"] = kwargs @@ -224,9 +212,7 @@ def __eq__(s, other): } ran.clear() - action = register.fill_task( - collector, "task1", target=batman, reference="d073d5000001", artifact="stuff" - ) + action = register.fill_task(collector, "task1", target=batman, reference="d073d5000001", artifact="stuff") assert isinstance(action, t1) await action.run() assert ran == { @@ -240,12 +226,8 @@ def __eq__(s, other): ran.clear() for kls, name in ((t2, "task2"), (t3, "task3")): - if name == "task2": - - action = register.fill_task( - collector, name, reference="d073d5000001", artifact="stuff" - ) + action = register.fill_task(collector, name, reference="d073d5000001", artifact="stuff") assert isinstance(action, kls) await action.run() assert ran == { @@ -266,13 +248,9 @@ def __eq__(s, other): available_targets=["batman"], restrictions=[{"target_types": ["hero"]}], ): - register.fill_task( - collector, name, reference="d073d5000001", artifact="stuff" - ) + register.fill_task(collector, name, reference="d073d5000001", artifact="stuff") - action = register.fill_task( - collector, name, target=batman, reference="d073d5000001", artifact="stuff" - ) + action = register.fill_task(collector, name, target=batman, reference="d073d5000001", artifact="stuff") assert isinstance(action, kls) await action.run() assert ran == { @@ -293,9 +271,7 @@ def __eq__(s, other): available_targets=["batman"], restrictions=[{"target_types": ["hero"]}], ): - register.fill_task( - collector, name, target="road", reference="d073d5000001", artifact="stuff" - ) + register.fill_task(collector, name, target="road", reference="d073d5000001", artifact="stuff") action = register.fill_task(collector, "task4", reference="d073d5000001") await action.run() @@ -309,9 +285,7 @@ def __eq__(s, other): } ran.clear() - with assertRaises( - BadOption, "This task requires you specify a reference, please do so!" - ): + with assertRaises(BadOption, "This task requires you specify a reference, please do so!"): register.fill_task(collector, "task4") assert ran == {} @@ -351,17 +325,13 @@ def __eq__(s, other): } ran.clear() - with assertRaises( - BadOption, "This task requires you specify a reference, please do so!" - ): + with assertRaises(BadOption, "This task requires you specify a reference, please do so!"): register.fill_task(collector, "task6") with assertRaises(BadTarget, "This task requires you specify a target"): register.fill_task(collector, t7) - with assertRaises( - BadOption, "This task requires you specify a reference, please do so!" - ): + with assertRaises(BadOption, "This task requires you specify a reference, please do so!"): register.fill_task(collector, t7, target=batman) action = register.fill_task(collector, "task7", target=batman, reference="_") @@ -376,9 +346,7 @@ def __eq__(s, other): } ran.clear() - action = register.fill_task( - collector, "task7", target=batman, reference="_", artifact="blah" - ) + action = register.fill_task(collector, "task7", target=batman, reference="_", artifact="blah") await action.run() assert ran == { "task7": { @@ -391,7 +359,6 @@ def __eq__(s, other): ran.clear() class TestTaskFromAClass: - @pytest.fixture() def collector(self): with alt_pytest_asyncio.Loop(new_loop=False): @@ -412,12 +379,8 @@ async def test_it_works(self, register, collector): herotarget = Target.FieldSpec().empty_normalise(type="hero") target_register.register_type("hero", HeroTarget) - road = mock.Mock( - name="resolvedroad", instantiated_name="road", spec=["instantiated_name"] - ) - batman = mock.Mock( - name="resolvedbatman", instantiated_name="batman", spec=["instantiated_name"] - ) + road = mock.Mock(name="resolvedroad", instantiated_name="road", spec=["instantiated_name"]) + batman = mock.Mock(name="resolvedbatman", instantiated_name="batman", spec=["instantiated_name"]) roadcreator = mock.Mock(name="roadcreator", return_value=road) batmancreator = mock.Mock(name="batmancreator", return_value=batman) @@ -511,9 +474,7 @@ async def execute_task(self, **kwargs): } ran.clear() - action = register.fill_task( - collector, "task1", target=batman, reference="d073d5000001", artifact="stuff" - ) + action = register.fill_task(collector, "task1", target=batman, reference="d073d5000001", artifact="stuff") assert isinstance(action, t1) await action.run() assert ran == { @@ -524,12 +485,8 @@ async def execute_task(self, **kwargs): ran.clear() for kls, name in ((t2, "task2"), (t3, "task3")): - if name == "task2": - - action = register.fill_task( - collector, name, reference="d073d5000001", artifact="stuff" - ) + action = register.fill_task(collector, name, reference="d073d5000001", artifact="stuff") assert isinstance(action, kls) await action.run() assert ran == { @@ -548,13 +505,9 @@ async def execute_task(self, **kwargs): available_targets=["batman"], restrictions=[{"target_types": "hero"}], ): - register.fill_task( - collector, name, reference="d073d5000001", artifact="stuff" - ) + register.fill_task(collector, name, reference="d073d5000001", artifact="stuff") - action = register.fill_task( - collector, name, target=batman, reference="d073d5000001", artifact="stuff" - ) + action = register.fill_task(collector, name, target=batman, reference="d073d5000001", artifact="stuff") assert isinstance(action, kls) await action.run() assert ran == { @@ -573,9 +526,7 @@ async def execute_task(self, **kwargs): available_targets=["batman"], restrictions=[{"target_types": "hero"}], ): - register.fill_task( - collector, name, target="road", reference="d073d5000001", artifact="stuff" - ) + register.fill_task(collector, name, target="road", reference="d073d5000001", artifact="stuff") action = register.fill_task(collector, "task4", reference="d073d5000001") await action.run() @@ -587,9 +538,7 @@ async def execute_task(self, **kwargs): } ran.clear() - with assertRaises( - BadOption, "This task requires you specify a reference, please do so!" - ): + with assertRaises(BadOption, "This task requires you specify a reference, please do so!"): register.fill_task(collector, "task4") assert ran == {} @@ -627,17 +576,13 @@ def __eq__(s, other): } ran.clear() - with assertRaises( - BadOption, "This task requires you specify a reference, please do so!" - ): + with assertRaises(BadOption, "This task requires you specify a reference, please do so!"): register.fill_task(collector, "task6") with assertRaises(BadTarget, "This task requires you specify a target"): register.fill_task(collector, t7) - with assertRaises( - BadOption, "This task requires you specify a reference, please do so!" - ): + with assertRaises(BadOption, "This task requires you specify a reference, please do so!"): register.fill_task(collector, t7, target=batman) action = register.fill_task(collector, "task7", target=batman, reference="_") @@ -653,9 +598,7 @@ def __eq__(s, other): } ran.clear() - action = register.fill_task( - collector, "task7", target=batman, reference="_", artifact="blah" - ) + action = register.fill_task(collector, "task7", target=batman, reference="_", artifact="blah") await action.run() assert ran == { "task7": { @@ -669,7 +612,6 @@ def __eq__(s, other): ran.clear() class TestFind: - @pytest.fixture() def collector(self): with alt_pytest_asyncio.Loop(new_loop=False): @@ -678,17 +620,13 @@ def collector(self): instantiated_name="superman", spec=["instantiated_name"], ) - batman = mock.Mock( - name="resolvedbatman", instantiated_name="batman", spec=["instantiated_name"] - ) + batman = mock.Mock(name="resolvedbatman", instantiated_name="batman", spec=["instantiated_name"]) vegemite = mock.Mock( name="resolvedvegemite", instantiated_name="vegemite", spec=["instantiated_name"], ) - road = mock.Mock( - name="resolvedroad", instantiated_name="road", spec=["instantiated_name"] - ) + road = mock.Mock(name="resolvedroad", instantiated_name="road", spec=["instantiated_name"]) collector = Collector() collector.prepare(None, {}) @@ -802,9 +740,7 @@ def six3(collector, target): return register, tasks - def test_it_can_find_the_correct_task( - self, batman, superman, vegemite, road, register, collector - ): + def test_it_can_find_the_correct_task(self, batman, superman, vegemite, road, register, collector): register, tasks = register available = sorted(["One", "Two", "three", "Four", "Five", "six", "six2", "six3"]) diff --git a/modules/tests/photons_app_tests/tasks/test_register_specs.py b/modules/tests/photons_app_tests/tasks/test_register_specs.py index b813e2fa..e91c3392 100644 --- a/modules/tests/photons_app_tests/tasks/test_register_specs.py +++ b/modules/tests/photons_app_tests/tasks/test_register_specs.py @@ -52,7 +52,6 @@ def test_it_cares_not(self, meta): class TestTargetSpec: class TestWithoutAValue: class TestMandatory: - @pytest.mark.parametrize("val", [None, "", sb.NotSpecified]) def test_it_complains_if_nothing_was_specified_and_is_mandatory(self, val): spec = target_spec({}, mandatory=True) @@ -61,14 +60,11 @@ def test_it_complains_if_nothing_was_specified_and_is_mandatory(self, val): spec.normalise(Meta.empty(), val) @pytest.mark.parametrize("val", [None, "", sb.NotSpecified]) - def test_it_returns_not_specified_if_nothing_was_specified_and_isnt_mandatory( - self, val - ): + def test_it_returns_not_specified_if_nothing_was_specified_and_isnt_mandatory(self, val): spec = target_spec({}, mandatory=False) assert spec.normalise(Meta.empty(), val) is sb.NotSpecified class TestWithAValue: - @pytest.fixture() def superman(self): return mock.Mock(name="resolvedsuperman") @@ -110,9 +106,7 @@ def test_it_can_resolve_the_name(self, meta, mandatory, superman, vegemite): assert target_spec({}, mandatory=mandatory).normalise(meta, "vegemite") is vegemite @pytest.mark.parametrize("mandatory", [True, False]) - def test_it_can_resolve_the_target_if_its_already_been_resolved_in_the_past( - self, meta, mandatory, superman, vegemite - ): + def test_it_can_resolve_the_target_if_its_already_been_resolved_in_the_past(self, meta, mandatory, superman, vegemite): with assertRaises(TargetNotFound): target_spec({}, mandatory=mandatory).normalise(meta, superman) assert target_spec({}, mandatory=mandatory).normalise(meta, "superman") is superman @@ -122,44 +116,22 @@ def test_it_can_resolve_the_target_if_its_already_been_resolved_in_the_past( assert target_spec({}, mandatory=mandatory).normalise(meta, vegemite) is vegemite @pytest.mark.parametrize("mandatory", [True, False]) - def test_it_can_restrict_what_its_searching_for( - self, meta, mandatory, superman, batman, vegemite - ): + def test_it_can_restrict_what_its_searching_for(self, meta, mandatory, superman, batman, vegemite): assert target_spec({}, mandatory=mandatory).normalise(meta, "superman") is superman with assertRaises(TargetNotFound): - target_spec({"target_types": ["villian"]}, mandatory=mandatory).normalise( - meta, "superman" - ) + target_spec({"target_types": ["villian"]}, mandatory=mandatory).normalise(meta, "superman") with assertRaises(TargetNotFound): - target_spec({"target_types": ["villian"]}, mandatory=mandatory).normalise( - meta, superman - ) - - assert ( - target_spec({"target_types": ["villian"]}, mandatory=mandatory).normalise( - meta, "vegemite" - ) - is vegemite - ) - - assert ( - target_spec({"target_names": ["batman"]}, mandatory=mandatory).normalise( - meta, "batman" - ) - is batman - ) - assert ( - target_spec({"target_names": ["batman"]}, mandatory=mandatory).normalise( - meta, batman - ) - is batman - ) + target_spec({"target_types": ["villian"]}, mandatory=mandatory).normalise(meta, superman) + + assert target_spec({"target_types": ["villian"]}, mandatory=mandatory).normalise(meta, "vegemite") is vegemite + + assert target_spec({"target_names": ["batman"]}, mandatory=mandatory).normalise(meta, "batman") is batman + assert target_spec({"target_names": ["batman"]}, mandatory=mandatory).normalise(meta, batman) is batman class TestReferenceSpec: class TestWithoutAValue: class TestMandatory: - @pytest.mark.parametrize("val", [None, "", sb.NotSpecified]) @pytest.mark.parametrize("special", [True, False]) def test_it_complains_if_nothing_was_specified_and_is_mandatory(self, val, special): @@ -169,23 +141,16 @@ def test_it_complains_if_nothing_was_specified_and_is_mandatory(self, val, speci spec.normalise(Meta.empty(), val) @pytest.mark.parametrize("val", [None, "", sb.NotSpecified]) - def test_it_returns_not_specified_if_nothing_was_specified_and_isnt_mandatory( - self, val - ): + def test_it_returns_not_specified_if_nothing_was_specified_and_isnt_mandatory(self, val): spec = reference_spec(mandatory=False, special=False) assert spec.normalise(Meta.empty(), val) is sb.NotSpecified @pytest.mark.parametrize("val", [None, "", sb.NotSpecified]) - def test_it_returns_a_reference_object_if_nothing_but_not_mandatory( - self, val, collector - ): + def test_it_returns_a_reference_object_if_nothing_but_not_mandatory(self, val, collector): spec = reference_spec(mandatory=False, special=True) - assert isinstance( - spec.normalise(Meta({"collector": collector}, []).at("test"), val), FoundSerials - ) + assert isinstance(spec.normalise(Meta({"collector": collector}, []).at("test"), val), FoundSerials) class TestWithAValue: - @pytest.fixture() def meta(self, collector): def resolve(s): @@ -195,9 +160,7 @@ def resolve(s): return Meta({"collector": collector}, []).at("test") - @pytest.mark.parametrize( - "special,mandatory", [(False, False), (False, True), (True, False), (True, True)] - ) + @pytest.mark.parametrize("special,mandatory", [(False, False), (False, True), (True, False), (True, True)]) def test_it_returns_as_is_if_not_a_string(self, meta, special, mandatory): val = HardCodedSerials([]) assert reference_spec(mandatory=mandatory, special=special).normalise(meta, val) is val @@ -208,9 +171,7 @@ def test_it_returns_as_is_if_a_string_and_special_is_False(self, meta, mandatory assert reference_spec(mandatory=mandatory, special=False).normalise(meta, val) is val @pytest.mark.parametrize("mandatory", [False, True]) - def test_it_creates_a_reference_object_if_special_is_true_and_val_is_a_string( - self, meta, mandatory - ): + def test_it_creates_a_reference_object_if_special_is_true_and_val_is_a_string(self, meta, mandatory): spec = reference_spec(mandatory=mandatory, special=True) result = spec.normalise(meta, "match:cap=hev") diff --git a/modules/tests/photons_app_tests/tasks/test_runner.py b/modules/tests/photons_app_tests/tasks/test_runner.py index bb516f49..dfbb453d 100644 --- a/modules/tests/photons_app_tests/tasks/test_runner.py +++ b/modules/tests/photons_app_tests/tasks/test_runner.py @@ -85,7 +85,6 @@ async def cleanup2(): assert called == [1, 2, 3, 4, "c1a", "c1b", "c2a", "c2b"] def test_it_cleans_up_after_we_finish_task_if_its_cancelled_outside(self, collector): - called = [] class T(Task): @@ -127,10 +126,7 @@ async def cleanup2(): assert called == [1, 2, 3, 4, "c1a", "c1b", "c2a", "c2b"] - def test_it_exceptions_stop_the_task_holder_unless_ApplicationStopped_for_a_graceful_task( - self, collector - ): - + def test_it_exceptions_stop_the_task_holder_unless_ApplicationStopped_for_a_graceful_task(self, collector): called = [] class TaskHolder: @@ -168,9 +164,7 @@ async def execute_task(s, name, exc, **kwargs): raise exc async def post(s, exc_info, name, **kwargs): - called.append( - ("graceful post", name, getattr(exc_info[0], "__name__", exc_info[0])) - ) + called.append(("graceful post", name, getattr(exc_info[0], "__name__", exc_info[0]))) for t in (T, G): with assertRaises(ApplicationCancelled): diff --git a/modules/tests/photons_app_tests/tasks/test_runner_signals.py b/modules/tests/photons_app_tests/tasks/test_runner_signals.py index f7282420..5281163b 100644 --- a/modules/tests/photons_app_tests/tasks/test_runner_signals.py +++ b/modules/tests/photons_app_tests/tasks/test_runner_signals.py @@ -81,7 +81,6 @@ async def run( *, code, ): - fut = hp.create_future() def ready(signum, frame): @@ -410,9 +409,7 @@ async def test_it_doesnt_kill_task_when_graceful_happens(self, sig): class H(GracefulTask): """Run inside an external script during test via subprocess""" - async def execute_task( - self, collector, notify, output, graceful_final_future, **kwargs - ): + async def execute_task(self, collector, notify, output, graceful_final_future, **kwargs): notify() if sys.argv[3] != "None": await hp.wait_for_all_futures(graceful_final_future) @@ -447,15 +444,11 @@ def run_loop(self, **kwargs): print("ran", file=fle) assert not self._final_future.cancelled(), "final future was cancelled" assert self._graceful.cancelled() - assert ( - self._final_future.exception() is self._error - ), "final future has wrong error" + assert self._final_future.exception() is self._error, "final future has wrong error" with open(output, "a") as fle: print("All good!", file=fle) - async def execute_task( - self, collector, notify, output, graceful_final_future, **kwargs - ): + async def execute_task(self, collector, notify, output, graceful_final_future, **kwargs): self._final_future = collector.photons_app.final_future self._graceful = graceful_final_future self._error = PhotonsAppError("HI") @@ -511,9 +504,7 @@ class L(GracefulTask): async def execute_task(self, notify, graceful_final_future, output, **kwargs): notify() - self.collector.photons_app.loop.call_soon( - self.collector.photons_app.final_future.set_exception, ValueError("NOPE") - ) + self.collector.photons_app.loop.call_soon(self.collector.photons_app.final_future.set_exception, ValueError("NOPE")) with open(output, "a") as fle: print("before", file=fle) await hp.wait_for_all_futures(graceful_final_future) diff --git a/modules/tests/photons_app_tests/tasks/test_task.py b/modules/tests/photons_app_tests/tasks/test_task.py index 02da0662..413baa7f 100644 --- a/modules/tests/photons_app_tests/tasks/test_task.py +++ b/modules/tests/photons_app_tests/tasks/test_task.py @@ -13,7 +13,6 @@ class TestTask: - @pytest.fixture() def collector(self): with alt_pytest_asyncio.Loop(new_loop=False): @@ -87,9 +86,7 @@ async def execute_task(s, **kwargs): assert got == [{"wat": 1, "blah": 2}] def test_it_has_order_of_cleanup_and_execution(self, FakeTime, MockedCallLater, collector): - got = [] - m = None with FakeTime() as t: diff --git a/modules/tests/photons_app_tests/tasks/test_task_specifier.py b/modules/tests/photons_app_tests/tasks/test_task_specifier.py index 17a7df95..e491b66e 100644 --- a/modules/tests/photons_app_tests/tasks/test_task_specifier.py +++ b/modules/tests/photons_app_tests/tasks/test_task_specifier.py @@ -47,7 +47,6 @@ def __exit__(s, exc_typ, exc, tb): class TestTaskSpecifierSpec: - @pytest.fixture() def spec(self): return task_specifier_spec() @@ -69,7 +68,6 @@ def test_it_can_split_by_last(self, spec): assert result == ("one", "three") class TestTakingInAnIterable: - def test_it_can_take_a_two_item(self, spec): result = spec.normalise(meta(), ("one", "three")) assert result == ("one", "three") @@ -184,14 +182,11 @@ def test_it_can_override_properties_on_a_target(self, spec): assert lan.default_broadcast == "255.255.255.255" def test_it_can_override_properties_with_another_target(self, spec): - class Container(Target): network = dictobj.Field(format_into=sb.any_spec, wrapper=sb.required) def extra_prepare(collector, configuration, args_dict): - collector.configuration["target_register"].register_type( - "container", Container.FieldSpec(formatter=MergedOptionStringFormatter) - ) + collector.configuration["target_register"].register_type("container", Container.FieldSpec(formatter=MergedOptionStringFormatter)) config = """ photons_app: diff --git a/modules/tests/photons_app_tests/test_collector.py b/modules/tests/photons_app_tests/test_collector.py index 1cfaa979..545fa44c 100644 --- a/modules/tests/photons_app_tests/test_collector.py +++ b/modules/tests/photons_app_tests/test_collector.py @@ -47,7 +47,6 @@ def mocks(collector, configuration, args_dict, photons_app, register): class TestCollector: - @pytest.fixture() def collector(self): with alt_pytest_asyncio.Loop(new_loop=False): @@ -59,7 +58,6 @@ def test_it_has_a_shortcut_to_the_photons_app(self, collector): assert collector.photons_app is collector.configuration["photons_app"] def test_it_has_a_shortcut_to_resolve_a_target(self): - class Target(dictobj.Spec): pass @@ -130,7 +128,6 @@ def test_it_can_be_cloned(self): assert clone2.configuration["photons_app"] is not collector.photons_app class TestExtraPrepare: - def test_it_puts_things_into_the_configuration_and_sets_up_the_addon_register(self): extra = str(uuid.uuid1()) photons_app = {"extra": extra} @@ -227,9 +224,7 @@ def R(*args): def rik(*args): register = info["register"] - assert sorted(register.addon_getter.namespaces.keys()) == sorted( - ["delfick_project.addons", "lifx.photons"] - ) + assert sorted(register.addon_getter.namespaces.keys()) == sorted(["delfick_project.addons", "lifx.photons"]) assert register.known == [("lifx.photons", "one"), ("lifx.photons", "two")] called.append("recursive_import_known") @@ -238,9 +233,7 @@ def rik(*args): def rri(): called.append("recursive_resolve_imported") - recursive_resolve_imported = mock.Mock( - name="recursive_resolve_imported", side_effect=rri - ) + recursive_resolve_imported = mock.Mock(name="recursive_resolve_imported", side_effect=rri) with mock.patch("photons_app.collector.Register", FakeRegister): with mock.patch.multiple( @@ -248,9 +241,7 @@ def rri(): recursive_import_known=recursive_import_known, recursive_resolve_imported=recursive_resolve_imported, ): - Collector().setup_addon_register( - {"addons": {"lifx.photons": ["one", "two"]}}, None - ) + Collector().setup_addon_register({"addons": {"lifx.photons": ["one", "two"]}}, None) recursive_import_known.assert_called_once_with() recursive_resolve_imported.assert_called_once_with() @@ -269,9 +260,7 @@ def R(*args): def rik(*args): register = info["register"] - assert sorted(register.addon_getter.namespaces.keys()) == sorted( - ["delfick_project.addons", "lifx.photons"] - ) + assert sorted(register.addon_getter.namespaces.keys()) == sorted(["delfick_project.addons", "lifx.photons"]) assert register.known == [ ("lifx.photons", "one"), ("lifx.photons", "two"), @@ -284,9 +273,7 @@ def rik(*args): def rri(): called.append("recursive_resolve_imported") - recursive_resolve_imported = mock.Mock( - name="recursive_resolve_imported", side_effect=rri - ) + recursive_resolve_imported = mock.Mock(name="recursive_resolve_imported", side_effect=rri) with mock.patch("photons_app.collector.Register", FakeRegister): with mock.patch.multiple( @@ -294,9 +281,7 @@ def rri(): recursive_import_known=recursive_import_known, recursive_resolve_imported=recursive_resolve_imported, ): - Collector().setup_addon_register( - {"addons": {"lifx.photons": ["one", "two"]}}, True - ) + Collector().setup_addon_register({"addons": {"lifx.photons": ["one", "two"]}}, True) recursive_import_known.assert_called_once_with() recursive_resolve_imported.assert_called_once_with() @@ -315,9 +300,7 @@ def R(*args): def rik(*args): register = info["register"] - assert sorted(register.addon_getter.namespaces.keys()) == sorted( - ["delfick_project.addons", "lifx.photons"] - ) + assert sorted(register.addon_getter.namespaces.keys()) == sorted(["delfick_project.addons", "lifx.photons"]) assert register.known == [] called.append("recursive_import_known") @@ -326,9 +309,7 @@ def rik(*args): def rri(): called.append("recursive_resolve_imported") - recursive_resolve_imported = mock.Mock( - name="recursive_resolve_imported", side_effect=rri - ) + recursive_resolve_imported = mock.Mock(name="recursive_resolve_imported", side_effect=rri) with mock.patch("photons_app.collector.Register", FakeRegister): with mock.patch.multiple( @@ -362,9 +343,7 @@ def test_it_calls_post_register(self): }, configuration=configuration, ) - configuration.converters._converters.insert( - 0, configuration.converters._converters.pop() - ) + configuration.converters._converters.insert(0, configuration.converters._converters.pop()) configuration.converters.activate() collector.extra_prepare_after_activation(configuration, args_dict) @@ -390,9 +369,7 @@ def test_it_creates_and_sets_up_a_task_finder(self): }, configuration=configuration, ) - configuration.converters._converters.insert( - 0, configuration.converters._converters.pop() - ) + configuration.converters._converters.insert(0, configuration.converters._converters.pop()) configuration.converters.activate() collector.extra_prepare_after_activation(configuration, args_dict) @@ -419,9 +396,7 @@ def test_it_sets_up_targets(self): }, configuration=configuration, ) - configuration.converters._converters.insert( - 0, configuration.converters._converters.pop() - ) + configuration.converters._converters.insert(0, configuration.converters._converters.pop()) configuration.converters.activate() add_targets = mock.Mock(name="add_targets") @@ -430,9 +405,7 @@ def test_it_sets_up_targets(self): collector.configuration = configuration - add_targets.assert_called_once_with( - configuration["target_register"], configuration["targets"] - ) + add_targets.assert_called_once_with(configuration["target_register"], configuration["targets"]) target_register = configuration["target_register"] with assertRaises(TargetNotFound): @@ -451,9 +424,7 @@ def test_it_returns_location_to_a_photons_apprcyml(self): current_home = os.environ.get("HOME") try: os.environ["HOME"] = "/home/bob" - assert ( - Collector().home_dir_configuration_location() == "/home/bob/.photons_apprc.yml" - ) + assert Collector().home_dir_configuration_location() == "/home/bob/.photons_apprc.yml" finally: if have_current_home: os.environ["HOME"] = current_home @@ -462,7 +433,6 @@ def test_it_returns_location_to_a_photons_apprcyml(self): class TestStartConfiguration: def test_it_returns_MergedOptions_that_doesnt_prefix_dictobj_objects(self): - class D(dictobj): fields = ["one"] @@ -525,7 +495,7 @@ def test_it_removes_config_root_from_result_if_we_already_have_that_in_the_confi assert configuration["config_root"] == config_root def test_it_removes_config_root_if_its_the_home_dir_configuration(self): - home_location = "/home/bob/{0}".format(str(uuid.uuid1())) + home_location = f"/home/bob/{str(uuid.uuid1())}" configuration = MergedOptions.using({"config_root": "/home/bob"}) new_config_root = str(uuid.uuid1()) @@ -534,18 +504,12 @@ def test_it_removes_config_root_if_its_the_home_dir_configuration(self): done = {} src = str(uuid.uuid1()) - home_dir_configuration_location = mock.Mock( - name="home_dir_configuration_location", return_value=home_location - ) + home_dir_configuration_location = mock.Mock(name="home_dir_configuration_location", return_value=home_location) collect_another_source = mock.NonCallableMock(name="collect_another_source") collector = Collector() - with mock.patch.object( - collector, "home_dir_configuration_location", home_dir_configuration_location - ): - collector.add_configuration( - configuration, collect_another_source, done, result, src - ) + with mock.patch.object(collector, "home_dir_configuration_location", home_dir_configuration_location): + collector.add_configuration(configuration, collect_another_source, done, result, src) home_dir_configuration_location.assert_called_once_with() assert configuration.storage.data[0] == ( @@ -557,7 +521,7 @@ def test_it_removes_config_root_if_its_the_home_dir_configuration(self): def test_it_sets_the_source_in_terms_of_the_config_root(self): src_item = str(uuid.uuid1()) - src = "/one/two/{0}".format(src_item) + src = f"/one/two/{src_item}" configuration = MergedOptions.using({"config_root": "/one/two"}) result = {"one": 1} @@ -591,9 +555,7 @@ def cas(name): collector = Collector() with mock.patch("os.path.exists", alwaystrue), mock.patch("os.path.isfile", alwaystrue): - collector.add_configuration( - configuration, collect_another_source, done, result, src - ) + collector.add_configuration(configuration, collect_another_source, done, result, src) assert collect_another_source.mock_calls == [ mock.call("/one/two/three"), @@ -620,15 +582,12 @@ def test_it_complains_if_an_extra_source_doesnt_exist(self): filename="/one/two/three", source=src, ): - Collector().add_configuration( - configuration, collect_another_source, done, result, src - ) + Collector().add_configuration(configuration, collect_another_source, done, result, src) exists.assert_called_once_with("/one/two/three") def test_it_can_do_extra_files_before_and_after_current_configuration(self, a_temp_dir): with a_temp_dir() as (d, make_file): - make_file( "before1.yml", """ @@ -774,9 +733,7 @@ def test_it_complains_if_a_filename_is_not_a_file(self, a_temp_dir): class TestExtraConfigurationCollection: def test_it_registers_converters_for_serveral_things(self): - configuration = MergedOptions.using( - {"targets": {"one": {"type": "special", "options": {1: 2}}}} - ) + configuration = MergedOptions.using({"targets": {"one": {"type": "special", "options": {1: 2}}}}) collector = Collector() configuration["collector"] = collector diff --git a/modules/tests/photons_app_tests/test_executor.py b/modules/tests/photons_app_tests/test_executor.py index c5004cde..6288acc2 100644 --- a/modules/tests/photons_app_tests/test_executor.py +++ b/modules/tests/photons_app_tests/test_executor.py @@ -19,7 +19,6 @@ def override_loop(): class TestApp: class TestSetupCollector: - def from_config(self, config): with hp.a_temp_file() as fle: fle.write(dedent(config).encode()) @@ -91,7 +90,6 @@ def test_it_sets_up_logging_theme_if_term_colors_is_specified(self): setup_logging_theme.assert_called_once_with(logging_handler, colors="light") class TestMainline: - def using_argv(self, argv): original_mainline = mock.Mock(name="original_mainline") diff --git a/modules/tests/photons_app_tests/test_formatter.py b/modules/tests/photons_app_tests/test_formatter.py index f1feaa32..09ec7a18 100644 --- a/modules/tests/photons_app_tests/test_formatter.py +++ b/modules/tests/photons_app_tests/test_formatter.py @@ -14,7 +14,6 @@ class TestMergedOptionStringFormatter: - @pytest.fixture() def V(self): class V: @@ -23,9 +22,7 @@ class V: @hp.memoized_property def meta(s): - options = MergedOptions.using( - {"target_register": s.target_register}, dont_prefix=[mock.Mock] - ) + options = MergedOptions.using({"target_register": s.target_register}, dont_prefix=[mock.Mock]) return Meta(options, []) return V() @@ -47,7 +44,7 @@ def test_it_routes_targets_into_the_target_register_and_accesses_from_there(self def test_it_complains_if_the_key_is_not_in_all_options(self, V): key = str(uuid.uuid1()) with assertRaises(BadOptionFormat, "Can't find key in options", key=key): - V.spec.normalise(V.meta, "{{{0}}}".format(key)) + V.spec.normalise(V.meta, f"{{{key}}}") def test_it_otherwise_just_gets_keys(self, V): val = str(uuid.uuid1()) diff --git a/modules/tests/photons_app_tests/test_photons_app.py b/modules/tests/photons_app_tests/test_photons_app.py index 0611fea7..b2ab577b 100644 --- a/modules/tests/photons_app_tests/test_photons_app.py +++ b/modules/tests/photons_app_tests/test_photons_app.py @@ -18,7 +18,6 @@ def make_photons_app(**kwargs): class TestPhotonsApp: - @pytest.fixture(autouse=True) def override_loop(self): with alt_pytest_asyncio.Loop(new_loop=False): @@ -55,9 +54,7 @@ def test_it_can_read_json_from_a_file(self): with hp.a_temp_file() as fle: fle.write(b'{"power": "off"}') fle.flush() - assert make_photons_app(extra=f"file://{fle.name}").extra_as_json == { - "power": "off" - } + assert make_photons_app(extra=f"file://{fle.name}").extra_as_json == {"power": "off"} path = os.path.relpath(fle.name, os.getcwd()) assert not path.startswith("/") @@ -71,9 +68,7 @@ def test_it_can_read_json_from_a_file(self): ): fle.write(b'"power": "off"}') fle.flush() - assert make_photons_app(extra=f"file://{fle.name}").extra_as_json == { - "power": "off" - } + assert make_photons_app(extra=f"file://{fle.name}").extra_as_json == {"power": "off"} path = os.path.join(os.getcwd(), "no_exist_yo.json") with assertRaises(BadOption, f"The path {path} does not exist"): diff --git a/modules/tests/photons_app_tests/test_photons_app_spec.py b/modules/tests/photons_app_tests/test_photons_app_spec.py index 77b31d82..fce6ce61 100644 --- a/modules/tests/photons_app_tests/test_photons_app_spec.py +++ b/modules/tests/photons_app_tests/test_photons_app_spec.py @@ -17,17 +17,13 @@ class V: @hp.memoized_property def meta(s): - return Meta({"collector": s.collector, "final_future": s.final_future}, []).at( - "options" - ) + return Meta({"collector": s.collector, "final_future": s.final_future}, []).at("options") return V() class TestPhotonsAppSpec: - class TestTargetNameSpec: - @pytest.fixture() def tns(self, V): return V.spec.target_name_spec @@ -53,9 +49,7 @@ def test_it_returns_as_is_otherwise(self, tns, V): class TestPhotonsAppSpec: def test_it_gets_us_back_a_PhotonsApp(self, V): - res = V.spec.photons_app_spec.normalise( - V.meta, {"task_specifier": "blah:things", "debug": True} - ) + res = V.spec.photons_app_spec.normalise(V.meta, {"task_specifier": "blah:things", "debug": True}) assert isinstance(res, PhotonsApp) assert res.task_specifier() == ("blah", "things") assert res.debug is True diff --git a/modules/tests/photons_app_tests/test_registers.py b/modules/tests/photons_app_tests/test_registers.py index ea084fbc..65efcf00 100644 --- a/modules/tests/photons_app_tests/test_registers.py +++ b/modules/tests/photons_app_tests/test_registers.py @@ -113,7 +113,6 @@ def test_it_can_be_pickled_for_the_docs(self): class TestReferenceResolverRegister: - @pytest.fixture() def register(self): return ReferenceResolverRegister() @@ -122,13 +121,9 @@ class TestInitialization: def test_it_has_file_resolver_by_default(self, register): filename = mock.Mock(name="filename") resolver = mock.Mock(name="resolver") - FakeResolveReferencesFromFile = mock.Mock( - name="ResolveReferencesFromFile", return_value=resolver - ) + FakeResolveReferencesFromFile = mock.Mock(name="ResolveReferencesFromFile", return_value=resolver) - with mock.patch( - "photons_app.registers.ResolveReferencesFromFile", FakeResolveReferencesFromFile - ): + with mock.patch("photons_app.registers.ResolveReferencesFromFile", FakeResolveReferencesFromFile): r = register.resolve("file", filename) assert r is resolver @@ -160,9 +155,7 @@ def test_it_uses_registered_resolver(self, register): resolver.assert_called_once_with("blah") class TestGettingAReferenceObject: - def test_it_returns_SpecialReference_objects_as_is(self, register): - class Reference(SpecialReference): pass @@ -189,9 +182,7 @@ def test_it_returns_the_resolved_reference_if_of_type_typoptions(self, register) resolved = register.reference_object(reference) assert resolved is ret - def test_it_returns_a_SpecialReference_if_our_resolver_returns_not_a_special_reference( - self, register - ): + def test_it_returns_a_SpecialReference_if_our_resolver_returns_not_a_special_reference(self, register): ret = "d073d5000001,d073d5000002" wanted = [binascii.unhexlify(ref) for ref in ret.split(",")] diff --git a/modules/tests/photons_app_tests/test_special.py b/modules/tests/photons_app_tests/test_special.py index 864ce837..a66fd475 100644 --- a/modules/tests/photons_app_tests/test_special.py +++ b/modules/tests/photons_app_tests/test_special.py @@ -34,7 +34,6 @@ async def test_it_can_reset_the_futures(self): assert not ref.found.done() class TestFind: - @pytest.fixture() def V(self): class V: @@ -45,7 +44,6 @@ class V: return V() async def test_it_transfers_cancellation_from_find_serials(self, V): - class Finder(SpecialReference): async def find_serials(s, sender, *, timeout, broadcast=True): f = hp.create_future() @@ -57,7 +55,6 @@ async def find_serials(s, sender, *, timeout, broadcast=True): await ref.find(V.sender, timeout=V.find_timeout) async def test_it_transfers_exceptions_from_find_serials(self, V): - class Finder(SpecialReference): async def find_serials(s, sender, *, timeout, broadcast=True): f = hp.create_future() @@ -137,13 +134,10 @@ async def test_it_calls_senderfind_devices_with_broadcast(self): res = await ref.find_serials(sender, broadcast=broadcast, timeout=find_timeout) assert res == found - sender.find_devices.assert_called_once_with( - broadcast=broadcast, raise_on_none=True, timeout=find_timeout - ) + sender.find_devices.assert_called_once_with(broadcast=broadcast, raise_on_none=True, timeout=find_timeout) class TestHardCodedSerials: - @pytest.fixture() def V(self): class V: @@ -181,7 +175,6 @@ async def test_it_can_take_in_list_of_unhexlified_serials(self): assert ref.serials == ["d073d5000001", "d073d5000002"] class TestFindSerials: - async def assertFindSerials(self, found, serials, expected, missing): broadcast = mock.Mock(name="broadcast") find_timeout = mock.Mock(name="find_timeout") @@ -196,9 +189,7 @@ async def assertFindSerials(self, found, serials, expected, missing): assert f == expected - sender.find_specific_serials.assert_called_once_with( - serials, broadcast=broadcast, raise_on_none=False, timeout=find_timeout - ) + sender.find_specific_serials.assert_called_once_with(serials, broadcast=broadcast, raise_on_none=False, timeout=find_timeout) assert ref.missing(f) == missing @@ -216,17 +207,13 @@ async def test_it_only_returns_from_the_serials_it_cares_about(self, V): missing = [] await self.assertFindSerials(found, serials, expected, missing) - async def test_it_doesnt_call_to_find_specific_serials_if_the_serials_are_already_on_the_sender( - self, V - ): + async def test_it_doesnt_call_to_find_specific_serials_if_the_serials_are_already_on_the_sender(self, V): broadcast = mock.Mock(name="broadcast") find_timeout = mock.Mock(name="find_timeout") sender = mock.Mock(name="sender") sender.found = {V.target1: V.info1, V.target2: V.info2} - sender.find_specific_serials = pytest.helpers.AsyncMock( - name="find_specific_serials", side_effect=AssertionError("Shouldn't be called") - ) + sender.find_specific_serials = pytest.helpers.AsyncMock(name="find_specific_serials", side_effect=AssertionError("Shouldn't be called")) ref = HardCodedSerials([V.serial1]) f = await ref.find_serials(sender, broadcast=broadcast, timeout=find_timeout) @@ -272,7 +259,7 @@ async def test_it_creates_and_uses_a_HardCodedSerials(self): FakeHardCodedSerials = mock.Mock(name="HardCodedSerials", return_value=resolver) with hp.a_temp_file() as fle: - fle.write("{}\n{}".format(serial1, serial2).encode()) + fle.write(f"{serial1}\n{serial2}".encode()) fle.close() with mock.patch("photons_app.special.HardCodedSerials", FakeHardCodedSerials): diff --git a/modules/tests/photons_app_tests/test_target_register.py b/modules/tests/photons_app_tests/test_target_register.py index 3a9d719c..fccee057 100644 --- a/modules/tests/photons_app_tests/test_target_register.py +++ b/modules/tests/photons_app_tests/test_target_register.py @@ -22,7 +22,6 @@ def test_it_has_defaults(self): class TestTargetRegister: - @pytest.fixture() def reg(self): return TargetRegister() @@ -85,9 +84,7 @@ def test_it_says_no_if_empty(self, reg): assert sb.NotSpecified not in reg def test_it_says_no_if_the_name_or_target_doesnt_exist(self, reg): - road = mock.Mock( - name="resolvedroad", instantiated_name="road", spec=["instantiated_name"] - ) + road = mock.Mock(name="resolvedroad", instantiated_name="road", spec=["instantiated_name"]) assert road not in reg assert "road" not in reg @@ -95,9 +92,7 @@ def test_it_says_no_if_the_name_or_target_doesnt_exist(self, reg): infratarget = Target.FieldSpec().empty_normalise(type="infrastructure") reg.register_type("infrastructure", InfraTarget) - road = mock.Mock( - name="resolvedroad", instantiated_name="road", spec=["instantiated_name"] - ) + road = mock.Mock(name="resolvedroad", instantiated_name="road", spec=["instantiated_name"]) roadcreator = mock.Mock(name="roadcreator", return_value=road) reg.add_target("road", infratarget, roadcreator) @@ -148,18 +143,14 @@ def test_it_returns_targets_that_were_resolved(self, reg): class TestTypeFor: def test_it_returns_the_type_of_the_target(self, reg): reg.register_type("o", mock.Mock(name="oTarget")) - reg.add_target( - "one", Target.FieldSpec().empty_normalise(type="o"), mock.Mock(name="creator") - ) + reg.add_target("one", Target.FieldSpec().empty_normalise(type="o"), mock.Mock(name="creator")) assert reg.type_for("one") == "o" with assertRaises(TargetNotFound): reg.type_for("two") reg.register_type("s", mock.Mock(name="sTarget")) - reg.add_target( - "two", Target.FieldSpec().empty_normalise(type="s"), mock.Mock(name="creator") - ) + reg.add_target("two", Target.FieldSpec().empty_normalise(type="s"), mock.Mock(name="creator")) assert reg.type_for("one") == "o" assert reg.type_for("two") == "s" @@ -350,15 +341,11 @@ def test_it_changes_underlying_data(self, reg): with assertRaises(KeyError, "This dictionary is read only"): reg.registered.update({"one": 1}) - assert reg.restricted(target_names=["batman"]).registered == { - "batman": ("hero", target2, creator2) - } + assert reg.restricted(target_names=["batman"]).registered == {"batman": ("hero", target2, creator2)} assert reg.restricted(target_names=["batman", "licorice"]).registered == { "licorice": ("villian", target3, creator3), "batman": ("hero", target2, creator2), } - assert reg.restricted( - target_names=["batman", "licorice"], target_types=["villian"] - ).registered == { + assert reg.restricted(target_names=["batman", "licorice"], target_types=["villian"]).registered == { "licorice": ("villian", target3, creator3), } diff --git a/modules/tests/photons_canvas_tests/conftest.py b/modules/tests/photons_canvas_tests/conftest.py index db80a75e..e5f3d2bc 100644 --- a/modules/tests/photons_canvas_tests/conftest.py +++ b/modules/tests/photons_canvas_tests/conftest.py @@ -16,10 +16,11 @@ def modify_hsbk_calculation(): is calculated to match! """ - scaled_hue_transform = ( - lambda _, v: int(0x10000 * (0 if v is sb.NotSpecified else float(v)) / 360) % 0x10000 - ) - scaled_to_65535_transform = lambda _, v: int(0xFFFF * (0 if v is sb.NotSpecified else float(v))) + def scaled_hue_transform(_, v): + return int(0x10000 * (0 if v is sb.NotSpecified else float(v)) / 360) % 0x10000 + + def scaled_to_65535_transform(_, v): + return int(0xFFFF * (0 if v is sb.NotSpecified else float(v))) p1 = mock.patch.object(scaled_hue, "_transform", scaled_hue_transform) p2 = mock.patch.object(scaled_to_65535, "_transform", scaled_to_65535_transform) diff --git a/modules/tests/photons_canvas_tests/points/conftest.py b/modules/tests/photons_canvas_tests/points/conftest.py index 52437432..54e459b9 100644 --- a/modules/tests/photons_canvas_tests/points/conftest.py +++ b/modules/tests/photons_canvas_tests/points/conftest.py @@ -26,9 +26,7 @@ def make_part( orientation=Orientation.RightSideUp, **kwargs, ): - return cont.Part( - user_x, user_y, width, height, part_number, orientation, device, **kwargs - ) + return cont.Part(user_x, user_y, width, height, part_number, orientation, device, **kwargs) @hp.memoized_property def real_part(s): diff --git a/modules/tests/photons_canvas_tests/points/test_canvas.py b/modules/tests/photons_canvas_tests/points/test_canvas.py index c8ebef0c..a0200224 100644 --- a/modules/tests/photons_canvas_tests/points/test_canvas.py +++ b/modules/tests/photons_canvas_tests/points/test_canvas.py @@ -130,14 +130,14 @@ def test_it_can_find_the_parts_for_each_point(self, V): # e = (4, 3) -> (5, 1) # f = d + e - O = Orientation.RightSideUp + OO = Orientation.RightSideUp device1 = V.device device2 = V.other_device # Part = user_x, user_y, width, height, part_number, orientation, device - a = cont.Part(1 / 8, 6 / 8, 4, 3, 2, O, device1) - b = cont.Part(2 / 8, 6 / 8, 2, 2, 1, O, device2) + a = cont.Part(1 / 8, 6 / 8, 4, 3, 2, OO, device1) + b = cont.Part(2 / 8, 6 / 8, 2, 2, 1, OO, device2) d = cont.Part(1 / 8, 3 / 8, 4, 2, 1, 1, device1) e = cont.Part(4 / 8, 3 / 8, 2, 3, 3, 1, device1) @@ -281,7 +281,8 @@ def test_it_updates_bounds_from_objects_with_bounds_on_them(self, V): c = Canvas() assert c.bounds == ((None, None), (None, None), (None, None)) - M = lambda h, v, s: mock.Mock(name="thing", bounds=(h, v, s), spec=["bounds"]) + def M(h, v, s): + return mock.Mock(name="thing", bounds=(h, v, s), spec=["bounds"]) part1 = V.make_part(V.device, 1, user_x=1 / 8, user_y=10 / 8, width=2, height=4) @@ -356,9 +357,7 @@ def test_it_can_add_with_colors_from_parts(self, V): part1 = V.make_part(V.device, 2, user_x=-1, user_y=3, width=7, height=10) colors2 = [(i + 20, 1, 0, 3500) for i in range(72)] - part2 = V.make_part( - V.device, 1, user_x=0, user_y=3, width=8, height=9, original_colors=colors2 - ) + part2 = V.make_part(V.device, 1, user_x=0, user_y=3, width=8, height=9, original_colors=colors2) assert part1.bounds == ((-8, -1), (24, 14), (7, 10)) assert part2.bounds == ((0, 8), (24, 15), (8, 9)) @@ -379,9 +378,7 @@ def test_it_can_add_with_a_zero_color(self, V): part1 = V.make_part(V.device, 2, user_x=-1, user_y=3, width=7, height=10) colors2 = [(i + 20, 1, 0, 3500) for i in range(72)] - part2 = V.make_part( - V.device, 1, user_x=0, user_y=3, width=8, height=9, original_colors=colors2 - ) + part2 = V.make_part(V.device, 1, user_x=0, user_y=3, width=8, height=9, original_colors=colors2) assert part1.bounds == ((-8, -1), (24, 14), (7, 10)) assert part2.bounds == ((0, 8), (24, 15), (8, 9)) @@ -402,9 +399,7 @@ def test_it_can_determine_if_all_points_in_the_parts_match_certain_criteria(self assert canvas.is_parts(hue=1, brightness=1, saturation=1, kelvin=9000) colors1 = [(i, 1, 1, 3500) for i in range(64)] - part1 = V.make_part( - V.device, 1, original_colors=colors1, user_x=20, user_y=20, width=8, height=8 - ) + part1 = V.make_part(V.device, 1, original_colors=colors1, user_x=20, user_y=20, width=8, height=8) canvas = Canvas() canvas.add_parts(part1) @@ -427,9 +422,7 @@ def test_it_can_determine_if_all_points_in_the_parts_match_certain_criteria(self assert not canvas.is_parts(hue=0) colors2 = [(i, 0, 1, 9000) for i in range(64)] - part2 = V.make_part( - V.device, 2, original_colors=colors2, user_x=-20, user_y=-20, width=8, height=8 - ) + part2 = V.make_part(V.device, 2, original_colors=colors2, user_x=-20, user_y=-20, width=8, height=8) canvas.add_parts(part2, with_colors=True) assert canvas.is_parts(brightness=1) assert not canvas.is_parts(brightness=0) diff --git a/modules/tests/photons_canvas_tests/points/test_helpers.py b/modules/tests/photons_canvas_tests/points/test_helpers.py index c5dcfad6..ad72e21b 100644 --- a/modules/tests/photons_canvas_tests/points/test_helpers.py +++ b/modules/tests/photons_canvas_tests/points/test_helpers.py @@ -36,9 +36,7 @@ def test_it_can_override_properties(self): assert php.Color.override(color, kelvin=20) == (0, 1, 2, 20) - assert php.Color.override( - color, hue=30, saturation=0.9, brightness=0.1, kelvin=9000 - ) == (30, 0.9, 0.1, 9000) + assert php.Color.override(color, hue=30, saturation=0.9, brightness=0.1, kelvin=9000) == (30, 0.9, 0.1, 9000) def test_it_doesnt_allow_out_of_limits(self): color = (40, 1, 2, 3) @@ -49,16 +47,12 @@ def test_it_doesnt_allow_out_of_limits(self): assert php.Color.override(color, kelvin=-1) == (40, 1, 2, 0) want = (0, 0, 0, 0) - assert ( - php.Color.override(color, hue=-1, saturation=-1, brightness=-1, kelvin=-1) == want - ) + assert php.Color.override(color, hue=-1, saturation=-1, brightness=-1, kelvin=-1) == want assert php.Color.override(color, hue=361) == (360, 1, 2, 3) assert php.Color.override(color, saturation=1.1) == (40, 1, 2, 3) assert php.Color.override(color, brightness=1.1) == (40, 1, 1, 3) assert php.Color.override(color, kelvin=666661) == (40, 1, 2, 65535) - assert php.Color.override( - color, hue=361, saturation=1.1, brightness=1.1, kelvin=66666 - ) == (360, 1, 1, 65535) + assert php.Color.override(color, hue=361, saturation=1.1, brightness=1.1, kelvin=66666) == (360, 1, 1, 65535) class TestAdjust: def test_it_can_adjust_hue(self): @@ -105,7 +99,6 @@ def test_it_can_adjust_combination(self): class TestAverageColor: - def assertColorAlmostEqual(self, got, want): assert want[0] == pytest.approx(got[0], rel=1e-3) assert want[1] == pytest.approx(got[1], rel=1e-3) diff --git a/modules/tests/photons_canvas_tests/points/test_multizone_message_maker.py b/modules/tests/photons_canvas_tests/points/test_multizone_message_maker.py index 32bf59bd..0281e303 100644 --- a/modules/tests/photons_canvas_tests/points/test_multizone_message_maker.py +++ b/modules/tests/photons_canvas_tests/points/test_multizone_message_maker.py @@ -47,7 +47,6 @@ async def sender(final_future): class TestSetZones: - async def test_it_set_zones(self, sender): colors = [hp.Color(i, 1, 1, 3500) for i in range(16)] @@ -77,6 +76,4 @@ async def test_it_set_zones_from_a_different_start_zone(self, sender): await sender(list(maker.msgs)) for strip in devices: - assert ( - strip.attrs.zones == [hp.Color(0, 0, 0, 0), hp.Color(0, 0, 0, 0)] + colors[:-2] - ), strip + assert strip.attrs.zones == [hp.Color(0, 0, 0, 0), hp.Color(0, 0, 0, 0)] + colors[:-2], strip diff --git a/modules/tests/photons_canvas_tests/points/test_part.py b/modules/tests/photons_canvas_tests/points/test_part.py index 602bff1a..0c53b2e8 100644 --- a/modules/tests/photons_canvas_tests/points/test_part.py +++ b/modules/tests/photons_canvas_tests/points/test_part.py @@ -84,15 +84,9 @@ def test_it_can_be_compared_for_equality(self, V): assert V.part != different_part assert V.part != different_device - assert V.part == mock.Mock( - name="a part", device=V.device, part_number=5, spec=["device", "part_number"] - ) - assert V.part != mock.Mock( - name="a part", device=V.device, part_number=1, spec=["device", "part_number"] - ) - assert V.part != mock.Mock( - name="a part", device=V.other_device, part_number=5, spec=["device", "part_number"] - ) + assert V.part == mock.Mock(name="a part", device=V.device, part_number=5, spec=["device", "part_number"]) + assert V.part != mock.Mock(name="a part", device=V.device, part_number=1, spec=["device", "part_number"]) + assert V.part != mock.Mock(name="a part", device=V.other_device, part_number=5, spec=["device", "part_number"]) assert V.part == (V.device, 5) assert V.part == (V.device.serial, 5) @@ -101,7 +95,6 @@ def test_it_can_be_compared_for_equality(self, V): assert V.part != (V.other_device.serial, 5) def test_it_can_be_ordered(self, V): - parts = [ V.make_part(V.device, 2), V.make_part(V.device, 1), @@ -296,12 +289,7 @@ def test_it_returns_a_SetColor_for_bulbs(self, V): msgs = list(part.msgs(colors, duration=100)) assert len(msgs) == 1 assert msgs[0] | LightMessages.SetColor - assert ( - msgs[0].payload - == LightMessages.SetColor( - hue=100, saturation=1, brightness=0.4, kelvin=2400, duration=100 - ).payload - ) + assert msgs[0].payload == LightMessages.SetColor(hue=100, saturation=1, brightness=0.4, kelvin=2400, duration=100).payload def test_it_returns_multizone_messages_for_strips(self, V): colors = mock.Mock(name="colors", spec=[]) @@ -326,9 +314,7 @@ def test_it_returns_multizone_messages_for_strips(self, V): assert list(part.msgs(colors, duration=duration)) == [m1, m2] - FakeMultizoneMessagesMaker.assert_called_once_with( - device.serial, cap, colors, duration=duration - ) + FakeMultizoneMessagesMaker.assert_called_once_with(device.serial, cap, colors, duration=duration) FakeMultizoneMessagesMaker.reset_mock() def test_it_returns_special_Set64_message_for_a_tile(self, V): @@ -373,17 +359,13 @@ def test_it_returns_special_Set64_message_for_a_tile(self, V): assert isinstance(msgs[0], Set64) class TestCaching: - def test_it_it_sends_same_messages_or_NO_MESSAGES_depending_on_time_and_difference( - self, FakeTime, V - ): + def test_it_it_sends_same_messages_or_NO_MESSAGES_depending_on_time_and_difference(self, FakeTime, V): colors = [(i, 1, 1, 3500) for i in range(64)] device = cont.Device("d073d5001337", Products.LCM3_TILE.cap) with FakeTime() as t: t.set(2) - part = V.make_part( - device, 3, orientation=Orientation.RotatedLeft, original_colors=colors - ) + part = V.make_part(device, 3, orientation=Orientation.RotatedLeft, original_colors=colors) assert part.next_force_send == 1 msgs = part.msgs(colors, force=False) @@ -418,9 +400,7 @@ def test_it_it_sends_different_messages_if_colors_are_different(self, FakeTime, with FakeTime() as t: t.set(2) - part = V.make_part( - device, 3, orientation=Orientation.RotatedLeft, original_colors=colors - ) + part = V.make_part(device, 3, orientation=Orientation.RotatedLeft, original_colors=colors) assert part.next_force_send == 1 msgs = part.msgs(colors, force=False) diff --git a/modules/tests/photons_canvas_tests/points/test_rearrange.py b/modules/tests/photons_canvas_tests/points/test_rearrange.py index 6d6af950..d9f15f11 100644 --- a/modules/tests/photons_canvas_tests/points/test_rearrange.py +++ b/modules/tests/photons_canvas_tests/points/test_rearrange.py @@ -18,9 +18,7 @@ def test_it_creates_a_new_canvas_from_the_parts_given_by_the_rearranger(self): colors1 = [(i, 1, 1, 3500) for i in range(16)] colors2 = [(i, 0, 0, 3500) for i in range(16)] - part1 = cont.Part( - 0, 0, 4, 4, 1, Orientation.RightSideUp, device, real_part=rp1, original_colors=colors1 - ) + part1 = cont.Part(0, 0, 4, 4, 1, Orientation.RightSideUp, device, real_part=rp1, original_colors=colors1) part2 = cont.Part( 1, 0.25, @@ -98,7 +96,6 @@ def rearrange(s, canvas): class TestRearrangers: - @classmethod def make_parts(cls, *corner_and_sizes): device = cont.Device("d073d5001337", Products.LCM3_TILE.cap) @@ -153,27 +150,15 @@ def assertParts(cls, rearranger, parts, *new_corners): class TestSeparateAlignment: def test_it_aligns_separate_user_x_and_leaves_y_alignment(self): - parts = list( - TestRearrangers.make_parts((0, 1, 8, 8), (-1, 2, 4, 5), (5, 7, 3, 10), (0, 4, 8, 8)) - ) + parts = list(TestRearrangers.make_parts((0, 1, 8, 8), (-1, 2, 4, 5), (5, 7, 3, 10), (0, 4, 8, 8))) TestRearrangers.assertParts(rea.Separate(), parts, (0, 1), (8, 2), (12, 7), (15, 4)) class TestStraightAlignment: def test_it_makes_all_parts_line_up_on_the_same_y_axis(self): - parts = list( - TestRearrangers.make_parts( - (0, 1, 7, 8), (-1, 2, 4, 5), (5, 7, 3, 10), (0, 4, 20, 8) - ) - ) - TestRearrangers.assertParts( - rea.Straight(), parts, (0, 0, 1), (4, 0, 0), (11, 0, 3), (31, 0, 2) - ) + parts = list(TestRearrangers.make_parts((0, 1, 7, 8), (-1, 2, 4, 5), (5, 7, 3, 10), (0, 4, 20, 8))) + TestRearrangers.assertParts(rea.Straight(), parts, (0, 0, 1), (4, 0, 0), (11, 0, 3), (31, 0, 2)) class TestVerticalAlignment: def test_it_puts_all_parts_at_the_same_y_level(self): - parts = list( - TestRearrangers.make_parts((0, 1, 8, 8), (-1, 2, 4, 5), (5, 7, 3, 10), (0, 4, 8, 8)) - ) - TestRearrangers.assertParts( - rea.VerticalAlignment(), parts, (0, 0), (-1, 0), (5, 0), (0, 0) - ) + parts = list(TestRearrangers.make_parts((0, 1, 8, 8), (-1, 2, 4, 5), (5, 7, 3, 10), (0, 4, 8, 8))) + TestRearrangers.assertParts(rea.VerticalAlignment(), parts, (0, 0), (-1, 0), (5, 0), (0, 0)) diff --git a/modules/tests/photons_canvas_tests/points/test_set64.py b/modules/tests/photons_canvas_tests/points/test_set64.py index b73f884b..6fe6c651 100644 --- a/modules/tests/photons_canvas_tests/points/test_set64.py +++ b/modules/tests/photons_canvas_tests/points/test_set64.py @@ -94,10 +94,7 @@ def test_it_allows_you_to_create_directly_with_attributes(self): real = TileMessages.Set64.create( **{ **kwargs, - "colors": [ - {"hue": h, "saturation": s, "brightness": b, "kelvin": k} - for h, s, b, k in colors - ], + "colors": [{"hue": h, "saturation": s, "brightness": b, "kelvin": k} for h, s, b, k in colors], } ) simple = Set64(**kwargs) @@ -105,7 +102,6 @@ def test_it_allows_you_to_create_directly_with_attributes(self): assertSame(real, simple) def test_it_lets_you_modify_attributes(self): - changes = [ ("source", 10), ("sequence", 12), @@ -176,7 +172,6 @@ def test_it_can_be_cloned(self): assert msg.width == 6 def test_it_can_be_given_colors_in_multiple_ways(self, seed): - c1 = Color(100, 1, 1, 3500) c2 = Color(200, 0, 0, 3500) @@ -201,11 +196,7 @@ def test_it_can_be_given_colors_in_multiple_ways(self, seed): def test_it_can_be_given_None_as_a_valid_color(self): simple = Set64(colors=[(100, 1, 0, 3500), None, (200, 0, 1, 9000)]) - assert ( - simple.colors - == [Color(100, 1, 0, 3500), Color(0, 0, 0, 0), Color(200, 0, 1, 9000)] - + [Color(0, 0, 0, 0)] * 61 - ) + assert simple.colors == [Color(100, 1, 0, 3500), Color(0, 0, 0, 0), Color(200, 0, 1, 9000)] + [Color(0, 0, 0, 0)] * 61 def test_it_can_have_a_source_set(self): simple = Set64() diff --git a/modules/tests/photons_canvas_tests/test_font.py b/modules/tests/photons_canvas_tests/test_font.py index 57e67b55..9057ced5 100644 --- a/modules/tests/photons_canvas_tests/test_font.py +++ b/modules/tests/photons_canvas_tests/test_font.py @@ -19,7 +19,6 @@ def test_it_is_a_character_with_a_particular_width(self): class TestCharacter: - @pytest.fixture() def char(self): return font.Character( @@ -80,7 +79,6 @@ def test_it_turns_left_x_and_top_y_into_integers(self, char): class TestCharacters: - @pytest.fixture() def char1(self): class Char1(font.Character): diff --git a/modules/tests/photons_canvas_tests/test_orientation.py b/modules/tests/photons_canvas_tests/test_orientation.py index 34dc4e87..599866e0 100644 --- a/modules/tests/photons_canvas_tests/test_orientation.py +++ b/modules/tests/photons_canvas_tests/test_orientation.py @@ -21,9 +21,7 @@ def test_it_works(self): for i, o, expected in testcases: got = orientation.rotated_index(i, o) - assert ( - got == expected - ), f"Rotated {i} to {got} instead of {expected} with orientation {o.name}" + assert got == expected, f"Rotated {i} to {got} instead of {expected} with orientation {o.name}" class TestReverseOrientation: @@ -39,9 +37,7 @@ def test_it_works(self): for o, expected in testcases: got = orientation.reverse_orientation(o) - assert ( - got is expected - ), f"Expected reverse of {o.name} to be {expected.name}, got {got.name}" + assert got is expected, f"Expected reverse of {o.name} to be {expected.name}, got {got.name}" class TestNearestOrientation: @@ -60,9 +56,7 @@ def test_it_works(self): for x, y, z, expected in testcases: got = orientation.nearest_orientation(x, y, z) - assert ( - got is expected - ), f"Expected accel meas ({x}, {y}, {x}) to be orientated {expected.name}, got {got.name}" + assert got is expected, f"Expected accel meas ({x}, {y}, {x}) to be orientated {expected.name}, got {got.name}" class TestReorient: diff --git a/modules/tests/photons_canvas_tests/test_theme.py b/modules/tests/photons_canvas_tests/test_theme.py index 4ceaedef..7c614bb8 100644 --- a/modules/tests/photons_canvas_tests/test_theme.py +++ b/modules/tests/photons_canvas_tests/test_theme.py @@ -71,7 +71,6 @@ def default_async_timeout() -> float: class TestApplyTheme: - async def test_it_can_apply_a_theme(self, async_timeout, sender): async_timeout.set_timeout_seconds(15) msg = ApplyTheme.msg({}) diff --git a/modules/tests/photons_control_tests/colour/test_parser.py b/modules/tests/photons_control_tests/colour/test_parser.py index 7b1ad8cf..234c1170 100644 --- a/modules/tests/photons_control_tests/colour/test_parser.py +++ b/modules/tests/photons_control_tests/colour/test_parser.py @@ -41,7 +41,6 @@ def test_it_has_named_colors(self): assert k is None or type(k) is int class TestGettingHsbk: - def assertCorrect(self, components, h, s, b, k): assert ColourParser.hsbk(components) == (h, s, b, k) @@ -95,9 +94,7 @@ def test_it_supports_just_brightness(self): with assertRaises(InvalidColor, "Unable to parse color"): ColourParser.hsbk("brightness:-1") - error = ValueOutOfRange( - "Value was not within bounds", component="brightness", minimum=0, maximum=1, value=2 - ) + error = ValueOutOfRange("Value was not within bounds", component="brightness", minimum=0, maximum=1, value=2) with assertRaises(InvalidColor, error=error.as_dict()): ColourParser.hsbk("brightness:2") @@ -108,9 +105,7 @@ def test_it_supports_just_saturation(self): with assertRaises(InvalidColor, "Unable to parse color"): ColourParser.hsbk("saturation:-1") - error = ValueOutOfRange( - "Value was not within bounds", component="saturation", minimum=0, maximum=1, value=2 - ) + error = ValueOutOfRange("Value was not within bounds", component="saturation", minimum=0, maximum=1, value=2) with assertRaises(InvalidColor, error=error.as_dict()): ColourParser.hsbk("saturation:2") @@ -122,9 +117,7 @@ def test_it_supports_just_hue(self): with assertRaises(InvalidColor, "Unable to parse color"): ColourParser.hsbk("hue:-1") - error = ValueOutOfRange( - "Value was not within bounds", component="hue", minimum=0, maximum=360, value=361 - ) + error = ValueOutOfRange("Value was not within bounds", component="hue", minimum=0, maximum=360, value=361) with assertRaises(InvalidColor, error=error.as_dict()): ColourParser.hsbk("hue:361") @@ -138,21 +131,15 @@ def test_it_supports_rgb(self): self.assertCorrect("rgb:0,200,100", 150.0, 1.0, 0.7843137254901961, None) self.assertCorrect("rgb:10,1,255", 242.12598425196848, 0.996078431372549, 1.0, None) - error = ValueOutOfRange( - "Value was not within bounds", component="r", minimum=0, maximum=255, value=256 - ) + error = ValueOutOfRange("Value was not within bounds", component="r", minimum=0, maximum=255, value=256) with assertRaises(InvalidColor, error=error.as_dict()): ColourParser.hsbk("rgb:256,1,255") - error = ValueOutOfRange( - "Value was not within bounds", component="g", minimum=0, maximum=255, value=256 - ) + error = ValueOutOfRange("Value was not within bounds", component="g", minimum=0, maximum=255, value=256) with assertRaises(InvalidColor, error=error.as_dict()): ColourParser.hsbk("rgb:255,256,255") - error = ValueOutOfRange( - "Value was not within bounds", component="b", minimum=0, maximum=255, value=256 - ) + error = ValueOutOfRange("Value was not within bounds", component="b", minimum=0, maximum=255, value=256) with assertRaises(InvalidColor, error=error.as_dict()): ColourParser.hsbk("rgb:255,255,256") @@ -160,9 +147,7 @@ def test_it_supports_hsb(self): self.assertCorrect("hsb:240,0.1,0.8", 240, 0.1, 0.8, None) self.assertCorrect("hsb:240,1%,80%", 240, 0.01, 0.8, None) - error = ValueOutOfRange( - "Value was not within bounds", component="hue", minimum=0, maximum=360, value=361 - ) + error = ValueOutOfRange("Value was not within bounds", component="hue", minimum=0, maximum=360, value=361) with assertRaises(InvalidColor, error=error.as_dict()): ColourParser.hsbk("hsb:361,0,0.8") @@ -196,9 +181,7 @@ def test_it_supports_hsb(self): with assertRaises(InvalidColor, error=error.as_dict()): ColourParser.hsbk("hsb:240,1,120%") - error = ValueOutOfRange( - "Value was not within bounds", component="brightness", minimum=0, maximum=1, value=8 - ) + error = ValueOutOfRange("Value was not within bounds", component="brightness", minimum=0, maximum=1, value=8) with assertRaises(InvalidColor, error=error.as_dict()): ColourParser.hsbk("hsb:240,1,8") diff --git a/modules/tests/photons_control_tests/device_finder/test_collections.py b/modules/tests/photons_control_tests/device_finder/test_collections.py index a0608cd7..c23c1bdb 100644 --- a/modules/tests/photons_control_tests/device_finder/test_collections.py +++ b/modules/tests/photons_control_tests/device_finder/test_collections.py @@ -64,7 +64,6 @@ def test_it_only_adds_new_name_if_we_a_greater_timestamp(self): class TestEquality: def test_it_says_no_if_not_a_collection(self): - class Other: pass @@ -72,7 +71,6 @@ class Other: assert collection != Other() def test_it_says_no_if_not_the_same_typ(self): - class Other: pass @@ -81,7 +79,6 @@ class Other: assert collection1 != collection2 def test_it_says_no_if_not_the_same_uuid(self): - class Other: pass @@ -90,7 +87,6 @@ class Other: assert collection1 != collection2 def test_it_says_yes_if_the_same_uuid_and_typ(self): - class Other: pass @@ -99,16 +95,11 @@ class Other: assert collection1 == collection2 def test_it_says_yes_if_the_same_uuid_and_typ_even_if_names_are_different(self): - class Other: pass - collection1 = Collection.FieldSpec().empty_normalise( - uuid="stuff", typ="group", name="one" - ) - collection2 = Collection.FieldSpec().empty_normalise( - uuid="stuff", typ="group", name="two" - ) + collection1 = Collection.FieldSpec().empty_normalise(uuid="stuff", typ="group", name="one") + collection2 = Collection.FieldSpec().empty_normalise(uuid="stuff", typ="group", name="two") assert collection1 == collection2 @@ -126,7 +117,6 @@ def test_it_starts_with_a_spec_for_creating_collection_objects(self): assert collection.uuid == cuuid class TestAdding: - @pytest.fixture() def V(self): class V: @@ -170,9 +160,7 @@ def test_it_creates_the_collection_if_it_doesnt_exist(self, V): def test_it_doesnt_recreate_collection_if_it_exists(self, V): collection = mock.Mock(name="collection") collection_spec = mock.Mock(name="collection_spec") - collection_spec.empty_normalise.side_effect = Exception( - "Expect empty_normalise to not be called" - ) + collection_spec.empty_normalise.side_effect = Exception("Expect empty_normalise to not be called") V.collections.collections["location"][V.uid] = collection diff --git a/modules/tests/photons_control_tests/device_finder/test_daemon.py b/modules/tests/photons_control_tests/device_finder/test_daemon.py index d6a73e34..3a9709ca 100644 --- a/modules/tests/photons_control_tests/device_finder/test_daemon.py +++ b/modules/tests/photons_control_tests/device_finder/test_daemon.py @@ -67,7 +67,6 @@ def test_it_can_be_given_an_explicit_finder(self): assert daemon.finder is finder class TestUsage: - @pytest.fixture() def final_future(self): fut = hp.create_future() @@ -159,7 +158,6 @@ async def test_it_will_not_finish_the_finder_if_one_is_provided(self, V): finish.assert_not_called() class TestSearchLoop: - async def test_it_keeps_doing_a_search(self, V): called = [] finish_fut = hp.create_future() @@ -191,7 +189,10 @@ async def find(fltr): async def test_it_does_refresh_information_loops(self, V): called = [] - m = lambda s: Device.FieldSpec().empty_normalise(serial=s) + + def m(s): + return Device.FieldSpec().empty_normalise(serial=s) + d1 = m("d073d5000001") d2 = m("d073d5000002") @@ -255,15 +256,15 @@ async def run(): for eril in (d1ril, d2ril): assert len(eril.mock_calls) >= 3 - assert eril.mock_calls[0] == mock.call( - V.daemon.sender, V.daemon.time_between_queries, V.daemon.finder.collections - ) + assert eril.mock_calls[0] == mock.call(V.daemon.sender, V.daemon.time_between_queries, V.daemon.finder.collections) async def test_it_keeps_going_if_find_fails(self, V): called = [] async with pytest.helpers.FutureDominoes(expected=5) as futs: - m = lambda s: Device.FieldSpec().empty_normalise(serial=s) + def m(s): + return Device.FieldSpec().empty_normalise(serial=s) + d1 = m("d073d5000001") d2 = m("d073d5000002") @@ -335,7 +336,9 @@ class TestSerials: async def test_it_yields_devices_from_finderfind(self, V): fltr = Filter.from_kwargs(label="kitchen") - m = lambda s: Device.FieldSpec().empty_normalise(serial=s) + def m(s): + return Device.FieldSpec().empty_normalise(serial=s) + d1 = m("d073d5000001") d2 = m("d073d5000002") @@ -357,7 +360,9 @@ class TestInfo: async def test_it_yields_devices_from_finderinfo(self, V): fltr = Filter.from_kwargs(label="kitchen") - m = lambda s: Device.FieldSpec().empty_normalise(serial=s) + def m(s): + return Device.FieldSpec().empty_normalise(serial=s) + d1 = m("d073d5000001") d2 = m("d073d5000002") @@ -377,7 +382,6 @@ async def info(fr): class TestGettingDevicesFromTheDaemon: - @pytest.fixture() async def V(self, final_future): class V: @@ -385,9 +389,7 @@ class V: devices = pytest.helpers.mimic() d1 = devices.add("d1")(serials[0], Products.LCM3_TILE, hp.Firmware(3, 50)) - d2 = devices.add("d2")( - serials[1], Products.LCM2_Z, hp.Firmware(2, 80), value_store=dict(zones=[]) - ) + d2 = devices.add("d2")(serials[1], Products.LCM2_Z, hp.Firmware(2, 80), value_store=dict(zones=[])) d3 = devices.add("d3")( serials[2], Products.LCM2_A19, diff --git a/modules/tests/photons_control_tests/device_finder/test_device.py b/modules/tests/photons_control_tests/device_finder/test_device.py index 7fed09d4..ff37785a 100644 --- a/modules/tests/photons_control_tests/device_finder/test_device.py +++ b/modules/tests/photons_control_tests/device_finder/test_device.py @@ -19,7 +19,6 @@ class TestDevice: - @pytest.fixture() def device(self): return Device.FieldSpec().empty_normalise(serial="d073d5000001") @@ -41,12 +40,8 @@ def test_it_has_property_fields(self, device): else: assert getattr(device, field) == sb.NotSpecified - device.group = Collection.FieldSpec().empty_normalise( - typ="group", uuid="uuidg", name="blah" - ) - device.location = Collection.FieldSpec().empty_normalise( - typ="location", uuid="uuidl", name="meh" - ) + device.group = Collection.FieldSpec().empty_normalise(typ="group", uuid="uuidg", name="blah") + device.location = Collection.FieldSpec().empty_normalise(typ="location", uuid="uuidl", name="meh") assert device.group_id == "uuidg" assert device.group_name == "blah" @@ -92,9 +87,7 @@ def assertChange(field, value): assertChange("label", "kitchen") assertChange("power", "on") - assertChange( - "group", Collection.FieldSpec().empty_normalise(typ="group", uuid="uuidg", name="blah") - ) + assertChange("group", Collection.FieldSpec().empty_normalise(typ="group", uuid="uuidg", name="blah")) assertChange( "location", Collection.FieldSpec().empty_normalise(typ="location", uuid="uuidl", name="meh"), @@ -108,17 +101,13 @@ def assertChange(field, value): info["product_name"] = values["product_name"] = "LIFX Z" info["product_type"] = "light" info["product_id"] = values["product_id"] = 32 - info["cap"] = values["cap"] = pytest.helpers.has_caps_list( - "color", "multizone", "variable_color_temp" - ) + info["cap"] = values["cap"] = pytest.helpers.has_caps_list("color", "multizone", "variable_color_temp") assert device.info == info assert device.as_dict() == values device.firmware = hp.Firmware(2, 80) values["firmware_version"] = "2.80" - values["cap"] = pytest.helpers.has_caps_list( - "color", "extended_multizone", "multizone", "variable_color_temp" - ) + values["cap"] = pytest.helpers.has_caps_list("color", "extended_multizone", "multizone", "variable_color_temp") assert device.info == values assert device.as_dict() == values @@ -156,9 +145,7 @@ def has(field): device.label = "kitchen" device.power = "on" device.product_id = 22 - device.group = Collection.FieldSpec().empty_normalise( - typ="group", uuid="uuidg", name="blah" - ) + device.group = Collection.FieldSpec().empty_normalise(typ="group", uuid="uuidg", name="blah") assert device.matches_fltr(filtr) @@ -182,9 +169,7 @@ def has(field): assert sorted(filtr.matches.mock_calls) == ( sorted( [ - mock.call( - "cap", pytest.helpers.has_caps_list("color", "variable_color_temp") - ), + mock.call("cap", pytest.helpers.has_caps_list("color", "variable_color_temp")), mock.call("label", "kitchen"), mock.call("power", "on"), mock.call("product_id", 22), @@ -198,15 +183,12 @@ def has(field): ) class TestSetFromPkt: - @pytest.fixture() def collections(self): return Collections() def test_it_can_take_in_a_LightState(self, device, collections): - pkt = LightMessages.LightState.create( - label="kitchen", power=0, hue=250, saturation=0.6, brightness=0.7, kelvin=4500 - ) + pkt = LightMessages.LightState.create(label="kitchen", power=0, hue=250, saturation=0.6, brightness=0.7, kelvin=4500) assert device.set_from_pkt(pkt, collections) is InfoPoints.LIGHT_STATE @@ -218,9 +200,7 @@ def test_it_can_take_in_a_LightState(self, device, collections): assert device.kelvin == 4500 # And test when power is on - pkt = LightMessages.LightState.create( - label="kitchen", power=65535, hue=250, saturation=0.6, brightness=0.7, kelvin=4500 - ) + pkt = LightMessages.LightState.create(label="kitchen", power=65535, hue=250, saturation=0.6, brightness=0.7, kelvin=4500) assert device.set_from_pkt(pkt, collections) is InfoPoints.LIGHT_STATE assert device.power == "on" @@ -235,9 +215,7 @@ def test_it_can_take_in_StateGroup(self, device, collections): group = device.group - pkt = DeviceMessages.StateGroup.create( - group=group_uuid, updated_at=2, label="group1renamed" - ) + pkt = DeviceMessages.StateGroup.create(group=group_uuid, updated_at=2, label="group1renamed") assert device.set_from_pkt(pkt, collections) is InfoPoints.GROUP assert device.group == collections.collections["group"][group_uuid] @@ -259,9 +237,7 @@ def test_it_can_take_in_StateGroup(self, device, collections): def test_it_can_take_in_StateLocation(self, device, collections): location_uuid = str(uuid.uuid1()).replace("-", "") - pkt = DeviceMessages.StateLocation.create( - location=location_uuid, updated_at=1, label="location1" - ) + pkt = DeviceMessages.StateLocation.create(location=location_uuid, updated_at=1, label="location1") assert device.set_from_pkt(pkt, collections) is InfoPoints.LOCATION assert device.location == collections.collections["location"][location_uuid] @@ -270,9 +246,7 @@ def test_it_can_take_in_StateLocation(self, device, collections): location = device.location - pkt = DeviceMessages.StateLocation.create( - location=location_uuid, updated_at=2, label="location1renamed" - ) + pkt = DeviceMessages.StateLocation.create(location=location_uuid, updated_at=2, label="location1renamed") assert device.set_from_pkt(pkt, collections) is InfoPoints.LOCATION assert device.location == collections.collections["location"][location_uuid] @@ -281,9 +255,7 @@ def test_it_can_take_in_StateLocation(self, device, collections): assert device.location_name == "location1renamed" location_uuid2 = str(uuid.uuid1()).replace("-", "") - pkt = DeviceMessages.StateLocation.create( - location=location_uuid2, updated_at=2, label="location2" - ) + pkt = DeviceMessages.StateLocation.create(location=location_uuid2, updated_at=2, label="location2") assert device.set_from_pkt(pkt, collections) is InfoPoints.LOCATION assert device.location == collections.collections["location"][location_uuid2] @@ -320,7 +292,6 @@ def test_it_takes_in_StateVersion(self, device, collections): ] class TestPointsFromFltr: - @pytest.fixture() def RF(self): class RF: @@ -337,7 +308,6 @@ def __repr__(self): @pytest.fixture() def Points(self, device, RF): - expect = {e: RF() for e in InfoPoints} expect[None] = RF() assert device.point_futures == expect @@ -369,9 +339,7 @@ def has(s, field): def test_it_returns_all_the_InfoPoints_for_an_empty_fltr(self, device): assert list(device.points_from_fltr(Filter.empty())) == list(InfoPoints) - def test_it_only_yields_points_if_one_of_its_keys_are_on_the_fltr( - self, device, Points, Fltr - ): + def test_it_only_yields_points_if_one_of_its_keys_are_on_the_fltr(self, device, Points, Fltr): for f in device.point_futures.values(): f.set_result(True) @@ -383,9 +351,7 @@ def test_it_only_yields_points_if_one_of_its_keys_are_on_the_fltr( assert list(device.points_from_fltr(fltr)) == [Points.TWO] assert all(f.done() for f in device.point_futures.values()) - def test_it_resets_futures_if_we_have_a_refresh_info_and_a_refresh_amount( - self, device, Points, Fltr, RF - ): + def test_it_resets_futures_if_we_have_a_refresh_info_and_a_refresh_amount(self, device, Points, Fltr, RF): for f in device.point_futures.values(): f.set_result(True) @@ -399,9 +365,7 @@ def test_it_resets_futures_if_we_have_a_refresh_info_and_a_refresh_amount( Points.THREE: RF(False), } - def test_it_does_not_reset_futures_if_we_have_a_refresh_info_but_fltr_doesnt_match( - self, device, Points, Fltr, RF - ): + def test_it_does_not_reset_futures_if_we_have_a_refresh_info_but_fltr_doesnt_match(self, device, Points, Fltr, RF): for f in device.point_futures.values(): f.set_result(True) diff --git a/modules/tests/photons_control_tests/device_finder/test_filter.py b/modules/tests/photons_control_tests/device_finder/test_filter.py index a098a78e..bcd1a5c9 100644 --- a/modules/tests/photons_control_tests/device_finder/test_filter.py +++ b/modules/tests/photons_control_tests/device_finder/test_filter.py @@ -18,7 +18,6 @@ def assertFltrMatches(filtr, expect): class TestFilter: class TestConstruction: - def test_it_defaults_everything_to_NotSpecified(self): filtr = Filter.empty() assert len(filtr.fields) == 16 @@ -122,9 +121,7 @@ def test_it_works(self): class TestEmpty: def test_it_gives_back_a_filter_with_just_refresh_options(self): - assertFltrMatches( - Filter.empty(), {"refresh_info": False, "refresh_discovery": False} - ) + assertFltrMatches(Filter.empty(), {"refresh_info": False, "refresh_discovery": False}) assertFltrMatches( Filter.empty(refresh_info=True), {"refresh_info": True, "refresh_discovery": False}, @@ -261,9 +258,7 @@ def test_it_says_no_if_any_of_the_fields_are_specified(self): class TestPoints: def test_it_returns_the_InfoPoint_enums_for_the_fields_that_have_values(self): filtr = Filter.from_kwargs(label="kitchen", product_id=22) - assert set(filtr.points) == set( - [InfoPoints.LIGHT_STATE, InfoPoints.LABEL, InfoPoints.VERSION] - ) + assert set(filtr.points) == set([InfoPoints.LIGHT_STATE, InfoPoints.LABEL, InfoPoints.VERSION]) filtr = Filter.from_kwargs(group_name="one") assert set(filtr.points) == set([InfoPoints.GROUP]) diff --git a/modules/tests/photons_control_tests/device_finder/test_filter_specs.py b/modules/tests/photons_control_tests/device_finder/test_filter_specs.py index f6181e4c..ec7ce83a 100644 --- a/modules/tests/photons_control_tests/device_finder/test_filter_specs.py +++ b/modules/tests/photons_control_tests/device_finder/test_filter_specs.py @@ -36,7 +36,6 @@ def test_it_passes_through_booleans(self): assert spec.normalise(meta, [True]) is True def test_it_complains_about_anything_else(self): - class Wat: pass diff --git a/modules/tests/photons_control_tests/device_finder/test_finder.py b/modules/tests/photons_control_tests/device_finder/test_finder.py index 59ee299c..703098d9 100644 --- a/modules/tests/photons_control_tests/device_finder/test_finder.py +++ b/modules/tests/photons_control_tests/device_finder/test_finder.py @@ -49,7 +49,6 @@ def test_it_allows_you_to_specify_forget_after(self): assert finder.forget_after == 42 class TestUsage: - @pytest.fixture() def final_future(self): fut = hp.create_future() @@ -83,9 +82,7 @@ async def test_it_can_be_used_as_an_async_generator(self, V): finish.assert_called_once_with(None, None, None) async def test_it_cleans_up_its_devices_on_finish(self, V): - serials = { - s: pytest.helpers.AsyncMock(name=f"{s}_finish") for s in ("s1", "s2", "s3", "s4") - } + serials = {s: pytest.helpers.AsyncMock(name=f"{s}_finish") for s in ("s1", "s2", "s3", "s4")} patches = [] for serial, finish in serials.items(): @@ -160,11 +157,9 @@ async def assertDevices(serials, added, removed): assert rd == removed assert all(serial not in V.finder.devices for serial in removed) - assert { - d.serial: id(d) - for d in V.finder.devices.values() - if d.serial in existing and d.serial not in removed - } == {serial: d for serial, d in existing.items() if serial not in removed} + assert {d.serial: id(d) for d in V.finder.devices.values() if d.serial in existing and d.serial not in removed} == { + serial: d for serial, d in existing.items() if serial not in removed + } for serial in V.finder.devices: assert serial not in removed @@ -188,14 +183,11 @@ async def assertDevices(serials, added, removed): await assertDevices(["s1", "s5"], [], []) class TestFind: - @pytest.mark.parametrize( "fltr,matches_runs", [(Filter.empty(), False), (Filter.from_kwargs(label="kitchen"), True)], ) - async def test_it_streams_devices_that_match_the_filter( - self, V, fltr, matches_runs, fake_time - ): + async def test_it_streams_devices_that_match_the_filter(self, V, fltr, matches_runs, fake_time): t = fake_time class Patches: @@ -214,17 +206,13 @@ async def finish(exc_typ=None, exc=None, tb=None): pmatch = mock.patch.object( d, "matches", - pytest.helpers.AsyncMock( - name=f"{d.serial}_matches", side_effect=match - ), + pytest.helpers.AsyncMock(name=f"{d.serial}_matches", side_effect=match), ) pfinish = mock.patch.object( d, "finish", - pytest.helpers.AsyncMock( - name=f"{d.serial}_finish", side_effect=finish - ), + pytest.helpers.AsyncMock(name=f"{d.serial}_finish", side_effect=finish), ) for p in (pmatch, pfinish): @@ -237,7 +225,10 @@ def __exit__(s, exc_typ, exc, tb): called = [] async with pytest.helpers.FutureDominoes(expected=6) as futs: - m = lambda s: Device.FieldSpec().empty_normalise(serial=s) + + def m(s): + return Device.FieldSpec().empty_normalise(serial=s) + s1 = m("s1") s2 = m("s2") s3 = m("s3") @@ -247,9 +238,7 @@ def __exit__(s, exc_typ, exc, tb): s7 = m("s7") all_serials = [s1, s2, s3, s4, s5, s6, s7] - private_find_all_serials = pytest.helpers.AsyncMock( - name="_find_all_serials", return_value=all_serials - ) + private_find_all_serials = pytest.helpers.AsyncMock(name="_find_all_serials", return_value=all_serials) removed = [s4, s5, s6] private_ensure_devices = mock.Mock(name="_ensure_devices", return_value=removed) @@ -257,16 +246,10 @@ def __exit__(s, exc_typ, exc, tb): assert V.finder.devices == {} V.finder.devices = {"s1": s1, "s2": s2, "s3": s3, "s7": s7} - ensure_devices_patch = mock.patch.object( - V.finder, "_ensure_devices", private_ensure_devices - ) - find_all_serials_patch = mock.patch.object( - V.finder, "_find_all_serials", private_find_all_serials - ) + ensure_devices_patch = mock.patch.object(V.finder, "_ensure_devices", private_ensure_devices) + find_all_serials_patch = mock.patch.object(V.finder, "_find_all_serials", private_find_all_serials) - with Patches( - [s1, s2, s3, s4, s5, s6, s7] - ), ensure_devices_patch, find_all_serials_patch: + with Patches([s1, s2, s3, s4, s5, s6, s7]), ensure_devices_patch, find_all_serials_patch: async def s4finish(): called.append("s4finish_start") @@ -354,9 +337,7 @@ async def s7matches(*args, **kwargs): for d in (s4, s5, s6): d.matches.assert_not_called() for d in (s1, s2, s3, s7): - d.matches.assert_called_once_with( - V.finder.sender, fltr, V.finder.collections - ) + d.matches.assert_called_once_with(V.finder.sender, fltr, V.finder.collections) else: for d in (s1, s2, s3, s4, s5, s6, s7): d.matches.assert_not_called() @@ -393,7 +374,6 @@ async def s7matches(*args, **kwargs): assert called == expected_called class TestInfo: - @pytest.mark.parametrize( "fltr", [ @@ -401,9 +381,7 @@ class TestInfo: Filter.from_options({"label": "attic", "refresh_info": True}), ], ) - async def test_it_streams_devices_after_getting_all_info_for_that_device( - self, V, fltr, fake_time - ): + async def test_it_streams_devices_after_getting_all_info_for_that_device(self, V, fltr, fake_time): t = fake_time class Patches: @@ -419,9 +397,7 @@ async def match(*args, **kwargs): pmatch = mock.patch.object( d, "matches", - pytest.helpers.AsyncMock( - name=f"{d.serial}_matches", side_effect=match - ), + pytest.helpers.AsyncMock(name=f"{d.serial}_matches", side_effect=match), ) pmatch.start() s.patches.append(pmatch) @@ -433,7 +409,9 @@ def __exit__(s, exc_typ, exc, tb): async with pytest.helpers.FutureDominoes(expected=7) as futs: called = [] - m = lambda s: Device.FieldSpec().empty_normalise(serial=s) + def m(s): + return Device.FieldSpec().empty_normalise(serial=s) + s1 = m("s1") s2 = m("s2") s3 = m("s3") @@ -514,6 +492,4 @@ async def s4matches(*args, **kwargs): empty_fltr = Filter.empty(refresh_info=fltr.refresh_info) for d in (s1, s2, s3, s4): - d.matches.assert_called_once_with( - V.finder.sender, empty_fltr, V.finder.collections - ) + d.matches.assert_called_once_with(V.finder.sender, empty_fltr, V.finder.collections) diff --git a/modules/tests/photons_control_tests/device_finder/test_information_retrieval.py b/modules/tests/photons_control_tests/device_finder/test_information_retrieval.py index 6f83e615..a3858965 100644 --- a/modules/tests/photons_control_tests/device_finder/test_information_retrieval.py +++ b/modules/tests/photons_control_tests/device_finder/test_information_retrieval.py @@ -60,16 +60,12 @@ def received(self, *pkts, keep_duplicates=False): store = devices.store(self.fake_device) total = 0 for pkt in pkts: - nxt = store.count( - Events.INCOMING(self.fake_device, self.fake_device.io["MEMORY"], pkt=pkt) - ) + nxt = store.count(Events.INCOMING(self.fake_device, self.fake_device.io["MEMORY"], pkt=pkt)) assert nxt > 0, (pkt.__class__.__name__, repr(pkt), nxt) total += nxt if keep_duplicates or len(pkts) == 0: - exists = store.count( - Events.INCOMING(self.fake_device, self.fake_device.io["MEMORY"], pkt=mock.ANY) - ) + exists = store.count(Events.INCOMING(self.fake_device, self.fake_device.io["MEMORY"], pkt=mock.ANY)) assert exists == len(pkts) store.clear() @@ -82,7 +78,6 @@ def assertTimes(self, points): class TestDevice: - @pytest.fixture() async def sender(self, final_future): async with devices.for_test(final_future) as sender: @@ -125,9 +120,7 @@ async def test_it_can_match_against_a_fltr(self, sender, finder, fake_time, fina V.t.add(2) # It never refreshes version - assert not ( - await V.matches(Filter.from_kwargs(group_name="aa", cap=["matrix"], refresh_info=True)) - ) + assert not (await V.matches(Filter.from_kwargs(group_name="aa", cap=["matrix"], refresh_info=True))) V.received(DeviceMessages.GetGroup()) V.assertTimes({InfoPoints.LIGHT_STATE: 8, InfoPoints.GROUP: 11, InfoPoints.VERSION: 1}) V.t.add(3) @@ -136,9 +129,7 @@ async def test_it_can_match_against_a_fltr(self, sender, finder, fake_time, fina V.received() V.assertTimes({InfoPoints.LIGHT_STATE: 8, InfoPoints.GROUP: 11, InfoPoints.VERSION: 1}) - async def test_it_can_match_against_a_fltr_for_a_non_light( - self, sender, finder, fake_time, final_future - ): + async def test_it_can_match_against_a_fltr_for_a_non_light(self, sender, finder, fake_time, final_future): V = VBase(fake_time, sender, finder, final_future) await V.choose_device("switch") V.t.add(1) @@ -167,9 +158,7 @@ async def test_it_can_match_against_a_fltr_for_a_non_light( V.t.add(2) # It never refreshes version - assert not ( - await V.matches(Filter.from_kwargs(group_name="aa", cap=["matrix"], refresh_info=True)) - ) + assert not (await V.matches(Filter.from_kwargs(group_name="aa", cap=["matrix"], refresh_info=True))) V.received(DeviceMessages.GetGroup()) V.assertTimes({InfoPoints.LABEL: 8, InfoPoints.GROUP: 11, InfoPoints.VERSION: 1}) V.t.add(3) @@ -204,9 +193,7 @@ def __init__(s, name, kls): s.make_fut() def make_fut(s, res=None): - fut = message_futs[s.name] = V.fake_device.attrs.event_waiter.wait_for_incoming( - V.fake_device.io["MEMORY"], s.kls - ) + fut = message_futs[s.name] = V.fake_device.attrs.event_waiter.wait_for_incoming(V.fake_device.io["MEMORY"], s.kls) fut.add_done_callback(s.make_fut) def __await__(s): @@ -234,9 +221,7 @@ async def checker(ff): info = {"serial": V.fake_device.serial, "product_type": "unknown"} assert V.device.info == info - await hp.wait_for_all_futures( - *[V.device.point_futures[kls] for kls in InfoPoints if kls is not InfoPoints.LABEL] - ) + await hp.wait_for_all_futures(*[V.device.point_futures[kls] for kls in InfoPoints if kls is not InfoPoints.LABEL]) found = [] for kls in list(InfoPoints): @@ -313,17 +298,11 @@ async def checker(ff): with hp.ChildOfFuture(V.final_future) as ff: async with hp.TaskHolder(ff, name="TEST") as ts: checker_task = ts.add(checker(ff)) - ts.add( - V.device.refresh_information_loop( - V.sender, time_between_queries, V.finder.collections - ) - ) + ts.add(V.device.refresh_information_loop(V.sender, time_between_queries, V.finder.collections)) await checker_task - async def test_it_can_start_an_information_loop_for_a_switch( - self, fake_time, sender, finder, final_future - ): + async def test_it_can_start_an_information_loop_for_a_switch(self, fake_time, sender, finder, final_future): V = VBase(fake_time, sender, finder, final_future) await V.choose_device("switch") fake_time.set(1) @@ -349,9 +328,7 @@ def __init__(s, name, kls): s.make_fut() def make_fut(s, res=None): - fut = message_futs[s.name] = V.fake_device.attrs.event_waiter.wait_for_incoming( - V.fake_device.io["MEMORY"], s.kls - ) + fut = message_futs[s.name] = V.fake_device.attrs.event_waiter.wait_for_incoming(V.fake_device.io["MEMORY"], s.kls) fut.add_done_callback(s.make_fut) def __await__(s): @@ -379,13 +356,7 @@ async def checker(ff): info = {"serial": V.fake_device.serial, "product_type": "unknown"} assert V.device.info == info - await hp.wait_for_all_futures( - *[ - V.device.point_futures[kls] - for kls in InfoPoints - if kls is not InfoPoints.LIGHT_STATE - ] - ) + await hp.wait_for_all_futures(*[V.device.point_futures[kls] for kls in InfoPoints if kls is not InfoPoints.LIGHT_STATE]) found = [] for kls in list(InfoPoints): @@ -457,17 +428,11 @@ async def checker(ff): with hp.ChildOfFuture(V.final_future) as ff: async with hp.TaskHolder(ff, name="TEST") as ts: checker_task = ts.add(checker(ff)) - ts.add( - V.device.refresh_information_loop( - V.sender, time_between_queries, V.finder.collections - ) - ) + ts.add(V.device.refresh_information_loop(V.sender, time_between_queries, V.finder.collections)) await checker_task - async def test_it_stops_the_information_loop_when_the_device_disappears( - self, fake_time, sender, finder, final_future - ): + async def test_it_stops_the_information_loop_when_the_device_disappears(self, fake_time, sender, finder, final_future): V = VBase(fake_time, sender, finder, final_future) await V.choose_device("light") fake_time.set(1) @@ -493,9 +458,7 @@ def __init__(s, name, kls): s.make_fut() def make_fut(s, res=None): - fut = message_futs[s.name] = V.fake_device.attrs.event_waiter.wait_for_incoming( - V.fake_device.io["MEMORY"], s.kls - ) + fut = message_futs[s.name] = V.fake_device.attrs.event_waiter.wait_for_incoming(V.fake_device.io["MEMORY"], s.kls) fut.add_done_callback(s.make_fut) def __await__(s): @@ -519,13 +482,11 @@ def done(s): ]: setattr(Futs, name, Waiter(name, kls)) - async def checker(ff, l): + async def checker(ff, item): info = {"serial": V.fake_device.serial, "product_type": "unknown"} assert V.device.info == info - await hp.wait_for_all_futures( - *[V.device.point_futures[kls] for kls in InfoPoints if kls is not InfoPoints.LABEL] - ) + await hp.wait_for_all_futures(*[V.device.point_futures[kls] for kls in InfoPoints if kls is not InfoPoints.LABEL]) found = [] for kls in list(InfoPoints): @@ -585,10 +546,10 @@ async def checker(ff, l): assert V.device.serial not in V.sender.found - assert not l.done() + assert not item.done() # This will timeout if it hasn't ended - await l + await item ff.cancel() @@ -599,31 +560,21 @@ async def checker(ff, l): with hp.ChildOfFuture(V.final_future) as ff: async with hp.TaskHolder(ff, name="TEST") as ts: - l = ts.add( - V.device.refresh_information_loop( - V.sender, time_between_queries, V.finder.collections - ) - ) - checker_task = ts.add(checker(ff, l)) + item = ts.add(V.device.refresh_information_loop(V.sender, time_between_queries, V.finder.collections)) + checker_task = ts.add(checker(ff, item)) await checker_task - async def test_it_doesnt_do_multiple_refresh_loops_at_the_same_time( - self, fake_time, sender, finder, final_future - ): + async def test_it_doesnt_do_multiple_refresh_loops_at_the_same_time(self, fake_time, sender, finder, final_future): V = VBase(fake_time, sender, finder, final_future) await V.choose_device("light") async def impl(*args, **kwargs): await asyncio.sleep(200) - private_refresh_information_loop = pytest.helpers.AsyncMock( - name="_refresh_information_loop", side_effect=impl - ) + private_refresh_information_loop = pytest.helpers.AsyncMock(name="_refresh_information_loop", side_effect=impl) - with mock.patch.object( - V.device, "_refresh_information_loop", private_refresh_information_loop - ): + with mock.patch.object(V.device, "_refresh_information_loop", private_refresh_information_loop): async with hp.TaskHolder(V.final_future, name="TEST") as ts: assert not V.device.refreshing.done() @@ -631,9 +582,7 @@ async def impl(*args, **kwargs): await asyncio.sleep(0) assert V.device.refreshing.done() - private_refresh_information_loop.assert_called_once_with( - V.sender, None, V.finder.collections - ) + private_refresh_information_loop.assert_called_once_with(V.sender, None, V.finder.collections) assert not t1.done() # Next time we add does nothing @@ -641,9 +590,7 @@ async def impl(*args, **kwargs): await asyncio.sleep(0) assert V.device.refreshing.done() - private_refresh_information_loop.assert_called_once_with( - V.sender, None, V.finder.collections - ) + private_refresh_information_loop.assert_called_once_with(V.sender, None, V.finder.collections) assert t2.done() assert not t1.done() diff --git a/modules/tests/photons_control_tests/device_finder/test_special_reference.py b/modules/tests/photons_control_tests/device_finder/test_special_reference.py index 6897f4ad..42ec443d 100644 --- a/modules/tests/photons_control_tests/device_finder/test_special_reference.py +++ b/modules/tests/photons_control_tests/device_finder/test_special_reference.py @@ -31,7 +31,6 @@ def test_it_can_take_in_a_finder(self): assert isinstance(reference, SpecialReference) class TestUsage: - @pytest.fixture() def V(self): class V: @@ -169,21 +168,16 @@ async def find(f): assert found == [d1, d2] class TestProxyingFilterClassmethods: - @pytest.fixture() def fltr(self): return Filter.from_kwargs(label="kitchen", cap=["matrix", "chain"]) def test_it_supports_from_json_str(self, V, fltr): - reference = DeviceFinder.from_json_str( - '{"label": "kitchen", "cap": ["matrix", "chain"]}' - ) + reference = DeviceFinder.from_json_str('{"label": "kitchen", "cap": ["matrix", "chain"]}') assert reference.fltr == fltr assert reference.finder is None - reference = DeviceFinder.from_json_str( - '{"label": "kitchen", "cap": ["matrix", "chain"]}', finder=V.finder - ) + reference = DeviceFinder.from_json_str('{"label": "kitchen", "cap": ["matrix", "chain"]}', finder=V.finder) assert reference.fltr == fltr assert reference.finder is V.finder @@ -192,9 +186,7 @@ def test_it_supports_from_key_value_str(self, V, fltr): assert reference.fltr == fltr assert reference.finder is None - reference = DeviceFinder.from_key_value_str( - "label=kitchen cap=matrix,chain", finder=V.finder - ) + reference = DeviceFinder.from_key_value_str("label=kitchen cap=matrix,chain", finder=V.finder) assert reference.fltr == fltr assert reference.finder is V.finder @@ -203,9 +195,7 @@ def test_it_supports_from_url_str(self, V, fltr): assert reference.fltr == fltr assert reference.finder is None - reference = DeviceFinder.from_url_str( - "label=kitchen&cap=matrix&cap=chain", finder=V.finder - ) + reference = DeviceFinder.from_url_str("label=kitchen&cap=matrix&cap=chain", finder=V.finder) assert reference.fltr == fltr assert reference.finder is V.finder @@ -214,9 +204,7 @@ def test_it_supports_from_kwargs(self, V, fltr): assert reference.fltr == fltr assert reference.finder is None - reference = DeviceFinder.from_kwargs( - label="kitchen", cap=["matrix", "chain"], finder=V.finder - ) + reference = DeviceFinder.from_kwargs(label="kitchen", cap=["matrix", "chain"], finder=V.finder) assert reference.fltr == fltr assert reference.finder is V.finder @@ -227,9 +215,7 @@ def test_it_supports_empty(self, V, fltr): assert reference.fltr == expected assert reference.finder is None - reference = DeviceFinder.empty( - refresh_info=ri, refresh_discovery=rd, finder=V.finder - ) + reference = DeviceFinder.empty(refresh_info=ri, refresh_discovery=rd, finder=V.finder) assert reference.fltr == expected assert reference.finder is V.finder @@ -242,21 +228,16 @@ def test_it_supports_empty(self, V, fltr): assert reference.finder is V.finder def test_it_supports_from_options(self, V, fltr): - reference = DeviceFinder.from_options( - {"label": "kitchen", "cap": ["matrix", "chain"]} - ) + reference = DeviceFinder.from_options({"label": "kitchen", "cap": ["matrix", "chain"]}) assert reference.fltr == fltr assert reference.finder is None - reference = DeviceFinder.from_options( - {"label": "kitchen", "cap": ["matrix", "chain"]}, finder=V.finder - ) + reference = DeviceFinder.from_options({"label": "kitchen", "cap": ["matrix", "chain"]}, finder=V.finder) assert reference.fltr == fltr assert reference.finder is V.finder class TestFindingDevices: - @pytest.fixture() async def V(self, final_future): class V: @@ -264,9 +245,7 @@ class V: devices = pytest.helpers.mimic() d1 = devices.add("d1")(serials[0], Products.LCM3_TILE, hp.Firmware(3, 50)) - d2 = devices.add("d2")( - serials[1], Products.LCM2_Z, hp.Firmware(2, 80), value_store=dict(zones=[]) - ) + d2 = devices.add("d2")(serials[1], Products.LCM2_Z, hp.Firmware(2, 80), value_store=dict(zones=[])) d3 = devices.add("d3")( serials[2], Products.LCM2_A19, @@ -345,9 +324,7 @@ async def test_it_can_get_serials_and_info(self, V): assert ss == [V.d1.serial] for device in V.devices: - V.devices.store(device).assertIncoming( - DiscoveryMessages.GetService(), DeviceMessages.GetVersion() - ) + V.devices.store(device).assertIncoming(DiscoveryMessages.GetService(), DeviceMessages.GetVersion()) V.devices.store(device).clear() reference = DeviceFinder.from_kwargs(cap=["matrix", "multizone"]) @@ -357,9 +334,7 @@ async def test_it_can_get_serials_and_info(self, V): assert ss == [V.d1.serial, V.d2.serial] for device in V.devices: - V.devices.store(device).assertIncoming( - DiscoveryMessages.GetService(), DeviceMessages.GetVersion() - ) + V.devices.store(device).assertIncoming(DiscoveryMessages.GetService(), DeviceMessages.GetVersion()) V.devices.store(device).clear() reference = DeviceFinder.from_kwargs(cap=["not_matrix"], label="kitchen") @@ -464,7 +439,6 @@ async def test_it_can_get_serials_and_info(self, V): V.devices.store(device).clear() async def test_it_can_reuse_a_finder(self, V): - finder = Finder(V.sender) reference = DeviceFinder.empty(finder=finder) diff --git a/modules/tests/photons_control_tests/planner/test_default_plans.py b/modules/tests/photons_control_tests/planner/test_default_plans.py index fe253063..568ab2a1 100644 --- a/modules/tests/photons_control_tests/planner/test_default_plans.py +++ b/modules/tests/photons_control_tests/planner/test_default_plans.py @@ -163,9 +163,7 @@ async def gather(sender, reference, *by_label, **kwargs): class TestDefaultPlans: - class TestPacketPlan: - async def test_it_gets_the_packet(self, sender): plan = PacketPlan(DeviceMessages.GetPower(), DeviceMessages.StatePower) got = await gather(sender, two_lights, {"result": plan}) @@ -174,12 +172,8 @@ async def test_it_gets_the_packet(self, sender): light2.serial: (True, {"result": mock.ANY}), } - pytest.helpers.print_packet_difference( - got[light1.serial][1]["result"], DeviceMessages.StatePower(level=0) - ) - pytest.helpers.print_packet_difference( - got[light2.serial][1]["result"], DeviceMessages.StatePower(level=65535) - ) + pytest.helpers.print_packet_difference(got[light1.serial][1]["result"], DeviceMessages.StatePower(level=0)) + pytest.helpers.print_packet_difference(got[light2.serial][1]["result"], DeviceMessages.StatePower(level=65535)) async def test_it_fails_if_we_cant_get_the_correct_response(self, sender): plan = PacketPlan(DeviceMessages.GetPower(), DeviceMessages.StateLabel) @@ -187,7 +181,6 @@ async def test_it_fails_if_we_cant_get_the_correct_response(self, sender): assert got == {} class TestPresencePlan: - async def test_it_returns_True(self, sender): got = await gather(sender, two_lights, "presence") assert got == { @@ -215,7 +208,6 @@ async def test_it_allows_us_to_get_serials_that_otherwise_wouldnt(self, sender): } async def test_it_fires_for_offline_devices_that_have_already_been_discovered(self, sender): - errors = [] _, serials = await FoundSerials().find(sender, timeout=1) assert all(serial in serials for serial in two_lights) @@ -256,7 +248,6 @@ async def test_it_does_not_fire_for_devices_that_dont_exist(self, sender): assert got == {light1.serial: (True, {"presence": True, "label": "bob"})} class TestAddressPlan: - async def test_it_gets_the_address(self, sender): got = await gather(sender, two_lights, "address") assert got == { @@ -265,7 +256,6 @@ async def test_it_gets_the_address(self, sender): } class TestLabelPlan: - async def test_it_gets_the_label(self, sender): got = await gather(sender, two_lights, "label") assert got == { @@ -274,7 +264,6 @@ async def test_it_gets_the_label(self, sender): } class TestStatePlan: - async def test_it_gets_the_power(self, sender): state1 = { "hue": light1.attrs.color.hue, @@ -301,7 +290,6 @@ async def test_it_gets_the_power(self, sender): } class TestPowerPlan: - async def test_it_gets_the_power(self, sender): got = await gather(sender, two_lights, "power") assert got == { @@ -310,7 +298,6 @@ async def test_it_gets_the_power(self, sender): } class TestHevStatusPlan: - async def test_it_works_when_hev_is_not_on(self, sender): assert not clean.attrs.clean_details.enabled assert clean.attrs.clean_details.last_result is LightLastHevCycleResult.NONE @@ -482,7 +469,6 @@ async def test_it_works_with_different_last_result_from_power_cycle(self, sender } class TestHEVConfigPlan: - async def test_it_can_get_hev_config(self, sender): got = await gather(sender, [clean.serial, light1.serial], "hev_config") assert got == { @@ -509,13 +495,9 @@ async def test_it_can_get_hev_config(self, sender): } class TestCapabilityPlan: - async def test_it_gets_the_power(self, sender): - def make_version(vendor, product): - msg = DeviceMessages.StateVersion.create( - vendor=vendor, product=product, source=1, sequence=1, target=None - ) + msg = DeviceMessages.StateVersion.create(vendor=vendor, product=product, source=1, sequence=1, target=None) # in the future, I don't have to do this trick to ensure reserved fields have values # Which matters in the test return DeviceMessages.StateVersion.create(msg.pack()).payload @@ -597,7 +579,6 @@ def make_version(vendor, product): assert not info["capability"]["cap"].has_extended_multizone class TestFirmwarePlan: - async def test_it_gets_the_firmware(self, sender): l1c = { "build": 0, @@ -639,7 +620,6 @@ async def test_it_gets_the_firmware(self, sender): } class TestVersionPlan: - async def test_it_gets_the_version(self, sender): got = await gather(sender, devices.serials, "version") assert got == { @@ -656,7 +636,6 @@ async def test_it_gets_the_version(self, sender): } class TestZonesPlan: - async def test_it_gets_zones(self, sender): got = await gather(sender, devices.serials, "zones") expected = { @@ -702,7 +681,6 @@ async def test_it_gets_zones(self, sender): devices.store(device).assertIncoming(*expected[device]) class TestColorsPlan: - async def test_it_gets_colors_for_different_devices(self, sender): serials = [ light1.serial, @@ -726,9 +704,7 @@ async def test_it_gets_colors_for_different_devices(self, sender): changes = [] for i in range(len(light1.attrs.chain)): for j in range(64): - changes.append( - light1.attrs.attrs_path("chain", i, "colors", j, "hue").changer_to(i + j) - ) + changes.append(light1.attrs.attrs_path("chain", i, "colors", j, "hue").changer_to(i + j)) await light1.attrs.attrs_apply(*changes, event=None) for i in range(len(light1.attrs.chain)): tile_expected.append(list(light1.attrs.chain[i].colors)) @@ -914,9 +890,7 @@ async def test_it_works_for_a_tile_set(self, sender): (("chain", 2, "colors"), co.reorient(colors3, co.Orientation.FaceDown)), event=None, ) - await device.attrs.attrs_apply( - device.attrs.attrs_path("chain").reduce_length_to(3), event=None - ) + await device.attrs.attrs_apply(device.attrs.attrs_path("chain").reduce_length_to(3), event=None) got = await gather(sender, [device.serial], "parts") info = got[device.serial][1]["parts"] @@ -971,7 +945,6 @@ async def test_it_works_for_a_tile_set(self, sender): assert pc.real_part.original_colors == colors class TestChainPlan: - async def test_it_gets_chain_for_a_bulb(self, sender): got = await gather(sender, [light2.serial], "chain") info = got[light2.serial][1]["chain"] @@ -1086,9 +1059,7 @@ async def test_it_gets_chain_for_a_strip(self, sender): colors = [hp.Color(i, 1, 1, 3500) for i in range(30)] assert info["reorient"](0, colors) == reorient(colors, Orientation.RightSideUp) - assert info["reverse_orient"](0, colors) == reorient( - colors, Orientation.RightSideUp - ) + assert info["reverse_orient"](0, colors) == reorient(colors, Orientation.RightSideUp) assert info["coords_and_sizes"] == [((0.0, 0.0), (info["width"], 1))] async def test_it_gets_chain_for_tiles(self, sender): @@ -1259,7 +1230,6 @@ async def test_it_gets_chain_for_tiles(self, sender): assert ro(4, colors) == reorient(colors, Orientation.RightSideUp) class TestFirmwareEffectsPlan: - async def test_it_gets_firmware_effects(self, sender): io = light1.io["MEMORY"] @@ -1333,9 +1303,7 @@ async def process_outgoing_striplcm1(reply, req_event, Cont): } serials = [light1.serial, light2.serial, striplcm1.serial] - with ( - process_outgoing_light1 - ), process_outgoing_striplcm1, process_request_light1, process_request_striplcm1: + with process_outgoing_light1, process_outgoing_striplcm1, process_request_light1, process_request_striplcm1: got = await gather(sender, serials, "firmware_effects") expected = { light1.serial: (True, {"firmware_effects": l1}), diff --git a/modules/tests/photons_control_tests/planner/test_gatherer.py b/modules/tests/photons_control_tests/planner/test_gatherer.py index 5a248d74..51844ab8 100644 --- a/modules/tests/photons_control_tests/planner/test_gatherer.py +++ b/modules/tests/photons_control_tests/planner/test_gatherer.py @@ -110,9 +110,7 @@ def forward(s, amount): class TestGatherer: - class TestAPlanSayingNoMessages: - async def test_it_processes_without_needing_messages(self, sender): called = [] @@ -208,7 +206,6 @@ async def info(s): compare_received({light1: [], light2: [DeviceMessages.GetLabel()], light3: []}) class TestAPlanSayingSkip: - async def test_it_has_no_processing_or_info(self, sender): called = [] @@ -289,7 +286,6 @@ async def info(s): compare_received({light1: [], light2: [DeviceMessages.GetLabel()], light3: []}) class TestAPlanWithNoMessages: - async def test_it_it_gets_all_other_messages(self, sender): called = [] @@ -332,9 +328,7 @@ async def info(s): ], ) - async def test_it_still_finishes_if_no_messages_processed_but_finished_after_no_more_messages( - self, sender - ): + async def test_it_still_finishes_if_no_messages_processed_but_finished_after_no_more_messages(self, sender): called = [] class NoMessagesPlan(Plan): @@ -361,7 +355,6 @@ async def info(s): compare_called(called, [("info", light1.serial), ("info", light2.serial)]) class TestAPlanThatNeverFinishes: - async def test_it_it_doesnt_get_recorded(self, sender): called = [] @@ -393,7 +386,6 @@ async def info(s): ) class TestAPlanWithMessages: - async def test_it_messages_are_processed_until_we_say_plan_is_done(self, sender): called = [] @@ -470,9 +462,7 @@ async def info(s): errors = [] found.clear() - async for serial, label, info in gatherer.gather( - plans, devices.serials, error_catcher=errors - ): + async for serial, label, info in gatherer.gather(plans, devices.serials, error_catcher=errors): found.append((serial, label, info)) assert errors == [error] @@ -529,9 +519,7 @@ async def info(s): with assertRaises(TimedOut, "Waiting for reply to a packet", serial=light1.serial): lost = light1.io["MEMORY"].packet_filter.lost_replies(DeviceMessages.GetLabel) with lost: - async for serial, label, info in gatherer.gather( - plans, two_lights, message_timeout=0.1 - ): + async for serial, label, info in gatherer.gather(plans, two_lights, message_timeout=0.1): found.append((serial, label, info)) assert found == [ @@ -583,9 +571,7 @@ async def info(s): with assertRaises(TimedOut, "Waiting for reply to a packet", serial=light1.serial): lost = light1.io["MEMORY"].packet_filter.lost_replies(DeviceMessages.GetLabel) with lost: - async for serial, completed, info in gatherer.gather_per_serial( - plans, two_lights, message_timeout=0.1 - ): + async for serial, completed, info in gatherer.gather_per_serial(plans, two_lights, message_timeout=0.1): found.append((serial, completed, info)) compare_received({light1: [DeviceMessages.GetLabel()], light2: [], light3: []}) @@ -745,9 +731,7 @@ def assertError(errors): called.clear() lost = light1.io["MEMORY"].packet_filter.lost_replies(DeviceMessages.GetLabel) with lost: - async for serial, completed, info in gatherer.gather_per_serial( - plans, two_lights, **kwargs - ): + async for serial, completed, info in gatherer.gather_per_serial(plans, two_lights, **kwargs): found.append((serial, completed, info)) assertError(error_catcher) @@ -776,7 +760,6 @@ def assertError(errors): } class TestRefreshing: - async def test_it_it_can_refresh_always(self, sender): called = [] @@ -803,9 +786,7 @@ async def info(s): label_type = DeviceMessages.StateLabel.Payload.message_type - compare_called( - called, [("label", light1.serial, label_type), ("info.label", light1.serial)] - ) + compare_called(called, [("label", light1.serial, label_type), ("info.label", light1.serial)]) compare_received({light1: [DeviceMessages.GetLabel()], light2: [], light3: []}) @@ -815,9 +796,7 @@ async def info(s): got = dict(await gatherer.gather_all(plans, light1.serial)) assert got == {light1.serial: (True, {"label": "bob"})} - compare_called( - called, [("label", light1.serial, label_type), ("info.label", light1.serial)] - ) + compare_called(called, [("label", light1.serial, label_type), ("info.label", light1.serial)]) compare_received({light1: [DeviceMessages.GetLabel()], light2: [], light3: []}) @@ -858,9 +837,7 @@ async def info(s): label_type = DeviceMessages.StateLabel.Payload.message_type - compare_called( - called, [("label", light1.serial, label_type), ("info.label", light1.serial)] - ) + compare_called(called, [("label", light1.serial, label_type), ("info.label", light1.serial)]) compare_received({light1: [DeviceMessages.GetLabel()], light2: [], light3: []}) @@ -880,9 +857,7 @@ async def info(s): got = dict(await gatherer.gather_all(plans, light1.serial)) assert got == {light1.serial: (True, {"label": "bob"})} - compare_called( - called, [("label", light1.serial, label_type), ("info.label", light1.serial)] - ) + compare_called(called, [("label", light1.serial, label_type), ("info.label", light1.serial)]) compare_received({light1: [DeviceMessages.GetLabel()], light2: [], light3: []}) called.clear() @@ -896,9 +871,7 @@ async def info(s): light2.serial: (True, {"label": "sam"}), } - compare_called( - called, [("label", light2.serial, label_type), ("info.label", light2.serial)] - ) + compare_called(called, [("label", light2.serial, label_type), ("info.label", light2.serial)]) compare_received({light1: [], light2: [DeviceMessages.GetLabel()], light3: []}) called.clear() @@ -910,9 +883,7 @@ async def info(s): light2.serial: (True, {"label": "sam"}), } - compare_called( - called, [("label", light1.serial, label_type), ("info.label", light1.serial)] - ) + compare_called(called, [("label", light1.serial, label_type), ("info.label", light1.serial)]) compare_received({light1: [DeviceMessages.GetLabel()], light2: [], light3: []}) @@ -946,9 +917,7 @@ async def info(s): called.clear() - async def test_it_cannot_steal_messages_from_completed_plans_if_we_refresh_messages_those_other_plans_use( - self, sender - ): + async def test_it_cannot_steal_messages_from_completed_plans_if_we_refresh_messages_those_other_plans_use(self, sender): called = [] class ReverseLabelPlan(Plan): @@ -1136,7 +1105,6 @@ async def info(s): compare_received({light1: [], light2: [], light3: []}) class TestDependencies: - async def test_it_it_can_get_dependencies(self, sender): called = [] @@ -1172,7 +1140,6 @@ def messages(s): return [DeviceMessages.GetLabel()] def process(s, pkt): - if pkt | DeviceMessages.StateLabel: called.append(("info.process.label", pkt.serial, pkt.pkt_type)) s.i = pkt.label @@ -1228,9 +1195,7 @@ async def info(s): } ) - async def test_it_it_can_get_dependencies_of_dependencies_and_messages_can_be_shared( - self, sender - ): + async def test_it_it_can_get_dependencies_of_dependencies_and_messages_can_be_shared(self, sender): called = [] class Plan1(Plan): @@ -1502,11 +1467,7 @@ async def info(s): errors = [] lost = light3.io["MEMORY"].packet_filter.lost_replies(DeviceMessages.GetLabel) with lost: - got = dict( - await gatherer.gather_all( - plans, devices.serials, error_catcher=errors, message_timeout=0.1 - ) - ) + got = dict(await gatherer.gather_all(plans, devices.serials, error_catcher=errors, message_timeout=0.1)) assert len(errors) == 1 assert got == { diff --git a/modules/tests/photons_control_tests/planner/test_plan_info.py b/modules/tests/photons_control_tests/planner/test_plan_info.py index fb110c45..f6c9b913 100644 --- a/modules/tests/photons_control_tests/planner/test_plan_info.py +++ b/modules/tests/photons_control_tests/planner/test_plan_info.py @@ -7,7 +7,6 @@ class TestPlanInfo: - @pytest.fixture() def V(self): class V: diff --git a/modules/tests/photons_control_tests/planner/test_session.py b/modules/tests/photons_control_tests/planner/test_session.py index 62d80c11..1e0e4897 100644 --- a/modules/tests/photons_control_tests/planner/test_session.py +++ b/modules/tests/photons_control_tests/planner/test_session.py @@ -29,8 +29,8 @@ def test_it_has_received_and_filled(self, session): assert isinstance(d, dict) key2 = str(uuid.uuid4()) - l = d[key2] - assert isinstance(l, list) + item = d[key2] + assert isinstance(item, list) key3 = str(uuid.uuid4()) d = session.filled[key3] @@ -203,7 +203,6 @@ def test_it_yields_known_packets_for_this_serial(self, session): assert ls == [pkt3, pkt5] class TestRefreshReceived: - @pytest.fixture() def V(self, fake_time, session): class V: @@ -213,15 +212,15 @@ class V: serial1 = "d073d5000001" serial2 = "d073d5000002" - def add(s, n, l, *, t, k): + def add(s, n, item, *, t, k): key = getattr(s, f"key{k}") pkt = mock.Mock( - name=f"pkt{n}{l}{k}", + name=f"pkt{n}{item}{k}", serial=getattr(s, f"serial{n}"), Information=Information(key), ) - setattr(s, f"pkt{n}{l}{k}", pkt) + setattr(s, f"pkt{n}{item}{k}", pkt) fake_time.set(t) session.receive(pkt) @@ -348,7 +347,6 @@ def test_it_removes_anything_older_than_refresh_seconds(self, session, fake_time } class TestRefreshFilled: - @pytest.fixture() def V(self, session, fake_time): class V: diff --git a/modules/tests/photons_control_tests/script/test_find_serials.py b/modules/tests/photons_control_tests/script/test_find_serials.py index 8623206a..cd350046 100644 --- a/modules/tests/photons_control_tests/script/test_find_serials.py +++ b/modules/tests/photons_control_tests/script/test_find_serials.py @@ -36,7 +36,6 @@ async def reset_devices(sender): class TestFindingSerials: - async def test_it_can_find_all_serials(self, sender): for ref in ("", "_", None, sb.NotSpecified, FoundSerials()): assert await find_serials(ref, sender, timeout=1) == (devices.serials, []) diff --git a/modules/tests/photons_control_tests/script/test_for_capability.py b/modules/tests/photons_control_tests/script/test_for_capability.py index 703906da..686f1de6 100644 --- a/modules/tests/photons_control_tests/script/test_for_capability.py +++ b/modules/tests/photons_control_tests/script/test_for_capability.py @@ -53,7 +53,6 @@ async def reset_devices(sender): class TestFromCapability: - async def assertScript(self, sender, msg, *, expected, **kwargs): await sender(msg, devices.serials, **kwargs) @@ -69,7 +68,6 @@ async def assertScript(self, sender, msg, *, expected, **kwargs): devices.store(device).clear() async def test_it_sends_the_messages_to_devices_with_only_correct_capability(self, sender): - msg = ForCapability(hev=LightMessages.GetHevCycle()) expected = { @@ -85,7 +83,6 @@ async def test_it_sends_the_messages_to_devices_with_only_correct_capability(sel await self.assertScript(sender, msg, expected=expected) async def test_it_can_send_message_to_groups(self, sender): - msg = ForCapability(**{"ir,hev": DeviceMessages.SetPower(level=65535)}) expected = { @@ -105,7 +102,6 @@ async def test_it_can_send_message_to_groups(self, sender): await self.assertScript(sender, msg, expected=expected) async def test_it_can_send_to_negative_capability(self, sender): - msg = ForCapability(hev=LightMessages.GetHevCycle(), not_hev=LightMessages.GetLightPower()) expected = { diff --git a/modules/tests/photons_control_tests/script/test_from_generator.py b/modules/tests/photons_control_tests/script/test_from_generator.py index a1b05d7c..104ba849 100644 --- a/modules/tests/photons_control_tests/script/test_from_generator.py +++ b/modules/tests/photons_control_tests/script/test_from_generator.py @@ -64,7 +64,6 @@ async def reset_devices(sender): class TestFromGenerator: - async def assertScript(self, sender, gen, *, generator_kwargs=None, expected, **kwargs): msg = FromGenerator(gen, **(generator_kwargs or {})) await sender(msg, devices.serials, **kwargs) @@ -81,7 +80,6 @@ async def assertScript(self, sender, gen, *, generator_kwargs=None, expected, ** devices.store(device).clear() async def test_it_is_able_to_do_a_FromGenerator_per_serial(self, sender): - async def gen(serial, sender, **kwargs): assert serial in (light1.serial, light2.serial) yield Pipeline([DeviceMessages.GetPower(), DeviceMessages.SetLabel(label="wat")]) @@ -120,10 +118,7 @@ async def gen(serial, sender, **kwargs): assert got[device.serial][0] | DeviceMessages.StatePower assert got[device.serial][1] | DeviceMessages.StateLabel - async def test_it_is_able_to_do_a_FromGenerator_per_serial_with_per_serial_error_catchers( - self, sender - ): - + async def test_it_is_able_to_do_a_FromGenerator_per_serial_with_per_serial_error_catchers(self, sender): per_light_errors = {light1.serial: [], light2.serial: [], light3.serial: []} def error_catcher_override(serial, original_error_catcher): @@ -161,9 +156,7 @@ async def gen(serial, sender, **kwargs): lost_light1 = light1.io["MEMORY"].packet_filter.lost_replies(DeviceMessages.SetLabel) lost_light2 = light2.io["MEMORY"].packet_filter.lost_replies(DeviceMessages.GetPower) with lost_light1, lost_light2: - async for pkt in sender( - msg, devices.serials, error_catcher=errors, message_timeout=2 - ): + async for pkt in sender(msg, devices.serials, error_catcher=errors, message_timeout=2): got[pkt.serial].append(pkt) assert len(devices) > 0 @@ -203,7 +196,6 @@ async def gen(serial, sender, **kwargs): } async def test_it_Can_get_results(self, sender): - async def gen(reference, sender, **kwargs): yield DeviceMessages.GetPower(target=light1.serial) yield DeviceMessages.GetPower(target=light2.serial) @@ -235,7 +227,6 @@ async def gen(reference, sender, **kwargs): assert got[device.serial][0] | DeviceMessages.StatePower async def test_it_Sends_all_the_messages_that_are_yielded(self, sender): - async def gen(reference, sender, **kwargs): get_power = DeviceMessages.GetPower() @@ -282,7 +273,6 @@ async def gen(reference, sender, **kwargs): assert got == [error] async def test_it_it_can_know_if_the_message_was_sent_successfully(self, sender): - async def gen(reference, sender, **kwargs): t = yield DeviceMessages.GetPower() assert await t @@ -293,12 +283,9 @@ async def gen(reference, sender, **kwargs): light3: [DeviceMessages.GetPower()], } - await self.assertScript( - sender, gen, generator_kwargs={"reference_override": True}, expected=expected - ) + await self.assertScript(sender, gen, generator_kwargs={"reference_override": True}, expected=expected) async def test_it_it_can_know_if_the_message_was_not_sent_successfully(self, sender): - async def gen(reference, sender, **kwargs): t = yield DeviceMessages.GetPower() assert not (await t) @@ -311,9 +298,7 @@ async def gen(reference, sender, **kwargs): errors = [] - lost_request_light1 = light1.io["MEMORY"].packet_filter.lost_request( - DeviceMessages.GetPower - ) + lost_request_light1 = light1.io["MEMORY"].packet_filter.lost_request(DeviceMessages.GetPower) with lost_request_light1: await self.assertScript( sender, @@ -334,7 +319,6 @@ async def gen(reference, sender, **kwargs): ) async def test_it_it_can_have_a_serial_override(self, sender): - async def gen(reference, sender, **kwargs): async def inner_gen(level, reference, sender2, **kwargs2): assert sender is sender2 @@ -429,9 +413,7 @@ async def gen(reference, sender, **kwargs): with psr1, psr2, psr3: start = time.time() errors = [] - await self.assertScript( - sender, gen, expected=expected, error_catcher=errors, message_timeout=2 - ) + await self.assertScript(sender, gen, expected=expected, error_catcher=errors, message_timeout=2) got = list(got.values()) assert len(got) == 3 diff --git a/modules/tests/photons_control_tests/script/test_pipeline.py b/modules/tests/photons_control_tests/script/test_pipeline.py index 8d420cba..0eda9a70 100644 --- a/modules/tests/photons_control_tests/script/test_pipeline.py +++ b/modules/tests/photons_control_tests/script/test_pipeline.py @@ -42,7 +42,6 @@ async def reset_devices(sender): class TestPipeline: - @pytest.mark.parametrize("reference", [devices.serials, FoundSerials()]) async def test_it_does_all_messages_at_once_if_pipeline_isnt_used(self, sender, reference): called = [] @@ -87,9 +86,7 @@ async def see_request(event): assert sorted(called) == sorted(devices.serials) @pytest.mark.parametrize("reference", [devices.serials, FoundSerials()]) - async def test_it_waits_on_replies_before_sending_next_if_we_have_a_pipeline( - self, sender, reference - ): + async def test_it_waits_on_replies_before_sending_next_if_we_have_a_pipeline(self, sender, reference): called = [] wait = hp.create_future() @@ -199,11 +196,7 @@ async def see_request(event): got[pkt.serial].append(pkt) called.append(("got_reply", type(pkt.payload).__name__)) - with_two = [ - serial - for serial, pkts in got.items() - if serial != light1.serial and len(pkts) == 2 - ] + with_two = [serial for serial, pkts in got.items() if serial != light1.serial and len(pkts) == 2] if len(with_two) == 2 and not light1_power_wait.done(): assert len(got) == 2, list(got) assert all(len(pkts) == 2 for pkts in got.values()) @@ -234,9 +227,7 @@ async def see_request(event): assert pkts[0] | DeviceMessages.StatePower, pkts assert pkts[1] | LightMessages.LightState, pkts - async def test_it_devices_are_slowed_down_by_other_slow_devices_if_synchronized_is_True( - self, sender - ): + async def test_it_devices_are_slowed_down_by_other_slow_devices_if_synchronized_is_True(self, sender): wait = hp.create_future() called = [] got_times = defaultdict(list) @@ -294,7 +285,6 @@ async def see_request(event): assert pkts[1] | LightMessages.LightState, pkts async def test_it_doesnt_stop_on_errors(self, sender): - async def process_request(event, Cont): if event | DeviceMessages.SetLabel: if event.pkt.serial == light1.serial: @@ -348,7 +338,6 @@ def error(e): assert [t for _, t in got[serial]] == [0, 1] async def test_it_can_short_cut_on_errors(self, sender): - async def process_request(event, Cont): if event | DeviceMessages.SetLabel: if event.pkt.serial == light1.serial: @@ -401,7 +390,6 @@ def error(e): assert got[serial][0][1] == 0 async def test_it_can_short_cut_on_errors_with_synchronized(self, sender): - async def process_request(event, Cont): if event | DeviceMessages.SetLabel: if event.pkt.serial == light1.serial: @@ -453,7 +441,6 @@ def error(e): assert got[serial][0][1] == 0 async def test_it_can_raise_all_errors(self, sender): - async def process_request(event, Cont): if event | DeviceMessages.SetLabel: if event.pkt.serial in (light1.serial, light2.serial): diff --git a/modules/tests/photons_control_tests/script/test_repeater.py b/modules/tests/photons_control_tests/script/test_repeater.py index 8f2e386e..f025d179 100644 --- a/modules/tests/photons_control_tests/script/test_repeater.py +++ b/modules/tests/photons_control_tests/script/test_repeater.py @@ -58,7 +58,6 @@ def assertReceived(received, want): class TestRepeater: - async def test_it_repeats_messages(self, sender): for use_pipeline in (True, False): pipeline = [ @@ -281,13 +280,10 @@ def no_errors(err): got[pkt.serial].append((pkt, time.time())) assert all(serial in got for serial in devices.serials), got - assert all(len(pkts) == 6 for pkts in got.values()), [ - (serial, len(pkts)) for serial, pkts in got.items() - ] + assert all(len(pkts) == 6 for pkts in got.values()), [(serial, len(pkts)) for serial, pkts in got.items()] assert len(done) == 3 async def test_it_is_not_stopped_by_errors(self, sender): - async def process_request(event, Cont): if event | DeviceMessages.SetPower: return @@ -318,16 +314,10 @@ def got_error(err): got = defaultdict(list) with psr1, psr2, psr3: - async for pkt in sender( - msg, devices.serials, error_catcher=got_error, message_timeout=0.1 - ): + async for pkt in sender(msg, devices.serials, error_catcher=got_error, message_timeout=0.1): got[pkt.serial].append(pkt) assert all(serial in got for serial in devices.serials), got - assert all(len(pkts) == 2 for pkts in got.values()), [ - (serial, len(pkts)) for serial, pkts in got.items() - ] - assert all( - all(pkt | LightMessages.LightState for pkt in pkts) for pkts in got.values() - ), got + assert all(len(pkts) == 2 for pkts in got.values()), [(serial, len(pkts)) for serial, pkts in got.items()] + assert all(all(pkt | LightMessages.LightState for pkt in pkts) for pkts in got.values()), got assert len(done) == 2 diff --git a/modules/tests/photons_control_tests/test_attributes.py b/modules/tests/photons_control_tests/test_attributes.py index 2a2b02c9..c2d249d1 100644 --- a/modules/tests/photons_control_tests/test_attributes.py +++ b/modules/tests/photons_control_tests/test_attributes.py @@ -3,7 +3,6 @@ class TestMakeHsbks: - @pytest.fixture() def colors(self): return [ @@ -26,7 +25,6 @@ def colors(self): ] def test_it_can_make_colors(self, colors): - def hsbk(*args, **kwargs): h, s, b, k = ColourParser.hsbk(*args, **kwargs) return {"hue": h, "saturation": s, "brightness": b, "kelvin": k} diff --git a/modules/tests/photons_control_tests/test_clean.py b/modules/tests/photons_control_tests/test_clean.py index ba541de9..bc74fab8 100644 --- a/modules/tests/photons_control_tests/test_clean.py +++ b/modules/tests/photons_control_tests/test_clean.py @@ -62,7 +62,6 @@ async def reset_devices(sender): class TestSetCleanConfig: - async def run_and_compare(self, sender, msg, *, expected): await sender(msg, devices.serials) @@ -91,13 +90,10 @@ async def test_it_sets_the_default_config(self, sender): ], light3: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()], } - await self.run_and_compare( - sender, SetCleanConfig(indication=True, duration_s=3600), expected=expected - ) + await self.run_and_compare(sender, SetCleanConfig(indication=True, duration_s=3600), expected=expected) class TestChangeCleanCycle: - async def run_and_compare(self, sender, msg, *, expected): await sender(msg, devices.serials) @@ -126,9 +122,7 @@ async def test_it_starts_a_clean_cycle(self, sender): ], light3: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()], } - await self.run_and_compare( - sender, ChangeCleanCycle(enable=True, duration_s=7200), expected=expected - ) + await self.run_and_compare(sender, ChangeCleanCycle(enable=True, duration_s=7200), expected=expected) async def test_it_stops_a_clean_cycle(self, sender): expected = { @@ -144,6 +138,4 @@ async def test_it_stops_a_clean_cycle(self, sender): ], light3: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()], } - await self.run_and_compare( - sender, ChangeCleanCycle(enable=False, duration_s=0), expected=expected - ) + await self.run_and_compare(sender, ChangeCleanCycle(enable=False, duration_s=0), expected=expected) diff --git a/modules/tests/photons_control_tests/test_multizone.py b/modules/tests/photons_control_tests/test_multizone.py index 7cc02c61..ca084d12 100644 --- a/modules/tests/photons_control_tests/test_multizone.py +++ b/modules/tests/photons_control_tests/test_multizone.py @@ -112,7 +112,6 @@ async def reset_devices(sender): class TestSetZonesPlan: - @pytest.fixture() def specifier(self): return [ @@ -441,9 +440,7 @@ def compare_received(by_light): class TestMultizoneHelpers: - class TestFindMultizone: - async def test_it_yields_serials_and_capability(self, sender): got = {} async for serial, cap in find_multizone(devices.serials, sender): @@ -460,30 +457,21 @@ async def test_it_resends_messages_each_time_if_we_reset_the_gatherer(self, send async for serial, cap in find_multizone(devices.serials, sender): pass - want = { - device: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()] - for device in devices - } + want = {device: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()] for device in devices} compare_received(want) del sender.gatherer async for serial, cap in find_multizone(devices.serials, sender): pass - want = { - device: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()] - for device in devices - } + want = {device: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()] for device in devices} compare_received(want) async def test_it_uses_cached_gatherer_on_the_sender(self, sender): async for serial, cap in find_multizone(devices.serials, sender): pass - want = { - device: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()] - for device in devices - } + want = {device: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()] for device in devices} compare_received(want) async for serial, cap in find_multizone(devices.serials, sender): @@ -493,7 +481,6 @@ async def test_it_uses_cached_gatherer_on_the_sender(self, sender): compare_received(want) class TestZonesFromReference: - async def test_it_yield_zones(self, sender): got = {} async for serial, zones in zones_from_reference(devices.serials, sender): @@ -510,14 +497,9 @@ async def test_it_resends_messages_if_no_gatherer_is_reset_between_runs(self, se async for serial, zones in zones_from_reference(devices.serials, sender): pass - want = { - device: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()] - for device in devices - } + want = {device: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()] for device in devices} want[striplcm1].append(MultiZoneMessages.GetColorZones(start_index=0, end_index=255)) - want[striplcm2noextended].append( - MultiZoneMessages.GetColorZones(start_index=0, end_index=255) - ) + want[striplcm2noextended].append(MultiZoneMessages.GetColorZones(start_index=0, end_index=255)) want[striplcm2extended].append(MultiZoneMessages.GetExtendedColorZones()) compare_received(want) @@ -531,14 +513,9 @@ async def test_it_uses_cached_gatherer_on_the_sender(self, sender): async for serial, zones in zones_from_reference(devices.serials, sender): pass - want = { - device: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()] - for device in devices - } + want = {device: [DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion()] for device in devices} want[striplcm1].append(MultiZoneMessages.GetColorZones(start_index=0, end_index=255)) - want[striplcm2noextended].append( - MultiZoneMessages.GetColorZones(start_index=0, end_index=255) - ) + want[striplcm2noextended].append(MultiZoneMessages.GetColorZones(start_index=0, end_index=255)) want[striplcm2extended].append(MultiZoneMessages.GetExtendedColorZones()) compare_received(want) @@ -548,7 +525,6 @@ async def test_it_uses_cached_gatherer_on_the_sender(self, sender): compare_received({device: [] for device in devices}) class TestSetZones: - async def test_it_can_power_on_devices_and_set_zones(self, sender): for device in strips: await device.change_one("zones", [zeroColor] * 16, event=None) @@ -740,7 +716,6 @@ async def test_it_uses_cached_gatherer_on_the_sender(self, sender): ) class TestSetZonesEffect: - async def test_it_can_power_on_devices_and_set_zones_effect(self, sender): msg = SetZonesEffect("move") got = await sender(msg, devices.serials) @@ -775,9 +750,7 @@ async def test_it_can_power_on_devices_and_set_zones_effect(self, sender): ) async def test_it_has_options(self, sender): - msg = SetZonesEffect( - "move", speed=5, duration=10, direction="LEFT", power_on_duration=20 - ) + msg = SetZonesEffect("move", speed=5, duration=10, direction="LEFT", power_on_duration=20) got = await sender(msg, devices.serials) assert got == [] @@ -876,17 +849,13 @@ async def test_it_can_target_particular_devices(self, sender): DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion(), LightMessages.SetLightPower(level=65535, duration=1), - MultiZoneMessages.SetMultiZoneEffect.create( - duration=5, type=MultiZoneEffectType.MOVE - ), + MultiZoneMessages.SetMultiZoneEffect.create(duration=5, type=MultiZoneEffectType.MOVE), ], striplcm2extended: [ DeviceMessages.GetHostFirmware(), DeviceMessages.GetVersion(), LightMessages.SetLightPower(level=65535, duration=1), - MultiZoneMessages.SetMultiZoneEffect.create( - duration=5, type=MultiZoneEffectType.MOVE - ), + MultiZoneMessages.SetMultiZoneEffect.create(duration=5, type=MultiZoneEffectType.MOVE), ], } ) diff --git a/modules/tests/photons_control_tests/test_tile.py b/modules/tests/photons_control_tests/test_tile.py index 1e3b9b4a..7ab1f8a0 100644 --- a/modules/tests/photons_control_tests/test_tile.py +++ b/modules/tests/photons_control_tests/test_tile.py @@ -60,9 +60,7 @@ def compare_received(by_light): class TestTileHelpers: - class TestSetTileEffect: - async def test_it_complains_if_we_have_more_than_16_colors_in_the_palette(self): with assertRaises(PhotonsAppError, "Palette can only be up to 16 colors", got=17): SetTileEffect("flame", palette=["red"] * 17) @@ -102,9 +100,7 @@ async def test_it_can_power_on_devices_and_set_tile_effect(self, sender): ) async def test_it_has_options(self, sender): - msg = SetTileEffect( - "flame", speed=5, duration=10, power_on_duration=20, palette=["red", "green"] - ) + msg = SetTileEffect("flame", speed=5, duration=10, power_on_duration=20, palette=["red", "green"]) got = await sender(msg, devices.serials) assert got == [] diff --git a/modules/tests/photons_control_tests/test_transformer.py b/modules/tests/photons_control_tests/test_transformer.py index b73a995a..d7eeacc9 100644 --- a/modules/tests/photons_control_tests/test_transformer.py +++ b/modules/tests/photons_control_tests/test_transformer.py @@ -113,7 +113,6 @@ def make_state(keys, extra_keys): class TestPowerToggle: - async def run_and_compare(self, sender, msg, *, expected): await sender(msg, devices.serials) @@ -167,7 +166,6 @@ async def test_it_toggles_the_power(self, sender): class TestPowerToggleGroup: - async def run_and_compare(self, sender, msg, *, expected): await sender(msg, devices.serials) @@ -221,9 +219,7 @@ async def test_it_toggles_the_power(self, sender): async def transform(sender, state, *, expected, keep_brightness=False, transition_color=False): - msg = Transformer.using( - state, keep_brightness=keep_brightness, transition_color=transition_color - ) + msg = Transformer.using(state, keep_brightness=keep_brightness, transition_color=transition_color) await sender(msg, devices.serials) assert len(devices) > 0 @@ -239,7 +235,6 @@ async def transform(sender, state, *, expected, keep_brightness=False, transitio class TestTransformer: - async def test_it_returns_an_empty_list_if_no_power_or_color_options(self): assert Transformer.using({}) == [] @@ -318,7 +313,6 @@ async def test_it_pipelines_turn_off_and_color_when_both_color_and_poweroff(self await transform(sender, state, expected=expected) class TestWhenPowerOnAndNeedColor: - async def test_it_sets_power_on_if_it_needs_to(self, sender): state = {"color": "blue", "power": "on"} expected = { @@ -326,9 +320,7 @@ async def test_it_sets_power_on_if_it_needs_to(self, sender): LightMessages.GetColor(), ColourParser.msg("blue", overrides={"brightness": 0}), DeviceMessages.SetPower(level=65535), - ColourParser.msg( - "blue", overrides={"brightness": light1.attrs.color.brightness} - ), + ColourParser.msg("blue", overrides={"brightness": light1.attrs.color.brightness}), ], light2: [LightMessages.GetColor(), ColourParser.msg("blue")], light3: [LightMessages.GetColor(), ColourParser.msg("blue")], diff --git a/modules/tests/photons_core_tests/test_main_lines.py b/modules/tests/photons_core_tests/test_main_lines.py index 0fea9364..44def5cd 100644 --- a/modules/tests/photons_core_tests/test_main_lines.py +++ b/modules/tests/photons_core_tests/test_main_lines.py @@ -8,15 +8,11 @@ class TestCommandSplitter: def test_it_can_format_argv(self): command = "{@:2}:{@:1} {@:3:}" - result = CommandSplitter( - {"argv": ["my_script", "one", "two", "three", "four"]}, command - ).split() + result = CommandSplitter({"argv": ["my_script", "one", "two", "three", "four"]}, command).split() assert result == ["two:one", "three", "four"] command = "{@:2:4}:{@:1} {@:4:}" - result = CommandSplitter( - {"argv": ["my_script", "one", "two", "three", "four", "five"]}, command - ).split() + result = CommandSplitter({"argv": ["my_script", "one", "two", "three", "four", "five"]}, command).split() assert result == ["two", "three:one", "four", "five"] def test_it_can_complain_about_an_env_specifier_without_a_name(self): @@ -26,9 +22,7 @@ def test_it_can_complain_about_an_env_specifier_without_a_name(self): def test_it_can_complain_if_an_environment_variable_is_needed_but_doesnt_exist(self): with pytest.helpers.modified_env(THING=None): - with assertRaises( - SystemExit, "This script requires you have a 'THING' variable in your environment" - ): + with assertRaises(SystemExit, "This script requires you have a 'THING' variable in your environment"): command = "{THING:env}" CommandSplitter({"argv": ["my_script"]}, command).split() @@ -93,7 +87,6 @@ def test_it_retains_options(self): class TestMainLines: - @pytest.fixture() def sys_argv(self): argv = ["my_script", "from", "the", "commandline"] @@ -106,9 +99,7 @@ def fake_command_splitter(self): command_splitter = mock.Mock(name="command_splitter", spec=["split"]) command_splitter.split.return_value = split - FakeCommandSplitter = mock.Mock( - name="CommandSplitter", spec=[], return_value=command_splitter - ) + FakeCommandSplitter = mock.Mock(name="CommandSplitter", spec=[], return_value=command_splitter) with mock.patch("photons_core.CommandSplitter", FakeCommandSplitter): yield FakeCommandSplitter, split @@ -149,9 +140,7 @@ def test_it_run_can_skip_going_through_the_splitter(self, V): def test_it_run_can_be_given_argv(self, V): run("lan:stuff", argv=["one", "two"]) - V.CommandSplitter.assert_called_once_with( - {"argv": ["my_script", "one", "two"]}, "lan:stuff" - ) + V.CommandSplitter.assert_called_once_with({"argv": ["my_script", "one", "two"]}, "lan:stuff") V.main.assert_called_once_with(V.split, default_activate=["core"]) def test_it_run_formats_correctly(self, fake_main): @@ -182,6 +171,4 @@ def test_it_will_not_format_json_dictionary(self, fake_main): with pytest.helpers.modified_env(LAN_TARGET=None): run("""lan:transform -- '{"power": "on"}'""", argv=["my_script"]) - fake_main.assert_called_once_with( - ["lan:transform", "--", '{"power": "on"}'], default_activate=["core"] - ) + fake_main.assert_called_once_with(["lan:transform", "--", '{"power": "on"}'], default_activate=["core"]) diff --git a/modules/tests/photons_messages_tests/test_colour.py b/modules/tests/photons_messages_tests/test_colour.py index d703c2f1..7d9c29a4 100644 --- a/modules/tests/photons_messages_tests/test_colour.py +++ b/modules/tests/photons_messages_tests/test_colour.py @@ -6,14 +6,11 @@ class TestLightMessages: - def create(self, msg): return LightMessages.create(msg, protocol_register=protocol_register) def test_it_has_Setcolor(self): - msg = self.create( - "3100001480dd8f29d073d522932200000000000000000301000000000000000066000000001c079919ff7fc409e8030000" - ) + msg = self.create("3100001480dd8f29d073d522932200000000000000000301000000000000000066000000001c079919ff7fc409e8030000") assert msg | LightMessages.SetColor pytest.helpers.assertPayloadsEquals( msg.payload, @@ -27,9 +24,7 @@ def test_it_has_Setcolor(self): assert msg.payload.actual("duration") == 1000 def test_it_has_SetWaveform(self): - msg = self.create( - "39000014575df165d073d52293220000000000000000030100000000000000006700000000001c479919ff7fc409d00700000000a040cc0c01" - ) + msg = self.create("39000014575df165d073d52293220000000000000000030100000000000000006700000000001c479919ff7fc409d00700000000a040cc0c01") assert msg | LightMessages.SetWaveform pytest.helpers.assertPayloadsEquals( msg.payload, @@ -134,10 +129,8 @@ def test_it_SetWaveformOptional_does_not_require_all_hsbk_values(self): def test_it_has_LightState(self): msg = self.create( - ( - "580000149c0bf333d073d522932200004c4946585632010100e8a719e40800006b0000000007" - "9919ff7fc4090000ffff64656e00000000000000000000000000000000000000000000000000000000000000000000000000" - ) + "580000149c0bf333d073d522932200004c4946585632010100e8a719e40800006b0000000007" + "9919ff7fc4090000ffff64656e00000000000000000000000000000000000000000000000000000000000000000000000000" ) assert msg | LightMessages.LightState pytest.helpers.assertPayloadsEquals( diff --git a/modules/tests/photons_messages_tests/test_frame.py b/modules/tests/photons_messages_tests/test_frame.py index 538dc80c..38709580 100644 --- a/modules/tests/photons_messages_tests/test_frame.py +++ b/modules/tests/photons_messages_tests/test_frame.py @@ -105,7 +105,6 @@ def test_it_packs_without_target(self): assert p.pack() == expected def test_it_is_an_ack_if_the_Payload_is_an_ack(self): - class P(frame.LIFXPacket): class Payload(dictobj.PacketSpec): represents_ack = True @@ -115,7 +114,6 @@ class Payload(dictobj.PacketSpec): assert p.represents_ack def test_it_is_not_an_ack_if_the_Payload_is_not_an_ack(self): - class P(frame.LIFXPacket): class Payload(dictobj.PacketSpec): represents_ack = True @@ -125,7 +123,6 @@ class Payload(dictobj.PacketSpec): assert p.represents_ack def test_it_has_the_right_size_bits_for_all_the_fields(self): - class P(frame.LIFXPacket): class Payload(dictobj.PacketSpec): message_type = 52 @@ -174,7 +171,6 @@ def test_it_has_payload_with_message_type_of_0(self): class TestOr: def test_it_says_yes_if_the_protocol_and_pkt_type_are_the_same_as_on_klsPayload(self): - class One(frame.LIFXPacket): class Payload(dictobj.PacketSpec): fields = [] @@ -205,7 +201,6 @@ class Payload(dictobj.PacketSpec): assert payloadtwo | One is False def test_it_can_get_the_values_from_the_packet_data_if_already_defined(self): - class One(frame.LIFXPacket): class Payload(dictobj.PacketSpec): fields = [] @@ -226,9 +221,7 @@ class Payload(dictobj.PacketSpec): payloadone = One(pkt_type=32, protocol=1024) payloadtwo = Two(pkt_type=33, protocol=1024) - with mock.patch.object( - frame.LIFXPacket, "__getitem__", mock.NonCallableMock(name="__getitem__") - ): + with mock.patch.object(frame.LIFXPacket, "__getitem__", mock.NonCallableMock(name="__getitem__")): assert payloadone | Two is False assert payloadone | One is True diff --git a/modules/tests/photons_products_tests/test_base.py b/modules/tests/photons_products_tests/test_base.py index 905acf8c..327639b6 100644 --- a/modules/tests/photons_products_tests/test_base.py +++ b/modules/tests/photons_products_tests/test_base.py @@ -68,24 +68,19 @@ def test_it_returns_no_items_by_default(self): class TestProduct: def test_it_complains_about_not_having_a_cap(self): - with assertRaises( - IncompleteProduct, "Product doesn't have a capability specified", name="P" - ): + with assertRaises(IncompleteProduct, "Product doesn't have a capability specified", name="P"): class P(base.Product): pass def test_it_complains_about_attributes_not_implemented(self): - with assertRaises( - IncompleteProduct, "Attribute wasn't overridden", attr="family", name="P" - ): + with assertRaises(IncompleteProduct, "Attribute wasn't overridden", attr="family", name="P"): class P(base.Product): class cap(base.Capability): pass def test_it_sets_the_cap_as_an_instance_of_the_cap_class(self): - class P(base.Product): pid = 1 family = Family.LCM1 @@ -99,7 +94,6 @@ class cap(base.Capability): assert P.cap.product == P def test_it_does_not_set_a_default_for_friendly(self): - msg = "Attribute wasn't overridden" with assertRaises(IncompleteProduct, msg, attr="friendly"): @@ -112,7 +106,6 @@ class cap(base.Capability): pass def test_it_has_company(self): - class CUBE(base.Product): pid = 1 family = Family.LCM3 @@ -125,7 +118,6 @@ class cap(base.Capability): assert CUBE.company == "LIFX" def test_it_is_equal_if_pid_and_vendor_match(self): - class capability(base.Capability): pass @@ -169,7 +161,6 @@ class P4(base.Product): assert P3 == (1, 2) def test_it_can_be_used_as_a_key_in_a_dictionary(self): - class P1(base.Product): pid = 29 family = Family.LCM1 @@ -185,7 +176,6 @@ class cap(base.Capability): assert d[(VendorRegistry.LIFX, 29)] == "thing" def test_it_has_a_repr(self): - class capability(base.Capability): pass @@ -215,7 +205,6 @@ class LCM2_MONITOR_STAND(base.Product): assert repr(LCM2_MONITOR_STAND) == "" def test_it_has_an_as_dict(self): - class LCM2_MONITOR_STAND(base.Product): pid = 29 family = Family.LCM2 @@ -240,7 +229,6 @@ def items(s): class TestMakeUnknownProduct: def test_it_works(self): - class cap(base.Capability): has_lattice = True @@ -254,7 +242,6 @@ class cap(base.Capability): class TestProductsHolder: - @pytest.fixture() def default_capability_kls(self): class capability(base.Capability): @@ -292,9 +279,7 @@ class LCM2_MONITOR_STAND(base.Product): def holder(self, ProductRegistry, default_capability_kls): return base.ProductsHolder(ProductRegistry, default_capability_kls) - def test_it_holds_onto_the_products_and_creates_by_pair( - self, ProductRegistry, holder, default_capability_kls - ): + def test_it_holds_onto_the_products_and_creates_by_pair(self, ProductRegistry, holder, default_capability_kls): assert holder.products is ProductRegistry assert holder.default_capability_kls is default_capability_kls assert holder.by_pair == { @@ -304,9 +289,7 @@ def test_it_holds_onto_the_products_and_creates_by_pair( } def test_it_can_yield_product_names(self, holder, ProductRegistry): - assert sorted(holder.names) == sorted( - ["LCM1_BOUNCY_BALL", "LCM2_DESK", "LCM2_MONITOR_STAND"] - ) + assert sorted(holder.names) == sorted(["LCM1_BOUNCY_BALL", "LCM2_DESK", "LCM2_MONITOR_STAND"]) def test_it_can_access_products_by_name(self, holder, ProductRegistry): assert holder.LCM1_BOUNCY_BALL is ProductRegistry.LCM1_BOUNCY_BALL diff --git a/modules/tests/photons_products_tests/test_capability.py b/modules/tests/photons_products_tests/test_capability.py index 60daf0ae..2a0d8e52 100644 --- a/modules/tests/photons_products_tests/test_capability.py +++ b/modules/tests/photons_products_tests/test_capability.py @@ -31,13 +31,7 @@ def test_it_can_have_one_value(self, cap): assert cv.value(cap(2, 80)) == 1 def test_it_can_have_upgrades(self, cap): - cv = ( - CapabilityValue(1) - .until(1, 40, becomes=2) - .until(2, 50, becomes=3) - .until(2, 60, becomes=4) - .until(3, 70, becomes=5) - ) + cv = CapabilityValue(1).until(1, 40, becomes=2).until(2, 50, becomes=3).until(2, 60, becomes=4).until(3, 70, becomes=5) assert cv.value(cap) == 1 assert cv.value(cap(1, 30)) == 1 assert cv.value(cap(1, 40)) == 2 @@ -49,7 +43,6 @@ def test_it_can_have_upgrades(self, cap): assert cv.value(cap(4, 60)) == 5 def test_it_can_have_upgrades_with_conditions(self): - cv = ( CapabilityValue(1) .until(1, 40, cond.Family("laptop"), becomes=2) @@ -118,9 +111,7 @@ class cap(Capability): def test_it_complains_if_you_give_upgrades_out_of_order(self): with assertRaises(ProgrammerError, "Each .until must be for a greater version number"): - CapabilityValue(1).until(1, 40, becomes=2).until(2, 60, becomes=4).until( - 2, 50, becomes=3 - ).until(3, 70, becomes=5) + CapabilityValue(1).until(1, 40, becomes=2).until(2, 60, becomes=4).until(2, 50, becomes=3).until(3, 70, becomes=5) def test_it_has_equality(self): cv1 = CapabilityValue(1) @@ -138,20 +129,10 @@ def test_it_has_equality_with_conditions(self): cv1 = CapabilityValue(1).until(2, 70, cond.Family("one"), becomes=20) cv2 = CapabilityValue(1).until(2, 70, cond.Family("one"), becomes=20) cv3 = CapabilityValue(1).until(2, 70, cond.Family("two"), becomes=20) - cv4 = ( - CapabilityValue(1).until(2, 70, cond.Family("one"), becomes=20).until(3, 60, becomes=10) - ) - cv5 = ( - CapabilityValue(1).until(2, 70, cond.Family("two"), becomes=20).until(3, 60, becomes=10) - ) - cv6 = ( - CapabilityValue(1).until(2, 70, cond.Family("two"), becomes=20).until(3, 60, becomes=10) - ) - cv7 = ( - CapabilityValue(1) - .until(2, 70, cond.Family("two"), cond.Capability(things=1), becomes=20) - .until(3, 60, becomes=10) - ) + cv4 = CapabilityValue(1).until(2, 70, cond.Family("one"), becomes=20).until(3, 60, becomes=10) + cv5 = CapabilityValue(1).until(2, 70, cond.Family("two"), becomes=20).until(3, 60, becomes=10) + cv6 = CapabilityValue(1).until(2, 70, cond.Family("two"), becomes=20).until(3, 60, becomes=10) + cv7 = CapabilityValue(1).until(2, 70, cond.Family("two"), cond.Capability(things=1), becomes=20).until(3, 60, becomes=10) assert cv1 == cv2 assert cv1 != cv3 @@ -163,7 +144,6 @@ def test_it_has_equality_with_conditions(self): class TestCapabilityRange: def test_it_can_create_two_CapabilityValue_objects(self): - class cap(Capability): one, two = CapabilityRange((1, 2)) @@ -171,21 +151,14 @@ class cap(Capability): assert cap.Meta.capabilities["two"] == CapabilityValue(2) class cap(Capability): - one, two = ( - CapabilityRange((1, 2)).until(2, 70, becomes=(3, 4)).until(7, 60, becomes=(5, 6)) - ) + one, two = CapabilityRange((1, 2)).until(2, 70, becomes=(3, 4)).until(7, 60, becomes=(5, 6)) - assert cap.Meta.capabilities["one"] == CapabilityValue(1).until(2, 70, becomes=3).until( - 7, 60, becomes=5 - ) - assert cap.Meta.capabilities["two"] == CapabilityValue(2).until(2, 70, becomes=4).until( - 7, 60, becomes=6 - ) + assert cap.Meta.capabilities["one"] == CapabilityValue(1).until(2, 70, becomes=3).until(7, 60, becomes=5) + assert cap.Meta.capabilities["two"] == CapabilityValue(2).until(2, 70, becomes=4).until(7, 60, becomes=6) class TestCapability: def test_it_puts_capabilities_on_Meta(self, product): - class cap(Capability): pass diff --git a/modules/tests/photons_products_tests/test_enums.py b/modules/tests/photons_products_tests/test_enums.py index a385cc7d..55281282 100644 --- a/modules/tests/photons_products_tests/test_enums.py +++ b/modules/tests/photons_products_tests/test_enums.py @@ -16,7 +16,6 @@ def test_it_equals_other_integers_and_other_Vendor(self): assert v == v def test_it_can_be_given_a_name(self): - class T: BLAH = Vendor(1) diff --git a/modules/tests/photons_products_tests/test_registry.py b/modules/tests/photons_products_tests/test_registry.py index f4af2739..4cb095a5 100644 --- a/modules/tests/photons_products_tests/test_registry.py +++ b/modules/tests/photons_products_tests/test_registry.py @@ -4,7 +4,6 @@ class TestLifxProduct: def test_it_has_default_vendor(self): - class P(lifx.Product): pid = 3 family = Family.LCM3 @@ -18,7 +17,6 @@ class cap(lifx.Capability): class TestCapability: def test_it_has_has_matrix(self): - class P(lifx.Product): pid = 1 name = "Product" @@ -44,7 +42,6 @@ class cap(lifx.Capability): assert not cap(P).has_matrix def test_it_has_has_multizone(self): - class P(lifx.Product): pid = 1 name = "Product" @@ -70,7 +67,6 @@ class cap(lifx.Capability): assert not cap(P).has_multizone def test_it_has_has_extended_multizone(self): - class P(lifx.Product): pid = 1 name = "Product" @@ -100,7 +96,6 @@ class cap(lifx.Capability): assert c(firmware_major=3, firmware_minor=60).has_extended_multizone def test_it_has_items(self): - class P(lifx.Product): pid = 1 name = "Product" @@ -160,7 +155,6 @@ class cap(lifx.Capability): assert dct == expected def test_it_has_items_for_non_light_products(self): - class P_SWITCH(lifx.Product): pid = 1 name = "Product" diff --git a/modules/tests/photons_protocol_tests/test_messages.py b/modules/tests/photons_protocol_tests/test_messages.py index 6a867e64..b9df5923 100644 --- a/modules/tests/photons_protocol_tests/test_messages.py +++ b/modules/tests/photons_protocol_tests/test_messages.py @@ -53,7 +53,6 @@ class M(Messages): } def test_it_has_the_MessagesMixin(self): - class M(Messages): pass diff --git a/modules/tests/photons_protocol_tests/test_messages_mixin.py b/modules/tests/photons_protocol_tests/test_messages_mixin.py index eeccd914..2f304b12 100644 --- a/modules/tests/photons_protocol_tests/test_messages_mixin.py +++ b/modules/tests/photons_protocol_tests/test_messages_mixin.py @@ -26,9 +26,7 @@ def test_it_delegates_for_dicts(self): packet_type_from_dict = mock.Mock(name="packet_type_from_dict", return_value=res) data = {} - with mock.patch.object( - PacketTypeExtractor, "packet_type_from_dict", packet_type_from_dict - ): + with mock.patch.object(PacketTypeExtractor, "packet_type_from_dict", packet_type_from_dict): assert PacketTypeExtractor.packet_type(data) is res packet_type_from_dict.assert_called_once_with(data) @@ -38,23 +36,17 @@ def test_it_delegates_for_bytes(self): packet_type_from_bytes = mock.Mock(name="packet_type_from_bytes", return_value=res) data = b"AA" - with mock.patch.object( - PacketTypeExtractor, "packet_type_from_bytes", packet_type_from_bytes - ): + with mock.patch.object(PacketTypeExtractor, "packet_type_from_bytes", packet_type_from_bytes): assert PacketTypeExtractor.packet_type(data) is res packet_type_from_bytes.assert_called_once_with(data) def test_it_delegates_for_bitarray(self): res = mock.Mock(name="res") - packet_type_from_bitarray = mock.Mock( - name="packet_type_from_bitarray", return_value=res - ) + packet_type_from_bitarray = mock.Mock(name="packet_type_from_bitarray", return_value=res) data = ba(b"AA") - with mock.patch.object( - PacketTypeExtractor, "packet_type_from_bitarray", packet_type_from_bitarray - ): + with mock.patch.object(PacketTypeExtractor, "packet_type_from_bitarray", packet_type_from_bitarray): assert PacketTypeExtractor.packet_type(data) is res packet_type_from_bitarray.assert_called_once_with(data) @@ -185,7 +177,6 @@ def test_it_can_get_the_source_for_packets(self, TestMessages): class TestMessagesMixin: - @pytest.fixture() def protocol_register(self, TestMessages): protocol_register = ProtocolRegister() @@ -194,7 +185,6 @@ def protocol_register(self, TestMessages): return protocol_register class TestGetPacketType: - def test_it_can_get_us_information_about_our_data(self, protocol_register, TestMessages): data = mock.Mock(name="data") packet_type = mock.Mock(name="packet_type", return_value=(1024, 78)) @@ -214,9 +204,7 @@ def test_it_can_get_us_information_about_our_data(self, protocol_register, TestM packet_type.assert_called_once_with(data) - def test_it_can_get_us_information_about_unknown_pkt_types_known_protocol( - self, protocol_register - ): + def test_it_can_get_us_information_about_unknown_pkt_types_known_protocol(self, protocol_register): data = mock.Mock(name="data") packet_type = mock.Mock(name="packet_type", return_value=(1024, 88)) @@ -264,9 +252,7 @@ def test_it_works(self, protocol_register, TestMessages): assert pkt.pack() == bts def test_it_works_with_unknown_packet(self, protocol_register): - bts = LIFXPacket( - pkt_type=100, source=1, sequence=2, target="d073d5000001", payload="AA" - ).pack() + bts = LIFXPacket(pkt_type=100, source=1, sequence=2, target="d073d5000001", payload="AA").pack() pkt = Messages.create(bts, protocol_register, unknown_ok=True) assert isinstance(pkt, LIFXPacket) @@ -358,9 +344,7 @@ def test_it_works_with_unknown_packet(self, protocol_register): bts = LIFXPacket.create(**data).pack() assert Messages.pack(data, protocol_register, unknown_ok=True) == bts - def test_it_works_out_packet_type_and_packs_when_you_have_a_PacketKls( - self, protocol_register - ): + def test_it_works_out_packet_type_and_packs_when_you_have_a_PacketKls(self, protocol_register): res = mock.Mock(name="res") kls = mock.Mock(name="kls") pkt = mock.Mock(name="pkt") @@ -379,9 +363,7 @@ def test_it_works_out_packet_type_and_packs_when_you_have_a_PacketKls( pkt.pack.assert_called_once_with() get_packet_type.assert_called_once_with(data, protocol_register) - def test_it_works_out_packet_type_and_packs_when_you_have_dont_have_PacketKls_but_unknown_is_ok( - self, protocol_register - ): + def test_it_works_out_packet_type_and_packs_when_you_have_dont_have_PacketKls_but_unknown_is_ok(self, protocol_register): res = mock.Mock(name="res") kls = mock.Mock(name="kls") pkt = mock.Mock(name="pkt") diff --git a/modules/tests/photons_protocol_tests/test_multiple.py b/modules/tests/photons_protocol_tests/test_multiple.py index 227127cf..90d363e3 100644 --- a/modules/tests/photons_protocol_tests/test_multiple.py +++ b/modules/tests/photons_protocol_tests/test_multiple.py @@ -27,11 +27,10 @@ def list_of_dicts(lst): This behaviour is due to a performance optimisation I don't want to remove so, I compare with normalised values instead """ - return [l.as_dict() for l in lst] + return [item.as_dict() for item in lst] class TestTheMultipleModifier: - def assertProperties(self, thing, checker): checker(thing) @@ -43,7 +42,6 @@ def assertProperties(self, thing, checker): checker(thing3) def test_it_allows_multiple_of_raw_types_and_structs(self): - class Other(dictobj.PacketSpec): fields = [("four", T.Uint32)] @@ -65,7 +63,6 @@ def test_thing(thing): self.assertProperties(thing, test_thing) def test_it_create_items_from_nothing(self): - class E(enum.Enum): ZERO = 0 MEH = 1 @@ -112,7 +109,6 @@ class Thing(dictobj.PacketSpec): ] def test_it_allows_replacing_items_in_place(self): - class E(enum.Enum): ZERO = 0 MEH = 1 @@ -180,7 +176,6 @@ def test_replacement(thing): self.assertProperties(thing, test_replacement) def test_it_allows_replacing_items_in_place_when_from_nothing(self): - class E(enum.Enum): ZERO = 0 MEH = 1 @@ -228,7 +223,6 @@ def test_replacement(thing): self.assertProperties(thing, test_replacement) def test_it_complains_if_setting_a_value_incorrectly(self): - class E(enum.Enum): ZERO = 0 MEH = 1 @@ -264,15 +258,12 @@ def test_thing(last_one_enum, thing): thing.five[1] = 6 with assertRaises(BadSpecValue, "Expected an integer"): thing.two[0] = "asdf" - with assertRaises( - BadSpecValue, "BoolInts must be True, False, 0 or 1", meta=Meta.empty().at("one") - ): + with assertRaises(BadSpecValue, "BoolInts must be True, False, 0 or 1", meta=Meta.empty().at("one")): thing.four[0] = {"one": "asdf"} self.assertProperties(thing, partial(test_thing, UnknownEnum(6))) def test_it_can_set_as_bytes(self): - class E(enum.Enum): ZERO = 0 MEH = 1 @@ -328,7 +319,6 @@ def check2(thing): self.assertProperties(thing, check2) def test_it_can_edit_structs_inline(self): - class Other(dictobj.PacketSpec): fields = [("other", T.BoolInt), ("another", T.String(64).default(""))] @@ -366,7 +356,6 @@ def check2(thing): self.assertProperties(thing, check2) def test_it_can_determine_class_and_number_based_off_other_fields(self): - class One(dictobj.PacketSpec): fields = [("one", T.BoolInt.multiple(4).default(lambda pkt: False))] @@ -386,9 +375,7 @@ class Chooser(dictobj.PacketSpec): ("val", T.Bytes(32).multiple(lambda pkt: pkt.amount, kls=choose_kls)), ] - chooser = Chooser( - choice="one", amount=3, val=[{"one": [True, True, False, True]}, {"one": [False, True]}] - ) + chooser = Chooser(choice="one", amount=3, val=[{"one": [True, True, False, True]}, {"one": [False, True]}]) def check(chooser): assert chooser.choice == "one" @@ -411,7 +398,6 @@ def check(chooser): self.assertProperties(chooser, check) def test_it_can_determine_number_based_off_other_fields(self): - class Vals(dictobj.PacketSpec): fields = [ ("amount", T.Uint8), diff --git a/modules/tests/photons_protocol_tests/test_packet_spec.py b/modules/tests/photons_protocol_tests/test_packet_spec.py index 3bba8e24..787d3261 100644 --- a/modules/tests/photons_protocol_tests/test_packet_spec.py +++ b/modules/tests/photons_protocol_tests/test_packet_spec.py @@ -20,9 +20,7 @@ def test_it_complains_if_we_have_fields_that_are_already_attributes(self): class Together(dictobj.PacketSpec): fields = [("items", T.Bool), ("values", T.Bool), ("one", T.Bool)] - with assertRaises( - ProgrammerError, r"Can't override attributes with fields\talready_attributes=\['one'\]" - ): + with assertRaises(ProgrammerError, r"Can't override attributes with fields\talready_attributes=\['one'\]"): class Together2(dictobj.PacketSpec): fields = [("one", T.Bool)] @@ -31,7 +29,6 @@ def one(self): pass def test_it_complains_if_we_have_duplicate_names(self): - class Group1(metaclass=PacketSpecMetaKls): fields = [("one", T.Bool), ("two", T.Bool)] @@ -56,7 +53,6 @@ class Child(metaclass=PacketSpecMetaKls): fields = {} def test_it_complains_if_it_cant_find_field(self): - class Parent: fields = {} @@ -72,7 +68,6 @@ class Child2(metaclass=PacketSpecMetaKls): pass def test_it_sets_the_defaults_for_groups_to_Initial_and_sbNotSpecified_for_normal_fields(self): - class Group1(metaclass=PacketSpecMetaKls): fields = [("one", T.Bool), ("two", T.Bool)] @@ -118,7 +113,6 @@ class Wat2(Wat): assert Wat2().yeap == yeap class TestMeta: - @pytest.fixture() def V(self): class V: @@ -144,21 +138,18 @@ class Group2(metaclass=PacketSpecMetaKls): return V() def test_it_has_a_nice_repr(self): - class Thing(metaclass=PacketSpecMetaKls): fields = [] assert repr(Thing.Meta) == "" def test_it_has_multi(self): - class Thing(metaclass=PacketSpecMetaKls): fields = [] assert Thing.Meta.multi is None def test_it_has_groups(self, V): - class Together(metaclass=PacketSpecMetaKls): fields = [("g1", V.Group1), ("g2", V.Group2), ("another", T.Bool)] @@ -167,7 +158,6 @@ class Together(metaclass=PacketSpecMetaKls): assert V.Group1.Meta.groups == {} def test_it_has_name_to_group(self, V): - class Together(metaclass=PacketSpecMetaKls): fields = [("g1", V.Group1), ("g2", V.Group2), ("another", T.Bool)] @@ -181,7 +171,6 @@ class Together(metaclass=PacketSpecMetaKls): assert V.Group1.Meta.name_to_group == {} def test_it_has_all_names(self, V): - class Together(metaclass=PacketSpecMetaKls): fields = [("g1", V.Group1), ("g2", V.Group2), ("another", T.Bool)] @@ -189,7 +178,6 @@ class Together(metaclass=PacketSpecMetaKls): assert V.Group1.Meta.all_names == ["one", "two"] def test_it_has_all_field_types(self, V): - class Together(metaclass=PacketSpecMetaKls): fields = [("g1", V.Group1), ("g2", V.Group2), ("another", T.Bool)] @@ -209,7 +197,6 @@ class Together(metaclass=PacketSpecMetaKls): assert V.Group1.Meta.all_field_types_dict == dict(V.Group1.Meta.all_field_types) def test_it_has_field_types(self, V): - class Together(metaclass=PacketSpecMetaKls): fields = [("g1", V.Group1), ("g2", V.Group2), ("another", T.Bool)] @@ -224,7 +211,6 @@ class Together(metaclass=PacketSpecMetaKls): assert V.Group1.Meta.field_types_dict == dict(V.Group1.Meta.field_types) def test_it_has_format_types(self, V): - class Together(metaclass=PacketSpecMetaKls): fields = [("g1", V.Group1), ("g2", V.Group2), ("another", T.Bool)] @@ -235,7 +221,6 @@ class Together(metaclass=PacketSpecMetaKls): assert V.Group2.Meta.format_types == [V.three_typ, V.four_typ] def test_it_has_original_fields(self, V): - class Together(metaclass=PacketSpecMetaKls): fields = [("g1", V.Group1), ("g2", V.Group2), ("another", T.Bool)] @@ -254,7 +239,6 @@ class Together(metaclass=PacketSpecMetaKls): ] def test_it_can_get_type_from_a_string(self, V): - class Together(metaclass=PacketSpecMetaKls): fields = [("g1", V.Group1), ("g2", V.Group2), ("another", "Another")] diff --git a/modules/tests/photons_protocol_tests/test_packet_spec_attributes.py b/modules/tests/photons_protocol_tests/test_packet_spec_attributes.py index dd75e55e..265d42d4 100644 --- a/modules/tests/photons_protocol_tests/test_packet_spec_attributes.py +++ b/modules/tests/photons_protocol_tests/test_packet_spec_attributes.py @@ -20,7 +20,6 @@ class TestPacketAttributes: class TestGetitem: def test_it_raises_KeyError_if_the_key_is_not_on_the_packet(self): - class P(dictobj.PacketSpec): fields = [] @@ -29,7 +28,6 @@ class P(dictobj.PacketSpec): p["one"] def test_it_does_not_raise_KeyError_if_the_key_is_a_group(self): - class P(dictobj.PacketSpec): fields = [("payload", "Payload")] @@ -40,7 +38,6 @@ class Payload(dictobj.PacketSpec): assert p["payload"] == P.Payload() def test_it_uses_sbNotSpecified_if_there_is_no_value_for_the_key(self): - class P(dictobj.PacketSpec): fields = [("one", T.String)] @@ -51,12 +48,9 @@ class P(dictobj.PacketSpec): with mock.patch.object(p, "getitem_spec", getitem_spec): assert p["one"] is val - getitem_spec.assert_called_once_with( - T.String, "one", sb.NotSpecified, None, None, True, False, True - ) + getitem_spec.assert_called_once_with(T.String, "one", sb.NotSpecified, None, None, True, False, True) def test_it_uses_found_value_if_there_is_a_value_for_the_key(self): - class P(dictobj.PacketSpec): fields = [("one", T.String)] @@ -71,7 +65,6 @@ class P(dictobj.PacketSpec): getitem_spec.assert_called_once_with(T.String, "one", v, None, None, True, False, True) def test_it_passes_along_information_provided_to_getitem_spec(self): - class P(dictobj.PacketSpec): fields = [("one", T.String)] @@ -97,12 +90,9 @@ class P(dictobj.PacketSpec): with mock.patch.object(p, "getitem_spec", getitem_spec): assert p.__getitem__("one", **options) is val - getitem_spec.assert_called_once_with( - T.String, "one", v, parent, serial, do_transform, allow_bitarray, unpacking - ) + getitem_spec.assert_called_once_with(T.String, "one", v, parent, serial, do_transform, allow_bitarray, unpacking) def test_it_returns_empty_payload_as_a_bitarray(self): - class P(dictobj.PacketSpec): parent_packet = True fields = [("payload", "Payload")] @@ -119,7 +109,6 @@ class Payload(dictobj.PacketSpec): assert P(payload=val).__getitem__("payload", allow_bitarray=True) == b def test_it_returns_nonempty_payload_as_that_payload(self): - class P(dictobj.PacketSpec): parent_packet = True fields = [("payload", "Payload")] @@ -138,7 +127,6 @@ class Payload(dictobj.PacketSpec): assert Child(one=True).payload == Child.Payload(one=True) def test_it_returns_groups_as_filled_in(self): - class G(dictobj.PacketSpec): fields = [ ("one", T.Bool.default(lambda p: True)), @@ -154,7 +142,6 @@ class P(dictobj.PacketSpec): assert type(g) is G def test_it_does_not_use_getitem_spec_if_do_spec_is_False(self): - class P(dictobj.PacketSpec): fields = [("one", T.String)] @@ -172,7 +159,6 @@ class P(dictobj.PacketSpec): assert len(getitem_spec.mock_calls) == 0 def test_it_works_for_transformed_values(self): - def pack_t(p, v): return v + 5 @@ -187,7 +173,6 @@ class P(dictobj.PacketSpec): assert p.__getitem__("one", unpacking=False) == 5 def test_it_works_for_bytes_values(self): - class P(dictobj.PacketSpec): fields = [("one", T.Bytes)] @@ -200,15 +185,13 @@ class P(dictobj.PacketSpec): assert p.__getitem__("one", allow_bitarray=True) == b def test_it_works_for_transform_values_that_have_no_value(self): - class P(dictobj.PacketSpec): fields = [ ( "one", T.Int16.transform( - lambda _, v: (int(str(v).split(".")[0]) << 0x10) - + int(str(v).split(".")[1]), - lambda v: float("{0}.{1}".format(v >> 0x10, v & 0xFF)), + lambda _, v: (int(str(v).split(".")[0]) << 0x10) + int(str(v).split(".")[1]), + lambda v: float(f"{v >> 0x10}.{v & 0xFF}"), ), ) ] @@ -217,7 +200,6 @@ class P(dictobj.PacketSpec): assert p.one is sb.NotSpecified class TestGetitemSpec: - @pytest.fixture() def V(self): class V: @@ -268,18 +250,14 @@ class P(PacketSpecMixin): p = P() meta = Meta.empty() - assert ( - V.getitem_spec(p, actual, do_transform=True, allow_bitarray=True) is V.untransformed - ) + assert V.getitem_spec(p, actual, do_transform=True, allow_bitarray=True) is V.untransformed actual.assert_called_with(V.parent, V.serial) V.typ.spec.assert_called_once_with(p, V.unpacking, transform=False) V.initd_spec.normalise.assert_called_with(meta.at(V.key), cald) V.untransform.assert_called_with(p, V.normalised) - def test_it_does_not_call_the_value_if_its_not_allowed_to_be_callable_and_is_callable( - self, V - ): + def test_it_does_not_call_the_value_if_its_not_allowed_to_be_callable_and_is_callable(self, V): actual = mock.Mock(name="actual") class P(PacketSpecMixin): @@ -287,9 +265,7 @@ class P(PacketSpecMixin): p = P() meta = Meta.empty() - assert ( - V.getitem_spec(p, actual, do_transform=True, allow_bitarray=True) is V.untransformed - ) + assert V.getitem_spec(p, actual, do_transform=True, allow_bitarray=True) is V.untransformed assert len(actual.mock_calls) == 0 V.typ.spec.assert_called_once_with(p, V.unpacking, transform=False) @@ -304,9 +280,7 @@ class P(PacketSpecMixin): p = P() meta = Meta.empty() - assert ( - V.getitem_spec(p, actual, do_transform=False, allow_bitarray=True) is V.normalised - ) + assert V.getitem_spec(p, actual, do_transform=False, allow_bitarray=True) is V.normalised assert len(actual.mock_calls) == 0 V.typ.spec.assert_called_once_with(p, V.unpacking, transform=False) @@ -314,7 +288,6 @@ class P(PacketSpecMixin): assert len(V.untransform.mock_calls) == 0 def test_it_does_not_transform_if_the_value_from_spec_is_sbNotSpecified(self, V): - class P(PacketSpecMixin): pass @@ -322,17 +295,13 @@ class P(PacketSpecMixin): meta = Meta.empty() V.initd_spec.normalise.return_value = sb.NotSpecified - assert ( - V.getitem_spec(p, sb.NotSpecified, do_transform=True, allow_bitarray=True) - is sb.NotSpecified - ) + assert V.getitem_spec(p, sb.NotSpecified, do_transform=True, allow_bitarray=True) is sb.NotSpecified V.typ.spec.assert_called_once_with(p, V.unpacking, transform=False) V.initd_spec.normalise.assert_called_with(meta.at(V.key), sb.NotSpecified) assert len(V.untransform.mock_calls) == 0 def test_it_does_not_transform_if_the_value_from_spec_is_Optional(self, V): - class P(PacketSpecMixin): pass @@ -340,10 +309,7 @@ class P(PacketSpecMixin): meta = Meta.empty() V.initd_spec.normalise.return_value = Optional - assert ( - V.getitem_spec(p, sb.NotSpecified, do_transform=True, allow_bitarray=True) - is Optional - ) + assert V.getitem_spec(p, sb.NotSpecified, do_transform=True, allow_bitarray=True) is Optional V.typ.spec.assert_called_once_with(p, V.unpacking, transform=False) V.initd_spec.normalise.assert_called_with(meta.at(V.key), sb.NotSpecified) @@ -388,9 +354,7 @@ class P(PacketSpecMixin): p = P() meta = Meta.empty() - assert V.getitem_spec(p, actual, do_transform=True, allow_bitarray=True) == bitarray( - "0000" - ) + assert V.getitem_spec(p, actual, do_transform=True, allow_bitarray=True) == bitarray("0000") V.typ.spec.assert_called_once_with(p, V.unpacking, transform=False) V.initd_spec.normalise.assert_called_with(meta.at(V.key), actual) @@ -405,9 +369,7 @@ class P(PacketSpecMixin): p = P() meta = Meta.empty() - assert V.getitem_spec(p, actual, do_transform=False, allow_bitarray=True) == bitarray( - "0000" - ) + assert V.getitem_spec(p, actual, do_transform=False, allow_bitarray=True) == bitarray("0000") V.typ.spec.assert_called_once_with(p, V.unpacking, transform=False) V.initd_spec.normalise.assert_called_with(meta.at(V.key), actual) @@ -430,7 +392,6 @@ class P(PacketSpecMixin): class TestGetattr: def test_it_uses_getitem_if_is_a_Group(self): - class P(PacketSpecMixin): class Meta: groups = ["one"] @@ -445,7 +406,6 @@ class Meta: __getitem__.assert_called_once_with("one") def test_it_uses_getitem_if_is_in_all_names(self): - class P(PacketSpecMixin): class Meta: groups = [] @@ -510,7 +470,6 @@ class Meta: class TestSetattr: def test_it_uses_setitem_if_key_is_a_group(self): - class P(PacketSpecMixin): class Meta: groups = ["one"] @@ -526,7 +485,6 @@ class Meta: __setitem__.assert_called_once_with("one", val) def test_it_uses_setitem_if_key_is_a_field(self): - class P(PacketSpecMixin): class Meta: groups = [] @@ -543,7 +501,6 @@ class Meta: __setitem__.assert_called_once_with("one", val) def test_it_uses_dictobj_setattr_if_key_is_neither_a_group_or_field(self): - class P(PacketSpecMixin): class Meta: groups = [] @@ -567,7 +524,6 @@ class Meta: dictobj__setattr__.assert_called_once_with(p, "one", val) def test_it_works_in_union_with_getattr_semantics(self): - def pack_t(p, v): return v + 5 @@ -588,7 +544,6 @@ class P(dictobj.PacketSpec): class TestSetitem: def test_it_does_nothing_if_the_key_is_a_group_and_value_is_Initial(self): - class G(dictobj.PacketSpec): fields = [("one", T.String)] @@ -622,7 +577,6 @@ class P(dictobj.PacketSpec): assert list(p.actual_items()) == [("one", sb.NotSpecified)] class TestTransformation: - @pytest.fixture() def V(self): class V: @@ -639,9 +593,7 @@ def unpack_t(s): @hp.memoized_property def two_typ(s): - return mock.Mock( - name="two_typ", _transform=sb.NotSpecified, spec=["_transform"] - ) + return mock.Mock(name="two_typ", _transform=sb.NotSpecified, spec=["_transform"]) @hp.memoized_property def P(s): @@ -699,7 +651,6 @@ def test_it_does_transformation_for_other_values(self, V): class TestSetGroupItem: class TestSettingEmptyPayload: - @pytest.fixture() def P(self): class P(dictobj.PacketSpec): @@ -736,7 +687,6 @@ def test_it_sets_the_value_if_its_str_bytes_or_bitarray(self, P): assert dictobj.__getitem__(p, "payload") == val class TestSettingAGroupAsSbNotSpecified: - @pytest.fixture() def P(self): class G(dictobj.PacketSpec): @@ -752,9 +702,7 @@ def test_it_sets_all_the_fields_in_that_group_as_NotSpecified(self, P): assert sorted(p.actual_items()) == sorted([("one", "wat"), ("two", 8)]) p["g"] = sb.NotSpecified - assert sorted(p.actual_items()) == sorted( - [("one", sb.NotSpecified), ("two", sb.NotSpecified)] - ) + assert sorted(p.actual_items()) == sorted([("one", sb.NotSpecified), ("two", sb.NotSpecified)]) class TestSettingAGroupFromAnInstanceOfThatGroup: def test_it_does_a_direct_copy_without_going_through_transformation_or_specs(self): @@ -817,7 +765,6 @@ class P(dictobj.PacketSpec): ) class TestSettingAGroupFromNotAnInstanceOfThatGroup: - @pytest.fixture() def V(self): class V: @@ -869,20 +816,15 @@ def test_it_sets_values_from_items_on_the_val(self, V): ] p = V.P() - assert sorted(p.actual_items()) == sorted( - [("one", sb.NotSpecified), ("two", sb.NotSpecified)] - ) + assert sorted(p.actual_items()) == sorted([("one", sb.NotSpecified), ("two", sb.NotSpecified)]) p["g"] = val - assert sorted(p.actual_items()) == sorted( - [("one", V.for_packing), ("two", "d073d5")] - ) + assert sorted(p.actual_items()) == sorted([("one", V.for_packing), ("two", "d073d5")]) assert p.one == V.for_user assert p.two == binascii.unhexlify("d073d5") class TestInformation: - @pytest.fixture def V(self): class V: diff --git a/modules/tests/photons_protocol_tests/test_packet_spec_mixin.py b/modules/tests/photons_protocol_tests/test_packet_spec_mixin.py index ccf0ae55..926bca61 100644 --- a/modules/tests/photons_protocol_tests/test_packet_spec_mixin.py +++ b/modules/tests/photons_protocol_tests/test_packet_spec_mixin.py @@ -26,7 +26,6 @@ class V: class TestPacketSpecMixin: class TestSimple: - @pytest.fixture() def Group1(self): class Group1(dictobj.PacketSpec): @@ -46,14 +45,11 @@ def packet(self, Packet): return Packet(one="wat", two=2, another=True) class TestPack: - def test_it_uses_the_provided_packing_kls(self, packet, V): res = mock.Mock(name="res") V.packing_kls.pack.return_value = res - r = packet.pack( - payload=V.payload, parent=V.parent, serial=V.serial, packing_kls=V.packing_kls - ) + r = packet.pack(payload=V.payload, parent=V.parent, serial=V.serial, packing_kls=V.packing_kls) assert r is res V.packing_kls.pack.assert_called_once_with(packet, V.payload, V.parent, V.serial) @@ -108,7 +104,6 @@ class Another(dictobj.PacketSpec): six_typ.size_bits.assert_called_once_with(values) class TestSpecWithMocks: - @pytest.fixture() def V(self): class V: @@ -223,9 +218,7 @@ def patched_packet_spec(s): def test_it_it_works_on_a_normal_PacketSpec(self, V): with V.patched_packet_spec() as packet_spec: assert V.Group1.spec() is V.spec - packet_spec.assert_called_once_with( - V.Group1, [("one", V.one_spec), ("two", V.two_spec)], {} - ) + packet_spec.assert_called_once_with(V.Group1, [("one", V.one_spec), ("two", V.two_spec)], {}) def test_it_it_works_on_a_PacketSpec_with_groups(self, V): with V.patched_packet_spec() as packet_spec: @@ -268,7 +261,6 @@ def test_it_it_works_on_a_child_PacketSpec_with_string_group(self, V): ) class TestSpecWithoutMocks: - @pytest.fixture() def V(self): class V: @@ -280,12 +272,11 @@ class Group2(dictobj.PacketSpec): ( "two", T.Int16.transform( - lambda _, v: (int(str(v).split(".")[0]) << 0x10) - + int(str(v).split(".")[1]), - lambda _, v: float("{0}.{1}".format(v >> 0x10, v & 0xFF)), + lambda _, v: (int(str(v).split(".")[0]) << 0x10) + int(str(v).split(".")[1]), + lambda _, v: float(f"{v >> 0x10}.{v & 0xFF}"), ), ), - ("mod", T.String.default(lambda p: "{0}.modified".format(p["two"]))), + ("mod", T.String.default(lambda p: f"{p['two']}.modified")), ("sb", T.Int8), ("bts", T.Bytes(lambda p: p["sb"])), ] @@ -355,7 +346,7 @@ class Packet(dictobj.PacketSpec): def test_it_works(self): b = bitarray(endian="little") - b.frombytes("wat".encode()) + b.frombytes(b"wat") b = b + bitarray("0" * 10) class Thing(dictobj.PacketSpec): @@ -367,7 +358,6 @@ class Thing(dictobj.PacketSpec): class TestIsDynamic: def test_it_says_no_if_no_field_allows_callable(self): - class P(dictobj.PacketSpec): fields = [("one", T.Bool), ("two", T.String)] @@ -375,7 +365,6 @@ class P(dictobj.PacketSpec): assert not p.is_dynamic def test_it_says_no_if_a_field_allows_callable_but_has_not_a_callable_alue(self): - class P(dictobj.PacketSpec): fields = [("one", T.Bool), ("two", T.String.allow_callable())] @@ -383,7 +372,6 @@ class P(dictobj.PacketSpec): assert not p.is_dynamic def test_it_says_yes_if_a_field_allows_callable_and_has_a_callable_alue(self): - class P(dictobj.PacketSpec): fields = [("one", T.Bool), ("two", T.String.allow_callable())] @@ -392,7 +380,6 @@ class P(dictobj.PacketSpec): class TestContains: def test_it_says_yes_if_the_field_is_on_the_packet(self): - class P(dictobj.PacketSpec): fields = [("one", T.Bool), ("two", T.String)] @@ -401,7 +388,6 @@ class P(dictobj.PacketSpec): assert "three" not in p def test_it_says_yes_if_the_field_is_in_a_group(self): - class G(dictobj.PacketSpec): fields = [("one", T.Bool), ("two", T.String)] @@ -413,7 +399,6 @@ class P(dictobj.PacketSpec): assert "three" not in p def test_it_says_yes_if_the_field_is_a_group(self): - class G(dictobj.PacketSpec): fields = [("one", T.Bool), ("two", T.String)] @@ -425,7 +410,6 @@ class P(dictobj.PacketSpec): class TestCloning: def test_it_works(self): - class G(dictobj.PacketSpec): fields = [("one", T.Bool), ("two", T.String)] @@ -544,7 +528,6 @@ class Child(P): class TestTobytes: def test_it_just_packs_if_payload_is_already_simple(self): - class P(dictobj.PacketSpec): fields = [("payload", T.Bytes)] @@ -561,7 +544,6 @@ class P(dictobj.PacketSpec): pack.assert_called_once_with(payload=b) def test_it_simplifies_first_if_payload_is_not_str_bytes_or_bitarray(self): - class P(dictobj.PacketSpec): fields = [("payload", "Payload")] @@ -592,7 +574,6 @@ class Payload(dictobj.PacketSpec): class TestAsDict: def test_it_returns_groups_with_transformed_values(self): - def pack_t(p, v): return v + 2 @@ -609,7 +590,6 @@ class P(dictobj.PacketSpec): assert dct == {"g": {"one": True, "two": 1}} def test_it_returns_groups_with_untransformed_values_if_asked_not_to_transform(self): - def pack_t(p, v): return v + 2 @@ -626,7 +606,6 @@ class P(dictobj.PacketSpec): assert dct == {"g": {"one": True, "two": 3}} def test_it_includes_payload_as_simple_if_we_are_a_parent_packet(self): - class G(dictobj.PacketSpec): fields = [("one", T.Bool)] @@ -646,7 +625,6 @@ class Payload(dictobj.PacketSpec): assert dct == {"g": {"one": True}, "payload": b.tobytes()} def test_it_includes_payload_as_complex_if_we_are_not_a_parent_packet(self): - class G(dictobj.PacketSpec): fields = [("one", T.Bool)] @@ -668,11 +646,8 @@ class Payload(dictobj.PacketSpec): assert dct == {"g": {"one": True}, "payload": {"two": 65}} def test_it_converts_lists(self): - class P(dictobj.PacketSpec): - fields = [ - ("one", T.Int16.transform(lambda _, v: int(v / 1000), lambda _, v: v * 1000)) - ] + fields = [("one", T.Int16.transform(lambda _, v: int(v / 1000), lambda _, v: v * 1000))] class Q(dictobj.PacketSpec): fields = [("things", T.Bytes(16).multiple(3, kls=lambda pkt: P))] @@ -705,7 +680,6 @@ class P(dictobj.PacketSpec): assert repr(p) == '{"payload": "d073d5"}' def test_it_reprs_what_isnt_jsonfiable(self): - class E(enum.Enum): ONE = 1 @@ -718,7 +692,6 @@ class P(dictobj.PacketSpec): class TestCreating: def test_it_uses_the_spec_on_the_kls(self): - class P(dictobj.PacketSpec): fields = [] @@ -736,7 +709,6 @@ class P(dictobj.PacketSpec): initd_spec.normalise.assert_called_once_with(mock.ANY, val) def test_it_allows_kwargs_val_with_create(self): - class P(dictobj.PacketSpec): fields = [] diff --git a/modules/tests/photons_protocol_tests/test_packing.py b/modules/tests/photons_protocol_tests/test_packing.py index 51e9ca77..7866d963 100644 --- a/modules/tests/photons_protocol_tests/test_packing.py +++ b/modules/tests/photons_protocol_tests/test_packing.py @@ -57,7 +57,6 @@ def test_it_complains_otherwise(self): class TestBitarraySlice: - @pytest.fixture() def slce(self): name = mock.Mock(name="name") @@ -108,9 +107,7 @@ def test_it_returns_as_boolean_value_if_fmt_is_bool_and_size_bits_is_1(self, slc slce.val = bitarray("1") assert slce.unpackd is True - def test_it_pads_left_if_original_size_is_greater_than_actual_val_and_we_have_left_cut( - self, slce - ): + def test_it_pads_left_if_original_size_is_greater_than_actual_val_and_we_have_left_cut(self, slce): slce.typ = T.Int8.S(6, left=True) slce.val = bitarray("000010", endian="little") @@ -122,9 +119,7 @@ def test_it_pads_left_if_original_size_is_greater_than_actual_val_and_we_have_le assert slce.unpackd == 64 - def test_it_pads_right_if_original_size_is_greater_than_actual_val_and_we_dont_have_left_cut( - self, slce - ): + def test_it_pads_right_if_original_size_is_greater_than_actual_val_and_we_dont_have_left_cut(self, slce): slce.typ = T.Int8.S(6) slce.val = bitarray("000010", endian="little") @@ -151,7 +146,6 @@ def test_it_raises_BadConversion_if_it_cant_unpack_the_field(self, slce): class TestFieldInfo: - @pytest.fixture() def val(self): return mock.Mock(name="val") @@ -183,17 +177,13 @@ class TestValue: def test_it_returns_value_as_is(self, info, val): assert info.value is val - def test_it_returns_value_as_0_bits_if_our_typ_is_Reserved_and_val_is_NotSpecified( - self, info - ): + def test_it_returns_value_as_0_bits_if_our_typ_is_Reserved_and_val_is_NotSpecified(self, info): info.typ = T.Reserved(8) info.size_bits = 8 info.val = sb.NotSpecified assert info.value == bitarray("0" * 8) - def test_it_returns_value_as_is_if_typ_is_Reserved_but_value_is_not_NotSpecified( - self, info, val - ): + def test_it_returns_value_as_is_if_typ_is_Reserved_but_value_is_not_NotSpecified(self, info, val): info.typ = T.Reserved(8) assert info.value == val @@ -247,7 +237,6 @@ def test_it_does_nothing_if_correct_size(self, info): to_bitarray.assert_called_once_with() class TestToBitarray: - @contextmanager def a_val(self, val): with mock.patch.object(FieldInfo, "value", val): @@ -357,7 +346,6 @@ def test_it_understands_the_Optional_value(self, info): class TestPacketPacking: - @pytest.fixture() def V(self): class V: @@ -385,9 +373,8 @@ class P(dictobj.PacketSpec): class TestFieldsIn: def test_it_yields_FieldInfo_objects(self, V): - def cb(pkt, serial): - return "{0}.cb".format(serial) + return f"{serial}.cb" p = V.P(one=True, two=cb, other=1) @@ -405,9 +392,8 @@ def cb(pkt, serial): class TestPktFromBitarray: def test_it_creates_a_pkt_field_by_field(self, V): - def cb(pkt, serial): - return "{0}.cb2".format(serial) + return f"{serial}.cb2" p = V.P(one=True, two=cb, other=1) packd = p.pack(serial="d073d5") @@ -466,7 +452,6 @@ def do_set(f, name, val): def test_it_returns_where_we_are_in_the_bitarray_which_is_helpful_when_we_have_an_empty_payload( self, ): - class P(dictobj.PacketSpec): parent_packet = True fields = [("one", T.Int16), ("payload", "Payload")] @@ -508,9 +493,7 @@ def test_it_gets_fields_from_fields_in_and_joins_the_bitarrays_to_form_a_final_b parent = mock.Mock(name="parent") serial = mock.Mock(name="serial") with mock.patch.object(PacketPacking, "fields_in", fields_in): - assert PacketPacking.pack(pkt, parent=parent, serial=serial) == bitarray( - "01111010", endian="little" - ) + assert PacketPacking.pack(pkt, parent=parent, serial=serial) == bitarray("01111010", endian="little") fields_in.assert_called_once_with(pkt, parent, serial) @@ -543,9 +526,7 @@ class Payload(dictobj.PacketSpec): parent = mock.Mock(name="parent") serial = mock.Mock(name="serial") with mock.patch.object(PacketPacking, "fields_in", fields_in): - assert PacketPacking.pack( - pkt, payload=payload, parent=parent, serial=serial - ) == bitarray("0111101001010101", endian="little") + assert PacketPacking.pack(pkt, payload=payload, parent=parent, serial=serial) == bitarray("0111101001010101", endian="little") fields_in.assert_called_once_with(pkt, parent, serial) @@ -578,14 +559,11 @@ class Payload(dictobj.PacketSpec): parent = mock.Mock(name="parent") serial = mock.Mock(name="serial") with mock.patch.object(PacketPacking, "fields_in", fields_in): - assert PacketPacking.pack(pkt, parent=parent, serial=serial) == bitarray( - "0111101001010101", endian="little" - ) + assert PacketPacking.pack(pkt, parent=parent, serial=serial) == bitarray("0111101001010101", endian="little") fields_in.assert_called_once_with(pkt, parent, serial) def test_it_does_not_set_payload_if_we_arent_a_parent_packet(self): - class P(dictobj.PacketSpec): parent_packet = True fields = [("payload", "Payload")] @@ -624,9 +602,7 @@ def test_it_complains_if_we_have_a_field_with_no_value(self): serial = mock.Mock(name="serial") with assertRaises(BadConversion, "Failed to convert field into a bitarray"): with mock.patch.object(PacketPacking, "fields_in", fields_in): - assert PacketPacking.pack(pkt, parent=parent, serial=serial) == bitarray( - "01111010", endian="little" - ) + assert PacketPacking.pack(pkt, parent=parent, serial=serial) == bitarray("01111010", endian="little") fields_in.assert_called_once_with(pkt, parent, serial) @@ -658,7 +634,6 @@ def test_it_uses_pkt_from_bitarray(self): ] def test_it_assigns_the_remainder_if_we_have_a_payload_with_message_type_0(self): - class P(dictobj.PacketSpec): parent_packet = True fields = [("one", T.Int8), ("payload", "Payload")] diff --git a/modules/tests/photons_protocol_tests/test_type.py b/modules/tests/photons_protocol_tests/test_type.py index a45d6ec9..d559f0e3 100644 --- a/modules/tests/photons_protocol_tests/test_type.py +++ b/modules/tests/photons_protocol_tests/test_type.py @@ -10,10 +10,8 @@ from photons_app import helpers as hp from photons_app.errors import ProgrammerError from photons_protocol.errors import BadConversion -from photons_protocol.types import Optional -from photons_protocol.types import Type +from photons_protocol.types import Optional, Type, UnknownEnum, json_spec, static_conversion_from_spec from photons_protocol.types import Type as T -from photons_protocol.types import UnknownEnum, json_spec, static_conversion_from_spec class TestTheJsonSpec: @@ -60,7 +58,6 @@ def test_it_takes_in_struct_format_and_conversion(self): assert t.conversion is conversion class TestAddingSizeBits: - @pytest.fixture() def V(self): class V: @@ -155,7 +152,6 @@ def test_it_generates_a_new_class_from_Type_and_instantiates_it(self): assert t.__class__ is not Type class TestModifiers: - @pytest.fixture() def V(self): class V: @@ -210,7 +206,6 @@ def test_it_sets_enum_to_the_value_passed_in(self, V): assert setd == {"_enum": em, "_unknown_enum_values": True} def test_it_allows_unknown_enums_by_default(self, V): - class E(enum.Enum): ONE = 1 TWO = 2 @@ -264,19 +259,13 @@ def test_it_complains_if_either_function_isnt_callable(self, V): uncallable_unpack_func = mock.NonCallableMock(name="uncallable_unpack_func") with V.clone(cloned=False) as (res, setd): - with assertRaises( - ProgrammerError, "Sorry, transform can only be given two callables" - ): + with assertRaises(ProgrammerError, "Sorry, transform can only be given two callables"): V.t.transform(uncallable_pack_func, unpack_func) - with assertRaises( - ProgrammerError, "Sorry, transform can only be given two callables" - ): + with assertRaises(ProgrammerError, "Sorry, transform can only be given two callables"): V.t.transform(pack_func, uncallable_unpack_func) - with assertRaises( - ProgrammerError, "Sorry, transform can only be given two callables" - ): + with assertRaises(ProgrammerError, "Sorry, transform can only be given two callables"): V.t.transform(uncallable_pack_func, uncallable_unpack_func) class TestAllowCallable: @@ -313,9 +302,7 @@ def test_it_sets_override_to_the_value_if_callable(self, V): assert V.t.override(val) is res assert setd == {"_override": val} - def test_it_sets_override_to_a_callable_taking_in_packet_return_value_if_not_callable( - self, V - ): + def test_it_sets_override_to_a_callable_taking_in_packet_return_value_if_not_callable(self, V): pkt = mock.Mock(name="pkt") val = mock.NonCallableMock(name="val") with V.clone() as (res, setd): @@ -329,9 +316,8 @@ def test_it_expects_a_list_of_name_size_fmt_conversion_to_create_types_from(self expected = { # D2 has a non None size, so we expect it to be called with the size - ("D2", ", }") == (1 << 1) + ( - 1 << 2 - ) + assert subject.normalise(meta, "{, }") == (1 << 1) + (1 << 2) def test_it_returns_as_is_if_the_value_is_a_number(self, meta, subject): assert subject.normalise(meta, 200) == 200 def test_it_complains_if_it_cant_convert_the_value(self, meta, bitmask, subject): for val in ("", "asdf", True, {}, {1: 2}, None, lambda: 1): - with assertRaises( - BadConversion, "Can't convert value into mask", mask=bitmask, got=val - ): + with assertRaises(BadConversion, "Can't convert value into mask", mask=bitmask, got=val): subject.normalise(meta, val) def test_it_converts_empty_array_into_0(self, meta, subject): @@ -479,7 +450,6 @@ def test_it_only_counts_values_once(self, meta, bitmask, subject): assert subject.normalise(meta, v) == (1 << 3) class TestUnpackingIntoAList: - @pytest.fixture() def subject(self, bitmask, pkt): return types.bitmask_spec(pkt, bitmask, unpacking=True) @@ -494,22 +464,15 @@ def test_it_returns_what_values_it_can_find_in_the_value(self, meta, bitmask, su def test_it_ignores_left_over(self, meta, bitmask, subject): v = (1 << 1) + (1 << 3) + (1 << 4) - assert subject.normalise(meta, v + 1) == set( - [bitmask.ONE, bitmask.THREE, bitmask.FOUR] - ) + assert subject.normalise(meta, v + 1) == set([bitmask.ONE, bitmask.THREE, bitmask.FOUR]) def test_it_works_with_the_string_set(self, meta, subject): assert subject.normalise(meta, "set()") == set() def test_it_works_with_a_set_as_a_string(self, meta, bitmask, subject): - assert subject.normalise(meta, "{, }") == set( - [bitmask.ONE, bitmask.TWO] - ) - - def test_it_complains_if_it_finds_a_value_from_a_different_enum( - self, meta, bitmask, subject - ): + assert subject.normalise(meta, "{, }") == set([bitmask.ONE, bitmask.TWO]) + def test_it_complains_if_it_finds_a_value_from_a_different_enum(self, meta, bitmask, subject): class Mask2(Enum): ONE = 1 << 1 TWO = 1 << 2 @@ -527,9 +490,7 @@ def test_it_complains_if_it_cant_find_a_string_value_in_the_mask(self, meta, sub with assertRaises(BadConversion, "Can't convert value into value from mask"): subject.normalise(meta, "SEVEN") - def test_it_does_not_complain_if_it_cant_find_an_integer_value_in_the_mask( - self, meta, subject - ): + def test_it_does_not_complain_if_it_cant_find_an_integer_value_in_the_mask(self, meta, subject): assert subject.normalise(meta, (1 << 24)) == set() @@ -548,7 +509,6 @@ def test_it_takes_in_some_things(self): assert spec.allow_unknown is allow_unknown class TestNormalisation: - @pytest.fixture() def enum(self): class Vals(Enum): @@ -561,7 +521,6 @@ class Vals(Enum): return Vals def test_it_complains_if_enum_is_not_an_Enum(self, meta, pkt): - class Kls: def __init__(s, pkt): pass @@ -573,12 +532,9 @@ def __call__(s, pkt): with assertRaises(ProgrammerError, "Enum is not an enum!"): types.enum_spec(pkt, thing).normalise(meta, mock.Mock(name="val")) with assertRaises(ProgrammerError, "Enum is not an enum!"): - types.enum_spec(pkt, thing, allow_unknown=True).normalise( - meta, mock.Mock(name="val") - ) + types.enum_spec(pkt, thing, allow_unknown=True).normalise(meta, mock.Mock(name="val")) class TestPackingIntoAValue: - @pytest.fixture() def subject(self, pkt, enum): return types.enum_spec(pkt, enum, unpacking=False) @@ -591,15 +547,11 @@ def test_it_can_convert_from_the_name(self, meta, subject, subject_with_unknown) assert subject.normalise(meta, "ONE") == 1 assert subject_with_unknown.normalise(meta, "ONE") == 1 - def test_it_can_convert_from_repr_of_the_member( - self, meta, subject, subject_with_unknown - ): + def test_it_can_convert_from_repr_of_the_member(self, meta, subject, subject_with_unknown): assert subject.normalise(meta, "") == 1 assert subject_with_unknown.normalise(meta, "") == 1 - def test_it_can_convert_from_member_itself( - self, meta, subject, enum, subject_with_unknown - ): + def test_it_can_convert_from_member_itself(self, meta, subject, enum, subject_with_unknown): assert subject.normalise(meta, enum.TWO) == 2 assert subject_with_unknown.normalise(meta, enum.TWO) == 2 @@ -612,19 +564,14 @@ def test_it_complains_if_its_not_in_the_enum(self, meta, subject, subject_with_u with assertRaises(BadConversion, "Value wasn't a valid enum value"): subject_with_unknown.normalise(meta, val) - def test_it_does_not_complain_if_allow_unknown_and_value_not_in_the_enum_and_valid_value( - self, meta, subject, subject_with_unknown - ): + def test_it_does_not_complain_if_allow_unknown_and_value_not_in_the_enum_and_valid_value(self, meta, subject, subject_with_unknown): ue = types.UnknownEnum(20) assert subject_with_unknown.normalise(meta, ue) == 20 assert subject_with_unknown.normalise(meta, repr(ue)) == 20 assert subject_with_unknown.normalise(meta, 40) == 40 - def test_it_complains_if_were_using_the_wrong_enum( - self, meta, subject, subject_with_unknown - ): - + def test_it_complains_if_were_using_the_wrong_enum(self, meta, subject, subject_with_unknown): class Vals2(Enum): ONE = 1 TWO = 2 @@ -638,7 +585,6 @@ class Vals2(Enum): subject_with_unknown.normalise(meta, Vals2.THREE) class TestUnpackingIntoEnumMember: - @pytest.fixture() def subject(self, pkt, enum): return types.enum_spec(pkt, enum, unpacking=True) @@ -647,14 +593,11 @@ def subject(self, pkt, enum): def subject_with_unknown(self, pkt, enum): return types.enum_spec(pkt, enum, unpacking=True, allow_unknown=True) - def test_it_returns_as_is_if_already_a_member( - self, meta, subject, enum, subject_with_unknown - ): + def test_it_returns_as_is_if_already_a_member(self, meta, subject, enum, subject_with_unknown): assert subject.normalise(meta, enum.TWO) is enum.TWO assert subject_with_unknown.normalise(meta, enum.TWO) is enum.TWO def test_it_complains_if_from_the_wrong_enum(self, meta, subject, subject_with_unknown): - class Vals2(Enum): ONE = 1 TWO = 2 @@ -671,15 +614,11 @@ def test_it_converts_from_name(self, meta, subject, enum, subject_with_unknown): assert subject.normalise(meta, "THREE") == enum.THREE assert subject_with_unknown.normalise(meta, "THREE") == enum.THREE - def test_it_converts_from_repr_of_member( - self, meta, subject, enum, subject_with_unknown - ): + def test_it_converts_from_repr_of_member(self, meta, subject, enum, subject_with_unknown): assert subject.normalise(meta, "") == enum.THREE assert subject_with_unknown.normalise(meta, "") == enum.THREE - def test_it_converts_from_value_of_member( - self, meta, subject, enum, subject_with_unknown - ): + def test_it_converts_from_value_of_member(self, meta, subject, enum, subject_with_unknown): assert subject.normalise(meta, 4) == enum.FOUR assert subject_with_unknown.normalise(meta, 4) == enum.FOUR @@ -693,9 +632,7 @@ def test_it_complains_if_value_isnt_in_enum(self, meta, subject, subject_with_un with assertRaises(BadConversion, "Value is not a valid value of the enum"): subject_with_unknown.normalise(meta, val) - def test_it_does_not_complain_if_allow_unknown_and_valid_unknown_value( - self, meta, subject, subject_with_unknown - ): + def test_it_does_not_complain_if_allow_unknown_and_valid_unknown_value(self, meta, subject, subject_with_unknown): ue = types.UnknownEnum(20) assert subject_with_unknown.normalise(meta, ue) is ue assert subject_with_unknown.normalise(meta, repr(ue)) == ue @@ -840,7 +777,6 @@ def test_it_takes_in_pkt_size_bits_and_unpacking(self): assert spec.unpacking is unpacking class TestPackingIntoBitarray: - @pytest.fixture() def subject(self, pkt): return types.csv_spec(pkt, 200 * 8, unpacking=False) @@ -851,9 +787,7 @@ def val(self): v2 = str(uuid.uuid1()) return [v1, v2] - def test_it_converts_a_list_into_a_comma_separated_string_into_bitarray( - self, meta, val, subject - ): + def test_it_converts_a_list_into_a_comma_separated_string_into_bitarray(self, meta, val, subject): expected_bytes = ",".join(val).encode() + b"\x00" assert len(expected_bytes) == 74 result = subject.normalise(meta, val).tobytes() @@ -894,7 +828,6 @@ def test_it_converts_bitarray_into_bitarray_with_correct_size(self, meta, val, s assert result[74:] == bitarray("0" * (200 - 74) * 8).tobytes() class TestUnpackingIntoList: - @pytest.fixture() def subject(self, pkt): return types.csv_spec(pkt, 200 * 8, unpacking=True) @@ -938,9 +871,7 @@ def test_it_works_from_the_repr_of_sbNotSpecified(self, meta, pkt): assert types.bytes_spec(pkt, 8).normalise(meta, repr(sb.NotSpecified)) == expected expected = bitarray("0" * 8) - assert ( - types.bytes_spec(pkt, 8).normalise(meta, repr(sb.NotSpecified).replace("'", "")) - ) == expected + assert (types.bytes_spec(pkt, 8).normalise(meta, repr(sb.NotSpecified).replace("'", ""))) == expected def test_it_returns_None_as_the_size_bits_of_bitarray(self, meta, pkt): expected = bitarray("0" * 8) @@ -961,26 +892,20 @@ def test_it_expands_if_not_long_enough(self, meta, pkt): expected = bitarray("1" * 8 + "0" * 12) assert types.bytes_spec(pkt, 20).normalise(meta, val) == expected assert types.bytes_spec(pkt, 20).normalise(meta, val.tobytes()) == expected - assert ( - types.bytes_spec(pkt, 20).normalise(meta, binascii.hexlify(val.tobytes()).decode()) - ) == expected + assert (types.bytes_spec(pkt, 20).normalise(meta, binascii.hexlify(val.tobytes()).decode())) == expected def test_it_cuts_off_if_too_long(self, meta, pkt): val = bitarray("1" * 24) expected = bitarray("1" * 9) assert types.bytes_spec(pkt, 9).normalise(meta, val) == expected assert types.bytes_spec(pkt, 9).normalise(meta, val.tobytes()) == expected - assert ( - types.bytes_spec(pkt, 9).normalise(meta, binascii.hexlify(val.tobytes()).decode()) - ) == expected + assert (types.bytes_spec(pkt, 9).normalise(meta, binascii.hexlify(val.tobytes()).decode())) == expected def test_it_returns_if_just_right(self, meta, pkt): val = bitarray("1" * 8) assert types.bytes_spec(pkt, 8).normalise(meta, val) == val assert types.bytes_spec(pkt, 8).normalise(meta, val.tobytes()) == val - assert ( - types.bytes_spec(pkt, 8).normalise(meta, binascii.hexlify(val.tobytes()).decode()) - ) == val + assert (types.bytes_spec(pkt, 8).normalise(meta, binascii.hexlify(val.tobytes()).decode())) == val def test_it_gets_size_bits_by_calling_it_with_the_pkt_if_its_a_callable(self, meta, pkt): size_bits = mock.Mock(name="size_bits", return_value=11) @@ -1006,7 +931,6 @@ def test_it_takes_in_pkt_size_bits_and_unpacking(self): assert spec.unpacking is unpacking class TestUnpackingIntoAString: - @pytest.fixture() def subject(self, pkt): return types.bytes_as_string_spec(pkt, 20 * 8, True) @@ -1025,7 +949,6 @@ def test_it_does_not_cut_if_no_null_byte_is_found(self, meta, subject): assert subject.normalise(meta, val) == val.decode() class TestPackingIntoBytes: - @pytest.fixture() def subject(self, pkt): return types.bytes_as_string_spec(pkt, 20 * 8, False) @@ -1063,7 +986,6 @@ def test_it_gets_size_bits_by_calling_it_with_the_pkt_if_its_a_callable(self, me class TestFloatSpec: - @pytest.fixture() def subject(self): return types.float_spec() diff --git a/modules/tests/photons_pytest/test_fake_call_later.py b/modules/tests/photons_pytest/test_fake_call_later.py index 756c17d0..4e7b8a39 100644 --- a/modules/tests/photons_pytest/test_fake_call_later.py +++ b/modules/tests/photons_pytest/test_fake_call_later.py @@ -8,7 +8,6 @@ def call_later(*args): class TestMockedCalledLater: - async def test_it_works(self, FakeTime, MockedCallLater): with FakeTime() as t: async with MockedCallLater(t): diff --git a/modules/tests/photons_transport_tests/comms/test_base_helpers.py b/modules/tests/photons_transport_tests/comms/test_base_helpers.py index d33c71e7..0852a696 100644 --- a/modules/tests/photons_transport_tests/comms/test_base_helpers.py +++ b/modules/tests/photons_transport_tests/comms/test_base_helpers.py @@ -8,9 +8,7 @@ class TestTimeoutTask: - async def test_it_does_nothing_if_the_task_has_a_result(self): - async def doit(): return 1 @@ -23,7 +21,6 @@ async def doit(): assert not errf.done() async def test_it_does_nothing_if_the_task_has_an_exception(self): - async def doit(): raise Exception("NOPE") @@ -38,7 +35,6 @@ async def doit(): assert not errf.done() async def test_it_does_nothing_if_the_task_was_cancelled(self): - async def doit(): return 1 diff --git a/modules/tests/photons_transport_tests/comms/test_communication.py b/modules/tests/photons_transport_tests/comms/test_communication.py index ae9f7ae9..6bfc8eda 100644 --- a/modules/tests/photons_transport_tests/comms/test_communication.py +++ b/modules/tests/photons_transport_tests/comms/test_communication.py @@ -69,7 +69,6 @@ def test_it_behaves_like_an_Acknowledgement(self): class TestCommunication: async def test_it_is_formattable(self, V): - class Other: pass @@ -80,9 +79,7 @@ class Thing(dictobj.Spec): other = dictobj.Field(sb.overridden("{other}"), formatted=True) comms = dictobj.Field(sb.overridden("{comms}"), formatted=True) - thing = Thing.FieldSpec(formatter=MergedOptionStringFormatter).normalise( - Meta(options, []).at("thing"), {} - ) + thing = Thing.FieldSpec(formatter=MergedOptionStringFormatter).normalise(Meta(options, []).at("thing"), {}) assert thing.comms is V.communication assert thing.other == str(other) @@ -294,9 +291,7 @@ async def test_it_can_replace_a_transport_when_closing_it_fails(self, V): serial = "d073d5000001" service = mock.Mock(name="service") othertransport = mock.Mock(name="othertransport") - othertransport.close = pytest.helpers.AsyncMock( - name="close", side_effect=Exception("NOPE") - ) + othertransport.close = pytest.helpers.AsyncMock(name="close", side_effect=Exception("NOPE")) V.communication.found[serial] = {service: othertransport} @@ -313,7 +308,6 @@ async def test_it_can_replace_a_transport_when_closing_it_fails(self, V): othertransport.close.assert_called_once_with() async def test_it_does_not_replace_if_the_transport_is_equal(self, V): - class T: def __eq__(s, other): return True @@ -349,14 +343,10 @@ async def test_it_uses_find_specific_serials(self, V): find_specific_serials.return_value = (found, missing) with mock.patch.object(V.communication, "find_specific_serials", find_specific_serials): - f = await V.communication.find_devices( - ignore_lost=ignore_lost, raise_on_none=raise_on_none, broadcast=broadcast, a=a - ) + f = await V.communication.find_devices(ignore_lost=ignore_lost, raise_on_none=raise_on_none, broadcast=broadcast, a=a) assert f is found - find_specific_serials.assert_called_once_with( - None, ignore_lost=ignore_lost, raise_on_none=raise_on_none, broadcast=broadcast, a=a - ) + find_specific_serials.assert_called_once_with(None, ignore_lost=ignore_lost, raise_on_none=raise_on_none, broadcast=broadcast, a=a) async def test_it_has_defaults_for_ignore_lost_and_raise_on_none(self, V): a = mock.Mock(name="a") @@ -370,12 +360,9 @@ async def test_it_has_defaults_for_ignore_lost_and_raise_on_none(self, V): f = await V.communication.find_devices(a=a) assert f is found - find_specific_serials.assert_called_once_with( - None, ignore_lost=False, raise_on_none=False, a=a - ) + find_specific_serials.assert_called_once_with(None, ignore_lost=False, raise_on_none=False, a=a) class TestFindSpecificSerials: - @pytest.fixture() def V(self, VBase): V = VBase @@ -408,9 +395,7 @@ async def assertSpecificSerials(s, serials, found, missing): _find_specific_serials = pytest.helpers.AsyncMock(name="_find_specific_serials") _find_specific_serials.return_value = f - with mock.patch.object( - s.communication, "_find_specific_serials", _find_specific_serials - ): + with mock.patch.object(s.communication, "_find_specific_serials", _find_specific_serials): f2, m = await s.communication.find_specific_serials( serials, ignore_lost=ignore_lost, @@ -430,18 +415,12 @@ async def assertSpecificSerials(s, serials, found, missing): ) _find_specific_serials.reset_mock() - with mock.patch.object( - s.communication, "_find_specific_serials", _find_specific_serials - ): - f3, m = await s.communication.find_specific_serials( - serials, broadcast=broadcast, a=a - ) + with mock.patch.object(s.communication, "_find_specific_serials", _find_specific_serials): + f3, m = await s.communication.find_specific_serials(serials, broadcast=broadcast, a=a) assert f3 is f assert m == missing - _find_specific_serials.assert_called_once_with( - serials, ignore_lost=False, raise_on_none=False, broadcast=broadcast, a=a - ) + _find_specific_serials.assert_called_once_with(serials, ignore_lost=False, raise_on_none=False, broadcast=broadcast, a=a) return V() @@ -506,10 +485,7 @@ async def _do_search(serials, timeout, **kwargs): timeout = mock.Mock(name="timeout") with mock.patch.object(V.communication, "_do_search", _do_search): - assert ( - await V.communication._find_specific_serials(serials, timeout=timeout, a=a) - is found - ) + assert await V.communication._find_specific_serials(serials, timeout=timeout, a=a) is found _do_search.assert_called_once_with(serials, timeout, a=a) @@ -536,10 +512,7 @@ async def _do_search(serials, timeout, **kwargs): timeout = mock.Mock(name="timeout") with mock.patch.object(V.communication, "_do_search", _do_search): - assert ( - await V.communication._find_specific_serials(serials, timeout=timeout, a=a) - is found - ) + assert await V.communication._find_specific_serials(serials, timeout=timeout, a=a) is found _do_search.assert_called_once_with(serials, timeout, a=a) @@ -568,11 +541,7 @@ async def _do_search(serials, timeout, **kwargs): timeout = mock.Mock(name="timeout") with mock.patch.object(V.communication, "_do_search", _do_search): - assert ( - await V.communication._find_specific_serials( - serials, timeout=timeout, ignore_lost=True, a=a - ) - ) is found + assert (await V.communication._find_specific_serials(serials, timeout=timeout, ignore_lost=True, a=a)) is found _do_search.assert_called_once_with(serials, timeout, a=a) @@ -595,18 +564,14 @@ async def _do_search(serials, timeout, **kwargs): with assertRaises(FoundNoDevices): with mock.patch.object(V.communication, "_do_search", _do_search): - await V.communication._find_specific_serials( - None, timeout=timeout, raise_on_none=True, a=a - ) + await V.communication._find_specific_serials(None, timeout=timeout, raise_on_none=True, a=a) _do_search.assert_called_once_with(None, timeout, a=a) assert not found s3.close.assert_called_once_with() - async def test_it_does_not_complain_if_none_are_found_and_raise_on_none_but_non_None_serials( - self, V - ): + async def test_it_does_not_complain_if_none_are_found_and_raise_on_none_but_non_None_serials(self, V): s3 = mock.Mock(name="s3", spec=[]) found = V.communication.found found["d073d5000003"] = {"UDP": s3} @@ -621,11 +586,7 @@ async def _do_search(serials, timeout, **kwargs): timeout = mock.Mock(name="timeout") with mock.patch.object(V.communication, "_do_search", _do_search): - assert ( - await V.communication._find_specific_serials( - serials, raise_on_none=True, timeout=timeout, a=a - ) - ) is found + assert (await V.communication._find_specific_serials(serials, raise_on_none=True, timeout=timeout, a=a)) is found _do_search.assert_called_once_with(serials, timeout, a=a) @@ -643,11 +604,7 @@ async def _do_search(serials, timeout, **kwargs): timeout = mock.Mock(name="timeout") with mock.patch.object(V.communication, "_do_search", _do_search): - assert ( - await V.communication._find_specific_serials( - None, ignore_lost=True, timeout=timeout, a=a - ) - ) is found + assert (await V.communication._find_specific_serials(None, ignore_lost=True, timeout=timeout, a=a)) is found _do_search.assert_called_once_with(None, timeout, a=a) @@ -663,21 +620,16 @@ async def test_it_is_a_send_with_a_broadcast_transport(self, V): transport = mock.Mock(name="transport") send_single = pytest.helpers.AsyncMock(name="send_single", return_value=res) - make_broadcast_transport = pytest.helpers.AsyncMock( - name="make_broadcast_transport", return_value=transport - ) + make_broadcast_transport = pytest.helpers.AsyncMock(name="make_broadcast_transport", return_value=transport) mod = {"send_single": send_single, "make_broadcast_transport": make_broadcast_transport} with mock.patch.multiple(V.communication, **mod): assert await V.communication.broadcast(packet, broadcast, a=a) is res make_broadcast_transport.assert_awaited_once_with(broadcast) - send_single.assert_awaited_once_with( - packet, is_broadcast=True, transport=transport, a=a - ) + send_single.assert_awaited_once_with(packet, is_broadcast=True, transport=transport, a=a) class TestPrivateTransportForSend: - @pytest.fixture() def V(self, VBase): V = VBase @@ -695,19 +647,11 @@ def transport(s): @contextmanager def maker_mocks(s): - make_broadcast_transport = pytest.helpers.AsyncMock( - name="make_broadcast_transport", return_value=s.transport - ) - choose_transport = pytest.helpers.AsyncMock( - name="choose_transport", return_value=s.transport - ) + make_broadcast_transport = pytest.helpers.AsyncMock(name="make_broadcast_transport", return_value=s.transport) + choose_transport = pytest.helpers.AsyncMock(name="choose_transport", return_value=s.transport) - mbt_patch = mock.patch.object( - s.communication, "make_broadcast_transport", make_broadcast_transport - ) - ct_patch = mock.patch.object( - s.communication, "choose_transport", choose_transport - ) + mbt_patch = mock.patch.object(s.communication, "make_broadcast_transport", make_broadcast_transport) + ct_patch = mock.patch.object(s.communication, "choose_transport", choose_transport) with mbt_patch, ct_patch: yield (make_broadcast_transport, choose_transport) @@ -716,9 +660,7 @@ def maker_mocks(s): async def test_it_uses_make_broadcast_transport_if_broadcast(self, V): with V.maker_mocks() as (make_broadcast_transport, choose_transport): - res = await V.communication._transport_for_send( - None, V.packet, V.original, True, V.connect_timeout - ) + res = await V.communication._transport_for_send(None, V.packet, V.original, True, V.connect_timeout) assert res == (V.transport, True) make_broadcast_transport.assert_called_once_with(True) @@ -729,9 +671,7 @@ async def test_it_uses_make_broadcast_transport_if_broadcast_is_an_address(self, broadcast = "192.168.0.255" with V.maker_mocks() as (make_broadcast_transport, choose_transport): - res = await V.communication._transport_for_send( - None, V.packet, V.original, broadcast, V.connect_timeout - ) + res = await V.communication._transport_for_send(None, V.packet, V.original, broadcast, V.connect_timeout) assert res == (V.transport, True) make_broadcast_transport.assert_called_once_with(broadcast) @@ -742,9 +682,7 @@ async def test_it_uses_make_broadcast_transport_if_packet_target_is_None(self, V V.packet.target = None with V.maker_mocks() as (make_broadcast_transport, choose_transport): - res = await V.communication._transport_for_send( - None, V.packet, V.original, False, V.connect_timeout - ) + res = await V.communication._transport_for_send(None, V.packet, V.original, False, V.connect_timeout) assert res == (V.transport, True) make_broadcast_transport.assert_called_once_with(True) @@ -759,9 +697,7 @@ async def test_it_uses_choose_transport_if_not_for_broadcasting(self, V): V.communication.found["d073d5"] = services with V.maker_mocks() as (make_broadcast_transport, choose_transport): - res = await V.communication._transport_for_send( - None, V.packet, V.original, False, V.connect_timeout - ) + res = await V.communication._transport_for_send(None, V.packet, V.original, False, V.connect_timeout) assert res == (V.transport, False) choose_transport.assert_called_once_with(V.original, services) @@ -774,9 +710,7 @@ async def test_it_complains_if_the_serial_doesnt_exist(self, V): with assertRaises(FailedToFindDevice, serial="d073d5"): with V.maker_mocks() as (make_broadcast_transport, choose_transport): - await V.communication._transport_for_send( - None, V.packet, V.original, False, V.connect_timeout - ) + await V.communication._transport_for_send(None, V.packet, V.original, False, V.connect_timeout) assert len(make_broadcast_transport.mock_calls) == 0 assert len(choose_transport.mock_calls) == 0 @@ -784,9 +718,7 @@ async def test_it_complains_if_the_serial_doesnt_exist(self, V): async def test_it_just_spawns_transport_if_one_is_provided(self, V): with V.maker_mocks() as (make_broadcast_transport, choose_transport): - res = await V.communication._transport_for_send( - V.transport, V.packet, V.original, False, V.connect_timeout - ) + res = await V.communication._transport_for_send(V.transport, V.packet, V.original, False, V.connect_timeout) assert res == (V.transport, False) assert len(make_broadcast_transport.mock_calls) == 0 @@ -823,9 +755,7 @@ def recv(pkt, addr, *, allow_zero): recv = pytest.helpers.AsyncMock(name="recv", side_effect=recv) with mock.patch.object(V.communication.receiver, "recv", recv): - pkt = LIFXPacket( - payload=b"things", pkt_type=9001, source=1, sequence=1, target=None - ) + pkt = LIFXPacket(payload=b"things", pkt_type=9001, source=1, sequence=1, target=None) data = pkt.pack().tobytes() await V.communication.received_data(data, addr, allow_zero=allow_zero) diff --git a/modules/tests/photons_transport_tests/comms/test_found.py b/modules/tests/photons_transport_tests/comms/test_found.py index e6ded610..1fe7c224 100644 --- a/modules/tests/photons_transport_tests/comms/test_found.py +++ b/modules/tests/photons_transport_tests/comms/test_found.py @@ -25,7 +25,8 @@ def test_it_can_be_cloned(self): found["d073d5000001"] = {"one": 1, "two": 2} found["d073d5000002"] = {"three": 3, "four": 4} - h = lambda serial: binascii.unhexlify(serial)[:6] + def h(serial): + return binascii.unhexlify(serial)[:6] found2 = found.clone() del found2["d073d5000001"]["one"] @@ -48,7 +49,6 @@ def test_it_can_be_cloned(self): assert found2.found == {h("d073d5000001"): {"two": 2}} def test_it_can_cleanse_a_serial(self, found): - def assertCleansed(i, o): assert found.cleanse_serial(i) == o @@ -166,10 +166,7 @@ def test_it_has_repr(self, found): found["d073d5000001"] = {"UDP": 1, "THI": 2} found["d073d5000002"] = {"MEMORY": 1} - assert ( - repr(found) - == """""" - ) + assert repr(found) == """""" def test_it_can_borrow_found(self, found): t1clone = mock.Mock(name="t1clone") @@ -207,7 +204,6 @@ def test_it_can_borrow_found(self, found): class TestFoundremoveLost: - async def test_it_closes_and_removes_transports_that_are_not_in_found_now(self): ts = [ "d073d5000002", diff --git a/modules/tests/photons_transport_tests/comms/test_receiver.py b/modules/tests/photons_transport_tests/comms/test_receiver.py index 608f1396..bab6467e 100644 --- a/modules/tests/photons_transport_tests/comms/test_receiver.py +++ b/modules/tests/photons_transport_tests/comms/test_receiver.py @@ -17,7 +17,6 @@ async def test_it_inits_some_variables(self): assert receiver.blank_target == b"\x00\x00\x00\x00\x00\x00\x00\x00" class TestUsage: - @pytest.fixture() def V(self): class V: @@ -29,9 +28,7 @@ class V: @hp.memoized_property def packet(s): - return LIFXPacket( - source=s.source, pkt_type=20, sequence=s.sequence, target=s.target - ) + return LIFXPacket(source=s.source, pkt_type=20, sequence=s.sequence, target=s.target) @hp.memoized_property def original(s): @@ -98,9 +95,7 @@ async def test_it_uses_message_catcher_if_cant_find_the_key_and_thats_defined(se assert V.packet.Information.remote_addr is None assert V.packet.Information.sender_message is None - async def test_it_does_not_use_message_catcher_if_can_find_the_key_and_thats_defined( - self, V - ): + async def test_it_does_not_use_message_catcher_if_can_find_the_key_and_thats_defined(self, V): V.register(V.source, V.sequence, V.target) message_catcher = pytest.helpers.AsyncMock(name="message_catcher") diff --git a/modules/tests/photons_transport_tests/comms/test_result.py b/modules/tests/photons_transport_tests/comms/test_result.py index efad9ad0..c83330a3 100644 --- a/modules/tests/photons_transport_tests/comms/test_result.py +++ b/modules/tests/photons_transport_tests/comms/test_result.py @@ -18,9 +18,7 @@ class V: @hp.memoized_property def request(s): - request = mock.NonCallableMock( - name="request", spec=["Meta", "res_required", "ack_required"] - ) + request = mock.NonCallableMock(name="request", spec=["Meta", "res_required", "ack_required"]) request.Meta = s.Meta request.ack_required = True request.res_required = True @@ -28,9 +26,7 @@ def request(s): @hp.memoized_property def gaps(s): - return Gaps( - gap_between_ack_and_res=0.2, gap_between_results=0.1, timeouts=[(1, 1)] - ).empty_normalise() + return Gaps(gap_between_ack_and_res=0.2, gap_between_results=0.1, timeouts=[(1, 1)]).empty_normalise() return V() @@ -40,9 +36,7 @@ def V(VBase): return VBase -gaps = Gaps( - gap_between_ack_and_res=0.2, gap_between_results=0.2, timeouts=[(0.1, 0.1)] -).empty_normalise() +gaps = Gaps(gap_between_ack_and_res=0.2, gap_between_results=0.2, timeouts=[(0.1, 0.1)]).empty_normalise() class TestResult: @@ -78,7 +72,6 @@ async def test_it_sets_as_done_if_ack_required_and_res_required_are_both_False(s assert (await result) == [] class TestAddPacket: - @pytest.fixture() def V(self, VBase): V = VBase @@ -113,7 +106,7 @@ async def test_it_adds_as_a_result_if_the_packet_is_not_an_ack(self, V): V.pkt.represents_ack = False V.result.add_packet(V.pkt) - add_result.assert_called_once_with((V.pkt)) + add_result.assert_called_once_with(V.pkt) assert len(add_ack.mock_calls) == 0 async def test_it_adds_as_a_result_if_no_represents_ack_property_on_the_pkt(self, V): @@ -129,7 +122,6 @@ async def test_it_adds_as_a_result_if_no_represents_ack_property_on_the_pkt(self assert len(add_ack.mock_calls) == 0 class TestAddAck: - @pytest.fixture() def add_ack(self, V): def add_ack(res_required, did_broadcast, now, already_done=False): @@ -175,31 +167,23 @@ async def check_result(expect=None): async def test_it_sets_last_ack_received(self, add_ack): now = time.time() - result, check_result, schedule_finisher = add_ack( - res_required=True, did_broadcast=False, now=now, already_done=True - ) + result, check_result, schedule_finisher = add_ack(res_required=True, did_broadcast=False, now=now, already_done=True) await check_result() assert result.last_ack_received == now assert result.last_res_received is None async def test_it_does_nothing_if_already_done_when_res_required_is_False(self, add_ack): now = time.time() - result, check_result, schedule_finisher = add_ack( - res_required=False, did_broadcast=False, now=now, already_done=True - ) + result, check_result, schedule_finisher = add_ack(res_required=False, did_broadcast=False, now=now, already_done=True) assert result.last_ack_received == now assert result.last_res_received is None await check_result() assert len(schedule_finisher.mock_calls) == 0 - async def test_it_uses_schedule_finisher_if_not_res_required_and_we_did_broadcast( - self, add_ack - ): + async def test_it_uses_schedule_finisher_if_not_res_required_and_we_did_broadcast(self, add_ack): now = time.time() - result, check_result, schedule_finisher = add_ack( - res_required=False, did_broadcast=True, now=now, already_done=False - ) + result, check_result, schedule_finisher = add_ack(res_required=False, did_broadcast=True, now=now, already_done=False) assert result.last_ack_received == now assert result.last_res_received is None @@ -208,9 +192,7 @@ async def test_it_uses_schedule_finisher_if_not_res_required_and_we_did_broadcas async def test_it_finishes_the_result_if_not_did_broadcast_and_dont_need_res(self, add_ack): now = time.time() - result, check_result, schedule_finisher = add_ack( - res_required=False, did_broadcast=False, now=now, already_done=False - ) + result, check_result, schedule_finisher = add_ack(res_required=False, did_broadcast=False, now=now, already_done=False) assert result.last_ack_received == now assert result.last_res_received is None @@ -220,9 +202,7 @@ async def test_it_finishes_the_result_if_not_did_broadcast_and_dont_need_res(sel async def test_it_does_nothing_if_not_finished_and_need_res(self, add_ack): for did_broadcast in (True, False): now = time.time() - result, check_result, schedule_finisher = add_ack( - res_required=True, did_broadcast=did_broadcast, now=now, already_done=False - ) + result, check_result, schedule_finisher = add_ack(res_required=True, did_broadcast=did_broadcast, now=now, already_done=False) assert result.last_ack_received == now assert result.last_res_received is None @@ -230,7 +210,6 @@ async def test_it_does_nothing_if_not_finished_and_need_res(self, add_ack): assert len(schedule_finisher.mock_calls) == 0 class TestAddResult: - @pytest.fixture() def add_result(self, V): def add_result(expected_num, results, now, already_done=False): @@ -278,9 +257,7 @@ async def check_result(expect=None): async def test_it_sets_last_res_received(self, add_result): now = time.time() - result, check_result, added_res, schedule_finisher = add_result( - expected_num=1, results=[], now=now, already_done=True - ) + result, check_result, added_res, schedule_finisher = add_result(expected_num=1, results=[], now=now, already_done=True) await check_result() assert result.last_res_received == now @@ -307,9 +284,7 @@ async def test_it_completes_the_result_if_we_reached_expected_num(self, add_resu one = mock.Mock(name="one") - result, check_result, added_res, schedule_finisher = add_result( - expected_num=2, results=[one], now=now, already_done=False - ) + result, check_result, added_res, schedule_finisher = add_result(expected_num=2, results=[one], now=now, already_done=False) assert result.last_res_received == now assert result.last_ack_received is None @@ -321,9 +296,7 @@ async def test_it_uses_schedule_finisher_if_expected_num_is_1(self, add_result): one = mock.Mock(name="one") - result, check_result, added_res, schedule_finisher = add_result( - expected_num=-1, results=[one], now=now, already_done=False - ) + result, check_result, added_res, schedule_finisher = add_result(expected_num=-1, results=[one], now=now, already_done=False) assert result.last_res_received == now assert result.last_ack_received is None @@ -335,9 +308,7 @@ async def test_it_does_nothing_if_we_havent_reached_num_expected_yet(self, add_r one = mock.Mock(name="one") - result, check_result, added_res, schedule_finisher = add_result( - expected_num=3, results=[one], now=now, already_done=False - ) + result, check_result, added_res, schedule_finisher = add_result(expected_num=3, results=[one], now=now, already_done=False) assert result.last_res_received == now assert result.last_ack_received is None @@ -345,11 +316,7 @@ async def test_it_does_nothing_if_we_havent_reached_num_expected_yet(self, add_r assert len(schedule_finisher.mock_calls) == 0 class TestScheduleFinisher: - - async def test_it_calls_maybe_finish_after_finish_multi_gap_with_the_current_value_for_attr( - self, V, FakeTime, MockedCallLater - ): - + async def test_it_calls_maybe_finish_after_finish_multi_gap_with_the_current_value_for_attr(self, V, FakeTime, MockedCallLater): result = Result(V.request, False, V.gaps) last_ack_received = mock.Mock(name="last_ack_received") result.last_ack_received = last_ack_received @@ -434,7 +401,6 @@ async def test_it_uses_num_results_if_that_is_already_set(self, V): assert result._determine_num_results() is num_results async def test_it_says_1_if_we_have_multi_but_no_matching_packets(self, V): - class Packet: def __init__(s, num, count): s.num = num @@ -452,7 +418,6 @@ def __or__(s, other): assert not hasattr(result, "_num_results") async def test_it_uses_multi_options_to_get_a_number_which_is_then_cached(self, V): - class Packet: def __init__(s, num, count): s.num = num @@ -467,9 +432,7 @@ def __or__(s, other): PacketTwo = Packet(2, count) determine_res_packet = mock.Mock(name="determine_res_packet", return_value=PacketTwo) - adjust_expected_number = mock.Mock( - name="adjust_expected_number", side_effect=lambda req, res: res.count - ) + adjust_expected_number = mock.Mock(name="adjust_expected_number", side_effect=lambda req, res: res.count) V.request.Meta.multi = MultiOptions(determine_res_packet, adjust_expected_number) result = Result(V.request, False, V.gaps) @@ -484,7 +447,6 @@ def __or__(s, other): assert result._num_results is count async def test_it_uses_first_matching_packet_when_adjusting_the_number(self, V): - class Packet: def __init__(s, num, count): s.num = num @@ -499,9 +461,7 @@ def __or__(s, other): PacketTwo = Packet(2, count) determine_res_packet = mock.Mock(name="determine_res_packet", return_value=PacketTwo) - adjust_expected_number = mock.Mock( - name="adjust_expected_number", side_effect=lambda req, res: res.count - ) + adjust_expected_number = mock.Mock(name="adjust_expected_number", side_effect=lambda req, res: res.count) V.request.Meta.multi = MultiOptions(determine_res_packet, adjust_expected_number) result = Result(V.request, False, V.gaps) @@ -524,9 +484,7 @@ async def test_it_returns_as_is_if_determine_num_results_returns_an_integer(self assert result.num_results is val _determine_num_results.assert_called_once_with() - async def test_it_calls_function_with_results_if_determine_num_results_returns_is_a_function( - self, V - ): + async def test_it_calls_function_with_results_if_determine_num_results_returns_is_a_function(self, V): count = mock.Mock(name="count") res = mock.Mock(name="res", return_value=count) _determine_num_results = mock.Mock(name="_determine_num_results", return_value=res) @@ -544,7 +502,6 @@ async def test_it_calls_function_with_results_if_determine_num_results_returns_i _determine_num_results.assert_called_once_with() class TestWaitForResult: - @pytest.fixture() def wait_on_result(self, V): def wait_on_result( @@ -587,13 +544,9 @@ async def test_it_says_no(self, wait_on_result): for results in ([], [1]): for now in (time.time(), time.time() - 20, time.time() + 20): for num_results in (-1, 0, 1): - assert not wait_on_result( - ack_required, False, {}, now, None, None, results, num_results - ) + assert not wait_on_result(ack_required, False, {}, now, None, None, results, num_results) - assert not wait_on_result( - ack_required, False, {}, now, None, 1, results, num_results - ) + assert not wait_on_result(ack_required, False, {}, now, None, 1, results, num_results) assert not wait_on_result( ack_required, @@ -609,26 +562,18 @@ async def test_it_says_no(self, wait_on_result): class TestWithJustResRequired: async def test_it_says_no_if_we_havent_had_a_result_yet(self, wait_on_result): for num_results in (-1, 0, 1): - assert not wait_on_result( - False, True, {}, time.time(), None, None, [], num_results - ) + assert not wait_on_result(False, True, {}, time.time(), None, None, [], num_results) - async def test_it_says_yes_if_num_results_is_1_and_we_have_a_result( - self, wait_on_result - ): + async def test_it_says_yes_if_num_results_is_1_and_we_have_a_result(self, wait_on_result): assert wait_on_result(False, True, {}, time.time(), None, 1, [], -1) - async def test_it_says_yes_if_time_since_last_res_is_less_than_gap_between_results_and_num_results_greater_than_1( - self, wait_on_result - ): + async def test_it_says_yes_if_time_since_last_res_is_less_than_gap_between_results_and_num_results_greater_than_1(self, wait_on_result): now = time.time() last = now - 0.1 retry_gaps = {"gap_between_results": 0.2} assert wait_on_result(False, True, retry_gaps, now, None, last, [], 1) - async def test_it_says_no_if_time_since_last_res_is_greater_than_gap_between_results_and_num_results_greater_than_1( - self, wait_on_result - ): + async def test_it_says_no_if_time_since_last_res_is_greater_than_gap_between_results_and_num_results_greater_than_1(self, wait_on_result): now = time.time() last = now - 0.3 retry_gaps = {"gap_between_results": 0.2} @@ -650,22 +595,16 @@ async def test_it_says_yes_if_we_have_results(self, wait_on_result): for num_results in (-1, 0, 1): assert wait_on_result(True, True, {}, time.time(), 1, 1, results, num_results) - async def test_it_says_yes_if_its_been_less_than_gap_between_ack_and_res_since_ack_and_no_results( - self, wait_on_result - ): + async def test_it_says_yes_if_its_been_less_than_gap_between_ack_and_res_since_ack_and_no_results(self, wait_on_result): now = time.time() last = time.time() - 0.1 retry_gaps = {"gap_between_ack_and_res": 0.2} for num_results in (-1, 0, 1): assert wait_on_result(True, True, retry_gaps, now, last, None, [], num_results) - async def test_it_says_yes_if_its_been_greater_than_gap_between_ack_and_res_since_ack_and_no_results( - self, wait_on_result - ): + async def test_it_says_yes_if_its_been_greater_than_gap_between_ack_and_res_since_ack_and_no_results(self, wait_on_result): now = time.time() last = time.time() - 0.3 retry_gaps = {"gap_between_ack_and_res": 0.2} for num_results in (-1, 0, 1): - assert not wait_on_result( - True, True, retry_gaps, now, last, None, [], num_results - ) + assert not wait_on_result(True, True, retry_gaps, now, last, None, [], num_results) diff --git a/modules/tests/photons_transport_tests/comms/test_send_single.py b/modules/tests/photons_transport_tests/comms/test_send_single.py index ac1caef2..84259918 100644 --- a/modules/tests/photons_transport_tests/comms/test_send_single.py +++ b/modules/tests/photons_transport_tests/comms/test_send_single.py @@ -15,9 +15,7 @@ from photons_products import Products devices = pytest.helpers.mimic() -devices.add("strip")( - "d073d5001337", Products.LCM2_Z, hp.Firmware(2, 80), value_store={"zones_count": 22} -) +devices.add("strip")("d073d5001337", Products.LCM2_Z, hp.Firmware(2, 80), value_store={"zones_count": 22}) @pytest.fixture() @@ -52,7 +50,6 @@ def assertSent(sender, *expected): class TestSendingASingleMessages: - @pytest.fixture() def send_single(self, sender): async def send_single(original, **kwargs): @@ -67,7 +64,6 @@ def device(self): return devices["strip"] class TestHappyPath: - async def test_it_can_send_and_receive_a_single_message(self, send_single, device): original = DeviceMessages.EchoRequest(echoing=b"hi") result = await send_single(original, timeout=1) @@ -83,15 +79,11 @@ async def test_it_can_send_and_receive_a_single_message(self, send_single, devic pkt=CoreMessages.Acknowledgement, replying_to=original, ), - devices.Events.OUTGOING( - device, device.io["MEMORY"], pkt=expected, replying_to=original - ), + devices.Events.OUTGOING(device, device.io["MEMORY"], pkt=expected, replying_to=original), ] async def test_it_can_get_multiple_replies(self, send_single, device): - await device.event( - devices.Events.SET_ZONES, zones=[(i, hp.Color(i, 1, 1, 3500)) for i in range(22)] - ) + await device.event(devices.Events.SET_ZONES, zones=[(i, hp.Color(i, 1, 1, 3500)) for i in range(22)]) devices.store(device).clear() original = MultiZoneMessages.GetColorZones(start_index=0, end_index=255) @@ -117,8 +109,7 @@ async def test_it_can_get_multiple_replies(self, send_single, device): { "zones_count": 22, "zone_index": 16, - "colors": [hp.Color(i, 1, 1, 3500) for i in range(16, 22)] - + [hp.Color(0, 0, 0, 0) for _ in range(22, 24)], + "colors": [hp.Color(i, 1, 1, 3500) for i in range(16, 22)] + [hp.Color(0, 0, 0, 0) for _ in range(22, 24)], }, ), ] @@ -134,17 +125,10 @@ async def test_it_can_get_multiple_replies(self, send_single, device): pkt=CoreMessages.Acknowledgement, replying_to=original, ), - *[ - devices.Events.OUTGOING( - device, device.io["MEMORY"], pkt=ex, replying_to=original - ) - for ex in expected - ], + *[devices.Events.OUTGOING(device, device.io["MEMORY"], pkt=ex, replying_to=original) for ex in expected], ] - async def test_it_can_get_unlimited_replies( - self, send_single, device, FakeTime, MockedCallLater - ): + async def test_it_can_get_unlimited_replies(self, send_single, device, FakeTime, MockedCallLater): original = DiscoveryMessages.GetService(ack_required=False) with FakeTime() as t: async with MockedCallLater(t): @@ -159,16 +143,11 @@ async def test_it_can_get_unlimited_replies( pytest.helpers.assertSamePackets(result, expected) assert devices.store(device) == [ devices.Events.INCOMING(device, device.io["MEMORY"], pkt=original), - devices.Events.OUTGOING( - device, device.io["MEMORY"], pkt=expected, replying_to=original - ), + devices.Events.OUTGOING(device, device.io["MEMORY"], pkt=expected, replying_to=original), ] class TestTimeouts: - - async def test_it_can_retry_until_it_gets_a_timeout( - self, send_single, sender, device, FakeTime, MockedCallLater - ): + async def test_it_can_retry_until_it_gets_a_timeout(self, send_single, sender, device, FakeTime, MockedCallLater): original = DeviceMessages.EchoRequest(echoing=b"hi") with FakeTime() as t: @@ -188,15 +167,10 @@ async def test_it_can_retry_until_it_gets_a_timeout( assertSent( sender, - *[ - (round(at * 0.2, 3), device.serial, original.Payload.__name__, original.payload) - for at in range(int(2 / 0.2)) - ], + *[(round(at * 0.2, 3), device.serial, original.Payload.__name__, original.payload) for at in range(int(2 / 0.2))], ) - async def test_it_can_retry_until_it_gets_a_result( - self, send_single, sender, device, FakeTime, MockedCallLater - ): + async def test_it_can_retry_until_it_gets_a_result(self, send_single, sender, device, FakeTime, MockedCallLater): original = DeviceMessages.EchoRequest(echoing=b"hi") io = device.io["MEMORY"] @@ -226,17 +200,12 @@ async def intercept(event, Cont): pkt=CoreMessages.Acknowledgement, replying_to=original, ), - devices.Events.OUTGOING( - device, device.io["MEMORY"], pkt=expected, replying_to=original - ), + devices.Events.OUTGOING(device, device.io["MEMORY"], pkt=expected, replying_to=original), ] assertSent( sender, - *[ - (at, device.serial, original.Payload.__name__, original.payload) - for at in [0, 0.2, 0.4, 0.6] - ], + *[(at, device.serial, original.Payload.__name__, original.payload) for at in [0, 0.2, 0.4, 0.6]], ) async def test_it_can_give_up_on_getting_multiple_messages_that_have_a_set_length( @@ -290,18 +259,11 @@ async def process_outgoing(reply, req_event, Cont): assertSent( sender, - *[ - (round(at * 0.2, 3), device.serial, original.Payload.__name__, original.payload) - for at in range(int(round(3 / 0.2))) - ], + *[(round(at * 0.2, 3), device.serial, original.Payload.__name__, original.payload) for at in range(int(round(3 / 0.2)))], ) - async def test_it_can_retry_getting_multiple_replies_till_it_has_all_replies( - self, send_single, sender, device, FakeTime, MockedCallLater - ): - original = MultiZoneMessages.GetColorZones( - start_index=0, end_index=255, ack_required=False - ) + async def test_it_can_retry_getting_multiple_replies_till_it_has_all_replies(self, send_single, sender, device, FakeTime, MockedCallLater): + original = MultiZoneMessages.GetColorZones(start_index=0, end_index=255, ack_required=False) io = device.io["MEMORY"] expected = ( @@ -326,8 +288,7 @@ async def test_it_can_retry_getting_multiple_replies_till_it_has_all_replies( dict( zones_count=22, zone_index=16, - colors=[hp.Color(i, 1, 1, 3500) for i in range(16, 22)] - + [hp.Color(0, 0, 0, 0) for _ in range(22, 24)], + colors=[hp.Color(i, 1, 1, 3500) for i in range(16, 22)] + [hp.Color(0, 0, 0, 0) for _ in range(22, 24)], ), ), ) @@ -400,14 +361,10 @@ async def process_outgoing(reply, req_event, Cont): assertSent( sender, - *[ - (round(at * 0.2, 3), device.serial, original.Payload.__name__, original.payload) - for at in range(1 + int(round(2.2 / 0.2))) - ], + *[(round(at * 0.2, 3), device.serial, original.Payload.__name__, original.payload) for at in range(1 + int(round(2.2 / 0.2)))], ) class TestWithoutRetries: - async def test_it_works_if_we_get_a_response_first_time(self, send_single, device): original = DeviceMessages.EchoRequest(echoing=b"hi") expected = (DeviceMessages.EchoResponse, {"echoing": b"hi"}) @@ -418,17 +375,11 @@ async def test_it_works_if_we_get_a_response_first_time(self, send_single, devic io = device.io["MEMORY"] assert devices.store(device) == [ devices.Events.INCOMING(device, io, pkt=original), - devices.Events.OUTGOING( - device, io, pkt=CoreMessages.Acknowledgement(), replying_to=original - ), - devices.Events.OUTGOING( - device, io, pkt=expected[0].create(**expected[1]), replying_to=original - ), + devices.Events.OUTGOING(device, io, pkt=CoreMessages.Acknowledgement(), replying_to=original), + devices.Events.OUTGOING(device, io, pkt=expected[0].create(**expected[1]), replying_to=original), ] - async def test_it_times_out_if_we_dont_get_a_response( - self, send_single, sender, device, FakeTime, MockedCallLater - ): + async def test_it_times_out_if_we_dont_get_a_response(self, send_single, sender, device, FakeTime, MockedCallLater): original = DeviceMessages.EchoRequest(echoing=b"hi") with FakeTime() as t: @@ -543,9 +494,7 @@ async def process_outgoing(reply, req_event, Cont): raise Cont() with process_request, process_outgoing, FakeTime() as t: - async with MockedCallLater(t) as m: - info["m"] = m with assertRaises( @@ -563,9 +512,7 @@ async def process_outgoing(reply, req_event, Cont): devices.Events.INCOMING(device, io, pkt=original), ] - assertSent( - sender, (0, device.serial, original.Payload.__name__, original.payload) - ) + assertSent(sender, (0, device.serial, original.Payload.__name__, original.payload)) await m.resume_after(1.5) assert devices.store(device) == [ @@ -604,9 +551,7 @@ async def process_outgoing(reply, req_event, Cont): raise Cont() with process_request, process_outgoing, FakeTime() as t: - async with MockedCallLater(t) as m: - info["m"] = m result = await send_single(original, timeout=1, no_retry=True) @@ -624,6 +569,4 @@ async def process_outgoing(reply, req_event, Cont): ), ) - assertSent( - sender, (0, device.serial, original.Payload.__name__, original.payload) - ) + assertSent(sender, (0, device.serial, original.Payload.__name__, original.payload)) diff --git a/modules/tests/photons_transport_tests/comms/test_writer.py b/modules/tests/photons_transport_tests/comms/test_writer.py index f06bf349..c5b7fe28 100644 --- a/modules/tests/photons_transport_tests/comms/test_writer.py +++ b/modules/tests/photons_transport_tests/comms/test_writer.py @@ -6,7 +6,6 @@ class TestWriter: - @pytest.fixture() def V(self): class V: diff --git a/modules/tests/photons_transport_tests/session/test_discovery_options.py b/modules/tests/photons_transport_tests/session/test_discovery_options.py index 72341fd9..1a10795d 100644 --- a/modules/tests/photons_transport_tests/session/test_discovery_options.py +++ b/modules/tests/photons_transport_tests/session/test_discovery_options.py @@ -14,7 +14,6 @@ def meta(): class TestServiceTypeSpec: - @pytest.fixture() def spec(self): return do.service_type_spec() @@ -39,7 +38,6 @@ def test_it_complains_if_we_dont_have_a_match(self, meta, spec): class TestHardcodedDiscoverySpec: - @pytest.fixture() def spec(self): return do.hardcoded_discovery_spec() @@ -54,9 +52,7 @@ def fake_spec(self, ret): fake_spec.normalise.return_value = ret return fake_spec - def test_it_uses_HARDCODED_DISCOVERY_environment_variable_if_it_exists( - self, meta, spec, ret, fake_spec - ): + def test_it_uses_HARDCODED_DISCOVERY_environment_variable_if_it_exists(self, meta, spec, ret, fake_spec): spec.spec = fake_spec with pytest.helpers.modified_env(HARDCODED_DISCOVERY='{"one": "two"}'): @@ -124,9 +120,7 @@ def __eq__(s, other): got="d073d500133", meta=meta.at("d073d500133"), ) - e2 = BadSpecValue( - "serials must start with d073d5", got="e073d5001338", meta=meta.at("e073d5001338") - ) + e2 = BadSpecValue("serials must start with d073d5", got="e073d5001338", meta=meta.at("e073d5001338")) e3 = BadSpecValue( "serials must be valid hex", error=S("Non-hexadecimal digit found"), @@ -141,7 +135,6 @@ def __eq__(s, other): class TestServiceInfoSpec: - @pytest.fixture() def spec(self): return do.service_info_spec() @@ -188,7 +181,6 @@ def test_it_complains_about_incomplete_dictionaries(self, meta, spec): class TestSerialSpec: - @pytest.fixture() def spec(self): return do.serial_spec() @@ -218,7 +210,6 @@ def test_it_otherwise_returns_the_serial(self, meta, spec): class TestSerialFilterSpec: - @pytest.fixture() def spec(self): return do.serial_filter_spec() @@ -267,35 +258,25 @@ def test_it_complains_about_invalid_serials_in_SERIAL_FILTER(self, meta, spec): spec.normalise(meta, v) def test_it_complains_about_invalid_serials_in_value(self, meta, spec): - e = BadSpecValue( - "serials must start with d073d5", got="e073d5001339", meta=meta.indexed_at(0) - ) + e = BadSpecValue("serials must start with d073d5", got="e073d5001339", meta=meta.indexed_at(0)) with assertRaises(BadSpecValue, _errors=[e]): spec.normalise(meta, "e073d5001339") class TestDiscoveryOptions: async def test_it_has_serial_filter_and_hardcoded_discovery(self): - with pytest.helpers.modified_env( - HARDCODED_DISCOVERY='{"d073d5001337": "192.168.0.1"}', SERIAL_FILTER="d073d5001337" - ): + with pytest.helpers.modified_env(HARDCODED_DISCOVERY='{"d073d5001337": "192.168.0.1"}', SERIAL_FILTER="d073d5001337"): options = do.DiscoveryOptions.FieldSpec().empty_normalise() assert options.serial_filter == ["d073d5001337"] - assert options.hardcoded_discovery == { - "d073d5001337": {Services.UDP: {"host": "192.168.0.1", "port": 56700}} - } + assert options.hardcoded_discovery == {"d073d5001337": {Services.UDP: {"host": "192.168.0.1", "port": 56700}}} options = do.DiscoveryOptions.FieldSpec().empty_normalise() assert options.serial_filter == sb.NotSpecified assert options.hardcoded_discovery == sb.NotSpecified - options = do.DiscoveryOptions.FieldSpec().empty_normalise( - serial_filter=["d073d5001338"], hardcoded_discovery={"d073d5001339": "192.178.1.1"} - ) + options = do.DiscoveryOptions.FieldSpec().empty_normalise(serial_filter=["d073d5001338"], hardcoded_discovery={"d073d5001339": "192.178.1.1"}) assert options.serial_filter == ["d073d5001338"] - assert options.hardcoded_discovery == { - "d073d5001339": {Services.UDP: {"host": "192.178.1.1", "port": 56700}} - } + assert options.hardcoded_discovery == {"d073d5001339": {Services.UDP: {"host": "192.178.1.1", "port": 56700}}} async def test_it_says_we_dont_have_hardcoded_discovery_if_thats_the_case(self): options = do.DiscoveryOptions.FieldSpec().empty_normalise() @@ -323,9 +304,7 @@ async def test_it_says_all_serials_are_wanted_if_we_dont_have_a_serial_filter(se assert options.want(mock.Mock(name="serial")) async def test_it_says_we_only_want_filtered_serials(self): - options = do.DiscoveryOptions.FieldSpec().empty_normalise( - serial_filter=["d073d5001337", "d073d5001338"] - ) + options = do.DiscoveryOptions.FieldSpec().empty_normalise(serial_filter=["d073d5001337", "d073d5001338"]) assert not options.want("d073d5000001") assert not options.want("d073d5000002") assert not options.want(mock.Mock(name="serial")) @@ -338,9 +317,7 @@ async def test_it_can_do_discovery(self): v = {"d073d5000001": "192.168.9.3", "d073d5000002": ["192.168.7.8", 56]} options = do.DiscoveryOptions.FieldSpec().empty_normalise(hardcoded_discovery=v) - expected_found = set( - [binascii.unhexlify("d073d5000001"), binascii.unhexlify("d073d5000002")] - ) + expected_found = set([binascii.unhexlify("d073d5000001"), binascii.unhexlify("d073d5000002")]) assert await options.discover(add_service) == expected_found assert add_service.mock_calls == [ @@ -355,13 +332,9 @@ async def test_it_pays_attention_to_serial_filter_in_discover(self): "d073d5000002": ["192.168.7.8", 56], "d073d5000003": "192.158.0.7", } - options = do.DiscoveryOptions.FieldSpec().empty_normalise( - hardcoded_discovery=v, serial_filter=["d073d5000001", "d073d5000002"] - ) + options = do.DiscoveryOptions.FieldSpec().empty_normalise(hardcoded_discovery=v, serial_filter=["d073d5000001", "d073d5000002"]) - expected_found = set( - [binascii.unhexlify("d073d5000001"), binascii.unhexlify("d073d5000002")] - ) + expected_found = set([binascii.unhexlify("d073d5000001"), binascii.unhexlify("d073d5000002")]) assert await options.discover(add_service) == expected_found assert add_service.mock_calls == [ @@ -372,9 +345,7 @@ async def test_it_pays_attention_to_serial_filter_in_discover(self): class TestNoDiscoveryOptions: def test_it_overrides_serial_filter_and_hardcoded_discovery_with_None(self): - with pytest.helpers.modified_env( - HARDCODED_DISCOVERY='{"d073d5001337": "192.168.0.1"}', SERIAL_FILTER="d073d5001337" - ): + with pytest.helpers.modified_env(HARDCODED_DISCOVERY='{"d073d5001337": "192.168.0.1"}', SERIAL_FILTER="d073d5001337"): options = do.NoDiscoveryOptions.FieldSpec().empty_normalise() assert options.serial_filter is None assert options.hardcoded_discovery is None @@ -401,9 +372,7 @@ def test_it_wants_all_serials(self): class TestNoEnvDiscoveryOptions: def test_it_does_not_care_about_environment_variables(self): - with pytest.helpers.modified_env( - HARDCODED_DISCOVERY='{"d073d5001337": "192.168.0.1"}', SERIAL_FILTER="d073d5001337" - ): + with pytest.helpers.modified_env(HARDCODED_DISCOVERY='{"d073d5001337": "192.168.0.1"}', SERIAL_FILTER="d073d5001337"): options = do.NoEnvDiscoveryOptions.FieldSpec().empty_normalise() assert options.serial_filter == sb.NotSpecified assert options.hardcoded_discovery == sb.NotSpecified @@ -412,44 +381,33 @@ def test_it_does_not_care_about_environment_variables(self): serial_filter=["d073d5001338"], hardcoded_discovery={"d073d5001339": "192.178.1.1"} ) assert options.serial_filter == ["d073d5001338"] - assert options.hardcoded_discovery == { - "d073d5001339": {Services.UDP: {"host": "192.178.1.1", "port": 56700}} - } + assert options.hardcoded_discovery == {"d073d5001339": {Services.UDP: {"host": "192.178.1.1", "port": 56700}}} assert isinstance(options, do.DiscoveryOptions) class TestDiscoveryOptionsSpec: - @pytest.fixture() def spec(self): return do.discovery_options_spec() - def test_it_creates_a_DiscoveryOptions_when_no_discovery_options_in_metaeverything( - self, meta, spec - ): + def test_it_creates_a_DiscoveryOptions_when_no_discovery_options_in_metaeverything(self, meta, spec): res = spec.normalise(meta, sb.NotSpecified) assert isinstance(res, do.DiscoveryOptions) def test_it_inherits_from_global_discovery_options(self, meta, spec): - options = do.DiscoveryOptions.FieldSpec().empty_normalise( - serial_filter=["d073d5000001"], hardcoded_discovery={"d073d5000001": "192.168.0.6"} - ) + options = do.DiscoveryOptions.FieldSpec().empty_normalise(serial_filter=["d073d5000001"], hardcoded_discovery={"d073d5000001": "192.168.0.6"}) meta.everything["discovery_options"] = options res = spec.normalise(meta, sb.NotSpecified) assert res.serial_filter == ["d073d5000001"] - assert res.hardcoded_discovery == { - "d073d5000001": {Services.UDP: {"host": "192.168.0.6", "port": 56700}} - } + assert res.hardcoded_discovery == {"d073d5000001": {Services.UDP: {"host": "192.168.0.6", "port": 56700}}} # And modifying res doesn't change global res.serial_filter.append("d073d5000002") res.hardcoded_discovery["d073d5000001"][Services.UDP]["wat"] = True assert options.serial_filter == ["d073d5000001"] - assert options.hardcoded_discovery == { - "d073d5000001": {Services.UDP: {"host": "192.168.0.6", "port": 56700}} - } + assert options.hardcoded_discovery == {"d073d5000001": {Services.UDP: {"host": "192.168.0.6", "port": 56700}}} def test_it_can_override_global_serial_filter(self, meta, spec): for gl in ("d073d5000001", ["d073d5000002"], None, sb.NotSpecified): @@ -475,9 +433,7 @@ def test_it_can_override_global_hardcoded_discovery(self, meta, spec): assert res.hardcoded_discovery is None res = spec.normalise(meta, {"hardcoded_discovery": {"d073d5000002": "192.168.0.2"}}) - assert res.hardcoded_discovery == { - "d073d5000002": {Services.UDP: {"host": "192.168.0.2", "port": 56700}} - } + assert res.hardcoded_discovery == {"d073d5000002": {Services.UDP: {"host": "192.168.0.2", "port": 56700}}} res = spec.normalise( meta, @@ -497,9 +453,7 @@ def test_it_can_override_global_hardcoded_discovery(self, meta, spec): assert options.hardcoded_discovery == gl def test_it_can_add_to_global_hardcoded_discovery(self, meta, spec): - options = do.DiscoveryOptions.FieldSpec().empty_normalise( - hardcoded_discovery={"d073d5000001": "192.168.0.1"} - ) + options = do.DiscoveryOptions.FieldSpec().empty_normalise(hardcoded_discovery={"d073d5000001": "192.168.0.1"}) meta.everything["discovery_options"] = options res = spec.normalise(meta, {"hardcoded_discovery": None}) @@ -520,6 +474,4 @@ def test_it_can_add_to_global_hardcoded_discovery(self, meta, spec): "d073d5000002": {Services.UDP: {"host": "192.168.0.2", "port": 56700}}, } - assert options.hardcoded_discovery == { - "d073d5000001": {Services.UDP: {"host": "192.168.0.1", "port": 56700}} - } + assert options.hardcoded_discovery == {"d073d5000001": {Services.UDP: {"host": "192.168.0.1", "port": 56700}}} diff --git a/modules/tests/photons_transport_tests/session/test_network.py b/modules/tests/photons_transport_tests/session/test_network.py index 3db1ead8..7b25b4be 100644 --- a/modules/tests/photons_transport_tests/session/test_network.py +++ b/modules/tests/photons_transport_tests/session/test_network.py @@ -18,7 +18,6 @@ class TestNetworkSession: - @pytest.fixture() def V(self): class V: @@ -40,9 +39,7 @@ def transport_target(s): transport_target.gaps = s.gaps transport_target.final_future = s.final_future transport_target.default_broadcast = s.default_broadcast - transport_target.discovery_options = ( - NoDiscoveryOptions.FieldSpec().empty_normalise() - ) + transport_target.discovery_options = NoDiscoveryOptions.FieldSpec().empty_normalise() return transport_target @hp.memoized_property @@ -51,9 +48,7 @@ def session(s): @hp.memoized_property def gaps(s): - return Gaps( - gap_between_ack_and_res=0.2, gap_between_results=0.35, timeouts=[(1, 1)] - ) + return Gaps(gap_between_ack_and_res=0.2, gap_between_results=0.35, timeouts=[(1, 1)]) return V() @@ -120,9 +115,7 @@ async def test_it_complains_if_we_cant_determined_need_transport(self, V): msg = "Unable to determine what service to send packet to" kwargs = {"protocol": 9001, "pkt_type": 89} with assertRaises(NoDesiredService, msg, **kwargs): - with mock.patch.object( - V.session, "determine_needed_transport", determine_needed_transport - ): + with mock.patch.object(V.session, "determine_needed_transport", determine_needed_transport): await V.session.choose_transport(packet, services) determine_needed_transport.assert_awaited_once_with(packet, services) @@ -137,9 +130,7 @@ async def test_it_returns_the_desired_service_or_complains_if_cant_be_found(self packet = mock.NonCallableMock(name="packet", spec=[]) services = {Services.UDP: udpservice} - with mock.patch.object( - V.session, "determine_needed_transport", determine_needed_transport - ): + with mock.patch.object(V.session, "determine_needed_transport", determine_needed_transport): assert await V.session.choose_transport(packet, services) is udpservice msg = "Don't have a desired service" @@ -149,7 +140,6 @@ async def test_it_returns_the_desired_service_or_complains_if_cant_be_found(self await V.session.choose_transport(packet, services) class TestPrivateDoSearch: - @pytest.fixture() def mocks(self, V): @contextmanager @@ -160,9 +150,7 @@ async def iterator(timeout): yield 7, 3 yield 4, 4 - _search_retry_iterator = pytest.helpers.MagicAsyncMock( - name="_search_retry_iterator", side_effect=iterator - ) + _search_retry_iterator = pytest.helpers.MagicAsyncMock(name="_search_retry_iterator", side_effect=iterator) script = mock.Mock(name="script", spec=["run"]) script.run = pytest.helpers.MagicAsyncMock(name="run", side_effect=run) @@ -177,51 +165,38 @@ async def iterator(timeout): return mocks async def test_it_can_use_hard_coded_discovery(self, V): - V.transport_target.discovery_options = ( - NoEnvDiscoveryOptions.FieldSpec().empty_normalise( - hardcoded_discovery={ - "d073d5000001": "192.168.0.1", - "d073d5000002": "192.168.0.2", - } - ) + V.transport_target.discovery_options = NoEnvDiscoveryOptions.FieldSpec().empty_normalise( + hardcoded_discovery={ + "d073d5000001": "192.168.0.1", + "d073d5000002": "192.168.0.2", + } ) assert V.session.found == Found() fn = await V.session._do_search(None, 20) - assert sorted(fn) == sorted( - [binascii.unhexlify(s) for s in ("d073d5000001", "d073d5000002")] - ) + assert sorted(fn) == sorted([binascii.unhexlify(s) for s in ("d073d5000001", "d073d5000002")]) assert V.session.found.serials == ["d073d5000001", "d073d5000002"] assert V.session.found["d073d5000001"] == { - Services.UDP: await V.session.make_transport( - "d073d5000001", Services.UDP, {"host": "192.168.0.1", "port": 56700} - ) + Services.UDP: await V.session.make_transport("d073d5000001", Services.UDP, {"host": "192.168.0.1", "port": 56700}) } assert V.session.found["d073d5000002"] == { - Services.UDP: await V.session.make_transport( - "d073d5000002", Services.UDP, {"host": "192.168.0.2", "port": 56700} - ) + Services.UDP: await V.session.make_transport("d073d5000002", Services.UDP, {"host": "192.168.0.2", "port": 56700}) } assert len(V.transport_target.script.mock_calls) == 0 async def test_it_finds(self, V, mocks): - async def run(*args, **kwargs): - s1 = DiscoveryMessages.StateService( - service=Services.UDP, port=56, target="d073d5000001" - ) + s1 = DiscoveryMessages.StateService(service=Services.UDP, port=56, target="d073d5000001") s1.Information.update( remote_addr=("192.168.0.3", 56700), sender_message=DiscoveryMessages.GetService(), ) yield s1 - s3 = DiscoveryMessages.StateService( - service=Services.UDP, port=58, target="d073d5000002" - ) + s3 = DiscoveryMessages.StateService(service=Services.UDP, port=58, target="d073d5000002") s3.Information.update( remote_addr=("192.168.0.4", 56700), sender_message=DiscoveryMessages.GetService(), @@ -254,37 +229,26 @@ async def run(*args, **kwargs): ) ) - assert sorted(fn) == sorted( - [binascii.unhexlify(s) for s in ("d073d5000001", "d073d5000002")] - ) + assert sorted(fn) == sorted([binascii.unhexlify(s) for s in ("d073d5000001", "d073d5000002")]) assert V.session.found.serials == ["d073d5000001", "d073d5000002"] assert V.session.found["d073d5000001"] == { - Services.UDP: await V.session.make_transport( - "d073d5000001", Services.UDP, {"host": "192.168.0.3", "port": 56} - ) + Services.UDP: await V.session.make_transport("d073d5000001", Services.UDP, {"host": "192.168.0.3", "port": 56}) } assert V.session.found["d073d5000002"] == { - Services.UDP: await V.session.make_transport( - "d073d5000002", Services.UDP, {"host": "192.168.0.4", "port": 58} - ) + Services.UDP: await V.session.make_transport("d073d5000002", Services.UDP, {"host": "192.168.0.4", "port": 58}) } async def test_it_can_filter_serials(self, V, mocks): - async def run(*args, **kwargs): - s1 = DiscoveryMessages.StateService( - service=Services.UDP, port=56, target="d073d5000001" - ) + s1 = DiscoveryMessages.StateService(service=Services.UDP, port=56, target="d073d5000001") s1.Information.update( remote_addr=("192.168.0.3", 56700), sender_message=DiscoveryMessages.GetService(), ) yield s1 - s3 = DiscoveryMessages.StateService( - service=Services.UDP, port=58, target="d073d5000002" - ) + s3 = DiscoveryMessages.StateService(service=Services.UDP, port=58, target="d073d5000002") s3.Information.update( remote_addr=("192.168.0.4", 56700), sender_message=DiscoveryMessages.GetService(), @@ -292,9 +256,7 @@ async def run(*args, **kwargs): yield s3 assert V.session.found == Found() - V.transport_target.discovery_options = ( - NoEnvDiscoveryOptions.FieldSpec().empty_normalise(serial_filter=["d073d5000001"]) - ) + V.transport_target.discovery_options = NoEnvDiscoveryOptions.FieldSpec().empty_normalise(serial_filter=["d073d5000001"]) a = mock.Mock(name="a") with mocks(20, run) as script: @@ -324,19 +286,12 @@ async def run(*args, **kwargs): assert V.session.found.serials == ["d073d5000001"] assert V.session.found["d073d5000001"] == { - Services.UDP: await V.session.make_transport( - "d073d5000001", Services.UDP, {"host": "192.168.0.3", "port": 56} - ) + Services.UDP: await V.session.make_transport("d073d5000001", Services.UDP, {"host": "192.168.0.3", "port": 56}) } - async def test_it_stops_after_first_search_if_serials_is_None_and_we_found_serials( - self, V, mocks - ): - + async def test_it_stops_after_first_search_if_serials_is_None_and_we_found_serials(self, V, mocks): async def run(*args, **kwargs): - s1 = DiscoveryMessages.StateService( - service=Services.UDP, port=56, target="d073d5000001" - ) + s1 = DiscoveryMessages.StateService(service=Services.UDP, port=56, target="d073d5000001") s1.Information.update( remote_addr=("192.168.0.3", 56700), sender_message=DiscoveryMessages.GetService(), @@ -368,9 +323,7 @@ async def run(*args, **kwargs): if len(called) != 3: return - s1 = DiscoveryMessages.StateService( - service=Services.UDP, port=56, target="d073d5000001" - ) + s1 = DiscoveryMessages.StateService(service=Services.UDP, port=56, target="d073d5000001") s1.Information.update( remote_addr=("192.168.0.3", 56700), sender_message=DiscoveryMessages.GetService(), @@ -417,18 +370,14 @@ async def run(*args, **kwargs): assert fn == [binascii.unhexlify("d073d5000001")] assert V.session.found.serials == ["d073d5000001"] - async def test_it_keeps_trying_till_we_have_all_serials_if_serials_is_not_None( - self, V, mocks - ): + async def test_it_keeps_trying_till_we_have_all_serials_if_serials_is_not_None(self, V, mocks): called = [] async def run(*args, **kwargs): called.append("run") if len(called) > 0: - s1 = DiscoveryMessages.StateService( - service=Services.UDP, port=56, target="d073d5000001" - ) + s1 = DiscoveryMessages.StateService(service=Services.UDP, port=56, target="d073d5000001") s1.Information.update( remote_addr=("192.168.0.3", 56700), sender_message=DiscoveryMessages.GetService(), @@ -436,9 +385,7 @@ async def run(*args, **kwargs): yield s1 if len(called) > 1: - s2 = DiscoveryMessages.StateService( - service=Services.UDP, port=58, target="d073d5000002" - ) + s2 = DiscoveryMessages.StateService(service=Services.UDP, port=58, target="d073d5000002") s2.Information.update( remote_addr=("192.168.0.4", 56700), sender_message=DiscoveryMessages.GetService(), @@ -446,9 +393,7 @@ async def run(*args, **kwargs): yield s2 if len(called) > 2: - s3 = DiscoveryMessages.StateService( - service=Services.UDP, port=59, target="d073d5000003" - ) + s3 = DiscoveryMessages.StateService(service=Services.UDP, port=59, target="d073d5000003") s3.Information.update( remote_addr=("192.168.0.5", 56700), sender_message=DiscoveryMessages.GetService(), @@ -505,9 +450,7 @@ async def run(*args, **kwargs): called.append("run") if len(called) > 0: - s1 = DiscoveryMessages.StateService( - service=Services.UDP, port=56, target="d073d5000001" - ) + s1 = DiscoveryMessages.StateService(service=Services.UDP, port=56, target="d073d5000001") s1.Information.update( remote_addr=("192.168.0.3", 56700), sender_message=DiscoveryMessages.GetService(), diff --git a/modules/tests/photons_transport_tests/targets/test_base.py b/modules/tests/photons_transport_tests/targets/test_base.py index 3b4e8191..bbc00689 100644 --- a/modules/tests/photons_transport_tests/targets/test_base.py +++ b/modules/tests/photons_transport_tests/targets/test_base.py @@ -59,9 +59,7 @@ async def test_it_gets_protocol_register_and_final_future_from_the_meta(self): assert t.final_future is final_future class TestUsage: - class TestScript: - @pytest.fixture() def script(self): return mock.Mock(name="script") @@ -98,9 +96,7 @@ def simplify(r): return mocked_simplify - async def test_it_says_items_is_None_if_we_simplify_to_an_empty_list( - self, mocked_simplify, script, script_runner_kls, target - ): + async def test_it_says_items_is_None_if_we_simplify_to_an_empty_list(self, mocked_simplify, script, script_runner_kls, target): raw = mock.Mock(name="raw") with mocked_simplify() as simplify: @@ -109,9 +105,7 @@ async def test_it_says_items_is_None_if_we_simplify_to_an_empty_list( simplify.assert_called_once_with(raw) script_runner_kls.assert_called_once_with(None, target=target) - async def test_it_gives_items_as_just_that_item_if_list_is_one_item( - self, mocked_simplify, script, script_runner_kls, target - ): + async def test_it_gives_items_as_just_that_item_if_list_is_one_item(self, mocked_simplify, script, script_runner_kls, target): raw = mock.Mock(name="raw") item = mock.Mock(name="item") @@ -121,9 +115,7 @@ async def test_it_gives_items_as_just_that_item_if_list_is_one_item( simplify.assert_called_once_with(raw) script_runner_kls.assert_called_once_with(item, target=target) - async def test_it_uses_a_FromGenerator_if_we_have_multiple_items( - self, mocked_simplify, script, script_runner_kls, target - ): + async def test_it_uses_a_FromGenerator_if_we_have_multiple_items(self, mocked_simplify, script, script_runner_kls, target): raw = mock.Mock(name="raw") item1 = mock.Mock(name="item1") item2 = mock.Mock(name="item2") @@ -184,7 +176,6 @@ async def test_it_creates_and_closes_a_sender(self, target): close_sender.assert_called_once_with(sender) class TestSimplify: - @pytest.fixture() def item_kls(self): return mock.Mock(name="item_kls") @@ -198,9 +189,7 @@ async def test_it_uses_part_as_is_if_it_already_has_a_run_on_it(self, target): part = mock.Mock(name="part", spec=["run"]) assert list(target.simplify(part)) == [part] - async def test_it_simplifies_items_that_have_a_simplified_method( - self, item_kls, target - ): + async def test_it_simplifies_items_that_have_a_simplified_method(self, item_kls, target): simplified = mock.Mock(name="simplified", spec=[]) part = mock.Mock(name="part", spec=["simplified"]) part.simplified.return_value = simplified @@ -213,9 +202,7 @@ async def test_it_simplifies_items_that_have_a_simplified_method( part.simplified.assert_called_once_with(target.simplify) item_kls.assert_called_once_with([simplified]) - async def test_it_splits_out_items_into_groups_with_pack_and_without_and_only_item_kls_for_groups_with_pack( - self, item_kls, target - ): + async def test_it_splits_out_items_into_groups_with_pack_and_without_and_only_item_kls_for_groups_with_pack(self, item_kls, target): part11 = mock.Mock(name="part11", spec=[]) part12 = mock.Mock(name="part12", spec=[]) part13 = mock.Mock(name="part13", spec=[]) @@ -236,7 +223,7 @@ def item_kls_init(buf): elif buf == [part31, part32]: return res2 else: - assert False, "Unknown args to item_kls, {0}".format(buf) + assert False, f"Unknown args to item_kls, {buf}" item_kls.side_effect = item_kls_init @@ -250,9 +237,7 @@ def item_kls_init(buf): mock.call([part31, part32]), ] - async def test_it_doesnt_separate_simplified_items_if_they_dont_have_a_run_method( - self, item_kls, target - ): + async def test_it_doesnt_separate_simplified_items_if_they_dont_have_a_run_method(self, item_kls, target): part11 = mock.Mock(name="part11", spec=[]) part12 = mock.Mock(name="part12", spec=[]) part13 = mock.Mock(name="part13", spec=[]) @@ -272,6 +257,4 @@ async def test_it_doesnt_separate_simplified_items_if_they_dont_have_a_run_metho part2.simplified.assert_called_once_with(target.simplify) - assert item_kls.mock_calls == [ - mock.call([part11, part12, part13, part2simplified, part31, part32]) - ] + assert item_kls.mock_calls == [mock.call([part11, part12, part13, part2simplified, part31, part32])] diff --git a/modules/tests/photons_transport_tests/targets/test_item.py b/modules/tests/photons_transport_tests/targets/test_item.py index 2ec08a0c..734f36da 100644 --- a/modules/tests/photons_transport_tests/targets/test_item.py +++ b/modules/tests/photons_transport_tests/targets/test_item.py @@ -28,7 +28,6 @@ def item(): class TestNoLimit: - async def test_it_behaves_like_a_normal_semaphore_context_manager(self): called = [] @@ -69,14 +68,11 @@ async def test_it_takes_in_parts(self): assert item.parts == [part, part2] class TestFunctionality: - class TestSimplifyParts: async def test_it_returns_originals_with_packets_as_they_are_if_they_are_dynamic_else_we_simplify_them( self, ): - part1_dynamic = mock.Mock( - name="part1_dynamic", is_dynamic=True, spec=["is_dynamic"] - ) + part1_dynamic = mock.Mock(name="part1_dynamic", is_dynamic=True, spec=["is_dynamic"]) part2_static = mock.Mock(name="part2_static", is_dynamic=False) part2_simple = mock.Mock(name="part2_simple") @@ -86,13 +82,9 @@ async def test_it_returns_originals_with_packets_as_they_are_if_they_are_dynamic part3_simple = mock.Mock(name="part3_simple") part3_static.simplify.return_value = part3_simple - part4_dynamic = mock.Mock( - name="part4_dynamic", is_dynamic=True, spec=["is_dynamic"] - ) + part4_dynamic = mock.Mock(name="part4_dynamic", is_dynamic=True, spec=["is_dynamic"]) - simplified = Item( - [part1_dynamic, part2_static, part3_static, part4_dynamic] - ).simplify_parts() + simplified = Item([part1_dynamic, part2_static, part3_static, part4_dynamic]).simplify_parts() assert simplified == [ (part1_dynamic, part1_dynamic), (part2_static, part2_simple), @@ -183,7 +175,6 @@ def seq_maker(t): c5.actual.assert_called_once_with("source") class TestSearch: - @pytest.fixture() def V(self, item): class V: @@ -304,9 +295,7 @@ def __eq__(s, other): a=V.a, ) - async def test_it_uses_find_specific_serials_if_found_is_not_None_and_dont_have_all_serials( - self, V - ): + async def test_it_uses_find_specific_serials_if_found_is_not_None_and_dont_have_all_serials(self, V): found = mock.Mock(name="found") missing = mock.Mock(name="missing") V.find_specific_serials.return_value = (found, missing) @@ -334,7 +323,6 @@ def __eq__(s, other): ) class TestWriteMessages: - @pytest.fixture() def V(self, final_future): class V: @@ -343,9 +331,7 @@ class V: results = [mock.Mock(name=f"res{i}") for i in range(10)] - sender = mock.Mock( - name="sender", stop_fut=final_future, spec=["send_single", "stop_fut"] - ) + sender = mock.Mock(name="sender", stop_fut=final_future, spec=["send_single", "stop_fut"]) error_catcher = [] @@ -383,7 +369,6 @@ def __init__(s): return V() async def test_it_sends_the_packets_and_gets_the_replies(self, item, V): - async def send_single(original, packet, **kwargs): assert dict(V.packets)[original] is packet if original is V.o1: @@ -409,22 +394,13 @@ async def send_single(original, packet, **kwargs): assert res == [V.results[i] for i in (1, 2, 7, 5, 6, 3, 4)] assert V.sender.send_single.mock_calls == [ - mock.call( - V.o1, V.p1, timeout=10, no_retry=False, broadcast=None, connect_timeout=10 - ), - mock.call( - V.o2, V.p2, timeout=10, no_retry=False, broadcast=None, connect_timeout=10 - ), - mock.call( - V.o3, V.p3, timeout=10, no_retry=False, broadcast=None, connect_timeout=10 - ), - mock.call( - V.o4, V.p4, timeout=10, no_retry=False, broadcast=None, connect_timeout=10 - ), + mock.call(V.o1, V.p1, timeout=10, no_retry=False, broadcast=None, connect_timeout=10), + mock.call(V.o2, V.p2, timeout=10, no_retry=False, broadcast=None, connect_timeout=10), + mock.call(V.o3, V.p3, timeout=10, no_retry=False, broadcast=None, connect_timeout=10), + mock.call(V.o4, V.p4, timeout=10, no_retry=False, broadcast=None, connect_timeout=10), ] async def test_it_gets_arguments_for_send_from_kwargs(self, item, V): - async def send_single(original, packet, **kwargs): assert dict(V.packets)[original] is packet if original is V.o1: @@ -496,7 +472,6 @@ async def send_single(original, packet, **kwargs): ] async def test_it_records_errors(self, item, V): - async def send_single(original, packet, **kwargs): assert dict(V.packets)[original] is packet if original is V.o1: @@ -528,7 +503,6 @@ async def send_single(original, packet, **kwargs): assert res == [V.results[i] for i in (0, 6)] class TestPrivateFind: - @pytest.fixture() def V(self): class V: @@ -553,18 +527,14 @@ async def test_it_returns_serials_as_a_list(self, item, V): assert s == ["d073d5000000"] assert m is None - f, s, m = await item._find( - None, ["d073d5000000", "d073d5000001"], V.sender, V.broadcast, V.timeout - ) + f, s, m = await item._find(None, ["d073d5000000", "d073d5000001"], V.sender, V.broadcast, V.timeout) assert f is V.found assert s == ["d073d5000000", "d073d5000001"] assert m is None async def test_it_returns_the_provided_found_if_one_was_given(self, item, V): found = mock.Mock(name="found") - f, s, m = await item._find( - found, ["d073d5000000", "d073d5000001"], V.sender, V.broadcast, V.timeout - ) + f, s, m = await item._find(found, ["d073d5000000", "d073d5000001"], V.sender, V.broadcast, V.timeout) assert f is found assert s == ["d073d5000000", "d073d5000001"] assert m is None @@ -618,7 +588,6 @@ def missing(s, f): ] class TestRun: - @pytest.fixture() def V(self, final_future): class V: @@ -643,9 +612,7 @@ async def test_it_finds_prepares_searches_writes(self, item, V): found = mock.Mock(name="found") serials = ["d073d5000000", "d073d5000001"] missing = None - _find = pytest.helpers.AsyncMock( - name="_find", return_value=(found, serials, missing) - ) + _find = pytest.helpers.AsyncMock(name="_find", return_value=(found, serials, missing)) packets = mock.Mock(name="packets") make_packets = mock.Mock(name="make_packets", return_value=packets) @@ -661,9 +628,7 @@ async def write_messages(*args, **kwargs): yield res1 yield res2 - write_messages = pytest.helpers.MagicAsyncMock( - name="write_messages", side_effect=write_messages - ) + write_messages = pytest.helpers.MagicAsyncMock(name="write_messages", side_effect=write_messages) mod = { "_find": _find, @@ -684,20 +649,14 @@ async def write_messages(*args, **kwargs): _find.assert_called_once_with(None, reference, V.sender, False, 20) make_packets.assert_called_once_with(V.sender, serials) - search.assert_called_once_with( - V.sender, found, False, packets, False, 20, {"a": a, "error_catcher": mock.ANY} - ) - write_messages.assert_called_once_with( - V.sender, packets, {"a": a, "error_catcher": mock.ANY} - ) + search.assert_called_once_with(V.sender, found, False, packets, False, 20, {"a": a, "error_catcher": mock.ANY}) + write_messages.assert_called_once_with(V.sender, packets, {"a": a, "error_catcher": mock.ANY}) async def test_it_shortcuts_if_no_packets_to_send(self, item, V): found = mock.Mock(name="found") serials = ["d073d5000000", "d073d5000001"] missing = None - _find = pytest.helpers.AsyncMock( - name="_find", return_value=(found, serials, missing) - ) + _find = pytest.helpers.AsyncMock(name="_find", return_value=(found, serials, missing)) make_packets = mock.Mock(name="make_packets", return_value=[]) @@ -746,12 +705,9 @@ async def test_it_doesnt_search_if_broadcasting(self, item, V): packets.append((part, clone)) assert len(search.mock_calls) == 0 - write_messages.assert_called_once_with( - V.sender, packets, {"broadcast": True, "error_catcher": mock.ANY} - ) + write_messages.assert_called_once_with(V.sender, packets, {"broadcast": True, "error_catcher": mock.ANY}) async def test_it_complains_if_we_havent_found_all_our_serials(self, item, V): - class Ref(SpecialReference): async def find(s, *args, **kwargs): found = Found() @@ -766,16 +722,12 @@ def missing(s, f): pass es = [] - async for _ in item.run( - Ref(), V.sender, require_all_devices=True, error_catcher=es - ): + async for _ in item.run(Ref(), V.sender, require_all_devices=True, error_catcher=es): pass assert es == [DevicesNotFound(missing=["d073d5000001"])] es = mock.Mock(name="es") - async for _ in item.run( - Ref(), V.sender, require_all_devices=True, error_catcher=es - ): + async for _ in item.run(Ref(), V.sender, require_all_devices=True, error_catcher=es): pass es.assert_called_once_with(DevicesNotFound(missing=["d073d5000001"])) @@ -789,9 +741,7 @@ async def write_messages(sender, packets, kwargs): hp.add_error(kwargs["error_catcher"], error) yield res2 - write_messages = pytest.helpers.MagicAsyncMock( - name="write_messages", side_effect=write_messages - ) + write_messages = pytest.helpers.MagicAsyncMock(name="write_messages", side_effect=write_messages) with mock.patch.object(item, "write_messages", write_messages): res = [] @@ -831,9 +781,7 @@ async def write_messages(sender, packets, kwargs): yield res2 hp.add_error(kwargs["error_catcher"], error2) - write_messages = pytest.helpers.MagicAsyncMock( - name="write_messages", side_effect=write_messages - ) + write_messages = pytest.helpers.MagicAsyncMock(name="write_messages", side_effect=write_messages) with mock.patch.object(item, "write_messages", write_messages): res = [] diff --git a/modules/tests/photons_transport_tests/targets/test_script.py b/modules/tests/photons_transport_tests/targets/test_script.py index 7d0b7048..93151381 100644 --- a/modules/tests/photons_transport_tests/targets/test_script.py +++ b/modules/tests/photons_transport_tests/targets/test_script.py @@ -17,7 +17,6 @@ def __eq__(self, other): class TestSenderWrapper: - @pytest.fixture() def V(self): class V: @@ -116,7 +115,6 @@ async def test_it_creates_and_closes_the_sender_if_none_provided(self, V): class TestScriptRunner: - @pytest.fixture() def V(self): class V: diff --git a/modules/tests/photons_transport_tests/test_retry_gaps.py b/modules/tests/photons_transport_tests/test_retry_gaps.py index 9a63dc5d..4942bda9 100644 --- a/modules/tests/photons_transport_tests/test_retry_gaps.py +++ b/modules/tests/photons_transport_tests/test_retry_gaps.py @@ -10,9 +10,7 @@ def test_it_can_be_given_defaults(self): assert obj.gap_between_results == 0.9 assert obj.timeouts == [(0.1, 0.5)] - obj = gaps.empty_normalise( - gap_between_ack_and_res=0.2, gap_between_results=0.1, timeouts=[(0.1, 0.6), (0.5, 3)] - ) + obj = gaps.empty_normalise(gap_between_ack_and_res=0.2, gap_between_results=0.1, timeouts=[(0.1, 0.6), (0.5, 3)]) assert obj.gap_between_ack_and_res == 0.2 assert obj.gap_between_results == 0.1 @@ -26,9 +24,7 @@ def test_it_can_make_a_retry_ticker(self): assert ticker.name == "hello" assert ticker.timeouts == [(0.1, 0.5)] - obj = gaps.empty_normalise( - gap_between_ack_and_res=0.2, gap_between_results=0.1, timeouts=[[0.1, 0.6], [0.5, 3]] - ) + obj = gaps.empty_normalise(gap_between_ack_and_res=0.2, gap_between_results=0.1, timeouts=[[0.1, 0.6], [0.5, 3]]) ticker = obj.retry_ticker(name="there") assert ticker.name == "there" diff --git a/modules/tests/photons_transport_tests/test_retry_ticker.py b/modules/tests/photons_transport_tests/test_retry_ticker.py index 113431c8..7764885d 100644 --- a/modules/tests/photons_transport_tests/test_retry_ticker.py +++ b/modules/tests/photons_transport_tests/test_retry_ticker.py @@ -48,9 +48,7 @@ async def test_it_yields_till_the_timeout(self, final_future, FakeTime, MockedCa (9.2, (0.8, 1.2)), ] - async def test_it_takes_into_account_how_long_the_block_takes( - self, final_future, FakeTime, MockedCallLater - ): + async def test_it_takes_into_account_how_long_the_block_takes(self, final_future, FakeTime, MockedCallLater): options = RetryTicker(timeouts=[[0.6, 1.8], [0.8, 5], [1.2, 15]]) found = [] diff --git a/modules/tests/photons_transport_tests/test_sending.py b/modules/tests/photons_transport_tests/test_sending.py index b3da7e7a..6d82b124 100644 --- a/modules/tests/photons_transport_tests/test_sending.py +++ b/modules/tests/photons_transport_tests/test_sending.py @@ -26,7 +26,6 @@ async def sender(final_future): class TestSendingMessages: - @pytest.fixture def V(self, sender): class V: @@ -38,7 +37,6 @@ class V: return V() class TestSendApi: - async def test_it_works_with_the_sender_as_sender_api(self, V, sender): original = DeviceMessages.EchoRequest(echoing=b"hi") @@ -84,10 +82,7 @@ async def test_it_targetsend_also_works_as_a_synchronous_api(self, V): assert dict(got) == {V.device.serial: [{"echoing": b"hi" + b"\x00" * 62}]} class TestBreakingAStream: - - async def test_it_is_possible_to_cleanly_stop_when_sending_just_a_packet( - self, V, sender - ): + async def test_it_is_possible_to_cleanly_stop_when_sending_just_a_packet(self, V, sender): got = [] msg = DeviceMessages.SetPower(level=0) async with sender(msg, [V.device.serial, V.device2.serial]) as pkts: @@ -105,9 +100,7 @@ async def test_it_is_possible_to_cleanly_stop_when_sending_just_a_packet( assert devices.store(device) == [ Events.INCOMING(device, io, pkt=msg), Events.ATTRIBUTE_CHANGE(device, [ChangeAttr.test("power", 0)], True), - Events.OUTGOING( - device, io, pkt=CoreMessages.Acknowledgement(), replying_to=msg - ), + Events.OUTGOING(device, io, pkt=CoreMessages.Acknowledgement(), replying_to=msg), Events.OUTGOING(device, io, pkt=reply, replying_to=msg), ] @@ -116,15 +109,11 @@ async def test_it_is_possible_to_cleanly_stop_when_sending_just_a_packet( assert devices.store(device2) == [ Events.INCOMING(device2, io2, pkt=msg), Events.ATTRIBUTE_CHANGE(device2, [ChangeAttr.test("power", 0)], True), - Events.OUTGOING( - device2, io2, pkt=CoreMessages.Acknowledgement(), replying_to=msg - ), + Events.OUTGOING(device2, io2, pkt=CoreMessages.Acknowledgement(), replying_to=msg), Events.OUTGOING(device2, io2, pkt=reply, replying_to=msg), ] - async def test_it_is_possible_to_cleanly_stop( - self, V, sender, FakeTime, MockedCallLater - ): + async def test_it_is_possible_to_cleanly_stop(self, V, sender, FakeTime, MockedCallLater): original = DeviceMessages.EchoRequest(echoing=b"hi", ack_required=False) async def gen(sd, reference, **kwargs): @@ -222,9 +211,7 @@ async def gen(sd, reference, **kwargs): ("finally", 5), ] - async def test_it_is_possible_to_perform_finally_blocks_in_deeper_layers( - self, V, sender - ): + async def test_it_is_possible_to_perform_finally_blocks_in_deeper_layers(self, V, sender): original2 = DeviceMessages.EchoRequest(echoing=b"bye", ack_required=False) called = [] @@ -272,9 +259,7 @@ async def gen(sd, reference, **kwargs): ] reply1 = expected[0][0].create(**expected[0][1]) reply2 = expected[1][0].create(**expected[1][1]) - pytest.helpers.assertSamePackets( - got, *[expected[0], *[expected[1]] * 3] * 2, expected[0], expected[1] - ) + pytest.helpers.assertSamePackets(got, *[expected[0], *[expected[1]] * 3] * 2, expected[0], expected[1]) assert len(got) == 10 device = V.device @@ -350,24 +335,16 @@ async def gen(sd, reference, **kwargs): assert not errors assert len(got) == 5 - async def test_it_allows_errors_to_go_to_an_error_catcher( - self, V, FakeTime, MockedCallLater, sender - ): + async def test_it_allows_errors_to_go_to_an_error_catcher(self, V, FakeTime, MockedCallLater, sender): ack = CoreMessages.Acknowledgement() original = DeviceMessages.EchoRequest(echoing=b"hi") reply = DeviceMessages.EchoResponse(echoing=b"hi") async def gen(sd, reference, **kwargs): - assert await ( - yield DeviceMessages.EchoRequest(echoing=b"hi", target=V.device.serial) - ) - assert not await ( - yield DeviceMessages.EchoRequest(echoing=b"hi", target=V.device2.serial) - ) + assert await (yield DeviceMessages.EchoRequest(echoing=b"hi", target=V.device.serial)) + assert not await (yield DeviceMessages.EchoRequest(echoing=b"hi", target=V.device2.serial)) for i in range(5): - assert await ( - yield DeviceMessages.EchoRequest(echoing=b"hi", target=V.device.serial) - ) + assert await (yield DeviceMessages.EchoRequest(echoing=b"hi", target=V.device.serial)) msg = FromGenerator(gen) @@ -425,19 +402,11 @@ async def test_it_doesnt_stop_errors(self, V, FakeTime, MockedCallLater, sender) reply = DeviceMessages.EchoResponse(echoing=b"hi") async def gen(sd, reference, **kwargs): - assert await ( - yield DeviceMessages.EchoRequest(echoing=b"hi", target=V.device.serial) - ) - assert not await ( - yield DeviceMessages.EchoRequest(echoing=b"hi", target=V.device2.serial) - ) - assert not await ( - yield DeviceMessages.EchoRequest(echoing=b"hi", target=V.device2.serial) - ) + assert await (yield DeviceMessages.EchoRequest(echoing=b"hi", target=V.device.serial)) + assert not await (yield DeviceMessages.EchoRequest(echoing=b"hi", target=V.device2.serial)) + assert not await (yield DeviceMessages.EchoRequest(echoing=b"hi", target=V.device2.serial)) for i in range(5): - assert await ( - yield DeviceMessages.EchoRequest(echoing=b"hi", target=V.device.serial) - ) + assert await (yield DeviceMessages.EchoRequest(echoing=b"hi", target=V.device.serial)) msg = FromGenerator(gen) @@ -448,9 +417,7 @@ async def gen(sd, reference, **kwargs): async with MockedCallLater(t, precision=0.01): try: with io2.packet_filter.lost_replies(DeviceMessages.EchoResponse): - async with sender( - msg, [V.device.serial, V.device2.serial], message_timeout=2 - ) as pkts: + async with sender(msg, [V.device.serial, V.device2.serial], message_timeout=2) as pkts: async for pkt in pkts: got.append(1) if len(got) == 4: @@ -492,7 +459,6 @@ async def gen(sd, reference, **kwargs): ] * (len(records.record) // 2) class TestRunWithApi: - async def test_it_works_with_the_run_with_api_with_sender(self, V, sender): original = DeviceMessages.EchoRequest(echoing=b"hi") script = V.target.script(original) @@ -530,9 +496,7 @@ async def test_it_works_with_run_with_api_without_sender(self, V, sender): assert dict(got) == {V.device.serial: [{"echoing": b"hi" + b"\x00" * 62}]} got = defaultdict(list) - async for pkt, remote_addr, sender_message in script.run_with( - V.device.serial, sender=sender - ): + async for pkt, remote_addr, sender_message in script.run_with(V.device.serial, sender=sender): assert pkt.Information.remote_addr == remote_addr assert pkt.Information.sender_message is sender_message assert sender_message is original @@ -555,9 +519,7 @@ async def test_it_works_with_the_run_with_all_api_with_sender(self, V, sender): script = V.target.script(original) got = defaultdict(list) - for pkt, remote_addr, sender_message in await script.run_with_all( - V.device.serial, sender - ): + for pkt, remote_addr, sender_message in await script.run_with_all(V.device.serial, sender): assert pkt.Information.remote_addr == remote_addr assert pkt.Information.sender_message is sender_message assert sender_message is original diff --git a/modules/tests/photons_transport_tests/transports/test_base.py b/modules/tests/photons_transport_tests/transports/test_base.py index 025aad0b..fc609d91 100644 --- a/modules/tests/photons_transport_tests/transports/test_base.py +++ b/modules/tests/photons_transport_tests/transports/test_base.py @@ -25,7 +25,6 @@ async def test_it_takes_in_arguments(self, session): assert transport.transport is None async def test_it_has_a_setup_function(self, session): - class T(Transport): def setup(s, one, two, *, three): s.one = one @@ -43,7 +42,6 @@ def setup(s, one, two, *, three): assert transport.three is three class TestSpawn: - @pytest.fixture() def V(self, session): class V: @@ -98,9 +96,7 @@ async def test_it_re_gets_the_transport_was_cancelled_first_time(self, original_ assert s is V.spawned assert V.called == [("spawn_transport", 10), ("spawn_transport", 20)] - async def test_it_re_gets_the_transport_if_has_exception_first_time( - self, original_message, V - ): + async def test_it_re_gets_the_transport_if_has_exception_first_time(self, original_message, V): assert V.called == [] V.spawn_transport.side_effect = ValueError("YEAP") @@ -137,7 +133,6 @@ async def test_it_re_gets_transport_if_its_no_longer_active(self, original_messa is_transport_active.assert_called_once_with(original_message, V.spawned) class TestClose: - @pytest.fixture() def transport(self, session): return Transport(session) @@ -146,7 +141,6 @@ async def test_it_does_nothing_if_transport_is_None(self, transport): await transport.close() async def test_it_doesnt_swallow_cancellations(self, transport, V): - async def getter(): await asyncio.sleep(2) return V.spawned @@ -192,7 +186,6 @@ async def test_it_closes_the_transport_if_there_is_one(self, transport, V): close_transport.assert_called_once_with(V.spawned) class TestHooks: - @pytest.fixture() def transport(self, session): return Transport(session) diff --git a/modules/tests/photons_transport_tests/transports/test_udp.py b/modules/tests/photons_transport_tests/transports/test_udp.py index e4a8da7d..ac9f49ec 100644 --- a/modules/tests/photons_transport_tests/transports/test_udp.py +++ b/modules/tests/photons_transport_tests/transports/test_udp.py @@ -20,16 +20,13 @@ def datagram_received(sp, data, addr): for msg in self.received(data, addr): self.udp_transport.sendto(msg, addr) - self.remote, _ = await hp.get_event_loop().create_datagram_endpoint( - ServerProtocol, local_addr=("0.0.0.0", self.port) - ) + self.remote, _ = await hp.get_event_loop().create_datagram_endpoint(ServerProtocol, local_addr=("0.0.0.0", self.port)) async def finish(self, exc_type=None, exc=None, tb=None): self.remote.close() class TestUDP: - @pytest.fixture() def V(self): class V: diff --git a/modules/tests/photons_web_server_tests/commander/test_messages.py b/modules/tests/photons_web_server_tests/commander/test_messages.py index 76544d3a..c588aa52 100644 --- a/modules/tests/photons_web_server_tests/commander/test_messages.py +++ b/modules/tests/photons_web_server_tests/commander/test_messages.py @@ -38,7 +38,6 @@ def test_it_turns_bytes_into_hex(self): assert reprer(b.tobytes()) == "616130303232" def test_it_reprs_everything_else(self): - class Thing: def __repr__(self): return "This thing is the best" @@ -59,7 +58,6 @@ def test_it_returns_a_sanic_json_response(self): assert res.body == b'{"error_code":"Bad","error":"very bad"}' def test_it_defaults_to_repr(self): - class Blah: ... blah = Blah() @@ -79,22 +77,18 @@ class Blah: ... class TestMessageFromExc: def test_it_re_raises_SanicExceptions(self): with pytest.raises(SanicException): - MessageFromExc(lc=hp.lc.using(), logger_name="logs")( - SanicException, SanicException("wat"), None - ) + MessageFromExc(lc=hp.lc.using(), logger_name="logs")(SanicException, SanicException("wat"), None) def test_it_can_see_SanicExceptions(self): try: raise Exception() - except: + except Exception: tb = sys.exc_info()[2] see_exception = mock.Mock(name="see_exception") exc = SanicException("NOPE") with pytest.raises(SanicException): - MessageFromExc(lc=hp.lc.using(), logger_name="logs", see_exception=see_exception)( - type(exc), exc, tb - ) + MessageFromExc(lc=hp.lc.using(), logger_name="logs", see_exception=see_exception)(type(exc), exc, tb) see_exception.assert_called_once_with(type(exc), exc, tb) def test_it_does_not_log_DelfickError_or_cancelledError(self, caplog): @@ -109,42 +103,34 @@ def test_it_does_not_log_DelfickError_or_cancelledError(self, caplog): def test_it_does_not_log_other_exceptions_if_told_not_to(self, caplog): exc = ValueError("asdf") - MessageFromExc(lc=hp.lc.using(), logger_name="logs", log_exceptions=False)( - type(exc), exc, None - ) + MessageFromExc(lc=hp.lc.using(), logger_name="logs", log_exceptions=False)(type(exc), exc, None) assert caplog.text == "" - MessageFromExc(lc=hp.lc.using(), logger_name="logs", log_exceptions=True)( - type(exc), exc, None - ) + MessageFromExc(lc=hp.lc.using(), logger_name="logs", log_exceptions=True)(type(exc), exc, None) assert "asdf" in caplog.text def test_it_turns_DelfickError_into_a_400_error_message(self): - class MyError(DelfickError): desc = "hi" exc = MyError("wat", one=5) - assert MessageFromExc(lc=hp.lc.using(), logger_name="logs")( - type(exc), exc, None - ) == ErrorMessage(status=400, error={"one": 5, "message": "hi. wat"}, error_code="MyError") + assert MessageFromExc(lc=hp.lc.using(), logger_name="logs")(type(exc), exc, None) == ErrorMessage( + status=400, error={"one": 5, "message": "hi. wat"}, error_code="MyError" + ) def test_it_turns_cancelled_error_into_request_cancelled(self): exc = asyncio.CancelledError() - assert MessageFromExc(lc=hp.lc.using(), logger_name="logs")( - type(exc), exc, None - ) == ErrorMessage(status=500, error="Request was cancelled", error_code="RequestCancelled") + assert MessageFromExc(lc=hp.lc.using(), logger_name="logs")(type(exc), exc, None) == ErrorMessage( + status=500, error="Request was cancelled", error_code="RequestCancelled" + ) def test_it_turns_everything_else_into_internal_server_errors(self): exc = ValueError("asdf") - assert MessageFromExc(lc=hp.lc.using(), logger_name="logs")( - type(exc), exc, None - ) == ErrorMessage( + assert MessageFromExc(lc=hp.lc.using(), logger_name="logs")(type(exc), exc, None) == ErrorMessage( status=500, error="Internal Server Error", error_code="InternalServerError" ) def test_it_has_the_ability_to_modify_the_error_information(self): - class MFE(MessageFromExc): def modify_error_dict( self, @@ -183,7 +169,6 @@ def test_it_defaults_to_getting_from_previous_frame(self, call_from_conftest): assert name == "photons_web_server.command.messages" def test_it_can_return_based_on_a_method(self): - class Thing: def my_method(self): pass @@ -225,12 +210,9 @@ def test_it_gets_a_logger_instance_using_get_logger_name_for_the_name(self): class TestProgressMessageMaker: - @pytest.fixture def maker(self) -> ProgressMessageMaker: - return ProgressMessageMaker( - lc=hp.lc.using(), logger_name="photons_web_server_tests.commander.test_messages" - ) + return ProgressMessageMaker(lc=hp.lc.using(), logger_name="photons_web_server_tests.commander.test_messages") async def test_it_calls_do_log_if_that_is_asked_for(self, maker: ProgressMessageMaker): message = mock.Mock(name="message") @@ -247,9 +229,7 @@ async def test_it_calls_do_log_if_that_is_asked_for(self, maker: ProgressMessage do_log.assert_called_once_with(message, info, three=one, four=two) - async def test_it_does_not_call_do_log_if_that_is_not_asked_for( - self, maker: ProgressMessageMaker - ): + async def test_it_does_not_call_do_log_if_that_is_not_asked_for(self, maker: ProgressMessageMaker): message = mock.Mock(name="message") one = mock.Mock(name="one") two = mock.Mock(name="two") @@ -265,9 +245,7 @@ async def test_it_does_not_call_do_log_if_that_is_not_asked_for( do_log.assert_not_called() class TestMakeInfo: - async def test_it_gathers_information_from_errors(self, maker: ProgressMessageMaker): - class MyDelfickError(DelfickError): desc = "I am the worst" @@ -303,9 +281,7 @@ async def test_it_turns_None_into_done_True(self, maker: ProgressMessageMaker): assert await maker(None) == {"done": True} assert await maker(None, six=6) == {"done": True, "six": 6} - async def test_it_Uses_information_if_the_message_is_a_dictionary( - self, maker: ProgressMessageMaker - ): + async def test_it_Uses_information_if_the_message_is_a_dictionary(self, maker: ProgressMessageMaker): message = {"one": 1, "two": 2} info = await maker(message) assert info == {"one": 1, "two": 2} @@ -316,15 +292,12 @@ async def test_it_Uses_information_if_the_message_is_a_dictionary( assert await maker(message, four=4) == {"one": 1, "two": 2, "four": 4} assert message == {"one": 1, "two": 2} - async def test_it_uses_message_as_an_info_value_otherwise( - self, maker: ProgressMessageMaker - ): + async def test_it_uses_message_as_an_info_value_otherwise(self, maker: ProgressMessageMaker): message = mock.Mock(name="message") assert await maker(message) == {"info": message} assert await maker(message, five=5) == {"info": message, "five": 5} class TestDoLog: - @pytest.fixture def message(self) -> mock.Mock: return mock.Mock(name="message") @@ -335,19 +308,14 @@ def assertLastRecord(self, caplog, expected_level: str, expected_msg: dict): assert rec.msg == expected_msg assert rec.levelname == expected_level - async def test_it_Logs_info_if_no_error_key( - self, caplog, message: mock.Mock, maker: ProgressMessageMaker - ): + async def test_it_Logs_info_if_no_error_key(self, caplog, message: mock.Mock, maker: ProgressMessageMaker): await maker.do_log(message, {"done": True}) self.assertLastRecord(caplog, "INFO", {"msg": "progress", "done": True}) await maker.do_log(message, {"one": True}) self.assertLastRecord(caplog, "INFO", {"msg": "progress", "one": True}) - async def test_it_Logs_info_as_key_if_not_a_dict( - self, caplog, message: mock.Mock, maker: ProgressMessageMaker - ): - + async def test_it_Logs_info_as_key_if_not_a_dict(self, caplog, message: mock.Mock, maker: ProgressMessageMaker): class Thing: pass @@ -355,10 +323,6 @@ class Thing: await maker.do_log(message, thing) self.assertLastRecord(caplog, "INFO", {"msg": "progress", "info": thing}) - async def test_it_logs_an_error_if_error_key_is_in_info( - self, caplog, message: mock.Mock, maker: ProgressMessageMaker - ): + async def test_it_logs_an_error_if_error_key_is_in_info(self, caplog, message: mock.Mock, maker: ProgressMessageMaker): await maker.do_log(message, {"error": "bad", "things": "happen"}) - self.assertLastRecord( - caplog, "ERROR", {"msg": "progress", "error": "bad", "things": "happen"} - ) + self.assertLastRecord(caplog, "ERROR", {"msg": "progress", "error": "bad", "things": "happen"}) diff --git a/modules/tests/photons_web_server_tests/commander/test_sio.py b/modules/tests/photons_web_server_tests/commander/test_sio.py index 7e22a6ef..16356929 100644 --- a/modules/tests/photons_web_server_tests/commander/test_sio.py +++ b/modules/tests/photons_web_server_tests/commander/test_sio.py @@ -43,9 +43,7 @@ def __repr__(self) -> str: class TestStoreWithSio: - async def test_it_supports_sio_commands( - self, final_future: asyncio.Future, fake_event_loop, caplog - ): + async def test_it_supports_sio_commands(self, final_future: asyncio.Future, fake_event_loop, caplog): store = Store() sio = socketio.AsyncServer(async_mode="sanic") diff --git a/modules/tests/photons_web_server_tests/commander/test_store.py b/modules/tests/photons_web_server_tests/commander/test_store.py index bb902f94..18143620 100644 --- a/modules/tests/photons_web_server_tests/commander/test_store.py +++ b/modules/tests/photons_web_server_tests/commander/test_store.py @@ -123,9 +123,7 @@ async def setup_routes(server: Server): assert made == [pytest.helpers.IsInstance(asyncio.Task), 3] assert time.time() == 3 + time_at_wait - async def test_it_can_do_dependency_injection_based_on_signature_args( - self, final_future: asyncio.Future, fake_event_loop - ): + async def test_it_can_do_dependency_injection_based_on_signature_args(self, final_future: asyncio.Future, fake_event_loop): store = Store() class Thing: ... @@ -151,9 +149,7 @@ def add_routes(kls, routes: RouteTransformer) -> None: routes.http(kls.async_route, "async_route") routes.http(kls.sync_route, "sync_route", methods=["PUT"]) - async def async_route( - s, progress: Progress, request: Request, /, _meta: strcs.Meta, thing: Thing - ) -> Response | None: + async def async_route(s, progress: Progress, request: Request, /, _meta: strcs.Meta, thing: Thing) -> Response | None: called.append(("async_route", _meta, thing)) return sanic.text("async_route") @@ -176,20 +172,14 @@ async def setup_routes(server: Server): async with pws_thp.WebServerRoutes(final_future, setup_routes) as srv: res1 = await srv.start_request("GET", "/async_route") - res2 = await srv.start_request( - "PUT", "/sync_route?three=3&four=thing&four=stuff", {"one": 2, "two": "blah"} - ) + res2 = await srv.start_request("PUT", "/sync_route?three=3&four=thing&four=stuff", {"one": 2, "two": "blah"}) assert (await res1.text()) == "async_route" assert (await res2.text()) == "sync_route" class IsMeta: def __eq__(self, o: object) -> bool: - assert ( - isinstance(o, strcs.Meta) - and all(o.data[k] == v for k, v in meta.data.items()) - and o is not meta - ) + assert isinstance(o, strcs.Meta) and all(o.data[k] == v for k, v in meta.data.items()) and o is not meta return True assert called == [ @@ -202,9 +192,7 @@ def __eq__(self, o: object) -> bool: ), ] - async def test_it_provides_ability_to_get_raw_body_and_params( - self, final_future: asyncio.Future, fake_event_loop - ): + async def test_it_provides_ability_to_get_raw_body_and_params(self, final_future: asyncio.Future, fake_event_loop): store = Store() called: list[tuple[object, ...]] = [] @@ -250,9 +238,7 @@ class COther(Command): def add_routes(kls, routes: RouteTransformer) -> None: routes.http(kls.route2, "route2") - async def route2( - s, progress: Progress, request: Request, /, thing: Thing - ) -> Response | None: + async def route2(s, progress: Progress, request: Request, /, thing: Thing) -> Response | None: return sanic.text(thing.param) @store.command @@ -261,9 +247,7 @@ class C(Command): def add_routes(kls, routes: RouteTransformer) -> None: routes.http(kls.route1, "route1") - async def route1( - s, progress: Progress, request: Request, /, route_transformer: RouteTransformer - ) -> Response | None: + async def route1(s, progress: Progress, request: Request, /, route_transformer: RouteTransformer) -> Response | None: with route_transformer.instantiate_route(request, COther, COther.route2) as route: return await route(progress, request, thing=Thing(param="blah")) @@ -275,9 +259,7 @@ async def setup_routes(server: Server): assert (await res1.text()) == "blah" - async def test_it_understands_when_the_route_itself_raises_a_CancelledError( - self, final_future: asyncio.Future, fake_event_loop - ): + async def test_it_understands_when_the_route_itself_raises_a_CancelledError(self, final_future: asyncio.Future, fake_event_loop): store = Store() @store.command @@ -298,14 +280,10 @@ async def setup_routes(server: Server): async with pws_thp.WebServerRoutes(final_future, setup_routes) as srv: res1 = await srv.start_request("GET", "/route1") - assert ( - await res1.text() - ) == '{"error_code":"RequestCancelled","error":"Request was cancelled"}' + assert (await res1.text()) == '{"error_code":"RequestCancelled","error":"Request was cancelled"}' assert res1.content_type == "application/json" - async def test_it_server_stopping_is_a_503_cancelled( - self, final_future: asyncio.Future, fake_event_loop - ): + async def test_it_server_stopping_is_a_503_cancelled(self, final_future: asyncio.Future, fake_event_loop): store = Store() @store.command @@ -327,21 +305,15 @@ async def setup_routes(server: Server): assert 5 < time.time() < 6 res = await t1 - assert ( - (await res.text()) - == dedent( - """ + assert (await res.text()) == dedent( + """ ⚠️ 503 — Service Unavailable ============================ Cancelled """ - ).strip() - + "\n\n" - ) + ).strip() + "\n\n" - async def test_it_understands_when_the_route_was_cancelled_above_the_route( - self, final_future: asyncio.Future, fake_event_loop - ): + async def test_it_understands_when_the_route_was_cancelled_above_the_route(self, final_future: asyncio.Future, fake_event_loop): store = Store() @store.command @@ -372,22 +344,16 @@ async def setup_routes(server): assert 5 < time.time() < 6 res = await t1 - assert ( - (await res.text()) - == dedent( - """ + assert (await res.text()) == dedent( + """ ⚠️ 503 — Service Unavailable ============================ Cancelled """ - ).strip() - + "\n\n" - ) + ).strip() + "\n\n" - async def test_it_logs_random_exceptions_and_returns_InternalServerError( - self, final_future: asyncio.Future, fake_event_loop, caplog - ): - identifier: str + async def test_it_logs_random_exceptions_and_returns_InternalServerError(self, final_future: asyncio.Future, fake_event_loop, caplog): + identifier: str = "" store = Store() error = ValueError("NUP") @@ -408,16 +374,12 @@ async def setup_routes(server): async with pws_thp.WebServerRoutes(final_future, setup_routes) as srv: res1 = await srv.start_request("GET", "/route1") - assert ( - await res1.text() - ) == '{"error_code":"InternalServerError","error":"Internal Server Error"}' + assert (await res1.text()) == '{"error_code":"InternalServerError","error":"Internal Server Error"}' assert res1.content_type == "application/json" assert len(caplog.records) > 3 record = caplog.records[-2] - assert ( - record.message == f"{{'request_identifier': '{identifier}', 'msg': 'ValueError: NUP'}}" - ) + assert record.message == f"{{'request_identifier': '{identifier}', 'msg': 'ValueError: NUP'}}" assert record.name == "photons_web_server_tests.commander.test_store:C:route1" assert record.exc_info == ( ValueError, @@ -425,10 +387,8 @@ async def setup_routes(server): pytest.helpers.IsInstance(types.TracebackType), ) - async def test_it_is_easy_to_log_things_in_route( - self, final_future: asyncio.Future, fake_event_loop, caplog - ): - identifier: str + async def test_it_is_easy_to_log_things_in_route(self, final_future: asyncio.Future, fake_event_loop, caplog): + identifier: str = "" store = Store() @store.command @@ -453,17 +413,12 @@ async def setup_routes(server): assert len(caplog.records) > 3 record = caplog.records[-2] - assert ( - record.message - == f"{{'request_identifier': '{identifier}', 'msg': 'Hello there', 'one': 2}}" - ) + assert record.message == f"{{'request_identifier': '{identifier}', 'msg': 'Hello there', 'one': 2}}" assert record.name == "photons_web_server_tests.commander.test_store:C:route1" assert record.exc_info is None - async def test_it_is_possible_to_have_progress_messages_on_a_http_handler( - self, final_future: asyncio.Future, fake_event_loop, caplog - ): - identifier: str + async def test_it_is_possible_to_have_progress_messages_on_a_http_handler(self, final_future: asyncio.Future, fake_event_loop, caplog): + identifier: str = "" store = Store() @store.command @@ -489,24 +444,16 @@ async def setup_routes(server): assert len(caplog.records) > 4 record = caplog.records[-3] - assert ( - record.message - == f"{{'request_identifier': '{identifier}', 'msg': 'progress', 'info': 'hi', 'there': True}}" - ) + assert record.message == f"{{'request_identifier': '{identifier}', 'msg': 'progress', 'info': 'hi', 'there': True}}" assert record.name == "photons_web_server_tests.commander.test_store:C:route1" assert record.exc_info is None record = caplog.records[-2] - assert ( - record.message - == f"{{'request_identifier': '{identifier}', 'msg': 'progress', 'error_code': 'ValueError', 'error': 'asdf'}}" - ) + assert record.message == f"{{'request_identifier': '{identifier}', 'msg': 'progress', 'error_code': 'ValueError', 'error': 'asdf'}}" assert record.name == "photons_web_server_tests.commander.test_store:C:route1" assert record.exc_info is None - async def test_it_supports_websocket_commands( - self, final_future: asyncio.Future, fake_event_loop, caplog - ): + async def test_it_supports_websocket_commands(self, final_future: asyncio.Future, fake_event_loop, caplog): store = Store() identifiers: set[str] = set() @@ -867,9 +814,7 @@ async def setup_routes(server): }, ] - async def test_it_supports_message_from_exc_from_commands( - self, final_future: asyncio.Future, fake_event_loop, caplog - ): + async def test_it_supports_message_from_exc_from_commands(self, final_future: asyncio.Future, fake_event_loop, caplog): store = Store() identifiers: set[str] = set() diff --git a/modules/tests/photons_web_server_tests/commander/test_store__determine_request_args_and_kwargs.py b/modules/tests/photons_web_server_tests/commander/test_store__determine_request_args_and_kwargs.py index 65d4aafa..7551c8ec 100644 --- a/modules/tests/photons_web_server_tests/commander/test_store__determine_request_args_and_kwargs.py +++ b/modules/tests/photons_web_server_tests/commander/test_store__determine_request_args_and_kwargs.py @@ -54,7 +54,6 @@ def index(request: Request) -> Response: class TestDeterminingRequestArgsAndKwargs: - @pytest.fixture def store(self) -> Store: return Store(strcs_register=register) @@ -63,9 +62,7 @@ def store(self) -> Store: def progress(self) -> Progress: return ProgressMessageMaker(lc=lc(), logger_name="test") - async def test_it_can_pass_in_progress_and_request( - self, store: Store, progress: Progress, app: sanic.Sanic - ): + async def test_it_can_pass_in_progress_and_request(self, store: Store, progress: Progress, app: sanic.Sanic): request, _ = await app.asgi_client.get("/") called: list[tuple[Progress, Request]] = [] @@ -74,14 +71,10 @@ def route(progress: Progress, request: Request, /) -> None: called.append((progress, request)) return None - use = store.determine_http_args_and_kwargs( - strcs.Meta(), route, progress, request, [1, 2], {1: 2} - ) + use = store.determine_http_args_and_kwargs(strcs.Meta(), route, progress, request, [1, 2], {1: 2}) assert use == [progress, request] - async def test_it_can_regcreate_missing_positionals_with_NotSpecified( - self, store: Store, progress: Progress, app: sanic.Sanic - ): + async def test_it_can_regcreate_missing_positionals_with_NotSpecified(self, store: Store, progress: Progress, app: sanic.Sanic): request, _ = await app.asgi_client.get("/") called: list[tuple[Progress, Request]] = [] @@ -93,9 +86,7 @@ def route(progress: Progress, request: Request, thing: Thing, /) -> None: use = store.determine_http_args_and_kwargs(strcs.Meta(), route, progress, request, [], {}) assert use == [progress, request, Thing(val="-1")] - async def test_it_can_pass_in_progress_and_request_when_no_annotations( - self, store: Store, progress: Progress, app: sanic.Sanic - ): + async def test_it_can_pass_in_progress_and_request_when_no_annotations(self, store: Store, progress: Progress, app: sanic.Sanic): request, _ = await app.asgi_client.get("/") called: list[tuple[Progress, Request]] = [] @@ -104,35 +95,25 @@ def route(progress, request, /): called.append((progress, request)) return None - use = store.determine_http_args_and_kwargs( - strcs.Meta(), route, progress, request, [1, 2], {1: 2} - ) + use = store.determine_http_args_and_kwargs(strcs.Meta(), route, progress, request, [1, 2], {1: 2}) assert use == [progress, request] - async def test_it_complains_if_first_argument_isnt_annotated_as_Progress( - self, store: Store, progress: Progress, app: sanic.Sanic - ): + async def test_it_complains_if_first_argument_isnt_annotated_as_Progress(self, store: Store, progress: Progress, app: sanic.Sanic): request, _ = await app.asgi_client.get("/") def route(request: Request, progress: Progress, /) -> None: return None with pytest.raises(IncorrectPositionalArgument): - store.determine_http_args_and_kwargs( - strcs.Meta(), route, progress, request, [1, 2], {1: 2} - ) + store.determine_http_args_and_kwargs(strcs.Meta(), route, progress, request, [1, 2], {1: 2}) def route2(progress: Progress, other: int, /) -> None: return None with pytest.raises(IncorrectPositionalArgument): - store.determine_http_args_and_kwargs( - strcs.Meta(), route2, progress, request, [1, 2], {1: 2} - ) + store.determine_http_args_and_kwargs(strcs.Meta(), route2, progress, request, [1, 2], {1: 2}) - async def test_it_can_pass_in_positional_args( - self, store: Store, progress: Progress, app: sanic.Sanic - ): + async def test_it_can_pass_in_positional_args(self, store: Store, progress: Progress, app: sanic.Sanic): request, _ = await app.asgi_client.get("/") called: list[tuple[Progress, Request]] = [] @@ -141,27 +122,19 @@ def route(progress: Progress, request: Request, one: int, /, two: int, three: st called.append((progress, request)) return None - use = store.determine_http_args_and_kwargs( - strcs.Meta(), route, progress, request, [1, 2], {"four": "six", "three": "five"} - ) + use = store.determine_http_args_and_kwargs(strcs.Meta(), route, progress, request, [1, 2], {"four": "six", "three": "five"}) assert use == [progress, request, 1, 2, "five"] - async def test_it_will_not_try_to_get_positional_only_from_meta( - self, store: Store, progress: Progress, app: sanic.Sanic - ): + async def test_it_will_not_try_to_get_positional_only_from_meta(self, store: Store, progress: Progress, app: sanic.Sanic): request, _ = await app.asgi_client.get("/") def route(progress: Progress, request: Request, one: int, /, two: int, three: str) -> None: return None with pytest.raises(NotEnoughArgs): - store.determine_http_args_and_kwargs( - strcs.Meta({"one": 1}), route, progress, request, [], {} - ) + store.determine_http_args_and_kwargs(strcs.Meta({"one": 1}), route, progress, request, [], {}) - async def test_it_will_use_default_if_positional_only_has_no_arg( - self, store: Store, progress: Progress, app: sanic.Sanic - ): + async def test_it_will_use_default_if_positional_only_has_no_arg(self, store: Store, progress: Progress, app: sanic.Sanic): request, _ = await app.asgi_client.get("/") called: list[tuple[Progress, Request]] = [] @@ -170,14 +143,10 @@ def route(progress: Progress, request: Request, one: int = 10, /) -> None: called.append((progress, request)) return None - use = store.determine_http_args_and_kwargs( - strcs.Meta({"one": 1}), route, progress, request, [], {} - ) + use = store.determine_http_args_and_kwargs(strcs.Meta({"one": 1}), route, progress, request, [], {}) assert use == [progress, request, 10] - async def test_it_can_get_the_meta_object( - self, store: Store, progress: Progress, app: sanic.Sanic - ): + async def test_it_can_get_the_meta_object(self, store: Store, progress: Progress, app: sanic.Sanic): request, _ = await app.asgi_client.get("/") called: list[tuple[Progress, Request]] = [] diff --git a/modules/tests/photons_web_server_tests/test_server.py b/modules/tests/photons_web_server_tests/test_server.py index b7a3c46c..ab224d6e 100644 --- a/modules/tests/photons_web_server_tests/test_server.py +++ b/modules/tests/photons_web_server_tests/test_server.py @@ -104,9 +104,7 @@ def __repr__(self) -> str: class TestTask: - def test_it_Runs_the_server(self, collector: Collector): - called = [] p = pytest.helpers.free_port() @@ -139,7 +137,6 @@ class T(WebServerTask): class TestServer: class TestTheSanicApp: async def test_it_has_config_that_weve_provided(self): - class MyConfig(Config): pass @@ -151,7 +148,6 @@ class MyServer(Server): assert server.app.name == "photons_web_server" async def test_it_has_server_name_weve_provided(self): - class MyServer(Server): sanic_server_name = "my_server_is_better_than_yours" @@ -160,9 +156,7 @@ class MyServer(Server): assert server.app.name == "my_server_is_better_than_yours" class TestLifecycle: - def test_it_has_own_lifecycle_methods_that_use_sanic_life_cycle_methods( - self, collector: Collector - ): + def test_it_has_own_lifecycle_methods_that_use_sanic_life_cycle_methods(self, collector: Collector): called: list[object] = [] calledlong = hp.create_future() p = pytest.helpers.free_port() @@ -260,10 +254,7 @@ class T(WebServerTask): "after_stop", ] - def test_it_fails_if_the_server_wants_a_port_already_in_use( - self, used_port: int, collector: Collector - ): - + def test_it_fails_if_the_server_wants_a_port_already_in_use(self, used_port: int, collector: Collector): def route(request: Request, /) -> HTTPResponse | None: return sanic.text("route") @@ -301,7 +292,6 @@ class T(WebServerTask): task.run_loop(collector=collector) class TestStoppingServer: - async def test_it_waits_for_requests_based_on_a_default_15_second_timeout_from_sanic( self, final_future: asyncio.Future, collector: Collector, fake_event_loop, fake_time ): @@ -366,9 +356,7 @@ class Config(Server.Config): server_properties = {"Config": Config} - async with pws_thp.WebServerRoutes( - final_future, setup_routes, server_properties - ) as srv: + async with pws_thp.WebServerRoutes(final_future, setup_routes, server_properties) as srv: req = srv.start_request("PUT", "/route") await started assert time.time() < 0.3 @@ -381,10 +369,7 @@ class Config(Server.Config): await req class TestLogging: - - async def test_it_records_commands_and_responses( - self, final_future: asyncio.Future, collector: Collector, fake_event_loop, caplog - ): + async def test_it_records_commands_and_responses(self, final_future: asyncio.Future, collector: Collector, fake_event_loop, caplog): identifiers: set[str] = set() Ident1 = pws_thp.IdentifierMatch(identifiers) @@ -417,12 +402,7 @@ async def setup_routes(server): } srv.stop() - records = [ - r.msg - for r in caplog.records - if isinstance(r.msg, dict) - and any(m in r.msg["msg"] for m in ("Response", "Request")) - ] + records = [r.msg for r in caplog.records if isinstance(r.msg, dict) and any(m in r.msg["msg"] for m in ("Response", "Request"))] assert records == [ { @@ -465,13 +445,9 @@ async def setup_routes(server): ] assert records[0]["request_identifier"] == records[1]["request_identifier"] - assert all( - r["request_identifier"] == records[-1]["request_identifier"] for r in records[2:] - ) + assert all(r["request_identifier"] == records[-1]["request_identifier"] for r in records[2:]) - async def test_it_lets_the_handler_hook_into_the_logging( - self, final_future: asyncio.Future, collector: Collector, fake_event_loop, caplog - ): + async def test_it_lets_the_handler_hook_into_the_logging(self, final_future: asyncio.Future, collector: Collector, fake_event_loop, caplog): called: list[object] = [] expected_called: list[object] = [] @@ -590,16 +566,9 @@ async def setup_routes(server: Server): } srv.stop() - assert (await unknown.text()).startswith( - "⚠️ 404 — Not Found\n==================\nRequested URL /unknown_route not found" - ) + assert (await unknown.text()).startswith("⚠️ 404 — Not Found\n==================\nRequested URL /unknown_route not found") - records = [ - r.msg - for r in caplog.records - if isinstance(r.msg, dict) - and any(m in r.msg["msg"] for m in ("Response", "Request")) - ] + records = [r.msg for r in caplog.records if isinstance(r.msg, dict) and any(m in r.msg["msg"] for m in ("Response", "Request"))] assert records == [ { @@ -697,10 +666,7 @@ async def setup_routes(server: Server): assert called == expected_called class TestWebsocketStreams: - - async def test_it_can_send_progress_messages( - self, final_future: asyncio.Future, collector: Collector, fake_event_loop, caplog - ): + async def test_it_can_send_progress_messages(self, final_future: asyncio.Future, collector: Collector, fake_event_loop, caplog): identifiers: set[str] = set() WSIdent1 = pws_thp.IdentifierMatch(identifiers) @@ -724,13 +690,9 @@ async def setup_routes(server): } await stream.recv() is None - async def test_it_can_provide_a_progress_callback( - self, final_future: asyncio.Future, collector: Collector, fake_event_loop, caplog - ): + async def test_it_can_provide_a_progress_callback(self, final_future: asyncio.Future, collector: Collector, fake_event_loop, caplog): identifiers: set[str] = set() - progress = pytest.helpers.AsyncMock( - name="progress", return_value={"ret": "from progress"} - ) + progress = pytest.helpers.AsyncMock(name="progress", return_value={"ret": "from progress"}) WSIdent1 = pws_thp.IdentifierMatch(identifiers) WSIdentM1 = pws_thp.IdentifierMatch(identifiers) @@ -756,9 +718,7 @@ async def setup_routes(server): progress.assert_called_once_with("there", do_log=True, one=1, two=2) - async def test_it_complains_if_the_message_isnt_valid_json( - self, final_future: asyncio.Future, collector: Collector, fake_event_loop, caplog - ): + async def test_it_complains_if_the_message_isnt_valid_json(self, final_future: asyncio.Future, collector: Collector, fake_event_loop, caplog): identifiers: set[str] = set() WSIdent1 = pws_thp.IdentifierMatch(identifiers) @@ -832,9 +792,7 @@ async def setup_routes(server): }, ] - async def test_it_can_use_message_id_that_is_provided( - self, final_future: asyncio.Future, collector: Collector, fake_event_loop, caplog - ): + async def test_it_can_use_message_id_that_is_provided(self, final_future: asyncio.Future, collector: Collector, fake_event_loop, caplog): identifiers: set[str] = set() WSIdent1 = pws_thp.IdentifierMatch(identifiers) @@ -884,9 +842,7 @@ async def setup_routes(server): }, ] - async def test_it_can_not_override_the_request_identifier( - self, final_future: asyncio.Future, collector: Collector, fake_event_loop, caplog - ): + async def test_it_can_not_override_the_request_identifier(self, final_future: asyncio.Future, collector: Collector, fake_event_loop, caplog): identifiers: set[str] = set() WSIdent1 = pws_thp.IdentifierMatch(identifiers) @@ -1077,9 +1033,7 @@ async def stream2(streamer: hp.ResultStreamer) -> tp.AsyncIterator[dict]: }, ] - async def test_it_doesnt_close_connection_on_an_exception( - self, final_future: asyncio.Future, collector: Collector, fake_event_loop, caplog - ): + async def test_it_doesnt_close_connection_on_an_exception(self, final_future: asyncio.Future, collector: Collector, fake_event_loop, caplog): async with pytest.helpers.FutureDominoes(expected=7) as futs: identifiers: set[str] = set() @@ -1248,9 +1202,7 @@ async def setup_routes(server): ] assert called == ["cancelled", "closed"] - async def test_it_logs_response_if_abruptly_closed( - self, final_future: asyncio.Future, collector: Collector, fake_event_loop, caplog - ): + async def test_it_logs_response_if_abruptly_closed(self, final_future: asyncio.Future, collector: Collector, fake_event_loop, caplog): identifiers: set[str] = set() WSIdent1 = pws_thp.IdentifierMatch(identifiers) diff --git a/modules/tests/stubs/pytest/__init__.pyi b/modules/tests/stubs/pytest/__init__.pyi index acd8d0d8..67ce6b62 100644 --- a/modules/tests/stubs/pytest/__init__.pyi +++ b/modules/tests/stubs/pytest/__init__.pyi @@ -1,3 +1,6 @@ +import typing as tp +from unittest import mock + from _pytest import version_tuple as version_tuple from _pytest._code import ExceptionInfo as ExceptionInfo from _pytest.assertion import register_assert_rewrite as register_assert_rewrite @@ -24,7 +27,6 @@ from _pytest.legacypath import TempdirFactory as TempdirFactory from _pytest.legacypath import Testdir as Testdir from _pytest.logging import LogCaptureFixture as LogCaptureFixture from _pytest.main import Session as Session -from _pytest.mark import MARK_GEN as mark from _pytest.mark import Mark as Mark from _pytest.mark import MarkDecorator as MarkDecorator from _pytest.mark import MarkGenerator as MarkGenerator @@ -85,15 +87,11 @@ from _pytest.warning_types import ( ) from _pytest.warning_types import PytestWarning as PytestWarning from _typeshed import Incomplete - -set_trace: Incomplete - -import typing as tp -from unittest import mock - from photons_pytest import FutureDominoes from tests.photons_web_server_tests.conftest import IsInstance +set_trace: Incomplete + class helpers: @staticmethod def free_port() -> int: ...