aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--Doc/c-api/typeobj.rst12
-rw-r--r--Doc/howto/clinic.rst63
-rw-r--r--Doc/howto/urllib2.rst2
-rw-r--r--Doc/library/pkgutil.rst4
-rw-r--r--Doc/library/re.rst2
-rw-r--r--Doc/library/stdtypes.rst37
-rw-r--r--Doc/tutorial/modules.rst2
-rw-r--r--Include/patchlevel.h6
-rw-r--r--Lib/_pyio.py2
-rw-r--r--Lib/dbm/dumb.py7
-rw-r--r--Lib/distutils/command/wininst-14.0-amd64.exebin589824 -> 587776 bytes
-rw-r--r--Lib/distutils/command/wininst-14.0.exebin460288 -> 458240 bytes
-rw-r--r--Lib/importlib/_bootstrap_external.py2
-rw-r--r--Lib/mailbox.py21
-rw-r--r--Lib/multiprocessing/context.py2
-rw-r--r--Lib/multiprocessing/spawn.py2
-rwxr-xr-xLib/tarfile.py31
-rw-r--r--Lib/test/_test_multiprocessing.py13
-rw-r--r--Lib/test/eintrdata/eintr_tester.py2
-rw-r--r--Lib/test/mp_preload.py18
-rw-r--r--Lib/test/support/__init__.py44
-rw-r--r--Lib/test/test_asyncore.py4
-rw-r--r--Lib/test/test_cmd_line.py9
-rw-r--r--Lib/test/test_dbm_dumb.py16
-rw-r--r--Lib/test/test_descr.py90
-rw-r--r--Lib/test/test_format.py26
-rw-r--r--Lib/test/test_fstring.py20
-rw-r--r--Lib/test/test_functools.py2
-rw-r--r--Lib/test/test_future.py63
-rw-r--r--Lib/test/test_gdb.py20
-rw-r--r--Lib/test/test_genericpath.py3
-rw-r--r--Lib/test/test_global.py6
-rw-r--r--Lib/test/test_importlib/test_locks.py2
-rw-r--r--Lib/test/test_mailbox.py4
-rw-r--r--Lib/test/test_pathlib.py7
-rw-r--r--Lib/test/test_posix.py6
-rw-r--r--Lib/test/test_pwd.py26
-rw-r--r--Lib/test/test_shutil.py6
-rw-r--r--Lib/test/test_socket.py21
-rw-r--r--Lib/test/test_stat.py3
-rw-r--r--Lib/test/test_support.py2
-rw-r--r--Lib/test/test_symtable.py8
-rw-r--r--Lib/test/test_syntax.py9
-rw-r--r--Lib/test/test_sysconfig.py5
-rw-r--r--Lib/test/test_threading.py2
-rw-r--r--Makefile.pre.in2
-rw-r--r--Misc/NEWS49
-rw-r--r--Modules/_asynciomodule.c19
-rw-r--r--Modules/_io/_iomodule.c2
-rw-r--r--Modules/timemodule.c2
-rw-r--r--Objects/abstract.c2
-rw-r--r--Objects/dictobject.c24
-rw-r--r--Objects/unicodeobject.c6
-rw-r--r--PC/bdist_wininst/install.c2
-rw-r--r--PCbuild/_freeze_importlib.vcxproj37
-rw-r--r--PCbuild/pcbuild.proj10
-rw-r--r--Python/ast.c11
-rw-r--r--Python/compile.c3
-rw-r--r--Python/errors.c12
-rw-r--r--Python/fileutils.c10
-rw-r--r--Python/importlib_external.h109
-rwxr-xr-xTools/gdb/libpython.py47
-rwxr-xr-xconfigure28
-rw-r--r--configure.ac28
-rw-r--r--setup.py10
65 files changed, 652 insertions, 393 deletions
diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
index 323f017d65b..ac6fd0b53fc 100644
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -199,8 +199,9 @@ type objects) *must* have the :attr:`ob_size` field.
This field is deprecated. When it is defined, it should point to a function
that acts the same as the :c:member:`~PyTypeObject.tp_getattro` function, but taking a C string
- instead of a Python string object to give the attribute name. The signature is
- the same as for :c:func:`PyObject_GetAttrString`.
+ instead of a Python string object to give the attribute name. The signature is ::
+
+ PyObject * tp_getattr(PyObject *o, char *attr_name);
This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_getattro`: a subtype
inherits both :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` from its base type when
@@ -213,10 +214,11 @@ type objects) *must* have the :attr:`ob_size` field.
This field is deprecated. When it is defined, it should point to a function
that acts the same as the :c:member:`~PyTypeObject.tp_setattro` function, but taking a C string
- instead of a Python string object to give the attribute name. The signature is
- the same as for :c:func:`PyObject_SetAttrString`, but setting
- *v* to *NULL* to delete an attribute must be supported.
+ instead of a Python string object to give the attribute name. The signature is ::
+
+ PyObject * tp_setattr(PyObject *o, char *attr_name, PyObject *v);
+ The *v* argument is set to *NULL* to delete the attribute.
This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_setattro`: a subtype
inherits both :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` from its base type when
the subtype's :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` are both *NULL*.
diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst
index 4742d84dab9..eaab20ad975 100644
--- a/Doc/howto/clinic.rst
+++ b/Doc/howto/clinic.rst
@@ -1,3 +1,5 @@
+.. highlightlang:: c
+
**********************
Argument Clinic How-To
**********************
@@ -78,17 +80,23 @@ Basic Concepts And Usage
========================
Argument Clinic ships with CPython; you'll find it in ``Tools/clinic/clinic.py``.
-If you run that script, specifying a C file as an argument::
+If you run that script, specifying a C file as an argument:
+
+.. code-block:: shell-session
- % python3 Tools/clinic/clinic.py foo.c
+ $ python3 Tools/clinic/clinic.py foo.c
Argument Clinic will scan over the file looking for lines that
-look exactly like this::
+look exactly like this:
+
+.. code-block:: none
/*[clinic input]
When it finds one, it reads everything up to a line that looks
-exactly like this::
+exactly like this:
+
+.. code-block:: none
[clinic start generated code]*/
@@ -99,7 +107,9 @@ lines, are collectively called an Argument Clinic "block".
When Argument Clinic parses one of these blocks, it
generates output. This output is rewritten into the C file
immediately after the block, followed by a comment containing a checksum.
-The Argument Clinic block now looks like this::
+The Argument Clinic block now looks like this:
+
+.. code-block:: none
/*[clinic input]
... clinic input goes here ...
@@ -375,15 +385,10 @@ Let's dive in!
Write a pickled representation of obj to the open file.
[clinic start generated code]*/
-12. Save and close the file, then run ``Tools/clinic/clinic.py`` on it.
- With luck everything worked and your block now has output! Reopen
- the file in your text editor to see::
-
- /*[clinic input]
- module _pickle
- class _pickle.Pickler "PicklerObject *" "&Pickler_Type"
- [clinic start generated code]*/
- /*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/
+12. Save and close the file, then run ``Tools/clinic/clinic.py`` on
+ it. With luck everything worked---your block now has output, and
+ a ``.c.h`` file has been generated! Reopen the file in your
+ text editor to see::
/*[clinic input]
_pickle.Pickler.dump
@@ -395,18 +400,20 @@ Let's dive in!
Write a pickled representation of obj to the open file.
[clinic start generated code]*/
- PyDoc_STRVAR(_pickle_Pickler_dump__doc__,
- "Write a pickled representation of obj to the open file.\n"
- "\n"
- ...
static PyObject *
- _pickle_Pickler_dump_impl(PicklerObject *self, PyObject *obj)
- /*[clinic end generated code: checksum=3bd30745bf206a48f8b576a1da3d90f55a0a4187]*/
+ _pickle_Pickler_dump(PicklerObject *self, PyObject *obj)
+ /*[clinic end generated code: output=87ecad1261e02ac7 input=552eb1c0f52260d9]*/
Obviously, if Argument Clinic didn't produce any output, it's because
it found an error in your input. Keep fixing your errors and retrying
until Argument Clinic processes your file without complaint.
+ For readability, most of the glue code has been generated to a ``.c.h``
+ file. You'll need to include that in your original ``.c`` file,
+ typically right after the clinic module block::
+
+ #include "clinic/_pickle.c.h"
+
13. Double-check that the argument-parsing code Argument Clinic generated
looks basically the same as the existing code.
@@ -1027,7 +1034,9 @@ that value, and an error has been set (``PyErr_Occurred()`` returns a true
value), then the generated code will propagate the error. Otherwise it will
encode the value you return like normal.
-Currently Argument Clinic supports only a few return converters::
+Currently Argument Clinic supports only a few return converters:
+
+.. code-block:: none
bool
int
@@ -1606,7 +1615,9 @@ code probably looks like this::
#endif /* HAVE_FUNCTIONNAME */
And then in the ``PyMethodDef`` structure at the bottom the existing code
-will have::
+will have:
+
+.. code-block:: none
#ifdef HAVE_FUNCTIONNAME
{'functionname', ... },
@@ -1656,7 +1667,9 @@ extra code when using the "block" output preset? It can't go in the output bloc
because that could be deactivated by the ``#ifdef``. (That's the whole point!)
In this situation, Argument Clinic writes the extra code to the "buffer" destination.
-This may mean that you get a complaint from Argument Clinic::
+This may mean that you get a complaint from Argument Clinic:
+
+.. code-block:: none
Warning in file "Modules/posixmodule.c" on line 12357:
Destination buffer 'buffer' not empty at end of file, emptying.
@@ -1676,7 +1689,9 @@ wouldn't make any sense to the Python interpreter. But using Argument Clinic
to run Python blocks lets you use Python as a Python preprocessor!
Since Python comments are different from C comments, Argument Clinic
-blocks embedded in Python files look slightly different. They look like this::
+blocks embedded in Python files look slightly different. They look like this:
+
+.. code-block:: python3
#/*[python input]
#print("def foo(): pass")
diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst
index 712b4b76238..18b5c6556be 100644
--- a/Doc/howto/urllib2.rst
+++ b/Doc/howto/urllib2.rst
@@ -578,7 +578,7 @@ Footnotes
This document was reviewed and revised by John Lee.
.. [#] Google for example.
-.. [#] Browser sniffing is a very bad practise for website design - building
+.. [#] Browser sniffing is a very bad practice for website design - building
sites using web standards is much more sensible. Unfortunately a lot of
sites still send different versions to different browsers.
.. [#] The user agent for MSIE 6 is
diff --git a/Doc/library/pkgutil.rst b/Doc/library/pkgutil.rst
index 90d69e40717..fba0ea641d9 100644
--- a/Doc/library/pkgutil.rst
+++ b/Doc/library/pkgutil.rst
@@ -224,4 +224,6 @@ support.
If the package cannot be located or loaded, or it uses a :term:`loader`
which does not support :meth:`get_data <importlib.abc.ResourceLoader.get_data>`,
- then ``None`` is returned.
+ then ``None`` is returned. In particular, the :term:`loader` for
+ :term:`namespace packages <namespace package>` does not support
+ :meth:`get_data <importlib.abc.ResourceLoader.get_data>`.
diff --git a/Doc/library/re.rst b/Doc/library/re.rst
index a298d97c9c3..7ef4cbeee79 100644
--- a/Doc/library/re.rst
+++ b/Doc/library/re.rst
@@ -762,7 +762,7 @@ form.
now are errors.
.. deprecated-removed:: 3.5 3.7
- Unknown escapes in *repl* consist of ``'\'`` and ASCII letter now raise
+ Unknown escapes in *repl* consisting of ``'\'`` and an ASCII letter now raise
a deprecation warning and will be forbidden in Python 3.7.
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index 122ed003876..1e665affb82 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -1644,18 +1644,20 @@ expression support in the :mod:`re` module).
Return true if all characters in the string are decimal
characters and there is at least one character, false
- otherwise. Decimal characters are those from general category "Nd". This category
- includes digit characters, and all characters
- that can be used to form decimal-radix numbers, e.g. U+0660,
- ARABIC-INDIC DIGIT ZERO.
+ otherwise. Decimal characters are those that can be used to form
+ numbers in base 10, e.g. U+0660, ARABIC-INDIC DIGIT
+ ZERO. Formally a decimal character is a character in the Unicode
+ General Category "Nd".
.. method:: str.isdigit()
Return true if all characters in the string are digits and there is at least one
character, false otherwise. Digits include decimal characters and digits that need
- special handling, such as the compatibility superscript digits. Formally, a digit
- is a character that has the property value Numeric_Type=Digit or Numeric_Type=Decimal.
+ special handling, such as the compatibility superscript digits.
+ This covers digits which cannot be used to form numbers in base 10,
+ like the Kharosthi numbers. Formally, a digit is a character that has the
+ property value Numeric_Type=Digit or Numeric_Type=Decimal.
.. method:: str.isidentifier()
@@ -2158,7 +2160,7 @@ The conversion types are:
+------------+-----------------------------------------------------+-------+
| ``'o'`` | Signed octal value. | \(1) |
+------------+-----------------------------------------------------+-------+
-| ``'u'`` | Obsolete type -- it is identical to ``'d'``. | \(7) |
+| ``'u'`` | Obsolete type -- it is identical to ``'d'``. | \(6) |
+------------+-----------------------------------------------------+-------+
| ``'x'`` | Signed hexadecimal (lowercase). | \(2) |
+------------+-----------------------------------------------------+-------+
@@ -2199,15 +2201,12 @@ The conversion types are:
Notes:
(1)
- The alternate form causes a leading zero (``'0'``) to be inserted between
- left-hand padding and the formatting of the number if the leading character
- of the result is not already a zero.
+ The alternate form causes a leading octal specifier (``'0o'``) to be
+ inserted before the first digit.
(2)
The alternate form causes a leading ``'0x'`` or ``'0X'`` (depending on whether
- the ``'x'`` or ``'X'`` format was used) to be inserted between left-hand padding
- and the formatting of the number if the leading character of the result is not
- already a zero.
+ the ``'x'`` or ``'X'`` format was used) to be inserted before the first digit.
(3)
The alternate form causes the result to always contain a decimal point, even if
@@ -2226,8 +2225,7 @@ Notes:
(5)
If precision is ``N``, the output is truncated to ``N`` characters.
-
-(7)
+(6)
See :pep:`237`.
Since Python strings have an explicit length, ``%s`` conversions do not assume
@@ -3303,15 +3301,12 @@ The conversion types are:
Notes:
(1)
- The alternate form causes a leading zero (``'0'``) to be inserted between
- left-hand padding and the formatting of the number if the leading character
- of the result is not already a zero.
+ The alternate form causes a leading octal specifier (``'0o'``) to be
+ inserted before the first digit.
(2)
The alternate form causes a leading ``'0x'`` or ``'0X'`` (depending on whether
- the ``'x'`` or ``'X'`` format was used) to be inserted between left-hand padding
- and the formatting of the number if the leading character of the result is not
- already a zero.
+ the ``'x'`` or ``'X'`` format was used) to be inserted before the first digit.
(3)
The alternate form causes the result to always contain a decimal point, even if
diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst
index 35db305d9e1..1e3d5c01a47 100644
--- a/Doc/tutorial/modules.rst
+++ b/Doc/tutorial/modules.rst
@@ -501,7 +501,7 @@ when the ``from...import`` statement is executed. (This also works when
``__all__`` is defined.)
Although certain modules are designed to export only names that follow certain
-patterns when you use ``import *``, it is still considered bad practise in
+patterns when you use ``import *``, it is still considered bad practice in
production code.
Remember, there is nothing wrong with using ``from Package import
diff --git a/Include/patchlevel.h b/Include/patchlevel.h
index f59e12ada13..49930e85565 100644
--- a/Include/patchlevel.h
+++ b/Include/patchlevel.h
@@ -19,11 +19,11 @@
#define PY_MAJOR_VERSION 3
#define PY_MINOR_VERSION 6
#define PY_MICRO_VERSION 0
-#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_GAMMA
-#define PY_RELEASE_SERIAL 1
+#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL
+#define PY_RELEASE_SERIAL 0
/* Version as a string */
-#define PY_VERSION "3.6.0rc1+"
+#define PY_VERSION "3.6.0+"
/*--end constants--*/
/* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2.
diff --git a/Lib/_pyio.py b/Lib/_pyio.py
index d0947f06d51..2ebfb0576f5 100644
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -277,7 +277,7 @@ class OpenWrapper:
try:
UnsupportedOperation = io.UnsupportedOperation
except AttributeError:
- class UnsupportedOperation(ValueError, OSError):
+ class UnsupportedOperation(OSError, ValueError):
pass
diff --git a/Lib/dbm/dumb.py b/Lib/dbm/dumb.py
index e7c6440ee65..2296dbfd547 100644
--- a/Lib/dbm/dumb.py
+++ b/Lib/dbm/dumb.py
@@ -97,8 +97,9 @@ class _Database(collections.MutableMapping):
try:
f = _io.open(self._dirfile, 'r', encoding="Latin-1")
except OSError:
- pass
+ self._modified = not self._readonly
else:
+ self._modified = False
with f:
for line in f:
line = line.rstrip()
@@ -113,7 +114,7 @@ class _Database(collections.MutableMapping):
# CAUTION: It's vital that _commit() succeed, and _commit() can
# be called from __del__(). Therefore we must never reference a
# global in this routine.
- if self._index is None:
+ if self._index is None or not self._modified:
return # nothing to do
try:
@@ -197,6 +198,7 @@ class _Database(collections.MutableMapping):
elif not isinstance(val, (bytes, bytearray)):
raise TypeError("values must be bytes or strings")
self._verify_open()
+ self._modified = True
if key not in self._index:
self._addkey(key, self._addval(val))
else:
@@ -229,6 +231,7 @@ class _Database(collections.MutableMapping):
if isinstance(key, str):
key = key.encode('utf-8')
self._verify_open()
+ self._modified = True
# The blocks used by the associated value are lost.
del self._index[key]
# XXX It's unclear why we do a _commit() here (the code always
diff --git a/Lib/distutils/command/wininst-14.0-amd64.exe b/Lib/distutils/command/wininst-14.0-amd64.exe
index 22299543a97..253c2e2ecce 100644
--- a/Lib/distutils/command/wininst-14.0-amd64.exe
+++ b/Lib/distutils/command/wininst-14.0-amd64.exe
Binary files differ
diff --git a/Lib/distutils/command/wininst-14.0.exe b/Lib/distutils/command/wininst-14.0.exe
index 0dac1103d98..46f5f356676 100644
--- a/Lib/distutils/command/wininst-14.0.exe
+++ b/Lib/distutils/command/wininst-14.0.exe
Binary files differ
diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py
index ab434460c26..9feec50842c 100644
--- a/Lib/importlib/_bootstrap_external.py
+++ b/Lib/importlib/_bootstrap_external.py
@@ -1440,6 +1440,4 @@ def _install(_bootstrap_module):
_setup(_bootstrap_module)
supported_loaders = _get_supported_file_loaders()
sys.path_hooks.extend([FileFinder.path_hook(*supported_loaders)])
- if _os.__name__ == 'nt':
- sys.meta_path.append(WindowsRegistryFinder)
sys.meta_path.append(PathFinder)
diff --git a/Lib/mailbox.py b/Lib/mailbox.py
index 0e23987ce75..39f24f9a723 100644
--- a/Lib/mailbox.py
+++ b/Lib/mailbox.py
@@ -313,11 +313,12 @@ class Maildir(Mailbox):
# final position in order to prevent race conditions with changes
# from other programs
try:
- if hasattr(os, 'link'):
+ try:
os.link(tmp_file.name, dest)
- os.remove(tmp_file.name)
- else:
+ except (AttributeError, PermissionError):
os.rename(tmp_file.name, dest)
+ else:
+ os.remove(tmp_file.name)
except OSError as e:
os.remove(tmp_file.name)
if e.errno == errno.EEXIST:
@@ -1200,13 +1201,14 @@ class MH(Mailbox):
for key in self.iterkeys():
if key - 1 != prev:
changes.append((key, prev + 1))
- if hasattr(os, 'link'):
+ try:
os.link(os.path.join(self._path, str(key)),
os.path.join(self._path, str(prev + 1)))
- os.unlink(os.path.join(self._path, str(key)))
- else:
+ except (AttributeError, PermissionError):
os.rename(os.path.join(self._path, str(key)),
os.path.join(self._path, str(prev + 1)))
+ else:
+ os.unlink(os.path.join(self._path, str(key)))
prev += 1
self._next_key = prev + 1
if len(changes) == 0:
@@ -2076,13 +2078,14 @@ def _lock_file(f, dotlock=True):
else:
raise
try:
- if hasattr(os, 'link'):
+ try:
os.link(pre_lock.name, f.name + '.lock')
dotlock_done = True
- os.unlink(pre_lock.name)
- else:
+ except (AttributeError, PermissionError):
os.rename(pre_lock.name, f.name + '.lock')
dotlock_done = True
+ else:
+ os.unlink(pre_lock.name)
except FileExistsError:
os.remove(pre_lock.name)
raise ExternalClashError('dot lock unavailable: %s' %
diff --git a/Lib/multiprocessing/context.py b/Lib/multiprocessing/context.py
index 09455e2ec77..623f6fb733a 100644
--- a/Lib/multiprocessing/context.py
+++ b/Lib/multiprocessing/context.py
@@ -196,7 +196,7 @@ class BaseContext(object):
def get_start_method(self, allow_none=False):
return self._name
- def set_start_method(self, method=None):
+ def set_start_method(self, method, force=False):
raise ValueError('cannot set start method of concrete context')
@property
diff --git a/Lib/multiprocessing/spawn.py b/Lib/multiprocessing/spawn.py
index dfb9f652701..4aba372e48e 100644
--- a/Lib/multiprocessing/spawn.py
+++ b/Lib/multiprocessing/spawn.py
@@ -217,7 +217,7 @@ def prepare(data):
process.ORIGINAL_DIR = data['orig_dir']
if 'start_method' in data:
- set_start_method(data['start_method'])
+ set_start_method(data['start_method'], force=True)
if 'init_main_from_name' in data:
_fixup_main_from_name(data['init_main_from_name'])
diff --git a/Lib/tarfile.py b/Lib/tarfile.py
index b78b1b1f4bb..5d4c86ce366 100755
--- a/Lib/tarfile.py
+++ b/Lib/tarfile.py
@@ -50,9 +50,13 @@ import copy
import re
try:
- import grp, pwd
+ import pwd
except ImportError:
- grp = pwd = None
+ pwd = None
+try:
+ import grp
+except ImportError:
+ grp = None
# os.symlink on Windows prior to 6.0 raises NotImplementedError
symlink_exception = (AttributeError, NotImplementedError)
@@ -2219,22 +2223,25 @@ class TarFile(object):
def chown(self, tarinfo, targetpath, numeric_owner):
"""Set owner of targetpath according to tarinfo. If numeric_owner
- is True, use .gid/.uid instead of .gname/.uname.
+ is True, use .gid/.uid instead of .gname/.uname. If numeric_owner
+ is False, fall back to .gid/.uid when the search based on name
+ fails.
"""
- if pwd and hasattr(os, "geteuid") and os.geteuid() == 0:
+ if hasattr(os, "geteuid") and os.geteuid() == 0:
# We have to be root to do so.
- if numeric_owner:
- g = tarinfo.gid
- u = tarinfo.uid
- else:
+ g = tarinfo.gid
+ u = tarinfo.uid
+ if not numeric_owner:
try:
- g = grp.getgrnam(tarinfo.gname)[2]
+ if grp:
+ g = grp.getgrnam(tarinfo.gname)[2]
except KeyError:
- g = tarinfo.gid
+ pass
try:
- u = pwd.getpwnam(tarinfo.uname)[2]
+ if pwd:
+ u = pwd.getpwnam(tarinfo.uname)[2]
except KeyError:
- u = tarinfo.uid
+ pass
try:
if tarinfo.issym() and hasattr(os, "lchown"):
os.lchown(targetpath, u, g)
diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py
index c00846c7b0f..b5f47825466 100644
--- a/Lib/test/_test_multiprocessing.py
+++ b/Lib/test/_test_multiprocessing.py
@@ -3818,6 +3818,19 @@ class TestStartMethod(unittest.TestCase):
self.assertTrue(methods == ['fork', 'spawn'] or
methods == ['fork', 'spawn', 'forkserver'])
+ def test_preload_resources(self):
+ if multiprocessing.get_start_method() != 'forkserver':
+ self.skipTest("test only relevant for 'forkserver' method")
+ name = os.path.join(os.path.dirname(__file__), 'mp_preload.py')
+ rc, out, err = test.support.script_helper.assert_python_ok(name)
+ out = out.decode()
+ err = err.decode()
+ if out.rstrip() != 'ok' or err != '':
+ print(out)
+ print(err)
+ self.fail("failed spawning forkserver or grandchild")
+
+
#
# Check that killing process does not leak named semaphores
#
diff --git a/Lib/test/eintrdata/eintr_tester.py b/Lib/test/eintrdata/eintr_tester.py
index 9fbe04de9c5..d194e775eae 100644
--- a/Lib/test/eintrdata/eintr_tester.py
+++ b/Lib/test/eintrdata/eintr_tester.py
@@ -20,6 +20,7 @@ import time
import unittest
from test import support
+android_not_root = support.android_not_root
@contextlib.contextmanager
def kill_on_error(proc):
@@ -311,6 +312,7 @@ class SocketEINTRTest(EINTRBaseTest):
# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=203162
@support.requires_freebsd_version(10, 3)
@unittest.skipUnless(hasattr(os, 'mkfifo'), 'needs mkfifo()')
+ @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user")
def _test_open(self, do_open_close_reader, do_open_close_writer):
filename = support.TESTFN
diff --git a/Lib/test/mp_preload.py b/Lib/test/mp_preload.py
new file mode 100644
index 00000000000..5314e8f0b21
--- /dev/null
+++ b/Lib/test/mp_preload.py
@@ -0,0 +1,18 @@
+import multiprocessing
+
+multiprocessing.Lock()
+
+
+def f():
+ print("ok")
+
+
+if __name__ == "__main__":
+ ctx = multiprocessing.get_context("forkserver")
+ modname = "test.mp_preload"
+ # Make sure it's importable
+ __import__(modname)
+ ctx.set_forkserver_preload([modname])
+ proc = ctx.Process(target=f)
+ proc.start()
+ proc.join()
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index 52c908e0284..15d8fc849b9 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -93,8 +93,10 @@ __all__ = [
"check__all__", "requires_android_level", "requires_multiprocessing_queue",
# sys
"is_jython", "is_android", "check_impl_detail", "unix_shell",
+ "setswitchinterval", "android_not_root",
# network
"HOST", "IPV6_ENABLED", "find_unused_port", "bind_port", "open_urlresource",
+ "bind_unix_socket",
# processes
'temp_umask', "reap_children",
# logging
@@ -360,9 +362,9 @@ if sys.platform.startswith("win"):
mode = 0
if stat.S_ISDIR(mode):
_waitfor(_rmtree_inner, fullname, waitall=True)
- _force_run(path, os.rmdir, fullname)
+ _force_run(fullname, os.rmdir, fullname)
else:
- _force_run(path, os.unlink, fullname)
+ _force_run(fullname, os.unlink, fullname)
_waitfor(_rmtree_inner, path, waitall=True)
_waitfor(lambda p: _force_run(p, os.rmdir, p), path)
else:
@@ -707,6 +709,15 @@ def bind_port(sock, host=HOST):
port = sock.getsockname()[1]
return port
+def bind_unix_socket(sock, addr):
+ """Bind a unix socket, raising SkipTest if PermissionError is raised."""
+ assert sock.family == socket.AF_UNIX
+ try:
+ sock.bind(addr)
+ except PermissionError:
+ sock.close()
+ raise unittest.SkipTest('cannot bind AF_UNIX sockets')
+
def _is_ipv6_enabled():
"""Check whether IPv6 is enabled on this host."""
if socket.has_ipv6:
@@ -768,6 +779,7 @@ is_jython = sys.platform.startswith('java')
_ANDROID_API_LEVEL = sysconfig.get_config_var('ANDROID_API_LEVEL')
is_android = (_ANDROID_API_LEVEL is not None and _ANDROID_API_LEVEL > 0)
+android_not_root = (is_android and os.geteuid() != 0)
if sys.platform != 'win32':
unix_shell = '/system/bin/sh' if is_android else '/bin/sh'
@@ -1054,9 +1066,16 @@ def make_bad_fd():
file.close()
unlink(TESTFN)
-def check_syntax_error(testcase, statement):
- testcase.assertRaises(SyntaxError, compile, statement,
- '<test string>', 'exec')
+def check_syntax_error(testcase, statement, *, lineno=None, offset=None):
+ with testcase.assertRaises(SyntaxError) as cm:
+ compile(statement, '<test string>', 'exec')
+ err = cm.exception
+ testcase.assertIsNotNone(err.lineno)
+ if lineno is not None:
+ testcase.assertEqual(err.lineno, lineno)
+ testcase.assertIsNotNone(err.offset)
+ if offset is not None:
+ testcase.assertEqual(err.offset, offset)
def open_urlresource(url, *args, **kw):
import urllib.request, urllib.parse
@@ -2547,3 +2566,18 @@ def missing_compiler_executable(cmd_names=[]):
continue
if spawn.find_executable(cmd[0]) is None:
return cmd[0]
+
+
+_is_android_emulator = None
+def setswitchinterval(interval):
+ # Setting a very low gil interval on the Android emulator causes python
+ # to hang (issue #26939).
+ minimum_interval = 1e-5
+ if is_android and interval < minimum_interval:
+ global _is_android_emulator
+ if _is_android_emulator is None:
+ _is_android_emulator = (subprocess.check_output(
+ ['getprop', 'ro.kernel.qemu']).strip() == b'1')
+ if _is_android_emulator:
+ interval = minimum_interval
+ return sys.setswitchinterval(interval)
diff --git a/Lib/test/test_asyncore.py b/Lib/test/test_asyncore.py
index dbee593c544..51c65737a44 100644
--- a/Lib/test/test_asyncore.py
+++ b/Lib/test/test_asyncore.py
@@ -95,7 +95,9 @@ def bind_af_aware(sock, addr):
if HAS_UNIX_SOCKETS and sock.family == socket.AF_UNIX:
# Make sure the path doesn't exist.
support.unlink(addr)
- sock.bind(addr)
+ support.bind_unix_socket(sock, addr)
+ else:
+ sock.bind(addr)
class HelperFunctionTests(unittest.TestCase):
diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py
index b71bb9f7ee5..ae2bcd43754 100644
--- a/Lib/test/test_cmd_line.py
+++ b/Lib/test/test_cmd_line.py
@@ -8,7 +8,7 @@ import shutil
import sys
import subprocess
import tempfile
-from test.support import script_helper
+from test.support import script_helper, is_android
from test.support.script_helper import (spawn_python, kill_python, assert_python_ok,
assert_python_failure)
@@ -178,15 +178,16 @@ class CmdLineTest(unittest.TestCase):
if not stdout.startswith(pattern):
raise AssertionError("%a doesn't start with %a" % (stdout, pattern))
- @unittest.skipUnless(sys.platform == 'darwin', 'test specific to Mac OS X')
- def test_osx_utf8(self):
+ @unittest.skipUnless((sys.platform == 'darwin' or
+ is_android), 'test specific to Mac OS X and Android')
+ def test_osx_android_utf8(self):
def check_output(text):
decoded = text.decode('utf-8', 'surrogateescape')
expected = ascii(decoded).encode('ascii') + b'\n'
env = os.environ.copy()
# C locale gives ASCII locale encoding, but Python uses UTF-8
- # to parse the command line arguments on Mac OS X
+ # to parse the command line arguments on Mac OS X and Android.
env['LC_ALL'] = 'C'
p = subprocess.Popen(
diff --git a/Lib/test/test_dbm_dumb.py b/Lib/test/test_dbm_dumb.py
index 2d77f078b76..df531d64e48 100644
--- a/Lib/test/test_dbm_dumb.py
+++ b/Lib/test/test_dbm_dumb.py
@@ -5,6 +5,7 @@
import io
import operator
import os
+import stat
import unittest
import warnings
import dbm.dumb as dumbdbm
@@ -259,6 +260,21 @@ class DumbDBMTestCase(unittest.TestCase):
f = dumbdbm.open(_fname, flag)
f.close()
+ @unittest.skipUnless(hasattr(os, 'chmod'), 'test needs os.chmod()')
+ def test_readonly_files(self):
+ with support.temp_dir() as dir:
+ fname = os.path.join(dir, 'db')
+ with dumbdbm.open(fname, 'n') as f:
+ self.assertEqual(list(f.keys()), [])
+ for key in self._dict:
+ f[key] = self._dict[key]
+ os.chmod(fname + ".dir", stat.S_IRUSR)
+ os.chmod(fname + ".dat", stat.S_IRUSR)
+ os.chmod(dir, stat.S_IRUSR|stat.S_IXUSR)
+ with dumbdbm.open(fname, 'r') as f:
+ self.assertEqual(sorted(f.keys()), sorted(self._dict))
+ f.close() # don't write
+
def tearDown(self):
_delete_files()
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 1e08ed92cec..c5bff7718dc 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -7,6 +7,7 @@ import pickle
import sys
import types
import unittest
+import warnings
import weakref
from copy import deepcopy
@@ -1661,6 +1662,77 @@ order (MRO) for bases """
self.assertEqual(b.foo, 3)
self.assertEqual(b.__class__, D)
+ @unittest.expectedFailure
+ def test_bad_new(self):
+ self.assertRaises(TypeError, object.__new__)
+ self.assertRaises(TypeError, object.__new__, '')
+ self.assertRaises(TypeError, list.__new__, object)
+ self.assertRaises(TypeError, object.__new__, list)
+ class C(object):
+ __new__ = list.__new__
+ self.assertRaises(TypeError, C)
+ class C(list):
+ __new__ = object.__new__
+ self.assertRaises(TypeError, C)
+
+ def test_object_new(self):
+ class A(object):
+ pass
+ object.__new__(A)
+ self.assertRaises(TypeError, object.__new__, A, 5)
+ object.__init__(A())
+ self.assertRaises(TypeError, object.__init__, A(), 5)
+
+ class A(object):
+ def __init__(self, foo):
+ self.foo = foo
+ object.__new__(A)
+ object.__new__(A, 5)
+ object.__init__(A(3))
+ self.assertRaises(TypeError, object.__init__, A(3), 5)
+
+ class A(object):
+ def __new__(cls, foo):
+ return object.__new__(cls)
+ object.__new__(A)
+ self.assertRaises(TypeError, object.__new__, A, 5)
+ object.__init__(A(3))
+ object.__init__(A(3), 5)
+
+ class A(object):
+ def __new__(cls, foo):
+ return object.__new__(cls)
+ def __init__(self, foo):
+ self.foo = foo
+ object.__new__(A)
+ self.assertRaises(TypeError, object.__new__, A, 5)
+ object.__init__(A(3))
+ self.assertRaises(TypeError, object.__init__, A(3), 5)
+
+ @unittest.expectedFailure
+ def test_restored_object_new(self):
+ class A(object):
+ def __new__(cls, *args, **kwargs):
+ raise AssertionError
+ self.assertRaises(AssertionError, A)
+ class B(A):
+ __new__ = object.__new__
+ def __init__(self, foo):
+ self.foo = foo
+ with warnings.catch_warnings():
+ warnings.simplefilter('error', DeprecationWarning)
+ b = B(3)
+ self.assertEqual(b.foo, 3)
+ self.assertEqual(b.__class__, B)
+ del B.__new__
+ self.assertRaises(AssertionError, B)
+ del A.__new__
+ with warnings.catch_warnings():
+ warnings.simplefilter('error', DeprecationWarning)
+ b = B(3)
+ self.assertEqual(b.foo, 3)
+ self.assertEqual(b.__class__, B)
+
def test_altmro(self):
# Testing mro() and overriding it...
class A(object):
@@ -3522,6 +3594,24 @@ order (MRO) for bases """
self.assertIsInstance(d, D)
self.assertEqual(d.foo, 1)
+ class C(object):
+ @staticmethod
+ def __new__(*args):
+ return args
+ self.assertEqual(C(1, 2), (C, 1, 2))
+ class D(C):
+ pass
+ self.assertEqual(D(1, 2), (D, 1, 2))
+
+ class C(object):
+ @classmethod
+ def __new__(*args):
+ return args
+ self.assertEqual(C(1, 2), (C, C, 1, 2))
+ class D(C):
+ pass
+ self.assertEqual(D(1, 2), (D, D, 1, 2))
+
def test_imul_bug(self):
# Testing for __imul__ problems...
# SF bug 544647
diff --git a/Lib/test/test_format.py b/Lib/test/test_format.py
index 8afd5b8f1fa..5471be21b5e 100644
--- a/Lib/test/test_format.py
+++ b/Lib/test/test_format.py
@@ -200,42 +200,28 @@ class FormatTest(unittest.TestCase):
testcommon("%#+37.34o", big, "+0o0012345670123456701234567012345670")
# next one gets one leading zero from precision
testcommon("%.33o", big, "012345670123456701234567012345670")
- # base marker shouldn't change that, since "0" is redundant
+ # base marker added in spite of leading zero (different to Python 2)
testcommon("%#.33o", big, "0o012345670123456701234567012345670")
- # but reduce precision, and base marker should add a zero
+ # reduce precision, and base marker is always added
testcommon("%#.32o", big, "0o12345670123456701234567012345670")
- # one leading zero from precision, and another from "0" flag & width
- testcommon("%034.33o", big, "0012345670123456701234567012345670")
- # base marker shouldn't change that
- testcommon("%0#34.33o", big, "0o012345670123456701234567012345670")
+ # one leading zero from precision, plus two from "0" flag & width
+ testcommon("%035.33o", big, "00012345670123456701234567012345670")
+ # base marker shouldn't change the size
+ testcommon("%0#35.33o", big, "0o012345670123456701234567012345670")
# Some small ints, in both Python int and flavors).
testcommon("%d", 42, "42")
testcommon("%d", -42, "-42")
- testcommon("%d", 42, "42")
- testcommon("%d", -42, "-42")
testcommon("%d", 42.0, "42")
testcommon("%#x", 1, "0x1")
- testcommon("%#x", 1, "0x1")
- testcommon("%#X", 1, "0X1")
testcommon("%#X", 1, "0X1")
testcommon("%#o", 1, "0o1")
- testcommon("%#o", 1, "0o1")
- testcommon("%#o", 0, "0o0")
testcommon("%#o", 0, "0o0")
testcommon("%o", 0, "0")
- testcommon("%o", 0, "0")
testcommon("%d", 0, "0")
- testcommon("%d", 0, "0")
- testcommon("%#x", 0, "0x0")
testcommon("%#x", 0, "0x0")
testcommon("%#X", 0, "0X0")
- testcommon("%#X", 0, "0X0")
testcommon("%x", 0x42, "42")
testcommon("%x", -0x42, "-42")
- testcommon("%x", 0x42, "42")
- testcommon("%x", -0x42, "-42")
- testcommon("%o", 0o42, "42")
- testcommon("%o", -0o42, "-42")
testcommon("%o", 0o42, "42")
testcommon("%o", -0o42, "-42")
# alternate float formatting
diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py
index 82050835f6a..708ed25b526 100644
--- a/Lib/test/test_fstring.py
+++ b/Lib/test/test_fstring.py
@@ -70,18 +70,18 @@ f'{a * x()}'"""
# Make sure x was called.
self.assertTrue(x.called)
- def test_literal_eval(self):
- # With no expressions, an f-string is okay.
- self.assertEqual(ast.literal_eval("f'x'"), 'x')
- self.assertEqual(ast.literal_eval("f'x' 'y'"), 'xy')
-
- # But this should raise an error.
- with self.assertRaisesRegex(ValueError, 'malformed node or string'):
- ast.literal_eval("f'x{3}'")
+ def test_docstring(self):
+ def f():
+ f'''Not a docstring'''
+ self.assertIsNone(f.__doc__)
+ def g():
+ '''Not a docstring''' \
+ f''
+ self.assertIsNone(g.__doc__)
- # As should this, which uses a different ast node
+ def test_literal_eval(self):
with self.assertRaisesRegex(ValueError, 'malformed node or string'):
- ast.literal_eval("f'{3}'")
+ ast.literal_eval("f'x'")
def test_ast_compile_time_concat(self):
x = ['']
diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py
index 75427dfad34..ba2a52fb734 100644
--- a/Lib/test/test_functools.py
+++ b/Lib/test/test_functools.py
@@ -1322,7 +1322,7 @@ class TestLRU:
f.cache_clear()
orig_si = sys.getswitchinterval()
- sys.setswitchinterval(1e-6)
+ support.setswitchinterval(1e-6)
try:
# create n threads in order to fill cache
threads = [threading.Thread(target=full, args=[k])
diff --git a/Lib/test/test_future.py b/Lib/test/test_future.py
index 213b2ba0755..2f1c410b1bf 100644
--- a/Lib/test/test_future.py
+++ b/Lib/test/test_future.py
@@ -2,6 +2,7 @@
import unittest
from test import support
+import os
import re
rx = re.compile(r'\((\S+).py, line (\d+)')
@@ -12,6 +13,12 @@ def get_error_location(msg):
class FutureTest(unittest.TestCase):
+ def check_syntax_error(self, err, basename, lineno, offset=0):
+ self.assertIn('%s.py, line %d' % (basename, lineno), str(err))
+ self.assertEqual(os.path.basename(err.filename), basename + '.py')
+ self.assertEqual(err.lineno, lineno)
+ self.assertEqual(err.offset, offset)
+
def test_future1(self):
with support.CleanImport('future_test1'):
from test import future_test1
@@ -27,68 +34,44 @@ class FutureTest(unittest.TestCase):
from test import test_future3
def test_badfuture3(self):
- try:
+ with self.assertRaises(SyntaxError) as cm:
from test import badsyntax_future3
- except SyntaxError as msg:
- self.assertEqual(get_error_location(msg), ("badsyntax_future3", '3'))
- else:
- self.fail("expected exception didn't occur")
+ self.check_syntax_error(cm.exception, "badsyntax_future3", 3)
def test_badfuture4(self):
- try:
+ with self.assertRaises(SyntaxError) as cm:
from test import badsyntax_future4
- except SyntaxError as msg:
- self.assertEqual(get_error_location(msg), ("badsyntax_future4", '3'))
- else:
- self.fail("expected exception didn't occur")
+ self.check_syntax_error(cm.exception, "badsyntax_future4", 3)
def test_badfuture5(self):
- try:
+ with self.assertRaises(SyntaxError) as cm:
from test import badsyntax_future5
- except SyntaxError as msg:
- self.assertEqual(get_error_location(msg), ("badsyntax_future5", '4'))
- else:
- self.fail("expected exception didn't occur")
+ self.check_syntax_error(cm.exception, "badsyntax_future5", 4)
def test_badfuture6(self):
- try:
+ with self.assertRaises(SyntaxError) as cm:
from test import badsyntax_future6
- except SyntaxError as msg:
- self.assertEqual(get_error_location(msg), ("badsyntax_future6", '3'))
- else:
- self.fail("expected exception didn't occur")
+ self.check_syntax_error(cm.exception, "badsyntax_future6", 3)
def test_badfuture7(self):
- try:
+ with self.assertRaises(SyntaxError) as cm:
from test import badsyntax_future7
- except SyntaxError as msg:
- self.assertEqual(get_error_location(msg), ("badsyntax_future7", '3'))
- else:
- self.fail("expected exception didn't occur")
+ self.check_syntax_error(cm.exception, "badsyntax_future7", 3, 53)
def test_badfuture8(self):
- try:
+ with self.assertRaises(SyntaxError) as cm:
from test import badsyntax_future8
- except SyntaxError as msg:
- self.assertEqual(get_error_location(msg), ("badsyntax_future8", '3'))
- else:
- self.fail("expected exception didn't occur")
+ self.check_syntax_error(cm.exception, "badsyntax_future8", 3)
def test_badfuture9(self):
- try:
+ with self.assertRaises(SyntaxError) as cm:
from test import badsyntax_future9
- except SyntaxError as msg:
- self.assertEqual(get_error_location(msg), ("badsyntax_future9", '3'))
- else:
- self.fail("expected exception didn't occur")
+ self.check_syntax_error(cm.exception, "badsyntax_future9", 3, 0)
def test_badfuture10(self):
- try:
+ with self.assertRaises(SyntaxError) as cm:
from test import badsyntax_future10
- except SyntaxError as msg:
- self.assertEqual(get_error_location(msg), ("badsyntax_future10", '3'))
- else:
- self.fail("expected exception didn't occur")
+ self.check_syntax_error(cm.exception, "badsyntax_future10", 3, 0)
def test_parserhack(self):
# test that the parser.c::future_hack function works as expected
diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py
index 2bd4457e616..60f1d928467 100644
--- a/Lib/test/test_gdb.py
+++ b/Lib/test/test_gdb.py
@@ -679,7 +679,7 @@ class StackNavigationTests(DebuggerTests):
def test_pyup_command(self):
'Verify that the "py-up" command works'
bt = self.get_stack_trace(script=self.get_sample_script(),
- cmds_after_breakpoint=['py-up'])
+ cmds_after_breakpoint=['py-up', 'py-up'])
self.assertMultilineMatches(bt,
r'''^.*
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 7, in bar \(a=1, b=2, c=3\)
@@ -698,7 +698,7 @@ $''')
def test_up_at_top(self):
'Verify handling of "py-up" at the top of the stack'
bt = self.get_stack_trace(script=self.get_sample_script(),
- cmds_after_breakpoint=['py-up'] * 4)
+ cmds_after_breakpoint=['py-up'] * 5)
self.assertEndsWith(bt,
'Unable to find an older python frame\n')
@@ -708,7 +708,7 @@ $''')
def test_up_then_down(self):
'Verify "py-up" followed by "py-down"'
bt = self.get_stack_trace(script=self.get_sample_script(),
- cmds_after_breakpoint=['py-up', 'py-down'])
+ cmds_after_breakpoint=['py-up', 'py-up', 'py-down'])
self.assertMultilineMatches(bt,
r'''^.*
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 7, in bar \(a=1, b=2, c=3\)
@@ -727,6 +727,7 @@ class PyBtTests(DebuggerTests):
self.assertMultilineMatches(bt,
r'''^.*
Traceback \(most recent call first\):
+ <built-in method id of module object .*>
File ".*gdb_sample.py", line 10, in baz
id\(42\)
File ".*gdb_sample.py", line 7, in bar
@@ -815,7 +816,6 @@ id(42)
)
self.assertIn('Garbage-collecting', gdb_output)
- @unittest.skip("FIXME: builtin method is not shown in py-bt and py-bt-full")
@unittest.skipIf(python_is_optimized(),
"Python was compiled with optimizations")
# Some older versions of gdb will fail with
@@ -854,7 +854,7 @@ class PyPrintTests(DebuggerTests):
def test_basic_command(self):
'Verify that the "py-print" command works'
bt = self.get_stack_trace(script=self.get_sample_script(),
- cmds_after_breakpoint=['py-print args'])
+ cmds_after_breakpoint=['py-up', 'py-print args'])
self.assertMultilineMatches(bt,
r".*\nlocal 'args' = \(1, 2, 3\)\n.*")
@@ -863,7 +863,7 @@ class PyPrintTests(DebuggerTests):
@unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands")
def test_print_after_up(self):
bt = self.get_stack_trace(script=self.get_sample_script(),
- cmds_after_breakpoint=['py-up', 'py-print c', 'py-print b', 'py-print a'])
+ cmds_after_breakpoint=['py-up', 'py-up', 'py-print c', 'py-print b', 'py-print a'])
self.assertMultilineMatches(bt,
r".*\nlocal 'c' = 3\nlocal 'b' = 2\nlocal 'a' = 1\n.*")
@@ -871,7 +871,7 @@ class PyPrintTests(DebuggerTests):
"Python was compiled with optimizations")
def test_printing_global(self):
bt = self.get_stack_trace(script=self.get_sample_script(),
- cmds_after_breakpoint=['py-print __name__'])
+ cmds_after_breakpoint=['py-up', 'py-print __name__'])
self.assertMultilineMatches(bt,
r".*\nglobal '__name__' = '__main__'\n.*")
@@ -879,7 +879,7 @@ class PyPrintTests(DebuggerTests):
"Python was compiled with optimizations")
def test_printing_builtin(self):
bt = self.get_stack_trace(script=self.get_sample_script(),
- cmds_after_breakpoint=['py-print len'])
+ cmds_after_breakpoint=['py-up', 'py-print len'])
self.assertMultilineMatches(bt,
r".*\nbuiltin 'len' = <built-in method len of module object at remote 0x-?[0-9a-f]+>\n.*")
@@ -888,7 +888,7 @@ class PyLocalsTests(DebuggerTests):
"Python was compiled with optimizations")
def test_basic_command(self):
bt = self.get_stack_trace(script=self.get_sample_script(),
- cmds_after_breakpoint=['py-locals'])
+ cmds_after_breakpoint=['py-up', 'py-locals'])
self.assertMultilineMatches(bt,
r".*\nargs = \(1, 2, 3\)\n.*")
@@ -897,7 +897,7 @@ class PyLocalsTests(DebuggerTests):
"Python was compiled with optimizations")
def test_locals_after_up(self):
bt = self.get_stack_trace(script=self.get_sample_script(),
- cmds_after_breakpoint=['py-up', 'py-locals'])
+ cmds_after_breakpoint=['py-up', 'py-up', 'py-locals'])
self.assertMultilineMatches(bt,
r".*\na = 1\nb = 2\nc = 3\n.*")
diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py
index ae5dd6a5f7c..f698e13f68a 100644
--- a/Lib/test/test_genericpath.py
+++ b/Lib/test/test_genericpath.py
@@ -8,6 +8,7 @@ import sys
import unittest
import warnings
from test import support
+android_not_root = support.android_not_root
def create_file(filename, data=b'foo'):
@@ -212,6 +213,7 @@ class GenericTest:
def test_samefile_on_symlink(self):
self._test_samefile_on_link_func(os.symlink)
+ @unittest.skipIf(android_not_root, "hard links not allowed, non root user")
def test_samefile_on_link(self):
self._test_samefile_on_link_func(os.link)
@@ -251,6 +253,7 @@ class GenericTest:
def test_samestat_on_symlink(self):
self._test_samestat_on_link_func(os.symlink)
+ @unittest.skipIf(android_not_root, "hard links not allowed, non root user")
def test_samestat_on_link(self):
self._test_samestat_on_link_func(os.link)
diff --git a/Lib/test/test_global.py b/Lib/test/test_global.py
index 37ec67255a5..9eeccf12506 100644
--- a/Lib/test/test_global.py
+++ b/Lib/test/test_global.py
@@ -24,7 +24,7 @@ def wrong1():
global a
global b
"""
- check_syntax_error(self, prog_text_1)
+ check_syntax_error(self, prog_text_1, lineno=4, offset=4)
def test2(self):
prog_text_2 = """\
@@ -32,7 +32,7 @@ def wrong2():
print(x)
global x
"""
- check_syntax_error(self, prog_text_2)
+ check_syntax_error(self, prog_text_2, lineno=3, offset=4)
def test3(self):
prog_text_3 = """\
@@ -41,7 +41,7 @@ def wrong3():
x = 2
global x
"""
- check_syntax_error(self, prog_text_3)
+ check_syntax_error(self, prog_text_3, lineno=4, offset=4)
def test4(self):
prog_text_4 = """\
diff --git a/Lib/test/test_importlib/test_locks.py b/Lib/test/test_importlib/test_locks.py
index b2aadff289b..dbce9c2dfdf 100644
--- a/Lib/test/test_importlib/test_locks.py
+++ b/Lib/test/test_importlib/test_locks.py
@@ -57,7 +57,7 @@ if threading is not None:
def setUp(self):
try:
self.old_switchinterval = sys.getswitchinterval()
- sys.setswitchinterval(0.000001)
+ support.setswitchinterval(0.000001)
except AttributeError:
self.old_switchinterval = None
diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py
index aeabdbb2b5e..2ba944335ae 100644
--- a/Lib/test/test_mailbox.py
+++ b/Lib/test/test_mailbox.py
@@ -2137,9 +2137,9 @@ class MaildirTestCase(unittest.TestCase):
if mbox:
fp.write(FROM_)
fp.write(DUMMY_MESSAGE)
- if hasattr(os, "link"):
+ try:
os.link(tmpname, newname)
- else:
+ except (AttributeError, PermissionError):
with open(newname, "w") as fp:
fp.write(DUMMY_MESSAGE)
self._msgfiles.append(newname)
diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py
index f98c1febb5c..ce1ca153ed0 100644
--- a/Lib/test/test_pathlib.py
+++ b/Lib/test/test_pathlib.py
@@ -10,6 +10,7 @@ import tempfile
import unittest
from test import support
+android_not_root = support.android_not_root
TESTFN = support.TESTFN
try:
@@ -1864,6 +1865,7 @@ class _BasePathTest(object):
self.assertFalse((P / 'fileA' / 'bah').is_fifo())
@unittest.skipUnless(hasattr(os, "mkfifo"), "os.mkfifo() required")
+ @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user")
def test_is_fifo_true(self):
P = self.cls(BASE, 'myfifo')
os.mkfifo(str(P))
@@ -1886,7 +1888,8 @@ class _BasePathTest(object):
try:
sock.bind(str(P))
except OSError as e:
- if "AF_UNIX path too long" in str(e):
+ if (isinstance(e, PermissionError) or
+ "AF_UNIX path too long" in str(e)):
self.skipTest("cannot bind Unix socket: " + str(e))
self.assertTrue(P.is_socket())
self.assertFalse(P.is_fifo())
@@ -2080,6 +2083,8 @@ class PosixPathTest(_BasePathTest, unittest.TestCase):
self.assertEqual(given, expect)
self.assertEqual(set(p.rglob("FILEd*")), set())
+ @unittest.skipUnless(hasattr(pwd, 'getpwall'),
+ 'pwd module does not expose getpwall()')
def test_expanduser(self):
P = self.cls
support.import_module('pwd')
diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py
index 63c74cd80da..029d0815e94 100644
--- a/Lib/test/test_posix.py
+++ b/Lib/test/test_posix.py
@@ -1,6 +1,7 @@
"Test posix functions"
from test import support
+android_not_root = support.android_not_root
# Skip these tests if there is no posix module.
posix = support.import_module('posix')
@@ -422,6 +423,7 @@ class PosixTester(unittest.TestCase):
posix.stat, list(os.fsencode(support.TESTFN)))
@unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
+ @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user")
def test_mkfifo(self):
support.unlink(support.TESTFN)
posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
@@ -429,6 +431,7 @@ class PosixTester(unittest.TestCase):
@unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
"don't have mknod()/S_IFIFO")
+ @unittest.skipIf(android_not_root, "mknod not allowed, non root user")
def test_mknod(self):
# Test using mknod() to create a FIFO (the only use specified
# by POSIX).
@@ -907,6 +910,7 @@ class PosixTester(unittest.TestCase):
posix.close(f)
@unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()")
+ @unittest.skipIf(android_not_root, "hard link not allowed, non root user")
def test_link_dir_fd(self):
f = posix.open(posix.getcwd(), posix.O_RDONLY)
try:
@@ -930,6 +934,7 @@ class PosixTester(unittest.TestCase):
@unittest.skipUnless((os.mknod in os.supports_dir_fd) and hasattr(stat, 'S_IFIFO'),
"test requires both stat.S_IFIFO and dir_fd support for os.mknod()")
+ @unittest.skipIf(android_not_root, "mknod not allowed, non root user")
def test_mknod_dir_fd(self):
# Test using mknodat() to create a FIFO (the only use specified
# by POSIX).
@@ -1013,6 +1018,7 @@ class PosixTester(unittest.TestCase):
posix.close(f)
@unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()")
+ @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user")
def test_mkfifo_dir_fd(self):
support.unlink(support.TESTFN)
f = posix.open(posix.getcwd(), posix.O_RDONLY)
diff --git a/Lib/test/test_pwd.py b/Lib/test/test_pwd.py
index b7b1a4a5f64..ac9cff789ee 100644
--- a/Lib/test/test_pwd.py
+++ b/Lib/test/test_pwd.py
@@ -4,10 +4,19 @@ from test import support
pwd = support.import_module('pwd')
+def _getpwall():
+ # Android does not have getpwall.
+ if hasattr(pwd, 'getpwall'):
+ return pwd.getpwall()
+ elif hasattr(pwd, 'getpwuid'):
+ return [pwd.getpwuid(0)]
+ else:
+ return []
+
class PwdTest(unittest.TestCase):
def test_values(self):
- entries = pwd.getpwall()
+ entries = _getpwall()
for e in entries:
self.assertEqual(len(e), 7)
@@ -33,7 +42,7 @@ class PwdTest(unittest.TestCase):
# and check afterwards (done in test_values_extended)
def test_values_extended(self):
- entries = pwd.getpwall()
+ entries = _getpwall()
entriesbyname = {}
entriesbyuid = {}
@@ -57,12 +66,13 @@ class PwdTest(unittest.TestCase):
self.assertRaises(TypeError, pwd.getpwuid, 3.14)
self.assertRaises(TypeError, pwd.getpwnam)
self.assertRaises(TypeError, pwd.getpwnam, 42)
- self.assertRaises(TypeError, pwd.getpwall, 42)
+ if hasattr(pwd, 'getpwall'):
+ self.assertRaises(TypeError, pwd.getpwall, 42)
# try to get some errors
bynames = {}
byuids = {}
- for (n, p, u, g, gecos, d, s) in pwd.getpwall():
+ for (n, p, u, g, gecos, d, s) in _getpwall():
bynames[n] = u
byuids[u] = n
@@ -96,13 +106,17 @@ class PwdTest(unittest.TestCase):
# loop, say), pwd.getpwuid() might still be able to find data for that
# uid. Using sys.maxint may provoke the same problems, but hopefully
# it will be a more repeatable failure.
+ # Android accepts a very large span of uids including sys.maxsize and
+ # -1; it raises KeyError with 1 or 2 for example.
fakeuid = sys.maxsize
self.assertNotIn(fakeuid, byuids)
- self.assertRaises(KeyError, pwd.getpwuid, fakeuid)
+ if not support.is_android:
+ self.assertRaises(KeyError, pwd.getpwuid, fakeuid)
# -1 shouldn't be a valid uid because it has a special meaning in many
# uid-related functions
- self.assertRaises(KeyError, pwd.getpwuid, -1)
+ if not support.is_android:
+ self.assertRaises(KeyError, pwd.getpwuid, -1)
# should be out of uid_t range
self.assertRaises(KeyError, pwd.getpwuid, 2**128)
self.assertRaises(KeyError, pwd.getpwuid, -2**128)
diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py
index af5f00fdf0d..46e2c57746d 100644
--- a/Lib/test/test_shutil.py
+++ b/Lib/test/test_shutil.py
@@ -22,7 +22,8 @@ import tarfile
import warnings
from test import support
-from test.support import TESTFN, check_warnings, captured_stdout, requires_zlib
+from test.support import (TESTFN, check_warnings, captured_stdout,
+ requires_zlib, android_not_root)
try:
import bz2
@@ -787,6 +788,7 @@ class TestShutil(unittest.TestCase):
@unittest.skipIf(os.name == 'nt', 'temporarily disabled on Windows')
@unittest.skipUnless(hasattr(os, 'link'), 'requires os.link')
+ @unittest.skipIf(android_not_root, "hard links not allowed, non root user")
def test_dont_copy_file_onto_link_to_itself(self):
# bug 851123.
os.mkdir(TESTFN)
@@ -839,6 +841,7 @@ class TestShutil(unittest.TestCase):
# Issue #3002: copyfile and copytree block indefinitely on named pipes
@unittest.skipUnless(hasattr(os, "mkfifo"), 'requires os.mkfifo()')
+ @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user")
def test_copyfile_named_pipe(self):
os.mkfifo(TESTFN)
try:
@@ -849,6 +852,7 @@ class TestShutil(unittest.TestCase):
finally:
os.remove(TESTFN)
+ @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user")
@unittest.skipUnless(hasattr(os, "mkfifo"), 'requires os.mkfifo()')
@support.skip_unless_symlink
def test_copytree_named_pipe(self):
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index 59564c9063d..6b29e182348 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -278,8 +278,14 @@ class ThreadableTest:
def clientRun(self, test_func):
self.server_ready.wait()
- self.clientSetUp()
- self.client_ready.set()
+ try:
+ self.clientSetUp()
+ except BaseException as e:
+ self.queue.put(e)
+ self.clientTearDown()
+ return
+ finally:
+ self.client_ready.set()
if self.server_crashed:
self.clientTearDown()
return
@@ -520,8 +526,11 @@ class ConnectedStreamTestMixin(SocketListeningTestMixin,
self.serv_conn = self.cli
def clientTearDown(self):
- self.serv_conn.close()
- self.serv_conn = None
+ try:
+ self.serv_conn.close()
+ self.serv_conn = None
+ except AttributeError:
+ pass
super().clientTearDown()
@@ -540,7 +549,7 @@ class UnixSocketTestBase(SocketTestBase):
def bindSock(self, sock):
path = tempfile.mktemp(dir=self.dir_path)
- sock.bind(path)
+ support.bind_unix_socket(sock, path)
self.addCleanup(support.unlink, path)
class UnixStreamBase(UnixSocketTestBase):
@@ -4631,7 +4640,7 @@ class TestUnixDomain(unittest.TestCase):
def bind(self, sock, path):
# Bind the socket
try:
- sock.bind(path)
+ support.bind_unix_socket(sock, path)
except OSError as e:
if str(e) == "AF_UNIX path too long":
self.skipTest(
diff --git a/Lib/test/test_stat.py b/Lib/test/test_stat.py
index f1a5938a39f..cd02a6ee374 100644
--- a/Lib/test/test_stat.py
+++ b/Lib/test/test_stat.py
@@ -1,7 +1,7 @@
import unittest
import os
import sys
-from test.support import TESTFN, import_fresh_module
+from test.support import TESTFN, import_fresh_module, android_not_root
c_stat = import_fresh_module('stat', fresh=['_stat'])
py_stat = import_fresh_module('stat', blocked=['_stat'])
@@ -168,6 +168,7 @@ class TestFilemode:
self.assertS_IS("LNK", st_mode)
@unittest.skipUnless(hasattr(os, 'mkfifo'), 'os.mkfifo not available')
+ @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user")
def test_fifo(self):
os.mkfifo(TESTFN, 0o700)
st_mode, modestr = self.get_mode()
diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py
index 553822b5823..e83a4d6426a 100644
--- a/Lib/test/test_support.py
+++ b/Lib/test/test_support.py
@@ -240,7 +240,7 @@ class TestSupport(unittest.TestCase):
self.assertEqual(cm.exception.errno, errno.EBADF)
def test_check_syntax_error(self):
- support.check_syntax_error(self, "def class")
+ support.check_syntax_error(self, "def class", lineno=1, offset=9)
with self.assertRaises(AssertionError):
support.check_syntax_error(self, "x=1")
diff --git a/Lib/test/test_symtable.py b/Lib/test/test_symtable.py
index 30471653c36..dfaee173ef7 100644
--- a/Lib/test/test_symtable.py
+++ b/Lib/test/test_symtable.py
@@ -159,15 +159,17 @@ class SymtableTest(unittest.TestCase):
def test_filename_correct(self):
### Bug tickler: SyntaxError file name correct whether error raised
### while parsing or building symbol table.
- def checkfilename(brokencode):
+ def checkfilename(brokencode, offset):
try:
symtable.symtable(brokencode, "spam", "exec")
except SyntaxError as e:
self.assertEqual(e.filename, "spam")
+ self.assertEqual(e.lineno, 1)
+ self.assertEqual(e.offset, offset)
else:
self.fail("no SyntaxError for %r" % (brokencode,))
- checkfilename("def f(x): foo)(") # parse-time
- checkfilename("def f(x): global x") # symtable-build-time
+ checkfilename("def f(x): foo)(", 14) # parse-time
+ checkfilename("def f(x): global x", 10) # symtable-build-time
symtable.symtable("pass", b"spam", "exec")
with self.assertWarns(DeprecationWarning), \
self.assertRaises(TypeError):
diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py
index 80e36fd46e5..7f7e6dafcf9 100644
--- a/Lib/test/test_syntax.py
+++ b/Lib/test/test_syntax.py
@@ -544,7 +544,7 @@ from test import support
class SyntaxTestCase(unittest.TestCase):
def _check_error(self, code, errtext,
- filename="<testcase>", mode="exec", subclass=None):
+ filename="<testcase>", mode="exec", subclass=None, lineno=None, offset=None):
"""Check that compiling code raises SyntaxError with errtext.
errtest is a regular expression that must be present in the
@@ -559,6 +559,11 @@ class SyntaxTestCase(unittest.TestCase):
mo = re.search(errtext, str(err))
if mo is None:
self.fail("SyntaxError did not contain '%r'" % (errtext,))
+ self.assertEqual(err.filename, filename)
+ if lineno is not None:
+ self.assertEqual(err.lineno, lineno)
+ if offset is not None:
+ self.assertEqual(err.offset, offset)
else:
self.fail("compile() did not raise SyntaxError")
@@ -569,7 +574,7 @@ class SyntaxTestCase(unittest.TestCase):
self._check_error("del f()", "delete")
def test_global_err_then_warn(self):
- # Bug tickler: The SyntaxError raised for one global statement
+ # Bug #763201: The SyntaxError raised for one global statement
# shouldn't be clobbered by a SyntaxWarning issued for a later one.
source = """if 1:
def error(a):
diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py
index 091e90522de..355bc614da3 100644
--- a/Lib/test/test_sysconfig.py
+++ b/Lib/test/test_sysconfig.py
@@ -385,7 +385,9 @@ class TestSysConfig(unittest.TestCase):
self.assertIsNotNone(vars['SO'])
self.assertEqual(vars['SO'], vars['EXT_SUFFIX'])
- @unittest.skipUnless(sys.platform == 'linux', 'Linux-specific test')
+ @unittest.skipUnless(sys.platform == 'linux' and
+ hasattr(sys.implementation, '_multiarch'),
+ 'multiarch-specific test')
def test_triplet_in_ext_suffix(self):
import ctypes, platform, re
machine = platform.machine()
@@ -395,7 +397,6 @@ class TestSysConfig(unittest.TestCase):
if re.match('(i[3-6]86|x86_64)$', machine):
if ctypes.sizeof(ctypes.c_char_p()) == 4:
self.assertTrue(suffix.endswith('i386-linux-gnu.so') or
- suffix.endswith('i686-linux-android.so') or
suffix.endswith('x86_64-linux-gnux32.so'),
suffix)
else: # 8 byte pointer size
diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py
index 845e7d4bd40..2c2914fd6d8 100644
--- a/Lib/test/test_threading.py
+++ b/Lib/test/test_threading.py
@@ -462,7 +462,7 @@ class ThreadTests(BaseTestCase):
self.addCleanup(sys.setswitchinterval, old_interval)
# Make the bug more likely to manifest.
- sys.setswitchinterval(1e-6)
+ test.support.setswitchinterval(1e-6)
for i in range(20):
t = threading.Thread(target=lambda: None)
diff --git a/Makefile.pre.in b/Makefile.pre.in
index cd7d33d2304..48b5180b074 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -858,8 +858,8 @@ UNICODE_DEPS = \
$(srcdir)/Objects/stringlib/unicode_format.h \
$(srcdir)/Objects/stringlib/unicodedefs.h
+Objects/bytes_methods.o: $(srcdir)/Objects/bytes_methods.c $(BYTESTR_DEPS)
Objects/bytesobject.o: $(srcdir)/Objects/bytesobject.c $(BYTESTR_DEPS)
-
Objects/bytearrayobject.o: $(srcdir)/Objects/bytearrayobject.c $(BYTESTR_DEPS)
Objects/unicodeobject.o: $(srcdir)/Objects/unicodeobject.c $(UNICODE_DEPS)
diff --git a/Misc/NEWS b/Misc/NEWS
index 5cf929f21f8..477dc9ba146 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -2,7 +2,7 @@
Python News
+++++++++++
-What's New in Python 3.6.0 release candidate 2
+What's New in Python 3.6.1 release candidate 1
==============================================
*Release date: XXXX-XX-XX*
@@ -10,19 +10,62 @@ What's New in Python 3.6.0 release candidate 2
Core and Builtins
-----------------
+- Issue #26919: On Android, operating system data is now always encoded/decoded
+ to/from UTF-8, instead of the locale encoding to avoid inconsistencies with
+ os.fsencode() and os.fsdecode() which are already using UTF-8.
+
- Issue #28147: Fix a memory leak in split-table dictionaries: setattr()
must not convert combined table into split table. Patch written by INADA
Naoki.
+- Issue #28739: f-string expressions no longer accepted as docstrings and
+ by ast.literal_eval() even if they do not include expressions.
+
+- Issue #28512: Fixed setting the offset attribute of SyntaxError by
+ PyErr_SyntaxLocationEx() and PyErr_SyntaxLocationObject().
+
+- Issue #28918: Fix the cross compilation of xxlimited when Python has been
+ built with Py_DEBUG defined.
+
+- Issue #28731: Optimize _PyDict_NewPresized() to create correct size dict.
+ Improve speed of dict literal with constant keys up to 30%.
+
+Library
+-------
+
+- Issue #28779: multiprocessing.set_forkserver_preload() would crash the
+ forkserver process if a preloaded module instantiated some
+ multiprocessing objects such as locks.
+
+- Issue #28847: dbm.dumb now supports reading read-only files and no longer
+ writes the index file when it is not changed.
+
+- Issue #26937: The chown() method of the tarfile.TarFile class does not fail
+ now when the grp module cannot be imported, as for example on Android
+ platforms.
+
Windows
-------
-- Issue #28896: Deprecate WindowsRegistryFinder
+- Issue #28896: Deprecate WindowsRegistryFinder and disable it by default.
+
+Tests
+-----
+
+- Issue #28683: Fix the tests that bind() a unix socket and raise
+ PermissionError on Android for a non-root user.
+
+- Issue #26939: Add the support.setswitchinterval() function to fix
+ test_functools hanging on the Android armv7 qemu emulator.
Build
-----
-- Issue #28898: Prevent gdb build errors due to HAVE_LONG_LONG redefinition.
+- Issue #20211: Do not add the directory for installing C header files and the
+ directory for installing object code libraries to the cross compilation
+ search paths. Original patch by Thomas Petazzoni.
+
+- Issue #28849: Do not define sys.implementation._multiarch on Android.
What's New in Python 3.6.0 release candidate 1
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index 4e8f74a3c94..fff90468a59 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -1327,7 +1327,7 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop)
return -1;
}
- res = _PyObject_CallMethodId(all_tasks, &PyId_add, "O", self, NULL);
+ res = _PyObject_CallMethodIdObjArgs(all_tasks, &PyId_add, self, NULL);
if (res == NULL) {
return -1;
}
@@ -1838,8 +1838,8 @@ task_call_wakeup(TaskObj *task, PyObject *fut)
}
else {
/* `task` is a subclass of Task */
- return _PyObject_CallMethodId(
- (PyObject*)task, &PyId__wakeup, "O", fut, NULL);
+ return _PyObject_CallMethodIdObjArgs((PyObject*)task, &PyId__wakeup,
+ fut, NULL);
}
}
@@ -1854,8 +1854,8 @@ task_call_step(TaskObj *task, PyObject *arg)
if (arg == NULL) {
arg = Py_None;
}
- return _PyObject_CallMethodId(
- (PyObject*)task, &PyId__step, "O", arg, NULL);
+ return _PyObject_CallMethodIdObjArgs((PyObject*)task, &PyId__step,
+ arg, NULL);
}
}
@@ -1869,8 +1869,8 @@ task_call_step_soon(TaskObj *task, PyObject *arg)
return -1;
}
- handle = _PyObject_CallMethodId(
- task->task_loop, &PyId_call_soon, "O", cb, NULL);
+ handle = _PyObject_CallMethodIdObjArgs(task->task_loop, &PyId_call_soon,
+ cb, NULL);
Py_DECREF(cb);
if (handle == NULL) {
return -1;
@@ -2135,8 +2135,9 @@ task_step_impl(TaskObj *task, PyObject *exc)
if (wrapper == NULL) {
goto fail;
}
- res = _PyObject_CallMethodId(
- result, &PyId_add_done_callback, "O", wrapper, NULL);
+ res = _PyObject_CallMethodIdObjArgs(result,
+ &PyId_add_done_callback,
+ wrapper, NULL);
Py_DECREF(wrapper);
if (res == NULL) {
goto fail;
diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c
index 60f8b549a82..f4d3cbd49f8 100644
--- a/Modules/_io/_iomodule.c
+++ b/Modules/_io/_iomodule.c
@@ -683,7 +683,7 @@ PyInit__io(void)
/* UnsupportedOperation inherits from ValueError and IOError */
state->unsupported_operation = PyObject_CallFunction(
(PyObject *)&PyType_Type, "s(OO){}",
- "UnsupportedOperation", PyExc_ValueError, PyExc_IOError);
+ "UnsupportedOperation", PyExc_OSError, PyExc_ValueError);
if (state->unsupported_operation == NULL)
goto fail;
Py_INCREF(state->unsupported_operation);
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index db0ab5805c5..ebd44ad525b 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -398,7 +398,7 @@ time_localtime(PyObject *self, PyObject *args)
struct tm local = buf;
char zone[100];
int gmtoff;
- strftime(zone, sizeof(buf), "%Z", &buf);
+ strftime(zone, sizeof(zone), "%Z", &buf);
gmtoff = timegm(&buf) - when;
return tmtotuple(&local, zone, gmtoff);
}
diff --git a/Objects/abstract.c b/Objects/abstract.c
index f9afece815b..d838856d452 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -2325,7 +2325,7 @@ exit:
return result;
}
-/* Positional arguments are obj followed args. */
+/* Positional arguments are obj followed by args. */
PyObject *
_PyObject_Call_Prepend(PyObject *func,
PyObject *obj, PyObject *args, PyObject *kwargs)
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 20b6f2f52e4..5fff34b1194 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -388,7 +388,7 @@ dk_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix)
* This can be used to reserve enough size to insert n entries without
* resizing.
*/
-#define ESTIMATE_SIZE(n) (((n)*3) >> 1)
+#define ESTIMATE_SIZE(n) (((n)*3+1) >> 1)
/* Alternative fraction that is otherwise close enough to 2n/3 to make
* little difference. 8 * 2/3 == 8 * 5/8 == 5. 16 * 2/3 == 16 * 5/8 == 10.
@@ -1359,12 +1359,26 @@ make_keys_shared(PyObject *op)
PyObject *
_PyDict_NewPresized(Py_ssize_t minused)
{
+ const Py_ssize_t max_presize = 128 * 1024;
Py_ssize_t newsize;
PyDictKeysObject *new_keys;
- for (newsize = PyDict_MINSIZE;
- newsize <= minused && newsize > 0;
- newsize <<= 1)
- ;
+
+ /* There are no strict guarantee that returned dict can contain minused
+ * items without resize. So we create medium size dict instead of very
+ * large dict or MemoryError.
+ */
+ if (minused > USABLE_FRACTION(max_presize)) {
+ newsize = max_presize;
+ }
+ else {
+ Py_ssize_t minsize = ESTIMATE_SIZE(minused);
+ newsize = PyDict_MINSIZE;
+ while (newsize < minsize) {
+ newsize <<= 1;
+ }
+ }
+ assert(IS_POWER_OF_2(newsize));
+
new_keys = new_keys_object(newsize);
if (new_keys == NULL)
return NULL;
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 9c998f7ab3e..44911671a0e 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -5083,10 +5083,10 @@ onError:
return NULL;
}
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(__ANDROID__)
/* Simplified UTF-8 decoder using surrogateescape error handler,
- used to decode the command line arguments on Mac OS X.
+ used to decode the command line arguments on Mac OS X and Android.
Return a pointer to a newly allocated wide character string (use
PyMem_RawFree() to free the memory), or NULL on memory allocation error. */
@@ -5137,7 +5137,7 @@ _Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size)
return unicode;
}
-#endif /* __APPLE__ */
+#endif /* __APPLE__ or __ANDROID__ */
/* Primary internal function which creates utf8 encoded bytes objects.
diff --git a/PC/bdist_wininst/install.c b/PC/bdist_wininst/install.c
index fd977f5a554..17cc30d25cf 100644
--- a/PC/bdist_wininst/install.c
+++ b/PC/bdist_wininst/install.c
@@ -154,7 +154,7 @@ HANDLE hBitmap;
char *bitmap_bytes;
static const char *REGISTRY_SUFFIX_6432 =
-#ifdef MS_WIN64
+#ifdef _WIN64
"";
#else
"-32";
diff --git a/PCbuild/_freeze_importlib.vcxproj b/PCbuild/_freeze_importlib.vcxproj
index f7714c003af..c73266301e8 100644
--- a/PCbuild/_freeze_importlib.vcxproj
+++ b/PCbuild/_freeze_importlib.vcxproj
@@ -76,31 +76,44 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
- <None Include="..\Lib\importlib\_bootstrap.py" />
+ <None Include="..\Lib\importlib\_bootstrap.py">
+ <IntFile>$(IntDir)importlib.g.h</IntFile>
+ <OutFile>$(PySourcePath)Python\importlib.h</OutFile>
+ </None>
+ <None Include="..\Lib\importlib\_bootstrap_external.py">
+ <IntFile>$(IntDir)importlib_external.g.h</IntFile>
+ <OutFile>$(PySourcePath)Python\importlib_external.h</OutFile>
+ </None>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
- <Target Name="RebuildImportLib" AfterTargets="AfterBuild" Condition="$(Configuration) == 'Debug' or $(Configuration) == 'Release'">
- <Exec Command='"$(TargetPath)" "$(PySourcePath)Lib\importlib\_bootstrap.py" "$(IntDir)importlib.g.h"' />
+ <Target Name="_RebuildImportLib">
+ <Exec Command='"$(TargetPath)" "%(None.FullPath)" "%(None.IntFile)"' />
<PropertyGroup>
- <_OldContent Condition="Exists('$(PySourcePath)Python\importlib.h')">$([System.IO.File]::ReadAllText('$(PySourcePath)Python\importlib.h').Replace(`&#x0D;&#x0A;`, `&#x0A;`))</_OldContent>
- <_NewContent Condition="Exists('$(IntDir)importlib.g.h')">$([System.IO.File]::ReadAllText('$(IntDir)importlib.g.h').Replace(`&#x0D;&#x0A;`, `&#x0A;`))</_NewContent>
+ <_OldContent Condition="Exists($(OutTargetPath))"></_OldContent>
+ <_NewContent Condition="Exists($(IntTargetPath))">$([System.IO.File]::ReadAllText($(IntTargetPath)).Replace(`&#x0D;&#x0A;`, `&#x0A;`))</_NewContent>
</PropertyGroup>
- <Copy SourceFiles="$(IntDir)importlib.g.h"
- DestinationFiles="$(PySourcePath)Python\importlib.h"
- Condition="Exists('$(IntDir)importlib.g.h') and '$(_OldContent)' != '$(_NewContent)'" />
+ <Copy SourceFiles="%(None.IntFile)"
+ DestinationFiles="%(None.OutFile)"
+ Condition="!Exists(%(None.OutFile)) or (Exists(%(None.IntFile)) and '$([System.IO.File]::ReadAllText(%(None.OutFile)).Replace(`&#x0D;&#x0A;`, `&#x0A;`))' != '$([System.IO.File]::ReadAllText(%(None.IntFile)).Replace(`&#x0D;&#x0A;`, `&#x0A;`))')">
+ <Output TaskParameter="CopiedFiles" ItemName="_Updated" />
+ </Copy>
- <Warning Text="importlib.h has been updated. You will need to rebuild pythoncore to see the changes."
- Condition="Exists('$(IntDir)importlib.g.h') and '$(_OldContent)' != '$(_NewContent)' and $(Configuration) == 'Debug'" />
- <Error Text="importlib.h has been updated. You will need to rebuild pythoncore to see the changes."
- Condition="Exists('$(IntDir)importlib.g.h') and '$(_OldContent)' != '$(_NewContent)' and $(Configuration) == 'Release'" />
+ <Warning Text="@(_Updated->'%(Filename)%(Extension)',', ') updated. You will need to rebuild pythoncore to see the changes."
+ Condition="'@(_Updated)' != '' and $(Configuration) == 'Debug'" />
+ <Error Text="@(_Updated->'%(Filename)%(Extension)',', ') updated. You will need to rebuild pythoncore to see the changes."
+ Condition="'@(_Updated)' != '' and $(Configuration) == 'Release'" />
+ </Target>
+ <Target Name="RebuildImportLib" AfterTargets="AfterBuild" Condition="$(Configuration) == 'Debug' or $(Configuration) == 'Release'"
+ DependsOnTargets="_RebuildImportLib">
</Target>
<Target Name="_CleanImportLib" BeforeTargets="CoreClean">
<ItemGroup>
<Clean Include="$(IntDir)importlib.g.h" />
+ <Clean Include="$(IntDir)importlib_external.g.h" />
</ItemGroup>
</Target>
</Project>
diff --git a/PCbuild/pcbuild.proj b/PCbuild/pcbuild.proj
index e0e6e93fc0a..c6b8487c0a2 100644
--- a/PCbuild/pcbuild.proj
+++ b/PCbuild/pcbuild.proj
@@ -28,7 +28,7 @@
<BuildTarget>Build</BuildTarget>
<CleanTarget>Clean</CleanTarget>
<CleanAllTarget>CleanAll</CleanAllTarget>
- <BuildInParallel>true</BuildInParallel>
+ <BuildInParallel>false</BuildInParallel>
</Projects2>
</ItemDefinitionGroup>
<ItemGroup>
@@ -48,8 +48,6 @@
<Projects Include="pylauncher.vcxproj;pywlauncher.vcxproj" />
<!-- pyshellext.dll -->
<Projects Include="pyshellext.vcxproj" />
- <!-- _freeze_importlib -->
- <Projects Include="_freeze_importlib.vcxproj" />
<!-- Extension modules -->
<ExtensionModules Include="_asyncio;_ctypes;_decimal;_elementtree;_msi;_multiprocessing;_overlapped;pyexpat;select;unicodedata;winsound" />
<!-- Extension modules that require external sources -->
@@ -68,10 +66,10 @@
<BuildInParallel>false</BuildInParallel>
</Projects>
+ <!-- _freeze_importlib -->
+ <Projects2 Include="_freeze_importlib.vcxproj" />
<!-- python[w].exe -->
- <Projects2 Include="python.vcxproj;pythonw.vcxproj">
- <BuildInParallel>false</BuildInParallel>
- </Projects2>
+ <Projects2 Include="python.vcxproj;pythonw.vcxproj" />
</ItemGroup>
<Target Name="Build">
diff --git a/Python/ast.c b/Python/ast.c
index 82f4529bf91..217ea14bf31 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -4789,6 +4789,7 @@ ExprList_Finish(ExprList *l, PyArena *arena)
typedef struct {
PyObject *last_str;
ExprList expr_list;
+ int fmode;
} FstringParser;
#ifdef NDEBUG
@@ -4807,6 +4808,7 @@ static void
FstringParser_Init(FstringParser *state)
{
state->last_str = NULL;
+ state->fmode = 0;
ExprList_Init(&state->expr_list);
FstringParser_check_invariants(state);
}
@@ -4869,6 +4871,7 @@ FstringParser_ConcatFstring(FstringParser *state, const char **str,
struct compiling *c, const node *n)
{
FstringParser_check_invariants(state);
+ state->fmode = 1;
/* Parse the f-string. */
while (1) {
@@ -4960,7 +4963,8 @@ FstringParser_Finish(FstringParser *state, struct compiling *c,
/* If we're just a constant string with no expressions, return
that. */
- if(state->expr_list.size == 0) {
+ if (!state->fmode) {
+ assert(!state->expr_list.size);
if (!state->last_str) {
/* Create a zero length string. */
state->last_str = PyUnicode_FromStringAndSize(NULL, 0);
@@ -4984,11 +4988,6 @@ FstringParser_Finish(FstringParser *state, struct compiling *c,
if (!seq)
goto error;
- /* If there's only one expression, return it. Otherwise, we need
- to join them together. */
- if (seq->size == 1)
- return seq->elements[0];
-
return JoinedStr(seq, LINENO(n), n->n_col_offset, c->c_arena);
error:
diff --git a/Python/compile.c b/Python/compile.c
index 35151cdd590..0e160758524 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -3415,7 +3415,8 @@ static int
compiler_joined_str(struct compiler *c, expr_ty e)
{
VISIT_SEQ(c, expr, e->v.JoinedStr.values);
- ADDOP_I(c, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values));
+ if (asdl_seq_LEN(e->v.JoinedStr.values) != 1)
+ ADDOP_I(c, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values));
return 1;
}
diff --git a/Python/errors.c b/Python/errors.c
index 7b25a2202c2..fd6c42fd27f 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -1059,16 +1059,15 @@ PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset)
PyErr_Clear();
Py_DECREF(tmp);
}
+ tmp = NULL;
if (col_offset >= 0) {
tmp = PyLong_FromLong(col_offset);
if (tmp == NULL)
PyErr_Clear();
- else {
- if (_PyObject_SetAttrId(v, &PyId_offset, tmp))
- PyErr_Clear();
- Py_DECREF(tmp);
- }
}
+ if (_PyObject_SetAttrId(v, &PyId_offset, tmp ? tmp : Py_None))
+ PyErr_Clear();
+ Py_XDECREF(tmp);
if (filename != NULL) {
if (_PyObject_SetAttrId(v, &PyId_filename, filename))
PyErr_Clear();
@@ -1080,9 +1079,6 @@ PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset)
Py_DECREF(tmp);
}
}
- if (_PyObject_SetAttrId(v, &PyId_offset, Py_None)) {
- PyErr_Clear();
- }
if (exc != PyExc_SyntaxError) {
if (!_PyObject_HasAttrId(v, &PyId_msg)) {
tmp = PyObject_Str(v);
diff --git a/Python/fileutils.c b/Python/fileutils.c
index 6a32c42c80a..e84d66e99a4 100644
--- a/Python/fileutils.c
+++ b/Python/fileutils.c
@@ -20,7 +20,7 @@ extern int winerror_to_errno(int);
#include <fcntl.h>
#endif /* HAVE_FCNTL_H */
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(__ANDROID__)
extern wchar_t* _Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size);
#endif
@@ -273,7 +273,7 @@ decode_ascii_surrogateescape(const char *arg, size_t *size)
wchar_t*
Py_DecodeLocale(const char* arg, size_t *size)
{
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(__ANDROID__)
wchar_t *wstr;
wstr = _Py_DecodeUTF8_surrogateescape(arg, strlen(arg));
if (size != NULL) {
@@ -406,7 +406,7 @@ oom:
if (size != NULL)
*size = (size_t)-1;
return NULL;
-#endif /* __APPLE__ */
+#endif /* __APPLE__ or __ANDROID__ */
}
/* Encode a wide character string to the locale encoding with the
@@ -424,7 +424,7 @@ oom:
char*
Py_EncodeLocale(const wchar_t *text, size_t *error_pos)
{
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(__ANDROID__)
Py_ssize_t len;
PyObject *unicode, *bytes = NULL;
char *cpath;
@@ -522,7 +522,7 @@ Py_EncodeLocale(const wchar_t *text, size_t *error_pos)
bytes = result;
}
return result;
-#endif /* __APPLE__ */
+#endif /* __APPLE__ or __ANDROID__ */
}
diff --git a/Python/importlib_external.h b/Python/importlib_external.h
index 1b767c5a9ba..2f40978fb78 100644
--- a/Python/importlib_external.h
+++ b/Python/importlib_external.h
@@ -2334,7 +2334,7 @@ const unsigned char _Py_M__importlib_external[] = {
111,111,116,115,116,114,97,112,32,109,111,100,117,108,101,46,
10,10,32,32,32,32,114,52,0,0,0,114,63,0,0,0,
218,8,98,117,105,108,116,105,110,115,114,140,0,0,0,90,
- 5,112,111,115,105,120,250,1,47,218,2,110,116,250,1,92,
+ 5,112,111,115,105,120,250,1,47,90,2,110,116,250,1,92,
99,1,0,0,0,0,0,0,0,2,0,0,0,3,0,0,
0,115,0,0,0,115,26,0,0,0,124,0,93,18,125,1,
116,0,124,1,131,1,100,0,107,2,86,0,1,0,113,2,
@@ -2376,61 +2376,58 @@ const unsigned char _Py_M__importlib_external[] = {
1,10,1,4,2,2,1,10,1,6,1,14,1,12,2,8,
1,12,1,12,1,18,3,2,1,14,1,16,2,10,1,12,
3,10,1,12,3,10,1,10,1,12,3,14,1,14,1,10,
- 1,10,1,10,1,114,32,1,0,0,99,1,0,0,0,0,
+ 1,10,1,10,1,114,31,1,0,0,99,1,0,0,0,0,
0,0,0,2,0,0,0,3,0,0,0,67,0,0,0,115,
- 72,0,0,0,116,0,124,0,131,1,1,0,116,1,131,0,
+ 50,0,0,0,116,0,124,0,131,1,1,0,116,1,131,0,
125,1,116,2,106,3,106,4,116,5,106,6,124,1,142,0,
- 103,1,131,1,1,0,116,7,106,8,100,1,107,2,114,56,
- 116,2,106,9,106,10,116,11,131,1,1,0,116,2,106,9,
- 106,10,116,12,131,1,1,0,100,2,83,0,41,3,122,41,
- 73,110,115,116,97,108,108,32,116,104,101,32,112,97,116,104,
- 45,98,97,115,101,100,32,105,109,112,111,114,116,32,99,111,
- 109,112,111,110,101,110,116,115,46,114,27,1,0,0,78,41,
- 13,114,32,1,0,0,114,159,0,0,0,114,8,0,0,0,
- 114,253,0,0,0,114,147,0,0,0,114,5,1,0,0,114,
- 18,1,0,0,114,3,0,0,0,114,109,0,0,0,218,9,
- 109,101,116,97,95,112,97,116,104,114,161,0,0,0,114,166,
- 0,0,0,114,248,0,0,0,41,2,114,31,1,0,0,90,
- 17,115,117,112,112,111,114,116,101,100,95,108,111,97,100,101,
- 114,115,114,4,0,0,0,114,4,0,0,0,114,6,0,0,
- 0,218,8,95,105,110,115,116,97,108,108,158,5,0,0,115,
- 12,0,0,0,0,2,8,1,6,1,20,1,10,1,12,1,
- 114,34,1,0,0,41,1,114,0,0,0,0,41,2,114,1,
- 0,0,0,114,2,0,0,0,41,1,114,49,0,0,0,41,
- 1,78,41,3,78,78,78,41,3,78,78,78,41,2,114,62,
- 0,0,0,114,62,0,0,0,41,1,78,41,1,78,41,58,
- 114,111,0,0,0,114,12,0,0,0,90,37,95,67,65,83,
- 69,95,73,78,83,69,78,83,73,84,73,86,69,95,80,76,
- 65,84,70,79,82,77,83,95,66,89,84,69,83,95,75,69,
- 89,114,11,0,0,0,114,13,0,0,0,114,19,0,0,0,
- 114,21,0,0,0,114,30,0,0,0,114,40,0,0,0,114,
- 41,0,0,0,114,45,0,0,0,114,46,0,0,0,114,48,
- 0,0,0,114,58,0,0,0,218,4,116,121,112,101,218,8,
- 95,95,99,111,100,101,95,95,114,142,0,0,0,114,17,0,
- 0,0,114,132,0,0,0,114,16,0,0,0,114,20,0,0,
- 0,90,17,95,82,65,87,95,77,65,71,73,67,95,78,85,
- 77,66,69,82,114,77,0,0,0,114,76,0,0,0,114,88,
- 0,0,0,114,78,0,0,0,90,23,68,69,66,85,71,95,
- 66,89,84,69,67,79,68,69,95,83,85,70,70,73,88,69,
- 83,90,27,79,80,84,73,77,73,90,69,68,95,66,89,84,
- 69,67,79,68,69,95,83,85,70,70,73,88,69,83,114,83,
- 0,0,0,114,89,0,0,0,114,95,0,0,0,114,99,0,
- 0,0,114,101,0,0,0,114,120,0,0,0,114,127,0,0,
- 0,114,139,0,0,0,114,145,0,0,0,114,148,0,0,0,
- 114,153,0,0,0,218,6,111,98,106,101,99,116,114,160,0,
- 0,0,114,165,0,0,0,114,166,0,0,0,114,181,0,0,
- 0,114,191,0,0,0,114,207,0,0,0,114,215,0,0,0,
- 114,220,0,0,0,114,226,0,0,0,114,221,0,0,0,114,
- 227,0,0,0,114,246,0,0,0,114,248,0,0,0,114,5,
- 1,0,0,114,23,1,0,0,114,159,0,0,0,114,32,1,
- 0,0,114,34,1,0,0,114,4,0,0,0,114,4,0,0,
- 0,114,4,0,0,0,114,6,0,0,0,218,8,60,109,111,
- 100,117,108,101,62,8,0,0,0,115,108,0,0,0,4,16,
- 4,1,4,1,2,1,6,3,8,17,8,5,8,5,8,6,
- 8,12,8,10,8,9,8,5,8,7,10,22,10,123,16,1,
- 12,2,4,1,4,2,6,2,6,2,8,2,16,45,8,34,
- 8,19,8,12,8,12,8,28,8,17,10,55,10,12,10,10,
- 8,14,6,3,4,1,14,67,14,64,14,29,16,110,14,41,
- 18,45,18,16,4,3,18,53,14,60,14,42,14,127,0,5,
- 14,127,0,22,10,23,8,11,8,68,
+ 103,1,131,1,1,0,116,2,106,7,106,8,116,9,131,1,
+ 1,0,100,1,83,0,41,2,122,41,73,110,115,116,97,108,
+ 108,32,116,104,101,32,112,97,116,104,45,98,97,115,101,100,
+ 32,105,109,112,111,114,116,32,99,111,109,112,111,110,101,110,
+ 116,115,46,78,41,10,114,31,1,0,0,114,159,0,0,0,
+ 114,8,0,0,0,114,253,0,0,0,114,147,0,0,0,114,
+ 5,1,0,0,114,18,1,0,0,218,9,109,101,116,97,95,
+ 112,97,116,104,114,161,0,0,0,114,248,0,0,0,41,2,
+ 114,30,1,0,0,90,17,115,117,112,112,111,114,116,101,100,
+ 95,108,111,97,100,101,114,115,114,4,0,0,0,114,4,0,
+ 0,0,114,6,0,0,0,218,8,95,105,110,115,116,97,108,
+ 108,158,5,0,0,115,8,0,0,0,0,2,8,1,6,1,
+ 20,1,114,33,1,0,0,41,1,114,0,0,0,0,41,2,
+ 114,1,0,0,0,114,2,0,0,0,41,1,114,49,0,0,
+ 0,41,1,78,41,3,78,78,78,41,3,78,78,78,41,2,
+ 114,62,0,0,0,114,62,0,0,0,41,1,78,41,1,78,
+ 41,58,114,111,0,0,0,114,12,0,0,0,90,37,95,67,
+ 65,83,69,95,73,78,83,69,78,83,73,84,73,86,69,95,
+ 80,76,65,84,70,79,82,77,83,95,66,89,84,69,83,95,
+ 75,69,89,114,11,0,0,0,114,13,0,0,0,114,19,0,
+ 0,0,114,21,0,0,0,114,30,0,0,0,114,40,0,0,
+ 0,114,41,0,0,0,114,45,0,0,0,114,46,0,0,0,
+ 114,48,0,0,0,114,58,0,0,0,218,4,116,121,112,101,
+ 218,8,95,95,99,111,100,101,95,95,114,142,0,0,0,114,
+ 17,0,0,0,114,132,0,0,0,114,16,0,0,0,114,20,
+ 0,0,0,90,17,95,82,65,87,95,77,65,71,73,67,95,
+ 78,85,77,66,69,82,114,77,0,0,0,114,76,0,0,0,
+ 114,88,0,0,0,114,78,0,0,0,90,23,68,69,66,85,
+ 71,95,66,89,84,69,67,79,68,69,95,83,85,70,70,73,
+ 88,69,83,90,27,79,80,84,73,77,73,90,69,68,95,66,
+ 89,84,69,67,79,68,69,95,83,85,70,70,73,88,69,83,
+ 114,83,0,0,0,114,89,0,0,0,114,95,0,0,0,114,
+ 99,0,0,0,114,101,0,0,0,114,120,0,0,0,114,127,
+ 0,0,0,114,139,0,0,0,114,145,0,0,0,114,148,0,
+ 0,0,114,153,0,0,0,218,6,111,98,106,101,99,116,114,
+ 160,0,0,0,114,165,0,0,0,114,166,0,0,0,114,181,
+ 0,0,0,114,191,0,0,0,114,207,0,0,0,114,215,0,
+ 0,0,114,220,0,0,0,114,226,0,0,0,114,221,0,0,
+ 0,114,227,0,0,0,114,246,0,0,0,114,248,0,0,0,
+ 114,5,1,0,0,114,23,1,0,0,114,159,0,0,0,114,
+ 31,1,0,0,114,33,1,0,0,114,4,0,0,0,114,4,
+ 0,0,0,114,4,0,0,0,114,6,0,0,0,218,8,60,
+ 109,111,100,117,108,101,62,8,0,0,0,115,108,0,0,0,
+ 4,16,4,1,4,1,2,1,6,3,8,17,8,5,8,5,
+ 8,6,8,12,8,10,8,9,8,5,8,7,10,22,10,123,
+ 16,1,12,2,4,1,4,2,6,2,6,2,8,2,16,45,
+ 8,34,8,19,8,12,8,12,8,28,8,17,10,55,10,12,
+ 10,10,8,14,6,3,4,1,14,67,14,64,14,29,16,110,
+ 14,41,18,45,18,16,4,3,18,53,14,60,14,42,14,127,
+ 0,5,14,127,0,22,10,23,8,11,8,68,
};
diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py
index e4d2c1ec4c3..798b062c6bc 100755
--- a/Tools/gdb/libpython.py
+++ b/Tools/gdb/libpython.py
@@ -1492,23 +1492,38 @@ class Frame(object):
'''
if self.is_waiting_for_gil():
return 'Waiting for the GIL'
- elif self.is_gc_collect():
+
+ if self.is_gc_collect():
return 'Garbage-collecting'
- else:
- # Detect invocations of PyCFunction instances:
- older = self.older()
- if older and older._gdbframe.name() == 'PyCFunction_Call':
- # Within that frame:
- # "func" is the local containing the PyObject* of the
- # PyCFunctionObject instance
- # "f" is the same value, but cast to (PyCFunctionObject*)
- # "self" is the (PyObject*) of the 'self'
- try:
- # Use the prettyprinter for the func:
- func = older._gdbframe.read_var('func')
- return str(func)
- except RuntimeError:
- return 'PyCFunction invocation (unable to read "func")'
+
+ # Detect invocations of PyCFunction instances:
+ older = self.older()
+ if not older:
+ return False
+
+ caller = older._gdbframe.name()
+ if not caller:
+ return False
+
+ if caller == 'PyCFunction_Call':
+ # Within that frame:
+ # "func" is the local containing the PyObject* of the
+ # PyCFunctionObject instance
+ # "f" is the same value, but cast to (PyCFunctionObject*)
+ # "self" is the (PyObject*) of the 'self'
+ try:
+ # Use the prettyprinter for the func:
+ func = older._gdbframe.read_var('func')
+ return str(func)
+ except RuntimeError:
+ return 'PyCFunction invocation (unable to read "func")'
+
+ elif caller == '_PyCFunction_FastCallDict':
+ try:
+ func = older._gdbframe.read_var('func_obj')
+ return str(func)
+ except RuntimeError:
+ return 'PyCFunction invocation (unable to read "func_obj")'
# This frame isn't worth reporting:
return False
diff --git a/configure b/configure
index cf95b2705a9..43f342e6fc2 100755
--- a/configure
+++ b/configure
@@ -5218,29 +5218,7 @@ cat >> conftest.c <<EOF
#undef sparc
#undef unix
#if defined(__ANDROID__)
-# if defined(__x86_64__) && defined(__LP64__)
- x86_64-linux-android
-# elif defined(__i386__)
- i686-linux-android
-# elif defined(__aarch64__) && defined(__AARCH64EL__)
-# if defined(__ILP32__)
- aarch64_ilp32-linux-android
-# else
- aarch64-linux-android
-# endif
-# elif defined(__ARM_EABI__) && defined(__ARMEL__)
- arm-linux-androideabi
-# elif defined(__mips_hard_float) && defined(_MIPSEL)
-# if _MIPS_SIM == _ABIO32
- mipsel-linux-android
-# elif _MIPS_SIM == _ABI64
- mips64el-linux-android
-# else
-# error unknown platform triplet
-# endif
-# else
-# error unknown platform triplet
-# endif
+ # Android is not a multiarch system.
#elif defined(__linux__)
# if defined(__x86_64__) && defined(__LP64__)
x86_64-linux-gnu
@@ -15712,7 +15690,9 @@ fi
# first curses header check
ac_save_cppflags="$CPPFLAGS"
-CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw"
+if test "$cross_compiling" = no; then
+ CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw"
+fi
for ac_header in curses.h ncurses.h
do :
diff --git a/configure.ac b/configure.ac
index 1d63813977e..af540923ac3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -770,29 +770,7 @@ cat >> conftest.c <<EOF
#undef sparc
#undef unix
#if defined(__ANDROID__)
-# if defined(__x86_64__) && defined(__LP64__)
- x86_64-linux-android
-# elif defined(__i386__)
- i686-linux-android
-# elif defined(__aarch64__) && defined(__AARCH64EL__)
-# if defined(__ILP32__)
- aarch64_ilp32-linux-android
-# else
- aarch64-linux-android
-# endif
-# elif defined(__ARM_EABI__) && defined(__ARMEL__)
- arm-linux-androideabi
-# elif defined(__mips_hard_float) && defined(_MIPSEL)
-# if _MIPS_SIM == _ABIO32
- mipsel-linux-android
-# elif _MIPS_SIM == _ABI64
- mips64el-linux-android
-# else
-# error unknown platform triplet
-# endif
-# else
-# error unknown platform triplet
-# endif
+ # Android is not a multiarch system.
#elif defined(__linux__)
# if defined(__x86_64__) && defined(__LP64__)
x86_64-linux-gnu
@@ -4907,7 +4885,9 @@ fi
# first curses header check
ac_save_cppflags="$CPPFLAGS"
-CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw"
+if test "$cross_compiling" = no; then
+ CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw"
+fi
AC_CHECK_HEADERS(curses.h ncurses.h)
diff --git a/setup.py b/setup.py
index af9a414f7d7..d218722e0e6 100644
--- a/setup.py
+++ b/setup.py
@@ -532,8 +532,9 @@ class PyBuildExt(build_ext):
for directory in reversed(options.dirs):
add_dir_to_list(dir_list, directory)
- if os.path.normpath(sys.base_prefix) != '/usr' \
- and not sysconfig.get_config_var('PYTHONFRAMEWORK'):
+ if (not cross_compiling and
+ os.path.normpath(sys.base_prefix) != '/usr' and
+ not sysconfig.get_config_var('PYTHONFRAMEWORK')):
# OSX note: Don't add LIBDIR and INCLUDEDIR to building a framework
# (PYTHONFRAMEWORK is set) to avoid # linking problems when
# building a framework with different architectures than
@@ -1349,7 +1350,8 @@ class PyBuildExt(build_ext):
panel_library = 'panel'
if curses_library == 'ncursesw':
curses_defines.append(('HAVE_NCURSESW', '1'))
- curses_includes.append('/usr/include/ncursesw')
+ if not cross_compiling:
+ curses_includes.append('/usr/include/ncursesw')
# Bug 1464056: If _curses.so links with ncursesw,
# _curses_panel.so must link with panelw.
panel_library = 'panelw'
@@ -1630,7 +1632,7 @@ class PyBuildExt(build_ext):
## ext = Extension('xx', ['xxmodule.c'])
## self.extensions.append(ext)
- if 'd' not in sys.abiflags:
+ if 'd' not in sysconfig.get_config_var('ABIFLAGS'):
ext = Extension('xxlimited', ['xxlimited.c'],
define_macros=[('Py_LIMITED_API', '0x03050000')])
self.extensions.append(ext)