json-duplicate-keys 2024.11.19__py3-none-any.whl → 2024.12.12__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,14 +1,16 @@
1
+ # -*- coding: utf-8 -*-
1
2
  try:
2
3
  unicode # Python 2
3
4
  except NameError:
4
5
  unicode = str # Python 3
5
6
 
7
+ from collections import OrderedDict
8
+ import json, re, copy
9
+
6
10
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
7
11
  # # # # # # # # # # # Normalize Key name # # # # # # # # # # #
8
12
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
9
13
  def normalize_key(name, dupSign_start="{{{", dupSign_end="}}}", _isDebug_=False):
10
- import re
11
-
12
14
  # User input data type validation
13
15
  if type(_isDebug_) != bool: _isDebug_ = False
14
16
 
@@ -30,9 +32,6 @@ def normalize_key(name, dupSign_start="{{{", dupSign_end="}}}", _isDebug_=False)
30
32
  # # # # # # # # # # # # # # # loads # # # # # # # # # # # # # #
31
33
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
32
34
  def loads(Jstr, dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False, _isDebug_=False):
33
- import json, re
34
- from collections import OrderedDict
35
-
36
35
  # User input data type validation
37
36
  if type(_isDebug_) != bool: _isDebug_ = False
38
37
 
@@ -150,9 +149,8 @@ def loads(Jstr, dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False, _isD
150
149
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
151
150
  def load(Jfilepath, dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False, _isDebug_=False):
152
151
  try:
153
- Jfile = open(Jfilepath)
154
- Jstr = Jfile.read()
155
- Jfile.close()
152
+ with open(Jfilepath) as Jfile:
153
+ Jstr = Jfile.read()
156
154
 
157
155
  return loads(Jstr, dupSign_start=dupSign_start, dupSign_end=dupSign_end, ordered_dict=ordered_dict, _isDebug_=_isDebug_)
158
156
  except Exception as e:
@@ -169,7 +167,6 @@ def load(Jfilepath, dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False,
169
167
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
170
168
  class JSON_DUPLICATE_KEYS:
171
169
  def __init__(self, Jobj):
172
- from collections import OrderedDict
173
170
  self.__Jobj = dict()
174
171
  if type(Jobj) in [dict, OrderedDict, list]:
175
172
  self.__Jobj = Jobj
@@ -188,9 +185,6 @@ class JSON_DUPLICATE_KEYS:
188
185
  # # # # # # # # # # # # # # # get # # # # # # # # # # # # # # #
189
186
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
190
187
  def get(self, name, case_insensitive=False, separator="||", parse_index="$", _isDebug_=False):
191
- import re
192
- from collections import OrderedDict
193
-
194
188
  # User input data type validation
195
189
  if type(_isDebug_) != bool: _isDebug_ = False
196
190
 
@@ -247,9 +241,6 @@ class JSON_DUPLICATE_KEYS:
247
241
  # # # # # # # # # # # # # # # set # # # # # # # # # # # # # # #
248
242
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
249
243
  def set(self, name, value, case_insensitive=False, separator="||", parse_index="$", dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False, _isDebug_=False):
250
- import re
251
- from collections import OrderedDict
252
-
253
244
  # User input data type validation
254
245
  if type(_isDebug_) != bool: _isDebug_ = False
255
246
 
@@ -307,16 +298,20 @@ class JSON_DUPLICATE_KEYS:
307
298
  else:
308
299
  if self.get(separator.join(name.split(separator)[:-1]), case_insensitive=case_insensitive, separator=separator, parse_index=parse_index)["value"] != "JSON_DUPLICATE_KEYS_ERROR":
309
300
  Jget = self.get(separator.join(name.split(separator)[:-1]), case_insensitive=case_insensitive, separator=separator, parse_index=parse_index)
310
- exec_expression = "self.getObject()"
301
+ if type(Jget["value"]) in [dict, OrderedDict]:
302
+ exec_expression = "self.getObject()"
311
303
 
312
- for k in Jget["name"].split(separator):
313
- if re.search("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$", k):
314
- exec_expression += "["+k.split(parse_index)[1]+"]"
315
- else:
316
- exec_expression += "["+repr(k)+"]"
304
+ for k in Jget["name"].split(separator)+[name.split(separator)[-1]]:
305
+ if re.search("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$", k):
306
+ exec_expression += "["+k.split(parse_index)[1]+"]"
307
+ else:
308
+ exec_expression += "["+repr(k)+"]"
317
309
 
318
- exec(exec_expression+"="+repr(value))
319
- return True
310
+ exec(exec_expression+"="+repr(value))
311
+ return True
312
+ else:
313
+ if _isDebug_: print("\x1b[31m[-] KeyNameInvalidError: \x1b[0m"+name)
314
+ return False
320
315
  else:
321
316
  if _isDebug_: print("\x1b[31m[-] KeyNameNotExistError: {}\x1b[0m".format(separator.join(Jget["name"].split(separator)[:-1])))
322
317
  return False
@@ -326,11 +321,54 @@ class JSON_DUPLICATE_KEYS:
326
321
 
327
322
 
328
323
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
329
- # # # # # # # # # # # # # # update # # # # # # # # # # # # # #
324
+ # # # # # # # # # # # # # # insert # # # # # # # # # # # # # #
330
325
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
331
- def update(self, name, value, case_insensitive=False, separator="||", parse_index="$", _isDebug_=False):
332
- import re
326
+ def insert(self, name, value, position=None, case_insensitive=False, separator="||", parse_index="$", dupSign_start="{{{", dupSign_end="}}}", _isDebug_=False):
327
+ # User input data type validation
328
+ if type(_isDebug_) != bool: _isDebug_ = False
329
+
330
+ if type(name) not in [str, unicode]:
331
+ if _isDebug_: print("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
332
+ return False
333
+
334
+ if type(position) != int: position = None
335
+
336
+ if type(case_insensitive) != bool: case_insensitive = False
337
+
338
+ if type(separator) not in [str, unicode]: separator = "||"
339
+
340
+ if type(parse_index) not in [str, unicode]: parse_index = "$"
341
+
342
+ if type(dupSign_start) not in [str, unicode]: dupSign_start = "{{{"
343
+
344
+ if type(dupSign_end) not in [str, unicode]: dupSign_end = "}}}"
345
+
346
+ if type(self.getObject()) not in [list, dict, OrderedDict]:
347
+ if _isDebug_: print("\x1b[31m[-] DataTypeError: the JSON object must be list, dict or OrderedDict, not {}\x1b[0m".format(type(self.getObject())))
348
+ return False
349
+
350
+ if re.search(re.escape(separator)+"$", name):
351
+ if _isDebug_: print("\x1b[31m[-] KeyNameInvalidError: \x1b[0m"+name)
352
+ return False
353
+
354
+ Jget = self.get(name, case_insensitive=case_insensitive, separator=separator, parse_index=parse_index, _isDebug_=_isDebug_)
355
+
356
+ if Jget["value"] != "JSON_DUPLICATE_KEYS_ERROR":
357
+ if type(Jget["value"]) == list:
358
+ if position == None: position = len(Jget["value"])
359
+
360
+ Jget["value"].insert(position, value)
361
+
362
+ return self.update(Jget["name"], Jget["value"], separator=separator, parse_index=parse_index, dupSign_start=dupSign_start, dupSign_end=dupSign_end, _isDebug_=_isDebug_)
363
+ else:
364
+ if _isDebug_: print("\x1b[31m[-] DataTypeError: The data type of {} must be list, not {}\x1b[0m".format(Jget["name"], type(Jget["value"])))
365
+ return False
366
+
333
367
 
368
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
369
+ # # # # # # # # # # # # # # update # # # # # # # # # # # # # #
370
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
371
+ def update(self, name, value, case_insensitive=False, allow_new_key=False, separator="||", parse_index="$", dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False, _isDebug_=False):
334
372
  # User input data type validation
335
373
  if type(_isDebug_) != bool: _isDebug_ = False
336
374
 
@@ -344,7 +382,10 @@ class JSON_DUPLICATE_KEYS:
344
382
 
345
383
  if type(parse_index) not in [str, unicode]: parse_index = "$"
346
384
 
347
- if self.get(name, case_insensitive=case_insensitive, separator=separator, parse_index=parse_index, _isDebug_=_isDebug_)["value"] != "JSON_DUPLICATE_KEYS_ERROR":
385
+ _debug_ = _isDebug_
386
+ if allow_new_key: _debug_ = False
387
+
388
+ if self.get(name, case_insensitive=case_insensitive, separator=separator, parse_index=parse_index, _isDebug_=_debug_)["value"] != "JSON_DUPLICATE_KEYS_ERROR":
348
389
  Jname = self.get(name, case_insensitive=case_insensitive, separator=separator, parse_index=parse_index)["name"]
349
390
  try:
350
391
  exec_expression = "self.getObject()"
@@ -359,6 +400,8 @@ class JSON_DUPLICATE_KEYS:
359
400
  return True
360
401
  except Exception as e:
361
402
  if _isDebug_: print("\x1b[31m[-] ExceptionError: {}\x1b[0m".format(e))
403
+ elif allow_new_key:
404
+ return self.set(name, value, case_insensitive=case_insensitive, separator=separator, parse_index=parse_index, dupSign_start=dupSign_start, dupSign_end=dupSign_end, ordered_dict=ordered_dict, _isDebug_=_isDebug_)
362
405
 
363
406
  return False
364
407
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -370,8 +413,6 @@ class JSON_DUPLICATE_KEYS:
370
413
  # # # # # # # # # # # # # # delete # # # # # # # # # # # # #
371
414
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
372
415
  def delete(self, name, case_insensitive=False, separator="||", parse_index="$", _isDebug_=False):
373
- import re
374
-
375
416
  # User input data type validation
376
417
  if type(_isDebug_) != bool: _isDebug_ = False
377
418
 
@@ -411,8 +452,6 @@ class JSON_DUPLICATE_KEYS:
411
452
  # # # # # # # # # # # # filter_keys # # # # # # # # # # # # #
412
453
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
413
454
  def filter_keys(self, name, separator="||", parse_index="$", ordered_dict=False):
414
- import re, copy
415
-
416
455
  JDKSObject = copy.deepcopy(self)
417
456
  JDKSObject.flatten(separator=separator, parse_index=parse_index, ordered_dict=ordered_dict)
418
457
  newJDKSObject = loads("{}", ordered_dict=ordered_dict)
@@ -420,10 +459,10 @@ class JSON_DUPLICATE_KEYS:
420
459
  for k, v in JDKSObject.getObject().items():
421
460
  if type(k) == str and type(name) == str:
422
461
  if re.search(name, k):
423
- newJDKSObject.set(k, v, separator="!!"+separator+"!!", parse_index="!!"+parse_index+"!!", ordered_dict=ordered_dict)
462
+ newJDKSObject.set(k, v, separator="§§"+separator+"§§", parse_index="§§"+parse_index+"§§", ordered_dict=ordered_dict)
424
463
  else:
425
464
  if name == k:
426
- newJDKSObject.set(k, v, separator="!!"+separator+"!!", parse_index="!!"+parse_index+"!!", ordered_dict=ordered_dict)
465
+ newJDKSObject.set(k, v, separator="§§"+separator+"§§", parse_index="§§"+parse_index+"§§", ordered_dict=ordered_dict)
427
466
 
428
467
  return newJDKSObject
429
468
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -435,8 +474,6 @@ class JSON_DUPLICATE_KEYS:
435
474
  # # # # # # # # # # # # filter_values # # # # # # # # # # # # #
436
475
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
437
476
  def filter_values(self, value, separator="||", parse_index="$", ordered_dict=False):
438
- import re, copy
439
-
440
477
  JDKSObject = copy.deepcopy(self)
441
478
  JDKSObject.flatten(separator=separator, parse_index=parse_index, ordered_dict=ordered_dict)
442
479
  newJDKSObject = loads("{}", ordered_dict=ordered_dict)
@@ -444,10 +481,10 @@ class JSON_DUPLICATE_KEYS:
444
481
  for k, v in JDKSObject.getObject().items():
445
482
  if type(v) == str and type(value) == str:
446
483
  if re.search(value, v):
447
- newJDKSObject.set(k, v, separator="!!"+separator+"!!", parse_index="!!"+parse_index+"!!", ordered_dict=ordered_dict)
484
+ newJDKSObject.set(k, v, separator="§§"+separator+"§§", parse_index="§§"+parse_index+"§§", ordered_dict=ordered_dict)
448
485
  else:
449
486
  if value == v:
450
- newJDKSObject.set(k, v, separator="!!"+separator+"!!", parse_index="!!"+parse_index+"!!", ordered_dict=ordered_dict)
487
+ newJDKSObject.set(k, v, separator="§§"+separator+"§§", parse_index="§§"+parse_index+"§§", ordered_dict=ordered_dict)
451
488
 
452
489
  return newJDKSObject
453
490
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -459,9 +496,6 @@ class JSON_DUPLICATE_KEYS:
459
496
  # # # # # # # # # # # # # # dumps # # # # # # # # # # # # # #
460
497
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
461
498
  def dumps(self, dupSign_start="{{{", dupSign_end="}}}", _isDebug_=False, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False):
462
- import json, re
463
- from collections import OrderedDict
464
-
465
499
  # User input data type validation
466
500
  if type(_isDebug_) != bool: _isDebug_ = False
467
501
 
@@ -505,8 +539,6 @@ class JSON_DUPLICATE_KEYS:
505
539
  # # # # # # # # # # # # # flatten # # # # # # # # # # # # # #
506
540
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
507
541
  def flatten(self, separator="||", parse_index="$", ordered_dict=False, _isDebug_=False):
508
- from collections import OrderedDict
509
-
510
542
  # User input data type validation
511
543
  if type(_isDebug_) != bool: _isDebug_ = False
512
544
 
@@ -566,9 +598,6 @@ class JSON_DUPLICATE_KEYS:
566
598
  # # # # # # # # # # # # # unflatten # # # # # # # # # # # # #
567
599
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
568
600
  def unflatten(self, separator="||", parse_index="$", ordered_dict=False, _isDebug_=False):
569
- import re
570
- from collections import OrderedDict
571
-
572
601
  # User input data type validation
573
602
  if type(_isDebug_) != bool: _isDebug_ = False
574
603
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: json-duplicate-keys
3
- Version: 2024.11.19
3
+ Version: 2024.12.12
4
4
  Summary: Flatten/ Unflatten and Load(s)/ Dump(s) JSON File/ Object with Duplicate Keys
5
5
  Home-page: https://github.com/truocphan/json-duplicate-keys
6
6
  Author: TP Cyber Security
@@ -17,12 +17,15 @@ License-File: LICENSE
17
17
  Flatten/ Unflatten and Load(s)/ Dump(s) JSON File/ Object with Duplicate Keys
18
18
 
19
19
  <p align="center">
20
- <a href="https://github.com/truocphan/json-duplicate-keys/releases/"><img src="https://img.shields.io/github/release/truocphan/json-duplicate-keys" height=30></a>
20
+ <a href="https://github.com/truocphan/json-duplicate-keys/releases/"><img src="https://img.shields.io/github/release/truocphan/json-duplicate-keys" height=30></a>
21
21
  <a href="#"><img src="https://img.shields.io/github/downloads/truocphan/json-duplicate-keys/total" height=30></a>
22
22
  <a href="#"><img src="https://img.shields.io/github/stars/truocphan/json-duplicate-keys" height=30></a>
23
23
  <a href="#"><img src="https://img.shields.io/github/forks/truocphan/json-duplicate-keys" height=30></a>
24
24
  <a href="https://github.com/truocphan/json-duplicate-keys/issues?q=is%3Aopen+is%3Aissue"><img src="https://img.shields.io/github/issues/truocphan/json-duplicate-keys" height=30></a>
25
25
  <a href="https://github.com/truocphan/json-duplicate-keys/issues?q=is%3Aissue+is%3Aclosed"><img src="https://img.shields.io/github/issues-closed/truocphan/json-duplicate-keys" height=30></a>
26
+ <br>
27
+ <a href="#"><img src="https://img.shields.io/pypi/v/json-duplicate-keys" height=30></a>
28
+ <a href="#"><img src="https://img.shields.io/pypi/dm/json-duplicate-keys" height=30></a>
26
29
  </p>
27
30
 
28
31
  ## Installation
@@ -122,13 +125,13 @@ Jstr = '{"author": "truocphan", "version": "22.3.3", "version": "latest", "relea
122
125
  JDKSObject = jdks.loads(Jstr)
123
126
 
124
127
  print(JDKSObject.get("version{{{_2_}}}"))
125
- # OUTPUT: latest
128
+ # OUTPUT: {'name': 'version{{{_2_}}}', 'value': 'latest'}
126
129
 
127
130
  print(JDKSObject.get("release||$0$"))
128
- # OUTPUT: {'version': 'latest'}
131
+ # OUTPUT: {'name': 'release||$0$', 'value': {'version': 'latest'}}
129
132
 
130
133
  print(JDKSObject.get("snapshot||author"))
131
- # OUTPUT: truocphan
134
+ # OUTPUT: {'name': 'snapshot||author', 'value': 'truocphan'}
132
135
  ```
133
136
  ---
134
137
 
@@ -197,13 +200,46 @@ print(JDKSObject.getObject())
197
200
  ```
198
201
  ---
199
202
 
200
- ### JSON_DUPLICATE_KEYS.update(`name`, `value`, `case_insensitive`=False, `separator`="||", `parse_index`="$", `_isDebug_`=False)
201
- _Update new `value` for existing `name` in the JSON object_
203
+ ### JSON_DUPLICATE_KEYS.insert(`name`, `value`, `position`=None, `case_insensitive`=False, `separator`="||", `parse_index`="$", `dupSign_start`="{{{", `dupSign_end`="}}}", `_isDebug_`=False)
204
+ _Insert `value` at `position` in value list of `name`_
202
205
  - `name`: the key name of the JSON object. Supported flatten key name format
203
206
  - `value`: new value for key `name`
207
+ - `position`: position of the `value` to insert (default insert at the last position of the list)
204
208
  - `case_insensitive`: the key name case (in)sensitive
205
209
  - `separator`:
206
210
  - `parse_index`:
211
+ - `dupSign_start`:
212
+ - `dupSign_end`:
213
+ - `_isDebug_`: Show/ Hide debug error messages
214
+ ```python
215
+ import json_duplicate_keys as jdks
216
+
217
+ Jstr = '{"author": "truocphan", "version": "22.3.3", "version": "latest", "release": [{"version": "latest"}], "snapshot": {"author": "truocphan", "version": "22.3.3", "release": [{"version": "latest"}]}}'
218
+
219
+ JDKSObject = jdks.loads(Jstr)
220
+
221
+ print(JDKSObject.getObject())
222
+ # OUTPUT: {'author': 'truocphan', 'version': '22.3.3', 'version{{{_2_}}}': 'latest', 'release': [{'version': 'latest'}], 'snapshot': {'author': 'truocphan', 'version': '22.3.3', 'release': [{'version': 'latest'}]}}
223
+
224
+ JDKSObject.insert("release", {'version': '2025.1.1'})
225
+ JDKSObject.insert("snapshot||release", {'version': '2025.1.1'}, 0)
226
+
227
+ print(JDKSObject.getObject())
228
+ # OUTPUT: {'author': 'truocphan', 'version': '22.3.3', 'version{{{_2_}}}': 'latest', 'release': [{'version': 'latest'}, {'version': '2025.1.1'}], 'snapshot': {'author': 'truocphan', 'version': '22.3.3', 'release': [{'version': '2025.1.1'}, {'version': 'latest'}]}}
229
+ ```
230
+ ---
231
+
232
+ ### JSON_DUPLICATE_KEYS.update(`name`, `value`, `case_insensitive`=False, `allow_new_key`=False, `separator`="||", `parse_index`="$", `dupSign_start`="{{{", `dupSign_end`="}}}", `ordered_dict`=False, `_isDebug_`=False)
233
+ _Update new `value` for existing `name` or Set a new `name` in the JSON object_
234
+ - `name`: the key name of the JSON object. Supported flatten key name format
235
+ - `value`: new value for key `name`
236
+ - `case_insensitive`: the key name case (in)sensitive
237
+ - `allow_new_key`: allows to create a new key name if the key name does not exist
238
+ - `separator`:
239
+ - `parse_index`:
240
+ - `dupSign_start`:
241
+ - `dupSign_end`:
242
+ - `ordered_dict`: preserves the order in which the Keys are inserted
207
243
  - `_isDebug_`: Show/ Hide debug error messages
208
244
  ```python
209
245
  import json_duplicate_keys as jdks
@@ -254,7 +290,7 @@ print(JDKSObject.getObject())
254
290
  - `name`:
255
291
  - `separator`:
256
292
  - `parse_index`:
257
- - `ordered_dict`:
293
+ - `ordered_dict`: preserves the order in which the Keys are inserted
258
294
  ```python
259
295
  import json_duplicate_keys as jdks
260
296
 
@@ -275,7 +311,7 @@ print(JDKSObject.dumps())
275
311
  - `value`:
276
312
  - `separator`:
277
313
  - `parse_index`:
278
- - `ordered_dict`:
314
+ - `ordered_dict`: preserves the order in which the Keys are inserted
279
315
  ```python
280
316
  import json_duplicate_keys as jdks
281
317
 
@@ -393,6 +429,12 @@ print(JDKSObject.getObject())
393
429
  ---
394
430
 
395
431
  ## CHANGELOG
432
+ #### [json-duplicate-keys v2024.12.12](https://github.com/truocphan/json-duplicate-keys/tree/2024.12.12)
433
+ - **New**: _insert_ function
434
+
435
+ #### [json-duplicate-keys v2024.11.28](https://github.com/truocphan/json-duplicate-keys/tree/2024.11.28)
436
+ - **Fixed**: Add subkey name to empty dict of existing key name
437
+
396
438
  #### [json-duplicate-keys v2024.11.19](https://github.com/truocphan/json-duplicate-keys/tree/2024.11.19)
397
439
  - **Updated**: Allows getting (`JSON_DUPLICATE_KEYS.get`), setting (`JSON_DUPLICATE_KEYS.set`), updating (`JSON_DUPLICATE_KEYS.update`), deleting (`JSON_DUPLICATE_KEYS.delete`) JSON_DUPLICATE_KEYS objects with case-insensitive key names
398
440
 
@@ -0,0 +1,6 @@
1
+ json_duplicate_keys/__init__.py,sha256=UDxU0fqzAmlqzxZq5Kt_AB07zxkJSGOxir2ZCdXZygc,28844
2
+ json_duplicate_keys-2024.12.12.dist-info/LICENSE,sha256=_hudSGMciUc27wGR8EMKfeb3atJRlf6rbhJtLnel-nc,1093
3
+ json_duplicate_keys-2024.12.12.dist-info/METADATA,sha256=8pMihvTXCGW5hXVQUa9Avn-0fxFIIS_6dBg02r1UrHg,20715
4
+ json_duplicate_keys-2024.12.12.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
5
+ json_duplicate_keys-2024.12.12.dist-info/top_level.txt,sha256=vdsGrPLVS_l-BFL1i4hCJBY5_-gq4Cwp-11yegA750Y,20
6
+ json_duplicate_keys-2024.12.12.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.41.1)
2
+ Generator: setuptools (75.5.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,6 +0,0 @@
1
- json_duplicate_keys/__init__.py,sha256=K9bg6uSaRnP4JNorn0Y_Chw_ZnRIZoIU0RGxqHFk8-s,26545
2
- json_duplicate_keys-2024.11.19.dist-info/LICENSE,sha256=_hudSGMciUc27wGR8EMKfeb3atJRlf6rbhJtLnel-nc,1093
3
- json_duplicate_keys-2024.11.19.dist-info/METADATA,sha256=yAQnSyE3h__xXLTnBIbtQfLBEgeCC7eoZSFtG4vdVGE,18084
4
- json_duplicate_keys-2024.11.19.dist-info/WHEEL,sha256=5sUXSg9e4bi7lTLOHcm6QEYwO5TIF1TNbTSVFVjcJcc,92
5
- json_duplicate_keys-2024.11.19.dist-info/top_level.txt,sha256=vdsGrPLVS_l-BFL1i4hCJBY5_-gq4Cwp-11yegA750Y,20
6
- json_duplicate_keys-2024.11.19.dist-info/RECORD,,