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

Replace global validate state with Figure level validate flag #2403

Merged
merged 9 commits into from
Apr 28, 2020
  •  
  •  
  •  
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