[Python-checkins] cpython (merge default -> default): merge heads

benjamin.peterson python-checkins at python.org
Tue May 31 02:25:45 CEST 2011


http://hg.python.org/cpython/rev/94066c3e2236
changeset:   70544:94066c3e2236
parent:      70543:6401ca1ee959
parent:      70542:1a9ccb5bef27
user:        Benjamin Peterson <benjamin at 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 at 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 at 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 at 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 at 8l$r!V(BPython$B!W$HL>$E$1$^$7$?!#(B
+$B$3$N$h$&$JGX7J$+$i at 8$^$l$?(B Python $B$N8 at 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 at 8l$G$O%f!<%6$NL\@h$NMxJX at -$rM%@h$7$F?'!9$J5!G=$r8 at 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 at 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 at L=c(Python)@: 9h?l1b =10m, 0-7BGQ GA7N1W7!9V >p>n at T4O4Y. FD at L=c@:
+H?@2@{@N 0m<vAX 5%@LEM 18A6?M 0#4\GOAv88 H?@2@{@N 04C<AvGbGA7N1W7!9V@;
+Av?xGU4O4Y. FD at L=c at G ?l>F(iPd:)GQ 9.9}0z 5?@{ E8 at LGN, 1W8.0m @NEMGA8.FC
+H/0f@: FD at L=c@; =:E)83FC0z ?)7/ :P>_?!<-?M 4k:N:P at G GC7'F{?!<- at G :|8%
+>VGC8.DI at L<G 039_@; GR <v @V4B @L;s@{@N >p>n7N 885i>nA]4O4Y.
+
+!YC90!3!: 3/>F6s >1~ E-! 1]>x at 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


More information about the Python-checkins mailing list