diff -Nru pycson-0.7/cson/parser.py pycson-0.8/cson/parser.py --- pycson-0.7/cson/parser.py 2016-07-22 18:36:08.000000000 +0000 +++ pycson-0.8/cson/parser.py 2019-01-22 17:55:40.000000000 +0000 @@ -168,7 +168,7 @@ with p: return int(p('0x[0-9a-fA-F]+')[2:], 16) with p: - return float(p(r'-?(?:[1-9][0-9]*|0)?\.[0-9]+(?:e[\+-]?[0-9]+)?|(?:[1-9][0-9]*|0)(?:\.[0-9]+)e[\+-]?[0-9]+')) + return float(p(r'-?(?:[1-9][0-9]*|0)?\.[0-9]+(?:[Ee][\+-]?[0-9]+)?|(?:[1-9][0-9]*|0)(?:\.[0-9]+)?[Ee][\+-]?[0-9]+')) with p: return int(p('-?[1-9][0-9]*|0'), 10) diff -Nru pycson-0.7/debian/changelog pycson-0.8/debian/changelog --- pycson-0.7/debian/changelog 2019-10-18 18:27:22.000000000 +0000 +++ pycson-0.8/debian/changelog 2020-02-18 20:00:20.000000000 +0000 @@ -1,8 +1,9 @@ -pycson (0.7-3build1) focal; urgency=medium +pycson (0.8-1) unstable; urgency=medium - * No-change rebuild to build with python3.8. + * add a watch file + * New upstream version 0.8 - -- Matthias Klose Fri, 18 Oct 2019 18:27:22 +0000 + -- Norbert Preining Wed, 19 Feb 2020 05:00:20 +0900 pycson (0.7-3) unstable; urgency=medium diff -Nru pycson-0.7/debian/watch pycson-0.8/debian/watch --- pycson-0.7/debian/watch 1970-01-01 00:00:00.000000000 +0000 +++ pycson-0.8/debian/watch 2020-02-18 20:00:20.000000000 +0000 @@ -0,0 +1,3 @@ +version=4 +opts=filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/pycson-$1\.tar\.gz/ \ + https://github.com/avakar/pycson/tags .*/v?(\d\S+)\.tar\.gz diff -Nru pycson-0.7/.gitignore pycson-0.8/.gitignore --- pycson-0.7/.gitignore 2016-07-22 18:36:08.000000000 +0000 +++ pycson-0.8/.gitignore 2019-01-22 17:55:40.000000000 +0000 @@ -1 +1,9 @@ *.pyc +__pycache__/ +*.egg-info/ +.coverage +.tox/ +.pytest_cache/ +.vscode/ +build/ +dist/ diff -Nru pycson-0.7/grammar.md pycson-0.8/grammar.md --- pycson-0.7/grammar.md 2016-07-22 18:36:08.000000000 +0000 +++ pycson-0.8/grammar.md 2019-01-22 17:55:40.000000000 +0000 @@ -1,3 +1,5 @@ +# CSON grammar + This is a formal grammar for the language parsed by pycson. It uses the standard [PEG syntax][1] with an extension to support indent sensitivity: for a PEG expression `E`, diff -Nru pycson-0.7/README.md pycson-0.8/README.md --- pycson-0.7/README.md 2016-07-22 18:36:08.000000000 +0000 +++ pycson-0.8/README.md 2019-01-22 17:55:40.000000000 +0000 @@ -1,12 +1,12 @@ -[![Build Status](https://travis-ci.org/avakar/pycson.svg?branch=master)](https://travis-ci.org/avakar/pycson) - # pycson +[![Build Status](https://travis-ci.org/avakar/pycson.svg?branch=master)](https://travis-ci.org/avakar/pycson) + A python parser for the Coffeescript Object Notation (CSON). ## Installation -The parser is tested on Python 2.7 and 3.4. +The parser is tested on Python 2.7 and 3.5. pip install cson @@ -38,16 +38,16 @@ Here are some important highlights (see the [formal grammar][3] for details). - * String interpolations (`"#{test}"`) are allowed, but are treated literally. - * Whitespace is ignored in arrays and in objects enclosed in braces - (Coffeescripts requires consistent indentation). - * Unbraced objects greedily consume as many key/value pairs as they can. - * All lines in an unbraced object must have the same indentation. This is the only place - where whitespace is significant. There are no special provisions for partial dedents. - For two lines to have the same indent, their maximal sequences of leading spaces and tabs - must be the same (Coffescript only tracks the number of whitespace characters). - * Unbraced objects that don't start on their own line will never span multiple lines. - * Commas at the end of the line can always be removed without changing the output. +* String interpolations (`"#{test}"`) are allowed, but are treated literally. +* Whitespace is ignored in arrays and in objects enclosed in braces + (Coffeescripts requires consistent indentation). +* Unbraced objects greedily consume as many key/value pairs as they can. +* All lines in an unbraced object must have the same indentation. This is the only place + where whitespace is significant. There are no special provisions for partial dedents. + For two lines to have the same indent, their maximal sequences of leading spaces and tabs + must be the same (Coffescript only tracks the number of whitespace characters). +* Unbraced objects that don't start on their own line will never span multiple lines. +* Commas at the end of the line can always be removed without changing the output. I believe the above rules make the parse unambiguous. diff -Nru pycson-0.7/setup.cfg pycson-0.8/setup.cfg --- pycson-0.7/setup.cfg 1970-01-01 00:00:00.000000000 +0000 +++ pycson-0.8/setup.cfg 2019-01-22 17:55:40.000000000 +0000 @@ -0,0 +1,2 @@ +[bdist_wheel] +universal = 1 diff -Nru pycson-0.7/setup.py pycson-0.8/setup.py --- pycson-0.7/setup.py 2016-07-22 18:36:08.000000000 +0000 +++ pycson-0.8/setup.py 2019-01-22 17:55:40.000000000 +0000 @@ -3,11 +3,17 @@ from setuptools import setup +with open('README.md', 'r') as fin: + _long_description = fin.read() + setup( name='cson', - version='0.7', + version='0.8', description='A parser for Coffeescript Object Notation (CSON)', + long_description=_long_description, + long_description_content_type='text/markdown', + author='Martin Vejnár', author_email='vejnar.martin@gmail.com', url='https://github.com/avakar/pycson', @@ -15,4 +21,20 @@ packages=['cson'], install_requires=['speg'], + + classifiers=[ + # Supported python versions + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + + # License + 'License :: OSI Approved :: MIT License', + + # Topics + 'Topic :: Software Development :: Libraries', + ] ) diff -Nru pycson-0.7/test/parser/floats.cson pycson-0.8/test/parser/floats.cson --- pycson-0.7/test/parser/floats.cson 1970-01-01 00:00:00.000000000 +0000 +++ pycson-0.8/test/parser/floats.cson 2019-01-22 17:55:40.000000000 +0000 @@ -0,0 +1,5 @@ +[ + 1.5, 0.5, .5, -.5, 1.0, -1.0, + 1e1, 1e+1, 1e-1, + 1E1, 1E+1, 1E-1, +] diff -Nru pycson-0.7/test/parser/floats.json pycson-0.8/test/parser/floats.json --- pycson-0.7/test/parser/floats.json 1970-01-01 00:00:00.000000000 +0000 +++ pycson-0.8/test/parser/floats.json 2019-01-22 17:55:40.000000000 +0000 @@ -0,0 +1,5 @@ +[ + 1.5, 0.5, 0.5, -0.5, 1.0, -1.0, + 1e1, 1e+1, 1e-1, + 1e1, 1e+1, 1e-1 +] diff -Nru pycson-0.7/test/test_parser.py pycson-0.8/test/test_parser.py --- pycson-0.7/test/test_parser.py 1970-01-01 00:00:00.000000000 +0000 +++ pycson-0.8/test/test_parser.py 2019-01-22 17:55:40.000000000 +0000 @@ -0,0 +1,20 @@ +import cson, os, json + +def test_parser(): + srcdir = os.path.join(os.path.split(__file__)[0], 'parser') + for name in os.listdir(srcdir): + if not name.endswith('.cson'): + continue + + cson_fname = os.path.join(srcdir, name) + with open(cson_fname, 'rb') as fin: + c = cson.load(fin) + + json_name = name[:-5] + '.json' + with open(os.path.join(srcdir, json_name), 'rb') as fin: + j = json.loads(fin.read().decode('utf-8')) + + assert c == j + with open(os.path.join(srcdir, json_name), 'rb') as fin: + c = cson.load(fin) + assert c == j diff -Nru pycson-0.7/test/test_writer.py pycson-0.8/test/test_writer.py --- pycson-0.7/test/test_writer.py 1970-01-01 00:00:00.000000000 +0000 +++ pycson-0.8/test/test_writer.py 2019-01-22 17:55:40.000000000 +0000 @@ -0,0 +1,92 @@ +import cson, os, json, pytest + +def test_writer(): + srcdir = os.path.join(os.path.split(__file__)[0], 'writer') + for name in os.listdir(srcdir): + if not name.endswith('.json'): + continue + + json_fname = os.path.join(srcdir, name) + with open(json_fname, 'rb') as fin: + j = json.loads(fin.read().decode('utf-8')) + + c = cson.dumps(j, indent=4, sort_keys=True, ensure_ascii=False) + + cson_name = name[:-5] + '.cson' + with open(os.path.join(srcdir, cson_name), 'rb') as fin: + cc = fin.read().decode('utf-8').replace('\r\n', '\n') + + assert c == cc + + c = cson.loads(c) + assert c == j + +def test_circular(): + with pytest.raises(ValueError): + o = [] + o.append({'a': o}) + cson.dumps(o, indent=4) + +def test_default_terse(): + class X: + pass + + xx = [1] + def x_def(x): + return xx + + c = cson.dumps(X(), default=x_def) + assert c == '[1]' + +def test_default_indent(): + class X: + pass + + xx = [1] + def x_def(x): + return xx + + c = cson.dumps(X(), indent=4, default=x_def) + assert c == '[\n 1\n]\n' + +def test_circular_in_default(): + class X: + pass + + xx = [1] + xx.append(xx) + def x_def(x): + return xx + + with pytest.raises(ValueError): + cson.dumps(X(), default=x_def) + +def test_circular_in_default_indent(): + class X: + pass + + xx = [1] + xx.append(xx) + def x_def(x): + return xx + + with pytest.raises(ValueError): + cson.dumps(X(), indent=4, default=x_def) + +def test_nonstring_keys(): + c = cson.dumps({1: 1}, indent=4) + assert c == "'1': 1\n" + +def test_unskipped_keys(): + class X: + pass + + with pytest.raises(TypeError): + cson.dumps({X(): 1}, indent=4) + +def test_skipkeys(): + class X: + pass + + c = cson.dumps({X(): 1}, indent=4, skipkeys=True) + assert c == "{}\n" diff -Nru pycson-0.7/test.py pycson-0.8/test.py --- pycson-0.7/test.py 2016-07-22 18:36:08.000000000 +0000 +++ pycson-0.8/test.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,158 +0,0 @@ -import sys, os, os.path, json - -sys.path.insert(0, os.path.join(os.path.split(__file__)[0], 'cson')) -import cson - -total = 0 -errors = [] - -def matches(name): - return not sys.argv[1:] or name in sys.argv[1:] - -srcdir = os.path.join(os.path.split(__file__)[0], 'test', 'parser') -for name in os.listdir(srcdir): - if not name.endswith('.cson'): - continue - if not matches(name): - continue - total += 1 - - cson_fname = os.path.join(srcdir, name) - with open(cson_fname, 'rb') as fin: - try: - c = cson.load(fin) - except cson.ParseError as e: - print('parser/{}({},{}): error: {}'.format(name, e.line, e.col, e.msg)) - errors.append(name) - continue - - json_name = name[:-5] + '.json' - - with open(os.path.join(srcdir, json_name), 'rb') as fin: - j = json.loads(fin.read().decode('utf-8')) - if c != j: - print('error: {}'.format(name)) - print(repr(c)) - print(repr(j)) - errors.append(name) - continue - with open(os.path.join(srcdir, json_name), 'rb') as fin: - try: - c = cson.load(fin) - except cson.ParseError as e: - print('parser/{}({},{}): error: {}'.format(json_name, e.line, e.col, e.msg)) - errors.append(name) - continue - if c != j: - print('error: {}'.format(name)) - print(repr(c)) - print(repr(j)) - errors.append(name) - -srcdir = os.path.join(os.path.split(__file__)[0], 'test', 'writer') -for name in os.listdir(srcdir): - if not name.endswith('.json'): - continue - if not matches(name): - continue - total += 1 - json_fname = os.path.join(srcdir, name) - with open(json_fname, 'rb') as fin: - j = json.loads(fin.read().decode('utf-8')) - - c = cson.dumps(j, indent=4, sort_keys=True, ensure_ascii=False) - - cson_name = name[:-5] + '.cson' - with open(os.path.join(srcdir, cson_name), 'rb') as fin: - cc = fin.read().decode('utf-8').replace('\r\n', '\n') - - if c != cc: - print('error: {}'.format(name)) - print(repr(c)) - print(repr(cc)) - errors.append(name) - continue - - try: - c = cson.loads(c) - except cson.ParseError as e: - print('writer/{}({},{}): error: {}'.format(name, e.line, e.col, e.msg)) - errors.append(name) - continue - - if c != j: - print('error: {}'.format(name)) - print(repr(c)) - print(repr(j)) - errors.append(name) - -try: - o = [] - o.append({'a': o}) - cson.dumps(o, indent=4) -except ValueError: - pass -else: - print('check_circular doesn\'t work') - errors.append('check_circular') - -class X: - pass - -xx = [1] -def x_def(x): - return xx - -c = cson.dumps(X(), default=x_def) -if c != '[1]': - print('default doesn\'t work') - print(c) - errors.append('default') - -c = cson.dumps(X(), indent=4, default=x_def) -if c != '[\n 1\n]\n': - print('default doesn\'t work') - print(c) - errors.append('default') - -xx.append(xx) -try: - cson.dumps(xx, default=x_def) -except ValueError: - pass -else: - print('check_circular doesn\'t work') - errors.append('check_circular') - -try: - cson.dumps(xx, indent=4, default=x_def) -except ValueError: - pass -else: - print('check_circular doesn\'t work') - errors.append('check_circular') - -c = cson.dumps({1: 1}, indent=4) -if c != "'1': 1\n": - print('non-string keys') - print(c) - errors.append('non-string keys') - -c = cson.dumps({X(): 1}, indent=4, skipkeys=True) -if c != "{}\n": - print('skipkeys') - print(c) - errors.append('skipkeys') - -try: - cson.dumps({X(): 1}, indent=4) -except TypeError: - pass -else: - print('skipkeys') - errors.append('skipkeys') - -if errors: - sys.exit(1) - -print('succeeded: {}'.format(total)) diff -Nru pycson-0.7/tox.ini pycson-0.8/tox.ini --- pycson-0.7/tox.ini 1970-01-01 00:00:00.000000000 +0000 +++ pycson-0.8/tox.ini 2019-01-22 17:55:40.000000000 +0000 @@ -0,0 +1,12 @@ +[tox] +envlist=py27,py35,py36,py37 + +[testenv] +usedevelop=True + +deps= + pytest + pytest-cov + +commands= + py.test --cov=cson --cov-report term-missing {posargs} diff -Nru pycson-0.7/.travis.yml pycson-0.8/.travis.yml --- pycson-0.7/.travis.yml 2016-07-22 18:36:08.000000000 +0000 +++ pycson-0.8/.travis.yml 2019-01-22 17:55:40.000000000 +0000 @@ -1,5 +1,8 @@ +sudo: false language: python python: - "2.7" - - "3.4" -script: python ./setup.py install && python ./test.py + - "3.5" + - "3.6" +install: pip install tox-travis coveralls +script: tox && coveralls