Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better DX with experiment module #463

Open
grimadas opened this issue Aug 13, 2020 · 9 comments
Open

Better DX with experiment module #463

grimadas opened this issue Aug 13, 2020 · 9 comments

Comments

@grimadas
Copy link
Contributor

grimadas commented Aug 13, 2020

As far as I can see, right now gumby works like this:

  • You create your own community with some logic.
  • You create your experiment module to work with your community.
  • This experiment module uses @static_module, so it cannot be reused, inherited or extended.

However during my experiments I notice that I need a better separation between community object and experiment logic.
As for now your overlay is fixed in __init__ of your experiment, but I want to reuse same experiment logic for different communities without boilerplate copying.

P.S.
DX for Developer Experience

@grimadas
Copy link
Contributor Author

If we already have good canonical way - we should include it somewhere in documentation.

@qstokkink
Copy link
Contributor

AFAIK you can also subclass @static_module classes, e.g.:

@static_module
class AlgorandModule(BlockchainModule):

@static_module
class BlockchainModule(ExperimentModule):

Does this not work?

@grimadas
Copy link
Contributor Author

Yes, but experiment_callbacks are not inherited

@qstokkink
Copy link
Contributor

Intuitively that's how it should work in my opinion. I'd almost consider experiment_callbacks not propagating to subclasses a bug.

I guess this is not propagating as experiment_callback is binding to the namespace of the superclass. If that is the case, it should be somewhat easy to fix/implement.

@qstokkink
Copy link
Contributor

This should be the culprit:

gumby/gumby/experiment.py

Lines 217 to 218 in c5aa64a

member_names = [name for name in dir(target) if type(getattr(target.__class__, name, None)).__name__ !=
"property"]

My guess would be getattr(target.__class__, name, None) should change to consider all classes in the mro.

@qstokkink
Copy link
Contributor

@grimadas do you have a minimum working example? If you do, could you try out this:

member_names = set()
for subclass in target.__class__.mro():
    for name in dir(subclass):
        if name not in member_names and type(getattr(subclass, name, None)).__name__ != "property":
            member_names.add(name)

@grimadas
Copy link
Contributor Author

@qstokkink Thanks it works.

Now my code looks like this:

@static_module
class BamiDataExperiments(BaseBamiDataExperiments):

    def __init__(self, experiment: Any) -> None:
        super().__init__(experiment, DataCommunity)


@static_module
class BamiDataWithDiscoveryExperiments(BaseBamiDataExperiments):

    def __init__(self, experiment: Any) -> None:
        super().__init__(experiment, DataCommunityWithDiscovery)

Notice that experiments differ only in their community. While communities have same interface. Do you think it can be further improved?

@qstokkink
Copy link
Contributor

Seems like that is about as small as it will get with "plain" Python. You could still minify this by making a new decorating function. It's probably not worth the time investment though (unless it really bothers you).

Could you make a PR for the member_names patch in its final form?

@grimadas
Copy link
Contributor Author

Yes, will create pr for this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants