partialjson 0.0.7__tar.gz → 0.0.9__tar.gz

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,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: partialjson
3
- Version: 0.0.7
3
+ Version: 0.0.9
4
4
  Summary: Parse incomplete or partial json
5
5
  Home-page: https://github.com/iw4p/partialjson
6
6
  Author: Nima Akbarzadeh
@@ -8,11 +8,17 @@ Author-email: iw4p@protonmail.com
8
8
  License: MIT
9
9
  Description-Content-Type: text/markdown
10
10
  License-File: LICENSE
11
+ Dynamic: author
12
+ Dynamic: author-email
13
+ Dynamic: description
14
+ Dynamic: description-content-type
15
+ Dynamic: home-page
16
+ Dynamic: license
17
+ Dynamic: summary
11
18
 
12
19
  # PartialJson
13
20
 
14
- [![Partialjson](https://github.com/iw4p/partialjson/raw/main/images/partialjson.png
15
- )](https://pypi.org/project/partialjson/)
21
+ [![Partialjson](https://github.com/iw4p/partialjson/raw/main/images/partialjson.png)](https://pypi.org/project/partialjson/)
16
22
 
17
23
  ## Parse Partial and incomplete JSON in python
18
24
 
@@ -24,41 +30,56 @@ License-File: LICENSE
24
30
  [![Supported Python versions](https://img.shields.io/pypi/pyversions/partialjson.svg)](#Installation)
25
31
  [![Downloads](https://pepy.tech/badge/partialjson)](https://pepy.tech/project/partialjson)
26
32
 
27
-
28
33
  ## Example
34
+
29
35
  ```python
30
36
  from partialjson.json_parser import JSONParser
31
37
  parser = JSONParser()
32
38
 
33
- incomplete_json = '{"name": "John", "age": 30, "is_student": false, "courses": ["Math", "Science"'
39
+ incomplete_json = '{"name": "John Doe", "age": 30, "is_student": false, "courses": ["Math", "Science"'
34
40
  print(parser.parse(incomplete_json))
35
41
  # {'name': 'John', 'age': 30, 'is_student': False, 'courses': ['Math', 'Science']}
36
42
  ```
37
43
 
44
+ Problem with `\n`? strict mode is here
45
+
46
+ ```python
47
+ from partialjson.json_parser import JSONParser
48
+ parser = JSONParser(strict=False)
49
+
50
+ incomplete_json = '{"name": "John\nDoe", "age": 30, "is_student": false, "courses": ["Math", "Science"'
51
+ print(parser.parse(incomplete_json))
52
+ # {'name': 'John\nDoe', 'age': 30, 'is_student': False, 'courses': ['Math', 'Science']}
53
+ ```
54
+
38
55
  ### Installation
39
56
 
40
57
  ```sh
41
58
  $ pip install partialjson
42
59
  ```
60
+
43
61
  Also can be found on [pypi](https://pypi.org/project/partialjson/)
44
62
 
45
63
  ### How can I use it?
46
- - Install the package by pip package manager.
47
- - After installing, you can use it and call the library.
64
+
65
+ - Install the package by pip package manager.
66
+ - After installing, you can use it and call the library.
48
67
 
49
68
  ## Star History
50
69
 
51
70
  [![Star History Chart](https://api.star-history.com/svg?repos=iw4p/partialjson&type=Date)](https://star-history.com/#iw4p/partialjson&Date)
52
71
 
53
72
  ### Issues
73
+
54
74
  Feel free to submit issues and enhancement requests or contact me via [vida.page/nima](https://vida.page/nima).
55
75
 
56
76
  ### Contributing
77
+
57
78
  Please refer to each project's style and contribution guidelines for submitting patches and additions. In general, we follow the "fork-and-pull" Git workflow.
58
79
 
59
- 1. **Fork** the repo on GitHub
60
- 2. **Clone** the project to your own machine
61
- 3. **Update the Version** inside __init__.py
62
- 4. **Commit** changes to your own branch
63
- 5. **Push** your work back up to your fork
64
- 6. Submit a **Pull request** so that we can review your changes
80
+ 1. **Fork** the repo on GitHub
81
+ 2. **Clone** the project to your own machine
82
+ 3. **Update the Version** inside **init**.py
83
+ 4. **Commit** changes to your own branch
84
+ 5. **Push** your work back up to your fork
85
+ 6. Submit a **Pull request** so that we can review your changes
@@ -1,18 +1,6 @@
1
- Metadata-Version: 2.1
2
- Name: partialjson
3
- Version: 0.0.7
4
- Summary: Parse incomplete or partial json
5
- Home-page: https://github.com/iw4p/partialjson
6
- Author: Nima Akbarzadeh
7
- Author-email: iw4p@protonmail.com
8
- License: MIT
9
- Description-Content-Type: text/markdown
10
- License-File: LICENSE
11
-
12
1
  # PartialJson
13
2
 
14
- [![Partialjson](https://github.com/iw4p/partialjson/raw/main/images/partialjson.png
15
- )](https://pypi.org/project/partialjson/)
3
+ [![Partialjson](https://github.com/iw4p/partialjson/raw/main/images/partialjson.png)](https://pypi.org/project/partialjson/)
16
4
 
17
5
  ## Parse Partial and incomplete JSON in python
18
6
 
@@ -24,41 +12,56 @@ License-File: LICENSE
24
12
  [![Supported Python versions](https://img.shields.io/pypi/pyversions/partialjson.svg)](#Installation)
25
13
  [![Downloads](https://pepy.tech/badge/partialjson)](https://pepy.tech/project/partialjson)
26
14
 
27
-
28
15
  ## Example
16
+
29
17
  ```python
30
18
  from partialjson.json_parser import JSONParser
31
19
  parser = JSONParser()
32
20
 
33
- incomplete_json = '{"name": "John", "age": 30, "is_student": false, "courses": ["Math", "Science"'
21
+ incomplete_json = '{"name": "John Doe", "age": 30, "is_student": false, "courses": ["Math", "Science"'
34
22
  print(parser.parse(incomplete_json))
35
23
  # {'name': 'John', 'age': 30, 'is_student': False, 'courses': ['Math', 'Science']}
36
24
  ```
37
25
 
26
+ Problem with `\n`? strict mode is here
27
+
28
+ ```python
29
+ from partialjson.json_parser import JSONParser
30
+ parser = JSONParser(strict=False)
31
+
32
+ incomplete_json = '{"name": "John\nDoe", "age": 30, "is_student": false, "courses": ["Math", "Science"'
33
+ print(parser.parse(incomplete_json))
34
+ # {'name': 'John\nDoe', 'age': 30, 'is_student': False, 'courses': ['Math', 'Science']}
35
+ ```
36
+
38
37
  ### Installation
39
38
 
40
39
  ```sh
41
40
  $ pip install partialjson
42
41
  ```
42
+
43
43
  Also can be found on [pypi](https://pypi.org/project/partialjson/)
44
44
 
45
45
  ### How can I use it?
46
- - Install the package by pip package manager.
47
- - After installing, you can use it and call the library.
46
+
47
+ - Install the package by pip package manager.
48
+ - After installing, you can use it and call the library.
48
49
 
49
50
  ## Star History
50
51
 
51
52
  [![Star History Chart](https://api.star-history.com/svg?repos=iw4p/partialjson&type=Date)](https://star-history.com/#iw4p/partialjson&Date)
52
53
 
53
54
  ### Issues
55
+
54
56
  Feel free to submit issues and enhancement requests or contact me via [vida.page/nima](https://vida.page/nima).
55
57
 
56
58
  ### Contributing
59
+
57
60
  Please refer to each project's style and contribution guidelines for submitting patches and additions. In general, we follow the "fork-and-pull" Git workflow.
58
61
 
59
- 1. **Fork** the repo on GitHub
60
- 2. **Clone** the project to your own machine
61
- 3. **Update the Version** inside __init__.py
62
- 4. **Commit** changes to your own branch
63
- 5. **Push** your work back up to your fork
64
- 6. Submit a **Pull request** so that we can review your changes
62
+ 1. **Fork** the repo on GitHub
63
+ 2. **Clone** the project to your own machine
64
+ 3. **Update the Version** inside **init**.py
65
+ 4. **Commit** changes to your own branch
66
+ 5. **Push** your work back up to your fork
67
+ 6. Submit a **Pull request** so that we can review your changes
@@ -3,10 +3,11 @@ Partial Json.
3
3
 
4
4
  Parsing ChatGPT JSON stream response — Partial and incomplete JSON parser python library for OpenAI
5
5
  """
6
+
6
7
  from .json_parser import JSONParser
7
8
 
8
- __version__ = "0.0.7"
9
- __author__ = 'Nima Akbarzadeh'
9
+ __version__ = "0.0.9"
10
+ __author__ = "Nima Akbarzadeh"
10
11
  __author_email__ = "iw4p@protonmail.com"
11
12
  __license__ = "MIT"
12
13
  __url__ = "https://github.com/iw4p/partialjson"
@@ -16,4 +17,4 @@ PYPI_SIMPLE_ENDPOINT: str = "https://pypi.org/project/partialjson"
16
17
  __all__ = [
17
18
  "JSONParser",
18
19
  "PYPI_SIMPLE_ENDPOINT",
19
- ]
20
+ ]
@@ -1,28 +1,33 @@
1
1
  import json
2
+ import re
3
+
2
4
 
3
5
  class JSONParser:
4
- def __init__(self):
6
+ def __init__(self, strict=True):
7
+ self.strict = strict
5
8
  self.parsers = {
6
- ' ': self.parse_space,
7
- '\r': self.parse_space,
8
- '\n': self.parse_space,
9
- '\t': self.parse_space,
10
- '[': self.parse_array,
11
- '{': self.parse_object,
9
+ " ": self.parse_space,
10
+ "\r": self.parse_space,
11
+ "\n": self.parse_space,
12
+ "\t": self.parse_space,
13
+ "[": self.parse_array,
14
+ "{": self.parse_object,
12
15
  '"': self.parse_string,
13
- 't': self.parse_true,
14
- 'f': self.parse_false,
15
- 'n': self.parse_null
16
+ "t": self.parse_true,
17
+ "f": self.parse_false,
18
+ "n": self.parse_null,
16
19
  }
17
- # Adding parsers for numbers
18
- for c in '0123456789.-':
20
+ for c in "0123456789.-":
19
21
  self.parsers[c] = self.parse_number
20
22
 
21
23
  self.last_parse_reminding = None
22
24
  self.on_extra_token = self.default_on_extra_token
23
25
 
24
26
  def default_on_extra_token(self, text, data, reminding):
25
- print('Parsed JSON with extra tokens:', {'text': text, 'data': data, 'reminding': reminding})
27
+ print(
28
+ "Parsed JSON with extra tokens:",
29
+ {"text": text, "data": data, "reminding": reminding},
30
+ )
26
31
 
27
32
  def parse(self, s):
28
33
  if len(s) >= 1:
@@ -33,7 +38,7 @@ class JSONParser:
33
38
  self.last_parse_reminding = reminding
34
39
  if self.on_extra_token and reminding:
35
40
  self.on_extra_token(s, data, reminding)
36
- return json.loads(json.dumps(data))
41
+ return data
37
42
  else:
38
43
  return json.loads("{}")
39
44
 
@@ -53,13 +58,13 @@ class JSONParser:
53
58
  acc = []
54
59
  s = s.strip()
55
60
  while s:
56
- if s[0] == ']':
61
+ if s[0] == "]":
57
62
  s = s[1:] # skip ending ']'
58
63
  break
59
64
  res, s = self.parse_any(s, e)
60
65
  acc.append(res)
61
66
  s = s.strip()
62
- if s.startswith(','):
67
+ if s.startswith(","):
63
68
  s = s[1:]
64
69
  s = s.strip()
65
70
  return acc, s
@@ -69,79 +74,95 @@ class JSONParser:
69
74
  acc = {}
70
75
  s = s.strip()
71
76
  while s:
72
- if s[0] == '}':
77
+ if s[0] == "}":
73
78
  s = s[1:] # skip ending '}'
74
79
  break
75
80
  key, s = self.parse_any(s, e)
76
81
  s = s.strip()
77
82
 
78
- # Handle case where object ends after a key
79
- if not s or s[0] == '}':
83
+ if not s or s[0] == "}":
80
84
  acc[key] = None
81
85
  break
82
86
 
83
- # Expecting a colon after the key
84
- if s[0] != ':':
87
+ if s[0] != ":":
85
88
  raise e # or handle this scenario as per your requirement
86
89
 
87
90
  s = s[1:] # skip ':'
88
91
  s = s.strip()
89
92
 
90
- # Handle case where value is missing or incomplete
91
- if not s or s[0] in ',}':
93
+ if not s or s[0] in ",}":
92
94
  acc[key] = None
93
- if s.startswith(','):
95
+ if s.startswith(","):
94
96
  s = s[1:]
95
97
  break
96
98
 
97
99
  value, s = self.parse_any(s, e)
98
100
  acc[key] = value
99
101
  s = s.strip()
100
- if s.startswith(','):
102
+ if s.startswith(","):
101
103
  s = s[1:]
102
104
  s = s.strip()
103
105
  return acc, s
104
106
 
105
107
  def parse_string(self, s, e):
108
+ incomplete_escape_regex = re.compile(r"^\\(?:u[0-9a-fA-F]{0,3})?$")
106
109
  end = s.find('"', 1)
107
- while end != -1 and s[end - 1] == '\\': # Handle escaped quotes
110
+ while end != -1 and s[end - 1] == "\\": # Handle escaped quotes
108
111
  end = s.find('"', end + 1)
109
112
  if end == -1:
110
- # Return the incomplete string without the opening quote
111
- return s[1:], ""
112
- str_val = s[:end + 1]
113
- s = s[end + 1:]
113
+ # Incomplete string: handle it based on strict mode
114
+ if not self.strict:
115
+ # Check for incomplete escape sequences
116
+ if incomplete_escape_regex.match(s[1:]):
117
+ return s[1:], ""
118
+ return s[1:], ""
119
+ else:
120
+ # Check for incomplete escape sequences
121
+ if incomplete_escape_regex.match(s[1:]):
122
+ return s[1:], ""
123
+ # Attempt to parse the string without incomplete escape sequences
124
+ try:
125
+ return json.loads(f'"{s[1:]}"'), ""
126
+ except json.JSONDecodeError:
127
+ return s[1:], ""
128
+ str_val = s[: end + 1]
129
+ s = s[end + 1 :]
130
+ if not self.strict:
131
+ return str_val[1:-1], s # Remove surrounding quotes for strict mode
114
132
  return json.loads(str_val), s
115
133
 
116
134
  def parse_number(self, s, e):
117
135
  i = 0
118
- while i < len(s) and s[i] in '0123456789.-':
136
+ while i < len(s) and s[i] in "0123456789.-":
119
137
  i += 1
120
138
  num_str = s[:i]
121
139
  s = s[i:]
122
140
  if not num_str or num_str == "-" or num_str == ".":
123
141
  return num_str, ""
124
142
  try:
125
- if num_str.endswith('.'):
143
+ if num_str.endswith("."):
126
144
  num = int(num_str[:-1])
127
145
  else:
128
- num = float(num_str) if '.' in num_str or 'e' in num_str or 'E' in num_str else int(num_str)
146
+ num = (
147
+ float(num_str)
148
+ if "." in num_str or "e" in num_str or "E" in num_str
149
+ else int(num_str)
150
+ )
129
151
  except ValueError:
130
152
  raise e
131
153
  return num, s
132
154
 
133
155
  def parse_true(self, s, e):
134
- if s.startswith('t') or s.startswith('T'):
156
+ if s.startswith("t") or s.startswith("T"):
135
157
  return True, s[4:]
136
158
  raise e
137
159
 
138
160
  def parse_false(self, s, e):
139
- if s.startswith('f') or s.startswith('F'):
161
+ if s.startswith("f") or s.startswith("F"):
140
162
  return False, s[5:]
141
163
  raise e
142
164
 
143
165
  def parse_null(self, s, e):
144
- if s.startswith('n'):
166
+ if s.startswith("n"):
145
167
  return None, s[4:]
146
168
  raise e
147
-
@@ -1,7 +1,24 @@
1
+ Metadata-Version: 2.2
2
+ Name: partialjson
3
+ Version: 0.0.9
4
+ Summary: Parse incomplete or partial json
5
+ Home-page: https://github.com/iw4p/partialjson
6
+ Author: Nima Akbarzadeh
7
+ Author-email: iw4p@protonmail.com
8
+ License: MIT
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+ Dynamic: author
12
+ Dynamic: author-email
13
+ Dynamic: description
14
+ Dynamic: description-content-type
15
+ Dynamic: home-page
16
+ Dynamic: license
17
+ Dynamic: summary
18
+
1
19
  # PartialJson
2
20
 
3
- [![Partialjson](https://github.com/iw4p/partialjson/raw/main/images/partialjson.png
4
- )](https://pypi.org/project/partialjson/)
21
+ [![Partialjson](https://github.com/iw4p/partialjson/raw/main/images/partialjson.png)](https://pypi.org/project/partialjson/)
5
22
 
6
23
  ## Parse Partial and incomplete JSON in python
7
24
 
@@ -13,41 +30,56 @@
13
30
  [![Supported Python versions](https://img.shields.io/pypi/pyversions/partialjson.svg)](#Installation)
14
31
  [![Downloads](https://pepy.tech/badge/partialjson)](https://pepy.tech/project/partialjson)
15
32
 
16
-
17
33
  ## Example
34
+
18
35
  ```python
19
36
  from partialjson.json_parser import JSONParser
20
37
  parser = JSONParser()
21
38
 
22
- incomplete_json = '{"name": "John", "age": 30, "is_student": false, "courses": ["Math", "Science"'
39
+ incomplete_json = '{"name": "John Doe", "age": 30, "is_student": false, "courses": ["Math", "Science"'
23
40
  print(parser.parse(incomplete_json))
24
41
  # {'name': 'John', 'age': 30, 'is_student': False, 'courses': ['Math', 'Science']}
25
42
  ```
26
43
 
44
+ Problem with `\n`? strict mode is here
45
+
46
+ ```python
47
+ from partialjson.json_parser import JSONParser
48
+ parser = JSONParser(strict=False)
49
+
50
+ incomplete_json = '{"name": "John\nDoe", "age": 30, "is_student": false, "courses": ["Math", "Science"'
51
+ print(parser.parse(incomplete_json))
52
+ # {'name': 'John\nDoe', 'age': 30, 'is_student': False, 'courses': ['Math', 'Science']}
53
+ ```
54
+
27
55
  ### Installation
28
56
 
29
57
  ```sh
30
58
  $ pip install partialjson
31
59
  ```
60
+
32
61
  Also can be found on [pypi](https://pypi.org/project/partialjson/)
33
62
 
34
63
  ### How can I use it?
35
- - Install the package by pip package manager.
36
- - After installing, you can use it and call the library.
64
+
65
+ - Install the package by pip package manager.
66
+ - After installing, you can use it and call the library.
37
67
 
38
68
  ## Star History
39
69
 
40
70
  [![Star History Chart](https://api.star-history.com/svg?repos=iw4p/partialjson&type=Date)](https://star-history.com/#iw4p/partialjson&Date)
41
71
 
42
72
  ### Issues
73
+
43
74
  Feel free to submit issues and enhancement requests or contact me via [vida.page/nima](https://vida.page/nima).
44
75
 
45
76
  ### Contributing
77
+
46
78
  Please refer to each project's style and contribution guidelines for submitting patches and additions. In general, we follow the "fork-and-pull" Git workflow.
47
79
 
48
- 1. **Fork** the repo on GitHub
49
- 2. **Clone** the project to your own machine
50
- 3. **Update the Version** inside __init__.py
51
- 4. **Commit** changes to your own branch
52
- 5. **Push** your work back up to your fork
53
- 6. Submit a **Pull request** so that we can review your changes
80
+ 1. **Fork** the repo on GitHub
81
+ 2. **Clone** the project to your own machine
82
+ 3. **Update the Version** inside **init**.py
83
+ 4. **Commit** changes to your own branch
84
+ 5. **Push** your work back up to your fork
85
+ 6. Submit a **Pull request** so that we can review your changes
@@ -0,0 +1,34 @@
1
+ import os.path
2
+ import pathlib
3
+ import re
4
+
5
+ from setuptools import setup
6
+
7
+ PROJECT_NAME = "partialjson"
8
+ # The directory containing this file
9
+ HERE = pathlib.Path(__file__).parent
10
+
11
+ # The text of the README file
12
+ README = (HERE / "README.md").read_text()
13
+
14
+
15
+ def get_property(prop):
16
+ result = re.search(
17
+ r'{}\s*=\s*[\'"]([^\'"]*)[\'"]'.format(prop),
18
+ open(os.path.join(PROJECT_NAME, "__init__.py")).read(),
19
+ )
20
+ return result.group(1)
21
+
22
+
23
+ setup(
24
+ name="partialjson",
25
+ version=get_property("__version__"),
26
+ description="Parse incomplete or partial json",
27
+ long_description=README,
28
+ long_description_content_type="text/markdown",
29
+ url=get_property("__url__"),
30
+ author=get_property("__author__"),
31
+ author_email=get_property("__author_email__"),
32
+ license=get_property("__license__"),
33
+ packages=["partialjson"],
34
+ )
@@ -1,32 +0,0 @@
1
- import os.path
2
- import pathlib
3
- import re
4
-
5
- from setuptools import setup
6
-
7
- PROJECT_NAME = 'partialjson'
8
- # The directory containing this file
9
- HERE = pathlib.Path(__file__).parent
10
-
11
- # The text of the README file
12
- README = (HERE / "README.md").read_text()
13
-
14
-
15
- def get_property(prop):
16
- result = re.search(r'{}\s*=\s*[\'"]([^\'"]*)[\'"]'.format(prop),
17
- open(os.path.join(PROJECT_NAME, '__init__.py')).read())
18
- return result.group(1)
19
-
20
-
21
- setup(
22
- name='partialjson',
23
- version=get_property('__version__'),
24
- description='Parse incomplete or partial json',
25
- long_description=README,
26
- long_description_content_type="text/markdown",
27
- url=get_property('__url__'),
28
- author=get_property('__author__'),
29
- author_email=get_property('__author_email__'),
30
- license=get_property('__license__'),
31
- packages=['partialjson'],
32
- )
File without changes
File without changes