json-duplicate-keys 2025.7.1__py3-none-any.whl → 2025.8.19__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,10 +1,8 @@
1
1
  # -*- coding: utf-8 -*-
2
- json_duplicate_keys_VERSION = "2025.7.1"
3
-
4
2
  try:
5
- unicode # Python 2
3
+ unicode
6
4
  except NameError:
7
- unicode = str # Python 3
5
+ unicode = str
8
6
 
9
7
  from collections import OrderedDict
10
8
  import json, re, copy
@@ -24,7 +22,7 @@ def normalize_key(name, dupSign_start="{{{", dupSign_end="}}}", _isDebug_=False)
24
22
 
25
23
  if type(dupSign_end) not in [str, unicode]: dupSign_end = "}}}"
26
24
 
27
- return re.sub('{dupSign_start}_\\d+_{dupSign_end}$'.format(dupSign_start=re.escape(dupSign_start), dupSign_end=re.escape(dupSign_end)), "", name)
25
+ return re.sub(re.escape(dupSign_start)+'_\\d+_'+re.escape(dupSign_end)+'$', "", name)
28
26
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
29
27
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
30
28
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -118,13 +116,13 @@ def loads(Jstr, dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False, skip
118
116
  Jstr = re.sub(r'"([^"]*)"[\s\t\r\n]*([,\]}])'.encode(), '\x04\x05\\1\x04\x05\\2'.encode(), Jstr)
119
117
 
120
118
 
121
- Jstr = re.sub(r'"([^"]+)"[\s\t\r\n]*:'.encode(), r'"\1{dupSign_start}_dupSign_{dupSign_end}":'.format(dupSign_start=dupSign_start_escape, dupSign_end=dupSign_end_escape).encode(), Jstr)
119
+ Jstr = re.sub(r'"([^"]+)"[\s\t\r\n]*:'.encode(), (r'"\1'+dupSign_start_escape+'_dupSign_'+dupSign_end_escape+'":').encode(), Jstr)
122
120
 
123
- Jstr = re.sub(r'""[\s\t\r\n]*:'.encode(), '"{dupSign_start}_dupSign_{dupSign_end}":'.format(dupSign_start=dupSign_start_escape, dupSign_end=dupSign_end_escape).encode(), Jstr)
121
+ Jstr = re.sub(r'""[\s\t\r\n]*:'.encode(), ('"'+dupSign_start_escape+'_dupSign_'+dupSign_end_escape+'":').encode(), Jstr)
124
122
 
125
123
  i = 0
126
- while re.search(r'{dupSign_start}_dupSign_{dupSign_end}"[\s\t\r\n]*:'.format(dupSign_start=dupSign_start_escape, dupSign_end=dupSign_end_escape).encode(), Jstr):
127
- Jstr = re.sub(r'{dupSign_start}_dupSign_{dupSign_end}"[\s\t\r\n]*:'.format(dupSign_start=dupSign_start_escape, dupSign_end=dupSign_end_escape).encode(), (dupSign_start_escape+"_"+str(i)+"_"+dupSign_end_escape+'":').encode(), Jstr, 1)
124
+ while re.search((dupSign_start_escape+'_dupSign_'+dupSign_end_escape+r'"[\s\t\r\n]*:').encode(), Jstr):
125
+ Jstr = re.sub((dupSign_start_escape+'_dupSign_'+dupSign_end_escape+r'"[\s\t\r\n]*:').encode(), (dupSign_start_escape+"_"+str(i)+"_"+dupSign_end_escape+'":').encode(), Jstr, 1)
128
126
  i += 1
129
127
 
130
128
  Jstr = re.sub('\x00\x01'.encode(), r'\\\\'.encode(), Jstr)
@@ -135,13 +133,13 @@ def loads(Jstr, dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False, skip
135
133
  Jstr = re.sub(r'\\"', '\x02\x03', Jstr)
136
134
  Jstr = re.sub(r'"([^"]*)"[\s\t\r\n]*([,\]}])', '\x04\x05\\1\x04\x05\\2', Jstr)
137
135
 
138
- Jstr = re.sub(r'"([^"]+)"[\s\t\r\n]*:', r'"\1{dupSign_start}_dupSign_{dupSign_end}":'.format(dupSign_start=dupSign_start_escape, dupSign_end=dupSign_end_escape), Jstr)
136
+ Jstr = re.sub(r'"([^"]+)"[\s\t\r\n]*:', r'"\1'+dupSign_start_escape+'_dupSign_'+dupSign_end_escape+'":', Jstr)
139
137
 
140
- Jstr = re.sub(r'""[\s\t\r\n]*:', '"{dupSign_start}_dupSign_{dupSign_end}":'.format(dupSign_start=dupSign_start_escape, dupSign_end=dupSign_end_escape), Jstr)
138
+ Jstr = re.sub(r'""[\s\t\r\n]*:', '"'+dupSign_start_escape+'_dupSign_'+dupSign_end_escape+'":', Jstr)
141
139
 
142
140
  i = 0
143
- while re.search(r'{dupSign_start}_dupSign_{dupSign_end}"[\s\t\r\n]*:'.format(dupSign_start=dupSign_start_escape, dupSign_end=dupSign_end_escape), Jstr):
144
- Jstr = re.sub(r'{dupSign_start}_dupSign_{dupSign_end}"[\s\t\r\n]*:'.format(dupSign_start=dupSign_start_escape, dupSign_end=dupSign_end_escape), dupSign_start_escape+"_"+str(i)+"_"+dupSign_end_escape+'":', Jstr, 1)
141
+ while re.search(dupSign_start_escape+'_dupSign_'+dupSign_end_escape+r'"[\s\t\r\n]*:', Jstr):
142
+ Jstr = re.sub(dupSign_start_escape+'_dupSign_'+dupSign_end_escape+r'"[\s\t\r\n]*:', dupSign_start_escape+"_"+str(i)+"_"+dupSign_end_escape+'":', Jstr, 1)
145
143
  i += 1
146
144
 
147
145
  Jstr = re.sub('\x00\x01', r'\\\\', Jstr)
@@ -178,11 +176,15 @@ def loads(Jstr, dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False, skip
178
176
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
179
177
  def load(Jfilepath, dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False, skipDuplicated=False, _isDebug_=False):
180
178
  try:
181
- with open(Jfilepath) as Jfile: Jstr = Jfile.read()
182
- except Exception as e:
183
- with open(Jfilepath, "rb") as Jfile: Jstr = Jfile.read()
179
+ try:
180
+ with open(Jfilepath) as Jfile: Jstr = Jfile.read()
181
+ except Exception as e:
182
+ with open(Jfilepath, "rb") as Jfile: Jstr = Jfile.read()
184
183
 
185
- return loads(Jstr, dupSign_start=dupSign_start, dupSign_end=dupSign_end, ordered_dict=ordered_dict, skipDuplicated=skipDuplicated, _isDebug_=_isDebug_)
184
+ return loads(Jstr, dupSign_start=dupSign_start, dupSign_end=dupSign_end, ordered_dict=ordered_dict, skipDuplicated=skipDuplicated, _isDebug_=_isDebug_)
185
+ except Exception as e:
186
+ if _isDebug_: print("\x1b[31m[-] ExceptionError: {}\x1b[0m".format(e))
187
+ return False
186
188
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
187
189
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
188
190
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -492,10 +494,10 @@ class JSON_DUPLICATE_KEYS:
492
494
  for k, v in JDKSObject.getObject().items():
493
495
  if type(k) == str and type(name) == str:
494
496
  if re.search(name, k):
495
- newJDKSObject.set(k, v, separator="§§"+separator+"§§", parse_index="§§"+parse_index+"§§", ordered_dict=ordered_dict)
497
+ newJDKSObject.set(k, v, separator=u"§§"+separator+u"§§", parse_index=u"§§"+parse_index+u"§§", ordered_dict=ordered_dict)
496
498
  else:
497
499
  if name == k:
498
- newJDKSObject.set(k, v, separator="§§"+separator+"§§", parse_index="§§"+parse_index+"§§", ordered_dict=ordered_dict)
500
+ newJDKSObject.set(k, v, separator=u"§§"+separator+u"§§", parse_index=u"§§"+parse_index+u"§§", ordered_dict=ordered_dict)
499
501
 
500
502
  return newJDKSObject
501
503
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -514,10 +516,10 @@ class JSON_DUPLICATE_KEYS:
514
516
  for k, v in JDKSObject.getObject().items():
515
517
  if type(v) == str and type(value) == str:
516
518
  if re.search(value, v):
517
- newJDKSObject.set(k, v, separator="§§"+separator+"§§", parse_index="§§"+parse_index+"§§", ordered_dict=ordered_dict)
519
+ newJDKSObject.set(k, v, separator=u"§§"+separator+u"§§", parse_index=u"§§"+parse_index+u"§§", ordered_dict=ordered_dict)
518
520
  else:
519
521
  if value == v:
520
- newJDKSObject.set(k, v, separator="§§"+separator+"§§", parse_index="§§"+parse_index+"§§", ordered_dict=ordered_dict)
522
+ newJDKSObject.set(k, v, separator=u"§§"+separator+u"§§", parse_index=u"§§"+parse_index+u"§§", ordered_dict=ordered_dict)
521
523
 
522
524
  return newJDKSObject
523
525
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -544,7 +546,7 @@ class JSON_DUPLICATE_KEYS:
544
546
 
545
547
  dupSign_end_escape_regex = re.escape(json.dumps({dupSign_end:""})[2:-6])
546
548
 
547
- return re.sub('{dupSign_start}_\\d+_{dupSign_end}":'.format(dupSign_start=dupSign_start_escape_regex, dupSign_end=dupSign_end_escape_regex), '":', json.dumps(self.getObject(), skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, cls=cls, indent=indent, separators=separators, default=default, sort_keys=sort_keys))
549
+ return re.sub(dupSign_start_escape_regex+'_\\d+_'+dupSign_end_escape_regex+'":', '":', json.dumps(self.getObject(), skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, cls=cls, indent=indent, separators=separators, default=default, sort_keys=sort_keys))
548
550
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
549
551
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
550
552
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -557,8 +559,8 @@ class JSON_DUPLICATE_KEYS:
557
559
  Jstr = self.dumps(dupSign_start=dupSign_start, dupSign_end=dupSign_end, _isDebug_=_isDebug_, skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, cls=cls, indent=indent, separators=separators, default=default, sort_keys=sort_keys)
558
560
 
559
561
  try:
560
- Jfile = open(Jfilepath, "w")
561
- Jfile.write(Jstr)
562
+ Jfile = open(Jfilepath, "wb")
563
+ Jfile.write(Jstr.encode("utf-8"))
562
564
  Jfile.close()
563
565
  except Exception as e:
564
566
  if _isDebug_: print("\x1b[31m[-] ExceptionError: {}\x1b[0m".format(e))
@@ -600,7 +602,7 @@ class JSON_DUPLICATE_KEYS:
600
602
  else:
601
603
  for k,v in Jobj.items():
602
604
  _Jobj = v
603
- _key = "{key}{separator}{k}".format(key=key,separator=separator,k=k) if key != None else "{k}".format(k=k)
605
+ _key = key+separator+k if key != None else k
604
606
 
605
607
  __convert_Jobj_to_Jflat(_Jobj, _key)
606
608
  elif type(Jobj) == list:
@@ -609,7 +611,7 @@ class JSON_DUPLICATE_KEYS:
609
611
  else:
610
612
  for i,v in enumerate(Jobj):
611
613
  _Jobj = v
612
- _key = "{key}{separator}{parse_index}{i}{parse_index}".format(key=key, separator=separator, parse_index=parse_index, i=i) if key != None else "{parse_index}{i}{parse_index}".format(parse_index=parse_index, i=i)
614
+ _key = key+separator+parse_index+str(i)+parse_index if key != None else parse_index+str(i)+parse_index
613
615
 
614
616
  __convert_Jobj_to_Jflat(_Jobj, _key)
615
617
  else:
@@ -1,32 +1,51 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: json-duplicate-keys
3
- Version: 2025.7.1
3
+ Version: 2025.8.19
4
4
  Summary: Flatten/ Unflatten and Load(s)/ Dump(s) JSON File/ Object with Duplicate Keys
5
- Home-page: https://github.com/truocphan/json-duplicate-keys
6
- Author: TP Cyber Security
7
- Author-email: tpcybersec2023@gmail.com
8
- License: MIT
5
+ Author-email: TP Cyber Security <tpcybersec2023@gmail.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2022 TP Cyber Security
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+ Project-URL: Homepage, https://github.com/tpcybersec/json-duplicate-keys
9
28
  Keywords: TPCyberSec,json,duplicate keys,json duplicate keys,flatten,unflatten
10
29
  Classifier: Programming Language :: Python :: 3
11
- Classifier: Programming Language :: Python :: 2
12
30
  Classifier: Programming Language :: Python :: Implementation :: Jython
13
31
  Description-Content-Type: text/markdown
14
32
  License-File: LICENSE
15
33
 
16
- # JSON Duplicate Keys - PyPI
17
- Flatten/ Unflatten and Load(s)/ Dump(s) JSON File/ Object with Duplicate Keys
18
-
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>
21
- <a href="#"><img src="https://img.shields.io/github/downloads/truocphan/json-duplicate-keys/total" height=30></a>
22
- <a href="#"><img src="https://img.shields.io/github/stars/truocphan/json-duplicate-keys" height=30></a>
23
- <a href="#"><img src="https://img.shields.io/github/forks/truocphan/json-duplicate-keys" height=30></a>
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
- <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>
34
+ <div align="center">
35
+ <h1>JSON Duplicate Keys - PyPI</h1>
36
+ <i>Flatten/ Unflatten and Load(s)/ Dump(s) JSON File/ Object with Duplicate Keys</i>
37
+ <br><br>
38
+ <a href="https://github.com/tpcybersec/json-duplicate-keys/releases/"><img src="https://img.shields.io/github/release/tpcybersec/json-duplicate-keys" height=30></a>
39
+ <a href="#"><img src="https://img.shields.io/github/downloads/tpcybersec/json-duplicate-keys/total" height=30></a>
40
+ <a href="#"><img src="https://img.shields.io/github/stars/tpcybersec/json-duplicate-keys" height=30></a>
41
+ <a href="#"><img src="https://img.shields.io/github/forks/tpcybersec/json-duplicate-keys" height=30></a>
42
+ <a href="https://github.com/tpcybersec/json-duplicate-keys/issues?q=is%3Aopen+is%3Aissue"><img src="https://img.shields.io/github/issues/tpcybersec/json-duplicate-keys" height=30></a>
43
+ <a href="https://github.com/tpcybersec/json-duplicate-keys/issues?q=is%3Aissue+is%3Aclosed"><img src="https://img.shields.io/github/issues-closed/tpcybersec/json-duplicate-keys" height=30></a>
26
44
  <br>
27
45
  <a href="#"><img src="https://img.shields.io/pypi/v/json-duplicate-keys" height=30></a>
46
+ <a href="#"><img src="https://img.shields.io/pypi/pyversions/json-duplicate-keys" height=30></a>
28
47
  <a href="#"><img src="https://img.shields.io/pypi/dm/json-duplicate-keys" height=30></a>
29
- </p>
48
+ </div>
30
49
 
31
50
  ## Installation
32
51
  #### From PyPI:
@@ -35,10 +54,10 @@ pip install json-duplicate-keys
35
54
  ```
36
55
  #### From Source:
37
56
  ```console
38
- git clone https://github.com/truocphan/json-duplicate-keys.git --branch <Branch/Tag>
57
+ git clone https://github.com/tpcybersec/json-duplicate-keys.git --branch <Branch/Tag>
39
58
  cd json-duplicate-keys
40
- python setup.py build
41
- python setup.py install
59
+ python -m build
60
+ python -m pip install dist/json_duplicate_keys-<version>-py3-none-any.whl
42
61
  ```
43
62
 
44
63
  ## Basic Usage
@@ -412,30 +431,34 @@ print(JDKSObject.getObject())
412
431
  ---
413
432
 
414
433
  ## CHANGELOG
415
- #### [json-duplicate-keys v2025.7.1](https://github.com/truocphan/json-duplicate-keys/tree/2025.7.1)
434
+ #### [json-duplicate-keys v2025.8.19](https://github.com/tpcybersec/json-duplicate-keys/tree/2025.8.19)
435
+ - [**Updated**] Add an exception when loading a non-existent file
436
+ - [**Updated**] Dump Unicode characters to a file
437
+
438
+ #### [json-duplicate-keys v2025.7.1](https://github.com/tpcybersec/json-duplicate-keys/tree/2025.7.1)
416
439
  - [**Updated**] Fixed some issues when loading JSON strings with `skipDuplicated` option
417
440
  - [**Updated**] Allow loading of JSON data in byte string format
418
441
  - [**Updated**] Issue with getting and setting an empty list
419
442
 
420
- #### [json-duplicate-keys v2025.6.6](https://github.com/truocphan/json-duplicate-keys/tree/2025.6.6)
443
+ #### [json-duplicate-keys v2025.6.6](https://github.com/tpcybersec/json-duplicate-keys/tree/2025.6.6)
421
444
  - [**Updated**] Added `skipDuplicated` parameter to `load` and `loads` functions to improve performance when parsing large JSON strings by skipping duplicate keys.
422
445
 
423
- #### [json-duplicate-keys v2024.12.12](https://github.com/truocphan/json-duplicate-keys/tree/2024.12.12)
446
+ #### [json-duplicate-keys v2024.12.12](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.12.12)
424
447
  - **New**: _insert_ function
425
448
 
426
- #### [json-duplicate-keys v2024.11.28](https://github.com/truocphan/json-duplicate-keys/tree/2024.11.28)
449
+ #### [json-duplicate-keys v2024.11.28](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.11.28)
427
450
  - **Fixed**: Add subkey name to empty dict of existing key name
428
451
 
429
- #### [json-duplicate-keys v2024.11.19](https://github.com/truocphan/json-duplicate-keys/tree/2024.11.19)
452
+ #### [json-duplicate-keys v2024.11.19](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.11.19)
430
453
  - **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
431
454
 
432
- #### [json-duplicate-keys v2024.7.17](https://github.com/truocphan/json-duplicate-keys/tree/2024.7.17)
433
- - **Fixed**: issue [#3](https://github.com/truocphan/json-duplicate-keys/issues/3) break the set function when the key's value is empty. Thanks [ptth222](https://github.com/ptth222) for reporting this issue.
455
+ #### [json-duplicate-keys v2024.7.17](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.7.17)
456
+ - **Fixed**: issue #3 break the set function when the key's value is empty. Thanks [ptth222](https://github.com/ptth222) for reporting this issue.
434
457
 
435
- #### [json-duplicate-keys v2024.4.20](https://github.com/truocphan/json-duplicate-keys/tree/2024.4.20)
458
+ #### [json-duplicate-keys v2024.4.20](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.4.20)
436
459
  - **New**: _filter_values_
437
460
  - **Updated**: _filter_keys_
438
461
 
439
- #### [json-duplicate-keys v2024.3.24](https://github.com/truocphan/json-duplicate-keys/tree/2024.3.24)
462
+ #### [json-duplicate-keys v2024.3.24](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.3.24)
440
463
  - **Updated**: _normalize_key_, _loads_, _get_, _set_, _update_, _delete_
441
464
  ---
@@ -0,0 +1,6 @@
1
+ json_duplicate_keys/__init__.py,sha256=j-jA6opC7If-__TFmt86AKtw9h7msoSUkUPpfUZ3YP4,30097
2
+ json_duplicate_keys-2025.8.19.dist-info/LICENSE,sha256=_hudSGMciUc27wGR8EMKfeb3atJRlf6rbhJtLnel-nc,1093
3
+ json_duplicate_keys-2025.8.19.dist-info/METADATA,sha256=g8CkjaHAODINJs7QvcCyilmGzbQnLKVWX6r9G1guWHY,24279
4
+ json_duplicate_keys-2025.8.19.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
5
+ json_duplicate_keys-2025.8.19.dist-info/top_level.txt,sha256=vdsGrPLVS_l-BFL1i4hCJBY5_-gq4Cwp-11yegA750Y,20
6
+ json_duplicate_keys-2025.8.19.dist-info/RECORD,,
@@ -1,6 +0,0 @@
1
- json_duplicate_keys/__init__.py,sha256=ClhnGD0jyYwBRsOs9zHevi6WWGtnMEOjczwkUC0BMv8,30753
2
- json_duplicate_keys-2025.7.1.dist-info/LICENSE,sha256=_hudSGMciUc27wGR8EMKfeb3atJRlf6rbhJtLnel-nc,1093
3
- json_duplicate_keys-2025.7.1.dist-info/METADATA,sha256=wvDz2_ia5VuzhLvNiVZnrI7YJEVfjGVwy07RGb2-dQk,22717
4
- json_duplicate_keys-2025.7.1.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
5
- json_duplicate_keys-2025.7.1.dist-info/top_level.txt,sha256=vdsGrPLVS_l-BFL1i4hCJBY5_-gq4Cwp-11yegA750Y,20
6
- json_duplicate_keys-2025.7.1.dist-info/RECORD,,