Update Python3

This commit is contained in:
PiotrVV
2017-06-04 17:52:17 +02:00
parent db3a8ee037
commit a32ed5f931
40 changed files with 2761 additions and 183 deletions

View File

@@ -1,6 +1,6 @@
--- Python-3.4.3/setup.py.orig 2015-02-25 05:27:46.000000000 -0600
+++ Python-3.4.3/setup.py 2015-05-05 11:18:04.030880000 -0500
@@ -1165,7 +1165,7 @@ class PyBuildExt(build_ext):
@@ -1241,7 +1241,7 @@ class PyBuildExt(build_ext):
dbm_setup_debug = False # verbose debug prints from this script?
dbm_order = ['gdbm']
# The standard Unix dbm module:
@@ -9,7 +9,7 @@
config_args = [arg.strip("'")
for arg in sysconfig.get_config_var("CONFIG_ARGS").split()]
dbm_args = [arg for arg in config_args
@@ -1220,6 +1220,15 @@ class PyBuildExt(build_ext):
@@ -1296,6 +1296,15 @@ class PyBuildExt(build_ext):
],
libraries = gdbm_libs)
break

View File

@@ -0,0 +1,640 @@
diff --git a/Lib/hashlib.py b/Lib/hashlib.py
index 316cece..b7ad879 100644
--- a/Lib/hashlib.py
+++ b/Lib/hashlib.py
@@ -24,6 +24,16 @@ the zlib module.
Choose your hash function wisely. Some have known collision weaknesses.
sha384 and sha512 will be slow on 32 bit platforms.
+If the underlying implementation supports "FIPS mode", and this is enabled, it
+may restrict the available hashes to only those that are compliant with FIPS
+regulations. For example, it may deny the use of MD5, on the grounds that this
+is not secure for uses such as authentication, system integrity checking, or
+digital signatures. If you need to use such a hash for non-security purposes
+(such as indexing into a data structure for speed), you can override the keyword
+argument "usedforsecurity" from True to False to signify that your code is not
+relying on the hash for security purposes, and this will allow the hash to be
+usable even in FIPS mode.
+
Hash objects have these methods:
- update(arg): Update the hash object with the bytes in arg. Repeated calls
are equivalent to a single call with the concatenation of all
@@ -67,6 +77,18 @@ algorithms_available = set(__always_supported)
__all__ = __always_supported + ('new', 'algorithms_guaranteed',
'algorithms_available', 'pbkdf2_hmac')
+import functools
+def __ignore_usedforsecurity(func):
+ """Used for sha3_* functions. Until OpenSSL implements them, we want
+ to use them from Python _sha3 module, but we want them to accept
+ usedforsecurity argument too."""
+ # TODO: remove this function when OpenSSL implements sha3
+ @functools.wraps(func)
+ def inner(*args, **kwargs):
+ if 'usedforsecurity' in kwargs:
+ kwargs.pop('usedforsecurity')
+ return func(*args, **kwargs)
+ return inner
__builtin_constructor_cache = {}
@@ -100,31 +122,39 @@ def __get_openssl_constructor(name):
f = getattr(_hashlib, 'openssl_' + name)
# Allow the C module to raise ValueError. The function will be
# defined but the hash not actually available thanks to OpenSSL.
- f()
+ # We pass "usedforsecurity=False" to disable FIPS-based restrictions:
+ # at this stage we're merely seeing if the function is callable,
+ # rather than using it for actual work.
+ f(usedforsecurity=False)
# Use the C function directly (very fast)
return f
except (AttributeError, ValueError):
+ # TODO: We want to just raise here when OpenSSL implements sha3
+ # because we want to make sure that Fedora uses everything from OpenSSL
return __get_builtin_constructor(name)
-def __py_new(name, data=b''):
- """new(name, data=b'') - Return a new hashing object using the named algorithm;
- optionally initialized with data (which must be bytes).
+def __py_new(name, data=b'', usedforsecurity=True):
+ """new(name, data=b'', usedforsecurity=True) - Return a new hashing object using
+ the named algorithm; optionally initialized with data (which must be bytes).
+ The 'usedforsecurity' keyword argument does nothing, and is for compatibilty
+ with the OpenSSL implementation
"""
return __get_builtin_constructor(name)(data)
-def __hash_new(name, data=b''):
- """new(name, data=b'') - Return a new hashing object using the named algorithm;
- optionally initialized with data (which must be bytes).
+def __hash_new(name, data=b'', usedforsecurity=True):
+ """new(name, data=b'', usedforsecurity=True) - Return a new hashing object using
+ the named algorithm; optionally initialized with data (which must be bytes).
+
+ Override 'usedforsecurity' to False when using for non-security purposes in
+ a FIPS environment
"""
try:
- return _hashlib.new(name, data)
+ return _hashlib.new(name, data, usedforsecurity)
except ValueError:
- # If the _hashlib module (OpenSSL) doesn't support the named
- # hash, try using our builtin implementations.
- # This allows for SHA224/256 and SHA384/512 support even though
- # the OpenSSL library prior to 0.9.8 doesn't provide them.
+ # TODO: We want to just raise here when OpenSSL implements sha3
+ # because we want to make sure that Fedora uses everything from OpenSSL
return __get_builtin_constructor(name)(data)
@@ -207,7 +237,10 @@ for __func_name in __always_supported:
# try them all, some may not work due to the OpenSSL
# version not supporting that algorithm.
try:
- globals()[__func_name] = __get_hash(__func_name)
+ func = __get_hash(__func_name)
+ if 'sha3_' in __func_name:
+ func = __ignore_usedforsecurity(func)
+ globals()[__func_name] = func
except ValueError:
import logging
logging.exception('code for hash %s was not found.', __func_name)
@@ -215,3 +248,4 @@ for __func_name in __always_supported:
# Cleanup locals()
del __always_supported, __func_name, __get_hash
del __py_new, __hash_new, __get_openssl_constructor
+del __ignore_usedforsecurity
\ No newline at end of file
diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py
index c9b113e..60e2392 100644
--- a/Lib/test/test_hashlib.py
+++ b/Lib/test/test_hashlib.py
@@ -24,7 +24,22 @@ from test.support import _4G, bigmemtest, import_fresh_module
COMPILED_WITH_PYDEBUG = hasattr(sys, 'gettotalrefcount')
c_hashlib = import_fresh_module('hashlib', fresh=['_hashlib'])
-py_hashlib = import_fresh_module('hashlib', blocked=['_hashlib'])
+# skipped on Fedora, since we always use OpenSSL implementation
+# py_hashlib = import_fresh_module('hashlib', blocked=['_hashlib'])
+
+def openssl_enforces_fips():
+ # Use the "openssl" command (if present) to try to determine if the local
+ # OpenSSL is configured to enforce FIPS
+ from subprocess import Popen, PIPE
+ try:
+ p = Popen(['openssl', 'md5'],
+ stdin=PIPE, stdout=PIPE, stderr=PIPE)
+ except OSError:
+ # "openssl" command not found
+ return False
+ stdout, stderr = p.communicate(input=b'abc')
+ return b'unknown cipher' in stderr
+OPENSSL_ENFORCES_FIPS = openssl_enforces_fips()
def hexstr(s):
assert isinstance(s, bytes), repr(s)
@@ -34,6 +49,16 @@ def hexstr(s):
r += h[(i >> 4) & 0xF] + h[i & 0xF]
return r
+# hashlib and _hashlib-based functions support a "usedforsecurity" keyword
+# argument, and FIPS mode requires that it be used overridden with a False
+# value for these selftests to work. Other cryptographic code within Python
+# doesn't support this keyword.
+# Modify a function to one in which "usedforsecurity=False" is added to the
+# keyword arguments:
+def suppress_fips(f):
+ def g(*args, **kwargs):
+ return f(*args, usedforsecurity=False, **kwargs)
+ return g
class HashLibTestCase(unittest.TestCase):
supported_hash_names = ( 'md5', 'MD5', 'sha1', 'SHA1',
@@ -63,11 +88,11 @@ class HashLibTestCase(unittest.TestCase):
# For each algorithm, test the direct constructor and the use
# of hashlib.new given the algorithm name.
for algorithm, constructors in self.constructors_to_test.items():
- constructors.add(getattr(hashlib, algorithm))
+ constructors.add(suppress_fips(getattr(hashlib, algorithm)))
def _test_algorithm_via_hashlib_new(data=None, _alg=algorithm):
if data is None:
- return hashlib.new(_alg)
- return hashlib.new(_alg, data)
+ return suppress_fips(hashlib.new)(_alg)
+ return suppress_fips(hashlib.new)(_alg, data)
constructors.add(_test_algorithm_via_hashlib_new)
_hashlib = self._conditional_import_module('_hashlib')
@@ -79,27 +104,12 @@ class HashLibTestCase(unittest.TestCase):
for algorithm, constructors in self.constructors_to_test.items():
constructor = getattr(_hashlib, 'openssl_'+algorithm, None)
if constructor:
- constructors.add(constructor)
+ constructors.add(suppress_fips(constructor))
def add_builtin_constructor(name):
constructor = getattr(hashlib, "__get_builtin_constructor")(name)
self.constructors_to_test[name].add(constructor)
- _md5 = self._conditional_import_module('_md5')
- if _md5:
- add_builtin_constructor('md5')
- _sha1 = self._conditional_import_module('_sha1')
- if _sha1:
- add_builtin_constructor('sha1')
- _sha256 = self._conditional_import_module('_sha256')
- if _sha256:
- add_builtin_constructor('sha224')
- add_builtin_constructor('sha256')
- _sha512 = self._conditional_import_module('_sha512')
- if _sha512:
- add_builtin_constructor('sha384')
- add_builtin_constructor('sha512')
-
super(HashLibTestCase, self).__init__(*args, **kwargs)
@property
@@ -148,9 +158,6 @@ class HashLibTestCase(unittest.TestCase):
else:
del sys.modules['_md5']
self.assertRaises(TypeError, get_builtin_constructor, 3)
- constructor = get_builtin_constructor('md5')
- self.assertIs(constructor, _md5.md5)
- self.assertEqual(sorted(builtin_constructor_cache), ['MD5', 'md5'])
def test_hexdigest(self):
for cons in self.hash_constructors:
@@ -433,6 +440,64 @@ class HashLibTestCase(unittest.TestCase):
self.assertEqual(expected_hash, hasher.hexdigest())
+ def test_issue9146(self):
+ # Ensure that various ways to use "MD5" from "hashlib" don't segfault:
+ m = hashlib.md5(usedforsecurity=False)
+ m.update(b'abc\n')
+ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1")
+
+ m = hashlib.new('md5', usedforsecurity=False)
+ m.update(b'abc\n')
+ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1")
+
+ m = hashlib.md5(b'abc\n', usedforsecurity=False)
+ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1")
+
+ m = hashlib.new('md5', b'abc\n', usedforsecurity=False)
+ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1")
+
+ @unittest.skipUnless(OPENSSL_ENFORCES_FIPS,
+ 'FIPS enforcement required for this test.')
+ def test_hashlib_fips_mode(self):
+ # Ensure that we raise a ValueError on vanilla attempts to use MD5
+ # in hashlib in a FIPS-enforced setting:
+ with self.assertRaisesRegexp(ValueError, '.*unknown cipher'):
+ m = hashlib.md5()
+
+ if not self._conditional_import_module('_md5'):
+ with self.assertRaisesRegexp(ValueError, '.*unknown cipher'):
+ m = hashlib.new('md5')
+
+ @unittest.skipUnless(OPENSSL_ENFORCES_FIPS,
+ 'FIPS enforcement required for this test.')
+ def test_hashopenssl_fips_mode(self):
+ # Verify the _hashlib module's handling of md5:
+ _hashlib = self._conditional_import_module('_hashlib')
+ if _hashlib:
+ assert hasattr(_hashlib, 'openssl_md5')
+
+ # Ensure that _hashlib raises a ValueError on vanilla attempts to
+ # use MD5 in a FIPS-enforced setting:
+ with self.assertRaisesRegexp(ValueError, '.*unknown cipher'):
+ m = _hashlib.openssl_md5()
+ with self.assertRaisesRegexp(ValueError, '.*unknown cipher'):
+ m = _hashlib.new('md5')
+
+ # Ensure that in such a setting we can whitelist a callsite with
+ # usedforsecurity=False and have it succeed:
+ m = _hashlib.openssl_md5(usedforsecurity=False)
+ m.update(b'abc\n')
+ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1")
+
+ m = _hashlib.new('md5', usedforsecurity=False)
+ m.update(b'abc\n')
+ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1")
+
+ m = _hashlib.openssl_md5(b'abc\n', usedforsecurity=False)
+ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1")
+
+ m = _hashlib.new('md5', b'abc\n', usedforsecurity=False)
+ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1")
class KDFTests(unittest.TestCase):
@@ -516,7 +581,7 @@ class KDFTests(unittest.TestCase):
out = pbkdf2(hash_name='sha1', password=b'password', salt=b'salt',
iterations=1, dklen=None)
self.assertEqual(out, self.pbkdf2_results['sha1'][0][0])
-
+ @unittest.skip('skipped on Fedora, as we always use OpenSSL pbkdf2_hmac')
def test_pbkdf2_hmac_py(self):
self._test_pbkdf2_hmac(py_hashlib.pbkdf2_hmac)
diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c
index 44765ac..b8cf490 100644
--- a/Modules/_hashopenssl.c
+++ b/Modules/_hashopenssl.c
@@ -20,6 +20,8 @@
/* EVP is the preferred interface to hashing in OpenSSL */
+#include <openssl/ssl.h>
+#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
/* We use the object interface to discover what hashes OpenSSL supports. */
@@ -45,11 +47,19 @@ typedef struct {
static PyTypeObject EVPtype;
+/* Struct to hold all the cached information we need on a specific algorithm.
+ We have one of these per algorithm */
+typedef struct {
+ PyObject *name_obj;
+ EVP_MD_CTX ctxs[2];
+ /* ctx_ptrs will point to ctxs unless an error occurred, when it will
+ be NULL: */
+ EVP_MD_CTX *ctx_ptrs[2];
+ PyObject *error_msgs[2];
+} EVPCachedInfo;
-#define DEFINE_CONSTS_FOR_NEW(Name) \
- static PyObject *CONST_ ## Name ## _name_obj = NULL; \
- static EVP_MD_CTX CONST_new_ ## Name ## _ctx; \
- static EVP_MD_CTX *CONST_new_ ## Name ## _ctx_p = NULL;
+#define DEFINE_CONSTS_FOR_NEW(Name) \
+ static EVPCachedInfo cached_info_ ##Name;
DEFINE_CONSTS_FOR_NEW(md5)
DEFINE_CONSTS_FOR_NEW(sha1)
@@ -92,6 +102,48 @@ EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len)
}
}
+static void
+mc_ctx_init(EVP_MD_CTX *ctx, int usedforsecurity)
+{
+ EVP_MD_CTX_init(ctx);
+
+ /*
+ If the user has declared that this digest is being used in a
+ non-security role (e.g. indexing into a data structure), set
+ the exception flag for openssl to allow it
+ */
+ if (!usedforsecurity) {
+#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
+ EVP_MD_CTX_set_flags(ctx,
+ EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+#endif
+ }
+}
+
+/* Get an error msg for the last error as a PyObject */
+static PyObject *
+error_msg_for_last_error(void)
+{
+ char *errstr;
+
+ errstr = ERR_error_string(ERR_peek_last_error(), NULL);
+ ERR_clear_error();
+
+ return PyUnicode_FromString(errstr); /* Can be NULL */
+}
+
+static void
+set_evp_exception(void)
+{
+ char *errstr;
+
+ errstr = ERR_error_string(ERR_peek_last_error(), NULL);
+ ERR_clear_error();
+
+ PyErr_SetString(PyExc_ValueError, errstr);
+}
+
+
/* Internal methods for a hash object */
static void
@@ -259,15 +311,16 @@ EVP_repr(EVPobject *self)
static int
EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
{
- static char *kwlist[] = {"name", "string", NULL};
+ static char *kwlist[] = {"name", "string", "usedforsecurity", NULL};
PyObject *name_obj = NULL;
PyObject *data_obj = NULL;
+ int usedforsecurity = 1;
Py_buffer view;
char *nameStr;
const EVP_MD *digest;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:HASH", kwlist,
- &name_obj, &data_obj)) {
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|Oi:HASH", kwlist,
+ &name_obj, &data_obj, &usedforsecurity)) {
return -1;
}
@@ -288,7 +341,12 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
PyBuffer_Release(&view);
return -1;
}
- EVP_DigestInit(&self->ctx, digest);
+ mc_ctx_init(&self->ctx, usedforsecurity);
+ if (!EVP_DigestInit_ex(&self->ctx, digest, NULL)) {
+ set_evp_exception();
+ PyBuffer_Release(&view);
+ return -1;
+ }
self->name = name_obj;
Py_INCREF(self->name);
@@ -372,7 +430,8 @@ static PyTypeObject EVPtype = {
static PyObject *
EVPnew(PyObject *name_obj,
const EVP_MD *digest, const EVP_MD_CTX *initial_ctx,
- const unsigned char *cp, Py_ssize_t len)
+ const unsigned char *cp, Py_ssize_t len,
+ int usedforsecurity)
{
EVPobject *self;
@@ -387,7 +446,12 @@ EVPnew(PyObject *name_obj,
if (initial_ctx) {
EVP_MD_CTX_copy(&self->ctx, initial_ctx);
} else {
- EVP_DigestInit(&self->ctx, digest);
+ mc_ctx_init(&self->ctx, usedforsecurity);
+ if (!EVP_DigestInit_ex(&self->ctx, digest, NULL)) {
+ set_evp_exception();
+ Py_DECREF(self);
+ return NULL;
+ }
}
if (cp && len) {
@@ -411,21 +475,29 @@ PyDoc_STRVAR(EVP_new__doc__,
An optional string argument may be provided and will be\n\
automatically hashed.\n\
\n\
-The MD5 and SHA1 algorithms are always supported.\n");
+The MD5 and SHA1 algorithms are always supported.\n\
+\n\
+An optional \"usedforsecurity=True\" keyword argument is provided for use in\n\
+environments that enforce FIPS-based restrictions. Some implementations of\n\
+OpenSSL can be configured to prevent the usage of non-secure algorithms (such\n\
+as MD5). If you have a non-security use for these algorithms (e.g. a hash\n\
+table), you can override this argument by marking the callsite as\n\
+\"usedforsecurity=False\".");
static PyObject *
EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
{
- static char *kwlist[] = {"name", "string", NULL};
+ static char *kwlist[] = {"name", "string", "usedforsecurity", NULL};
PyObject *name_obj = NULL;
PyObject *data_obj = NULL;
+ int usedforsecurity = 1;
Py_buffer view = { 0 };
PyObject *ret_obj;
char *name;
const EVP_MD *digest;
- if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O|O:new", kwlist,
- &name_obj, &data_obj)) {
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O|Oi:new", kwlist,
+ &name_obj, &data_obj, &usedforsecurity)) {
return NULL;
}
@@ -439,7 +511,8 @@ EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
digest = EVP_get_digestbyname(name);
- ret_obj = EVPnew(name_obj, digest, NULL, (unsigned char*)view.buf, view.len);
+ ret_obj = EVPnew(name_obj, digest, NULL, (unsigned char*)view.buf, view.len,
+ usedforsecurity);
if (data_obj)
PyBuffer_Release(&view);
@@ -722,57 +795,114 @@ generate_hash_name_list(void)
/*
- * This macro generates constructor function definitions for specific
- * hash algorithms. These constructors are much faster than calling
- * the generic one passing it a python string and are noticably
- * faster than calling a python new() wrapper. Thats important for
+ * This macro and function generates a family of constructor function
+ * definitions for specific hash algorithms. These constructors are much
+ * faster than calling the generic one passing it a python string and are
+ * noticably faster than calling a python new() wrapper. That's important for
* code that wants to make hashes of a bunch of small strings.
*/
#define GEN_CONSTRUCTOR(NAME) \
static PyObject * \
- EVP_new_ ## NAME (PyObject *self, PyObject *args) \
+ EVP_new_ ## NAME (PyObject *self, PyObject *args, PyObject *kwdict) \
{ \
- PyObject *data_obj = NULL; \
- Py_buffer view = { 0 }; \
- PyObject *ret_obj; \
- \
- if (!PyArg_ParseTuple(args, "|O:" #NAME , &data_obj)) { \
- return NULL; \
- } \
- \
- if (data_obj) \
- GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view); \
- \
- ret_obj = EVPnew( \
- CONST_ ## NAME ## _name_obj, \
- NULL, \
- CONST_new_ ## NAME ## _ctx_p, \
- (unsigned char*)view.buf, \
- view.len); \
- \
- if (data_obj) \
- PyBuffer_Release(&view); \
- return ret_obj; \
+ return implement_specific_EVP_new(self, args, kwdict, \
+ "|Oi:" #NAME, \
+ &cached_info_ ## NAME ); \
}
+static PyObject *
+implement_specific_EVP_new(PyObject *self, PyObject *args, PyObject *kwdict,
+ const char *format,
+ EVPCachedInfo *cached_info)
+{
+ static char *kwlist[] = {"string", "usedforsecurity", NULL};
+ PyObject *data_obj = NULL;
+ Py_buffer view = { 0 };
+ int usedforsecurity = 1;
+ int idx;
+ PyObject *ret_obj = NULL;
+
+ assert(cached_info);
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, format, kwlist,
+ &data_obj, &usedforsecurity)) {
+ return NULL;
+ }
+
+ if (data_obj)
+ GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view);
+
+ idx = usedforsecurity ? 1 : 0;
+
+ /*
+ * If an error occurred during creation of the global content, the ctx_ptr
+ * will be NULL, and the error_msg will hopefully be non-NULL:
+ */
+ if (cached_info->ctx_ptrs[idx]) {
+ /* We successfully initialized this context; copy it: */
+ ret_obj = EVPnew(cached_info->name_obj,
+ NULL,
+ cached_info->ctx_ptrs[idx],
+ (unsigned char*)view.buf, view.len,
+ usedforsecurity);
+ } else {
+ /* Some kind of error happened initializing the global context for
+ this (digest, usedforsecurity) pair.
+ Raise an exception with the saved error message: */
+ if (cached_info->error_msgs[idx]) {
+ PyErr_SetObject(PyExc_ValueError, cached_info->error_msgs[idx]);
+ } else {
+ PyErr_SetString(PyExc_ValueError, "Error initializing hash");
+ }
+ }
+
+ if (data_obj)
+ PyBuffer_Release(&view);
+
+ return ret_obj;
+}
+
/* a PyMethodDef structure for the constructor */
#define CONSTRUCTOR_METH_DEF(NAME) \
- {"openssl_" #NAME, (PyCFunction)EVP_new_ ## NAME, METH_VARARGS, \
+ {"openssl_" #NAME, (PyCFunction)EVP_new_ ## NAME, \
+ METH_VARARGS|METH_KEYWORDS, \
PyDoc_STR("Returns a " #NAME \
" hash object; optionally initialized with a string") \
}
-/* used in the init function to setup a constructor: initialize OpenSSL
- constructor constants if they haven't been initialized already. */
-#define INIT_CONSTRUCTOR_CONSTANTS(NAME) do { \
- if (CONST_ ## NAME ## _name_obj == NULL) { \
- CONST_ ## NAME ## _name_obj = PyUnicode_FromString(#NAME); \
- if (EVP_get_digestbyname(#NAME)) { \
- CONST_new_ ## NAME ## _ctx_p = &CONST_new_ ## NAME ## _ctx; \
- EVP_DigestInit(CONST_new_ ## NAME ## _ctx_p, EVP_get_digestbyname(#NAME)); \
- } \
- } \
+/*
+ Macro/function pair to set up the constructors.
+
+ Try to initialize a context for each hash twice, once with
+ EVP_MD_CTX_FLAG_NON_FIPS_ALLOW and once without.
+
+ Any that have errors during initialization will end up with a NULL ctx_ptrs
+ entry, and err_msgs will be set (unless we're very low on memory)
+*/
+#define INIT_CONSTRUCTOR_CONSTANTS(NAME) do { \
+ init_constructor_constant(&cached_info_ ## NAME, #NAME); \
} while (0);
+static void
+init_constructor_constant(EVPCachedInfo *cached_info, const char *name)
+{
+ assert(cached_info);
+ cached_info->name_obj = PyUnicode_FromString(name);
+ if (EVP_get_digestbyname(name)) {
+ int i;
+ for (i=0; i<2; i++) {
+ mc_ctx_init(&cached_info->ctxs[i], i);
+ if (EVP_DigestInit_ex(&cached_info->ctxs[i],
+ EVP_get_digestbyname(name), NULL)) {
+ /* Success: */
+ cached_info->ctx_ptrs[i] = &cached_info->ctxs[i];
+ } else {
+ /* Failure: */
+ cached_info->ctx_ptrs[i] = NULL;
+ cached_info->error_msgs[i] = error_msg_for_last_error();
+ }
+ }
+ }
+}
GEN_CONSTRUCTOR(md5)
GEN_CONSTRUCTOR(sha1)
@@ -819,13 +949,10 @@ PyInit__hashlib(void)
{
PyObject *m, *openssl_md_meth_names;
- OpenSSL_add_all_digests();
- ERR_load_crypto_strings();
+ SSL_load_error_strings();
+ SSL_library_init();
- /* TODO build EVP_functions openssl_* entries dynamically based
- * on what hashes are supported rather than listing many
- * but having some be unsupported. Only init appropriate
- * constants. */
+ OpenSSL_add_all_digests();
Py_TYPE(&EVPtype) = &PyType_Type;
if (PyType_Ready(&EVPtype) < 0)

View File

@@ -0,0 +1,15 @@
diff -up Python-3.2.3/Lib/ctypes/__init__.py.rhbz814391 Python-3.2.3/Lib/ctypes/__init__.py
--- Python-3.2.3/Lib/ctypes/__init__.py.rhbz814391 2012-04-20 15:12:49.017867692 -0400
+++ Python-3.2.3/Lib/ctypes/__init__.py 2012-04-20 15:15:09.501111408 -0400
@@ -266,11 +266,6 @@ def _reset_cache():
# _SimpleCData.c_char_p_from_param
POINTER(c_char).from_param = c_char_p.from_param
_pointer_type_cache[None] = c_void_p
- # XXX for whatever reasons, creating the first instance of a callback
- # function is needed for the unittests on Win64 to succeed. This MAY
- # be a compiler bug, since the problem occurs only when _ctypes is
- # compiled with the MS SDK compiler. Or an uninitialized variable?
- CFUNCTYPE(c_int)(lambda: None)
def create_unicode_buffer(init, size=None):
"""create_unicode_buffer(aString) -> character array

View File

@@ -0,0 +1,68 @@
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index e9fdb07..ea60e6e 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -1723,30 +1723,36 @@ class PosixUidGidTests(unittest.TestCase):
def test_setuid(self):
if os.getuid() != 0:
self.assertRaises(OSError, os.setuid, 0)
+ self.assertRaises(TypeError, os.setuid, 'not an int')
self.assertRaises(OverflowError, os.setuid, 1<<32)
@unittest.skipUnless(hasattr(os, 'setgid'), 'test needs os.setgid()')
def test_setgid(self):
if os.getuid() != 0 and not HAVE_WHEEL_GROUP:
self.assertRaises(OSError, os.setgid, 0)
+ self.assertRaises(TypeError, os.setgid, 'not an int')
self.assertRaises(OverflowError, os.setgid, 1<<32)
@unittest.skipUnless(hasattr(os, 'seteuid'), 'test needs os.seteuid()')
def test_seteuid(self):
if os.getuid() != 0:
self.assertRaises(OSError, os.seteuid, 0)
+ self.assertRaises(TypeError, os.seteuid, 'not an int')
self.assertRaises(OverflowError, os.seteuid, 1<<32)
@unittest.skipUnless(hasattr(os, 'setegid'), 'test needs os.setegid()')
def test_setegid(self):
if os.getuid() != 0 and not HAVE_WHEEL_GROUP:
self.assertRaises(OSError, os.setegid, 0)
+ self.assertRaises(TypeError, os.setegid, 'not an int')
self.assertRaises(OverflowError, os.setegid, 1<<32)
@unittest.skipUnless(hasattr(os, 'setreuid'), 'test needs os.setreuid()')
def test_setreuid(self):
if os.getuid() != 0:
self.assertRaises(OSError, os.setreuid, 0, 0)
+ self.assertRaises(TypeError, os.setreuid, 'not an int', 0)
+ self.assertRaises(TypeError, os.setreuid, 0, 'not an int')
self.assertRaises(OverflowError, os.setreuid, 1<<32, 0)
self.assertRaises(OverflowError, os.setreuid, 0, 1<<32)
@@ -1762,6 +1768,8 @@ class PosixUidGidTests(unittest.TestCase):
def test_setregid(self):
if os.getuid() != 0 and not HAVE_WHEEL_GROUP:
self.assertRaises(OSError, os.setregid, 0, 0)
+ self.assertRaises(TypeError, os.setregid, 'not an int', 0)
+ self.assertRaises(TypeError, os.setregid, 0, 'not an int')
self.assertRaises(OverflowError, os.setregid, 1<<32, 0)
self.assertRaises(OverflowError, os.setregid, 0, 1<<32)
diff --git a/Lib/test/test_pwd.py b/Lib/test/test_pwd.py
index ac9cff7..db98159 100644
--- a/Lib/test/test_pwd.py
+++ b/Lib/test/test_pwd.py
@@ -104,11 +104,11 @@ class PwdTest(unittest.TestCase):
# In some cases, byuids isn't a complete list of all users in the
# system, so if we try to pick a value not in byuids (via a perturbing
# loop, say), pwd.getpwuid() might still be able to find data for that
- # uid. Using sys.maxint may provoke the same problems, but hopefully
+ # uid. Using 2**32 - 2 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
+ fakeuid = 2**32 - 2
self.assertNotIn(fakeuid, byuids)
if not support.is_android:
self.assertRaises(KeyError, pwd.getpwuid, fakeuid)

View File

@@ -0,0 +1,310 @@
diff --git a/Include/object.h b/Include/object.h
index 0c88603..e3413e8 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -1071,6 +1071,49 @@ PyAPI_FUNC(void)
_PyObject_DebugTypeStats(FILE *out);
#endif /* ifndef Py_LIMITED_API */
+/*
+ Define a pair of assertion macros.
+
+ These work like the regular C assert(), in that they will abort the
+ process with a message on stderr if the given condition fails to hold,
+ but compile away to nothing if NDEBUG is defined.
+
+ However, before aborting, Python will also try to call _PyObject_Dump() on
+ the given object. This may be of use when investigating bugs in which a
+ particular object is corrupt (e.g. buggy a tp_visit method in an extension
+ module breaking the garbage collector), to help locate the broken objects.
+
+ The WITH_MSG variant allows you to supply an additional message that Python
+ will attempt to print to stderr, after the object dump.
+*/
+#ifdef NDEBUG
+/* No debugging: compile away the assertions: */
+#define PyObject_ASSERT_WITH_MSG(obj, expr, msg) ((void)0)
+#else
+/* With debugging: generate checks: */
+#define PyObject_ASSERT_WITH_MSG(obj, expr, msg) \
+ ((expr) \
+ ? (void)(0) \
+ : _PyObject_AssertFailed((obj), \
+ (msg), \
+ (__STRING(expr)), \
+ (__FILE__), \
+ (__LINE__), \
+ (__PRETTY_FUNCTION__)))
+#endif
+
+#define PyObject_ASSERT(obj, expr) \
+ PyObject_ASSERT_WITH_MSG(obj, expr, NULL)
+
+/*
+ Declare and define the entrypoint even when NDEBUG is defined, to avoid
+ causing compiler/linker errors when building extensions without NDEBUG
+ against a Python built with NDEBUG defined
+*/
+PyAPI_FUNC(void) _PyObject_AssertFailed(PyObject *, const char *,
+ const char *, const char *, int,
+ const char *);
+
#ifdef __cplusplus
}
#endif
diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py
index e727499..6efcafb 100644
--- a/Lib/test/test_gc.py
+++ b/Lib/test/test_gc.py
@@ -1,10 +1,11 @@
import unittest
from test.support import (verbose, refcount_test, run_unittest,
strip_python_stderr, cpython_only, start_threads,
- temp_dir, requires_type_collecting)
+ temp_dir, import_module, requires_type_collecting)
from test.support.script_helper import assert_python_ok, make_script
import sys
+import sysconfig
import time
import gc
import weakref
@@ -50,6 +51,8 @@ class GC_Detector(object):
# gc collects it.
self.wr = weakref.ref(C1055820(666), it_happened)
+BUILD_WITH_NDEBUG = ('-DNDEBUG' in sysconfig.get_config_vars()['PY_CFLAGS'])
+
@with_tp_del
class Uncollectable(object):
"""Create a reference cycle with multiple __del__ methods.
@@ -862,6 +865,50 @@ class GCCallbackTests(unittest.TestCase):
self.assertEqual(len(gc.garbage), 0)
+ @unittest.skipIf(BUILD_WITH_NDEBUG,
+ 'built with -NDEBUG')
+ def test_refcount_errors(self):
+ self.preclean()
+ # Verify the "handling" of objects with broken refcounts
+ import_module("ctypes") #skip if not supported
+
+ import subprocess
+ code = '''if 1:
+ a = []
+ b = [a]
+
+ # Simulate the refcount of "a" being too low (compared to the
+ # references held on it by live data), but keeping it above zero
+ # (to avoid deallocating it):
+ import ctypes
+ ctypes.pythonapi.Py_DecRef(ctypes.py_object(a))
+
+ # The garbage collector should now have a fatal error when it reaches
+ # the broken object:
+ import gc
+ gc.collect()
+ '''
+ p = subprocess.Popen([sys.executable, "-c", code],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ stdout, stderr = p.communicate()
+ p.stdout.close()
+ p.stderr.close()
+ # Verify that stderr has a useful error message:
+ self.assertRegex(stderr,
+ b'Modules/gcmodule.c:[0-9]+: visit_decref: Assertion "\(\(gc\)->gc.gc_refs >> \(1\)\) != 0" failed.')
+ self.assertRegex(stderr,
+ b'refcount was too small')
+ self.assertRegex(stderr,
+ b'object : \[\]')
+ self.assertRegex(stderr,
+ b'type : list')
+ self.assertRegex(stderr,
+ b'refcount: 1')
+ self.assertRegex(stderr,
+ b'address : 0x[0-9a-f]+')
+
+
class GCTogglingTests(unittest.TestCase):
def setUp(self):
gc.enable()
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 0c6f444..87edd5a 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -342,7 +342,8 @@ update_refs(PyGC_Head *containers)
{
PyGC_Head *gc = containers->gc.gc_next;
for (; gc != containers; gc = gc->gc.gc_next) {
- assert(_PyGCHead_REFS(gc) == GC_REACHABLE);
+ PyObject_ASSERT(FROM_GC(gc),
+ _PyGCHead_REFS(gc) == GC_REACHABLE);
_PyGCHead_SET_REFS(gc, Py_REFCNT(FROM_GC(gc)));
/* Python's cyclic gc should never see an incoming refcount
* of 0: if something decref'ed to 0, it should have been
@@ -362,7 +363,8 @@ update_refs(PyGC_Head *containers)
* so serious that maybe this should be a release-build
* check instead of an assert?
*/
- assert(_PyGCHead_REFS(gc) != 0);
+ PyObject_ASSERT(FROM_GC(gc),
+ _PyGCHead_REFS(gc) != 0);
}
}
@@ -377,7 +379,9 @@ visit_decref(PyObject *op, void *data)
* generation being collected, which can be recognized
* because only they have positive gc_refs.
*/
- assert(_PyGCHead_REFS(gc) != 0); /* else refcount was too small */
+ PyObject_ASSERT_WITH_MSG(FROM_GC(gc),
+ _PyGCHead_REFS(gc) != 0,
+ "refcount was too small"); /* else refcount was too small */
if (_PyGCHead_REFS(gc) > 0)
_PyGCHead_DECREF(gc);
}
@@ -437,9 +441,10 @@ visit_reachable(PyObject *op, PyGC_Head *reachable)
* If gc_refs == GC_UNTRACKED, it must be ignored.
*/
else {
- assert(gc_refs > 0
- || gc_refs == GC_REACHABLE
- || gc_refs == GC_UNTRACKED);
+ PyObject_ASSERT(FROM_GC(gc),
+ gc_refs > 0
+ || gc_refs == GC_REACHABLE
+ || gc_refs == GC_UNTRACKED);
}
}
return 0;
@@ -481,7 +486,7 @@ move_unreachable(PyGC_Head *young, PyGC_Head *unreachable)
*/
PyObject *op = FROM_GC(gc);
traverseproc traverse = Py_TYPE(op)->tp_traverse;
- assert(_PyGCHead_REFS(gc) > 0);
+ PyObject_ASSERT(op, _PyGCHead_REFS(gc) > 0);
_PyGCHead_SET_REFS(gc, GC_REACHABLE);
(void) traverse(op,
(visitproc)visit_reachable,
@@ -544,7 +549,7 @@ move_legacy_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers)
for (gc = unreachable->gc.gc_next; gc != unreachable; gc = next) {
PyObject *op = FROM_GC(gc);
- assert(IS_TENTATIVELY_UNREACHABLE(op));
+ PyObject_ASSERT(op, IS_TENTATIVELY_UNREACHABLE(op));
next = gc->gc.gc_next;
if (has_legacy_finalizer(op)) {
@@ -620,7 +625,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
PyWeakReference **wrlist;
op = FROM_GC(gc);
- assert(IS_TENTATIVELY_UNREACHABLE(op));
+ PyObject_ASSERT(op, IS_TENTATIVELY_UNREACHABLE(op));
next = gc->gc.gc_next;
if (! PyType_SUPPORTS_WEAKREFS(Py_TYPE(op)))
@@ -641,9 +646,9 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
* the callback pointer intact. Obscure: it also
* changes *wrlist.
*/
- assert(wr->wr_object == op);
+ PyObject_ASSERT(wr->wr_object, wr->wr_object == op);
_PyWeakref_ClearRef(wr);
- assert(wr->wr_object == Py_None);
+ PyObject_ASSERT(wr->wr_object, wr->wr_object == Py_None);
if (wr->wr_callback == NULL)
continue; /* no callback */
@@ -677,7 +682,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
*/
if (IS_TENTATIVELY_UNREACHABLE(wr))
continue;
- assert(IS_REACHABLE(wr));
+ PyObject_ASSERT(op, IS_REACHABLE(wr));
/* Create a new reference so that wr can't go away
* before we can process it again.
@@ -686,7 +691,8 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
/* Move wr to wrcb_to_call, for the next pass. */
wrasgc = AS_GC(wr);
- assert(wrasgc != next); /* wrasgc is reachable, but
+ PyObject_ASSERT(op, wrasgc != next);
+ /* wrasgc is reachable, but
next isn't, so they can't
be the same */
gc_list_move(wrasgc, &wrcb_to_call);
@@ -702,11 +708,11 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
gc = wrcb_to_call.gc.gc_next;
op = FROM_GC(gc);
- assert(IS_REACHABLE(op));
- assert(PyWeakref_Check(op));
+ PyObject_ASSERT(op, IS_REACHABLE(op));
+ PyObject_ASSERT(op, PyWeakref_Check(op));
wr = (PyWeakReference *)op;
callback = wr->wr_callback;
- assert(callback != NULL);
+ PyObject_ASSERT(op, callback != NULL);
/* copy-paste of weakrefobject.c's handle_callback() */
temp = PyObject_CallFunctionObjArgs(callback, wr, NULL);
@@ -823,12 +829,14 @@ check_garbage(PyGC_Head *collectable)
for (gc = collectable->gc.gc_next; gc != collectable;
gc = gc->gc.gc_next) {
_PyGCHead_SET_REFS(gc, Py_REFCNT(FROM_GC(gc)));
- assert(_PyGCHead_REFS(gc) != 0);
+ PyObject_ASSERT(FROM_GC(gc),
+ _PyGCHead_REFS(gc) != 0);
}
subtract_refs(collectable);
for (gc = collectable->gc.gc_next; gc != collectable;
gc = gc->gc.gc_next) {
- assert(_PyGCHead_REFS(gc) >= 0);
+ PyObject_ASSERT(FROM_GC(gc),
+ _PyGCHead_REFS(gc) >= 0);
if (_PyGCHead_REFS(gc) != 0)
return -1;
}
diff --git a/Objects/object.c b/Objects/object.c
index 559794f..a47d47f 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -2025,6 +2025,35 @@ _PyTrash_thread_destroy_chain(void)
}
}
+PyAPI_FUNC(void)
+_PyObject_AssertFailed(PyObject *obj, const char *msg, const char *expr,
+ const char *file, int line, const char *function)
+{
+ fprintf(stderr,
+ "%s:%d: %s: Assertion \"%s\" failed.\n",
+ file, line, function, expr);
+ if (msg) {
+ fprintf(stderr, "%s\n", msg);
+ }
+
+ fflush(stderr);
+
+ if (obj) {
+ /* This might succeed or fail, but we're about to abort, so at least
+ try to provide any extra info we can: */
+ _PyObject_Dump(obj);
+ }
+ else {
+ fprintf(stderr, "NULL object\n");
+ }
+
+ fflush(stdout);
+ fflush(stderr);
+
+ /* Terminate the process: */
+ abort();
+}
+
#ifndef Py_TRACE_REFS
/* For Py_LIMITED_API, we need an out-of-line version of _Py_Dealloc.
Define this here, so we can undefine the macro. */

View File

@@ -0,0 +1,30 @@
diff -r 39b9b05c3085 Lib/distutils/sysconfig.py
--- a/Lib/distutils/sysconfig.py Wed Apr 10 00:27:23 2013 +0200
+++ b/Lib/distutils/sysconfig.py Wed Apr 10 10:14:18 2013 +0200
@@ -370,7 +370,10 @@
done[n] = item = ""
if found:
after = value[m.end():]
- value = value[:m.start()] + item + after
+ value = value[:m.start()]
+ if item.strip() not in value:
+ value += item
+ value += after
if "$" in after:
notdone[name] = value
else:
diff -r 39b9b05c3085 Lib/sysconfig.py
--- a/Lib/sysconfig.py Wed Apr 10 00:27:23 2013 +0200
+++ b/Lib/sysconfig.py Wed Apr 10 10:14:18 2013 +0200
@@ -294,7 +294,10 @@
if found:
after = value[m.end():]
- value = value[:m.start()] + item + after
+ value = value[:m.start()]
+ if item.strip() not in value:
+ value += item
+ value += after
if "$" in after:
notdone[name] = value
else:

View File

@@ -0,0 +1,11 @@
diff -r 28c04e954bb6 Lib/lib2to3/main.py
--- a/Lib/lib2to3/main.py Tue Oct 29 22:25:55 2013 -0400
+++ b/Lib/lib2to3/main.py Wed Nov 06 14:33:07 2013 +0100
@@ -213,6 +213,7 @@
# Set up logging handler
level = logging.DEBUG if options.verbose else logging.INFO
+ logging.root.handlers = []
logging.basicConfig(format='%(name)s: %(message)s', level=level)
logger = logging.getLogger('lib2to3.main')

View File

@@ -0,0 +1,232 @@
diff -Nur Python-3.4.1/Lib/ensurepip/__init__.py Python-3.4.1-rewheel/Lib/ensurepip/__init__.py
--- Python-3.4.1/Lib/ensurepip/__init__.py 2014-08-21 10:49:30.792695824 +0200
+++ Python-3.4.1-rewheel/Lib/ensurepip/__init__.py 2014-08-21 10:10:41.958341726 +0200
@@ -1,8 +1,10 @@
import os
import os.path
import pkgutil
+import shutil
import sys
import tempfile
+from ensurepip import rewheel
__all__ = ["version", "bootstrap"]
@@ -25,6 +27,8 @@
# Install the bundled software
import pip
+ if args[0] in ["install", "list", "wheel"]:
+ args.append('--pre')
pip.main(args)
@@ -73,20 +77,39 @@
# omit pip and easy_install
os.environ["ENSUREPIP_OPTIONS"] = "install"
+ whls = []
+ rewheel_dir = None
+ # try to see if we have system-wide versions of _PROJECTS
+ dep_records = rewheel.find_system_records([p[0] for p in _PROJECTS])
+ # TODO: check if system-wide versions are the newest ones
+ # if --upgrade is used?
+ if all(dep_records):
+ # if we have all _PROJECTS installed system-wide, we'll recreate
+ # wheels from them and install those
+ rewheel_dir = tempfile.TemporaryDirectory()
+ for dr in dep_records:
+ new_whl = rewheel.rewheel_from_record(dr, rewheel_dir.name)
+ whls.append(os.path.join(rewheel_dir.name, new_whl))
+ else:
+ # if we don't have all the _PROJECTS installed system-wide,
+ # let's just fall back to bundled wheels
+ for project, version in _PROJECTS:
+ whl = os.path.join(
+ os.path.dirname(__file__),
+ "_bundled",
+ "{}-{}-py2.py3-none-any.whl".format(project, version)
+ )
+ whls.append(whl)
+
with tempfile.TemporaryDirectory() as tmpdir:
# Put our bundled wheels into a temporary directory and construct the
# additional paths that need added to sys.path
additional_paths = []
- for project, version in _PROJECTS:
- wheel_name = "{}-{}-py2.py3-none-any.whl".format(project, version)
- whl = pkgutil.get_data(
- "ensurepip",
- "_bundled/{}".format(wheel_name),
- )
- with open(os.path.join(tmpdir, wheel_name), "wb") as fp:
- fp.write(whl)
-
- additional_paths.append(os.path.join(tmpdir, wheel_name))
+ for whl in whls:
+ shutil.copy(whl, tmpdir)
+ additional_paths.append(os.path.join(tmpdir, os.path.basename(whl)))
+ if rewheel_dir:
+ rewheel_dir.cleanup()
# Construct the arguments to be passed to the pip command
args = ["install", "--no-index", "--find-links", tmpdir]
diff -Nur Python-3.4.1/Lib/ensurepip/rewheel/__init__.py Python-3.4.1-rewheel/Lib/ensurepip/rewheel/__init__.py
--- Python-3.4.1/Lib/ensurepip/rewheel/__init__.py 1970-01-01 01:00:00.000000000 +0100
+++ Python-3.4.1-rewheel/Lib/ensurepip/rewheel/__init__.py 2014-08-21 10:11:22.560320121 +0200
@@ -0,0 +1,143 @@
+import argparse
+import codecs
+import csv
+import email.parser
+import os
+import io
+import re
+import site
+import subprocess
+import sys
+import zipfile
+
+def run():
+ parser = argparse.ArgumentParser(description='Recreate wheel of package with given RECORD.')
+ parser.add_argument('record_path',
+ help='Path to RECORD file')
+ parser.add_argument('-o', '--output-dir',
+ help='Dir where to place the wheel, defaults to current working dir.',
+ dest='outdir',
+ default=os.path.curdir)
+
+ ns = parser.parse_args()
+ retcode = 0
+ try:
+ print(rewheel_from_record(**vars(ns)))
+ except BaseException as e:
+ print('Failed: {}'.format(e))
+ retcode = 1
+ sys.exit(1)
+
+def find_system_records(projects):
+ """Return list of paths to RECORD files for system-installed projects.
+
+ If a project is not installed, the resulting list contains None instead
+ of a path to its RECORD
+ """
+ records = []
+ # get system site-packages dirs
+ sys_sitepack = site.getsitepackages([sys.base_prefix, sys.base_exec_prefix])
+ sys_sitepack = [sp for sp in sys_sitepack if os.path.exists(sp)]
+ # try to find all projects in all system site-packages
+ for project in projects:
+ path = None
+ for sp in sys_sitepack:
+ dist_info_re = os.path.join(sp, project) + r'-[^\{0}]+\.dist-info'.format(os.sep)
+ candidates = [os.path.join(sp, p) for p in os.listdir(sp)]
+ # filter out candidate dirs based on the above regexp
+ filtered = [c for c in candidates if re.match(dist_info_re, c)]
+ # if we have 0 or 2 or more dirs, something is wrong...
+ if len(filtered) == 1:
+ path = filtered[0]
+ if path is not None:
+ records.append(os.path.join(path, 'RECORD'))
+ else:
+ records.append(None)
+ return records
+
+def rewheel_from_record(record_path, outdir):
+ """Recreates a whee of package with given record_path and returns path
+ to the newly created wheel."""
+ site_dir = os.path.dirname(os.path.dirname(record_path))
+ record_relpath = record_path[len(site_dir):].strip(os.path.sep)
+ to_write, to_omit = get_records_to_pack(site_dir, record_relpath)
+ new_wheel_name = get_wheel_name(record_path)
+ new_wheel_path = os.path.join(outdir, new_wheel_name + '.whl')
+
+ new_wheel = zipfile.ZipFile(new_wheel_path, mode='w', compression=zipfile.ZIP_DEFLATED)
+ # we need to write a new record with just the files that we will write,
+ # e.g. not binaries and *.pyc/*.pyo files
+ new_record = io.StringIO()
+ writer = csv.writer(new_record)
+
+ # handle files that we can write straight away
+ for f, sha_hash, size in to_write:
+ new_wheel.write(os.path.join(site_dir, f), arcname=f)
+ writer.writerow([f, sha_hash,size])
+
+ # rewrite the old wheel file with a new computed one
+ writer.writerow([record_relpath, '', ''])
+ new_wheel.writestr(record_relpath, new_record.getvalue())
+
+ new_wheel.close()
+
+ return new_wheel.filename
+
+def get_wheel_name(record_path):
+ """Return proper name of the wheel, without .whl."""
+
+ wheel_info_path = os.path.join(os.path.dirname(record_path), 'WHEEL')
+ with codecs.open(wheel_info_path, encoding='utf-8') as wheel_info_file:
+ wheel_info = email.parser.Parser().parsestr(wheel_info_file.read())
+
+ metadata_path = os.path.join(os.path.dirname(record_path), 'METADATA')
+ with codecs.open(metadata_path, encoding='utf-8') as metadata_file:
+ metadata = email.parser.Parser().parsestr(metadata_file.read())
+
+ # construct name parts according to wheel spec
+ distribution = metadata.get('Name')
+ version = metadata.get('Version')
+ build_tag = '' # nothing for now
+ lang_tag = []
+ for t in wheel_info.get_all('Tag'):
+ lang_tag.append(t.split('-')[0])
+ lang_tag = '.'.join(lang_tag)
+ abi_tag, plat_tag = wheel_info.get('Tag').split('-')[1:3]
+ # leave out build tag, if it is empty
+ to_join = filter(None, [distribution, version, build_tag, lang_tag, abi_tag, plat_tag])
+ return '-'.join(list(to_join))
+
+def get_records_to_pack(site_dir, record_relpath):
+ """Accepts path of sitedir and path of RECORD file relative to it.
+ Returns two lists:
+ - list of files that can be written to new RECORD straight away
+ - list of files that shouldn't be written or need some processing
+ (pyc and pyo files, scripts)
+ """
+ record_file_path = os.path.join(site_dir, record_relpath)
+ with codecs.open(record_file_path, encoding='utf-8') as record_file:
+ record_contents = record_file.read()
+ # temporary fix for https://github.com/pypa/pip/issues/1376
+ # we need to ignore files under ".data" directory
+ data_dir = os.path.dirname(record_relpath).strip(os.path.sep)
+ data_dir = data_dir[:-len('dist-info')] + 'data'
+
+ to_write = []
+ to_omit = []
+ for l in record_contents.splitlines():
+ spl = l.split(',')
+ if len(spl) == 3:
+ # new record will omit (or write differently):
+ # - abs paths, paths with ".." (entry points),
+ # - pyc+pyo files
+ # - the old RECORD file
+ # TODO: is there any better way to recognize an entry point?
+ if os.path.isabs(spl[0]) or spl[0].startswith('..') or \
+ spl[0].endswith('.pyc') or spl[0].endswith('.pyo') or \
+ spl[0] == record_relpath or spl[0].startswith(data_dir):
+ to_omit.append(spl)
+ else:
+ to_write.append(spl)
+ else:
+ pass # bad RECORD or empty line
+ return to_write, to_omit
diff -Nur Python-3.4.1/Makefile.pre.in Python-3.4.1-rewheel/Makefile.pre.in
--- Python-3.4.1/Makefile.pre.in 2014-08-21 10:49:31.512695040 +0200
+++ Python-3.4.1-rewheel/Makefile.pre.in 2014-08-21 10:10:41.961341722 +0200
@@ -1227,7 +1227,7 @@
test/test_asyncio \
collections concurrent concurrent/futures encodings \
email email/mime test/test_email test/test_email/data \
- ensurepip ensurepip/_bundled \
+ ensurepip ensurepip/_bundled ensurepip/rewheel \
html json test/test_json http dbm xmlrpc \
sqlite3 sqlite3/test \
logging csv wsgiref urllib \

View File

@@ -2,7 +2,7 @@ Cygwin ld (as of binutils-2.19.51) does not understand --enable-new-dtags.
--- Python-3.1/Lib/distutils/unixccompiler.py.orig 2009-05-09 06:55:12.000000000 -0500
+++ Python-3.1/Lib/distutils/unixccompiler.py 2009-08-19 22:46:55.222993300 -0500
@@ -279,7 +279,7 @@ class UnixCCompiler(CCompiler):
@@ -224,7 +224,7 @@ class UnixCCompiler(CCompiler):
# the configuration data stored in the Python installation, so
# we use this hack.
compiler = os.path.basename(sysconfig.get_config_var("CC"))
@@ -10,4 +10,4 @@ Cygwin ld (as of binutils-2.19.51) does not understand --enable-new-dtags.
+ if sys.platform[:6] == "darwin" or sys.platform[:6] == "cygwin":
# MacOSX's linker doesn't understand the -R flag at all
return "-L" + dir
elif sys.platform[:5] == "hp-ux":
elif sys.platform[:7] == "freebsd":

View File

@@ -0,0 +1,15 @@
diff -up Python-3.5.0/configure.ac Python-3.5.0/configure.ac
--- Python-3.5.0/configure.ac 2015-09-23 13:52:20.756909744 +0200
+++ Python-3.5.0/configure.ac 2015-09-23 13:52:46.859163629 +0200
@@ -799,9 +799,9 @@ cat >> conftest.c <<EOF
alpha-linux-gnu
# elif defined(__ARM_EABI__) && defined(__ARM_PCS_VFP)
# if defined(__ARMEL__)
- arm-linux-gnueabihf
+ arm-linux-gnueabi
# else
- armeb-linux-gnueabihf
+ armeb-linux-gnueabi
# endif
# elif defined(__ARM_EABI__) && !defined(__ARM_PCS_VFP)
# if defined(__ARMEL__)

View File

@@ -0,0 +1,42 @@
diff -urp Python-3.5.0/configure p/configure
--- Python-3.5.0/configure 2016-02-25 16:12:12.615184011 +0000
+++ p/configure 2016-02-25 16:13:01.293412517 +0000
@@ -5267,7 +5267,7 @@ cat >> conftest.c <<EOF
# elif _MIPS_SIM == _ABIN32
mips64el-linux-gnuabin32
# elif _MIPS_SIM == _ABI64
- mips64el-linux-gnuabi64
+ mips64el-linux-gnu
# else
# error unknown platform triplet
# endif
@@ -5277,7 +5277,7 @@ cat >> conftest.c <<EOF
# elif _MIPS_SIM == _ABIN32
mips64-linux-gnuabin32
# elif _MIPS_SIM == _ABI64
- mips64-linux-gnuabi64
+ mips64-linux-gnu
# else
# error unknown platform triplet
# endif
diff -urp Python-3.5.0/configure.ac p/configure.ac
--- Python-3.5.0/configure.ac 2016-02-25 16:12:11.663159985 +0000
+++ p/configure.ac 2016-02-25 16:13:18.814854710 +0000
@@ -821,7 +821,7 @@ cat >> conftest.c <<EOF
# elif _MIPS_SIM == _ABIN32
mips64el-linux-gnuabin32
# elif _MIPS_SIM == _ABI64
- mips64el-linux-gnuabi64
+ mips64el-linux-gnu
# else
# error unknown platform triplet
# endif
@@ -831,7 +831,7 @@ cat >> conftest.c <<EOF
# elif _MIPS_SIM == _ABIN32
mips64-linux-gnuabin32
# elif _MIPS_SIM == _ABI64
- mips64-linux-gnuabi64
+ mips64-linux-gnu
# else
# error unknown platform triplet
# endif

View File

@@ -0,0 +1,12 @@
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 28df0e1..42f811c 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -879,6 +879,7 @@ Python/frozen.o: Python/importlib.h Python/importlib_external.h
# follow our naming conventions. dtrace(1) uses the output filename to generate
# an include guard, so we can't use a pipeline to transform its output.
Include/pydtrace_probes.h: $(srcdir)/Include/pydtrace.d
+ @$(MKDIR_P) Include
$(DTRACE) $(DFLAGS) -o $@ -h -s $<
: sed in-place edit with POSIX-only tools
sed 's/PYTHON_/PyDTrace_/' $@ > $@.tmp

View File

@@ -0,0 +1,45 @@
diff --git a/Lib/distutils/cmd.py b/Lib/distutils/cmd.py
index c89d5ef..dd61621 100644
--- a/Lib/distutils/cmd.py
+++ b/Lib/distutils/cmd.py
@@ -296,7 +296,8 @@ class Command:
finalized command object.
"""
cmd_obj = self.distribution.get_command_obj(command, create)
- cmd_obj.ensure_finalized()
+ if cmd_obj is not None:
+ cmd_obj.ensure_finalized()
return cmd_obj
# XXX rename to 'get_reinitialized_command()'? (should do the
diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py
index 8174192..30ca739 100644
--- a/Lib/distutils/command/install.py
+++ b/Lib/distutils/command/install.py
@@ -122,6 +122,8 @@ class install(Command):
"force installation (overwrite any existing files)"),
('skip-build', None,
"skip rebuilding everything (for testing/debugging)"),
+ ('executable=', 'e',
+ "specify final destination interpreter path (install.py)"),
# Where to install documentation (eventually!)
#('doc-format=', None, "format of documentation to generate"),
@@ -195,6 +197,7 @@ class install(Command):
# directory not in sys.path.
self.force = 0
self.skip_build = 0
+ self.executable = None
self.warn_dir = 1
# These are only here as a conduit from the 'build' command to the
@@ -367,6 +370,9 @@ class install(Command):
('build_base', 'build_base'),
('build_lib', 'build_lib'))
+ if self.executable is None:
+ self.executable = os.path.normpath(sys.executable)
+
# Punt on doc directories for now -- after all, we're punting on
# documentation completely!

View File

@@ -0,0 +1,183 @@
diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py
index 9f5d151..4dfa8a1 100644
--- a/Lib/ensurepip/__init__.py
+++ b/Lib/ensurepip/__init__.py
@@ -10,13 +10,25 @@ import tempfile
__all__ = ["version", "bootstrap"]
-_SETUPTOOLS_VERSION = "28.8.0"
+_SETUPTOOLS_VERSION = "34.2.0"
_PIP_VERSION = "9.0.1"
+_SIX_VERSION = "1.10.0"
+
+_APPDIRS_VERSION = "1.4.0"
+
+_PACKAGING_VERSION = "16.8"
+
+_PYPARSING_VERSION = "2.1.10"
+
_PROJECTS = [
- ("setuptools", _SETUPTOOLS_VERSION),
- ("pip", _PIP_VERSION),
+ ("setuptools", _SETUPTOOLS_VERSION),
+ ("pip", _PIP_VERSION),
+ ("six", _SIX_VERSION),
+ ("appdirs", _APPDIRS_VERSION),
+ ("packaging", _PACKAGING_VERSION),
+ ("pyparsing", _PYPARSING_VERSION)
]
diff --git a/Lib/test/test_ensurepip.py b/Lib/test/test_ensurepip.py
index 9b04c18..23664c4 100644
--- a/Lib/test/test_ensurepip.py
+++ b/Lib/test/test_ensurepip.py
@@ -40,13 +40,14 @@ class TestBootstrap(EnsurepipMixin, unittest.TestCase):
self.run_pip.assert_called_once_with(
[
"install", "--no-index", "--find-links",
- unittest.mock.ANY, "setuptools", "pip",
+ unittest.mock.ANY,
+ "setuptools", "pip", "six", "appdirs", "packaging", "pyparsing",
],
unittest.mock.ANY,
)
additional_paths = self.run_pip.call_args[0][1]
- self.assertEqual(len(additional_paths), 2)
+ self.assertEqual(len(additional_paths), 6)
def test_bootstrapping_with_root(self):
ensurepip.bootstrap(root="/foo/bar/")
@@ -55,7 +56,7 @@ class TestBootstrap(EnsurepipMixin, unittest.TestCase):
[
"install", "--no-index", "--find-links",
unittest.mock.ANY, "--root", "/foo/bar/",
- "setuptools", "pip",
+ "setuptools", "pip", "six", "appdirs", "packaging", "pyparsing",
],
unittest.mock.ANY,
)
@@ -66,7 +67,8 @@ class TestBootstrap(EnsurepipMixin, unittest.TestCase):
self.run_pip.assert_called_once_with(
[
"install", "--no-index", "--find-links",
- unittest.mock.ANY, "--user", "setuptools", "pip",
+ unittest.mock.ANY, "--user",
+ "setuptools", "pip", "six", "appdirs", "packaging", "pyparsing",
],
unittest.mock.ANY,
)
@@ -77,7 +79,8 @@ class TestBootstrap(EnsurepipMixin, unittest.TestCase):
self.run_pip.assert_called_once_with(
[
"install", "--no-index", "--find-links",
- unittest.mock.ANY, "--upgrade", "setuptools", "pip",
+ unittest.mock.ANY, "--upgrade",
+ "setuptools", "pip", "six", "appdirs", "packaging", "pyparsing",
],
unittest.mock.ANY,
)
@@ -88,7 +91,8 @@ class TestBootstrap(EnsurepipMixin, unittest.TestCase):
self.run_pip.assert_called_once_with(
[
"install", "--no-index", "--find-links",
- unittest.mock.ANY, "-v", "setuptools", "pip",
+ unittest.mock.ANY, "-v",
+ "setuptools", "pip", "six", "appdirs", "packaging", "pyparsing",
],
unittest.mock.ANY,
)
@@ -99,7 +103,8 @@ class TestBootstrap(EnsurepipMixin, unittest.TestCase):
self.run_pip.assert_called_once_with(
[
"install", "--no-index", "--find-links",
- unittest.mock.ANY, "-vv", "setuptools", "pip",
+ unittest.mock.ANY, "-vv",
+ "setuptools", "pip", "six", "appdirs", "packaging", "pyparsing",
],
unittest.mock.ANY,
)
@@ -110,7 +115,8 @@ class TestBootstrap(EnsurepipMixin, unittest.TestCase):
self.run_pip.assert_called_once_with(
[
"install", "--no-index", "--find-links",
- unittest.mock.ANY, "-vvv", "setuptools", "pip",
+ unittest.mock.ANY, "-vvv",
+ "setuptools", "pip", "six", "appdirs", "packaging", "pyparsing",
],
unittest.mock.ANY,
)
@@ -186,8 +192,8 @@ class TestUninstall(EnsurepipMixin, unittest.TestCase):
self.run_pip.assert_called_once_with(
[
- "uninstall", "-y", "--disable-pip-version-check", "pip",
- "setuptools",
+ "uninstall", "-y", "--disable-pip-version-check",
+ "pyparsing", "packaging", "appdirs", "six", "pip", "setuptools",
]
)
@@ -197,8 +203,8 @@ class TestUninstall(EnsurepipMixin, unittest.TestCase):
self.run_pip.assert_called_once_with(
[
- "uninstall", "-y", "--disable-pip-version-check", "-v", "pip",
- "setuptools",
+ "uninstall", "-y", "--disable-pip-version-check", "-v",
+ "pyparsing", "packaging", "appdirs", "six", "pip", "setuptools",
]
)
@@ -208,8 +214,8 @@ class TestUninstall(EnsurepipMixin, unittest.TestCase):
self.run_pip.assert_called_once_with(
[
- "uninstall", "-y", "--disable-pip-version-check", "-vv", "pip",
- "setuptools",
+ "uninstall", "-y", "--disable-pip-version-check", "-vv",
+ "pyparsing", "packaging", "appdirs", "six", "pip", "setuptools",
]
)
@@ -220,7 +226,7 @@ class TestUninstall(EnsurepipMixin, unittest.TestCase):
self.run_pip.assert_called_once_with(
[
"uninstall", "-y", "--disable-pip-version-check", "-vvv",
- "pip", "setuptools",
+ "pyparsing", "packaging", "appdirs", "six", "pip", "setuptools",
]
)
@@ -260,13 +266,14 @@ class TestBootstrappingMainFunction(EnsurepipMixin, unittest.TestCase):
self.run_pip.assert_called_once_with(
[
"install", "--no-index", "--find-links",
- unittest.mock.ANY, "setuptools", "pip",
+ unittest.mock.ANY,
+ "setuptools", "pip", "six", "appdirs", "packaging", "pyparsing",
],
unittest.mock.ANY,
)
additional_paths = self.run_pip.call_args[0][1]
- self.assertEqual(len(additional_paths), 2)
+ self.assertEqual(len(additional_paths), 6)
class TestUninstallationMainFunction(EnsurepipMixin, unittest.TestCase):
@@ -284,8 +291,8 @@ class TestUninstallationMainFunction(EnsurepipMixin, unittest.TestCase):
self.run_pip.assert_called_once_with(
[
- "uninstall", "-y", "--disable-pip-version-check", "pip",
- "setuptools",
+ "uninstall", "-y", "--disable-pip-version-check", "pyparsing", "packaging",
+ "appdirs", "six", "pip", "setuptools",
]
)

View File

@@ -0,0 +1,104 @@
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py
index 6c3625d..2a53f3d 100644
--- a/Lib/test/test_capi.py
+++ b/Lib/test/test_capi.py
@@ -385,7 +385,7 @@ class EmbeddingTests(unittest.TestCase):
def test_subinterps(self):
# This is just a "don't crash" test
- out, err = self.run_embedded_interpreter()
+ out, err = self.run_embedded_interpreter("repeated_init_and_subinterpreters")
if support.verbose:
print()
print(out)
diff --git a/Programs/_testembed.c b/Programs/_testembed.c
index 3968399..a68d4fa 100644
--- a/Programs/_testembed.c
+++ b/Programs/_testembed.c
@@ -33,7 +33,7 @@ static void print_subinterp(void)
);
}
-static void test_repeated_init_and_subinterpreters(void)
+static int test_repeated_init_and_subinterpreters(void)
{
PyThreadState *mainstate, *substate;
#ifdef WITH_THREAD
@@ -70,6 +70,7 @@ static void test_repeated_init_and_subinterpreters(void)
PyEval_RestoreThread(mainstate);
Py_Finalize();
}
+ return 0;
}
/*****************************************************
@@ -103,7 +104,7 @@ static void check_stdio_details(const char *encoding, const char * errors)
Py_Finalize();
}
-static void test_forced_io_encoding(void)
+static int test_forced_io_encoding(void)
{
/* Check various combinations */
printf("--- Use defaults ---\n");
@@ -122,19 +123,51 @@ static void test_forced_io_encoding(void)
printf("Unexpected success calling Py_SetStandardStreamEncoding");
}
Py_Finalize();
+ return 0;
}
-/* Different embedding tests */
-int main(int argc, char *argv[])
+/* *********************************************************
+ * List of test cases and the function that implements it.
+ *
+ * Names are compared case-sensitively with the first
+ * argument. If no match is found, or no first argument was
+ * provided, the names of all test cases are printed and
+ * the exit code will be -1.
+ *
+ * The int returned from test functions is used as the exit
+ * code, and test_capi treats all non-zero exit codes as a
+ * failed test.
+ *********************************************************/
+struct TestCase
{
+ const char *name;
+ int (*func)(void);
+};
+
+static struct TestCase TestCases[] = {
+ { "forced_io_encoding", test_forced_io_encoding },
+ { "repeated_init_and_subinterpreters", test_repeated_init_and_subinterpreters },
+ { NULL, NULL }
+};
- /* TODO: Check the argument string to allow for more test cases */
+int main(int argc, char *argv[])
+{
if (argc > 1) {
- /* For now: assume "forced_io_encoding */
- test_forced_io_encoding();
- } else {
- /* Run the original embedding test case by default */
- test_repeated_init_and_subinterpreters();
+ for (struct TestCase *tc = TestCases; tc && tc->name; tc++) {
+ if (strcmp(argv[1], tc->name) == 0)
+ return (*tc->func)();
+ }
}
- return 0;
+
+ /* No match found, or no test name provided, so display usage */
+ printf("Python " PY_VERSION " _testembed executable for embedded interpreter tests\n"
+ "Normally executed via 'EmbeddingTests' in Lib/test/test_capi.py\n\n"
+ "Usage: %s TESTNAME\n\nAll available tests:\n", argv[0]);
+ for (struct TestCase *tc = TestCases; tc && tc->name; tc++) {
+ printf(" %s\n", tc->name);
+ }
+
+ /* Non-zero exit code will cause test_capi.py tests to fail.
+ This is intentional. */
+ return -1;
}

View File

@@ -0,0 +1,683 @@
diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst
index 195f63f..0d0a127 100644
--- a/Doc/using/cmdline.rst
+++ b/Doc/using/cmdline.rst
@@ -713,6 +713,40 @@ conflict.
.. versionadded:: 3.6
+
+.. envvar:: PYTHONCOERCECLOCALE
+
+ If set to the value ``0``, causes the main Python command line application
+ to skip coercing the legacy ASCII-based C locale to a more capable UTF-8
+ based alternative. Note that this setting is checked even when the
+ :option:`-E` or :option:`-I` options are used, as it is handled prior to
+ the processing of command line options.
+
+ If this variable is *not* set, or is set to a value other than ``0``, and
+ the current locale reported for the ``LC_CTYPE`` category is the default
+ ``C`` locale, then the Python CLI will attempt to configure one of the
+ following locales for the given locale categories before loading the
+ interpreter runtime:
+
+ * ``C.UTF-8`` (``LC_ALL``)
+ * ``C.utf8`` (``LC_ALL``)
+ * ``UTF-8`` (``LC_CTYPE``)
+
+ If setting one of these locale categories succeeds, then the matching
+ environment variables will be set (both ``LC_ALL`` and ``LANG`` for the
+ ``LC_ALL`` category, and ``LC_CTYPE`` for the ``LC_CTYPE`` category) in
+ the current process environment before the Python runtime is initialized.
+
+ Configuring one of these locales (either explicitly or via the above
+ implicit locale coercion) will automatically set the error handler for
+ :data:`sys.stdin` and :data:`sys.stdout` to ``surrogateescape``. This
+ behavior can be overridden using :envvar:`PYTHONIOENCODING` as usual.
+
+ Availability: \*nix
+
+ .. versionadded:: 3.7
+ See :pep:`538` for more details.
+
Debug-mode variables
~~~~~~~~~~~~~~~~~~~~
diff --git a/Lib/test/support/script_helper.py b/Lib/test/support/script_helper.py
index ca5f9c2..7aa460b 100644
--- a/Lib/test/support/script_helper.py
+++ b/Lib/test/support/script_helper.py
@@ -51,8 +51,35 @@ def interpreter_requires_environment():
return __cached_interp_requires_environment
-_PythonRunResult = collections.namedtuple("_PythonRunResult",
- ("rc", "out", "err"))
+class _PythonRunResult(collections.namedtuple("_PythonRunResult",
+ ("rc", "out", "err"))):
+ """Helper for reporting Python subprocess run results"""
+ def fail(self, cmd_line):
+ """Provide helpful details about failed subcommand runs"""
+ # Limit to 80 lines to ASCII characters
+ maxlen = 80 * 100
+ out, err = self.out, self.err
+ if len(out) > maxlen:
+ out = b'(... truncated stdout ...)' + out[-maxlen:]
+ if len(err) > maxlen:
+ err = b'(... truncated stderr ...)' + err[-maxlen:]
+ out = out.decode('ascii', 'replace').rstrip()
+ err = err.decode('ascii', 'replace').rstrip()
+ raise AssertionError("Process return code is %d\n"
+ "command line: %r\n"
+ "\n"
+ "stdout:\n"
+ "---\n"
+ "%s\n"
+ "---\n"
+ "\n"
+ "stderr:\n"
+ "---\n"
+ "%s\n"
+ "---"
+ % (self.rc, cmd_line,
+ out,
+ err))
# Executing the interpreter in a subprocess
@@ -110,30 +137,7 @@ def run_python_until_end(*args, **env_vars):
def _assert_python(expected_success, *args, **env_vars):
res, cmd_line = run_python_until_end(*args, **env_vars)
if (res.rc and expected_success) or (not res.rc and not expected_success):
- # Limit to 80 lines to ASCII characters
- maxlen = 80 * 100
- out, err = res.out, res.err
- if len(out) > maxlen:
- out = b'(... truncated stdout ...)' + out[-maxlen:]
- if len(err) > maxlen:
- err = b'(... truncated stderr ...)' + err[-maxlen:]
- out = out.decode('ascii', 'replace').rstrip()
- err = err.decode('ascii', 'replace').rstrip()
- raise AssertionError("Process return code is %d\n"
- "command line: %r\n"
- "\n"
- "stdout:\n"
- "---\n"
- "%s\n"
- "---\n"
- "\n"
- "stderr:\n"
- "---\n"
- "%s\n"
- "---"
- % (res.rc, cmd_line,
- out,
- err))
+ res.fail(cmd_line)
return res
def assert_python_ok(*args, **env_vars):
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py
index 2a53f3d..391ca15 100644
--- a/Lib/test/test_capi.py
+++ b/Lib/test/test_capi.py
@@ -369,14 +369,15 @@ class EmbeddingTests(unittest.TestCase):
def tearDown(self):
os.chdir(self.oldcwd)
- def run_embedded_interpreter(self, *args):
+ def run_embedded_interpreter(self, *args, env=None):
"""Runs a test in the embedded interpreter"""
cmd = [self.test_exe]
cmd.extend(args)
p = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
- universal_newlines=True)
+ universal_newlines=True,
+ env=env)
(out, err) = p.communicate()
self.assertEqual(p.returncode, 0,
"bad returncode %d, stderr is %r" %
@@ -386,7 +387,7 @@ class EmbeddingTests(unittest.TestCase):
def test_subinterps(self):
# This is just a "don't crash" test
out, err = self.run_embedded_interpreter("repeated_init_and_subinterpreters")
- if support.verbose:
+ if support.verbose > 1:
print()
print(out)
print(err)
@@ -403,13 +404,14 @@ class EmbeddingTests(unittest.TestCase):
def test_forced_io_encoding(self):
# Checks forced configuration of embedded interpreter IO streams
- out, err = self.run_embedded_interpreter("forced_io_encoding")
- if support.verbose:
+ env = {"PYTHONIOENCODING": "UTF-8:surrogateescape"}
+ out, err = self.run_embedded_interpreter("forced_io_encoding", env=env)
+ if support.verbose > 1:
print()
print(out)
print(err)
- expected_errors = sys.__stdout__.errors
- expected_stdin_encoding = sys.__stdin__.encoding
+ expected_errors = "surrogateescape"
+ expected_stdin_encoding = "UTF-8"
expected_pipe_encoding = self._get_default_pipe_encoding()
expected_output = '\n'.join([
"--- Use defaults ---",
diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py
index ae2bcd4..0a302ff 100644
--- a/Lib/test/test_cmd_line.py
+++ b/Lib/test/test_cmd_line.py
@@ -9,8 +9,9 @@ import sys
import subprocess
import tempfile
from test.support import script_helper, is_android
-from test.support.script_helper import (spawn_python, kill_python, assert_python_ok,
- assert_python_failure)
+from test.support.script_helper import (
+ spawn_python, kill_python, assert_python_ok, assert_python_failure
+)
# XXX (ncoghlan): Move to script_helper and make consistent with run_python
@@ -151,6 +152,7 @@ class CmdLineTest(unittest.TestCase):
env = os.environ.copy()
# Use C locale to get ascii for the locale encoding
env['LC_ALL'] = 'C'
+ env['PYTHONCOERCECLOCALE'] = '0'
code = (
b'import locale; '
b'print(ascii("' + undecodable + b'"), '
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index df9ebd4..63145e4 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -680,6 +680,7 @@ class SysModuleTest(unittest.TestCase):
# Force the POSIX locale
env = os.environ.copy()
env["LC_ALL"] = "C"
+ env["PYTHONCOERCECLOCALE"] = "0"
code = '\n'.join((
'import sys',
'def dump(name):',
diff --git a/Programs/_testembed.c b/Programs/_testembed.c
index a68d4fa..e28de1c 100644
--- a/Programs/_testembed.c
+++ b/Programs/_testembed.c
@@ -1,4 +1,5 @@
-#include <Python.h>
+#include "Python.h"
+#include "pyconfig.h"
#include <stdio.h>
/*********************************************************
@@ -126,6 +127,20 @@ static int test_forced_io_encoding(void)
return 0;
}
+static int test_c_locale_warning(void)
+{
+#ifdef PY_WARN_ON_C_LOCALE
+ /* Force use of the C locale */
+ setenv("LC_ALL", "C", 1);
+
+ _testembed_Py_Initialize();
+ Py_Finalize();
+#else
+ printf("C locale compatibility warning disabled at compile time\n");
+#endif
+ return 0;
+}
+
/* *********************************************************
* List of test cases and the function that implements it.
*
@@ -147,6 +162,7 @@ struct TestCase
static struct TestCase TestCases[] = {
{ "forced_io_encoding", test_forced_io_encoding },
{ "repeated_init_and_subinterpreters", test_repeated_init_and_subinterpreters },
+ { "c_locale_warning", test_c_locale_warning },
{ NULL, NULL }
};
diff --git a/Programs/python.c b/Programs/python.c
index a7afbc7..03f8295 100644
--- a/Programs/python.c
+++ b/Programs/python.c
@@ -15,6 +15,21 @@ wmain(int argc, wchar_t **argv)
}
#else
+/* Access private pylifecycle helper API to better handle the legacy C locale
+ *
+ * The legacy C locale assumes ASCII as the default text encoding, which
+ * causes problems not only for the CPython runtime, but also other
+ * components like GNU readline.
+ *
+ * Accordingly, when the CLI detects it, it attempts to coerce it to a
+ * more capable UTF-8 based alternative.
+ *
+ * See the documentation of the PYTHONCOERCECLOCALE setting for more details.
+ *
+ */
+extern int _Py_LegacyLocaleDetected(void);
+extern void _Py_CoerceLegacyLocale(void);
+
int
main(int argc, char **argv)
{
@@ -25,7 +40,11 @@ main(int argc, char **argv)
char *oldloc;
/* Force malloc() allocator to bootstrap Python */
+#ifdef Py_DEBUG
+ (void)_PyMem_SetupAllocators("malloc_debug");
+# else
(void)_PyMem_SetupAllocators("malloc");
+# endif
argv_copy = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1));
argv_copy2 = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1));
@@ -49,7 +68,21 @@ main(int argc, char **argv)
return 1;
}
+#ifdef __ANDROID__
+ /* Passing "" to setlocale() on Android requests the C locale rather
+ * than checking environment variables, so request C.UTF-8 explicitly
+ */
+ setlocale(LC_ALL, "C.UTF-8");
+#else
+ /* Reconfigure the locale to the default for this process */
setlocale(LC_ALL, "");
+#endif
+
+ if (_Py_LegacyLocaleDetected()) {
+ _Py_CoerceLegacyLocale();
+ }
+
+ /* Convert from char to wchar_t based on the locale settings */
for (i = 0; i < argc; i++) {
argv_copy[i] = Py_DecodeLocale(argv[i], NULL);
if (!argv_copy[i]) {
@@ -70,7 +103,11 @@ main(int argc, char **argv)
/* Force again malloc() allocator to release memory blocks allocated
before Py_Main() */
+#ifdef Py_DEBUG
+ (void)_PyMem_SetupAllocators("malloc_debug");
+# else
(void)_PyMem_SetupAllocators("malloc");
+# endif
for (i = 0; i < argc; i++) {
PyMem_RawFree(argv_copy2[i]);
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index a4f7f82..261ed34 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -167,6 +167,7 @@ Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
return 0;
}
+
/* Global initializations. Can be undone by Py_FinalizeEx(). Don't
call this twice without an intervening Py_FinalizeEx() call. When
initializations fail, a fatal error is issued and the function does
@@ -301,6 +302,173 @@ import_init(PyInterpreterState *interp, PyObject *sysmod)
}
+/* Helper functions to better handle the legacy C locale
+ *
+ * The legacy C locale assumes ASCII as the default text encoding, which
+ * causes problems not only for the CPython runtime, but also other
+ * components like GNU readline.
+ *
+ * Accordingly, when the CLI detects it, it attempts to coerce it to a
+ * more capable UTF-8 based alternative as follows:
+ *
+ * if (_Py_LegacyLocaleDetected()) {
+ * _Py_CoerceLegacyLocale();
+ * }
+ *
+ * See the documentation of the PYTHONCOERCECLOCALE setting for more details.
+ *
+ * Locale coercion also impacts the default error handler for the standard
+ * streams: while the usual default is "strict", the default for the legacy
+ * C locale and for any of the coercion target locales is "surrogateescape".
+ */
+
+int
+_Py_LegacyLocaleDetected(void)
+{
+ const char *ctype_loc = setlocale(LC_CTYPE, NULL);
+ return ctype_loc != NULL && strcmp(ctype_loc, "C") == 0;
+}
+
+typedef struct _CandidateLocale {
+ const char *locale_name;
+ int category;
+} _LocaleCoercionTarget;
+
+static _LocaleCoercionTarget _TARGET_LOCALES[] = {
+ { "C.UTF-8", LC_ALL },
+ { "C.utf8", LC_ALL },
+ { "UTF-8", LC_CTYPE },
+ { NULL, 0 }
+};
+
+static char *
+get_default_standard_stream_error_handler(void)
+{
+ const char *ctype_loc = setlocale(LC_CTYPE, NULL);
+ if (ctype_loc != NULL) {
+ /* "surrogateescape" is the default in the legacy C locale */
+ if (strcmp(ctype_loc, "C") == 0) {
+ return "surrogateescape";
+ }
+
+ /* "surrogateescape" is the default in locale coercion target locales */
+ const _LocaleCoercionTarget *target = NULL;
+ for (target = _TARGET_LOCALES; target->locale_name; target++) {
+ if (strcmp(ctype_loc, target->locale_name) == 0) {
+ return "surrogateescape";
+ }
+ }
+ }
+
+ /* Otherwise return NULL to request the typical default error handler */
+ return NULL;
+}
+
+#ifdef PY_COERCE_C_LOCALE
+static const char *_C_LOCALE_COERCION_WARNING =
+ "Python detected LC_CTYPE=C: %.20s coerced to %.20s (set another locale "
+ "or PYTHONCOERCECLOCALE=0 to disable this locale coercion behavior).\n";
+
+static void
+_coerce_default_locale_settings(const _LocaleCoercionTarget *target)
+{
+ const char *newloc = target->locale_name;
+ int category = target->category;
+
+ /* Reset locale back to currently configured defaults */
+ setlocale(LC_ALL, "");
+
+ /* Set the relevant locale environment variables */
+ if (category == LC_ALL) {
+ const char *env_vars_updated = "LC_ALL & LANG";
+ if (setenv("LC_ALL", newloc, 1)) {
+ fprintf(stderr,
+ "Error setting LC_ALL, skipping C locale coercion\n");
+ return;
+ }
+ if (setenv("LANG", newloc, 1)) {
+ fprintf(stderr,
+ "Error setting LANG during C locale coercion\n");
+ env_vars_updated = "LC_ALL";
+ }
+ fprintf(stderr, _C_LOCALE_COERCION_WARNING, env_vars_updated, newloc);
+ } else if (category == LC_CTYPE) {
+ if (setenv("LC_CTYPE", newloc, 1)) {
+ fprintf(stderr,
+ "Error setting LC_CTYPE, skipping C locale coercion\n");
+ return;
+ }
+ fprintf(stderr, _C_LOCALE_COERCION_WARNING, "LC_CTYPE", newloc);
+ } else {
+ fprintf(stderr, "Locale coercion must target LC_ALL or LC_CTYPE\n");
+ return;
+ }
+
+ /* Reconfigure with the overridden environment variables */
+ setlocale(LC_ALL, "");
+}
+
+static int
+c_locale_coercion_is_expected(void)
+{
+ /* This may be called prior to Py_Initialize, so we don't call any other
+ * Python APIs, and we ignore the -E and -I flags
+ */
+ const char *coerce_c_locale = getenv("PYTHONCOERCECLOCALE");
+ if (coerce_c_locale == NULL || strncmp(coerce_c_locale, "0", 2) != 0) {
+ return 1;
+ }
+ return 0;
+}
+#endif
+
+void
+_Py_CoerceLegacyLocale(void)
+{
+#ifdef PY_COERCE_C_LOCALE
+ /* We ignore the Python -E and -I flags here, as the CLI needs to sort out
+ * the locale settings *before* we try to do anything with the command
+ * line arguments. For cross-platform debugging purposes, we also need
+ * to give end users a way to force even scripts that are otherwise
+ * isolated from their environment to use the legacy ASCII-centric C
+ * locale.
+ */
+ if (c_locale_coercion_is_expected()) {
+ /* PYTHONCOERCECLOCALE is not set, or is not set to exactly "0" */
+ const _LocaleCoercionTarget *target = NULL;
+ for (target = _TARGET_LOCALES; target->locale_name; target++) {
+ const char *reconfigured_locale = setlocale(target->category,
+ target->locale_name);
+ if (reconfigured_locale != NULL) {
+ /* Successfully configured locale, so make it the default */
+ _coerce_default_locale_settings(target);
+ return;
+ }
+ }
+ }
+ /* No C locale warning here, as Py_Initialize will emit one later */
+#endif
+}
+
+
+#ifdef PY_WARN_ON_C_LOCALE
+static const char *_C_LOCALE_WARNING =
+ "Python runtime initialized with LC_CTYPE=C (a locale with default ASCII "
+ "encoding), which may cause Unicode compatibility problems. Using C.UTF-8, "
+ "C.utf8, or UTF-8 (if available) as alternative Unicode-compatible "
+ "locales is recommended.\n";
+
+static void
+_emit_stderr_warning_for_c_locale(void)
+{
+ if (c_locale_coercion_is_expected()) {
+ if (_Py_LegacyLocaleDetected()) {
+ fprintf(stderr, "%s", _C_LOCALE_WARNING);
+ }
+ }
+}
+#endif
+
void
_Py_InitializeEx_Private(int install_sigs, int install_importlib)
{
@@ -315,11 +483,19 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)
initialized = 1;
_Py_Finalizing = NULL;
-#ifdef HAVE_SETLOCALE
+#ifdef __ANDROID__
+ /* Passing "" to setlocale() on Android requests the C locale rather
+ * than checking environment variables, so request C.UTF-8 explicitly
+ */
+ setlocale(LC_CTYPE, "C.UTF-8");
+#else
/* Set up the LC_CTYPE locale, so we can obtain
the locale's charset without having to switch
locales. */
setlocale(LC_CTYPE, "");
+#ifdef PY_WARN_ON_C_LOCALE
+ _emit_stderr_warning_for_c_locale();
+#endif
#endif
if ((p = Py_GETENV("PYTHONDEBUG")) && *p != '\0')
@@ -1242,12 +1418,8 @@ initstdio(void)
}
}
if (!errors && !(pythonioencoding && *pythonioencoding)) {
- /* When the LC_CTYPE locale is the POSIX locale ("C locale"),
- stdin and stdout use the surrogateescape error handler by
- default, instead of the strict error handler. */
- char *loc = setlocale(LC_CTYPE, NULL);
- if (loc != NULL && strcmp(loc, "C") == 0)
- errors = "surrogateescape";
+ /* Choose the default error handler based on the current locale */
+ errors = get_default_standard_stream_error_handler();
}
}
diff --git a/configure b/configure
index 2915246..39e5a27 100755
--- a/configure
+++ b/configure
@@ -834,6 +834,8 @@ with_thread
enable_ipv6
with_doc_strings
with_pymalloc
+with_c_locale_coercion
+with_c_locale_warning
with_valgrind
with_dtrace
with_fpectl
@@ -1527,6 +1529,12 @@ Optional Packages:
deprecated; use --with(out)-threads
--with(out)-doc-strings disable/enable documentation strings
--with(out)-pymalloc disable/enable specialized mallocs
+ --with(out)-c-locale-coercion
+ disable/enable C locale coercion to a UTF-8 based
+ locale
+ --with(out)-c-locale-warning
+ disable/enable locale compatibility warning in the C
+ locale
--with-valgrind Enable Valgrind support
--with(out)-dtrace disable/enable DTrace support
--with-fpectl enable SIGFPE catching
@@ -11010,6 +11018,52 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_pymalloc" >&5
$as_echo "$with_pymalloc" >&6; }
+# Check for --with-c-locale-coercion
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-c-locale-coercion" >&5
+$as_echo_n "checking for --with-c-locale-coercion... " >&6; }
+
+# Check whether --with-c-locale-coercion was given.
+if test "${with_c_locale_coercion+set}" = set; then :
+ withval=$with_c_locale_coercion;
+fi
+
+
+if test -z "$with_c_locale_coercion"
+then
+ with_c_locale_coercion="yes"
+fi
+if test "$with_c_locale_coercion" != "no"
+then
+
+$as_echo "#define PY_COERCE_C_LOCALE 1" >>confdefs.h
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_c_locale_coercion" >&5
+$as_echo "$with_c_locale_coercion" >&6; }
+
+# Check for --with-c-locale-warning
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-c-locale-warning" >&5
+$as_echo_n "checking for --with-c-locale-warning... " >&6; }
+
+# Check whether --with-c-locale-warning was given.
+if test "${with_c_locale_warning+set}" = set; then :
+ withval=$with_c_locale_warning;
+fi
+
+
+if test -z "$with_c_locale_warning"
+then
+ with_c_locale_warning="yes"
+fi
+if test "$with_c_locale_warning" != "no"
+then
+
+$as_echo "#define PY_WARN_ON_C_LOCALE 1" >>confdefs.h
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_c_locale_warning" >&5
+$as_echo "$with_c_locale_warning" >&6; }
+
# Check for Valgrind support
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-valgrind" >&5
$as_echo_n "checking for --with-valgrind... " >&6; }
diff --git a/configure.ac b/configure.ac
index 67dfba3..b9c9f04 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3279,6 +3279,40 @@ then
fi
AC_MSG_RESULT($with_pymalloc)
+# Check for --with-c-locale-coercion
+AC_MSG_CHECKING(for --with-c-locale-coercion)
+AC_ARG_WITH(c-locale-coercion,
+ AS_HELP_STRING([--with(out)-c-locale-coercion],
+ [disable/enable C locale coercion to a UTF-8 based locale]))
+
+if test -z "$with_c_locale_coercion"
+then
+ with_c_locale_coercion="yes"
+fi
+if test "$with_c_locale_coercion" != "no"
+then
+ AC_DEFINE(PY_COERCE_C_LOCALE, 1,
+ [Define if you want to coerce the C locale to a UTF-8 based locale])
+fi
+AC_MSG_RESULT($with_c_locale_coercion)
+
+# Check for --with-c-locale-warning
+AC_MSG_CHECKING(for --with-c-locale-warning)
+AC_ARG_WITH(c-locale-warning,
+ AS_HELP_STRING([--with(out)-c-locale-warning],
+ [disable/enable locale compatibility warning in the C locale]))
+
+if test -z "$with_c_locale_warning"
+then
+ with_c_locale_warning="yes"
+fi
+if test "$with_c_locale_warning" != "no"
+then
+ AC_DEFINE(PY_WARN_ON_C_LOCALE, 1,
+ [Define to emit a locale compatibility warning in the C locale])
+fi
+AC_MSG_RESULT($with_c_locale_warning)
+
# Check for Valgrind support
AC_MSG_CHECKING([for --with-valgrind])
AC_ARG_WITH([valgrind],
diff --git a/pyconfig.h.in b/pyconfig.h.in
index b10c57f..0a6f3e2 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -1244,9 +1244,15 @@
/* Define as the preferred size in bits of long digits */
#undef PYLONG_BITS_IN_DIGIT
+/* Define if you want to coerce the C locale to a UTF-8 based locale */
+#undef PY_COERCE_C_LOCALE
+
/* Define to printf format modifier for Py_ssize_t */
#undef PY_FORMAT_SIZE_T
+/* Define to emit a locale compatibility warning in the C locale */
+#undef PY_WARN_ON_C_LOCALE
+
/* Define if you want to build an interpreter with many run-time checks. */
#undef Py_DEBUG

View File

@@ -0,0 +1,12 @@
diff --git a/Lib/ctypes/test/test_structures.py b/Lib/ctypes/test/test_structures.py
index 3eded77..ad7859a 100644
--- a/Lib/ctypes/test/test_structures.py
+++ b/Lib/ctypes/test/test_structures.py
@@ -392,6 +392,7 @@ class StructureTestCase(unittest.TestCase):
(1, 0, 0, 0, 0, 0))
self.assertRaises(TypeError, lambda: Z(1, 2, 3, 4, 5, 6, 7))
+ @unittest.skip('Fails on aarch64: http://bugs.python.org/issue29804')
def test_pass_by_value(self):
# This should mirror the structure in Modules/_ctypes/_ctypes_test.c
class X(Structure):

View File

@@ -1,6 +1,6 @@
--- Python-3.4.3/setup.py.orig 2015-02-25 05:27:46.000000000 -0600
+++ Python-3.4.3/setup.py 2015-05-05 11:18:04.030880000 -0500
@@ -1763,12 +1772,6 @@ class PyBuildExt(build_ext):
@@ -1849,12 +1849,6 @@ class PyBuildExt(build_ext):
include_dirs.append('/usr/X11/include')
added_lib_dirs.append('/usr/X11/lib')
@@ -13,7 +13,7 @@
# Check for BLT extension
if self.compiler.find_library_file(lib_dirs + added_lib_dirs,
'BLT8.0'):
@@ -1786,9 +1789,8 @@ class PyBuildExt(build_ext):
@@ -1872,9 +1866,8 @@ class PyBuildExt(build_ext):
if host_platform in ['aix3', 'aix4']:
libs.append('ld')

View File

@@ -1,7 +1,7 @@
--- Python-3.4.3/Lib/ctypes/__init__.py.orig 2015-02-25 05:27:44.000000000 -0600
+++ Python-3.4.3/Lib/ctypes/__init__.py 2015-05-05 11:39:39.945940300 -0500
@@ -434,7 +434,8 @@ pydll = LibraryLoader(PyDLL)
if _os.name in ("nt", "ce"):
@@ -431,7 +431,8 @@ pydll = LibraryLoader(PyDLL)
if _os.name == "nt":
pythonapi = PyDLL("python dll", None, _sys.dllhandle)
elif _sys.platform == "cygwin":
- pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
@@ -12,7 +12,7 @@
--- Python-3.4.3/Lib/ctypes/util.py.orig 2015-02-25 05:27:44.000000000 -0600
+++ Python-3.4.3/Lib/ctypes/util.py 2015-05-05 11:10:45.202655900 -0500
@@ -83,6 +83,25 @@ if os.name == "posix" and sys.platform =
@@ -80,6 +80,25 @@ if os.name == "posix" and sys.platform =
continue
return None
@@ -38,7 +38,7 @@
elif os.name == "posix":
# Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
import re, tempfile
@@ -258,6 +277,10 @@ def test():
@@ -328,6 +347,10 @@ def test():
print(cdll.LoadLibrary("libcrypto.dylib"))
print(cdll.LoadLibrary("libSystem.dylib"))
print(cdll.LoadLibrary("System.framework/System"))

View File

@@ -1,16 +0,0 @@
Avoid redefine error.
--- Python-3.1/Modules/main.c.orig 2009-02-12 09:55:38.000000000 -0600
+++ Python-3.1/Modules/main.c 2009-07-22 22:50:19.981100800 -0500
@@ -14,9 +14,11 @@
#include <windows.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
+#ifndef PATH_MAX
#define PATH_MAX MAXPATHLEN
#endif
#endif
+#endif
#ifdef _MSC_VER
#include <crtdbg.h>

View File

@@ -0,0 +1,12 @@
--- Python-3.6.0/Modules/main.c.orig 2017-02-08 04:28:31.840450700 -0500
+++ Python-3.6.0/Modules/main.c 2017-02-08 04:31:01.757513100 -0500
@@ -12,6 +12,9 @@
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
+#ifndef PATH_MAX
+#define PATH_MAX MAXPATHLEN
+#endif
#endif
#endif

View File

@@ -1,6 +1,6 @@
--- Python-3.2/Include/pyerrors.h.orig
+++ Python-3.2/Include/pyerrors.h
@@ -244,7 +244,7 @@ PyAPI_FUNC(int) PyErr_CheckSignals(void)
@@ -358,7 +358,7 @@ PyAPI_FUNC(int) PyErr_CheckSignals(void)
/* In signalmodule.c */
#ifndef Py_LIMITED_API

View File

@@ -1,6 +1,6 @@
--- Python-3.4.3/Lib/distutils/command/build_ext.py.orig 2015-02-25 05:27:44.000000000 -0600
+++ Python-3.4.3/Lib/distutils/command/build_ext.py 2015-05-05 11:15:40.666175000 -0500
@@ -696,9 +696,9 @@ class build_ext(Command):
@@ -716,9 +716,9 @@ class build_ext(Command):
else:
return ext.libraries
elif sys.platform[:6] == "cygwin":
@@ -14,7 +14,7 @@
return ext.libraries + [pythonlib]
--- Python-3.4.3/Makefile.pre.in.orig 2015-02-25 05:27:45.000000000 -0600
+++ Python-3.4.3/Makefile.pre.in 2015-05-05 11:15:40.672175700 -0500
@@ -638,7 +638,7 @@ $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION
@@ -674,7 +674,7 @@ $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION
# This rule builds the Cygwin Python DLL and import library if configured
# for a shared core library; otherwise, this rule is a noop.
@@ -25,7 +25,7 @@
$(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST); \
--- Python-3.4.3/Modules/makesetup.orig 2015-02-25 05:27:46.000000000 -0600
+++ Python-3.4.3/Modules/makesetup 2015-05-05 11:15:40.676676300 -0500
@@ -91,7 +91,7 @@ CYGWIN*) if test $libdir = .
@@ -92,7 +92,7 @@ CYGWIN*) if test $libdir = .
else
ExtraLibDir='$(LIBPL)'
fi
@@ -36,7 +36,7 @@
# Main loop
--- Python-3.4.3/configure.ac.orig 2015-02-25 05:27:46.000000000 -0600
+++ Python-3.4.3/configure.ac 2015-05-05 11:24:25.915873200 -0500
@@ -944,6 +944,7 @@ if test $enable_shared = "yes"; then
@@ -1144,6 +1144,7 @@ if test $enable_shared = "yes"; then
case $ac_sys_system in
CYGWIN*)
LDLIBRARY='libpython$(LDVERSION).dll.a'

View File

@@ -3,7 +3,7 @@ an implib but no static lib (e.g. sqlite3).
--- Python-3.2.3/Lib/distutils/cygwinccompiler.py.orig 2012-04-11 01:54:02.000000000 -0500
+++ Python-3.2.3/Lib/distutils/cygwinccompiler.py 2012-06-22 19:37:11.740576800 -0500
@@ -88,9 +88,7 @@ class CygwinCCompiler(UnixCCompiler):
@@ -92,9 +92,7 @@ class CygwinCCompiler(UnixCCompiler):
compiler_type = 'cygwin'
obj_extension = ".o"
static_lib_extension = ".a"
@@ -16,8 +16,8 @@ an implib but no static lib (e.g. sqlite3).
def __init__(self, verbose=0, dry_run=0, force=0):
--- Python-3.2.5/Lib/distutils/unixccompiler.py.orig 2013-07-30 16:39:21.092550800 -0500
+++ Python-3.2.5/Lib/distutils/unixccompiler.py 2013-07-30 20:01:52.168552600 -0500
@@ -79,6 +79,7 @@ class UnixCCompiler(CCompiler):
static_lib_format = shared_lib_format = dylib_lib_format = "lib%s%s"
@@ -81,6 +81,7 @@ class UnixCCompiler(CCompiler):
xcode_stub_lib_format = dylib_lib_format
if sys.platform == "cygwin":
exe_extension = ".exe"
+ dylib_lib_extension = ".dll.a"

View File

@@ -9,14 +9,14 @@
".dll",
#else /* !__CYGWIN__ */
"." SOABI ".so",
--- Python-3.4.3/configure.ac.orig 2015-02-25 05:27:46.000000000 -0600
+++ Python-3.4.3/configure.ac 2015-05-05 11:24:25.915873200 -0500
@@ -4096,7 +4097,7 @@ AC_MSG_RESULT($SOABI)
--- Python-3.6.0/configure.ac.orig 2017-02-08 04:39:39.793333600 -0500
+++ Python-3.6.0/configure.ac 2017-02-08 04:45:44.649752400 -0500
@@ -4614,7 +4614,7 @@
AC_SUBST(EXT_SUFFIX)
case $ac_sys_system in
- Linux*|GNU*)
+ Linux*|GNU*|CYGWIN*)
- Linux*|GNU*|Darwin)
+ Linux*|GNU*|Darwin|CYGWIN*)
EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX};;
*)
EXT_SUFFIX=${SHLIB_SUFFIX};;

View File

@@ -1,7 +1,7 @@
--- Python-3.4.3/Include/pythread.h.orig 2015-02-25 05:27:44.000000000 -0600
+++ Python-3.4.3/Include/pythread.h 2015-05-05 11:27:20.117994100 -0500
@@ -77,11 +77,11 @@ PyAPI_FUNC(int) PyThread_set_stacksize(s
PyAPI_FUNC(PyObject*) PyThread_GetInfo(void);
@@ -74,11 +74,11 @@ PyAPI_FUNC(int) PyThread_set_stacksize(s
#endif
/* Thread Local Storage (TLS) API */
-PyAPI_FUNC(int) PyThread_create_key(void);
@@ -17,20 +17,38 @@
/* Cleanup after a fork */
PyAPI_FUNC(void) PyThread_ReInitTLS(void);
--- Python-3.4.3/Python/pystate.c.orig 2015-02-25 05:27:46.000000000 -0600
+++ Python-3.4.3/Python/pystate.c 2015-05-05 11:27:20.122994700 -0500
@@ -37,7 +37,7 @@ static PyThread_type_lock head_mutex = N
--- Python-3.6.0/Python/pystate.c.orig 2017-02-08 04:54:10.265051500 -0500
+++ Python-3.6.0/Python/pystate.c 2017-02-08 05:00:43.539089400 -0500
@@ -47,7 +47,7 @@
GILState implementation
*/
static PyInterpreterState *autoInterpreterState = NULL;
-static int autoTLSkey = 0;
+static long autoTLSkey = 0L;
-static int autoTLSkey = -1;
+static long autoTLSkey = -1L;
#else
#define HEAD_INIT() /* Nothing */
#define HEAD_LOCK() /* Nothing */
--- Python-3.4.3/Python/thread_pthread.h.orig 2015-02-25 05:27:46.000000000 -0600
+++ Python-3.4.3/Python/thread_pthread.h 2015-05-05 11:27:20.126495200 -0500
@@ -603,28 +603,28 @@ _pythread_pthread_set_stacksize(size_t s
@@ -713,7 +713,7 @@ _PyGILState_Init(PyInterpreterState *i,
{
assert(i && t); /* must init with valid states */
autoTLSkey = PyThread_create_key();
- if (autoTLSkey == -1)
+ if (autoTLSkey == -1L)
Py_FatalError("Could not allocate TLS entry");
autoInterpreterState = i;
assert(PyThread_get_key_value(autoTLSkey) == NULL);
@@ -745,7 +745,7 @@ _PyGILState_Reinit(void)
{
PyThreadState *tstate = PyGILState_GetThisThreadState();
PyThread_delete_key(autoTLSkey);
- if ((autoTLSkey = PyThread_create_key()) == -1)
+ if ((autoTLSkey = PyThread_create_key()) == -1L)
Py_FatalError("Could not allocate TLS entry");
/* If the thread had an associated auto thread state, reassociate it with
--- Python-3.6.0/Python/thread_pthread.h.orig 2016-12-22 21:21:22.000000000 -0500
+++ Python-3.6.0/Python/thread_pthread.h 2017-02-08 05:18:45.791168100 -0500
@@ -603,36 +603,36 @@
#define Py_HAVE_NATIVE_TLS
@@ -40,8 +58,19 @@
{
pthread_key_t key;
int fail = pthread_key_create(&key, NULL);
- return fail ? -1 : key;
+ return fail ? -1L : (long) key;
if (fail)
- return -1;
- if (key > INT_MAX) {
+ return -1L;
+ if (key > LONG_MAX) {
/* Issue #22206: handle integer overflow */
pthread_key_delete(key);
errno = ENOMEM;
- return -1;
+ return -1L;
}
- return (int)key;
+ return (long)key;
}
void
@@ -64,7 +93,7 @@
{
int fail;
fail = pthread_setspecific(key, value);
@@ -632,7 +632,7 @@ PyThread_set_key_value(int key, void *va
@@ -640,7 +640,7 @@ PyThread_set_key_value(int key, void *va
}
void *

View File

@@ -1,6 +1,6 @@
--- Python-3.2.3/Modules/getpath.c.orig 2012-04-11 02:54:07.000000000 -0400
+++ Python-3.2.3/Modules/getpath.c 2012-06-14 13:33:30.179375000 -0400
@@ -491,6 +491,28 @@
@@ -551,6 +551,28 @@
if (isxfile(progpath))
break;

View File

@@ -1,8 +1,8 @@
--- Python-3.4.3/Modules/selectmodule.c.orig 2015-02-25 05:27:46.000000000 -0600
+++ Python-3.4.3/Modules/selectmodule.c 2015-05-05 13:58:58.914394500 -0500
@@ -4,6 +4,16 @@
have any value except INVALID_SOCKET.
*/
@@ -8,6 +8,16 @@
#define _GNU_SOURCE
#endif
+/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
+ 64 is too small (too many people have bumped into that limit).
@@ -17,7 +17,7 @@
#include "Python.h"
#include <structmember.h>
@@ -22,16 +32,6 @@
@@ -26,16 +36,6 @@
#undef HAVE_BROKEN_POLL
#endif

View File

@@ -1,6 +1,6 @@
--- Python-3.4.3/Modules/signalmodule.c.orig 2015-02-25 05:27:46.000000000 -0600
+++ Python-3.4.3/Modules/signalmodule.c 2015-05-05 16:10:10.357940900 -0500
@@ -741,7 +741,11 @@ fill_siginfo(siginfo_t *si)
@@ -957,7 +957,11 @@ fill_siginfo(siginfo_t *si)
PyStructSequence_SET_ITEM(result, 4, _PyLong_FromUid(si->si_uid));
PyStructSequence_SET_ITEM(result, 5,
PyLong_FromLong((long)(si->si_status)));

View File

@@ -1,6 +1,6 @@
--- Python-3.4.3/Modules/_struct.c.orig 2015-02-25 05:27:45.000000000 -0600
+++ Python-3.4.3/Modules/_struct.c 2015-05-05 16:17:01.509150400 -0500
@@ -1627,7 +1627,7 @@ unpackiter_iternext(unpackiterobject *se
@@ -1650,7 +1650,7 @@ unpackiter_iternext(unpackiterobject *se
}
static PyTypeObject unpackiter_type = {

View File

@@ -0,0 +1,11 @@
--- a/setup.py
+++ b/setup.py
@@ -2061,7 +2061,7 @@ class PyBuildExt(build_ext):
undef_macros = []
if '--with-system-libmpdec' in sysconfig.get_config_var("CONFIG_ARGS"):
include_dirs = []
- libraries = [':libmpdec.so.2']
+ libraries = [':libmpdec.dll.a']
sources = ['_decimal/_decimal.c']
depends = ['_decimal/docstrings.h']
else:

View File

@@ -1,16 +0,0 @@
--- Python-3.4.4/Lib/cgi.py 2015-12-21 00:00:58.000000000 -0600
+++ Python-3.4.4/Lib/cgi.py 2016-05-24 00:33:59.673777200 -0500
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
# NOTE: the above "/usr/local/bin/python" is NOT a mistake. It is
# intentionally NOT "/usr/bin/env python". On many systems
--- Python-3.4.4/Lib/encodings/rot_13.py 2015-12-21 00:00:58.000000000 -0600
+++ Python-3.4.4/Lib/encodings/rot_13.py 2016-05-24 00:34:13.983796900 -0500
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
""" Python Character Mapping Codec for ROT13.
This codec de/encodes from str to str.

View File

@@ -1,7 +1,7 @@
diff -urN a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py
--- a/Lib/distutils/sysconfig.py 2014-10-11 14:19:27.487874300 +0100
+++ b/Lib/distutils/sysconfig.py 2014-10-11 14:19:30.049020800 +0100
@@ -165,7 +165,23 @@
@@ -156,7 +156,23 @@
Mainly needed on Unix, so we can plug in the information that
varies across Unices and is stored in Python's Makefile.
"""
@@ -26,7 +26,7 @@ diff -urN a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py
if sys.platform == "darwin":
# Perform first-time customization of compiler-related
# config vars on OS X now that we know we need a compiler.
@@ -175,7 +191,6 @@
@@ -166,7 +182,6 @@
# that Python itself was built on. Also the user OS
# version and build tools may not support the same set
# of CPU architectures for universal builds.

14
python3/3.6-ftm.patch Normal file
View File

@@ -0,0 +1,14 @@
--- origsrc/Python-3.6.1rc1/configure.ac 2017-03-12 14:28:34.395001700 -0500
+++ src/Python-3.6.1rc1/configure.ac 2017-03-21 00:27:44.595584900 -0500
@@ -138,11 +138,6 @@ AC_DEFINE(_GNU_SOURCE, 1, [Define on Lin
AC_DEFINE(_NETBSD_SOURCE, 1, [Define on NetBSD to activate all library features])
# The later defininition of _XOPEN_SOURCE and _POSIX_C_SOURCE disables
-# certain features on FreeBSD, so we need __BSD_VISIBLE to re-enable
-# them.
-AC_DEFINE(__BSD_VISIBLE, 1, [Define on FreeBSD to activate all library features])
-
-# The later defininition of _XOPEN_SOURCE and _POSIX_C_SOURCE disables
# u_int on Irix 5.3. Defining _BSD_TYPES brings it back.
AC_DEFINE(_BSD_TYPES, 1, [Define on Irix to enable u_int])

View File

@@ -0,0 +1,19 @@
getrandom(2) without GRND_RANDOM is broken prior to Cygwin 2.8.0:
https://sourceware.org/git/?p=newlib-cygwin.git;a=commitdiff;h=6c420fa
--- origsrc/Python-3.6.1/configure.ac 2017-03-21 21:36:53.153779000 -0500
+++ src/Python-3.6.1/configure.ac 2017-03-21 21:42:30.270960000 -0500
@@ -5372,6 +5372,12 @@ AC_MSG_CHECKING(for the getrandom() func
AC_LINK_IFELSE(
[
AC_LANG_SOURCE([[
+ #ifdef __CYGWIN__
+ #include <cygwin/version.h>
+ #if CYGWIN_VERSION_DLL_MAJOR < 2008
+ #error getrandom(2) is broken prior to Cygwin 2.8.0
+ #endif
+ #endif
#include <sys/random.h>
int main() {

View File

@@ -11,10 +11,10 @@ diff -Naur Python-3.4.3-orig/config.guess Python-3.4.3/config.guess
p*:CYGWIN*:*)
echo powerpcle-unknown-cygwin
exit ;;
diff -Naur Python-3.4.3-orig/configure.ac Python-3.4.3/configure.ac
--- Python-3.4.3-orig/configure.ac 2015-05-07 09:55:44.998000000 +0300
+++ Python-3.4.3/configure.ac 2015-05-07 09:58:31.825600000 +0300
@@ -373,6 +373,9 @@
diff -Naur Python-3.6.0/configure.ac.orig Python-3.6.0/configure.ac
--- Python-3.6.0/configure.ac.orig 2017-02-08 09:14:49.544766100 -0500
+++ Python-3.6.0/configure.ac 2017-02-08 09:23:26.742594900 -0500
@@ -383,6 +383,9 @@
*-*-cygwin*)
ac_sys_system=Cygwin
;;
@@ -24,7 +24,7 @@ diff -Naur Python-3.4.3-orig/configure.ac Python-3.4.3/configure.ac
*)
# for now, limit cross builds to known configurations
MACHDEP="unknown"
@@ -397,6 +400,7 @@
@@ -407,6 +410,7 @@
case $MACHDEP in
linux*) MACHDEP="linux";;
cygwin*) MACHDEP="cygwin";;
@@ -32,7 +32,7 @@ diff -Naur Python-3.4.3-orig/configure.ac Python-3.4.3/configure.ac
darwin*) MACHDEP="darwin";;
irix646) MACHDEP="irix6";;
'') MACHDEP="unknown";;
@@ -418,6 +422,9 @@
@@ -428,6 +432,9 @@
*-*-cygwin*)
_host_cpu=
;;
@@ -42,16 +42,16 @@ diff -Naur Python-3.4.3-orig/configure.ac Python-3.4.3/configure.ac
*)
# for now, limit cross builds to known configurations
MACHDEP="unknown"
@@ -892,7 +899,7 @@
@@ -1087,7 +1094,7 @@
if test -z "$enable_shared"
then
then
case $ac_sys_system in
- CYGWIN*)
+ CYGWIN*|MSYS*)
enable_shared="yes";;
*)
enable_shared="no";;
@@ -947,6 +954,11 @@
@@ -1142,6 +1149,11 @@
BLDLIBRARY='-L. -lpython$(LDVERSION)'
DLLLIBRARY='libpython$(LDVERSION).dll'
;;
@@ -63,7 +63,7 @@ diff -Naur Python-3.4.3-orig/configure.ac Python-3.4.3/configure.ac
SunOS*)
LDLIBRARY='libpython$(LDVERSION).so'
BLDLIBRARY='-Wl,-R,$(LIBDIR) -L. -lpython$(LDVERSION)'
@@ -998,7 +1010,7 @@
@@ -1188,7 +1200,7 @@
else # shared is disabled
PY_ENABLE_SHARED=0
case $ac_sys_system in
@@ -72,7 +72,7 @@ diff -Naur Python-3.4.3-orig/configure.ac Python-3.4.3/configure.ac
BLDLIBRARY='$(LIBRARY)'
LDLIBRARY='libpython$(LDVERSION).dll.a'
;;
@@ -1056,7 +1068,7 @@
@@ -1238,7 +1250,7 @@
AC_SUBST(LN)
if test -z "$LN" ; then
case $ac_sys_system in
@@ -81,7 +81,7 @@ diff -Naur Python-3.4.3-orig/configure.ac Python-3.4.3/configure.ac
*) LN=ln;;
esac
fi
@@ -1962,7 +1974,7 @@
@@ -2380,7 +2392,7 @@
*) SHLIB_SUFFIX=.sl;;
esac
;;
@@ -90,7 +90,7 @@ diff -Naur Python-3.4.3-orig/configure.ac Python-3.4.3/configure.ac
*) SHLIB_SUFFIX=.so;;
esac
fi
@@ -2100,7 +2112,7 @@
@@ -2518,7 +2530,7 @@
SCO_SV*)
LDSHARED='$(CC) -Wl,-G,-Bexport'
LDCXXSHARED='$(CXX) -Wl,-G,-Bexport';;
@@ -99,7 +99,7 @@ diff -Naur Python-3.4.3-orig/configure.ac Python-3.4.3/configure.ac
LDSHARED="gcc -shared -Wl,--enable-auto-image-base"
LDCXXSHARED="g++ -shared -Wl,--enable-auto-image-base";;
*) LDSHARED="ld";;
@@ -2186,7 +2198,7 @@
@@ -2606,7 +2618,7 @@
LINKFORSHARED="-Xlinker --export-dynamic"
fi;;
esac;;
@@ -108,7 +108,7 @@ diff -Naur Python-3.4.3-orig/configure.ac Python-3.4.3/configure.ac
if test $enable_shared = "no"
then
LINKFORSHARED='-Wl,--out-implib=$(LDLIBRARY)'
@@ -2208,7 +2220,7 @@
@@ -2628,7 +2640,7 @@
if test ! "$LIBRARY" = "$LDLIBRARY"
then
case $ac_sys_system in
@@ -117,7 +117,7 @@ diff -Naur Python-3.4.3-orig/configure.ac Python-3.4.3/configure.ac
# Cygwin needs CCSHARED when building extension DLLs
# but not when building the interpreter DLL.
CFLAGSFORSHARED='';;
@@ -2637,7 +2649,7 @@
@@ -3061,7 +3073,7 @@
fi
AC_CHECK_FUNCS(pthread_sigmask,
[case $ac_sys_system in
@@ -126,19 +126,28 @@ diff -Naur Python-3.4.3-orig/configure.ac Python-3.4.3/configure.ac
AC_DEFINE(HAVE_BROKEN_PTHREAD_SIGMASK, 1,
[Define if pthread_sigmask() does not work on your system.])
;;
@@ -4097,7 +4109,7 @@
@@ -4609,7 +4621,7 @@
AC_SUBST(EXT_SUFFIX)
case $ac_sys_system in
- Linux*|GNU*|CYGWIN*)
+ Linux*|GNU*|CYGWIN*|MSYS*)
- Linux*|GNU*|Darwin|CYGWIN*)
+ Linux*|GNU*|Darwin|CYGWIN*|MSYS*)
EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX};;
*)
EXT_SUFFIX=${SHLIB_SUFFIX};;
diff -Naur Python-3.4.3-orig/Lib/asyncio/base_events.py Python-3.4.3/Lib/asyncio/base_events.py
--- Python-3.4.3-orig/Lib/asyncio/base_events.py 2015-02-25 14:27:44.000000000 +0300
+++ Python-3.4.3/Lib/asyncio/base_events.py 2015-05-07 09:58:31.825600000 +0300
@@ -784,7 +784,7 @@
diff -Naur Python-3.6.0/Lib/asyncio/base_events.py.orig Python-3.6.0/Lib/asyncio/base_events.py
--- Python-3.6.0/Lib/asyncio/base_events.py.orig 2016-12-22 21:21:19.000000000 -0500
+++ Python-3.6.0/Lib/asyncio/base_events.py 2017-02-08 08:59:15.247005800 -0500
@@ -895,7 +895,7 @@
exceptions = []
if reuse_address is None:
- reuse_address = os.name == 'posix' and sys.platform != 'cygwin'
+ reuse_address = os.name == 'posix' and sys.platform != 'cygwin' and sys.platform != 'msys'
for ((family, proto),
(local_address, remote_address)) in addr_pairs_info:
@@ -997,7 +997,7 @@
AF_INET6 = getattr(socket, 'AF_INET6', 0)
if reuse_address is None:
@@ -146,7 +155,7 @@ diff -Naur Python-3.4.3-orig/Lib/asyncio/base_events.py Python-3.4.3/Lib/asyncio
+ reuse_address = os.name == 'posix' and sys.platform != 'cygwin' and sys.platform != 'msys'
sockets = []
if host == '':
host = None
hosts = [None]
diff -Naur Python-3.4.3-orig/Lib/ctypes/__init__.py Python-3.4.3/Lib/ctypes/__init__.py
--- Python-3.4.3-orig/Lib/ctypes/__init__.py 2015-05-07 09:55:34.078000000 +0300
+++ Python-3.4.3/Lib/ctypes/__init__.py 2015-05-07 09:58:31.825600000 +0300
@@ -158,9 +167,9 @@ diff -Naur Python-3.4.3-orig/Lib/ctypes/__init__.py Python-3.4.3/Lib/ctypes/__in
__version__ = "1.1.0"
@@ -433,9 +433,8 @@
@@ -430,9 +430,8 @@
if _os.name in ("nt", "ce"):
if _os.name == "nt":
pythonapi = PyDLL("python dll", None, _sys.dllhandle)
-elif _sys.platform == "cygwin":
- pythonapi = PyDLL("libpython%d.%d%s.dll" % \
@@ -173,8 +182,8 @@ diff -Naur Python-3.4.3-orig/Lib/ctypes/__init__.py Python-3.4.3/Lib/ctypes/__in
diff -Naur Python-3.4.3-orig/Lib/ctypes/test/test_loading.py Python-3.4.3/Lib/ctypes/test/test_loading.py
--- Python-3.4.3-orig/Lib/ctypes/test/test_loading.py 2015-02-25 14:27:44.000000000 +0300
+++ Python-3.4.3/Lib/ctypes/test/test_loading.py 2015-05-07 09:58:31.841200000 +0300
@@ -15,6 +15,8 @@
libc_name = "coredll"
@@ -13,6 +13,8 @@
libc_name = find_library("c")
elif sys.platform == "cygwin":
libc_name = "cygwin1.dll"
+ elif sys.platform == "msys":
@@ -185,7 +194,7 @@ diff -Naur Python-3.4.3-orig/Lib/ctypes/test/test_loading.py Python-3.4.3/Lib/ct
diff -Naur Python-3.4.3-orig/Lib/ctypes/util.py Python-3.4.3/Lib/ctypes/util.py
--- Python-3.4.3-orig/Lib/ctypes/util.py 2015-05-07 09:55:34.078000000 +0300
+++ Python-3.4.3/Lib/ctypes/util.py 2015-05-07 10:01:40.261800000 +0300
@@ -83,7 +83,7 @@
@@ -80,7 +80,7 @@
continue
return None
@@ -194,7 +203,7 @@ diff -Naur Python-3.4.3-orig/Lib/ctypes/util.py Python-3.4.3/Lib/ctypes/util.py
def find_library(name):
for libdir in ['/usr/lib', '/usr/local/lib']:
for libext in ['lib%s.dll.a' % name, 'lib%s.a' % name]:
@@ -281,6 +281,10 @@
@@ -351,6 +351,10 @@
print(cdll.LoadLibrary("cygbz2-1.dll"))
print(cdll.LoadLibrary("cygcrypt-0.dll"))
print(find_library("crypt"))
@@ -228,7 +237,7 @@ diff -Naur Python-3.4.3-orig/Lib/distutils/ccompiler.py Python-3.4.3/Lib/distuti
diff -Naur Python-3.4.3-orig/Lib/distutils/command/build_ext.py Python-3.4.3/Lib/distutils/command/build_ext.py
--- Python-3.4.3-orig/Lib/distutils/command/build_ext.py 2015-05-07 09:55:34.811200000 +0300
+++ Python-3.4.3/Lib/distutils/command/build_ext.py 2015-05-07 09:58:31.856800000 +0300
@@ -223,7 +223,7 @@
@@ -217,7 +217,7 @@
# for extensions under Cygwin and AtheOS Python's library directory must be
# appended to library_dirs
@@ -237,7 +246,7 @@ diff -Naur Python-3.4.3-orig/Lib/distutils/command/build_ext.py Python-3.4.3/Lib
if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")):
# building third party extensions
self.library_dirs.append(os.path.join(sys.prefix, "lib",
@@ -695,7 +695,7 @@
@@ -715,7 +715,7 @@
return ext.libraries + [pythonlib]
else:
return ext.libraries
@@ -258,7 +267,7 @@ diff -Naur Python-3.4.3-orig/Lib/distutils/cygwinccompiler.py Python-3.4.3/Lib/d
diff -Naur Python-3.4.3-orig/Lib/distutils/sysconfig.py Python-3.4.3/Lib/distutils/sysconfig.py
--- Python-3.4.3-orig/Lib/distutils/sysconfig.py 2015-05-07 09:55:46.604800000 +0300
+++ Python-3.4.3/Lib/distutils/sysconfig.py 2015-05-07 10:07:03.222600000 +0300
@@ -166,7 +166,7 @@
@@ -157,7 +157,7 @@
varies across Unices and is stored in Python's Makefile.
"""
global _config_vars
@@ -267,7 +276,7 @@ diff -Naur Python-3.4.3-orig/Lib/distutils/sysconfig.py Python-3.4.3/Lib/distuti
# Note that cygwin use posix build and 'unix' compiler.
# If build is not based on posix then we must predefine
# some environment variables corresponding to posix
@@ -181,7 +181,7 @@
@@ -172,7 +172,7 @@
_config_vars['AR'] = "ar"
_config_vars['ARFLAGS'] = "rc"
@@ -288,19 +297,19 @@ diff -Naur Python-3.4.3-orig/Lib/distutils/tests/support.py Python-3.4.3/Lib/dis
def mkdtemp(self):
"""Create a temporary directory that will be cleaned up.
diff -Naur Python-3.4.3-orig/Lib/distutils/unixccompiler.py Python-3.4.3/Lib/distutils/unixccompiler.py
--- Python-3.4.3-orig/Lib/distutils/unixccompiler.py 2015-05-07 09:55:44.108800000 +0300
+++ Python-3.4.3/Lib/distutils/unixccompiler.py 2015-05-07 09:58:31.856800000 +0300
@@ -77,7 +77,7 @@
shared_lib_extension = ".so"
dylib_lib_extension = ".dylib"
diff -Naur Python-3.6.0/Lib/distutils/unixccompiler.py.orig Python-3.6.0/Lib/distutils/unixccompiler.py
--- Python-3.6.0/Lib/distutils/unixccompiler.py.orig 2017-02-08 08:22:40.592815800 -0500
+++ Python-3.6.0/Lib/distutils/unixccompiler.py 2017-02-08 08:32:38.946960100 -0500
@@ -79,7 +79,7 @@
xcode_stub_lib_extension = ".tbd"
static_lib_format = shared_lib_format = dylib_lib_format = "lib%s%s"
xcode_stub_lib_format = dylib_lib_format
- if sys.platform == "cygwin":
+ if sys.platform in ["cygwin", "msys"]:
exe_extension = ".exe"
dylib_lib_extension = ".dll.a"
@@ -223,7 +223,7 @@
@@ -225,7 +225,7 @@
# the configuration data stored in the Python installation, so
# we use this hack.
compiler = os.path.basename(sysconfig.get_config_var("CC"))
@@ -308,7 +317,7 @@ diff -Naur Python-3.4.3-orig/Lib/distutils/unixccompiler.py Python-3.4.3/Lib/dis
+ if sys.platform[:6] == "darwin" or sys.platform[:6] == "cygwin" or sys.platform[:4] == "msys":
# MacOSX's linker doesn't understand the -R flag at all
return "-L" + dir
elif sys.platform[:5] == "hp-ux":
elif sys.platform[:7] == "freebsd":
diff -Naur Python-3.4.3-orig/Lib/distutils/util.py Python-3.4.3/Lib/distutils/util.py
--- Python-3.4.3-orig/Lib/distutils/util.py 2015-02-25 14:27:44.000000000 +0300
+++ Python-3.4.3/Lib/distutils/util.py 2015-05-07 09:58:31.872400000 +0300
@@ -325,22 +334,22 @@ diff -Naur Python-3.4.3-orig/Lib/distutils/util.py Python-3.4.3/Lib/distutils/ut
elif osname[:6] == "darwin":
import _osx_support, distutils.sysconfig
osname, release, machine = _osx_support.get_platform_osx(
diff -Naur Python-3.4.3-orig/Lib/importlib/_bootstrap.py Python-3.4.3/Lib/importlib/_bootstrap.py
--- Python-3.4.3-orig/Lib/importlib/_bootstrap.py 2015-02-25 14:27:44.000000000 +0300
+++ Python-3.4.3/Lib/importlib/_bootstrap.py 2015-05-07 09:58:31.872400000 +0300
diff -Naur Python-3.6.0/Lib/importlib/_bootstrap_external.py.orig Python-3.6.0/Lib/importlib/_bootstrap_external.py
--- Python-3.6.0/Lib/importlib/_bootstrap_external.py.orig 2017-02-08 08:43:48.316520300 -0500
+++ Python-3.6.0/Lib/importlib/_bootstrap_external.py 2017-02-08 08:44:28.339129300 -0500
@@ -22,7 +22,7 @@
# Bootstrap-related code ######################################################
-_CASE_INSENSITIVE_PLATFORMS = 'win', 'cygwin', 'darwin'
+_CASE_INSENSITIVE_PLATFORMS = 'win', 'cygwin', 'msys', 'darwin'
def _make_relax_case():
_CASE_INSENSITIVE_PLATFORMS_STR_KEY = 'win',
-_CASE_INSENSITIVE_PLATFORMS_BYTES_KEY = 'cygwin', 'darwin'
+_CASE_INSENSITIVE_PLATFORMS_BYTES_KEY = 'cygwin', 'msys', 'darwin'
_CASE_INSENSITIVE_PLATFORMS = (_CASE_INSENSITIVE_PLATFORMS_BYTES_KEY
+ _CASE_INSENSITIVE_PLATFORMS_STR_KEY)
diff -Naur Python-3.4.3-orig/Lib/sysconfig.py Python-3.4.3/Lib/sysconfig.py
--- Python-3.4.3-orig/Lib/sysconfig.py 2015-02-25 14:27:44.000000000 +0300
+++ Python-3.4.3/Lib/sysconfig.py 2015-05-07 09:58:34.087600000 +0300
@@ -671,6 +671,13 @@
@@ -683,6 +683,13 @@
m = rel_re.match(release)
if m:
release = m.group()
@@ -357,7 +366,7 @@ diff -Naur Python-3.4.3-orig/Lib/sysconfig.py Python-3.4.3/Lib/sysconfig.py
diff -Naur Python-3.4.3-orig/Lib/tempfile.py Python-3.4.3/Lib/tempfile.py
--- Python-3.4.3-orig/Lib/tempfile.py 2015-02-25 14:27:44.000000000 +0300
+++ Python-3.4.3/Lib/tempfile.py 2015-05-07 09:58:35.086000000 +0300
@@ -467,7 +467,7 @@
@@ -557,7 +557,7 @@
_os.close(fd)
raise
@@ -369,19 +378,19 @@ diff -Naur Python-3.4.3-orig/Lib/tempfile.py Python-3.4.3/Lib/tempfile.py
diff -Naur Python-3.4.3-orig/Lib/test/test_curses.py Python-3.4.3/Lib/test/test_curses.py
--- Python-3.4.3-orig/Lib/test/test_curses.py 2015-02-25 14:27:45.000000000 +0300
+++ Python-3.4.3/Lib/test/test_curses.py 2015-05-07 09:58:35.086000000 +0300
@@ -33,6 +33,8 @@
@@ -40,6 +40,8 @@
"$TERM=%r, calling initscr() may cause exit" % term)
@unittest.skipIf(sys.platform == "cygwin",
"cygwin's curses mostly just hangs")
+@unittest.skipIf(sys.platform == "msys",
+ "msys's curses mostly just hangs")
class TestCurses(unittest.TestCase):
@classmethod
def setUpClass(cls):
diff -Naur Python-3.4.3-orig/Lib/test/test_importlib/util.py Python-3.4.3/Lib/test/test_importlib/util.py
--- Python-3.4.3-orig/Lib/test/test_importlib/util.py 2015-02-25 14:27:45.000000000 +0300
+++ Python-3.4.3/Lib/test/test_importlib/util.py 2015-05-07 09:58:35.086000000 +0300
@@ -31,7 +31,7 @@
@@ -85,7 +85,7 @@
CASE_INSENSITIVE_FS = True
# Windows is the only OS that is *always* case-insensitive
# (OS X *can* be case-sensitive).
@@ -393,7 +402,7 @@ diff -Naur Python-3.4.3-orig/Lib/test/test_importlib/util.py Python-3.4.3/Lib/te
diff -Naur Python-3.4.3-orig/Lib/test/test_mailbox.py Python-3.4.3/Lib/test/test_mailbox.py
--- Python-3.4.3-orig/Lib/test/test_mailbox.py 2015-02-25 14:27:45.000000000 +0300
+++ Python-3.4.3/Lib/test/test_mailbox.py 2015-05-07 09:58:35.086000000 +0300
@@ -596,7 +596,7 @@
@@ -591,7 +591,7 @@
def setUp(self):
TestMailbox.setUp(self)
@@ -417,7 +426,7 @@ diff -Naur Python-3.4.3-orig/Lib/test/test_netrc.py Python-3.4.3/Lib/test/test_n
diff -Naur Python-3.4.3-orig/Lib/test/test_shutil.py Python-3.4.3/Lib/test/test_shutil.py
--- Python-3.4.3-orig/Lib/test/test_shutil.py 2015-02-25 14:27:45.000000000 +0300
+++ Python-3.4.3/Lib/test/test_shutil.py 2015-05-07 09:58:35.117200000 +0300
@@ -99,7 +99,7 @@
@@ -97,7 +97,7 @@
super(TestShutil, self).tearDown()
while self.tempdirs:
d = self.tempdirs.pop()
@@ -426,7 +435,7 @@ diff -Naur Python-3.4.3-orig/Lib/test/test_shutil.py Python-3.4.3/Lib/test/test_
def mkdtemp(self):
@@ -200,7 +200,7 @@
@@ -196,7 +196,7 @@
@unittest.skipUnless(hasattr(os, 'chmod'), 'requires os.chmod()')
@@ -450,8 +459,8 @@ diff -Naur Python-3.4.3-orig/Lib/tkinter/test/test_tkinter/test_loadtk.py Python
diff -Naur Python-3.4.3-orig/Modules/makesetup Python-3.4.3/Modules/makesetup
--- Python-3.4.3-orig/Modules/makesetup 2015-05-07 09:55:42.954400000 +0300
+++ Python-3.4.3/Modules/makesetup 2015-05-07 09:58:35.132800000 +0300
@@ -85,7 +85,7 @@
# Setup to link with extra libraries when makeing shared extensions.
@@ -86,7 +86,7 @@
# Setup to link with extra libraries when making shared extensions.
# Currently, only Cygwin needs this baggage.
case `uname -s` in
-CYGWIN*) if test $libdir = .
@@ -462,7 +471,7 @@ diff -Naur Python-3.4.3-orig/Modules/makesetup Python-3.4.3/Modules/makesetup
diff -Naur Python-3.4.3-orig/setup.py Python-3.4.3/setup.py
--- Python-3.4.3-orig/setup.py 2015-05-07 09:55:33.329200000 +0300
+++ Python-3.4.3/setup.py 2015-05-07 09:58:35.132800000 +0300
@@ -317,7 +317,7 @@
@@ -361,7 +361,7 @@
# Workaround for Cygwin: Cygwin currently has fork issues when many
# modules have been imported
@@ -471,7 +480,7 @@ diff -Naur Python-3.4.3-orig/setup.py Python-3.4.3/setup.py
self.announce('WARNING: skipping import check for Cygwin-based "%s"'
% ext.name)
return
@@ -1263,7 +1263,7 @@
@@ -1339,7 +1339,7 @@
exts.append( Extension('resource', ['resource.c']) )
# Sun yellow pages. Some systems have the functions in libc.
@@ -480,7 +489,7 @@ diff -Naur Python-3.4.3-orig/setup.py Python-3.4.3/setup.py
find_file('rpcsvc/yp_prot.h', inc_dirs, []) is not None):
if (self.compiler.find_library_file(lib_dirs, 'nsl')):
libs = ['nsl']
@@ -1500,6 +1500,10 @@
@@ -1577,6 +1577,10 @@
macros = dict()
libraries = []
@@ -491,3 +500,15 @@ diff -Naur Python-3.4.3-orig/setup.py Python-3.4.3/setup.py
elif host_platform in ('freebsd4', 'freebsd5', 'freebsd6', 'freebsd7', 'freebsd8'):
# FreeBSD's P1003.1b semaphore support is very experimental
# and has many known problems. (as of June 2008)
diff -aur Python-3.6.0/Lib/test/test_asyncio/test_base_events.py.orig Python-3.6.0/Lib/test/test_asyncio/test_base_events.py
--- Python-3.6.0/Lib/test/test_asyncio/test_base_events.py.orig 2017-02-08 15:03:29.184676300 -0500
+++ Python-3.6.0/Lib/test/test_asyncio/test_base_events.py 2017-02-08 15:49:05.932013200 -0500
@@ -1576,7 +1576,7 @@
sock = transport.get_extra_info('socket')
reuse_address_default_on = (
- os.name == 'posix' and sys.platform != 'cygwin')
+ os.name == 'posix' and sys.platform != 'cygwin' and sys.platform != 'msys')
reuseport_supported = hasattr(socket, 'SO_REUSEPORT')
if reuse_address_default_on:

View File

@@ -1,6 +1,6 @@
--- a/Lib/posixpath.py 2013-11-27 06:57:57.000000000 +0000
+++ b/Lib/posixpath.py 2014-02-21 10:43:34.423932700 +0000
@@ -41,6 +41,12 @@
@@ -42,6 +42,12 @@
else:
return '/'
@@ -13,9 +13,9 @@
# Normalize the case of a pathname. Trivial in Posix, string.lower on Mac.
# On MS-DOS this may also turn slashes into backslashes; however, other
# normalizations (such as optimizing '../' away) are not allowed
@@ -61,7 +67,12 @@
def isabs(s):
@@ -63,7 +69,12 @@
"""Test whether a path is absolute"""
s = os.fspath(s)
sep = _get_sep(s)
- return s.startswith(sep)
+ altsep = _get_altsep(s)

View File

@@ -2,15 +2,15 @@
# Contributor: Ray Donnelly <mingw.android@gmail.com>
pkgname=python
pkgver=3.4.5
pkgver=3.6.1
pkgrel=1
_pybasever=3.4
_pybasever=3.6
pkgdesc="Next generation of the python high-level scripting language"
arch=('i686' 'x86_64')
license=('custom')
url="https://www.python.org/"
depends=('libbz2' 'libexpat' 'libffi' 'liblzma' 'ncurses' 'libopenssl' 'libreadline' 'libsqlite' 'zlib')
makedepends=('libbz2-devel' 'libexpat-devel' 'libsqlite-devel' 'libffi-devel' 'ncurses-devel' 'libreadline-devel' 'liblzma-devel' 'openssl-devel' 'zlib-devel')
depends=('libbz2' 'libexpat' 'libffi' 'liblzma' 'ncurses' 'libopenssl' 'libreadline' 'mpdecimal' 'libsqlite' 'zlib')
makedepends=('libbz2-devel' 'libexpat-devel' 'mpdecimal-devel' 'libsqlite-devel' 'libffi-devel' 'ncurses-devel' 'libreadline-devel' 'liblzma-devel' 'openssl-devel' 'zlib-devel')
#optdepends=('tk: for tkinter' 'sqlite')
provides=('python3')
replaces=('python3')
@@ -20,43 +20,77 @@ source=(https://www.python.org/ftp/python/${pkgver%rc*}/Python-${pkgver}.tar.xz
002-3.1-enable-new-dtags.patch
003-3.4-tkinter-cygwin.patch
004-3.4-ctypes-cygwin.patch
005-3.1-PATH_MAX.patch
005-3.6-PATH_MAX.patch
006-3.1-ncurses-abi6.patch
007-3.2-export-PySignal_SetWakeupFd.patch
008-3.4-distutils-soname.patch
009-3.2-distutils-shlibext.patch
010-3.4-pep3149-cygwin.patch
011-3.4-thread-cygwin64.patch
010-3.6-pep3149-cygwin.patch
011-3.6-thread-cygwin64.patch
012-3.2-getpath-exe-extension.patch
013-3.4-select-cygwin.patch
014-3.4-signal-cygwin.patch
015-3.4-struct-cygwin.patch
017-3.4-shebang.patch
025-MINGW-compiler-customize-mingw-cygwin-compilers.patch
900-msysize.patch
910-libffi-msys2.patch
920-allow-win-drives-in-os-path-isabs.patch)
sha256sums=('ee64b1c8a47461009abf25252332d29a4e587cb4f0c1c96aa793a3732e9d898a'
'4fadf48332d86266c0fa30548dba56ca295d936d556b879972aea81290ad7520'
'4db598b2bf7ae3767a7ab84501ba9cc0d2b26d2b94e6c2652884143b40bf9820'
'fc27003dda4a96cc5154faec447183c325cb7508339de58e7152207ecd19bfa5'
'7b688e9103af3eed42999c418c29a26c973020eec89cfc35c5a63c03c42ec9d9'
'bb5a438ecb655e1e2e54372e3980abafc667c2e229dda0f269eccd79ed72ed4e'
3.6-ftm.patch
3.6-getrandom.patch
025-MINGW-compiler-customize-mingw-cygwin-compilers.patch
900-msysize.patch
910-libffi-msys2.patch
920-allow-win-drives-in-os-path-isabs.patch
dont-make-libpython-readonly.patch
00155-avoid-ctypes-thunks.patch
00157-uid-gid-overflows.patch
00170-gc-assertions.patch
00178-dont-duplicate-flags-in-sysconfig.patch
00188-fix-lib2to3-tests-when-hashlib-doesnt-compile-properly.patch
00189-add-rewheel-module.patch
00206-remove-hf-from-arm-triplet.patch
00243-fix-mips64-triplet.patch
00249-fix-out-of-tree-dtrace-builds.patch
00252-add-executable-option.patch
00260-require-setuptools-dependencies.patch
00261-use-proper-command-line-parsing-in-_testembed.patch
00264-skip-test-failing-on-aarch64.patch
python3-powerppc-arch.patch
016-3.6-mpdec-cygwin.patch)
sha256sums=('a01810ddfcec216bcdb357a84bfaafdfaa0ca42bbdaa4cb7ff74f5a9961e4041'
'de52e4722a6902e09dd6f343fdac0e7d45339f89386c8096b9c582c31aeb82e7'
'b5a787f02811f46800f98bf242448770492643a4431771bb4283e6ae97016263'
'4d7601b62e73c04553d22d480a873983a28b11df1f06be6898014453ce04afc3'
'edf33a790c7c0903b8edbc8e68baf91cf2d34c13e607503d1cc7f270186ea76c'
'85499ca7f1016087df48223e4712db60930aa97a2eae634d2d955fb71bdfc864'
'8a138293fa5ad3a7522e00194994fecc8967c6a71822127391e4d756b2280e74'
'8e8c554e5f2e3a5765a3487e1b80f03c4e377f878548730fe43f0860a9dc0108'
'3e557cbd67246c33da738e80de59e56352e0822ce604cee8d12df50c311f7c12'
'8e1ea7683ccd3f4b45f97075c125be86f28d4db9a342a257ea2f138936fd80a4'
'df1e72d5dc55c480d15a039dfe7ba2b73700e6ec6fac860ed2e6152e55ca9f29'
'a5250b1d4b38d90b8bb03ba93642c1b6d44b51d76c3659c9360363610b7cc698'
'e7e3aa7adbee914a30aad34dcc6fe0beb036580edcefdfae596c55b408c450c9'
'63189f7e171eaa082af1f6315f14cc1aebb4b3b431ec0e120d1b7b178263c39f'
'98ec5d02475388ff899bd59566b37996895cd2a049c40d2845c052816e4875ff'
'4d2331bf3af0beb8528c0aad4669b4d58093481f4f8120e80a71645d98565495'
'46e37c95e4acd527fd60168ae1513553f7d466ec30f0c7ba4a4a1d1ee5344311'
'0f96dc585398d3d04e2f02e5e398f2d81f65cbd6544999e5acf38d985975caba'
'e21c674a9454f3ff441ca2d298889616ec126defaa29fc7469e74427b1df44bb'
'1ab20d38926aa85e638317620c29c484fcbbc228cd7cdf9543c29b750556d23f'
'7a7425b5fa28b7692bafff226981650748d7f40a42a711378b9a9c8b23a98060'
'6ead37259110c28b16e35e05c93c82b46aa0fbb5152ff61bdaf1eea5f1ad01da'
'f5b67408d39d3fda539ea90b12c48a05bd950b38460ec3e6a688e3377b071ed3'
'73083aebc0ed9ce34bd52b1aeef73f7bcb3b27dff81967276562101e41dfaa5a'
'c09d3612d748852def0bcd1cb36dda7bd24366ed6b386743c800c7cb21eb0298'
'e668b749e5f0bc584262add2cd7fffb2f6f32393a14918029d791012eda930f3'
'30564663c1f2cd7d0d10a2b07eceb139534f17bc3a38dc8daafad0d5111e8bbc'
'505c736e35772835b06597de552217e4838052b759d1350b65b4cb079b6403f3'
'7c4774d40b18d5a4ef4f3e05d53cc2d4d0ca3d0f970b3af7f7164ac8be0a4c56'
'd1f4b04c59bce82532f5ff5fdae4dda7f03f87b2ab03da61bee008915ce2ddc9'
'5b1083e9b50e149d623d863dee38ac1fb8d142f1bb78c8a01dcb09bfd97f4118'
'9bbe2921b16ba689472a54de8aa5921cbf7eb9a3921ae1c9697d44ffaf8f414f'
'7e587d145db24fbee1c7c7b96a4d7f247d132315384d551005ffb39b51f41906'
'a1edaeda01466268cd75eb50c440b1ee76eafea334b14515b3cfb66c1e38d0e9')
'387a2b7931fb4958e2526991760d85677f44fa13cff0aeb0f41a267f1f7fd214'
'f8b15d7079bfa1707e5bea78f600a0fca2077c25428c2bac5793b19b408f276e'
'7a3f8f43b9c9eecb65d80b60c875344950a8b55082401830599d091548a3a985'
'13519ee9358cc5378b3fab60501b9db4d56e86d0b69da8b9841989d437492c7e'
'e70369c7096b8204b0af968679d493bf272996df637e53ca6fad4a236f1a2b02'
'4e7ce358f0650545ee9ae112b26cee4dce8f763eac5612f556e975ad38056fb8'
'd04b7bec35418c699358c8140a7213efe1a133772972715800b7a6101e0d699a'
'f093014bf6c0b64a662ea7d41812e6bbe33726af2b607062a3dbae226691948f'
'd61273d74f734bcdef933531cbd3cc77cf79b5826837cbd40cd48e5b1bc76072'
'f81a0a0907e65a00bff1a1ede4827a33984a6f2aee3aed2ce6a2423decdfd26d'
'8fa156c7c3615f1e9affb51b536d568c69811852a3f6c9afa43746365c8a9486'
'735257fc216be2300b35dab8a97ff76199cc98d69b0bce36f099d476fb0f30e5'
'df334d534d225587a1a90e143be7f788cc2a1b8ae30f6d378cef0ef83ef3ced4'
'bb21618672c91f549e9ba3c9fd63f419670f9e3aa051f23e773fc08fbecac80f'
'843c26c4325f1d42f30f6e1fac5e6ff06122903bd37aa67683838ae49609e276'
'0de3e6e67d86f7e3593c504385399537b42920aca94329424cc8b1d65ae2ac4f'
'e3ef181333d5c9d20297849a46a68271a2190b7fc611c40c68c1ae240fa7ec36')
prepare() {
cd "${srcdir}/Python-${pkgver}"
@@ -67,23 +101,44 @@ prepare() {
patch -p1 -i ${srcdir}/002-3.1-enable-new-dtags.patch
patch -p1 -i ${srcdir}/003-3.4-tkinter-cygwin.patch
patch -p1 -i ${srcdir}/004-3.4-ctypes-cygwin.patch
patch -p1 -i ${srcdir}/005-3.1-PATH_MAX.patch
patch -p1 -i ${srcdir}/005-3.6-PATH_MAX.patch
patch -p1 -i ${srcdir}/006-3.1-ncurses-abi6.patch
patch -p1 -i ${srcdir}/007-3.2-export-PySignal_SetWakeupFd.patch
patch -p1 -i ${srcdir}/008-3.4-distutils-soname.patch
patch -p1 -i ${srcdir}/009-3.2-distutils-shlibext.patch
patch -p1 -i ${srcdir}/010-3.4-pep3149-cygwin.patch
patch -p1 -i ${srcdir}/011-3.4-thread-cygwin64.patch
patch -p1 -i ${srcdir}/010-3.6-pep3149-cygwin.patch
patch -p1 -i ${srcdir}/011-3.6-thread-cygwin64.patch
patch -p1 -i ${srcdir}/012-3.2-getpath-exe-extension.patch
patch -p1 -i ${srcdir}/013-3.4-select-cygwin.patch
patch -p1 -i ${srcdir}/014-3.4-signal-cygwin.patch
patch -p1 -i ${srcdir}/015-3.4-struct-cygwin.patch
patch -p1 -i ${srcdir}/017-3.4-shebang.patch
patch -p2 -i ${srcdir}/3.6-ftm.patch
patch -p2 -i ${srcdir}/3.6-getrandom.patch
patch -p1 -i ${srcdir}/025-MINGW-compiler-customize-mingw-cygwin-compilers.patch
patch -p1 -i ${srcdir}/900-msysize.patch
patch -p1 -i ${srcdir}/910-libffi-msys2.patch
patch -p1 -i ${srcdir}/920-allow-win-drives-in-os-path-isabs.patch
#archlinux
patch -p1 -i ${srcdir}/dont-make-libpython-readonly.patch
#fedora
patch -p1 -i ${srcdir}/00155-avoid-ctypes-thunks.patch
patch -p1 -i ${srcdir}/00157-uid-gid-overflows.patch
patch -p1 -i ${srcdir}/00170-gc-assertions.patch
patch -p1 -i ${srcdir}/00178-dont-duplicate-flags-in-sysconfig.patch
patch -p1 -i ${srcdir}/00188-fix-lib2to3-tests-when-hashlib-doesnt-compile-properly.patch
patch -p1 -i ${srcdir}/00189-add-rewheel-module.patch
patch -p1 -i ${srcdir}/00206-remove-hf-from-arm-triplet.patch
patch -p1 -i ${srcdir}/00243-fix-mips64-triplet.patch
patch -p1 -i ${srcdir}/00249-fix-out-of-tree-dtrace-builds.patch
patch -p1 -i ${srcdir}/00252-add-executable-option.patch
patch -p1 -i ${srcdir}/00260-require-setuptools-dependencies.patch
patch -p1 -i ${srcdir}/00261-use-proper-command-line-parsing-in-_testembed.patch
patch -p1 -i ${srcdir}/00264-skip-test-failing-on-aarch64.patch
patch -p1 -i ${srcdir}/python3-powerppc-arch.patch
#PiotrVV
patch -p1 -i ${srcdir}/016-3.6-mpdec-cygwin.patch
# Incomplete patch from Ray Donnelly
# patch -p1 -i ${srcdir}/3.3.2-allow-windows-paths-for-executable.patch
@@ -92,7 +147,7 @@ prepare() {
rm -r Modules/expat
rm -r Modules/zlib
rm -r Modules/_ctypes/{darwin,libffi}*
rm -r Modules/_decimal/libmpdec
autoreconf -fiv
}
@@ -115,10 +170,13 @@ build() {
--with-system-expat \
--with-system-ffi \
--with-threads \
--with-system-libmpdec \
--enable-loadable-sqlite-extensions \
--without-ensurepip \
ac_cv_func_bind_textdomain_codeset=yes
make
LC_CTYPE=en_US.UTF-8 make EXTRA_CFLAGS="$CFLAGS"
}
check() {
@@ -128,13 +186,14 @@ check() {
package() {
cd "${srcdir}/Python-${pkgver}"
make DESTDIR="${pkgdir}" install maninstall
make DESTDIR="${pkgdir}" EXTRA_CFLAGS="$CFLAGS" install maninstall
# Why are these not done by default...
ln -sf python3 "${pkgdir}"/usr/bin/python.exe
ln -sf python3-config "${pkgdir}"/usr/bin/python-config
ln -sf idle3 "${pkgdir}"/usr/bin/idle
ln -sf pydoc3 "${pkgdir}"/usr/bin/pydoc
ln -sf pyvenv-${_pybasever} "${pkgdir}"/usr/bin/pyvenv3
ln -sf python${_pybasever}.1 "${pkgdir}"/usr/share/man/man1/python3.1
ln -sf python${_pybasever}.1 "${pkgdir}"/usr/share/man/man1/python.1
@@ -142,7 +201,7 @@ package() {
cp -f "${pkgdir}"/usr/lib/python${_pybasever}/config-${_pybasever}m/libpython${_pybasever}m.dll.a "${pkgdir}"/usr/lib/libpython${_pybasever}m.dll.a
# Clean-up reference to build directory
sed -i "s|$srcdir/Python-${pkgver}:||" "$pkgdir/usr/lib/python${_pybasever}/config-${_pybasever}m/Makefile"
sed -i "s|$srcdir/Python-${pkgver}:||" "${pkgdir}/usr/lib/python${_pybasever}/config-${_pybasever}m/Makefile"
# License
install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"

View File

@@ -0,0 +1,13 @@
diff --git a/Makefile.pre.in b/Makefile.pre.in
index ce2c0aa..7d6dcf7 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -70,7 +70,7 @@ INSTALL_DATA= @INSTALL_DATA@
# Shared libraries must be installed with executable mode on some systems;
# rather than figuring out exactly which, we always give them executable mode.
# Also, making them read-only seems to be a good idea...
-INSTALL_SHARED= ${INSTALL} -m 555
+INSTALL_SHARED= ${INSTALL} -m 755
MKDIR_P= @MKDIR_P@

View File

@@ -0,0 +1,30 @@
diff -up Python-3.5.0/configure.ac.than Python-3.5.0/configure.ac
--- Python-3.5.0/configure.ac.than 2015-11-13 11:51:32.039560172 -0500
+++ Python-3.5.0/configure.ac 2015-11-13 11:52:11.670168157 -0500
@@ -841,9 +841,9 @@ cat >> conftest.c <<EOF
powerpc-linux-gnuspe
# elif defined(__powerpc64__)
# if defined(__LITTLE_ENDIAN__)
- powerpc64le-linux-gnu
+ ppc64le-linux-gnu
# else
- powerpc64-linux-gnu
+ ppc64-linux-gnu
# endif
# elif defined(__powerpc__)
powerpc-linux-gnu
diff -up Python-3.5.0/configure.than Python-3.5.0/configure
--- Python-3.5.0/configure.than 2015-11-13 12:13:19.039658399 -0500
+++ Python-3.5.0/configure 2015-11-13 12:13:35.199906857 -0500
@@ -5287,9 +5287,9 @@ cat >> conftest.c <<EOF
powerpc-linux-gnuspe
# elif defined(__powerpc64__)
# if defined(__LITTLE_ENDIAN__)
- powerpc64le-linux-gnu
+ ppc64le-linux-gnu
# else
- powerpc64-linux-gnu
+ ppc64-linux-gnu
# endif
# elif defined(__powerpc__)
powerpc-linux-gnu