diff --git a/python-2.5-subprocess-eintr-safety.patch b/python-2.5-subprocess-eintr-safety.patch new file mode 100644 index 0000000..1ef2898 --- /dev/null +++ b/python-2.5-subprocess-eintr-safety.patch @@ -0,0 +1,196 @@ +--- Lib/subprocess.py 2007-03-14 19:16:36.000000000 +0100 ++++ Lib/subprocess.py 2007-03-14 19:18:50.000000000 +0100 +@@ -655,12 +655,12 @@ class Popen(object): + stderr = None + if self.stdin: + if input: +- self.stdin.write(input) ++ self._fo_write_no_intr(self.stdin, input) + self.stdin.close() + elif self.stdout: +- stdout = self.stdout.read() ++ stdout = self._fo_read_no_intr(self.stdout) + elif self.stderr: +- stderr = self.stderr.read() ++ stderr = self._fo_read_no_intr(self.stderr) + self.wait() + return (stdout, stderr) + +@@ -977,6 +977,62 @@ class Popen(object): + pass + + ++ def _read_no_intr(self, fd, buffersize): ++ """Like os.read, but retries on EINTR""" ++ while True: ++ try: ++ return os.read(fd, buffersize) ++ except OSError, e: ++ if e.errno == errno.EINTR: ++ continue ++ else: ++ raise ++ ++ ++ def _write_no_intr(self, fd, s): ++ """Like os.write, but retries on EINTR""" ++ while True: ++ try: ++ return os.write(fd, s) ++ except OSError, e: ++ if e.errno == errno.EINTR: ++ continue ++ else: ++ raise ++ ++ def _waitpid_no_intr(self, pid, options): ++ """Like os.waitpid, but retries on EINTR""" ++ while True: ++ try: ++ return os.waitpid(pid, options) ++ except OSError, e: ++ if e.errno == errno.EINTR: ++ continue ++ else: ++ raise ++ ++ def _fo_read_no_intr(self, obj): ++ """Like obj.read(), but retries on EINTR""" ++ while True: ++ try: ++ return obj.read() ++ except IOError, e: ++ if e.errno == errno.EINTR: ++ continue ++ else: ++ raise ++ ++ def _fo_write_no_intr(self, obj, data): ++ """Like obj.write(), but retries on EINTR""" ++ while True: ++ try: ++ return obj.write(data) ++ except IOError, e: ++ if e.errno == errno.EINTR: ++ continue ++ else: ++ raise ++ + def _execute_child(self, args, executable, preexec_fn, close_fds, + cwd, env, universal_newlines, + startupinfo, creationflags, shell, +@@ -1055,7 +1121,7 @@ class Popen(object): + exc_value, + tb) + exc_value.child_traceback = ''.join(exc_lines) +- os.write(errpipe_write, pickle.dumps(exc_value)) ++ self._write_no_intr(errpipe_write, pickle.dumps(exc_value)) + + # This exitcode won't be reported to applications, so it + # really doesn't matter what we return. +@@ -1071,10 +1137,10 @@ class Popen(object): + os.close(errwrite) + + # Wait for exec to fail or succeed; possibly raising exception +- data = os.read(errpipe_read, 1048576) # Exceptions limited to 1 MB ++ data = self._read_no_intr(errpipe_read, 1048576) # Exceptions limited to 1 MB + os.close(errpipe_read) + if data != "": +- os.waitpid(self.pid, 0) ++ self._waitpid_no_intr(self.pid, 0) + child_exception = pickle.loads(data) + raise child_exception + +@@ -1094,7 +1160,7 @@ class Popen(object): + attribute.""" + if self.returncode is None: + try: +- pid, sts = os.waitpid(self.pid, os.WNOHANG) ++ pid, sts = self._waitpid_no_intr(self.pid, os.WNOHANG) + if pid == self.pid: + self._handle_exitstatus(sts) + except os.error: +@@ -1107,7 +1173,7 @@ class Popen(object): + """Wait for child process to terminate. Returns returncode + attribute.""" + if self.returncode is None: +- pid, sts = os.waitpid(self.pid, 0) ++ pid, sts = self._waitpid_no_intr(self.pid, 0) + self._handle_exitstatus(sts) + return self.returncode + +@@ -1135,27 +1201,33 @@ class Popen(object): + + input_offset = 0 + while read_set or write_set: +- rlist, wlist, xlist = select.select(read_set, write_set, []) ++ try: ++ rlist, wlist, xlist = select.select(read_set, write_set, []) ++ except select.error, e: ++ if e[0] == errno.EINTR: ++ continue ++ else: ++ raise + + if self.stdin in wlist: + # When select has indicated that the file is writable, + # we can write up to PIPE_BUF bytes without risk + # blocking. POSIX defines PIPE_BUF >= 512 +- bytes_written = os.write(self.stdin.fileno(), buffer(input, input_offset, 512)) ++ bytes_written = self._write_no_intr(self.stdin.fileno(), buffer(input, input_offset, 512)) + input_offset += bytes_written + if input_offset >= len(input): + self.stdin.close() + write_set.remove(self.stdin) + + if self.stdout in rlist: +- data = os.read(self.stdout.fileno(), 1024) ++ data = self._read_no_intr(self.stdout.fileno(), 1024) + if data == "": + self.stdout.close() + read_set.remove(self.stdout) + stdout.append(data) + + if self.stderr in rlist: +- data = os.read(self.stderr.fileno(), 1024) ++ data = self._read_no_intr(self.stderr.fileno(), 1024) + if data == "": + self.stderr.close() + read_set.remove(self.stderr) +--- Lib/test/test_subprocess.py 2007-03-14 19:16:36.000000000 +0100 ++++ Lib/test/test_subprocess.py 2007-03-14 19:18:57.000000000 +0100 +@@ -580,6 +578,34 @@ class ProcessTestCase(unittest.TestCase) + os.remove(fname) + self.assertEqual(rc, 47) + ++ def test_eintr(self): ++ # retries on EINTR for an argv ++ ++ # send ourselves a signal that causes EINTR ++ prev_handler = signal.signal(signal.SIGALRM, lambda x,y: 1) ++ signal.alarm(1) ++ time.sleep(0.5) ++ ++ rc = subprocess.Popen(['sleep', '1']) ++ self.assertEqual(rc.wait(), 0) ++ ++ signal.signal(signal.SIGALRM, prev_handler) ++ ++ def test_eintr_out(self): ++ # retries on EINTR for a shell call and pipelining ++ ++ # send ourselves a signal that causes EINTR ++ prev_handler = signal.signal(signal.SIGALRM, lambda x,y: 1) ++ signal.alarm(1) ++ time.sleep(0.5) ++ ++ rc = subprocess.Popen("sleep 1; echo hello", ++ shell=True, stdout=subprocess.PIPE) ++ out = rc.communicate()[0] ++ self.assertEqual(rc.returncode, 0) ++ self.assertEqual(out, "hello\n") ++ ++ signal.signal(signal.SIGALRM, prev_handler) + + # + # Windows tests diff --git a/python-doc.spec b/python-doc.spec index 52bef9b..80d95b7 100644 --- a/python-doc.spec +++ b/python-doc.spec @@ -17,7 +17,7 @@ Group: Development/Languages/Python BuildRoot: %{_tmppath}/%{name}-%{version}-build Summary: Additional Package Documentation for Python. Version: 2.5.1 -Release: 1 +Release: 15 %define pyver %{version} BuildArch: noarch %define tarname Python-%{pyver} diff --git a/python.changes b/python.changes index 9d51050..4b11169 100644 --- a/python.changes +++ b/python.changes @@ -1,3 +1,16 @@ +------------------------------------------------------------------- +Fri Jul 27 14:51:03 CEST 2007 - jmatejek@suse.cz + +- removed emacs python-mode and dependency on emacs + +------------------------------------------------------------------- +Fri Jun 8 16:33:09 CEST 2007 - jmatejek@suse.cz + +- revisited & explained failing tests +- applied EINTR recovery patch (#278622) +- experimental replacement of shebang strings, + removing dependency on /usr/bin/env + ------------------------------------------------------------------- Thu May 24 18:47:20 CEST 2007 - jmatejek@suse.cz diff --git a/python.spec b/python.spec index 611f07d..e1d22ab 100644 --- a/python.spec +++ b/python.spec @@ -11,25 +11,24 @@ # norootforbuild Name: python -BuildRequires: blt db-devel emacs-nox gcc-c++ gdbm-devel gmp-devel libbz2-devel ncurses-devel openssl-devel readline-devel sqlite-devel tk-devel xorg-x11-devel +BuildRequires: blt db-devel gcc-c++ gdbm-devel gmp-devel libbz2-devel ncurses-devel openssl-devel readline-devel sqlite-devel tk-devel xorg-x11-devel Requires: openssl >= 0.9.8e URL: http://www.python.org/ -License: X11/MIT +License: X11/MIT, PSF LICENSE AGREEMENT FOR PYTHON 2.3 Group: Development/Languages/Python Autoreqprov: on Obsoletes: python-nothreads python21 Summary: Python Interpreter Version: 2.5.1 -Release: 1 +Release: 18 %define tarname Python-%{version} Source0: %{tarname}.tar.bz2 Source6: README.SUSE -Source7: suse-start-python-mode.el Source8: pythonstart Source9: python.sh Source10: python.csh #Source11: testfiles.tar.bz2 -# issues with copyrighted files +# issues with copyrighted Unicode testing files Source13: distutils.cfg Patch01: Python-2.3.3-dirs.patch Patch10: python-distutils-rpm-8.patch @@ -38,6 +37,7 @@ Patch23: ssl-compat.diff Patch25: python-2.4.2-canonicalize2.patch Patch26: python-2.4-localpath.patch Patch27: python-2.5-https_warn.patch +Patch28: python-2.5-subprocess-eintr-safety.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build %define python_version %(echo %{version} | head -c 3) %define idle_name idle @@ -95,7 +95,7 @@ Authors: %package devel Requires: python = %{version} python-tk -Summary: Include Files and Libraries Mandatory for Building Python Modules. +Summary: Include Files and Libraries Mandatory for Building Python Modules Group: Development/Languages/Python Autoreqprov: on @@ -196,12 +196,10 @@ Python2.x, it is part of the core Python distribution. %patch25 %patch26 %patch27 +%patch28 # some cleanup find . -name .cvsignore -type f -print0 | xargs -0 rm -f find . -name CVS -type d -print0 | xargs -0 rm -rf -# replace rest of /usr/local/bin/python with /usr/bin/env python -find . -name '*.py' -type f -print0 | xargs -0 grep -lE '^#! ?(/usr/.*bin/)?python' | xargs sed -r -i -e '1s@^#![[:space:]]*(/usr/(local/)?bin/)?python@#!/usr/bin/env python@' -# the grep inbetween makes it a) faster and b) compile at all :p %build ######################################## @@ -236,10 +234,9 @@ make %{?jobs:-j%jobs} DESTDIR=$RPM_BUILD_ROOT %ifnarch hppa %arm # extensive bsddb test fails (probably on all 64-bit arches): # Berkeley DB library configured to support only private environments -# test_file fails in autobuild env. probably a bug in python, will fix/report +# test_file fails in autobuild env - "stdin.seek(-1)" wrongly succeeds. probably an issue with autobuild's stdin # test_nis fails in autobuild env. probably a misconfiguration of mbuild servers EXCLUDE="-x test_file -x test_nis" -#EXCLUDE="" %ifarch ia64 EXCLUDE="$EXCLUDE -x test_mmap -x test_threaded_import" %endif @@ -249,13 +246,12 @@ make test TESTOPTS="-l $EXCLUDE" # use network, be verbose: #make test TESTOPTS="-l -u network -v" %endif -######################################## -# precompile emacs stuff -######################################## -emacs --batch --no-site -f batch-byte-compile Misc/python-mode.el %install rm -rf $RPM_BUILD_ROOT +# replace rest of /usr/local/bin/python with /usr/bin/env python +find . -wholename "./Parser" -prune -o -name '*.py' -type f -print0 | xargs -0 grep -lE '^#! *(/usr/.*bin/(env +)?)?python' | xargs sed -r -i -e '1s@^#![[:space:]]*(/usr/(local/)?bin/(env +)?)?python@#!/usr/bin/python@' +# the grep inbetween makes it much faster ######################################## # install it ######################################## @@ -308,13 +304,6 @@ install -d -m755 ${RPM_BUILD_ROOT}/etc/%{idle_name} # install Makefile.pre.in and Makefile.pre cp Makefile Makefile.pre.in Makefile.pre $RPM_BUILD_ROOT%{_libdir}/python%{python_version}/config/ ######################################## -# emacs stuff -######################################## -install -d $RPM_BUILD_ROOT%{_prefix}/share/emacs/site-lisp -install -p -m644 Misc/python-mode.el $RPM_BUILD_ROOT%{_prefix}/share/emacs/site-lisp -install -p -m644 Misc/python-mode.elc $RPM_BUILD_ROOT%{_prefix}/share/emacs/site-lisp -install -p -m644 %{S:7} $RPM_BUILD_ROOT%{_prefix}/share/emacs/site-lisp -######################################## # startup script ######################################## install -m 644 %{S:8} $RPM_BUILD_ROOT/etc @@ -382,7 +371,6 @@ rm -rf $RPM_BUILD_ROOT %defattr(644, root, root, 755) %config /etc/pythonstart %config /etc/profile.d/python.* -%{_prefix}/share/emacs/site-lisp/* %dir %{_docdir}/%{name} %doc %{_docdir}/%{name}/README %doc %{_docdir}/%{name}/LICENSE @@ -473,6 +461,13 @@ rm -rf $RPM_BUILD_ROOT %attr(755, root, root) %{_bindir}/smtpd.py %changelog +* Fri Jul 27 2007 - jmatejek@suse.cz +- removed emacs python-mode and dependency on emacs +* Fri Jun 08 2007 - jmatejek@suse.cz +- revisited & explained failing tests +- applied EINTR recovery patch (#278622) +- experimental replacement of shebang strings, + removing dependency on /usr/bin/env * Thu May 24 2007 - jmatejek@suse.cz - update to 2.5.1 - bugfix only release, over 150 bugs fixed diff --git a/suse-start-python-mode.el b/suse-start-python-mode.el deleted file mode 100644 index 2d4c34b..0000000 --- a/suse-start-python-mode.el +++ /dev/null @@ -1,3 +0,0 @@ -(autoload 'python-mode "python-mode") -(add-to-list 'auto-mode-alist - '("\\.py\\'" . python-mode))