From fac1a8b05607ca834dd8cf9b6792e5a2fa8bde74 Mon Sep 17 00:00:00 2001 From: John Millikin Date: Mon, 26 Aug 2019 12:48:10 +0900 Subject: [PATCH] proposal: JSON Module --- proposals/2019-08-26-json-module.md | 99 +++++++++++++++++++++++++++++ proposals/README.md | 1 + 2 files changed, 100 insertions(+) create mode 100644 proposals/2019-08-26-json-module.md diff --git a/proposals/2019-08-26-json-module.md b/proposals/2019-08-26-json-module.md new file mode 100644 index 0000000..7780efa --- /dev/null +++ b/proposals/2019-08-26-json-module.md @@ -0,0 +1,99 @@ +--- +title: JSON Module +status: Draft +created: 2019-08-26 +updated: 2019-08-26 +authors: + - [jmillikin](https://john-millikin.com) +reviewers: + - Starlark core reviewers +discussion thread: [#](https://github.com/bazelbuild/starlark/issues/) +--- + +# JSON Module + +## Abstract + +This document proposes an API for encoding and decoding JSON from Starlark. If accepted, implementations of Starlark +that implement JSON support would be expected to implement this API. The goal is to allow users to write JSON code that +behaves consistently across Starlark implementations. + +## Background + +JSON is a popular syntax for representing basic data structures. Partial support for parsing or serializing JSON from +Starlark has been independently requested and/or implemented several times: + +* Bazel's [`struct`](https://docs.bazel.build/versions/master/skylark/lib/struct.html) type has a `to_json()` method + that can generate JSON documents. Issue [bazelbuild/bazel#7879](https://github.com/bazelbuild/bazel/issues/7879) + requests additional control over the behavior of this method (i.e. optional whitespace). + +* [bazelbuild/bazel#3732](https://github.com/bazelbuild/bazel/issues/3732) requests support for parsing JSON from + within a Bazel repository rule, for use with introspecting the state of external tools. + +* [`json_parser.bzl`](https://github.com/erickj/bazel_json) is a JSON parser implemented entirely within Starlark. + Limitations of the Starlark language prevent this parser from being recommended for production use. + +* [google/starlark-go#179](https://github.com/google/starlark-go/pull/179) proposes a JSON module for the Go + implementation of starlark. + +* [Skycfg](https://github.com/stripe/skycfg) has a `json.marshal()` method that can generate JSON documents, for use + with config formats based on JSON syntax. + +JSON implementations in the broader community have wildly variant APIs. It is likely that ad-hoc JSON extensions to +Starlark will have different APIs between Starlark implementations. + +## Proposed API + +The JSON module is a value named `json` in the global namespace. Its API comprises the following functions. Starlark +implementations are not required to support the entire API, but should avoid extending the API with non-standard +functions or parameters. + +JSON implementations should comply with the format documented as +[ECMA-404](https://www.ecma-international.org/publications/standards/Ecma-404.htm) and +[RFC 8259](https://www.rfc-editor.org/rfc/rfc8259.html), which supercedes earlier drafts of JSON. In particular, the +only permitted character encoding for contemporary JSON is UTF-8. + +To maintain compatibility with existing callers, new required parameters should not be added to these functions. New +optional parameters should be defined using keyword-only parameters +([PEP-3102](https://www.python.org/dev/peps/pep-3102/)). + +### json.decode() + +The `json.decode()` function decodes a JSON document into a Starlark value. + +```python +def json.decode(data): +``` + +Type conversions are: +* JSON arrays are decoded to Starlark `list` values. Key are in the same order as the input data. +* JSON objects are decoded to Starlark `dict` values. +* JSON `true`, `false`, and `null` literals are decoded to Starlark `True`, `False`, and `None` respectively. +* JSON strings are decoded to Starlark `string` values. +* JSON numbers with no fractional component are decoded to Starlark `int` values. Starlark implementations without + arbitrary-precision integers should reject numbers that exceed their supported range. +* JSON numbers with a fractional component may be decoded to an arbitrary-precision or floating-point value, if + supported by the current Starlark implementation. + * Starlark implementations without arbitrary-precision numeric values should reject numbers that exceed their + supported range. + +### json.encode() + +```python +json.encode(value, *, indent=None, sort_keys=False) +``` + +Type conversions are: +* Starlark `list` and `tuple` values are encoded to JSON arrays. +* Starlark `dict` values are encoded to JSON objects. +* Starlark values `True`, `False`, and `None` are encoded to JSON `true`, `false`, and `null` respectively. +* Starlark strings are encoded to JSON strings. +* Starlark `int` values are encoded to JSON numbers. + +Starlark implementations may support encoding other types + +If `indent` is a number, it is how many spaces to indent by. Indent levels less than 1 will only insert newlines. +If `indent` is `None` (the default), JSON will be encoded in one line with no extra spaces. + +If `sort_keys` is `True`, then encoded objects' keys are sorted in lexicographical order. If `sort_keys` is `False` +(the default), then object keys are in the same order as the `dict` keys. diff --git a/proposals/README.md b/proposals/README.md index 7c3be3e..1366763 100644 --- a/proposals/README.md +++ b/proposals/README.md @@ -6,5 +6,6 @@ proposal, see the [design process](../process.md). Last updated | Status | Title | Author(s) | Category ------------ | ------ | ------| ----------| -------- +2019-08-26 | Draft | [JSON Module](https://github.com/bazelbuild/starlark/blob/master/proposals/2019-08-26-json-module.md) | [jmillikin](https://john-millikin.com) | Modules 2018-08-17 | Draft | [Genrule setup for Starlark](https://github.com/bazelbuild/starlark/blob/master/proposals/2018-08-17-genrule-setup-for-starlark.md) | [brandjon@](https://github.com/brandjon) | Actions 2018-10-03 | Draft | [ToolchainInfo Schema](https://github.com/bazelbuild/starlark/blob/master/proposals/2018-10-03-toolchaininfo-schema.md) | [brandjon@](https://github.com/brandjon) | Toolchains