HPInc / HP-Digital-Microfluidics

HP Digital Microfluidics Software Platform and Libraries
MIT License
2 stars 0 forks source link

Alow delay of importing platform package in `PlatformChoiceExerciser` #217

Closed EvanKirshenbaum closed 5 months ago

EvanKirshenbaum commented 5 months ago

A PlatformChoiceExerciser is instantiated by providing a sequence of PlatformChoiceTasks, either by value, by value-returning function (e.g., class), or by name. e.g.:

    platforms = (
                "devices.bilby.PlatformTask",
                joey.PlatformTask,
                opendrop.PlatformTask,
                wombat.PlatformTask,
                wombat.YaminonPlatformTask,
                )
    pipettors = (opentrons.PipettorConfig,)
    default_pipettor = manual_pipettor.PipettorConfig

    exerciser = PlatformChoiceExerciser.for_task(DisplayOnly, 
                                                 "Interact with a DMF board",
                                                 platforms=platforms,
                                                 pipettors=pipettors,
                                                 default_pipettor=default_pipettor)

The reason I allow a string is that I didn't want to require the module for, e.g., bilby to be imported, since it might depend on a DLL that people might not have. Unfortunately, inside the constructor for PlatformChoiceExerciser, I turn around and say:

        for p in platforms:
            platform: ValOrFn[PlatformChoiceTask]
            if isinstance(p, str):
                ...
                module_name = ...
                try:
                    module = import_module(module_name)
                    val = getattr(module, name)
                except ModuleNotFoundError as ex:
                    bad_spec(f"requires '{ex.name}' module")
                    continue
                ...

That is, I immediately do the import, which kinda defeats the purpose. And, crashes on other people's machines. (Not mine, of course, so I didn't notice how stupid this was.) And is keeping them from using the interactive script, which works, as opposed to, e.g., the wombat display script, which has weird arguments and excessive tracing.

What I think I need to do is to allow a (name, val) platform description, with the name being the thing that's registered, and the string being used (or function called) only if that is the platform chosen. This would probably require some sort of DelayedPlatformChoiceTask. This would also allow the user to change the name of a platform, and possibly also provide aliases.

Migrated from internal repository. Originally created by @EvanKirshenbaum on Jan 14, 2023 at 6:14 PM PST. Closed on Jan 15, 2023 at 11:01 AM PST.
EvanKirshenbaum commented 5 months ago

This issue was referenced by the following commit before migration:

EvanKirshenbaum commented 5 months ago

That approach didn't quite work, because the argument parser requires that arguments be specified for subparsers before you start. (Why isn't there an option to specify the subparser arguments only when it is chosen? Oh, well.)

What I settled on instead was simply to move devices.bilby.ParserTask into its own module (devices.bilby_task) and delay the loading of devices.bilby to its make_board() method. That seems to work.

Migrated from internal repository. Originally created by @EvanKirshenbaum on Jan 15, 2023 at 11:01 AM PST.