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

Monkey patch GUI elements #151

Merged
merged 10 commits into from
Oct 12, 2022
5 changes: 5 additions & 0 deletions pyiron_gui/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
__version__ = "0.1"
__all__ = []

# desired API
from pyiron_gui.project.project import activate_gui
from pyiron_gui.project.project_browser import ProjectBrowser, DataContainerGUI

# monkey patching
import pyiron_gui.monkey_patching


from ._version import get_versions

__version__ = get_versions()["version"]
Expand Down
67 changes: 67 additions & 0 deletions pyiron_gui/monkey_patching.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# coding: utf-8
# Copyright (c) Max-Planck-Institut für Eisenforschung GmbH - Computational Materials Design (CM) Department
# Distributed under the terms of "New BSD License", see the LICENSE file.

"""Adding gui functionality to pyiron classes via monkey patching on import of pyiron_gui. """
import warnings

from pyiron_gui.project.project_browser import (
ProjectBrowser,
HasGroupsBrowser,
DataContainerGUI,
)
from pyiron_base.interfaces.has_groups import HasGroups
from pyiron_base import Project
from pyiron_base import DataContainer

__author__ = "Niklas Siemer"
__copyright__ = (
"Copyright 2021, Max-Planck-Institut für Eisenforschung GmbH - "
"Computational Materials Design (CM) Department"
)
__version__ = "0.1"
__maintainer__ = "Niklas Siemer"
__email__ = "[email protected]"
__status__ = "development"
__date__ = "July 06, 2022"


def safe_monkey_patch(cls, attr_name, value):
if hasattr(cls, attr_name):
warnings.warn(
f"Class {cls.__name__} already has attribute {attr_name} - Aborting monkey path of gui elements."
)
else:
setattr(cls, attr_name, value)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might break in a similar way under reloading module has @jan-janssen pointed out in pyiron_base#808. I discussed a potential fix there also.

niklassiemer marked this conversation as resolved.
Show resolved Hide resolved


def _has_groups_gui(self, box=None, refresh=False):
if self._has_groups_browser is None or refresh:
self._has_groups_browser = HasGroupsBrowser(self, box=box)
return self._has_groups_browser


safe_monkey_patch(HasGroups, "_has_groups_browser", None)
safe_monkey_patch(HasGroups, "gui", _has_groups_gui)


def _datacontainer_gui(self, box=None, refresh=False):
if self._datacontainer_gui is None or refresh:
self._datacontainer_gui = DataContainerGUI(self, box=box)
return self._datacontainer_browser


safe_monkey_patch(DataContainer, "_datacontainer_gui", _datacontainer_gui)
niklassiemer marked this conversation as resolved.
Show resolved Hide resolved
safe_monkey_patch(DataContainer, "gui", _datacontainer_gui)


def _pyiron_base_project_browser(self):
if self._project_browser is None:
self._project_browser = ProjectBrowser(
project=self, show_files=False, Vbox=None
)
return self._project_browser


safe_monkey_patch(Project, "_project_browser", None)
safe_monkey_patch(Project, "browser", property(_pyiron_base_project_browser))