Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
31b73ce
Added backslashes to descriptions with '[][]'
daexs Aug 12, 2025
fae9563
Fixed markdown formatting for valType 'info_array'
daexs Aug 14, 2025
f345aef
Fixed double bracket error for regular expressions
daexs Aug 14, 2025
f840f11
Minor code cleanup
daexs Aug 14, 2025
4a7873c
Fixed double bracket error in 'basedatatypes.py'
daexs Aug 14, 2025
b0cd2f9
Merge branch 'mkdocs-conversion' of https://github.com/plotly/plotly.…
daexs Aug 14, 2025
cd623aa
Regenerated code after basevalidators.py changes
daexs Aug 14, 2025
98fab98
Fix SyntaxWarning and adjusted valType 'enumerated' docstring format.
daexs Aug 14, 2025
9ddde0f
Fixed formatting issues with nested enumerated docstrings in info_arr…
daexs Aug 15, 2025
683643c
Fixed list format in 'Dash' and 'String' properties.
daexs Aug 18, 2025
efde201
Fixed formatting for 'Compound' and 'color' properties.
daexs Aug 18, 2025
01da1c6
Fixed formatting for 'Integer' types.
daexs Aug 18, 2025
8d12a05
Fixed formatting for 'Colorscale', 'CompoundArray', and 'BaseData' ty…
daexs Aug 19, 2025
6690116
Fixed confusing indentation & some formatting
daexs Aug 19, 2025
4154910
Fixed formatting issues and consistency
daexs Aug 19, 2025
df9cc3a
feat: allow `--schema path` option to code generation
gvwilson Aug 20, 2025
77d19bb
Merge pull request #17 from gvwilson/mkdocs-conversion
daexs Aug 20, 2025
bdd049b
Fixed code block and type annotation formatting.
daexs Aug 21, 2025
cbd983d
Minor code cleanup
daexs Aug 21, 2025
95ea818
Fixed example parsing error
daexs Aug 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
135 changes: 75 additions & 60 deletions _plotly_utils/basevalidators.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ def fullmatch(regex, string, flags=0):
regex_string = regex
return re.match("(?:" + regex_string + r")\Z", string, flags=flags)

# Constants
INDENT = 8
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice :-)



# Utility functions
# -----------------
Expand Down Expand Up @@ -523,7 +526,9 @@ def description(self):
enum_regexs = []
for v, regex in zip(self.values, self.val_regexs):
if regex is not None:
enum_regexs.append(regex.pattern)
enum_pattern = regex.pattern
escaped_pattern = enum_pattern.replace("[", r"\[").replace("]", r"\]")
enum_regexs.append(escaped_pattern)
else:
enum_vals.append(v)
desc = """\
Expand All @@ -535,41 +540,42 @@ def description(self):
enum_vals_str = "\n".join(
textwrap.wrap(
repr(enum_vals),
initial_indent=" " * 12,
subsequent_indent=" " * 12,
initial_indent=" " * INDENT,
subsequent_indent=" " * INDENT,
break_on_hyphens=False,
)
)

desc = (
desc
+ """
- One of the following enumeration values:
+ """\n
- One of the following enumeration values:\n
{enum_vals_str}""".format(enum_vals_str=enum_vals_str)
)

if enum_regexs:
enum_regexs_str = "\n".join(
textwrap.wrap(
repr(enum_regexs),
initial_indent=" " * 12,
subsequent_indent=" " * 12,
initial_indent=" " * INDENT,
subsequent_indent=" " * INDENT,
break_on_hyphens=False,
break_long_words=False,
)
)

desc = (
desc
+ """
- A string that matches one of the following regular expressions:
+ """\n
- A string that matches one of the following regular expressions:\n
{enum_regexs_str}""".format(enum_regexs_str=enum_regexs_str)
)

if self.array_ok:
desc = (
desc
+ """
- A tuple, list, or one-dimensional numpy array of the above"""
+ """\n
- A tuple, list, or one-dimensional numpy array of the above"""
)

return desc
Expand Down Expand Up @@ -724,23 +730,23 @@ def description(self):
desc = (
desc
+ """\n
- An int or float"""
- An int or float"""
)

else:
desc = (
desc
+ """
- An int or float in the interval [{min_val}, {max_val}]""".format(
+ """\n
- An int or float in the interval [{min_val}, {max_val}]""".format(
min_val=self.min_val, max_val=self.max_val
)
)

if self.array_ok:
desc = (
desc
+ """
- A tuple, list, or one-dimensional numpy array of the above"""
+ """\n
- A tuple, list, or one-dimensional numpy array of the above"""
)

return desc
Expand Down Expand Up @@ -853,20 +859,20 @@ def __init__(

def description(self):
desc = """\
The '{plotly_name}' property is a integer and may be specified as:""".format(
The '{plotly_name}' property is a integer and may be specified as:\n""".format(
plotly_name=self.plotly_name
)

if not self.has_min_max:
desc = (
desc
+ """
- An int (or float that will be cast to an int)"""
- An int (or float that will be cast to an int)"""
)
else:
desc = desc + (
"""
- An int (or float that will be cast to an int)
- An int (or float that will be cast to an int)
in the interval [{min_val}, {max_val}]""".format(
min_val=self.min_val, max_val=self.max_val
)
Expand Down Expand Up @@ -1007,44 +1013,44 @@ def description(self):
if self.no_blank:
desc = (
desc
+ """
- A non-empty string"""
+ """\n
- A non-empty string"""
)
elif self.values:
valid_str = "\n".join(
textwrap.wrap(
repr(self.values),
initial_indent=" " * 12,
subsequent_indent=" " * 12,
initial_indent=" " * INDENT,
subsequent_indent=" " * INDENT,
break_on_hyphens=False,
)
)

desc = (
desc
+ """
- One of the following strings:
+ """\n
- One of the following strings:
{valid_str}""".format(valid_str=valid_str)
)
else:
desc = (
desc
+ """
- A string"""
+ """\n
- A string"""
)

if not self.strict:
desc = (
desc
+ """
- A number that will be converted to a string"""
+ """\n
- A number that will be converted to a string"""
)

if self.array_ok:
desc = (
desc
+ """
- A tuple, list, or one-dimensional numpy array of the above"""
+ """\n
- A tuple, list, or one-dimensional numpy array of the above"""
)

return desc
Expand Down Expand Up @@ -1311,27 +1317,28 @@ def numbers_allowed(self):
def description(self):
valid_color_description = """\
The '{plotly_name}' property is a color and may be specified as:
- A hex string (e.g. '#ff0000')
- An rgb/rgba string (e.g. 'rgb(255,0,0)')
- An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
- An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
- A named CSS color: see https://plotly.com/python/css-colors/ for a list""".format(

- A hex string (e.g. '#ff0000')
- An rgb/rgba string (e.g. 'rgb(255,0,0)')
- An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
- An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
- A named CSS color: see https://plotly.com/python/css-colors/ for a list""".format(
plotly_name=self.plotly_name
)

if self.colorscale_path:
valid_color_description = (
valid_color_description
+ """
- A number that will be interpreted as a color
according to {colorscale_path}""".format(colorscale_path=self.colorscale_path)
)
- A number that will be interpreted as a color according to {colorscale_path}""".format(
colorscale_path=self.colorscale_path)
)

if self.array_ok:
valid_color_description = (
valid_color_description
+ """
- A list or array of any of the above"""
- A list or array of any of the above"""
)

return valid_color_description
Expand Down Expand Up @@ -1989,10 +1996,12 @@ def description(self):

for i, item_validator in enumerate(self.item_validators):
el_desc = item_validator.description().strip()
lines = el_desc.splitlines()
el_desc_indented = '\n'.join([lines[0]] + [' ' + line for line in lines[1:]])
desc = (
desc
+ """\n
({i}) {el_desc}""".format(i=i, el_desc=el_desc)
({i}) {el_desc_indented}""".format(i=i, el_desc_indented=el_desc_indented)
)

# ### Case 2 ###
Expand All @@ -2005,7 +2014,7 @@ def description(self):
for i, item_validator in enumerate(self.item_validators):
# Update name for 2d
orig_name = item_validator.plotly_name
item_validator.plotly_name = "{name}\\[i\\]\\[{i}\\]".format(
item_validator.plotly_name = "{name}\\\\[i\\\\]\\\\[{i}\\\\]".format(
name=self.plotly_name, i=i
)

Expand All @@ -2027,21 +2036,28 @@ def description(self):

el_desc = item_validator.description().strip()

desc += """
* a list of elements where:
{el_desc}
""".format(el_desc=el_desc)
# Adds an indentation of 4 spaces, especially when el_desc
# is a fully auto-generated docstring with nested lists.
lines = el_desc.splitlines()
el_desc_indented = '\n'.join([lines[0]] + [' ' + line for line in lines[1:]])

desc += """\n
* a list of elements where:\n
{el_desc_indented}
""".format(el_desc_indented=el_desc_indented)

if self.dimensions in ("1-2", 2):
item_validator.plotly_name = "{name}\\[i\\]\\[j\\]".format(
item_validator.plotly_name = "{name}\\\\[i\\\\]\\\\[j\\\\]".format(
name=self.plotly_name
)

el_desc = item_validator.description().strip()
lines = el_desc.splitlines()
el_desc_indented = '\n'.join([lines[0]] + [' ' + line for line in lines[1:]])
desc += """\n
* a 2D list where:\n
{el_desc}
""".format(el_desc=el_desc)
{el_desc_indented}
""".format(el_desc_indented=el_desc_indented)

item_validator.plotly_name = orig_name

Expand Down Expand Up @@ -2272,25 +2288,25 @@ def description(self):
enum_vals_str = "\n".join(
textwrap.wrap(
repr(enum_vals),
initial_indent=" " * 12,
subsequent_indent=" " * 12,
initial_indent=" " * INDENT,
subsequent_indent=" " * INDENT,
break_on_hyphens=False,
width=80,
)
)

desc = (
desc
+ """
- One of the following dash styles:
+ """\n
- One of the following dash styles:\n
{enum_vals_str}""".format(enum_vals_str=enum_vals_str)
)

desc = (
desc
+ """
- A string containing a dash length list in pixels or percentages
(e.g. '5px 10px 2px 2px', '5, 10, 2, 2', '10% 20% 40%', etc.)
+ """\n
- A string containing a dash length list in pixels or percentages\n
(e.g. '5px 10px 2px 2px', '5, 10, 2, 2', '10% 20% 40%', etc.)
"""
)
return desc
Expand Down Expand Up @@ -2404,10 +2420,9 @@ def description(self):
desc = (
"""\
The '{plotly_name}' property is an instance of {class_str}
that may be specified as:
- An instance of :class:`{module_str}.{class_str}`
- A dict of string/value properties that will be passed
to the {class_str} constructor"""
that may be specified as:\n
- An instance of :class:`{module_str}.{class_str}`
- A dict of string/value properties that will be passed to the {class_str} constructor"""
).format(
plotly_name=self.plotly_name,
class_str=self.data_class_str,
Expand Down
8 changes: 4 additions & 4 deletions plotly/basedatatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4741,10 +4741,10 @@ def __getitem__(self, prop):
property is returned.

If prop is a nested property path string (e.g. 'foo[1].bar'),
then a nested property is returned (e.g. obj['foo'][1]['bar'])
then a nested property is returned (e.g. obj\\['foo'\\]\\[1\\]\\['bar'\\])

If prop is a path tuple (e.g. ('foo', 1, 'bar')), then a nested
property is returned (e.g. obj['foo'][1]['bar']).
property is returned (e.g. obj\\['foo'\\]\\[1\\]\\['bar'\\]).

Returns
-------
Expand Down Expand Up @@ -4836,11 +4836,11 @@ def __contains__(self, prop):

If prop is a property path string (e.g. 'foo[0].bar'),
then return true if the obejct contains the nested elements for
each entry in the path string (e.g. 'bar' in obj['foo'][0])
each entry in the path string (e.g. 'bar' in obj\\['foo'\\]\\[0\\])

If prop is a property path tuple (e.g. ('foo', 0, 'bar')),
then return true if the object contains the nested elements for
each entry in the path string (e.g. 'bar' in obj['foo'][0])
each entry in the path string (e.g. 'bar' in obj\\['foo'\\]\\[0\\])

Returns
-------
Expand Down
Loading