3030 'Differ' ,'IS_CHARACTER_JUNK' , 'IS_LINE_JUNK' , 'context_diff' ,
3131 'unified_diff' , 'diff_bytes' , 'HtmlDiff' , 'Match' ]
3232
33+ from _colorize import can_colorize , get_theme
3334from heapq import nlargest as _nlargest
3435from collections import namedtuple as _namedtuple
3536from types import GenericAlias
@@ -1094,7 +1095,7 @@ def _format_range_unified(start, stop):
10941095 return '{},{}' .format (beginning , length )
10951096
10961097def unified_diff (a , b , fromfile = '' , tofile = '' , fromfiledate = '' ,
1097- tofiledate = '' , n = 3 , lineterm = '\n ' ):
1098+ tofiledate = '' , n = 3 , lineterm = '\n ' , * , color = False ):
10981099 r"""
10991100 Compare two sequences of lines; generate the delta as a unified diff.
11001101
@@ -1111,6 +1112,10 @@ def unified_diff(a, b, fromfile='', tofile='', fromfiledate='',
11111112 For inputs that do not have trailing newlines, set the lineterm
11121113 argument to "" so that the output will be uniformly newline free.
11131114
1115+ Set 'color' to True to enable output in color, similar to
1116+ 'git diff --color'. Even if enabled, it can be
1117+ controlled using environment variables such as 'NO_COLOR'.
1118+
11141119 The unidiff format normally has a header for filenames and modification
11151120 times. Any or all of these may be specified using strings for
11161121 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.
@@ -1134,32 +1139,37 @@ def unified_diff(a, b, fromfile='', tofile='', fromfiledate='',
11341139 four
11351140 """
11361141
1142+ if color and can_colorize ():
1143+ t = get_theme (force_color = True ).difflib
1144+ else :
1145+ t = get_theme (force_no_color = True ).difflib
1146+
11371147 _check_types (a , b , fromfile , tofile , fromfiledate , tofiledate , lineterm )
11381148 started = False
11391149 for group in SequenceMatcher (None ,a ,b ).get_grouped_opcodes (n ):
11401150 if not started :
11411151 started = True
11421152 fromdate = '\t {}' .format (fromfiledate ) if fromfiledate else ''
11431153 todate = '\t {}' .format (tofiledate ) if tofiledate else ''
1144- yield ' --- {}{}{}' . format ( fromfile , fromdate , lineterm )
1145- yield ' +++ {}{}{}' . format ( tofile , todate , lineterm )
1154+ yield f' { t . header } --- { fromfile } { fromdate } { lineterm } { t . reset } '
1155+ yield f' { t . header } +++ { tofile } { todate } { lineterm } { t . reset } '
11461156
11471157 first , last = group [0 ], group [- 1 ]
11481158 file1_range = _format_range_unified (first [1 ], last [2 ])
11491159 file2_range = _format_range_unified (first [3 ], last [4 ])
1150- yield ' @@ -{} +{} @@{}' . format ( file1_range , file2_range , lineterm )
1160+ yield f' { t . hunk } @@ -{ file1_range } +{ file2_range } @@{ lineterm } { t . reset } '
11511161
11521162 for tag , i1 , i2 , j1 , j2 in group :
11531163 if tag == 'equal' :
11541164 for line in a [i1 :i2 ]:
1155- yield ' ' + line
1165+ yield f' { t . context } { line } { t . reset } '
11561166 continue
11571167 if tag in {'replace' , 'delete' }:
11581168 for line in a [i1 :i2 ]:
1159- yield '-' + line
1169+ yield f' { t . removed } - { line } { t . reset } '
11601170 if tag in {'replace' , 'insert' }:
11611171 for line in b [j1 :j2 ]:
1162- yield '+' + line
1172+ yield f' { t . added } + { line } { t . reset } '
11631173
11641174
11651175########################################################################
0 commit comments