##// END OF EJS Templates
procutil: delete Python 2 support code...
Gregory Szorc -
r49765:3681b4c5 default
parent child Browse files
Show More
@@ -80,7 +80,7 b' io.BufferedIOBase.register(LineBufferedW'
80 80
81 81
82 82 def make_line_buffered(stream):
83 if pycompat.ispy3 and not isinstance(stream, io.BufferedIOBase):
83 if not isinstance(stream, io.BufferedIOBase):
84 84 # On Python 3, buffered streams can be expected to subclass
85 85 # BufferedIOBase. This is definitively the case for the streams
86 86 # initialized by the interpreter. For unbuffered streams, we don't need
@@ -121,7 +121,6 b' io.IOBase.register(WriteAllWrapper)'
121 121
122 122
123 123 def _make_write_all(stream):
124 assert pycompat.ispy3
125 124 if isinstance(stream, WriteAllWrapper):
126 125 return stream
127 126 if isinstance(stream, io.BufferedIOBase):
@@ -133,52 +132,32 b' def _make_write_all(stream):'
133 132 return WriteAllWrapper(stream)
134 133
135 134
136 if pycompat.ispy3:
137 # Python 3 implements its own I/O streams. Unlike stdio of C library,
138 # sys.stdin/stdout/stderr may be None if underlying fd is closed.
139
140 # TODO: .buffer might not exist if std streams were replaced; we'll need
141 # a silly wrapper to make a bytes stream backed by a unicode one.
135 # Python 3 implements its own I/O streams. Unlike stdio of C library,
136 # sys.stdin/stdout/stderr may be None if underlying fd is closed.
142 137
143 if sys.stdin is None:
144 stdin = BadFile()
145 else:
146 stdin = sys.stdin.buffer
147 if sys.stdout is None:
148 stdout = BadFile()
149 else:
150 stdout = _make_write_all(sys.stdout.buffer)
151 if sys.stderr is None:
152 stderr = BadFile()
153 else:
154 stderr = _make_write_all(sys.stderr.buffer)
138 # TODO: .buffer might not exist if std streams were replaced; we'll need
139 # a silly wrapper to make a bytes stream backed by a unicode one.
155 140
156 if pycompat.iswindows:
157 # Work around Windows bugs.
158 stdout = platform.winstdout(stdout) # pytype: disable=module-attr
159 stderr = platform.winstdout(stderr) # pytype: disable=module-attr
160 if isatty(stdout):
161 # The standard library doesn't offer line-buffered binary streams.
162 stdout = make_line_buffered(stdout)
141 if sys.stdin is None:
142 stdin = BadFile()
143 else:
144 stdin = sys.stdin.buffer
145 if sys.stdout is None:
146 stdout = BadFile()
163 147 else:
164 # Python 2 uses the I/O streams provided by the C library.
165 stdin = sys.stdin
166 stdout = sys.stdout
167 stderr = sys.stderr
168 if pycompat.iswindows:
169 # Work around Windows bugs.
170 stdout = platform.winstdout(stdout) # pytype: disable=module-attr
171 stderr = platform.winstdout(stderr) # pytype: disable=module-attr
172 if isatty(stdout):
173 if pycompat.iswindows:
174 # The Windows C runtime library doesn't support line buffering.
175 stdout = make_line_buffered(stdout)
176 else:
177 # glibc determines buffering on first write to stdout - if we
178 # replace a TTY destined stdout with a pipe destined stdout (e.g.
179 # pager), we want line buffering.
180 stdout = os.fdopen(stdout.fileno(), 'wb', 1)
148 stdout = _make_write_all(sys.stdout.buffer)
149 if sys.stderr is None:
150 stderr = BadFile()
151 else:
152 stderr = _make_write_all(sys.stderr.buffer)
181 153
154 if pycompat.iswindows:
155 # Work around Windows bugs.
156 stdout = platform.winstdout(stdout) # pytype: disable=module-attr
157 stderr = platform.winstdout(stderr) # pytype: disable=module-attr
158 if isatty(stdout):
159 # The standard library doesn't offer line-buffered binary streams.
160 stdout = make_line_buffered(stdout)
182 161
183 162 findexe = platform.findexe
184 163 _gethgcmd = platform.gethgcmd
@@ -704,7 +683,7 b' if pycompat.iswindows:'
704 683
705 684 else:
706 685
707 def runbgcommandpy3(
686 def runbgcommand(
708 687 cmd,
709 688 env,
710 689 shell=False,
@@ -787,128 +766,3 b' else:'
787 766 returncode = p.wait
788 767 if record_wait is not None:
789 768 record_wait(returncode)
790
791 def runbgcommandpy2(
792 cmd,
793 env,
794 shell=False,
795 stdout=None,
796 stderr=None,
797 ensurestart=True,
798 record_wait=None,
799 stdin_bytes=None,
800 ):
801 """Spawn a command without waiting for it to finish.
802
803
804 When `record_wait` is not None, the spawned process will not be fully
805 detached and the `record_wait` argument will be called with a the
806 `Subprocess.wait` function for the spawned process. This is mostly
807 useful for developers that need to make sure the spawned process
808 finished before a certain point. (eg: writing test)"""
809 if pycompat.isdarwin:
810 # avoid crash in CoreFoundation in case another thread
811 # calls gui() while we're calling fork().
812 gui()
813
814 # double-fork to completely detach from the parent process
815 # based on http://code.activestate.com/recipes/278731
816 if record_wait is None:
817 pid = os.fork()
818 if pid:
819 if not ensurestart:
820 # Even though we're not waiting on the child process,
821 # we still must call waitpid() on it at some point so
822 # it's not a zombie/defunct. This is especially relevant for
823 # chg since the parent process won't die anytime soon.
824 # We use a thread to make the overhead tiny.
825 def _do_wait():
826 os.waitpid(pid, 0)
827
828 t = threading.Thread(target=_do_wait)
829 t.daemon = True
830 t.start()
831 return
832 # Parent process
833 (_pid, status) = os.waitpid(pid, 0)
834 if os.WIFEXITED(status):
835 returncode = os.WEXITSTATUS(status)
836 else:
837 returncode = -(os.WTERMSIG(status))
838 if returncode != 0:
839 # The child process's return code is 0 on success, an errno
840 # value on failure, or 255 if we don't have a valid errno
841 # value.
842 #
843 # (It would be slightly nicer to return the full exception info
844 # over a pipe as the subprocess module does. For now it
845 # doesn't seem worth adding that complexity here, though.)
846 if returncode == 255:
847 returncode = errno.EINVAL
848 raise OSError(
849 returncode,
850 b'error running %r: %s'
851 % (cmd, os.strerror(returncode)),
852 )
853 return
854
855 returncode = 255
856 stdin = None
857
858 try:
859 if record_wait is None:
860 # Start a new session
861 os.setsid()
862 # connect stdin to devnull to make sure the subprocess can't
863 # muck up that stream for mercurial.
864 if stdin_bytes is None:
865 stdin = open(os.devnull, b'r')
866 else:
867 stdin = pycompat.unnamedtempfile()
868 stdin.write(stdin_bytes)
869 stdin.flush()
870 stdin.seek(0)
871
872 if stdout is None:
873 stdout = open(os.devnull, b'w')
874 if stderr is None:
875 stderr = open(os.devnull, b'w')
876
877 p = subprocess.Popen(
878 cmd,
879 shell=shell,
880 env=env,
881 close_fds=True,
882 stdin=stdin,
883 stdout=stdout,
884 stderr=stderr,
885 )
886 if record_wait is not None:
887 record_wait(p.wait)
888 returncode = 0
889 except EnvironmentError as ex:
890 returncode = ex.errno & 0xFF
891 if returncode == 0:
892 # This shouldn't happen, but just in case make sure the
893 # return code is never 0 here.
894 returncode = 255
895 except Exception:
896 returncode = 255
897 finally:
898 # mission accomplished, this child needs to exit and not
899 # continue the hg process here.
900 if stdin is not None:
901 stdin.close()
902 if record_wait is None:
903 os._exit(returncode)
904
905 if pycompat.ispy3:
906 # This branch is more robust, because it avoids running python
907 # code (hence gc finalizers, like sshpeer.__del__, which
908 # blocks). But we can't easily do the equivalent in py2,
909 # because of the lack of start_new_session=True flag. Given
910 # that the py2 branch should die soon, the short-lived
911 # duplication seems acceptable.
912 runbgcommand = runbgcommandpy3
913 else:
914 runbgcommand = runbgcommandpy2
General Comments 0
You need to be logged in to leave comments. Login now