Skip to content

Commit

Permalink
Merge pull request #4941 from neutrinoceros/dep/ipywidgets_as_optional
Browse files Browse the repository at this point in the history
DEP: make ipywidgets/IPython optional dependencies again
  • Loading branch information
matthewturk authored Sep 3, 2024
2 parents a88534c + c508a45 commit f39ed50
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 74 deletions.
5 changes: 2 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ requires-python = ">=3.9.2"
dependencies = [
"cmyt>=1.1.2",
"ewah-bool-utils>=1.2.0",
"ipywidgets>=8.0.0",
"matplotlib>=3.5",
"more-itertools>=8.4",
"numpy>=1.19.3, <3", # keep minimal requirement in sync with NPY_TARGET_VERSION
Expand Down Expand Up @@ -136,7 +135,8 @@ full = [
"cartopy>=0.22.0",
"firefly>=3.2.0",
"glueviz>=0.13.3",
"ipython>=2.0.0",
"ipython>=7.16.2",
"ipywidgets>=8.0.0",
"miniballcpp>=0.2.1",
"mpi4py>=3.0.3",
"pandas>=1.1.2",
Expand Down Expand Up @@ -210,7 +210,6 @@ mapserver = [
minimal = [
"cmyt==1.1.2",
"ewah-bool-utils==1.2.0",
"ipywidgets==8.0.0",
"matplotlib==3.5",
"more-itertools==8.4",
"numpy==1.19.3",
Expand Down
31 changes: 31 additions & 0 deletions yt/_maintenance/ipython_compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from importlib.metadata import version
from importlib.util import find_spec

from packaging.version import Version

__all__ = [
"IS_IPYTHON",
"IPYWIDGETS_ENABLED",
]

IS_IPYTHON: bool
HAS_IPYWIDGETS_GE_8: bool
IPYWIDGETS_ENABLED: bool


try:
# this name is only defined if running within ipython/jupyter
__IPYTHON__ # type: ignore [name-defined] # noqa: B018
except NameError:
IS_IPYTHON = False
else:
IS_IPYTHON = True


HAS_IPYWIDGETS_GE_8 = (
Version(version("ipywidgets")) >= Version("8.0.0")
if find_spec("ipywidgets") is not None
else False
)

IPYWIDGETS_ENABLED = IS_IPYTHON and HAS_IPYWIDGETS_GE_8
6 changes: 2 additions & 4 deletions yt/data_objects/static_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from unyt.exceptions import UnitConversionError, UnitParseError

from yt._maintenance.deprecation import issue_deprecation_warning
from yt._maintenance.ipython_compat import IPYWIDGETS_ENABLED
from yt._typing import (
AnyFieldKey,
AxisOrder,
Expand Down Expand Up @@ -119,10 +120,7 @@ def __init__(self, display_array=False):
# We can assume that ipywidgets will not be *added* to the system
# during the course of execution, and if it is, we will not wrap the
# array.
if display_array and find_spec("ipywidgets") is not None:
self.display_array = True
else:
self.display_array = False
self.display_array = display_array and IPYWIDGETS_ENABLED

def __get__(self, instance, owner):
return self.data.get(instance, None)
Expand Down
120 changes: 66 additions & 54 deletions yt/fields/field_type_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import weakref
from functools import cached_property

from yt._maintenance.ipython_compat import IPYWIDGETS_ENABLED
from yt.fields.derived_field import DerivedField


Expand Down Expand Up @@ -59,22 +60,24 @@ def __contains__(self, obj):

return ob in self.field_types

def _ipython_display_(self):
import ipywidgets
from IPython.display import display
if IPYWIDGETS_ENABLED:

fnames = []
children = []
for ftype in sorted(self.field_types):
fnc = getattr(self, ftype)
children.append(ipywidgets.Output())
with children[-1]:
display(fnc)
fnames.append(ftype)
tabs = ipywidgets.Tab(children=children)
for i, n in enumerate(fnames):
tabs.set_title(i, n)
display(tabs)
def _ipython_display_(self):
import ipywidgets
from IPython.display import display

fnames = []
children = []
for ftype in sorted(self.field_types):
fnc = getattr(self, ftype)
children.append(ipywidgets.Output())
with children[-1]:
display(fnc)
fnames.append(ftype)
tabs = ipywidgets.Tab(children=children)
for i, n in enumerate(fnames):
tabs.set_title(i, n)
display(tabs)


class FieldNameContainer:
Expand Down Expand Up @@ -112,46 +115,55 @@ def __contains__(self, obj):
return True
return False

def _ipython_display_(self):
import ipywidgets
from IPython.display import Markdown, display

names = dir(self)
names.sort()

def change_field(_ftype, _box, _var_window):
def _change_field(event):
fobj = getattr(_ftype, event["new"])
_box.clear_output()
with _box:
display(
Markdown(
data="```python\n"
+ textwrap.dedent(fobj.get_source())
+ "\n```"
if IPYWIDGETS_ENABLED:
# for discussion of this class-level conditional: https://github.com/yt-project/yt/pull/4941

def _ipython_display_(self):
import ipywidgets
from IPython.display import Markdown, display

names = dir(self)
names.sort()

def change_field(_ftype, _box, _var_window):
def _change_field(event):
fobj = getattr(_ftype, event["new"])
_box.clear_output()
with _box:
display(
Markdown(
data="```python\n"
+ textwrap.dedent(fobj.get_source())
+ "\n```"
)
)
)
values = inspect.getclosurevars(fobj._function).nonlocals
_var_window.value = _fill_values(values)
values = inspect.getclosurevars(fobj._function).nonlocals
_var_window.value = _fill_values(values)

return _change_field
return _change_field

flist = ipywidgets.Select(options=names, layout=ipywidgets.Layout(height="95%"))
source = ipywidgets.Output(layout=ipywidgets.Layout(width="100%", height="9em"))
var_window = ipywidgets.HTML(value="Empty")
var_box = ipywidgets.Box(
layout=ipywidgets.Layout(width="100%", height="100%", overflow_y="scroll")
)
var_box.children = [var_window]
ftype_tabs = ipywidgets.Tab(
children=[source, var_box],
layout=ipywidgets.Layout(flex="2 1 auto", width="auto", height="95%"),
)
ftype_tabs.set_title(0, "Source")
ftype_tabs.set_title(1, "Variables")
flist.observe(change_field(self, source, var_window), "value")
display(
ipywidgets.HBox(
[flist, ftype_tabs], layout=ipywidgets.Layout(height="14em")
flist = ipywidgets.Select(
options=names, layout=ipywidgets.Layout(height="95%")
)
source = ipywidgets.Output(
layout=ipywidgets.Layout(width="100%", height="9em")
)
var_window = ipywidgets.HTML(value="Empty")
var_box = ipywidgets.Box(
layout=ipywidgets.Layout(
width="100%", height="100%", overflow_y="scroll"
)
)
var_box.children = [var_window]
ftype_tabs = ipywidgets.Tab(
children=[source, var_box],
layout=ipywidgets.Layout(flex="2 1 auto", width="auto", height="95%"),
)
ftype_tabs.set_title(0, "Source")
ftype_tabs.set_title(1, "Variables")
flist.observe(change_field(self, source, var_window), "value")
display(
ipywidgets.HBox(
[flist, ftype_tabs], layout=ipywidgets.Layout(height="14em")
)
)
)
4 changes: 2 additions & 2 deletions yt/funcs.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import base64
import builtins
import contextlib
import copy
import errno
Expand All @@ -24,6 +23,7 @@
from more_itertools import always_iterable, collapse, first

from yt._maintenance.deprecation import issue_deprecation_warning
from yt._maintenance.ipython_compat import IS_IPYTHON
from yt.config import ytcfg
from yt.units import YTArray, YTQuantity
from yt.utilities.exceptions import YTFieldNotFound, YTInvalidWidthError
Expand Down Expand Up @@ -1023,7 +1023,7 @@ def toggle_interactivity():
global interactivity
interactivity = not interactivity
if interactivity:
if "__IPYTHON__" in dir(builtins):
if IS_IPYTHON:
import IPython

shell = IPython.get_ipython()
Expand Down
5 changes: 2 additions & 3 deletions yt/visualization/image_writer.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import builtins

import numpy as np

from yt._maintenance.ipython_compat import IS_IPYTHON
from yt.config import ytcfg
from yt.funcs import mylog
from yt.units.yt_array import YTQuantity
Expand Down Expand Up @@ -418,7 +417,7 @@ def display_in_notebook(image, max_val=None):
three channels.
"""

if "__IPYTHON__" in dir(builtins):
if IS_IPYTHON:
from IPython.core.displaypub import publish_display_data

data = write_bitmap(image, None, max_val=max_val)
Expand Down
4 changes: 2 additions & 2 deletions yt/visualization/plot_container.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import abc
import base64
import builtins
import os
import warnings
from collections import defaultdict
Expand All @@ -12,6 +11,7 @@
from unyt.dimensions import length

from yt._maintenance.deprecation import issue_deprecation_warning
from yt._maintenance.ipython_compat import IS_IPYTHON
from yt._typing import FieldKey, Quantity
from yt.config import ytcfg
from yt.data_objects.time_series import DatasetSeries
Expand Down Expand Up @@ -634,7 +634,7 @@ def show(self):
for v in sorted(self.plots.values()):
v.show()
else:
if "__IPYTHON__" in dir(builtins):
if IS_IPYTHON:
from IPython.display import display

display(self)
Expand Down
4 changes: 2 additions & 2 deletions yt/visualization/profile_plotter.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import base64
import builtins
import os
from collections.abc import Iterable
from functools import wraps
Expand All @@ -9,6 +8,7 @@
import numpy as np
from more_itertools.more import always_iterable, unzip

from yt._maintenance.ipython_compat import IS_IPYTHON
from yt._typing import FieldKey
from yt.data_objects.profiles import create_profile, sanitize_field_tuple_keys
from yt.data_objects.static_output import Dataset
Expand Down Expand Up @@ -342,7 +342,7 @@ def show(self):
>>> pp.show()
"""
if "__IPYTHON__" in dir(builtins):
if IS_IPYTHON:
from IPython.display import display

display(self)
Expand Down
4 changes: 2 additions & 2 deletions yt/visualization/volume_rendering/old_camera.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import builtins
import sys
from copy import deepcopy

import numpy as np

from yt._maintenance.ipython_compat import IS_IPYTHON
from yt.config import ytcfg
from yt.data_objects.api import ImageArray
from yt.funcs import ensure_numpy_array, get_num_threads, get_pbar, is_sequence, mylog
Expand Down Expand Up @@ -900,7 +900,7 @@ def show(self, clip_ratio=None):
>>> cam.show()
"""
if "__IPYTHON__" in dir(builtins):
if IS_IPYTHON:
from IPython.core.displaypub import publish_display_data

image = self.snapshot()[:, :, :3]
Expand Down
4 changes: 2 additions & 2 deletions yt/visualization/volume_rendering/scene.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import builtins
import functools
from collections import OrderedDict
from typing import Optional, Union

import numpy as np

from yt._maintenance.ipython_compat import IS_IPYTHON
from yt.config import ytcfg
from yt.funcs import mylog
from yt.units.dimensions import length # type: ignore
Expand Down Expand Up @@ -909,7 +909,7 @@ def show(self, sigma_clip=None):
>>> sc.show()
"""
if "__IPYTHON__" in dir(builtins):
if IS_IPYTHON:
from IPython.display import display

self._sigma_clip = sigma_clip
Expand Down

0 comments on commit f39ed50

Please sign in to comment.