Skip to content

Commit

Permalink
tests n docs
Browse files Browse the repository at this point in the history
  • Loading branch information
ctomkow committed Sep 9, 2024
1 parent 9ba5122 commit da2a42f
Show file tree
Hide file tree
Showing 5 changed files with 396 additions and 84 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/jsonparse-buildtest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
pip install .[buildtest27]
- name: Test with pytest and generate codecov
run: |
pytest --cov=jsonparse --ignore=tests/test_webapi.py
pytest --cov=jsonparse --ignore=tests/test_webapi.py --ignore=tests/test_parser.py
- uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
> **jsonparse** is a simple JSON parsing library. Extract what's needed from key:value pairs.
## What's New
- Python 2.7 compat. :sweat_smile: :relieved:
- A new function, [find_value](#find_value), has been added. This function will return all keys of the matched value. :grinning:
- [CLI tool](#CLI-tool). Parse json text files or stdin via the command line :tada:

Expand Down Expand Up @@ -221,6 +222,10 @@ find_value(data, False)
['cable']
```

# Python 2.7 Usage

- 2.7 does not guarantee ordering of dictionary's. If ordering matters, use [OrderedDict](https://docs.python.org/2.7/library/collections.html) for all dictionary's in the data.

# Web API

## Documentation
Expand Down
32 changes: 16 additions & 16 deletions src/jsonparse/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def __init__(self, stack_trace=False, queue_trace=False):
self.queue_ref = self._queue_init()

def find_key(self, data, key):
# type: (Union[dict, list], str) -> list
# type: (Union[dict, list, OrderedDict], str) -> list
if not self._valid_key_input(data, key):
raise

Expand Down Expand Up @@ -80,7 +80,7 @@ def find_key(self, data, key):
return value_list

def find_keys(self, data, keys, group=True):
# type: (Union[dict, list], list, bool) -> list
# type: (Union[dict, list, OrderedDict], list, bool) -> list
if not self._valid_keys_input(data, keys, group):
raise

Expand Down Expand Up @@ -110,7 +110,7 @@ def find_keys(self, data, keys, group=True):
return value_list

def find_key_chain(self, data, keys):
# type: (Union[dict, list], list) -> list
# type: (Union[dict, list, OrderedDict], list) -> list
if not self._valid_key_chain_input(data, keys):
raise

Expand Down Expand Up @@ -148,7 +148,7 @@ def find_key_chain(self, data, keys):
return self.queue_ref

def find_key_value(self, data, key, value):
# type: (Union[dict, list], str, Union[str, int, float, bool, None]) -> list
# type: (Union[dict, list, OrderedDict], str, Union[str, int, float, bool, None]) -> list
if not self._valid_key_value_input(data, key, value):
raise

Expand All @@ -174,7 +174,7 @@ def find_key_value(self, data, key, value):
return value_list

def find_value(self, data, value):
# type: (Union[dict, list], Union[str, int, float, bool, None]) -> list
# type: (Union[dict, list, OrderedDict], Union[str, int, float, bool, None]) -> list
if not self._valid_value_input(data, value):
raise

Expand Down Expand Up @@ -208,18 +208,18 @@ def _stack_init(self):
return stack

def _stack_push(self, elem):
# type: (Union[dict, list]) -> None
# type: (Union[dict, list, OrderedDict]) -> None
self.stack_ref.append(elem)

def _stack_pop(self):
# type: () -> Union[dict, list]
# type: () -> Union[dict, list, OrderedDict]
try:
return self.stack_ref.pop()
except IndexError:
raise

def _stack_peak(self):
# type: () -> Union[dict, list]
# type: () -> Union[dict, list, OrderedDict]
try:
return self.stack_ref[-1:][0]
except IndexError:
Expand All @@ -242,7 +242,7 @@ def _stack_push_list_elem(self, elem):
self._stack_trace()

def _stack_all_key_values_in_dict(self, key, elem):
# type: (str, dict) -> list
# type: (str, Union[dict, OrderedDict]) -> list
value_list = []

if not isinstance(elem, (dict, OrderedDict)):
Expand All @@ -262,7 +262,7 @@ def _stack_all_key_values_in_dict(self, key, elem):
return value_list

def _stack_all_keys_values_in_dict(self, keys, elem):
# type: (list, dict) -> list
# type: (list, Union[dict, OrderedDict]) -> list
value_list = []

if not isinstance(elem, (dict, OrderedDict)):
Expand All @@ -285,7 +285,7 @@ def _stack_all_keys_values_in_dict(self, keys, elem):
return value_list

def _stack_all_key_and_value_in_dict(self, key, value, elem):
# type: (str, Union[str, int, float, bool, None], dict) -> bool
# type: (str, Union[str, int, float, bool, None], Union[dict, OrderedDict]) -> bool
if not isinstance(elem, (dict, OrderedDict)):
raise TypeError
elif type(key) is not str:
Expand All @@ -305,7 +305,7 @@ def _stack_all_key_and_value_in_dict(self, key, value, elem):
return False

def _stack_all_value_in_dict(self, value, elem):
# type: (Union[str, int, float, bool, None], dict) -> str
# type: (Union[str, int, float, bool, None], Union[dict, OrderedDict]) -> str
if not isinstance(elem, (dict, OrderedDict)):
raise TypeError
elif not isinstance(value, (str, int, float, bool, type(None))):
Expand Down Expand Up @@ -339,18 +339,18 @@ def _queue_init(self):
return queue

def _queue_push(self, elem):
# type: (Union[dict, list]) -> None
# type: (Union[dict, list, OrderedDict]) -> None
self.queue_ref.append(elem)

def _queue_pop(self):
# type: () -> Union[dict, list]
# type: () -> Union[dict, list, OrderedDict]
try:
return self.queue_ref.pop(0)
except IndexError:
raise

def _queue_peak(self):
# type: () -> Union[dict, list]
# type: () -> Union[dict, list, OrderedDict]
try:
return self.queue_ref[0]
except IndexError:
Expand All @@ -373,7 +373,7 @@ def _queue_push_list_elem(self, elem):
self._queue_trace()

def _queue_all_key_values_in_dict(self, key, elem):
# type: (str, dict) -> bool
# type: (str, Union[dict, OrderedDict]) -> bool
found = False
if not isinstance(elem, (dict, OrderedDict)):
raise TypeError
Expand Down
143 changes: 76 additions & 67 deletions tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# local imports
from jsonparse.parser import Parser
from collections import OrderedDict, deque
from collections import OrderedDict

# 3rd part imports
import pytest
Expand All @@ -21,72 +21,81 @@ def parser(self):
def complex_json(self):

return [
OrderedDict([
("id", "0001"),
("type", "donut"),
("exists", True),
("ppu", 0.55),
("batters", OrderedDict([
("batter", [
OrderedDict([("id", "1001"), ("type", "Reg")]),
OrderedDict([("id", "1002"), ("type", "Chocolate")]),
OrderedDict([("id", "1003"), ("type", "Blueberry")]),
OrderedDict([("id", "1004"), ("type", "Devil's Food")]),
OrderedDict([("start", 5), ("end", 8)])
])
])),
("topping", [
OrderedDict([("id", "5001"), ("ty", "None")]),
OrderedDict([("id", "5002"), ("type", "Glazed")]),
OrderedDict([("id", "5003"), ("type", "Sugar")]),
OrderedDict([("id", "5004"), ("type", "Powdered Sugar")]),
OrderedDict([("id", "5005"), ("type", "Chocolate with Sprinkles")]),
OrderedDict([("id", "5006"), ("type", "Chocolate")]),
OrderedDict([("id", "5007"), ("type", "Maple")])
]),
("start", 22),
("end", 99)
]),
OrderedDict([
("id", "0002"),
("type", "donut"),
("exists", False),
("ppu", 42),
("batters", OrderedDict([
("batter", [
OrderedDict([("id", "1001"), ("type", "Rul")])
])
])),
("top_stuff", [
OrderedDict([("id", "5001"), ("typ", "None")]),
OrderedDict([("id", "5002"), ("type", "Glazed")]),
OrderedDict([("id", "5003"), ("type", "Sugar")]),
OrderedDict([("id", "5004"), ("type", "Chocolate")]),
OrderedDict([("id", "5005"), ("type", "Maple")])
]),
("start", 1),
("end", 9)
]),
OrderedDict([
("id", "0003"),
("type", "donut"),
("exists", None),
("ppu", 7),
("batters", OrderedDict([
("batter", [
OrderedDict([("id", "1001"), ("type", "Lar")]),
OrderedDict([("id", "1002"), ("type", "Chocolate")])
])
])),
("on_top_thing", [
OrderedDict([("id", "5001"), ("type", "None")]),
OrderedDict([("id", "5002"), ("type", "Glazed")]),
OrderedDict([("id", "5003"), ("type", "Chocolate")]),
OrderedDict([("id", "5004"), ("type", "Maple")])
]),
("start", 4),
("end", 7)
])
{
"id": "0001",
"type": "donut",
"exists": True,
"ppu": 0.55,
"batters":
{
"batter":
[
{"id": "1001", "type": "Reg"},
{"id": "1002", "type": "Chocolate"},
{"id": "1003", "type": "Blueberry"},
{"id": "1004", "type": "Devil's Food"},
{"start": 5, "end": 8}
]
},
"topping":
[
{"id": "5001", "ty": "None"},
{"id": "5002", "type": "Glazed"},
{"id": "5003", "type": "Sugar"},
{"id": "5004", "type": "Powdered Sugar"},
{"id": "5005", "type": "Chocolate with Sprinkles"},
{"id": "5006", "type": "Chocolate"},
{"id": "5007", "type": "Maple"}
],
"start": 22,
"end": 99
},
{
"id": "0002",
"type": "donut",
"exists": False,
"ppu": 42,
"batters":
{
"batter":
[
{"id": "1001", "type": "Rul"}
]
},
"top_stuff":
[
{"id": "5001", "typ": "None"},
{"id": "5002", "type": "Glazed"},
{"id": "5003", "type": "Sugar"},
{"id": "5004", "type": "Chocolate"},
{"id": "5005", "type": "Maple"}
],
"start": 1,
"end": 9
},
{
"id": "0003",
"type": "donut",
"exists": None,
"ppu": 7,
"batters":
{
"batter":
[
{"id": "1001", "type": "Lar"},
{"id": "1002", "type": "Chocolate"}
]
},
"on_top_thing":
[
{"id": "5001", "type": "None"},
{"id": "5002", "type": "Glazed"},
{"id": "5003", "type": "Chocolate"},
{"id": "5004", "type": "Maple"}
],
"start": 4,
"end": 7
}
]

def test_find_key(self, parser, complex_json):
Expand Down
Loading

0 comments on commit da2a42f

Please sign in to comment.