Commit 388c0e23 authored by Benjamin Peterson's avatar Benjamin Peterson

merge heads

parents 6d8f7447 900c292c
......@@ -598,6 +598,17 @@ The module :mod:`curses` defines the following functions:
Only one *ch* can be pushed before :meth:`getch` is called.
.. function:: unget_wch(ch)
Push *ch* so the next :meth:`get_wch` will return it.
.. note::
Only one *ch* can be pushed before :meth:`get_wch` is called.
.. versionadded:: 3.3
.. function:: ungetmouse(id, x, y, z, bstate)
Push a :const:`KEY_MOUSE` event onto the input queue, associating the given
......
......@@ -571,9 +571,9 @@ For an example of the usage of queues for interprocess communication see
Return ``True`` if the queue is full, ``False`` otherwise. Because of
multithreading/multiprocessing semantics, this is not reliable.
.. method:: put(item[, block[, timeout]])
.. method:: put(obj[, block[, timeout]])
Put item into the queue. If the optional argument *block* is ``True``
Put obj into the queue. If the optional argument *block* is ``True``
(the default) and *timeout* is ``None`` (the default), block if necessary until
a free slot is available. If *timeout* is a positive number, it blocks at
most *timeout* seconds and raises the :exc:`queue.Full` exception if no
......@@ -582,9 +582,9 @@ For an example of the usage of queues for interprocess communication see
available, else raise the :exc:`queue.Full` exception (*timeout* is
ignored in that case).
.. method:: put_nowait(item)
.. method:: put_nowait(obj)
Equivalent to ``put(item, False)``.
Equivalent to ``put(obj, False)``.
.. method:: get([block[, timeout]])
......
......@@ -72,7 +72,7 @@ Extending files
---------------
A configuration file can be extended (i.e. included) by other files. For this,
a ``DEFAULT`` section must contain an ``extends`` key which value points to one
a ``DEFAULT`` section must contain an ``extends`` key whose value points to one
or more files which will be merged into the current files by adding new sections
and fields. If a file loaded by ``extends`` contains sections or keys that
already exist in the original file, they will not override the previous values.
......
......@@ -608,7 +608,7 @@ PyAPI_FUNC(Py_ssize_t) PyUnicode_AsWideChar(
/* Convert the Unicode object to a wide character string. The output string
always ends with a nul character. If size is not NULL, write the number of
wide characters (including the nul character) into *size.
wide characters (excluding the null character) into *size.
Returns a buffer allocated by PyMem_Alloc() (use PyMem_Free() to free it)
on success. On error, returns NULL, *size is undefined and raises a
......
......@@ -40,9 +40,8 @@ class install_egg_info(Command):
"Creating "+self.install_dir)
log.info("Writing %s", target)
if not self.dry_run:
f = open(target, 'w')
self.distribution.metadata.write_pkg_file(f)
f.close()
with open(target, 'w', encoding='UTF-8') as f:
self.distribution.metadata.write_pkg_file(f)
def get_outputs(self):
return self.outputs
......
......@@ -306,7 +306,10 @@ class sdist(Command):
try:
self.filelist.process_template_line(line)
except DistutilsTemplateError as msg:
# the call above can raise a DistutilsTemplateError for
# malformed lines, or a ValueError from the lower-level
# convert_path function
except (DistutilsTemplateError, ValueError) as msg:
self.warn("%s, line %d: %s" % (template.filename,
template.current_line,
msg))
......
......@@ -1010,11 +1010,9 @@ class DistributionMetadata:
def write_pkg_info(self, base_dir):
"""Write the PKG-INFO file into the release tree.
"""
pkg_info = open(os.path.join(base_dir, 'PKG-INFO'), 'w')
try:
with open(os.path.join(base_dir, 'PKG-INFO'), 'w',
encoding='UTF-8') as pkg_info:
self.write_pkg_file(pkg_info)
finally:
pkg_info.close()
def write_pkg_file(self, file):
"""Write the PKG-INFO format data to a file object.
......
......@@ -15,6 +15,7 @@ from distutils.tests.test_config import PyPIRCCommandTestCase
from distutils.errors import DistutilsOptionError
from distutils.spawn import find_executable
from distutils.log import WARN
from distutils.filelist import FileList
from distutils.archive_util import ARCHIVE_FORMATS
SETUP_PY = """
......@@ -78,9 +79,6 @@ class SDistTestCase(PyPIRCCommandTestCase):
dist.include_package_data = True
cmd = sdist(dist)
cmd.dist_dir = 'dist'
def _warn(*args):
pass
cmd.warn = _warn
return dist, cmd
@unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run')
......@@ -235,7 +233,8 @@ class SDistTestCase(PyPIRCCommandTestCase):
# with the `check` subcommand
cmd.ensure_finalized()
cmd.run()
warnings = self.get_logs(WARN)
warnings = [msg for msg in self.get_logs(WARN) if
msg.startswith('warning: check:')]
self.assertEqual(len(warnings), 2)
# trying with a complete set of metadata
......@@ -244,7 +243,8 @@ class SDistTestCase(PyPIRCCommandTestCase):
cmd.ensure_finalized()
cmd.metadata_check = 0
cmd.run()
warnings = self.get_logs(WARN)
warnings = [msg for msg in self.get_logs(WARN) if
msg.startswith('warning: check:')]
self.assertEqual(len(warnings), 0)
def test_check_metadata_deprecated(self):
......@@ -266,7 +266,6 @@ class SDistTestCase(PyPIRCCommandTestCase):
self.assertEqual(len(output), num_formats)
def test_finalize_options(self):
dist, cmd = self.get_cmd()
cmd.finalize_options()
......@@ -286,6 +285,32 @@ class SDistTestCase(PyPIRCCommandTestCase):
cmd.formats = 'supazipa'
self.assertRaises(DistutilsOptionError, cmd.finalize_options)
# the following tests make sure there is a nice error message instead
# of a traceback when parsing an invalid manifest template
def _test_template(self, content):
dist, cmd = self.get_cmd()
os.chdir(self.tmp_dir)
self.write_file('MANIFEST.in', content)
cmd.ensure_finalized()
cmd.filelist = FileList()
cmd.read_template()
warnings = self.get_logs(WARN)
self.assertEqual(len(warnings), 1)
def test_invalid_template_unknown_command(self):
self._test_template('taunt knights *')
def test_invalid_template_wrong_arguments(self):
# this manifest command takes one argument
self._test_template('prune')
@unittest.skipIf(os.name != 'nt', 'test relevant for Windows only')
def test_invalid_template_wrong_path(self):
# on Windows, trailing slashes are not allowed
# this used to crash instead of raising a warning: #8286
self._test_template('include examples/')
@unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run')
def test_get_file_list(self):
# make sure MANIFEST is recalculated
......
......@@ -458,4 +458,4 @@ class HTMLParser(_markupbase.ParserBase):
return '&'+s+';'
return re.sub(r"&(#?[xX]?(?:[0-9a-fA-F]+|\w{1,8}));",
replaceEntities, s, re.ASCII)
replaceEntities, s, flags=re.ASCII)
......@@ -946,7 +946,7 @@ class PackagingLibChecks(support.TempdirManager,
def _distutils_pkg_info(self):
tmp = self._distutils_setup_py_pkg()
self.write_file([tmp, 'PKG-INFO'], '')
self.write_file([tmp, 'PKG-INFO'], '', encoding='UTF-8')
return tmp
def _setup_cfg_with_no_metadata_pkg(self):
......@@ -971,7 +971,7 @@ class PackagingLibChecks(support.TempdirManager,
def _pkg_info_with_no_distutils(self):
tmp = self._random_setup_py_pkg()
self.write_file([tmp, 'PKG-INFO'], '')
self.write_file([tmp, 'PKG-INFO'], '', encoding='UTF-8')
return tmp
def _random_setup_py_pkg(self):
......
......@@ -2366,17 +2366,11 @@ class TarFile(object):
try:
g = grp.getgrnam(tarinfo.gname)[2]
except KeyError:
try:
g = grp.getgrgid(tarinfo.gid)[2]
except KeyError:
g = os.getgid()
g = tarinfo.gid
try:
u = pwd.getpwnam(tarinfo.uname)[2]
except KeyError:
try:
u = pwd.getpwuid(tarinfo.uid)[2]
except KeyError:
u = os.getuid()
u = tarinfo.uid
try:
if tarinfo.issym() and hasattr(os, "lchown"):
os.lchown(targetpath, u, g)
......
......@@ -264,6 +264,22 @@ def test_issue6243(stdscr):
curses.ungetch(1025)
stdscr.getkey()
def test_unget_wch(stdscr):
if not hasattr(curses, 'unget_wch'):
return
ch = 'a'
curses.unget_wch(ch)
read = stdscr.get_wch()
read = chr(read)
if read != ch:
raise AssertionError("%r != %r" % (read, ch))
ch = ord('a')
curses.unget_wch(ch)
read = stdscr.get_wch()
if read != ch:
raise AssertionError("%r != %r" % (read, ch))
def main(stdscr):
curses.savetty()
try:
......@@ -272,6 +288,7 @@ def main(stdscr):
test_userptr_without_set(stdscr)
test_resize_term(stdscr)
test_issue6243(stdscr)
test_unget_wch(stdscr)
finally:
curses.resetty()
......
......@@ -377,7 +377,8 @@ class HTMLParserTolerantTestCase(TestCaseBase):
p = html.parser.HTMLParser()
self.assertEqual(p.unescape('&#bad;'),'&#bad;')
self.assertEqual(p.unescape('&'),'&')
# see #12888
self.assertEqual(p.unescape('{ ' * 1050), '{ ' * 1050)
def test_main():
support.run_unittest(HTMLParserTestCase, HTMLParserTolerantTestCase)
......
......@@ -704,6 +704,7 @@ Douglas Orr
Michele Orrù
Oleg Oshmyan
Denis S. Otkidach
Peter Otten
Michael Otteneder
R. M. Oudkerk
Russel Owen
......
......@@ -271,6 +271,23 @@ Core and Builtins
Library
-------
- Issue #12567: Add curses.unget_wch() function. Push a character so the next
get_wch() will return it.
- Issue #9561: distutils and packaging now writes egg-info files using UTF-8,
instead of the locale encoding.
- Issue #8286: The distutils command sdist will print a warning message instead
of crashing when an invalid path is given in the manifest template.
- Issue #12841: tarfile unnecessarily checked the existence of numerical user
and group ids on extraction. If one of them did not exist the respective id
of the current user (i.e. root) was used for the file and ownership
information was lost.
- Issue #12888: Fix a bug in HTMLParser.unescape that prevented it to escape
more than 128 entities. Patch by Peter Otten.
- Issue #12878: Expose a __dict__ attribute on io.IOBase and its subclasses.
- Issue #12636: IDLE reads the coding cookie when executing a Python script.
......
......@@ -2696,6 +2696,71 @@ PyCurses_UngetCh(PyObject *self, PyObject *args)
return PyCursesCheckERR(ungetch(ch), "ungetch");
}
#ifdef HAVE_NCURSESW
/* Convert an object to a character (wchar_t):
- int
- str of length 1
Return 1 on success, 0 on error. */
static int
PyCurses_ConvertToWchar_t(PyObject *obj,
wchar_t *wch)
{
if (PyUnicode_Check(obj)) {
wchar_t buffer[2];
if (PyUnicode_AsWideChar(obj, buffer, 2) != 1) {
PyErr_Format(PyExc_TypeError,
"expect bytes or str of length 1, or int, "
"got a str of length %zi",
PyUnicode_GET_SIZE(obj));
return 0;
}
*wch = buffer[0];
return 2;
}
else if (PyLong_CheckExact(obj)) {
long value;
int overflow;
value = PyLong_AsLongAndOverflow(obj, &overflow);
if (overflow) {
PyErr_SetString(PyExc_OverflowError,
"int doesn't fit in long");
return 0;
}
*wch = (wchar_t)value;
if ((long)*wch != value) {
PyErr_Format(PyExc_OverflowError,
"character doesn't fit in wchar_t");
return 0;
}
return 1;
}
else {
PyErr_Format(PyExc_TypeError,
"expect bytes or str of length 1, or int, got %s",
Py_TYPE(obj)->tp_name);
return 0;
}
}
static PyObject *
PyCurses_Unget_Wch(PyObject *self, PyObject *args)
{
PyObject *obj;
wchar_t wch;
PyCursesInitialised;
if (!PyArg_ParseTuple(args,"O", &obj))
return NULL;
if (!PyCurses_ConvertToWchar_t(obj, &wch))
return NULL;
return PyCursesCheckERR(unget_wch(wch), "unget_wch");
}
#endif
static PyObject *
PyCurses_Use_Env(PyObject *self, PyObject *args)
{
......@@ -2823,6 +2888,9 @@ static PyMethodDef PyCurses_methods[] = {
{"typeahead", (PyCFunction)PyCurses_TypeAhead, METH_VARARGS},
{"unctrl", (PyCFunction)PyCurses_UnCtrl, METH_VARARGS},
{"ungetch", (PyCFunction)PyCurses_UngetCh, METH_VARARGS},
#ifdef HAVE_NCURSESW
{"unget_wch", (PyCFunction)PyCurses_Unget_Wch, METH_VARARGS},
#endif
{"use_env", (PyCFunction)PyCurses_Use_Env, METH_VARARGS},
#ifndef STRICT_SYSV_CURSES
{"use_default_colors", (PyCFunction)PyCurses_Use_Default_Colors, METH_NOARGS},
......
......@@ -1204,12 +1204,12 @@ PyUnicode_FromFormat(const char *format, ...)
/* Helper function for PyUnicode_AsWideChar() and PyUnicode_AsWideCharString():
convert a Unicode object to a wide character string.
- If w is NULL: return the number of wide characters (including the nul
- If w is NULL: return the number of wide characters (including the null
character) required to convert the unicode object. Ignore size argument.
- Otherwise: return the number of wide characters (excluding the nul
- Otherwise: return the number of wide characters (excluding the null
character) written into w. Write at most size wide characters (including
the nul character). */
the null character). */
static Py_ssize_t
unicode_aswidechar(PyUnicodeObject *unicode,
wchar_t *w,
......@@ -1257,7 +1257,7 @@ unicode_aswidechar(PyUnicodeObject *unicode,
return w - worig;
}
else {
nchar = 1; /* nul character at the end */
nchar = 1; /* null character at the end */
while (u != uend) {
if (0xD800 <= u[0] && u[0] <= 0xDBFF
&& 0xDC00 <= u[1] && u[1] <= 0xDFFF)
......@@ -1295,7 +1295,7 @@ unicode_aswidechar(PyUnicodeObject *unicode,
return w - worig;
}
else {
nchar = 1; /* nul character */
nchar = 1; /* null character */
while (u != uend) {
if (*u > 0xffff)
nchar += 2;
......
......@@ -30,4 +30,9 @@ product_codes = {
'3.2.1121':'{4f90de4a-83dd-4443-b625-ca130ff361dd}', # 3.2.1rc1
'3.2.1122':'{dc5eb04d-ff8a-4bed-8f96-23942fd59e5f}', # 3.2.1rc2
'3.2.1150':'{34b2530c-6349-4292-9dc3-60bda4aed93c}', # 3.2.1
'3.2.2121':'{DFB29A53-ACC4-44e6-85A6-D0DA26FE8E4E}', # 3.2.2rc1
'3.2.2150':'{4CDE3168-D060-4b7c-BC74-4D8F9BB01AFD}', # 3.2.2
'3.2.3121':'{B8E8CFF7-E4C6-4a7c-9F06-BB3A8B75DDA8}', # 3.2.3rc1
'3.2.3150':'{789C9644-9F82-44d3-B4CA-AC31F46F5882}', # 3.2.3
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment