Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
n-takumasa committed Jul 21, 2022
1 parent e316c56 commit 191a316
Show file tree
Hide file tree
Showing 10 changed files with 511 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ profile_default/
ipython_config.py

# pyenv
.python-version
# .python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
Expand Down
4 changes: 4 additions & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
3.7.9
3.8.10
3.9.13
3.10.5
3 changes: 3 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
exclude .gitignore
include README.md
include LICENSE
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# JSON with Comments for Python

## Features
* Remove single line (`//`) and block comments (`/* */`)
* Remove trailing commas from arrays and objects

## Usage

```py
import jsonc
```
And just like `json` module
110 changes: 110 additions & 0 deletions jsonc/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
r"""JSON with Comments for Python
>>> import jsonc
>>> jsonc.loads("{// comment \n}")
{}
>>> jsonc.loads("{/* comment */}")
{}
>>> jsonc.loads('{"spam": "ham // egg" /* comment */}')
{'spam': 'ham // egg'}
>>> jsonc.loads('{"spam": /* comment */"ham /* egg */"}')
{'spam': 'ham /* egg */'}
"""

from __future__ import annotations

from typing import TextIO

__version__ = "1.0.0"
import json
import re
from json import dump, dumps # for compatibility

_REMOVE_C_COMMENT = r"""
( # String Literal
\"(?:[^\\\"]|\\\"|\\\\|\\)*?\"
|
\'(?:[^\\\"]|\\\"|\\\\|\\)*?\'
)
|
( # Comment
\/\*.*?\*\/
|
\/\/[^\r\n]*?(?:[\r\n]|\Z)
)
"""


_REMOVE_TRAILING_COMMA = r"""
( # String Literal
\"(?:[^\\\"]|\\\"|\\\\|\\)*?\"
|
\'(?:[^\\\"]|\\\"|\\\\|\\)*?\'
)
| # Right Brace without Trailing Comma & Spaces
,\s*([\]}])
"""


def _remove_c_comment(text: str) -> str:
return re.sub(_REMOVE_C_COMMENT, lambda x: x.group(1), text, flags=re.DOTALL | re.VERBOSE)


def _remove_trailing_comma(text: str) -> str:
return re.sub(_REMOVE_TRAILING_COMMA, lambda x: x.group(1) or x.group(2), text, flags=re.DOTALL | re.VERBOSE)


def load(
fp: TextIO,
*,
cls=None,
object_hook=None,
parse_float=None,
parse_int=None,
parse_constant=None,
object_pairs_hook=None,
**kw,
):
"""Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
a JSON document) to a Python object.
Reference: ``json.load``
"""
return json.loads(
_remove_trailing_comma(_remove_c_comment(fp.read())),
cls=cls,
object_hook=object_hook,
parse_float=parse_float,
parse_int=parse_int,
parse_constant=parse_constant,
object_pairs_hook=object_pairs_hook,
**kw,
)


def loads(
s: str,
*,
cls=None,
object_hook=None,
parse_float=None,
parse_int=None,
parse_constant=None,
object_pairs_hook=None,
**kw,
):
"""Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance
containing a JSON document) to a Python object.
Reference: ``json.loads``
"""
return json.loads(
_remove_trailing_comma(_remove_c_comment(s)),
cls=cls,
object_hook=object_hook,
parse_float=parse_float,
parse_int=parse_int,
parse_constant=parse_constant,
object_pairs_hook=object_pairs_hook,
**kw,
)
Loading

0 comments on commit 191a316

Please sign in to comment.