Skip to content

Commit

Permalink
Add custom encoding to dump/dumps. (#88)
Browse files Browse the repository at this point in the history
Add support for custom encoders (and bump version to 0.10.0).

This change reimplements `dump()` and `dumps()` on top of a  `JSON5Encoder` class that can be subclassed to customize the encoding of a data structure. The new class is somewhat similar to the `JSONEncoder` class in the standard library, except that in addition to a `default()` method that you can define to say how to encode an object that the normal encoder can't handle, there's also an `encode()` method that you can override to customize how existing data types are handled.

The change also adds a `quote_style` argument that can be used to customize how strings are encoded (whether to use double or single quotes by default, etc.).
  • Loading branch information
dpranke authored Nov 26, 2024
1 parent 9adb352 commit 3bc470c
Show file tree
Hide file tree
Showing 14 changed files with 1,040 additions and 742 deletions.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,32 @@ $ git push --tags origin

## Version History / Release Notes

* v0.10.0 (2024-11-25)
* [GitHub issue #57](https://github.com/dpranke/pyjson5/issues/57).
Added a `JSON5Encoder` class that can be overridden to do custom
encoding of values. This class is vaguely similar to the `JSONEncoder`
class in the standard `json` library, except that it has an
`encode()` method that can be overridden to customize *any*
value, not just ones the standard encoder doesn't know how to handle.
It does also support a `default()` method that can be used to
encode things not normally encodable, like the JSONEncoder class.
It does not support an `iterencode` method. One could probably
be added in the future, although exactly how that would work and
interact with `encode` is a little unclear.
* Restructured the code to use the new encoder class; doing so actually
allowed me to delete a bunch of tediously duplicative code.
* Added a new `quote_style` argument to `dump()`/`dumps()` to control
how strings are encoded by default. For compatibility with older
versions of the json5 library and the standard json library, it
uses `QuoteStyle.ALWAYS_DOUBLE` which encodes all strings with double
quotes all the time. You can also configure it to use single quotes
all the time (`ALWAYS_SINGLE`), and to switch between single and double
when doing so eliminates a need to escape quotes (`PREFER_SINGLE` and
`PREFER_DOUBLE`). This also adds a `--quote-style` argument to
`python -m json5`.
* This release has a fair number of changes, but is intended to be
completely backwards-compatible. Code without changes should run exactly
as it did before.
* v0.9.28 (2024-11-11)
* Fix GitHub CI to install `uv` so `./run tests` works properly.
* Mark Python3.13 as supported in package metadata.
Expand Down
8 changes: 5 additions & 3 deletions json5/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@

"""A pure Python implementation of the JSON5 configuration language."""

from .lib import load, loads, dump, dumps
from .version import __version__, VERSION
from json5.lib import JSON5Encoder, QuoteStyle, load, loads, dump, dumps
from json5.version import __version__, VERSION


__all__ = [
'__version__',
'JSON5Encoder',
'QuoteStyle',
'VERSION',
'__version__',
'dump',
'dumps',
'load',
Expand Down
8 changes: 5 additions & 3 deletions json5/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import sys # pragma: no cover
# pragma: no cover

from .tool import main # pragma: no cover
import sys

from json5.tool import main

if __name__ == '__main__': # pragma: no cover

if __name__ == '__main__':
sys.exit(main())
61 changes: 0 additions & 61 deletions json5/arg_parser.py

This file was deleted.

8 changes: 4 additions & 4 deletions json5/host.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ def join(self, *comps):
def mkdtemp(self, **kwargs):
return tempfile.mkdtemp(**kwargs)

def print_(self, msg='', end='\n', stream=None):
stream = stream or self.stdout
stream.write(str(msg) + end)
stream.flush()
def print(self, msg='', end='\n', file=None):
file = file or self.stdout
file.write(str(msg) + end)
file.flush()

def rmtree(self, path):
shutil.rmtree(path, ignore_errors=True)
Expand Down
Loading

0 comments on commit 3bc470c

Please sign in to comment.