mirror of
https://github.com/esphome/esphome.git
synced 2025-09-10 07:12:21 +01:00
@@ -261,3 +261,51 @@ def file_compare(path1, path2):
|
||||
if not blob1:
|
||||
# Reached end
|
||||
return True
|
||||
|
||||
|
||||
# A dict of types that need to be converted to heaptypes before a class can be added
|
||||
# to the object
|
||||
_TYPE_OVERLOADS = {
|
||||
int: type('int', (int,), dict()),
|
||||
float: type('float', (float,), dict()),
|
||||
str: type('str', (str,), dict()),
|
||||
dict: type('dict', (str,), dict()),
|
||||
list: type('list', (list,), dict()),
|
||||
}
|
||||
|
||||
if IS_PY2:
|
||||
_TYPE_OVERLOADS[long] = type('long', (long,), dict())
|
||||
_TYPE_OVERLOADS[unicode] = type('unicode', (unicode,), dict())
|
||||
|
||||
# cache created classes here
|
||||
_CLASS_LOOKUP = {}
|
||||
|
||||
|
||||
def add_class_to_obj(value, cls):
|
||||
"""Add a class to a python type.
|
||||
|
||||
This function modifies value so that it has cls as a basetype.
|
||||
The value itself may be modified by this action! You must use the return
|
||||
value of this function however, since some types need to be copied first (heaptypes).
|
||||
"""
|
||||
if isinstance(value, cls):
|
||||
# If already is instance, do not add
|
||||
return value
|
||||
|
||||
try:
|
||||
orig_cls = value.__class__
|
||||
key = (orig_cls, cls)
|
||||
new_cls = _CLASS_LOOKUP.get(key)
|
||||
if new_cls is None:
|
||||
new_cls = orig_cls.__class__(orig_cls.__name__, (orig_cls, cls), {})
|
||||
_CLASS_LOOKUP[key] = new_cls
|
||||
value.__class__ = new_cls
|
||||
return value
|
||||
except TypeError:
|
||||
# Non heap type, look in overloads dict
|
||||
for type_, func in _TYPE_OVERLOADS.items():
|
||||
# Use type() here, we only need to trigger if it's the exact type,
|
||||
# as otherwise we don't need to overload the class
|
||||
if type(value) is type_: # pylint: disable=unidiomatic-typecheck
|
||||
return add_class_to_obj(func(value), cls)
|
||||
raise
|
||||
|
Reference in New Issue
Block a user