From a3cc1b2663a533dea3445d06e500312cb9ceb959 Mon Sep 17 00:00:00 2001 From: Hai Nguyen Date: Fri, 22 Nov 2024 17:36:35 -0500 Subject: [PATCH] yapf --- .style.yapf | 2 + nglview/__init__.py | 3 +- nglview/adaptor.py | 15 +++++ nglview/base.py | 13 +++-- nglview/color.py | 8 +-- nglview/component.py | 4 +- nglview/contrib/movie.py | 55 +++++++++--------- nglview/layout.py | 3 +- nglview/parameters.py | 3 +- nglview/remote_thread.py | 1 + nglview/sandbox/amber.py | 2 +- nglview/sandbox/grid_view.py | 2 + nglview/shape.py | 23 ++++---- nglview/show.py | 5 +- nglview/tests/make_dummy_comm.py | 7 +++ nglview/tests/test_show.py | 10 +++- nglview/tests/test_theme.py | 4 +- nglview/tests/test_widget.py | 21 ++++--- nglview/tests/utils.py | 15 +++-- nglview/theme/theme.py | 6 +- nglview/utils/py_utils.py | 12 ++-- nglview/utils/test_utils.py | 17 +++--- nglview/utils/widget_utils.py | 3 +- nglview/widget.py | 97 ++++++++++++++++---------------- 24 files changed, 188 insertions(+), 143 deletions(-) create mode 100644 .style.yapf diff --git a/.style.yapf b/.style.yapf new file mode 100644 index 00000000..0e9640c2 --- /dev/null +++ b/.style.yapf @@ -0,0 +1,2 @@ +[style] +based_on_style = google diff --git a/nglview/__init__.py b/nglview/__init__.py index cdea4ef2..b392385b 100644 --- a/nglview/__init__.py +++ b/nglview/__init__.py @@ -21,6 +21,7 @@ with warnings.catch_warnings(): warnings.simplefilter("ignore") + # Register nbextension # FIXME: do we still need this? def _jupyter_nbextension_paths(): @@ -33,4 +34,4 @@ def _jupyter_nbextension_paths(): __all__ = ['NGLWidget', 'write_html' - ] + widget.__all__ + adaptor.__all__ + show.__all__ + ] + widget.__all__ + adaptor.__all__ + show.__all__ diff --git a/nglview/adaptor.py b/nglview/adaptor.py index 33f4c8c5..2422828e 100644 --- a/nglview/adaptor.py +++ b/nglview/adaptor.py @@ -62,6 +62,7 @@ def _get_structure_string(write_method, suffix='.pdb'): class register_backend: + def __init__(self, package_name): # package_name must match exactly to your Python package self.package_name = package_name @@ -72,6 +73,7 @@ def __call__(self, cls): class FileStructure(Structure): + def __init__(self, path): super().__init__() self.fm = FileManager(path) @@ -84,6 +86,7 @@ def get_structure_string(self): class TextStructure(Structure): + def __init__(self, text, ext='pdb', params={}): super().__init__() self.path = '' @@ -97,6 +100,7 @@ def get_structure_string(self): @register_backend('rdkit') class RdkitStructure(Structure): + def __init__(self, rdkit_mol, ext="pdb", conf_id=-1): super().__init__() self.path = '' @@ -114,6 +118,7 @@ def get_structure_string(self): class PdbIdStructure(Structure): + def __init__(self, pdbid): super().__init__() self.pdbid = pdbid @@ -126,6 +131,7 @@ def get_structure_string(self): class ASEStructure(Structure): + def __init__(self, ase_atoms, ext='pdb', params={}): super().__init__() self.path = '' @@ -138,6 +144,7 @@ def get_structure_string(self): class IODataStructure(Structure): + def __init__(self, obj): super().__init__() self._obj = obj @@ -152,6 +159,7 @@ def get_structure_string(self): class QCElementalStructure(Structure): + def __init__(self, obj): super().__init__() self._obj = obj @@ -166,6 +174,7 @@ class Psi4Structure(QCElementalStructure): class OpenbabelStructure(Structure): + def __init__(self, obj): super().__init__() self._obj = obj @@ -183,6 +192,7 @@ def get_structure_string(self): class BiopythonStructure(Structure): + def __init__(self, entity, ext='pdb', params={}): super().__init__() self.path = '' @@ -201,6 +211,7 @@ def get_structure_string(self): class IOTBXStructure(Structure): + def __init__(self, obj, ext='pdb', params={}): """ obj must have as_pdb_string method @@ -216,6 +227,7 @@ def get_structure_string(self): class RosettaStructure(Structure): + def __init__(self, pose, ext='pdb', params={}): # type: (pyrosetta.rosetta.core.pose.Pose, str, Dict) -> None super().__init__() @@ -230,6 +242,7 @@ def get_structure_string(self): @register_backend('prody') class ProdyStructure(Structure): + def __init__(self, obj): super().__init__() self._obj = obj @@ -251,6 +264,7 @@ def write(fname): @register_backend('prody') class ProdyTrajectory(Trajectory, ProdyStructure): + def __init__(self, obj): ProdyStructure.__init__(self, obj) @@ -370,6 +384,7 @@ def get_structure_string(self, index=0): @register_backend('parmed') class ParmEdStructure(Structure): + def __init__(self, structure): self._structure = structure self.only_save_1st_model = True diff --git a/nglview/base.py b/nglview/base.py index 523d3951..a56c13ca 100644 --- a/nglview/base.py +++ b/nglview/base.py @@ -5,10 +5,12 @@ def _singleton(cls): # https://www.python.org/dev/peps/pep-0318/#examples instances = {} + def getinstance(): if cls not in instances: instances[cls] = cls() return instances[cls] + return getinstance @@ -21,9 +23,12 @@ def _js(self, code): self._call("executeCode", code) def _call(self, method_name, *args, **kwargs): - msg = {"type": "callMethod", - "methodName": method_name, - "args": args, "kwargs": kwargs} + msg = { + "type": "callMethod", + "methodName": method_name, + "args": args, + "kwargs": kwargs + } if not self._ready: # fire later self._msg_q.append(msg) @@ -31,7 +36,7 @@ def _call(self, method_name, *args, **kwargs): self.send(msg) msg_ar = self._msg_ar[:] msg_ar.append(msg) - self._msg_ar = msg_ar # trigger sync + self._msg_ar = msg_ar # trigger sync @observe("_ready") def _on_ready(self, change): diff --git a/nglview/color.py b/nglview/color.py index c826e0c2..3ed35351 100644 --- a/nglview/color.py +++ b/nglview/color.py @@ -5,7 +5,6 @@ from IPython.display import display import time - COLOR_SCHEMES = [ " ", "picking", "random", "uniform", "atomindex", "residueindex", "chainindex", "modelindex", "sstruc", "element", "resname", "bfactor", @@ -15,7 +14,6 @@ _USER_COLOR_DICT = {} - class _ColorScheme: _color_dict = {} @@ -38,12 +36,14 @@ class _ColormakerRegistry(BaseWidget): _model_name = Unicode("ColormakerRegistryModel").tag(sync=True) _model_module = Unicode("nglview-js-widgets").tag(sync=True) _model_module_version = Unicode(__frontend_version__).tag(sync=True) - _msg_q = List().tag(sync=True) # overwrite BaseWidget's trait to avoid caling base method in frontend + _msg_q = List().tag( + sync=True + ) # overwrite BaseWidget's trait to avoid caling base method in frontend def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) try: - get_ipython() # only display in notebook + get_ipython() # only display in notebook self._ipython_display_() except NameError: pass diff --git a/nglview/component.py b/nglview/component.py index c7536a9f..22e059d0 100644 --- a/nglview/component.py +++ b/nglview/component.py @@ -21,8 +21,8 @@ def __init__(self, view, id): widget_utils._add_repr_method_shortcut(self, self._view) self._borrow_attribute(self._view, [ 'clear_representations', '_remove_representations_by_name', - '_update_representations_by_name', 'center_view', 'center', - 'clear', 'set_representations' + '_update_representations_by_name', 'center_view', 'center', 'clear', + 'set_representations' ], ['get_structure_string', 'get_coordinates', 'n_frames']) @property diff --git a/nglview/contrib/movie.py b/nglview/contrib/movie.py index 03d1eed6..08eda3ab 100644 --- a/nglview/contrib/movie.py +++ b/nglview/contrib/movie.py @@ -132,8 +132,8 @@ def sleep(self): def make_old_impl(self, in_memory=False): # TODO : make base class so we can reuse this with sandbox/base.py - progress = IntProgress( - description='Rendering...', max=len(self._time_range) - 1) + progress = IntProgress(description='Rendering...', + max=len(self._time_range) - 1) self._event = threading.Event() def _make(event): @@ -156,18 +156,16 @@ def _make(event): iw = self.view.render_image(**self.render_params) self.sleep() if self.in_memory: - rgb = self._base64_to_ndarray( - self.view._image_data) + rgb = self._base64_to_ndarray(self.view._image_data) self._image_array.append(rgb) if iw: iw.close() # free memory if not self.in_memory: template = "{}/{}.{}.png" image_files = [ - image_dir - for image_dir in (template.format( + image_dir for image_dir in (template.format( self.download_folder, self.prefix, str(i)) - for i in self._time_range) + for i in self._time_range) if os.path.exists(image_dir) ] else: @@ -177,20 +175,20 @@ def _make(event): clip = mpy.ImageSequenceClip(image_files, fps=self.fps) with Output(): if self.output.endswith('.gif'): - clip.write_gif( - self.output, - fps=self.fps, - verbose=False, - **self.moviepy_params) + clip.write_gif(self.output, + fps=self.fps, + verbose=False, + **self.moviepy_params) else: - clip.write_videofile( - self.output, fps=self.fps, **self.moviepy_params) + clip.write_videofile(self.output, + fps=self.fps, + **self.moviepy_params) self._image_array = [] progress.description = 'Done' time.sleep(1) progress.close() - self.thread = threading.Thread(target=_make, args=(self._event, )) + self.thread = threading.Thread(target=_make, args=(self._event,)) self.thread.daemon = True self.thread.start() return progress @@ -219,8 +217,9 @@ def hook(frame): # trigger movie making communication between backend and frontend self.perframe_hook and hook(frame) - self.view._set_coordinates( - frame, movie_making=True, render_params=self.render_params) + self.view._set_coordinates(frame, + movie_making=True, + render_params=self.render_params) self._progress.description = 'Rendering ...' def on_msg(widget, msg, buffers): @@ -229,10 +228,9 @@ def on_msg(widget, msg, buffers): try: frame = next(iframe) self.perframe_hook and hook(frame) - self.view._set_coordinates( - frame, - movie_making=True, - render_params=self.render_params) + self.view._set_coordinates(frame, + movie_making=True, + render_params=self.render_params) self._progress.value = frame except StopIteration: if movie: @@ -262,15 +260,15 @@ def _make_from_array(self, image_array: List[str]): clip = mpy.ImageSequenceClip(image_files, fps=self.fps) with self._woutput: if self.output.endswith('.gif'): - clip.write_gif( - self.output, - fps=self.fps, - verbose=False, - **self.moviepy_params) + clip.write_gif(self.output, + fps=self.fps, + verbose=False, + **self.moviepy_params) else: - clip.write_videofile( - self.output, fps=self.fps, **self.moviepy_params) + clip.write_videofile(self.output, + fps=self.fps, + **self.moviepy_params) def interupt(self): """ Stop making process """ @@ -287,4 +285,3 @@ def _base64_to_ndarray(cls, value): im_bytes = io.BytesIO(im_bytes) # convert to numpy RGB value (for moviepy.editor.VideoClip) return np.array(Image.open(im_bytes)) - diff --git a/nglview/layout.py b/nglview/layout.py index 161c3941..fd9eb7f0 100644 --- a/nglview/layout.py +++ b/nglview/layout.py @@ -34,8 +34,7 @@ def _relayout(box, form_item_layout): kid, ], layout=form_item_layout) else: - box2 = Box([Label(value=label_value), kid], - layout=form_item_layout) + box2 = Box([Label(value=label_value), kid], layout=form_item_layout) form_items.append(box2) return form_items diff --git a/nglview/parameters.py b/nglview/parameters.py index 929bf6f5..c16e6b31 100644 --- a/nglview/parameters.py +++ b/nglview/parameters.py @@ -25,5 +25,4 @@ ] REPRESENTATION_NAMES = list( - sorted({name - for pairs in REPRESENTATION_NAME_PAIRS for name in pairs})) + sorted({name for pairs in REPRESENTATION_NAME_PAIRS for name in pairs})) diff --git a/nglview/remote_thread.py b/nglview/remote_thread.py index 81c7a1f2..20d754b4 100644 --- a/nglview/remote_thread.py +++ b/nglview/remote_thread.py @@ -3,6 +3,7 @@ class RemoteCallThread(threading.Thread): + def __init__(self, view, timeout=0.1, registered_funcs=['loadFile']): ''' diff --git a/nglview/sandbox/amber.py b/nglview/sandbox/amber.py index e9c87d82..8c78b1b0 100644 --- a/nglview/sandbox/amber.py +++ b/nglview/sandbox/amber.py @@ -65,7 +65,7 @@ def _update(event): self._update_coordinates(traj[0].xyz) # non-blocking so we can use other Jupyter's cells - self.thread = threading.Thread(target=_update, args=(self.event, )) + self.thread = threading.Thread(target=_update, args=(self.event,)) self.thread.daemon = True self.thread.start() diff --git a/nglview/sandbox/grid_view.py b/nglview/sandbox/grid_view.py index 4c9d80c2..d1e44324 100644 --- a/nglview/sandbox/grid_view.py +++ b/nglview/sandbox/grid_view.py @@ -43,6 +43,7 @@ class GridBoxNGL(GridBox): + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._ngl_class_id = None @@ -69,6 +70,7 @@ def fullscreen(self, js_code=None): class GridBoxViewAndPlayer(GridBoxNGL): + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._view = self.children[0] diff --git a/nglview/shape.py b/nglview/shape.py index 1ddc29c1..d0809acd 100644 --- a/nglview/shape.py +++ b/nglview/shape.py @@ -2,7 +2,7 @@ SHAPE_EXAMPLES = { 'mesh': - """ + """ # add_mesh(position, color, index, normal, name) >>> shape.add_mesh( [ 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1 ], @@ -10,52 +10,52 @@ ) """, 'sphere': - """ + """ # add_sphere(position, color, radius, name) >>> shape.add_sphere([0, 0, 9], [1, 0, 0], 1.5) """, 'ellipsoid': - """ + """ # add_ellipsoid(position, color, radius, majorAxis, minorAxis, name) >>> shape.add_ellipsoid([ 6, 0, 0], [ 1, 0, 0 ], 1.5, [ 3, 0, 0 ], [ 0, 2, 0 ]) """, 'cylinder': - """ + """ # add_cylinder(position1, position2, color, radius, name) >>> shape.add_cylinder( [ 0, 2, 7 ], [ 0, 0, 9 ], [ 1, 1, 0 ], 0.5 ) """, 'cone': - """ + """ # add_cone(position1, position2, color, radius, name) >>> shape.add_cone( [ 0, 2, 7 ], [ 0, 3, 3 ], [ 1, 1, 0 ], 1.5 ) """, 'arrow': - """ + """ # add_arrow(position1, position2, color, radius, name) >>> shape.add_arrow( [ 0, 2, 7 ], [ 0, 0, 9 ], [ 1, 1, 0 ], 0.5 ) """, 'label': - """ + """ # add_text(position, color, size, text) >>> shape.add_text( [ 10, -2, 4 ], [ 0.2, 0.5, 0.8 ], 0.5, "Hello" ) """, 'text': - """ + """ # add_text(position, color, size, text) >>> shape.add_text( [ 10, -2, 4 ], [ 0.2, 0.5, 0.8 ], 0.5, "Hello" ) """, 'tetrahedron': - """ + """ # add_tetrahedron >>> shape.add_tetrahedron([ 27, 0, 1 ], [ 0, 1, 0 ], 2, [ 0, 1, 1 ], [ 1, 0, 1 ]) """, 'octahedron': - """ + """ # add_octahedron >>> shape.add_octahedron([ 8, 5, 14 ], [ 0, 1, 0 ], 2, [ 0, 1, 1 ], [ 1, 0, 1 ]) """, 'torus': - """ + """ # add_torus >>> shape.add_torus([ 16, 5, 14 ], [ 0, 1, 0 ], 2, [ 0, 1, 1 ], [ 1, 0, 1 ]) """ @@ -91,6 +91,7 @@ def _make_func(self, names): from types import MethodType def make_func(name): + def func(self, *args): args_with_name = [ name, diff --git a/nglview/show.py b/nglview/show.py index d11e30b4..d8f074e1 100644 --- a/nglview/show.py +++ b/nglview/show.py @@ -8,8 +8,7 @@ ProdyStructure, ProdyTrajectory, PyTrajTrajectory, QCElementalStructure, RosettaStructure, SchrodingerStructure, SchrodingerTrajectory, - RdkitStructure, - TextStructure) + RdkitStructure, TextStructure) from .widget import NGLWidget __all__ = [ @@ -371,7 +370,7 @@ def show_rdkit(rdkit_mol, **kwargs): ext = kwargs.pop("fmt", "pdb") conf_id = kwargs.pop("conf_id", -1) struc = RdkitStructure(rdkit_mol, ext=ext, conf_id=conf_id) - return NGLWidget(struc, **kwargs) + return NGLWidget(struc, **kwargs) def show_mdanalysis(atomgroup, **kwargs): diff --git a/nglview/tests/make_dummy_comm.py b/nglview/tests/make_dummy_comm.py index e68e87de..c8dc845d 100644 --- a/nglview/tests/make_dummy_comm.py +++ b/nglview/tests/make_dummy_comm.py @@ -63,6 +63,7 @@ def dummy_get_comm_manager(**kwargs): orig_create_comm = comm.create_comm orig_get_comm_manager = comm.get_comm_manager + def setup_test_comm(): if NEW_COMM_PACKAGE: comm.create_comm = dummy_create_comm @@ -73,10 +74,13 @@ def setup_test_comm(): Widget.comm.klass = DummyComm ipywidgets.widgets.widget.Comm = DummyComm _widget_attrs['_repr_mimebundle_'] = Widget._repr_mimebundle_ + def raise_not_implemented(*args, **kwargs): raise NotImplementedError() + Widget._repr_mimebundle_ = raise_not_implemented + def teardown_test_comm(): if NEW_COMM_PACKAGE: comm.create_comm = orig_create_comm @@ -93,11 +97,14 @@ def teardown_test_comm(): setattr(Widget, attr, value) _widget_attrs.clear() + def setup(): setup_test_comm() + def teardown(): teardown_test_comm() + def call_method(method, *args, **kwargs): method(*args, **kwargs) diff --git a/nglview/tests/test_show.py b/nglview/tests/test_show.py index 7ce6a6a0..bd906c3b 100644 --- a/nglview/tests/test_show.py +++ b/nglview/tests/test_show.py @@ -14,12 +14,14 @@ def _write(*args, **kargs): class MockStructure: + def as_pdb_string(self): with open(nglview.datafiles.PDB) as fh: return fh.read() class MockRosettaPose: + def dump_pdb(self, _): _write() @@ -69,7 +71,9 @@ def test_show_iotbx(): def test_show_iodata(): + class MockIO: + def to_file(self, fname): with open(fname, 'w') as fh: fh.write("""3 @@ -83,7 +87,9 @@ def to_file(self, fname): def test_show_qcelemental_show_psi4(): + class MockMol: + def to_string(self, format): return '1\nHe\nHe 0.000000000000 0.000000000000 0.000000000000\n' @@ -114,6 +120,7 @@ def test_show_prody(): sys.modules['prody'] = prody class MockEnsemble: + def __getitem__(self, index): return 0 @@ -121,7 +128,9 @@ def numConfs(self): return 1 def getConformation(self, index): + class Struct: + def getCoords(self): return @@ -138,7 +147,6 @@ def getCoords(self): assert prody.writePDB.called - try: import rdkit from rdkit import Chem diff --git a/nglview/tests/test_theme.py b/nglview/tests/test_theme.py index b01f4976..2c1e3c33 100644 --- a/nglview/tests/test_theme.py +++ b/nglview/tests/test_theme.py @@ -3,8 +3,8 @@ def test_theme(): - m = ThemeManager() - assert m is ThemeManager() # singleton + m = ThemeManager() + assert m is ThemeManager() # singleton assert m._theme_css == '' m.dark() assert m._theme == 'dark' diff --git a/nglview/tests/test_widget.py b/nglview/tests/test_widget.py index a52d074f..fd5ad3e9 100644 --- a/nglview/tests/test_widget.py +++ b/nglview/tests/test_widget.py @@ -227,7 +227,7 @@ def test_API_promise_to_have(): view.frame = -1 msg = dict(type='request_frame', data=dict()) # async_message - msg = {'type': 'async_message', 'data': 'ok'} + msg = {'type': 'async_message', 'data': 'ok'} view._handle_nglview_custom_msg(None, msg, []) # render_image r = view.render_image() @@ -280,6 +280,7 @@ def update_coords(view=view): def test_API_promise_to_have_add_more_backend(): + @nv.register_backend('dummy') class MyLovelyClass(nv.Structure, nv.Trajectory): pass @@ -343,7 +344,11 @@ def test_load_data(): # raise if passing dummy name - with pytest.raises(ValueError, match='you must provide file extension if using file-like object or text content'): + with pytest.raises( + ValueError, + match= + 'you must provide file extension if using file-like object or text content' + ): view._load_data("hahahaha") # load PyTrajectory @@ -366,7 +371,6 @@ def test_representations(): def func(): view.representations = {'0': MagicMock()} - # Representations # make fake params try: @@ -488,13 +492,13 @@ def test_show_ase(): def test_show_pymatgen(): from pymatgen.core import Lattice, Structure lattice = Lattice.cubic(4.2) - structure = Structure(lattice, ["Cs", "Cl"], - [[0, 0, 0], [0.5, 0.5, 0.5]]) + structure = Structure(lattice, ["Cs", "Cl"], [[0, 0, 0], [0.5, 0.5, 0.5]]) view = nv.show_pymatgen(structure) view -@pytest.mark.skipif(not has_qcelemental, reason='skip if not having qcelemental') +@pytest.mark.skipif(not has_qcelemental, + reason='skip if not having qcelemental') def test_show_qcelemental(): import qcelemental as qcel @@ -703,8 +707,8 @@ def copy_coordinate_dict(view): def test_existing_js_files(): from glob import glob jsfiles = glob(os.path.join(os.path.dirname(nv.__file__), 'static', '*js')) - mapfiles = glob( - os.path.join(os.path.dirname(nv.__file__), 'static', '*map')) + mapfiles = glob(os.path.join(os.path.dirname(nv.__file__), 'static', + '*map')) assert len(jsfiles) == 2 assert len(mapfiles) == 1 @@ -770,6 +774,7 @@ def test_loaded_attribute(): view.add_trajectory(traj) view + def test_widget_utils(): box = HBox() i0 = IntText() diff --git a/nglview/tests/utils.py b/nglview/tests/utils.py index ab2354fc..d670ee87 100644 --- a/nglview/tests/utils.py +++ b/nglview/tests/utils.py @@ -33,8 +33,9 @@ def get_fn(fn): 'lazy': False, 'linewidth': 2, 'matrix': { - 'elements': - [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] + 'elements': [ + 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 + ] }, 'metalness': 0, 'opacity': 1, @@ -81,8 +82,9 @@ def get_fn(fn): 'lineOnly': False, 'linewidth': 2, 'matrix': { - 'elements': - [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] + 'elements': [ + 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 + ] }, 'metalness': 0, 'opacity': 1, @@ -129,8 +131,9 @@ def get_fn(fn): 'lineOnly': False, 'linewidth': 2, 'matrix': { - 'elements': - [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] + 'elements': [ + 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 + ] }, 'metalness': 0, 'multipleBond': 'off', diff --git a/nglview/theme/theme.py b/nglview/theme/theme.py index 0c2a86b5..b28cf55a 100644 --- a/nglview/theme/theme.py +++ b/nglview/theme/theme.py @@ -77,9 +77,11 @@ def remove(self): self._theme_css = '' def dark(self): - self._theme_css = _get_css_content('dark.css') + _get_css_content('main.css') + self._theme_css = _get_css_content('dark.css') + _get_css_content( + 'main.css') self._theme = 'dark' def light(self): - self._theme_css = _get_css_content('light.css') + _get_css_content('main.css') + self._theme_css = _get_css_content('light.css') + _get_css_content( + 'main.css') self._theme = 'light' diff --git a/nglview/utils/py_utils.py b/nglview/utils/py_utils.py index 12fb3ecf..71ca0f83 100644 --- a/nglview/utils/py_utils.py +++ b/nglview/utils/py_utils.py @@ -206,8 +206,8 @@ def is_compressed(self): ''' if self._compressed is None: if self.is_filename or self.is_url: - return (self.src.endswith('gz') or self.src.endswith('zip') - or self.src.endswith('bz2')) + return (self.src.endswith('gz') or self.src.endswith('zip') or + self.src.endswith('bz2')) else: return False else: @@ -237,8 +237,8 @@ def ext(self): if self._ext is not None: return self._ext else: - if hasattr(self.src, 'read') or (not self.is_filename - and not self.is_url): + if hasattr(self.src, 'read') or (not self.is_filename and + not self.is_url): raise ValueError( "you must provide file extension if using file-like object or text content" ) @@ -267,5 +267,5 @@ def is_binary(self): def is_url(self): url_ext = ['http', 'rcsb://', 'data://'] + \ [f"{k}://" for k in DatasourceRegistry.sources] - return (isinstance(self.src, str) - and self.src.startswith(tuple(url_ext))) + return (isinstance(self.src, str) and + self.src.startswith(tuple(url_ext))) diff --git a/nglview/utils/test_utils.py b/nglview/utils/test_utils.py index 130a79e0..4b59eedd 100644 --- a/nglview/utils/test_utils.py +++ b/nglview/utils/test_utils.py @@ -1,8 +1,11 @@ from ..adaptor import Trajectory, Structure import numpy as np + def get_mocked_traj(): + class MockedTraj(Structure, Trajectory): + def __init__(self): Structure.__init__(self) Trajectory.__init__(self) @@ -12,16 +15,14 @@ def n_frames(self): return 5 def get_coordinates(self, frame): - coordinates = [ - [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]], - [[0.1, 0.1, 0.1], [1.1, 0.1, 0.1], [0.1, 1.1, 0.1]], - [[0.2, 0.2, 0.2], [1.2, 0.2, 0.2], [0.2, 1.2, 0.2]], - [[0.3, 0.3, 0.3], [1.3, 0.3, 0.3], [0.3, 1.3, 0.3]], - [[0.4, 0.4, 0.4], [1.4, 0.4, 0.4], [0.4, 1.4, 0.4]] - ] + coordinates = [[[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]], + [[0.1, 0.1, 0.1], [1.1, 0.1, 0.1], [0.1, 1.1, 0.1]], + [[0.2, 0.2, 0.2], [1.2, 0.2, 0.2], [0.2, 1.2, 0.2]], + [[0.3, 0.3, 0.3], [1.3, 0.3, 0.3], [0.3, 1.3, 0.3]], + [[0.4, 0.4, 0.4], [1.4, 0.4, 0.4], [0.4, 1.4, 0.4]]] return np.array(coordinates)[frame] def get_structure_string(self): return 'hello' - return MockedTraj() \ No newline at end of file + return MockedTraj() diff --git a/nglview/utils/widget_utils.py b/nglview/utils/widget_utils.py index ab1ebe1e..059d4607 100644 --- a/nglview/utils/widget_utils.py +++ b/nglview/utils/widget_utils.py @@ -31,8 +31,7 @@ def get_widget_by_name(box, widget_name): if children is not None: for widget in children: - if hasattr(widget, - '_ngl_name') and widget._ngl_name == widget_name: + if hasattr(widget, '_ngl_name') and widget._ngl_name == widget_name: return widget return None diff --git a/nglview/widget.py b/nglview/widget.py index 5d5a2e32..2969e3cc 100644 --- a/nglview/widget.py +++ b/nglview/widget.py @@ -10,8 +10,8 @@ from ipywidgets import embed import numpy as np from IPython.display import display -from ipywidgets import (Image, Box, DOMWidget, HBox, VBox, IntSlider, Output, Play, Widget, - jslink) +from ipywidgets import (Image, Box, DOMWidget, HBox, VBox, IntSlider, Output, + Play, Widget, jslink) from ipywidgets import widget as _widget from traitlets import (Bool, CaselessStrEnum, Dict, Instance, Int, Integer, List, Unicode, observe, validate) @@ -51,8 +51,11 @@ _INIT_VIEWS = {'color_maker_registry': color.ColormakerRegistry} _TRACKED_WIDGETS = {} + def _deprecated(msg): + def wrap_1(func): + def wrap_2(*args, **kwargs): logger.warn(msg) return func(*args, **kwargs) @@ -110,7 +113,8 @@ def _unset_serialization(views): # hacky thing for https://github.com/nglviewer/nglview/issues/1107 # NGL must be fixed before we can remove this hack _frontend = {'__frontend_version__': __frontend_version__} - pattern = r'("model_module":\s*"nglview-js-widgets",\s*"model_module_version":\s*)"' + re.escape(_frontend['__frontend_version__']) + '",' + pattern = r'("model_module":\s*"nglview-js-widgets",\s*"model_module_version":\s*)"' + re.escape( + _frontend['__frontend_version__']) + '",' replacement = r'\g<1>"3.0.8",' snippet = re.sub(pattern, replacement, snippet) html_code = embed.html_template.format(title='nglview-demo', @@ -128,7 +132,6 @@ def _unset_serialization(views): _unset_serialization(views) - class NGLWidget(DOMWidget): _view_name = Unicode("NGLView").tag(sync=True) _view_module = Unicode("nglview-js-widgets").tag(sync=True) @@ -147,8 +150,8 @@ class NGLWidget(DOMWidget): loaded = Bool(False).tag(sync=False) picked = Dict().tag(sync=True) n_components = Int(0).tag(sync=True) - _view_width = Unicode().tag(sync=True) # px - _view_height = Unicode().tag(sync=True) # px + _view_width = Unicode().tag(sync=True) # px + _view_height = Unicode().tag(sync=True) # px _scene_position = Dict().tag(sync=True) _scene_rotation = Dict().tag(sync=True) # hack to always display movie @@ -170,7 +173,8 @@ class NGLWidget(DOMWidget): _send_binary = Bool(True).tag(sync=False) _init_gui = Bool(False).tag(sync=False) gui_style = CaselessStrEnum(['ngl'], allow_none=True).tag(sync=True) - _gui_theme = CaselessStrEnum(['dark', 'light'], allow_none=True).tag(sync=True) + _gui_theme = CaselessStrEnum(['dark', 'light'], + allow_none=True).tag(sync=True) _widget_theme = None _ngl_serialize = Bool(False).tag(sync=True) _ngl_msg_archive = List().tag(sync=True) @@ -182,10 +186,11 @@ class NGLWidget(DOMWidget): # instance _iplayer = Instance(widgets.Box, allow_none=True).tag(sync=True, **widget_serialization) - _igui = Instance(widgets.Tab, - allow_none=True).tag(sync=True, **widget_serialization) + _igui = Instance(widgets.Tab, allow_none=True).tag(sync=True, + **widget_serialization) _ibtn_fullscreen = Instance(widgets.Button, - allow_none=True).tag(sync=True, **widget_serialization) + allow_none=True).tag(sync=True, + **widget_serialization) def __init__(self, structure=None, @@ -208,7 +213,7 @@ def __init__(self, self.stage = Stage(view=self) self.control = ViewerControl(view=self) self._handle_msg_thread = threading.Thread( - target=self.on_msg, args=(self._handle_nglview_custom_msg, )) + target=self.on_msg, args=(self._handle_nglview_custom_msg,)) # # register to get data from JS side self._handle_msg_thread.daemon = True self._handle_msg_thread.start() @@ -229,8 +234,8 @@ def __init__(self, if 'default' in kwargs: kwargs['default_representation'] = kwargs['default'] - autoview = 'center' not in kwargs or ('center' in kwargs - and kwargs.pop('center')) + autoview = 'center' not in kwargs or ('center' in kwargs and + kwargs.pop('center')) # NOTE: Using `pop` to avoid passing `center` to NGL. if parameters: @@ -270,8 +275,8 @@ def _create_ibtn_fullscreen(self): # onclick is implemented in frontend self._ibtn_fullscreen = button - def _sync_with_layout(self): + def on_change_layout(change): new = change['new'] if change['name'] == 'width': @@ -386,8 +391,9 @@ def handle_resize(self): def _update_max_frame(self): self.max_frame = max( - int(traj.n_frames) for traj in self._trajlist - if hasattr(traj, 'n_frames')) - 1 # index starts from 0 + int(traj.n_frames) + for traj in self._trajlist + if hasattr(traj, 'n_frames')) - 1 # index starts from 0 def _wait_until_finished(self, timeout=0.0001): # NGL need to send 'finished' signal to @@ -422,6 +428,7 @@ def on_loaded(self, change): self._fire_callbacks(self._ngl_displayed_callbacks_before_loaded) def _fire_callbacks(self, callbacks): + def _call(event): for callback in callbacks: callback(self) @@ -486,15 +493,15 @@ def _set_sync_repr(self, other_views): def _set_unsync_repr(self, other_views): model_ids = {v._model_id for v in other_views} - self._synced_repr_model_ids = list(set(self._synced_repr_model_ids) - model_ids) + self._synced_repr_model_ids = list( + set(self._synced_repr_model_ids) - model_ids) self._remote_call("setSyncRepr", target="Widget", args=[self._synced_repr_model_ids]) def _set_sync_camera(self, other_views): model_ids = {v._model_id for v in other_views} - self._synced_model_ids = sorted( - set(self._synced_model_ids) | model_ids) + self._synced_model_ids = sorted(set(self._synced_model_ids) | model_ids) self._remote_call("setSyncCamera", target="Widget", args=[self._synced_model_ids]) @@ -553,8 +560,7 @@ def representations(self): @representations.setter def representations(self, reps): if isinstance(reps, dict): - self._remote_call("_set_representation_from_repr_dict", - args=[reps]) + self._remote_call("_set_representation_from_repr_dict", args=[reps]) else: self._representations = reps[:] for index in range(len(self._ngl_component_ids)): @@ -618,8 +624,7 @@ def _remove_representations_by_name(self, repr_name, component=0): target='Widget', args=[repr_name, component]) - def _update_representations_by_name(self, repr_name, component=0, - **kwargs): + def _update_representations_by_name(self, repr_name, component=0, **kwargs): kwargs = _camelize_dict(kwargs) self._remote_call('updateRepresentationsByName', target='Widget', @@ -647,20 +652,20 @@ def _set_coordinates(self, index, movie_making=False, render_params=None): try: if trajectory.shown: - coordinates_dict[traj_index] = trajectory.get_coordinates(index) + coordinates_dict[ + traj_index] = trajectory.get_coordinates(index) else: coordinates_dict[traj_index] = np.empty((0), dtype='f4') except (IndexError, ValueError): coordinates_dict[traj_index] = np.empty((0), dtype='f4') self.set_coordinates(coordinates_dict, - render_params=render_params, - movie_making=movie_making) + render_params=render_params, + movie_making=movie_making) else: print("no trajectory available") - def set_coordinates(self, arr_dict, movie_making=False, - render_params=None): + def set_coordinates(self, arr_dict, movie_making=False, render_params=None): # type: (Dict[int, np.ndarray]) -> None """Used for update coordinates of a given trajectory >>> # arr: numpy array, ndim=2 @@ -676,16 +681,14 @@ def set_coordinates(self, arr_dict, movie_making=False, buffers.append(arr.astype('f4').tobytes()) coordinates_meta[index] = index msg = { - 'type': 'binary_single', - 'data': coordinates_meta, - } + 'type': 'binary_single', + 'data': coordinates_meta, + } if movie_making: msg['movie_making'] = movie_making msg['render_params'] = render_params - self.send( - msg, - buffers=buffers) + self.send(msg, buffers=buffers) @observe('frame') def _on_frame_changed(self, change): @@ -740,7 +743,10 @@ def _add_shape(self, shapes, name='shape'): >>> c = view._add_shape([sphere, arrow], name='my_shape') """ - self._remote_call('addShape', target='Widget', args=[name, shapes], fire_embed=True) + self._remote_call('addShape', + target='Widget', + args=[name, shapes], + fire_embed=True) # Added to remain in sync with the JS components # Similarly to _loadData @@ -940,7 +946,8 @@ def _handle_repr_parameters(self): data_dict = self._ngl_msg['data'] name = data_dict.pop('name') + '\n' selection = data_dict.get('sele', '') + '\n' - data_dict_json = json.dumps(data_dict).replace('true', 'True').replace('false', 'False') + data_dict_json = json.dumps(data_dict).replace('true', 'True').replace( + 'false', 'False') data_dict_json = data_dict_json.replace('null', '"null"') def _handle_request_loaded(self): @@ -960,7 +967,8 @@ def _handle_async_message(self): def _handle_image_data(self): self._image_data = self._ngl_msg.get('data') - _TRACKED_WIDGETS[self._ngl_msg.get('ID')].value = base64.b64decode(self._image_data) + _TRACKED_WIDGETS[self._ngl_msg.get('ID')].value = base64.b64decode( + self._image_data) def _handle_nglview_custom_msg(self, _, msg, buffers): self._ngl_msg = msg @@ -1157,10 +1165,7 @@ def _load_data(self, obj, **kwargs): name = py_utils.get_name(obj, **kwargs2) self._ngl_component_names.append(name) - self._remote_call("loadFile", - target='Stage', - args=args, - kwargs=kwargs2) + self._remote_call("loadFile", target='Stage', args=args, kwargs=kwargs2) def remove_component(self, c): """remove component by its uuid. @@ -1291,10 +1296,7 @@ def _trim_message(self, messages): messages_rm += [load_comps[r[1]] for r in remove_comps] messages_rm = set(messages_rm) - return [ - msg for i, msg in enumerate(messages) - if i not in messages_rm - ] + return [msg for i, msg in enumerate(messages) if i not in messages_rm] def _remote_call(self, method_name, @@ -1418,10 +1420,7 @@ def _js(self, code, **kwargs): self._execute_js_code(code, **kwargs) def _execute_js_code(self, code, **kwargs): - self._remote_call('executeCode', - target='Widget', - args=[code], - **kwargs) + self._remote_call('executeCode', target='Widget', args=[code], **kwargs) def _update_component_auto_completion(self): trajids = [traj.id for traj in self._trajlist]