├── .gitignore ├── .hgignore ├── LICENSE.txt ├── MANIFEST.in ├── README.rst ├── appveyor.yml ├── appveyor ├── install.ps1 └── run_with_env.cmd ├── bin ├── json2axon └── xml2axon ├── dev-requirements.txt ├── docs ├── Makefile ├── api.rst ├── changelog.rst ├── conf.py ├── ebnf │ ├── diagram │ │ ├── Railroad-Diagram-Generator.png │ │ ├── anonymous-complex-value.png │ │ ├── atomic-value.png │ │ ├── axon.png │ │ ├── binary-data.png │ │ ├── complex-value.png │ │ ├── constant-nan.png │ │ ├── constant.png │ │ ├── data-attr.png │ │ ├── data-item.png │ │ ├── date-time.png │ │ ├── date.png │ │ ├── datetime.png │ │ ├── day.png │ │ ├── decimal.png │ │ ├── dict-item.png │ │ ├── dict.png │ │ ├── exp.png │ │ ├── fixed-point.png │ │ ├── float.png │ │ ├── hours.png │ │ ├── identifier.png │ │ ├── indented-data-attr.png │ │ ├── indented-data-item.png │ │ ├── int.png │ │ ├── key.png │ │ ├── label.png │ │ ├── list.png │ │ ├── microseconds.png │ │ ├── minutes.png │ │ ├── month.png │ │ ├── name.png │ │ ├── named-complex-value.png │ │ ├── nl-indent.png │ │ ├── node-braces.png │ │ ├── node-nobraces.png │ │ ├── node.png │ │ ├── number.png │ │ ├── odict.png │ │ ├── onstant-infinity.png │ │ ├── seconds.png │ │ ├── string-key.png │ │ ├── text.png │ │ ├── time-offset.png │ │ ├── time.png │ │ ├── tuple.png │ │ ├── value.png │ │ └── year.png │ ├── grammar.ebnf │ └── index.html ├── figs │ ├── anonymous-complex-value.png │ ├── axon.png │ ├── base64.png │ ├── binary-data.png │ ├── complex-value.png │ ├── constant-infinity.png │ ├── constant-nan.png │ ├── constant.png │ ├── construct.png │ ├── control-char.png │ ├── data-attr.png │ ├── data-item.png │ ├── date-time.png │ ├── date.png │ ├── datetime.png │ ├── day.png │ ├── decimal.png │ ├── def-reference.png │ ├── dict.png │ ├── element.png │ ├── element2.png │ ├── empty.png │ ├── empty2.png │ ├── exp.png │ ├── fixed-point.png │ ├── float.png │ ├── hours.png │ ├── identifier.png │ ├── instance.png │ ├── instance2.png │ ├── int.png │ ├── key.png │ ├── label.png │ ├── list.png │ ├── mapping.png │ ├── mapping2.png │ ├── microseconds.png │ ├── minutes.png │ ├── month.png │ ├── name.png │ ├── named-complex-value.png │ ├── number.png │ ├── object.png │ ├── reference.png │ ├── seconds.png │ ├── sequence.png │ ├── sequence2.png │ ├── set.png │ ├── simple-value.png │ ├── simpleon_logo.png │ ├── simpleon_logo_72.png │ ├── string-key.png │ ├── text.png │ ├── time-offset.png │ ├── time.png │ ├── tuple.png │ ├── unicode-hex.png │ ├── value.png │ └── year.png └── index.rst ├── examples ├── axon_bench.ipynb ├── axon_by_examples.ipynb ├── axon_by_examples2.ipynb ├── axon_by_examples_ru.ipynb ├── axon_datamodel.ipynb ├── axon_examples.ipynb ├── axon_fat_free_xml.ipynb ├── axon_habr.ipynb ├── axon_json_xml.ipynb ├── axon_metadata.ipynb ├── axon_object_datamodel.ipynb ├── axon_object_serialization.ipynb ├── axon_patterns.ipynb ├── axon_readable_as_yaml.ipynb ├── axon_schema.ipynb ├── axon_step_by_step.ipynb ├── axon_tutorial.ipynb ├── axon_what.ipynb ├── axon_with_python.ipynb ├── basic_sample.axon ├── basic_sample.json ├── better_json.axon ├── better_json_crossref.axon ├── data │ ├── auctions.axon │ ├── auctions.json │ ├── test_1.axon │ ├── test_1.json │ ├── test_2.axon │ └── test_2.json ├── example_config.yaml ├── example_config1.axon ├── example_config2.axon ├── large_files.ipynb ├── quick_start.ipynb ├── readme.ipynb ├── test.ipynb ├── utils.py ├── what_axon_looks_like.ipynb └── what_is_axon_ru.ipynb ├── lib └── axon │ ├── __init__.py │ ├── _common.pxd │ ├── _dumper.pxd │ ├── _dumper.py │ ├── _loader.pxd │ ├── _loader.py │ ├── _objects.pxd │ ├── _objects.py │ ├── api.py │ ├── errors.py │ ├── objects.py │ ├── odict.pxd │ ├── odict.pyx │ ├── test │ ├── __init__.py │ ├── benchmark │ │ ├── __init__.py │ │ ├── test_vs_json.py │ │ └── test_vs_yaml.py │ ├── profiling.py │ ├── samples.py │ ├── test_base64.py │ ├── test_constant.py │ ├── test_crossref.py │ ├── test_datetime.py │ ├── test_datetime10.py │ ├── test_decimal.py │ ├── test_dict.py │ ├── test_element.py │ ├── test_errors.py │ ├── test_float.py │ ├── test_instance.py │ ├── test_int.py │ ├── test_list.py │ ├── test_load.py │ ├── test_mapping.py │ ├── test_odict.py │ ├── test_samples.py │ ├── test_sequence.py │ ├── test_set.py │ ├── test_string.py │ ├── test_suite.py │ ├── test_tuple.py │ ├── test_unsafe_loads.py │ └── xml │ │ └── simple.xml │ ├── types.py │ ├── utils.h │ └── utils.py ├── requirements.txt ├── setup.py ├── test_all.py ├── test_benchmark.py └── update_git /.gitignore: -------------------------------------------------------------------------------- 1 | .hg 2 | MANIFEST 3 | python/build 4 | python/dist 5 | python/doc/_build 6 | *.pyc 7 | *.pyo 8 | __pycache__ 9 | *.egg-info 10 | *~ 11 | *.bak 12 | -------------------------------------------------------------------------------- /.hgignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | 3 | *~ 4 | .DS_Store 5 | .ipynb_checkpoints 6 | .pyc 7 | .pyo 8 | *.bak 9 | __pycache__ 10 | *.egg-info 11 | 12 | .git 13 | docs/_build 14 | build 15 | dist 16 | MANIFEST 17 | pyaxon.bbprojectd/* 18 | pyaxon.bbprojectd/*.* 19 | lib/axon/_objects.c 20 | lib/axon/_objects.h 21 | lib/axon/_dumper.c 22 | lib/axon/_dumper.h 23 | lib/axon/_loader.c 24 | lib/axon/_loader.h 25 | lib/axon/odict.c 26 | lib/axon/odict.h 27 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) <2011-2016> 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include setup.py 2 | include README.rst 3 | include LICENSE.txt 4 | include test_all.py 5 | include test_benchmark.py 6 | include lib/axon/*.py 7 | exclude lib/axon/_objects.py 8 | exclude lib/axon/_loader.py 9 | exclude lib/axon/_dumper.py 10 | include lib/axon/*.c 11 | include lib/axon/*.h 12 | include lib/axon/test/*.py 13 | include lib/axon/test/benchmark/*.py 14 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ====== 2 | PYAXON 3 | ====== 4 | 5 | ``pyaxon`` is an `MIT Licensed `_ python library 6 | for `AXON `_. 7 | AXON is eXtended Object Notation. It's a simple text based format for interchanging 8 | objects, documents and data. 9 | It tries to combine the best of `JSON `_, 10 | `XML `_ and `YAML `_. 11 | 12 | links 13 | ----- 14 | 15 | * Main repository for ``pyaxon`` is on `bitbucket `_. 16 | * Mirror on `github `_ 17 | * `Blog `_ about AXON. 18 | * History of `changes `_. 19 | 20 | Installation 21 | ------------ 22 | 23 | ``pyaxon`` runs under Python 2.7, 3.3, 3.4 and 3.5 24 | 25 | It can be installed via pip:: 26 | 27 | pip install pyaxon 28 | 29 | It can be installed from sources:: 30 | 31 | python setup.py install 32 | 33 | Quick start 34 | ----------- 35 | 36 | First import `axon` module:: 37 | 38 | >>> import axon 39 | 40 | Load and dump lists, dicts, tuples:: 41 | 42 | >>> from decimal import Decimal 43 | >>> from datetime import datetime, time, date 44 | >>> text = axon.dumps([['abc абв', 1, 3.14, True], 45 | [datetime.now(), Decimal('3.14')]]) 46 | >>> print(text) 47 | ["abc абв" 1 3.14 true] 48 | [^2015-05-12T13:08:37.078189 3.14D] 49 | 50 | >>> vals = [{'id':1, 'nickname':'nick', 'time':time(12, 31, 34), 'text':'hello!'}, 51 | {'id':2, 'nickname':'mark', 'time':time(12, 32, 3), 'text':'hi!'}] 52 | >>> text = axon.dumps(vals) 53 | >>> print(text) 54 | {id:1 nickname:"nick" text:"hello!" time:^12:31:34} 55 | {id:2 nickname:"mark" text:"hi!" time:^12:32:03} 56 | >>> text = axon.dumps(vals, pretty=1) 57 | >>> print(text) 58 | { id: 1 59 | nickname: "nick" 60 | text: "hello!" 61 | time: ^12:31:34} 62 | { id: 2 63 | nickname: "mark" 64 | text: "hi!" 65 | time: ^12:32:03} 66 | >>> vals == axon.loads(text) 67 | True 68 | 69 | >>> vals = [[{'a':1, 'b':2, 'c':3}, {'a':[1,2,3], 'b':(1,2,3), 'c':{1,2,3}}]] 70 | >>> text = axon.dumps(vals) 71 | >>> print(text) 72 | [{a:1 b:2 c:3} {a:[1 2 3] b:(1 2 3) c:{1 2 3}}] 73 | >>> text = axon.dumps(vals, pretty=1) 74 | >>> print(text) 75 | [ { a: 1 76 | b: 2 77 | c: 3} 78 | { a: [1 2 3] 79 | b: (1 2 3) 80 | c: {1 2 3}}] 81 | >>> vals == axon.loads(text) 82 | True 83 | 84 | Dump, load objects in "safe" mode:: 85 | 86 | >>> vals = axon.loads('person{name:"nick" age:32 email:"nail@example.com"}') 87 | >>> print(type(vals[0])) 88 | 89 | >>> print(vals[0]) 90 | node('person', {'email': 'nail@example.com', 'age': 32, 'name': 'nick'}) 91 | 92 | >>> text = axon.dumps(vals) 93 | >>> print(text) 94 | person{age:32 email:"nail@example.com" name:"nick"} 95 | >>> text = axon.dumps(vals, pretty=1) 96 | >>> print(text) 97 | person 98 | age: 32 99 | email: "nail@example.com" 100 | name: "nick" 101 | >>> text = axon.dumps(vals, pretty=1, braces=1) 102 | >>> print(text) 103 | person { 104 | age: 32 105 | email: "nail@example.com" 106 | name: "nick"} 107 | 108 | Dump, load objects in unsafe mode:: 109 | 110 | class Person: 111 | def __init__(self, name, age, email): 112 | self.name = name 113 | self.age = age 114 | self.email = email 115 | 116 | def __str__(self): 117 | return "Person(name=%r, age=%r, email=%r)" % (self.name, self.age, self.email) 118 | 119 | @axon.reduce(Person) 120 | def reduce_Person(p): 121 | return axon.node('person', {'name':p.name, 'age':p.age, 'email': p.email}) 122 | 123 | @axon.factory('person') 124 | def factory_Person(attrs, vals): 125 | return Person(name=attrs['name'], age=attrs['age'], email=attrs['email']) 126 | 127 | >>> p = Person('nick', 32, 'mail@example.com') 128 | >>> text = axon.dumps([p]) 129 | >>> print(text) 130 | person{age:32 email:"mail@example.com" name:"nick"} 131 | >>> val = axon.loads(text, mode='strict')[0] 132 | >>> print(val) 133 | Person(name='nick', age=32, email='mail@example.com') 134 | 135 | Features 136 | -------- 137 | 138 | 1. Provide simple API for loading and dumping of objects in textual AXON format. 139 | 2. Provide safe loading and dumping by default. 140 | 3. Provide unsafe loading and dumping of objects on the base of registration of factory/reduce callables. 141 | 4. Provide a way for fully controlled by application/framework/library unsafe loading and dumping. 142 | 5. It's sufficiently fast so as to be useful. 143 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | global: 3 | # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the 4 | # /E:ON and /V:ON options are not enabled in the batch script intepreter 5 | # See: http://stackoverflow.com/a/13751649/163740 6 | CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_env.cmd" 7 | 8 | matrix: 9 | 10 | # Python 2.7.10 is the latest version and is not pre-installed. 11 | 12 | #- PYTHON: "C:\\Python27.10" 13 | # PYTHON_VERSION: "2.7.10" 14 | # PYTHON_ARCH: "32" 15 | 16 | #- PYTHON: "C:\\Python27.10-x64" 17 | # PYTHON_VERSION: "2.7.10" 18 | # PYTHON_ARCH: "64" 19 | 20 | # Pre-installed Python versions, which Appveyor may upgrade to 21 | # a later point release. 22 | 23 | - PYTHON: "C:\\Python27" 24 | PYTHON_VERSION: "2.7.x" # currently 2.7.9 25 | PYTHON_ARCH: "32" 26 | 27 | - PYTHON: "C:\\Python27-x64" 28 | PYTHON_VERSION: "2.7.x" 29 | PYTHON_ARCH: "64" 30 | 31 | - PYTHON: "C:\\Python33" 32 | PYTHON_VERSION: "3.3.x" 33 | PYTHON_ARCH: "32" 34 | 35 | - PYTHON: "C:\\Python33-x64" 36 | PYTHON_VERSION: "3.3.x" 37 | PYTHON_ARCH: "64" 38 | 39 | - PYTHON: "C:\\Python34" 40 | PYTHON_VERSION: "3.4.x" 41 | PYTHON_ARCH: "32" 42 | 43 | - PYTHON: "C:\\Python34-x64" 44 | PYTHON_VERSION: "3.4.x" 45 | PYTHON_ARCH: "64" 46 | 47 | - PYTHON: "C:\\Python35" 48 | PYTHON_VERSION: "3.5.x" 49 | PYTHON_ARCH: "32" 50 | 51 | - PYTHON: "C:\\Python35-x64" 52 | PYTHON_VERSION: "3.5.x" 53 | PYTHON_ARCH: "64" 54 | 55 | install: 56 | - ECHO "Filesystem root:" 57 | - ps: "ls \"C:/\"" 58 | 59 | - ECHO "Installed SDKs:" 60 | - ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\"" 61 | 62 | # Install Python (from the official .msi of http://python.org) and pip when 63 | # not already installed. 64 | - ps: if (-not(Test-Path($env:PYTHON))) { & appveyor\install.ps1 } 65 | 66 | # Prepend newly installed Python to the PATH of this build (this cannot be 67 | # done from inside the powershell script as it would require to restart 68 | # the parent CMD process). 69 | - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" 70 | 71 | # Check that we have the expected version and architecture for Python 72 | - "python --version" 73 | - "python -c \"import struct; print(struct.calcsize('P') * 8)\"" 74 | 75 | # Upgrade to the latest version of pip to avoid it displaying warnings 76 | # about it being out of date. 77 | - "pip install --disable-pip-version-check --user --upgrade pip" 78 | 79 | # Install the build dependencies of the project. If some dependencies contain 80 | # compiled extensions and are not provided as pre-built wheel packages, 81 | # pip will build them from source using the MSVC compiler matching the 82 | # target Python version and andrchitecture 83 | - "%CMD_IN_ENV% pip install -r dev-requirements.txt" 84 | 85 | build: false # Not a C# project, build stuff at the test step instead. 86 | 87 | test_script: 88 | # Build the compiled extension and run the project tests 89 | #- "%CMD_IN_ENV% python setup.py nosetests" 90 | - "%CMD_IN_ENV% python setup.py install" 91 | - "%CMD_IN_ENV% python test_all.py" 92 | 93 | after_test: 94 | # If tests are successful, create binary packages for the project. 95 | - "%CMD_IN_ENV% python setup.py bdist_wheel" 96 | #- "%CMD_IN_ENV% python setup.py bdist_wininst" 97 | #- "%CMD_IN_ENV% python setup.py bdist_msi" 98 | - ps: "ls dist" 99 | 100 | artifacts: 101 | # Archive the generated packages in the ci.appveyor.com build report. 102 | - path: dist\* 103 | 104 | #on_success: 105 | # - TODO: upload the content of dist/*.whl to a public wheelhouse 106 | # 107 | -------------------------------------------------------------------------------- /appveyor/run_with_env.cmd: -------------------------------------------------------------------------------- 1 | :: To build extensions for 64 bit Python 3, we need to configure environment 2 | :: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of: 3 | :: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1) 4 | :: 5 | :: To build extensions for 64 bit Python 2, we need to configure environment 6 | :: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of: 7 | :: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0) 8 | :: 9 | :: 32 bit builds, and 64-bit builds for 3.5 and beyond, do not require specific 10 | :: environment configurations. 11 | :: 12 | :: Note: this script needs to be run with the /E:ON and /V:ON flags for the 13 | :: cmd interpreter, at least for (SDK v7.0) 14 | :: 15 | :: More details at: 16 | :: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows 17 | :: http://stackoverflow.com/a/13751649/163740 18 | :: 19 | :: Author: Olivier Grisel 20 | :: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/ 21 | :: 22 | :: Notes about batch files for Python people: 23 | :: 24 | :: Quotes in values are literally part of the values: 25 | :: SET FOO="bar" 26 | :: FOO is now five characters long: " b a r " 27 | :: If you don't want quotes, don't include them on the right-hand side. 28 | :: 29 | :: The CALL lines at the end of this file look redundant, but if you move them 30 | :: outside of the IF clauses, they do not run properly in the SET_SDK_64==Y 31 | :: case, I don't know why. 32 | @ECHO OFF 33 | 34 | SET COMMAND_TO_RUN=%* 35 | SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows 36 | SET WIN_WDK=c:\Program Files (x86)\Windows Kits\10\Include\wdf 37 | 38 | :: Extract the major and minor versions, and allow for the minor version to be 39 | :: more than 9. This requires the version number to have two dots in it. 40 | SET MAJOR_PYTHON_VERSION=%PYTHON_VERSION:~0,1% 41 | IF "%PYTHON_VERSION:~3,1%" == "." ( 42 | SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,1% 43 | ) ELSE ( 44 | SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,2% 45 | ) 46 | 47 | :: Based on the Python version, determine what SDK version to use, and whether 48 | :: to set the SDK for 64-bit. 49 | IF %MAJOR_PYTHON_VERSION% == 2 ( 50 | SET WINDOWS_SDK_VERSION="v7.0" 51 | SET SET_SDK_64=Y 52 | ) ELSE ( 53 | IF %MAJOR_PYTHON_VERSION% == 3 ( 54 | SET WINDOWS_SDK_VERSION="v7.1" 55 | IF %MINOR_PYTHON_VERSION% LEQ 4 ( 56 | SET SET_SDK_64=Y 57 | ) ELSE ( 58 | SET SET_SDK_64=N 59 | IF EXIST "%WIN_WDK%" ( 60 | :: See: https://connect.microsoft.com/VisualStudio/feedback/details/1610302/ 61 | REN "%WIN_WDK%" 0wdf 62 | ) 63 | ) 64 | ) ELSE ( 65 | ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%" 66 | EXIT 1 67 | ) 68 | ) 69 | 70 | IF %PYTHON_ARCH% == 64 ( 71 | IF %SET_SDK_64% == Y ( 72 | ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture 73 | SET DISTUTILS_USE_SDK=1 74 | SET MSSdk=1 75 | "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION% 76 | "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release 77 | ECHO Executing: %COMMAND_TO_RUN% 78 | call %COMMAND_TO_RUN% || EXIT 1 79 | ) ELSE ( 80 | ECHO Using default MSVC build environment for 64 bit architecture 81 | ECHO Executing: %COMMAND_TO_RUN% 82 | call %COMMAND_TO_RUN% || EXIT 1 83 | ) 84 | ) ELSE ( 85 | ECHO Using default MSVC build environment for 32 bit architecture 86 | ECHO Executing: %COMMAND_TO_RUN% 87 | call %COMMAND_TO_RUN% || EXIT 1 88 | ) 89 | -------------------------------------------------------------------------------- /bin/json2axon: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from __future__ import print_function, unicode_literals 3 | 4 | from axon.utils import json2axon 5 | import io 6 | import sys 7 | 8 | if __name__ == '__main__': 9 | 10 | is_stringio = 0 11 | if len(sys.argv) == 2: 12 | from_file = sys.argv[1] 13 | is_stringio = 1 14 | elif len(sys.argv) > 3: 15 | print('Usage: xml2axon ') 16 | sys.exit() 17 | else: 18 | from_file, to_file = sys.argv[1], sys.argv[2] 19 | if is_stringio: 20 | text = json2axon(from_file) 21 | print(text) 22 | else: 23 | json2axon(from_file, to_file) 24 | -------------------------------------------------------------------------------- /bin/xml2axon: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from __future__ import print_function, unicode_literals 3 | 4 | from axon.utils import xml2axon 5 | import io 6 | import sys 7 | 8 | if __name__ == '__main__': 9 | 10 | is_stringio = 0 11 | if len(sys.argv) == 2: 12 | from_file = sys.argv[1] 13 | is_stringio = 1 14 | elif len(sys.argv) > 3: 15 | print('Usage: xml2axon ') 16 | sys.exit() 17 | else: 18 | from_file, to_file = sys.argv[1], sys.argv[2] 19 | if is_stringio: 20 | text = xml2axon(from_file) 21 | print(text) 22 | else: 23 | xml2axon(from_file, to_file) 24 | -------------------------------------------------------------------------------- /dev-requirements.txt: -------------------------------------------------------------------------------- 1 | wheel 2 | cython 3 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # Internal variables. 11 | PAPEROPT_a4 = -D latex_paper_size=a4 12 | PAPEROPT_letter = -D latex_paper_size=letter 13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 14 | 15 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest 16 | 17 | help: 18 | @echo "Please use \`make ' where is one of" 19 | @echo " html to make standalone HTML files" 20 | @echo " dirhtml to make HTML files named index.html in directories" 21 | @echo " singlehtml to make a single large HTML file" 22 | @echo " pickle to make pickle files" 23 | @echo " json to make JSON files" 24 | @echo " htmlhelp to make HTML files and a HTML help project" 25 | @echo " qthelp to make HTML files and a qthelp project" 26 | @echo " devhelp to make HTML files and a Devhelp project" 27 | @echo " epub to make an epub" 28 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 29 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 30 | @echo " text to make text files" 31 | @echo " man to make manual pages" 32 | @echo " changes to make an overview of all changed/added/deprecated items" 33 | @echo " linkcheck to check all external links for integrity" 34 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 35 | 36 | clean: 37 | -rm -rf $(BUILDDIR)/* 38 | 39 | html: 40 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 41 | @echo 42 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 43 | 44 | dirhtml: 45 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 46 | @echo 47 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 48 | 49 | singlehtml: 50 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 51 | @echo 52 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 53 | 54 | pickle: 55 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 56 | @echo 57 | @echo "Build finished; now you can process the pickle files." 58 | 59 | json: 60 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 61 | @echo 62 | @echo "Build finished; now you can process the JSON files." 63 | 64 | htmlhelp: 65 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 66 | @echo 67 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 68 | ".hhp project file in $(BUILDDIR)/htmlhelp." 69 | 70 | qthelp: 71 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 72 | @echo 73 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 74 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 75 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Tablib.qhcp" 76 | @echo "To view the help file:" 77 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Tablib.qhc" 78 | 79 | devhelp: 80 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 81 | @echo 82 | @echo "Build finished." 83 | @echo "To view the help file:" 84 | @echo "# mkdir -p $$HOME/.local/share/devhelp/Tablib" 85 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Tablib" 86 | @echo "# devhelp" 87 | 88 | epub: 89 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 90 | @echo 91 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 92 | 93 | latex: 94 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 95 | @echo 96 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 97 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 98 | "(use \`make latexpdf' here to do that automatically)." 99 | 100 | latexpdf: 101 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 102 | @echo "Running LaTeX files through pdflatex..." 103 | make -C $(BUILDDIR)/latex all-pdf 104 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 105 | 106 | text: 107 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 108 | @echo 109 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 110 | 111 | man: 112 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 113 | @echo 114 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 115 | 116 | changes: 117 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 118 | @echo 119 | @echo "The overview file is in $(BUILDDIR)/changes." 120 | 121 | linkcheck: 122 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 123 | @echo 124 | @echo "Link check complete; look for any errors in the above output " \ 125 | "or in $(BUILDDIR)/linkcheck/output.txt." 126 | 127 | doctest: 128 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 129 | @echo "Testing of doctests in the sources finished, look at the " \ 130 | "results in $(BUILDDIR)/doctest/output.txt." 131 | -------------------------------------------------------------------------------- /docs/api.rst: -------------------------------------------------------------------------------- 1 | .. _api: 2 | 3 | === 4 | API 5 | === 6 | 7 | 8 | .. module:: axon 9 | 10 | This part of the documentation covers interfaces of *axon*. 11 | 12 | 13 | ------- 14 | Classes 15 | ------- 16 | 17 | 18 | .. autoclass:: Loader 19 | :members: 20 | 21 | .. autoclass:: Dumper 22 | :members: 23 | :inherited-members: 24 | 25 | .. autoclass:: Node 26 | :members: 27 | :inherited-members: 28 | 29 | --------- 30 | Functions 31 | --------- 32 | 33 | Loading and dumping 34 | ------------------- 35 | 36 | .. autofunction:: display 37 | 38 | .. autofunction:: load 39 | 40 | .. autofunction:: loads 41 | 42 | .. autofunction:: iload 43 | 44 | .. autofunction:: iloads 45 | 46 | .. autofunction:: dump 47 | 48 | .. autofunction:: dumps 49 | 50 | Factory functions for safe mode complex values 51 | ---------------------------------------------- 52 | 53 | .. autofunction:: node 54 | 55 | 56 | ---------- 57 | Exceptions 58 | ---------- 59 | 60 | 61 | .. class:: LoadExit 62 | 63 | Exception for exit load AXON representation from file or text. 64 | 65 | -------------------------------------------------------------------------------- /docs/changelog.rst: -------------------------------------------------------------------------------- 1 | History of changes 2 | ------------------ 3 | 4 | **0.9** 5 | 6 | 1. Now date/time/datetime values have prefix ``^`` in order to be more explicit 7 | (``12:00`` --> ``^12:00``, ``2010-12-31`` --> ``^2010-12-31``). 8 | This change is important for adding support for more wider range of simple type values 9 | for keys in dicts in the next version ``0.10``. 10 | In 0.9.x loading of old notation of date/time/datetime values are allowed. 11 | In ``0.10`` old notation will be removed. 12 | In order to convert ``pyaxon`` text in safe mode to new date/time/datetime notation ``0.9``:: 13 | 14 | import axon 15 | 16 | axon.dumps(axon.loads(text)) 17 | axon.dump(path, axon.load(path, text)) 18 | 19 | 2. Add syntax reprsenting sets. For example:: 20 | 21 | {1 2 3} 22 | {"a" "b" "c" "d"} 23 | 24 | **0.8.2** 25 | 26 | 1. Fix dump of toplevel dict when sort=1. 27 | 28 | **0.8.1** 29 | 30 | 1. Now node objects support access to subnodes using attribute access. 31 | 2. Now pyaxon support continues integration via appveyor. 32 | 33 | **0.8** 34 | 35 | 1. Now name of complex value in formatted form without {} hasn't suffix ':'. For example:: 36 | 37 | person 38 | name: "Alex" 39 | age: 36 40 | 41 | instead of:: 42 | 43 | person: 44 | name: "Alex" 45 | age: 36 46 | 47 | 2. Introduce used defined constants using ``defname(name, value)`` function. 48 | Such names in ``AXON`` message always have ``$`` prefix (for example, ``$one``, ``$PI``). 49 | 3. Attributes of the ``Node`` objects are ``axon.OrederDict`` instance now to preserve order 50 | of attributes. 51 | 4. Introduce new syntax for oredered dict: ``[... key:val ...]`` and ``[:]`` for empty ordered dict. 52 | Later ``<>``-syntax for ordered dicts will be removed. 53 | 5. Extend ``AXON`` for converting text into ``axon.OrderedDict`` object 54 | and dumping instances of ``collections.MutableMapping`` to text containing sequence 55 | of ``key:val`` pairs. 56 | For example:: 57 | 58 | name: "Alex" 59 | age: 32 60 | email: "mail@example.com" 61 | 62 | will converted to ``axon.OrderedDict([('name','Alex'), ('age',32), ('email','mail@example.com')])``. 63 | 64 | 6. ``pyaxon`` now builds with MSVC. 65 | 66 | 67 | **0.7** 68 | 69 | 1. Safe mode loading/dumping on named complex values are based on general ``Node`` objects. 70 | 2. Attributes in safe mode are represented as ``Attribute`` objects. 71 | 3. Named complex values are now sensitive to an order of containing values and attributes. 72 | 4. The protocol for unsafe loading/dumping of named complex values is changed. 73 | 5. Old safe mode loading/dumping are still here in the ``mode='safe_old'`` 74 | 75 | **0.6** 76 | 77 | 1. Use compiled `decimal` module when possible. 78 | 2. Add syntax "< ... key:value ... >" to AXON in order to load/dump ordered dicts. 79 | 3. Add cython implementation of ordered dict `axon.odict`. 80 | (API compatible with `collections.OrderedDict`). 81 | 4. Fix bug with number-like string keys in dicts. 82 | 83 | **0.5.11** 84 | 85 | 1. Add ability to dump custom class objects as dict, list or tuple. 86 | 2. Add support (`axon.convert`) to convertion of safely loaded objects to given type. 87 | 3. Fix several bugs. 88 | 89 | Special credit to `sbant `_. 90 | 91 | **0.5.10** 92 | 93 | 1. Make error messages in loader more useful. 94 | 2. Refactoring of comment handling with addition of some tests. 95 | 3. Fix crossreference issue with unsafe mode of loading/dumping. 96 | 4. Add windows installers. 97 | 98 | **0.5.9** 99 | 100 | 1. Some errors with processing of comment lines are fixed. 101 | 2. It's possible now to use "d"/"D" suffix instead of "$" to indicate decimal values. 102 | 3. Fix problem with mixing of tabs ('\t') with other spacing characters. 103 | 4. Fix example of AXON in index.rst to use "d/D" suffix for decimal values. 104 | 105 | **0.5.8** 106 | 107 | 1. Fix 2.7/3.3 compatibility error with reading from files. 108 | 2. Pretty dumping now is more compact in simple cases. 109 | 3. Now default pretty dumping mode (``pretty=1``) is indented without braces (like YAML); 110 | new parameter ``braces=1`` with ``pretty=1`` specifies formatted mode with braces (like JSON). 111 | 112 | **0.5.7** 113 | 114 | 1. Refine indentation control when loading complex objects in indented form. 115 | 2. Restore support of names as quoted strings a.k.a. ``'the name'``. 116 | 3. Make ``date/time/datetime`` creation code compatible with pure python mode. 117 | 4. Add ``hsize`` parameter in pretty dumping mode. It specifies maximum number of 118 | simple data items in the line. 119 | 5. Add more tests by examples. 120 | 121 | **0.5.6** 122 | 123 | 1. Fix support for decimal ``Infinity`` and ``NaN``. 124 | 2. Fix support for ``base64`` in ``python2.7``. 125 | 3. Add support for complex names like ``a.b.c.d``. 126 | 127 | **0.5.5** 128 | 129 | 1. Make creation of custom builders of atomic values easier too (in ``cython`` only). 130 | 2. Make creation of custom object builders easier (both in ``cython`` and ``python``). 131 | This allows you to implement custom import/export for data in ``XML`` and ``YAML`` 132 | representation. 133 | 3. Add plotting of results to simple benchmark script. 134 | 135 | **0.5.4** 136 | 137 | 1. Make internal timezone class (for ``python2.7``) compatible with datetime.timezone class (for ``python3.2`` and higher). 138 | 2. Make creation of custom object builders (both safe and unsafe) easier (in ``cython`` only). 139 | 140 | **0.5.3** 141 | 142 | 1. Dumping is now faster. 143 | 144 | **0.5.2** 145 | 146 | 1. Refactor setup.py so that .py sources of extensions dosn't installed. 147 | 2. Ensuire that attribute names and keys loads and dumps correctly. 148 | 3. Add explicit flag (``use_cython``) in order to decide when to use cython compiler. 149 | 150 | **0.5.1** 151 | 152 | 1. Add notebook with performance comparisons with ``JSON`` and ``YAML``. 153 | 2. Refactor setup.py so that project could be installed with/without ``Cython`` installation. 154 | 3. Some improvements with introductory notebooks. 155 | 4. Make project uploadable to ``PyPI`` by ``setup.py``. 156 | 157 | 158 | 159 | **0.5** 160 | 161 | First public release of ``pyaxon``. 162 | 163 | .. raw:: html 164 | 165 | 174 | -------------------------------------------------------------------------------- /docs/ebnf/diagram/Railroad-Diagram-Generator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/Railroad-Diagram-Generator.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/anonymous-complex-value.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/anonymous-complex-value.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/atomic-value.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/atomic-value.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/axon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/axon.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/binary-data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/binary-data.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/complex-value.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/complex-value.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/constant-nan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/constant-nan.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/constant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/constant.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/data-attr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/data-attr.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/data-item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/data-item.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/date-time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/date-time.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/date.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/date.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/datetime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/datetime.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/day.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/decimal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/decimal.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/dict-item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/dict-item.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/dict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/dict.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/exp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/exp.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/fixed-point.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/fixed-point.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/float.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/float.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/hours.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/hours.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/identifier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/identifier.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/indented-data-attr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/indented-data-attr.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/indented-data-item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/indented-data-item.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/int.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/int.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/key.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/label.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/label.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/list.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/microseconds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/microseconds.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/minutes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/minutes.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/month.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/month.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/name.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/named-complex-value.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/named-complex-value.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/nl-indent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/nl-indent.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/node-braces.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/node-braces.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/node-nobraces.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/node-nobraces.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/node.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/node.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/number.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/number.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/odict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/odict.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/onstant-infinity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/onstant-infinity.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/seconds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/seconds.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/string-key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/string-key.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/text.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/time-offset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/time-offset.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/time.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/tuple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/tuple.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/value.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/value.png -------------------------------------------------------------------------------- /docs/ebnf/diagram/year.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/ebnf/diagram/year.png -------------------------------------------------------------------------------- /docs/ebnf/grammar.ebnf: -------------------------------------------------------------------------------- 1 | axon ::= data-item* 2 | 3 | data-item ::= ('&' label)? value | '*' label 4 | label ::= ([A-Z] | [a-z] | [0-9] | '_' )+ 5 | 6 | value ::= complex-value | atomic-value 7 | 8 | complex-value ::= anonymous-complex-value | named-complex-value 9 | 10 | anonymous-complex-value ::= dict | list | tuple | odict 11 | named-complex-value ::= node 12 | 13 | dict ::= '{' dict-item* '}' 14 | odict ::= '[' dict-item* ']' 15 | 16 | dict-item ::= key ':' data-item 17 | key ::= identifier | text 18 | 19 | list ::= '[' data-item* ']' 20 | 21 | tuple ::= '(' data-item* ')' 22 | 23 | node ::= node-braces | node-nobraces 24 | 25 | node-braces ::= name '{' data-attr* data-item* '}' 26 | node-nobraces ::= name indented-data-attr* indented-data-item* 27 | 28 | indented-data-attr ::= nl-indent data-attr 29 | indented-data-item ::= nl-indent data-item 30 | 31 | nl-indent ::= 'new line + constant indentation relative to name' 32 | 33 | data-attr ::= name ':' data-item 34 | 35 | name ::= identifier | string-key 36 | 37 | identifier ::= ( 'unicode alphabetic char' | '_') ('unicode alphanumeric char' | '_')* 38 | string-key ::= "'" ( " any unicode character except ' " | "\'" ) "'" 39 | 40 | atomic-value ::= number | text | date-time | constant 41 | 42 | number ::= int | float | decimal 43 | int ::= '-'? [0-9]+ 44 | 45 | float ::= fixed-point exp? | int exp 46 | fixed-point ::= '-'? [0-9]+ '.' [0-9]* | '-'? '.' [0-9]+ 47 | exp ::= ('E' | 'e') ('+' | '-')? [0-9]+ 48 | 49 | decimal ::= (int | float) ('d' | 'D') 50 | 51 | text ::= '"' ( ' any unicode character except " ' | '\"' ) '"' 52 | 53 | date-time ::= date | time | datetime 54 | 55 | date ::= year '-' month '-' day 56 | 57 | year ::= 'unsigned int value: year > 0' 58 | month ::= 'unsigned int value: 1 <= month <= 12' 59 | day ::= 'unsigned int value: 1 <= day <= 31' 60 | 61 | time ::= hours ':' minutes (':' seconds ('.' microseconds)? )? time-offset? 62 | 63 | hours ::= 'unsigned int value: 0 <= hours <= 23' 64 | minutes ::= 'unsigned int value: 0 <= minutes <= 59' 65 | seconds ::= 'unsigned int value: 0 <= seconds <= 59' 66 | microseconds ::= 'unsigned int value: 0 <= microseconds <= 999999' 67 | 68 | time-offset ::= ('+'|'-') hours (':' minutes)? 69 | 70 | datetime ::= date 'T' time time-offset? 71 | 72 | constant ::= 'null' | 'true' | 'false' | '-'? constant-infinity | constant-nan 73 | onstant-infinity ::= '∞' 74 | constant-nan ::= '?' 75 | 76 | binary-data ::= '|' 'Base64 encoded multiline ascii string' 77 | -------------------------------------------------------------------------------- /docs/figs/anonymous-complex-value.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/anonymous-complex-value.png -------------------------------------------------------------------------------- /docs/figs/axon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/axon.png -------------------------------------------------------------------------------- /docs/figs/base64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/base64.png -------------------------------------------------------------------------------- /docs/figs/binary-data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/binary-data.png -------------------------------------------------------------------------------- /docs/figs/complex-value.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/complex-value.png -------------------------------------------------------------------------------- /docs/figs/constant-infinity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/constant-infinity.png -------------------------------------------------------------------------------- /docs/figs/constant-nan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/constant-nan.png -------------------------------------------------------------------------------- /docs/figs/constant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/constant.png -------------------------------------------------------------------------------- /docs/figs/construct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/construct.png -------------------------------------------------------------------------------- /docs/figs/control-char.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/control-char.png -------------------------------------------------------------------------------- /docs/figs/data-attr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/data-attr.png -------------------------------------------------------------------------------- /docs/figs/data-item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/data-item.png -------------------------------------------------------------------------------- /docs/figs/date-time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/date-time.png -------------------------------------------------------------------------------- /docs/figs/date.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/date.png -------------------------------------------------------------------------------- /docs/figs/datetime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/datetime.png -------------------------------------------------------------------------------- /docs/figs/day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/day.png -------------------------------------------------------------------------------- /docs/figs/decimal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/decimal.png -------------------------------------------------------------------------------- /docs/figs/def-reference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/def-reference.png -------------------------------------------------------------------------------- /docs/figs/dict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/dict.png -------------------------------------------------------------------------------- /docs/figs/element.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/element.png -------------------------------------------------------------------------------- /docs/figs/element2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/element2.png -------------------------------------------------------------------------------- /docs/figs/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/empty.png -------------------------------------------------------------------------------- /docs/figs/empty2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/empty2.png -------------------------------------------------------------------------------- /docs/figs/exp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/exp.png -------------------------------------------------------------------------------- /docs/figs/fixed-point.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/fixed-point.png -------------------------------------------------------------------------------- /docs/figs/float.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/float.png -------------------------------------------------------------------------------- /docs/figs/hours.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/hours.png -------------------------------------------------------------------------------- /docs/figs/identifier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/identifier.png -------------------------------------------------------------------------------- /docs/figs/instance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/instance.png -------------------------------------------------------------------------------- /docs/figs/instance2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/instance2.png -------------------------------------------------------------------------------- /docs/figs/int.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/int.png -------------------------------------------------------------------------------- /docs/figs/key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/key.png -------------------------------------------------------------------------------- /docs/figs/label.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/label.png -------------------------------------------------------------------------------- /docs/figs/list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/list.png -------------------------------------------------------------------------------- /docs/figs/mapping.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/mapping.png -------------------------------------------------------------------------------- /docs/figs/mapping2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/mapping2.png -------------------------------------------------------------------------------- /docs/figs/microseconds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/microseconds.png -------------------------------------------------------------------------------- /docs/figs/minutes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/minutes.png -------------------------------------------------------------------------------- /docs/figs/month.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/month.png -------------------------------------------------------------------------------- /docs/figs/name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/name.png -------------------------------------------------------------------------------- /docs/figs/named-complex-value.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/named-complex-value.png -------------------------------------------------------------------------------- /docs/figs/number.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/number.png -------------------------------------------------------------------------------- /docs/figs/object.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/object.png -------------------------------------------------------------------------------- /docs/figs/reference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/reference.png -------------------------------------------------------------------------------- /docs/figs/seconds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/seconds.png -------------------------------------------------------------------------------- /docs/figs/sequence.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/sequence.png -------------------------------------------------------------------------------- /docs/figs/sequence2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/sequence2.png -------------------------------------------------------------------------------- /docs/figs/set.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/set.png -------------------------------------------------------------------------------- /docs/figs/simple-value.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/simple-value.png -------------------------------------------------------------------------------- /docs/figs/simpleon_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/simpleon_logo.png -------------------------------------------------------------------------------- /docs/figs/simpleon_logo_72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/simpleon_logo_72.png -------------------------------------------------------------------------------- /docs/figs/string-key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/string-key.png -------------------------------------------------------------------------------- /docs/figs/text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/text.png -------------------------------------------------------------------------------- /docs/figs/time-offset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/time-offset.png -------------------------------------------------------------------------------- /docs/figs/time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/time.png -------------------------------------------------------------------------------- /docs/figs/tuple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/tuple.png -------------------------------------------------------------------------------- /docs/figs/unicode-hex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/unicode-hex.png -------------------------------------------------------------------------------- /docs/figs/value.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/value.png -------------------------------------------------------------------------------- /docs/figs/year.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellimath/pyaxon/fcadf741bedd71fdb21d6e8b865da2a22f2bd1fb/docs/figs/year.png -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | 2 | .. 3 | ================================= 4 | AXON is eXtended Object Notation 5 | ================================= 6 | 7 | .. Contents: 8 | .. 9 | .. .. toctree:: 10 | .. :maxdepth: 2 11 | .. 12 | 13 | .. Indices and tables 14 | .. ================== 15 | .. 16 | .. * :ref:`genindex` 17 | .. * :ref:`modindex` 18 | .. * :ref:`search` 19 | 20 | What is AXON 21 | ------------ 22 | 23 | AXON is eXtended Object Notation (``AXON``). It's a simple text based format 24 | for interchanging of objects, documents and data. 25 | There is `railroad diagram `_ 26 | in order to describe `AXON`. 27 | 28 | It tries to combine the best of `JSON `_, 29 | `XML `_ and `YAML `_. 30 | 31 | ``AXON`` is designed as a text based language for data exchange in the first place. 32 | 33 | It combines in itself: 34 | 35 | * **simplicity** of ``JSON``, 36 | 37 | * **extensibility** of ``XML``, 38 | 39 | * **readability** of ``YAML``. 40 | 41 | Creation of ``AXON`` had the following objectives: 42 | 43 | * Overcoming lack of support of date/time, decimal and binary data in ``JSON``. 44 | 45 | * Overcoming inability to represent in ``JSON`` complex data 46 | with cross-references natively. 47 | 48 | * Extension of ``JSON`` for native support of named/taged data structures 49 | (typed complex data, elements of documents etc.) in order to act in 50 | cases where ``XML`` is more suitable than ``JSON``. 51 | 52 | * Support both ``JSON``-style and ``YAML``-style of formatting of ``AXON`` messages. 53 | 54 | * Removing ``','`` as mandatory character-separator for items in containers. 55 | 56 | * Saving relative simplicity of the language compared to ``JSON``. 57 | 58 | ``AXON`` is designed as text based format that has compact form and 59 | formatted form in both ``JSON/C`` and ``YAML/Python`` style for ease of developers. 60 | 61 | ``AXON`` is an object notation for data, which are composed from atomic values 62 | by several rules of composition: 63 | 64 | .. raw:: html 65 | 66 | 67 | 80 | 81 | 82 | 85 | 86 | 87 | 90 | 91 | 92 | 95 | 96 | 97 | 100 | 101 | 102 | 105 | 106 | 107 | 112 |
NameRuleExample
list[ VV ]
 83 |     [1 3.14 3.25D ∞ -∞ ?]
 84 |     
tuple( VV )
 88 |     (true ^12:00 ^2001-12-31 ^2001-12-31T12:00)
 89 |     
set{ VV }
 93 |     {"a" "b" "c" "d" "e" "f"}
 94 |     
dict{ K:VK:V }
 98 |     {alpha:1 beta:2 gamma:3 "other chars":4}
 99 |     
ordered dict[ K:VK:V ]
103 |     [alpha:1 beta:2 gamma:3 "other chars":4]
104 |     
nodeN { N:VN:V VV }
108 |     greek {alpha:123 beta:212 gamma:322}
109 |     primes {2 3 5 7 11 13 17 19 23}
110 |     tree {id:1 leaf{id:2 "AAA"} leaf{id:3 "BBB"}}
111 |     
113 | 114 | where **N** denotes a *name*, **K** denotes a *key*, **V** denotes a *value*. 115 | 116 | Here is an example of ``AXON`` message: 117 | 118 | .. raw:: html 119 | 120 | 121 | 122 | 123 | 158 | 193 | 194 | 195 | 207 |
statement formformatted expression form
124 | 	axon
125 | 	  name: "AXON is eXtended Object Notation"
126 | 	  short_name: "AXON"
127 | 	  python_library: "pyaxon"
128 | 	  atomic_values
129 | 	    int: [0 -1 17]
130 | 	    float: [3.1428 1.5e-17]
131 | 	    decimal: [10D 1000.35D -1.25E+6D]
132 | 	    bool: [true false]
133 | 	    string: "abc абв 中文本"
134 | 	    multiline_string: "one
135 | 	two
136 | 	three"
137 | 	    date: ^2012-12-31
138 | 	    time: [^12:30:34 ^12:35:12.000120 ^12:35+03]
139 | 	    datetime: [^2012-12-31T12:30 ^2012-12-31T12:35+03]
140 | 	    binary: |QVhPTiBpcyBlWHRlbmRlZCBPYmplY3QgTm90YXRpb24=
141 | 
142 | 	complex_values
143 | 	    list: ["one" "two" "three"]
144 | 	    dict: {
145 | 	      one: 1
146 | 	      three: 3
147 | 	      two: 2}
148 | 	    odered_dict: [
149 | 	      one: 1
150 | 	      three: 3
151 | 	      two: 2]
152 | 	    tuple: ("nodes" "edges")
153 | 	    set: {"a" "b" "c"}
154 | 	    node: person
155 | 	      name: "Alex"
156 | 	      age: 32
157 |     
159 | 	axon {
160 | 	  name: "AXON is eXtended Object Notation"
161 | 	  short_name: "AXON"
162 | 	  python_library: "pyaxon"
163 | 	  atomic_values {
164 | 	    int: [0 -1 17]
165 | 	    float: [3.1428 1.5e-17]
166 | 	    decimal: [10D 1000.35D -1.25E+6D]
167 | 	    bool: [true false]
168 | 	    string: "abc абв 中文本"
169 | 	    multiline_string: "one
170 | 	two
171 | 	three"
172 | 	    date: ^2012-12-31
173 | 	    time: [^12:30:34 ^12:35:12.000120 ^12:35+03]
174 | 	    datetime: [2012-12-31T12:30 2012-12-31T12:35+03]
175 | 	    binary: |QVhPTiBpcyBlWHRlbmRlZCBPYmplY3QgTm90YXRpb24=
176 | 	}
177 | 	complex_values {
178 | 	    list: ["one" "two" "three"]
179 | 	    dict: {
180 | 	      one: 1
181 | 	      three: 3
182 | 	      two: 2}
183 | 	    odered_dict: [
184 | 	      one: 1
185 | 	      three: 3
186 | 	      two: 2]
187 | 	    tuple: ("nodes" "edges")
188 | 	    set: {"a" "b" "c"}
189 | 	    node: person {
190 | 	      name: "Alex"
191 | 	      age: 32}}}
192 |     
compact expression form
196 | 	axon{name:"AXON is eXtended Object Notation" short_name:"AXON" python_library:"pyaxon"
197 | 	atomic_values{int:[0 -1 17] float:[3.1428 1.5e-17] decimal:[10D 1000.35D -1.25E+6D] 
198 | 	bool:[true false] string:"abc абв 中文本" multiline_string:"one
199 | 	two
200 | 	three" date:^2012-12-31 time:[^12:30:34 ^12:35:12.000120 ^12:35+03]
201 | 	datetime:[^2012-12-31T12:30 ^2012-12-31T12:35+03]
202 | 	binary:|QVhPTiBpcyBlWHRlbmRlZCBPYmplY3QgTm90YXRpb24=
203 | 	} complex_values{list:["one" "two" "three"] dict:{one:1 three:3 two:2}
204 | 	odered_dict:[one:1 two:2 three:3] tuple:("nodes" "edges")
205 | 	set:{"a" "b" "c"} node:person{name:"Alex" age:32}}}
206 |     
208 | 209 | 210 | 211 | Python pyaxon library 212 | --------------------- 213 | 214 | `pyaxon `_ is an `MIT Licensed `_ 215 | `python `_ library for ``AXON``. 216 | 217 | There are some `IPython` `notebooks `_. 218 | 219 | `Repository `_ for ``AXON`` and ``pyaxon``. 220 | Mirror on `github `_. 221 | 222 | `Blog `_ about AXON. 223 | 224 | History of `changes `_. 225 | 226 | API Reference 227 | ------------- 228 | 229 | .. toctree:: 230 | :maxdepth: 2 231 | 232 | api 233 | 234 | .. raw:: html 235 | 236 | 245 | -------------------------------------------------------------------------------- /examples/axon_datamodel.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# AXON data model" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "Data model of `AXON` includes several types of objects:\n", 15 | "\n", 16 | "* *dictionary* and *ordered dictionary*\n", 17 | "* *list* and *tuple*\n", 18 | "* *node*\n", 19 | "\n", 20 | "Each kind of objects corresponds to specific way of composition of values." 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "`AXON` message is a collection of *data items*.\n", 28 | "\n", 29 | "**Data item** is *atomic* value, *complex value* or *reference* to the complex value.\n", 30 | "\n", 31 | "**Atomic value** is *integer* values, *float* value, *decimal* value, *date*/*time*/*datetime* value, *boolean* value or constant.\n", 32 | "\n", 33 | "**Complex value** is *named complex value* or *anonimous complex value*.\n", 34 | "\n", 35 | "**Anonimous complex value** is *dictionary*, *list* or *tuple*.\n", 36 | "\n", 37 | "**Named complex value** is *node*." 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": {}, 43 | "source": [ 44 | "## Anonimous values" 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "metadata": {}, 50 | "source": [ 51 | "### Dictionary" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "metadata": {}, 57 | "source": [ 58 | "**Dictionary** is a _unordered_ collection of *key*:*data item* pairs, where *key* is an unicode string, enclosed in double quotes or identifier name. Members of the dictionary are accesses by keys." 59 | ] 60 | }, 61 | { 62 | "cell_type": "markdown", 63 | "metadata": {}, 64 | "source": [ 65 | "### Ordered dictionary" 66 | ] 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "metadata": {}, 71 | "source": [ 72 | "**Ordered Dictionary** is a _ordered_ collection of *key*:*data item* pairs, where *key* is an unicode string, enclosed in double quotes or identifier name. Members of the ordered dictionary are accesses by keys." 73 | ] 74 | }, 75 | { 76 | "cell_type": "markdown", 77 | "metadata": {}, 78 | "source": [ 79 | "### List" 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "metadata": {}, 85 | "source": [ 86 | "**List** is a oredered (usually mutable) collection of *data items*. Members of the list are accessed by integer index." 87 | ] 88 | }, 89 | { 90 | "cell_type": "markdown", 91 | "metadata": {}, 92 | "source": [ 93 | "### Tuple" 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": {}, 99 | "source": [ 100 | "**Tuple** is fixed ordered collection of data items. Members of the tuple are accessed by integer index." 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "metadata": {}, 106 | "source": [ 107 | "## Named complex value" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": {}, 113 | "source": [ 114 | "### Node" 115 | ] 116 | }, 117 | { 118 | "cell_type": "markdown", 119 | "metadata": {}, 120 | "source": [ 121 | "**Node** is a *mapping* with a nested/child *list* of values." 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": null, 127 | "metadata": { 128 | "collapsed": false 129 | }, 130 | "outputs": [], 131 | "source": [] 132 | } 133 | ], 134 | "metadata": { 135 | "kernelspec": { 136 | "display_name": "Python 3", 137 | "language": "python", 138 | "name": "python3" 139 | }, 140 | "language_info": { 141 | "codemirror_mode": { 142 | "name": "ipython", 143 | "version": 3 144 | }, 145 | "file_extension": ".py", 146 | "mimetype": "text/x-python", 147 | "name": "python", 148 | "nbconvert_exporter": "python", 149 | "pygments_lexer": "ipython3", 150 | "version": "3.4.3" 151 | } 152 | }, 153 | "nbformat": 4, 154 | "nbformat_minor": 0 155 | } 156 | -------------------------------------------------------------------------------- /examples/axon_habr.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 2, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import axon\n", 12 | "from collections import namedtuple" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 13, 18 | "metadata": { 19 | "collapsed": false 20 | }, 21 | "outputs": [ 22 | { 23 | "name": "stdout", 24 | "output_type": "stream", 25 | "text": [ 26 | "Person(name='Иванов', age=30)\n" 27 | ] 28 | } 29 | ], 30 | "source": [ 31 | "text = \"\"\"\n", 32 | "person { name:\"Иванов\" age:30 }\n", 33 | "\"\"\"\n", 34 | "Person = namedtuple(\"Person\", \"name age\")\n", 35 | "\n", 36 | "@axon.factory(\"person\")\n", 37 | "def Person_factory(attrs, vals):\n", 38 | " return Person(**attrs)\n", 39 | "\n", 40 | "\n", 41 | "vals = axon.loads(text, mode=\"strict\")\n", 42 | "print(vals[0])" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 15, 48 | "metadata": { 49 | "collapsed": false 50 | }, 51 | "outputs": [ 52 | { 53 | "name": "stdout", 54 | "output_type": "stream", 55 | "text": [ 56 | "[[Person(name='Иванов', age=30), Person(name='Сидоров', age=33)]]\n" 57 | ] 58 | } 59 | ], 60 | "source": [ 61 | "text2 = \"\"\"\n", 62 | "persons {\n", 63 | " {name: \"Иванов\" age: 30}\n", 64 | " {name: \"Сидоров\" age:33}\n", 65 | "}\n", 66 | "\"\"\"\n", 67 | "\n", 68 | "@axon.factory(\"persons\")\n", 69 | "def persons_factory(attra, vals):\n", 70 | " return [Person(**val) for val in vals]\n", 71 | "\n", 72 | "\n", 73 | "vals = axon.loads(text2, mode=\"strict\")\n", 74 | "print(vals)" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": null, 80 | "metadata": { 81 | "collapsed": true 82 | }, 83 | "outputs": [], 84 | "source": [] 85 | } 86 | ], 87 | "metadata": { 88 | "kernelspec": { 89 | "display_name": "Python 3", 90 | "language": "python", 91 | "name": "python3" 92 | }, 93 | "language_info": { 94 | "codemirror_mode": { 95 | "name": "ipython", 96 | "version": 3 97 | }, 98 | "file_extension": ".py", 99 | "mimetype": "text/x-python", 100 | "name": "python", 101 | "nbconvert_exporter": "python", 102 | "pygments_lexer": "ipython3", 103 | "version": "3.5.2" 104 | } 105 | }, 106 | "nbformat": 4, 107 | "nbformat_minor": 0 108 | } 109 | -------------------------------------------------------------------------------- /examples/axon_metadata.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import axon" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 2, 17 | "metadata": { 18 | "collapsed": false 19 | }, 20 | "outputs": [ 21 | { 22 | "name": "stdout", 23 | "output_type": "stream", 24 | "text": [ 25 | "{@:'name', @type:'test', 'a': 1, 'b': 2, 'c': 3} {'': 'name', 'type': 'test'}\n", 26 | "{@:\"name\" @type:\"test\" a:1 b:2 c:3}\n", 27 | "{ @: \"name\"\n", 28 | " @type: \"test\"\n", 29 | " a: 1\n", 30 | " b: 2\n", 31 | " c: 3}\n" 32 | ] 33 | } 34 | ], 35 | "source": [ 36 | "vals = axon.loads('''{@: \"name\" \n", 37 | "@type: \"test\" \n", 38 | "a:1 b:2 c:3}''')\n", 39 | "print(vals[0], vals[0].__metadata__)\n", 40 | "text = axon.dumps(vals)\n", 41 | "print(text)\n", 42 | "text = axon.dumps(vals, pretty=1)\n", 43 | "print(text)" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 3, 49 | "metadata": { 50 | "collapsed": false 51 | }, 52 | "outputs": [ 53 | { 54 | "name": "stdout", 55 | "output_type": "stream", 56 | "text": [ 57 | "[@:'name', @type:'test', 1, 2, 3] {'': 'name', 'type': 'test'}\n", 58 | "[@:\"name\" @type:\"test\" 1 2 3]\n", 59 | "[ @: \"name\"\n", 60 | " @type: \"test\"\n", 61 | " 1 2 3]\n" 62 | ] 63 | } 64 | ], 65 | "source": [ 66 | "vals = axon.loads('''[@: \"name\" \n", 67 | "@type: \"test\" \n", 68 | "1 2 3]''')\n", 69 | "print(vals[0], vals[0].__metadata__)\n", 70 | "text = axon.dumps(vals)\n", 71 | "print(text)\n", 72 | "text = axon.dumps(vals, pretty=1)\n", 73 | "print(text)" 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": null, 79 | "metadata": { 80 | "collapsed": true 81 | }, 82 | "outputs": [], 83 | "source": [] 84 | } 85 | ], 86 | "metadata": { 87 | "kernelspec": { 88 | "display_name": "Python 3", 89 | "language": "python", 90 | "name": "python3" 91 | }, 92 | "language_info": { 93 | "codemirror_mode": { 94 | "name": "ipython", 95 | "version": 3 96 | }, 97 | "file_extension": ".py", 98 | "mimetype": "text/x-python", 99 | "name": "python", 100 | "nbconvert_exporter": "python", 101 | "pygments_lexer": "ipython3", 102 | "version": "3.4.3" 103 | } 104 | }, 105 | "nbformat": 4, 106 | "nbformat_minor": 0 107 | } 108 | -------------------------------------------------------------------------------- /examples/axon_object_datamodel.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "This post continue [series](http://intellimath.bitbucket.org/blog/categories/axon.html) about [AXON](http://intellimath.bitbucket.org/axon) and [pyaxon](http://pypi.python.org/pypi/pyaxon). Now we consider AXON datamodel and some realted aspects of object serialization." 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "AXON datamodel bases on composition of several data construction patterns. It reflects both JSON and XML datamodels." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "AXON datamodel has two rules of composition that reflects JSON datamodel:\n", 22 | "\n", 23 | "* if *values* $D_1,\\dots,D_n$ belong to AXON datamodel then the *list* $[D_1,\\dots,D_n]$ belongs to AXON datamodel;\n", 24 | "* if *values* $D_1,\\dots,D_n$ belong to AXON datamodel then for any sequence of *string keys* $k_1,\\dots,k_n$ the *dictionary* $\\{k_1\\colon D_1,\\dots,k_2\\colon D_n\\}$ belongs to AXON datamodel.\n", 25 | "\n", 26 | "In addition AXON datamodel has a rule of composition for construction of tuples — fixed sequence of values:\n", 27 | "\n", 28 | "* if *values* $D_1,\\dots,D_n$ belong to AXON datamodel then the *tuple* $(D_1,\\dots,D_n)$ belongs to AXON datamodel.\n" 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "metadata": {}, 34 | "source": [ 35 | "AXON datamodel also has three rules of composition that reflects XML infoset datamodel:\n", 36 | "\n", 37 | "* if *values* $D_1,\\dots,D_n$ belong to AXON datamodel then for any *name* $\\text{N}$ the *named sequence* $\\text{N}\\{D_1,\\dots,D_n\\}$ belongs to AXON datamodel;\n", 38 | "* if *values* $D_1,\\dots,D_n$ belong to AXON datamodel then for any sequence of *attribute names* $a_1,\\dots,a_n$ and any *name* $\\text{N}$ the *named mapping* $\\text{N}\\{a_1\\colon D_1,\\dots,a_n\\colon D_n\\}$ belongs to AXON datamodel;\n", 39 | "* *values* if $D_1,\\dots,D_n$ and $E_1,\\dots,E_m$ belong to AXON datamodel then for any *name* $\\text{N}$ and sequence of *attribute names* $a_1,\\dots,a_n$ the *named element* $\\text{N}\\{a_1\\colon D_1,\\dots,a_n\\colon D_n,\\ E_1,\\dots,E_m \\}$ belongs to AXON datamodel.\n", 40 | "\n", 41 | "First rule allows to construct structures (*named sequences*) similar to XML element without attributes. Second rule allows to construct structures (*named mappings*) similar to XML element without of subelements. Third rule allows to construct structures (*named elements*) similar XML element both with attributes and subelements. Unlike XML, in AXON attribute's value can be an arbitrary value." 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "metadata": {}, 47 | "source": [ 48 | "AXON datamodel has yet another rule of composition that reflects concept of *named tuple*, which contain fixed number of values and may contain also *optional* values specified by their *attribute name*:\n", 49 | "res, which are composed by several rules:\n", 50 | "\n", 51 | "* if *values* $D_1,\\dots,D_n$ and $E_1,\\dots,E_m$ belong to AXON datamodel then for any name $\\text{N}$ and sequence of *attribute names* $a_1,\\dots,a_n$ the *named instance* $\\text{N}\\{E_1,\\dots,E_m,\\ a_1\\colon D_1,\\dots,a_n\\colon D_n \\}$ belongs to AXON datamodel.\n", 52 | "\n", 53 | "Last rule is for symmetry; it useful for representation of data rows with fixed fields and optional fields specified by their names." 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "metadata": {}, 59 | "source": [ 60 | "AXON named complex values can be mapped to objects by their names. [pyaxon](http://pypi.python.org/pypi/pyaxon) module supports protocol for loading and dumping." 61 | ] 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "metadata": {}, 66 | "source": [ 67 | "AXON lists, dicts and tuples are mapped to python's list, dicts and tuples." 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "metadata": {}, 73 | "source": [ 74 | "### Loading protocol" 75 | ] 76 | }, 77 | { 78 | "cell_type": "markdown", 79 | "metadata": {}, 80 | "source": [ 81 | "For named complex values one can define a class with base class `GenericBuilder`, which has four methods:\n", 82 | "\n", 83 | "* `sequence(name, list)`;\n", 84 | "* `mapping(name, dict)`;\n", 85 | "* `element(name, dict, list)`;\n", 86 | "* `instance(name, list, dict)`.\n" 87 | ] 88 | }, 89 | { 90 | "cell_type": "markdown", 91 | "metadata": {}, 92 | "source": [ 93 | "During loading these methods are called according to next rules that corresponds to last four above rules of composition:\n", 94 | "\n", 95 | "* for objects $D_1,\\dots,D_n$ and name $\\text{N}$ object is constructed by calling of the method `sequence(` $\\text{N}$, $[D_1,\\dots,D_n]$ `)`;\n", 96 | "* for objects $D_1,\\dots,D_n$, names $a_1,\\dots,a_n$ and name $\\text{N}$ object is constructed by calling of the method `mapping(` $\\text{N}$, $\\{a_1\\colon D_1,\\dots,a_n\\colon D_n\\}$ `)`;\n", 97 | "* for objects $D_1,\\dots,D_n$ and $E_1,\\dots,E_m$, name $\\text{N}$ and names $a_1,\\dots,a_n$ object is constructed by calling of the method `element(` $\\text{N}$, $\\{a_1\\colon D_1,\\dots,a_n\\colon D_n\\}, [E_1,\\dots,E_m]$ `)`;\n", 98 | "* for objects $D_1,\\dots,D_n$ and $E_1,\\dots,E_m$, name $\\text{N}$ and names $a_1,\\dots,a_n$ object is constructed by calling of the method `instance(` $\\text{N}$, $[E_1,\\dots,E_m]$, $\\{a_1\\colon D_1,\\dots,a_n\\colon D_n\\}$ `)`.\n" 99 | ] 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "metadata": {}, 104 | "source": [ 105 | "### Dumping protocol" 106 | ] 107 | }, 108 | { 109 | "cell_type": "markdown", 110 | "metadata": {}, 111 | "source": [ 112 | "There is a protocol for dumping python objects. In order to dump the class `C` instances one have to do the following:\n", 113 | "\n", 114 | "* define function that takes instance `o` of the class `C` and returns instance of `Empty`, `Sequence`, `Mapping`, `Element` or `Instance`;\n", 115 | "* register them using builtin `reduce` function." 116 | ] 117 | }, 118 | { 119 | "cell_type": "markdown", 120 | "metadata": {}, 121 | "source": [ 122 | "Empty" 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": 1, 128 | "metadata": { 129 | "collapsed": false 130 | }, 131 | "outputs": [], 132 | "source": [ 133 | "from __future__ import print_function, unicode_literals\n", 134 | "from axon.api import loads, dumps\n", 135 | "\n", 136 | "# pretty printing of python objects\n", 137 | "from pprint import pprint\n", 138 | "\n", 139 | "# ipython tools for pretty of images and html\n", 140 | "from IPython.display import HTML, display" 141 | ] 142 | } 143 | ], 144 | "metadata": { 145 | "kernelspec": { 146 | "display_name": "Python 3", 147 | "language": "python", 148 | "name": "python3" 149 | }, 150 | "language_info": { 151 | "codemirror_mode": { 152 | "name": "ipython", 153 | "version": 3 154 | }, 155 | "file_extension": ".py", 156 | "mimetype": "text/x-python", 157 | "name": "python", 158 | "nbconvert_exporter": "python", 159 | "pygments_lexer": "ipython3", 160 | "version": "3.5.2" 161 | }, 162 | "widgets": { 163 | "state": {}, 164 | "version": "1.1.2" 165 | } 166 | }, 167 | "nbformat": 4, 168 | "nbformat_minor": 0 169 | } 170 | -------------------------------------------------------------------------------- /examples/axon_readable_as_yaml.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Isn't AXON as readable as YAML?" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "Let's consider example of `YAML` formatted configuration file:\n", 15 | "\n", 16 | "``` yaml\n", 17 | "application: myapp\n", 18 | "version: alpha-001\n", 19 | "runtime: python27\n", 20 | "api_version: 1\n", 21 | "threadsafe: true\n", 22 | "\n", 23 | "# url handlers\n", 24 | "handlers:\n", 25 | "- url: /\n", 26 | " script: home.app\n", 27 | "\n", 28 | "- url: /index\\.html\n", 29 | " script: home.app\n", 30 | "\n", 31 | "- url: /stylesheets\n", 32 | " static_dir: stylesheets\n", 33 | "\n", 34 | "- url: /(.*\\.(gif|png|jpg))\n", 35 | " static_files: static/\\1\n", 36 | " upload: static/.*\\.(gif|png|jpg)\n", 37 | "\n", 38 | "- url: /admin/.*\n", 39 | " script: admin.app\n", 40 | " login: admin\n", 41 | "\n", 42 | "- url: /.*\n", 43 | " script: not_found.app\n", 44 | "```" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": 1, 50 | "metadata": { 51 | "collapsed": false 52 | }, 53 | "outputs": [ 54 | { 55 | "name": "stdout", 56 | "output_type": "stream", 57 | "text": [ 58 | "['/', '/index\\\\.html', '/stylesheets', '/(.*\\\\.(gif|png|jpg))', '/admin/.*', '/.*']\n" 59 | ] 60 | } 61 | ], 62 | "source": [ 63 | "# print all urls\n", 64 | "import yaml\n", 65 | "import io\n", 66 | "val = yaml.safe_load(io.open(\"example_config.yaml\", \"rt\"))\n", 67 | "print([entry[\"url\"] for entry in val[\"handlers\"]])" 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "metadata": {}, 73 | "source": [ 74 | "In [AXON](http://intellimath.bitbucket.org/axon) it will be formatted as:\n", 75 | "\n", 76 | "``` yaml\n", 77 | "application: \"myapp\"\n", 78 | "version: \"alpha-001\"\n", 79 | "runtime: \"python27\"\n", 80 | "api_version: 1\n", 81 | "threadsafe: true\n", 82 | "\n", 83 | "# url handlers\n", 84 | "handlers: [\n", 85 | " { url: \"/\"\n", 86 | " script: \"home.app\" }\n", 87 | " \n", 88 | " { url: \"/index\\.html\"\n", 89 | " script: \"home.app\" }\n", 90 | " \n", 91 | " { url: \"/stylesheets\"\n", 92 | " static_dir: \"stylesheets\" }\n", 93 | " \n", 94 | " { url: \"/(.*\\.(gif|png|jpg))\"\n", 95 | " static_files: \"static/\\1\"\n", 96 | " upload: \"static/.*\\.(gif|png|jpg)\" }\n", 97 | " \n", 98 | " { url: \"/admin/.*\"\n", 99 | " script: \"admin.app\"\n", 100 | " login: \"admin\" }\n", 101 | " \n", 102 | " { url: \"/.*\"\n", 103 | " script: \"not_found.app\" }\n", 104 | "]\n", 105 | "```" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": 2, 111 | "metadata": { 112 | "collapsed": false 113 | }, 114 | "outputs": [ 115 | { 116 | "name": "stdout", 117 | "output_type": "stream", 118 | "text": [ 119 | "['/', '/index\\\\.html', '/stylesheets', '/(.*\\\\.(gif|png|jpg))', '/admin/.*', '/.*']\n" 120 | ] 121 | } 122 | ], 123 | "source": [ 124 | "# print all urls\n", 125 | "import axon\n", 126 | "val = axon.load(\"example_config1.axon\")\n", 127 | "print([entry[\"url\"] for entry in val[\"handlers\"]])" 128 | ] 129 | }, 130 | { 131 | "cell_type": "markdown", 132 | "metadata": { 133 | "collapsed": true 134 | }, 135 | "source": [ 136 | "With `AXON` it can be also presented in the following form:\n", 137 | "\n", 138 | "``` yaml\n", 139 | "_\n", 140 | " application: \"myapp\"\n", 141 | " version: \"alpha-001\"\n", 142 | " runtime: \"python27\"\n", 143 | " api_version: 1\n", 144 | " threadsafe: true\n", 145 | "\n", 146 | " # url handlers\n", 147 | " handlers\n", 148 | " _\n", 149 | " url: \"/\"\n", 150 | " script: \"home.app\" \n", 151 | " _\n", 152 | " url: \"/index\\.html\"\n", 153 | " script: \"home.app\"\n", 154 | " _\n", 155 | " url: \"/stylesheets\"\n", 156 | " static_dir: \"stylesheets\"\n", 157 | " _\n", 158 | " url: \"/(.*\\.(gif|png|jpg))\"\n", 159 | " static_files: \"static\\1\"\n", 160 | " upload: \"static/.*\\.(gif|png|jpg)\"\n", 161 | " _\n", 162 | " url: \"/admin/.*\"\n", 163 | " script: \"admin.app\"\n", 164 | " login: \"admin\"\n", 165 | " _\n", 166 | " url: \"/.*\"\n", 167 | " script: \"not_found.app\"\n", 168 | "```" 169 | ] 170 | }, 171 | { 172 | "cell_type": "code", 173 | "execution_count": 3, 174 | "metadata": { 175 | "collapsed": false 176 | }, 177 | "outputs": [ 178 | { 179 | "name": "stdout", 180 | "output_type": "stream", 181 | "text": [ 182 | "['/', '/index\\\\.html', '/stylesheets', '/(.*\\\\.(gif|png|jpg))', '/admin/.*', '/.*']\n" 183 | ] 184 | } 185 | ], 186 | "source": [ 187 | "# print all urls\n", 188 | "vals = axon.load(\"example_config2.axon\")\n", 189 | "print([entry.url for entry in vals[0].handlers])" 190 | ] 191 | }, 192 | { 193 | "cell_type": "markdown", 194 | "metadata": {}, 195 | "source": [ 196 | "Isn't configuration file in `AXON` as readable as in `YAML`?" 197 | ] 198 | }, 199 | { 200 | "cell_type": "code", 201 | "execution_count": null, 202 | "metadata": { 203 | "collapsed": true 204 | }, 205 | "outputs": [], 206 | "source": [] 207 | } 208 | ], 209 | "metadata": { 210 | "kernelspec": { 211 | "display_name": "Python 3", 212 | "language": "python", 213 | "name": "python3" 214 | }, 215 | "language_info": { 216 | "codemirror_mode": { 217 | "name": "ipython", 218 | "version": 3 219 | }, 220 | "file_extension": ".py", 221 | "mimetype": "text/x-python", 222 | "name": "python", 223 | "nbconvert_exporter": "python", 224 | "pygments_lexer": "ipython3", 225 | "version": "3.4.3" 226 | } 227 | }, 228 | "nbformat": 4, 229 | "nbformat_minor": 0 230 | } 231 | -------------------------------------------------------------------------------- /examples/axon_schema.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import axon" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 3, 17 | "metadata": { 18 | "collapsed": false 19 | }, 20 | "outputs": [], 21 | "source": [ 22 | "#@axon.schema(\"person\")\n", 23 | "class SchemaPerson:\n", 24 | " #\n", 25 | " def mapping_factory(self, attrs):\n", 26 | " return Person(\n", 27 | " schema_profile.factory(attrs[\"profile\"]),\n", 28 | " [schema_post.factory(p) for p in attrs[\"posts\"]])\n", 29 | " #\n", 30 | " def reduce(self, obj):\n", 31 | " return axon.mapping(\"person\", \n", 32 | " {\"profile\":schema_profile.reduce(obj.profile), \n", 33 | " \"posts\":[schema_post.reduce(p) for p in obj.posts]})\n", 34 | " \n", 35 | " \n", 36 | "#@axon.schema(\"post\")\n", 37 | "class SchemaPost:\n", 38 | " #\n", 39 | " def factory(self, args):\n", 40 | " return Post(*args)\n", 41 | " #\n", 42 | " def validate(self, post, context):\n", 43 | " return post[\"date\"].year > 1900\n", 44 | " #\n", 45 | " def reduce(self, obj):\n", 46 | " return {\"to\":obj.to, \"text\":obj.text, \"date\":obj.date, \"time\":obj.time}\n", 47 | " #\n", 48 | "\n", 49 | "#@axon.schema(\"profile\")\n", 50 | "class SchemaProfile:\n", 51 | " #\n", 52 | " def factory(self, name, age):\n", 53 | " return Profile(name, age)\n", 54 | " #\n", 55 | " def reduce(self, obj):\n", 56 | " return {\"name\": obj.name, \"age\":obj.age}\n", 57 | " #\n", 58 | "\n", 59 | " " 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": 4, 65 | "metadata": { 66 | "collapsed": true 67 | }, 68 | "outputs": [], 69 | "source": [ 70 | "text = \"\"\"\n", 71 | "person {\n", 72 | " profile: {\n", 73 | " name: \"Alex\"\n", 74 | " age: 27 \n", 75 | " }\n", 76 | " posts: [\n", 77 | " {to:\"Frank\" text:\"Hello Frank\" date:2015-04-20 time:12:23:24}\n", 78 | " {to:\"Henry\" text:\"How are you\" date:2015-04-20 time:12:26:38}\n", 79 | " ]\n", 80 | "}\n", 81 | "\"\"\"" 82 | ] 83 | }, 84 | { 85 | "cell_type": "code", 86 | "execution_count": null, 87 | "metadata": { 88 | "collapsed": true 89 | }, 90 | "outputs": [], 91 | "source": [] 92 | } 93 | ], 94 | "metadata": { 95 | "kernelspec": { 96 | "display_name": "Python 3", 97 | "language": "python", 98 | "name": "python3" 99 | }, 100 | "language_info": { 101 | "codemirror_mode": { 102 | "name": "ipython", 103 | "version": 3 104 | }, 105 | "file_extension": ".py", 106 | "mimetype": "text/x-python", 107 | "name": "python", 108 | "nbconvert_exporter": "python", 109 | "pygments_lexer": "ipython3", 110 | "version": "3.4.3" 111 | } 112 | }, 113 | "nbformat": 4, 114 | "nbformat_minor": 0 115 | } 116 | -------------------------------------------------------------------------------- /examples/axon_step_by_step.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# AXON: Step by step" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 8, 13 | "metadata": { 14 | "collapsed": true 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import axon\n", 19 | "from pprint import pprint" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": {}, 25 | "source": [ 26 | "Load top-level lis of objects:" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": 13, 32 | "metadata": { 33 | "collapsed": false 34 | }, 35 | "outputs": [ 36 | { 37 | "name": "stdout", 38 | "output_type": "stream", 39 | "text": [ 40 | "[{'blue': 64, 'green': 32, 'red': 0},\n", 41 | " {'blue': 0, 'green': 64, 'red': 32},\n", 42 | " {'blue': 32, 'green': 0, 'red': 64}]\n", 43 | "{ blue: 64\n", 44 | " green: 32\n", 45 | " red: 0}\n", 46 | "{ blue: 0\n", 47 | " green: 64\n", 48 | " red: 32}\n", 49 | "{ blue: 32\n", 50 | " green: 0\n", 51 | " red: 64}\n" 52 | ] 53 | } 54 | ], 55 | "source": [ 56 | "text = \"\"\"\n", 57 | "{red:0 green:32 blue:64}\n", 58 | "{red:32 green:64 blue:0}\n", 59 | "{red:64 green:0 blue:32}\n", 60 | "\"\"\"\n", 61 | "vals = axon.loads(text)\n", 62 | "pprint(vals)\n", 63 | "print(axon.dumps(vals, pretty=1))" 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": {}, 69 | "source": [ 70 | "Load top-level ordered map:" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 14, 76 | "metadata": { 77 | "collapsed": false 78 | }, 79 | "outputs": [ 80 | { 81 | "name": "stdout", 82 | "output_type": "stream", 83 | "text": [ 84 | "OrderedDict([('a', [1, 2, 3]), ('b', [4, 5, 6]), ('c', [7, 8, 9])])\n", 85 | "a: [1 2 3]\n", 86 | "b: [4 5 6]\n", 87 | "c: [7 8 9]\n" 88 | ] 89 | } 90 | ], 91 | "source": [ 92 | "text = \"\"\"\n", 93 | "a: [1 2 3]\n", 94 | "b: [4 5 6]\n", 95 | "c: [7 8 9]\n", 96 | "\"\"\"\n", 97 | "vals = axon.loads(text)\n", 98 | "pprint(vals)\n", 99 | "print(axon.dumps(vals, pretty=1))" 100 | ] 101 | }, 102 | { 103 | "cell_type": "markdown", 104 | "metadata": {}, 105 | "source": [ 106 | "Load `JSON`-like objects:" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": 16, 112 | "metadata": { 113 | "collapsed": false 114 | }, 115 | "outputs": [ 116 | { 117 | "name": "stdout", 118 | "output_type": "stream", 119 | "text": [ 120 | "{'bool': (True, False),\n", 121 | " 'decimal': [Decimal('10000'),\n", 122 | " Decimal('3.141528'),\n", 123 | " Decimal('-0'),\n", 124 | " Decimal('NaN'),\n", 125 | " Decimal('Infinity'),\n", 126 | " Decimal('-Infinity')],\n", 127 | " 'dict': {'blue': 0, 'green': 32, 'red': 10},\n", 128 | " 'float': [3.141528, 0, nan, inf, -inf],\n", 129 | " 'int': [0, 1000, 123456789123456789123456789],\n", 130 | " 'list': [1, 2, 3],\n", 131 | " 'node': message{from: 'nick', to: 'mark' 'Hello'},\n", 132 | " 'odict': OrderedDict([('red', 10), ('green', 32), ('blue', 0)])}\n", 133 | "{ bool: (true false)\n", 134 | " decimal: [10000D 3.141528D -0D ?D ∞D -∞D]\n", 135 | " dict: {\n", 136 | " blue: 0\n", 137 | " green: 32\n", 138 | " red: 10}\n", 139 | " float: [3.141528 0 ? ∞ -∞]\n", 140 | " int: [0 1000 123456789123456789123456789]\n", 141 | " list: [1 2 3]\n", 142 | " node: message\n", 143 | " from: \"nick\"\n", 144 | " to: \"mark\"\n", 145 | " \"Hello\"\n", 146 | " odict: [\n", 147 | " blue: 0\n", 148 | " green: 32\n", 149 | " red: 10]}\n" 150 | ] 151 | } 152 | ], 153 | "source": [ 154 | "text = \"\"\"\n", 155 | "{\n", 156 | " int: [0 1000 123456789123456789123456789]\n", 157 | " float: [3.141528 -0 ? ∞ -∞]\n", 158 | " decimal: [10000D 3.141528D -0D ?D ∞D -∞D]\n", 159 | " bool: (true false)\n", 160 | " dict: {red:10 green:32 blue:0}\n", 161 | " odict: [red:10 green:32 blue:0]\n", 162 | " list: [1 2 3]\n", 163 | " node: message {from:\"nick\" to:\"mark\" \"Hello\"}\n", 164 | "}\n", 165 | "\"\"\"\n", 166 | "vals = axon.loads(text)\n", 167 | "val = vals[0]\n", 168 | "pprint(val)\n", 169 | "print(axon.dumps(vals, pretty=1))" 170 | ] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": null, 175 | "metadata": { 176 | "collapsed": true 177 | }, 178 | "outputs": [], 179 | "source": [] 180 | } 181 | ], 182 | "metadata": { 183 | "kernelspec": { 184 | "display_name": "Python 3", 185 | "language": "python", 186 | "name": "python3" 187 | }, 188 | "language_info": { 189 | "codemirror_mode": { 190 | "name": "ipython", 191 | "version": 3 192 | }, 193 | "file_extension": ".py", 194 | "mimetype": "text/x-python", 195 | "name": "python", 196 | "nbconvert_exporter": "python", 197 | "pygments_lexer": "ipython3", 198 | "version": "3.4.4" 199 | } 200 | }, 201 | "nbformat": 4, 202 | "nbformat_minor": 0 203 | } 204 | -------------------------------------------------------------------------------- /examples/basic_sample.axon: -------------------------------------------------------------------------------- 1 | person { 2 | firstName: "John" 3 | lastName: "Smith" 4 | age: 25 5 | address { 6 | streetAddress: "21 2nd Street" 7 | city: "New York" 8 | state: "NY" 9 | postalCode: 10021 } 10 | phoneNumber { type: "home" number: "212 555-1234" } 11 | phoneNumber { type: "fax" number: "646 555-4567" } 12 | } 13 | -------------------------------------------------------------------------------- /examples/basic_sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "firstName": "John", 3 | "lastName": "Smith", 4 | "age": 25, 5 | "address": { 6 | "streetAddress": "21 2nd Street", 7 | "city": "New York", 8 | "state": "NY", 9 | "postalCode": 10021 10 | }, 11 | "phoneNumber": [ 12 | { "type": "home", 13 | "number": "212 555-1234" 14 | }, 15 | { "type": "fax", 16 | "number": "646 555-4567" 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /examples/better_json.axon: -------------------------------------------------------------------------------- 1 | { 2 | # first comment 3 | date: 2012-12-01 4 | time: 12:00 5 | debet: 1230$ 6 | credit: 230$ 7 | } 8 | { 9 | # second comment 10 | date: 2012-12-10 11 | time: 9:00 12 | debet: 2130$ 13 | credit: 1020$ 14 | } 15 | { 16 | # third comment 17 | date: 2012-12-20 18 | time: 15:00 19 | debet: 230$ 20 | credit: 1200$ 21 | } 22 | 23 | -------------------------------------------------------------------------------- /examples/better_json_crossref.axon: -------------------------------------------------------------------------------- 1 | # first leaf with label 1 2 | &1 { 3 | id: 1 4 | value: "A" 5 | } 6 | # second leaf with label 2 7 | &2 { 8 | id: 2 9 | value: "B" 10 | } 11 | # node with childrens 12 | { 13 | id: 3 14 | children: [*1 *2] 15 | } 16 | 17 | -------------------------------------------------------------------------------- /examples/example_config.yaml: -------------------------------------------------------------------------------- 1 | application: myapp 2 | version: alpha-001 3 | runtime: python27 4 | api_version: 1 5 | threadsafe: true 6 | 7 | handlers: 8 | - url: / 9 | script: home.app 10 | 11 | - url: /index\.html 12 | script: home.app 13 | 14 | - url: /stylesheets 15 | static_dir: stylesheets 16 | 17 | - url: /(.*\.(gif|png|jpg)) 18 | static_files: static/\1 19 | upload: static/.*\.(gif|png|jpg) 20 | 21 | - url: /admin/.* 22 | script: admin.app 23 | login: admin 24 | 25 | - url: /.* 26 | script: not_found.app 27 | -------------------------------------------------------------------------------- /examples/example_config1.axon: -------------------------------------------------------------------------------- 1 | application: "myapp" 2 | version: "alpha-001" 3 | runtime: "python27" 4 | api_version: 1 5 | threadsafe: true 6 | 7 | # url handlers 8 | handlers: [ 9 | { url: "/" 10 | script: "home.app" } 11 | 12 | { url: "/index\.html" 13 | script: "home.app" } 14 | 15 | { url: "/stylesheets" 16 | static_dir: "stylesheets" } 17 | 18 | { url: "/(.*\.(gif|png|jpg))" 19 | static_files: "static/\1" 20 | upload: "static/.*\.(gif|png|jpg)" } 21 | 22 | { url: "/admin/.*" 23 | script: "admin.app" 24 | login: "admin" } 25 | 26 | { url: "/.*" 27 | script: "not_found.app" } 28 | ] 29 | -------------------------------------------------------------------------------- /examples/example_config2.axon: -------------------------------------------------------------------------------- 1 | _ 2 | application: "myapp" 3 | version: "alpha-001" 4 | runtime: "python27" 5 | api_version: 1 6 | threadsafe: true 7 | 8 | # url handlers 9 | handlers 10 | _ 11 | url: "/" 12 | script: "home.app" 13 | _ 14 | url: "/index\.html" 15 | script: "home.app" 16 | _ 17 | url: "/stylesheets" 18 | static_dir: "stylesheets" 19 | _ 20 | url: "/(.*\.(gif|png|jpg))" 21 | static_files: "static\1" 22 | upload: "static/.*\.(gif|png|jpg)" 23 | _ 24 | url: "/admin/.*" 25 | script: "admin.app" 26 | login: "admin" 27 | _ 28 | url: "/.*" 29 | script: "not_found.app" 30 | -------------------------------------------------------------------------------- /examples/large_files.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "" 4 | }, 5 | "nbformat": 3, 6 | "nbformat_minor": 0, 7 | "worksheets": [ 8 | { 9 | "cells": [ 10 | { 11 | "cell_type": "code", 12 | "collapsed": false, 13 | "input": [ 14 | "import axon\n", 15 | "from xml.etree.cElementTree import ElementTree, Element, parse\n", 16 | "import json" 17 | ], 18 | "language": "python", 19 | "metadata": {}, 20 | "outputs": [], 21 | "prompt_number": 1 22 | }, 23 | { 24 | "cell_type": "code", 25 | "collapsed": false, 26 | "input": [ 27 | "!ls -l data/EPAXML*.*" 28 | ], 29 | "language": "python", 30 | "metadata": {}, 31 | "outputs": [ 32 | { 33 | "output_type": "stream", 34 | "stream": "stdout", 35 | "text": [ 36 | "-rw-r--r--@ 1 sz staff 186459594 1 \u043d\u043e\u044f 21:45 data/EPAXML.axon\r\n", 37 | "-rw-r--r-- 1 sz staff 11384371 2 \u043d\u043e\u044f 01:06 data/EPAXML.axon.gz\r\n", 38 | "-rw-r--r--@ 1 sz staff 233268372 8 \u043c\u0430\u0440 2013 data/EPAXML.xml\r\n", 39 | "-rw-r--r-- 1 sz staff 12576825 2 \u043d\u043e\u044f 01:05 data/EPAXML.xml.gz\r\n", 40 | "-rw-r--r--@ 1 sz staff 166923140 2 \u043d\u043e\u044f 00:46 data/EPAXML0.axon\r\n", 41 | "-rw-r--r-- 1 sz staff 10922863 2 \u043d\u043e\u044f 01:06 data/EPAXML0.axon.gz\r\n" 42 | ] 43 | } 44 | ], 45 | "prompt_number": 2 46 | }, 47 | { 48 | "cell_type": "code", 49 | "collapsed": false, 50 | "input": [ 51 | "%time xml_root = parse(\"data/EPAXML.xml\")" 52 | ], 53 | "language": "python", 54 | "metadata": {}, 55 | "outputs": [ 56 | { 57 | "output_type": "stream", 58 | "stream": "stdout", 59 | "text": [ 60 | "CPU times: user 3.33 s, sys: 461 ms, total: 3.79 s\n", 61 | "Wall time: 18.5 s\n" 62 | ] 63 | } 64 | ], 65 | "prompt_number": 3 66 | }, 67 | { 68 | "cell_type": "code", 69 | "collapsed": false, 70 | "input": [ 71 | "root = xml_root.getroot()" 72 | ], 73 | "language": "python", 74 | "metadata": {}, 75 | "outputs": [], 76 | "prompt_number": 4 77 | }, 78 | { 79 | "cell_type": "code", 80 | "collapsed": false, 81 | "input": [ 82 | "children = root.getchildren()" 83 | ], 84 | "language": "python", 85 | "metadata": {}, 86 | "outputs": [], 87 | "prompt_number": 5 88 | }, 89 | { 90 | "cell_type": "code", 91 | "collapsed": false, 92 | "input": [ 93 | "@axon.reduce(type(Element('a')))\n", 94 | "def element_reduce(elem):\n", 95 | " children = elem.getchildren()\n", 96 | " if elem.attrib:\n", 97 | " if children:\n", 98 | " return axon.element(elem.tag, elem.attrib, children)\n", 99 | " else:\n", 100 | " return axon.mapping(elem.tag, elem.attrib)\n", 101 | " elif children:\n", 102 | " return axon.sequence(elem.tag, children)\n", 103 | " elif elem.text:\n", 104 | " return axon.sequence(elem.tag, [elem.text])\n", 105 | " else:\n", 106 | " return axon.empty(elem.tag)\n", 107 | " \n", 108 | "@axon.reduce(ElementTree)\n", 109 | "def etree_reduce(element):\n", 110 | " return element_reduce(element.getroot())\n" 111 | ], 112 | "language": "python", 113 | "metadata": {}, 114 | "outputs": [], 115 | "prompt_number": 6 116 | }, 117 | { 118 | "cell_type": "code", 119 | "collapsed": false, 120 | "input": [ 121 | "def update_attribs(d):\n", 122 | " for key, val in d.items():\n", 123 | " d[key] = unicode(val)\n", 124 | "\n", 125 | "class ElementTreeBuilder(axon.GenericBuilder):\n", 126 | " def empty(self, name):\n", 127 | " return et.Element(name)\n", 128 | " def mapping(self, name, attribs):\n", 129 | " update_attribs(attribs)\n", 130 | " return et.Element(name, attribs)\n", 131 | " def sequence(self, name, children):\n", 132 | " e = cElementTree.Element(name)\n", 133 | " e.extend(children)\n", 134 | " return e\n", 135 | " def element(self, name, attribs, children):\n", 136 | " update_attribs(attribs)\n", 137 | " e = et.Element(name, attribs)\n", 138 | " e.extend(children)\n", 139 | " return e\n", 140 | "\n", 141 | "axon.register_builder('etree', ElementTreeBuilder()) " 142 | ], 143 | "language": "python", 144 | "metadata": {}, 145 | "outputs": [], 146 | "prompt_number": 7 147 | }, 148 | { 149 | "cell_type": "code", 150 | "collapsed": false, 151 | "input": [ 152 | "axon._dumper.reduce_dict" 153 | ], 154 | "language": "python", 155 | "metadata": {}, 156 | "outputs": [ 157 | { 158 | "metadata": {}, 159 | "output_type": "pyout", 160 | "prompt_number": 8, 161 | "text": [ 162 | "{Element: ,\n", 163 | " ElementTree: ,\n", 164 | " axon._objects.Element: ,\n", 165 | " axon._objects.Sequence: ,\n", 166 | " axon._objects.Instance: ,\n", 167 | " axon._objects.Empty: ,\n", 168 | " axon._objects.Mapping: }" 169 | ] 170 | } 171 | ], 172 | "prompt_number": 8 173 | }, 174 | { 175 | "cell_type": "code", 176 | "collapsed": false, 177 | "input": [ 178 | "%time axon.dump(\"data/EPAXML0.axon\", [xml_root], pretty=0)" 179 | ], 180 | "language": "python", 181 | "metadata": {}, 182 | "outputs": [ 183 | { 184 | "output_type": "stream", 185 | "stream": "stdout", 186 | "text": [ 187 | "CPU times: user 16.3 s, sys: 797 ms, total: 17.1 s\n", 188 | "Wall time: 29.7 s\n" 189 | ] 190 | } 191 | ], 192 | "prompt_number": 11 193 | }, 194 | { 195 | "cell_type": "code", 196 | "collapsed": false, 197 | "input": [ 198 | "del root, xml_root" 199 | ], 200 | "language": "python", 201 | "metadata": {}, 202 | "outputs": [], 203 | "prompt_number": 12 204 | }, 205 | { 206 | "cell_type": "code", 207 | "collapsed": false, 208 | "input": [ 209 | "%time vs = axon.load(\"data/EPAXML0.axon\")" 210 | ], 211 | "language": "python", 212 | "metadata": {}, 213 | "outputs": [], 214 | "prompt_number": "*" 215 | }, 216 | { 217 | "cell_type": "code", 218 | "collapsed": false, 219 | "input": [], 220 | "language": "python", 221 | "metadata": {}, 222 | "outputs": [] 223 | } 224 | ], 225 | "metadata": {} 226 | } 227 | ] 228 | } -------------------------------------------------------------------------------- /examples/test.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 16, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import axon\n", 12 | "import numpy as np" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 8, 18 | "metadata": { 19 | "collapsed": true 20 | }, 21 | "outputs": [], 22 | "source": [ 23 | "text = \"\"\"\n", 24 | "array\n", 25 | " dtype: [(\"id\" \"int\") (\"val\" \"float\")]\n", 26 | " (1 1.0)\n", 27 | " (2 2.0)\n", 28 | " (3 3.0)\n", 29 | "\"\"\"" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 9, 35 | "metadata": { 36 | "collapsed": false 37 | }, 38 | "outputs": [ 39 | { 40 | "name": "stdout", 41 | "output_type": "stream", 42 | "text": [ 43 | "array\n", 44 | " dtype: [\n", 45 | " (\"id\" \"int\")\n", 46 | " (\"val\" \"float\")]\n", 47 | " (1 1.0)\n", 48 | " (2 2.0)\n", 49 | " (3 3.0)\n" 50 | ] 51 | } 52 | ], 53 | "source": [ 54 | "vals = axon.loads(text)\n", 55 | "print(axon.dumps(vals, pretty=1))" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 10, 61 | "metadata": { 62 | "collapsed": true 63 | }, 64 | "outputs": [], 65 | "source": [ 66 | "val = vals[0]" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": 15, 72 | "metadata": { 73 | "collapsed": false 74 | }, 75 | "outputs": [ 76 | { 77 | "name": "stdout", 78 | "output_type": "stream", 79 | "text": [ 80 | "[('id', 'int'), ('val', 'float')]\n", 81 | "[(1, 1.0), (2, 2.0), (3, 3.0)]\n" 82 | ] 83 | } 84 | ], 85 | "source": [ 86 | "print(val.dtype)\n", 87 | "print(val.__vals__)" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 17, 93 | "metadata": { 94 | "collapsed": false 95 | }, 96 | "outputs": [ 97 | { 98 | "data": { 99 | "text/plain": [ 100 | "array([(1, 1.0), (2, 2.0), (3, 3.0)], \n", 101 | " dtype=[('id', ' 11 | Compact form 12 |
%s
13 | Expression formatted 14 | Statement indented 15 |
%s
%s
16 | 17 | ''' 18 | return HTML(template % (text1, text2, text3)) 19 | 20 | def test_av(text): 21 | vals = loads(text) 22 | text1 = dumps(vals) 23 | text2 = dumps(vals, pretty=1) 24 | template = '''\ 25 | 26 | Compact form 27 | 28 | 29 | 30 |
%s
Expression formatted
%s
31 | ''' 32 | return HTML(template % (text1, text2)) 33 | -------------------------------------------------------------------------------- /lib/axon/__init__.py: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | # 3 | # Copyright (c) <2011-2015> 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | from axon.api import * 24 | from axon.objects import * 25 | from axon.utils import * 26 | from axon.types import * 27 | from axon.odict import * 28 | from axon.errors import AxonError 29 | 30 | __version__ = '0.8' 31 | -------------------------------------------------------------------------------- /lib/axon/_common.pxd: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | # The MIT License (MIT) 4 | # 5 | # Copyright (c) <2011-2015> 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in 15 | # all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | # THE SOFTWARE. 24 | 25 | from cpython.object cimport PyObject, PyObject_Unicode 26 | from cpython.dict cimport PyDict_GetItem, PyDict_SetItem 27 | 28 | #from axon.odict cimport OrderedDict 29 | 30 | cdef extern from "utils.h": 31 | inline unicode c_object_to_unicode(object o) 32 | 33 | cdef extern from "Python.h": 34 | cdef int PY_MAJOR_VERSION 35 | 36 | cdef inline object dict_get(object op, object key, object default): 37 | cdef PyObject* val = PyDict_GetItem(op, key) 38 | if val == NULL: 39 | return default 40 | else: 41 | return val 42 | 43 | cdef inline dict c_as_dict(object ob): 44 | if type(ob) is dict: 45 | return ob 46 | elif ob is None: 47 | return {} 48 | else: 49 | return dict(ob) 50 | 51 | # cdef inline OrderedDict c_as_odict(object ob): 52 | # if type(ob) is OrderedDict: 53 | # return ob 54 | # elif ob is None: 55 | # return OrderedDict([]) 56 | # else: 57 | # return OrderedDict(ob) 58 | 59 | cdef inline list c_as_list(object ob): 60 | if type(ob) is list: 61 | return ob 62 | elif ob is None: 63 | return [] 64 | else: 65 | return list(ob) 66 | 67 | cdef inline tuple c_as_tuple(object ob): 68 | if type(ob) is tuple: 69 | return ob 70 | elif ob is None: 71 | return () 72 | else: 73 | return tuple(ob) 74 | 75 | cdef inline unicode c_as_unicode(object ob): 76 | tp = type(ob) 77 | if tp is unicode: 78 | return ob 79 | elif tp is str: 80 | return c_object_to_unicode(ob) 81 | else: 82 | if PY_MAJOR_VERSION >= 3: 83 | raise TypeError("The type of the object should be `str` or `unicode`.") 84 | else: 85 | raise TypeError("The type of the object should be `str`.") 86 | -------------------------------------------------------------------------------- /lib/axon/api.py: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | # 3 | # Copyright (c) <2011-2015> 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | 23 | from __future__ import unicode_literals, print_function 24 | from axon._loader import Loader 25 | from axon._dumper import Dumper 26 | from axon.types import unicode_type, str_type 27 | from axon._objects import as_unicode, StringReader, StringWriter 28 | 29 | import io 30 | 31 | def display(text, pretty=1, braces=0, sorted=0, hsize=0, crossref=0): 32 | ''' 33 | Display AXON text in formatted form for easy read. 34 | 35 | :param text: 36 | Unicode AXON text 37 | 38 | :returns: 39 | Formatted form of AXON encoded text. 40 | ''' 41 | vals = loads(text) 42 | print(dumps(vals, pretty, braces, sorted, hsize, crossref)) 43 | 44 | def display_html(vals): 45 | ''' 46 | Convert objects into three AXON forms for output in IPython notebook. 47 | 48 | :param vals: 49 | List of objects or ordered dict. 50 | 51 | :returns: 52 | IPython TabbedView widget. 53 | ''' 54 | try: 55 | from ipywidgets import Tab, HTML 56 | except: 57 | from IPython.html.widgets import Tab, HTML 58 | 59 | # Compact form 60 | p1 = dumps(vals, crossref=1) 61 | # Formatted form without braces 62 | p2 = dumps(vals, pretty=1, crossref=1) 63 | # Formatted form with braces 64 | p3 = dumps(vals, pretty=1, braces=1, crossref=1) 65 | 66 | wg = Tab( 67 | ( HTML("
%s
" % p1), 68 | HTML("
%s
" % p2), 69 | HTML("
%s
" % p3)) 70 | ) 71 | wg.set_title(0, "Compact") 72 | wg.set_title(1, "Formatted") 73 | wg.set_title(2, "Formatted with {}") 74 | wg.selected_index = 1 75 | 76 | return wg 77 | 78 | def dumps(vals, pretty=0, braces=0, sorted=0, hsize=0, crossref=0): 79 | ''' 80 | Dump sequence of values into unicode text. 81 | 82 | :param vals: 83 | Sequence of values to convert. 84 | 85 | :param pretty: 86 | Flag indicating pretty dumping: 87 | 88 | * `True` - use pretty dumping 89 | * `False` - compact dumping (default) 90 | 91 | :param braces: 92 | Flag indicating using braces (JSON-style) during formatting: 93 | 94 | * `True` - use formatting with braces (JSON-style) 95 | * `False` - use formatting without braces (YAML-style, default) 96 | 97 | :param crossref: 98 | Flag for crossreferece support in unsafe mode 99 | 100 | * `True` - use reference to the object on duplicate 101 | * `False` - use copy of the object on duplicate (default) 102 | 103 | :returns: 104 | Unicode text in AXON format. 105 | ''' 106 | fd = StringWriter() 107 | 108 | dumper = Dumper(fd, pretty, braces, sorted, hsize, crossref) 109 | dumper.dump(vals) 110 | v = fd.getvalue() 111 | fd.close() 112 | return v 113 | 114 | def dump(fpath, val, pretty=0, braces=0, sorted=0, hsize=0, crossref=0, encoding='utf-8'): 115 | '''\ 116 | Same as :py:func:`dumps` but for dumping into a file. 117 | 118 | :param fpath: 119 | Path to file for dumping. 120 | 121 | For other parameters see :py:func:`dumps`. 122 | ''' 123 | fd = io.open(fpath, mode='w', encoding=encoding) 124 | 125 | dumper = Dumper(fd, pretty, braces, sorted, hsize, crossref) 126 | dumper.dump(val) 127 | fd.close() 128 | 129 | def loads(text, mode="safe", errto=None): 130 | '''\ 131 | Load values from unicode text. 132 | 133 | :param text: 134 | Unicode text. 135 | 136 | :param mode: 137 | Specifies the method of building python objects for complex values 138 | (see .. py:func:`load`) 139 | 140 | :param errto: 141 | Name of file for reporting errors 142 | 143 | :returns: 144 | List of values. 145 | ''' 146 | text = as_unicode(text) 147 | fd = StringReader(text) 148 | 149 | loader = Loader(fd, mode, errto) 150 | return loader.load() 151 | 152 | def load(fd, mode="safe", errto=None, encoding='utf-8'): 153 | ''' 154 | Load object from unicode text. 155 | 156 | :param fd: 157 | Input file name of file object opening as TextIO/StringIO. 158 | 159 | :param mode: 160 | Specifies the method of building python objects for complex values. 161 | 162 | There are values of parameter `mode`: 163 | * `safe` - use safe object builder 164 | * `strict` - use unsafe builder with strict name resolution: if there is no registered name 165 | for building object builder return `undef` object 166 | * `mixed` - use unsafe object builder with following rule: if there is no registered name 167 | for building object then use `safe` mode. 168 | 169 | :param errto: 170 | Name of file for reporting errors 171 | 172 | :param encoding: 173 | Encoding of input file (default `utf-8`). 174 | 175 | :returns: 176 | List of values. 177 | ''' 178 | if type(fd) in (str_type, unicode_type): 179 | fd = io.open(fd, mode='r', encoding=encoding) 180 | 181 | loader = Loader(fd, mode, errto) 182 | return loader.load() 183 | 184 | def iload(fd, mode="safe", errto=None, encoding='utf-8'): 185 | '''\ 186 | Iterative loading values from input file. 187 | 188 | Arguments are same as in .. py:func:`load`. 189 | 190 | :returns: 191 | iterator object. 192 | ''' 193 | 194 | if type(fd) in (str_type, unicode_type): 195 | fd = io.open(fd, mode='r', encoding=encoding) 196 | 197 | loader = Loader(fd, mode, errto) 198 | for val in loader.iload(): 199 | yield val 200 | 201 | def iloads(text, mode="safe", errto=None): 202 | '''\ 203 | Iterative loading values from unicode text. 204 | 205 | :param text: 206 | Unicode text. 207 | 208 | :param mode: 209 | Specifies the method of building python objects for complex values 210 | (see .. py:func:`load`) 211 | 212 | :param errto: 213 | Name of file for reporting errors 214 | 215 | :returns: 216 | Iterator object. It returns values during iteration. 217 | ''' 218 | text = as_unicode(text) 219 | fd = StringReader(text) 220 | 221 | loader = Loader(fd, mode, errto) 222 | for val in loader.iload(): 223 | yield val 224 | 225 | 226 | # def itokens(text, mode="safe", errto=None, encoding='utf-8'): 227 | # text = as_unicode(text) 228 | # fd = StringReader(text) 229 | # 230 | # loader = Loader(fd, mode, errto) 231 | # 232 | # for tok in loader.itokens(): 233 | # yield tok 234 | # 235 | -------------------------------------------------------------------------------- /lib/axon/errors.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | # The MIT License (MIT) 4 | # 5 | # Copyright (c) <2011-2015> 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in 15 | # all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | # THE SOFTWARE. 24 | 25 | from __future__ import unicode_literals 26 | 27 | import sys 28 | 29 | class AxonError(Exception): 30 | # 31 | def __init__(self, msg, pos=None, chunk=''): 32 | self.msg = msg 33 | self.pos = pos 34 | self.chunk = chunk 35 | # 36 | def __str__(self): 37 | text = 'ERROR:: ' + self.msg 38 | if self.pos is not None: 39 | lnum, pos = self.pos 40 | text += ' line:%s pos:%s' % (lnum, pos) 41 | if self.chunk: 42 | text += ' chunk: %s' % self.chunk 43 | return text 44 | 45 | def error(self, msg): 46 | e = AxonError(msg, (self.lnum, self.pos), self.line[self.pos:self.pos+16]) 47 | if sys.flags.debug: 48 | self.errto.write(str(e)) 49 | raise e 50 | # 51 | # def error_getvalue(self): 52 | # error(self, 'Invalid simple value') 53 | # 54 | def error_unexpected_end_complex_value(self): 55 | error(self, 'Unexpected end inside complex value') 56 | # 57 | def error_unexpected_end_list(self): 58 | error(self, 'Unexpected end inside list') 59 | # 60 | def error_unexpected_end_odict(self): 61 | error(self, 'Unexpected end inside ordered dict') 62 | # 63 | def error_unexpected_end_tuple(self): 64 | error(self, 'Unexpected end inside tuple') 65 | # 66 | def error_unexpected_end_string(self): 67 | error(self, 'Unexpected end of the string') 68 | # 69 | def error_unexpected_keyval(self): 70 | error(self, 'Unexpected key:val') 71 | # 72 | def error_expected_keyval(self): 73 | error(self, 'Expected key:val') 74 | # 75 | def error_expected_key(self): 76 | error(self, 'Expected key') 77 | # 78 | def error_expected_named_constant(self): 79 | error(self, 'Expected named constant') 80 | # 81 | def error_getnumber(self): 82 | error(self, 'Invalid number') 83 | # 84 | def error_getint_part(self): 85 | error(self, 'Invalid int part or value') 86 | # 87 | def error_invalid_date(self): 88 | error(self, 'Invalid date') 89 | # 90 | def error_invalid_time(self): 91 | error(self, 'Invalid time') 92 | # 93 | def error_invalid_datetime(self): 94 | error(self, 'Invalid datetime') 95 | # 96 | def error_invalid_value(self, vtype=''): 97 | error(self, 'Invalid %s value' % vtype.__name__) 98 | # 99 | def error_invalid_odict(self, vtype=''): 100 | error(self, 'Invalid ordered dict') 101 | # 102 | def error_invalid_value_with_prefix(self, prefix): 103 | error(self, "Invalid value with prefix '%s'" % prefix) 104 | # 105 | def error_dict_value(self): 106 | error(self, 'dict can contain only key:value pairs') 107 | # 108 | def error_unexpected_attribute(self, name): 109 | error(self, 'Unexpected attribute %s:?' % name) 110 | # 111 | def error_expected_attribute(self): 112 | error(self, 'Expected attribute') 113 | # 114 | def error_unexpected_value(self, context=''): 115 | error(self, 'Unexpected value: %s' % context) 116 | # 117 | def error_end_item(self): 118 | error(self, "Expected space character, '[', '}' or ')' here") 119 | # 120 | def error_star(self): 121 | error(self, 'Invalid usage of symbol *') 122 | # 123 | def error_undefined_name(self, name): 124 | error(self, 'Undefined name %r' % name ) 125 | # 126 | def error_indentation(self, idn): 127 | error(self, 'Invalid indentation: current position=%s ident position=%s' % (self.pos, idn)) 128 | # 129 | def error_expected_name(self): 130 | error(self, 'Expected name here') 131 | # 132 | def error_expected_same_name(self, name): 133 | error(self, "Element must have same name as '%s'" % name) 134 | # 135 | def error_expected_complex_value(self): 136 | error(self, "Expected complex here") 137 | # 138 | def error_expected_label(self): 139 | error(self, "Expected label of the value") 140 | 141 | def error2(msg): 142 | e = AxonError(msg) 143 | if sys.flags.debug: 144 | self.errto.write(str(e)) 145 | raise e 146 | 147 | def error_no_handler(name): 148 | error2('Handler for name <%s> is not registered' % name) 149 | 150 | def error_no_reducer(tp): 151 | error2('There is no reducer for this type: %r' % tp) 152 | # 153 | def error_reducer_wrong_type(tp): 154 | error2('Reducer return wrong type: %r' % tp) 155 | # 156 | 157 | def error_no_attributes(tp): 158 | error2('The type %r does not contain attributes' % tp) 159 | 160 | def error_no_children(tp): 161 | error2('The type %r does not contain child values' % tp) 162 | -------------------------------------------------------------------------------- /lib/axon/objects.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # The MIT License (MIT) 4 | # 5 | # Copyright (c) <2011-2015> 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in 15 | # all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | # THE SOFTWARE. 24 | 25 | from axon._objects import Node, Attribute, KeyVal 26 | from axon._objects import node, attribute, keyval 27 | from axon._objects import Builder 28 | from axon._objects import timezone 29 | from axon._loader import register_builder 30 | -------------------------------------------------------------------------------- /lib/axon/odict.pxd: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | #cython: boundscheck=False 4 | #cython: wraparound=False 5 | #cython: nonecheck=False 6 | #cython: language_level=3 7 | 8 | # The MIT License (MIT) 9 | # 10 | # Copyright (c) <2011-2015> 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining a copy 13 | # of this software and associated documentation files (the "Software"), to deal 14 | # in the Software without restriction, including without limitation the rights 15 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | # copies of the Software, and to permit persons to whom the Software is 17 | # furnished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included in 20 | # all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | # THE SOFTWARE. 29 | 30 | cimport cython 31 | from cpython.object cimport Py_EQ, Py_NE 32 | 33 | from operator import eq as _eq 34 | import sys as _sys 35 | import collections 36 | 37 | from axon._common cimport c_as_unicode, c_as_list, c_as_dict, c_as_tuple, dict_get 38 | 39 | cdef dict _repr_running = {} 40 | 41 | 42 | cdef class _MappingView: 43 | 44 | cdef OrderedDict _mapping 45 | 46 | cdef class _KeysView(_MappingView): 47 | pass 48 | 49 | 50 | cdef class _ItemsView(_MappingView): 51 | pass 52 | 53 | cdef class _ValuesView(_MappingView): 54 | pass 55 | 56 | ################################################################################ 57 | ### OrderedDict 58 | ################################################################################ 59 | 60 | @cython.freelist(64) 61 | @cython.final 62 | cdef public class Link[object LinkObject, type LinkType]: 63 | cdef cython.void *prev 64 | cdef cython.void *next 65 | cdef object key 66 | cdef object val 67 | 68 | cdef Link link_marker 69 | 70 | cdef public class OrderedDict[object OrderedDictObject, type OrderedDictType]: 71 | cdef Link root 72 | cdef dict map 73 | 74 | cdef _update(self, object args, object kw) 75 | 76 | cdef c_init_odict(OrderedDict od, list args) 77 | 78 | cdef OrderedDict c_new_odict(list args) 79 | -------------------------------------------------------------------------------- /lib/axon/test/__init__.py: -------------------------------------------------------------------------------- 1 | # {{LICENCE}} 2 | 3 | from axon.test.test_int import * 4 | from axon.test.test_float import * 5 | from axon.test.test_decimal import * 6 | from axon.test.test_string import * 7 | from axon.test.test_constant import * 8 | from axon.test.test_datetime import * 9 | from axon.test.test_datetime10 import * 10 | from axon.test.test_list import * 11 | from axon.test.test_dict import * 12 | from axon.test.test_tuple import * 13 | from axon.test.test_set import * 14 | from axon.test.test_unsafe_loads import * 15 | from axon.test.test_crossref import * 16 | from axon.test.test_base64 import * 17 | from axon.test.test_errors import * 18 | from axon.test.test_samples import * 19 | from axon.test.test_odict import * 20 | 21 | def test_all(): 22 | import unittest 23 | unittest.main(verbosity=2) 24 | -------------------------------------------------------------------------------- /lib/axon/test/benchmark/__init__.py: -------------------------------------------------------------------------------- 1 | # {{LICENCE}} 2 | 3 | 4 | -------------------------------------------------------------------------------- /lib/axon/test/benchmark/test_vs_yaml.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import print_function 3 | 4 | import yaml 5 | import random 6 | import time 7 | import axon 8 | 9 | def random_string(n): 10 | text = ''.join([chr(ord('a')+random.randint(1,20)) for i in range(20)]) 11 | return axon.as_unicode(text) 12 | 13 | class AXONvsYAML: 14 | 15 | def test_vs_yaml_1(self): 16 | lst = [] 17 | for i in range(2000): 18 | lst.append({ 19 | random_string(8): random.random(), 20 | random_string(8): random.randint(1,99999), 21 | random_string(8): random_string(32), 22 | random_string(8): random.random(), 23 | random_string(8): random.randint(1,99999), 24 | random_string(8): random_string(32), 25 | random_string(8): random.random(), 26 | random_string(8): random.randint(1,99999), 27 | random_string(8): random_string(32), 28 | }) 29 | yaml_text = yaml.dump(lst, Dumper=yaml.CDumper) 30 | t0 = time.time() 31 | v = yaml.load(yaml_text, Loader=yaml.CLoader) 32 | dt_yaml = time.time() - t0 33 | 34 | axon_text = axon.dumps(lst, pretty=False) 35 | t0 = time.time() 36 | v = axon.loads(axon_text) 37 | dt_axon = time.time() - t0 38 | 39 | print('axon:', dt_axon, 'yaml', dt_yaml) 40 | 41 | def test_vs_yaml_2(self): 42 | d = {} 43 | for j in range(50): 44 | lst = [] 45 | for i in range(100): 46 | lst.append({ 47 | random_string(8): random.random(), 48 | random_string(8): random.randint(1,99999), 49 | random_string(8): random_string(32), 50 | random_string(8): random.random(), 51 | random_string(8): random.randint(1,99999), 52 | random_string(8): random_string(32), 53 | }) 54 | d[random_string(8)] = lst 55 | yaml_text = yaml.dump(d, Dumper=yaml.CDumper) 56 | t0 = time.time() 57 | v = yaml.load(yaml_text, Loader=yaml.CLoader) 58 | dt_yaml = time.time() - t0 59 | 60 | axon_text = axon.dumps([d], pretty=False) 61 | #print(axon_text) 62 | t0 = time.time() 63 | v = axon.loads(axon_text) 64 | dt_axon = time.time() - t0 65 | 66 | print('axon:', dt_axon, 'yaml', dt_yaml) 67 | 68 | def test_yaml(): 69 | inst = AXONvsYAML() 70 | inst.test_vs_yaml_1() 71 | inst.test_vs_yaml_2() 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /lib/axon/test/profiling.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | import pstats, cProfile 4 | 5 | import test_vs_json as test 6 | 7 | cProfile.runctx("test.run()", globals(), locals(), "Profile.prof") 8 | 9 | s = pstats.Stats("Profile.prof") 10 | s.strip_dirs().sort_stats("time").print_stats() 11 | -------------------------------------------------------------------------------- /lib/axon/test/test_base64.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import unicode_literals, print_function 4 | import unittest 5 | from axon import loads, dumps 6 | from axon.types import str_type, unicode_type 7 | 8 | import sys 9 | 10 | try: 11 | _chr = unichr 12 | except NameError: 13 | _chr = chr 14 | 15 | class Base64TestCase(unittest.TestCase): 16 | 17 | def setUp(self): 18 | pass 19 | if sys.version_info.major == 3: 20 | def test_1(self): 21 | from random import randint 22 | for i in range(10): 23 | btext = bytes([randint(1,255) for i in range(256)]) 24 | text1= dumps([btext]) 25 | #print('***', btext, '***') 26 | #print('***', text1, '***') 27 | btext1 = loads(text1)[0] 28 | self.assertEqual(btext, btext1) 29 | # 30 | 31 | def suite(): 32 | suite = unittest.TestSuite() 33 | suite.addTest(unittest.makeSuite(Base64TestCase)) 34 | return suite 35 | 36 | -------------------------------------------------------------------------------- /lib/axon/test/test_constant.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import unicode_literals 4 | import unittest 5 | from axon import loads, dumps 6 | 7 | class ConstantTestCase(unittest.TestCase): 8 | 9 | def setUp(self): 10 | pass 11 | 12 | def test_nan2(self): 13 | v = loads('?')[0] 14 | s = dumps([v]) 15 | self.assertEqual(s, '?') 16 | # 17 | def test_null(self): 18 | v = loads('null')[0] 19 | s = dumps([v]) 20 | self.assertEqual(s, 'null') 21 | # 22 | def test_true(self): 23 | v = loads('true')[0] 24 | s = dumps([v]) 25 | self.assertEqual(s, 'true') 26 | # 27 | def test_false(self): 28 | v = loads('false')[0] 29 | s = dumps([v]) 30 | self.assertEqual(s, 'false') 31 | # 32 | def test_inf1(self): 33 | v = loads('∞')[0] 34 | s = dumps([v]) 35 | self.assertEqual(s, '∞') 36 | # 37 | def test_ninf1(self): 38 | v = loads('-∞')[0] 39 | s = dumps([v]) 40 | self.assertEqual(s, '-∞') 41 | # 42 | def test_decimal_nan2(self): 43 | v = loads('?D')[0] 44 | s = dumps([v]) 45 | self.assertEqual(s, '?D') 46 | # 47 | def test_decimal_inf1(self): 48 | v = loads('∞D')[0] 49 | s = dumps([v]) 50 | self.assertEqual(s, '∞D') 51 | # 52 | def test_decimal_ninf1(self): 53 | v = loads('-∞D')[0] 54 | s = dumps([v]) 55 | self.assertEqual(s, '-∞D') 56 | # 57 | 58 | def suite(): 59 | suite = unittest.TestSuite() 60 | suite.addTest(unittest.makeSuite(ConstantTestCase)) 61 | return suite 62 | -------------------------------------------------------------------------------- /lib/axon/test/test_crossref.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import unicode_literals 4 | import unittest 5 | from axon import * 6 | 7 | pretty = False 8 | 9 | class CrossrefTestCase(unittest.TestCase): 10 | 11 | def setUp(self): 12 | pass 13 | 14 | def test_crossref_1(self): 15 | v1, v2 = loads('&123 [ 17]\na{ *123 "abc" }') 16 | self.assertTrue(v1 is v2[0]) 17 | # 18 | def test_crossref_2(self): 19 | v1, v2 = loads('&_123_ a{ a:1 }\nb{ *_123_ "abc" }') 20 | self.assertTrue(v1 is v2[0]) 21 | text = dumps([v1,v2], crossref=1) 22 | self.assertEqual(text, '&1 a{a:1}\nb{*1 "abc"}') 23 | # 24 | def test_crossref_3(self): 25 | v1, v2 = loads('&123 a{ a:1 100 200}\nb{ *123 "abc" }') 26 | self.assertTrue(v1 is v2[0]) 27 | text = dumps([v1,v2], crossref=1) 28 | self.assertEqual(text, '&1 a{a:1 100 200}\nb{*1 "abc"}') 29 | 30 | 31 | def suite(): 32 | suite = unittest.TestSuite() 33 | suite.addTest(unittest.makeSuite(CrossrefTestCase)) 34 | return suite 35 | -------------------------------------------------------------------------------- /lib/axon/test/test_datetime.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import unicode_literals 4 | import unittest 5 | from axon import loads, dumps 6 | from datetime import date, time, datetime, tzinfo 7 | 8 | class DateTimeTestCase(unittest.TestCase): 9 | 10 | def setUp(self): 11 | pass 12 | 13 | def test_date1(self): 14 | v = loads('2010-12-01')[0] 15 | self.assertEqual(type(v), date) 16 | s = dumps([v]) 17 | self.assertEqual(s, '^2010-12-01') 18 | # 19 | def test_date2(self): 20 | v = loads('1900-01-01')[0] 21 | self.assertEqual(type(v), date) 22 | s = dumps([v]) 23 | self.assertEqual(s, '^1900-01-01') 24 | # 25 | def test_date3(self): 26 | v = loads('12-01-01')[0] 27 | self.assertEqual(type(v), date) 28 | s = dumps([v]) 29 | self.assertEqual(s, '^12-01-01') 30 | # 31 | def test_date4(self): 32 | v = loads('0-00-00')[0] 33 | self.assertEqual(type(v), date) 34 | s = dumps([v]) 35 | self.assertEqual(s, '^0-00-00') 36 | # 37 | def test_time1(self): 38 | v = loads('00:00')[0] 39 | self.assertEqual(type(v), time) 40 | s = dumps([v]) 41 | self.assertEqual(s, '^00:00') 42 | # 43 | def test_time2(self): 44 | v = loads('23:59:59')[0] 45 | self.assertEqual(type(v), time) 46 | s = dumps([v]) 47 | self.assertEqual(s, '^23:59:59') 48 | # 49 | def test_time3(self): 50 | v = loads('23:59:59.000123')[0] 51 | self.assertEqual(type(v), time) 52 | s = dumps([v]) 53 | self.assertEqual(s, '^23:59:59.000123') 54 | # 55 | def test_time4(self): 56 | v = loads('23:59:59+00:00')[0] 57 | self.assertEqual(type(v), time) 58 | self.assertIsInstance(v.tzinfo, tzinfo) 59 | s = dumps([v]) 60 | self.assertEqual(s, '^23:59:59+00') 61 | self.assertEqual(v.utcoffset().seconds, 0) 62 | # 63 | def test_time5(self): 64 | v = loads('23:59:59+01:00')[0] 65 | self.assertEqual(type(v), time) 66 | self.assertIsInstance(v.tzinfo, tzinfo) 67 | s = dumps([v]) 68 | self.assertEqual(s, '^23:59:59+01') 69 | self.assertEqual(v.utcoffset().seconds/60, 60) 70 | # 71 | def test_time6(self): 72 | v = loads('23:59:59-01:00')[0] 73 | self.assertEqual(type(v), time) 74 | self.assertIsInstance(v.tzinfo, tzinfo) 75 | s = dumps([v]) 76 | self.assertEqual(s, '^23:59:59-01') 77 | self.assertEqual(v.utcoffset().seconds/60, 23*60) 78 | # 79 | def test_time7(self): 80 | v = loads('23:59:59+12:00')[0] 81 | self.assertEqual(type(v), time) 82 | self.assertIsInstance(v.tzinfo, tzinfo) 83 | s = dumps([v]) 84 | self.assertEqual(s, '^23:59:59+12') 85 | self.assertEqual(v.utcoffset().seconds/60, 12*60) 86 | # 87 | def test_time8(self): 88 | v = loads('23:59:59+23:00')[0] 89 | self.assertEqual(type(v), time) 90 | self.assertIsInstance(v.tzinfo, tzinfo) 91 | s = dumps([v]) 92 | self.assertEqual(s, '^23:59:59+23') 93 | self.assertEqual(v.utcoffset().seconds/60, 23*60) 94 | # 95 | def test_time9(self): 96 | v = loads('23:59:59-23:00')[0] 97 | self.assertEqual(type(v), time) 98 | self.assertIsInstance(v.tzinfo, tzinfo) 99 | s = dumps([v]) 100 | self.assertEqual(s, '^23:59:59-23') 101 | self.assertEqual(v.utcoffset().seconds/60, 60) 102 | # 103 | def test_time10(self): 104 | v = loads('23:59:59+3:15')[0] 105 | self.assertEqual(type(v), time) 106 | self.assertIsInstance(v.tzinfo, tzinfo) 107 | s = dumps([v]) 108 | self.assertEqual(s, '^23:59:59+03:15') 109 | self.assertEqual(v.utcoffset().seconds/60, 3*60+15) 110 | # 111 | def test_time11(self): 112 | v = loads('23:59:59-3:15')[0] 113 | self.assertEqual(type(v), time) 114 | self.assertIsInstance(v.tzinfo, tzinfo) 115 | s = dumps([v]) 116 | self.assertEqual(s, '^23:59:59-03:15') 117 | self.assertEqual(v.utcoffset().seconds/60, 1440-3*60-15) 118 | # 119 | def test_datetime1(self): 120 | v = loads('2010-01-01T00:00')[0] 121 | self.assertEqual(type(v), datetime) 122 | self.assertEqual(v.tzinfo, None) 123 | s = dumps([v]) 124 | self.assertEqual(s, '^2010-01-01T00:00') 125 | # 126 | def test_datetime2(self): 127 | v = loads('1-01-01T23:59:59')[0] 128 | self.assertEqual(type(v), datetime) 129 | self.assertEqual(v.tzinfo, None) 130 | s = dumps([v]) 131 | self.assertEqual(s, '^1-01-01T23:59:59') 132 | # 133 | def test_datetime3(self): 134 | v = loads('2010-01-01T23:59:59.000123')[0] 135 | self.assertEqual(type(v), datetime) 136 | self.assertEqual(v.tzinfo, None) 137 | s = dumps([v]) 138 | self.assertEqual(s, '^2010-01-01T23:59:59.000123') 139 | # 140 | def test_datetime4(self): 141 | v = loads('2010-01-01T23:59:59+00:00')[0] 142 | self.assertEqual(type(v), datetime) 143 | self.assertIsInstance(v.tzinfo, tzinfo) 144 | s = dumps([v]) 145 | self.assertEqual(s, '^2010-01-01T23:59:59+00') 146 | self.assertEqual(v.utcoffset().seconds, 0) 147 | # 148 | def test_datetime5(self): 149 | v = loads('2010-01-01T23:59:59+01:00')[0] 150 | self.assertEqual(type(v), datetime) 151 | self.assertIsInstance(v.tzinfo, tzinfo) 152 | s = dumps([v]) 153 | self.assertEqual(s, '^2010-01-01T23:59:59+01') 154 | self.assertEqual(v.utcoffset().seconds/60, 60) 155 | # 156 | def test_datetime6(self): 157 | v = loads('2010-01-01T23:59:59-01:00')[0] 158 | self.assertEqual(type(v), datetime) 159 | self.assertIsInstance(v.tzinfo, tzinfo) 160 | s = dumps([v]) 161 | self.assertEqual(s, '^2010-01-01T23:59:59-01') 162 | self.assertEqual(v.utcoffset().seconds/60, 23*60) 163 | # 164 | def test_datetime7(self): 165 | v = loads('2010-01-01T23:59:59+12:00')[0] 166 | self.assertEqual(type(v), datetime) 167 | self.assertIsInstance(v.tzinfo, tzinfo) 168 | s = dumps([v]) 169 | self.assertEqual(s, '^2010-01-01T23:59:59+12') 170 | self.assertEqual(v.utcoffset().seconds/60, 12*60) 171 | # 172 | def test_datetime8(self): 173 | v = loads('2010-01-01T23:59:59+23:00')[0] 174 | self.assertEqual(type(v), datetime) 175 | self.assertIsInstance(v.tzinfo, tzinfo) 176 | s = dumps([v]) 177 | self.assertEqual(s, '^2010-01-01T23:59:59+23') 178 | self.assertEqual(v.utcoffset().seconds/60, 23*60) 179 | # 180 | def test_datetime9(self): 181 | v = loads('2010-01-01T23:59:59-23:00')[0] 182 | self.assertEqual(type(v), datetime) 183 | self.assertIsInstance(v.tzinfo, tzinfo) 184 | s = dumps([v]) 185 | self.assertEqual(s, '^2010-01-01T23:59:59-23') 186 | self.assertEqual(v.utcoffset().seconds/60, 60) 187 | # 188 | def test_datetime10(self): 189 | v = loads('2010-01-01T23:59:59+3:15')[0] 190 | self.assertEqual(type(v), datetime) 191 | self.assertIsInstance(v.tzinfo, tzinfo) 192 | s = dumps([v]) 193 | self.assertEqual(s, '^2010-01-01T23:59:59+03:15') 194 | self.assertEqual(v.utcoffset().seconds/60, 3*60+15) 195 | # 196 | def test_datetime11(self): 197 | v = loads('2010-01-01T23:59:59-3:15')[0] 198 | self.assertEqual(type(v), datetime) 199 | self.assertIsInstance(v.tzinfo, tzinfo) 200 | s = dumps([v]) 201 | self.assertEqual(s, '^2010-01-01T23:59:59-03:15') 202 | self.assertEqual(v.utcoffset().seconds/60, 1440-3*60-15) 203 | # 204 | 205 | def suite(): 206 | suite = unittest.TestSuite() 207 | suite.addTest(unittest.makeSuite(DateTimeTestCase)) 208 | return suite 209 | -------------------------------------------------------------------------------- /lib/axon/test/test_datetime10.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import unicode_literals 4 | import unittest 5 | from axon import loads, dumps 6 | from datetime import date, time, datetime, tzinfo 7 | 8 | class DateTime10TestCase(unittest.TestCase): 9 | 10 | def setUp(self): 11 | pass 12 | 13 | def test_date1(self): 14 | v = loads('^2010-12-01')[0] 15 | self.assertEqual(type(v), date) 16 | s = dumps([v]) 17 | self.assertEqual(s, '^2010-12-01') 18 | # 19 | def test_date2(self): 20 | v = loads('^1900-01-01')[0] 21 | self.assertEqual(type(v), date) 22 | s = dumps([v]) 23 | self.assertEqual(s, '^1900-01-01') 24 | # 25 | def test_date3(self): 26 | v = loads('^12-01-01')[0] 27 | self.assertEqual(type(v), date) 28 | s = dumps([v]) 29 | self.assertEqual(s, '^12-01-01') 30 | # 31 | def test_date4(self): 32 | v = loads('^0-00-00')[0] 33 | self.assertEqual(type(v), date) 34 | s = dumps([v]) 35 | self.assertEqual(s, '^0-00-00') 36 | # 37 | def test_time1(self): 38 | v = loads('^00:00')[0] 39 | self.assertEqual(type(v), time) 40 | s = dumps([v]) 41 | self.assertEqual(s, '^00:00') 42 | # 43 | def test_time2(self): 44 | v = loads('^23:59:59')[0] 45 | self.assertEqual(type(v), time) 46 | s = dumps([v]) 47 | self.assertEqual(s, '^23:59:59') 48 | # 49 | def test_time3(self): 50 | v = loads('^23:59:59.000123')[0] 51 | self.assertEqual(type(v), time) 52 | s = dumps([v]) 53 | self.assertEqual(s, '^23:59:59.000123') 54 | # 55 | def test_time4(self): 56 | v = loads('^23:59:59+00:00')[0] 57 | self.assertEqual(type(v), time) 58 | self.assertIsInstance(v.tzinfo, tzinfo) 59 | s = dumps([v]) 60 | self.assertEqual(s, '^23:59:59+00') 61 | self.assertEqual(v.utcoffset().seconds, 0) 62 | # 63 | def test_time5(self): 64 | v = loads('^23:59:59+01:00')[0] 65 | self.assertEqual(type(v), time) 66 | self.assertIsInstance(v.tzinfo, tzinfo) 67 | s = dumps([v]) 68 | self.assertEqual(s, '^23:59:59+01') 69 | self.assertEqual(v.utcoffset().seconds/60, 60) 70 | # 71 | def test_time6(self): 72 | v = loads('^23:59:59-01:00')[0] 73 | self.assertEqual(type(v), time) 74 | self.assertIsInstance(v.tzinfo, tzinfo) 75 | s = dumps([v]) 76 | self.assertEqual(s, '^23:59:59-01') 77 | self.assertEqual(v.utcoffset().seconds/60, 23*60) 78 | # 79 | def test_time7(self): 80 | v = loads('^23:59:59+12:00')[0] 81 | self.assertEqual(type(v), time) 82 | self.assertIsInstance(v.tzinfo, tzinfo) 83 | s = dumps([v]) 84 | self.assertEqual(s, '^23:59:59+12') 85 | self.assertEqual(v.utcoffset().seconds/60, 12*60) 86 | # 87 | def test_time8(self): 88 | v = loads('^23:59:59+23:00')[0] 89 | self.assertEqual(type(v), time) 90 | self.assertIsInstance(v.tzinfo, tzinfo) 91 | s = dumps([v]) 92 | self.assertEqual(s, '^23:59:59+23') 93 | self.assertEqual(v.utcoffset().seconds/60, 23*60) 94 | # 95 | def test_time9(self): 96 | v = loads('^23:59:59-23:00')[0] 97 | self.assertEqual(type(v), time) 98 | self.assertIsInstance(v.tzinfo, tzinfo) 99 | s = dumps([v]) 100 | self.assertEqual(s, '^23:59:59-23') 101 | self.assertEqual(v.utcoffset().seconds/60, 60) 102 | # 103 | def test_time10(self): 104 | v = loads('^23:59:59+3:15')[0] 105 | self.assertEqual(type(v), time) 106 | self.assertIsInstance(v.tzinfo, tzinfo) 107 | s = dumps([v]) 108 | self.assertEqual(s, '^23:59:59+03:15') 109 | self.assertEqual(v.utcoffset().seconds/60, 3*60+15) 110 | # 111 | def test_time11(self): 112 | v = loads('^23:59:59-3:15')[0] 113 | self.assertEqual(type(v), time) 114 | self.assertIsInstance(v.tzinfo, tzinfo) 115 | s = dumps([v]) 116 | self.assertEqual(s, '^23:59:59-03:15') 117 | self.assertEqual(v.utcoffset().seconds/60, 1440-3*60-15) 118 | # 119 | def test_datetime1(self): 120 | v = loads('^2010-01-01T00:00')[0] 121 | self.assertEqual(type(v), datetime) 122 | self.assertEqual(v.tzinfo, None) 123 | s = dumps([v]) 124 | self.assertEqual(s, '^2010-01-01T00:00') 125 | # 126 | def test_datetime2(self): 127 | v = loads('^1-01-01T23:59:59')[0] 128 | self.assertEqual(type(v), datetime) 129 | self.assertEqual(v.tzinfo, None) 130 | s = dumps([v]) 131 | self.assertEqual(s, '^1-01-01T23:59:59') 132 | # 133 | def test_datetime3(self): 134 | v = loads('^2010-01-01T23:59:59.000123')[0] 135 | self.assertEqual(type(v), datetime) 136 | self.assertEqual(v.tzinfo, None) 137 | s = dumps([v]) 138 | self.assertEqual(s, '^2010-01-01T23:59:59.000123') 139 | # 140 | def test_datetime4(self): 141 | v = loads('^2010-01-01T23:59:59+00:00')[0] 142 | self.assertEqual(type(v), datetime) 143 | self.assertIsInstance(v.tzinfo, tzinfo) 144 | s = dumps([v]) 145 | self.assertEqual(s, '^2010-01-01T23:59:59+00') 146 | self.assertEqual(v.utcoffset().seconds, 0) 147 | # 148 | def test_datetime5(self): 149 | v = loads('^2010-01-01T23:59:59+01:00')[0] 150 | self.assertEqual(type(v), datetime) 151 | self.assertIsInstance(v.tzinfo, tzinfo) 152 | s = dumps([v]) 153 | self.assertEqual(s, '^2010-01-01T23:59:59+01') 154 | self.assertEqual(v.utcoffset().seconds/60, 60) 155 | # 156 | def test_datetime6(self): 157 | v = loads('^2010-01-01T23:59:59-01:00')[0] 158 | self.assertEqual(type(v), datetime) 159 | self.assertIsInstance(v.tzinfo, tzinfo) 160 | s = dumps([v]) 161 | self.assertEqual(s, '^2010-01-01T23:59:59-01') 162 | self.assertEqual(v.utcoffset().seconds/60, 23*60) 163 | # 164 | def test_datetime7(self): 165 | v = loads('^2010-01-01T23:59:59+12:00')[0] 166 | self.assertEqual(type(v), datetime) 167 | self.assertIsInstance(v.tzinfo, tzinfo) 168 | s = dumps([v]) 169 | self.assertEqual(s, '^2010-01-01T23:59:59+12') 170 | self.assertEqual(v.utcoffset().seconds/60, 12*60) 171 | # 172 | def test_datetime8(self): 173 | v = loads('^2010-01-01T23:59:59+23:00')[0] 174 | self.assertEqual(type(v), datetime) 175 | self.assertIsInstance(v.tzinfo, tzinfo) 176 | s = dumps([v]) 177 | self.assertEqual(s, '^2010-01-01T23:59:59+23') 178 | self.assertEqual(v.utcoffset().seconds/60, 23*60) 179 | # 180 | def test_datetime9(self): 181 | v = loads('^2010-01-01T23:59:59-23:00')[0] 182 | self.assertEqual(type(v), datetime) 183 | self.assertIsInstance(v.tzinfo, tzinfo) 184 | s = dumps([v]) 185 | self.assertEqual(s, '^2010-01-01T23:59:59-23') 186 | self.assertEqual(v.utcoffset().seconds/60, 60) 187 | # 188 | def test_datetime10(self): 189 | v = loads('^2010-01-01T23:59:59+3:15')[0] 190 | self.assertEqual(type(v), datetime) 191 | self.assertIsInstance(v.tzinfo, tzinfo) 192 | s = dumps([v]) 193 | self.assertEqual(s, '^2010-01-01T23:59:59+03:15') 194 | self.assertEqual(v.utcoffset().seconds/60, 3*60+15) 195 | # 196 | def test_datetime11(self): 197 | v = loads('^2010-01-01T23:59:59-3:15')[0] 198 | self.assertEqual(type(v), datetime) 199 | self.assertIsInstance(v.tzinfo, tzinfo) 200 | s = dumps([v]) 201 | self.assertEqual(s, '^2010-01-01T23:59:59-03:15') 202 | self.assertEqual(v.utcoffset().seconds/60, 1440-3*60-15) 203 | # 204 | 205 | def suite(): 206 | suite = unittest.TestSuite() 207 | suite.addTest(unittest.makeSuite(DateTime10TestCase)) 208 | return suite 209 | -------------------------------------------------------------------------------- /lib/axon/test/test_decimal.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import unicode_literals 4 | import unittest 5 | from axon import loads, dumps 6 | try: 7 | from cdecimal import Decimal as decimal 8 | except: 9 | from decimal import Decimal as decimal 10 | 11 | class DecimalTestCase(unittest.TestCase): 12 | 13 | def setUp(self): 14 | pass 15 | 16 | def test_decimal1(self): 17 | v = loads('0d')[0] 18 | self.assertAlmostEqual(v, decimal('0.')) 19 | def test_decimal2(self): 20 | v = loads('0.D')[0] 21 | self.assertAlmostEqual(v, decimal('0.')) 22 | def test_decimal3(self): 23 | v = loads('123d')[0] 24 | self.assertAlmostEqual(v, decimal('123')) 25 | def test_decimal4(self): 26 | v = loads('3.141528D')[0] 27 | self.assertAlmostEqual(v, decimal('3.141528')) 28 | def test_decimal5(self): 29 | v = loads('-1.2345e5d')[0] 30 | self.assertAlmostEqual(v, decimal('-1.2345e5')) 31 | def test_decimal6(self): 32 | v = loads('-1.2345e+5d')[0] 33 | self.assertAlmostEqual(v, decimal('-1.2345e5')) 34 | def test_decimal7(self): 35 | v = loads('-1.2345e-5D')[0] 36 | self.assertAlmostEqual(v, decimal('-1.2345e-5')) 37 | def test_decimal8(self): 38 | v = loads('-1.2345e27D')[0] 39 | self.assertAlmostEqual(v, decimal('-1.2345e27')) 40 | def test_decimal9(self): 41 | v = loads('-1.2345e-27d')[0] 42 | self.assertAlmostEqual(v, decimal('-1.2345e-27')) 43 | def test_decimal10(self): 44 | v = loads('1.2345e+27D')[0] 45 | self.assertAlmostEqual(v, decimal('1.2345e+27')) 46 | # 47 | 48 | def suite(): 49 | suite = unittest.TestSuite() 50 | suite.addTest(unittest.makeSuite(DecimalTestCase)) 51 | return suite 52 | -------------------------------------------------------------------------------- /lib/axon/test/test_dict.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import unicode_literals 4 | import unittest 5 | from axon import * 6 | 7 | class DictTestCase(unittest.TestCase): 8 | 9 | def setUp(self): 10 | pass 11 | # 12 | def test_empty_dict1(self): 13 | v = loads('{}')[0] 14 | self.assertEqual(type(v), dict) 15 | self.assertEqual(v, {}) 16 | s = dumps([v]) 17 | self.assertEqual(s, '{}') 18 | # 19 | def test_empty_dict2(self): 20 | v = loads('{}\n')[0] 21 | self.assertEqual(type(v), dict) 22 | self.assertEqual(v, {}) 23 | s = dumps([v], pretty=True) 24 | self.assertEqual(s, '{}') 25 | # 26 | def test_dict1(self): 27 | v = loads('{a:1 b:2}')[0] 28 | self.assertEqual(type(v), dict) 29 | self.assertEqual(list(sorted(v.items())), [('a',1),('b',2)]) 30 | # 31 | def test_dict1_1(self): 32 | v = loads('{a:1 b:2}')[0] 33 | self.assertEqual(type(v), dict) 34 | self.assertEqual(list(sorted(v.items())), [('a',1),('b',2)]) 35 | # 36 | def test_dict2(self): 37 | v = loads('{a:[1 2] b:{c:3}}')[0] 38 | self.assertEqual(type(v), dict) 39 | self.assertEqual(list(sorted(v.items())), [('a',[1,2]),('b',{'c':3})]) 40 | 41 | def suite(): 42 | suite = unittest.TestSuite() 43 | suite.addTest(unittest.makeSuite(DictTestCase)) 44 | return suite 45 | -------------------------------------------------------------------------------- /lib/axon/test/test_element.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import unicode_literals 4 | import unittest 5 | from axon import * 6 | 7 | class ElementTestCase(unittest.TestCase): 8 | 9 | def setUp(self): 10 | pass 11 | # 12 | def test_empty_element(self): 13 | v = element('aaa', {}, []) 14 | self.assertEqual(v.name, 'aaa') 15 | self.assertEqual(v.mapping, {}) 16 | self.assertEqual(v.sequence, []) 17 | # 18 | def test_element_init(self): 19 | l = {'a':1, 'b':2} 20 | v = element('aaa', {'a':1, 'b':2}, [1,2,3]) 21 | self.assertEqual(v.mapping, {'a':1, 'b':2}) 22 | self.assertEqual(v.sequence, [1,2,3]) 23 | # 24 | def test_element1(self): 25 | v = loads('aaa{a:1 b:2 c:3 4 5 6}')[0] 26 | self.assertEqual(v.name, 'aaa') 27 | self.assertEqual(type(v), Element) 28 | self.assertEqual(v.sequence, [4, 5, 6]) 29 | self.assertEqual(v.mapping, {'a': 1, 'b': 2, 'c': 3}) 30 | s = dumps([v]) 31 | self.assertEqual(s, "aaa{a:1 b:2 c:3 4 5 6}") 32 | # 33 | def test_element1_1(self): 34 | v = loads(''' 35 | aaa: 36 | a:1 37 | b:2 38 | c:3 39 | 4 5 6 40 | ''')[0] 41 | self.assertEqual(v.name, 'aaa') 42 | self.assertEqual(type(v), Element) 43 | self.assertEqual(v.sequence, [4, 5, 6]) 44 | self.assertEqual(v.mapping, {'a': 1, 'b': 2, 'c': 3}) 45 | s = dumps([v]) 46 | self.assertEqual(s, \ 47 | 'aaa{' + \ 48 | ' '.join("%s:%s" % (k,x) for k,x in sorted(v.mapping.items())) + ' ' + \ 49 | ' '.join("%s" % x for x in v.sequence) + \ 50 | '}') 51 | # 52 | def test_element2(self): 53 | v = loads('aaa {a:1 b:2 c:3 4 5 6}')[0] 54 | self.assertEqual(v.name, 'aaa') 55 | self.assertEqual(type(v), Element) 56 | self.assertEqual(v.sequence, [4, 5, 6]) 57 | self.assertEqual(v.mapping, {'a': 1, 'b': 2, 'c': 3}) 58 | s = dumps([v], pretty=1) 59 | self.assertEqual(s, \ 60 | 'aaa:\n ' + \ 61 | '\n '.join(\ 62 | "%s: %s" % (k,x) \ 63 | for k,x in sorted(v.mapping.items())) + \ 64 | '\n ' + \ 65 | ' '.join("%s" % x for x in v.sequence) 66 | ) 67 | # 68 | def test_element_ident1(self): 69 | v = loads(''' 70 | aaa: 71 | \ta:1 72 | b: 2 73 | c : 3 74 | \t1 75 | 2\t 76 | \t3 77 | ''')[0] 78 | self.assertEqual(v.name, 'aaa') 79 | self.assertEqual(type(v), Element) 80 | self.assertEqual(v.sequence, [1,2,3]) 81 | self.assertEqual(v.mapping, {'a': 1, 'b': 2, 'c': 3}) 82 | s = dumps([v]) 83 | self.assertEqual(s, 'aaa{a:1 b:2 c:3 1 2 3}') 84 | # 85 | def test_element_ident2(self): 86 | v = loads(''' 87 | aaa: 88 | \t\ta:1 89 | \tb: 2 90 | \tc : 3 91 | 1\t 92 | \t 2 93 | \t3 94 | ''')[0] 95 | self.assertEqual(v.name, 'aaa') 96 | self.assertEqual(type(v), Element) 97 | self.assertEqual(v.sequence, [1,2,3]) 98 | self.assertEqual(v.mapping, {'a': 1, 'b': 2, 'c': 3}) 99 | s = dumps([v]) 100 | self.assertEqual(s, 'aaa{a:1 b:2 c:3 1 2 3}') 101 | # 102 | 103 | def suite(): 104 | suite = unittest.TestSuite() 105 | suite.addTest(unittest.makeSuite(ElementTestCase)) 106 | return suite 107 | -------------------------------------------------------------------------------- /lib/axon/test/test_errors.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import unicode_literals 4 | import unittest 5 | from axon import loads, dumps 6 | from axon.errors import AxonError 7 | 8 | class AxonErrorTestCase(unittest.TestCase): 9 | 10 | def setUp(self): 11 | pass 12 | 13 | def test_unexpected_end_1(self): 14 | text = 'a{' 15 | try: 16 | vs = loads(text) 17 | except AxonError: 18 | pass 19 | 20 | def test_unexpected_end_11(self): 21 | text = '{' 22 | try: 23 | vs = loads(text) 24 | except AxonError: 25 | pass 26 | 27 | def test_unexpected_end_12(self): 28 | text = '[' 29 | try: 30 | vs = loads(text) 31 | except AxonError: 32 | pass 33 | 34 | def test_unexpected_end_2(self): 35 | text = '"abc' 36 | try: 37 | vs = loads(text) 38 | except AxonError: 39 | pass 40 | 41 | def test_unexpected_end_3(self): 42 | text = '''"abc 43 | qwertyuiop 44 | ''' 45 | try: 46 | vs = loads(text) 47 | except AxonError: 48 | pass 49 | 50 | def test_unexpected_end_4(self): 51 | text = 'a{name:' 52 | try: 53 | vs = loads(text) 54 | except AxonError: 55 | pass 56 | 57 | def test_unexpected_end_41(self): 58 | text = '{name:' 59 | try: 60 | vs = loads(text) 61 | except AxonError: 62 | pass 63 | 64 | def test_unexpected_end_5(self): 65 | text = 'a{name:}' 66 | try: 67 | vs = loads(text) 68 | except AxonError: 69 | pass 70 | 71 | def test_unexpected_end_51(self): 72 | text = '{name:}' 73 | try: 74 | vs = loads(text) 75 | except AxonError: 76 | pass 77 | 78 | def test_unexpected_end_52(self): 79 | text = '{name:"anne" 17}' 80 | try: 81 | vs = loads(text) 82 | except AxonError: 83 | pass 84 | 85 | def test_unexpected_end_6(self): 86 | text = 'a{name:1 age:' 87 | try: 88 | vs = loads(text) 89 | except AxonError: 90 | pass 91 | 92 | def test_unexpected_end_61(self): 93 | text = '{name:1 age:' 94 | try: 95 | vs = loads(text) 96 | except AxonError: 97 | pass 98 | 99 | def test_unexpected_end_7(self): 100 | text = '[1 2 ' 101 | try: 102 | vs = loads(text) 103 | except AxonError: 104 | pass 105 | 106 | def test_unexpected_end_71(self): 107 | text = '[1 2 a:' 108 | try: 109 | vs = loads(text) 110 | except AxonError: 111 | pass 112 | 113 | def test_unexpected_end_72(self): 114 | text = '[1 2 a:7' 115 | try: 116 | vs = loads(text) 117 | except AxonError: 118 | pass 119 | 120 | def test_invalid_indent_1(self): 121 | text = \ 122 | ''' 123 | aaa 124 | a:1 125 | b: 2 126 | ''' 127 | try: 128 | vs = loads(text) 129 | except AxonError: 130 | pass 131 | 132 | def test_invalid_indent_2(self): 133 | text = \ 134 | ''' 135 | aaa 136 | 100 137 | 200 138 | ''' 139 | try: 140 | vs = loads(text) 141 | except AxonError: 142 | pass 143 | 144 | def test_invalid_indent_3(self): 145 | text = \ 146 | ''' 147 | aaa 148 | a:1 149 | b: 2 150 | ''' 151 | try: 152 | vs = loads(text) 153 | except AxonError: 154 | pass 155 | 156 | def test_invalid_indent_4(self): 157 | text = \ 158 | ''' 159 | aaa 160 | 100 161 | 200 162 | ''' 163 | try: 164 | vs = loads(text) 165 | except AxonError: 166 | pass 167 | 168 | # 169 | # 170 | # 171 | 172 | def test_invalid_indent_11(self): 173 | text = \ 174 | ''' 175 | aaa 176 | bbb 177 | a:1 178 | b: 2 179 | ''' 180 | try: 181 | vs = loads(text) 182 | except AxonError: 183 | pass 184 | 185 | def test_invalid_indent_12(self): 186 | text = \ 187 | ''' 188 | aaa 189 | bbb: 190 | 100 191 | 200 192 | ''' 193 | try: 194 | vs = loads(text) 195 | except AxonError: 196 | pass 197 | 198 | def test_invalid_indent_13(self): 199 | text = \ 200 | ''' 201 | aaa 202 | bbb 203 | a:1 204 | b: 2 205 | ''' 206 | try: 207 | vs = loads(text) 208 | except AxonError: 209 | pass 210 | 211 | def test_invalid_indent_14(self): 212 | text = \ 213 | ''' 214 | aaa 215 | bbb 216 | 100 217 | 200 218 | ''' 219 | try: 220 | vs = loads(text) 221 | except AxonError: 222 | pass 223 | 224 | def test_invalid_indent_15(self): 225 | text = \ 226 | ''' 227 | aaa 228 | bbb 229 | 100 230 | 200 231 | ccc 232 | a:1 233 | b:2 234 | ''' 235 | try: 236 | vs = loads(text) 237 | except AxonError: 238 | pass 239 | 240 | def test_invalid_key_1(self): 241 | try: 242 | text = dumps([{('foo', 'bar'): True}]) 243 | except TypeError: 244 | pass 245 | 246 | 247 | def suite(): 248 | suite = unittest.TestSuite() 249 | suite.addTest(unittest.makeSuite(AxonErrorTestCase)) 250 | return suite 251 | -------------------------------------------------------------------------------- /lib/axon/test/test_float.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import unicode_literals 4 | import unittest 5 | from axon import loads, dumps 6 | 7 | class FloatTestCase(unittest.TestCase): 8 | 9 | def setUp(self): 10 | pass 11 | 12 | def test_float1(self): 13 | v = loads('0.')[0] 14 | self.assertAlmostEqual(v, 0.) 15 | def test_float2(self): 16 | v = loads('3.141528')[0] 17 | self.assertAlmostEqual(v, 3.141528) 18 | def test_float3(self): 19 | v = loads('-1.2345e5')[0] 20 | self.assertAlmostEqual(v, -1.2345e5) 21 | def test_float4(self): 22 | v = loads('-1.2345e+5')[0] 23 | self.assertAlmostEqual(v, -1.2345e5) 24 | def test_float5(self): 25 | v = loads('-1.2345e-5')[0] 26 | self.assertAlmostEqual(v, -1.2345e-5) 27 | def test_float6(self): 28 | v = loads('-1.2345e27')[0] 29 | self.assertAlmostEqual(v, -1.2345e27) 30 | def test_float7(self): 31 | v = loads('-1.2345e-27')[0] 32 | self.assertAlmostEqual(v, -1.2345e-27) 33 | def test_zero(self): 34 | v = loads('-0.')[0] 35 | s = dumps([v]) 36 | self.assertEqual(s, '-0.0') 37 | # 38 | 39 | def suite(): 40 | suite = unittest.TestSuite() 41 | suite.addTest(unittest.makeSuite(FloatTestCase)) 42 | return suite 43 | -------------------------------------------------------------------------------- /lib/axon/test/test_instance.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import unicode_literals 4 | import unittest 5 | from axon import * 6 | 7 | class ObjectTestCase(unittest.TestCase): 8 | 9 | def setUp(self): 10 | pass 11 | # 12 | def test_empty_object(self): 13 | v = instance('aaa', [], {}) 14 | self.assertEqual(v.name, 'aaa') 15 | self.assertEqual(v.mapping, {}) 16 | self.assertEqual(v.sequence, ()) 17 | # 18 | def test_object_init(self): 19 | l = {'a':1, 'b':2} 20 | v = instance('aaa', [1,2,3], {'a':1, 'b':2}) 21 | self.assertEqual(v.mapping, {'a':1, 'b':2}) 22 | self.assertEqual(v.sequence, (1,2,3)) 23 | # 24 | def test_object1(self): 25 | v = loads('aaa {4 5 6 a:1 b:2 c:3}')[0] 26 | self.assertEqual(v.name, 'aaa') 27 | self.assertEqual(type(v), Instance) 28 | self.assertEqual(v.sequence, (4, 5, 6)) 29 | self.assertEqual(v.mapping, {'a': 1, 'b': 2, 'c': 3}) 30 | s = dumps([v]) 31 | self.assertEqual(s, '''aaa{4 5 6 a:1 b:2 c:3}''') 32 | # 33 | def test_object2(self): 34 | v = loads('aaa{4 5 6 a:1 b : 2 c:3}')[0] 35 | self.assertEqual(v.name, 'aaa') 36 | self.assertEqual(type(v), Instance) 37 | self.assertEqual(v.sequence, (4, 5, 6)) 38 | self.assertEqual(v.mapping, {'a': 1, 'b': 2, 'c': 3}) 39 | s = dumps([v], pretty=1) 40 | self.assertEqual(s, '''\ 41 | aaa: 42 | 4 5 6 43 | a: 1 44 | b: 2 45 | c: 3''') 46 | # 47 | def test_instance_ident1(self): 48 | v = loads(''' 49 | aaa: 50 | \t1 51 | 2\t 52 | \t3 53 | \ta:1 54 | b: 2 55 | c : 3 56 | ''')[0] 57 | self.assertEqual(v.name, 'aaa') 58 | self.assertEqual(type(v), Instance) 59 | self.assertEqual(v.sequence, (1,2,3)) 60 | self.assertEqual(v.mapping, {'a': 1, 'b': 2, 'c': 3}) 61 | s = dumps([v]) 62 | self.assertEqual(s, 'aaa{1 2 3 a:1 b:2 c:3}') 63 | # 64 | def test_instance_ident2(self): 65 | v = loads(''' 66 | aaa: 67 | 1\t 68 | \t 2 69 | \t3 70 | \t\ta:1 71 | \tb: 2 72 | \tc : 3 73 | ''')[0] 74 | self.assertEqual(v.name, 'aaa') 75 | self.assertEqual(type(v), Instance) 76 | self.assertEqual(v.sequence, (1,2,3)) 77 | self.assertEqual(v.mapping, {'a': 1, 'b': 2, 'c': 3}) 78 | s = dumps([v]) 79 | self.assertEqual(s, 'aaa{1 2 3 a:1 b:2 c:3}') 80 | # 81 | 82 | def suite(): 83 | suite = unittest.TestSuite() 84 | suite.addTest(unittest.makeSuite(ObjectTestCase)) 85 | return suite 86 | -------------------------------------------------------------------------------- /lib/axon/test/test_int.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import unicode_literals 4 | import unittest 5 | from axon import loads, dumps 6 | 7 | class IntTestCase(unittest.TestCase): 8 | 9 | def setUp(self): 10 | pass 11 | 12 | def test_int1(self): 13 | v = loads('0')[0] 14 | self.assertEqual(v, 0) 15 | s = dumps([v]) 16 | self.assertEqual(s, '0') 17 | def test_int1a(self): 18 | v = loads('-0')[0] 19 | self.assertEqual(v, 0) 20 | s = dumps([v]) 21 | self.assertEqual(s, '0') 22 | def test_int2(self): 23 | v = loads('-1')[0] 24 | self.assertEqual(v, -1) 25 | s = dumps([v]) 26 | self.assertEqual(s, '-1') 27 | def test_int3(self): 28 | v = loads('1')[0] 29 | self.assertEqual(v, 1) 30 | s = dumps([v]) 31 | self.assertEqual(s, '1') 32 | def test_int4(self): 33 | v = loads('17171717171717171717171717')[0] 34 | self.assertEqual(v, 17171717171717171717171717) 35 | s = dumps([v]) 36 | self.assertEqual(s, '17171717171717171717171717') 37 | def test_int5(self): 38 | v = loads('17')[0] 39 | self.assertEqual(v, 17) 40 | s = dumps([v]) 41 | self.assertEqual(s, '17') 42 | 43 | def suite(): 44 | suite = unittest.TestSuite() 45 | suite.addTest(unittest.makeSuite(IntTestCase)) 46 | return suite 47 | -------------------------------------------------------------------------------- /lib/axon/test/test_list.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import unicode_literals 4 | import unittest 5 | from axon import * 6 | 7 | pretty = False 8 | 9 | class ListTestCase(unittest.TestCase): 10 | 11 | def setUp(self): 12 | pass 13 | 14 | def test_empty_list1(self): 15 | v = loads('[]')[0] 16 | self.assertEqual(type(v), list) 17 | self.assertEqual(v, []) 18 | s = dumps([v]) 19 | self.assertEqual(s, '[]') 20 | # 21 | def test_empty_list2(self): 22 | v = loads('[]')[0] 23 | self.assertEqual(type(v), list) 24 | self.assertEqual(v, []) 25 | s = dumps([v], pretty=True) 26 | self.assertEqual(s, '[]') 27 | # 28 | def test_list1(self): 29 | v = loads('[1 2]')[0] 30 | self.assertEqual(type(v), list) 31 | self.assertEqual(v, [1,2]) 32 | # 33 | def test_list2(self): 34 | v = loads('[[1 2] [2 3]]')[0] 35 | self.assertEqual(type(v), list) 36 | self.assertEqual(v, [[1,2], [2,3]]) 37 | # 38 | def test_list3(self): 39 | v = loads(''' 40 | [ 41 | [1 2] 42 | [2 3] 43 | ]''' 44 | )[0] 45 | self.assertEqual(type(v), list) 46 | self.assertEqual(v, [[1,2], [2,3]]) 47 | # 48 | 49 | def suite(): 50 | suite = unittest.TestSuite() 51 | suite.addTest(unittest.makeSuite(ListTestCase)) 52 | return suite 53 | -------------------------------------------------------------------------------- /lib/axon/test/test_mapping.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import unicode_literals 4 | import unittest 5 | from axon import * 6 | 7 | class MappingTestCase(unittest.TestCase): 8 | 9 | def setUp(self): 10 | pass 11 | # 12 | def test_empty_mapping(self): 13 | v = mapping('aaa', {}) 14 | self.assertEqual(v.name, 'aaa') 15 | self.assertFalse(v.mapping) 16 | self.assertEqual(v.mapping, {}) 17 | self.assertFalse(v.sequence) 18 | self.assertEqual(v.sequence, None) 19 | # 20 | def test_mapping_init(self): 21 | l = {'a':1, 'b':2} 22 | v = mapping('aaa', l) 23 | self.assertEqual(v.mapping, {'a':1, 'b':2}) 24 | # 25 | def test_mapping1(self): 26 | v = loads('aaa{a:1 b: 2 c : 3}')[0] 27 | self.assertEqual(v.name, 'aaa') 28 | self.assertEqual(type(v), Mapping) 29 | self.assertEqual(v.sequence, None) 30 | self.assertEqual(v.mapping, {'a': 1, 'b': 2, 'c': 3}) 31 | s = dumps([v]) 32 | self.assertEqual(s, '''aaa{a:1 b:2 c:3}''') 33 | # 34 | def test_mapping1_1(self): 35 | v = loads(''' 36 | aaa: 37 | a:1 38 | b: 2 39 | c : 3 40 | ''')[0] 41 | self.assertEqual(v.name, 'aaa') 42 | self.assertEqual(type(v), Mapping) 43 | self.assertEqual(v.sequence, None) 44 | self.assertEqual(v.mapping, {'a': 1, 'b': 2, 'c': 3}) 45 | s = dumps([v]) 46 | self.assertEqual(s, '''aaa{a:1 b:2 c:3}''') 47 | # 48 | def test_mapping2(self): 49 | v = loads('aaa {a: 1 b:2 c:3}')[0] 50 | self.assertEqual(v.name, 'aaa') 51 | self.assertEqual(type(v), Mapping) 52 | self.assertEqual(v.sequence, None) 53 | self.assertEqual(v.mapping, {'a': 1, 'b': 2, 'c': 3}) 54 | s = dumps([v], pretty=1) 55 | self.assertEqual(s, '''\ 56 | aaa: 57 | a: 1 58 | b: 2 59 | c: 3''') 60 | # 61 | def test_mapping3(self): 62 | v = loads(''' 63 | aaa: 64 | a: 1 65 | b: 2 66 | c: c: 67 | e: 1 68 | f: f: 69 | r: 2 70 | s: 3 71 | d: 4 72 | ''')[0] 73 | self.assertEqual(v.name, 'aaa') 74 | self.assertEqual(type(v), Mapping) 75 | self.assertEqual(v.sequence, None) 76 | s = dumps([v]) 77 | self.assertEqual(s, '''aaa{a:1 b:2 c:c{e:1 f:f{r:2 s:3}} d:4}''') 78 | s = dumps([v], pretty=1) 79 | self.assertEqual(s, '''\ 80 | aaa: 81 | a: 1 82 | b: 2 83 | c: c: 84 | e: 1 85 | f: f: 86 | r: 2 87 | s: 3 88 | d: 4''') 89 | # 90 | def test_mapping4(self): 91 | v = loads(''' 92 | aaa: 93 | a: 1 94 | b: 2 95 | c: 96 | e: 1 97 | f: 98 | r: 2 99 | s: 3 100 | d: 101 | 4 102 | ''')[0] 103 | self.assertEqual(v.name, 'aaa') 104 | self.assertEqual(type(v), Element) 105 | s = dumps([v]) 106 | self.assertEqual(s, '''aaa{a:1 b:2 c{e:1 f{r:2 s:3}} d{4}}''') 107 | s = dumps([v], pretty=1) 108 | self.assertEqual(s, '''\ 109 | aaa: 110 | a: 1 111 | b: 2 112 | c: 113 | e: 1 114 | f: 115 | r: 2 116 | s: 3 117 | d: 118 | 4''') 119 | # 120 | def test_mapping_dotted_names(self): 121 | l = {'en.a':1, 'ru.a':2} 122 | v = mapping('example.aaa', l) 123 | self.assertEqual(v.mapping, {'en.a':1, 'ru.a':2}) 124 | self.assertEqual(v.name, 'example.aaa') 125 | # 126 | def test_mapping_ident1(self): 127 | v = loads(''' 128 | aaa: 129 | \ta:1 130 | b: 2 131 | c : 3 132 | ''')[0] 133 | self.assertEqual(v.name, 'aaa') 134 | self.assertEqual(type(v), Mapping) 135 | self.assertEqual(v.sequence, None) 136 | self.assertEqual(v.mapping, {'a': 1, 'b': 2, 'c': 3}) 137 | s = dumps([v]) 138 | self.assertEqual(s, 'aaa{a:1 b:2 c:3}') 139 | # 140 | def test_mapping_ident2(self): 141 | v = loads(''' 142 | aaa: 143 | \t\ta:1 144 | \tb: 2 145 | \tc : 3 146 | ''')[0] 147 | self.assertEqual(v.name, 'aaa') 148 | self.assertEqual(type(v), Mapping) 149 | self.assertEqual(v.sequence, None) 150 | self.assertEqual(v.mapping, {'a': 1, 'b': 2, 'c': 3}) 151 | s = dumps([v]) 152 | self.assertEqual(s, 'aaa{a:1 b:2 c:3}') 153 | # 154 | 155 | def suite(): 156 | suite = unittest.TestSuite() 157 | suite.addTest(unittest.makeSuite(MappingTestCase)) 158 | return suite 159 | -------------------------------------------------------------------------------- /lib/axon/test/test_samples.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals, print_function 2 | from axon import loads, dumps 3 | import unittest 4 | 5 | from axon.test import samples 6 | 7 | 8 | _dict = {} 9 | for name in dir(samples): 10 | if name.startswith('text'): 11 | items = name.split('_') 12 | _, num, key = items 13 | d = _dict.setdefault(num, {}) 14 | d[key] = getattr(samples, name) 15 | 16 | class SamplesTestCase(unittest.TestCase): 17 | pass 18 | 19 | for key, d in _dict.items(): 20 | text_o, text_0, text_1, text_2 = d['o'], d['0'], d['1'], d['2'] 21 | def ftest(self, text_o=text_o, text_0=text_0, text_1=text_1, text_2=text_2): 22 | vs = loads(text_o) 23 | t_0 = dumps(vs, sorted=1) 24 | t_1 = dumps(vs, pretty=1, braces=1, sorted=1) 25 | t_2 = dumps(vs, pretty=1, sorted=1) 26 | #toks = tokens(text_o) 27 | #t_3 = ''.join(toks) 28 | #print(t_0, t_1, t_2) 29 | #print(text_0, text_1, text_2) 30 | self.assertEqual(t_0, text_0) 31 | self.assertEqual(t_1, text_1) 32 | self.assertEqual(t_2, text_2) 33 | #self.assertEqual(t_3, text_0) 34 | fname = '_'.join(['test_samples', key]) 35 | #setattr(ftest, str('__name__'), fname) 36 | setattr(SamplesTestCase, fname, ftest) 37 | del ftest 38 | 39 | def suite(): 40 | suite = unittest.TestSuite() 41 | suite.addTest(unittest.makeSuite(SamplesTestCase)) 42 | return suite 43 | -------------------------------------------------------------------------------- /lib/axon/test/test_sequence.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import unicode_literals 4 | import unittest 5 | from axon import * 6 | 7 | class SequenceTestCase(unittest.TestCase): 8 | 9 | def setUp(self): 10 | pass 11 | # 12 | def test_empty_sequence(self): 13 | v = sequence('aaa', []) 14 | self.assertEqual(v.name, 'aaa') 15 | self.assertFalse(v.sequence) 16 | self.assertEqual(v.sequence, []) 17 | self.assertFalse(v.mapping) 18 | self.assertEqual(v.mapping, None) 19 | # 20 | def test_sequence_init2(self): 21 | l = [1,2,3] 22 | v = sequence('aaa', l) 23 | self.assertEqual(v.sequence, l) 24 | # 25 | def test_sequence1(self): 26 | v = loads('aaa{1 2 3}')[0] 27 | self.assertEqual(v.name, 'aaa') 28 | self.assertEqual(type(v), Sequence) 29 | self.assertEqual(v.sequence, [1, 2, 3]) 30 | self.assertEqual(v.mapping, None) 31 | s = dumps([v]) 32 | self.assertEqual(s, 'aaa{1 2 3}') 33 | # 34 | def test_sequence1_1(self): 35 | v = loads(''' 36 | aaa: 37 | 1 38 | 2 39 | 3 40 | ''')[0] 41 | self.assertEqual(v.name, 'aaa') 42 | self.assertEqual(type(v), Sequence) 43 | self.assertEqual(v.sequence, [1, 2, 3]) 44 | self.assertEqual(v.mapping, None) 45 | s = dumps([v]) 46 | self.assertEqual(s, 'aaa{1 2 3}') 47 | # 48 | def test_sequence1_2(self): 49 | v = loads(''' 50 | aaa: 51 | 1 2 52 | 3 4 53 | ''')[0] 54 | self.assertEqual(v.name, 'aaa') 55 | self.assertEqual(type(v), Sequence) 56 | self.assertEqual(v.sequence, [1, 2, 3, 4]) 57 | self.assertEqual(v.mapping, None) 58 | s = dumps([v]) 59 | self.assertEqual(s, 'aaa{1 2 3 4}') 60 | # 61 | def test_sequence1_3(self): 62 | v = loads(''' 63 | aaa: 64 | 1 2 65 | bbb {1 2 3} 66 | 3 4 67 | ''')[0] 68 | self.assertEqual(v.name, 'aaa') 69 | self.assertEqual(type(v), Sequence) 70 | #self.assertEqual(v.sequence, [1, 2, 3, 4]) 71 | self.assertEqual(v.mapping, None) 72 | s = dumps([v]) 73 | self.assertEqual(s, 'aaa{1 2 bbb{1 2 3} 3 4}') 74 | # 75 | def test_sequence1_4(self): 76 | v = loads(''' 77 | aaa: 78 | 1 2 79 | bbb: 80 | 1 2 81 | 3 82 | 3 4 83 | ''')[0] 84 | self.assertEqual(v.name, 'aaa') 85 | self.assertEqual(type(v), Sequence) 86 | #self.assertEqual(v.sequence, [1, 2, 3, 4]) 87 | self.assertEqual(v.mapping, None) 88 | s = dumps([v]) 89 | self.assertEqual(s, 'aaa{1 2 bbb{1 2 3} 3 4}') 90 | # 91 | def test_sequence2(self): 92 | v = loads('aaa{1 2 3}')[0] 93 | self.assertEqual(v.name, 'aaa') 94 | self.assertEqual(type(v), Sequence) 95 | self.assertEqual(v.sequence, [1, 2, 3]) 96 | self.assertEqual(v.mapping, None) 97 | s = dumps([v], pretty=1) 98 | self.assertEqual(s, \ 99 | '''aaa: 100 | 1 2 3''') 101 | # 102 | def test_sequence_ident1(self): 103 | v = loads(''' 104 | aaa: 105 | \t1 106 | 2\t 107 | \t3 108 | ''')[0] 109 | self.assertEqual(v.name, 'aaa') 110 | self.assertEqual(type(v), Sequence) 111 | self.assertEqual(v.sequence, [1,2,3]) 112 | self.assertEqual(v.mapping, None) 113 | s = dumps([v]) 114 | self.assertEqual(s, 'aaa{1 2 3}') 115 | # 116 | def test_sequence_ident2(self): 117 | v = loads(''' 118 | aaa: 119 | 1\t 120 | \t 2 121 | \t3 122 | ''')[0] 123 | self.assertEqual(v.name, 'aaa') 124 | self.assertEqual(type(v), Sequence) 125 | self.assertEqual(v.sequence, [1,2,3]) 126 | self.assertEqual(v.mapping, None) 127 | s = dumps([v]) 128 | self.assertEqual(s, 'aaa{1 2 3}') 129 | # 130 | 131 | def suite(): 132 | suite = unittest.TestSuite() 133 | suite.addTest(unittest.makeSuite(SequenceTestCase)) 134 | return suite 135 | -------------------------------------------------------------------------------- /lib/axon/test/test_set.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import unicode_literals 4 | import unittest 5 | from axon import * 6 | 7 | pretty = False 8 | 9 | class SetTestCase(unittest.TestCase): 10 | 11 | def setUp(self): 12 | pass 13 | 14 | def test_empty_set1(self): 15 | v = loads('∅')[0] 16 | self.assertEqual(type(v), set) 17 | self.assertEqual(v, set()) 18 | s = dumps([v]) 19 | self.assertEqual(s, '∅') 20 | # 21 | def test_empty_set1set2(self): 22 | v = loads('∅')[0] 23 | self.assertEqual(type(v), set) 24 | self.assertEqual(v, set()) 25 | s = dumps([v], pretty=True) 26 | self.assertEqual(s, '∅') 27 | # 28 | def test_set1(self): 29 | v = loads('{1 2}')[0] 30 | self.assertEqual(type(v), set) 31 | self.assertEqual(list(sorted(v)), [1,2]) 32 | # 33 | 34 | def suite(): 35 | suite = unittest.SetSuite() 36 | suite.addTest(unittest.makeSuite(SetTestCase)) 37 | return suite 38 | -------------------------------------------------------------------------------- /lib/axon/test/test_string.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import unicode_literals 4 | import unittest 5 | from axon import loads, dumps 6 | 7 | class StringTestCase(unittest.TestCase): 8 | 9 | def setUp(self): 10 | pass 11 | 12 | def test_str1(self): 13 | v = loads('""')[0] 14 | self.assertEqual(v, '') 15 | s = dumps([v]) 16 | self.assertEqual(s, '""') 17 | def test_str2(self): 18 | v = loads('"\n"')[0] 19 | self.assertEqual(v, '\n') 20 | s = dumps([v]) 21 | self.assertEqual(s, '"\n"') 22 | def test_str3(self): 23 | t = '''"\ 24 | abc\ 25 | def"''' 26 | v = loads(t)[0] 27 | self.assertEqual(v, 'abcdef') 28 | s = dumps([v]) 29 | self.assertEqual(s, '"abcdef"') 30 | def test_str4(self): 31 | v = loads('"abc абв"')[0] 32 | self.assertEqual(v, 'abc абв') 33 | s = dumps([v]) 34 | self.assertEqual(s, '"abc абв"') 35 | def test_str5(self): 36 | t = '"ab\tcd\nef"' 37 | v = loads(t)[0] 38 | self.assertEqual(v, 'ab\tcd\nef') 39 | s = dumps([v]) 40 | self.assertEqual(s, t) 41 | def test_str6(self): 42 | t = '''"abfdsfdfd 43 | sdfdfdfdfsdfdwrerwrwerwe 44 | cvbnbnfrtt"''' 45 | v = loads(t)[0] 46 | self.assertEqual(v, '''abfdsfdfd 47 | sdfdfdfdfsdfdwrerwrwerwe 48 | cvbnbnfrtt''') 49 | s = dumps([v]) 50 | self.assertEqual(s, t) 51 | # def test_str(self): 52 | # t = '"\\u0041\\U0042"' 53 | # v = loads(t)[0] 54 | # self.assertEqual(v, "AB") 55 | # s = dumps([v]) 56 | # self.assertEqual(s, '"AB"') 57 | # 58 | 59 | def suite(): 60 | suite = unittest.TestSuite() 61 | suite.addTest(unittest.makeSuite(StringTestCase)) 62 | return suite 63 | -------------------------------------------------------------------------------- /lib/axon/test/test_suite.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import unicode_literals 4 | import unittest 5 | 6 | import test_int 7 | import test_float 8 | import test_decimal 9 | import test_string 10 | import test_constant 11 | import test_datetime 12 | import test_anonymous 13 | import test_element 14 | import test_mapping 15 | import test_sequence 16 | import test_construct 17 | import test_safe_loads 18 | import test_unsafe_loads 19 | import test_crossref 20 | import test_base64 21 | import test_errors 22 | import test_vs_json 23 | import test_vs_yaml 24 | 25 | def suite(): 26 | suite = unittest.TestSuite() 27 | suite.addTest(unittest.makeSuite(test_int.IntTestCase)) 28 | suite.addTest(unittest.makeSuite(test_float.FloatTestCase)) 29 | suite.addTest(unittest.makeSuite(test_decimal.DecimalTestCase)) 30 | suite.addTest(unittest.makeSuite(test_string.StringTestCase)) 31 | suite.addTest(unittest.makeSuite(test_constant.ConstantTestCase)) 32 | suite.addTest(unittest.makeSuite(test_datetime.DateTimeTestCase)) 33 | suite.addTest(unittest.makeSuite(test_anonymous.AnonymousTestCase)) 34 | suite.addTest(unittest.makeSuite(test_element.ElementTestCase)) 35 | suite.addTest(unittest.makeSuite(test_mapping.MappingTestCase)) 36 | suite.addTest(unittest.makeSuite(test_sequence.SequenceTestCase)) 37 | suite.addTest(unittest.makeSuite(test_construct.ConstructTestCase)) 38 | suite.addTest(unittest.makeSuite(test_safe_loads.SafeLoadsTestCase)) 39 | suite.addTest(unittest.makeSuite(test_unsafe_loads.UnsafeLoadsTestCase)) 40 | suite.addTest(unittest.makeSuite(test_crossref.CrossrefTestCase)) 41 | suite.addTest(unittest.makeSuite(test_base64.Base64TestCase)) 42 | suite.addTest(unittest.makeSuite(test_errors.LoaderErrorTestCase)) 43 | suite.addTest(unittest.makeSuite(test_vs_json.SimpleONvsJSONTestCase)) 44 | suite.addTest(unittest.makeSuite(test_vs_json.SimpleONvsYAMLTestCase)) 45 | 46 | return suite 47 | 48 | -------------------------------------------------------------------------------- /lib/axon/test/test_tuple.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import unicode_literals 4 | import unittest 5 | from axon import * 6 | 7 | pretty = False 8 | 9 | class TupleTestCase(unittest.TestCase): 10 | 11 | def setUp(self): 12 | pass 13 | 14 | def test_empty_tuple1(self): 15 | v = loads('()')[0] 16 | self.assertEqual(type(v), tuple) 17 | self.assertEqual(v, ()) 18 | s = dumps([v]) 19 | self.assertEqual(s, '()') 20 | # 21 | def test_empty_tuple2(self): 22 | v = loads('()')[0] 23 | self.assertEqual(type(v), tuple) 24 | self.assertEqual(v, ()) 25 | s = dumps([v], pretty=True) 26 | self.assertEqual(s, '()') 27 | # 28 | def test_tuple1(self): 29 | v = loads('(1 2)')[0] 30 | self.assertEqual(type(v), tuple) 31 | self.assertEqual(v, (1,2)) 32 | # 33 | # 34 | 35 | def suite(): 36 | suite = unittest.TestSuite() 37 | suite.addTest(unittest.makeSuite(TupleTestCase)) 38 | return suite 39 | -------------------------------------------------------------------------------- /lib/axon/test/test_unsafe_loads.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import unicode_literals, print_function 4 | import unittest 5 | import axon 6 | from axon.odict import OrderedDict 7 | 8 | class C(object): 9 | pass 10 | 11 | class D(object): 12 | pass 13 | 14 | class E(object): 15 | def __init__(self, a, b, c): 16 | self.a = a 17 | self.b = b 18 | self.c = c 19 | 20 | def instance_maker(cls): 21 | def make_instance(attrs, vals=None): 22 | inst = cls.__new__(cls) 23 | for name, value in attrs.items(): 24 | setattr(inst, name, value) 25 | return inst 26 | return make_instance 27 | 28 | def reducer_maker(cls): 29 | def type_reducer(o): 30 | attrs = [] 31 | for name in o.__dict__: 32 | if name.startswith('_'): 33 | continue 34 | attrs.append((axon.as_name(name), getattr(o, name))) 35 | 36 | return axon.node(axon.as_name(cls.__name__), attrs, None) 37 | return type_reducer 38 | 39 | 40 | axon.factory('C', instance_maker(C)) 41 | axon.factory('D', instance_maker(D)) 42 | axon.factory('E', instance_maker(E)) 43 | 44 | axon.reduce(C, reducer_maker(C)) 45 | axon.reduce(D, reducer_maker(D)) 46 | axon.reduce(E, reducer_maker(E)) 47 | 48 | class Base(object): 49 | # 50 | def __str__(self): 51 | return '%s: %r' % (self.__class__.__name__, self.__dict__) 52 | # 53 | __repr__ = __str__ 54 | 55 | class Graph(Base): 56 | def __init__(self, nodes, edges): 57 | self.nodes = list(nodes) if nodes else [] 58 | self.edges = list(edges) if edges else [] 59 | 60 | 61 | class Node(Base): 62 | def __init__(self, x, y): 63 | self.x = x 64 | self.y = y 65 | 66 | class Edge(Base): 67 | def __init__(self, p1, p2): 68 | self.p1 = p1 69 | self.p2 = p2 70 | 71 | 72 | @axon.factory('graph') 73 | def create_graph2(attrs, args): 74 | return Graph(**attrs) 75 | 76 | @axon.factory('node') 77 | def create_node2(attrs, args): 78 | return Node(*args) 79 | 80 | @axon.factory('edge') 81 | def create_edge(attrs, args): 82 | return Edge(*args) 83 | 84 | @axon.reduce(Graph) 85 | def reduce_graph(graph): 86 | return axon.node('graph', {'nodes':graph.nodes, 87 | 'edges':graph.edges}, None) 88 | 89 | @axon.reduce(Node) 90 | def reduce_node(node): 91 | return axon.node('node', None, [node.x, node.y]) 92 | 93 | @axon.reduce(Edge) 94 | def reduce_edge(edge): 95 | return axon.node('edge', None, [edge.p1, edge.p2]) 96 | 97 | 98 | class UnsafeLoadsTestCase(unittest.TestCase): 99 | 100 | def setUp(self): 101 | pass 102 | # 103 | def test_usafe_1(self): 104 | v = C() 105 | v.a = 1 106 | v.b = 2 107 | v.c = 3 108 | text = axon.dumps([v]) 109 | #display(text) 110 | v1 = axon.loads(text, mode='strict')[0] 111 | self.assertEqual(v.a, v1.a) 112 | self.assertEqual(v.b, v1.b) 113 | self.assertEqual(v.c, v1.c) 114 | # 115 | def test_usafe_2(self): 116 | v = C() 117 | v.a = 1 118 | v.b = 2 119 | v.c = 3 120 | w = D() 121 | w.a = 'a' 122 | w.b = [1,2] 123 | w.c = 2 124 | text = axon.dumps([v, w]) 125 | v1, w1 = axon.loads(text, mode='strict') 126 | self.assertEqual(v.a, v1.a) 127 | self.assertEqual(v.b, v1.b) 128 | self.assertEqual(v.c, v1.c) 129 | self.assertEqual(w.a, w1.a) 130 | self.assertEqual(w.b, w1.b) 131 | self.assertEqual(w.c, w1.c) 132 | # 133 | def test_usafe_3(self): 134 | v = E(1, 2, 3) 135 | text = axon.dumps([v]) 136 | v1 = axon.loads(text, mode='strict')[0] 137 | self.assertEqual(v.a, v1.a) 138 | self.assertEqual(v.b, v1.b) 139 | self.assertEqual(v.c, v1.c) 140 | # 141 | def test_usafe_4(self): 142 | v = C() 143 | v.x = 1 144 | v.y = lst = [] 145 | for i in range(3): 146 | w = D() 147 | w.z = i 148 | lst.append(w) 149 | text = axon.dumps([v]) 150 | #self.assertEqual(text, 'C{x:1 y:[D{z:0} D{z:1} D{z:2}]}') 151 | v1 = axon.loads(text, mode='strict')[0] 152 | self.assertEqual(v1.x, 1) 153 | self.assertEqual(len(v1.y), 3) 154 | self.assertEqual(all([type(z) is D for z in v1.y]), True) 155 | self.assertEqual(all([z.z==z1.z for z,z1 in zip(v1.y, lst)]), True) 156 | # 157 | def test_usafe_5(self): 158 | vs = [] 159 | v = C() 160 | v.x = 1 161 | v.y = lst = [] 162 | for i in range(3): 163 | w = D() 164 | w.z = i 165 | lst.append(w) 166 | vs.append(w) 167 | vs.append(v) 168 | text = axon.dumps(vs, crossref=1, pretty=1) 169 | # self.assertEqual(text, '''\ 170 | # &1 D: 171 | # z: 0 172 | # &2 D: 173 | # z: 1 174 | # &3 D: 175 | # z: 2 176 | # C: 177 | # x: 1 178 | # y: [*1 *2 *3]''') 179 | self.assertEqual(vs[-1].y[0], vs[0]) 180 | self.assertEqual(vs[-1].y[1], vs[1]) 181 | self.assertEqual(vs[-1].y[2], vs[2]) 182 | # 183 | # def test_usafe_6(self): 184 | # text = """\ 185 | # graph { 186 | # nodes: [ 187 | # &1 node { 188 | # 1 1} 189 | # &2 node { 190 | # 1 2} 191 | # &3 node { 192 | # 2 1} 193 | # &4 node { 194 | # 2 2}] 195 | # edges: [ 196 | # edge { 197 | # *1 198 | # *2} 199 | # edge { 200 | # *1 201 | # *3} 202 | # edge { 203 | # *2 204 | # *3} 205 | # edge { 206 | # *1 207 | # *4} 208 | # edge { 209 | # *3 210 | # *4}]} 211 | # """ 212 | # obs = axon.loads(text, mode='strict') 213 | # text2 = axon.dumps(obs, crossref=1, sorted=0) 214 | # obs2 = axon.loads(text2, mode='strict') 215 | # print(axon.dumps(obs2, crossref=1, sorted=0)) 216 | # self.assertEqual(obs2[0].nodes[0] is obs2[0].edges[0].p1, True) 217 | # self.assertEqual(obs2[0].nodes[1] is obs2[0].edges[0].p2, True) 218 | # self.assertEqual(obs2[0].nodes[2] is obs2[0].edges[1].p2, True) 219 | # self.assertEqual(obs2[0].nodes[2] is obs2[0].edges[2].p2, True) 220 | # self.assertEqual(obs2[0].nodes[2] is obs2[0].edges[4].p1, True) 221 | # self.assertEqual(obs2[0].nodes[3] is obs2[0].edges[3].p2, True) 222 | # self.assertEqual(obs2[0].nodes[3] is obs2[0].edges[4].p2, True) 223 | # 224 | 225 | 226 | 227 | def suite(): 228 | suite = unittest.TestSuite() 229 | suite.addTest(unittest.makeSuite(UnsafeLoadsTestCase)) 230 | return suite 231 | -------------------------------------------------------------------------------- /lib/axon/test/xml/simple.xml: -------------------------------------------------------------------------------- 1 | textобъектная нотацияtail 2 | -------------------------------------------------------------------------------- /lib/axon/types.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | # The MIT License (MIT) 4 | # 5 | # Copyright (c) <2011-2014> 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in 15 | # all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | # THE SOFTWARE. 24 | 25 | try: 26 | import builtins 27 | except ImportError: 28 | import __builtin__ as builtins 29 | 30 | import datetime 31 | 32 | try: 33 | from cdecimal import Decimal 34 | except: 35 | from decimal import Decimal 36 | 37 | try: 38 | unicode_type = builtins.unicode 39 | except AttributeError: 40 | unicode_type = builtins.str 41 | 42 | str_type = builtins.str 43 | 44 | try: 45 | long_type = builtins.long 46 | int_type = builtins.int 47 | except AttributeError: 48 | int_type = builtins.int 49 | long_type = builtins.int 50 | 51 | float_type = builtins.float 52 | bool_type = builtins.bool 53 | bytes_type = builtins.bytes 54 | bytearray_type = builtins.bytearray 55 | date_type = datetime.date 56 | time_type = datetime.time 57 | datetime_type = datetime.datetime 58 | decimal_type = Decimal 59 | none_type = type(None) 60 | -------------------------------------------------------------------------------- /lib/axon/utils.h: -------------------------------------------------------------------------------- 1 | #include "Python.h" 2 | 3 | #define CH_BETWEEN(x, a, b) (x >= a) && (x <= b) 4 | 5 | #if PY_MAJOR_VERSION == 3 6 | 7 | /*PyObject* PyFloat_FromString(PyObject*);*/ 8 | #define c_float_fromstring(text) (PyFloat_FromString((PyObject*)text)) 9 | 10 | #else 11 | 12 | /*PyObject* PyFloat_FromString(PyObject*, char **);*/ 13 | #define c_float_fromstring(text) (PyFloat_FromString((PyObject*)text, NULL)) 14 | 15 | #endif 16 | 17 | #if PY_MAJOR_VERSION == 3 18 | 19 | #define c_int_fromstring(text) PyLong_FromString(text, NULL, 10) 20 | 21 | #define c_int_tostring(ob) _PyLong_Format(ob, 10) 22 | 23 | #define c_int_fromlong(val) PyLong_FromLong(val) 24 | #define c_int_fromint(val) PyLong_FromLong((long)val) 25 | 26 | #define c_object_to_unicode(o) PyObject_Str(o) 27 | 28 | #else 29 | 30 | #define c_int_fromstring(text) PyInt_FromString(text, NULL, 10) 31 | 32 | #define c_int_fromlong(val) PyInt_FromLong(val) 33 | #define c_int_fromint(val) PyInt_FromLong((long)val) 34 | 35 | #define c_int_tostring(ob) PyLong_Check(ob)? _PyLong_Format(ob, 10, 0, 1) : _PyInt_Format((PyIntObject*)ob, 10, 1) 36 | 37 | #define c_object_to_unicode(o) PyObject_Unicode(o) 38 | 39 | #endif 40 | 41 | 42 | #if PY_VERSION_HEX >= 0x03030000 43 | 44 | #define c_unicode_substr(text, start, end) \ 45 | PyUnicode_FromKindAndData(PyUnicode_KIND(text), PyUnicode_1BYTE_DATA(text) + start*PyUnicode_KIND(text), end-start) 46 | 47 | #define c_unicode_length(text) PyUnicode_GET_LENGTH(text) 48 | #define c_bytes_length(text) PyBytes_GET_LENGTH(text) 49 | 50 | #else 51 | 52 | #define c_unicode_substr(text, start, end) \ 53 | PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(text)+start, end-start) 54 | 55 | #define c_unicode_length(text) PyUnicode_GET_SIZE(text) 56 | #define c_bytes_length(text) PyBytes_GET_SIZE(text) 57 | 58 | #endif 59 | 60 | #define c_dict_size(d) ((PyDictObject*)d)->ma_used 61 | 62 | #if PY_VERSION_HEX >= 0x03030000 63 | #define c_unicode_char(u, i) PyUnicode_READ(PyUnicode_KIND(u), PyUnicode_DATA(u), (i)) 64 | #define c_unicode_write_char(u, i, c) PyUnicode_WRITE(PyUnicode_KIND(u), PyUnicode_DATA(u), (i), (c)) 65 | #else 66 | #define c_unicode_char(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[(i)])) 67 | #define c_unicode_write_char(u, i, c) (PyUnicode_AS_UNICODE(u)[(i)] = (Py_UCS4)c) 68 | #endif 69 | 70 | #define current_char(self) c_unicode_char(self->line, self->pos) 71 | #define skip_char(self) (self->pos)++ 72 | #define next_char(self) c_unicode_char(self->line, ++(self->pos)) 73 | 74 | #define get_chunk(self, pos0) c_unicode_substr(self->line, pos0, self->pos) 75 | 76 | #define Py_SET_SIZE(o, n) Py_SIZE(o) = n 77 | 78 | /* 79 | static CYTHON_INLINE int pylist_append(PyObject* list, PyObject* x) { 80 | PyListObject* L = (PyListObject*) list; 81 | Py_ssize_t len = Py_SIZE(list); 82 | if (L->allocated > len) { 83 | Py_INCREF(x); 84 | PyList_SET_ITEM(list, len, x); 85 | Py_SIZE(list) = len+1; 86 | return 0; 87 | } 88 | return PyList_Append(list, x); 89 | } 90 | */ -------------------------------------------------------------------------------- /lib/axon/utils.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | # The MIT License (MIT) 4 | # 5 | # Copyright (c) <2011-2014> 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in 15 | # all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | # THE SOFTWARE. 24 | 25 | from axon._objects import defname, factory, type_factory 26 | from axon._objects import convert, reset_factory, reset_type_factory 27 | from axon._objects import undef, as_unicode, as_list, as_dict, as_tuple, as_name 28 | from axon._dumper import reduce, dump_as_str 29 | 30 | 31 | import axon 32 | import xml.etree.ElementTree as etree 33 | import json 34 | 35 | @reduce(etree.Element) 36 | def reduce_ElementTree(e): 37 | attrs = {axon.as_unicode(name):val for name,val in e.attrib.items()} 38 | if e.text: 39 | vals = [e.text] 40 | else: 41 | vals = [] 42 | for child in e.getchildren(): 43 | vals.append(child) 44 | if child.tail: 45 | vals.append(child.tail) 46 | child.tail = None 47 | if len(attrs) == 0: 48 | attrs = None 49 | if len(vals) == 0: 50 | vals = None 51 | return axon.node(axon.as_unicode(e.tag), attrs, vals) 52 | 53 | del reduce_ElementTree 54 | 55 | 56 | def xml2axon(from_, to_=None, pretty=1, braces=0): 57 | ''' 58 | Convert from `XML` to `AXON`. 59 | 60 | :from: 61 | The path of input file with `XML` or `XML` string. 62 | 63 | :to: 64 | The path of output file with `XML`` (default is `None`). 65 | If `to` is valid path then result of convertion to `AXON` will write to the file. 66 | 67 | :result: 68 | If `to` is `None` then return string with `AXON`, else return `None`. 69 | ''' 70 | _text = from_.lstrip() 71 | if _text.startswith('<'): 72 | tree = etree.fromstring(from_) 73 | else: 74 | tree = etree.parse(from_) 75 | root = tree._root 76 | 77 | if to_ is None: 78 | return axon.dumps([root], pretty=pretty, braces=braces) 79 | else: 80 | axon.dump(to_, [root], pretty=pretty, braces=braces) 81 | 82 | def json2axon(from_, to_=None, pretty=1, braces=1): 83 | ''' 84 | Convert from `JSON` to `AXON`. 85 | 86 | :from: 87 | The path of input file with `JSON` or `JSON` string. 88 | 89 | :to: 90 | The path of output file with `JSON` (default is `None`). 91 | If `to` is valid path then result of convertion to `AXON` will write to the file. 92 | 93 | :result: 94 | If `to` is `None` then return string with `AXON`, else return `None`. 95 | ''' 96 | text = from_.lstrip() 97 | if text.startswith('[') or text.startswith('{'): 98 | val = json.loads(from_) 99 | else: 100 | val = json.load(from_) 101 | 102 | if to_ is None: 103 | return axon.dumps([val], pretty=pretty, braces=braces) 104 | else: 105 | axon.dump(to_, [val], pretty=pretty, braces=braces) 106 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pyaxon 2 | Cython>=19.1 3 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | # The MIT License (MIT) 4 | # 5 | # Copyright (c) <2011-2016> 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in 15 | # all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | # THE SOFTWARE. 24 | 25 | from io import open 26 | 27 | #from distutils.core import setup 28 | from setuptools import setup 29 | 30 | from distutils.command.build_py import build_py as _build_py 31 | 32 | class build_py(_build_py): 33 | def find_package_modules(self, package, package_dir): 34 | modules = _build_py.find_package_modules(self, package, package_dir) 35 | py_ext_modules = [] 36 | for ext in self.distribution.ext_modules: 37 | for src in ext.sources: 38 | if src.endswith('.py'): 39 | py_ext_modules.append(src) 40 | if py_ext_modules: 41 | modules = [m for m in modules if m[2] not in py_ext_modules] 42 | return modules 43 | 44 | use_cython = 1 45 | 46 | if use_cython: 47 | from Cython.Distutils import Extension, build_ext 48 | from Cython.Compiler import Options 49 | Options.fast_fail = True 50 | #Options.emit_code_comments = False 51 | 52 | 53 | ext_modules = [ 54 | Extension( 55 | "axon._objects", 56 | ["lib/axon/_objects.py"], 57 | #extra_compile_args=['-Wno-unused-function', '-Wno-unreachable-code'], 58 | ), 59 | Extension( 60 | "axon._loader", 61 | ["lib/axon/_loader.py"], 62 | #extra_compile_args=['-Wno-unused-function', '-Wno-unreachable-code'], 63 | ), 64 | Extension( 65 | "axon._dumper", 66 | ["lib/axon/_dumper.py"], 67 | #extra_compile_args=['-Wno-unused-function', '-Wno-unreachable-code'], 68 | ), 69 | Extension( 70 | "axon.odict", 71 | ["lib/axon/odict.pyx"], 72 | #extra_compile_args=['-Wno-unused-function', '-Wno-unreachable-code'], 73 | ), 74 | ] 75 | else: 76 | from distutils.command.build_ext import build_ext 77 | from distutils.extension import Extension 78 | ext_modules = [ 79 | Extension( 80 | "axon._objects", 81 | sources=["lib/axon/_objects.c"], 82 | #extra_compile_args=['-Wno-unused-function', '-Wno-unreachable-code'], 83 | ), 84 | Extension( 85 | "axon._loader", 86 | sources=["lib/axon/_loader.c"], 87 | #extra_compile_args=['-Wno-unused-function', '-Wno-unreachable-code'], 88 | ), 89 | Extension( 90 | "axon._dumper", 91 | sources=["lib/axon/_dumper.c"], 92 | #extra_compile_args=['-Wno-unused-function', '-Wno-unreachable-code'], 93 | ), 94 | Extension( 95 | "axon.odict", 96 | ["lib/axon/odict.c"], 97 | #extra_compile_args=['-Wno-unused-function', '-Wno-unreachable-code'], 98 | ), 99 | ] 100 | 101 | long_description = open('README.rst', encoding='utf-8').read() 102 | 103 | 104 | setup( 105 | name = 'pyaxon', 106 | version = '0.9', 107 | description = 'Python library for AXON', 108 | author = 'Zaur Shibzukhov', 109 | author_email = 'szport@gmail.com', 110 | #maintainer = 'Zaur Shibzukhov', 111 | #maintainer_email = 'szport@gmail.com', 112 | license = "MIT License", 113 | cmdclass = {'build_ext': build_ext, 'build_py': build_py}, 114 | ext_modules = ext_modules, 115 | package_dir = {'': 'lib'}, 116 | packages = ['axon', 'axon.test', 'axon.test.benchmark'], 117 | scripts = ['bin/xml2axon', 'bin/json2axon'], 118 | url = 'http://intellimath.bitbucket.org/axon', 119 | download_url = 'https://bitbucket.org/intellimath/pyaxon', 120 | long_description = long_description, 121 | platforms = 'Linux, Mac OS X, Windows', 122 | keywords = ['Object Notation', 'Serialization', 'Configuration'], 123 | classifiers = [ 124 | 'Development Status :: 4 - Beta', 125 | 'Intended Audience :: Developers', 126 | 'Intended Audience :: Information Technology', 127 | 'License :: OSI Approved :: MIT License', 128 | 'Programming Language :: Python :: 2', 129 | 'Programming Language :: Python :: 2.7', 130 | 'Programming Language :: Python :: 3', 131 | 'Programming Language :: Python :: 3.2', 132 | 'Programming Language :: Python :: 3.3', 133 | 'Programming Language :: Python :: 3.4', 134 | 'Programming Language :: Python :: 3.5', 135 | 'Operating System :: OS Independent', 136 | 'Topic :: Software Development :: Libraries :: Python Modules' 137 | ], 138 | ) 139 | -------------------------------------------------------------------------------- /test_all.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | # The MIT License (MIT) 4 | # 5 | # Copyright (c) <2011-2016> 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in 15 | # all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | # THE SOFTWARE. 24 | 25 | from axon.test import * 26 | 27 | test_all() 28 | 29 | -------------------------------------------------------------------------------- /update_git: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | hg push git+ssh://git@github.com/intellimath/pyaxon.git 3 | --------------------------------------------------------------------------------