@@ -46,6 +46,8 @@ def asdict(
4646 .. versionadded:: 16.0.0 *dict_factory*
4747 .. versionadded:: 16.1.0 *retain_collection_types*
4848 .. versionadded:: 20.3.0 *value_serializer*
49+ .. versionadded:: 21.3.0 If a dict has a collection for a key, it is
50+ serialized as a tuple.
4951 """
5052 attrs = fields (inst .__class__ )
5153 rv = dict_factory ()
@@ -61,22 +63,23 @@ def asdict(
6163 if has (v .__class__ ):
6264 rv [a .name ] = asdict (
6365 v ,
64- True ,
65- filter ,
66- dict_factory ,
67- retain_collection_types ,
68- value_serializer ,
66+ recurse = True ,
67+ filter = filter ,
68+ dict_factory = dict_factory ,
69+ retain_collection_types = retain_collection_types ,
70+ value_serializer = value_serializer ,
6971 )
7072 elif isinstance (v , (tuple , list , set , frozenset )):
7173 cf = v .__class__ if retain_collection_types is True else list
7274 rv [a .name ] = cf (
7375 [
7476 _asdict_anything (
7577 i ,
76- filter ,
77- dict_factory ,
78- retain_collection_types ,
79- value_serializer ,
78+ is_key = False ,
79+ filter = filter ,
80+ dict_factory = dict_factory ,
81+ retain_collection_types = retain_collection_types ,
82+ value_serializer = value_serializer ,
8083 )
8184 for i in v
8285 ]
@@ -87,17 +90,19 @@ def asdict(
8790 (
8891 _asdict_anything (
8992 kk ,
90- filter ,
91- df ,
92- retain_collection_types ,
93- value_serializer ,
93+ is_key = True ,
94+ filter = filter ,
95+ dict_factory = df ,
96+ retain_collection_types = retain_collection_types ,
97+ value_serializer = value_serializer ,
9498 ),
9599 _asdict_anything (
96100 vv ,
97- filter ,
98- df ,
99- retain_collection_types ,
100- value_serializer ,
101+ is_key = False ,
102+ filter = filter ,
103+ dict_factory = df ,
104+ retain_collection_types = retain_collection_types ,
105+ value_serializer = value_serializer ,
101106 ),
102107 )
103108 for kk , vv in iteritems (v )
@@ -111,6 +116,7 @@ def asdict(
111116
112117def _asdict_anything (
113118 val ,
119+ is_key ,
114120 filter ,
115121 dict_factory ,
116122 retain_collection_types ,
@@ -123,22 +129,29 @@ def _asdict_anything(
123129 # Attrs class.
124130 rv = asdict (
125131 val ,
126- True ,
127- filter ,
128- dict_factory ,
129- retain_collection_types ,
130- value_serializer ,
132+ recurse = True ,
133+ filter = filter ,
134+ dict_factory = dict_factory ,
135+ retain_collection_types = retain_collection_types ,
136+ value_serializer = value_serializer ,
131137 )
132138 elif isinstance (val , (tuple , list , set , frozenset )):
133- cf = val .__class__ if retain_collection_types is True else list
139+ if retain_collection_types is True :
140+ cf = val .__class__
141+ elif is_key :
142+ cf = tuple
143+ else :
144+ cf = list
145+
134146 rv = cf (
135147 [
136148 _asdict_anything (
137149 i ,
138- filter ,
139- dict_factory ,
140- retain_collection_types ,
141- value_serializer ,
150+ is_key = False ,
151+ filter = filter ,
152+ dict_factory = dict_factory ,
153+ retain_collection_types = retain_collection_types ,
154+ value_serializer = value_serializer ,
142155 )
143156 for i in val
144157 ]
@@ -148,10 +161,20 @@ def _asdict_anything(
148161 rv = df (
149162 (
150163 _asdict_anything (
151- kk , filter , df , retain_collection_types , value_serializer
164+ kk ,
165+ is_key = True ,
166+ filter = filter ,
167+ dict_factory = df ,
168+ retain_collection_types = retain_collection_types ,
169+ value_serializer = value_serializer ,
152170 ),
153171 _asdict_anything (
154- vv , filter , df , retain_collection_types , value_serializer
172+ vv ,
173+ is_key = False ,
174+ filter = filter ,
175+ dict_factory = df ,
176+ retain_collection_types = retain_collection_types ,
177+ value_serializer = value_serializer ,
155178 ),
156179 )
157180 for kk , vv in iteritems (val )
0 commit comments