Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-testfixtures for
openSUSE:Factory checked in at 2022-11-15 13:18:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-testfixtures (Old)
and /work/SRC/openSUSE:Factory/.python-testfixtures.new.1597 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-testfixtures"
Tue Nov 15 13:18:12 2022 rev:23 rq:1035575 version:7.0.3
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-testfixtures/python-testfixtures.changes
2022-10-10 18:44:23.970847600 +0200
+++
/work/SRC/openSUSE:Factory/.python-testfixtures.new.1597/python-testfixtures.changes
2022-11-15 13:20:54.740641820 +0100
@@ -1,0 +2,14 @@
+Wed Nov 9 19:29:23 UTC 2022 - Yogalakshmi Arunachalam <[email protected]>
+
+- Update to 7.0.3 (3 Nov 2022)
+ * Further bugfixes around self-referential datastructures and
:func:`compare`.
+
+- Update to 7.0.2 (1 Nov 2022)
+ * Reinstate support for self-referential data structures in :func:`compare`.
The new implementation provides more clarity about
+ what's going on and also ignores more immutable data types.
+
+- Update to 7.0.1 (1 Nov 2022)
+ * Remove non-functional support for self-referential data structures in
:func:`compare`. The functionality didn't work but did cause
+ erroneous reported equality of values in dictionaries that were actually
not equal.
+
+-------------------------------------------------------------------
Old:
----
testfixtures-7.0.0.tar.gz
New:
----
testfixtures-7.0.3.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-testfixtures.spec ++++++
--- /var/tmp/diff_new_pack.V6R3YQ/_old 2022-11-15 13:20:55.144643906 +0100
+++ /var/tmp/diff_new_pack.V6R3YQ/_new 2022-11-15 13:20:55.152643948 +0100
@@ -16,10 +16,9 @@
#
-%{?!python_module:%define python_module() python3-%{**}}
%define skip_python2 1
Name: python-testfixtures
-Version: 7.0.0
+Version: 7.0.3
Release: 0
Summary: A collection of helpers and mock objects for unit tests and
doc tests
License: MIT
++++++ testfixtures-7.0.0.tar.gz -> testfixtures-7.0.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/testfixtures-7.0.0/CHANGELOG.rst
new/testfixtures-7.0.3/CHANGELOG.rst
--- old/testfixtures-7.0.0/CHANGELOG.rst 2022-07-06 09:40:25.000000000
+0200
+++ new/testfixtures-7.0.3/CHANGELOG.rst 2022-11-03 11:37:48.000000000
+0100
@@ -1,6 +1,25 @@
Changes
=======
+7.0.3 (3 Nov 2022)
+------------------
+
+- Further bugfixes around self-referential datastructures and :func:`compare`.
+
+7.0.2 (1 Nov 2022)
+------------------
+
+- Reinstate support for self-referential data structures in :func:`compare`.
+ The new implementation provides more clarity about what's going on and also
ignores more
+ immutable data types.
+
+7.0.1 (1 Nov 2022)
+------------------
+
+- Remove non-functional support for self-referential data structures in
:func:`compare`.
+ The functionality didn't work but did cause erroneous reported equality of
values in dictionaries
+ that were actually not equal.
+
7.0.0 (6 Jul 2022)
------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/testfixtures-7.0.0/PKG-INFO
new/testfixtures-7.0.3/PKG-INFO
--- old/testfixtures-7.0.0/PKG-INFO 2022-07-06 09:40:31.347435000 +0200
+++ new/testfixtures-7.0.3/PKG-INFO 2022-11-03 11:37:55.922026200 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: testfixtures
-Version: 7.0.0
+Version: 7.0.3
Summary: A collection of helpers and mock objects for unit tests and doc tests.
Home-page: https://github.com/Simplistix/testfixtures
Author: Chris Withers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/testfixtures-7.0.0/testfixtures/comparison.py
new/testfixtures-7.0.3/testfixtures/comparison.py
--- old/testfixtures-7.0.0/testfixtures/comparison.py 2022-07-06
09:40:25.000000000 +0200
+++ new/testfixtures-7.0.3/testfixtures/comparison.py 2022-11-03
11:37:48.000000000 +0100
@@ -19,6 +19,10 @@
from unittest.mock import call as unittest_mock_call
+# Some common types that are immutable, for optimisation purposes within
CompareContext
+IMMUTABLE_TYPEs = str, bytes, int, float, tuple, type(None)
+
+
def diff(x: str, y: str, x_label: str = '', y_label: str = ''):
"""
A shorthand function that uses :mod:`difflib` to return a
@@ -148,6 +152,8 @@
Return a textual description of the difference between two objects
including information about their types.
"""
+ if type(x) is AlreadySeen and type(x.obj) is type(y) and x.obj == y:
+ return ''
source = locals()
to_render = {}
for name in 'x', 'y':
@@ -486,6 +492,23 @@
_unsafe_iterables = str, bytes, dict
+class AlreadySeen:
+
+ def __init__(self, id_, obj, breadcrumb):
+ self.id = id_
+ self.obj = obj
+ self.breadcrumb = breadcrumb
+
+ def __repr__(self):
+ return f'<AlreadySeen for {self.obj!r} at {self.breadcrumb} with id
{self.id}>'
+
+ def __eq__(self, other):
+ if isinstance(other, AlreadySeen):
+ return self.breadcrumb == other.breadcrumb
+ else:
+ return self.obj == other
+
+
class CompareContext(object):
def __init__(
@@ -511,7 +534,7 @@
self.options: Dict[str, Any] = options or {}
self.message: str = ''
self.breadcrumbs: List[str] = []
- self._seen = set()
+ self._seen = {}
def extract_args(self, args: tuple, x: Any, y: Any, expected: Any, actual:
Any) -> List:
@@ -572,22 +595,23 @@
def _separator(self) -> str:
return '\n\nWhile comparing %s: ' % ''.join(self.breadcrumbs[1:])
- def seen(self, x: Any, y: Any) -> bool:
- # don't get confused by interning:
- singleton_types = str, bytes, int, float
- if isinstance(x, singleton_types) and isinstance(y, singleton_types):
- return False
- key = id(x), id(y)
- if key in self._seen:
- return True
- self._seen.add(key)
+ def _break_loops(self, obj, breadcrumb):
+ # Don't bother with this process for simple, immutable types:
+ if isinstance(obj, IMMUTABLE_TYPEs):
+ return obj
+
+ id_ = id(obj)
+ breadcrumb_ = self._seen.get(id_)
+ if breadcrumb_ is not None:
+ return AlreadySeen(id_, obj, breadcrumb_)
+ else:
+ self._seen[id_] = breadcrumb
+ return obj
def different(self, x: Any, y: Any, breadcrumb: str) -> Union[bool,
Optional[str]]:
- if self.seen(x, y):
- # a self-referential hierarchy; so lets say this one is
- # equal and hope the first time we saw it covers things...
- return False
+ x = self._break_loops(x, breadcrumb)
+ y = self._break_loops(y, breadcrumb)
recursed = bool(self.breadcrumbs)
self.breadcrumbs.append(breadcrumb)
@@ -596,18 +620,18 @@
current_message = ''
try:
- if not (self.strict or self.ignore_eq) and x == y:
- return False
+ if type(y) is AlreadySeen or not (self.strict or self.ignore_eq):
+ try:
+ if x == y:
+ return False
+ except RecursionError:
+ pass
comparer: Comparer = self._lookup(x, y)
result = comparer(x, y, self)
specific_comparer = comparer is not compare_simple
- if self.strict:
- if x == y and not specific_comparer:
- return False
-
if result:
if specific_comparer and recursed:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/testfixtures-7.0.0/testfixtures/tests/test_compare.py
new/testfixtures-7.0.3/testfixtures/tests/test_compare.py
--- old/testfixtures-7.0.0/testfixtures/tests/test_compare.py 2022-07-06
09:40:25.000000000 +0200
+++ new/testfixtures-7.0.3/testfixtures/tests/test_compare.py 2022-11-03
11:37:48.000000000 +0100
@@ -395,6 +395,27 @@
"'y': 1.0 != 2.0"
)
+ def test_dict_identical_none_matching_nones_and_ones(self):
+ self.check_raises(
+ {
+ 'foo': None,
+ 'baz': None,
+ },
+ {
+ 'foo': 1,
+ 'baz': 1,
+ },
+ "dict not as expected:\n"
+ "\n"
+ 'values differ:\n'
+ "'baz': None != 1\n"
+ "'foo': None != 1\n"
+ '\n'
+ "While comparing ['baz']: None != 1\n"
+ "\n"
+ "While comparing ['foo']: None != 1"
+ )
+
def test_dict_labels_specified(self):
self.check_raises(
dict(x=1, y=2), dict(x=2, z=3),
@@ -949,7 +970,7 @@
"second:\n[2]"
)
- def test_strict_okay(self):
+ def test_same_object_strict_okay(self):
m = object()
compare(m, m, strict=True)
@@ -1538,6 +1559,20 @@
m.foo(1, 2, x=3)
compare(m.mock_calls, m.mock_calls, strict=True)
+ def test_mock_call_equal(self):
+ m1 = Mock()
+ m1.foo(1, 2, x=3)
+ m2 = Mock()
+ m2.foo(1, 2, x=3)
+ compare(m1.mock_calls, m2.mock_calls)
+
+ def test_mock_call_equal_strict(self):
+ m1 = Mock()
+ m1.foo(1, 2, x=3)
+ m2 = Mock()
+ m2.foo(1, 2, x=3)
+ compare(m1.mock_calls, m2.mock_calls, strict=True)
+
def test_calls_different(self):
m1 = Mock()
m2 = Mock()
@@ -1897,6 +1932,146 @@
'Both x and y appear as "re.compile(\''+'a'*199+')", but are not
equal!'
)
+ def test_self_referential_same(self):
+ expected = {1: 'foo'}
+ expected[2] = expected
+ actual = {1: 'foo'}
+ actual[2] = actual
+ compare(expected, actual)
+
+ def test_self_referential_different(self):
+ expected = {1: 'foo'}
+ expected[2] = expected
+ actual = {1: 'bar'}
+ actual[2] = actual
+ self.check_raises(
+ expected,
+ actual,
+ 'dict not as expected:\n'
+ '\n'
+ 'same:\n'
+ '[2]\n'
+ '\n'
+ 'values differ:\n'
+ "1: 'foo' != 'bar'\n"
+ '\n'
+ "While comparing [1]: 'foo' != 'bar'"
+ )
+
+ def test_self_referential_different_but_shows_already_seen(self):
+ ouroboros1 = {}
+ ouroboros1['ouroboros'] = ouroboros1
+ ouroboros2 = {}
+ ouroboros2['ouroboros'] = ouroboros2
+ id2 = str(id(ouroboros2))
+ self.check_raises(
+ {1: ouroboros1, 2: 'foo'},
+ {1: ouroboros2, 2: ouroboros2},
+ 'dict not as expected:\n'
+ '\n'
+ 'same:\n'
+ '[1]\n'
+ '\n'
+ 'values differ:\n'
+ "2: 'foo' != {'ouroboros': <Recursion on dict with id="+id2+">}\n"
+ '\n'
+ "While comparing [2]: 'foo' != "
+ "<AlreadySeen for {'ouroboros': {...}} at [1] with id "+id2+">"
+ )
+
+ def test_self_referential_object_tree(self):
+
+ class Node:
+
+ def __init__(self):
+ self.parent = None
+ self.children = []
+
+ def add(self, child: 'Node'):
+ self.children.append(child)
+ child.parent = self
+
+ def __repr__(self):
+ return f'<Node: {self.children}>'
+
+ expected = Node()
+ expected.add(Node())
+ expected.add(Node())
+
+ actual = Node()
+ actual.add(Node())
+
+ self.check_raises(
+ expected,
+ actual,
+ 'Node not as expected:\n'
+ '\n'
+ 'attributes same:\n'
+ "['parent']\n"
+ '\n'
+ 'attributes differ:\n'
+ "'children': [<Node: []>, <Node: []>] != [<Node: []>]\n"
+ '\n'
+ 'While comparing .children: sequence not as expected:\n'
+ '\n'
+ 'same:\n'
+ '[<Node: []>]\n'
+ '\n'
+ 'first:\n'
+ '[<Node: []>]\n'
+ '\n'
+ 'second:\n'
+ '[]'
+ )
+
+ def test_repeated_object_on_the_left_side_ignore_eq(self):
+ item = [1, 2, 3]
+ compare(expected=[item, item], actual=[[1, 2, 3], [1, 2, 3]],
ignore_eq=True)
+
+ def test_repeated_object_on_both_sides_ignore_eq(self):
+ item = [1, 2, 3]
+ compare(expected=[item, item], actual=[item, [1, 2, 3]],
ignore_eq=True)
+
+ def
test_repeated_object_on_both_sides_left_at_compare_strict_type_same(self):
+ item = [1, 2, 3]
+ compare(expected=[item, item], actual=[item, [1, 2, 3]], strict=True)
+
+ def
test_repeated_object_on_both_sides_right_at_compare_strict_type_same(self):
+ item = [1, 2, 3]
+ compare(expected=[item, [1, 2, 3]], actual=[item, item], strict=True)
+
+ def test_repeated_object_on_both_sides_strict_type_different(self):
+ item = [1, 2, 3]
+
+ class MyList(list):
+
+ def __repr__(self):
+ return f'<{type(self).__name__}:{super().__repr__()}>'
+
+ type_repr = repr(MyList)
+
+ self.check_raises(
+ [item, item],
+ [item, MyList((1, 2, 3))],
+ strict=True,
+ message = (
+ 'sequence not as expected:\n'
+ '\n'
+ 'same:\n'
+ '[[1, 2, 3]]\n'
+ '\n'
+ 'first:\n'
+ '[[1, 2, 3]]\n'
+ '\n'
+ 'second:\n'
+ '[<MyList:[1, 2, 3]>]\n'
+ '\n'
+ f"While comparing [1]: <AlreadySeen for [1, 2, 3] at ... "
+ f"(<class 'testfixtures.comparison.AlreadySeen'>) != "
+ f"<MyList:[1, 2, 3]> ({type_repr})"
+ )
+ )
+
class TestIgnore(CompareHelper):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/testfixtures-7.0.0/testfixtures/version.txt
new/testfixtures-7.0.3/testfixtures/version.txt
--- old/testfixtures-7.0.0/testfixtures/version.txt 2022-07-06
09:40:25.000000000 +0200
+++ new/testfixtures-7.0.3/testfixtures/version.txt 2022-11-03
11:37:48.000000000 +0100
@@ -1 +1 @@
-7.0.0
+7.0.3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/testfixtures-7.0.0/testfixtures.egg-info/PKG-INFO
new/testfixtures-7.0.3/testfixtures.egg-info/PKG-INFO
--- old/testfixtures-7.0.0/testfixtures.egg-info/PKG-INFO 2022-07-06
09:40:31.000000000 +0200
+++ new/testfixtures-7.0.3/testfixtures.egg-info/PKG-INFO 2022-11-03
11:37:55.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: testfixtures
-Version: 7.0.0
+Version: 7.0.3
Summary: A collection of helpers and mock objects for unit tests and doc tests.
Home-page: https://github.com/Simplistix/testfixtures
Author: Chris Withers