{"record":{"id":"5f7a441f15765152","repo":"apache/beam","slug":"failed-assert-r-r","errorCode":null,"errorMessage":"Failed assert: %r == %r","messagePattern":"Failed assert: %r == %r","errorType":"exception","errorClass":"BeamAssertException","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/testing/util.py","lineNumber":205,"sourceCode":"    # 2) As a fallback if we encounter a TypeError in python 3. this method\n    #    works on collections that have different types.\n    unexpected = []\n    for element in actual:\n      found = False\n      for i, v in enumerate(expected_list):\n        if equals_fn(v, element):\n          found = True\n          expected_list.pop(i)\n          break\n      if not found:\n        unexpected.append(element)\n    if unexpected or expected_list:\n      msg = 'Failed assert: %r == %r' % (expected, actual)\n      if unexpected:\n        msg = msg + ', unexpected elements %r' % unexpected\n      if expected_list:\n        msg = msg + ', missing elements %r' % expected_list\n      raise BeamAssertException(msg)\n\n  return _equal\n\n\ndef row_namedtuple_equals_fn(expected, actual, fallback_equals_fn=None):\n  \"\"\"\n  equals_fn which can be used by equal_to which treats Rows and\n  NamedTuples as equivalent types. This can be useful since Beam converts\n  Rows to NamedTuples when they are sent across portability layers, so a Row\n  may be converted to a NamedTuple automatically by Beam.\n  \"\"\"\n  if fallback_equals_fn is None:\n    fallback_equals_fn = lambda e, a: e == a\n  if type(expected) is not pvalue.Row and not _is_named_tuple(expected):\n    return fallback_equals_fn(expected, actual)\n  if type(actual) is not pvalue.Row and not _is_named_tuple(actual):\n    return fallback_equals_fn(expected, actual)\n","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/testing/util.py#L187-L223","documentation":"This is the failure path of the equal_to() matcher's _equal function: after matching actual elements against expected, if there are unexpected actual elements or missing expected elements, it raises BeamAssertException with a formatted 'expected == actual' message, appending the specific unexpected and/or missing elements when present.","triggerScenarios":"assert_that(pcoll, equal_to([...])) where the actual output differs from the expected list in any way: missing items, extra items, wrong order handled via multiset matching, or type-differing values (e.g. '1' vs 1).","commonSituations":"Ordinary test failures where pipeline output diverges from expectations; encoding differences (bytes vs str); duplicate counts differing; NaN or unhashable values handled differently across runners.","solutions":["Read the 'missing elements'/'unexpected elements' suffix of the message and update either the expectation or the pipeline accordingly.","Verify element types match exactly (str vs bytes, int vs float).","Compare against actual output by logging the PCollection contents before the assertion."],"exampleFix":"// before\nassert_that(pcoll, equal_to(['a', 'b']))  # pipeline emits ['a', 'c']\n// after\nassert_that(pcoll, equal_to(['a', 'c']))","handlingStrategy":"try-catch","validationCode":"# pre-check: run the pipeline logic on sample data locally and compare\n# expected_set = set(expected); actual_set = set(dry_run_output)\n# assert expected_set == actual_set","typeGuard":null,"tryCatchPattern":"from apache_beam.testing.util import BeamAssertException\ntry:\n    assert_that(pcoll, equal_to(expected))\nexcept BeamAssertException as e:\n    logging.error('Pipeline output mismatch: %s', e)\n    raise","preventionTips":["Read the 'missing/unexpected elements' suffix to fix precisely one side","Normalize types (bytes/str) at PCollection boundaries","Regenerate expectations whenever the transform under test changes"],"tags":["python","apache-beam","assertion","test","equality"],"backgroundTag":"assertion-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}