Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-cbor2 for openSUSE:Factory 
checked in at 2021-04-23 17:50:38
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-cbor2 (Old)
 and      /work/SRC/openSUSE:Factory/.python-cbor2.new.12324 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-cbor2"

Fri Apr 23 17:50:38 2021 rev:6 rq:887881 version:5.2.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-cbor2/python-cbor2.changes        
2020-08-21 19:17:19.168824687 +0200
+++ /work/SRC/openSUSE:Factory/.python-cbor2.new.12324/python-cbor2.changes     
2021-04-23 17:50:55.218824572 +0200
@@ -1,0 +2,12 @@
+Thu Apr 22 20:17:32 UTC 2021 - Dirk M??ller <[email protected]>
+
+- update to 5.2.0:
+  * Final version tested with Python 2.7 and 3.5
+  * README: Announce deprecation of Python 2.7, 3.5
+  * README: More detail and examples
+  * Bugfix: Fix segfault on loading huge arrays with C-backend (Sekenre)
+  * Build system: Allow packagers to force C-backend building or disable using 
env var (jameshilliard)
+  * Feature: :module:`cbor2.tool` Command line diagnostic tool (Sekenre)
+  * Feature: Ignore semantic tag used for file magic 55799 AKA "Self-Described 
CBOR" (kalcutter) 
+
+-------------------------------------------------------------------

Old:
----
  cbor2-5.1.2.tar.gz

New:
----
  cbor2-5.2.0.tar.gz

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

Other differences:
------------------
++++++ python-cbor2.spec ++++++
--- /var/tmp/diff_new_pack.fUFMua/_old  2021-04-23 17:50:55.626825273 +0200
+++ /var/tmp/diff_new_pack.fUFMua/_new  2021-04-23 17:50:55.626825273 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-cbor2
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-cbor2
-Version:        5.1.2
+Version:        5.2.0
 Release:        0
 Summary:        Pure Python CBOR (de)serializer with extensive tag support
 License:        MIT

++++++ cbor2-5.1.2.tar.gz -> cbor2-5.2.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cbor2-5.1.2/.travis.yml new/cbor2-5.2.0/.travis.yml
--- old/cbor2-5.1.2/.travis.yml 2020-07-21 18:59:30.000000000 +0200
+++ new/cbor2-5.2.0/.travis.yml 2020-09-30 11:59:25.000000000 +0200
@@ -39,11 +39,15 @@
       python: "3.7"
 
     - stage: test
-      env: TOXENV=py38
+      env: TOXENV=py38-clib
       python: "3.8"
-      
+
+    - stage: test
+      env: TOXENV=py38-noclib
+      python: "3.8"
+
     - stage: test
-      env: TOXENV=py38
+      env: TOXENV=py38-clib
       python: "3.8"
       arch: s390x
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cbor2-5.1.2/LICENSE.txt new/cbor2-5.2.0/LICENSE.txt
--- old/cbor2-5.1.2/LICENSE.txt 2020-07-21 18:59:30.000000000 +0200
+++ new/cbor2-5.2.0/LICENSE.txt 2020-09-30 11:59:25.000000000 +0200
@@ -1,19 +1,20 @@
-This is the MIT license: http://www.opensource.org/licenses/mit-license.php
+The MIT License (MIT)
 
-Copyright (c) Alex Gr??nholm
+Copyright (c) 2016 Alex Gr??nholm
 
-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:
+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:
 
-The above copyright notice and this permission notice shall be included in all 
copies or
-substantial portions of the Software.
+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.
+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/cbor2-5.1.2/PKG-INFO new/cbor2-5.2.0/PKG-INFO
--- old/cbor2-5.1.2/PKG-INFO    2020-07-21 18:59:46.000000000 +0200
+++ new/cbor2-5.2.0/PKG-INFO    2020-09-30 11:59:41.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: cbor2
-Version: 5.1.2
+Version: 5.2.0
 Summary: Pure Python CBOR (de)serializer with extensive tag support
 Home-page: UNKNOWN
 Author: Alex Gr??nholm
@@ -21,18 +21,111 @@
           :target: https://cbor2.readthedocs.io/en/latest/?badge=latest
           :alt: Documentation Status
         
+        About
+        =====
+        
+        .. warning:: This project will be ending it's support of Python 3.5 
and lower with release 6.0.0. Version 5.2 will be the last version tested on 
Python 2.7 and 3.5
+        
         This library provides encoding and decoding for the Concise Binary 
Object Representation (CBOR)
         (`RFC 7049`_) serialization format. `Read the docs 
<https://cbor2.readthedocs.io/>`_ to learn more.
         
-        It is implemented in pure python with an optional C backend and is 
compatible with versions 2.7 through to 3.7.
-        
-        On cPython>=3.3 cbor2 can use a built in C module for performance 
similar to how ``pickle``
-        wraps the ``_pickle`` C module in the Python Standard Library. On 
Windows, this is restricted to cPython>=3.5.
+        It is implemented in pure python with an optional C backend.
         
         On PyPy, cbor2 runs with almost identical performance to the C backend.
         
         .. _RFC 7049: https://tools.ietf.org/html/rfc7049
         
+        Features
+        --------
+        
+        * Simple api like ``json`` or ``pickle`` modules.
+        * Support many `CBOR tags`_ with `stdlib objects`_.
+        * Generic tag decoding.
+        * `Shared value`_ references including cyclic references.
+        * Optional C module backend tested on big- and little-endian 
architectures.
+        * Extensible `tagged value handling`_ using ``tag_hook`` and 
``object_hook`` on decode and ``default`` on encode.
+        * Command-line diagnostic tool, converting CBOR file or stream to JSON 
``python -m cbor2.tool``
+          (This is a lossy conversion, for diagnostics only)
+        * Thorough test suite.
+        
+        .. _CBOR tags: 
https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml
+        .. _stdlib objects: 
https://cbor2.readthedocs.io/en/latest/usage.html#tag-support
+        .. _Shared value: http://cbor.schmorp.de/value-sharing
+        .. _tagged value handling: 
https://cbor2.readthedocs.io/en/latest/customizing.html#using-the-cbor-tags-for-custom-types
+        
+        Installation
+        ============
+        
+        ::
+        
+            pip install cbor2
+        
+        Requirements
+        ------------
+        
+        * cPython==2.7 or cPython>=3.5 or `PyPy`_ (Python 2.7 and 3.5 support 
will be removed with release 6.0.0)
+        * C-extension: Any C compiler that can build Python extensions.
+          Any modern libc with the exception of Glibc<2.9
+        
+        .. _PyPy: https://www.pypy.org/
+        
+        Building the C-Extension
+        ------------------------
+        
+        To force building of the optional C-extension, set OS env 
``CBOR2_BUILD_C_EXTENSION=1``.
+        To disable building of the optional C-extension, set OS env 
``CBOR2_BUILD_C_EXTENSION=0``.
+        If this environment variable is unset, setup.py will default to auto 
detecting a compatible C library and
+        attempt to compile the extension.
+        
+        
+        Usage
+        =====
+        
+        `Basic Usage 
<https://cbor2.readthedocs.io/en/latest/usage.html#basic-usage>`_
+        
+        Command-line Usage
+        ==================
+        
+        ``python -m cbor2.tool`` converts CBOR data in raw binary or base64 
encoding into
+        a representation that allows printing as JSON. This is a lossy 
transformation as
+        each datatype is converted into something that can be represented as a 
JSON value.
+        
+        Usage::
+        
+            # Pass hexadecimal through xxd.
+            $ echo a16568656c6c6f65776f726c64 | xxd -r -ps | python -m 
cbor2.tool --pretty
+            {
+                "hello": "world"
+            }
+            # Decode Base64 directly
+            $ echo ggEC | python -m cbor2.tool --decode
+            [1, 2]
+            # Read from a file encoded in Base64
+            $ python -m cbor2.tool -d tests/examples.cbor.b64
+            {...}
+        
+        It can be used in a pipeline with json processing tools like `jq`_ to 
allow syntax
+        coloring, field extraction and more.
+        
+        CBOR data items concatenated into a sequence can be decoded also::
+        
+            $ echo ggECggMEggUG | python -m cbor2.tool -d --sequence
+            [1, 2]
+            [3, 4]
+            [5, 6]
+        
+        Multiple files can also be sent to a single output file::
+        
+            $ python -m cbor2.tool -o all_files.json file1.cbor file2.cbor ... 
fileN.cbor
+        
+        .. _jq: https://stedolan.github.io/jq/
+        
+        Security
+        ========
+        
+        This library has not been tested against malicious input. In theory it 
should be
+        as safe as JSON, since unlike ``pickle`` the decoder does not execute 
any code.
+        
 Keywords: serialization cbor
 Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cbor2-5.1.2/README.rst new/cbor2-5.2.0/README.rst
--- old/cbor2-5.1.2/README.rst  2020-07-21 18:59:30.000000000 +0200
+++ new/cbor2-5.2.0/README.rst  2020-09-30 11:59:25.000000000 +0200
@@ -8,14 +8,107 @@
   :target: https://cbor2.readthedocs.io/en/latest/?badge=latest
   :alt: Documentation Status
 
+About
+=====
+
+.. warning:: This project will be ending it's support of Python 3.5 and lower 
with release 6.0.0. Version 5.2 will be the last version tested on Python 2.7 
and 3.5
+
 This library provides encoding and decoding for the Concise Binary Object 
Representation (CBOR)
 (`RFC 7049`_) serialization format. `Read the docs 
<https://cbor2.readthedocs.io/>`_ to learn more.
 
-It is implemented in pure python with an optional C backend and is compatible 
with versions 2.7 through to 3.7.
-
-On cPython>=3.3 cbor2 can use a built in C module for performance similar to 
how ``pickle``
-wraps the ``_pickle`` C module in the Python Standard Library. On Windows, 
this is restricted to cPython>=3.5.
+It is implemented in pure python with an optional C backend.
 
 On PyPy, cbor2 runs with almost identical performance to the C backend.
 
 .. _RFC 7049: https://tools.ietf.org/html/rfc7049
+
+Features
+--------
+
+* Simple api like ``json`` or ``pickle`` modules.
+* Support many `CBOR tags`_ with `stdlib objects`_.
+* Generic tag decoding.
+* `Shared value`_ references including cyclic references.
+* Optional C module backend tested on big- and little-endian architectures.
+* Extensible `tagged value handling`_ using ``tag_hook`` and ``object_hook`` 
on decode and ``default`` on encode.
+* Command-line diagnostic tool, converting CBOR file or stream to JSON 
``python -m cbor2.tool``
+  (This is a lossy conversion, for diagnostics only)
+* Thorough test suite.
+
+.. _CBOR tags: https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml
+.. _stdlib objects: 
https://cbor2.readthedocs.io/en/latest/usage.html#tag-support
+.. _Shared value: http://cbor.schmorp.de/value-sharing
+.. _tagged value handling: 
https://cbor2.readthedocs.io/en/latest/customizing.html#using-the-cbor-tags-for-custom-types
+
+Installation
+============
+
+::
+
+    pip install cbor2
+
+Requirements
+------------
+
+* cPython==2.7 or cPython>=3.5 or `PyPy`_ (Python 2.7 and 3.5 support will be 
removed with release 6.0.0)
+* C-extension: Any C compiler that can build Python extensions.
+  Any modern libc with the exception of Glibc<2.9
+
+.. _PyPy: https://www.pypy.org/
+
+Building the C-Extension
+------------------------
+
+To force building of the optional C-extension, set OS env 
``CBOR2_BUILD_C_EXTENSION=1``.
+To disable building of the optional C-extension, set OS env 
``CBOR2_BUILD_C_EXTENSION=0``.
+If this environment variable is unset, setup.py will default to auto detecting 
a compatible C library and
+attempt to compile the extension.
+
+
+Usage
+=====
+
+`Basic Usage <https://cbor2.readthedocs.io/en/latest/usage.html#basic-usage>`_
+
+Command-line Usage
+==================
+
+``python -m cbor2.tool`` converts CBOR data in raw binary or base64 encoding 
into
+a representation that allows printing as JSON. This is a lossy transformation 
as
+each datatype is converted into something that can be represented as a JSON 
value.
+
+Usage::
+
+    # Pass hexadecimal through xxd.
+    $ echo a16568656c6c6f65776f726c64 | xxd -r -ps | python -m cbor2.tool 
--pretty
+    {
+        "hello": "world"
+    }
+    # Decode Base64 directly
+    $ echo ggEC | python -m cbor2.tool --decode
+    [1, 2]
+    # Read from a file encoded in Base64
+    $ python -m cbor2.tool -d tests/examples.cbor.b64
+    {...}
+
+It can be used in a pipeline with json processing tools like `jq`_ to allow 
syntax
+coloring, field extraction and more.
+
+CBOR data items concatenated into a sequence can be decoded also::
+
+    $ echo ggECggMEggUG | python -m cbor2.tool -d --sequence
+    [1, 2]
+    [3, 4]
+    [5, 6]
+
+Multiple files can also be sent to a single output file::
+
+    $ python -m cbor2.tool -o all_files.json file1.cbor file2.cbor ... 
fileN.cbor
+
+.. _jq: https://stedolan.github.io/jq/
+
+Security
+========
+
+This library has not been tested against malicious input. In theory it should 
be
+as safe as JSON, since unlike ``pickle`` the decoder does not execute any code.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cbor2-5.1.2/cbor2/decoder.py 
new/cbor2-5.2.0/cbor2/decoder.py
--- old/cbor2-5.1.2/cbor2/decoder.py    2020-07-21 18:59:30.000000000 +0200
+++ new/cbor2-5.2.0/cbor2/decoder.py    2020-09-30 11:59:25.000000000 +0200
@@ -276,11 +276,11 @@
                 else:
                     items.append(value)
         else:
-            items = [None] * length
+            items = []
             if not self._immutable:
                 self.set_shareable(items)
             for index in range(length):
-                items[index] = self._decode()
+                items.append(self._decode())
 
         if self._immutable:
             items = tuple(items)
@@ -300,15 +300,6 @@
                     break
                 else:
                     dictionary[key] = self._decode(unshared=True)
-        elif self._share_index is None:
-            # Optimization: pre-allocate structures from length. Note this
-            # cannot be done when sharing the structure as the resulting
-            # structure is not the one initially allocated
-            seq = [None] * length
-            for index in range(length):
-                key = self._decode(immutable=True, unshared=True)
-                seq[index] = (key, self._decode(unshared=True))
-            dictionary = dict(seq)
         else:
             dictionary = {}
             self.set_shareable(dictionary)
@@ -485,6 +476,10 @@
                     break
         raise CBORDecodeValueError("invalid ipnetwork value %r" % net_map)
 
+    def decode_self_describe_cbor(self):
+        # Semantic tag 55799
+        return self._decode()
+
     #
     # Special decoders (major tag 7)
     #
@@ -532,21 +527,22 @@
 }
 
 semantic_decoders = {
-    0:   CBORDecoder.decode_datetime_string,
-    1:   CBORDecoder.decode_epoch_datetime,
-    2:   CBORDecoder.decode_positive_bignum,
-    3:   CBORDecoder.decode_negative_bignum,
-    4:   CBORDecoder.decode_fraction,
-    5:   CBORDecoder.decode_bigfloat,
-    28:  CBORDecoder.decode_shareable,
-    29:  CBORDecoder.decode_sharedref,
-    30:  CBORDecoder.decode_rational,
-    35:  CBORDecoder.decode_regexp,
-    36:  CBORDecoder.decode_mime,
-    37:  CBORDecoder.decode_uuid,
-    258: CBORDecoder.decode_set,
-    260: CBORDecoder.decode_ipaddress,
-    261: CBORDecoder.decode_ipnetwork,
+    0:     CBORDecoder.decode_datetime_string,
+    1:     CBORDecoder.decode_epoch_datetime,
+    2:     CBORDecoder.decode_positive_bignum,
+    3:     CBORDecoder.decode_negative_bignum,
+    4:     CBORDecoder.decode_fraction,
+    5:     CBORDecoder.decode_bigfloat,
+    28:    CBORDecoder.decode_shareable,
+    29:    CBORDecoder.decode_sharedref,
+    30:    CBORDecoder.decode_rational,
+    35:    CBORDecoder.decode_regexp,
+    36:    CBORDecoder.decode_mime,
+    37:    CBORDecoder.decode_uuid,
+    258:   CBORDecoder.decode_set,
+    260:   CBORDecoder.decode_ipaddress,
+    261:   CBORDecoder.decode_ipnetwork,
+    55799: CBORDecoder.decode_self_describe_cbor,
 }
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cbor2-5.1.2/cbor2/tool.py 
new/cbor2-5.2.0/cbor2/tool.py
--- old/cbor2-5.1.2/cbor2/tool.py       1970-01-01 01:00:00.000000000 +0100
+++ new/cbor2-5.2.0/cbor2/tool.py       2020-09-30 11:59:25.000000000 +0200
@@ -0,0 +1,225 @@
+r"""Command-line tool for CBOR diagnostics and testing"""
+import argparse
+import base64
+import decimal
+import fractions
+import io
+import json
+import re
+import sys
+import uuid
+from collections import OrderedDict
+from datetime import datetime
+from functools import partial
+
+from . import CBORDecoder, load
+from .types import FrozenDict
+
+try:
+    from _cbor2 import CBORSimpleValue, CBORTag, undefined
+except ImportError:
+    from .types import CBORSimpleValue, CBORTag, undefined
+
+try:
+    import ipaddress
+
+    default_encoders = OrderedDict(
+        [
+            (ipaddress.IPv4Address, str),
+            (ipaddress.IPv6Address, str),
+            (ipaddress.IPv4Network, str),
+            (ipaddress.IPv6Network, str),
+        ]
+    )
+except ImportError:
+    default_encoders = OrderedDict()
+
+
+default_encoders.update(
+    [
+        (bytes, lambda x: x.decode(encoding='utf-8', 
errors='backslashreplace')),
+        (decimal.Decimal, str),
+        (FrozenDict, lambda x: str(dict(x))),
+        (CBORSimpleValue, lambda x: 'cbor_simple:{:d}'.format(x.value)),
+        (type(undefined), lambda x: 'cbor:undef'),
+        (datetime, lambda x: x.isoformat()),
+        (fractions.Fraction, str),
+        (uuid.UUID, lambda x: x.urn),
+        (CBORTag, lambda x: {'CBORTag:{:d}'.format(x.tag): x.value}),
+        (set, list),
+        (re.compile('').__class__, lambda x: x.pattern),
+    ]
+)
+
+
+def tag_hook(decoder, tag, ignore_tags=set()):
+    if tag.tag in ignore_tags:
+        return tag.value
+    if tag.tag == 24:
+        return decoder.decode_from_bytes(tag.value)
+    else:
+        if decoder.immutable:
+            return 'CBORtag:{}:{}'.format(tag.tag, tag.value)
+        return tag
+
+
+class DefaultEncoder(json.JSONEncoder):
+    def default(self, v):
+        obj_type = v.__class__
+        encoder = default_encoders.get(obj_type)
+        if encoder:
+            return encoder(v)
+        return json.JSONEncoder.default(self, v)
+
+
+def iterdecode(f, *args, **kwargs):
+    decoder = CBORDecoder(f, *args, **kwargs)
+    while True:
+        try:
+            yield decoder.decode()
+        except EOFError:
+            return
+
+
+def key_to_str(d, dict_ids=None):
+    dict_ids = set(dict_ids or [])
+    rval = {}
+    if not isinstance(d, dict):
+        if isinstance(d, CBORSimpleValue):
+            v = 'cbor_simple:{:d}'.format(d.value)
+            return v
+        if isinstance(d, (tuple, list, set)):
+            if id(d) in dict_ids:
+                raise ValueError("Cannot convert self-referential data to 
JSON")
+            else:
+                dict_ids.add(id(d))
+            v = [key_to_str(x, dict_ids) for x in d]
+            dict_ids.remove(id(d))
+            return v
+        else:
+            return d
+
+    if id(d) in dict_ids:
+        raise ValueError("Cannot convert self-referential data to JSON")
+    else:
+        dict_ids.add(id(d))
+
+    for k, v in d.items():
+        if isinstance(k, bytes):
+            k = k.decode(encoding='utf-8', errors='backslashreplace')
+        if isinstance(k, CBORSimpleValue):
+            k = 'cbor_simple:{:d}'.format(k.value)
+        if isinstance(k, (FrozenDict, frozenset, tuple)):
+            k = str(k)
+        if isinstance(v, dict):
+            v = key_to_str(v, dict_ids)
+        elif isinstance(v, (tuple, list, set)):
+            v = [key_to_str(x, dict_ids) for x in v]
+        rval[k] = v
+    return rval
+
+
+def main():
+    prog = 'python -m cbor2.tool'
+    description = (
+        'A simple command line interface for cbor2 module '
+        'to validate and pretty-print CBOR objects.'
+    )
+    parser = argparse.ArgumentParser(prog=prog, description=description)
+    parser.add_argument(
+        '-o', '--outfile', type=str, help='output file', default='-'
+    )
+    parser.add_argument(
+        'infiles',
+        nargs='*',
+        type=argparse.FileType('rb'),
+        help='Collection of CBOR files to process or - for stdin',
+    )
+    parser.add_argument(
+        '-k',
+        '--sort-keys',
+        action='store_true',
+        default=False,
+        help='sort the output of dictionaries alphabetically by key',
+    )
+    parser.add_argument(
+        '-p',
+        '--pretty', action='store_true', default=False, help='indent the 
output to look good'
+    )
+    parser.add_argument(
+        '-s',
+        '--sequence',
+        action='store_true',
+        default=False,
+        help='Parse a sequence of concatenated CBOR items',
+    )
+    parser.add_argument(
+        '-d',
+        '--decode',
+        action='store_true',
+        default=False,
+        help='CBOR data is base64 encoded (handy for stdin)',
+    )
+    parser.add_argument(
+        '-i',
+        '--tag-ignore',
+        type=str,
+        help='Comma separated list of tags to ignore and only return the 
value',
+    )
+    options = parser.parse_args()
+
+    outfile = options.outfile
+    sort_keys = options.sort_keys
+    pretty = options.pretty
+    sequence = options.sequence
+    decode = options.decode
+    infiles = options.infiles or [sys.stdin]
+
+    closefd = True
+    if outfile == '-':
+        outfile = 1
+        closefd = False
+
+    if sys.version_info < (3, 3):
+        opener = dict(mode='wb', closefd=closefd)
+        dumpargs = dict(ensure_ascii=True, encoding='raw_unicode_escape')
+    else:
+        opener = dict(mode='w', encoding='utf-8', errors='backslashescape', 
closefd=closefd)
+        dumpargs = dict(ensure_ascii=False)
+
+    if options.tag_ignore:
+        ignore_s = options.tag_ignore.split(',')
+        droptags = set(int(n) for n in ignore_s if (len(n) and n[0].isdigit()))
+    else:
+        droptags = set()
+
+    my_hook = partial(tag_hook, ignore_tags=droptags)
+
+    with io.open(outfile, **opener) as outfile:
+        for infile in infiles:
+            if hasattr(infile, 'buffer') and not decode:
+                infile = infile.buffer
+            with infile:
+                if decode:
+                    infile = io.BytesIO(base64.b64decode(infile.read()))
+                try:
+                    if sequence:
+                        objs = iterdecode(infile, tag_hook=my_hook)
+                    else:
+                        objs = (load(infile, tag_hook=my_hook),)
+                    for obj in objs:
+                        json.dump(
+                            key_to_str(obj),
+                            outfile,
+                            sort_keys=sort_keys,
+                            indent=(None, 4)[pretty],
+                            cls=DefaultEncoder,
+                            **dumpargs
+                        )
+                        outfile.write('\n')
+                except (ValueError, EOFError) as e:  # pragma: no cover
+                    raise SystemExit(e)
+
+
+if __name__ == '__main__':  # pragma: no cover
+    main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cbor2-5.1.2/cbor2.egg-info/PKG-INFO 
new/cbor2-5.2.0/cbor2.egg-info/PKG-INFO
--- old/cbor2-5.1.2/cbor2.egg-info/PKG-INFO     2020-07-21 18:59:46.000000000 
+0200
+++ new/cbor2-5.2.0/cbor2.egg-info/PKG-INFO     2020-09-30 11:59:41.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: cbor2
-Version: 5.1.2
+Version: 5.2.0
 Summary: Pure Python CBOR (de)serializer with extensive tag support
 Home-page: UNKNOWN
 Author: Alex Gr??nholm
@@ -21,18 +21,111 @@
           :target: https://cbor2.readthedocs.io/en/latest/?badge=latest
           :alt: Documentation Status
         
+        About
+        =====
+        
+        .. warning:: This project will be ending it's support of Python 3.5 
and lower with release 6.0.0. Version 5.2 will be the last version tested on 
Python 2.7 and 3.5
+        
         This library provides encoding and decoding for the Concise Binary 
Object Representation (CBOR)
         (`RFC 7049`_) serialization format. `Read the docs 
<https://cbor2.readthedocs.io/>`_ to learn more.
         
-        It is implemented in pure python with an optional C backend and is 
compatible with versions 2.7 through to 3.7.
-        
-        On cPython>=3.3 cbor2 can use a built in C module for performance 
similar to how ``pickle``
-        wraps the ``_pickle`` C module in the Python Standard Library. On 
Windows, this is restricted to cPython>=3.5.
+        It is implemented in pure python with an optional C backend.
         
         On PyPy, cbor2 runs with almost identical performance to the C backend.
         
         .. _RFC 7049: https://tools.ietf.org/html/rfc7049
         
+        Features
+        --------
+        
+        * Simple api like ``json`` or ``pickle`` modules.
+        * Support many `CBOR tags`_ with `stdlib objects`_.
+        * Generic tag decoding.
+        * `Shared value`_ references including cyclic references.
+        * Optional C module backend tested on big- and little-endian 
architectures.
+        * Extensible `tagged value handling`_ using ``tag_hook`` and 
``object_hook`` on decode and ``default`` on encode.
+        * Command-line diagnostic tool, converting CBOR file or stream to JSON 
``python -m cbor2.tool``
+          (This is a lossy conversion, for diagnostics only)
+        * Thorough test suite.
+        
+        .. _CBOR tags: 
https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml
+        .. _stdlib objects: 
https://cbor2.readthedocs.io/en/latest/usage.html#tag-support
+        .. _Shared value: http://cbor.schmorp.de/value-sharing
+        .. _tagged value handling: 
https://cbor2.readthedocs.io/en/latest/customizing.html#using-the-cbor-tags-for-custom-types
+        
+        Installation
+        ============
+        
+        ::
+        
+            pip install cbor2
+        
+        Requirements
+        ------------
+        
+        * cPython==2.7 or cPython>=3.5 or `PyPy`_ (Python 2.7 and 3.5 support 
will be removed with release 6.0.0)
+        * C-extension: Any C compiler that can build Python extensions.
+          Any modern libc with the exception of Glibc<2.9
+        
+        .. _PyPy: https://www.pypy.org/
+        
+        Building the C-Extension
+        ------------------------
+        
+        To force building of the optional C-extension, set OS env 
``CBOR2_BUILD_C_EXTENSION=1``.
+        To disable building of the optional C-extension, set OS env 
``CBOR2_BUILD_C_EXTENSION=0``.
+        If this environment variable is unset, setup.py will default to auto 
detecting a compatible C library and
+        attempt to compile the extension.
+        
+        
+        Usage
+        =====
+        
+        `Basic Usage 
<https://cbor2.readthedocs.io/en/latest/usage.html#basic-usage>`_
+        
+        Command-line Usage
+        ==================
+        
+        ``python -m cbor2.tool`` converts CBOR data in raw binary or base64 
encoding into
+        a representation that allows printing as JSON. This is a lossy 
transformation as
+        each datatype is converted into something that can be represented as a 
JSON value.
+        
+        Usage::
+        
+            # Pass hexadecimal through xxd.
+            $ echo a16568656c6c6f65776f726c64 | xxd -r -ps | python -m 
cbor2.tool --pretty
+            {
+                "hello": "world"
+            }
+            # Decode Base64 directly
+            $ echo ggEC | python -m cbor2.tool --decode
+            [1, 2]
+            # Read from a file encoded in Base64
+            $ python -m cbor2.tool -d tests/examples.cbor.b64
+            {...}
+        
+        It can be used in a pipeline with json processing tools like `jq`_ to 
allow syntax
+        coloring, field extraction and more.
+        
+        CBOR data items concatenated into a sequence can be decoded also::
+        
+            $ echo ggECggMEggUG | python -m cbor2.tool -d --sequence
+            [1, 2]
+            [3, 4]
+            [5, 6]
+        
+        Multiple files can also be sent to a single output file::
+        
+            $ python -m cbor2.tool -o all_files.json file1.cbor file2.cbor ... 
fileN.cbor
+        
+        .. _jq: https://stedolan.github.io/jq/
+        
+        Security
+        ========
+        
+        This library has not been tested against malicious input. In theory it 
should be
+        as safe as JSON, since unlike ``pickle`` the decoder does not execute 
any code.
+        
 Keywords: serialization cbor
 Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cbor2-5.1.2/cbor2.egg-info/SOURCES.txt 
new/cbor2-5.2.0/cbor2.egg-info/SOURCES.txt
--- old/cbor2-5.1.2/cbor2.egg-info/SOURCES.txt  2020-07-21 18:59:46.000000000 
+0200
+++ new/cbor2-5.2.0/cbor2.egg-info/SOURCES.txt  2020-09-30 11:59:41.000000000 
+0200
@@ -9,6 +9,7 @@
 cbor2/compat.py
 cbor2/decoder.py
 cbor2/encoder.py
+cbor2/tool.py
 cbor2/types.py
 cbor2.egg-info/PKG-INFO
 cbor2.egg-info/SOURCES.txt
@@ -39,6 +40,9 @@
 source/tags.c
 source/tags.h
 tests/conftest.py
+tests/examples.cbor.b64
+tests/examples.json
 tests/test_decoder.py
 tests/test_encoder.py
+tests/test_tool.py
 tests/test_types.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cbor2-5.1.2/docs/index.rst 
new/cbor2-5.2.0/docs/index.rst
--- old/cbor2-5.1.2/docs/index.rst      2020-07-21 18:59:30.000000000 +0200
+++ new/cbor2-5.2.0/docs/index.rst      2020-09-30 11:59:25.000000000 +0200
@@ -1,6 +1,5 @@
 .. include:: ../README.rst
-   :start-line: 7
-   :end-before: Project links
+   :start-line: 10
 
 Table of contents
 -----------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cbor2-5.1.2/docs/usage.rst 
new/cbor2-5.2.0/docs/usage.rst
--- old/cbor2-5.1.2/docs/usage.rst      2020-07-21 18:59:30.000000000 +0200
+++ new/cbor2-5.2.0/docs/usage.rst      2020-09-30 11:59:25.000000000 +0200
@@ -72,28 +72,38 @@
 
 In addition to all standard CBOR tags, this library supports many extended 
tags:
 
-=== ======================================== 
====================================================
-Tag Semantics                                Python type(s)
-=== ======================================== 
====================================================
-0   Standard date/time string                datetime.date / datetime.datetime
-1   Epoch-based date/time                    datetime.date / datetime.datetime
-2   Positive bignum                          int / long
-3   Negative bignum                          int / long
-4   Decimal fraction                         decimal.Decimal
-5   Bigfloat                                 decimal.Decimal
-28  Mark shared value                        N/A
-29  Reference shared value                   N/A
-30  Rational number                          fractions.Fraction
-35  Regular expression                       ``_sre.SRE_Pattern`` (result of 
``re.compile(...)``)
-36  MIME message                             email.message.Message
-37  Binary UUID                              uuid.UUID
-258 Set of unique items                      set
-260 Network address                          :class:`ipaddress.IPv4Address` 
(or IPv6)
-261 Network prefix                           :class:`ipaddress.IPv4Network` 
(or IPv6)
-=== ======================================== 
====================================================
+===== ======================================== 
====================================================
+Tag   Semantics                                Python type(s)
+===== ======================================== 
====================================================
+0     Standard date/time string                datetime.date / 
datetime.datetime
+1     Epoch-based date/time                    datetime.date / 
datetime.datetime
+2     Positive bignum                          int / long
+3     Negative bignum                          int / long
+4     Decimal fraction                         decimal.Decimal
+5     Bigfloat                                 decimal.Decimal
+28    Mark shared value                        N/A
+29    Reference shared value                   N/A
+30    Rational number                          fractions.Fraction
+35    Regular expression                       ``_sre.SRE_Pattern`` (result of 
``re.compile(...)``)
+36    MIME message                             email.message.Message
+37    Binary UUID                              uuid.UUID
+258   Set of unique items                      set
+260   Network address                          :class:`ipaddress.IPv4Address` 
(or IPv6)
+261   Network prefix                           :class:`ipaddress.IPv4Network` 
(or IPv6)
+55799 Self-Described CBOR                      object
+===== ======================================== 
====================================================
 
 Arbitary tags can be represented with the :class:`~cbor2.types.CBORTag` class.
 
+If you want to write a file that is detected as CBOR by the Unix ``file`` 
utility, wrap your data in
+a `~cbor2.types.CBORTag` object like so::
+
+    from cbor2 import dump, CBORTag
+
+    with open('output.cbor', 'wb') as fp:
+        dump(CBORTag(55799, obj), fp)
+
+This will be ignored on decode and the original data content will be returned.
 
 Use Cases
 ---------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cbor2-5.1.2/docs/versionhistory.rst 
new/cbor2-5.2.0/docs/versionhistory.rst
--- old/cbor2-5.1.2/docs/versionhistory.rst     2020-07-21 18:59:30.000000000 
+0200
+++ new/cbor2-5.2.0/docs/versionhistory.rst     2020-09-30 11:59:25.000000000 
+0200
@@ -5,6 +5,15 @@
 
 This library adheres to `Semantic Versioning <http://semver.org/>`_.
 
+**5.2.0** (2020-09-30)
+
+- Final version tested with Python 2.7 and 3.5
+- README: Announce deprecation of Python 2.7, 3.5
+- README: More detail and examples
+- Bugfix: Fix segfault on loading huge arrays with C-backend (Sekenre)
+- Build system: Allow packagers to force C-backend building or disable using 
env var (jameshilliard)
+- Feature: :module:`cbor2.tool` Command line diagnostic tool (Sekenre)
+- Feature: Ignore semantic tag used for file magic 55799 AKA "Self-Described 
CBOR" (kalcutter)
 
 **5.1.2** (2020-07-21)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cbor2-5.1.2/setup.py new/cbor2-5.2.0/setup.py
--- old/cbor2-5.1.2/setup.py    2020-07-21 18:59:30.000000000 +0200
+++ new/cbor2-5.2.0/setup.py    2020-09-30 11:59:25.000000000 +0200
@@ -1,11 +1,15 @@
 import sys
 import os
 import platform
+import warnings
 from pkg_resources import parse_version
 from setuptools import setup, Extension
 
 min_glibc = parse_version('2.9')
 
+if sys.version_info < (3, 6):
+    warnings.warn("Support for Python<3.6 will be dropped with cbor2 version 
6.0.0")
+
 
 def check_libc():
     "check that if we have glibc < 2.9 we should not build c ext"
@@ -27,7 +31,13 @@
 windows = sys.platform.startswith('win')
 min_win_version = sys.version_info >= (3, 5)
 min_unix_version = sys.version_info >= (3, 3)
-build_c_ext = cpython and ((windows and min_win_version) or (check_libc() and 
min_unix_version))
+use_c_ext = os.environ.get("CBOR2_BUILD_C_EXTENSION", None)
+if use_c_ext == "1":
+    build_c_ext = True
+elif use_c_ext == "0":
+    build_c_ext = False
+else:
+    build_c_ext = cpython and ((windows and min_win_version) or (check_libc() 
and min_unix_version))
 
 # Enable GNU features for libc's like musl, should have no effect
 # on Apple/BSDs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cbor2-5.1.2/source/decoder.c 
new/cbor2-5.2.0/source/decoder.c
--- old/cbor2-5.1.2/source/decoder.c    2020-07-21 18:59:30.000000000 +0200
+++ new/cbor2-5.2.0/source/decoder.c    2020-09-30 11:59:25.000000000 +0200
@@ -61,6 +61,7 @@
 static PyObject * CBORDecoder_decode_float64(CBORDecoderObject *);
 static PyObject * CBORDecoder_decode_ipaddress(CBORDecoderObject *);
 static PyObject * CBORDecoder_decode_ipnetwork(CBORDecoderObject *);
+static PyObject * CBORDecoder_decode_self_describe_cbor(CBORDecoderObject *);
 
 static PyObject * CBORDecoder_decode_shareable(CBORDecoderObject *);
 static PyObject * CBORDecoder_decode_sharedref(CBORDecoderObject *);
@@ -344,7 +345,7 @@
         obj = PyObject_CallFunctionObjArgs(self->read, size_obj, NULL);
         if (obj) {
             assert(PyBytes_CheckExact(obj));
-            if (PyBytes_GET_SIZE(obj) == size) {
+            if (PyBytes_GET_SIZE(obj) == (Py_ssize_t) size) {
                 data = PyBytes_AS_STRING(obj);
                 memcpy(buf, data, size);
                 ret = 0;
@@ -698,55 +699,94 @@
 
 
 static PyObject *
-decode_definite_array(CBORDecoderObject *self, uint64_t length)
+decode_definite_array(CBORDecoderObject *self, Py_ssize_t length)
 {
     Py_ssize_t i;
     PyObject *array, *item, *ret = NULL;
 
-    if (length > PY_SSIZE_T_MAX) {
+    if (length > PY_SSIZE_T_MAX || length < 0) {
         PyErr_Format(
                 _CBOR2_CBORDecodeValueError,
                 "excessive array size %llu", length);
         return NULL;
-    }
-    if (self->immutable) {
-        array = PyTuple_New(length);
+    } else if (length > 65536) {
+        // Let cPython manage allocation of huge lists by appending
+        // items one-by-one
+        array = PyList_New(0);
         if (array) {
             ret = array;
-            for (i = 0; i < (Py_ssize_t) length; ++i) {
+            set_shareable(self, array);
+            for (i = 0; i < length; ++i) {
                 item = decode(self, DECODE_UNSHARED);
-                if (item)
-                    PyTuple_SET_ITEM(array, i, item);
-                else {
+                if (item) {
+                    if (PyList_Append(array, item) == -1) {
+                        ret = NULL;
+                        Py_DECREF(item);
+                        break;
+                    }
+                    Py_DECREF(item);
+                } else {
                     ret = NULL;
                     break;
                 }
             }
+            if (ret && self->immutable) {
+                ret = PyList_AsTuple(array);
+                if (ret) {
+                    Py_DECREF(array);
+                    // There's a potential here for an indefinite length 
recursive
+                    // array to wind up with a strange representation (the 
outer
+                    // being a tuple, the inners all being a list). However, a
+                    // recursive tuple isn't valid in the first place so it's 
a bit
+                    // of a waste of time searching for recursive references 
just
+                    // to throw an error
+                    set_shareable(self, ret);
+                } else
+                    ret = NULL;
+            }
+            if (!ret)
+                Py_DECREF(array);
         }
-        // This is done *after* the construction of the tuple because while
-        // it's valid for a tuple object to be shared, it's not valid for it to
-        // contain a reference to itself (because a reference to it can't exist
-        // during its own construction ... in Python at least; as can be seen
-        // above this *is* theoretically possible at the C level).
-        set_shareable(self, ret);
     } else {
-        array = PyList_New(length);
-        if (array) {
-            ret = array;
-            set_shareable(self, array);
-            for (i = 0; i < (Py_ssize_t) length; ++i) {
-                item = decode(self, DECODE_UNSHARED);
-                if (item)
-                    PyList_SET_ITEM(array, i, item);
-                else {
-                    ret = NULL;
-                    break;
+        if (self->immutable) {
+            array = PyTuple_New(length);
+            if (array) {
+                ret = array;
+                for (i = 0; i < length; ++i) {
+                    item = decode(self, DECODE_UNSHARED);
+                    if (item)
+                        PyTuple_SET_ITEM(array, i, item);
+                    else {
+                        ret = NULL;
+                        break;
+                    }
+                }
+            }
+            // This is done *after* the construction of the tuple because while
+            // it's valid for a tuple object to be shared, it's not valid for 
it to
+            // contain a reference to itself (because a reference to it can't 
exist
+            // during its own construction ... in Python at least; as can be 
seen
+            // above this *is* theoretically possible at the C level).
+            set_shareable(self, ret);
+        } else {
+            array = PyList_New(length);
+            if (array) {
+                ret = array;
+                set_shareable(self, array);
+                for (i = 0; i < length; ++i) {
+                    item = decode(self, DECODE_UNSHARED);
+                    if (item)
+                        PyList_SET_ITEM(array, i, item);
+                    else {
+                        ret = NULL;
+                        break;
+                    }
                 }
             }
         }
+        if (!ret)
+            Py_DECREF(array);
     }
-    if (!ret)
-        Py_DECREF(array);
     return ret;
 }
 
@@ -763,7 +803,7 @@
     if (indefinite)
         return decode_indefinite_array(self);
     else
-        return decode_definite_array(self, length);
+        return decode_definite_array(self, (Py_ssize_t) length);
 }
 
 
@@ -851,21 +891,24 @@
 
     if (decode_length(self, subtype, &tagnum, NULL) == 0) {
         switch (tagnum) {
-            case 0:   ret = CBORDecoder_decode_datetime_string(self); break;
-            case 1:   ret = CBORDecoder_decode_epoch_datetime(self);  break;
-            case 2:   ret = CBORDecoder_decode_positive_bignum(self); break;
-            case 3:   ret = CBORDecoder_decode_negative_bignum(self); break;
-            case 4:   ret = CBORDecoder_decode_fraction(self);        break;
-            case 5:   ret = CBORDecoder_decode_bigfloat(self);        break;
-            case 28:  ret = CBORDecoder_decode_shareable(self);       break;
-            case 29:  ret = CBORDecoder_decode_sharedref(self);       break;
-            case 30:  ret = CBORDecoder_decode_rational(self);        break;
-            case 35:  ret = CBORDecoder_decode_regexp(self);          break;
-            case 36:  ret = CBORDecoder_decode_mime(self);            break;
-            case 37:  ret = CBORDecoder_decode_uuid(self);            break;
-            case 258: ret = CBORDecoder_decode_set(self);             break;
-            case 260: ret = CBORDecoder_decode_ipaddress(self);       break;
-            case 261: ret = CBORDecoder_decode_ipnetwork(self);       break;
+            case 0:     ret = CBORDecoder_decode_datetime_string(self); break;
+            case 1:     ret = CBORDecoder_decode_epoch_datetime(self);  break;
+            case 2:     ret = CBORDecoder_decode_positive_bignum(self); break;
+            case 3:     ret = CBORDecoder_decode_negative_bignum(self); break;
+            case 4:     ret = CBORDecoder_decode_fraction(self);        break;
+            case 5:     ret = CBORDecoder_decode_bigfloat(self);        break;
+            case 28:    ret = CBORDecoder_decode_shareable(self);       break;
+            case 29:    ret = CBORDecoder_decode_sharedref(self);       break;
+            case 30:    ret = CBORDecoder_decode_rational(self);        break;
+            case 35:    ret = CBORDecoder_decode_regexp(self);          break;
+            case 36:    ret = CBORDecoder_decode_mime(self);            break;
+            case 37:    ret = CBORDecoder_decode_uuid(self);            break;
+            case 258:   ret = CBORDecoder_decode_set(self);             break;
+            case 260:   ret = CBORDecoder_decode_ipaddress(self);       break;
+            case 261:   ret = CBORDecoder_decode_ipnetwork(self);       break;
+            case 55799: ret = CBORDecoder_decode_self_describe_cbor(self);
+                break;
+
             default:
                 tag = CBORTag_New(tagnum);
                 if (tag) {
@@ -1398,6 +1441,15 @@
     return ret;
 }
 
+
+// CBORDecoder.decode_self_describe_cbor(self)
+static PyObject *
+CBORDecoder_decode_self_describe_cbor(CBORDecoderObject *self)
+{
+    // semantic tag 55799
+    return decode(self, DECODE_NORMAL);
+}
+
 
 // Special decoders //////////////////////////////////////////////////////////
 
@@ -1690,6 +1742,10 @@
         "decode a set or frozenset from the input"},
     {"decode_ipaddress", (PyCFunction) CBORDecoder_decode_ipaddress, 
METH_NOARGS,
         "decode an IPv4Address or IPv6Address from the input"},
+    {"decode_ipnetwork", (PyCFunction) CBORDecoder_decode_ipnetwork, 
METH_NOARGS,
+        "decode an IPv4Network or IPv6Network from the input"},
+    {"decode_self_describe_cbor", (PyCFunction) 
CBORDecoder_decode_self_describe_cbor, METH_NOARGS,
+        "decode a data item after a self-describe CBOR tag"},
     {"decode_simple_value",
         (PyCFunction) CBORDecoder_decode_simple_value, METH_NOARGS,
         "decode a CBORSimpleValue from the input"},
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cbor2-5.1.2/tests/examples.cbor.b64 
new/cbor2-5.2.0/tests/examples.cbor.b64
--- old/cbor2-5.1.2/tests/examples.cbor.b64     1970-01-01 01:00:00.000000000 
+0100
+++ new/cbor2-5.2.0/tests/examples.cbor.b64     2020-09-30 11:59:25.000000000 
+0200
@@ -0,0 +1,12 @@
+s2VieXRlc4NARAECAwRCwsJoZGVjaW1hbHOFxIIiGTcrxIIiOTcq+X4A+XwA+fwAaGRpY3Rfa2V5
+gaGhAgFgZmZsb2F0c4b7P/GZmZmZmZr7fjfkPIgAdZz7wBBmZmZmZmb5fAD5fgD5/ABoZnJhY3Rp
+b26B2B6CAgVoaW50ZWdlcnORAAEKFxgYGGQZA+gaAA9CQBsAAADo1KUQABv//////////8JJAQAA
+AAAAAAAAO///////////w0kBAAAAAAAAAAAgKThjOQPnZmlwYWRkcoLZAQREwAoKAdkBBFAgAQ24
+haMAAAAAii4DcHM0ZWlwbmV0gtkBBaFEwKgAABgY2QEFoVAgAQ24haMAAAAAii4AAAAAGGBlcmVn
+ZXiB2CNtaGVsbG8gKHdvcmxkKWdzaW1wbGVzhODi8/ggaHNwZWNpYWxzhPT19vdnc3RyaW5nc4Zg
+YWFkSUVURmIiXGLDvGPmsLRmdGFnZ2VkgdkXcGVIZWxsb2p0aW1lc3RhbXBzh8B0MjAxMy0wMy0y
+MVQyMDowNDowMFrAeBsyMDEzLTAzLTIxVDIwOjA0OjAwLjM4MDg0MVrAeBkyMDEzLTAzLTIxVDIy
+OjA0OjAwKzAyOjAwwHQyMDEzLTAzLTIxVDIwOjA0OjAwWsB0MjAxMy0wMy0yMVQyMDowNDowMFrA
+eBsyMDEzLTAzLTIxVDIwOjA0OjAwLjEyMzQ1NlrAdDIwMTMtMDMtMjFUMjA6MDQ6MDBaaXR1cGxl
+X2tleYGhggIBYGR1dWlkgdglUF6v+si1HkgFgSd/3MeEL69qc2ltcGxlX2tleYGh+GP2anRhZ19h
+c19rZXmBodkXd2xub3RpbXBvcnRhbnT2aGVtYmVkZGVkgdgYSYRhYWFiYWNhZA==
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cbor2-5.1.2/tests/examples.json 
new/cbor2-5.2.0/tests/examples.json
--- old/cbor2-5.1.2/tests/examples.json 1970-01-01 01:00:00.000000000 +0100
+++ new/cbor2-5.2.0/tests/examples.json 2020-09-30 11:59:25.000000000 +0200
@@ -0,0 +1,120 @@
+{
+    "bytes": [
+        "",
+        "\u0001\u0002\u0003\u0004",
+        "\\xc2\\xc2"
+    ],
+    "decimals": [
+        "14.123",
+        "-14.123",
+        NaN,
+        Infinity,
+        -Infinity
+    ],
+    "dict_key": [
+        {
+            "FrozenDict({2: 1})": ""
+        }
+    ],
+    "embedded": [
+        [
+            "a",
+            "b",
+            "c",
+            "d"
+        ]
+    ],
+    "floats": [
+        1.1,
+        1e+300,
+        -4.1,
+        Infinity,
+        NaN,
+        -Infinity
+    ],
+    "fraction": [
+        "2/5"
+    ],
+    "integers": [
+        0,
+        1,
+        10,
+        23,
+        24,
+        100,
+        1000,
+        1000000,
+        1000000000000,
+        18446744073709551615,
+        18446744073709551616,
+        -18446744073709551616,
+        -18446744073709551617,
+        -1,
+        -10,
+        -100,
+        -1000
+    ],
+    "ipaddr": [
+        "192.10.10.1",
+        "2001:db8:85a3::8a2e:370:7334"
+    ],
+    "ipnet": [
+        "192.168.0.0/24",
+        "2001:db8:85a3::8a2e:0:0/96"
+    ],
+    "regex": [
+        "hello (world)"
+    ],
+    "simple_key": [
+        {
+            "cbor_simple:99": null
+        }
+    ],
+    "simples": [
+        "cbor_simple:0",
+        "cbor_simple:2",
+        "cbor_simple:19",
+        "cbor_simple:32"
+    ],
+    "specials": [
+        false,
+        true,
+        null,
+        "cbor:undef"
+    ],
+    "strings": [
+        "",
+        "a",
+        "IETF",
+        "\"\\",
+        "??",
+        "???"
+    ],
+    "tag_as_key": [
+        {
+            "CBORtag:6007:notimportant": null
+        }
+    ],
+    "tagged": [
+        {
+            "CBORTag:6000": "Hello"
+        }
+    ],
+    "timestamps": [
+        "2013-03-21T20:04:00+00:00",
+        "2013-03-21T20:04:00.380841+00:00",
+        "2013-03-21T22:04:00+02:00",
+        "2013-03-21T20:04:00+00:00",
+        "2013-03-21T20:04:00+00:00",
+        "2013-03-21T20:04:00.123456+00:00",
+        "2013-03-21T20:04:00+00:00"
+    ],
+    "tuple_key": [
+        {
+            "(2, 1)": ""
+        }
+    ],
+    "uuid": [
+        "urn:uuid:5eaffac8-b51e-4805-8127-7fdcc7842faf"
+    ]
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cbor2-5.1.2/tests/test_decoder.py 
new/cbor2-5.2.0/tests/test_decoder.py
--- old/cbor2-5.1.2/tests/test_decoder.py       2020-07-21 18:59:30.000000000 
+0200
+++ new/cbor2-5.2.0/tests/test_decoder.py       2020-09-30 11:59:25.000000000 
+0200
@@ -501,10 +501,7 @@
 
 def test_uninitialized_shared_reference(impl):
     with pytest.raises(impl.CBORDecodeError) as exc:
-        # encode a set of a recursive array; the set forces the embedded array
-        # to be decoded as a recursive tuple which is impossible, and leads to
-        # the expected error
-        impl.loads(unhexlify('d90102d81c81d81d00'))
+        impl.loads(unhexlify('D81CA1D81D014161'))
         assert str(exc.value).endswith('shared value 0 has not been 
initialized')
         assert isinstance(exc, ValueError)
 
@@ -531,6 +528,14 @@
     assert decoded == {0: decoded}
 
 
[email protected]('payload, expected', [
+    ('d9d9f71903e8', 1000),
+    ('d9d9f7c249010000000000000000', 18446744073709551616),
+], ids=['self_describe_cbor+int', 'self_describe_cbor+positive_bignum'])
+def test_self_describe_cbor(impl, payload, expected):
+    assert impl.loads(unhexlify(payload)) == expected
+
+
 def test_unhandled_tag(impl):
     """
     Test that a tag is simply ignored and its associated value returned if 
there is no special
@@ -626,3 +631,18 @@
 def test_immutable_keys(impl, payload, expected):
     value = impl.loads(unhexlify(payload))
     assert value == expected
+
+
+def test_huge_truncated_array(impl):
+    with pytest.raises(impl.CBORDecodeEOF):
+        impl.loads(unhexlify('9b37388519251ae9ca'))
+
+
+def test_huge_truncated_bytes(impl):
+    with pytest.raises((impl.CBORDecodeEOF, MemoryError)):
+        impl.loads(unhexlify('5b37388519251ae9ca'))
+
+
+def test_huge_truncated_string(impl):
+    with pytest.raises((impl.CBORDecodeEOF, MemoryError)):
+        impl.loads(unhexlify('7B37388519251ae9ca'))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cbor2-5.1.2/tests/test_tool.py 
new/cbor2-5.2.0/tests/test_tool.py
--- old/cbor2-5.1.2/tests/test_tool.py  1970-01-01 01:00:00.000000000 +0100
+++ new/cbor2-5.2.0/tests/test_tool.py  2020-09-30 11:59:25.000000000 +0200
@@ -0,0 +1,140 @@
+from __future__ import unicode_literals
+import pytest
+import sys
+import binascii
+import json
+from io import BytesIO, TextIOWrapper
+
+import cbor2.tool
+
+
[email protected](
+    'value, expected',
+    [
+        ((1, 2, 3), [1, 2, 3]),
+        ({b"\x01\x02\x03": "b"}, {"\x01\x02\x03": "b"}),
+        ({"dict": {"b": 17}}, {"dict": {"b": 17}}),
+    ],
+    ids=['tuple', 'byte_key', 'recursion'],
+)
+def test_key_to_str(value, expected):
+    assert cbor2.tool.key_to_str(value) == expected
+
+
+def test_default():
+    with pytest.raises(TypeError):
+        json.dumps(BytesIO(b''), cls=cbor2.tool.DefaultEncoder)
+
+
[email protected](
+    'payload', ["D81CA16162D81CA16161D81D00", "d81c81d81c830102d81d00"], 
ids=['dict', 'list']
+)
+def test_self_referencing(payload):
+    decoded = cbor2.loads(binascii.unhexlify(payload))
+    with pytest.raises(ValueError, match="Cannot convert self-referential data 
to JSON"):
+        cbor2.tool.key_to_str(decoded)
+
+
+def test_nonrecursive_ref():
+    payload = 'd81c83d81ca26162d81ca16161016163d81d02d81d01d81d01'
+    decoded = cbor2.loads(binascii.unhexlify(payload))
+    result = cbor2.tool.key_to_str(decoded)
+    expected = [
+        {"b": {"a": 1}, "c": {"a": 1}},
+        {"b": {"a": 1}, "c": {"a": 1}},
+        {"b": {"a": 1}, "c": {"a": 1}},
+    ]
+    assert result == expected
+
+
+def test_stdin(monkeypatch, tmpdir):
+    f = tmpdir.join('outfile')
+    argv = ['-o', str(f)]
+    inbuf = TextIOWrapper(BytesIO(binascii.unhexlify('02')))
+    with monkeypatch.context() as m:
+        m.setattr('sys.argv', [''] + argv)
+        m.setattr('sys.stdin', inbuf)
+        cbor2.tool.main()
+        assert f.read() == '2\n'
+
+
+def test_stdout(monkeypatch, tmpdir):
+    argv = ['-o', '-']
+    inbuf = TextIOWrapper(BytesIO(binascii.unhexlify('02')))
+    outbuf = BytesIO()
+    with monkeypatch.context() as m:
+        m.setattr('sys.argv', [''] + argv)
+        m.setattr('sys.stdin', inbuf)
+        m.setattr('sys.stdout', outbuf)
+        cbor2.tool.main()
+
+
+def test_readfrom(monkeypatch, tmpdir):
+    f = tmpdir.join('infile')
+    outfile = tmpdir.join('outfile')
+    f.write_binary(binascii.unhexlify('02'))
+    argv = ['-o', str(outfile), str(f)]
+    with monkeypatch.context() as m:
+        m.setattr('sys.argv', [''] + argv)
+        cbor2.tool.main()
+        assert outfile.read() == '2\n'
+
+
+def test_b64(monkeypatch, tmpdir):
+    f = tmpdir.join('outfile')
+    argv = ['-d', '-o', str(f)]
+    inbuf = TextIOWrapper(BytesIO(b'oQID'))
+    with monkeypatch.context() as m:
+        m.setattr('sys.argv', [''] + argv)
+        m.setattr('sys.stdin', inbuf)
+        cbor2.tool.main()
+        assert f.read() == '{"2": 3}\n'
+
+
+def test_stream(monkeypatch, tmpdir):
+    f = tmpdir.join('outfile')
+    argv = ['--sequence', '-o', str(f)]
+    inbuf = TextIOWrapper(BytesIO(binascii.unhexlify('0203')))
+    with monkeypatch.context() as m:
+        m.setattr('sys.argv', [''] + argv)
+        m.setattr('sys.stdin', inbuf)
+        cbor2.tool.main()
+        assert f.read() == '2\n3\n'
+
+
+def test_embed_bytes(monkeypatch, tmpdir):
+    f = tmpdir.join('outfile')
+    argv = ['-o', str(f)]
+    inbuf = TextIOWrapper(BytesIO(binascii.unhexlify('42C2C2')))
+    expected = b'"\\u00c2\\u00c2"\n' if sys.version_info < (3, 3) else 
'"\\\\xc2\\\\xc2"\n'
+    with monkeypatch.context() as m:
+        m.setattr('sys.argv', [''] + argv)
+        m.setattr('sys.stdin', inbuf)
+        cbor2.tool.main()
+        assert f.read() == expected
+
+
[email protected](
+    sys.version_info < (3, 3), reason="Requires CPython > 3.3"
+)
+def test_dtypes_from_file(monkeypatch, tmpdir):
+    infile = 'tests/examples.cbor.b64'
+    expected = open('tests/examples.json', 'r').read()
+    outfile = tmpdir.join('outfile.json')
+    argv = ['--sort-keys', '--pretty', '-d', '-o', str(outfile), infile]
+    with monkeypatch.context() as m:
+        m.setattr('sys.argv', [''] + argv)
+        cbor2.tool.main()
+        assert outfile.read() == expected
+
+
+def test_ignore_tag(monkeypatch, tmpdir):
+    f = tmpdir.join('outfile')
+    argv = ['-o', str(f), '-i', '6000']
+    inbuf = TextIOWrapper(BytesIO(binascii.unhexlify('D917706548656C6C6F')))
+    expected = '"Hello"\n'
+    with monkeypatch.context() as m:
+        m.setattr('sys.argv', [''] + argv)
+        m.setattr('sys.stdin', inbuf)
+        cbor2.tool.main()
+        assert f.read() == expected
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cbor2-5.1.2/tox.ini new/cbor2-5.2.0/tox.ini
--- old/cbor2-5.1.2/tox.ini     2020-07-21 18:59:30.000000000 +0200
+++ new/cbor2-5.2.0/tox.ini     2020-09-30 11:59:25.000000000 +0200
@@ -1,5 +1,5 @@
 [tox]
-envlist = py27, py35, py36, py37, py38, pypy, pypy3, flake8
+envlist = py27, py35, py36, py37, py38-clib, py38-noclib, pypy, pypy3, flake8
 skip_missing_interpreters = true
 
 [testenv]
@@ -10,3 +10,11 @@
 deps = flake8
 commands = flake8 cbor2 tests
 skip_install = true
+
+[testenv:py38-clib]
+setenv =
+    CBOR2_BUILD_C_EXTENSION = 1
+
+[testenv:py38-noclib]
+setenv =
+    CBOR2_BUILD_C_EXTENSION = 0

Reply via email to