cpython (merge default -> default): merge heads
http://hg.python.org/cpython/rev/94066c3e2236 changeset: 70544:94066c3e2236 parent: 70543:6401ca1ee959 parent: 70542:1a9ccb5bef27 user: Benjamin Peterson <benjamin@python.org> date: Mon May 30 19:25:43 2011 -0500 summary: merge heads files: Doc/library/codecs.rst | 3 +- Doc/library/signal.rst | 7 +- Doc/library/threading.rst | 19 +++- Lib/logging/__init__.py | 11 +- Lib/packaging/install.py | 27 +++++- Lib/packaging/tests/test_uninstall.py | 30 +++++- Lib/reprlib.py | 2 +- Lib/test/cjkencodings/iso2022_jp-utf8.txt | 7 + Lib/test/cjkencodings/iso2022_jp.txt | 7 + Lib/test/cjkencodings/iso2022_kr-utf8.txt | 7 + Lib/test/cjkencodings/iso2022_kr.txt | 7 + Lib/test/lock_tests.py | 4 +- Lib/test/regrtest.py | 4 - Lib/test/test_capi.py | 5 +- Lib/test/test_codecencodings_iso2022.py | 46 +++++++++++ Lib/test/test_multibytecodec.py | 9 +- Lib/test/test_multibytecodec_support.py | 4 +- Lib/test/test_signal.py | 4 +- Lib/test/test_sys.py | 6 +- Lib/test/test_threaded_import.py | 2 +- Lib/test/test_threading.py | 4 +- Lib/threading.py | 21 ++-- Misc/ACKS | 38 +++++++++ Misc/NEWS | 16 +++- Modules/cjkcodecs/multibytecodec.c | 14 ++- Objects/abstract.c | 3 +- Parser/myreadline.c | 1 + 27 files changed, 247 insertions(+), 61 deletions(-) diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -458,7 +458,8 @@ .. method:: reset() - Reset the encoder to the initial state. + Reset the encoder to the initial state. The output is discarded: call + ``.encode('', final=True)`` to reset the encoder and to get the output. .. method:: IncrementalEncoder.getstate() diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -187,10 +187,9 @@ Send the signal *signum* to the thread *thread_id*, another thread in the same process as the caller. The signal is asynchronously directed to thread. - *thread_id* can be read from the :attr:`~threading.Thread.ident` attribute - of :attr:`threading.Thread`. For example, - ``threading.current_thread().ident`` gives the identifier of the current - thread. + Use :func:`threading.get_ident()` or the :attr:`~threading.Thread.ident` + attribute of :attr:`threading.Thread` to get a 'thread identifier' for + *thread_id*. If *signum* is 0, then no signal is sent, but error checking is still performed; this can be used to check if a thread is still running. diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -48,6 +48,17 @@ returned. +.. function:: get_ident() + + Return the 'thread identifier' of the current thread. This is a nonzero + integer. Its value has no direct meaning; it is intended as a magic cookie + to be used e.g. to index a dictionary of thread-specific data. Thread + identifiers may be recycled when a thread exits and another thread is + created. + + .. versionadded:: 3.3 + + .. function:: enumerate() Return a list of all :class:`Thread` objects currently alive. The list @@ -332,10 +343,10 @@ .. attribute:: ident The 'thread identifier' of this thread or ``None`` if the thread has not - been started. This is a nonzero integer. See the - :func:`thread.get_ident()` function. Thread identifiers may be recycled - when a thread exits and another thread is created. The identifier is - available even after the thread has exited. + been started. This is a nonzero integer. See the :func:`get_ident()` + function. Thread identifiers may be recycled when a thread exits and + another thread is created. The identifier is available even after the + thread has exited. .. method:: is_alive() diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -41,10 +41,9 @@ codecs = None try: - import _thread as thread import threading except ImportError: #pragma: no cover - thread = None + threading = None __author__ = "Vinay Sajip <vinay_sajip@red-dove.com>" __status__ = "production" @@ -199,7 +198,7 @@ #the lock would already have been acquired - so we need an RLock. #The same argument applies to Loggers and Manager.loggerDict. # -if thread: +if threading: _lock = threading.RLock() else: #pragma: no cover _lock = None @@ -278,8 +277,8 @@ self.created = ct self.msecs = (ct - int(ct)) * 1000 self.relativeCreated = (self.created - _startTime) * 1000 - if logThreads and thread: - self.thread = thread.get_ident() + if logThreads and threading: + self.thread = threading.get_ident() self.threadName = threading.current_thread().name else: # pragma: no cover self.thread = None @@ -773,7 +772,7 @@ """ Acquire a thread lock for serializing access to the underlying I/O. """ - if thread: + if threading: self.lock = threading.RLock() else: #pragma: no cover self.lock = None diff --git a/Lib/packaging/install.py b/Lib/packaging/install.py --- a/Lib/packaging/install.py +++ b/Lib/packaging/install.py @@ -376,7 +376,10 @@ def remove(project_name, paths=sys.path, auto_confirm=True): - """Removes a single project from the installation""" + """Removes a single project from the installation. + + Returns True on success + """ dist = get_distribution(project_name, use_egg_info=True, paths=paths) if dist is None: raise PackagingError('Distribution "%s" not found' % project_name) @@ -384,13 +387,26 @@ rmdirs = [] rmfiles = [] tmp = tempfile.mkdtemp(prefix=project_name + '-uninstall') + + def _move_file(source, target): + try: + os.rename(source, target) + except OSError as err: + return err + return None + + success = True + error = None try: for file_, md5, size in files: if os.path.isfile(file_): dirname, filename = os.path.split(file_) tmpfile = os.path.join(tmp, filename) try: - os.rename(file_, tmpfile) + error = _move_file(file_, tmpfile) + if error is not None: + success = False + break finally: if not os.path.isfile(file_): os.rename(tmpfile, file_) @@ -401,6 +417,11 @@ finally: shutil.rmtree(tmp) + if not success: + logger.info('%r cannot be removed.', project_name) + logger.info('Error: %s' % str(error)) + return False + logger.info('Removing %r: ', project_name) for file_ in rmfiles: @@ -447,6 +468,8 @@ logger.info('Success: removed %d files and %d dirs', file_count, dir_count) + return True + def install(project): logger.info('Getting information about %r...', project) diff --git a/Lib/packaging/tests/test_uninstall.py b/Lib/packaging/tests/test_uninstall.py --- a/Lib/packaging/tests/test_uninstall.py +++ b/Lib/packaging/tests/test_uninstall.py @@ -2,6 +2,7 @@ import os import sys from io import StringIO +import stat from packaging.database import disable_cache, enable_cache from packaging.run import main @@ -80,12 +81,9 @@ if not dirname: dirname = self.make_dist(name, **kw) os.chdir(dirname) - old_out = sys.stdout + old_out = sys.stderr sys.stderr = StringIO() - try: - dist = self.run_setup('install_dist', '--prefix=' + self.root_dir) - finally: - sys.sterr = old_out + dist = self.run_setup('install_dist', '--prefix=' + self.root_dir) install_lib = self.get_path(dist, 'purelib') return dist, install_lib @@ -99,10 +97,30 @@ self.assertIsFile(install_lib, 'foo', '__init__.py') self.assertIsFile(install_lib, 'foo', 'sub', '__init__.py') self.assertIsFile(install_lib, 'Foo-0.1.dist-info', 'RECORD') - remove('Foo', paths=[install_lib]) + self.assertTrue(remove('Foo', paths=[install_lib])) self.assertIsNotFile(install_lib, 'foo', 'sub', '__init__.py') self.assertIsNotFile(install_lib, 'Foo-0.1.dist-info', 'RECORD') + @unittest.skipIf(sys.platform == 'win32', 'deactivated for now') + def test_remove_issue(self): + # makes sure if there are OSErrors (like permission denied) + # remove() stops and display a clean error + dist, install_lib = self.install_dist('Meh') + + # breaking os.rename + old = os.rename + + def _rename(source, target): + raise OSError() + + os.rename = _rename + try: + self.assertFalse(remove('Meh', paths=[install_lib])) + finally: + os.rename = old + + self.assertTrue(remove('Meh', paths=[install_lib])) + def test_suite(): return unittest.makeSuite(UninstallTestCase) diff --git a/Lib/reprlib.py b/Lib/reprlib.py --- a/Lib/reprlib.py +++ b/Lib/reprlib.py @@ -5,7 +5,7 @@ import builtins from itertools import islice try: - from _thread import get_ident + from threading import get_ident except ImportError: from _dummy_thread import get_ident diff --git a/Lib/test/cjkencodings/iso2022_jp-utf8.txt b/Lib/test/cjkencodings/iso2022_jp-utf8.txt new file mode 100644 --- /dev/null +++ b/Lib/test/cjkencodings/iso2022_jp-utf8.txt @@ -0,0 +1,7 @@ +Python の開発は、1990 年ごろから開始されています。 +開発者の Guido van Rossum は教育用のプログラミング言語「ABC」の開発に参加していましたが、ABC は実用上の目的にはあまり適していませんでした。 +このため、Guido はより実用的なプログラミング言語の開発を開始し、英国 BBS 放送のコメディ番組「モンティ パイソン」のファンである Guido はこの言語を「Python」と名づけました。 +このような背景から生まれた Python の言語設計は、「シンプル」で「習得が容易」という目標に重点が置かれています。 +多くのスクリプト系言語ではユーザの目先の利便性を優先して色々な機能を言語要素として取り入れる場合が多いのですが、Python ではそういった小細工が追加されることはあまりありません。 +言語自体の機能は最小限に押さえ、必要な機能は拡張モジュールとして追加する、というのが Python のポリシーです。 + diff --git a/Lib/test/cjkencodings/iso2022_jp.txt b/Lib/test/cjkencodings/iso2022_jp.txt new file mode 100644 --- /dev/null +++ b/Lib/test/cjkencodings/iso2022_jp.txt @@ -0,0 +1,7 @@ +Python $B$N3+H/$O!"(B1990 $BG/$4$m$+$i3+;O$5$l$F$$$^$9!#(B +$B3+H/<T$N(B Guido van Rossum $B$O650iMQ$N%W%m%0%i%_%s%08@8l!V(BABC$B!W$N3+H/$K;22C$7$F$$$^$7$?$,!"(BABC $B$O<BMQ>e$NL\E*$K$O$"$^$jE,$7$F$$$^$;$s$G$7$?!#(B +$B$3$N$?$a!"(BGuido $B$O$h$j<BMQE*$J%W%m%0%i%_%s%08@8l$N3+H/$r3+;O$7!"1Q9q(B BBS $BJ|Aw$N%3%a%G%#HVAH!V%b%s%F%#(B $B%Q%$%=%s!W$N%U%!%s$G$"$k(B Guido $B$O$3$N8@8l$r!V(BPython$B!W$HL>$E$1$^$7$?!#(B +$B$3$N$h$&$JGX7J$+$i@8$^$l$?(B Python $B$N8@8l@_7W$O!"!V%7%s%W%k!W$G!V=,F@$,MF0W!W$H$$$&L\I8$K=EE@$,CV$+$l$F$$$^$9!#(B +$BB?$/$N%9%/%j%W%H7O8@8l$G$O%f!<%6$NL\@h$NMxJX@-$rM%@h$7$F?'!9$J5!G=$r8@8lMWAG$H$7$F<h$jF~$l$k>l9g$,B?$$$N$G$9$,!"(BPython $B$G$O$=$&$$$C$?>.:Y9)$,DI2C$5$l$k$3$H$O$"$^$j$"$j$^$;$s!#(B +$B8@8l<+BN$N5!G=$O:G>.8B$K2!$5$(!"I,MW$J5!G=$O3HD%%b%8%e!<%k$H$7$FDI2C$9$k!"$H$$$&$N$,(B Python $B$N%]%j%7!<$G$9!#(B + diff --git a/Lib/test/cjkencodings/iso2022_kr-utf8.txt b/Lib/test/cjkencodings/iso2022_kr-utf8.txt new file mode 100644 --- /dev/null +++ b/Lib/test/cjkencodings/iso2022_kr-utf8.txt @@ -0,0 +1,7 @@ +◎ 파이썬(Python)은 배우기 쉽고, 강력한 프로그래밍 언어입니다. 파이썬은 +효율적인 고수준 데이터 구조와 간단하지만 효율적인 객체지향프로그래밍을 +지원합니다. 파이썬의 우아(優雅)한 문법과 동적 타이핑, 그리고 인터프리팅 +환경은 파이썬을 스크립팅과 여러 분야에서와 대부분의 플랫폼에서의 빠른 +애플리케이션 개발을 할 수 있는 이상적인 언어로 만들어줍니다. + +☆첫가끝: 날아라 쓩~ 큼! 금없이 전니다. 그런거 다. diff --git a/Lib/test/cjkencodings/iso2022_kr.txt b/Lib/test/cjkencodings/iso2022_kr.txt new file mode 100644 --- /dev/null +++ b/Lib/test/cjkencodings/iso2022_kr.txt @@ -0,0 +1,7 @@ +$)C!] FD@L=c(Python)@: 9h?l1b =10m, 0-7BGQ GA7N1W7!9V >p>n@T4O4Y. FD@L=c@: +H?@2@{@N 0m<vAX 5%@LEM 18A6?M 0#4\GOAv88 H?@2@{@N 04C<AvGbGA7N1W7!9V@; +Av?xGU4O4Y. FD@L=c@G ?l>F(iPd:)GQ 9.9}0z 5?@{ E8@LGN, 1W8.0m @NEMGA8.FC +H/0f@: FD@L=c@; =:E)83FC0z ?)7/ :P>_?!<-?M 4k:N:P@G GC7'F{?!<-@G :|8% +>VGC8.DI@L<G 039_@; GR <v @V4B @L;s@{@N >p>n7N 885i>nA]4O4Y. + +!YC90!3!: 3/>F6s >1~ E-! 1]>x@L @|4O4Y. 1W710E 4Y. diff --git a/Lib/test/lock_tests.py b/Lib/test/lock_tests.py --- a/Lib/test/lock_tests.py +++ b/Lib/test/lock_tests.py @@ -4,7 +4,7 @@ import sys import time -from _thread import start_new_thread, get_ident, TIMEOUT_MAX +from _thread import start_new_thread, TIMEOUT_MAX import threading import unittest @@ -31,7 +31,7 @@ self.finished = [] self._can_exit = not wait_before_exit def task(): - tid = get_ident() + tid = threading.get_ident() self.started.append(tid) try: f() diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -1023,10 +1023,6 @@ def runtest_inner(test, verbose, quiet, huntrleaks=False, debug=False): support.unload(test) - if verbose: - capture_stdout = None - else: - capture_stdout = io.StringIO() test_time = 0.0 refleak = False # True if the test leaked references. diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -190,18 +190,17 @@ idents = [] def callback(): - idents.append(_thread.get_ident()) + idents.append(threading.get_ident()) _testcapi._test_thread_state(callback) a = b = callback time.sleep(1) # Check our main thread is in the list exactly 3 times. - if idents.count(_thread.get_ident()) != 3: + if idents.count(threading.get_ident()) != 3: raise support.TestFailed( "Couldn't find main thread correctly in the list") if threading: - import _thread import time TestThreadState() t = threading.Thread(target=TestThreadState) diff --git a/Lib/test/test_codecencodings_iso2022.py b/Lib/test/test_codecencodings_iso2022.py new file mode 100644 --- /dev/null +++ b/Lib/test/test_codecencodings_iso2022.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +# +# Codec encoding tests for ISO 2022 encodings. + +from test import support +from test import test_multibytecodec_support +import unittest + +COMMON_CODEC_TESTS = ( + # invalid bytes + (b'ab\xFFcd', 'replace', 'ab\uFFFDcd'), + (b'ab\x1Bdef', 'replace', 'ab\x1Bdef'), + (b'ab\x1B$def', 'replace', 'ab\uFFFD'), + ) + +class Test_ISO2022_JP(test_multibytecodec_support.TestBase, unittest.TestCase): + encoding = 'iso2022_jp' + tstring = test_multibytecodec_support.load_teststring('iso2022_jp') + codectests = COMMON_CODEC_TESTS + ( + (b'ab\x1BNdef', 'replace', 'ab\x1BNdef'), + ) + +class Test_ISO2022_JP2(test_multibytecodec_support.TestBase, unittest.TestCase): + encoding = 'iso2022_jp_2' + tstring = test_multibytecodec_support.load_teststring('iso2022_jp') + codectests = COMMON_CODEC_TESTS + ( + (b'ab\x1BNdef', 'replace', 'abdef'), + ) + +class Test_ISO2022_KR(test_multibytecodec_support.TestBase, unittest.TestCase): + encoding = 'iso2022_kr' + tstring = test_multibytecodec_support.load_teststring('iso2022_kr') + codectests = COMMON_CODEC_TESTS + ( + (b'ab\x1BNdef', 'replace', 'ab\x1BNdef'), + ) + + # iso2022_kr.txt cannot be used to test "chunk coding": the escape + # sequence is only written on the first line + def test_chunkcoding(self): + pass + +def test_main(): + support.run_unittest(__name__) + +if __name__ == "__main__": + test_main() diff --git a/Lib/test/test_multibytecodec.py b/Lib/test/test_multibytecodec.py --- a/Lib/test/test_multibytecodec.py +++ b/Lib/test/test_multibytecodec.py @@ -260,7 +260,8 @@ text = '\u4E16\u4E16' encoding = 'iso-2022-jp' expected = b'\x1b$B@$@$' - expected_reset = b'\x1b$B@$@$\x1b(B' + reset = b'\x1b(B' + expected_reset = expected + reset def test_encode(self): self.assertEqual(self.text.encode(self.encoding), self.expected_reset) @@ -271,6 +272,8 @@ encoder.encode(char) for char in self.text) self.assertEqual(output, self.expected) + self.assertEqual(encoder.encode('', final=True), self.reset) + self.assertEqual(encoder.encode('', final=True), b'') def test_incrementalencoder_final(self): encoder = codecs.getincrementalencoder(self.encoding)() @@ -279,12 +282,14 @@ encoder.encode(char, index == last_index) for index, char in enumerate(self.text)) self.assertEqual(output, self.expected_reset) + self.assertEqual(encoder.encode('', final=True), b'') class TestHZStateful(TestStateful): text = '\u804a\u804a' encoding = 'hz' expected = b'~{ADAD' - expected_reset = b'~{ADAD~}' + reset = b'~}' + expected_reset = expected + reset def test_main(): support.run_unittest(__name__) diff --git a/Lib/test/test_multibytecodec_support.py b/Lib/test/test_multibytecodec_support.py --- a/Lib/test/test_multibytecodec_support.py +++ b/Lib/test/test_multibytecodec_support.py @@ -60,7 +60,9 @@ self.assertTrue(type(result) is str, type(result)) else: self.assertTrue(type(result) is bytes, type(result)) - self.assertEqual(result, expected) + self.assertEqual(result, expected, + '%a.decode(%r)=%a != %a' + % (source, self.encoding, result, expected)) else: self.assertRaises(UnicodeError, func, source, scheme) diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -557,7 +557,7 @@ def kill(self, signum): if self.has_pthread_kill: - tid = threading.current_thread().ident + tid = threading.get_ident() signal.pthread_kill(tid, signum) else: pid = os.getpid() @@ -589,7 +589,7 @@ 'need signal.pthread_kill()') def test_pthread_kill(self): signum = signal.SIGUSR1 - current = threading.current_thread().ident + current = threading.get_ident() old_handler = signal.signal(signum, self.handler) self.addCleanup(signal.signal, signum, old_handler) diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -343,7 +343,7 @@ # Test sys._current_frames() in a WITH_THREADS build. @test.support.reap_threads def current_frames_with_threads(self): - import threading, _thread + import threading import traceback # Spawn a thread that blocks at a known place. Then the main @@ -357,7 +357,7 @@ g456() def g456(): - thread_info.append(_thread.get_ident()) + thread_info.append(threading.get_ident()) entered_g.set() leave_g.wait() @@ -373,7 +373,7 @@ d = sys._current_frames() - main_id = _thread.get_ident() + main_id = threading.get_ident() self.assertIn(main_id, d) self.assertIn(thread_id, d) diff --git a/Lib/test/test_threaded_import.py b/Lib/test/test_threaded_import.py --- a/Lib/test/test_threaded_import.py +++ b/Lib/test/test_threaded_import.py @@ -30,7 +30,7 @@ except Exception as e: errors.append(e.with_traceback(None)) finally: - done_tasks.append(thread.get_ident()) + done_tasks.append(threading.get_ident()) finished = len(done_tasks) == N if finished: done.set() diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -173,7 +173,7 @@ exception = ctypes.py_object(AsyncExc) # First check it works when setting the exception from the same thread. - tid = _thread.get_ident() + tid = threading.get_ident() try: result = set_async_exc(ctypes.c_long(tid), exception) @@ -202,7 +202,7 @@ class Worker(threading.Thread): def run(self): - self.id = _thread.get_ident() + self.id = threading.get_ident() self.finished = False try: diff --git a/Lib/threading.py b/Lib/threading.py --- a/Lib/threading.py +++ b/Lib/threading.py @@ -24,7 +24,7 @@ # Rename some stuff so "from threading import *" is safe _start_new_thread = _thread.start_new_thread _allocate_lock = _thread.allocate_lock -_get_ident = _thread.get_ident +get_ident = _thread.get_ident ThreadError = _thread.error try: _CRLock = _thread.RLock @@ -52,7 +52,7 @@ format = format % args # Issue #4188: calling current_thread() can incur an infinite # recursion if it has to create a DummyThread on the fly. - ident = _get_ident() + ident = get_ident() try: name = _active[ident].name except KeyError: @@ -110,7 +110,7 @@ self.__class__.__name__, owner, self._count) def acquire(self, blocking=True, timeout=-1): - me = _get_ident() + me = get_ident() if self._owner == me: self._count = self._count + 1 if __debug__: @@ -130,7 +130,7 @@ __enter__ = acquire def release(self): - if self._owner != _get_ident(): + if self._owner != get_ident(): raise RuntimeError("cannot release un-acquired lock") self._count = count = self._count - 1 if not count: @@ -166,7 +166,7 @@ return (count, owner) def _is_owned(self): - return self._owner == _get_ident() + return self._owner == get_ident() _PyRLock = _RLock @@ -714,7 +714,7 @@ raise def _set_ident(self): - self._ident = _get_ident() + self._ident = get_ident() def _bootstrap_inner(self): try: @@ -787,7 +787,7 @@ try: # We don't call self._delete() because it also # grabs _active_limbo_lock. - del _active[_get_ident()] + del _active[get_ident()] except: pass @@ -823,7 +823,7 @@ try: with _active_limbo_lock: - del _active[_get_ident()] + del _active[get_ident()] # There must not be any python code between the previous line # and after the lock is released. Otherwise a tracing function # could try to acquire the lock again in the same thread, (in @@ -1006,9 +1006,8 @@ def current_thread(): try: - return _active[_get_ident()] + return _active[get_ident()] except KeyError: - ##print "current_thread(): no current thread for", _get_ident() return _DummyThread() currentThread = current_thread @@ -1062,7 +1061,7 @@ if thread is current: # There is only one active thread. We reset the ident to # its new value since it can have changed. - ident = _get_ident() + ident = get_ident() thread._ident = ident # Any condition variables hanging off of the active thread may # be in an invalid state, so we reinitialize them. diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -12,7 +12,9 @@ and the list is in rough alphabetical order by last names. David Abrahams +Rajiv Abraham Ron Adam +Ali Afshar Jim Ahlstrom Farhan Ahmad Matthew Ahrens @@ -58,6 +60,7 @@ Cesar Eduardo Barros Des Barry Ulf Bartelt +Pior Bastida Nick Bastin Jeff Bauer Mike Bayer @@ -122,6 +125,7 @@ Daniel Brotsky Jean Brouwers Gary S. Brown +Titus Brown Oleg Broytmann Dave Brueck Stan Bubrouski @@ -135,6 +139,7 @@ Tarn Weisner Burton Lee Busby Ralph Butler +Nicolas Cadou Jp Calderone Daniel Calvelo Tony Campbell @@ -153,6 +158,7 @@ Mitch Chapman Greg Chapman Brad Chapman +Godefroid Chapelle David Chaum Nicolas Chauvat Jerry Chen @@ -176,6 +182,7 @@ Jeffery Collins Robert Collins Paul Colomiets +Christophe Combelles Denver Coneybeare Geremy Condra Juan José Conti @@ -206,6 +213,7 @@ Lars Damerow Evan Dandrea Eric Daniel +Pierre-Yves David Scott David Daniels Ben Darnell Jonathan Dasteel @@ -213,6 +221,7 @@ Ned Deily Vincent Delft Arnaud Delobelle +Konrad Delong Erik Demaine Roger Dev Raghuram Devarakonda @@ -226,6 +235,7 @@ Humberto Diogenes Yves Dionne Daniel Dittmar +Josip Djolonga Jaromir Dolecek Ismail Donmez Marcos Donolo @@ -264,6 +274,7 @@ Michael Ernst Ben Escoto Andy Eskilsson +André Espaze Stefan Esser Stephen D Evans Carey Evans @@ -277,8 +288,10 @@ Clovis Fabricio Andreas Faerber Bill Fancher +Andrew Francis Troy J. Farrell Mark Favas +Boris Feld Niels Ferguson Sebastian Fernandez Florian Festi @@ -328,6 +341,7 @@ Jonathan Giddy Johannes Gijsbers Michael Gilfix +Yannick Gingras Christoph Gohlke Tim Golden Chris Gonnerman @@ -351,6 +365,7 @@ Bob Halley Jesse Hallio Jun Hamano +Alexandre Hamelin Mark Hammond Manus Hand Milton L. Hankins @@ -382,6 +397,7 @@ Magnus L. Hetland Raymond Hettinger Kevan Heydon +Kelsey Hightower Jason Hildebrand Richie Hindle Konrad Hinsen @@ -409,6 +425,7 @@ Ken Howard Brad Howes Chih-Hao Huang +Christian Hudon Lawrence Hudson Michael Hudson Jim Hugunin @@ -436,6 +453,7 @@ Geert Jansen Jack Jansen Bill Janssen +Julien Jehannet Drew Jenkins Flemming Kjær Jensen MunSic Jeong @@ -484,6 +502,7 @@ Bastian Kleineidam Bob Kline Matthias Klose +Jeremy Kloth Kim Knapp Lenny Kneler Pat Knight @@ -512,11 +531,13 @@ Andrew Langmead Detlef Lannert Soren Larsen +Amos Latteier Piers Lauder Ben Laurie Simon Law Chris Lawrence Brian Leair +Mathieu Leduc-Hamel James Lee John J. Lee Inyeol Lee @@ -532,6 +553,7 @@ Marc-Andre Lemburg John Lenton Christopher Tur Lesniewski-Laas +Alain Leufroy Mark Levinson William Lewis Xuanji Li @@ -576,6 +598,7 @@ Sébastien Martini Roger Masse Nick Mathewson +Simon Mathieu Graham Matthews Dieter Maurer Arnaud Mazin @@ -595,7 +618,9 @@ Ezio Melotti Brian Merrell Luke Mewburn +Carl Meyer Mike Meyer +Alexis Métaireau Steven Miale Trent Mick Stan Mihai @@ -605,21 +630,26 @@ Jason V. Miller Jay T. Miller Roman Milner +Julien Miotte Andrii V. Mishkovskyi Dustin J. Mitchell Dom Mitchell +Zubin Mithra Doug Moen The Dragon De Monsyne Skip Montanaro Paul Moore Derek Morr James A Morrison +Derek McTavish Mounce Pablo Mouzo Mher Movsisyan Sjoerd Mullender Sape Mullender Michael Muller Neil Muller +Michael Mulich +Louis Munro R. David Murray Piotr Meyer John Nagle @@ -672,11 +702,14 @@ Alexandre Parenteau Dan Parisien Harri Pasanen +Gaël Pasgrimaud Randy Pausch Samuele Pedroni Marcel van der Peijl Steven Pemberton Santiago Peresón +George Peristerakis +Mathieu Perreault Mark Perrego Trevor Perrin Gabriel de Perthuis @@ -685,6 +718,7 @@ Joe Peterson Chris Petrilli Bjorn Pettersen +Ronny Pfannschmidt Geoff Philbrick Gavrie Philipson Adrian Phillips @@ -731,6 +765,7 @@ Bernhard Reiter Steven Reiz Roeland Rengelink +Antoine Reversat Tim Rice Francesco Ricciardi Jan Pieter Riegel @@ -745,11 +780,14 @@ Mark Roddy Kevin Rodgers Giampaolo Rodola +Luis Rojas Mike Romberg Armin Ronacher Case Roole Timothy Roscoe +Erik Rose Jim Roskind +Brian Rosner Just van Rossum Hugo van Rossum Saskia van Rossum diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,10 @@ Core and Builtins ----------------- +- Issue #1195: my_fgets() now always clears errors before calling fgets(). Fix + the following case: sys.stdin.read() stopped with CTRL+d (end of file), + raw_input() interrupted by CTRL+c. + - Issue #12216: Allow unexpected EOF errors to happen on any line of the file. - Issue #12199: The TryExcept and TryFinally and AST nodes have been unified @@ -177,9 +181,16 @@ Library ------- +- Issue #12028: Make threading._get_ident() public, rename it to + threading.get_ident() and document it. This function was already used using + _thread.get_ident(). + +- Issue #12171: IncrementalEncoder.reset() of CJK codecs (multibytecodec) calls + encreset() instead of decreset(). + - Issue #12218: Removed wsgiref.egg-info. -- Issue #12196: Add pipe2() to the os module. +- Issue #12196: Add pipe2() to the os module. - Issue #985064: Make plistlib more resilient to faulty input plists. Patch by Mher Movsisyan. @@ -774,6 +785,9 @@ Tests ----- +- Issue #12057: Add tests for ISO 2022 codecs (iso2022_jp, iso2022_jp_2, + iso2022_kr). + - Issue #12180: Fixed a few remaining errors in test_packaging when no threading. diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -901,11 +901,17 @@ static PyObject * mbiencoder_reset(MultibyteIncrementalEncoderObject *self) { - if (self->codec->decreset != NULL && - self->codec->decreset(&self->state, self->codec->config) != 0) - return NULL; + /* Longest output: 4 bytes (b'\x0F\x1F(B') with ISO 2022 */ + unsigned char buffer[4], *outbuf; + Py_ssize_t r; + if (self->codec->encreset != NULL) { + outbuf = buffer; + r = self->codec->encreset(&self->state, self->codec->config, + &outbuf, sizeof(buffer)); + if (r != 0) + return NULL; + } self->pendingsize = 0; - Py_RETURN_NONE; } diff --git a/Objects/abstract.c b/Objects/abstract.c --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -237,7 +237,8 @@ pb = obj->ob_type->tp_as_buffer; if (pb == NULL || pb->bf_getbuffer == NULL) { PyErr_SetString(PyExc_TypeError, - "expected an object with the buffer interface"); + "expected bytes, bytearray " + "or buffer compatible object"); return -1; } if ((*pb->bf_getbuffer)(obj, &view, PyBUF_SIMPLE)) return -1; diff --git a/Parser/myreadline.c b/Parser/myreadline.c --- a/Parser/myreadline.c +++ b/Parser/myreadline.c @@ -40,6 +40,7 @@ if (PyOS_InputHook != NULL) (void)(PyOS_InputHook)(); errno = 0; + clearerr(fp); p = fgets(buf, len, fp); if (p != NULL) return 0; /* No error */ -- Repository URL: http://hg.python.org/cpython
participants (1)
-
benjamin.peterson