Repository: yt-dlp/yt-dlp
File: test/test_utils.py (Python)

Code before:
        self.assertEqual(traverse_obj(_TEST_DATA, 'str'), 'str',
                         msg='single items should be treated as a path')
        self.assertEqual(traverse_obj(_TEST_DATA, None), _TEST_DATA)
        self.assertEqual(traverse_obj(_TEST_DATA, 100), 100)
        self.assertEqual(traverse_obj(_TEST_DATA, 1.2), 1.2)

        # Test Ellipsis behavior
        self.assertCountEqual(traverse_obj(_TEST_DATA, ...),
                              (item for item in _TEST_DATA.values() if item is not None),
                              msg='`...` should give all values except `None`')
        self.assertCountEqual(traverse_obj(_TEST_DATA, ('urls', 0, ...)), _TEST_DATA['urls'][0].values(),
                              msg='`...` selection for dicts should select all values')
        self.assertEqual(traverse_obj(_TEST_DATA, (..., ..., 'url')),
                         ['https://www.example.com/0', 'https://www.example.com/1'],
                         msg='nested `...` queries should work')
        self.assertCountEqual(traverse_obj(_TEST_DATA, (..., ..., 'index')), range(4),
                              msg='`...` query result should be flattened')

        # Test function as key
        self.assertEqual(traverse_obj(_TEST_DATA, lambda x, y: x == 'urls' and isinstance(y, list)),
                         [_TEST_DATA['urls']],
                         msg='function as query key should perform a filter based on (key, value)')
        self.assertCountEqual(traverse_obj(_TEST_DATA, lambda _, x: isinstance(x[0], str)), {'str'},
                              msg='exceptions in the query function should be catched')
        if __debug__:
            with self.assertRaises(Exception, msg='Unassignable parameters should raise in debug'):
                traverse_obj(_TEST_DATA, lambda a: ...)
            with self.assertRaises(Exception, msg='Unassignable parameters should raise in debug'):
                traverse_obj(_TEST_DATA, lambda a, b, c: ...)

        # Test set as key (transformation)
        self.assertEqual(traverse_obj('str', ({str.upper}, )), 'STR',
                         msg='Set should function as a transformation')
        self.assertEqual(traverse_obj(_TEST_DATA, {dict}), _TEST_DATA,
                         msg='A single set should be treated as a path')
        self.assertEqual(traverse_obj(_TEST_DATA, (..., {str.upper})), ['STR'],
                         msg='Transformation function should not raise')
        self.assertEqual(traverse_obj(_TEST_DATA, (..., {str}, {str.upper})),
                         [str(item).upper() for item in _TEST_DATA.values() if item is not None],
                         msg='Any callable in the set should be treated as a transformation function')
        if __debug__:
            with self.assertRaises(Exception, msg='Sets with length != 1 should raise in debug'):
                traverse_obj(_TEST_DATA, set())
            with self.assertRaises(Exception, msg='Sets with length != 1 should raise in debug'):
                traverse_obj(_TEST_DATA, {str.upper, str})

        # Test alternative paths
        self.assertEqual(traverse_obj(_TEST_DATA, 'fail', 'str'), 'str',
                         msg='multiple `paths` should be treated as alternative paths')
        self.assertEqual(traverse_obj(_TEST_DATA, 'str', 100), 'str',
                         msg='alternatives should exit early')

Review comment (bug):
```suggestion

        # Test wrong function signature
        if __debug__:
```

Code after:
                         msg='allow iterable path')
        self.assertEqual(traverse_obj(_TEST_DATA, 'str'), 'str',
                         msg='single items should be treated as a path')
        self.assertEqual(traverse_obj(_TEST_DATA, None), _TEST_DATA)
        self.assertEqual(traverse_obj(_TEST_DATA, 100), 100)
        self.assertEqual(traverse_obj(_TEST_DATA, 1.2), 1.2)

        # Test Ellipsis behavior
        self.assertCountEqual(traverse_obj(_TEST_DATA, ...),
                              (item for item in _TEST_DATA.values() if item is not None),
                              msg='`...` should give all values except `None`')
        self.assertCountEqual(traverse_obj(_TEST_DATA, ('urls', 0, ...)), _TEST_DATA['urls'][0].values(),
                              msg='`...` selection for dicts should select all values')
        self.assertEqual(traverse_obj(_TEST_DATA, (..., ..., 'url')),
                         ['https://www.example.com/0', 'https://www.example.com/1'],
                         msg='nested `...` queries should work')
        self.assertCountEqual(traverse_obj(_TEST_DATA, (..., ..., 'index')), range(4),
                              msg='`...` query result should be flattened')

        # Test function as key
        self.assertEqual(traverse_obj(_TEST_DATA, lambda x, y: x == 'urls' and isinstance(y, list)),
                         [_TEST_DATA['urls']],
                         msg='function as query key should perform a filter based on (key, value)')
        self.assertCountEqual(traverse_obj(_TEST_DATA, lambda _, x: isinstance(x[0], str)), {'str'},
                              msg='exceptions in the query function should be catched')
        if __debug__:
            with self.assertRaises(Exception, msg='Wrong function signature should raise in debug'):
                traverse_obj(_TEST_DATA, lambda a: ...)
            with self.assertRaises(Exception, msg='Wrong function signature should raise in debug'):
                traverse_obj(_TEST_DATA, lambda a, b, c: ...)

        # Test set as key (transformation/type, like `expected_type`)
        self.assertEqual(traverse_obj(_TEST_DATA, (..., {str.upper}, )), ['STR'],
                         msg='Function in set should be a transformation')
        self.assertEqual(traverse_obj(_TEST_DATA, (..., {str})), ['str'],
                         msg='Type in set should be a type filter')
        self.assertEqual(traverse_obj(_TEST_DATA, {dict}), _TEST_DATA,
                         msg='A single set should be wrapped into a path')
        self.assertEqual(traverse_obj(_TEST_DATA, (..., {str.upper})), ['STR'],
                         msg='Transformation function should not raise')
        self.assertEqual(traverse_obj(_TEST_DATA, (..., {str_or_none})),
                         [item for item in map(str_or_none, _TEST_DATA.values()) if item is not None],
                         msg='Function in set should be a transformation')
        if __debug__:
            with self.assertRaises(Exception, msg='Sets with length != 1 should raise in debug'):
                traverse_obj(_TEST_DATA, set())
            with self.assertRaises(Exception, msg='Sets with length != 1 should raise in debug'):
                traverse_obj(_TEST_DATA, {str.upper, str})

        # Test alternative paths
        self.assertEqual(traverse_obj(_TEST_DATA, 'fail', 'str'), 'str',