Skip to content

Commit

Permalink
Merge pull request #2403 from plotly/figure_level_validate
Browse files Browse the repository at this point in the history
Replace global validate state with Figure level validate flag
  • Loading branch information
nicolaskruchten authored Apr 28, 2020
2 parents e778c6b + f8ae78d commit e882f85
Show file tree
Hide file tree
Showing 846 changed files with 883 additions and 45 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ This project adheres to [Semantic Versioning](http://semver.org/).
makes it possible to skip hover information for some arguments or to change
the formatting of hover informatiom [#2377](https://github.com/plotly/plotly.py/pull/2377).

### Performance
This version includes several performance improvements ([#2368](https://github.com/plotly/plotly.py/pull/2368), [#2403](https://github.com/plotly/plotly.py/pull/2403)).

- Child graph objects (e.g. `figure.layout.xaxis`) are no longer created eagerly during graph object construction. Instead, they are created lazily the first time the property is accessed.
- Property validation is now disabled for select internal operations.
- When used with Python 3.7 and above, ploty.py now takes advantage of [PEP-562](https://www.python.org/dev/peps/pep-0562/) to perform submodule imports lazily. This dramatically improves import times.

## [4.6] - 2020-03-31

### Updated
Expand Down
10 changes: 5 additions & 5 deletions packages/python/plotly/_plotly_utils/basevalidators.py
Original file line number Diff line number Diff line change
Expand Up @@ -2438,12 +2438,12 @@ def description(self):

return desc

def validate_coerce(self, v, skip_invalid=False):
def validate_coerce(self, v, skip_invalid=False, _validate=True):
if v is None:
v = self.data_class()

elif isinstance(v, dict):
v = self.data_class(v, skip_invalid=skip_invalid)
v = self.data_class(v, skip_invalid=skip_invalid, _validate=_validate)

elif isinstance(v, self.data_class):
# Copy object
Expand Down Expand Up @@ -2614,7 +2614,7 @@ def get_trace_class(self, trace_name):

return self._class_map[trace_name]

def validate_coerce(self, v, skip_invalid=False):
def validate_coerce(self, v, skip_invalid=False, _validate=True):
from plotly.basedatatypes import BaseTraceType

# Import Histogram2dcontour, this is the deprecated name of the
Expand Down Expand Up @@ -2649,15 +2649,15 @@ def validate_coerce(self, v, skip_invalid=False):
if skip_invalid:
# Treat as scatter trace
trace = self.get_trace_class("scatter")(
skip_invalid=skip_invalid, **v_copy
skip_invalid=skip_invalid, _validate=_validate, **v_copy
)
res.append(trace)
else:
res.append(None)
invalid_els.append(v_el)
else:
trace = self.get_trace_class(trace_type)(
skip_invalid=skip_invalid, **v_copy
skip_invalid=skip_invalid, _validate=_validate, **v_copy
)
res.append(trace)
else:
Expand Down
5 changes: 2 additions & 3 deletions packages/python/plotly/codegen/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,6 @@ def perform_codegen():
for dep_clas in DEPRECATED_DATATYPES:
root_datatype_imports.append(f"._deprecations.{dep_clas}")

validate_import = "from .._validate import validate\n"
optional_figure_widget_import = f"""
if sys.version_info < (3, 7):
try:
Expand Down Expand Up @@ -307,7 +306,7 @@ def __getattr__(import_name):
rel_classes = datatype_rel_class_imports[path_parts]
rel_modules = datatype_rel_module_imports.get(path_parts, [])
if path_parts == ():
init_extra = validate_import + optional_figure_widget_import
init_extra = optional_figure_widget_import
else:
init_extra = ""
write_init_py(graph_objs_pkg, path_parts, rel_modules, rel_classes, init_extra)
Expand All @@ -325,7 +324,7 @@ def __getattr__(import_name):
graph_objects_init_source = build_from_imports_py(
graph_objects_rel_modules,
graph_objects_rel_classes,
init_extra=validate_import + optional_figure_widget_import,
init_extra=optional_figure_widget_import,
)
graph_objects_path = opath.join(outdir, "graph_objects", "__init__.py")
os.makedirs(opath.join(outdir, "graph_objects"), exist_ok=True)
Expand Down
1 change: 1 addition & 0 deletions packages/python/plotly/codegen/datatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ def __init__(self"""
# Handle skip_invalid
# -------------------
self._skip_invalid = kwargs.pop('skip_invalid', False)
self._validate = kwargs.pop('_validate', True)
"""
)

Expand Down
12 changes: 0 additions & 12 deletions packages/python/plotly/plotly/_validate.py

This file was deleted.

35 changes: 28 additions & 7 deletions packages/python/plotly/plotly/basedatatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from copy import deepcopy, copy

from _plotly_utils.utils import _natural_sort_strings
from plotly._validate import validate
from .optional_imports import get_module

# Create Undefined sentinel value
Expand Down Expand Up @@ -92,6 +91,9 @@ class is a subclass of both BaseFigure and widgets.DOMWidget.

super(BaseFigure, self).__init__()

# Initialize validation
self._validate = kwargs.pop("_validate", True)

# Assign layout_plotly to layout
# ------------------------------
# See docstring note for explanation
Expand Down Expand Up @@ -140,7 +142,9 @@ class is a subclass of both BaseFigure and widgets.DOMWidget.
self._data_validator = DataValidator(set_uid=self._set_trace_uid)

# ### Import traces ###
data = self._data_validator.validate_coerce(data, skip_invalid=skip_invalid)
data = self._data_validator.validate_coerce(
data, skip_invalid=skip_invalid, _validate=self._validate
)

# ### Save tuple of trace objects ###
self._data_objs = data
Expand Down Expand Up @@ -182,7 +186,7 @@ class is a subclass of both BaseFigure and widgets.DOMWidget.

# ### Import Layout ###
self._layout_obj = self._layout_validator.validate_coerce(
layout, skip_invalid=skip_invalid
layout, skip_invalid=skip_invalid, _validate=self._validate
)

# ### Import clone of layout properties ###
Expand Down Expand Up @@ -314,6 +318,8 @@ def __setitem__(self, prop, value):
for p in prop[:-1]:
res = res[p]

res._validate = self._validate

res[prop[-1]] = value

def __setattr__(self, prop, value):
Expand Down Expand Up @@ -1940,10 +1946,13 @@ def _initialize_layout_template(self):

if self._layout_obj._props.get("template", None) is None:
if pio.templates.default is not None:
with validate(False):
# Assume default template is already validated
# Assume default template is already validated
self._layout_obj._validate = False
try:
template_dict = pio.templates[pio.templates.default]
self._layout_obj.template = template_dict
finally:
self._layout_obj._validate = self._validate

@property
def layout(self):
Expand Down Expand Up @@ -3339,6 +3348,8 @@ def __init__(self, plotly_name, **kwargs):
# invalid properties will result in an exception
self._skip_invalid = False

self._validate = True

# Validate inputs
# ---------------
self._process_kwargs(**kwargs)
Expand Down Expand Up @@ -3378,6 +3389,14 @@ def __init__(self, plotly_name, **kwargs):
# ### Backing property for backward compatible _validator property ##
self.__validators = None

# @property
# def _validate(self):
# fig = self.figure
# if fig is None:
# return True
# else:
# return fig._validate

def _get_validator(self, prop):
from .validator_cache import ValidatorCache

Expand Down Expand Up @@ -3425,7 +3444,7 @@ def _process_kwargs(self, **kwargs):
if k in self:
# e.g. underscore kwargs like marker_line_color
self[k] = v
elif not validate._should_validate:
elif not self._validate:
# Set extra property as-is
self[k] = v
else:
Expand Down Expand Up @@ -3885,7 +3904,7 @@ def __setitem__(self, prop, value):
# ### Unwrap scalar tuple ###
prop = prop[0]

if validate._should_validate:
if self._validate:
if prop not in self._valid_props:
self._raise_on_invalid_property_error(prop)

Expand Down Expand Up @@ -3937,6 +3956,8 @@ def __setitem__(self, prop, value):
for p in prop[:-1]:
res = res[p]

res._validate = self._validate

res[prop[-1]] = value

def __setattr__(self, prop, value):
Expand Down
1 change: 0 additions & 1 deletion packages/python/plotly/plotly/graph_objects/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,6 @@
],
)

from .._validate import validate

if sys.version_info < (3, 7):
try:
Expand Down
1 change: 0 additions & 1 deletion packages/python/plotly/plotly/graph_objs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,6 @@
],
)

from .._validate import validate

if sys.version_info < (3, 7):
try:
Expand Down
1 change: 1 addition & 0 deletions packages/python/plotly/plotly/graph_objs/_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,7 @@ def __init__(
# Handle skip_invalid
# -------------------
self._skip_invalid = kwargs.pop("skip_invalid", False)
self._validate = kwargs.pop("_validate", True)

# Populate data dict with properties
# ----------------------------------
Expand Down
1 change: 1 addition & 0 deletions packages/python/plotly/plotly/graph_objs/_bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -2649,6 +2649,7 @@ def __init__(
# Handle skip_invalid
# -------------------
self._skip_invalid = kwargs.pop("skip_invalid", False)
self._validate = kwargs.pop("_validate", True)

# Populate data dict with properties
# ----------------------------------
Expand Down
1 change: 1 addition & 0 deletions packages/python/plotly/plotly/graph_objs/_barpolar.py
Original file line number Diff line number Diff line change
Expand Up @@ -1664,6 +1664,7 @@ def __init__(
# Handle skip_invalid
# -------------------
self._skip_invalid = kwargs.pop("skip_invalid", False)
self._validate = kwargs.pop("_validate", True)

# Populate data dict with properties
# ----------------------------------
Expand Down
1 change: 1 addition & 0 deletions packages/python/plotly/plotly/graph_objs/_box.py
Original file line number Diff line number Diff line change
Expand Up @@ -2644,6 +2644,7 @@ def __init__(
# Handle skip_invalid
# -------------------
self._skip_invalid = kwargs.pop("skip_invalid", False)
self._validate = kwargs.pop("_validate", True)

# Populate data dict with properties
# ----------------------------------
Expand Down
1 change: 1 addition & 0 deletions packages/python/plotly/plotly/graph_objs/_candlestick.py
Original file line number Diff line number Diff line change
Expand Up @@ -1409,6 +1409,7 @@ def __init__(
# Handle skip_invalid
# -------------------
self._skip_invalid = kwargs.pop("skip_invalid", False)
self._validate = kwargs.pop("_validate", True)

# Populate data dict with properties
# ----------------------------------
Expand Down
1 change: 1 addition & 0 deletions packages/python/plotly/plotly/graph_objs/_carpet.py
Original file line number Diff line number Diff line change
Expand Up @@ -1612,6 +1612,7 @@ def __init__(
# Handle skip_invalid
# -------------------
self._skip_invalid = kwargs.pop("skip_invalid", False)
self._validate = kwargs.pop("_validate", True)

# Populate data dict with properties
# ----------------------------------
Expand Down
1 change: 1 addition & 0 deletions packages/python/plotly/plotly/graph_objs/_choropleth.py
Original file line number Diff line number Diff line change
Expand Up @@ -1933,6 +1933,7 @@ def __init__(
# Handle skip_invalid
# -------------------
self._skip_invalid = kwargs.pop("skip_invalid", False)
self._validate = kwargs.pop("_validate", True)

# Populate data dict with properties
# ----------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1926,6 +1926,7 @@ def __init__(
# Handle skip_invalid
# -------------------
self._skip_invalid = kwargs.pop("skip_invalid", False)
self._validate = kwargs.pop("_validate", True)

# Populate data dict with properties
# ----------------------------------
Expand Down
1 change: 1 addition & 0 deletions packages/python/plotly/plotly/graph_objs/_cone.py
Original file line number Diff line number Diff line change
Expand Up @@ -2160,6 +2160,7 @@ def __init__(
# Handle skip_invalid
# -------------------
self._skip_invalid = kwargs.pop("skip_invalid", False)
self._validate = kwargs.pop("_validate", True)

# Populate data dict with properties
# ----------------------------------
Expand Down
1 change: 1 addition & 0 deletions packages/python/plotly/plotly/graph_objs/_contour.py
Original file line number Diff line number Diff line change
Expand Up @@ -2444,6 +2444,7 @@ def __init__(
# Handle skip_invalid
# -------------------
self._skip_invalid = kwargs.pop("skip_invalid", False)
self._validate = kwargs.pop("_validate", True)

# Populate data dict with properties
# ----------------------------------
Expand Down
1 change: 1 addition & 0 deletions packages/python/plotly/plotly/graph_objs/_contourcarpet.py
Original file line number Diff line number Diff line change
Expand Up @@ -2056,6 +2056,7 @@ def __init__(
# Handle skip_invalid
# -------------------
self._skip_invalid = kwargs.pop("skip_invalid", False)
self._validate = kwargs.pop("_validate", True)

# Populate data dict with properties
# ----------------------------------
Expand Down
1 change: 1 addition & 0 deletions packages/python/plotly/plotly/graph_objs/_densitymapbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -1874,6 +1874,7 @@ def __init__(
# Handle skip_invalid
# -------------------
self._skip_invalid = kwargs.pop("skip_invalid", False)
self._validate = kwargs.pop("_validate", True)

# Populate data dict with properties
# ----------------------------------
Expand Down
1 change: 1 addition & 0 deletions packages/python/plotly/plotly/graph_objs/_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ def __init__(
# Handle skip_invalid
# -------------------
self._skip_invalid = kwargs.pop("skip_invalid", False)
self._validate = kwargs.pop("_validate", True)

# Populate data dict with properties
# ----------------------------------
Expand Down
1 change: 1 addition & 0 deletions packages/python/plotly/plotly/graph_objs/_funnel.py
Original file line number Diff line number Diff line change
Expand Up @@ -2192,6 +2192,7 @@ def __init__(
# Handle skip_invalid
# -------------------
self._skip_invalid = kwargs.pop("skip_invalid", False)
self._validate = kwargs.pop("_validate", True)

# Populate data dict with properties
# ----------------------------------
Expand Down
1 change: 1 addition & 0 deletions packages/python/plotly/plotly/graph_objs/_funnelarea.py
Original file line number Diff line number Diff line change
Expand Up @@ -1689,6 +1689,7 @@ def __init__(
# Handle skip_invalid
# -------------------
self._skip_invalid = kwargs.pop("skip_invalid", False)
self._validate = kwargs.pop("_validate", True)

# Populate data dict with properties
# ----------------------------------
Expand Down
1 change: 1 addition & 0 deletions packages/python/plotly/plotly/graph_objs/_heatmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -2242,6 +2242,7 @@ def __init__(
# Handle skip_invalid
# -------------------
self._skip_invalid = kwargs.pop("skip_invalid", False)
self._validate = kwargs.pop("_validate", True)

# Populate data dict with properties
# ----------------------------------
Expand Down
1 change: 1 addition & 0 deletions packages/python/plotly/plotly/graph_objs/_heatmapgl.py
Original file line number Diff line number Diff line change
Expand Up @@ -1750,6 +1750,7 @@ def __init__(
# Handle skip_invalid
# -------------------
self._skip_invalid = kwargs.pop("skip_invalid", False)
self._validate = kwargs.pop("_validate", True)

# Populate data dict with properties
# ----------------------------------
Expand Down
1 change: 1 addition & 0 deletions packages/python/plotly/plotly/graph_objs/_histogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -2242,6 +2242,7 @@ def __init__(
# Handle skip_invalid
# -------------------
self._skip_invalid = kwargs.pop("skip_invalid", False)
self._validate = kwargs.pop("_validate", True)

# Populate data dict with properties
# ----------------------------------
Expand Down
1 change: 1 addition & 0 deletions packages/python/plotly/plotly/graph_objs/_histogram2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -2393,6 +2393,7 @@ def __init__(
# Handle skip_invalid
# -------------------
self._skip_invalid = kwargs.pop("skip_invalid", False)
self._validate = kwargs.pop("_validate", True)

# Populate data dict with properties
# ----------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2529,6 +2529,7 @@ def __init__(
# Handle skip_invalid
# -------------------
self._skip_invalid = kwargs.pop("skip_invalid", False)
self._validate = kwargs.pop("_validate", True)

# Populate data dict with properties
# ----------------------------------
Expand Down
Loading

0 comments on commit e882f85

Please sign in to comment.