1- # -*- coding: utf-8 -*-
21import asyncio
2+ from collections .abc import Hashable
3+ from copy import deepcopy
34import functools
45import json
56import re
67import threading
78import typing
8- from collections .abc import Hashable
9-
10- from slugify import slugify
11-
12- from copy import deepcopy
139
1410from construct import Container , ListContainer
11+ from slugify import slugify
1512
1613main_thread_loop = asyncio .get_event_loop ()
1714
@@ -38,7 +35,7 @@ def default(self, o):
3835 if isinstance (o , bytes ):
3936 return o .decode ("utf-8" )
4037
41- return super (JSONByteEncoder , self ).default (o )
38+ return super ().default (o )
4239
4340
4441class SerializableToJSONEncoder (json .JSONEncoder ):
@@ -66,15 +63,22 @@ def deep_merge(*dicts, extend_lists=False, initializer=None):
6663 def merge_into (d1 , d2 ):
6764 if d1 is None :
6865 return d2
69- for key in d2 :
66+ for key , value in d2 . items () :
7067 if key not in d1 : # key is missing
71- d1 [key ] = deepcopy (d2 [ key ] )
68+ d1 [key ] = deepcopy (value )
7269 elif extend_lists and isinstance (d1 [key ], list ):
73- d1 [key ].extend (deepcopy (d2 [key ]))
70+ if isinstance (value , list ):
71+ # Use list concatenation instead of extend for better performance with large lists
72+ d1 [key ] = d1 [key ] + deepcopy (value )
73+ else :
74+ # Keep original behavior for non-list values
75+ d1 [key ].extend (deepcopy (value ))
7476 elif not isinstance (d1 [key ], dict ):
75- d1 [key ] = deepcopy (d2 [key ])
76- else :
77- d1 [key ] = merge_into (d1 [key ], d2 [key ])
77+ d1 [key ] = deepcopy (value )
78+ elif isinstance (value , dict ): # Ensure both are dicts before recursion
79+ d1 [key ] = merge_into (d1 [key ], value )
80+ else : # d1[key] is dict but value is not
81+ d1 [key ] = deepcopy (value )
7882 return d1
7983
8084 return functools .reduce (merge_into , dicts , initializer )
@@ -92,23 +96,23 @@ def sanitize_key(key):
9296
9397def construct_free (container : Container ):
9498 if isinstance (container , (Container , typing .Mapping )):
95- return dict (
96- ( k , construct_free (v ) )
99+ return {
100+ k : construct_free (v )
97101 for k , v in container .items ()
98102 if not (isinstance (k , str ) and k .startswith ("_" ))
99- )
103+ }
100104 elif isinstance (container , (ListContainer , typing .List )):
101105 return list (construct_free (v ) for v in container )
102106 else :
103107 return container
104108
105109
106- class memoized ( object ) :
110+ class memoized :
107111 """From: https://wiki.python.org/moin/PythonDecoratorLibrary#Memoize
108- Decorator. Caches a function's return value each time it is called.
109- If called later with the same arguments, the cached value is returned
110- (not reevaluated).
111- """
112+ Decorator. Caches a function's return value each time it is called.
113+ If called later with the same arguments, the cached value is returned
114+ (not reevaluated).
115+ """
112116
113117 def __init__ (self , func ):
114118 self .func = func
0 commit comments