Simplify @pyside_cache decorator
This fixes a compatibility issue with Python 3.9+, and at the same time avoids a not-yet-quite-stable area of Blender's Python API.
This commit is contained in:
parent
ce331c7b22
commit
3a2e9bc672
@ -1,5 +1,9 @@
|
|||||||
# Blender Cloud changelog
|
# Blender Cloud changelog
|
||||||
|
|
||||||
|
## Version 1.19 (in development)
|
||||||
|
|
||||||
|
- Another Python 3.9+ compatibility fix.
|
||||||
|
|
||||||
## Version 1.18 (2021-02-16)
|
## Version 1.18 (2021-02-16)
|
||||||
|
|
||||||
- Add compatibility with Python 3.9 (as used in Blender 2.93).
|
- Add compatibility with Python 3.9 (as used in Blender 2.93).
|
||||||
|
@ -47,7 +47,7 @@ log = logging.getLogger(__name__)
|
|||||||
icons = None
|
icons = None
|
||||||
|
|
||||||
|
|
||||||
@pyside_cache("version")
|
@pyside_cache
|
||||||
def blender_syncable_versions(self, context):
|
def blender_syncable_versions(self, context):
|
||||||
"""Returns the list of items used by SyncStatusProperties.version EnumProperty."""
|
"""Returns the list of items used by SyncStatusProperties.version EnumProperty."""
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ class SyncStatusProperties(PropertyGroup):
|
|||||||
self["available_blender_versions"] = new_versions
|
self["available_blender_versions"] = new_versions
|
||||||
|
|
||||||
|
|
||||||
@pyside_cache("project")
|
@pyside_cache
|
||||||
def bcloud_available_projects(self, context):
|
def bcloud_available_projects(self, context):
|
||||||
"""Returns the list of items used by BlenderCloudProjectGroup.project EnumProperty."""
|
"""Returns the list of items used by BlenderCloudProjectGroup.project EnumProperty."""
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ def scene_sample_count(scene) -> int:
|
|||||||
return samples
|
return samples
|
||||||
|
|
||||||
|
|
||||||
@pyside_cache("manager")
|
@pyside_cache
|
||||||
def available_managers(self, context):
|
def available_managers(self, context):
|
||||||
"""Returns the list of items used by a manager-selector EnumProperty."""
|
"""Returns the list of items used by a manager-selector EnumProperty."""
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
import json
|
import json
|
||||||
import pathlib
|
import pathlib
|
||||||
import typing
|
import typing
|
||||||
|
from typing import Any, Dict, Optional, Tuple
|
||||||
|
|
||||||
|
|
||||||
def sizeof_fmt(num: int, suffix="B") -> str:
|
def sizeof_fmt(num: int, suffix="B") -> str:
|
||||||
@ -35,7 +36,7 @@ def sizeof_fmt(num: int, suffix="B") -> str:
|
|||||||
return "%.1f Yi%s" % (num, suffix)
|
return "%.1f Yi%s" % (num, suffix)
|
||||||
|
|
||||||
|
|
||||||
def find_in_path(path: pathlib.Path, filename: str) -> typing.Optional[pathlib.Path]:
|
def find_in_path(path: pathlib.Path, filename: str) -> Optional[pathlib.Path]:
|
||||||
"""Performs a breadth-first search for the filename.
|
"""Performs a breadth-first search for the filename.
|
||||||
|
|
||||||
Returns the path that contains the file, or None if not found.
|
Returns the path that contains the file, or None if not found.
|
||||||
@ -66,41 +67,29 @@ def find_in_path(path: pathlib.Path, filename: str) -> typing.Optional[pathlib.P
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def pyside_cache(propname):
|
# Mapping from (module name, function name) to the last value returned by that function.
|
||||||
|
_pyside_cache: Dict[Tuple[str, str], Any] = {}
|
||||||
|
|
||||||
|
|
||||||
|
def pyside_cache(wrapped):
|
||||||
"""Decorator, stores the result of the decorated callable in Python-managed memory.
|
"""Decorator, stores the result of the decorated callable in Python-managed memory.
|
||||||
|
|
||||||
This is to work around the warning at
|
This is to work around the warning at
|
||||||
https://www.blender.org/api/blender_python_api_master/bpy.props.html#bpy.props.EnumProperty
|
https://www.blender.org/api/blender_python_api_master/bpy.props.html#bpy.props.EnumProperty
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if callable(propname):
|
import functools
|
||||||
raise TypeError('Usage: pyside_cache("property_name")')
|
|
||||||
|
|
||||||
def decorator(wrapped):
|
@functools.wraps(wrapped)
|
||||||
"""Stores the result of the callable in Python-managed memory.
|
# We can't use (*args, **kwargs), because EnumProperty explicitly checks
|
||||||
|
# for the number of fixed positional arguments.
|
||||||
This is to work around the warning at
|
def decorator(self, context):
|
||||||
https://www.blender.org/api/blender_python_api_master/bpy.props.html#bpy.props.EnumProperty
|
result = None
|
||||||
"""
|
try:
|
||||||
|
result = wrapped(self, context)
|
||||||
import functools
|
return result
|
||||||
|
finally:
|
||||||
@functools.wraps(wrapped)
|
_pyside_cache[wrapped.__module__, wrapped.__name__] = result
|
||||||
# We can't use (*args, **kwargs), because EnumProperty explicitly checks
|
|
||||||
# for the number of fixed positional arguments.
|
|
||||||
def wrapper(self, context):
|
|
||||||
result = None
|
|
||||||
try:
|
|
||||||
result = wrapped(self, context)
|
|
||||||
return result
|
|
||||||
finally:
|
|
||||||
try:
|
|
||||||
rna_type, rna_info = self.bl_rna.__annotations__[propname]
|
|
||||||
except AttributeError:
|
|
||||||
rna_type, rna_info = getattr(self.bl_rna, propname)
|
|
||||||
rna_info["_cached_result"] = result
|
|
||||||
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user