Skip to content

test_set_of_sets_reprs of test_pprint is silently ignored #111147

@sobolevn

Description

@sobolevn

Bug report

Right now this test is marked as expectedFailure with a big comment about why:

@unittest.expectedFailure
#See http://bugs.python.org/issue13907
@test.support.cpython_only
def test_set_of_sets_reprs(self):
# This test creates a complex arrangement of frozensets and
# compares the pretty-printed repr against a string hard-coded in
# the test. The hard-coded repr depends on the sort order of
# frozensets.
#
# However, as the docs point out: "Since sets only define
# partial ordering (subset relationships), the output of the
# list.sort() method is undefined for lists of sets."
#
# In a nutshell, the test assumes frozenset({0}) will always
# sort before frozenset({1}), but:
#
# >>> frozenset({0}) < frozenset({1})
# False
# >>> frozenset({1}) < frozenset({0})
# False
#
# Consequently, this test is fragile and
# implementation-dependent. Small changes to Python's sort
# algorithm cause the test to fail when it should pass.
# XXX Or changes to the dictionary implementation...

With self.maxDiff = None:

» ./python.exe -m test test_pprint -m test_set_of_sets_reprs
Using random seed 3151060862
0:00:00 load avg: 1.34 Run 1 test sequentially
0:00:00 load avg: 1.34 [1/1] test_pprint
test test_pprint failed -- Traceback (most recent call last):
  File "/Users/sobolev/Desktop/cpython/Lib/test/test_pprint.py", line 672, in test_set_of_sets_reprs
    self.assertEqual(pprint.pformat(cube), cube_repr_tgt)
AssertionError: '{fro[43 chars]set({1}), frozenset({0})}),\n frozenset({0}): [843 chars])})}' != '{fro[43 chars]set({0}), frozenset({1})}),\n frozenset({0}): [1017 chars])})}'
- {frozenset(): frozenset({frozenset({2}), frozenset({1}), frozenset({0})}),
-  frozenset({0}): frozenset({frozenset(), frozenset({0, 1}), frozenset({0, 2})}),
-  frozenset({1}): frozenset({frozenset(), frozenset({0, 1}), frozenset({1, 2})}),
? ^          ---                                       ---                ---
+ {frozenset(): frozenset({frozenset({2}), frozenset({0}), frozenset({1})}),
? ^                                  +++
+  frozenset({0}): frozenset({frozenset(),
+                             frozenset({0, 2}),
+                             frozenset({0, 1})}),
+  frozenset({1}): frozenset({frozenset(),
+                             frozenset({1, 2}),
+                             frozenset({0, 1})}),
+  frozenset({2}): frozenset({frozenset(),
+                             frozenset({1, 2}),
+                             frozenset({0, 2})}),
-  frozenset({0, 1}): frozenset({frozenset({1}),
?             ^  ^                          ^
+  frozenset({1, 2}): frozenset({frozenset({2}),
?             ^  ^                          ^
-                                frozenset({0}),
?                                           ^
+                                frozenset({1}),
?                                           ^
                                 frozenset({0, 1, 2})}),
-  frozenset({2}): frozenset({frozenset(), frozenset({0, 2}), frozenset({1, 2})}),
   frozenset({0, 2}): frozenset({frozenset({2}),
                                 frozenset({0}),
                                 frozenset({0, 1, 2})}),
-  frozenset({1, 2}): frozenset({frozenset({2}),
?              ---                          ^
+  frozenset({0, 1}): frozenset({frozenset({0}),
?             +++                           ^
                                 frozenset({1}),
                                 frozenset({0, 1, 2})}),
-  frozenset({0, 1, 2}): frozenset({frozenset({0, 1}),
?                                              ^  ^
+  frozenset({0, 1, 2}): frozenset({frozenset({1, 2}),
?                                              ^  ^
                                    frozenset({0, 2}),
-                                   frozenset({1, 2})})}
?                                               ---
+                                   frozenset({0, 1})})}
?                                              +++


test_pprint failed (1 failure)

== Tests result: FAILURE ==

1 test failed:
    test_pprint

Total duration: 38 ms
Total tests: run=1 (filtered) failures=1
Total test files: run=1/1 (filtered) failed=1
Result: FAILURE

There are several problems with this test:

  1. It creates an explicit relation with test_set because of an import:
    import test.test_set
    We try to revome such dependencies
  2. It does not work :)
  3. It is not very readable:
Снимок экрана 2023-10-21 в 08 49 09

Why is this test unstable? Because frozenset({0}) < frozenset({1}) is False and frozenset({1}) < frozenset({0}) is False. However, we can refator this test to use frozenset(), it is always ordered: frozenset() < frozenset({1, 2}) is True, frozenset() > frozenset({1, 2}) is False

So, my idea is to:

  • Refactor this test to still do pretty much the same
  • But reliably
  • With more readability
  • Without test_set dependency

Refs:

Linked PRs

Metadata

Metadata

Assignees

Labels

stdlibStandard Library Python modules in the Lib/ directorytestsTests in the Lib/test dirtype-bugAn unexpected behavior, bug, or error

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions