2828 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2929 SOFTWARE.
3030"""
31- from __future__ import print_function
32-
3331__author__ = "Conan.io <info@conan.io>"
3432__version__ = "1.19.0-dev"
3533__license__ = "MIT"
3634__url__ = "https://github.com/conan-io/python-patch"
3735
36+ import codecs
3837import copy
38+ import io
3939import 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
5540import os
5641import posixpath
42+ import re
5743import shutil
58- import sys
5944import 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 tempfile
46+ import urllib .request
47+ from os .path import exists , isfile , abspath
8148
8249#------------------------------------------------
8350# Logging is controlled by logger named after the
@@ -90,22 +57,10 @@ def tostr(b):
9057warning = logger .warning
9158error = logger .error
9259
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-
10560streamhandler = logging .StreamHandler ()
10661
10762# initialize logger itself
108- logger .addHandler (NullHandler ())
63+ logger .addHandler (logging . NullHandler ())
10964
11065debugmode = False
11166
@@ -194,19 +149,18 @@ def fromfile(filename):
194149 """
195150 patchset = PatchSet ()
196151 debug ("reading %s" % filename )
197- fp = open (filename , "rb" )
198- res = patchset .parse (fp )
199- fp .close ()
200- if res == True :
201- return patchset
152+ with open (filename , "rb" ) as fp :
153+ res = patchset .parse (fp )
154+ if res == True :
155+ return patchset
202156 return False
203157
204158
205159def fromstring (s ):
206160 """ Parse text string and return PatchSet()
207161 object (or False if parsing fails)
208162 """
209- ps = PatchSet ( StringIO (s ) )
163+ ps = PatchSet ( io . BytesIO (s ) )
210164 if ps .errors == 0 :
211165 return ps
212166 return False
@@ -217,7 +171,7 @@ def fromurl(url):
217171 if an error occured. Note that this also
218172 can throw urlopen() exceptions.
219173 """
220- ps = PatchSet ( urllib_request .urlopen (url ) )
174+ ps = PatchSet ( urllib . request .urlopen (url ) )
221175 if ps .errors == 0 :
222176 return ps
223177 return False
@@ -261,15 +215,6 @@ def decode_text(text):
261215 return text .decode ("utf-8" , "ignore" ) # Ignore not compatible characters
262216
263217
264- 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" )
270- return content
271-
272-
273218def load (path , binary = False ):
274219 """ Loads a file content """
275220 with open (path , 'rb' ) as handle :
@@ -290,7 +235,9 @@ def save(path, content, only_if_modified=False):
290235 except Exception :
291236 pass
292237
293- new_content = to_file_bytes (content )
238+ new_content = content
239+ if not isinstance (content , bytes ):
240+ new_content = bytes (content , "utf-8" )
294241
295242 if only_if_modified and os .path .exists (path ):
296243 old_content = load (path , binary = True )
@@ -328,8 +275,7 @@ def __init__(self):
328275 self .type = None
329276
330277 def __iter__ (self ):
331- for h in self .hunks :
332- yield h
278+ return iter (self .hunks )
333279
334280
335281class PatchSet (object ):
@@ -359,8 +305,7 @@ def __len__(self):
359305 return len (self .items )
360306
361307 def __iter__ (self ):
362- for i in self .items :
363- yield i
308+ return iter (self .items )
364309
365310 def parse (self , stream ):
366311 """ parse unified diff
@@ -394,7 +339,7 @@ def next(self):
394339 return False
395340
396341 try :
397- self ._lineno , self ._line = compat_next ( super (wrapumerate , self ))
342+ self ._lineno , self ._line = super (wrapumerate , self ). __next__ ( )
398343 except StopIteration :
399344 self ._exhausted = True
400345 self ._line = False
@@ -902,7 +847,7 @@ def diffstat(self):
902847 #print(iratio, dratio, iwidth, dwidth, histwidth)
903848 hist = "+" * int (iwidth ) + "-" * int (dwidth )
904849 # -- /calculating +- histogram --
905- output += (format % (tostr ( names [i ]), str (insert [i ] + delete [i ]), hist ))
850+ output += (format % (names [i ]. decode ( 'utf-8' ), str (insert [i ] + delete [i ]), hist ))
906851
907852 output += (" %d files changed, %d insertions(+), %d deletions(-), %+d bytes"
908853 % (len (names ), sum (insert ), sum (delete ), delta ))
@@ -1270,15 +1215,11 @@ def get_line():
12701215
12711216
12721217 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 ))
1218+ with open (srcname , "rb" ) as src , open (tgtname , "wb" ) as tgt :
1219+ debug ("processing target file %s" % tgtname )
1220+
1221+ tgt .writelines (self .patch_stream (src , hunks ))
12791222
1280- tgt .close ()
1281- src .close ()
12821223 # [ ] TODO: add test for permission copy
12831224 shutil .copymode (srcname , tgtname )
12841225 return True
0 commit comments