Skip to content

Instantly share code, notes, and snippets.

@spyoungtech
Last active May 26, 2020 04:59
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save spyoungtech/933df1cc0d928d32c8dd5776025c1016 to your computer and use it in GitHub Desktop.
generate json
# Make sure to pip install json-five
from functools import singledispatch, update_wrapper
from json5.model import *
from json5.dumper import ModelDumper
import json5
import random
import string
VALUE_MODELS = [Integer, JSONObject, JSONArray, DoubleQuotedString, SingleQuotedString, Float, NullLiteral,
BooleanLiteral, Infinity, NaN, UnaryOp]
KEY_MODELS = [DoubleQuotedString, SingleQuotedString, Identifier]
NUMBER_MODELS = [Integer, Float, Infinity]
def singledispatchcls(func):
dispatcher = singledispatch(func)
def wrapper(*args, **kwargs):
return dispatcher.dispatch(args[0])(*args, **kwargs)
wrapper.register = dispatcher.register
update_wrapper(wrapper, func)
return wrapper
def generate_json(nonterminal=True):
if nonterminal:
value = generate_node(random.choice([JSONObject, JSONArray]))
else:
value = generate_node(random.choice(VALUE_MODELS))
return JSONText(value=value)
@singledispatchcls
def generate_node(node_type):
raise ValueError(f"Cant generate node of type {node_type}")
generate = generate_node.register
@generate(Integer)
def generate_integer(_):
return Integer(raw_value=str(random.randint(0, 10)))
@generate(String)
def generate_dqs(string_type):
num_chars = random.randint(0, 20)
s = ''.join(random.choice(string.ascii_letters) for _ in range(num_chars))
if isinstance(string_type, DoubleQuotedString):
raw = f'"{s}"'
else:
raw = f"'{s}'"
return string_type(s, raw)
@generate(JSONArray)
def generate_array(_):
num_elements = random.randint(0, 10)
values = [generate_node(random.choice(VALUE_MODELS)) for _ in range(num_elements)]
return JSONArray(*values)
@generate(JSONObject)
def generate_object(_):
num_kvps = random.randint(0, 10)
kvps = [generate_node(KeyValuePair) for _ in range(num_kvps)]
return JSONObject(*kvps)
@generate(KeyValuePair)
def generate_kvp(_):
key = generate_node(random.choice(KEY_MODELS))
value = generate_node(random.choice(VALUE_MODELS))
return KeyValuePair(key=key, value=value)
@generate(Identifier)
def generate_identifier(_):
length = random.randint(1, 10)
name = ''.join(random.choice(string.ascii_letters) for _ in range(length))
return Identifier(name=name)
@generate(Float)
def generate_float(_):
f = str(random.uniform(0, 10))
return Float(raw_value=f)
@generate(BooleanLiteral)
def generate_bool(_):
return BooleanLiteral(random.choice([True, False]))
@generate(Infinity)
def generate_inf(_):
return Infinity()
@generate(NaN)
def generate_nan(_):
return NaN()
@generate(UnaryOp)
def generate_unary(_):
op = random.choice(['-', '+'])
value = generate_node(random.choice(NUMBER_MODELS))
return UnaryOp(op, value)
@generate(NullLiteral)
def generate_null(_):
return NullLiteral()
def main():
model = generate_json()
print(json5.dumps(model, dumper=ModelDumper()))
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment