merge heads
diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst
index 4d5058e..90bd0dd 100644
--- 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
index 68a5d2c..f2a37cc 100644
--- 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
index df47045..504a2fb 100644
--- 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
index 3a8a639..1a4b241 100644
--- 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
index cd2bbb6..9f94532 100644
--- 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
index d5a2521..4b37286 100644
--- 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
index f803360..092874a 100644
--- 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
index 0000000..7763250
--- /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
index 0000000..fc398d6
--- /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
index 0000000..d5c9d6e
--- /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
index 0000000..2cece21
--- /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
index 126f97c..7bcc436 100644
--- 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
index b5e5127..29e8648 100755
--- 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
index 327ac66..7236474 100644
--- 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
index 0000000..8c6e8a5
--- /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
index 86c68dc..4448072 100644
--- 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
index a48fbe4..7735976 100644
--- 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
index cdd3f3e..4bf2d2d 100644
--- 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
index 04bdfef..bc0f34c 100644
--- 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
index 7791935..6919d21 100644
--- 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
index c22d965..12e596e 100644
--- 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
index fafe779..1f638b4 100644
--- 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
index 350cc3c..0fc999d 100644
--- 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
index 785761c..ff7ed66 100644
--- 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
index bb8176f..1b37845 100644
--- 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
index 11e145f..f992573 100644
--- 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
index b12d052..fb4b805 100644
--- 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 */