28
28
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
29
SOFTWARE.
30
30
"""
31
- from __future__ import print_function
32
-
33
31
__author__ = "Conan.io <info@conan.io>"
34
32
__version__ = "1.18.0"
35
33
__license__ = "MIT"
36
34
__url__ = "https://github.com/conan-io/python-patch"
37
35
36
+ import codecs
38
37
import copy
38
+ import io
39
39
import logging
40
- import re
41
- import tempfile
42
- import codecs
43
-
44
- # cStringIO doesn't support unicode in 2.5
45
- try :
46
- from StringIO import StringIO
47
- except ImportError :
48
- from io import BytesIO as StringIO # python 3
49
- try :
50
- import urllib2 as urllib_request
51
- except ImportError :
52
- import urllib .request as urllib_request
53
-
54
- from os .path import exists , isfile , abspath
55
40
import os
56
41
import posixpath
42
+ import re
57
43
import shutil
58
- import sys
59
44
import stat
60
-
61
-
62
- PY3K = sys .version_info >= (3 , 0 )
63
-
64
- # PEP 3114
65
- if not PY3K :
66
- compat_next = lambda gen : gen .next ()
67
- else :
68
- compat_next = lambda gen : gen .__next__ ()
69
-
70
- def tostr (b ):
71
- """ Python 3 bytes encoder. Used to print filename in
72
- diffstat output. Assumes that filenames are in utf-8.
73
- """
74
- if not PY3K :
75
- return b
76
-
77
- # [ ] figure out how to print non-utf-8 filenames without
78
- # information loss
79
- return b .decode ('utf-8' )
80
-
45
+ import sys
46
+ import tempfile
47
+ import urllib .request
48
+ from os .path import exists , isfile , abspath
81
49
82
50
#------------------------------------------------
83
51
# Logging is controlled by logger named after the
@@ -90,22 +58,10 @@ def tostr(b):
90
58
warning = logger .warning
91
59
error = logger .error
92
60
93
- class NullHandler (logging .Handler ):
94
- """ Copied from Python 2.7 to avoid getting
95
- `No handlers could be found for logger "patch"`
96
- http://bugs.python.org/issue16539
97
- """
98
- def handle (self , record ):
99
- pass
100
- def emit (self , record ):
101
- pass
102
- def createLock (self ):
103
- self .lock = None
104
-
105
61
streamhandler = logging .StreamHandler ()
106
62
107
63
# initialize logger itself
108
- logger .addHandler (NullHandler ())
64
+ logger .addHandler (logging . NullHandler ())
109
65
110
66
debugmode = False
111
67
@@ -194,10 +150,9 @@ def fromfile(filename):
194
150
"""
195
151
patchset = PatchSet ()
196
152
debug ("reading %s" % filename )
197
- fp = open (filename , "rb" )
198
- res = patchset .parse (fp )
199
- fp .close ()
200
- if res == True :
153
+ with open (filename , "rb" ) as fp :
154
+ res = patchset .parse (fp )
155
+ if res is True :
201
156
return patchset
202
157
return False
203
158
@@ -206,7 +161,7 @@ def fromstring(s):
206
161
""" Parse text string and return PatchSet()
207
162
object (or False if parsing fails)
208
163
"""
209
- ps = PatchSet ( StringIO (s ) )
164
+ ps = PatchSet ( io . BytesIO (s ) )
210
165
if ps .errors == 0 :
211
166
return ps
212
167
return False
@@ -217,7 +172,7 @@ def fromurl(url):
217
172
if an error occured. Note that this also
218
173
can throw urlopen() exceptions.
219
174
"""
220
- ps = PatchSet ( urllib_request .urlopen (url ) )
175
+ ps = PatchSet ( urllib . request .urlopen (url ) )
221
176
if ps .errors == 0 :
222
177
return ps
223
178
return False
@@ -262,11 +217,8 @@ def decode_text(text):
262
217
263
218
264
219
def to_file_bytes (content ):
265
- if PY3K :
266
- if not isinstance (content , bytes ):
267
- content = bytes (content , "utf-8" )
268
- elif isinstance (content , unicode ):
269
- content = content .encode ("utf-8" )
220
+ if not isinstance (content , bytes ):
221
+ content = bytes (content , "utf-8" )
270
222
return content
271
223
272
224
@@ -328,8 +280,7 @@ def __init__(self):
328
280
self .type = None
329
281
330
282
def __iter__ (self ):
331
- for h in self .hunks :
332
- yield h
283
+ return iter (self .hunks )
333
284
334
285
335
286
class PatchSet (object ):
@@ -359,8 +310,7 @@ def __len__(self):
359
310
return len (self .items )
360
311
361
312
def __iter__ (self ):
362
- for i in self .items :
363
- yield i
313
+ return iter (self .items )
364
314
365
315
def parse (self , stream ):
366
316
""" parse unified diff
@@ -394,7 +344,7 @@ def next(self):
394
344
return False
395
345
396
346
try :
397
- self ._lineno , self ._line = compat_next (super (wrapumerate , self ))
347
+ self ._lineno , self ._line = next (super (wrapumerate , self ))
398
348
except StopIteration :
399
349
self ._exhausted = True
400
350
self ._line = False
@@ -902,7 +852,7 @@ def diffstat(self):
902
852
#print(iratio, dratio, iwidth, dwidth, histwidth)
903
853
hist = "+" * int (iwidth ) + "-" * int (dwidth )
904
854
# -- /calculating +- histogram --
905
- output += (format % (tostr ( names [i ]), str (insert [i ] + delete [i ]), hist ))
855
+ output += (format % (names [i ]. decode ( ), str (insert [i ] + delete [i ]), hist ))
906
856
907
857
output += (" %d files changed, %d insertions(+), %d deletions(-), %+d bytes"
908
858
% (len (names ), sum (insert ), sum (delete ), delta ))
@@ -1270,15 +1220,11 @@ def get_line():
1270
1220
1271
1221
1272
1222
def write_hunks (self , srcname , tgtname , hunks ):
1273
- src = open (srcname , "rb" )
1274
- tgt = open (tgtname , "wb" )
1275
-
1276
- debug ("processing target file %s" % tgtname )
1277
-
1278
- tgt .writelines (self .patch_stream (src , hunks ))
1223
+ with open (srcname , "rb" ) as src , open (tgtname , "wb" ) as tgt :
1224
+ debug ("processing target file %s" % tgtname )
1225
+
1226
+ tgt .writelines (self .patch_stream (src , hunks ))
1279
1227
1280
- tgt .close ()
1281
- src .close ()
1282
1228
# [ ] TODO: add test for permission copy
1283
1229
shutil .copymode (srcname , tgtname )
1284
1230
return True
0 commit comments