Skip to content

Commit

Permalink
Attempt to handle lack of __dict__ on TypeVar in Python 3.12
Browse files Browse the repository at this point in the history
  • Loading branch information
mwaskom committed Jan 16, 2024
1 parent 7e4431c commit 3232421
Showing 1 changed file with 22 additions and 10 deletions.
32 changes: 22 additions & 10 deletions synchronicity/synchronizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,12 +243,17 @@ def _translate_scalar_out(self, obj, interface):
interface = Interface.BLOCKING

# If it's an internal object, translate it to the external interface
if inspect.isclass(obj) or isinstance(obj, typing.TypeVar): # TODO: functions?
if inspect.isclass(obj): # TODO: functions?
cls_dct = obj.__dict__
if self._wrapped_attr in cls_dct:
return cls_dct[self._wrapped_attr][interface]
else:
return obj
elif isinstance(obj, typing.TypeVar):
if hasattr(obj, self._wrapped_attr):
return getattr(obj, self._wrapped_attr)[interface]
else:
return obj
else:
cls_dct = obj.__class__.__dict__
if self._wrapped_attr in cls_dct:
Expand Down Expand Up @@ -620,16 +625,22 @@ def _wrap(
# It wraps the object, and caches the wrapped object

# Get the list of existing interfaces
if self._wrapped_attr not in obj.__dict__:
if isinstance(obj.__dict__, dict):
# This works for instances
obj.__dict__.setdefault(self._wrapped_attr, {})
else:
# This works for classes & functions
if hasattr(obj, "__dict__"):
if self._wrapped_attr not in obj.__dict__:
if isinstance(obj.__dict__, dict):
# This works for instances
obj.__dict__.setdefault(self._wrapped_attr, {})
else:
# This works for classes & functions
setattr(obj, self._wrapped_attr, {})
interfaces = obj.__dict__[self._wrapped_attr]
else:
# e.g., TypeVar in Python>=3.12
if not hasattr(obj, self._wrapped_attr):
setattr(obj, self._wrapped_attr, {})
interfaces = getattr(obj, self._wrapped_attr)

# If this is already wrapped, return the existing interface
interfaces = obj.__dict__[self._wrapped_attr]
if interface in interfaces:
if self._multiwrap_warning:
warnings.warn(f"Object {obj} is already wrapped, but getting wrapped again")
Expand Down Expand Up @@ -674,8 +685,9 @@ def _wrap_type_var(self, obj, interface, name, target_module):
new_obj.__dict__[SYNCHRONIZER_ATTR] = self
new_obj.__dict__[TARGET_INTERFACE_ATTR] = interface
new_obj.__module__ = target_module
obj.__dict__.setdefault(self._wrapped_attr, {})
obj.__dict__[self._wrapped_attr][interface] = new_obj
if not hasattr(obj, self._wrapped_attr):
setattr(obj, self._wrapped_attr, {})
getattr(obj, self._wrapped_attr)[interface] = new_obj
return new_obj

def nowrap(self, obj):
Expand Down

0 comments on commit 3232421

Please sign in to comment.