This report is out-of-date.
The state of things has changed dramatically, for the better, since I first wrote this in early 2008. Although my test cases are still quite useful, any information regarding specific python packages is likely to be inaccurate. I am leaving these pages here primarily for historic interest.
Strings
The set of tests on this page is primarily concerned with strings of ASCII characters only. See the Unicode tests page for comparisons involving non-ASCII characters.
Notation: Because some of the examples on this page contain
unprintable or invisible characters, a special notation delimited by
guillemets, as in , is adopted
to represent a single occurance of a Unicode character, in this case
U+007B.
Converting Python strings to JSON
These tests exercise some of the basic character handling. For the purposes of these tests, the following Python defintions will be used:
import UserString UsrStr = UserString.UserString( 'Hello' )
Control characters: Note that JSON requires that all control characters
U+0000 through
U+001F
be escaped, either with \uxxxx or a predefined \
escape code.
The python-json module though incorrectly outputs most of the
control characters literally without any escaping. Similarly,
simplejson does not escape
U+001A through
U+001F
as required.
DEL: On the other hand, although JSON permits the delete character U+007F to be escaped, it does not require it. The demjson and python-json modules choose to output U+007F literally without escaping. The simplejson module escapes it by default, unless it is explicitly told not to (see the Unicode discussion on the next page).
| Test# | from Python | to JSON | demjson | jsonlib | python-cjson | python-json | simplejson |
|---|---|---|---|---|---|---|---|
| 1–1 | [""] | [""] | yes | yes | yes | yes | yes |
| 1–2 | ["Hello"] | ["Hello"] | yes | yes | yes | yes | yes |
| 1–3 | [ UsrStr ] | ["Hello"] | yes | no: error | no: error | no: error | no: error |
| 1–4 | ["\x00"] | ["\u0000"] | yes | yes | yes | no, outputs:["«U+0000»"] |
yes |
| 1–5 | ["A\x00Z"] | ["A\u0000Z"] | yes | yes | yes | no, outputs:["A«U+0000»Z"] |
yes |
| 1–6 | ["\x08"] | ["\b"] | yes | yes | yes | yes | yes |
| 1–7 | ["\x09"] | ["\t"] | yes | yes | yes | yes | yes |
| 1–8 | ["\x0a"] | ["\n"] | yes | yes | yes | yes | yes |
| 1–9 | ["\x0b"] | ["\u000b"] | yes | yes | yes | no, outputs:["«U+000B»"] |
yes |
| 1–10 | ["\x0c"] | ["\f"] | yes | yes | yes | yes | yes |
| 1–11 | ["\x0d"] | ["\r"] | yes | yes | yes | yes | yes |
| 1–12 | ["\x1a"] | ["\u001a"] | yes | yes | yes | no, outputs:["«U+001A»"] |
no, outputs:["«U+001A»"] |
| 1–13 | ["\x1f"] | ["\u001f"] | yes | yes | yes | no, outputs:["«U+001F»"] |
no, outputs:["«U+001F»"] |
| 1–14 | ["\x22"] | ["\""] | yes | yes | yes | yes | yes |
| 1–15 | ["\x27"] | ["'"] | yes | yes | yes | yes | yes |
| 1–16 | ["\x2f"] | ["/"] | yes | yes, outputs:["\/"] |
yes | yes | yes, outputs:["\/"] |
| 1–17 | ["\x5c"] | ["\\"] | yes | yes | yes | yes | yes |
| 1–18 | ["\x7f"] | ["«U+007F»"] | yes | yes, outputs:["\u007f"] |
yes, outputs:["\u007f"] |
yes | yes, outputs:["\u007f"] |
Converting JSON strings to Python
| Test# | from JSON | to Python | demjson | jsonlib | python-cjson | python-json | simplejson |
|---|---|---|---|---|---|---|---|
| 2–1 | [""] | [''] | yes | yes | yes | yes | yes |
| 2–2 | ["Hello"] | ['Hello'] | yes | yes | yes | yes | yes |
| 2–3 | ["\b"] | ['\x08'] | yes | yes | yes | yes | yes |
| 2–4 | ["\f"] | ['\f'] | yes | yes | yes | yes | yes |
| 2–5 | ["\n"] | ['\n'] | yes | yes | yes | yes | yes |
| 2–6 | ["\r"] | ['\r'] | yes | yes | yes | yes | yes |
| 2–7 | ["\t"] | ['\t'] | yes | yes | yes | yes | yes |
| 2–8 | ["\\"] | ['\\'] | yes | yes | yes | yes | yes |
| 2–9 | ["\/"] | ['/'] | yes | yes | no, outputs:['\\\\/'] |
yes | yes |
| 2–10 | ["\""] | ['"'] | yes | yes | yes | yes | yes |
Dealing with invalid JSON strings
The JSON string syntax is much more strict than that of JavaScript. The following tests include strings which are not legal JSON, yet are valid JavaScript. A conforming parser should either raise an error, or should produce the same string value as that of JavaScript.
| Test# | from JavaScript | demjson/strict | demjson/loose | jsonlib | python-cjson | python-json | simplejson |
|---|---|---|---|---|---|---|---|
| 3–1 | ['Hello'] | yes: error | almost, outputs:['Hello'] |
yes: error | yes: error | yes: error | yes: error |
| 3–2 | ["\v"] | yes: error | almost, outputs:['\x0b'] |
yes: error | no, outputs:['\\v'] |
yes: error | yes: error |
| 3–3 | ["\0"] | yes: error | almost, outputs:['\x00'] |
yes: error | no, outputs:['\\0'] |
yes: error | yes: error |
| 3–4 | ["\0123"] | yes: error | almost, outputs:['\n3'] |
yes: error | no, outputs:['\\0123'] |
yes: error | yes: error |
| 3–5 | ["\x9A"] | yes: error | almost, outputs:['\x9a'] |
yes: error | no, outputs:['\\x9A'] |
yes: error | yes: error |
| 3–6 | ["\e"] | yes: error | almost, outputs:['e'] |
yes: error | no, outputs:['\\e'] |
yes: error | yes: error |
| 3–7 | ["\zulu"] | yes: error | almost, outputs:['zulu'] |
yes: error | no, outputs:['\\zulu'] |
yes: error | yes: error |
The following strings are neither valid JSON nor valid JavaScript, and so any compliant parser should reject them with an error.
| Test# | Illegal input | demjson/strict | demjson/loose | jsonlib | python-cjson | python-json | simplejson |
|---|---|---|---|---|---|---|---|
| 4–1 | ["A Z"] |
yes: error | no, outputs:[u'A
Z'] |
no, outputs:['A\nZ'] |
no, outputs:['A\nZ'] |
no, outputs:['A\nZ'] |
no, outputs:['A\nZ'] |
| 4–2 | ["A«U+0000»Z"] | yes: error | no, outputs:['A\x00Z'] |
yes: error | no, outputs:['A\x00Z'] |
no, outputs:['A\x00Z'] |
no, outputs:['A\x00Z'] |
| 4–3 | ["A«U+001F»Z"] | yes: error | no, outputs:['A\x1fZ'] |
no, outputs:[u'A\x1fZ'] |
no, outputs:['A\x1fZ'] |
no, outputs:['A\x1fZ'] |
no, outputs:['A\x1fZ'] |

