Browse Source

Adjust Popen object creation order to fix issue #30

Have to create pager Popen object before the translator Popen object
in PatchStreamForwarder, otherwise the `stdin=subprocess.PIPE` would cause
trouble to the translator pipe (select() never see EOF after input stream
ended), most likely python bug 12607 (http://bugs.python.org/issue12607)
which was fixed in python 2.7.3.
Matthew Wang 10 years ago
parent
commit
1755970048
1 changed files with 15 additions and 20 deletions
  1. 15
    20
      cdiff.py

+ 15
- 20
cdiff.py View File

@@ -251,13 +251,6 @@ class PatchStreamForwarder(object):
251 251
             line = next(self._istream)
252 252
             self._in.write(line.encode('utf-8'))
253 253
         except StopIteration:
254
-            # XXX: close() does not notify select() for EOF event in python
255
-            # < 2.7.3, one of these two interface must be buggy
256
-            #
257
-            # Sending EOF manually does not work either
258
-            #
259
-            #print('StopIteration, closing (sending EOF)')
260
-            #self._in.write('\x1a'.encode('utf-8'))
261 254
             self._in.close()
262 255
 
263 256
     def __iter__(self):
@@ -267,19 +260,9 @@ class PatchStreamForwarder(object):
267 260
                 if line:
268 261
                     yield line
269 262
                 else:
270
-                    #print('got EOF')
271 263
                     return
272 264
             elif not self._in.closed:
273 265
                 self._forward_line()
274
-            else:
275
-                #print('no data to read and istream closed')
276
-                # XXX: `close` or `select` seems buggy in python < 2.7.3, select
277
-                # does not tell ready event on _translator.stdout anymore once
278
-                # the stdin is closed.  Just add a timeout here to detect, when
279
-                # that happen the remaining in output stream will be discarded
280
-                #
281
-                if not self._can_read(0.5):
282
-                    return
283 266
 
284 267
 
285 268
 class DiffParser(object):
@@ -607,14 +590,26 @@ class DiffMarker(object):
607 590
 
608 591
 
609 592
 def markup_to_pager(stream, opts):
593
+    """Pipe unified diff stream to pager (less).
594
+
595
+    Note: have to create pager Popen object before the translator Popen object
596
+    in PatchStreamForwarder, otherwise the `stdin=subprocess.PIPE` would cause
597
+    trouble to the translator pipe (select() never see EOF after input stream
598
+    ended), most likely python bug 12607 (http://bugs.python.org/issue12607)
599
+    which was fixed in python 2.7.3.
600
+
601
+    See issue #30 (https://github.com/ymattw/cdiff/issues/30) for more
602
+    information.
603
+    """
604
+    # Args stolen from git source: github.com/git/git/blob/master/pager.c
605
+    pager = subprocess.Popen(
606
+        ['less', '-FRSX'], stdin=subprocess.PIPE, stdout=sys.stdout)
607
+
610 608
     diffs = DiffParser(stream).get_diff_generator()
611 609
     marker = DiffMarker()
612 610
     color_diff = marker.markup(diffs, side_by_side=opts.side_by_side,
613 611
                                width=opts.width)
614 612
 
615
-    # Args stolen from git source: github.com/git/git/blob/master/pager.c
616
-    pager = subprocess.Popen(
617
-        ['less', '-FRSX'], stdin=subprocess.PIPE, stdout=sys.stdout)
618 613
     for line in color_diff:
619 614
         pager.stdin.write(line.encode('utf-8'))
620 615