Bug report
Bug description:
Both difflib.unified_diff and difflib.context_diff document that a and b input arguments are to be lists of strings. These functions perform argument type checking by way of difflib._check_types, however this function allows a and b to be direct str arguments. Technically this does not cause a failure in difflib.unified_diff (and I assume the same is true for context_diff but I have not tested it), however, for very large strings a and/or b, difflib.unified_diff is exponentially slower to calculate the diff, because the underlying SequenceMatcher is optimized to compare two lists of string, not two sequences of chars.
We can obviously see that the implementation of _check_types uses a seemingly naive type check of the first element in a and b which will pass for both the documented input of a list of strings, but also for a positive length string itself.
def _check_types(a, b, *args):
# Checking types is weird, but the alternative is garbled output when
# someone passes mixed bytes and str to {unified,context}_diff(). E.g.
# without this check, passing filenames as bytes results in output like
# --- b'oldfile.txt'
# +++ b'newfile.txt'
# because of how str.format() incorporates bytes objects.
if a and not isinstance(a[0], str):
raise TypeError('lines to compare must be str, not %s (%r)' %
(type(a[0]).__name__, a[0]))
if b and not isinstance(b[0], str):
raise TypeError('lines to compare must be str, not %s (%r)' %
(type(b[0]).__name__, b[0]))
for arg in args:
if not isinstance(arg, str):
raise TypeError('all arguments must be str, not: %r' % (arg,))
This would be rather trivial to fix in _check_types but I want to first make sure that the documentation of a list of string is to be considered correct behavior?
CPython versions tested on:
3.8, 3.9, 3.10, 3.11, 3.12, 3.13, CPython main branch
Operating systems tested on:
Linux, macOS
Linked PRs
Bug report
Bug description:
Both
difflib.unified_diffanddifflib.context_diffdocument thataandbinput arguments are to be lists of strings. These functions perform argument type checking by way ofdifflib._check_types, however this function allowsaandbto be directstrarguments. Technically this does not cause a failure indifflib.unified_diff(and I assume the same is true forcontext_diffbut I have not tested it), however, for very large stringsaand/orb,difflib.unified_diffis exponentially slower to calculate the diff, because the underlyingSequenceMatcheris optimized to compare two lists of string, not two sequences of chars.We can obviously see that the implementation of
_check_typesuses a seemingly naive type check of the first element inaandbwhich will pass for both the documented input of a list of strings, but also for a positive length string itself.This would be rather trivial to fix in
_check_typesbut I want to first make sure that the documentation of a list of string is to be considered correct behavior?CPython versions tested on:
3.8, 3.9, 3.10, 3.11, 3.12, 3.13, CPython main branch
Operating systems tested on:
Linux, macOS
Linked PRs