diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 9dfc8c62babadb..990478152f84a6 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -29,6 +29,9 @@ _PyType_HasFeature(PyTypeObject *type, unsigned long feature) { extern void _PyType_InitCache(PyInterpreterState *interp); +PyAPI_FUNC(PyObject *) _PyType_DisabledNew(PyTypeObject *type, PyObject *args, + PyObject *kwds); + /* Inline functions trading binary compatibility for speed: _PyObject_Init() is the fast version of PyObject_Init(), and diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py index 11184add6d399b..e7e1b04656f94d 100644 --- a/Lib/test/test_array.py +++ b/Lib/test/test_array.py @@ -40,6 +40,12 @@ def test_bad_constructor(self): self.assertRaises(TypeError, array.array, 'xx') self.assertRaises(ValueError, array.array, 'x') + @support.cpython_only + def test_uninitialised_new(self): + # Prevent heap types from being created uninitialised (bpo-43916) + tp = type(iter(array.array('I'))) + self.assertRaises(TypeError, tp) + @support.cpython_only def test_immutable(self): # bpo-43908: check that array.array is immutable diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py index 280a9dc0eedfce..5ad787775796d5 100644 --- a/Lib/test/test_curses.py +++ b/Lib/test/test_curses.py @@ -6,7 +6,7 @@ import tempfile import unittest -from test.support import requires, verbose, SaveSignals +from test.support import requires, verbose, SaveSignals, cpython_only from test.support.import_helper import import_module # Optionally test curses module. This currently requires that the @@ -1046,6 +1046,7 @@ def __del__(self): panel.set_userptr(A()) panel.set_userptr(None) + @cpython_only @requires_curses_func('panel') def test_new_curses_panel(self): w = curses.newwin(10, 10) diff --git a/Lib/test/test_dbm_gnu.py b/Lib/test/test_dbm_gnu.py index 017d0ffa658bd6..e22440b8a45295 100644 --- a/Lib/test/test_dbm_gnu.py +++ b/Lib/test/test_dbm_gnu.py @@ -1,5 +1,5 @@ from test import support -from test.support import import_helper +from test.support import import_helper, cpython_only gdbm = import_helper.import_module("dbm.gnu") #skip if not supported import unittest import os @@ -27,6 +27,13 @@ def tearDown(self): self.g.close() unlink(filename) + @cpython_only + def test_uninitialised_new(self): + # Prevent heap types from being created uninitialised (bpo-43916) + self.g = gdbm.open(filename, 'c') + tp = type(self.g) + self.assertRaises(TypeError, tp) + def test_key_methods(self): self.g = gdbm.open(filename, 'c') self.assertEqual(self.g.keys(), []) diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index fba9281deb3763..e3f7ddc18b242d 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -948,6 +948,12 @@ class TestCmpToKeyC(TestCmpToKey, unittest.TestCase): if c_functools: cmp_to_key = c_functools.cmp_to_key + @support.cpython_only + def test_uninitialised_new(self): + # Prevent heap types from being created uninitialised (bpo-43916) + tp = type(c_functools.cmp_to_key(None)) + self.assertRaises(TypeError, tp) + class TestCmpToKeyPy(TestCmpToKey, unittest.TestCase): cmp_to_key = staticmethod(py_functools.cmp_to_key) diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 93611f04515ae9..daed5a0e8fd695 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -58,6 +58,13 @@ def tearDown(self): os_helper.unlink(teardown_file) self._warnings_manager.__exit__(None, None, None) + @support.cpython_only + def test_uninitialised_new(self): + # Prevent heap types from being created uninitialised (bpo-43916) + self.assertRaises(TypeError, posix.DirEntry) + tp = type(posix.scandir()) + self.assertRaises(TypeError, tp) + def testNoArgFunctions(self): # test posix functions which take no arguments and have # no side-effects which we need to cleanup (e.g., fork, wait, abort) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 96d0cdb17a7ee3..c131407a40786d 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -2215,6 +2215,15 @@ def test_signedness(self): self.assertGreaterEqual(sre_compile.MAXREPEAT, 0) self.assertGreaterEqual(sre_compile.MAXGROUPS, 0) + @cpython_only + def test_uninitialised_new(self): + # Prevent heap types from being created uninitialised (bpo-43916) + self.assertRaises(TypeError, re.Match) + self.assertRaises(TypeError, re.Pattern) + pat = re.compile("") + tp = type(pat.scanner("")) + self.assertRaises(TypeError, tp) + class ExternalTests(unittest.TestCase): diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py index ee7344c48ed0be..cd3aacf6f8844c 100644 --- a/Lib/test/test_tcl.py +++ b/Lib/test/test_tcl.py @@ -736,8 +736,11 @@ def check(value): check('{\n') check('}\n') + @support.cpython_only def test_new_tcl_obj(self): self.assertRaises(TypeError, _tkinter.Tcl_Obj) + self.assertRaises(TypeError, _tkinter.TkttType) + self.assertRaises(TypeError, _tkinter.TkappType) class BigmemTclTest(unittest.TestCase): diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index f44f17f2978f7b..a1519c042f1adb 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -119,6 +119,13 @@ def func(): pass thread = threading.Thread(target=func) self.assertEqual(thread.name, "Thread-5 (func)") + @cpython_only + def test_uninitialised_new(self): + # Prevent heap types from being created uninitialised (bpo-43916) + lock = threading.Lock() + tp = type(lock) + self.assertRaises(TypeError, tp) + # Create a bunch of threads, let each do some work, wait until all are # done. def test_various_ops(self): diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py index edfd860fd5f12f..40b6da3bf59156 100644 --- a/Lib/test/test_unicodedata.py +++ b/Lib/test/test_unicodedata.py @@ -11,7 +11,8 @@ import sys import unicodedata import unittest -from test.support import open_urlresource, requires_resource, script_helper +from test.support import (open_urlresource, requires_resource, script_helper, + cpython_only) class UnicodeMethodsTest(unittest.TestCase): @@ -225,6 +226,11 @@ def test_east_asian_width_9_0_changes(self): class UnicodeMiscTest(UnicodeDatabaseTest): + @cpython_only + def test_uninitialised_new(self): + # Prevent heap types from being created uninitialised (bpo-43916) + self.assertRaises(TypeError, unicodedata.UCD) + def test_failed_import_during_compiling(self): # Issue 4367 # Decoding \N escapes requires the unicodedata module. If it can't be diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py index 7f30cac64f71b9..274d51a24e20de 100644 --- a/Lib/test/test_zlib.py +++ b/Lib/test/test_zlib.py @@ -129,6 +129,14 @@ def test_overflow(self): with self.assertRaisesRegex(OverflowError, 'int too large'): zlib.decompressobj().flush(sys.maxsize + 1) + @support.cpython_only + def test_uninitialised_new(self): + # Prevent heap types from being created uninitialised (bpo-43916) + comp_type = type(zlib.compressobj()) + decomp_type = type(zlib.decompressobj()) + self.assertRaises(TypeError, comp_type) + self.assertRaises(TypeError, decomp_type) + class BaseCompressTestCase(object): def check_big_compress_buffer(self, size, compress_func): diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-04-28-10-09-16.bpo-43916.ecedNo.rst b/Misc/NEWS.d/next/Core and Builtins/2021-04-28-10-09-16.bpo-43916.ecedNo.rst new file mode 100644 index 00000000000000..cf25431e12b1d7 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2021-04-28-10-09-16.bpo-43916.ecedNo.rst @@ -0,0 +1,7 @@ +Fix regressions for extension modules that have been converted to :ref:`heap +types `. Inheritance differs for *static types* and *heap +types*: A *static type* with its :c:member:`~PyTypeObject.tp_new` set to +``NULL`` does not have a public contructor, but *heap types* inherit +contructors from their base classes, resulting in it being possible to +create instances without proper initialisation, possibly resulting in a +crash. diff --git a/Modules/_curses_panel.c b/Modules/_curses_panel.c index 94caf8c93bc8c3..92e59e7bd6c1cc 100644 --- a/Modules/_curses_panel.c +++ b/Modules/_curses_panel.c @@ -13,6 +13,7 @@ static const char PyCursesVersion[] = "2.1"; #include "Python.h" #include "py_curses.h" +#include "pycore_object.h" // _PyType_DisabledNew() #include @@ -514,6 +515,7 @@ static PyMethodDef PyCursesPanel_Methods[] = { static PyType_Slot PyCursesPanel_Type_slots[] = { {Py_tp_dealloc, PyCursesPanel_Dealloc}, {Py_tp_methods, PyCursesPanel_Methods}, + {Py_tp_new, _PyType_DisabledNew}, {0, 0}, }; @@ -656,7 +658,6 @@ _curses_panel_exec(PyObject *mod) if (state->PyCursesPanel_Type == NULL) { return -1; } - ((PyTypeObject *)state->PyCursesPanel_Type)->tp_new = NULL; if (PyModule_AddType(mod, state->PyCursesPanel_Type) < 0) { return -1; diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c index 97772a04d08fe0..7153df6f39a0fc 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -4,6 +4,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_object.h" // _PyType_DisabledNew() #include #include @@ -397,6 +398,7 @@ static PyMethodDef dbm_methods[] = { }; static PyType_Slot dbmtype_spec_slots[] = { + {Py_tp_new, _PyType_DisabledNew}, {Py_tp_dealloc, dbm_dealloc}, {Py_tp_methods, dbm_methods}, {Py_sq_contains, dbm_contains}, diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index eea542e18c92d2..3cb6a73c5077f8 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -540,6 +540,7 @@ static PyType_Slot keyobject_type_slots[] = { {Py_tp_clear, keyobject_clear}, {Py_tp_richcompare, keyobject_richcompare}, {Py_tp_members, keyobject_members}, + {Py_tp_new, _PyType_DisabledNew}, {0, 0} }; @@ -760,6 +761,7 @@ lru_list_elem_dealloc(lru_list_elem *link) static PyType_Slot lru_list_elem_type_slots[] = { {Py_tp_dealloc, lru_list_elem_dealloc}, + {Py_tp_new, _PyType_DisabledNew}, {0, 0} }; diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c index 9e843acbaa6ba5..f60bb19622567c 100644 --- a/Modules/_gdbmmodule.c +++ b/Modules/_gdbmmodule.c @@ -5,6 +5,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_object.h" // _PyType_DisabledNew() #include #include @@ -560,6 +561,7 @@ static PyType_Slot gdbmtype_spec_slots[] = { {Py_mp_subscript, gdbm_subscript}, {Py_mp_ass_subscript, gdbm_ass_sub}, {Py_tp_doc, (char*)gdbm_object__doc__}, + {Py_tp_new, _PyType_DisabledNew}, {0, 0} }; diff --git a/Modules/_sre.c b/Modules/_sre.c index 59f7551a227cd3..ed8e515d59a456 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -43,6 +43,7 @@ static const char copyright[] = #include "Python.h" #include "pycore_long.h" // _PyLong_GetZero() #include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_object.h" // _PyType_DisabledNew() #include "structmember.h" // PyMemberDef #include "sre.h" @@ -2683,6 +2684,7 @@ static PyType_Slot pattern_slots[] = { {Py_tp_methods, pattern_methods}, {Py_tp_members, pattern_members}, {Py_tp_getset, pattern_getset}, + {Py_tp_new, _PyType_DisabledNew}, {0, NULL}, }; @@ -2740,6 +2742,7 @@ static PyType_Slot match_slots[] = { {Py_tp_methods, match_methods}, {Py_tp_members, match_members}, {Py_tp_getset, match_getset}, + {Py_tp_new, _PyType_DisabledNew}, /* As mapping. * @@ -2775,6 +2778,7 @@ static PyType_Slot scanner_slots[] = { {Py_tp_dealloc, scanner_dealloc}, {Py_tp_methods, scanner_methods}, {Py_tp_members, scanner_members}, + {Py_tp_new, _PyType_DisabledNew}, {0, NULL}, }; diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index 7feb0b8a1f1f4d..f1646540889adf 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -5,6 +5,7 @@ #include "Python.h" #include "pycore_interp.h" // _PyInterpreterState.num_threads #include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_object.h" // _PyType_DisabledNew() #include "pycore_pylifecycle.h" #include "pycore_pystate.h" // _PyThreadState_Init() #include // offsetof() @@ -306,6 +307,7 @@ static PyType_Slot lock_type_slots[] = { {Py_tp_methods, lock_methods}, {Py_tp_traverse, lock_traverse}, {Py_tp_members, lock_type_members}, + {Py_tp_new, _PyType_DisabledNew}, {0, 0} }; @@ -677,6 +679,7 @@ static PyType_Slot local_dummy_type_slots[] = { {Py_tp_dealloc, (destructor)localdummy_dealloc}, {Py_tp_doc, "Thread-local dummy"}, {Py_tp_members, local_dummy_type_members}, + {Py_tp_new, _PyType_DisabledNew}, {0, 0} }; diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 46d6a6e0954f51..2a539099863f20 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -24,6 +24,7 @@ Copyright (C) 1994 Steen Lumholt. #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_object.h" // _PyType_DisabledNew() #include #ifdef MS_WINDOWS @@ -995,6 +996,7 @@ static PyType_Slot PyTclObject_Type_slots[] = { {Py_tp_getattro, PyObject_GenericGetAttr}, {Py_tp_richcompare, PyTclObject_richcompare}, {Py_tp_getset, PyTclObject_getsetlist}, + {Py_tp_new, _PyType_DisabledNew}, {0, 0} }; @@ -3287,6 +3289,7 @@ static PyType_Slot Tktt_Type_slots[] = { {Py_tp_dealloc, Tktt_Dealloc}, {Py_tp_repr, Tktt_Repr}, {Py_tp_methods, Tktt_methods}, + {Py_tp_new, _PyType_DisabledNew}, {0, 0} }; @@ -3341,6 +3344,7 @@ static PyMethodDef Tkapp_methods[] = static PyType_Slot Tkapp_Type_slots[] = { {Py_tp_dealloc, Tkapp_Dealloc}, {Py_tp_methods, Tkapp_methods}, + {Py_tp_new, _PyType_DisabledNew}, {0, 0} }; @@ -3537,7 +3541,6 @@ PyInit__tkinter(void) Py_DECREF(m); return NULL; } - ((PyTypeObject *)o)->tp_new = NULL; if (PyModule_AddObject(m, "TkappType", o)) { Py_DECREF(o); Py_DECREF(m); @@ -3550,7 +3553,6 @@ PyInit__tkinter(void) Py_DECREF(m); return NULL; } - ((PyTypeObject *)o)->tp_new = NULL; if (PyModule_AddObject(m, "TkttType", o)) { Py_DECREF(o); Py_DECREF(m); @@ -3563,7 +3565,6 @@ PyInit__tkinter(void) Py_DECREF(m); return NULL; } - ((PyTypeObject *)o)->tp_new = NULL; if (PyModule_AddObject(m, "Tcl_Obj", o)) { Py_DECREF(o); Py_DECREF(m); diff --git a/Modules/_winapi.c b/Modules/_winapi.c index 9d5a45adac59d0..1cbde5b15a3fa2 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -44,6 +44,9 @@ #include #include "winreparse.h" +// Include pycore_object.h to avoid conflict with windows.h +#include "pycore_object.h" // _PyType_DisabledNew() + #if defined(MS_WIN32) && !defined(MS_WIN64) #define HANDLE_TO_PYNUM(handle) \ PyLong_FromUnsignedLong((unsigned long) handle) @@ -325,6 +328,7 @@ static PyType_Slot winapi_overlapped_type_slots[] = { {Py_tp_doc, "OVERLAPPED structure wrapper"}, {Py_tp_methods, overlapped_methods}, {Py_tp_members, overlapped_members}, + {Py_tp_new, _PyType_DisabledNew}, {0,0} }; diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 367621fd03b882..65d8dab4fd933f 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -6,6 +6,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" #include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_object.h" // _PyType_DisabledNew() #include "structmember.h" // PyMemberDef #include // offsetof() @@ -2980,6 +2981,7 @@ static PyType_Slot arrayiter_slots[] = { {Py_tp_iter, PyObject_SelfIter}, {Py_tp_iternext, arrayiter_next}, {Py_tp_methods, arrayiter_methods}, + {Py_tp_new, _PyType_DisabledNew}, {0, NULL}, }; diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 5070c983d402c3..2206c09126e51e 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -6,6 +6,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_object.h" // _PyType_DisabledNew() #include "structmember.h" // PyMemberDef #include "multibytecodec.h" #include "clinic/multibytecodec.c.h" @@ -742,6 +743,7 @@ static PyType_Slot multibytecodec_slots[] = { {Py_tp_getattro, PyObject_GenericGetAttr}, {Py_tp_methods, multibytecodec_methods}, {Py_tp_traverse, multibytecodec_traverse}, + {Py_tp_new, _PyType_DisabledNew}, {0, NULL}, }; diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index ecd210e4babf54..af95faa13fb858 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -29,6 +29,7 @@ #include "pycore_ceval.h" // _PyEval_ReInitThreads() #include "pycore_import.h" // _PyImport_ReInitLock() #include "pycore_initconfig.h" // _PyStatus_EXCEPTION() +#include "pycore_object.h" // _PyType_DisabledNew() #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "structmember.h" // PyMemberDef #ifndef MS_WINDOWS @@ -13786,6 +13787,7 @@ static PyType_Slot DirEntryType_slots[] = { {Py_tp_repr, DirEntry_repr}, {Py_tp_methods, DirEntry_methods}, {Py_tp_members, DirEntry_members}, + {Py_tp_new, _PyType_DisabledNew}, {0, 0}, }; @@ -14219,6 +14221,7 @@ static PyType_Slot ScandirIteratorType_slots[] = { {Py_tp_iter, PyObject_SelfIter}, {Py_tp_iternext, ScandirIterator_iternext}, {Py_tp_methods, ScandirIterator_methods}, + {Py_tp_new, _PyType_DisabledNew}, {0, 0}, }; diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index a13d340a3ea0f0..01b850429ba489 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -1,6 +1,7 @@ #include "Python.h" #include +#include "pycore_object.h" // _PyType_DisabledNew() #include "structmember.h" // PyMemberDef #include "frameobject.h" #include "expat.h" @@ -1500,6 +1501,7 @@ static PyType_Slot _xml_parse_type_spec_slots[] = { {Py_tp_methods, xmlparse_methods}, {Py_tp_members, xmlparse_members}, {Py_tp_getset, xmlparse_getsetlist}, + {Py_tp_new, _PyType_DisabledNew}, {0, 0} }; diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index aebae7da576561..5ac58951df0bbe 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -16,6 +16,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_object.h" // _PyType_DisabledNew() #include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI #include "structmember.h" // PyMemberDef @@ -1448,6 +1449,7 @@ static PyType_Slot ucd_type_slots[] = { {Py_tp_getattro, PyObject_GenericGetAttr}, {Py_tp_methods, unicodedata_functions}, {Py_tp_members, DB_members}, + {Py_tp_new, _PyType_DisabledNew}, {0, 0} }; diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c index 8a20dfcbf9e27a..810214a2404d67 100644 --- a/Modules/zlibmodule.c +++ b/Modules/zlibmodule.c @@ -6,6 +6,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_object.h" // _PyType_DisabledNew() #include "structmember.h" // PyMemberDef #include "zlib.h" @@ -1382,6 +1383,7 @@ static PyMethodDef zlib_methods[] = static PyType_Slot Comptype_slots[] = { {Py_tp_dealloc, Comp_dealloc}, {Py_tp_methods, comp_methods}, + {Py_tp_new, _PyType_DisabledNew}, {0, 0}, }; @@ -1397,6 +1399,7 @@ static PyType_Slot Decomptype_slots[] = { {Py_tp_dealloc, Decomp_dealloc}, {Py_tp_methods, Decomp_methods}, {Py_tp_members, Decomp_members}, + {Py_tp_new, _PyType_DisabledNew}, {0, 0}, }; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index e1c8be4b815452..45a9a73f687910 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1004,6 +1004,14 @@ type_repr(PyTypeObject *type) return rtn; } +PyObject * +_PyType_DisabledNew(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyErr_Format(PyExc_TypeError, "cannot create '%s' instances", + type->tp_name); + return NULL; +} + static PyObject * type_call(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -1041,10 +1049,7 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds) } if (type->tp_new == NULL) { - _PyErr_Format(tstate, PyExc_TypeError, - "cannot create '%.100s' instances", - type->tp_name); - return NULL; + return _PyType_DisabledNew(type, args, kwds); } obj = type->tp_new(type, args, kwds); diff --git a/setup.py b/setup.py index ca0ed8363ef358..afea4404cfd725 100644 --- a/setup.py +++ b/setup.py @@ -1190,6 +1190,7 @@ def detect_readline_curses(self): self.add(Extension('_curses_panel', ['_curses_panel.c'], include_dirs=curses_includes, define_macros=curses_defines, + extra_compile_args=['-DPy_BUILD_CORE_MODULE'], libraries=[panel_library, *curses_libs])) elif not skip_curses_panel: self.missing.append('_curses_panel') @@ -1440,6 +1441,7 @@ class db_found(Exception): pass else: dbm_order = "ndbm:gdbm:bdb".split(":") dbmext = None + dbm_compile_args = ['-DPy_BUILD_CORE_MODULE'] for cand in dbm_order: if cand == "ndbm": if find_file("ndbm.h", self.inc_dirs, []) is not None: @@ -1458,6 +1460,7 @@ class db_found(Exception): pass define_macros=[ ('HAVE_NDBM_H',None), ], + extra_compile_args=dbm_compile_args, libraries=ndbm_libs) break @@ -1474,6 +1477,7 @@ class db_found(Exception): pass define_macros=[ ('HAVE_GDBM_NDBM_H', None), ], + extra_compile_args=dbm_compile_args, libraries = gdbm_libs) break if find_file("gdbm-ndbm.h", self.inc_dirs, []) is not None: @@ -1483,6 +1487,7 @@ class db_found(Exception): pass define_macros=[ ('HAVE_GDBM_DASH_NDBM_H', None), ], + extra_compile_args=dbm_compile_args, libraries = gdbm_libs) break elif cand == "bdb": @@ -1496,6 +1501,7 @@ class db_found(Exception): pass ('HAVE_BERKDB_H', None), ('DB_DBM_HSEARCH', None), ], + extra_compile_args=dbm_compile_args, libraries=dblibs) break if dbmext is not None: @@ -1507,6 +1513,7 @@ class db_found(Exception): pass if ('gdbm' in dbm_order and self.compiler.find_library_file(self.lib_dirs, 'gdbm')): self.add(Extension('_gdbm', ['_gdbmmodule.c'], + extra_compile_args=dbm_compile_args, libraries=['gdbm'])) else: self.missing.append('_gdbm') @@ -1682,6 +1689,7 @@ def detect_compress_exts(self): zlib_extra_link_args = () self.add(Extension('zlib', ['zlibmodule.c'], libraries=['z'], + extra_compile_args=['-DPy_BUILD_CORE_MODULE'], extra_link_args=zlib_extra_link_args)) have_zlib = True else: @@ -1752,7 +1760,7 @@ def detect_expat_elementtree(self): # call XML_SetHashSalt(), expat entropy sources are not needed ('XML_POOR_ENTROPY', '1'), ] - extra_compile_args = [] + extra_compile_args = ['-DPy_BUILD_CORE_MODULE'] expat_lib = [] expat_sources = ['expat/xmlparse.c', 'expat/xmlrole.c', @@ -1802,7 +1810,8 @@ def detect_expat_elementtree(self): def detect_multibytecodecs(self): # Hye-Shik Chang's CJKCodecs modules. self.add(Extension('_multibytecodec', - ['cjkcodecs/multibytecodec.c'])) + ['cjkcodecs/multibytecodec.c'], + extra_compile_args=['-DPy_BUILD_CORE_MODULE'])) for loc in ('kr', 'jp', 'cn', 'tw', 'hk', 'iso2022'): self.add(Extension('_codecs_%s' % loc, ['cjkcodecs/_codecs_%s.c' % loc])) @@ -1925,6 +1934,7 @@ def detect_tkinter_fromenv(self): return False extra_compile_args = tcltk_includes.split() + extra_compile_args.append('-DPy_BUILD_CORE_MODULE') extra_link_args = tcltk_libs.split() self.add(Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'], define_macros=[('WITH_APPINIT', 1)], @@ -2056,6 +2066,7 @@ def detect_tkinter_darwin(self): if '-Wstrict-prototypes' in cflags.split(): compile_args.append('-Wno-strict-prototypes') + compile_args.append('-DPy_BUILD_CORE_MODULE') self.add(Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'], define_macros=[('WITH_APPINIT', 1)], include_dirs=include_dirs, @@ -2180,10 +2191,12 @@ def detect_tkinter(self): # *** Uncomment these for TOGL extension only: # -lGL -lGLU -lXext -lXmu \ + extra_compile_args = ['-DPy_BUILD_CORE_MODULE'] self.add(Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'], define_macros=[('WITH_APPINIT', 1)] + defs, include_dirs=include_dirs, libraries=libs, + extra_compile_args=extra_compile_args, library_dirs=added_lib_dirs)) return True