Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/python_api/sphinx_doc_gen.py72
-rw-r--r--release/scripts/modules/rna_info.py36
2 files changed, 97 insertions, 11 deletions
diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py
index ebaea669679..0d514e0694d 100644
--- a/doc/python_api/sphinx_doc_gen.py
+++ b/doc/python_api/sphinx_doc_gen.py
@@ -89,6 +89,16 @@ if USE_SHARED_RNA_ENUM_ITEMS_STATIC:
del rna_enum_dict[key]
del key, rna_enum_items_static
+ # Build enum `{pointer: identifier}` map, so any enum property pointer can
+ # lookup an identifier using `InfoPropertyRNA.enum_pointer` as the key.
+ rna_enum_pointer_to_id_map = {
+ enum_prop.as_pointer(): key
+ for key, enum_items in rna_enum_dict.items()
+ # It's possible the first item is a heading (which has no identifier).
+ # skip these as the `EnumProperty.enum_items` does not expose them.
+ if (enum_prop := next(iter(enum_prop for enum_prop in enum_items if enum_prop.identifier), None))
+ }
+
def handle_args():
"""
@@ -1231,15 +1241,23 @@ def pycontext2sphinx(basepath):
# No need to check if there are duplicates yet as it's known there wont be.
unique.add(prop.identifier)
+ enum_descr_override = None
+ if USE_SHARED_RNA_ENUM_ITEMS_STATIC:
+ enum_descr_override = pyrna_enum2sphinx_shared_link(prop)
+
type_descr = prop.get_type_description(
- class_fmt=":class:`bpy.types.%s`", collection_id=_BPY_PROP_COLLECTION_ID)
+ class_fmt=":class:`bpy.types.%s`",
+ collection_id=_BPY_PROP_COLLECTION_ID,
+ enum_descr_override=enum_descr_override,
+ )
fw(".. data:: %s\n\n" % prop.identifier)
if prop.description:
fw(" %s\n\n" % prop.description)
# Special exception, can't use generic code here for enums.
if prop.type == "enum":
- enum_text = pyrna_enum2sphinx(prop)
+ # If the link has been written, no need to inline the enum items.
+ enum_text = "" if enum_descr_override else pyrna_enum2sphinx(prop)
if enum_text:
write_indented_lines(" ", fw, enum_text)
fw("\n")
@@ -1301,6 +1319,11 @@ def pyrna_enum2sphinx(prop, use_empty_descriptions=False):
Write a bullet point list of enum + descriptions.
"""
+ # Write a link to the enum if this is part of `rna_enum_pointer_map`.
+ if USE_SHARED_RNA_ENUM_ITEMS_STATIC:
+ if (result := pyrna_enum2sphinx_shared_link(prop)) is not None:
+ return result
+
if use_empty_descriptions:
ok = True
else:
@@ -1379,10 +1402,15 @@ def pyrna2sphinx(basepath):
kwargs["collection_id"] = _BPY_PROP_COLLECTION_ID
- type_descr = prop.get_type_description(**kwargs)
+ enum_descr_override = None
+ if USE_SHARED_RNA_ENUM_ITEMS_STATIC:
+ enum_descr_override = pyrna_enum2sphinx_shared_link(prop)
+ kwargs["enum_descr_override"] = enum_descr_override
- enum_text = pyrna_enum2sphinx(prop)
+ type_descr = prop.get_type_description(**kwargs)
+ # If the link has been written, no need to inline the enum items.
+ enum_text = "" if enum_descr_override else pyrna_enum2sphinx(prop)
if prop.name or prop.description or enum_text:
fw(ident + ":%s%s:\n\n" % (id_name, identifier))
@@ -1483,7 +1511,15 @@ def pyrna2sphinx(basepath):
if identifier in struct_blacklist:
continue
- type_descr = prop.get_type_description(class_fmt=":class:`%s`", collection_id=_BPY_PROP_COLLECTION_ID)
+ enum_descr_override = None
+ if USE_SHARED_RNA_ENUM_ITEMS_STATIC:
+ enum_descr_override = pyrna_enum2sphinx_shared_link(prop)
+
+ type_descr = prop.get_type_description(
+ class_fmt=":class:`%s`",
+ collection_id=_BPY_PROP_COLLECTION_ID,
+ enum_descr_override=enum_descr_override,
+ )
# Read-only properties use "data" directive, variables properties use "attribute" directive.
if "readonly" in type_descr:
fw(" .. data:: %s\n" % identifier)
@@ -1500,7 +1536,8 @@ def pyrna2sphinx(basepath):
# Special exception, can't use generic code here for enums.
if prop.type == "enum":
- enum_text = pyrna_enum2sphinx(prop)
+ # If the link has been written, no need to inline the enum items.
+ enum_text = "" if enum_descr_override else pyrna_enum2sphinx(prop)
if enum_text:
write_indented_lines(" ", fw, enum_text)
fw("\n")
@@ -1539,8 +1576,16 @@ def pyrna2sphinx(basepath):
for prop in func.return_values:
# TODO: pyrna_enum2sphinx for multiple return values... actually don't
# think we even use this but still!
+
+ enum_descr_override = None
+ if USE_SHARED_RNA_ENUM_ITEMS_STATIC:
+ enum_descr_override = pyrna_enum2sphinx_shared_link(prop)
+
type_descr = prop.get_type_description(
- as_ret=True, class_fmt=":class:`%s`", collection_id=_BPY_PROP_COLLECTION_ID)
+ as_ret=True, class_fmt=":class:`%s`",
+ collection_id=_BPY_PROP_COLLECTION_ID,
+ enum_descr_override=enum_descr_override,
+ )
descr = prop.description
if not descr:
descr = prop.name
@@ -2067,6 +2112,19 @@ def write_rst_data(basepath):
EXAMPLE_SET_USED.add("bpy.data")
+def pyrna_enum2sphinx_shared_link(prop):
+ """
+ Return a reference to the enum used by ``prop`` or None when not found.
+ """
+ if (
+ (prop.type == "enum") and
+ (pointer := prop.enum_pointer) and
+ (identifier := rna_enum_pointer_to_id_map.get(pointer))
+ ):
+ return ":ref:`%s`" % identifier
+ return None
+
+
def write_rst_enum_items(basepath, key, key_no_prefix, enum_items):
"""
Write a single page for a static enum in RST.
diff --git a/release/scripts/modules/rna_info.py b/release/scripts/modules/rna_info.py
index 04120508df5..4788ed6a5fa 100644
--- a/release/scripts/modules/rna_info.py
+++ b/release/scripts/modules/rna_info.py
@@ -242,6 +242,7 @@ class InfoPropertyRNA:
"default_str",
"default",
"enum_items",
+ "enum_pointer",
"min",
"max",
"array_length",
@@ -285,9 +286,17 @@ class InfoPropertyRNA:
else:
self.fixed_type = None
+ self.enum_pointer = 0
if self.type == "enum":
- self.enum_items[:] = [(item.identifier, item.name, item.description) for item in rna_prop.enum_items]
+ items = tuple(rna_prop.enum_items)
+ items_static = tuple(rna_prop.enum_items_static)
+ self.enum_items[:] = [(item.identifier, item.name, item.description) for item in items]
self.is_enum_flag = rna_prop.is_enum_flag
+ # Prioritize static items as this is never going to be allocated data and is therefor
+ # will be a stable match to compare against.
+ item = (items_static or items)
+ if item:
+ self.enum_pointer = item[0].as_pointer()
else:
self.is_enum_flag = False
@@ -342,7 +351,19 @@ class InfoPropertyRNA:
return "%s=%s" % (self.identifier, default)
return self.identifier
- def get_type_description(self, as_ret=False, as_arg=False, class_fmt="%s", collection_id="Collection"):
+ def get_type_description(
+ self, *,
+ as_ret=False,
+ as_arg=False,
+ class_fmt="%s",
+ collection_id="Collection",
+ enum_descr_override=None,
+ ):
+ """
+ :arg enum_descr_override: Optionally override items for enum.
+ Otherwise expand the literal items.
+ :type enum_descr_override: string or None when unset.
+ """
type_str = ""
if self.fixed_type is None:
type_str += self.type
@@ -357,10 +378,17 @@ class InfoPropertyRNA:
if self.type in {"float", "int"}:
type_str += " in [%s, %s]" % (range_str(self.min), range_str(self.max))
elif self.type == "enum":
+ enum_descr = enum_descr_override
+ if not enum_descr:
+ if self.is_enum_flag:
+ enum_descr = "{%s}" % ", ".join(("'%s'" % s[0]) for s in self.enum_items)
+ else:
+ enum_descr = "[%s]" % ", ".join(("'%s'" % s[0]) for s in self.enum_items)
if self.is_enum_flag:
- type_str += " set in {%s}" % ", ".join(("'%s'" % s[0]) for s in self.enum_items)
+ type_str += " set in %s" % enum_descr
else:
- type_str += " in [%s]" % ", ".join(("'%s'" % s[0]) for s in self.enum_items)
+ type_str += " in %s" % enum_descr
+ del enum_descr
if not (as_arg or as_ret):
# write default property, ignore function args for this