Hello community,

here is the log from the commit of package python-pytoml for openSUSE:Factory 
checked in at 2018-12-12 17:28:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pytoml (Old)
 and      /work/SRC/openSUSE:Factory/.python-pytoml.new.28833 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pytoml"

Wed Dec 12 17:28:24 2018 rev:2 rq:655995 version:0.1.20

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pytoml/python-pytoml.changes      
2018-05-28 08:07:54.501965635 +0200
+++ /work/SRC/openSUSE:Factory/.python-pytoml.new.28833/python-pytoml.changes   
2018-12-12 17:28:27.094879398 +0100
@@ -1,0 +2,9 @@
+Fri Dec  7 10:20:44 UTC 2018 - Tomáš Chvátal <tchva...@suse.com>
+
+- Fix fdupes call
+- Update to 0.1.20:
+  * many small bugfixes around
+  * Include license file
+- Update the test tgz tarball from the git
+
+-------------------------------------------------------------------

Old:
----
  LICENSE
  fa9501a1.tar.gz
  pytoml-0.1.14.tar.gz

New:
----
  b212790.tar.gz
  pytoml-0.1.20.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-pytoml.spec ++++++
--- /var/tmp/diff_new_pack.oGza3o/_old  2018-12-12 17:28:27.846878445 +0100
+++ /var/tmp/diff_new_pack.oGza3o/_new  2018-12-12 17:28:27.846878445 +0100
@@ -12,13 +12,13 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-pytoml
-Version:        0.1.14
+Version:        0.1.20
 Release:        0
 Summary:        TOML-0.4.0 parser/writer for Python
 License:        MIT
@@ -26,10 +26,7 @@
 URL:            https://github.com/avakar/pytoml
 Source0:        
https://files.pythonhosted.org/packages/source/p/pytoml/pytoml-%{version}.tar.gz
 # toml-test for tests from author's fork with specific commit
-Source1:        https://github.com/avakar/toml-test/archive/fa9501a1.tar.gz
-# Next release should contain it in std tgz
-Source2:        https://raw.githubusercontent.com/avakar/pytoml/master/LICENSE
-BuildRequires:  %{python_module base}
+Source1:        https://github.com/avakar/toml-test/archive/b212790.tar.gz
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
@@ -39,29 +36,26 @@
 
 %description
 A specs-conforming and strict parser and writer for TOML files.
-The library currently supports version 0.4.0 of the specs and
-runs with Python 2.6+ and 3.3+.
+The library currently supports version 0.4.0 of the specs.
 
 %prep
 %setup -q -n pytoml-%{version}
-cp -a %{SOURCE2} LICENSE
 tar -C test -xzf%{SOURCE1}
 cd test 
-mv toml-test-fa9501a192b7c46b82059caddaef978e3de883dc toml-test
-
+mv toml-test-b212790a6b7367489f389411bda009e5ff765f20 toml-test
 
 %build
 %python_build
 
 %install
 %python_install
-%fdupes %{buildroot}%{_prefix}
+%python_expand %fdupes %{buildroot}%{$python_sitelib}
 
 %check
-%python_expand export PYTHONPATH=%{buildroot}%{python_sitelib}; python 
test/test.py 
+export PYTHONDONTWRITEBYTECODE=1
+%python_expand PYTHONPATH=%{buildroot}%{python_sitelib} $python test/test.py
 
 %files %{python_files}
-%defattr(-,root,root)
 %license LICENSE
 %{python_sitelib}/pytoml/
 %{python_sitelib}/pytoml-%{version}-py%{py_ver}.egg-info/

++++++ fa9501a1.tar.gz -> b212790.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/COPYING 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/COPYING
--- old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/COPYING      
2016-05-19 17:36:31.000000000 +0200
+++ new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/COPYING      
2018-10-28 15:18:15.000000000 +0100
@@ -1,14 +1,21 @@
-            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
-                    Version 2, December 2004
+The MIT License (MIT)
 
- Copyright (C) 2004 Sam Hocevar <s...@hocevar.net>
+Copyright (c) 2018 TOML authors
 
- Everyone is permitted to copy and distribute verbatim or modified
- copies of this license document, and changing it is allowed as long
- as the name is changed.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
 
-            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. You just DO WHAT THE FUCK YOU WANT TO.
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
 
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/README.md 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/README.md
--- old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/README.md    
2016-05-19 17:36:31.000000000 +0200
+++ new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/README.md    
2018-10-28 15:18:15.000000000 +0100
@@ -14,10 +14,10 @@
 invalid-encoder directory. The JSON given to a TOML encoder is in the same 
 format as the JSON that a TOML decoder should output.
 
-Version: v0.2.0 (in sync with TOML)
+Version: v0.4.0 (in sync with TOML)
 
 Compatible with TOML version
-[v0.2.0](https://github.com/mojombo/toml/blob/master/versions/toml-v0.2.0.md)
+[v0.4.0](https://github.com/mojombo/toml/blob/master/versions/toml-v0.4.0.md)
 
 Dependencies: [Go](http://golang.org).
 
@@ -101,6 +101,7 @@
 Empty hashes correspond to empty JSON objects (i.e., `{}`) and empty arrays 
 correspond to empty JSON arrays (i.e., `[]`).
 
+Datetime should be encoded following RFC 3339.
 
 ### Example JSON encoding
 
@@ -210,8 +211,12 @@
 * C++ (@skystrife) - https://github.com/skystrife/cpptoml
 * Go (@thompelletier) - https://github.com/pelletier/go-toml
 * Go w/ Reflection (@BurntSushi) - 
https://github.com/BurntSushi/toml/tree/master/cmd/toml-test-decoder
+* LabVIEW (@dbtaylor) - https://github.com/erdosmiller/lv-toml
+* Node.js/Browser (@redhotvengeance) - https://github.com/redhotvengeance/topl
+* PHP (@leonelquinteros) - https://github.com/leonelquinteros/php-toml
 * Python (@uiri) - https://github.com/uiri/toml
 * Python (@marksteve) - https://github.com/marksteve/toml-ply
+* Racket (@greghendershott) - https://github.com/greghendershott/toml
 * Ruby (@jm, @cespare) - https://gist.github.com/cespare/5052442
 * Rust (@mneumann) - https://github.com/mneumann/rust-toml
 
@@ -229,4 +234,4 @@
 * Julia (@pygy) - https://github.com/pygy/TOML.jl
 * PHP (@yosymfony) - https://github.com/yosymfony/toml
 * Python (@f03lipe) - https://github.com/f03lipe/toml-python
-
+* JavaScript (@iarna) - https://github.com/iarna/iarna-toml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/json.go 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/json.go
--- old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/json.go      
2016-05-19 17:36:31.000000000 +0200
+++ new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/json.go      
2018-10-28 15:18:15.000000000 +0100
@@ -2,6 +2,7 @@
 
 import (
        "strconv"
+       "time"
 )
 
 // compareJson consumes the recursive structure of both `expected` and `test`
@@ -114,29 +115,38 @@
        // equality.
        if etype == "array" {
                return r.cmpJsonArrays(e["value"], t["value"])
-       }
-
-       // Floats need special attention too. Not every language can
-       // represent the same floats, and sometimes the string version of
-       // a float can be wonky with extra zeroes and what not.
-       if etype == "float" {
-               enum, ok := e["value"].(string)
+       } else {
+               // Atomic values are always strings
+               evalue, ok := e["value"].(string)
                if !ok {
-                       return r.failedf("BUG in test case. 'value' should be a 
string, "+
-                               "but it is a %T.", e["value"])
+                       return r.failedf("BUG in test case. 'value' "+
+                               "should be a string, but it is a %T.",
+                               e["value"])
                }
-               tnum, ok := t["value"].(string)
+               tvalue, ok := t["value"].(string)
                if !ok {
-                       return r.failedf("Malformed parser output. 'value' 
should be a "+
-                               "string but it is a %T.", t["value"])
+                       return r.failedf("Malformed parser output. 'value' "+
+                               "should be a string but it is a %T.",
+                               t["value"])
+               }
+
+               // Excepting floats and datetimes, other values can be
+               // compared as strings.
+               switch etype {
+               case "float":
+                       return r.cmpFloats(evalue, tvalue);
+               case "datetime":
+                       return r.cmpAsDatetimes(evalue, tvalue);
+               default:
+                       return r.cmpAsStrings(evalue, tvalue);
                }
-               return r.cmpFloats(enum, tnum)
        }
+}
 
-       // Otherwise, we can do simple string equality.
-       if e["value"] != t["value"] {
+func (r result) cmpAsStrings(e, t string) result {
+       if e != t {
                return r.failedf("Values for key '%s' don't match. Expected a "+
-                       "value of '%s' but got '%s'.", r.key, e["value"], 
t["value"])
+                       "value of '%s' but got '%s'.", r.key, e, t)
        }
        return r
 }
@@ -144,19 +154,40 @@
 func (r result) cmpFloats(e, t string) result {
        ef, err := strconv.ParseFloat(e, 64)
        if err != nil {
-               return r.failedf("BUG in test case. Could not read '%s' as a 
float "+
-                       "value for key '%s'.", e, r.key)
+               return r.failedf("BUG in test case. Could not read '%s' as a "+
+                       "float value for key '%s'.", e, r.key)
        }
 
        tf, err := strconv.ParseFloat(t, 64)
        if err != nil {
-               return r.failedf("Malformed parser output. Could not read '%s' 
as "+
-                       "a float value for key '%s'.", t, r.key)
+               return r.failedf("Malformed parser output. Could not read '%s' 
"+
+                       "as a float value for key '%s'.", t, r.key)
        }
        if ef != tf {
                return r.failedf("Values for key '%s' don't match. Expected a "+
                        "value of '%v' but got '%v'.", r.key, ef, tf)
        }
+       return r
+}
+
+func (r result) cmpAsDatetimes(e, t string) result {
+       var err error
+
+       ef, err := time.Parse(time.RFC3339Nano, e)
+       if err != nil {
+               return r.failedf("BUG in test case. Could not read '%s' as a "+
+                       "datetime value for key '%s'.", e, r.key)
+       }
+
+       tf, err := time.Parse(time.RFC3339Nano, t)
+       if err != nil {
+               return r.failedf("Malformed parser output. Could not read '%s' 
"+
+                       "as datetime value for key '%s'.", t, r.key)
+       }
+       if !ef.Equal(tf) {
+               return r.failedf("Values for key '%s' don't match. Expected a "+
+                       "value of '%v' but got '%v'.", r.key, ef, tf)
+       }
        return r
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/main.go 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/main.go
--- old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/main.go      
2016-05-19 17:36:31.000000000 +0200
+++ new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/main.go      
2018-10-28 15:18:15.000000000 +0100
@@ -68,8 +68,8 @@
                path.Base(os.Args[0]))
        log.Println(`
 parser-cmd should be a program that accepts TOML data on stdin until EOF,
-and outputs the corresponding JSON encoding on stdout. Please see 'README.md' 
-for details on how to satisfy the interface expected by 'toml-test' with your 
+and outputs the corresponding JSON encoding on stdout. Please see 'README.md'
+for details on how to satisfy the interface expected by 'toml-test' with your
 own parser.
 
 The 'testdir' directory should have two sub-directories: 'invalid' and 'valid'.
@@ -77,7 +77,7 @@
 The 'invalid' directory should contain 'toml' files,
 where test names are the file names not including the '.toml' suffix.
 
-The 'valid' directory should contian 'toml' files and a 'json' file for each
+The 'valid' directory should contain 'toml' files and a 'json' file for each
 'toml' file, that contains the expected output of 'parser-cmd'. Test names
 are the file names not including the '.toml' or '.json' suffix.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/.gitattributes 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/.gitattributes
--- old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/.gitattributes 
1970-01-01 01:00:00.000000000 +0100
+++ new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/.gitattributes 
2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1 @@
+*.toml  -text
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/invalid/datetime-malformed-no-z.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/invalid/datetime-malformed-no-z.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/invalid/datetime-malformed-no-z.toml
   2016-05-19 17:36:31.000000000 +0200
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/invalid/datetime-malformed-no-z.toml
   1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-no-z = 1987-07-05T17:45:00
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/invalid/inline-table-linebreak.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/invalid/inline-table-linebreak.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/invalid/inline-table-linebreak.toml
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/invalid/inline-table-linebreak.toml
    2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,2 @@
+simple = { a = 1 
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/invalid/key-after-array.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/invalid/key-after-array.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/invalid/key-after-array.toml
   1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/invalid/key-after-array.toml
   2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1 @@
+[[agencies]] owner = "S Cjelli"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/invalid/multi-line-inline-table.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/invalid/multi-line-inline-table.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/invalid/multi-line-inline-table.toml
   1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/invalid/multi-line-inline-table.toml
   2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,4 @@
+json_like = {
+          first = "Tom",
+          last = "Preston-Werner"
+}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/invalid/string-bad-codepoint.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/invalid/string-bad-codepoint.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/invalid/string-bad-codepoint.toml
      1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/invalid/string-bad-codepoint.toml
      2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1 @@
+invalid-codepoint = "This string contains a non scalar unicode codepoint 
\uD801"
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/invalid/string-bad-slash-escape.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/invalid/string-bad-slash-escape.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/invalid/string-bad-slash-escape.toml
   1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/invalid/string-bad-slash-escape.toml
   2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1 @@
+invalid-escape = "This string has a bad \/ escape character."
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/array-of-array-of-dict.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/array-of-array-of-dict.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/array-of-array-of-dict.json
      1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/array-of-array-of-dict.json
      2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,10 @@
+{
+    "a": {
+        "type": "array",
+        "value": [
+            [
+                {}
+            ]
+        ]
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/array-of-array-of-dict.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/array-of-array-of-dict.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/array-of-array-of-dict.toml
      1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/array-of-array-of-dict.toml
      2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1 @@
+a = [[{}]]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/array-string-quote-comma-2.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/array-string-quote-comma-2.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/array-string-quote-comma-2.json
  1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/array-string-quote-comma-2.json
  2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1 @@
+{"title": {"type": "array", "value": [{"type": "string", "value": " \", "}]}}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/array-string-quote-comma-2.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/array-string-quote-comma-2.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/array-string-quote-comma-2.toml
  1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/array-string-quote-comma-2.toml
  2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1 @@
+title = [ " \", ",]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/array-string-quote-comma.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/array-string-quote-comma.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/array-string-quote-comma.json
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/array-string-quote-comma.json
    2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,9 @@
+{
+    "title": {
+        "type": "array",
+        "value": [
+            {"type": "string", "value": "Client: \"XXXX\", Job: XXXX"},
+            {"type": "string", "value": "Code: XXXX"}
+        ]
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/array-string-quote-comma.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/array-string-quote-comma.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/array-string-quote-comma.toml
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/array-string-quote-comma.toml
    2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,4 @@
+title = [
+"Client: \"XXXX\", Job: XXXX",
+"Code: XXXX"
+]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/array-string-with-comma.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/array-string-with-comma.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/array-string-with-comma.json
     1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/array-string-with-comma.json
     2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,9 @@
+{
+    "title": {
+        "type": "array",
+        "value": [
+            {"type": "string", "value": "Client: XXXX, Job: XXXX"},
+            {"type": "string", "value": "Code: XXXX"}
+        ]
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/array-string-with-comma.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/array-string-with-comma.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/array-string-with-comma.toml
     1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/array-string-with-comma.toml
     2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,4 @@
+title = [
+"Client: XXXX, Job: XXXX",
+"Code: XXXX"
+]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/array-table-array-string-backslash.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/array-table-array-string-backslash.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/array-table-array-string-backslash.json
  1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/array-table-array-string-backslash.json
  2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,7 @@
+{
+  "foo": [
+    {
+        "bar": {"type": "string", "value": "\"{{baz}}\"" }
+    }
+  ]
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/array-table-array-string-backslash.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/array-table-array-string-backslash.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/array-table-array-string-backslash.toml
  1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/array-table-array-string-backslash.toml
  2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1 @@
+foo = [ { bar="\"{{baz}}\""} ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/arrays.json 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/arrays.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/arrays.json  
    2016-05-19 17:36:31.000000000 +0200
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/arrays.json  
    2018-10-28 15:18:15.000000000 +0100
@@ -30,5 +30,12 @@
             {"type": "datetime", "value": "1979-05-27T07:32:00Z"},
             {"type": "datetime", "value": "2006-06-01T11:00:00Z"}
         ]
+    },
+    "comments": {
+        "type": "array",
+        "value": [
+            {"type": "integer", "value": "1"},
+            {"type": "integer", "value": "2"}
+        ]
     }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/arrays.toml 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/arrays.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/arrays.toml  
    2016-05-19 17:36:31.000000000 +0200
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/arrays.toml  
    2018-10-28 15:18:15.000000000 +0100
@@ -6,3 +6,7 @@
   1979-05-27T07:32:00Z,
   2006-06-01T11:00:00Z,
 ]
+comments = [
+         1,
+         2, #this is ok
+]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/datetime-timezone.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/datetime-timezone.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/datetime-timezone.json
   1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/datetime-timezone.json
   2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,3 @@
+{
+    "bestdayever": {"type": "datetime", "value": "2017-06-06T12:34:56-05:00"}
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/datetime-timezone.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/datetime-timezone.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/datetime-timezone.toml
   1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/datetime-timezone.toml
   2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1 @@
+bestdayever = 2017-06-06T12:34:56-05:00
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/datetime.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/datetime.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/datetime.json
    2016-05-19 17:36:31.000000000 +0200
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/datetime.json
    2018-10-28 15:18:15.000000000 +0100
@@ -1,3 +1,5 @@
 {
-    "bestdayever": {"type": "datetime", "value": "1987-07-05T17:45:00Z"}
+    "bestdayever": {"type": "datetime", "value": "1987-07-05T17:45:00Z"},
+    "numoffset": {"type": "datetime", "value": "1977-06-28T12:32:00Z"},
+    "milliseconds": {"type": "datetime", "value": 
"1977-12-21T03:32:00.555+00:00"}
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/datetime.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/datetime.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/datetime.toml
    2016-05-19 17:36:31.000000000 +0200
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/datetime.toml
    2018-10-28 15:18:15.000000000 +0100
@@ -1 +1,3 @@
 bestdayever = 1987-07-05T17:45:00Z
+numoffset = 1977-06-28T07:32:00-05:00
+milliseconds = 1977-12-21T10:32:00.555+07:00
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/double-quote-escape.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/double-quote-escape.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/double-quote-escape.json
 1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/double-quote-escape.json
 2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,6 @@
+{
+  "test": {
+    "type": "string",
+    "value": "\"one\""
+  } 
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/double-quote-escape.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/double-quote-escape.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/double-quote-escape.toml
 1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/double-quote-escape.toml
 2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1 @@
+test = "\"one\""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/escaped-escape.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/escaped-escape.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/escaped-escape.json
      1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/escaped-escape.json
      2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,3 @@
+{
+    "answer": {"type": "string", "value": "\\x64"}
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/escaped-escape.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/escaped-escape.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/escaped-escape.toml
      1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/escaped-escape.toml
      2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1 @@
+answer = "\\x64"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/exponent-part-float.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/exponent-part-float.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/exponent-part-float.json
 1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/exponent-part-float.json
 2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,6 @@
+{
+    "million": {"type": "float", "value": "1000000"},
+    "minustenth": {"type": "float", "value": "-0.1"},
+    "beast": {"type": "float", "value": "666"}
+}
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/exponent-part-float.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/exponent-part-float.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/exponent-part-float.toml
 1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/exponent-part-float.toml
 2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,3 @@
+million = 1e6
+minustenth = -1E-1
+beast = 6.66E2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/inline-table-array.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/inline-table-array.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/inline-table-array.json
  1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/inline-table-array.json
  2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,16 @@
+{
+    "people": [
+        {
+            "first_name": {"type": "string", "value": "Bruce"},
+            "last_name": {"type": "string", "value": "Springsteen"}
+        },
+        {
+            "first_name": {"type": "string", "value": "Eric"},
+            "last_name": {"type": "string", "value": "Clapton"}
+        },
+        {
+            "first_name": {"type": "string", "value": "Bob"},
+            "last_name": {"type": "string", "value": "Seger"}
+        }
+    ]
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/inline-table-array.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/inline-table-array.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/inline-table-array.toml
  1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/inline-table-array.toml
  2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,3 @@
+people = [{first_name = "Bruce", last_name = "Springsteen"},
+          {first_name = "Eric", last_name = "Clapton"},
+          {first_name = "Bob", last_name = "Seger"}]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/inline-table.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/inline-table.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/inline-table.json
        2016-05-19 17:36:31.000000000 +0200
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/inline-table.json
        2018-10-28 15:18:15.000000000 +0100
@@ -1,11 +1,16 @@
 {
+    "name": {
+        "first": {"type": "string", "value": "Tom"},
+        "last": {"type": "string", "value": "Preston-Werner"}
+    },
+    "point": {
+        "x": {"type": "integer", "value": "1"},
+        "y": {"type": "integer", "value": "2"}
+    },
     "simple": { "a": {"type": "integer", "value": "1"} },
     "str-key": { "a": {"type": "integer", "value": "1"} },
-    "table-array": {
-        "type": "array",
-        "value": [
-            { "a": {"type": "integer", "value": "1"} },
-            { "b": {"type": "integer", "value": "2"} }
-        ]
-    }
+    "table-array": [
+        { "a": {"type": "integer", "value": "1"} },
+        { "b": {"type": "integer", "value": "2"} }
+    ]
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/inline-table.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/inline-table.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/inline-table.toml
        2016-05-19 17:36:31.000000000 +0200
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/inline-table.toml
        2018-10-28 15:18:15.000000000 +0100
@@ -1,3 +1,5 @@
+name = { first = "Tom", last = "Preston-Werner" }
+point = { x = 1, y = 2 }
 simple = { a = 1 }
 str-key = { "a" = 1 }
 table-array = [{ "a" = 1 }, { "b" = 2 }]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/integer.json 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/integer.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/integer.json 
    2016-05-19 17:36:31.000000000 +0200
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/integer.json 
    2018-10-28 15:18:15.000000000 +0100
@@ -1,6 +1,6 @@
 {
     "answer": {"type": "integer", "value": "42"},
-    "posanswer": {"type": "integer", "value": "42"},
     "neganswer": {"type": "integer", "value": "-42"},
+    "posanswer": {"type": "integer", "value": "42"},
     "zero": {"type": "integer", "value": "0"}
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/key-uni-chars.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/key-uni-chars.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/key-uni-chars.json
       1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/key-uni-chars.json
       2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,5 @@
+{
+    "Á": {
+        "type": "integer", "value": "1"
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/key-uni-chars.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/key-uni-chars.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/key-uni-chars.toml
       1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/key-uni-chars.toml
       2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1 @@
+"Á" = 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/keys-with-dots.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/keys-with-dots.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/keys-with-dots.json
      1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/keys-with-dots.json
      2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,14 @@
+{
+  "plain": {"type": "integer", "value": "1"},
+  "with.dot": {"type": "integer", "value": "2"},
+  "plain_table": {
+    "plain": {"type": "integer", "value": "3"},
+    "with.dot": {"type": "integer", "value": "4"}
+  },
+  "table": {
+    "withdot": {
+      "plain": {"type": "integer", "value": "5"},
+      "key.with.dots": {"type": "integer", "value": "6"}
+    }
+  }
+}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/keys-with-dots.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/keys-with-dots.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/keys-with-dots.toml
      1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/keys-with-dots.toml
      2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,10 @@
+plain = 1
+"with.dot" = 2
+
+[plain_table]
+plain = 3
+"with.dot" = 4
+
+[table.withdot]
+plain = 5
+"key.with.dots" = 6
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/newline-crlf.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/newline-crlf.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/newline-crlf.json
        1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/newline-crlf.json
        2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,4 @@
+{
+    "os": {"type": "string", "value": "DOS"},
+    "newline": {"type": "string", "value": "crlf"}
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/newline-crlf.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/newline-crlf.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/newline-crlf.toml
        1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/newline-crlf.toml
        2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,2 @@
+os = "DOS"
+newline = "crlf"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/newline-lf.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/newline-lf.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/newline-lf.json
  1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/newline-lf.json
  2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,4 @@
+{
+    "os": {"type": "string", "value": "unix"},
+    "newline": {"type": "string", "value": "lf"}
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/newline-lf.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/newline-lf.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/newline-lf.toml
  1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/newline-lf.toml
  2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,2 @@
+os = "unix"
+newline = "lf"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/quote-before-escape.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/quote-before-escape.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/quote-before-escape.json
 1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/quote-before-escape.json
 2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,6 @@
+{
+    "a": {
+        "type": "string",
+        "value": "b \"\n c"
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/quote-before-escape.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/quote-before-escape.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/quote-before-escape.toml
 1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/quote-before-escape.toml
 2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1 @@
+a = """b "\n c"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/raw-multiline-string.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/raw-multiline-string.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/raw-multiline-string.json
        2016-05-19 17:36:31.000000000 +0200
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/raw-multiline-string.json
        2018-10-28 15:18:15.000000000 +0100
@@ -10,5 +10,9 @@
     "multiline": {
         "type": "string",
         "value": "This string\nhas ' a quote character\nand more than\none 
newline\nin it."
+    },
+    "tab": {
+        "type": "string",
+        "value": "This string contains a tab character >\t<"
     }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/raw-multiline-string.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/raw-multiline-string.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/raw-multiline-string.toml
        2016-05-19 17:36:31.000000000 +0200
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/raw-multiline-string.toml
        2018-10-28 15:18:15.000000000 +0100
@@ -7,3 +7,4 @@
 and more than
 one newline
 in it.'''
+tab = '''This string contains a tab character >        <'''
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/raw-string.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/raw-string.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/raw-string.json
  2016-05-19 17:36:31.000000000 +0200
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/raw-string.json
  2018-10-28 15:18:15.000000000 +0100
@@ -7,6 +7,10 @@
         "type": "string",
         "value": "This string has a \\t tab character."
     },
+    "tab_unescaped": {
+        "type": "string",
+        "value": "This string has a literal tab character >\t<."
+    },
     "newline": {
         "type": "string",
         "value": "This string has a \\n new line character."
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/raw-string.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/raw-string.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/raw-string.toml
  2016-05-19 17:36:31.000000000 +0200
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/raw-string.toml
  2018-10-28 15:18:15.000000000 +0100
@@ -1,5 +1,6 @@
 backspace = 'This string has a \b backspace character.'
 tab = 'This string has a \t tab character.'
+tab_unescaped = 'This string has a literal tab character >     <.'
 newline = 'This string has a \n new line character.'
 formfeed = 'This string has a \f form feed character.'
 carriage = 'This string has a \r carriage return character.'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/table-array-table-array.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/table-array-table-array.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/table-array-table-array.json
     1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/table-array-table-array.json
     2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,10 @@
+{
+  "a": [
+    {
+      "b": [
+        { "c" : { "d": {"type": "string", "value": "val0" } } },
+        { "c" : { "d": {"type": "string", "value": "val1" } } }
+      ]
+    }
+  ]
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/table-array-table-array.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/table-array-table-array.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/table-array-table-array.toml
     1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/table-array-table-array.toml
     2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,7 @@
+[[a]]
+    [[a.b]]
+        [a.b.c]
+            d = "val0"
+    [[a.b]]
+        [a.b.c]
+            d = "val1"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/table-with-literal-string.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/table-with-literal-string.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/table-with-literal-string.json
   1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/table-with-literal-string.json
   2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,9 @@
+{
+    "a": {
+        "\"b\"": {
+            "c": {
+                "answer": {"type": "integer", "value": "42"}
+            }
+        }
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/table-with-literal-string.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/table-with-literal-string.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/table-with-literal-string.toml
   1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/table-with-literal-string.toml
   2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,4 @@
+['a']
+[a.'"b"']
+[a.'"b"'.c]
+answer = 42 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/table-with-single-quotes.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/table-with-single-quotes.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/table-with-single-quotes.json
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/table-with-single-quotes.json
    2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,9 @@
+{
+    "a": {
+        "b": {
+            "c": {
+                "answer": {"type": "integer", "value": "42"}
+            }
+        }
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/table-with-single-quotes.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/table-with-single-quotes.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/table-with-single-quotes.toml
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/table-with-single-quotes.toml
    2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,4 @@
+['a']
+[a.'b']
+[a.'b'.c]
+answer = 42 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/underscored-float.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/underscored-float.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/underscored-float.json
   1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/underscored-float.json
   2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,3 @@
+{
+    "electron_mass": {"type": "float", "value": "9.109109383e-31"}
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/underscored-float.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/underscored-float.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/underscored-float.toml
   1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/underscored-float.toml
   2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1 @@
+electron_mass = 9_109.109_383e-3_4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/underscored-integer.json
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/underscored-integer.json
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/underscored-integer.json
 1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/underscored-integer.json
 2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1,3 @@
+{
+    "million": {"type": "integer", "value": "1000000"}
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/underscored-integer.toml
 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/underscored-integer.toml
--- 
old/toml-test-fa9501a192b7c46b82059caddaef978e3de883dc/tests/valid/underscored-integer.toml
 1970-01-01 01:00:00.000000000 +0100
+++ 
new/toml-test-b212790a6b7367489f389411bda009e5ff765f20/tests/valid/underscored-integer.toml
 2018-10-28 15:18:15.000000000 +0100
@@ -0,0 +1 @@
+million = 1_000_000

++++++ pytoml-0.1.14.tar.gz -> pytoml-0.1.20.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytoml-0.1.14/LICENSE new/pytoml-0.1.20/LICENSE
--- old/pytoml-0.1.14/LICENSE   1970-01-01 01:00:00.000000000 +0100
+++ new/pytoml-0.1.20/LICENSE   2018-10-27 21:21:13.000000000 +0200
@@ -0,0 +1,16 @@
+No-notice MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytoml-0.1.14/MANIFEST.in 
new/pytoml-0.1.20/MANIFEST.in
--- old/pytoml-0.1.14/MANIFEST.in       1970-01-01 01:00:00.000000000 +0100
+++ new/pytoml-0.1.20/MANIFEST.in       2018-10-27 21:21:13.000000000 +0200
@@ -0,0 +1,2 @@
+include LICENSE
+include README.md
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytoml-0.1.14/PKG-INFO new/pytoml-0.1.20/PKG-INFO
--- old/pytoml-0.1.14/PKG-INFO  2017-07-01 11:39:02.000000000 +0200
+++ new/pytoml-0.1.20/PKG-INFO  2018-10-28 15:22:09.000000000 +0100
@@ -1,10 +1,62 @@
-Metadata-Version: 1.0
+Metadata-Version: 2.1
 Name: pytoml
-Version: 0.1.14
+Version: 0.1.20
 Summary: A parser for TOML-0.4.0
 Home-page: https://github.com/avakar/pytoml
 Author: Martin Vejnár
-Author-email: ava...@ratatanek.cz
+Author-email: vejnar.mar...@gmail.com
 License: MIT
-Description: UNKNOWN
+Description: 
[![PyPI](https://img.shields.io/pypi/v/pytoml.svg)](https://pypi.python.org/pypi/pytoml)
+        [![Build 
Status](https://travis-ci.org/avakar/pytoml.svg?branch=master)](https://travis-ci.org/avakar/pytoml)
+        
+        # pytoml
+        
+        This project aims at being a specs-conforming and strict parser and 
writer for [TOML][1] files.
+        The library currently supports [version 0.4.0][2] of the specs and 
runs with Python 2.7+ and 3.5+.
+        
+        Install:
+        
+            pip install pytoml
+        
+        The interface is the same as for the standard `json` package.
+        
+            >>> import pytoml as toml
+            >>> toml.loads('a = 1')
+            {'a': 1}
+            >>> with open('file.toml', 'rb') as fin:
+            ...     obj = toml.load(fin)
+            >>> obj
+            {'a': 1}
+        
+        The `loads` function accepts either a bytes object
+        (that gets decoded as UTF-8 with no BOM allowed),
+        or a unicode object.
+        
+        Use `dump` or `dumps` to serialize a dict into TOML.
+        
+            >>> print toml.dumps(obj)
+            a = 1
+        
+        ## tests
+        
+        To run the tests update the `toml-test` submodule:
+        
+            git submodule update --init --recursive
+        
+        Then run the tests:
+        
+            python test/test.py
+        
+          [1]: https://github.com/toml-lang/toml
+          [2]: 
https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md
+        
 Platform: UNKNOWN
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Topic :: Software Development :: Libraries
+Description-Content-Type: text/markdown
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytoml-0.1.14/README.md new/pytoml-0.1.20/README.md
--- old/pytoml-0.1.14/README.md 1970-01-01 01:00:00.000000000 +0100
+++ new/pytoml-0.1.20/README.md 2018-10-27 21:21:13.000000000 +0200
@@ -0,0 +1,43 @@
+[![PyPI](https://img.shields.io/pypi/v/pytoml.svg)](https://pypi.python.org/pypi/pytoml)
+[![Build 
Status](https://travis-ci.org/avakar/pytoml.svg?branch=master)](https://travis-ci.org/avakar/pytoml)
+
+# pytoml
+
+This project aims at being a specs-conforming and strict parser and writer for 
[TOML][1] files.
+The library currently supports [version 0.4.0][2] of the specs and runs with 
Python 2.7+ and 3.5+.
+
+Install:
+
+    pip install pytoml
+
+The interface is the same as for the standard `json` package.
+
+    >>> import pytoml as toml
+    >>> toml.loads('a = 1')
+    {'a': 1}
+    >>> with open('file.toml', 'rb') as fin:
+    ...     obj = toml.load(fin)
+    >>> obj
+    {'a': 1}
+
+The `loads` function accepts either a bytes object
+(that gets decoded as UTF-8 with no BOM allowed),
+or a unicode object.
+
+Use `dump` or `dumps` to serialize a dict into TOML.
+
+    >>> print toml.dumps(obj)
+    a = 1
+
+## tests
+
+To run the tests update the `toml-test` submodule:
+
+    git submodule update --init --recursive
+
+Then run the tests:
+
+    python test/test.py
+
+  [1]: https://github.com/toml-lang/toml
+  [2]: https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytoml-0.1.14/pytoml/__init__.py 
new/pytoml-0.1.20/pytoml/__init__.py
--- old/pytoml-0.1.14/pytoml/__init__.py        2017-05-20 20:10:58.000000000 
+0200
+++ new/pytoml-0.1.20/pytoml/__init__.py        2018-10-28 14:35:02.000000000 
+0100
@@ -1,3 +1,4 @@
 from .core import TomlError
 from .parser import load, loads
-from .writer import dump, dumps
+from .test import translate_to_test
+from .writer import dump, dumps
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytoml-0.1.14/pytoml/parser.py 
new/pytoml-0.1.20/pytoml/parser.py
--- old/pytoml-0.1.14/pytoml/parser.py  2017-07-01 11:28:56.000000000 +0200
+++ new/pytoml-0.1.20/pytoml/parser.py  2018-10-28 14:40:08.000000000 +0100
@@ -1,40 +1,41 @@
 import string, re, sys, datetime
 from .core import TomlError
+from .utils import rfc3339_re, parse_rfc3339_re
 
 if sys.version_info[0] == 2:
     _chr = unichr
 else:
     _chr = chr
 
-def load(fin, translate=lambda t, x, v: v):
-    return loads(fin.read(), translate=translate, filename=getattr(fin, 
'name', repr(fin)))
+def load(fin, translate=lambda t, x, v: v, object_pairs_hook=dict):
+    return loads(fin.read(), translate=translate, 
object_pairs_hook=object_pairs_hook, filename=getattr(fin, 'name', repr(fin)))
 
-def loads(s, filename='<string>', translate=lambda t, x, v: v):
+def loads(s, filename='<string>', translate=lambda t, x, v: v, 
object_pairs_hook=dict):
     if isinstance(s, bytes):
         s = s.decode('utf-8')
 
     s = s.replace('\r\n', '\n')
 
-    root = {}
-    tables = {}
+    root = object_pairs_hook()
+    tables = object_pairs_hook()
     scope = root
 
     src = _Source(s, filename=filename)
-    ast = _p_toml(src)
+    ast = _p_toml(src, object_pairs_hook=object_pairs_hook)
 
     def error(msg):
         raise TomlError(msg, pos[0], pos[1], filename)
 
-    def process_value(v):
+    def process_value(v, object_pairs_hook):
         kind, text, value, pos = v
         if kind == 'str' and value.startswith('\n'):
             value = value[1:]
         if kind == 'array':
             if value and any(k != value[0][0] for k, t, v, p in value[1:]):
                 error('array-type-mismatch')
-            value = [process_value(item) for item in value]
+            value = [process_value(item, object_pairs_hook=object_pairs_hook) 
for item in value]
         elif kind == 'table':
-            value = dict([(k, process_value(value[k])) for k in value])
+            value = object_pairs_hook([(k, process_value(value[k], 
object_pairs_hook=object_pairs_hook)) for k in value])
         return translate(kind, text, value)
 
     for kind, value, pos in ast:
@@ -42,7 +43,7 @@
             k, v = value
             if k in scope:
                 error('duplicate_keys. Key "{0}" was used more than 
once.'.format(k))
-            scope[k] = process_value(v)
+            scope[k] = process_value(v, object_pairs_hook=object_pairs_hook)
         else:
             is_table_array = (kind == 'table_array')
             cur = tables
@@ -50,19 +51,19 @@
                 if isinstance(cur.get(name), list):
                     d, cur = cur[name][-1]
                 else:
-                    d, cur = cur.setdefault(name, (None, {}))
+                    d, cur = cur.setdefault(name, (None, object_pairs_hook()))
 
-            scope = {}
+            scope = object_pairs_hook()
             name = value[-1]
             if name not in cur:
                 if is_table_array:
-                    cur[name] = [(scope, {})]
+                    cur[name] = [(scope, object_pairs_hook())]
                 else:
-                    cur[name] = (scope, {})
+                    cur[name] = (scope, object_pairs_hook())
             elif isinstance(cur[name], list):
                 if not is_table_array:
                     error('table_type_mismatch')
-                cur[name].append((scope, {}))
+                cur[name].append((scope, object_pairs_hook()))
             else:
                 if is_table_array:
                     error('table_type_mismatch')
@@ -73,7 +74,7 @@
 
     def merge_tables(scope, tables):
         if scope is None:
-            scope = {}
+            scope = object_pairs_hook()
         for k in tables:
             if k in scope:
                 error('key_table_conflict')
@@ -179,13 +180,13 @@
 def _p_ws(s):
     s.expect_re(_ws_re)
 
-_escapes = { 'b': '\b', 'n': '\n', 'r': '\r', 't': '\t', '"': '"', '\'': '\'',
-    '\\': '\\', '/': '/', 'f': '\f' }
+_escapes = { 'b': '\b', 'n': '\n', 'r': '\r', 't': '\t', '"': '"',
+    '\\': '\\', 'f': '\f' }
 
 _basicstr_re = re.compile(r'[^"\\\000-\037]*')
 _short_uni_re = re.compile(r'u([0-9a-fA-F]{4})')
 _long_uni_re = re.compile(r'U([0-9a-fA-F]{8})')
-_escapes_re = re.compile('[bnrt"\'\\\\/f]')
+_escapes_re = re.compile(r'[btnfr\"\\]')
 _newline_esc_re = re.compile('\n[ \t\n]*')
 def _p_basicstr_content(s, content=_basicstr_re):
     res = []
@@ -196,7 +197,10 @@
         if s.consume_re(_newline_esc_re):
             pass
         elif s.consume_re(_short_uni_re) or s.consume_re(_long_uni_re):
-            res.append(_chr(int(s.last().group(1), 16)))
+            v = int(s.last().group(1), 16)
+            if 0xd800 <= v < 0xe000:
+                s.fail()
+            res.append(_chr(v))
         else:
             s.expect_re(_escapes_re)
             res.append(_escapes[s.last().group(0)])
@@ -220,12 +224,11 @@
     return s.expect_re(_key_re).group(0)
 
 _float_re = 
re.compile(r'[+-]?(?:0|[1-9](?:_?\d)*)(?:\.\d(?:_?\d)*)?(?:[eE][+-]?(?:\d(?:_?\d)*))?')
-_datetime_re = 
re.compile(r'(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d+)?(?:Z|([+-]\d{2}):(\d{2}))')
 
-_basicstr_ml_re = re.compile(r'(?:(?:|"|"")[^"\\\000-\011\013-\037])*')
-_litstr_re = re.compile(r"[^'\000-\037]*")
-_litstr_ml_re = re.compile(r"(?:(?:|'|'')(?:[^'\000-\011\013-\037]))*")
-def _p_value(s):
+_basicstr_ml_re = re.compile(r'(?:""?(?!")|[^"\\\000-\011\013-\037])*')
+_litstr_re = re.compile(r"[^'\000\010\012-\037]*")
+_litstr_ml_re = re.compile(r"(?:(?:|'|'')(?:[^'\000-\010\013-\037]))*")
+def _p_value(s, object_pairs_hook):
     pos = s.pos()
 
     if s.consume('true'):
@@ -251,24 +254,9 @@
             s.expect('\'')
         return 'str', r, r, pos
 
-    if s.consume_re(_datetime_re):
+    if s.consume_re(rfc3339_re):
         m = s.last()
-        s0 = m.group(0)
-        r = map(int, m.groups()[:6])
-        if m.group(7):
-            micro = float(m.group(7))
-        else:
-            micro = 0
-
-        if m.group(8):
-            g = int(m.group(8), 10) * 60 + int(m.group(9), 10)
-            tz = _TimeZone(datetime.timedelta(0, g * 60))
-        else:
-            tz = _TimeZone(datetime.timedelta(0, 0))
-
-        y, m, d, H, M, S = r
-        dt = datetime.datetime(y, m, d, H, M, S, int(micro * 1000000), tz)
-        return 'datetime', s0, dt, pos
+        return 'datetime', m.group(0), parse_rfc3339_re(m), pos
 
     if s.consume_re(_float_re):
         m = s.last().group(0)
@@ -283,7 +271,7 @@
         with s:
             while True:
                 _p_ews(s)
-                items.append(_p_value(s))
+                items.append(_p_value(s, object_pairs_hook=object_pairs_hook))
                 s.commit()
                 _p_ews(s)
                 s.expect(',')
@@ -294,13 +282,13 @@
 
     if s.consume('{'):
         _p_ws(s)
-        items = {}
+        items = object_pairs_hook()
         if not s.consume('}'):
             k = _p_key(s)
             _p_ws(s)
             s.expect('=')
             _p_ws(s)
-            items[k] = _p_value(s)
+            items[k] = _p_value(s, object_pairs_hook=object_pairs_hook)
             _p_ws(s)
             while s.consume(','):
                 _p_ws(s)
@@ -308,14 +296,14 @@
                 _p_ws(s)
                 s.expect('=')
                 _p_ws(s)
-                items[k] = _p_value(s)
+                items[k] = _p_value(s, object_pairs_hook=object_pairs_hook)
                 _p_ws(s)
             s.expect('}')
         return 'table', None, items, pos
 
     s.fail()
 
-def _p_stmt(s):
+def _p_stmt(s, object_pairs_hook):
     pos = s.pos()
     if s.consume(   '['):
         is_array = s.consume('[')
@@ -335,40 +323,19 @@
     _p_ws(s)
     s.expect('=')
     _p_ws(s)
-    value = _p_value(s)
+    value = _p_value(s, object_pairs_hook=object_pairs_hook)
     return 'kv', (key, value), pos
 
 _stmtsep_re = re.compile(r'(?:[ \t]*(?:#[^\n]*)?\n)+[ \t]*')
-def _p_toml(s):
+def _p_toml(s, object_pairs_hook):
     stmts = []
     _p_ews(s)
     with s:
-        stmts.append(_p_stmt(s))
+        stmts.append(_p_stmt(s, object_pairs_hook=object_pairs_hook))
         while True:
             s.commit()
             s.expect_re(_stmtsep_re)
-            stmts.append(_p_stmt(s))
+            stmts.append(_p_stmt(s, object_pairs_hook=object_pairs_hook))
     _p_ews(s)
     s.expect_eof()
     return stmts
-
-class _TimeZone(datetime.tzinfo):
-    def __init__(self, offset):
-        self._offset = offset
-
-    def utcoffset(self, dt):
-        return self._offset
-
-    def dst(self, dt):
-        return None
-
-    def tzname(self, dt):
-        m = self._offset.total_seconds() // 60
-        if m < 0:
-            res = '-'
-            m = -m
-        else:
-            res = '+'
-        h = m // 60
-        m = m - h * 60
-        return '{}{:.02}{:.02}'.format(res, h, m)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytoml-0.1.14/pytoml/test.py 
new/pytoml-0.1.20/pytoml/test.py
--- old/pytoml-0.1.14/pytoml/test.py    1970-01-01 01:00:00.000000000 +0100
+++ new/pytoml-0.1.20/pytoml/test.py    2018-10-28 14:35:02.000000000 +0100
@@ -0,0 +1,30 @@
+import datetime
+from .utils import format_rfc3339
+
+try:
+    _string_types = (str, unicode)
+    _int_types = (int, long)
+except NameError:
+    _string_types = str
+    _int_types = int
+
+def translate_to_test(v):
+    if isinstance(v, dict):
+        return { k: translate_to_test(v) for k, v in v.items() }
+    if isinstance(v, list):
+        a = [translate_to_test(x) for x in v]
+        if v and isinstance(v[0], dict):
+            return a
+        else:
+            return {'type': 'array', 'value': a}
+    if isinstance(v, datetime.datetime):
+        return {'type': 'datetime', 'value': format_rfc3339(v)}
+    if isinstance(v, bool):
+        return {'type': 'bool', 'value': 'true' if v else 'false'}
+    if isinstance(v, _int_types):
+        return {'type': 'integer', 'value': str(v)}
+    if isinstance(v, float):
+        return {'type': 'float', 'value': '{:.17}'.format(v)}
+    if isinstance(v, _string_types):
+        return {'type': 'string', 'value': v}
+    raise RuntimeError('unexpected value: {!r}'.format(v))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytoml-0.1.14/pytoml/utils.py 
new/pytoml-0.1.20/pytoml/utils.py
--- old/pytoml-0.1.14/pytoml/utils.py   1970-01-01 01:00:00.000000000 +0100
+++ new/pytoml-0.1.20/pytoml/utils.py   2018-10-28 14:35:02.000000000 +0100
@@ -0,0 +1,67 @@
+import datetime
+import re
+
+rfc3339_re = 
re.compile(r'(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d+)?(?:Z|([+-]\d{2}):(\d{2}))')
+
+def parse_rfc3339(v):
+    m = rfc3339_re.match(v)
+    if not m or m.group(0) != v:
+        return None
+    return parse_rfc3339_re(m)
+
+def parse_rfc3339_re(m):
+    r = map(int, m.groups()[:6])
+    if m.group(7):
+        micro = float(m.group(7))
+    else:
+        micro = 0
+
+    if m.group(8):
+        g = int(m.group(8), 10) * 60 + int(m.group(9), 10)
+        tz = _TimeZone(datetime.timedelta(0, g * 60))
+    else:
+        tz = _TimeZone(datetime.timedelta(0, 0))
+
+    y, m, d, H, M, S = r
+    return datetime.datetime(y, m, d, H, M, S, int(micro * 1000000), tz)
+
+
+def format_rfc3339(v):
+    offs = v.utcoffset()
+    offs = int(offs.total_seconds()) // 60 if offs is not None else 0
+
+    if offs == 0:
+        suffix = 'Z'
+    else:
+        if offs > 0:
+            suffix = '+'
+        else:
+            suffix = '-'
+            offs = -offs
+        suffix = '{0}{1:02}:{2:02}'.format(suffix, offs // 60, offs % 60)
+
+    if v.microsecond:
+        return v.strftime('%Y-%m-%dT%H:%M:%S.%f') + suffix
+    else:
+        return v.strftime('%Y-%m-%dT%H:%M:%S') + suffix
+
+class _TimeZone(datetime.tzinfo):
+    def __init__(self, offset):
+        self._offset = offset
+
+    def utcoffset(self, dt):
+        return self._offset
+
+    def dst(self, dt):
+        return None
+
+    def tzname(self, dt):
+        m = self._offset.total_seconds() // 60
+        if m < 0:
+            res = '-'
+            m = -m
+        else:
+            res = '+'
+        h = m // 60
+        m = m - h * 60
+        return '{}{:.02}{:.02}'.format(res, h, m)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytoml-0.1.14/pytoml/writer.py 
new/pytoml-0.1.20/pytoml/writer.py
--- old/pytoml-0.1.14/pytoml/writer.py  2017-07-01 11:33:47.000000000 +0200
+++ new/pytoml-0.1.20/pytoml/writer.py  2018-10-28 15:14:35.000000000 +0100
@@ -1,5 +1,7 @@
 from __future__ import unicode_literals
-import io, datetime, math, sys
+import io, datetime, math, string, sys
+
+from .utils import format_rfc3339
 
 if sys.version_info[0] == 3:
     long = int
@@ -39,22 +41,13 @@
     return '"' + ''.join(res) + '"'
 
 
+_key_chars = string.digits + string.ascii_letters + '-_'
 def _escape_id(s):
-    if any(not c.isalnum() and c not in '-_' for c in s):
+    if any(c not in _key_chars for c in s):
         return _escape_string(s)
     return s
 
 
-def _format_list(v):
-    return '[{0}]'.format(', '.join(_format_value(obj) for obj in v))
-
-# Formula from:
-#   
https://docs.python.org/2/library/datetime.html#datetime.timedelta.total_seconds
-# Once support for py26 is dropped, this can be replaced by td.total_seconds()
-def _total_seconds(td):
-    return ((td.microseconds
-             + (td.seconds + td.days * 24 * 3600) * 10**6) / 10.0**6)
-
 def _format_value(v):
     if isinstance(v, bool):
         return 'true' if v else 'false'
@@ -68,25 +61,11 @@
     elif isinstance(v, unicode) or isinstance(v, bytes):
         return _escape_string(v)
     elif isinstance(v, datetime.datetime):
-        offs = v.utcoffset()
-        offs = _total_seconds(offs) // 60 if offs is not None else 0
-
-        if offs == 0:
-            suffix = 'Z'
-        else:
-            if offs > 0:
-                suffix = '+'
-            else:
-                suffix = '-'
-                offs = -offs
-            suffix = '{0}{1:.02}{2:.02}'.format(suffix, offs // 60, offs % 60)
-
-        if v.microsecond:
-            return v.strftime('%Y-%m-%dT%H:%M:%S.%f') + suffix
-        else:
-            return v.strftime('%Y-%m-%dT%H:%M:%S') + suffix
+        return format_rfc3339(v)
     elif isinstance(v, list):
-        return _format_list(v)
+        return '[{0}]'.format(', '.join(_format_value(obj) for obj in v))
+    elif isinstance(v, dict):
+        return '{{{0}}}'.format(', '.join('{} = {}'.format(_escape_id(k), 
_format_value(obj)) for k, obj in v.items()))
     else:
         raise RuntimeError(v)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytoml-0.1.14/pytoml.egg-info/PKG-INFO 
new/pytoml-0.1.20/pytoml.egg-info/PKG-INFO
--- old/pytoml-0.1.14/pytoml.egg-info/PKG-INFO  2017-07-01 11:39:02.000000000 
+0200
+++ new/pytoml-0.1.20/pytoml.egg-info/PKG-INFO  2018-10-28 15:22:09.000000000 
+0100
@@ -1,10 +1,62 @@
-Metadata-Version: 1.0
+Metadata-Version: 2.1
 Name: pytoml
-Version: 0.1.14
+Version: 0.1.20
 Summary: A parser for TOML-0.4.0
 Home-page: https://github.com/avakar/pytoml
 Author: Martin Vejnár
-Author-email: ava...@ratatanek.cz
+Author-email: vejnar.mar...@gmail.com
 License: MIT
-Description: UNKNOWN
+Description: 
[![PyPI](https://img.shields.io/pypi/v/pytoml.svg)](https://pypi.python.org/pypi/pytoml)
+        [![Build 
Status](https://travis-ci.org/avakar/pytoml.svg?branch=master)](https://travis-ci.org/avakar/pytoml)
+        
+        # pytoml
+        
+        This project aims at being a specs-conforming and strict parser and 
writer for [TOML][1] files.
+        The library currently supports [version 0.4.0][2] of the specs and 
runs with Python 2.7+ and 3.5+.
+        
+        Install:
+        
+            pip install pytoml
+        
+        The interface is the same as for the standard `json` package.
+        
+            >>> import pytoml as toml
+            >>> toml.loads('a = 1')
+            {'a': 1}
+            >>> with open('file.toml', 'rb') as fin:
+            ...     obj = toml.load(fin)
+            >>> obj
+            {'a': 1}
+        
+        The `loads` function accepts either a bytes object
+        (that gets decoded as UTF-8 with no BOM allowed),
+        or a unicode object.
+        
+        Use `dump` or `dumps` to serialize a dict into TOML.
+        
+            >>> print toml.dumps(obj)
+            a = 1
+        
+        ## tests
+        
+        To run the tests update the `toml-test` submodule:
+        
+            git submodule update --init --recursive
+        
+        Then run the tests:
+        
+            python test/test.py
+        
+          [1]: https://github.com/toml-lang/toml
+          [2]: 
https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md
+        
 Platform: UNKNOWN
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Topic :: Software Development :: Libraries
+Description-Content-Type: text/markdown
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytoml-0.1.14/pytoml.egg-info/SOURCES.txt 
new/pytoml-0.1.20/pytoml.egg-info/SOURCES.txt
--- old/pytoml-0.1.14/pytoml.egg-info/SOURCES.txt       2017-07-01 
11:39:02.000000000 +0200
+++ new/pytoml-0.1.20/pytoml.egg-info/SOURCES.txt       2018-10-28 
15:22:09.000000000 +0100
@@ -1,7 +1,12 @@
+LICENSE
+MANIFEST.in
+README.md
 setup.py
 pytoml/__init__.py
 pytoml/core.py
 pytoml/parser.py
+pytoml/test.py
+pytoml/utils.py
 pytoml/writer.py
 pytoml.egg-info/PKG-INFO
 pytoml.egg-info/SOURCES.txt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytoml-0.1.14/setup.cfg new/pytoml-0.1.20/setup.cfg
--- old/pytoml-0.1.14/setup.cfg 2017-07-01 11:39:02.000000000 +0200
+++ new/pytoml-0.1.20/setup.cfg 2018-10-28 15:22:09.000000000 +0100
@@ -1,5 +1,4 @@
 [egg_info]
 tag_build = 
 tag_date = 0
-tag_svn_revision = 0
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytoml-0.1.14/setup.py new/pytoml-0.1.20/setup.py
--- old/pytoml-0.1.14/setup.py  2017-07-01 11:38:41.000000000 +0200
+++ new/pytoml-0.1.20/setup.py  2018-10-28 15:21:35.000000000 +0100
@@ -3,15 +3,35 @@
 
 from setuptools import setup
 
+with open('README.md', 'r') as fin:
+    long_description = fin.read()
+
 setup(
     name='pytoml',
-    version='0.1.14',
+    version='0.1.20',
 
     description='A parser for TOML-0.4.0',
+    long_description=long_description,
+    long_description_content_type='text/markdown',
+
     author='Martin Vejnár',
-    author_email='ava...@ratatanek.cz',
+    author_email='vejnar.mar...@gmail.com',
     url='https://github.com/avakar/pytoml',
     license='MIT',
-
     packages=['pytoml'],
-    )
+    classifiers=[
+        # Supported python versions
+        'Programming Language :: Python :: 2',
+        'Programming Language :: Python :: 2.7',
+        'Programming Language :: Python :: 3',
+        'Programming Language :: Python :: 3.5',
+        'Programming Language :: Python :: 3.6',
+        'Programming Language :: Python :: 3.7',
+
+        # License
+        'License :: OSI Approved :: MIT License',
+
+        # Topics
+        'Topic :: Software Development :: Libraries',
+    ]
+)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytoml-0.1.14/test/test.py 
new/pytoml-0.1.20/test/test.py
--- old/pytoml-0.1.14/test/test.py      2017-05-20 20:10:58.000000000 +0200
+++ new/pytoml-0.1.20/test/test.py      2018-10-28 15:15:49.000000000 +0100
@@ -1,41 +1,31 @@
 import os, json, sys, io, traceback, argparse
 import pytoml as toml
+from pytoml.utils import parse_rfc3339
 
-# Formula from:
-#   
https://docs.python.org/2/library/datetime.html#datetime.timedelta.total_seconds
-# Once support for py26 is dropped, this can be replaced by td.total_seconds()
-def _total_seconds(td):
-    return ((td.microseconds
-             + (td.seconds + td.days * 24 * 3600) * 10**6) / 10.0**6)
-
-def _testbench_literal(type, text, value):
-    if type == 'table':
-        return value
-    if type == 'array':
-        return { 'type': 'array', 'value': value }
-    if type == 'datetime':
-        offs = _total_seconds(value.tzinfo.utcoffset(value)) // 60
-        offs = 'Z' if offs == 0 else '{}{}:{}'.format('-' if offs < 0 else 
'-', abs(offs) // 60, abs(offs) % 60)
-        v = '{0:04}-{1:02}-{2:02}T{3:02}:{4:02}:{5:02}{6}'.format(value.year, 
value.month, value.day, value.hour, value.minute, value.second, offs)
-        return { 'type': 'datetime', 'value': v }
-    if type == 'bool':
-        return { 'type': 'bool', 'value': 'true' if value else 'false' }
-    if type == 'float':
-        return { 'type': 'float', 'value': value }
-    if type == 'str':
-        return { 'type': 'string', 'value': value }
-    if type == 'int':
-        return { 'type': 'integer', 'value': str(value) }
-
-def adjust_bench(v):
-    if isinstance(v, dict):
-        if v.get('type') == 'float':
-            v['value'] = float(v['value'])
-            return v
-        return dict([(k, adjust_bench(v[k])) for k in v])
-    if isinstance(v, list):
-        return [adjust_bench(v) for v in v]
-    return v
+def is_bench_equal(a, b):
+    if isinstance(a, dict):
+        if 'type' in a:
+            if b.get('type') != a['type']:
+                return False
+
+            if a['type'] == 'float':
+                return float(a['value']) == float(b['value'])
+            if a['type'] == 'datetime':
+                x = parse_rfc3339(a['value'])
+                y = parse_rfc3339(b['value'])
+                return x == y
+            if a['type'] == 'array':
+                return is_bench_equal(a['value'], b['value'])
+            return a['value'] == b['value']
+
+        return (isinstance(b, dict) and len(a) == len(b)
+            and all(k in b and is_bench_equal(a[k], b[k]) for k in a))
+
+    if isinstance(a, list):
+        return (isinstance(b, list) and len(a) == len(b)
+            and all(is_bench_equal(x, y) for x, y in zip(a, b)))
+
+    raise RuntimeError('Invalid data in the bench JSON')
 
 def _main():
     ap = argparse.ArgumentParser()
@@ -78,7 +68,8 @@
                         continue
 
                     with open(os.path.join(top, fname), 'rb') as fin:
-                        parsed = toml.load(fin, translate=_testbench_literal)
+                        parsed = toml.load(fin)
+                    parsed = toml.translate_to_test(parsed)
 
                 try:
                     with io.open(os.path.join(top, fname[:-5] + '.json'), 
'rt', encoding='utf-8') as fin:
@@ -86,7 +77,7 @@
                 except IOError:
                     bench = None
 
-                if parsed != adjust_bench(bench):
+                if (parsed is None) != (bench is None) or (parsed is not None 
and not is_bench_equal(parsed, bench)):
                     failed.append((fname, parsed, bench, parse_error))
                 else:
                     succeeded.append(fname)
@@ -103,4 +94,6 @@
     return 1 if failed or not succeeded else 0
 
 if __name__ == '__main__':
-    sys.exit(_main())
+    r = _main()
+    if r:
+        sys.exit(r)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytoml-0.1.14/test/test_parser.py 
new/pytoml-0.1.20/test/test_parser.py
--- old/pytoml-0.1.14/test/test_parser.py       2017-05-20 20:10:58.000000000 
+0200
+++ new/pytoml-0.1.20/test/test_parser.py       2018-10-27 21:21:13.000000000 
+0200
@@ -1,5 +1,6 @@
 from __future__ import unicode_literals
 
+import collections
 import sys
 if sys.version_info < (2, 7):
     from StringIO import StringIO
@@ -22,3 +23,15 @@
     source = StringIO("[")
     error = pytest.raises(toml.TomlError, lambda: toml.load(source))
     assert error.value.filename == repr(source)
+
+
+def test_object_pairs_hook():
+    source = StringIO(u"""\
+    [x.a]
+    [x.b]
+    [x.c]
+    """)
+
+    d = toml.load(source, object_pairs_hook=collections.defaultdict)
+    assert isinstance(d, collections.defaultdict)
+    assert isinstance(d['x'], collections.defaultdict)


Reply via email to