Hello community,
here is the log from the commit of package python-pytricia for openSUSE:Factory
checked in at 2020-03-20 23:57:17
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pytricia (Old)
and /work/SRC/openSUSE:Factory/.python-pytricia.new.3160 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pytricia"
Fri Mar 20 23:57:17 2020 rev:3 rq:786786 version:1.0.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pytricia/python-pytricia.changes
2019-06-06 18:16:50.640694432 +0200
+++
/work/SRC/openSUSE:Factory/.python-pytricia.new.3160/python-pytricia.changes
2020-03-21 00:02:03.081120732 +0100
@@ -1,0 +2,10 @@
+Fri Mar 20 08:48:03 UTC 2020 - [email protected]
+
+- version update to 1.0.1
+ * no upstream changelog
+- modified sources
+ % test.py (downloaded newer version)
+- deleted sources
+ - COPYING.LESSER (included in tarball)
+
+-------------------------------------------------------------------
Old:
----
COPYING.LESSER
pytricia-1.0.0.tar.gz
New:
----
pytricia-1.0.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-pytricia.spec ++++++
--- /var/tmp/diff_new_pack.HIO7DS/_old 2020-03-21 00:02:06.933122843 +0100
+++ /var/tmp/diff_new_pack.HIO7DS/_new 2020-03-21 00:02:06.941122848 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-pytricia
#
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -18,19 +18,17 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-pytricia
-Version: 1.0.0
+Version: 1.0.1
Release: 0
Summary: A library for IP address lookup in Python
License: LGPL-3.0-or-later
Group: Development/Languages/Python
-Url: https://github.com/jsommers/pytricia
+URL: https://github.com/jsommers/pytricia
Source:
https://files.pythonhosted.org/packages/source/p/pytricia/pytricia-%{version}.tar.gz
# https://github.com/jsommers/pytricia/issues/25
-Source1:
https://raw.githubusercontent.com/jsommers/pytricia/master/COPYING.LESSER
-# shorthened https://raw.githubusercontent.com/jsommers/pytricia/master/test.py
-# see https://github.com/jsommers/pytricia/issues/26
-Source2: test.py
+Source2:
https://raw.githubusercontent.com/jsommers/pytricia/master/test.py
BuildRequires: %{python_module devel}
+BuildRequires: %{python_module pytest}
BuildRequires: %{python_module setuptools}
BuildRequires: python-rpm-macros
%python_subpackages
@@ -42,7 +40,6 @@
%prep
%setup -q -n pytricia-%{version}
-cp %{SOURCE1} .
cp %{SOURCE2} .
%build
@@ -53,7 +50,7 @@
%python_install
%check
-%python_expand PYTHONPATH=%{buildroot}%{$python_sitearch} $python -m unittest
discover
+%pytest_arch test.py
%files %{python_files}
%license COPYING.LESSER
++++++ pytricia-1.0.0.tar.gz -> pytricia-1.0.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytricia-1.0.0/COPYING.LESSER
new/pytricia-1.0.1/COPYING.LESSER
--- old/pytricia-1.0.0/COPYING.LESSER 1970-01-01 01:00:00.000000000 +0100
+++ new/pytricia-1.0.1/COPYING.LESSER 2017-02-17 08:47:49.000000000 +0100
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytricia-1.0.0/MANIFEST.in
new/pytricia-1.0.1/MANIFEST.in
--- old/pytricia-1.0.0/MANIFEST.in 2016-01-30 14:28:45.000000000 +0100
+++ new/pytricia-1.0.1/MANIFEST.in 2019-01-16 14:00:35.000000000 +0100
@@ -4,3 +4,4 @@
include MANIFEST.in
include setup.py
include README.md
+include COPYING.LESSER
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytricia-1.0.0/PKG-INFO new/pytricia-1.0.1/PKG-INFO
--- old/pytricia-1.0.0/PKG-INFO 2017-10-26 19:58:00.000000000 +0200
+++ new/pytricia-1.0.1/PKG-INFO 2020-02-19 02:21:18.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: pytricia
-Version: 1.0.0
+Version: 1.0.1
Summary: An efficient IP address storage and lookup module for Python.
Home-page: https://github.com/jsommers/pytricia
Author: Joel Sommers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytricia-1.0.0/pytricia.c
new/pytricia-1.0.1/pytricia.c
--- old/pytricia-1.0.0/pytricia.c 2017-05-31 02:34:50.000000000 +0200
+++ new/pytricia-1.0.1/pytricia.c 2019-01-16 15:36:20.000000000 +0100
@@ -31,6 +31,7 @@
PyObject_HEAD
patricia_tree_t *m_tree;
int m_family;
+ u_short m_raw_output;
} PyTricia;
typedef struct {
@@ -183,6 +184,28 @@
pfx_rv = New_Prefix(AF_INET, &packed_addr, 32);
} else if (PyBytes_Check(key)) {
pfx_rv = _bytes_to_prefix(key);
+ } else if (PyTuple_Check(key)) {
+ PyObject* value = PyTuple_GetItem(key, 0);
+ PyObject* size = PyTuple_GetItem(key, 1);
+ if (!PyBytes_Check(value)) {
+ PyErr_SetString(PyExc_ValueError, "Invalid key tuple value type");
+ return NULL;
+ }
+ Py_ssize_t slen = PyBytes_Size(value);
+ if (slen != 4 && slen != 16) {
+ PyErr_SetString(PyExc_ValueError, "Invalid key tuple value");
+ return NULL;
+ }
+ pfx_rv = _bytes_to_prefix(value);
+ if (pfx_rv) {
+ if (!PyLong_Check(size)) {
+ PyErr_SetString(PyExc_ValueError, "Invalid key tuple size
type");
+ return NULL;
+ }
+ unsigned long bitlen = PyLong_AsUnsignedLong(size);
+ if (bitlen < pfx_rv->bitlen)
+ pfx_rv->bitlen = bitlen;
+ }
}
#if PY_MINOR_VERSION >= 4
// do we have an IPv4/6Address or IPv4/6Network object (ipaddress
@@ -234,6 +257,29 @@
} else if (PyLong_Check(key) || PyInt_Check(key)) {
unsigned long packed_addr = htonl(PyInt_AsUnsignedLongMask(key));
pfx_rv = New_Prefix(AF_INET, &packed_addr, 32);
+ } else if (PyTuple_Check(key)) {
+ PyObject* value = PyTuple_GetItem(key, 0);
+ PyObject* size = PyTuple_GetItem(key, 1);
+ if (!PyString_Check(value)) {
+ PyErr_SetString(PyExc_ValueError, "Invalid key tuple value type");
+ return NULL;
+ }
+ Py_ssize_t slen = PyString_Size(value);
+ if (slen != 4 && slen != 16) {
+ PyErr_SetString(PyExc_ValueError, "Invalid key tuple value");
+ return NULL;
+ }
+ char* temp = PyString_AsString(value);
+ pfx_rv = _packed_addr_to_prefix(temp, slen);
+ if (pfx_rv) {
+ if (!PyLong_Check(size) && !PyInt_Check(size)) {
+ PyErr_SetString(PyExc_ValueError, "Invalid key tuple size
type");
+ return NULL;
+ }
+ unsigned long bitlen = PyInt_AsLong(size);
+ if (bitlen < pfx_rv->bitlen)
+ pfx_rv->bitlen = bitlen;
+ }
} else {
PyErr_SetString(PyExc_ValueError, "Invalid key type");
}
@@ -241,6 +287,32 @@
return pfx_rv;
}
+static PyObject *
+_prefix_to_key_object(prefix_t* prefix, int raw_output) {
+ if (raw_output) {
+ int addr_size;
+ char *addr = (char*) prefix_touchar(prefix);
+ if (prefix->family == AF_INET6) {
+ addr_size = 16;
+ } else {
+ addr_size = 4;
+ }
+ PyObject* value;
+#if PY_MAJOR_VERSION == 3
+ value = PyBytes_FromStringAndSize(addr, addr_size);
+#else
+ value = PyString_FromStringAndSize(addr, addr_size);
+#endif
+ PyObject* tuple;
+ tuple = Py_BuildValue("(Oi)", value, prefix->bitlen);
+ Py_XDECREF(value);
+ return tuple;
+ }
+ char buffer[64];
+ prefix_toa2x(prefix, buffer, 1);
+ return Py_BuildValue("s", buffer);
+}
+
static void
pytricia_xdecref(void *data) {
Py_XDECREF((PyObject*)data);
@@ -269,7 +341,8 @@
pytricia_init(PyTricia *self, PyObject *args, PyObject *kwds) {
int prefixlen = 32;
int family = AF_INET;
- if (!PyArg_ParseTuple(args, "|ii", &prefixlen, &family)) {
+ PyObject* raw_output = NULL;
+ if (!PyArg_ParseTuple(args, "|iiO", &prefixlen, &family, &raw_output)) {
self->m_tree = New_Patricia(1); // need to have *something* to dealloc
PyErr_SetString(PyExc_ValueError, "Error parsing prefix length or
address family");
return -1;
@@ -289,6 +362,7 @@
self->m_tree = New_Patricia(prefixlen);
self->m_family = family;
+ self->m_raw_output = raw_output && PyObject_IsTrue(raw_output);
if (self->m_tree == NULL) {
return -1;
}
@@ -495,9 +569,7 @@
Py_RETURN_NONE;
}
- char buffer[64];
- prefix_toa2x(node->prefix, buffer, 1);
- return Py_BuildValue("s", buffer);
+ return _prefix_to_key_object(node->prefix, obj->m_raw_output);
}
static int
@@ -544,9 +616,7 @@
int err = 0;
PATRICIA_WALK (self->m_tree->head, node) {
- char buffer[64];
- prefix_toa2x(node->prefix, buffer, 1);
- PyObject *item = Py_BuildValue("s", buffer);
+ PyObject *item = _prefix_to_key_object(node->prefix,
self->m_raw_output);
if (!item) {
Py_DECREF(rvlist);
return NULL;
@@ -583,30 +653,28 @@
patricia_node_t* base_node = patricia_search_exact(self->m_tree, prefix);
Deref_Prefix(prefix);
if (!base_node) {
- PyErr_SetString(PyExc_KeyError, "Prefix doesn't exist.");
- Py_DECREF(rvlist);
- return NULL;
+ PyErr_SetString(PyExc_KeyError, "Prefix doesn't exist.");
+ Py_DECREF(rvlist);
+ return NULL;
}
patricia_node_t* node = NULL;
int err = 0;
PATRICIA_WALK (base_node, node) {
- /* Discard first prefix (we want strict children) */
- if (node != base_node) {
- char buffer[64];
- prefix_toa2x(node->prefix, buffer, 1);
- PyObject *item = Py_BuildValue("s", buffer);
- if (!item) {
- Py_DECREF(rvlist);
- return NULL;
- }
- err = PyList_Append(rvlist, item);
- Py_DECREF(item);
- if (err != 0) {
- Py_DECREF(rvlist);
- return NULL;
- }
- }
+ /* Discard first prefix (we want strict children) */
+ if (node != base_node) {
+ PyObject *item = _prefix_to_key_object(node->prefix,
self->m_raw_output);
+ if (!item) {
+ Py_DECREF(rvlist);
+ return NULL;
+ }
+ err = PyList_Append(rvlist, item);
+ Py_DECREF(item);
+ if (err != 0) {
+ Py_DECREF(rvlist);
+ return NULL;
+ }
+ }
} PATRICIA_WALK_END;
return rvlist;
}
@@ -636,9 +704,7 @@
Py_RETURN_NONE;
}
- char buffer[64];
- prefix_toa2x(parent_node->prefix, buffer, 1);
- return Py_BuildValue("s", buffer);
+ return _prefix_to_key_object(parent_node->prefix, self->m_raw_output);
}
static PyMappingMethods pytricia_as_mapping = {
@@ -705,11 +771,7 @@
}
if (iter->m_Xnode->prefix) {
- /* build Python value to hand back */
- char buffer[64];
- prefix_toa2x(iter->m_Xnode->prefix, buffer, 1);
- PyObject *rv = Py_BuildValue("s", buffer);
- return rv;
+ return _prefix_to_key_object(iter->m_Xnode->prefix,
iter->m_parent->m_raw_output);
}
} else {
PyErr_SetNone(PyExc_StopIteration);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytricia-1.0.0/pytricia.egg-info/PKG-INFO
new/pytricia-1.0.1/pytricia.egg-info/PKG-INFO
--- old/pytricia-1.0.0/pytricia.egg-info/PKG-INFO 2017-10-26
19:58:00.000000000 +0200
+++ new/pytricia-1.0.1/pytricia.egg-info/PKG-INFO 2020-02-19
02:21:18.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: pytricia
-Version: 1.0.0
+Version: 1.0.1
Summary: An efficient IP address storage and lookup module for Python.
Home-page: https://github.com/jsommers/pytricia
Author: Joel Sommers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytricia-1.0.0/pytricia.egg-info/SOURCES.txt
new/pytricia-1.0.1/pytricia.egg-info/SOURCES.txt
--- old/pytricia-1.0.0/pytricia.egg-info/SOURCES.txt 2017-10-26
19:58:00.000000000 +0200
+++ new/pytricia-1.0.1/pytricia.egg-info/SOURCES.txt 2020-02-19
02:21:18.000000000 +0100
@@ -1,3 +1,4 @@
+COPYING.LESSER
MANIFEST.in
README.md
patricia.c
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytricia-1.0.0/setup.cfg new/pytricia-1.0.1/setup.cfg
--- old/pytricia-1.0.0/setup.cfg 2017-10-26 19:58:00.000000000 +0200
+++ new/pytricia-1.0.1/setup.cfg 2020-02-19 02:21:18.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/pytricia-1.0.0/setup.py new/pytricia-1.0.1/setup.py
--- old/pytricia-1.0.0/setup.py 2017-10-26 19:48:18.000000000 +0200
+++ new/pytricia-1.0.1/setup.py 2020-02-19 02:20:59.000000000 +0100
@@ -18,7 +18,7 @@
from setuptools import setup, Extension
setup(name="pytricia",
- version="1.0.0",
+ version="1.0.1",
description="An efficient IP address storage and lookup module for
Python.",
author="Joel Sommers",
author_email="[email protected]",
++++++ test.py ++++++
--- /var/tmp/diff_new_pack.HIO7DS/_old 2020-03-21 00:02:07.025122893 +0100
+++ /var/tmp/diff_new_pack.HIO7DS/_new 2020-03-21 00:02:07.025122893 +0100
@@ -411,4 +411,44 @@
self.assertFalse('1.2.3.0/24' in pyt)
+ def testRaw(self):
+ pyt = pytricia.PyTricia(32, socket.AF_INET, True)
+ prefixes = [
+ (b'\x01\x02\x00\x00', 16),
+ (b'\x01\x02\x02\x00', 24),
+ (b'\x01\x02\x03\x00', 24),
+ (b'\x01\x02\x03\x04', 32)
+ ]
+ values = ["A", "B", "C", "D"]
+ for prefix, value in zip(prefixes, values):
+ pyt.insert(prefix, value)
+
+ with self.assertRaises(ValueError) as cm:
+ pyt.insert((b'invalid', 24), "Z")
+ self.assertEqual(pyt.get_key((b'\x01\x02\x02\x02', 30)),
(b'\x01\x02\x02\x00', 24))
+ self.assertListEqual(sorted(pyt.keys()), sorted(prefixes))
+ self.assertEqual(pyt.parent((b'\x01\x02\x03\x04', 32)),
(b'\x01\x02\x03\x00', 24))
+ self.assertListEqual(list(pyt.children((b'\x01\x02\x03\x00', 24))),
[(b'\x01\x02\x03\x04', 32)])
+ self.assertListEqual(sorted(list(pyt)), sorted(prefixes))
+
+ def testRawIP6(self):
+ pyt = pytricia.PyTricia(128, socket.AF_INET6, True)
+ prefixes = [
+
(b'\xAA\xBB\xCC\xDD\xAA\xBB\xCC\xDD\xAA\xBB\xCC\xDD\x01\x02\x00\x00', 96+16),
+
(b'\xAA\xBB\xCC\xDD\xAA\xBB\xCC\xDD\xAA\xBB\xCC\xDD\x01\x02\x02\x00', 96+24),
+
(b'\xAA\xBB\xCC\xDD\xAA\xBB\xCC\xDD\xAA\xBB\xCC\xDD\x01\x02\x03\x00', 96+24),
+
(b'\xAA\xBB\xCC\xDD\xAA\xBB\xCC\xDD\xAA\xBB\xCC\xDD\x01\x02\x03\x04', 96+32)
+ ]
+ values = ["A", "B", "C", "D"]
+ for prefix, value in zip(prefixes, values):
+ pyt.insert(prefix, value)
+
+
self.assertEqual(pyt.get_key((b'\xAA\xBB\xCC\xDD\xAA\xBB\xCC\xDD\xAA\xBB\xCC\xDD\x01\x02\x02\x02',
96+30)), (b'\xAA\xBB\xCC\xDD\xAA\xBB\xCC\xDD\xAA\xBB\xCC\xDD\x01\x02\x02\x00',
96+24))
+ self.assertListEqual(sorted(pyt.keys()), sorted(prefixes))
+
self.assertEqual(pyt.parent((b'\xAA\xBB\xCC\xDD\xAA\xBB\xCC\xDD\xAA\xBB\xCC\xDD\x01\x02\x03\x04',
96+32)), (b'\xAA\xBB\xCC\xDD\xAA\xBB\xCC\xDD\xAA\xBB\xCC\xDD\x01\x02\x03\x00',
96+24))
+
self.assertListEqual(list(pyt.children((b'\xAA\xBB\xCC\xDD\xAA\xBB\xCC\xDD\xAA\xBB\xCC\xDD\x01\x02\x03\x00',
96+24))),
[(b'\xAA\xBB\xCC\xDD\xAA\xBB\xCC\xDD\xAA\xBB\xCC\xDD\x01\x02\x03\x04', 96+32)])
+ self.assertListEqual(sorted(list(pyt)), sorted(prefixes))
+
+if __name__ == '__main__':
+ unittest.main()