From 3b88d10e86d69ff8ef73bf9f0134ae559df916b2 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 30 Aug 2018 16:36:12 +0200 Subject: [PATCH 01/50] Write a new README to create the pythoncapi branch. --- README.rst | 271 ++--------------------------------------------------- 1 file changed, 8 insertions(+), 263 deletions(-) diff --git a/README.rst b/README.rst index 90c8f5c354726c..387bce0dbd20e7 100644 --- a/README.rst +++ b/README.rst @@ -1,268 +1,13 @@ -This is Python version 3.8.0 alpha 0 +Design a new better C API for Python ==================================== -.. image:: https://travis-ci.org/python/cpython.svg?branch=master - :alt: CPython build status on Travis CI - :target: https://travis-ci.org/python/cpython +This project is a fork of the development version of the future CPython 3.8. +The intent is to experiment to implement the new C API described at: -.. image:: https://ci.appveyor.com/api/projects/status/4mew1a93xdkbf5ua/branch/master?svg=true - :alt: CPython build status on Appveyor - :target: https://ci.appveyor.com/project/python/cpython/branch/master + https://pythoncapi.readthedocs.io/ -.. image:: https://codecov.io/gh/python/cpython/branch/master/graph/badge.svg - :alt: CPython code coverage on Codecov - :target: https://codecov.io/gh/python/cpython +The changes live in the **pythoncapi** branch. See also: -.. image:: https://img.shields.io/badge/zulip-join_chat-brightgreen.svg - :alt: Python Zulip chat - :target: https://python.zulipchat.com - - -Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -2012, 2013, 2014, 2015, 2016, 2017, 2018 Python Software Foundation. All rights -reserved. - -See the end of this file for further copyright and license information. - -.. contents:: - -General Information -------------------- - -- Website: https://www.python.org -- Source code: https://github.com/python/cpython -- Issue tracker: https://bugs.python.org -- Documentation: https://docs.python.org -- Developer's Guide: https://devguide.python.org/ - -Contributing to CPython ------------------------ - -For more complete instructions on contributing to CPython development, -see the `Developer Guide`_. - -.. _Developer Guide: https://devguide.python.org/ - -Using Python ------------- - -Installable Python kits, and information about using Python, are available at -`python.org`_. - -.. _python.org: https://www.python.org/ - -Build Instructions ------------------- - -On Unix, Linux, BSD, macOS, and Cygwin:: - - ./configure - make - make test - sudo make install - -This will install Python as python3. - -You can pass many options to the configure script; run ``./configure --help`` -to find out more. On macOS and Cygwin, the executable is called ``python.exe``; -elsewhere it's just ``python``. - -If you are running on macOS with the latest updates installed, make sure to install -openSSL or some other SSL software along with Homebrew or another package manager. -If issues persist, see https://devguide.python.org/setup/#macos-and-os-x for more -information. - -On macOS, if you have configured Python with ``--enable-framework``, you -should use ``make frameworkinstall`` to do the installation. Note that this -installs the Python executable in a place that is not normally on your PATH, -you may want to set up a symlink in ``/usr/local/bin``. - -On Windows, see `PCbuild/readme.txt -`_. - -If you wish, you can create a subdirectory and invoke configure from there. -For example:: - - mkdir debug - cd debug - ../configure --with-pydebug - make - make test - -(This will fail if you *also* built at the top-level directory. You should do -a ``make clean`` at the toplevel first.) - -To get an optimized build of Python, ``configure --enable-optimizations`` -before you run ``make``. This sets the default make targets up to enable -Profile Guided Optimization (PGO) and may be used to auto-enable Link Time -Optimization (LTO) on some platforms. For more details, see the sections -below. - - -Profile Guided Optimization -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -PGO takes advantage of recent versions of the GCC or Clang compilers. If used, -either via ``configure --enable-optimizations`` or by manually running -``make profile-opt`` regardless of configure flags, the optimized build -process will perform the following steps: - -The entire Python directory is cleaned of temporary files that may have -resulted from a previous compilation. - -An instrumented version of the interpreter is built, using suitable compiler -flags for each flavour. Note that this is just an intermediary step. The -binary resulting from this step is not good for real life workloads as it has -profiling instructions embedded inside. - -After the instrumented interpreter is built, the Makefile will run a training -workload. This is necessary in order to profile the interpreter execution. -Note also that any output, both stdout and stderr, that may appear at this step -is suppressed. - -The final step is to build the actual interpreter, using the information -collected from the instrumented one. The end result will be a Python binary -that is optimized; suitable for distribution or production installation. - - -Link Time Optimization -^^^^^^^^^^^^^^^^^^^^^^ - -Enabled via configure's ``--with-lto`` flag. LTO takes advantage of the -ability of recent compiler toolchains to optimize across the otherwise -arbitrary ``.o`` file boundary when building final executables or shared -libraries for additional performance gains. - - -What's New ----------- - -We have a comprehensive overview of the changes in the `What's New in Python -3.8 `_ document. For a more -detailed change log, read `Misc/NEWS -`_, but a full -accounting of changes can only be gleaned from the `commit history -`_. - -If you want to install multiple versions of Python see the section below -entitled "Installing multiple versions". - - -Documentation -------------- - -`Documentation for Python 3.8 `_ is online, -updated daily. - -It can also be downloaded in many formats for faster access. The documentation -is downloadable in HTML, PDF, and reStructuredText formats; the latter version -is primarily for documentation authors, translators, and people with special -formatting requirements. - -For information about building Python's documentation, refer to `Doc/README.rst -`_. - - -Converting From Python 2.x to 3.x ---------------------------------- - -Significant backward incompatible changes were made for the release of Python -3.0, which may cause programs written for Python 2 to fail when run with Python -3. For more information about porting your code from Python 2 to Python 3, see -the `Porting HOWTO `_. - - -Testing -------- - -To test the interpreter, type ``make test`` in the top-level directory. The -test set produces some output. You can generally ignore the messages about -skipped tests due to optional features which can't be imported. If a message -is printed about a failed test or a traceback or core dump is produced, -something is wrong. - -By default, tests are prevented from overusing resources like disk space and -memory. To enable these tests, run ``make testall``. - -If any tests fail, you can re-run the failing test(s) in verbose mode. For -example, if ``test_os`` and ``test_gdb`` failed, you can run:: - - make test TESTOPTS="-v test_os test_gdb" - -If the failure persists and appears to be a problem with Python rather than -your environment, you can `file a bug report `_ and -include relevant output from that command to show the issue. - -See `Running & Writing Tests `_ -for more on running tests. - -Installing multiple versions ----------------------------- - -On Unix and Mac systems if you intend to install multiple versions of Python -using the same installation prefix (``--prefix`` argument to the configure -script) you must take care that your primary python executable is not -overwritten by the installation of a different version. All files and -directories installed using ``make altinstall`` contain the major and minor -version and can thus live side-by-side. ``make install`` also creates -``${prefix}/bin/python3`` which refers to ``${prefix}/bin/pythonX.Y``. If you -intend to install multiple versions using the same prefix you must decide which -version (if any) is your "primary" version. Install that version using ``make -install``. Install all other versions using ``make altinstall``. - -For example, if you want to install Python 2.7, 3.6, and 3.8 with 3.8 being the -primary version, you would execute ``make install`` in your 3.8 build directory -and ``make altinstall`` in the others. - - -Issue Tracker and Mailing List ------------------------------- - -Bug reports are welcome! You can use the `issue tracker -`_ to report bugs, and/or submit pull requests `on -GitHub `_. - -You can also follow development discussion on the `python-dev mailing list -`_. - - -Proposals for enhancement -------------------------- - -If you have a proposal to change Python, you may want to send an email to the -comp.lang.python or `python-ideas`_ mailing lists for initial feedback. A -Python Enhancement Proposal (PEP) may be submitted if your idea gains ground. -All current PEPs, as well as guidelines for submitting a new PEP, are listed at -`python.org/dev/peps/ `_. - -.. _python-ideas: https://mail.python.org/mailman/listinfo/python-ideas/ - - -Release Schedule ----------------- - -See :pep:`569` for Python 3.8 release details. - - -Copyright and License Information ---------------------------------- - -Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -2012, 2013, 2014, 2015, 2016, 2017, 2018 Python Software Foundation. All rights -reserved. - -Copyright (c) 2000 BeOpen.com. All rights reserved. - -Copyright (c) 1995-2001 Corporation for National Research Initiatives. All -rights reserved. - -Copyright (c) 1991-1995 Stichting Mathematisch Centrum. All rights reserved. - -See the file "LICENSE" for information on the history of this software, terms & -conditions for usage, and a DISCLAIMER OF ALL WARRANTIES. - -This Python distribution contains *no* GNU General Public License (GPL) code, -so it may be used in proprietary projects. There are interfaces to some GNU -code but these are entirely optional. - -All trademarks referenced herein are property of their respective holders. +* `github.com/pythoncapi/cpython `_ +* `capi-sig mailing list + `_ From fcabd49a8efd2430c5bb8045545709021c90814f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 30 Aug 2018 18:59:58 +0200 Subject: [PATCH 02/50] Add Py_NEWCAPI and Py_NEWCAPI_BORROWED_REF --- Include/pyport.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Include/pyport.h b/Include/pyport.h index f4b547a50b8580..c1f91062d7c142 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -792,4 +792,9 @@ extern _invalid_parameter_handler _Py_silent_invalid_parameter_handler; #define WITH_THREAD #endif +/* New C API */ +#ifdef Py_NEWCAPI +# define Py_NEWCAPI_BORROWED_REF +#endif + #endif /* Py_PYPORT_H */ From 47c5ce3219ed443391d04804b157c5cc98202407 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 30 Aug 2018 19:00:15 +0200 Subject: [PATCH 03/50] Convert 3 tuple macros to function calls --- Include/tupleobject.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Include/tupleobject.h b/Include/tupleobject.h index 72a7d8d5850dfd..e97a21eb872eb8 100644 --- a/Include/tupleobject.h +++ b/Include/tupleobject.h @@ -53,8 +53,12 @@ PyAPI_FUNC(PyObject *) PyTuple_Pack(Py_ssize_t, ...); PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *); #endif +#ifdef Py_NEWCAPI_BORROWED_REF +#define PyTuple_GET_ITEM(op, i) PyTuple_GetItem(op, i) +#define PyTuple_GET_SIZE(op, i) PyTuple_Size(op, i) +#define PyTuple_SET_ITEM(op, i, v) PyTuple_SetItem(op, i, v) +#elif !defined(Py_LIMITED_API) /* Macro, trading safety for speed */ -#ifndef Py_LIMITED_API #define PyTuple_GET_ITEM(op, i) (((PyTupleObject *)(op))->ob_item[i]) #define PyTuple_GET_SIZE(op) (assert(PyTuple_Check(op)),Py_SIZE(op)) From b2357f0914a1d6983f727c84fc7abada6c0630be Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 30 Aug 2018 19:09:23 +0200 Subject: [PATCH 04/50] Add unit tests --- .gitignore | 3 +- README.rst | 7 ++ capi/tests/.gitignore | 1 + capi/tests/Makefile | 9 +++ capi/tests/test_tuple.c | 145 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 capi/tests/.gitignore create mode 100644 capi/tests/Makefile create mode 100644 capi/tests/test_tuple.c diff --git a/.gitignore b/.gitignore index 215d7f526f465c..ea3bfaae4b2c8e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ Modules/python.exp buildaix/ installp/ -.gitignore # Two-trick pony for OSX and other case insensitive file systems: # Ignore ./python binary on Unix but still look into ./Python/ directory. @@ -33,7 +32,7 @@ Include/pydtrace_probes.h Lib/distutils/command/*.pdb Lib/lib2to3/*.pickle Lib/test/data/* -Makefile +#Makefile Makefile.pre Misc/python.pc Misc/python-config.sh diff --git a/README.rst b/README.rst index 387bce0dbd20e7..99a66f506f3b77 100644 --- a/README.rst +++ b/README.rst @@ -6,6 +6,13 @@ The intent is to experiment to implement the new C API described at: https://pythoncapi.readthedocs.io/ +Build and run unit tests:: + + ./configure --with-shared --with-pydebug + make + cd capi/tests + make + The changes live in the **pythoncapi** branch. See also: * `github.com/pythoncapi/cpython `_ diff --git a/capi/tests/.gitignore b/capi/tests/.gitignore new file mode 100644 index 00000000000000..71ec8777af6723 --- /dev/null +++ b/capi/tests/.gitignore @@ -0,0 +1 @@ +test_tuple diff --git a/capi/tests/Makefile b/capi/tests/Makefile new file mode 100644 index 00000000000000..25665611ae32e6 --- /dev/null +++ b/capi/tests/Makefile @@ -0,0 +1,9 @@ +CPYTHON_SRC=../.. +LIBPYTHON=python3.8dm + +all: test_tuple + LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib ./test_tuple + +test_tuple: test_tuple.c + $(CC) -o $@ $< -I $(CPYTHON_SRC) -I $(CPYTHON_SRC)/Include -l $(LIBPYTHON) -L $(CPYTHON_SRC) + diff --git a/capi/tests/test_tuple.c b/capi/tests/test_tuple.c new file mode 100644 index 00000000000000..094f9d53d04b1d --- /dev/null +++ b/capi/tests/test_tuple.c @@ -0,0 +1,145 @@ +#include + +typedef enum { + capitest_enum_SUCCESS, + capitest_enum_FAIL, + capitest_enum_SKIPPED +} capitest_ResultEnum; + +typedef struct { + capitest_ResultEnum result; + const char *msg; + const char *filename; + int lineno; +} capitest_Result; + +typedef capitest_Result (*capitest_TestFunc) (); + +typedef struct { + capitest_Result result; + const char *name; + capitest_TestFunc func; +} capitest_Test; + +typedef struct { + size_t ntest; + /* FIXME: don't use hardcoded array size */ + capitest_Test tests[10]; +} capitest_TestSuite; + +#define capitest_TestSuite_INIT {.ntest = 0} + +#define capitest_FAIL_MSG(message) \ + (capitest_Result){.result = capitest_enum_FAIL, .msg = (message), .filename = __FILE__, .lineno = __LINE__} +#define capitest_FAIL(message) capitest_FAIL_MSG(NULL) +#define capitest_SUCCESS() \ + (capitest_Result){.result = capitest_enum_SUCCESS, .filename = __FILE__, .lineno = __LINE__} + +static capitest_Result +check_PyTuple_New_Size(size_t size) +{ + PyObject *tuple = PyTuple_New(size); + if (tuple == NULL) { + return capitest_FAIL(); + } + if (Py_TYPE(tuple) != &PyTuple_Type) { + return capitest_FAIL(); + } + /* don't check Py_REFCNT() to PyTuple_New(0): CPython uses a singleton */ + if (size != 0) { + if (Py_REFCNT(tuple) != 1) { + return capitest_FAIL(); + } + } + if (PyTuple_Size(tuple) != size) { + return capitest_FAIL(); + } + Py_DECREF(tuple); + return capitest_SUCCESS(); +} + + +static capitest_Result +test_PyTuple_New(void) +{ + capitest_Result result; + result = check_PyTuple_New_Size(0); + if (result.result != capitest_enum_SUCCESS) { + return result; + } + result = check_PyTuple_New_Size(1); + if (result.result != capitest_enum_SUCCESS) { + return result; + } + result = check_PyTuple_New_Size(5); + return result; +} + + +static capitest_Result +test_PyTuple_GET_ITEM(void) +{ + PyObject *tuple = PyTuple_New(0); + if (tuple == NULL) { + return capitest_FAIL(); + } + Py_DECREF(tuple); + return capitest_SUCCESS(); +} + + +static void +capitest_run_test(capitest_Test *test) +{ + printf("%s: ", test->name); + fflush(stdout); + + test->result = test->func(); + capitest_Result *result = &test->result; + + if (result->result == capitest_enum_FAIL) { + printf("FAIL at %s:%i", result->filename, result->lineno); + if (result->msg) { + printf("(%s)", result->msg); + } + printf("\n"); + } + else { + assert(result->result == capitest_enum_SUCCESS); + printf("ok\n"); + } + fflush(stdout); +} + +/* FIXME: handle error */ +static void +capitest_register(capitest_TestSuite *suite, const char *name, capitest_TestFunc func) +{ + capitest_Test test = {.name = name, .func = func}; + assert(suite->ntest < Py_ARRAY_LENGTH(suite->tests)); + size_t i = suite->ntest; + suite->ntest++; + suite->tests[i] = test; +} + +#define CAPITEST_REGISTER(suite, test_func) capitest_register(&suite, #test_func, test_func) + +static void +capitest_run_testsuite(capitest_TestSuite *suite) +{ + Py_Initialize(); + for (size_t i=0; i < suite->ntest; i++) { + capitest_Test *test = &suite->tests[i]; + capitest_run_test(test); + /* FIXME: store result somewhere */ + } + Py_Finalize(); +} + +int main() +{ + capitest_TestSuite suite = capitest_TestSuite_INIT ; + CAPITEST_REGISTER(suite, test_PyTuple_New); + CAPITEST_REGISTER(suite, test_PyTuple_GET_ITEM); + capitest_run_testsuite(&suite); +} From 4bd37f85fdd1f5ebbaafdae445a2d5fb2647bce9 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 31 Aug 2018 01:08:59 +0200 Subject: [PATCH 05/50] tests: add capitest.c and capitest.h --- capi/tests/Makefile | 4 +- capi/tests/capitest.c | 70 +++++++++++++++++++++++++++++++++ capi/tests/capitest.h | 43 +++++++++++++++++++++ capi/tests/test_tuple.c | 86 ++--------------------------------------- 4 files changed, 118 insertions(+), 85 deletions(-) create mode 100644 capi/tests/capitest.c create mode 100644 capi/tests/capitest.h diff --git a/capi/tests/Makefile b/capi/tests/Makefile index 25665611ae32e6..51a35246c6245f 100644 --- a/capi/tests/Makefile +++ b/capi/tests/Makefile @@ -4,6 +4,6 @@ LIBPYTHON=python3.8dm all: test_tuple LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib ./test_tuple -test_tuple: test_tuple.c - $(CC) -o $@ $< -I $(CPYTHON_SRC) -I $(CPYTHON_SRC)/Include -l $(LIBPYTHON) -L $(CPYTHON_SRC) +test_tuple: test_tuple.c capitest.c + $(CC) -o $@ $^ -I $(CPYTHON_SRC) -I $(CPYTHON_SRC)/Include -l $(LIBPYTHON) -L $(CPYTHON_SRC) diff --git a/capi/tests/capitest.c b/capi/tests/capitest.c new file mode 100644 index 00000000000000..fbee8a9f6d62d8 --- /dev/null +++ b/capi/tests/capitest.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include "capitest.h" + + +/* FIXME: handle error */ +void +capitest_register(capitest_TestSuite *suite, const char *name, capitest_TestFunc func) +{ + capitest_Test test = {.name = name, .func = func}; + assert(suite->ntest < Py_ARRAY_LENGTH(suite->tests)); + size_t i = suite->ntest; + suite->ntest++; + suite->tests[i] = test; +} + + +void +capitest_run_test(capitest_Test *test) +{ + printf("%s: ", test->name); + fflush(stdout); + + test->result = test->func(); + capitest_Result *result = &test->result; + + if (result->result == capitest_enum_FAIL) { + printf("FAIL at %s:%i", result->filename, result->lineno); + if (result->msg) { + printf("(%s)", result->msg); + } + printf("\n"); + } + else { + assert(result->result == capitest_enum_SUCCESS); + printf("ok\n"); + } + fflush(stdout); +} + + +int +capitest_run_testsuite(capitest_TestSuite *suite) +{ + size_t nfail = 0; + Py_Initialize(); + for (size_t i=0; i < suite->ntest; i++) { + capitest_Test *test = &suite->tests[i]; + capitest_run_test(test); + if (test->result.result != capitest_enum_SUCCESS) { + nfail++; + } + } + Py_Finalize(); + printf("\n"); + printf("Tests (%i) result: ", suite->ntest); + if (nfail) { + printf("%s FAILS\n", nfail); + } + else { + printf("SUCCESS\n"); + } + if (nfail) { + return 1; + } + else { + return 0; + } +} diff --git a/capi/tests/capitest.h b/capi/tests/capitest.h new file mode 100644 index 00000000000000..a2e569cb9d6a17 --- /dev/null +++ b/capi/tests/capitest.h @@ -0,0 +1,43 @@ +#ifndef CAPITEST_H +#define CAPITEST_H + +typedef enum { + capitest_enum_SUCCESS, + capitest_enum_FAIL, + capitest_enum_SKIPPED +} capitest_ResultEnum; + +typedef struct { + capitest_ResultEnum result; + const char *msg; + const char *filename; + int lineno; +} capitest_Result; + +#define capitest_FAIL_MSG(message) \ + (capitest_Result){.result = capitest_enum_FAIL, .msg = (message), .filename = __FILE__, .lineno = __LINE__} +#define capitest_FAIL(message) capitest_FAIL_MSG(NULL) +#define capitest_SUCCESS() \ + (capitest_Result){.result = capitest_enum_SUCCESS, .filename = __FILE__, .lineno = __LINE__} + +typedef capitest_Result (*capitest_TestFunc) (); + +typedef struct { + capitest_Result result; + const char *name; + capitest_TestFunc func; +} capitest_Test; + +typedef struct { + size_t ntest; + /* FIXME: don't use hardcoded array size */ + capitest_Test tests[10]; +} capitest_TestSuite; + +#define capitest_TestSuite_INIT {.ntest = 0} + +void capitest_register(capitest_TestSuite *suite, const char *name, capitest_TestFunc func); +void capitest_run_test(capitest_Test *test); +int capitest_run_testsuite(capitest_TestSuite *suite); + +#endif /* CAPITEST_H */ diff --git a/capi/tests/test_tuple.c b/capi/tests/test_tuple.c index 094f9d53d04b1d..2e03ad2e1cc51f 100644 --- a/capi/tests/test_tuple.c +++ b/capi/tests/test_tuple.c @@ -1,39 +1,5 @@ #include - -typedef enum { - capitest_enum_SUCCESS, - capitest_enum_FAIL, - capitest_enum_SKIPPED -} capitest_ResultEnum; - -typedef struct { - capitest_ResultEnum result; - const char *msg; - const char *filename; - int lineno; -} capitest_Result; - -typedef capitest_Result (*capitest_TestFunc) (); - -typedef struct { - capitest_Result result; - const char *name; - capitest_TestFunc func; -} capitest_Test; - -typedef struct { - size_t ntest; - /* FIXME: don't use hardcoded array size */ - capitest_Test tests[10]; -} capitest_TestSuite; - -#define capitest_TestSuite_INIT {.ntest = 0} - -#define capitest_FAIL_MSG(message) \ - (capitest_Result){.result = capitest_enum_FAIL, .msg = (message), .filename = __FILE__, .lineno = __LINE__} -#define capitest_FAIL(message) capitest_FAIL_MSG(NULL) -#define capitest_SUCCESS() \ - (capitest_Result){.result = capitest_enum_SUCCESS, .filename = __FILE__, .lineno = __LINE__} +#include "capitest.h" static capitest_Result check_PyTuple_New_Size(size_t size) @@ -42,7 +8,7 @@ check_PyTuple_New_Size(size_t size) if (tuple == NULL) { return capitest_FAIL(); } - if (Py_TYPE(tuple) != &PyTuple_Type) { + if (!PyTuple_CheckExact(tuple)) { return capitest_FAIL(); } /* don't check Py_REFCNT() to PyTuple_New(0): CPython uses a singleton */ @@ -87,59 +53,13 @@ test_PyTuple_GET_ITEM(void) return capitest_SUCCESS(); } - -static void -capitest_run_test(capitest_Test *test) -{ - printf("%s: ", test->name); - fflush(stdout); - - test->result = test->func(); - capitest_Result *result = &test->result; - - if (result->result == capitest_enum_FAIL) { - printf("FAIL at %s:%i", result->filename, result->lineno); - if (result->msg) { - printf("(%s)", result->msg); - } - printf("\n"); - } - else { - assert(result->result == capitest_enum_SUCCESS); - printf("ok\n"); - } - fflush(stdout); -} - -/* FIXME: handle error */ -static void -capitest_register(capitest_TestSuite *suite, const char *name, capitest_TestFunc func) -{ - capitest_Test test = {.name = name, .func = func}; - assert(suite->ntest < Py_ARRAY_LENGTH(suite->tests)); - size_t i = suite->ntest; - suite->ntest++; - suite->tests[i] = test; -} - #define CAPITEST_REGISTER(suite, test_func) capitest_register(&suite, #test_func, test_func) -static void -capitest_run_testsuite(capitest_TestSuite *suite) -{ - Py_Initialize(); - for (size_t i=0; i < suite->ntest; i++) { - capitest_Test *test = &suite->tests[i]; - capitest_run_test(test); - /* FIXME: store result somewhere */ - } - Py_Finalize(); -} int main() { capitest_TestSuite suite = capitest_TestSuite_INIT ; CAPITEST_REGISTER(suite, test_PyTuple_New); CAPITEST_REGISTER(suite, test_PyTuple_GET_ITEM); - capitest_run_testsuite(&suite); + return capitest_run_testsuite(&suite); } From 1308e688598c5ce1bf27ef59277f80b916f1ba7c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 31 Aug 2018 01:10:51 +0200 Subject: [PATCH 06/50] ignore again Makefile --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ea3bfaae4b2c8e..cf79490079f12e 100644 --- a/.gitignore +++ b/.gitignore @@ -32,7 +32,7 @@ Include/pydtrace_probes.h Lib/distutils/command/*.pdb Lib/lib2to3/*.pickle Lib/test/data/* -#Makefile +Makefile Makefile.pre Misc/python.pc Misc/python-config.sh From 9692ef30c21a3a2e8e2fb44caceab02390ea0723 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 31 Aug 2018 01:20:30 +0200 Subject: [PATCH 07/50] tests: add runtests.c --- capi/tests/.gitignore | 2 +- capi/tests/Makefile | 8 +++++--- capi/tests/capitest.c | 16 +++++++++------- capi/tests/capitest.h | 12 +++++++++--- capi/tests/runtests.c | 13 +++++++++++++ capi/tests/test_tuple.c | 17 +++++++++-------- 6 files changed, 46 insertions(+), 22 deletions(-) create mode 100644 capi/tests/runtests.c diff --git a/capi/tests/.gitignore b/capi/tests/.gitignore index 71ec8777af6723..7bad3b1a47b61c 100644 --- a/capi/tests/.gitignore +++ b/capi/tests/.gitignore @@ -1 +1 @@ -test_tuple +runtests diff --git a/capi/tests/Makefile b/capi/tests/Makefile index 51a35246c6245f..fb11f4d344981d 100644 --- a/capi/tests/Makefile +++ b/capi/tests/Makefile @@ -1,9 +1,11 @@ CPYTHON_SRC=../.. LIBPYTHON=python3.8dm -all: test_tuple - LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib ./test_tuple +all: runtests + LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib ./runtests -test_tuple: test_tuple.c capitest.c +runtests: runtests.c capitest.c test_tuple.c $(CC) -o $@ $^ -I $(CPYTHON_SRC) -I $(CPYTHON_SRC)/Include -l $(LIBPYTHON) -L $(CPYTHON_SRC) +clean: + rm runtests diff --git a/capi/tests/capitest.c b/capi/tests/capitest.c index fbee8a9f6d62d8..0a3259fb0346aa 100644 --- a/capi/tests/capitest.c +++ b/capi/tests/capitest.c @@ -4,20 +4,22 @@ #include "capitest.h" -/* FIXME: handle error */ -void -capitest_register(capitest_TestSuite *suite, const char *name, capitest_TestFunc func) +int +capitest_testsuite_add(capitest_TestSuite *suite, const char *name, capitest_TestFunc func) { capitest_Test test = {.name = name, .func = func}; - assert(suite->ntest < Py_ARRAY_LENGTH(suite->tests)); + if (suite->ntest >= Py_ARRAY_LENGTH(suite->tests)) { + return -1; + } size_t i = suite->ntest; suite->ntest++; suite->tests[i] = test; + return 0; } void -capitest_run_test(capitest_Test *test) +capitest_test_run(capitest_Test *test) { printf("%s: ", test->name); fflush(stdout); @@ -41,13 +43,13 @@ capitest_run_test(capitest_Test *test) int -capitest_run_testsuite(capitest_TestSuite *suite) +capitest_testsuite_run(capitest_TestSuite *suite) { size_t nfail = 0; Py_Initialize(); for (size_t i=0; i < suite->ntest; i++) { capitest_Test *test = &suite->tests[i]; - capitest_run_test(test); + capitest_test_run(test); if (test->result.result != capitest_enum_SUCCESS) { nfail++; } diff --git a/capi/tests/capitest.h b/capi/tests/capitest.h index a2e569cb9d6a17..37116b932ba652 100644 --- a/capi/tests/capitest.h +++ b/capi/tests/capitest.h @@ -36,8 +36,14 @@ typedef struct { #define capitest_TestSuite_INIT {.ntest = 0} -void capitest_register(capitest_TestSuite *suite, const char *name, capitest_TestFunc func); -void capitest_run_test(capitest_Test *test); -int capitest_run_testsuite(capitest_TestSuite *suite); +int capitest_testsuite_add(capitest_TestSuite *suite, const char *name, capitest_TestFunc func); +void capitest_test_run(capitest_Test *test); +int capitest_testsuite_run(capitest_TestSuite *suite); +int capitest_testsuite_clear(capitest_TestSuite *suite); + +#define CAPITEST_REGISTER(suite, test_func) capitest_testsuite_add(suite, #test_func, test_func) + +int register_test_tuple(capitest_TestSuite *suite); + #endif /* CAPITEST_H */ diff --git a/capi/tests/runtests.c b/capi/tests/runtests.c new file mode 100644 index 00000000000000..d9f8c77a6e8006 --- /dev/null +++ b/capi/tests/runtests.c @@ -0,0 +1,13 @@ +#include +#include "capitest.h" + +int main() +{ + capitest_TestSuite suite = capitest_TestSuite_INIT; + if (register_test_tuple(&suite) < 0) { + printf("failed to register test_tuple\n"); + return 1; + } + int exitcode = capitest_testsuite_run(&suite); + return exitcode; +} diff --git a/capi/tests/test_tuple.c b/capi/tests/test_tuple.c index 2e03ad2e1cc51f..86c9cc4ba70022 100644 --- a/capi/tests/test_tuple.c +++ b/capi/tests/test_tuple.c @@ -53,13 +53,14 @@ test_PyTuple_GET_ITEM(void) return capitest_SUCCESS(); } -#define CAPITEST_REGISTER(suite, test_func) capitest_register(&suite, #test_func, test_func) - - -int main() +int +register_test_tuple(capitest_TestSuite *suite) { - capitest_TestSuite suite = capitest_TestSuite_INIT ; - CAPITEST_REGISTER(suite, test_PyTuple_New); - CAPITEST_REGISTER(suite, test_PyTuple_GET_ITEM); - return capitest_run_testsuite(&suite); + if (CAPITEST_REGISTER(suite, test_PyTuple_New) < 0) { + return -1; + } + if (CAPITEST_REGISTER(suite, test_PyTuple_GET_ITEM) < 0) { + return -1; + } + return 0; } From 7e5cf8310477092295495bfdafbf5e7eb300baae Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 31 Aug 2018 01:39:54 +0200 Subject: [PATCH 08/50] more unit tests --- capi/tests/test_tuple.c | 117 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 115 insertions(+), 2 deletions(-) diff --git a/capi/tests/test_tuple.c b/capi/tests/test_tuple.c index 86c9cc4ba70022..d20fe33522c662 100644 --- a/capi/tests/test_tuple.c +++ b/capi/tests/test_tuple.c @@ -1,3 +1,4 @@ +#define Py_NEWCAPI #include #include "capitest.h" @@ -42,25 +43,137 @@ test_PyTuple_New(void) } +static capitest_Result +check_PyTuple_GetItem(size_t size, int use_macro) +{ + capitest_Result res; + PyObject* items[size]; /* strong references */ + PyObject *tuple = PyTuple_New(size); + if (tuple == NULL) { + return capitest_FAIL(); + } + for (int i=i; i < size; i++) { + PyObject *obj = PyLong_FromLong(i); + if (obj == NULL) { + res = capitest_FAIL(); + goto done; + } + if (PyTuple_SetItem(tuple, i, obj) < 0) { + res = capitest_FAIL(); + goto done; + } + items[i] = obj; + } + for (int i=i; i < size; i++) { + PyObject *obj; /* borrowed reference */ + if (use_macro) { + obj = PyTuple_GET_ITEM(tuple, i); + } + else { + obj = PyTuple_GetItem(tuple, i); + } + if (obj != items[i]) { + res = capitest_FAIL(); + goto done; + } + } + res = capitest_SUCCESS(); +done: + for (int i=i; i < size; i++) { + Py_DECREF(items[i]); + } + Py_DECREF(tuple); + return res; +} + + +static capitest_Result +test_PyTuple_GetItem(void) +{ + check_PyTuple_GetItem(3, 0); +} + + static capitest_Result test_PyTuple_GET_ITEM(void) { - PyObject *tuple = PyTuple_New(0); + check_PyTuple_GetItem(3, 1); +} + + +static capitest_Result +check_PyTuple_SizeN(size_t size, int use_macro) +{ + capitest_Result res = capitest_SUCCESS(); + PyObject* items[size]; /* borrowed references */ + PyObject *tuple = PyTuple_New(size); if (tuple == NULL) { return capitest_FAIL(); } + for (int i=i; i < size; i++) { + if (PyTuple_SetItem(tuple, i, Py_None) < 0) { + Py_DECREF(tuple); + return capitest_FAIL(); + } + } + Py_ssize_t tuple_size; + if (use_macro) { + tuple_size = PyTuple_GET_SIZE(tuple); + } + else { + tuple_size = PyTuple_Size(tuple); + } + if (tuple_size != size) { + res = capitest_FAIL(); + goto done; + } +done: Py_DECREF(tuple); - return capitest_SUCCESS(); + return res; } + +static capitest_Result +check_PyTuple_Size(int use_macro) +{ + check_PyTuple_SizeN(0, use_macro); + check_PyTuple_SizeN(1, use_macro); + check_PyTuple_SizeN(2, use_macro); + check_PyTuple_SizeN(5, use_macro); +} + + +static capitest_Result +test_PyTuple_Size(void) +{ + check_PyTuple_Size(0); +} + + +static capitest_Result +test_PyTuple_GET_SIZE(void) +{ + check_PyTuple_Size(1); +} + + int register_test_tuple(capitest_TestSuite *suite) { if (CAPITEST_REGISTER(suite, test_PyTuple_New) < 0) { return -1; } + if (CAPITEST_REGISTER(suite, test_PyTuple_GetItem) < 0) { + return -1; + } if (CAPITEST_REGISTER(suite, test_PyTuple_GET_ITEM) < 0) { return -1; } + if (CAPITEST_REGISTER(suite, test_PyTuple_Size) < 0) { + return -1; + } + if (CAPITEST_REGISTER(suite, test_PyTuple_GET_SIZE) < 0) { + return -1; + } return 0; } From 09174f998fcbfb2e128dd7edad0dd55090a93e35 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 31 Aug 2018 01:40:15 +0200 Subject: [PATCH 09/50] Fix PyTuple_GET_SIZE() --- Include/tupleobject.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Include/tupleobject.h b/Include/tupleobject.h index e97a21eb872eb8..d7a92698130d99 100644 --- a/Include/tupleobject.h +++ b/Include/tupleobject.h @@ -55,7 +55,7 @@ PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *); #ifdef Py_NEWCAPI_BORROWED_REF #define PyTuple_GET_ITEM(op, i) PyTuple_GetItem(op, i) -#define PyTuple_GET_SIZE(op, i) PyTuple_Size(op, i) +#define PyTuple_GET_SIZE(op) PyTuple_Size(op) #define PyTuple_SET_ITEM(op, i, v) PyTuple_SetItem(op, i, v) #elif !defined(Py_LIMITED_API) /* Macro, trading safety for speed */ From 4db4e1ede5ce63800f386520d0d5b041d38ff30c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 31 Aug 2018 01:41:46 +0200 Subject: [PATCH 10/50] build all with Py_NEWCAPI defined --- capi/tests/Makefile | 2 +- capi/tests/test_tuple.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/capi/tests/Makefile b/capi/tests/Makefile index fb11f4d344981d..036dda427ab082 100644 --- a/capi/tests/Makefile +++ b/capi/tests/Makefile @@ -5,7 +5,7 @@ all: runtests LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib ./runtests runtests: runtests.c capitest.c test_tuple.c - $(CC) -o $@ $^ -I $(CPYTHON_SRC) -I $(CPYTHON_SRC)/Include -l $(LIBPYTHON) -L $(CPYTHON_SRC) + $(CC) -D Py_NEWCAPI -o $@ $^ -I $(CPYTHON_SRC) -I $(CPYTHON_SRC)/Include -l $(LIBPYTHON) -L $(CPYTHON_SRC) clean: rm runtests diff --git a/capi/tests/test_tuple.c b/capi/tests/test_tuple.c index d20fe33522c662..f2cdeeb1256f7f 100644 --- a/capi/tests/test_tuple.c +++ b/capi/tests/test_tuple.c @@ -1,4 +1,3 @@ -#define Py_NEWCAPI #include #include "capitest.h" From 11dfb2da412d38e1fcd6bcbf89d2c8980b7b6554 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 31 Aug 2018 11:52:46 +0200 Subject: [PATCH 11/50] Rewrite tests using Check --- README.rst | 6 +- capi/tests/Makefile | 6 +- capi/tests/capitest.c | 72 --------------- capi/tests/capitest.h | 49 ---------- capi/tests/runtests.c | 34 +++++-- capi/tests/test_tuple.c | 200 ++++++++++++++++++++++------------------ 6 files changed, 143 insertions(+), 224 deletions(-) delete mode 100644 capi/tests/capitest.c delete mode 100644 capi/tests/capitest.h diff --git a/README.rst b/README.rst index 99a66f506f3b77..0167547b3b5066 100644 --- a/README.rst +++ b/README.rst @@ -6,9 +6,13 @@ The intent is to experiment to implement the new C API described at: https://pythoncapi.readthedocs.io/ +Install dependencies on Fedora:: + + dnf install -y make gcc check + Build and run unit tests:: - ./configure --with-shared --with-pydebug + ./configure --enable-shared --with-pydebug make cd capi/tests make diff --git a/capi/tests/Makefile b/capi/tests/Makefile index 036dda427ab082..d56bed88d333b3 100644 --- a/capi/tests/Makefile +++ b/capi/tests/Makefile @@ -1,11 +1,13 @@ CPYTHON_SRC=../.. LIBPYTHON=python3.8dm +PYTHON_CFLAGS=-I $(CPYTHON_SRC) -I $(CPYTHON_SRC)/Include +PYTHON_LDFLAGS=-l $(LIBPYTHON) -L $(CPYTHON_SRC) all: runtests LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib ./runtests -runtests: runtests.c capitest.c test_tuple.c - $(CC) -D Py_NEWCAPI -o $@ $^ -I $(CPYTHON_SRC) -I $(CPYTHON_SRC)/Include -l $(LIBPYTHON) -L $(CPYTHON_SRC) +runtests: runtests.c test_tuple.c + $(CC) -g -o $@ $^ -l check $(pkg-config check --cflags --libs) $(PYTHON_CFLAGS) $(PYTHON_LDFLAGS) clean: rm runtests diff --git a/capi/tests/capitest.c b/capi/tests/capitest.c deleted file mode 100644 index 0a3259fb0346aa..00000000000000 --- a/capi/tests/capitest.c +++ /dev/null @@ -1,72 +0,0 @@ -#include -#include -#include -#include "capitest.h" - - -int -capitest_testsuite_add(capitest_TestSuite *suite, const char *name, capitest_TestFunc func) -{ - capitest_Test test = {.name = name, .func = func}; - if (suite->ntest >= Py_ARRAY_LENGTH(suite->tests)) { - return -1; - } - size_t i = suite->ntest; - suite->ntest++; - suite->tests[i] = test; - return 0; -} - - -void -capitest_test_run(capitest_Test *test) -{ - printf("%s: ", test->name); - fflush(stdout); - - test->result = test->func(); - capitest_Result *result = &test->result; - - if (result->result == capitest_enum_FAIL) { - printf("FAIL at %s:%i", result->filename, result->lineno); - if (result->msg) { - printf("(%s)", result->msg); - } - printf("\n"); - } - else { - assert(result->result == capitest_enum_SUCCESS); - printf("ok\n"); - } - fflush(stdout); -} - - -int -capitest_testsuite_run(capitest_TestSuite *suite) -{ - size_t nfail = 0; - Py_Initialize(); - for (size_t i=0; i < suite->ntest; i++) { - capitest_Test *test = &suite->tests[i]; - capitest_test_run(test); - if (test->result.result != capitest_enum_SUCCESS) { - nfail++; - } - } - Py_Finalize(); - printf("\n"); - printf("Tests (%i) result: ", suite->ntest); - if (nfail) { - printf("%s FAILS\n", nfail); - } - else { - printf("SUCCESS\n"); - } - if (nfail) { - return 1; - } - else { - return 0; - } -} diff --git a/capi/tests/capitest.h b/capi/tests/capitest.h deleted file mode 100644 index 37116b932ba652..00000000000000 --- a/capi/tests/capitest.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef CAPITEST_H -#define CAPITEST_H - -typedef enum { - capitest_enum_SUCCESS, - capitest_enum_FAIL, - capitest_enum_SKIPPED -} capitest_ResultEnum; - -typedef struct { - capitest_ResultEnum result; - const char *msg; - const char *filename; - int lineno; -} capitest_Result; - -#define capitest_FAIL_MSG(message) \ - (capitest_Result){.result = capitest_enum_FAIL, .msg = (message), .filename = __FILE__, .lineno = __LINE__} -#define capitest_FAIL(message) capitest_FAIL_MSG(NULL) -#define capitest_SUCCESS() \ - (capitest_Result){.result = capitest_enum_SUCCESS, .filename = __FILE__, .lineno = __LINE__} - -typedef capitest_Result (*capitest_TestFunc) (); - -typedef struct { - capitest_Result result; - const char *name; - capitest_TestFunc func; -} capitest_Test; - -typedef struct { - size_t ntest; - /* FIXME: don't use hardcoded array size */ - capitest_Test tests[10]; -} capitest_TestSuite; - -#define capitest_TestSuite_INIT {.ntest = 0} - -int capitest_testsuite_add(capitest_TestSuite *suite, const char *name, capitest_TestFunc func); -void capitest_test_run(capitest_Test *test); -int capitest_testsuite_run(capitest_TestSuite *suite); -int capitest_testsuite_clear(capitest_TestSuite *suite); - -#define CAPITEST_REGISTER(suite, test_func) capitest_testsuite_add(suite, #test_func, test_func) - -int register_test_tuple(capitest_TestSuite *suite); - - -#endif /* CAPITEST_H */ diff --git a/capi/tests/runtests.c b/capi/tests/runtests.c index d9f8c77a6e8006..e34a1a7a699bab 100644 --- a/capi/tests/runtests.c +++ b/capi/tests/runtests.c @@ -1,13 +1,31 @@ #include -#include "capitest.h" +#include +#include -int main() +void register_PyTuple(Suite *s); + +int main(void) { - capitest_TestSuite suite = capitest_TestSuite_INIT; - if (register_test_tuple(&suite) < 0) { - printf("failed to register test_tuple\n"); - return 1; +#if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x03080000 + _PyCoreConfig config = _PyCoreConfig_INIT; + config._frozen = 1; /* Disable warnings about missing prefix */ + _PyInitError err = _Py_InitializeFromConfig(&config); + if (_Py_INIT_FAILED(err)) { + _Py_FatalInitError(err); } - int exitcode = capitest_testsuite_run(&suite); - return exitcode; +#else + Py_Initialize(); +#endif + + Suite *s = suite_create("CAPI"); + register_PyTuple(s); + SRunner *sr = srunner_create(s); + + srunner_run_all(sr, CK_NORMAL); + int number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + + Py_Finalize(); + + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/capi/tests/test_tuple.c b/capi/tests/test_tuple.c index f2cdeeb1256f7f..51e01f5e34a048 100644 --- a/capi/tests/test_tuple.c +++ b/capi/tests/test_tuple.c @@ -1,68 +1,68 @@ +/* Test PyTuple C API */ + +/* FIXME: write tests for: + - PyTuple_Type + - PyTupleIter_Type + - PyTuple_Check() + - PyTuple_SetItem() + - PyTuple_SET_ITEM() + - PyTuple_GetSlice() +*/ + +/* Not tested in CPython 3.8 full API: + - PyTupleObject + - _PyTuple_Resize() + - _PyTuple_MaybeUntrack() + - PyTuple_ClearFreeList() + - _PyTuple_DebugMallocStats() +*/ + +#include +#include #include -#include "capitest.h" -static capitest_Result -check_PyTuple_New_Size(size_t size) +static void +check_PyTuple_New(size_t size) { PyObject *tuple = PyTuple_New(size); - if (tuple == NULL) { - return capitest_FAIL(); - } - if (!PyTuple_CheckExact(tuple)) { - return capitest_FAIL(); - } - /* don't check Py_REFCNT() to PyTuple_New(0): CPython uses a singleton */ + ck_assert_ptr_nonnull(tuple); + ck_assert(PyTuple_CheckExact(tuple)); + /* don't check Py_REFCNT() on PyTuple_New(0): CPython uses a singleton */ if (size != 0) { - if (Py_REFCNT(tuple) != 1) { - return capitest_FAIL(); - } - } - if (PyTuple_Size(tuple) != size) { - return capitest_FAIL(); + ck_assert_int_eq(Py_REFCNT(tuple), 1); } + ck_assert_int_eq(PyTuple_Size(tuple), size); Py_DECREF(tuple); - return capitest_SUCCESS(); } -static capitest_Result -test_PyTuple_New(void) +START_TEST(test_PyTuple_New) { - capitest_Result result; - result = check_PyTuple_New_Size(0); - if (result.result != capitest_enum_SUCCESS) { - return result; - } - result = check_PyTuple_New_Size(1); - if (result.result != capitest_enum_SUCCESS) { - return result; - } - result = check_PyTuple_New_Size(5); - return result; + check_PyTuple_New(0); + check_PyTuple_New(1); + check_PyTuple_New(5); + + PyObject *tuple = PyTuple_New(-1); + ck_assert_ptr_null(tuple); } +END_TEST -static capitest_Result -check_PyTuple_GetItem(size_t size, int use_macro) +static void +check_PyTuple_GetItem(int use_macro) { - capitest_Result res; + const size_t size = 3; PyObject* items[size]; /* strong references */ PyObject *tuple = PyTuple_New(size); - if (tuple == NULL) { - return capitest_FAIL(); - } + ck_assert_ptr_nonnull(tuple); for (int i=i; i < size; i++) { PyObject *obj = PyLong_FromLong(i); - if (obj == NULL) { - res = capitest_FAIL(); - goto done; - } - if (PyTuple_SetItem(tuple, i, obj) < 0) { - res = capitest_FAIL(); - goto done; - } + ck_assert_ptr_nonnull(obj); + int res = PyTuple_SetItem(tuple, i, obj); + ck_assert_int_eq(res, 0); items[i] = obj; } + for (int i=i; i < size; i++) { PyObject *obj; /* borrowed reference */ if (use_macro) { @@ -71,49 +71,39 @@ check_PyTuple_GetItem(size_t size, int use_macro) else { obj = PyTuple_GetItem(tuple, i); } - if (obj != items[i]) { - res = capitest_FAIL(); - goto done; - } + ck_assert_ptr_eq(obj, items[i]); } - res = capitest_SUCCESS(); -done: + for (int i=i; i < size; i++) { Py_DECREF(items[i]); } Py_DECREF(tuple); - return res; } -static capitest_Result -test_PyTuple_GetItem(void) +START_TEST(test_PyTuple_GetItem) { - check_PyTuple_GetItem(3, 0); + check_PyTuple_GetItem(0); } +END_TEST -static capitest_Result -test_PyTuple_GET_ITEM(void) +START_TEST(test_PyTuple_GET_ITEM) { - check_PyTuple_GetItem(3, 1); + check_PyTuple_GetItem(1); } +END_TEST -static capitest_Result +static void check_PyTuple_SizeN(size_t size, int use_macro) { - capitest_Result res = capitest_SUCCESS(); PyObject* items[size]; /* borrowed references */ PyObject *tuple = PyTuple_New(size); - if (tuple == NULL) { - return capitest_FAIL(); - } + ck_assert_ptr_nonnull(tuple); for (int i=i; i < size; i++) { - if (PyTuple_SetItem(tuple, i, Py_None) < 0) { - Py_DECREF(tuple); - return capitest_FAIL(); - } + int res = PyTuple_SetItem(tuple, i, Py_None); + ck_assert_int_eq(res, 0); } Py_ssize_t tuple_size; if (use_macro) { @@ -122,17 +112,12 @@ check_PyTuple_SizeN(size_t size, int use_macro) else { tuple_size = PyTuple_Size(tuple); } - if (tuple_size != size) { - res = capitest_FAIL(); - goto done; - } -done: + ck_assert_int_eq(tuple_size, size); Py_DECREF(tuple); - return res; } -static capitest_Result +static void check_PyTuple_Size(int use_macro) { check_PyTuple_SizeN(0, use_macro); @@ -142,37 +127,68 @@ check_PyTuple_Size(int use_macro) } -static capitest_Result -test_PyTuple_Size(void) +START_TEST(test_PyTuple_Size) { check_PyTuple_Size(0); } +END_TEST -static capitest_Result -test_PyTuple_GET_SIZE(void) +START_TEST(test_PyTuple_GET_SIZE) { check_PyTuple_Size(1); } +END_TEST -int -register_test_tuple(capitest_TestSuite *suite) +START_TEST(test_PyTuple_CheckExact) { - if (CAPITEST_REGISTER(suite, test_PyTuple_New) < 0) { - return -1; - } - if (CAPITEST_REGISTER(suite, test_PyTuple_GetItem) < 0) { - return -1; - } - if (CAPITEST_REGISTER(suite, test_PyTuple_GET_ITEM) < 0) { - return -1; + PyObject *tuple = PyTuple_New(0); + ck_assert_ptr_nonnull(tuple); + ck_assert(PyTuple_CheckExact(tuple)); + Py_DECREF(tuple); + + PyObject *list = PyList_New(0); + ck_assert_ptr_nonnull(list); + ck_assert(!PyTuple_CheckExact(list)); + Py_DECREF(list); + +} +END_TEST + + +START_TEST(test_PyTuple_Pack) +{ + const size_t size = 3; + PyObject* items[size]; + + for (int i=0; i < size; i++) { + items[i] = PyLong_FromLong(i); + ck_assert_ptr_nonnull(items[i]); } - if (CAPITEST_REGISTER(suite, test_PyTuple_Size) < 0) { - return -1; + + PyObject *tuple = PyTuple_Pack(size, items[0], items[1], items[2]); + ck_assert_int_eq(PyTuple_Size(tuple), size); + for (int i=0; i < size; i++) { + ck_assert_ptr_eq(PyTuple_GetItem(tuple, i), items[i]); } - if (CAPITEST_REGISTER(suite, test_PyTuple_GET_SIZE) < 0) { - return -1; + + for (int i=0; i < size; i++) { + Py_DECREF(items[i]); } - return 0; +} +END_TEST + + +void register_PyTuple(Suite *s) +{ + TCase *tc_core = tcase_create("Py_Tuple"); + tcase_add_test(tc_core, test_PyTuple_New); + tcase_add_test(tc_core, test_PyTuple_GetItem); + tcase_add_test(tc_core, test_PyTuple_GET_ITEM); + tcase_add_test(tc_core, test_PyTuple_Size); + tcase_add_test(tc_core, test_PyTuple_GET_SIZE); + tcase_add_test(tc_core, test_PyTuple_CheckExact); + tcase_add_test(tc_core, test_PyTuple_Pack); + suite_add_tcase(s, tc_core); } From 18ca3a8dd77ffbdedc9174eeffcacdf835ff7538 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 31 Aug 2018 12:25:30 +0200 Subject: [PATCH 12/50] add README to tests --- capi/tests/README.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 capi/tests/README.rst diff --git a/capi/tests/README.rst b/capi/tests/README.rst new file mode 100644 index 00000000000000..1022af68119dc6 --- /dev/null +++ b/capi/tests/README.rst @@ -0,0 +1,12 @@ +++++++++++++++++++++++++++++++ +Test suite on the Python C API +++++++++++++++++++++++++++++++ + +Unit tests are written using the C Unit framework "Check": + + https://libcheck.github.io/check + https://github.com/libcheck/check + +To run unit tests:: + + make From 1dec3c1a5f01815ee2e676b664421d53a149233a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 31 Aug 2018 12:26:12 +0200 Subject: [PATCH 13/50] rename capi/tests/ to capi_tests/ --- README.rst | 2 +- {capi/tests => capi_tests}/.gitignore | 0 {capi/tests => capi_tests}/Makefile | 0 {capi/tests => capi_tests}/README.rst | 0 {capi/tests => capi_tests}/runtests.c | 0 {capi/tests => capi_tests}/test_tuple.c | 0 6 files changed, 1 insertion(+), 1 deletion(-) rename {capi/tests => capi_tests}/.gitignore (100%) rename {capi/tests => capi_tests}/Makefile (100%) rename {capi/tests => capi_tests}/README.rst (100%) rename {capi/tests => capi_tests}/runtests.c (100%) rename {capi/tests => capi_tests}/test_tuple.c (100%) diff --git a/README.rst b/README.rst index 0167547b3b5066..48a6d133b40107 100644 --- a/README.rst +++ b/README.rst @@ -14,7 +14,7 @@ Build and run unit tests:: ./configure --enable-shared --with-pydebug make - cd capi/tests + cd capi_tests make The changes live in the **pythoncapi** branch. See also: diff --git a/capi/tests/.gitignore b/capi_tests/.gitignore similarity index 100% rename from capi/tests/.gitignore rename to capi_tests/.gitignore diff --git a/capi/tests/Makefile b/capi_tests/Makefile similarity index 100% rename from capi/tests/Makefile rename to capi_tests/Makefile diff --git a/capi/tests/README.rst b/capi_tests/README.rst similarity index 100% rename from capi/tests/README.rst rename to capi_tests/README.rst diff --git a/capi/tests/runtests.c b/capi_tests/runtests.c similarity index 100% rename from capi/tests/runtests.c rename to capi_tests/runtests.c diff --git a/capi/tests/test_tuple.c b/capi_tests/test_tuple.c similarity index 100% rename from capi/tests/test_tuple.c rename to capi_tests/test_tuple.c From 1812c37c10b75928015ff23191134a05363f4663 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 31 Aug 2018 14:41:54 +0200 Subject: [PATCH 14/50] fix Makefile for capi_tests/ rename --- capi_tests/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/capi_tests/Makefile b/capi_tests/Makefile index d56bed88d333b3..3e66ea17e6be15 100644 --- a/capi_tests/Makefile +++ b/capi_tests/Makefile @@ -1,4 +1,4 @@ -CPYTHON_SRC=../.. +CPYTHON_SRC=.. LIBPYTHON=python3.8dm PYTHON_CFLAGS=-I $(CPYTHON_SRC) -I $(CPYTHON_SRC)/Include PYTHON_LDFLAGS=-l $(LIBPYTHON) -L $(CPYTHON_SRC) From 9c3b42f2fcd221dbd2751372319b6751d36c8f0a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 31 Aug 2018 14:49:12 +0200 Subject: [PATCH 15/50] Add PyTuple_GetItemRef() and Py_NO_BORROWED_REF If Py_NO_BORROWED_REF is defined, PyTuple_GetItem() and PyTuple_GET_ITEM() are not defined. --- Include/pyport.h | 8 ++++++-- Include/tupleobject.h | 21 +++++++++++++-------- Objects/tupleobject.c | 8 ++++++++ 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/Include/pyport.h b/Include/pyport.h index c1f91062d7c142..7f0b826fabbb7d 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -793,8 +793,12 @@ extern _invalid_parameter_handler _Py_silent_invalid_parameter_handler; #endif /* New C API */ -#ifdef Py_NEWCAPI -# define Py_NEWCAPI_BORROWED_REF +#ifdef Py_NEWCAPI_BORROWED_REF +# define Py_NEWCAPI +#endif + +#if defined(Py_NEWCAPI) && !defined(Py_NEWCAPI_BORROWED_REF) +# define Py_NO_BORROWED_REF #endif #endif /* Py_PYPORT_H */ diff --git a/Include/tupleobject.h b/Include/tupleobject.h index d7a92698130d99..e339a7f5a42cc0 100644 --- a/Include/tupleobject.h +++ b/Include/tupleobject.h @@ -42,7 +42,10 @@ PyAPI_DATA(PyTypeObject) PyTupleIter_Type; PyAPI_FUNC(PyObject *) PyTuple_New(Py_ssize_t size); PyAPI_FUNC(Py_ssize_t) PyTuple_Size(PyObject *); +#ifndef Py_NO_BORROWED_REF PyAPI_FUNC(PyObject *) PyTuple_GetItem(PyObject *, Py_ssize_t); +#endif +PyAPI_FUNC(PyObject *) PyTuple_GetItemRef(PyObject *, Py_ssize_t); PyAPI_FUNC(int) PyTuple_SetItem(PyObject *, Py_ssize_t, PyObject *); PyAPI_FUNC(PyObject *) PyTuple_GetSlice(PyObject *, Py_ssize_t, Py_ssize_t); #ifndef Py_LIMITED_API @@ -54,16 +57,18 @@ PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *); #endif #ifdef Py_NEWCAPI_BORROWED_REF -#define PyTuple_GET_ITEM(op, i) PyTuple_GetItem(op, i) -#define PyTuple_GET_SIZE(op) PyTuple_Size(op) -#define PyTuple_SET_ITEM(op, i, v) PyTuple_SetItem(op, i, v) +# define PyTuple_GET_SIZE(op) PyTuple_Size(op) +# ifdef Py_NEWCAPI_BORROWED_REF +# define PyTuple_GET_ITEM(op, i) PyTuple_GetItem(op, i) +# define PyTuple_SET_ITEM(op, i, v) PyTuple_SetItem(op, i, v) +# endif #elif !defined(Py_LIMITED_API) -/* Macro, trading safety for speed */ -#define PyTuple_GET_ITEM(op, i) (((PyTupleObject *)(op))->ob_item[i]) -#define PyTuple_GET_SIZE(op) (assert(PyTuple_Check(op)),Py_SIZE(op)) + /* Macro, trading safety for speed */ +# define PyTuple_GET_ITEM(op, i) (((PyTupleObject *)(op))->ob_item[i]) +# define PyTuple_GET_SIZE(op) (assert(PyTuple_Check(op)), Py_SIZE(op)) -/* Macro, *only* to be used to fill in brand new tuples */ -#define PyTuple_SET_ITEM(op, i, v) (((PyTupleObject *)(op))->ob_item[i] = v) + /* Macro, *only* to be used to fill in brand new tuples */ +# define PyTuple_SET_ITEM(op, i, v) (((PyTupleObject *)(op))->ob_item[i] = v) #endif PyAPI_FUNC(int) PyTuple_ClearFreeList(void); diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index eaf92d57f3f60a..ac7c352b8556f0 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -159,6 +159,14 @@ PyTuple_GetItem(PyObject *op, Py_ssize_t i) return ((PyTupleObject *)op) -> ob_item[i]; } +PyObject * +PyTuple_GetItemRef(PyObject *op, Py_ssize_t i) +{ + PyObject *item = PyTuple_GetItem(op, i); + Py_XINCREF(item); + return item; +} + int PyTuple_SetItem(PyObject *op, Py_ssize_t i, PyObject *newitem) { From 95ca4ba11e1a7dd8e1f95489d8c24046ac003180 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 31 Aug 2018 14:50:56 +0200 Subject: [PATCH 16/50] Update tests for Py_NO_BORROWED_REF --- capi_tests/Makefile | 6 ++++-- capi_tests/test_tuple.c | 10 +++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/capi_tests/Makefile b/capi_tests/Makefile index 3e66ea17e6be15..1145c8e1096df2 100644 --- a/capi_tests/Makefile +++ b/capi_tests/Makefile @@ -2,12 +2,14 @@ CPYTHON_SRC=.. LIBPYTHON=python3.8dm PYTHON_CFLAGS=-I $(CPYTHON_SRC) -I $(CPYTHON_SRC)/Include PYTHON_LDFLAGS=-l $(LIBPYTHON) -L $(CPYTHON_SRC) +CFLAGS=-D Py_NEWCAPI $(pkg-config check --cflags --libs) $(PYTHON_CFLAGS) +LDFLAGS=$(pkg-config check --libs) $(PYTHON_LDFLAGS) all: runtests LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib ./runtests runtests: runtests.c test_tuple.c - $(CC) -g -o $@ $^ -l check $(pkg-config check --cflags --libs) $(PYTHON_CFLAGS) $(PYTHON_LDFLAGS) + $(CC) -g -o $@ $^ -l check $(CFLAGS) $(LDFLAGS) clean: - rm runtests + rm -f runtests diff --git a/capi_tests/test_tuple.c b/capi_tests/test_tuple.c index 51e01f5e34a048..bba0833763b1bc 100644 --- a/capi_tests/test_tuple.c +++ b/capi_tests/test_tuple.c @@ -48,6 +48,7 @@ START_TEST(test_PyTuple_New) END_TEST +#ifndef Py_NO_BORROWED_REF static void check_PyTuple_GetItem(int use_macro) { @@ -65,6 +66,7 @@ check_PyTuple_GetItem(int use_macro) for (int i=i; i < size; i++) { PyObject *obj; /* borrowed reference */ + Py_ssize_t refcnt = Py_REFCNT(items[i]); if (use_macro) { obj = PyTuple_GET_ITEM(tuple, i); } @@ -72,6 +74,7 @@ check_PyTuple_GetItem(int use_macro) obj = PyTuple_GetItem(tuple, i); } ck_assert_ptr_eq(obj, items[i]); + ck_assert_int_eq(Py_REFCNT(obj), refcnt); } for (int i=i; i < size; i++) { @@ -93,6 +96,7 @@ START_TEST(test_PyTuple_GET_ITEM) check_PyTuple_GetItem(1); } END_TEST +#endif /* Py_NO_BORROWED_REF */ static void @@ -170,7 +174,9 @@ START_TEST(test_PyTuple_Pack) PyObject *tuple = PyTuple_Pack(size, items[0], items[1], items[2]); ck_assert_int_eq(PyTuple_Size(tuple), size); for (int i=0; i < size; i++) { - ck_assert_ptr_eq(PyTuple_GetItem(tuple, i), items[i]); + PyObject *item = PyTuple_GetItemRef(tuple, i); + ck_assert_ptr_eq(item, items[i]); + Py_DECREF(item); } for (int i=0; i < size; i++) { @@ -184,8 +190,10 @@ void register_PyTuple(Suite *s) { TCase *tc_core = tcase_create("Py_Tuple"); tcase_add_test(tc_core, test_PyTuple_New); +#ifndef Py_NO_BORROWED_REF tcase_add_test(tc_core, test_PyTuple_GetItem); tcase_add_test(tc_core, test_PyTuple_GET_ITEM); +#endif tcase_add_test(tc_core, test_PyTuple_Size); tcase_add_test(tc_core, test_PyTuple_GET_SIZE); tcase_add_test(tc_core, test_PyTuple_CheckExact); From 10063d095f682b11caf0235df802275e55ea0f43 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 31 Aug 2018 14:54:52 +0200 Subject: [PATCH 17/50] Test matrix --- capi_tests/.gitignore | 4 +++- capi_tests/Makefile | 26 +++++++++++++++++++------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/capi_tests/.gitignore b/capi_tests/.gitignore index 7bad3b1a47b61c..ba505e5a11e698 100644 --- a/capi_tests/.gitignore +++ b/capi_tests/.gitignore @@ -1 +1,3 @@ -runtests +runtests_fullapi +runtests_newcapi +runtests_no_borrow diff --git a/capi_tests/Makefile b/capi_tests/Makefile index 1145c8e1096df2..0660749e7294e4 100644 --- a/capi_tests/Makefile +++ b/capi_tests/Makefile @@ -2,14 +2,26 @@ CPYTHON_SRC=.. LIBPYTHON=python3.8dm PYTHON_CFLAGS=-I $(CPYTHON_SRC) -I $(CPYTHON_SRC)/Include PYTHON_LDFLAGS=-l $(LIBPYTHON) -L $(CPYTHON_SRC) -CFLAGS=-D Py_NEWCAPI $(pkg-config check --cflags --libs) $(PYTHON_CFLAGS) -LDFLAGS=$(pkg-config check --libs) $(PYTHON_LDFLAGS) +CFLAGS=$(shell pkg-config check --cflags) $(PYTHON_CFLAGS) +LDFLAGS=$(shell pkg-config check --libs) $(PYTHON_LDFLAGS) +SOURCES=runtests.c test_tuple.c -all: runtests - LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib ./runtests +all: runtests_fullapi runtests_newcapi runtests_no_borrow + @echo "=== Full API tests ===" + LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib ./runtests_fullapi + @echo "=== New C API tests ===" + LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib ./runtests_newcapi + @echo "=== No borrowed reference tests ===" + LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib ./runtests_no_borrow -runtests: runtests.c test_tuple.c - $(CC) -g -o $@ $^ -l check $(CFLAGS) $(LDFLAGS) +runtests_fullapi: $(SOURCES) + $(CC) -g -o $@ $^ $(CFLAGS) $(LDFLAGS) + +runtests_newcapi: $(SOURCES) + $(CC) -g -o $@ $^ -D Py_NEWCAPI $(CFLAGS) $(LDFLAGS) + +runtests_no_borrow: $(SOURCES) + $(CC) -g -o $@ $^ -D Py_NEWCAPI_BORROWED_REF $(CFLAGS) $(LDFLAGS) clean: - rm -f runtests + rm -f runtests_fullapi runtests_newcapi runtests_no_borrow From 70515360ac7a9b4329aae3c9e8c4c28b2469a299 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 31 Aug 2018 15:04:34 +0200 Subject: [PATCH 18/50] Add "make testmatrix" "make" in tests now only tests Py_NEWCAPI. Fix also a minor compiler warning. --- README.rst | 3 ++- capi_tests/Makefile | 15 +++++++++++++-- capi_tests/test_tuple.c | 1 - 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 48a6d133b40107..a787af6cb6f712 100644 --- a/README.rst +++ b/README.rst @@ -15,7 +15,8 @@ Build and run unit tests:: ./configure --enable-shared --with-pydebug make cd capi_tests - make + make # only test Py_NEWCAPI + # or to run the full test matrix: make testmatrix The changes live in the **pythoncapi** branch. See also: diff --git a/capi_tests/Makefile b/capi_tests/Makefile index 0660749e7294e4..54990665aaa0a8 100644 --- a/capi_tests/Makefile +++ b/capi_tests/Makefile @@ -1,16 +1,27 @@ CPYTHON_SRC=.. LIBPYTHON=python3.8dm -PYTHON_CFLAGS=-I $(CPYTHON_SRC) -I $(CPYTHON_SRC)/Include +PYTHON_CFLAGS=-Wall -I $(CPYTHON_SRC) -I $(CPYTHON_SRC)/Include PYTHON_LDFLAGS=-l $(LIBPYTHON) -L $(CPYTHON_SRC) CFLAGS=$(shell pkg-config check --cflags) $(PYTHON_CFLAGS) LDFLAGS=$(shell pkg-config check --libs) $(PYTHON_LDFLAGS) SOURCES=runtests.c test_tuple.c -all: runtests_fullapi runtests_newcapi runtests_no_borrow +.PHONY: test_fullapi test_newcapi test_no_borrow +.NOTPARALLEL: test_fullapi test_newcapi test_no_borrow + +all: test_newcapi + +testmatrix: test_fullapi test_newcapi test_no_borrow + +test_fullapi: runtests_fullapi @echo "=== Full API tests ===" LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib ./runtests_fullapi + +test_newcapi: runtests_newcapi @echo "=== New C API tests ===" LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib ./runtests_newcapi + +test_no_borrow: runtests_no_borrow @echo "=== No borrowed reference tests ===" LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib ./runtests_no_borrow diff --git a/capi_tests/test_tuple.c b/capi_tests/test_tuple.c index bba0833763b1bc..0e9b825a91572d 100644 --- a/capi_tests/test_tuple.c +++ b/capi_tests/test_tuple.c @@ -102,7 +102,6 @@ END_TEST static void check_PyTuple_SizeN(size_t size, int use_macro) { - PyObject* items[size]; /* borrowed references */ PyObject *tuple = PyTuple_New(size); ck_assert_ptr_nonnull(tuple); for (int i=i; i < size; i++) { From bea88db564c8607972797098ede7058b1143226a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 31 Aug 2018 15:25:02 +0200 Subject: [PATCH 19/50] Test the new PyTuple_GetItemRef() --- capi_tests/test_tuple.c | 69 +++++++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 16 deletions(-) diff --git a/capi_tests/test_tuple.c b/capi_tests/test_tuple.c index 0e9b825a91572d..f1683aa09fedb9 100644 --- a/capi_tests/test_tuple.c +++ b/capi_tests/test_tuple.c @@ -48,23 +48,62 @@ START_TEST(test_PyTuple_New) END_TEST -#ifndef Py_NO_BORROWED_REF -static void -check_PyTuple_GetItem(int use_macro) +static PyObject* +create_tuple(const size_t size, PyObject **items) { - const size_t size = 3; - PyObject* items[size]; /* strong references */ PyObject *tuple = PyTuple_New(size); ck_assert_ptr_nonnull(tuple); - for (int i=i; i < size; i++) { + for (size_t i=0; i < size; i++) { PyObject *obj = PyLong_FromLong(i); ck_assert_ptr_nonnull(obj); int res = PyTuple_SetItem(tuple, i, obj); ck_assert_int_eq(res, 0); items[i] = obj; } + return tuple; +} + + +static void +free_tuple(PyObject *tuple, PyObject **items) +{ + size_t size = PyTuple_Size(tuple); + for (size_t i=0; i < size; i++) { + Py_DECREF(items); + } + Py_DECREF(tuple); +} + - for (int i=i; i < size; i++) { +START_TEST(test_PyTuple_GetItemRef) +{ + const size_t size = 5; + PyObject* items[size]; /* strong references */ + PyObject *tuple = create_tuple(size, items); + + for (size_t i=0; i < size; i++) { + PyObject *obj; /* borrowed reference */ + Py_ssize_t refcnt = Py_REFCNT(items[i]); + obj = PyTuple_GetItemRef(tuple, i); + ck_assert_ptr_eq(obj, items[i]); + ck_assert_int_eq(Py_REFCNT(obj), refcnt + 1); + Py_DECREF(obj); + } + + free_tuple(tuple, items); +} +END_TEST + + +#ifndef Py_NO_BORROWED_REF +static void +check_PyTuple_GetItem(int use_macro) +{ + const size_t size = 5; + PyObject* items[size]; /* strong references */ + PyObject *tuple = create_tuple(size, items); + + for (size_t i=0; i < size; i++) { PyObject *obj; /* borrowed reference */ Py_ssize_t refcnt = Py_REFCNT(items[i]); if (use_macro) { @@ -77,10 +116,7 @@ check_PyTuple_GetItem(int use_macro) ck_assert_int_eq(Py_REFCNT(obj), refcnt); } - for (int i=i; i < size; i++) { - Py_DECREF(items[i]); - } - Py_DECREF(tuple); + free_tuple(tuple, items); } @@ -104,7 +140,7 @@ check_PyTuple_SizeN(size_t size, int use_macro) { PyObject *tuple = PyTuple_New(size); ck_assert_ptr_nonnull(tuple); - for (int i=i; i < size; i++) { + for (size_t i=i; i < size; i++) { int res = PyTuple_SetItem(tuple, i, Py_None); ck_assert_int_eq(res, 0); } @@ -165,20 +201,20 @@ START_TEST(test_PyTuple_Pack) const size_t size = 3; PyObject* items[size]; - for (int i=0; i < size; i++) { + for (size_t i=0; i < size; i++) { items[i] = PyLong_FromLong(i); ck_assert_ptr_nonnull(items[i]); } PyObject *tuple = PyTuple_Pack(size, items[0], items[1], items[2]); ck_assert_int_eq(PyTuple_Size(tuple), size); - for (int i=0; i < size; i++) { + for (size_t i=0; i < size; i++) { PyObject *item = PyTuple_GetItemRef(tuple, i); ck_assert_ptr_eq(item, items[i]); Py_DECREF(item); } - for (int i=0; i < size; i++) { + for (size_t i=0; i < size; i++) { Py_DECREF(items[i]); } } @@ -187,8 +223,9 @@ END_TEST void register_PyTuple(Suite *s) { - TCase *tc_core = tcase_create("Py_Tuple"); + TCase *tc_core = tcase_create("PyTuple"); tcase_add_test(tc_core, test_PyTuple_New); + tcase_add_test(tc_core, test_PyTuple_GetItemRef); #ifndef Py_NO_BORROWED_REF tcase_add_test(tc_core, test_PyTuple_GetItem); tcase_add_test(tc_core, test_PyTuple_GET_ITEM); From 66de200d653505c057269e7442cd1589b4cd6668 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 31 Aug 2018 15:27:22 +0200 Subject: [PATCH 20/50] fix typo --- capi_tests/test_tuple.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/capi_tests/test_tuple.c b/capi_tests/test_tuple.c index f1683aa09fedb9..a524d34dd169b0 100644 --- a/capi_tests/test_tuple.c +++ b/capi_tests/test_tuple.c @@ -140,7 +140,7 @@ check_PyTuple_SizeN(size_t size, int use_macro) { PyObject *tuple = PyTuple_New(size); ck_assert_ptr_nonnull(tuple); - for (size_t i=i; i < size; i++) { + for (size_t i=0; i < size; i++) { int res = PyTuple_SetItem(tuple, i, Py_None); ck_assert_int_eq(res, 0); } From 3f94c13817a00e5431228462ad9b421d5fda0393 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 31 Aug 2018 15:28:04 +0200 Subject: [PATCH 21/50] coding style --- capi_tests/test_tuple.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/capi_tests/test_tuple.c b/capi_tests/test_tuple.c index a524d34dd169b0..f34fbbe87ace16 100644 --- a/capi_tests/test_tuple.c +++ b/capi_tests/test_tuple.c @@ -53,7 +53,7 @@ create_tuple(const size_t size, PyObject **items) { PyObject *tuple = PyTuple_New(size); ck_assert_ptr_nonnull(tuple); - for (size_t i=0; i < size; i++) { + for (size_t i = 0; i < size; i++) { PyObject *obj = PyLong_FromLong(i); ck_assert_ptr_nonnull(obj); int res = PyTuple_SetItem(tuple, i, obj); @@ -68,7 +68,7 @@ static void free_tuple(PyObject *tuple, PyObject **items) { size_t size = PyTuple_Size(tuple); - for (size_t i=0; i < size; i++) { + for (size_t i = 0; i < size; i++) { Py_DECREF(items); } Py_DECREF(tuple); @@ -81,7 +81,7 @@ START_TEST(test_PyTuple_GetItemRef) PyObject* items[size]; /* strong references */ PyObject *tuple = create_tuple(size, items); - for (size_t i=0; i < size; i++) { + for (size_t i = 0; i < size; i++) { PyObject *obj; /* borrowed reference */ Py_ssize_t refcnt = Py_REFCNT(items[i]); obj = PyTuple_GetItemRef(tuple, i); @@ -103,7 +103,7 @@ check_PyTuple_GetItem(int use_macro) PyObject* items[size]; /* strong references */ PyObject *tuple = create_tuple(size, items); - for (size_t i=0; i < size; i++) { + for (size_t i = 0; i < size; i++) { PyObject *obj; /* borrowed reference */ Py_ssize_t refcnt = Py_REFCNT(items[i]); if (use_macro) { @@ -140,7 +140,7 @@ check_PyTuple_SizeN(size_t size, int use_macro) { PyObject *tuple = PyTuple_New(size); ck_assert_ptr_nonnull(tuple); - for (size_t i=0; i < size; i++) { + for (size_t i = 0; i < size; i++) { int res = PyTuple_SetItem(tuple, i, Py_None); ck_assert_int_eq(res, 0); } @@ -201,20 +201,20 @@ START_TEST(test_PyTuple_Pack) const size_t size = 3; PyObject* items[size]; - for (size_t i=0; i < size; i++) { + for (size_t i = 0; i < size; i++) { items[i] = PyLong_FromLong(i); ck_assert_ptr_nonnull(items[i]); } PyObject *tuple = PyTuple_Pack(size, items[0], items[1], items[2]); ck_assert_int_eq(PyTuple_Size(tuple), size); - for (size_t i=0; i < size; i++) { + for (size_t i = 0; i < size; i++) { PyObject *item = PyTuple_GetItemRef(tuple, i); ck_assert_ptr_eq(item, items[i]); Py_DECREF(item); } - for (size_t i=0; i < size; i++) { + for (size_t i = 0; i < size; i++) { Py_DECREF(items[i]); } } From 04fdf505a5d5f94697896f5827f75b9f95f3f03c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 31 Aug 2018 15:53:51 +0200 Subject: [PATCH 22/50] Add PyTuple_SetItemRef() --- Include/tupleobject.h | 3 + Objects/tupleobject.c | 7 ++ capi_tests/test_tuple.c | 272 ++++++++++++++++++++++++++-------------- 3 files changed, 190 insertions(+), 92 deletions(-) diff --git a/Include/tupleobject.h b/Include/tupleobject.h index e339a7f5a42cc0..c8ecfa39504214 100644 --- a/Include/tupleobject.h +++ b/Include/tupleobject.h @@ -46,7 +46,10 @@ PyAPI_FUNC(Py_ssize_t) PyTuple_Size(PyObject *); PyAPI_FUNC(PyObject *) PyTuple_GetItem(PyObject *, Py_ssize_t); #endif PyAPI_FUNC(PyObject *) PyTuple_GetItemRef(PyObject *, Py_ssize_t); +#ifndef Py_NO_BORROWED_REF PyAPI_FUNC(int) PyTuple_SetItem(PyObject *, Py_ssize_t, PyObject *); +#endif +PyAPI_FUNC(int) PyTuple_SetItemRef(PyObject *, Py_ssize_t, PyObject *); PyAPI_FUNC(PyObject *) PyTuple_GetSlice(PyObject *, Py_ssize_t, Py_ssize_t); #ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyTuple_Resize(PyObject **, Py_ssize_t); diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index ac7c352b8556f0..a0349f44ad27a2 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -187,6 +187,13 @@ PyTuple_SetItem(PyObject *op, Py_ssize_t i, PyObject *newitem) return 0; } +int +PyTuple_SetItemRef(PyObject *op, Py_ssize_t i, PyObject *newitem) +{ + Py_INCREF(newitem); + return PyTuple_SetItem(op, i, newitem); +} + void _PyTuple_MaybeUntrack(PyObject *op) { diff --git a/capi_tests/test_tuple.c b/capi_tests/test_tuple.c index f34fbbe87ace16..ed57fc1e37be95 100644 --- a/capi_tests/test_tuple.c +++ b/capi_tests/test_tuple.c @@ -4,8 +4,6 @@ - PyTuple_Type - PyTupleIter_Type - PyTuple_Check() - - PyTuple_SetItem() - - PyTuple_SET_ITEM() - PyTuple_GetSlice() */ @@ -21,6 +19,20 @@ #include #include +#define SMALL_SIZE 5 + +#ifndef Py_NO_BORROWED_REF +# define BORROW_REF +#endif + +typedef enum { + STRONG, +#ifdef BORROW_REF + MACRO, + BORROW +#endif +} func_type; + static void check_PyTuple_New(size_t size) { @@ -48,91 +60,20 @@ START_TEST(test_PyTuple_New) END_TEST -static PyObject* -create_tuple(const size_t size, PyObject **items) +START_TEST(test_PyTuple_CheckExact) { - PyObject *tuple = PyTuple_New(size); + PyObject *tuple = PyTuple_New(0); ck_assert_ptr_nonnull(tuple); - for (size_t i = 0; i < size; i++) { - PyObject *obj = PyLong_FromLong(i); - ck_assert_ptr_nonnull(obj); - int res = PyTuple_SetItem(tuple, i, obj); - ck_assert_int_eq(res, 0); - items[i] = obj; - } - return tuple; -} - - -static void -free_tuple(PyObject *tuple, PyObject **items) -{ - size_t size = PyTuple_Size(tuple); - for (size_t i = 0; i < size; i++) { - Py_DECREF(items); - } + ck_assert(PyTuple_CheckExact(tuple)); Py_DECREF(tuple); -} - - -START_TEST(test_PyTuple_GetItemRef) -{ - const size_t size = 5; - PyObject* items[size]; /* strong references */ - PyObject *tuple = create_tuple(size, items); - - for (size_t i = 0; i < size; i++) { - PyObject *obj; /* borrowed reference */ - Py_ssize_t refcnt = Py_REFCNT(items[i]); - obj = PyTuple_GetItemRef(tuple, i); - ck_assert_ptr_eq(obj, items[i]); - ck_assert_int_eq(Py_REFCNT(obj), refcnt + 1); - Py_DECREF(obj); - } - - free_tuple(tuple, items); -} -END_TEST - - -#ifndef Py_NO_BORROWED_REF -static void -check_PyTuple_GetItem(int use_macro) -{ - const size_t size = 5; - PyObject* items[size]; /* strong references */ - PyObject *tuple = create_tuple(size, items); - - for (size_t i = 0; i < size; i++) { - PyObject *obj; /* borrowed reference */ - Py_ssize_t refcnt = Py_REFCNT(items[i]); - if (use_macro) { - obj = PyTuple_GET_ITEM(tuple, i); - } - else { - obj = PyTuple_GetItem(tuple, i); - } - ck_assert_ptr_eq(obj, items[i]); - ck_assert_int_eq(Py_REFCNT(obj), refcnt); - } - - free_tuple(tuple, items); -} - - -START_TEST(test_PyTuple_GetItem) -{ - check_PyTuple_GetItem(0); -} -END_TEST + PyObject *list = PyList_New(0); + ck_assert_ptr_nonnull(list); + ck_assert(!PyTuple_CheckExact(list)); + Py_DECREF(list); -START_TEST(test_PyTuple_GET_ITEM) -{ - check_PyTuple_GetItem(1); } END_TEST -#endif /* Py_NO_BORROWED_REF */ static void @@ -141,7 +82,7 @@ check_PyTuple_SizeN(size_t size, int use_macro) PyObject *tuple = PyTuple_New(size); ck_assert_ptr_nonnull(tuple); for (size_t i = 0; i < size; i++) { - int res = PyTuple_SetItem(tuple, i, Py_None); + int res = PyTuple_SetItemRef(tuple, i, Py_None); ck_assert_int_eq(res, 0); } Py_ssize_t tuple_size; @@ -180,20 +121,91 @@ START_TEST(test_PyTuple_GET_SIZE) END_TEST -START_TEST(test_PyTuple_CheckExact) +static PyObject* +create_tuple(const size_t size, PyObject **items) { - PyObject *tuple = PyTuple_New(0); + PyObject *tuple = PyTuple_New(size); ck_assert_ptr_nonnull(tuple); - ck_assert(PyTuple_CheckExact(tuple)); + for (size_t i = 0; i < size; i++) { + PyObject *obj = PyLong_FromLong(i); + ck_assert_ptr_nonnull(obj); + int res = PyTuple_SetItemRef(tuple, i, obj); + ck_assert_int_eq(res, 0); + items[i] = obj; + } + return tuple; +} + + +static void +free_tuple(PyObject *tuple, PyObject **items) +{ + size_t size = PyTuple_Size(tuple); + for (size_t i = 0; i < size; i++) { + Py_DECREF(items); + } Py_DECREF(tuple); +} - PyObject *list = PyList_New(0); - ck_assert_ptr_nonnull(list); - ck_assert(!PyTuple_CheckExact(list)); - Py_DECREF(list); +static void +check_PyTuple_GetItem(func_type ftype) +{ + const size_t size = SMALL_SIZE; + PyObject* items[size]; /* strong references */ + PyObject *tuple = create_tuple(size, items); + + for (size_t i = 0; i < size; i++) { + PyObject *obj; /* borrowed reference */ + Py_ssize_t refcnt = Py_REFCNT(items[i]); + + switch(ftype) { + case STRONG: + obj = PyTuple_GetItemRef(tuple, i); + ck_assert_int_eq(Py_REFCNT(obj), refcnt + 1); + break; +#ifdef BORROW_REF + case MACRO: + obj = PyTuple_GET_ITEM(tuple, i); + ck_assert_int_eq(Py_REFCNT(obj), refcnt); + Py_INCREF(obj); + break; + case BORROW: + obj = PyTuple_GetItem(tuple, i); + ck_assert_int_eq(Py_REFCNT(obj), refcnt); + Py_INCREF(obj); + break; +#endif + } + ck_assert_ptr_eq(obj, items[i]); + Py_DECREF(obj); + } + + free_tuple(tuple, items); +} + + +START_TEST(test_PyTuple_GetItemRef) +{ + check_PyTuple_GetItem(STRONG); +} +END_TEST + + +#ifdef BORROW_REF +START_TEST(test_PyTuple_GetItem) +{ + check_PyTuple_GetItem(BORROW); +} +END_TEST + + +START_TEST(test_PyTuple_GET_ITEM) +{ + check_PyTuple_GetItem(MACRO); } END_TEST +#endif /* BORROW_REF */ START_TEST(test_PyTuple_Pack) @@ -221,18 +233,94 @@ START_TEST(test_PyTuple_Pack) END_TEST +static void +check_PyTuple_SetItemRef(func_type ftype) +{ + const size_t size = SMALL_SIZE; + PyObject *tuple = PyTuple_New(size); + ck_assert_ptr_nonnull(tuple); + for (size_t i = 0; i < size; i++) { + PyObject *obj = PyLong_FromLong(i); + ck_assert_ptr_nonnull(obj); + Py_ssize_t refcnt = Py_REFCNT(obj); + + switch (ftype) + { + case STRONG: + { + int res = PyTuple_SetItemRef(tuple, i, obj); + ck_assert_int_eq(res, 0); + ck_assert_int_eq(Py_REFCNT(obj), refcnt + 1); + break; + } +#ifdef BORROW_REF + case BORROW: + { + int res = PyTuple_SetItem(tuple, i, obj); + ck_assert_int_eq(res, 0); + ck_assert_int_eq(Py_REFCNT(obj), refcnt); + Py_INCREF(obj); + break; + } + case MACRO: + { + PyTuple_SET_ITEM(tuple, i, obj); + ck_assert_int_eq(Py_REFCNT(obj), refcnt); + Py_INCREF(obj); + break; + } +#endif + } + + PyObject *obj2 = PyTuple_GetItemRef(tuple, i); + ck_assert_ptr_eq(obj, obj2); + Py_DECREF(obj); + Py_DECREF(obj2); + } + Py_DECREF(tuple); +} + + +START_TEST(test_PyTuple_SetItemRef) +{ + check_PyTuple_SetItemRef(STRONG); +} +END_TEST + + +#ifdef BORROW_REF +START_TEST(test_PyTuple_SetItem) +{ + check_PyTuple_SetItemRef(BORROW); +} +END_TEST + + +START_TEST(test_PyTuple_SET_ITEM) +{ + check_PyTuple_SetItemRef(MACRO); +} +END_TEST +#endif + + void register_PyTuple(Suite *s) { TCase *tc_core = tcase_create("PyTuple"); tcase_add_test(tc_core, test_PyTuple_New); + tcase_add_test(tc_core, test_PyTuple_CheckExact); + tcase_add_test(tc_core, test_PyTuple_Size); + tcase_add_test(tc_core, test_PyTuple_GET_SIZE); tcase_add_test(tc_core, test_PyTuple_GetItemRef); -#ifndef Py_NO_BORROWED_REF +#ifdef BORROW_REF tcase_add_test(tc_core, test_PyTuple_GetItem); tcase_add_test(tc_core, test_PyTuple_GET_ITEM); #endif - tcase_add_test(tc_core, test_PyTuple_Size); - tcase_add_test(tc_core, test_PyTuple_GET_SIZE); - tcase_add_test(tc_core, test_PyTuple_CheckExact); + tcase_add_test(tc_core, test_PyTuple_SetItemRef); +#ifdef BORROW_REF + tcase_add_test(tc_core, test_PyTuple_SetItem); + tcase_add_test(tc_core, test_PyTuple_SET_ITEM); +#endif tcase_add_test(tc_core, test_PyTuple_Pack); suite_add_tcase(s, tc_core); } From 8142989d0eab279c7dd0f5bc7efd1add50340134 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 31 Aug 2018 15:55:20 +0200 Subject: [PATCH 23/50] add TODO.rst --- README.rst | 2 ++ TODO.rst | 4 ++++ 2 files changed, 6 insertions(+) create mode 100644 TODO.rst diff --git a/README.rst b/README.rst index a787af6cb6f712..96e9184e0cd8e3 100644 --- a/README.rst +++ b/README.rst @@ -18,6 +18,8 @@ Build and run unit tests:: make # only test Py_NEWCAPI # or to run the full test matrix: make testmatrix +If you want to help, look at ``TODO.rst``. + The changes live in the **pythoncapi** branch. See also: * `github.com/pythoncapi/cpython `_ diff --git a/TODO.rst b/TODO.rst new file mode 100644 index 00000000000000..70ad545946a7f5 --- /dev/null +++ b/TODO.rst @@ -0,0 +1,4 @@ +TODO list for new Python C API +============================== + +* capi_tests: check for reference leaks From 525c2ddc888008f9a81020a1dfb95a32bbc94337 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Sep 2018 01:11:06 +0200 Subject: [PATCH 24/50] Fix free_tuple() --- capi_tests/test_tuple.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/capi_tests/test_tuple.c b/capi_tests/test_tuple.c index ed57fc1e37be95..debca2acb4f10f 100644 --- a/capi_tests/test_tuple.c +++ b/capi_tests/test_tuple.c @@ -142,7 +142,7 @@ free_tuple(PyObject *tuple, PyObject **items) { size_t size = PyTuple_Size(tuple); for (size_t i = 0; i < size; i++) { - Py_DECREF(items); + Py_DECREF(items[i]); } Py_DECREF(tuple); } From 26d79d30de9b18c466d1937e161e438490f9496b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Sep 2018 00:48:25 +0200 Subject: [PATCH 25/50] test Py_INCREF() --- capi_tests/Makefile | 2 +- capi_tests/runtests.c | 2 ++ capi_tests/test_object.c | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 capi_tests/test_object.c diff --git a/capi_tests/Makefile b/capi_tests/Makefile index 54990665aaa0a8..f0a7e00d61e419 100644 --- a/capi_tests/Makefile +++ b/capi_tests/Makefile @@ -4,7 +4,7 @@ PYTHON_CFLAGS=-Wall -I $(CPYTHON_SRC) -I $(CPYTHON_SRC)/Include PYTHON_LDFLAGS=-l $(LIBPYTHON) -L $(CPYTHON_SRC) CFLAGS=$(shell pkg-config check --cflags) $(PYTHON_CFLAGS) LDFLAGS=$(shell pkg-config check --libs) $(PYTHON_LDFLAGS) -SOURCES=runtests.c test_tuple.c +SOURCES=runtests.c test_object.c test_tuple.c .PHONY: test_fullapi test_newcapi test_no_borrow .NOTPARALLEL: test_fullapi test_newcapi test_no_borrow diff --git a/capi_tests/runtests.c b/capi_tests/runtests.c index e34a1a7a699bab..f49aec9357f944 100644 --- a/capi_tests/runtests.c +++ b/capi_tests/runtests.c @@ -2,6 +2,7 @@ #include #include +void register_PyObject(Suite *s); void register_PyTuple(Suite *s); int main(void) @@ -18,6 +19,7 @@ int main(void) #endif Suite *s = suite_create("CAPI"); + register_PyObject(s); register_PyTuple(s); SRunner *sr = srunner_create(s); diff --git a/capi_tests/test_object.c b/capi_tests/test_object.c new file mode 100644 index 00000000000000..63724ea47c5c81 --- /dev/null +++ b/capi_tests/test_object.c @@ -0,0 +1,39 @@ +/* Test PyObject API */ + +#include +#include +#include + + +START_TEST(test_Py_INCREF) +{ + PyObject *obj = Py_None; + Py_ssize_t refcnt = Py_REFCNT(obj); + + Py_INCREF(obj); + ck_assert_int_eq(Py_REFCNT(obj), refcnt + 1); + + Py_DECREF(obj); +} +END_TEST + + +START_TEST(test_Py_DECREF) +{ + PyObject *obj = Py_None; + Py_INCREF(obj); + Py_ssize_t refcnt = Py_REFCNT(obj); + + Py_DECREF(obj); + ck_assert_int_eq(Py_REFCNT(obj), refcnt - 1); +} +END_TEST + + +void register_PyObject(Suite *s) +{ + TCase *testcase = tcase_create("PyObject"); + tcase_add_test(testcase, test_Py_INCREF); + tcase_add_test(testcase, test_Py_DECREF); + suite_add_tcase(s, testcase); +} From 03d1556bb9065f2ff4f08b334532063d68c31619 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Sep 2018 01:11:34 +0200 Subject: [PATCH 26/50] Replace Py_INCREF/DECREF macros with function calls --- Include/object.h | 7 +++++++ Include/pyport.h | 18 +++++++++++++++--- Include/tupleobject.h | 2 +- Objects/object.c | 15 +++++++++++++++ 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/Include/object.h b/Include/object.h index c772deaf57dbb5..3fa4229ad37213 100644 --- a/Include/object.h +++ b/Include/object.h @@ -790,6 +790,12 @@ PyAPI_FUNC(void) _Py_Dealloc(PyObject *); #endif #endif /* !Py_TRACE_REFS */ +#ifdef Py_NEWCAPI_NO_STRUCT +PyAPI_FUNC(void) _Py_INCREF_impl(PyObject *op); +# define Py_INCREF(op) _Py_INCREF_impl(op) +PyAPI_FUNC(void) _Py_DECREF_impl(PyObject *op); +# define Py_DECREF(op) _Py_DECREF_impl(op) +#else #define Py_INCREF(op) ( \ _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \ ((PyObject *)(op))->ob_refcnt++) @@ -803,6 +809,7 @@ PyAPI_FUNC(void) _Py_Dealloc(PyObject *); else \ _Py_Dealloc(_py_decref_tmp); \ } while (0) +#endif /* Safely decref `op` and set `op` to NULL, especially useful in tp_clear * and tp_dealloc implementations. diff --git a/Include/pyport.h b/Include/pyport.h index 7f0b826fabbb7d..51d0cb7a2ae9ec 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -792,13 +792,25 @@ extern _invalid_parameter_handler _Py_silent_invalid_parameter_handler; #define WITH_THREAD #endif -/* New C API */ +/* New C API: + * Py_NEWCAPI_BORROWED_REF: new C API with borrowed references + * Py_NEWCAPI: new C API without borrowed references + * Py_NEWCAPI_NO_MACRO: replace macros with function calls + * PyTuple_GET_SIZE() becomes PyTuple_Size() + * Py_NEWCAPI_NO_STRUCT: must not use PyObject.ob_refcnt or any other field + * of Python object structures; structures should hide their fields: + * compilation error. + */ #ifdef Py_NEWCAPI_BORROWED_REF # define Py_NEWCAPI #endif -#if defined(Py_NEWCAPI) && !defined(Py_NEWCAPI_BORROWED_REF) -# define Py_NO_BORROWED_REF +#if defined(Py_NEWCAPI) +# define Py_NEWCAPI_NO_STRUCT +# define Py_NEWCAPI_NO_MACRO +# ifndef Py_NEWCAPI_BORROWED_REF +# define Py_NO_BORROWED_REF +# endif #endif #endif /* Py_PYPORT_H */ diff --git a/Include/tupleobject.h b/Include/tupleobject.h index c8ecfa39504214..a381579ff0efb0 100644 --- a/Include/tupleobject.h +++ b/Include/tupleobject.h @@ -59,7 +59,7 @@ PyAPI_FUNC(PyObject *) PyTuple_Pack(Py_ssize_t, ...); PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *); #endif -#ifdef Py_NEWCAPI_BORROWED_REF +#ifdef Py_NEWCAPI_NO_MACRO # define PyTuple_GET_SIZE(op) PyTuple_Size(op) # ifdef Py_NEWCAPI_BORROWED_REF # define PyTuple_GET_ITEM(op, i) PyTuple_GetItem(op, i) diff --git a/Objects/object.c b/Objects/object.c index 6498756c92bd0d..ccdb355e8baca2 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -39,6 +39,21 @@ _PyDebug_PrintTotalRefs(void) { } #endif /* Py_REF_DEBUG */ + +void +_Py_INCREF_impl(PyObject *op) +{ + Py_INCREF(op); +} + + +void +_Py_DECREF_impl(PyObject *op) +{ + Py_DECREF(op); +} + + /* Object allocation routines used by NEWOBJ and NEWVAROBJ macros. These are used by the individual routines for object creation. Do not call them otherwise, they do not initialize the object! */ From 8e6eee8c866b313a5a1bce8b131c8a86a5cbf591 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Sep 2018 01:22:40 +0200 Subject: [PATCH 27/50] detect reference leaks --- capi_tests/Makefile | 8 +++++--- capi_tests/runtests.c | 17 ++++++++++++++++- capi_tests/test_tuple.c | 2 ++ 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/capi_tests/Makefile b/capi_tests/Makefile index f0a7e00d61e419..2bb625e4dc6e2d 100644 --- a/capi_tests/Makefile +++ b/capi_tests/Makefile @@ -5,6 +5,8 @@ PYTHON_LDFLAGS=-l $(LIBPYTHON) -L $(CPYTHON_SRC) CFLAGS=$(shell pkg-config check --cflags) $(PYTHON_CFLAGS) LDFLAGS=$(shell pkg-config check --libs) $(PYTHON_LDFLAGS) SOURCES=runtests.c test_object.c test_tuple.c +# CK_FORK=no to detect reference leaks +ENV_RUNTEST=CK_FORK=no LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib .PHONY: test_fullapi test_newcapi test_no_borrow .NOTPARALLEL: test_fullapi test_newcapi test_no_borrow @@ -15,15 +17,15 @@ testmatrix: test_fullapi test_newcapi test_no_borrow test_fullapi: runtests_fullapi @echo "=== Full API tests ===" - LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib ./runtests_fullapi + $(ENV_RUNTEST) ./runtests_fullapi test_newcapi: runtests_newcapi @echo "=== New C API tests ===" - LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib ./runtests_newcapi + $(ENV_RUNTEST) ./runtests_newcapi test_no_borrow: runtests_no_borrow @echo "=== No borrowed reference tests ===" - LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib ./runtests_no_borrow + $(ENV_RUNTEST) ./runtests_no_borrow runtests_fullapi: $(SOURCES) $(CC) -g -o $@ $^ $(CFLAGS) $(LDFLAGS) diff --git a/capi_tests/runtests.c b/capi_tests/runtests.c index f49aec9357f944..0d59a160e21718 100644 --- a/capi_tests/runtests.c +++ b/capi_tests/runtests.c @@ -18,6 +18,11 @@ int main(void) Py_Initialize(); #endif + int exitcode; +#ifdef Py_REF_DEBUG + Py_ssize_t ref_total = _Py_RefTotal; +#endif + Suite *s = suite_create("CAPI"); register_PyObject(s); register_PyTuple(s); @@ -27,7 +32,17 @@ int main(void) int number_failed = srunner_ntests_failed(sr); srunner_free(sr); + exitcode = (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; + +#ifdef Py_REF_DEBUG + Py_ssize_t ref_diff = _Py_RefTotal - ref_total; + if (ref_diff != 0) { + printf("ERROR: total reference count changed: %+zi!\n", ref_diff); + exitcode = EXIT_FAILURE; + } +#endif + Py_Finalize(); - return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; + return exitcode; } diff --git a/capi_tests/test_tuple.c b/capi_tests/test_tuple.c index debca2acb4f10f..b4a0122793c755 100644 --- a/capi_tests/test_tuple.c +++ b/capi_tests/test_tuple.c @@ -56,6 +56,7 @@ START_TEST(test_PyTuple_New) PyObject *tuple = PyTuple_New(-1); ck_assert_ptr_null(tuple); + PyErr_Clear(); } END_TEST @@ -225,6 +226,7 @@ START_TEST(test_PyTuple_Pack) ck_assert_ptr_eq(item, items[i]); Py_DECREF(item); } + Py_DECREF(tuple); for (size_t i = 0; i < size; i++) { Py_DECREF(items[i]); From 87066c026925f6e4381f12578c23f051204b71e4 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Sep 2018 01:56:40 +0200 Subject: [PATCH 28/50] Convert Py_REFCNT, Py_TYPE, Py_SIZE to function calls And write unit tests on them. --- Include/object.h | 20 ++++++++++++++++++- Objects/object.c | 22 +++++++++++++++++++++ capi_tests/test_object.c | 42 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/Include/object.h b/Include/object.h index 3fa4229ad37213..d259d24a4fa896 100644 --- a/Include/object.h +++ b/Include/object.h @@ -114,9 +114,18 @@ typedef struct { Py_ssize_t ob_size; /* Number of items in variable part */ } PyVarObject; + +#ifdef Py_NEWCAPI_NO_STRUCT +PyAPI_FUNC(Py_ssize_t) _Py_REFCNT_impl(PyObject *op); +/* Py_REFCNT(op) = 1 is illegal */ +#define Py_REFCNT(ob) _Py_REFCNT_impl((PyObject*)(ob)) +PyAPI_FUNC(Py_ssize_t) _Py_SIZE_impl(PyObject *op); +#define Py_SIZE(ob) _Py_SIZE_impl(ob) +#else #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt) -#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) #define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size) +#endif + #ifndef Py_LIMITED_API /********************* String Literals ****************************************/ @@ -435,6 +444,15 @@ typedef struct _typeobject { } PyTypeObject; #endif + +#ifdef Py_NEWCAPI_NO_STRUCT +PyAPI_FUNC(PyTypeObject*) _Py_TYPE_impl(PyObject *op); +#define Py_TYPE(ob) _Py_TYPE_impl(ob) +#else +#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) +#endif + + typedef struct{ int slot; /* slot id, see below */ void *pfunc; /* function pointer */ diff --git a/Objects/object.c b/Objects/object.c index ccdb355e8baca2..f58c99d46e0362 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -40,6 +40,28 @@ _PyDebug_PrintTotalRefs(void) { #endif /* Py_REF_DEBUG */ +Py_ssize_t +_Py_REFCNT_impl(PyObject *op) +{ + return Py_REFCNT(op); +} + + +PyTypeObject* +_Py_TYPE_impl(PyObject *op) +{ + return Py_TYPE(op); +} + + +Py_ssize_t +_Py_SIZE_impl(PyObject *op) +{ + return Py_SIZE(op); +} + + + void _Py_INCREF_impl(PyObject *op) { diff --git a/capi_tests/test_object.c b/capi_tests/test_object.c index 63724ea47c5c81..f07ffb339a4758 100644 --- a/capi_tests/test_object.c +++ b/capi_tests/test_object.c @@ -30,10 +30,52 @@ START_TEST(test_Py_DECREF) END_TEST +START_TEST(test_Py_REFCNT) +{ + PyObject *obj = Py_None; + Py_ssize_t refcnt = Py_REFCNT(obj); + + Py_INCREF(obj); + ck_assert_int_eq(Py_REFCNT(obj), refcnt + 1); + Py_DECREF(obj); +} +END_TEST + + +START_TEST(test_Py_TYPE) +{ + PyObject *obj = PyLong_FromLong(5); + PyTypeObject *expected = &PyLong_Type; + Py_ssize_t refcnt = Py_REFCNT(expected); + + PyTypeObject *type = Py_TYPE(obj); + ck_assert_ptr_eq(type, expected); + ck_assert_int_eq(Py_REFCNT(expected), refcnt); /* borrowed ref */ + + Py_DECREF(obj); +} +END_TEST + + +START_TEST(test_Py_SIZE) +{ + PyObject *obj = Py_BuildValue("(ii)", 3, 4); + + Py_ssize_t size = Py_SIZE(obj); + ck_assert_int_eq(size, 2); + + Py_DECREF(obj); +} +END_TEST + + void register_PyObject(Suite *s) { TCase *testcase = tcase_create("PyObject"); tcase_add_test(testcase, test_Py_INCREF); tcase_add_test(testcase, test_Py_DECREF); + tcase_add_test(testcase, test_Py_REFCNT); + tcase_add_test(testcase, test_Py_TYPE); + tcase_add_test(testcase, test_Py_SIZE); suite_add_tcase(s, testcase); } From 159f85efabd019993ab05e43ab66400abf1f795a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Sep 2018 12:28:33 +0200 Subject: [PATCH 29/50] Py_XINCREF/Py_XDECREF as func calls Add unit tests: * Py_XINCREF() * Py_IncRef() * Py_XDECREF() * Py_DecRef() * Py_CLEAR() * Py_SETREF() * Py_XSETREF() * Py_RETURN_NONE() * Py_RETURN_TRUE() * Py_RETURN_FALSE() * Py_RETURN_NOTIMPLEMENTED() * Py_RETURN_RICHCOMPARE() --- Include/object.h | 5 + Include/pyport.h | 6 + capi_tests/Makefile | 1 + capi_tests/test_object.c | 239 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 243 insertions(+), 8 deletions(-) diff --git a/Include/object.h b/Include/object.h index d259d24a4fa896..af4ba79a4372b3 100644 --- a/Include/object.h +++ b/Include/object.h @@ -872,6 +872,10 @@ PyAPI_FUNC(void) _Py_DECREF_impl(PyObject *op); } \ } while (0) +#ifdef Py_NEWCAPI_NO_STRUCT +# define Py_XINCREF(op) Py_IncRef(op) +# define Py_XDECREF(op) Py_DecRef(op) +#else /* Macros to use in case the object pointer may be NULL: */ #define Py_XINCREF(op) \ do { \ @@ -886,6 +890,7 @@ PyAPI_FUNC(void) _Py_DECREF_impl(PyObject *op); if (_py_xdecref_tmp != NULL) \ Py_DECREF(_py_xdecref_tmp); \ } while (0) +#endif #ifndef Py_LIMITED_API /* Safely decref `op` and set `op` to `op2`. diff --git a/Include/pyport.h b/Include/pyport.h index 51d0cb7a2ae9ec..615023706cfe59 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -804,8 +804,14 @@ extern _invalid_parameter_handler _Py_silent_invalid_parameter_handler; #ifdef Py_NEWCAPI_BORROWED_REF # define Py_NEWCAPI #endif +#if defined(Py_NEWCAPI_NO_STRUCT) && !defined(Py_NEWCAPI_NO_MACRO) + /* Py_NEWCAPI_NO_STRUCT implies Py_NEWCAPI_NO_MACRO */ +# define Py_NEWCAPI_NO_MACRO +#endif #if defined(Py_NEWCAPI) + /* Py_NEWCAPI implies Py_NEWCAPI_NO_STRUCT, Py_NEWCAPI_NO_MACRO + and Py_NO_BORROWED_REF (if Py_NEWCAPI_BORROWED_REF is not defined). */ # define Py_NEWCAPI_NO_STRUCT # define Py_NEWCAPI_NO_MACRO # ifndef Py_NEWCAPI_BORROWED_REF diff --git a/capi_tests/Makefile b/capi_tests/Makefile index 2bb625e4dc6e2d..3c1d536d8e0788 100644 --- a/capi_tests/Makefile +++ b/capi_tests/Makefile @@ -5,6 +5,7 @@ PYTHON_LDFLAGS=-l $(LIBPYTHON) -L $(CPYTHON_SRC) CFLAGS=$(shell pkg-config check --cflags) $(PYTHON_CFLAGS) LDFLAGS=$(shell pkg-config check --libs) $(PYTHON_LDFLAGS) SOURCES=runtests.c test_object.c test_tuple.c +ENV_RUNTEST=LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib # CK_FORK=no to detect reference leaks ENV_RUNTEST=CK_FORK=no LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib diff --git a/capi_tests/test_object.c b/capi_tests/test_object.c index f07ffb339a4758..6d819d45473c64 100644 --- a/capi_tests/test_object.c +++ b/capi_tests/test_object.c @@ -5,27 +5,132 @@ #include +#define TEST_INCREF(INCREF_FUNC) \ + do { \ + PyObject *obj = Py_None; \ + Py_ssize_t refcnt = Py_REFCNT(obj); \ + \ + INCREF_FUNC(obj); \ + ck_assert_int_eq(Py_REFCNT(obj), refcnt + 1); \ + \ + Py_DECREF(obj); \ + } while (0) + START_TEST(test_Py_INCREF) { - PyObject *obj = Py_None; - Py_ssize_t refcnt = Py_REFCNT(obj); + TEST_INCREF(Py_INCREF); +} +END_TEST - Py_INCREF(obj); - ck_assert_int_eq(Py_REFCNT(obj), refcnt + 1); - Py_DECREF(obj); +START_TEST(test_Py_XINCREF) +{ + TEST_INCREF(Py_XINCREF); + + /* Py_XINCREF(NULL) does nothing: it must not crash */ + Py_XINCREF(NULL); } END_TEST +START_TEST(test_Py_IncRef) +{ + TEST_INCREF(Py_IncRef); + + /* Py_IncRef(NULL) does nothing: it must not crash */ + Py_IncRef(NULL); +} + + +#define TEST_DECREF(DECREF_FUNC) \ + do { \ + PyObject *obj = Py_None; \ + Py_INCREF(obj); \ + Py_ssize_t refcnt = Py_REFCNT(obj); \ + \ + DECREF_FUNC(obj); \ + ck_assert_int_eq(Py_REFCNT(obj), refcnt - 1); \ + } while (0) + +END_TEST START_TEST(test_Py_DECREF) +{ + TEST_DECREF(Py_DECREF); +} +END_TEST + + +START_TEST(test_Py_XDECREF) +{ + TEST_DECREF(Py_XDECREF); + + /* Py_XDECREF(NULL) does nothing: it must not crash */ + Py_XDECREF(NULL); +} +END_TEST + + +START_TEST(test_Py_DecRef) +{ + TEST_DECREF(Py_DecRef); + + /* Py_DecRef(NULL) does nothing: it must not crash */ + Py_DecRef(NULL); +} +END_TEST + + +START_TEST(test_Py_CLEAR) { PyObject *obj = Py_None; Py_INCREF(obj); - Py_ssize_t refcnt = Py_REFCNT(obj); + Py_ssize_t refcnt = Py_REFCNT(Py_None); - Py_DECREF(obj); - ck_assert_int_eq(Py_REFCNT(obj), refcnt - 1); + Py_CLEAR(obj); + ck_assert_int_eq(Py_REFCNT(Py_None), refcnt - 1); + ck_assert_ptr_null(obj); + + obj = NULL; + /* Py_CLEAR(NULL) does nothing: it must not crash */ + Py_CLEAR(obj); +} +END_TEST + + +#define TEST_SETSET(SETREF_FUNC) \ + do { \ + PyObject *value1 = Py_True; \ + PyObject *value2 = Py_False; \ + \ + Py_INCREF(value1); \ + PyObject *obj = value1; \ + Py_ssize_t refcnt1 = Py_REFCNT(value1); \ + Py_ssize_t refcnt2 = Py_REFCNT(value2); \ + \ + SETREF_FUNC(obj, value2); \ + ck_assert_ptr_eq(obj, value2); \ + ck_assert_int_eq(Py_REFCNT(value1), refcnt1 - 1); \ + ck_assert_int_eq(Py_REFCNT(value2), refcnt2); \ + } while (0) + +START_TEST(test_Py_SETREF) +{ + TEST_SETSET(Py_SETREF); +} +END_TEST + + +START_TEST(test_Py_XSETREF) +{ + TEST_SETSET(Py_XSETREF); + + /* Py_XSETREF(NULL, value) must not crash */ + PyObject *value3 = Py_None; + Py_ssize_t refcnt3 = Py_REFCNT(value3); + PyObject *obj = NULL; + Py_XSETREF(obj, value3); + ck_assert_ptr_eq(obj, value3); + ck_assert_int_eq(Py_REFCNT(value3), refcnt3); } END_TEST @@ -69,13 +174,131 @@ START_TEST(test_Py_SIZE) END_TEST +static PyObject* +return_none(void) +{ + Py_RETURN_NONE; +} + +#define TEST_RETURN_FUNC(VALUE, RETURN_FUNC) \ + do { \ + PyObject *value = (VALUE); \ + Py_ssize_t refcnt = Py_REFCNT(value); \ + PyObject *obj = RETURN_FUNC(); \ + \ + ck_assert_ptr_eq(obj, value); \ + ck_assert_int_eq(Py_REFCNT(value), refcnt + 1); \ + \ + Py_DECREF(obj); \ + } while (0) + +START_TEST(test_Py_RETURN_NONE) +{ + TEST_RETURN_FUNC(Py_None, return_none); +} +END_TEST + + +static PyObject* +return_true(void) +{ + Py_RETURN_TRUE; +} + +START_TEST(test_Py_RETURN_TRUE) +{ + TEST_RETURN_FUNC(Py_True, return_true); +} +END_TEST + + +static PyObject* +return_false(void) +{ + Py_RETURN_FALSE; +} + +START_TEST(test_Py_RETURN_FALSE) +{ + TEST_RETURN_FUNC(Py_False, return_false); +} +END_TEST + + +static PyObject* +return_not_implemented(void) +{ + Py_RETURN_NOTIMPLEMENTED; +} + +START_TEST(test_Py_RETURN_NOTIMPLEMENTED) +{ + TEST_RETURN_FUNC(Py_NotImplemented, return_not_implemented); +} +END_TEST + + +static PyObject* +return_rich_compare(int a, int b, int op) +{ + Py_RETURN_RICHCOMPARE(a, b, op); +} + + +START_TEST(test_Py_RETURN_RICHCOMPARE) +{ +#define TEST_CMP(A, OP, B, VALUE) \ + do { \ + PyObject *value = (VALUE); \ + Py_ssize_t refcnt = Py_REFCNT(value); \ + PyObject *obj = return_rich_compare((A), (B), (OP)); \ + ck_assert_ptr_eq(obj, value); \ + ck_assert_int_eq(Py_REFCNT(value), refcnt + 1); \ + Py_DECREF(obj); \ + } while (0) + + /* 1 == 1 */ + TEST_CMP(1, Py_EQ, 1, Py_True); + TEST_CMP(1, Py_NE, 1, Py_False); + TEST_CMP(1, Py_LT, 1, Py_False); + TEST_CMP(1, Py_GT, 1, Py_False); + TEST_CMP(1, Py_LE, 1, Py_True); + TEST_CMP(1, Py_GE, 1, Py_True); + + /* 1 == 2 */ + TEST_CMP(1, Py_EQ, 2, Py_False); + TEST_CMP(1, Py_NE, 2, Py_True); + TEST_CMP(1, Py_LT, 2, Py_True); + TEST_CMP(1, Py_GT, 2, Py_False); + TEST_CMP(1, Py_LE, 2, Py_True); + TEST_CMP(1, Py_GE, 2, Py_False); +} +END_TEST + + void register_PyObject(Suite *s) { TCase *testcase = tcase_create("PyObject"); tcase_add_test(testcase, test_Py_INCREF); + tcase_add_test(testcase, test_Py_XINCREF); + tcase_add_test(testcase, test_Py_IncRef); + tcase_add_test(testcase, test_Py_DECREF); + tcase_add_test(testcase, test_Py_XDECREF); + tcase_add_test(testcase, test_Py_DecRef); + + tcase_add_test(testcase, test_Py_CLEAR); + tcase_add_test(testcase, test_Py_SETREF); + tcase_add_test(testcase, test_Py_XSETREF); tcase_add_test(testcase, test_Py_REFCNT); + tcase_add_test(testcase, test_Py_TYPE); tcase_add_test(testcase, test_Py_SIZE); + + tcase_add_test(testcase, test_Py_RETURN_NONE); + tcase_add_test(testcase, test_Py_RETURN_TRUE); + tcase_add_test(testcase, test_Py_RETURN_FALSE); + tcase_add_test(testcase, test_Py_RETURN_NOTIMPLEMENTED); + tcase_add_test(testcase, test_Py_RETURN_RICHCOMPARE); suite_add_tcase(s, testcase); } From d87dcac9ac9de1dca33ab7e55a2f7575e4d8b038 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Sep 2018 12:44:58 +0200 Subject: [PATCH 30/50] Refine defines --- Include/pyport.h | 37 ++++++++++++++++++++++++------------- Include/tupleobject.h | 4 ++-- capi_tests/.gitignore | 1 + capi_tests/Makefile | 17 ++++++++++++----- capi_tests/test_tuple.c | 20 ++++++++------------ 5 files changed, 47 insertions(+), 32 deletions(-) diff --git a/Include/pyport.h b/Include/pyport.h index 615023706cfe59..881c80db692fa7 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -792,31 +792,42 @@ extern _invalid_parameter_handler _Py_silent_invalid_parameter_handler; #define WITH_THREAD #endif -/* New C API: - * Py_NEWCAPI_BORROWED_REF: new C API with borrowed references - * Py_NEWCAPI: new C API without borrowed references +/* New C API defines: + * * Py_NEWCAPI_NO_MACRO: replace macros with function calls * PyTuple_GET_SIZE() becomes PyTuple_Size() * Py_NEWCAPI_NO_STRUCT: must not use PyObject.ob_refcnt or any other field * of Python object structures; structures should hide their fields: * compilation error. + * Py_NEWCAPI: new C API without borrowed references, without macro, + * without struct + * + * Related defines: + * + * Py_NEWCAPI_BORROWED_REF: declare functions/macros using + * borrowed references -- enabled by Py_NEWCAPI_NO_MACRO + * and Py_NEWCAPI_NO_STRUCT. */ -#ifdef Py_NEWCAPI_BORROWED_REF -# define Py_NEWCAPI + +#if defined(Py_NEWCAPI) +# ifdef Py_NEWCAPI_BORROWED_REF +# error "Py_NEWCAPI and Py_NEWCAPI_BORROWED_REF are exclusive" +# endif + + /* Py_NEWCAPI implies Py_NEWCAPI_NO_STRUCT and Py_NEWCAPI_NO_MACRO */ +# define Py_NEWCAPI_NO_STRUCT +# define Py_NEWCAPI_NO_MACRO #endif + #if defined(Py_NEWCAPI_NO_STRUCT) && !defined(Py_NEWCAPI_NO_MACRO) /* Py_NEWCAPI_NO_STRUCT implies Py_NEWCAPI_NO_MACRO */ # define Py_NEWCAPI_NO_MACRO #endif -#if defined(Py_NEWCAPI) - /* Py_NEWCAPI implies Py_NEWCAPI_NO_STRUCT, Py_NEWCAPI_NO_MACRO - and Py_NO_BORROWED_REF (if Py_NEWCAPI_BORROWED_REF is not defined). */ -# define Py_NEWCAPI_NO_STRUCT -# define Py_NEWCAPI_NO_MACRO -# ifndef Py_NEWCAPI_BORROWED_REF -# define Py_NO_BORROWED_REF -# endif +#if ((defined(Py_NEWCAPI_NO_STRUCT) || defined(Py_NEWCAPI_NO_MACRO)) \ + && !defined(Py_NEWCAPI) \ + && !defined(Py_NEWCAPI_BORROWED_REF)) +# define Py_NEWCAPI_BORROWED_REF #endif #endif /* Py_PYPORT_H */ diff --git a/Include/tupleobject.h b/Include/tupleobject.h index a381579ff0efb0..83a10e322dd756 100644 --- a/Include/tupleobject.h +++ b/Include/tupleobject.h @@ -42,11 +42,11 @@ PyAPI_DATA(PyTypeObject) PyTupleIter_Type; PyAPI_FUNC(PyObject *) PyTuple_New(Py_ssize_t size); PyAPI_FUNC(Py_ssize_t) PyTuple_Size(PyObject *); -#ifndef Py_NO_BORROWED_REF +#ifndef Py_NEWCAPI PyAPI_FUNC(PyObject *) PyTuple_GetItem(PyObject *, Py_ssize_t); #endif PyAPI_FUNC(PyObject *) PyTuple_GetItemRef(PyObject *, Py_ssize_t); -#ifndef Py_NO_BORROWED_REF +#ifndef Py_NEWCAPI PyAPI_FUNC(int) PyTuple_SetItem(PyObject *, Py_ssize_t, PyObject *); #endif PyAPI_FUNC(int) PyTuple_SetItemRef(PyObject *, Py_ssize_t, PyObject *); diff --git a/capi_tests/.gitignore b/capi_tests/.gitignore index ba505e5a11e698..8472fbe863ca19 100644 --- a/capi_tests/.gitignore +++ b/capi_tests/.gitignore @@ -1,3 +1,4 @@ runtests_fullapi runtests_newcapi runtests_no_borrow +runtests_no_struct diff --git a/capi_tests/Makefile b/capi_tests/Makefile index 3c1d536d8e0788..f92377fcddbe26 100644 --- a/capi_tests/Makefile +++ b/capi_tests/Makefile @@ -9,25 +9,29 @@ ENV_RUNTEST=LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib # CK_FORK=no to detect reference leaks ENV_RUNTEST=CK_FORK=no LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib -.PHONY: test_fullapi test_newcapi test_no_borrow -.NOTPARALLEL: test_fullapi test_newcapi test_no_borrow +.PHONY: test_fullapi test_newcapi test_no_borrow test_no_struct +.NOTPARALLEL: test_fullapi test_newcapi test_no_borrow test_no_struct all: test_newcapi -testmatrix: test_fullapi test_newcapi test_no_borrow +testmatrix: test_fullapi test_newcapi test_no_borrow test_no_struct test_fullapi: runtests_fullapi @echo "=== Full API tests ===" $(ENV_RUNTEST) ./runtests_fullapi test_newcapi: runtests_newcapi - @echo "=== New C API tests ===" + @echo "=== New C API tests (Py_NEWCAPI) ===" $(ENV_RUNTEST) ./runtests_newcapi test_no_borrow: runtests_no_borrow - @echo "=== No borrowed reference tests ===" + @echo "=== No borrowed reference tests (Py_NEWCAPI_BORROWED_REF) ===" $(ENV_RUNTEST) ./runtests_no_borrow +test_no_struct: runtests_no_struct + @echo "=== No struct tests (Py_NEWCAPI_NO_STRUCT) ===" + $(ENV_RUNTEST) ./runtests_no_struct + runtests_fullapi: $(SOURCES) $(CC) -g -o $@ $^ $(CFLAGS) $(LDFLAGS) @@ -37,5 +41,8 @@ runtests_newcapi: $(SOURCES) runtests_no_borrow: $(SOURCES) $(CC) -g -o $@ $^ -D Py_NEWCAPI_BORROWED_REF $(CFLAGS) $(LDFLAGS) +runtests_no_struct: $(SOURCES) + $(CC) -g -o $@ $^ -D Py_NEWCAPI_NO_STRUCT $(CFLAGS) $(LDFLAGS) + clean: rm -f runtests_fullapi runtests_newcapi runtests_no_borrow diff --git a/capi_tests/test_tuple.c b/capi_tests/test_tuple.c index b4a0122793c755..1e3039305934a5 100644 --- a/capi_tests/test_tuple.c +++ b/capi_tests/test_tuple.c @@ -21,13 +21,9 @@ #define SMALL_SIZE 5 -#ifndef Py_NO_BORROWED_REF -# define BORROW_REF -#endif - typedef enum { STRONG, -#ifdef BORROW_REF +#ifndef Py_NEWCAPI MACRO, BORROW #endif @@ -165,7 +161,7 @@ check_PyTuple_GetItem(func_type ftype) obj = PyTuple_GetItemRef(tuple, i); ck_assert_int_eq(Py_REFCNT(obj), refcnt + 1); break; -#ifdef BORROW_REF +#ifndef Py_NEWCAPI case MACRO: obj = PyTuple_GET_ITEM(tuple, i); ck_assert_int_eq(Py_REFCNT(obj), refcnt); @@ -193,7 +189,7 @@ START_TEST(test_PyTuple_GetItemRef) END_TEST -#ifdef BORROW_REF +#ifndef Py_NEWCAPI START_TEST(test_PyTuple_GetItem) { check_PyTuple_GetItem(BORROW); @@ -206,7 +202,7 @@ START_TEST(test_PyTuple_GET_ITEM) check_PyTuple_GetItem(MACRO); } END_TEST -#endif /* BORROW_REF */ +#endif /* !Py_NEWCAPI */ START_TEST(test_PyTuple_Pack) @@ -255,7 +251,7 @@ check_PyTuple_SetItemRef(func_type ftype) ck_assert_int_eq(Py_REFCNT(obj), refcnt + 1); break; } -#ifdef BORROW_REF +#ifndef Py_NEWCAPI case BORROW: { int res = PyTuple_SetItem(tuple, i, obj); @@ -290,7 +286,7 @@ START_TEST(test_PyTuple_SetItemRef) END_TEST -#ifdef BORROW_REF +#ifndef Py_NEWCAPI START_TEST(test_PyTuple_SetItem) { check_PyTuple_SetItemRef(BORROW); @@ -314,12 +310,12 @@ void register_PyTuple(Suite *s) tcase_add_test(tc_core, test_PyTuple_Size); tcase_add_test(tc_core, test_PyTuple_GET_SIZE); tcase_add_test(tc_core, test_PyTuple_GetItemRef); -#ifdef BORROW_REF +#ifndef Py_NEWCAPI tcase_add_test(tc_core, test_PyTuple_GetItem); tcase_add_test(tc_core, test_PyTuple_GET_ITEM); #endif tcase_add_test(tc_core, test_PyTuple_SetItemRef); -#ifdef BORROW_REF +#ifndef Py_NEWCAPI tcase_add_test(tc_core, test_PyTuple_SetItem); tcase_add_test(tc_core, test_PyTuple_SET_ITEM); #endif From 0efc477c84b8876190539f503865fc1e8c8f4f19 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Sep 2018 13:36:30 +0200 Subject: [PATCH 31/50] Remove Py_TYPE() from Py_NEWCAPI --- Include/object.h | 7 ++++++- Include/tupleobject.h | 4 ++-- Objects/object.c | 2 +- capi_tests/Makefile | 4 ++++ capi_tests/test_object.c | 4 ++++ 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/Include/object.h b/Include/object.h index af4ba79a4372b3..419ee444baffd5 100644 --- a/Include/object.h +++ b/Include/object.h @@ -445,11 +445,16 @@ typedef struct _typeobject { #endif + +#define _Py_TYPE(ob) (((PyObject*)(ob))->ob_type) + #ifdef Py_NEWCAPI_NO_STRUCT +#ifdef Py_NEWCAPI_BORROWED_REF PyAPI_FUNC(PyTypeObject*) _Py_TYPE_impl(PyObject *op); #define Py_TYPE(ob) _Py_TYPE_impl(ob) +#endif #else -#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) +#define Py_TYPE(ob) _Py_TYPE(ob) #endif diff --git a/Include/tupleobject.h b/Include/tupleobject.h index 83a10e322dd756..15fca79247a995 100644 --- a/Include/tupleobject.h +++ b/Include/tupleobject.h @@ -37,8 +37,8 @@ PyAPI_DATA(PyTypeObject) PyTuple_Type; PyAPI_DATA(PyTypeObject) PyTupleIter_Type; #define PyTuple_Check(op) \ - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TUPLE_SUBCLASS) -#define PyTuple_CheckExact(op) (Py_TYPE(op) == &PyTuple_Type) + PyType_FastSubclass(_Py_TYPE(op), Py_TPFLAGS_TUPLE_SUBCLASS) +#define PyTuple_CheckExact(op) (_Py_TYPE(op) == &PyTuple_Type) PyAPI_FUNC(PyObject *) PyTuple_New(Py_ssize_t size); PyAPI_FUNC(Py_ssize_t) PyTuple_Size(PyObject *); diff --git a/Objects/object.c b/Objects/object.c index f58c99d46e0362..1923ebea0cb46f 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -50,7 +50,7 @@ _Py_REFCNT_impl(PyObject *op) PyTypeObject* _Py_TYPE_impl(PyObject *op) { - return Py_TYPE(op); + return _Py_TYPE(op); } diff --git a/capi_tests/Makefile b/capi_tests/Makefile index f92377fcddbe26..504eec1e028a6a 100644 --- a/capi_tests/Makefile +++ b/capi_tests/Makefile @@ -19,18 +19,22 @@ testmatrix: test_fullapi test_newcapi test_no_borrow test_no_struct test_fullapi: runtests_fullapi @echo "=== Full API tests ===" $(ENV_RUNTEST) ./runtests_fullapi + @echo test_newcapi: runtests_newcapi @echo "=== New C API tests (Py_NEWCAPI) ===" $(ENV_RUNTEST) ./runtests_newcapi + @echo test_no_borrow: runtests_no_borrow @echo "=== No borrowed reference tests (Py_NEWCAPI_BORROWED_REF) ===" $(ENV_RUNTEST) ./runtests_no_borrow + @echo test_no_struct: runtests_no_struct @echo "=== No struct tests (Py_NEWCAPI_NO_STRUCT) ===" $(ENV_RUNTEST) ./runtests_no_struct + @echo runtests_fullapi: $(SOURCES) $(CC) -g -o $@ $^ $(CFLAGS) $(LDFLAGS) diff --git a/capi_tests/test_object.c b/capi_tests/test_object.c index 6d819d45473c64..f9284e15bef4e2 100644 --- a/capi_tests/test_object.c +++ b/capi_tests/test_object.c @@ -147,6 +147,7 @@ START_TEST(test_Py_REFCNT) END_TEST +#ifndef Py_NEWCAPI START_TEST(test_Py_TYPE) { PyObject *obj = PyLong_FromLong(5); @@ -160,6 +161,7 @@ START_TEST(test_Py_TYPE) Py_DECREF(obj); } END_TEST +#endif START_TEST(test_Py_SIZE) @@ -292,7 +294,9 @@ void register_PyObject(Suite *s) tcase_add_test(testcase, test_Py_XSETREF); tcase_add_test(testcase, test_Py_REFCNT); +#ifndef Py_NEWCAPI tcase_add_test(testcase, test_Py_TYPE); +#endif tcase_add_test(testcase, test_Py_SIZE); tcase_add_test(testcase, test_Py_RETURN_NONE); From b8d81ecef6db136c51894ac33d8687317f69c3df Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Sep 2018 13:51:04 +0200 Subject: [PATCH 32/50] Add _Py_SET_TYPE() and _Py_SET_SIZE() * PyObject_INIT and PyObject_INIT_VAR use do/while (0) * NEWCAPI macros now cases properly to (PyObject*)(op) --- Include/object.h | 22 +++++++----- Include/objimpl.h | 4 +-- Modules/_asynciomodule.c | 2 +- Modules/_blake2/blake2module.c | 4 +-- Modules/_collectionsmodule.c | 4 +-- Modules/_ctypes/_ctypes.c | 12 +++---- Modules/_datetimemodule.c | 4 +-- Modules/_decimal/_decimal.c | 4 +-- Modules/_hashopenssl.c | 2 +- Modules/_pickle.c | 22 ++++++------ Modules/_sha3/sha3module.c | 2 +- Modules/_sqlite/prepare_protocol.c | 2 +- Modules/_struct.c | 2 +- Modules/_testbuffer.c | 4 +-- Modules/_testcapimodule.c | 8 +++-- Modules/arraymodule.c | 14 ++++---- Modules/gcmodule.c | 6 ++-- Modules/itertoolsmodule.c | 2 +- Modules/md5module.c | 2 +- Modules/selectmodule.c | 6 ++-- Modules/sha1module.c | 2 +- Modules/sha256module.c | 4 +-- Modules/sha512module.c | 4 +-- Modules/socketmodule.c | 4 +-- Modules/unicodedata.c | 2 +- Objects/bytearrayobject.c | 6 ++-- Objects/bytesobject.c | 8 ++--- Objects/classobject.c | 2 +- Objects/complexobject.c | 2 +- Objects/floatobject.c | 4 +-- Objects/listobject.c | 22 ++++++------ Objects/longobject.c | 55 +++++++++++++++--------------- Objects/methodobject.c | 2 +- Objects/moduleobject.c | 2 +- Objects/object.c | 12 ++++--- Objects/odictobject.c | 2 +- Objects/structseq.c | 2 +- Objects/tupleobject.c | 4 +-- Objects/typeobject.c | 8 ++--- Objects/unicodeobject.c | 4 +-- Objects/weakrefobject.c | 4 +-- Python/ceval.c | 2 +- Python/hamt.c | 4 +-- Python/marshal.c | 2 +- TODO.rst | 7 ++++ 45 files changed, 158 insertions(+), 140 deletions(-) diff --git a/Include/object.h b/Include/object.h index 419ee444baffd5..c69d5d24bd1663 100644 --- a/Include/object.h +++ b/Include/object.h @@ -114,16 +114,20 @@ typedef struct { Py_ssize_t ob_size; /* Number of items in variable part */ } PyVarObject; +#define _Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size) + +#define _Py_SET_SIZE(ob, size) \ + do { _Py_SIZE(ob) = (size); } while (0) #ifdef Py_NEWCAPI_NO_STRUCT PyAPI_FUNC(Py_ssize_t) _Py_REFCNT_impl(PyObject *op); /* Py_REFCNT(op) = 1 is illegal */ #define Py_REFCNT(ob) _Py_REFCNT_impl((PyObject*)(ob)) PyAPI_FUNC(Py_ssize_t) _Py_SIZE_impl(PyObject *op); -#define Py_SIZE(ob) _Py_SIZE_impl(ob) +#define Py_SIZE(ob) _Py_SIZE_impl((PyObject *)(ob)) #else #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt) -#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size) +#define Py_SIZE(ob) _Py_SIZE(ob) #endif @@ -446,12 +450,14 @@ typedef struct _typeobject { -#define _Py_TYPE(ob) (((PyObject*)(ob))->ob_type) +#define _Py_TYPE(ob) (((PyObject*)(ob))->ob_type) +#define _Py_SET_TYPE(ob, type) \ + do { _Py_TYPE(ob) = (type); } while (0) #ifdef Py_NEWCAPI_NO_STRUCT #ifdef Py_NEWCAPI_BORROWED_REF PyAPI_FUNC(PyTypeObject*) _Py_TYPE_impl(PyObject *op); -#define Py_TYPE(ob) _Py_TYPE_impl(ob) +#define Py_TYPE(ob) _Py_TYPE_impl((PyObject *)(ob)) #endif #else #define Py_TYPE(ob) _Py_TYPE(ob) @@ -815,9 +821,9 @@ PyAPI_FUNC(void) _Py_Dealloc(PyObject *); #ifdef Py_NEWCAPI_NO_STRUCT PyAPI_FUNC(void) _Py_INCREF_impl(PyObject *op); -# define Py_INCREF(op) _Py_INCREF_impl(op) +# define Py_INCREF(op) _Py_INCREF_impl((PyObject *)(op)) PyAPI_FUNC(void) _Py_DECREF_impl(PyObject *op); -# define Py_DECREF(op) _Py_DECREF_impl(op) +# define Py_DECREF(op) _Py_DECREF_impl((PyObject *)(op)) #else #define Py_INCREF(op) ( \ _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \ @@ -878,8 +884,8 @@ PyAPI_FUNC(void) _Py_DECREF_impl(PyObject *op); } while (0) #ifdef Py_NEWCAPI_NO_STRUCT -# define Py_XINCREF(op) Py_IncRef(op) -# define Py_XDECREF(op) Py_DecRef(op) +# define Py_XINCREF(op) Py_IncRef((PyObject *)(op)) +# define Py_XDECREF(op) Py_DecRef((PyObject *)(op)) #else /* Macros to use in case the object pointer may be NULL: */ #define Py_XINCREF(op) \ diff --git a/Include/objimpl.h b/Include/objimpl.h index 4eeb8dfe50cd5b..e39036c385c3b4 100644 --- a/Include/objimpl.h +++ b/Include/objimpl.h @@ -141,9 +141,9 @@ PyAPI_FUNC(PyVarObject *) _PyObject_NewVar(PyTypeObject *, Py_ssize_t); /* Macros trading binary compatibility for speed. See also pymem.h. Note that these macros expect non-NULL object pointers.*/ #define PyObject_INIT(op, typeobj) \ - ( Py_TYPE(op) = (typeobj), _Py_NewReference((PyObject *)(op)), (op) ) + do { _Py_SET_TYPE(op, typeobj); _Py_NewReference((PyObject *)(op)); } while (0) #define PyObject_INIT_VAR(op, typeobj, size) \ - ( Py_SIZE(op) = (size), PyObject_INIT((op), (typeobj)) ) + do { _Py_SET_SIZE(op, size); PyObject_INIT((op), (typeobj)); } while (0) #define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize ) diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 3d7ce01a680c3d..4cf9ede86df53f 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -1009,7 +1009,7 @@ _asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn) } if (j < len) { - Py_SIZE(newlist) = j; + _Py_SET_SIZE(newlist, j); } j = PyList_GET_SIZE(newlist); len = PyList_GET_SIZE(self->fut_callbacks); diff --git a/Modules/_blake2/blake2module.c b/Modules/_blake2/blake2module.c index e2a3d420d4eb8e..a4af74531084c3 100644 --- a/Modules/_blake2/blake2module.c +++ b/Modules/_blake2/blake2module.c @@ -62,7 +62,7 @@ PyInit__blake2(void) return NULL; /* BLAKE2b */ - Py_TYPE(&PyBlake2_BLAKE2bType) = &PyType_Type; + _Py_SET_TYPE(&PyBlake2_BLAKE2bType, &PyType_Type); if (PyType_Ready(&PyBlake2_BLAKE2bType) < 0) { return NULL; } @@ -82,7 +82,7 @@ PyInit__blake2(void) PyModule_AddIntConstant(m, "BLAKE2B_MAX_DIGEST_SIZE", BLAKE2B_OUTBYTES); /* BLAKE2s */ - Py_TYPE(&PyBlake2_BLAKE2sType) = &PyType_Type; + _Py_SET_TYPE(&PyBlake2_BLAKE2sType, &PyType_Type); if (PyType_Ready(&PyBlake2_BLAKE2sType) < 0) { return NULL; } diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index c0448577140220..0fba77e9d7d39f 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -163,7 +163,7 @@ deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds) MARK_END(b->rightlink); assert(BLOCKLEN >= 2); - Py_SIZE(deque) = 0; + _Py_SET_SIZE(deque, 0); deque->leftblock = b; deque->rightblock = b; deque->leftindex = CENTER + 1; @@ -580,7 +580,7 @@ deque_clear(dequeobject *deque) /* Set the deque to be empty using the newly allocated block */ MARK_END(b->leftlink); MARK_END(b->rightlink); - Py_SIZE(deque) = 0; + _Py_SET_SIZE(deque, 0); deque->leftblock = b; deque->rightblock = b; deque->leftindex = CENTER + 1; diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 3ae6348fef4317..98173328cf9884 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -5486,42 +5486,42 @@ PyInit__ctypes(void) if (PyType_Ready(&PyCData_Type) < 0) return NULL; - Py_TYPE(&Struct_Type) = &PyCStructType_Type; + _Py_SET_TYPE(&Struct_Type, &PyCStructType_Type); Struct_Type.tp_base = &PyCData_Type; if (PyType_Ready(&Struct_Type) < 0) return NULL; Py_INCREF(&Struct_Type); PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type); - Py_TYPE(&Union_Type) = &UnionType_Type; + _Py_SET_TYPE(&Union_Type, &UnionType_Type); Union_Type.tp_base = &PyCData_Type; if (PyType_Ready(&Union_Type) < 0) return NULL; Py_INCREF(&Union_Type); PyModule_AddObject(m, "Union", (PyObject *)&Union_Type); - Py_TYPE(&PyCPointer_Type) = &PyCPointerType_Type; + _Py_SET_TYPE(&PyCPointer_Type, &PyCPointerType_Type); PyCPointer_Type.tp_base = &PyCData_Type; if (PyType_Ready(&PyCPointer_Type) < 0) return NULL; Py_INCREF(&PyCPointer_Type); PyModule_AddObject(m, "_Pointer", (PyObject *)&PyCPointer_Type); - Py_TYPE(&PyCArray_Type) = &PyCArrayType_Type; + _Py_SET_TYPE(&PyCArray_Type, &PyCArrayType_Type); PyCArray_Type.tp_base = &PyCData_Type; if (PyType_Ready(&PyCArray_Type) < 0) return NULL; Py_INCREF(&PyCArray_Type); PyModule_AddObject(m, "Array", (PyObject *)&PyCArray_Type); - Py_TYPE(&Simple_Type) = &PyCSimpleType_Type; + _Py_SET_TYPE(&Simple_Type, &PyCSimpleType_Type); Simple_Type.tp_base = &PyCData_Type; if (PyType_Ready(&Simple_Type) < 0) return NULL; Py_INCREF(&Simple_Type); PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type); - Py_TYPE(&PyCFuncPtr_Type) = &PyCFuncPtrType_Type; + _Py_SET_TYPE(&PyCFuncPtr_Type, &PyCFuncPtrType_Type); PyCFuncPtr_Type.tp_base = &PyCData_Type; if (PyType_Ready(&PyCFuncPtr_Type) < 0) return NULL; diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 3ba700bbf852cf..07679447882cfd 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -629,7 +629,7 @@ time_alloc(PyTypeObject *type, Py_ssize_t aware) sizeof(_PyDateTime_BaseTime)); if (self == NULL) return (PyObject *)PyErr_NoMemory(); - (void)PyObject_INIT(self, type); + PyObject_INIT(self, type); return self; } @@ -644,7 +644,7 @@ datetime_alloc(PyTypeObject *type, Py_ssize_t aware) sizeof(_PyDateTime_BaseDateTime)); if (self == NULL) return (PyObject *)PyErr_NoMemory(); - (void)PyObject_INIT(self, type); + PyObject_INIT(self, type); return self; } diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 5bce780cb7fb48..eaccc26d241cec 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -3253,9 +3253,9 @@ dec_as_long(PyObject *dec, PyObject *context, int round) i--; } - Py_SIZE(pylong) = i; + _Py_SET_SIZE(pylong, i); if (mpd_isnegative(x) && !mpd_iszero(x)) { - Py_SIZE(pylong) = -i; + _Py_SET_SIZE(pylong, -i); } mpd_del(x); diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 40cd6327312d67..7a9a40b360f589 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -1082,7 +1082,7 @@ PyInit__hashlib(void) * but having some be unsupported. Only init appropriate * constants. */ - Py_TYPE(&EVPtype) = &PyType_Type; + _Py_SET_TYPE(&EVPtype, &PyType_Type); if (PyType_Ready(&EVPtype) < 0) return NULL; diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 2de70f5d9405dc..c8f4e86fb1416b 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -457,7 +457,7 @@ Pdata_New(void) if (!(self = PyObject_New(Pdata, &Pdata_Type))) return NULL; - Py_SIZE(self) = 0; + _Py_SET_SIZE(self, 0); self->mark_set = 0; self->fence = 0; self->allocated = 8; @@ -484,7 +484,7 @@ Pdata_clear(Pdata *self, Py_ssize_t clearto) while (--i >= clearto) { Py_CLEAR(self->data[i]); } - Py_SIZE(self) = clearto; + _Py_SET_SIZE(self, clearto); return 0; } @@ -535,7 +535,7 @@ Pdata_pop(Pdata *self) Pdata_stack_underflow(self); return NULL; } - return self->data[--Py_SIZE(self)]; + return self->data[--_Py_SIZE(self)]; } #define PDATA_POP(D, V) do { (V) = Pdata_pop((D)); } while (0) @@ -545,7 +545,7 @@ Pdata_push(Pdata *self, PyObject *obj) if (Py_SIZE(self) == self->allocated && Pdata_grow(self) < 0) { return -1; } - self->data[Py_SIZE(self)++] = obj; + self->data[_Py_SIZE(self)++] = obj; return 0; } @@ -575,7 +575,7 @@ Pdata_poptuple(Pdata *self, Py_ssize_t start) for (i = start, j = 0; j < len; i++, j++) PyTuple_SET_ITEM(tuple, j, self->data[i]); - Py_SIZE(self) = start; + _Py_SET_SIZE(self, start); return tuple; } @@ -592,7 +592,7 @@ Pdata_poplist(Pdata *self, Py_ssize_t start) for (i = start, j = 0; j < len; i++, j++) PyList_SET_ITEM(list, j, self->data[i]); - Py_SIZE(self) = start; + _Py_SET_SIZE(self, start); return list; } @@ -5685,7 +5685,7 @@ load_pop(UnpicklerObject *self) else { len--; Py_DECREF(self->stack->data[len]); - Py_SIZE(self->stack) = len; + _Py_SET_SIZE(self->stack, len); } return 0; } @@ -6029,13 +6029,13 @@ do_append(UnpicklerObject *self, Py_ssize_t x) result = _Pickle_FastCall(append_func, value); if (result == NULL) { Pdata_clear(self->stack, i + 1); - Py_SIZE(self->stack) = x; + _Py_SET_SIZE(self->stack, x); Py_DECREF(append_func); return -1; } Py_DECREF(result); } - Py_SIZE(self->stack) = x; + _Py_SET_SIZE(self->stack, x); Py_DECREF(append_func); } } @@ -6157,12 +6157,12 @@ load_additems(UnpicklerObject *self) result = _Pickle_FastCall(add_func, item); if (result == NULL) { Pdata_clear(self->stack, i + 1); - Py_SIZE(self->stack) = mark; + _Py_SET_SIZE(self->stack, mark); return -1; } Py_DECREF(result); } - Py_SIZE(self->stack) = mark; + _Py_SET_SIZE(self->stack, mark); } return 0; diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c index f5032fcb72ddfb..8bc697d1ec47e5 100644 --- a/Modules/_sha3/sha3module.c +++ b/Modules/_sha3/sha3module.c @@ -706,7 +706,7 @@ PyInit__sha3(void) #define init_sha3type(name, type) \ do { \ - Py_TYPE(type) = &PyType_Type; \ + _Py_SET_TYPE(type, &PyType_Type); \ if (PyType_Ready(type) < 0) { \ goto error; \ } \ diff --git a/Modules/_sqlite/prepare_protocol.c b/Modules/_sqlite/prepare_protocol.c index f2c85f9af6cb68..da812af919f13d 100644 --- a/Modules/_sqlite/prepare_protocol.c +++ b/Modules/_sqlite/prepare_protocol.c @@ -78,6 +78,6 @@ PyTypeObject pysqlite_PrepareProtocolType= { extern int pysqlite_prepare_protocol_setup_types(void) { pysqlite_PrepareProtocolType.tp_new = PyType_GenericNew; - Py_TYPE(&pysqlite_PrepareProtocolType)= &PyType_Type; + _Py_SET_TYPE(&pysqlite_PrepareProtocolType, &PyType_Type); return PyType_Ready(&pysqlite_PrepareProtocolType); } diff --git a/Modules/_struct.c b/Modules/_struct.c index 0be52d9ab94b01..d2dc66536f8616 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -2326,7 +2326,7 @@ PyInit__struct(void) if (m == NULL) return NULL; - Py_TYPE(&PyStructType) = &PyType_Type; + _Py_SET_TYPE(&PyStructType, &PyType_Type); if (PyType_Ready(&PyStructType) < 0) return NULL; diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index b1b8ff37015195..010fba6ef8368c 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -2837,11 +2837,11 @@ PyInit__testbuffer(void) if (m == NULL) return NULL; - Py_TYPE(&NDArray_Type) = &PyType_Type; + _Py_SET_TYPE(&NDArray_Type, &PyType_Type); Py_INCREF(&NDArray_Type); PyModule_AddObject(m, "ndarray", (PyObject *)&NDArray_Type); - Py_TYPE(&StaticArray_Type) = &PyType_Type; + _Py_SET_TYPE(&StaticArray_Type, &PyType_Type); Py_INCREF(&StaticArray_Type); PyModule_AddObject(m, "staticarray", (PyObject *)&StaticArray_Type); diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 7c2c57b98001a0..7b796fd7b28e5c 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -7,6 +7,10 @@ #define PY_SSIZE_T_CLEAN +/* _testcapi.c relies on many low-level functions of the C API */ +#undef Py_NEWCAPI_NO_MACRO +#undef Py_NEWCAPI_NO_STRUCT + #include "Python.h" #include #include "structmember.h" @@ -5359,9 +5363,9 @@ PyInit__testcapi(void) if (m == NULL) return NULL; - Py_TYPE(&_HashInheritanceTester_Type)=&PyType_Type; + _Py_SET_TYPE(&_HashInheritanceTester_Type, &PyType_Type); - Py_TYPE(&test_structmembersType)=&PyType_Type; + _Py_SET_TYPE(&test_structmembersType, &PyType_Type); Py_INCREF(&test_structmembersType); /* don't use a name starting with "test", since we don't want test_capi to automatically call this */ diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 6a9ff3ec6252d9..3dd537f58c07f4 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -128,14 +128,14 @@ array_resize(arrayobject *self, Py_ssize_t newsize) if (self->allocated >= newsize && Py_SIZE(self) < newsize + 16 && self->ob_item != NULL) { - Py_SIZE(self) = newsize; + _Py_SET_SIZE(self, newsize); return 0; } if (newsize == 0) { PyMem_FREE(self->ob_item); self->ob_item = NULL; - Py_SIZE(self) = 0; + _Py_SET_SIZE(self, 0); self->allocated = 0; return 0; } @@ -165,7 +165,7 @@ array_resize(arrayobject *self, Py_ssize_t newsize) return -1; } self->ob_item = items; - Py_SIZE(self) = newsize; + _Py_SET_SIZE(self, newsize); self->allocated = _new_size; return 0; } @@ -595,7 +595,7 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *des op->ob_descr = descr; op->allocated = size; op->weakreflist = NULL; - Py_SIZE(op) = size; + _Py_SET_SIZE(op, size); if (size <= 0) { op->ob_item = NULL; } @@ -2571,7 +2571,7 @@ array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags) view->suboffsets = NULL; view->shape = NULL; if ((flags & PyBUF_ND)==PyBUF_ND) { - view->shape = &((Py_SIZE(self))); + view->shape = &_Py_SIZE(self); } view->strides = NULL; if ((flags & PyBUF_STRIDES)==PyBUF_STRIDES) @@ -2727,7 +2727,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } self->ob_item = item; - Py_SIZE(self) = n / sizeof(Py_UNICODE); + _Py_SET_SIZE(self, n / sizeof(Py_UNICODE)); memcpy(item, ustr, n); self->allocated = Py_SIZE(self); } @@ -3026,7 +3026,7 @@ array_modexec(PyObject *m) if (PyType_Ready(&Arraytype) < 0) return -1; - Py_TYPE(&PyArrayIter_Type) = &PyType_Type; + _Py_SET_TYPE(&PyArrayIter_Type, &PyType_Type); Py_INCREF((PyObject *)&Arraytype); PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype); diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index e3e290cf97a1bd..0bbbb70ff6d37d 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -1906,7 +1906,7 @@ _PyObject_GC_New(PyTypeObject *tp) { PyObject *op = _PyObject_GC_Malloc(_PyObject_SIZE(tp)); if (op != NULL) - op = PyObject_INIT(op, tp); + PyObject_INIT(op, tp); return op; } @@ -1923,7 +1923,7 @@ _PyObject_GC_NewVar(PyTypeObject *tp, Py_ssize_t nitems) size = _PyObject_VAR_SIZE(tp, nitems); op = (PyVarObject *) _PyObject_GC_Malloc(size); if (op != NULL) - op = PyObject_INIT_VAR(op, tp, nitems); + PyObject_INIT_VAR(op, tp, nitems); return op; } @@ -1939,7 +1939,7 @@ _PyObject_GC_Resize(PyVarObject *op, Py_ssize_t nitems) if (g == NULL) return (PyVarObject *)PyErr_NoMemory(); op = (PyVarObject *) FROM_GC(g); - Py_SIZE(op) = nitems; + _Py_SET_SIZE(op, nitems); return op; } diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 8a36755bfa7265..b19e2951138c06 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -4682,7 +4682,7 @@ PyInit_itertools(void) NULL }; - Py_TYPE(&teedataobject_type) = &PyType_Type; + _Py_SET_TYPE(&teedataobject_type, &PyType_Type); m = PyModule_Create(&itertoolsmodule); if (m == NULL) return NULL; diff --git a/Modules/md5module.c b/Modules/md5module.c index b019f82876845b..9f5e341104ea0f 100644 --- a/Modules/md5module.c +++ b/Modules/md5module.c @@ -570,7 +570,7 @@ PyInit__md5(void) { PyObject *m; - Py_TYPE(&MD5type) = &PyType_Type; + _Py_SET_TYPE(&MD5type, &PyType_Type); if (PyType_Ready(&MD5type) < 0) return NULL; diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 836af5429af582..b9439add939d76 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -2546,7 +2546,7 @@ PyInit_select(void) #endif #ifdef HAVE_EPOLL - Py_TYPE(&pyEpoll_Type) = &PyType_Type; + _Py_SET_TYPE(&pyEpoll_Type, &PyType_Type); if (PyType_Ready(&pyEpoll_Type) < 0) return NULL; @@ -2594,14 +2594,14 @@ PyInit_select(void) #ifdef HAVE_KQUEUE kqueue_event_Type.tp_new = PyType_GenericNew; - Py_TYPE(&kqueue_event_Type) = &PyType_Type; + _Py_SET_TYPE(&kqueue_event_Type, &PyType_Type); if(PyType_Ready(&kqueue_event_Type) < 0) return NULL; Py_INCREF(&kqueue_event_Type); PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type); - Py_TYPE(&kqueue_queue_Type) = &PyType_Type; + _Py_SET_TYPE(&kqueue_queue_Type, &PyType_Type); if(PyType_Ready(&kqueue_queue_Type) < 0) return NULL; Py_INCREF(&kqueue_queue_Type); diff --git a/Modules/sha1module.c b/Modules/sha1module.c index d39190b4d5e6b2..4edac3f1edaa32 100644 --- a/Modules/sha1module.c +++ b/Modules/sha1module.c @@ -547,7 +547,7 @@ PyInit__sha1(void) { PyObject *m; - Py_TYPE(&SHA1type) = &PyType_Type; + _Py_SET_TYPE(&SHA1type, &PyType_Type); if (PyType_Ready(&SHA1type) < 0) return NULL; diff --git a/Modules/sha256module.c b/Modules/sha256module.c index e4cb3286ce9502..97be36ea66caf3 100644 --- a/Modules/sha256module.c +++ b/Modules/sha256module.c @@ -709,10 +709,10 @@ PyInit__sha256(void) { PyObject *m; - Py_TYPE(&SHA224type) = &PyType_Type; + _Py_SET_TYPE(&SHA224type, &PyType_Type); if (PyType_Ready(&SHA224type) < 0) return NULL; - Py_TYPE(&SHA256type) = &PyType_Type; + _Py_SET_TYPE(&SHA256type, &PyType_Type); if (PyType_Ready(&SHA256type) < 0) return NULL; diff --git a/Modules/sha512module.c b/Modules/sha512module.c index 5ac2a2a61cf539..0172a6573824dd 100644 --- a/Modules/sha512module.c +++ b/Modules/sha512module.c @@ -774,10 +774,10 @@ PyInit__sha512(void) { PyObject *m; - Py_TYPE(&SHA384type) = &PyType_Type; + _Py_SET_TYPE(&SHA384type, &PyType_Type); if (PyType_Ready(&SHA384type) < 0) return NULL; - Py_TYPE(&SHA512type) = &PyType_Type; + _Py_SET_TYPE(&SHA512type, &PyType_Type); if (PyType_Ready(&SHA512type) < 0) return NULL; diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 3a439c4bfadc30..906416cf9f6c3f 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -349,7 +349,7 @@ remove_unusable_flags(PyObject *m) for (int i=0; iob_bytes, bytes, size); new->ob_bytes[size] = '\0'; /* Trailing null byte */ } - Py_SIZE(new) = size; + _Py_SET_SIZE(new, size); new->ob_alloc = alloc; new->ob_start = new->ob_bytes; new->ob_exports = 0; @@ -218,7 +218,7 @@ PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size) } else { /* Minor downsize; quick exit */ - Py_SIZE(self) = size; + _Py_SET_SIZE(self, size); PyByteArray_AS_STRING(self)[size] = '\0'; /* Trailing null */ return 0; } @@ -258,7 +258,7 @@ PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size) } obj->ob_bytes = obj->ob_start = sval; - Py_SIZE(self) = size; + _Py_SET_SIZE(self, size); obj->ob_alloc = alloc; obj->ob_bytes[size] = '\0'; /* Trailing null byte */ diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index fb344c1896ad29..8521d8007c8aa6 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -85,7 +85,7 @@ _PyBytes_FromSize(Py_ssize_t size, int use_calloc) op = (PyBytesObject *)PyObject_Malloc(PyBytesObject_SIZE + size); if (op == NULL) return PyErr_NoMemory(); - (void)PyObject_INIT_VAR(op, &PyBytes_Type, size); + PyObject_INIT_VAR(op, &PyBytes_Type, size); op->ob_shash = -1; if (!use_calloc) op->ob_sval[size] = '\0'; @@ -163,7 +163,7 @@ PyBytes_FromString(const char *str) op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + size); if (op == NULL) return PyErr_NoMemory(); - (void)PyObject_INIT_VAR(op, &PyBytes_Type, size); + PyObject_INIT_VAR(op, &PyBytes_Type, size); op->ob_shash = -1; memcpy(op->ob_sval, str, size+1); /* share short strings */ @@ -1508,7 +1508,7 @@ bytes_repeat(PyBytesObject *a, Py_ssize_t n) op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + nbytes); if (op == NULL) return PyErr_NoMemory(); - (void)PyObject_INIT_VAR(op, &PyBytes_Type, size); + PyObject_INIT_VAR(op, &PyBytes_Type, size); op->ob_shash = -1; op->ob_sval[size] = '\0'; if (Py_SIZE(a) == 1 && n > 0) { @@ -2967,7 +2967,7 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize) } _Py_NewReference(*pv); sv = (PyBytesObject *) *pv; - Py_SIZE(sv) = newsize; + _Py_SET_SIZE(sv, newsize); sv->ob_sval[newsize] = '\0'; sv->ob_shash = -1; /* invalidate cached hash value */ return 0; diff --git a/Objects/classobject.c b/Objects/classobject.c index a193ada6d44c54..5f9537598c6f11 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -55,7 +55,7 @@ PyMethod_New(PyObject *func, PyObject *self) im = free_list; if (im != NULL) { free_list = (PyMethodObject *)(im->im_self); - (void)PyObject_INIT(im, &PyMethod_Type); + PyObject_INIT(im, &PyMethod_Type); numfree--; } else { diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 6e3d47b62d1937..316697eb946b59 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -228,7 +228,7 @@ PyComplex_FromCComplex(Py_complex cval) op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject)); if (op == NULL) return PyErr_NoMemory(); - (void)PyObject_INIT(op, &PyComplex_Type); + PyObject_INIT(op, &PyComplex_Type); op->cval = cval; return (PyObject *) op; } diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 67f9e5d5b4ef7a..e1b269fde55057 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -124,7 +124,7 @@ PyFloat_FromDouble(double fval) return PyErr_NoMemory(); } /* Inline PyObject_New */ - (void)PyObject_INIT(op, &PyFloat_Type); + PyObject_INIT(op, &PyFloat_Type); op->ob_fval = fval; return (PyObject *) op; } @@ -221,7 +221,7 @@ float_dealloc(PyFloatObject *op) return; } numfree++; - Py_TYPE(op) = (struct _typeobject *)free_list; + _Py_SET_TYPE(op, (struct _typeobject *)free_list); free_list = op; } else diff --git a/Objects/listobject.c b/Objects/listobject.c index 3d4a187f692902..d59b5e45fa1c55 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -43,7 +43,7 @@ list_resize(PyListObject *self, Py_ssize_t newsize) */ if (allocated >= newsize && newsize >= (allocated >> 1)) { assert(self->ob_item != NULL || newsize == 0); - Py_SIZE(self) = newsize; + _Py_SET_SIZE(self, newsize); return 0; } @@ -71,7 +71,7 @@ list_resize(PyListObject *self, Py_ssize_t newsize) return -1; } self->ob_item = items; - Py_SIZE(self) = newsize; + _Py_SET_SIZE(self, newsize); self->allocated = new_allocated; return 0; } @@ -174,7 +174,7 @@ PyList_New(Py_ssize_t size) return PyErr_NoMemory(); } } - Py_SIZE(op) = size; + _Py_SET_SIZE(op, size); op->allocated = size; _PyObject_GC_TRACK(op); return (PyObject *) op; @@ -466,7 +466,7 @@ list_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh) Py_INCREF(v); dest[i] = v; } - Py_SIZE(np) = len; + _Py_SET_SIZE(np, len); return (PyObject *)np; } @@ -515,7 +515,7 @@ list_concat(PyListObject *a, PyObject *bb) Py_INCREF(v); dest[i] = v; } - Py_SIZE(np) = size; + _Py_SET_SIZE(np, size); return (PyObject *)np; #undef b } @@ -558,7 +558,7 @@ list_repeat(PyListObject *a, Py_ssize_t n) } } } - Py_SIZE(np) = size; + _Py_SET_SIZE(np, size); return (PyObject *) np; } @@ -571,7 +571,7 @@ _list_clear(PyListObject *a) /* Because XDECREF can recursively invoke operations on this list, we make it empty first. */ i = Py_SIZE(a); - Py_SIZE(a) = 0; + _Py_SET_SIZE(a, 0); a->ob_item = NULL; a->allocated = 0; while (--i >= 0) { @@ -910,7 +910,7 @@ list_extend(PyListObject *self, PyObject *iterable) if (list_resize(self, mn) < 0) goto error; /* Make the list sane again. */ - Py_SIZE(self) = m; + _Py_SET_SIZE(self, m); } /* Run iterator to exhaustion. */ @@ -2197,7 +2197,7 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) saved_ob_size = Py_SIZE(self); saved_ob_item = self->ob_item; saved_allocated = self->allocated; - Py_SIZE(self) = 0; + _Py_SET_SIZE(self, 0); self->ob_item = NULL; self->allocated = -1; /* any operation will reset it to >= 0 */ @@ -2402,7 +2402,7 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) keyfunc_fail: final_ob_item = self->ob_item; i = Py_SIZE(self); - Py_SIZE(self) = saved_ob_size; + _Py_SET_SIZE(self, saved_ob_size); self->ob_item = saved_ob_item; self->allocated = saved_allocated; if (final_ob_item != NULL) { @@ -2770,7 +2770,7 @@ list_subscript(PyListObject* self, PyObject* item) Py_INCREF(it); dest[i] = it; } - Py_SIZE(result) = slicelength; + _Py_SET_SIZE(result, slicelength); return result; } } diff --git a/Objects/longobject.c b/Objects/longobject.c index 399d3542709901..69f04fac598c4a 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -91,7 +91,7 @@ _PyLong_Negate(PyLongObject **x_p) x = (PyLongObject *)*x_p; if (Py_REFCNT(x) == 1) { - Py_SIZE(x) = -Py_SIZE(x); + _Py_SET_SIZE(x, -Py_SIZE(x)); return; } @@ -131,7 +131,7 @@ long_normalize(PyLongObject *v) while (i > 0 && v->ob_digit[i-1] == 0) --i; if (i != j) - Py_SIZE(v) = (Py_SIZE(v) < 0) ? -(i) : i; + _Py_SET_SIZE(v, (Py_SIZE(v) < 0) ? -(i) : i); return v; } @@ -211,7 +211,8 @@ _PyLong_New(Py_ssize_t size) PyErr_NoMemory(); return NULL; } - return (PyLongObject*)PyObject_INIT_VAR(result, &PyLong_Type, size); + PyObject_INIT_VAR(result, &PyLong_Type, size); + return (PyLongObject*)result; } PyObject * @@ -230,7 +231,7 @@ _PyLong_Copy(PyLongObject *src) } result = _PyLong_New(i); if (result != NULL) { - Py_SIZE(result) = Py_SIZE(src); + _Py_SET_SIZE(result, Py_SIZE(src)); while (--i >= 0) result->ob_digit[i] = src->ob_digit[i]; } @@ -265,7 +266,7 @@ PyLong_FromLong(long ival) if (!(abs_ival >> PyLong_SHIFT)) { v = _PyLong_New(1); if (v) { - Py_SIZE(v) = sign; + _Py_SET_SIZE(v, sign); v->ob_digit[0] = Py_SAFE_DOWNCAST( abs_ival, unsigned long, digit); } @@ -277,7 +278,7 @@ PyLong_FromLong(long ival) if (!(abs_ival >> 2*PyLong_SHIFT)) { v = _PyLong_New(2); if (v) { - Py_SIZE(v) = 2*sign; + _Py_SET_SIZE(v, 2*sign); v->ob_digit[0] = Py_SAFE_DOWNCAST( abs_ival & PyLong_MASK, unsigned long, digit); v->ob_digit[1] = Py_SAFE_DOWNCAST( @@ -296,7 +297,7 @@ PyLong_FromLong(long ival) v = _PyLong_New(ndigits); if (v != NULL) { digit *p = v->ob_digit; - Py_SIZE(v) = ndigits*sign; + _Py_SET_SIZE(v, ndigits*sign); t = abs_ival; while (t) { *p++ = Py_SAFE_DOWNCAST( @@ -373,7 +374,7 @@ PyLong_FromDouble(double dval) frac = ldexp(frac, PyLong_SHIFT); } if (neg) - Py_SIZE(v) = -(Py_SIZE(v)); + _Py_SET_SIZE(v, -(Py_SIZE(v))); return (PyObject *)v; } @@ -877,7 +878,7 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n, } } - Py_SIZE(v) = is_signed ? -idigit : idigit; + _Py_SET_SIZE(v, is_signed ? -idigit : idigit); return (PyObject *)long_normalize(v); } @@ -1102,7 +1103,7 @@ PyLong_FromLongLong(long long ival) v = _PyLong_New(ndigits); if (v != NULL) { digit *p = v->ob_digit; - Py_SIZE(v) = negative ? -ndigits : ndigits; + _Py_SET_SIZE(v, negative ? -ndigits : ndigits); t = abs_ival; while (t) { *p++ = (digit)(t & PyLong_MASK); @@ -1170,7 +1171,7 @@ PyLong_FromSsize_t(Py_ssize_t ival) v = _PyLong_New(ndigits); if (v != NULL) { digit *p = v->ob_digit; - Py_SIZE(v) = negative ? -ndigits : ndigits; + _Py_SET_SIZE(v, negative ? -ndigits : ndigits); t = abs_ival; while (t) { *p++ = (digit)(t & PyLong_MASK); @@ -1200,7 +1201,7 @@ PyLong_FromSize_t(size_t ival) v = _PyLong_New(ndigits); if (v != NULL) { digit *p = v->ob_digit; - Py_SIZE(v) = ndigits; + _Py_SET_SIZE(v, ndigits); while (ival) { *p++ = (digit)(ival & PyLong_MASK); ival >>= PyLong_SHIFT; @@ -2441,7 +2442,7 @@ digit beyond the first. if (z == NULL) { return NULL; } - Py_SIZE(z) = 0; + _Py_SET_SIZE(z, 0); /* `convwidth` consecutive input digits are treated as a single * digit in base `convmultmax`. @@ -2530,7 +2531,7 @@ digit beyond the first. goto onError; } if (sign < 0) { - Py_SIZE(z) = -(Py_SIZE(z)); + _Py_SET_SIZE(z, -(Py_SIZE(z))); } while (*str && Py_ISSPACE(Py_CHARMASK(*str))) { str++; @@ -3170,7 +3171,7 @@ x_sub(PyLongObject *a, PyLongObject *b) } assert(borrow == 0); if (sign < 0) { - Py_SIZE(z) = -Py_SIZE(z); + _Py_SET_SIZE(z, -Py_SIZE(z)); } return long_normalize(z); } @@ -3194,7 +3195,7 @@ long_add(PyLongObject *a, PyLongObject *b) That also means z is not an element of small_ints, so negating it in-place is safe. */ assert(Py_REFCNT(z) == 1); - Py_SIZE(z) = -(Py_SIZE(z)); + _Py_SET_SIZE(z, -(Py_SIZE(z))); } } else @@ -3226,7 +3227,7 @@ long_sub(PyLongObject *a, PyLongObject *b) z = x_add(a, b); if (z != NULL) { assert(Py_SIZE(z) == 0 || Py_REFCNT(z) == 1); - Py_SIZE(z) = -(Py_SIZE(z)); + _Py_SET_SIZE(z, -(Py_SIZE(z))); } } else { @@ -3618,7 +3619,7 @@ k_lopsided_mul(PyLongObject *a, PyLongObject *b) /* Multiply the next slice of b by a. */ memcpy(bslice->ob_digit, b->ob_digit + nbdone, nbtouse * sizeof(digit)); - Py_SIZE(bslice) = nbtouse; + _Py_SET_SIZE(bslice, nbtouse); product = k_mul(a, bslice); if (product == NULL) goto fail; @@ -4328,7 +4329,7 @@ long_neg(PyLongObject *v) return PyLong_FromLong(-MEDIUM_VALUE(v)); z = (PyLongObject *)_PyLong_Copy(v); if (z != NULL) - Py_SIZE(z) = -(Py_SIZE(v)); + _Py_SET_SIZE(z, -(Py_SIZE(v))); return (PyObject *)z; } @@ -4462,7 +4463,7 @@ long_lshift(PyObject *v, PyObject *w) return NULL; if (Py_SIZE(a) < 0) { assert(Py_REFCNT(z) == 1); - Py_SIZE(z) = -Py_SIZE(z); + _Py_SET_SIZE(z, -Py_SIZE(z)); } for (i = 0; i < wordshift; i++) z->ob_digit[i] = 0; @@ -4612,7 +4613,7 @@ long_bitwise(PyLongObject *a, /* Complement result if negative. */ if (negz) { - Py_SIZE(z) = -(Py_SIZE(z)); + _Py_SET_SIZE(z, -(Py_SIZE(z))); z->ob_digit[size_z] = PyLong_MASK; v_complement(z->ob_digit, z->ob_digit, size_z+1); } @@ -4760,7 +4761,7 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) T = -C; C = -D; D = T; } if (c != NULL) - Py_SIZE(c) = size_a; + _Py_SET_SIZE(c, size_a); else if (Py_REFCNT(a) == 1) { Py_INCREF(a); c = a; @@ -4773,11 +4774,11 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) } if (d != NULL) - Py_SIZE(d) = size_a; + _Py_SET_SIZE(d, size_a); else if (Py_REFCNT(b) == 1 && size_a <= alloc_b) { Py_INCREF(b); d = b; - Py_SIZE(d) = size_a; + _Py_SET_SIZE(d, size_a); } else { alloc_b = size_a; @@ -4957,7 +4958,7 @@ long_subtype_new(PyTypeObject *type, PyObject *x, PyObject *obase) return NULL; } assert(PyLong_Check(newobj)); - Py_SIZE(newobj) = Py_SIZE(tmp); + _Py_SET_SIZE(newobj, Py_SIZE(tmp)); for (i = 0; i < n; i++) newobj->ob_digit[i] = tmp->ob_digit[i]; Py_DECREF(tmp); @@ -5589,9 +5590,9 @@ _PyLong_Init(void) assert(v->ob_digit[0] == (digit)abs(ival)); } else { - (void)PyObject_INIT(v, &PyLong_Type); + PyObject_INIT(v, &PyLong_Type); } - Py_SIZE(v) = size; + _Py_SET_SIZE(v, size); v->ob_digit[0] = (digit)abs(ival); } #endif diff --git a/Objects/methodobject.c b/Objects/methodobject.c index a7042ca39e388b..0b6bfb4ecd5b36 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -31,7 +31,7 @@ PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) op = free_list; if (op != NULL) { free_list = (PyCFunctionObject *)(op->m_self); - (void)PyObject_INIT(op, &PyCFunction_Type); + PyObject_INIT(op, &PyCFunction_Type); numfree--; } else { diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 2156ca0765a0b1..eb1ce32913987e 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -48,7 +48,7 @@ PyModuleDef_Init(struct PyModuleDef* def) if (def->m_base.m_index == 0) { max_module_number++; Py_REFCNT(def) = 1; - Py_TYPE(def) = &PyModuleDef_Type; + _Py_SET_TYPE(def, &PyModuleDef_Type); def->m_base.m_index = max_module_number; } return (PyObject*)def; diff --git a/Objects/object.c b/Objects/object.c index 1923ebea0cb46f..8fd075436a2a2b 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -57,7 +57,7 @@ _Py_TYPE_impl(PyObject *op) Py_ssize_t _Py_SIZE_impl(PyObject *op) { - return Py_SIZE(op); + return _Py_SIZE(op); } @@ -268,7 +268,7 @@ PyObject_Init(PyObject *op, PyTypeObject *tp) if (op == NULL) return PyErr_NoMemory(); /* Any changes should be reflected in PyObject_INIT (objimpl.h) */ - Py_TYPE(op) = tp; + _Py_SET_TYPE(op, tp); _Py_NewReference(op); return op; } @@ -280,7 +280,7 @@ PyObject_InitVar(PyVarObject *op, PyTypeObject *tp, Py_ssize_t size) return (PyVarObject *) PyErr_NoMemory(); /* Any changes should be reflected in PyObject_INIT_VAR */ op->ob_size = size; - Py_TYPE(op) = tp; + _Py_SET_TYPE(op, tp); _Py_NewReference((PyObject *)op); return op; } @@ -292,7 +292,8 @@ _PyObject_New(PyTypeObject *tp) op = (PyObject *) PyObject_MALLOC(_PyObject_SIZE(tp)); if (op == NULL) return PyErr_NoMemory(); - return PyObject_INIT(op, tp); + PyObject_INIT(op, tp); + return op; } PyVarObject * @@ -303,7 +304,8 @@ _PyObject_NewVar(PyTypeObject *tp, Py_ssize_t nitems) op = (PyVarObject *) PyObject_MALLOC(size); if (op == NULL) return (PyVarObject *)PyErr_NoMemory(); - return PyObject_INIT_VAR(op, tp, nitems); + PyObject_INIT_VAR(op, tp, nitems); + return op; } void diff --git a/Objects/odictobject.c b/Objects/odictobject.c index 353afd23d6b5e8..da27adb039fcd9 100644 --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -1437,7 +1437,7 @@ odict_repr(PyODictObject *self) count++; } if (count < PyList_GET_SIZE(pieces)) - Py_SIZE(pieces) = count; + _Py_SET_SIZE(pieces, count); } else { PyObject *items = _PyObject_CallMethodIdObjArgs((PyObject *)self, diff --git a/Objects/structseq.c b/Objects/structseq.c index 1705837f71fa57..abc6d13de68354 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -39,7 +39,7 @@ PyStructSequence_New(PyTypeObject *type) return NULL; /* Hack the size of the variable object, so invisible fields don't appear to Python code. */ - Py_SIZE(obj) = VISIBLE_SIZE_TP(type); + _Py_SET_SIZE(obj, VISIBLE_SIZE_TP(type)); for (i = 0; i < size; i++) obj->ob_item[i] = NULL; diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index a0349f44ad27a2..c88958518d2b7c 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -101,8 +101,8 @@ PyTuple_New(Py_ssize_t size) #endif /* Inline PyObject_InitVar */ #ifdef Py_TRACE_REFS - Py_SIZE(op) = size; - Py_TYPE(op) = &PyTuple_Type; + _Py_SET_SIZE(op, size); + _Py_SET_TYPE(op, &PyTuple_Type); #endif _Py_NewReference((PyObject *)op); } diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 52fcfeb2287188..ab2e7e2290440d 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -980,9 +980,9 @@ PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems) Py_INCREF(type); if (type->tp_itemsize == 0) - (void)PyObject_INIT(obj, type); + PyObject_INIT(obj, type); else - (void) PyObject_INIT_VAR((PyVarObject *)obj, type, nitems); + PyObject_INIT_VAR((PyVarObject *)obj, type, nitems); if (PyType_IS_GC(type)) _PyObject_GC_TRACK(obj); @@ -3993,7 +3993,7 @@ object_set_class(PyObject *self, PyObject *value, void *closure) if (compatible_for_assignment(oldto, newto, "__class__")) { if (newto->tp_flags & Py_TPFLAGS_HEAPTYPE) Py_INCREF(newto); - Py_TYPE(self) = newto; + _Py_SET_TYPE(self, newto); if (oldto->tp_flags & Py_TPFLAGS_HEAPTYPE) Py_DECREF(oldto); return 0; @@ -5156,7 +5156,7 @@ PyType_Ready(PyTypeObject *type) not NULL (it's initialized to &PyType_Type). But coverity doesn't know that. */ if (Py_TYPE(type) == NULL && base != NULL) - Py_TYPE(type) = Py_TYPE(base); + _Py_SET_TYPE(type, Py_TYPE(base)); /* Initialize tp_bases */ bases = type->tp_bases; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index a797f838eb4139..8b0fb36f43fd3d 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1281,9 +1281,7 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) obj = (PyObject *) PyObject_MALLOC(struct_size + (size + 1) * char_size); if (obj == NULL) return PyErr_NoMemory(); - obj = PyObject_INIT(obj, &PyUnicode_Type); - if (obj == NULL) - return NULL; + PyObject_INIT(obj, &PyUnicode_Type); unicode = (PyCompactUnicodeObject *)obj; if (is_ascii) diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index 9f492e4b25e49f..a2e01b789fe034 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -822,9 +822,9 @@ PyWeakref_NewProxy(PyObject *ob, PyObject *callback) PyWeakReference *prev; if (PyCallable_Check(ob)) - Py_TYPE(result) = &_PyWeakref_CallableProxyType; + _Py_SET_TYPE(result, &_PyWeakref_CallableProxyType); else - Py_TYPE(result) = &_PyWeakref_ProxyType; + _Py_SET_TYPE(result, &_PyWeakref_ProxyType); get_basic_refs(*list, &ref, &proxy); if (callback == NULL) { if (proxy != NULL) { diff --git a/Python/ceval.c b/Python/ceval.c index f3a74b00a2b64a..1445b4b92821cb 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -4185,7 +4185,7 @@ unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp) *--sp = PyList_GET_ITEM(l, ll - j); } /* Resize the list. */ - Py_SIZE(l) = ll - argcntafter; + _Py_SET_SIZE(l, ll - argcntafter); Py_DECREF(it); return 1; diff --git a/Python/hamt.c b/Python/hamt.c index 562f777ea0bf86..2f546bf9d1877e 100644 --- a/Python/hamt.c +++ b/Python/hamt.c @@ -549,7 +549,7 @@ hamt_node_bitmap_new(Py_ssize_t size) return NULL; } - Py_SIZE(node) = size; + _Py_SET_SIZE(node, size); for (i = 0; i < size; i++) { node->b_array[i] = NULL; @@ -1286,7 +1286,7 @@ hamt_node_collision_new(int32_t hash, Py_ssize_t size) node->c_array[i] = NULL; } - Py_SIZE(node) = size; + _Py_SET_SIZE(node, size); node->c_hash = hash; _PyObject_GC_TRACK(node); diff --git a/Python/marshal.c b/Python/marshal.c index 21cdd60c7e1377..f816349a39a0bb 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -811,7 +811,7 @@ r_PyLong(RFILE *p) if (ob == NULL) return NULL; - Py_SIZE(ob) = n > 0 ? size : -size; + _Py_SET_SIZE(ob, n > 0 ? size : -size); for (i = 0; i < size-1; i++) { d = 0; diff --git a/TODO.rst b/TODO.rst index 70ad545946a7f5..2cc976219bb42a 100644 --- a/TODO.rst +++ b/TODO.rst @@ -2,3 +2,10 @@ TODO list for new Python C API ============================== * capi_tests: check for reference leaks + +Issues +====== + +Following code becomes invalid:: + + (void)PyObject_INIT(im, &PyMethod_Type); From 9f9f263ead684286ba0922512e990fa35a06f5d3 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Sep 2018 13:51:26 +0200 Subject: [PATCH 33/50] setup.py: compile extensions with Py_NEWCAPI_NO_STRUCT --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 37c5dd58a6d2d7..367180f4f98cf7 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ # modules (Issue #21121). cflags = sysconfig.get_config_var('CFLAGS') py_cflags_nodist = sysconfig.get_config_var('PY_CFLAGS_NODIST') -sysconfig.get_config_vars()['CFLAGS'] = cflags + ' ' + py_cflags_nodist +sysconfig.get_config_vars()['CFLAGS'] = cflags + ' ' + py_cflags_nodist + ' -D Py_NEWCAPI_NO_STRUCT' class Dummy: """Hack for parallel build""" From c6a467a24a2d93115fe4325a48e0c28b67bab12c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Sep 2018 14:24:41 +0200 Subject: [PATCH 34/50] update TODO --- TODO.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO.rst b/TODO.rst index 2cc976219bb42a..ccd57da481f89c 100644 --- a/TODO.rst +++ b/TODO.rst @@ -9,3 +9,5 @@ Issues Following code becomes invalid:: (void)PyObject_INIT(im, &PyMethod_Type); + Py_SIZE(obj) = size; /* must use _Py_SET_SIZE(obj, size); */ + Py_TYPE(obj) = type; /* must use _Py_SET_TYPE(obj, type); */ From 868609fe7437db500a4099cd48ed05b0a9e45175 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Sep 2018 14:48:14 +0200 Subject: [PATCH 35/50] TODO --- TODO.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO.rst b/TODO.rst index ccd57da481f89c..85e5ab5d9299cd 100644 --- a/TODO.rst +++ b/TODO.rst @@ -2,6 +2,8 @@ TODO list for new Python C API ============================== * capi_tests: check for reference leaks +* Modify PyObject_INIT(op, type) macro to return op again? use an inlined + function? Issues ====== From f2d11018c2bd3d193a0f42f61fcb4321b72e29fc Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Sep 2018 14:52:50 +0200 Subject: [PATCH 36/50] PyEval_CallFunction() & PyEval_CallMethod() removed from Py_NEWCAPI --- Include/ceval.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Include/ceval.h b/Include/ceval.h index bce8a0beed85e1..4d1f4d479a0912 100644 --- a/Include/ceval.h +++ b/Include/ceval.h @@ -22,11 +22,13 @@ PyAPI_FUNC(PyObject *) PyEval_CallObjectWithKeywords( #define PyEval_CallObject(callable, arg) \ PyEval_CallObjectWithKeywords(callable, arg, (PyObject *)NULL) +#ifndef Py_NEWCAPI PyAPI_FUNC(PyObject *) PyEval_CallFunction(PyObject *callable, const char *format, ...); PyAPI_FUNC(PyObject *) PyEval_CallMethod(PyObject *obj, const char *name, const char *format, ...); +#endif #ifndef Py_LIMITED_API PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); From c74582b942a88319e65287bb9907bd0f2bb2b8ab Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Sep 2018 14:57:59 +0200 Subject: [PATCH 37/50] Use _Py_TYPE() --- Include/abstract.h | 2 +- Include/boolobject.h | 2 +- Include/bytearrayobject.h | 2 +- Include/bytesobject.h | 4 ++-- Include/cellobject.h | 2 +- Include/code.h | 2 +- Include/complexobject.h | 2 +- Include/context.h | 6 +++--- Include/datetime.h | 20 ++++++++++---------- Include/descrobject.h | 2 +- Include/dictobject.h | 4 ++-- Include/floatobject.h | 2 +- Include/frameobject.h | 2 +- Include/funcobject.h | 2 +- Include/genobject.h | 6 +++--- Include/iterobject.h | 4 ++-- Include/listobject.h | 4 ++-- Include/longobject.h | 4 ++-- Include/memoryobject.h | 2 +- Include/methodobject.h | 2 +- Include/moduleobject.h | 2 +- Include/object.h | 16 ++++++++-------- Include/objimpl.h | 6 +++--- Include/odictobject.h | 2 +- Include/py_curses.h | 2 +- Include/pycapsule.h | 2 +- Include/rangeobject.h | 2 +- Include/setobject.h | 18 +++++++++--------- Include/sliceobject.h | 2 +- Include/symtable.h | 2 +- Include/traceback.h | 2 +- Include/unicodeobject.h | 4 ++-- Include/weakrefobject.h | 6 +++--- 33 files changed, 71 insertions(+), 71 deletions(-) diff --git a/Include/abstract.h b/Include/abstract.h index 85550a34ca2686..31caec350498b7 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -934,7 +934,7 @@ PyAPI_FUNC(PyObject *) PySequence_Fast(PyObject *o, const char* m); need to be corrected for a negative index. */ #ifndef Py_LIMITED_API #define PySequence_ITEM(o, i)\ - ( Py_TYPE(o)->tp_as_sequence->sq_item(o, i) ) + ( _Py_TYPE(o)->tp_as_sequence->sq_item(o, i) ) #endif /* Return a pointer to the underlying item array for diff --git a/Include/boolobject.h b/Include/boolobject.h index 7cc2f1fe23937a..694b590d94c075 100644 --- a/Include/boolobject.h +++ b/Include/boolobject.h @@ -9,7 +9,7 @@ extern "C" { PyAPI_DATA(PyTypeObject) PyBool_Type; -#define PyBool_Check(x) (Py_TYPE(x) == &PyBool_Type) +#define PyBool_Check(x) (_Py_TYPE(x) == &PyBool_Type) /* Py_False and Py_True are the only two bools in existence. Don't forget to apply Py_INCREF() when returning either!!! */ diff --git a/Include/bytearrayobject.h b/Include/bytearrayobject.h index a757b880592979..995b8fd78fb6de 100644 --- a/Include/bytearrayobject.h +++ b/Include/bytearrayobject.h @@ -36,7 +36,7 @@ PyAPI_DATA(PyTypeObject) PyByteArrayIter_Type; /* Type check macros */ #define PyByteArray_Check(self) PyObject_TypeCheck(self, &PyByteArray_Type) -#define PyByteArray_CheckExact(self) (Py_TYPE(self) == &PyByteArray_Type) +#define PyByteArray_CheckExact(self) (_Py_TYPE(self) == &PyByteArray_Type) /* Direct API functions */ PyAPI_FUNC(PyObject *) PyByteArray_FromObject(PyObject *); diff --git a/Include/bytesobject.h b/Include/bytesobject.h index 3fde4a221fdb18..d863044728130d 100644 --- a/Include/bytesobject.h +++ b/Include/bytesobject.h @@ -45,8 +45,8 @@ PyAPI_DATA(PyTypeObject) PyBytes_Type; PyAPI_DATA(PyTypeObject) PyBytesIter_Type; #define PyBytes_Check(op) \ - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_BYTES_SUBCLASS) -#define PyBytes_CheckExact(op) (Py_TYPE(op) == &PyBytes_Type) + PyType_FastSubclass(_Py_TYPE(op), Py_TPFLAGS_BYTES_SUBCLASS) +#define PyBytes_CheckExact(op) (_Py_TYPE(op) == &PyBytes_Type) PyAPI_FUNC(PyObject *) PyBytes_FromStringAndSize(const char *, Py_ssize_t); PyAPI_FUNC(PyObject *) PyBytes_FromString(const char *); diff --git a/Include/cellobject.h b/Include/cellobject.h index 2f9b5b75d998ae..2587bdc867062f 100644 --- a/Include/cellobject.h +++ b/Include/cellobject.h @@ -13,7 +13,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyCell_Type; -#define PyCell_Check(op) (Py_TYPE(op) == &PyCell_Type) +#define PyCell_Check(op) (_Py_TYPE(op) == &PyCell_Type) PyAPI_FUNC(PyObject *) PyCell_New(PyObject *); PyAPI_FUNC(PyObject *) PyCell_Get(PyObject *); diff --git a/Include/code.h b/Include/code.h index 2e661e8b36b7f7..b193deb982da3a 100644 --- a/Include/code.h +++ b/Include/code.h @@ -97,7 +97,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyCode_Type; -#define PyCode_Check(op) (Py_TYPE(op) == &PyCode_Type) +#define PyCode_Check(op) (_Py_TYPE(op) == &PyCode_Type) #define PyCode_GetNumFree(op) (PyTuple_GET_SIZE((op)->co_freevars)) /* Public interface */ diff --git a/Include/complexobject.h b/Include/complexobject.h index cb8c52c5800854..f0021b04f84d46 100644 --- a/Include/complexobject.h +++ b/Include/complexobject.h @@ -39,7 +39,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyComplex_Type; #define PyComplex_Check(op) PyObject_TypeCheck(op, &PyComplex_Type) -#define PyComplex_CheckExact(op) (Py_TYPE(op) == &PyComplex_Type) +#define PyComplex_CheckExact(op) (_Py_TYPE(op) == &PyComplex_Type) #ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) PyComplex_FromCComplex(Py_complex); diff --git a/Include/context.h b/Include/context.h index 8b9f1292d75b6f..17ef658e038b94 100644 --- a/Include/context.h +++ b/Include/context.h @@ -17,9 +17,9 @@ PyAPI_DATA(PyTypeObject) PyContextToken_Type; typedef struct _pycontexttokenobject PyContextToken; -#define PyContext_CheckExact(o) (Py_TYPE(o) == &PyContext_Type) -#define PyContextVar_CheckExact(o) (Py_TYPE(o) == &PyContextVar_Type) -#define PyContextToken_CheckExact(o) (Py_TYPE(o) == &PyContextToken_Type) +#define PyContext_CheckExact(o) (_Py_TYPE(o) == &PyContext_Type) +#define PyContextVar_CheckExact(o) (_Py_TYPE(o) == &PyContextVar_Type) +#define PyContextToken_CheckExact(o) (_Py_TYPE(o) == &PyContextToken_Type) PyAPI_FUNC(PyContext *) PyContext_New(void); diff --git a/Include/datetime.h b/Include/datetime.h index 059d5ecf7a2113..e64b97e29d0c13 100644 --- a/Include/datetime.h +++ b/Include/datetime.h @@ -184,19 +184,19 @@ typedef struct { /* Macros for type checking when building the Python core. */ #define PyDate_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateType) -#define PyDate_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DateType) +#define PyDate_CheckExact(op) (_Py_TYPE(op) == &PyDateTime_DateType) #define PyDateTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateTimeType) -#define PyDateTime_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DateTimeType) +#define PyDateTime_CheckExact(op) (_Py_TYPE(op) == &PyDateTime_DateTimeType) #define PyTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeType) -#define PyTime_CheckExact(op) (Py_TYPE(op) == &PyDateTime_TimeType) +#define PyTime_CheckExact(op) (_Py_TYPE(op) == &PyDateTime_TimeType) #define PyDelta_Check(op) PyObject_TypeCheck(op, &PyDateTime_DeltaType) -#define PyDelta_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DeltaType) +#define PyDelta_CheckExact(op) (_Py_TYPE(op) == &PyDateTime_DeltaType) #define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType) -#define PyTZInfo_CheckExact(op) (Py_TYPE(op) == &PyDateTime_TZInfoType) +#define PyTZInfo_CheckExact(op) (_Py_TYPE(op) == &PyDateTime_TZInfoType) #else @@ -211,19 +211,19 @@ static PyDateTime_CAPI *PyDateTimeAPI = NULL; /* Macros for type checking when not building the Python core. */ #define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType) -#define PyDate_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DateType) +#define PyDate_CheckExact(op) (_Py_TYPE(op) == PyDateTimeAPI->DateType) #define PyDateTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateTimeType) -#define PyDateTime_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DateTimeType) +#define PyDateTime_CheckExact(op) (_Py_TYPE(op) == PyDateTimeAPI->DateTimeType) #define PyTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TimeType) -#define PyTime_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->TimeType) +#define PyTime_CheckExact(op) (_Py_TYPE(op) == PyDateTimeAPI->TimeType) #define PyDelta_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DeltaType) -#define PyDelta_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DeltaType) +#define PyDelta_CheckExact(op) (_Py_TYPE(op) == PyDateTimeAPI->DeltaType) #define PyTZInfo_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TZInfoType) -#define PyTZInfo_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->TZInfoType) +#define PyTZInfo_CheckExact(op) (_Py_TYPE(op) == PyDateTimeAPI->TZInfoType) /* Macros for accessing constructors in a simplified fashion. */ #define PyDate_FromDate(year, month, day) \ diff --git a/Include/descrobject.h b/Include/descrobject.h index 73bbb3fe54e5d0..8bd9fba3e8e719 100644 --- a/Include/descrobject.h +++ b/Include/descrobject.h @@ -95,7 +95,7 @@ PyAPI_FUNC(PyObject *) _PyMethodDescr_FastCallKeywords( PyObject *descrobj, PyObject *const *stack, Py_ssize_t nargs, PyObject *kwnames); PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *, struct wrapperbase *, void *); -#define PyDescr_IsData(d) (Py_TYPE(d)->tp_descr_set != NULL) +#define PyDescr_IsData(d) (_Py_TYPE(d)->tp_descr_set != NULL) #endif PyAPI_FUNC(PyObject *) PyDictProxy_New(PyObject *); diff --git a/Include/dictobject.h b/Include/dictobject.h index 28930f436d70e9..6bc96aa6f7dfb6 100644 --- a/Include/dictobject.h +++ b/Include/dictobject.h @@ -56,8 +56,8 @@ PyAPI_DATA(PyTypeObject) PyDictItems_Type; PyAPI_DATA(PyTypeObject) PyDictValues_Type; #define PyDict_Check(op) \ - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS) -#define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type) + PyType_FastSubclass(_Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS) +#define PyDict_CheckExact(op) (_Py_TYPE(op) == &PyDict_Type) #define PyDictKeys_Check(op) PyObject_TypeCheck(op, &PyDictKeys_Type) #define PyDictItems_Check(op) PyObject_TypeCheck(op, &PyDictItems_Type) #define PyDictValues_Check(op) PyObject_TypeCheck(op, &PyDictValues_Type) diff --git a/Include/floatobject.h b/Include/floatobject.h index f1044d64cba84d..18572c3ab60d6c 100644 --- a/Include/floatobject.h +++ b/Include/floatobject.h @@ -21,7 +21,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyFloat_Type; #define PyFloat_Check(op) PyObject_TypeCheck(op, &PyFloat_Type) -#define PyFloat_CheckExact(op) (Py_TYPE(op) == &PyFloat_Type) +#define PyFloat_CheckExact(op) (_Py_TYPE(op) == &PyFloat_Type) #ifdef Py_NAN #define Py_RETURN_NAN return PyFloat_FromDouble(Py_NAN) diff --git a/Include/frameobject.h b/Include/frameobject.h index a95baf8867a360..4fe6c87555c0b5 100644 --- a/Include/frameobject.h +++ b/Include/frameobject.h @@ -51,7 +51,7 @@ typedef struct _frame { PyAPI_DATA(PyTypeObject) PyFrame_Type; -#define PyFrame_Check(op) (Py_TYPE(op) == &PyFrame_Type) +#define PyFrame_Check(op) (_Py_TYPE(op) == &PyFrame_Type) PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *, PyObject *, PyObject *); diff --git a/Include/funcobject.h b/Include/funcobject.h index 86674ac90a08de..4e181749fce786 100644 --- a/Include/funcobject.h +++ b/Include/funcobject.h @@ -42,7 +42,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyFunction_Type; -#define PyFunction_Check(op) (Py_TYPE(op) == &PyFunction_Type) +#define PyFunction_Check(op) (_Py_TYPE(op) == &PyFunction_Type) PyAPI_FUNC(PyObject *) PyFunction_New(PyObject *, PyObject *); PyAPI_FUNC(PyObject *) PyFunction_NewWithQualName(PyObject *, PyObject *, PyObject *); diff --git a/Include/genobject.h b/Include/genobject.h index 16b983339cc649..b2a924682e495b 100644 --- a/Include/genobject.h +++ b/Include/genobject.h @@ -36,7 +36,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyGen_Type; #define PyGen_Check(op) PyObject_TypeCheck(op, &PyGen_Type) -#define PyGen_CheckExact(op) (Py_TYPE(op) == &PyGen_Type) +#define PyGen_CheckExact(op) (_Py_TYPE(op) == &PyGen_Type) PyAPI_FUNC(PyObject *) PyGen_New(struct _frame *); PyAPI_FUNC(PyObject *) PyGen_NewWithQualName(struct _frame *, @@ -59,7 +59,7 @@ PyAPI_DATA(PyTypeObject) _PyCoroWrapper_Type; PyAPI_DATA(PyTypeObject) _PyAIterWrapper_Type; -#define PyCoro_CheckExact(op) (Py_TYPE(op) == &PyCoro_Type) +#define PyCoro_CheckExact(op) (_Py_TYPE(op) == &PyCoro_Type) PyObject *_PyCoro_GetAwaitableIter(PyObject *o); PyAPI_FUNC(PyObject *) PyCoro_New(struct _frame *, PyObject *name, PyObject *qualname); @@ -88,7 +88,7 @@ PyAPI_DATA(PyTypeObject) _PyAsyncGenAThrow_Type; PyAPI_FUNC(PyObject *) PyAsyncGen_New(struct _frame *, PyObject *name, PyObject *qualname); -#define PyAsyncGen_CheckExact(op) (Py_TYPE(op) == &PyAsyncGen_Type) +#define PyAsyncGen_CheckExact(op) (_Py_TYPE(op) == &PyAsyncGen_Type) PyObject *_PyAsyncGenValueWrapperNew(PyObject *); diff --git a/Include/iterobject.h b/Include/iterobject.h index f61726f1f7f83a..4a07bff84a4b55 100644 --- a/Include/iterobject.h +++ b/Include/iterobject.h @@ -9,12 +9,12 @@ PyAPI_DATA(PyTypeObject) PySeqIter_Type; PyAPI_DATA(PyTypeObject) PyCallIter_Type; PyAPI_DATA(PyTypeObject) PyCmpWrapper_Type; -#define PySeqIter_Check(op) (Py_TYPE(op) == &PySeqIter_Type) +#define PySeqIter_Check(op) (_Py_TYPE(op) == &PySeqIter_Type) PyAPI_FUNC(PyObject *) PySeqIter_New(PyObject *); -#define PyCallIter_Check(op) (Py_TYPE(op) == &PyCallIter_Type) +#define PyCallIter_Check(op) (_Py_TYPE(op) == &PyCallIter_Type) PyAPI_FUNC(PyObject *) PyCallIter_New(PyObject *, PyObject *); diff --git a/Include/listobject.h b/Include/listobject.h index 6057279d51c3a4..2c3a2fdd730c3e 100644 --- a/Include/listobject.h +++ b/Include/listobject.h @@ -46,8 +46,8 @@ PyAPI_DATA(PyTypeObject) PyListRevIter_Type; PyAPI_DATA(PyTypeObject) PySortWrapper_Type; #define PyList_Check(op) \ - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS) -#define PyList_CheckExact(op) (Py_TYPE(op) == &PyList_Type) + PyType_FastSubclass(_Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS) +#define PyList_CheckExact(op) (_Py_TYPE(op) == &PyList_Type) PyAPI_FUNC(PyObject *) PyList_New(Py_ssize_t size); PyAPI_FUNC(Py_ssize_t) PyList_Size(PyObject *); diff --git a/Include/longobject.h b/Include/longobject.h index 82c06c92a63899..9832eebd80310f 100644 --- a/Include/longobject.h +++ b/Include/longobject.h @@ -12,8 +12,8 @@ typedef struct _longobject PyLongObject; /* Revealed in longintrepr.h */ PyAPI_DATA(PyTypeObject) PyLong_Type; #define PyLong_Check(op) \ - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS) -#define PyLong_CheckExact(op) (Py_TYPE(op) == &PyLong_Type) + PyType_FastSubclass(_Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS) +#define PyLong_CheckExact(op) (_Py_TYPE(op) == &PyLong_Type) PyAPI_FUNC(PyObject *) PyLong_FromLong(long); PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLong(unsigned long); diff --git a/Include/memoryobject.h b/Include/memoryobject.h index 990a716f220399..f207e370740b28 100644 --- a/Include/memoryobject.h +++ b/Include/memoryobject.h @@ -11,7 +11,7 @@ PyAPI_DATA(PyTypeObject) _PyManagedBuffer_Type; #endif PyAPI_DATA(PyTypeObject) PyMemoryView_Type; -#define PyMemoryView_Check(op) (Py_TYPE(op) == &PyMemoryView_Type) +#define PyMemoryView_Check(op) (_Py_TYPE(op) == &PyMemoryView_Type) #ifndef Py_LIMITED_API /* Get a pointer to the memoryview's private copy of the exporter's buffer. */ diff --git a/Include/methodobject.h b/Include/methodobject.h index ea35d86bcd171d..865e6654b1f216 100644 --- a/Include/methodobject.h +++ b/Include/methodobject.h @@ -13,7 +13,7 @@ extern "C" { PyAPI_DATA(PyTypeObject) PyCFunction_Type; -#define PyCFunction_Check(op) (Py_TYPE(op) == &PyCFunction_Type) +#define PyCFunction_Check(op) (_Py_TYPE(op) == &PyCFunction_Type) typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); typedef PyObject *(*_PyCFunctionFast) (PyObject *, PyObject *const *, Py_ssize_t); diff --git a/Include/moduleobject.h b/Include/moduleobject.h index 1d8fe46dea03a1..48b07229873852 100644 --- a/Include/moduleobject.h +++ b/Include/moduleobject.h @@ -10,7 +10,7 @@ extern "C" { PyAPI_DATA(PyTypeObject) PyModule_Type; #define PyModule_Check(op) PyObject_TypeCheck(op, &PyModule_Type) -#define PyModule_CheckExact(op) (Py_TYPE(op) == &PyModule_Type) +#define PyModule_CheckExact(op) (_Py_TYPE(op) == &PyModule_Type) #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(PyObject *) PyModule_NewObject( diff --git a/Include/object.h b/Include/object.h index c69d5d24bd1663..8fdf8f73f45d78 100644 --- a/Include/object.h +++ b/Include/object.h @@ -507,13 +507,13 @@ typedef struct _heaptypeobject { /* access macro to the members which are floating "behind" the object */ #define PyHeapType_GET_MEMBERS(etype) \ - ((PyMemberDef *)(((char *)etype) + Py_TYPE(etype)->tp_basicsize)) + ((PyMemberDef *)(((char *)etype) + _Py_TYPE(etype)->tp_basicsize)) #endif /* Generic type check */ PyAPI_FUNC(int) PyType_IsSubtype(PyTypeObject *, PyTypeObject *); #define PyObject_TypeCheck(ob, tp) \ - (Py_TYPE(ob) == (tp) || PyType_IsSubtype(Py_TYPE(ob), (tp))) + (_Py_TYPE(ob) == (tp) || PyType_IsSubtype(_Py_TYPE(ob), (tp))) PyAPI_DATA(PyTypeObject) PyType_Type; /* built-in 'type' */ PyAPI_DATA(PyTypeObject) PyBaseObject_Type; /* built-in 'object' */ @@ -522,8 +522,8 @@ PyAPI_DATA(PyTypeObject) PySuper_Type; /* built-in 'super' */ PyAPI_FUNC(unsigned long) PyType_GetFlags(PyTypeObject*); #define PyType_Check(op) \ - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TYPE_SUBCLASS) -#define PyType_CheckExact(op) (Py_TYPE(op) == &PyType_Type) + PyType_FastSubclass(_Py_TYPE(op), Py_TPFLAGS_TYPE_SUBCLASS) +#define PyType_CheckExact(op) (_Py_TYPE(op) == &PyType_Type) PyAPI_FUNC(int) PyType_Ready(PyTypeObject *); PyAPI_FUNC(PyObject *) PyType_GenericAlloc(PyTypeObject *, Py_ssize_t); @@ -779,9 +779,9 @@ PyAPI_FUNC(void) _PyDebug_PrintTotalRefs(void); #ifdef COUNT_ALLOCS PyAPI_FUNC(void) inc_count(PyTypeObject *); PyAPI_FUNC(void) dec_count(PyTypeObject *); -#define _Py_INC_TPALLOCS(OP) inc_count(Py_TYPE(OP)) -#define _Py_INC_TPFREES(OP) dec_count(Py_TYPE(OP)) -#define _Py_DEC_TPFREES(OP) Py_TYPE(OP)->tp_frees-- +#define _Py_INC_TPALLOCS(OP) inc_count(_Py_TYPE(OP)) +#define _Py_INC_TPFREES(OP) dec_count(_Py_TYPE(OP)) +#define _Py_DEC_TPFREES(OP) _Py_TYPE(OP)->tp_frees-- #define _Py_COUNT_ALLOCS_COMMA , #else #define _Py_INC_TPALLOCS(OP) @@ -815,7 +815,7 @@ PyAPI_FUNC(void) _Py_Dealloc(PyObject *); #else #define _Py_Dealloc(op) ( \ _Py_INC_TPFREES(op) _Py_COUNT_ALLOCS_COMMA \ - (*Py_TYPE(op)->tp_dealloc)((PyObject *)(op))) + (*_Py_TYPE(op)->tp_dealloc)((PyObject *)(op))) #endif #endif /* !Py_TRACE_REFS */ diff --git a/Include/objimpl.h b/Include/objimpl.h index e39036c385c3b4..4c8606a9011445 100644 --- a/Include/objimpl.h +++ b/Include/objimpl.h @@ -241,8 +241,8 @@ PyAPI_FUNC(Py_ssize_t) _PyGC_CollectIfEnabled(void); /* Test if an object has a GC head */ #ifndef Py_LIMITED_API -#define PyObject_IS_GC(o) (PyType_IS_GC(Py_TYPE(o)) && \ - (Py_TYPE(o)->tp_is_gc == NULL || Py_TYPE(o)->tp_is_gc(o))) +#define PyObject_IS_GC(o) (PyType_IS_GC(_Py_TYPE(o)) && \ + (_Py_TYPE(o)->tp_is_gc == NULL || _Py_TYPE(o)->tp_is_gc(o))) #endif PyAPI_FUNC(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, Py_ssize_t); @@ -377,7 +377,7 @@ PyAPI_FUNC(void) PyObject_GC_Del(void *); #define PyType_SUPPORTS_WEAKREFS(t) ((t)->tp_weaklistoffset > 0) #define PyObject_GET_WEAKREFS_LISTPTR(o) \ - ((PyObject **) (((char *) (o)) + Py_TYPE(o)->tp_weaklistoffset)) + ((PyObject **) (((char *) (o)) + _Py_TYPE(o)->tp_weaklistoffset)) #endif #ifdef __cplusplus diff --git a/Include/odictobject.h b/Include/odictobject.h index 8378dc4bfa45b4..749172ae300311 100644 --- a/Include/odictobject.h +++ b/Include/odictobject.h @@ -19,7 +19,7 @@ PyAPI_DATA(PyTypeObject) PyODictItems_Type; PyAPI_DATA(PyTypeObject) PyODictValues_Type; #define PyODict_Check(op) PyObject_TypeCheck(op, &PyODict_Type) -#define PyODict_CheckExact(op) (Py_TYPE(op) == &PyODict_Type) +#define PyODict_CheckExact(op) (_Py_TYPE(op) == &PyODict_Type) #define PyODict_SIZE(op) PyDict_GET_SIZE((op)) PyAPI_FUNC(PyObject *) PyODict_New(void); diff --git a/Include/py_curses.h b/Include/py_curses.h index 2702b37ea7cfe9..f798dff2e16cbf 100644 --- a/Include/py_curses.h +++ b/Include/py_curses.h @@ -64,7 +64,7 @@ typedef struct { char *encoding; } PyCursesWindowObject; -#define PyCursesWindow_Check(v) (Py_TYPE(v) == &PyCursesWindow_Type) +#define PyCursesWindow_Check(v) (_Py_TYPE(v) == &PyCursesWindow_Type) #define PyCurses_CAPSULE_NAME "_curses._C_API" diff --git a/Include/pycapsule.h b/Include/pycapsule.h index d9ecda7a4b6e4a..ead91917b66695 100644 --- a/Include/pycapsule.h +++ b/Include/pycapsule.h @@ -22,7 +22,7 @@ PyAPI_DATA(PyTypeObject) PyCapsule_Type; typedef void (*PyCapsule_Destructor)(PyObject *); -#define PyCapsule_CheckExact(op) (Py_TYPE(op) == &PyCapsule_Type) +#define PyCapsule_CheckExact(op) (_Py_TYPE(op) == &PyCapsule_Type) PyAPI_FUNC(PyObject *) PyCapsule_New( diff --git a/Include/rangeobject.h b/Include/rangeobject.h index 7e4dc28894b042..a6795a1d15b097 100644 --- a/Include/rangeobject.h +++ b/Include/rangeobject.h @@ -19,7 +19,7 @@ PyAPI_DATA(PyTypeObject) PyRange_Type; PyAPI_DATA(PyTypeObject) PyRangeIter_Type; PyAPI_DATA(PyTypeObject) PyLongRangeIter_Type; -#define PyRange_Check(op) (Py_TYPE(op) == &PyRange_Type) +#define PyRange_Check(op) (_Py_TYPE(op) == &PyRange_Type) #ifdef __cplusplus } diff --git a/Include/setobject.h b/Include/setobject.h index fc0ea83925f92f..57a02ec6ac4d83 100644 --- a/Include/setobject.h +++ b/Include/setobject.h @@ -88,19 +88,19 @@ PyAPI_FUNC(int) PySet_Discard(PyObject *set, PyObject *key); PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set); PyAPI_FUNC(Py_ssize_t) PySet_Size(PyObject *anyset); -#define PyFrozenSet_CheckExact(ob) (Py_TYPE(ob) == &PyFrozenSet_Type) +#define PyFrozenSet_CheckExact(ob) (_Py_TYPE(ob) == &PyFrozenSet_Type) #define PyAnySet_CheckExact(ob) \ - (Py_TYPE(ob) == &PySet_Type || Py_TYPE(ob) == &PyFrozenSet_Type) + (_Py_TYPE(ob) == &PySet_Type || _Py_TYPE(ob) == &PyFrozenSet_Type) #define PyAnySet_Check(ob) \ - (Py_TYPE(ob) == &PySet_Type || Py_TYPE(ob) == &PyFrozenSet_Type || \ - PyType_IsSubtype(Py_TYPE(ob), &PySet_Type) || \ - PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) + (_Py_TYPE(ob) == &PySet_Type || _Py_TYPE(ob) == &PyFrozenSet_Type || \ + PyType_IsSubtype(_Py_TYPE(ob), &PySet_Type) || \ + PyType_IsSubtype(_Py_TYPE(ob), &PyFrozenSet_Type)) #define PySet_Check(ob) \ - (Py_TYPE(ob) == &PySet_Type || \ - PyType_IsSubtype(Py_TYPE(ob), &PySet_Type)) + (_Py_TYPE(ob) == &PySet_Type || \ + PyType_IsSubtype(_Py_TYPE(ob), &PySet_Type)) #define PyFrozenSet_Check(ob) \ - (Py_TYPE(ob) == &PyFrozenSet_Type || \ - PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) + (_Py_TYPE(ob) == &PyFrozenSet_Type || \ + PyType_IsSubtype(_Py_TYPE(ob), &PyFrozenSet_Type)) #ifdef __cplusplus } diff --git a/Include/sliceobject.h b/Include/sliceobject.h index c238b099ea8151..5179e4e79c9255 100644 --- a/Include/sliceobject.h +++ b/Include/sliceobject.h @@ -28,7 +28,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PySlice_Type; PyAPI_DATA(PyTypeObject) PyEllipsis_Type; -#define PySlice_Check(op) (Py_TYPE(op) == &PySlice_Type) +#define PySlice_Check(op) (_Py_TYPE(op) == &PySlice_Type) PyAPI_FUNC(PyObject *) PySlice_New(PyObject* start, PyObject* stop, PyObject* step); diff --git a/Include/symtable.h b/Include/symtable.h index 007f88db40e7eb..31189936c0df45 100644 --- a/Include/symtable.h +++ b/Include/symtable.h @@ -65,7 +65,7 @@ typedef struct _symtable_entry { PyAPI_DATA(PyTypeObject) PySTEntry_Type; -#define PySTEntry_Check(op) (Py_TYPE(op) == &PySTEntry_Type) +#define PySTEntry_Check(op) (_Py_TYPE(op) == &PySTEntry_Type) PyAPI_FUNC(int) PyST_GetScope(PySTEntryObject *, PyObject *); diff --git a/Include/traceback.h b/Include/traceback.h index b5874100f477a5..0805af0a72f6f6 100644 --- a/Include/traceback.h +++ b/Include/traceback.h @@ -29,7 +29,7 @@ PyAPI_FUNC(void) _PyTraceback_Add(const char *, const char *, int); /* Reveal traceback type so we can typecheck traceback objects */ PyAPI_DATA(PyTypeObject) PyTraceBack_Type; -#define PyTraceBack_Check(v) (Py_TYPE(v) == &PyTraceBack_Type) +#define PyTraceBack_Check(v) (_Py_TYPE(v) == &PyTraceBack_Type) #ifndef Py_LIMITED_API /* Write the Python traceback into the file 'fd'. For example: diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 0274de6733ab0e..99680e8583966a 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -360,8 +360,8 @@ PyAPI_DATA(PyTypeObject) PyUnicode_Type; PyAPI_DATA(PyTypeObject) PyUnicodeIter_Type; #define PyUnicode_Check(op) \ - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS) -#define PyUnicode_CheckExact(op) (Py_TYPE(op) == &PyUnicode_Type) + PyType_FastSubclass(_Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS) +#define PyUnicode_CheckExact(op) (_Py_TYPE(op) == &PyUnicode_Type) /* Fast access macros */ #ifndef Py_LIMITED_API diff --git a/Include/weakrefobject.h b/Include/weakrefobject.h index 17051568f3a6e9..558f43035bd94e 100644 --- a/Include/weakrefobject.h +++ b/Include/weakrefobject.h @@ -46,10 +46,10 @@ PyAPI_DATA(PyTypeObject) _PyWeakref_CallableProxyType; #define PyWeakref_CheckRef(op) PyObject_TypeCheck(op, &_PyWeakref_RefType) #define PyWeakref_CheckRefExact(op) \ - (Py_TYPE(op) == &_PyWeakref_RefType) + (_Py_TYPE(op) == &_PyWeakref_RefType) #define PyWeakref_CheckProxy(op) \ - ((Py_TYPE(op) == &_PyWeakref_ProxyType) || \ - (Py_TYPE(op) == &_PyWeakref_CallableProxyType)) + ((_Py_TYPE(op) == &_PyWeakref_ProxyType) || \ + (_Py_TYPE(op) == &_PyWeakref_CallableProxyType)) #define PyWeakref_Check(op) \ (PyWeakref_CheckRef(op) || PyWeakref_CheckProxy(op)) From 48c30fdb0efeac873f791725c3b4620424d6981d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Sep 2018 15:32:27 +0200 Subject: [PATCH 38/50] Fix PyTuple_SetItemRef(NULL) --- Objects/tupleobject.c | 2 +- capi_tests/Makefile | 3 ++- capi_tests/test_tuple.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index c88958518d2b7c..ebd64db7b4ee03 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -190,7 +190,7 @@ PyTuple_SetItem(PyObject *op, Py_ssize_t i, PyObject *newitem) int PyTuple_SetItemRef(PyObject *op, Py_ssize_t i, PyObject *newitem) { - Py_INCREF(newitem); + Py_XINCREF(newitem); return PyTuple_SetItem(op, i, newitem); } diff --git a/capi_tests/Makefile b/capi_tests/Makefile index 504eec1e028a6a..441f469208385d 100644 --- a/capi_tests/Makefile +++ b/capi_tests/Makefile @@ -5,7 +5,8 @@ PYTHON_LDFLAGS=-l $(LIBPYTHON) -L $(CPYTHON_SRC) CFLAGS=$(shell pkg-config check --cflags) $(PYTHON_CFLAGS) LDFLAGS=$(shell pkg-config check --libs) $(PYTHON_LDFLAGS) SOURCES=runtests.c test_object.c test_tuple.c -ENV_RUNTEST=LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib + +#ENV_RUNTEST=LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib # CK_FORK=no to detect reference leaks ENV_RUNTEST=CK_FORK=no LD_LIBRARY_PATH=$(CPYTHON_SRC) PYTHONPATH=$(CPYTHON_SRC)/Lib diff --git a/capi_tests/test_tuple.c b/capi_tests/test_tuple.c index 1e3039305934a5..87a2fc937b9054 100644 --- a/capi_tests/test_tuple.c +++ b/capi_tests/test_tuple.c @@ -276,6 +276,38 @@ check_PyTuple_SetItemRef(func_type ftype) Py_DECREF(obj2); } Py_DECREF(tuple); + + /* Tuple items set explicitly to NULL */ + tuple = PyTuple_New(size); + ck_assert_ptr_nonnull(tuple); + for (size_t i = 0; i < size; i++) { + switch (ftype) + { + case STRONG: + { + int res = PyTuple_SetItemRef(tuple, i, NULL); + ck_assert_int_eq(res, 0); + break; + } +#ifndef Py_NEWCAPI + case BORROW: + { + int res = PyTuple_SetItem(tuple, i, NULL); + ck_assert_int_eq(res, 0); + break; + } + case MACRO: + { + PyTuple_SET_ITEM(tuple, i, NULL); + break; + } +#endif + } + + PyObject *item = PyTuple_GetItemRef(tuple, i); + ck_assert_ptr_null(item); + } + Py_DECREF(tuple); } From e0889e90b9e627c36521702126ee62e580a725d0 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Sep 2018 15:33:06 +0200 Subject: [PATCH 39/50] Add PySequence_Fast_GetItemRef() and PyList_GetItemRef() Add PySequence_Fast_GetItemRef(), PyStructSequence_SetItemRef(), PyList_GetItemRef(). Add again Py_TYPE(). --- Include/abstract.h | 2 + Include/listobject.h | 1 + Include/object.h | 2 - Include/structseq.h | 1 + Modules/_asynciomodule.c | 32 ++-- Modules/_ctypes/_ctypes.c | 142 +++++++++++------ Modules/_ctypes/callbacks.c | 6 +- Modules/_ctypes/callproc.c | 13 +- Modules/_ctypes/stgdict.c | 7 +- Modules/_datetimemodule.c | 242 +++++++++++++++++++---------- Modules/_decimal/_decimal.c | 30 +++- Modules/_elementtree.c | 10 +- Modules/_json.c | 28 +++- Modules/_pickle.c | 157 +++++++++++++------ Modules/_posixsubprocess.c | 23 ++- Modules/_randommodule.c | 15 +- Modules/_sqlite/connection.c | 7 +- Modules/_sqlite/cursor.c | 28 ++-- Modules/_sqlite/row.c | 25 +-- Modules/_sqlite/statement.c | 3 +- Modules/_ssl.c | 59 ++++--- Modules/_struct.c | 3 +- Modules/_testbuffer.c | 79 ++++++---- Modules/_testcapimodule.c | 1 + Modules/_tkinter.c | 55 ++++--- Modules/arraymodule.c | 12 +- Modules/audioop.c | 16 +- Modules/cjkcodecs/multibytecodec.c | 54 +++++-- Modules/grpmodule.c | 2 +- Modules/mathmodule.c | 12 +- Modules/parsermodule.c | 10 +- Modules/pyexpat.c | 6 +- Modules/resource.c | 15 +- Modules/selectmodule.c | 18 ++- Modules/socketmodule.c | 24 ++- Modules/spwdmodule.c | 8 +- Objects/listobject.c | 9 ++ TODO.rst | 1 + setup.py | 2 +- 39 files changed, 771 insertions(+), 389 deletions(-) diff --git a/Include/abstract.h b/Include/abstract.h index 31caec350498b7..165eb958dd2af0 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -929,6 +929,8 @@ PyAPI_FUNC(PyObject *) PySequence_Fast(PyObject *o, const char* m); by PySequence_Fast, and that i is within bounds. */ #define PySequence_Fast_GET_ITEM(o, i)\ (PyList_Check(o) ? PyList_GET_ITEM(o, i) : PyTuple_GET_ITEM(o, i)) +#define PySequence_Fast_GetItemRef(o, i)\ + (PyList_Check(o) ? PyList_GetItemRef(o, i) : PyTuple_GetItemRef(o, i)) /* Assume tp_as_sequence and sq_item exist and that 'i' does not need to be corrected for a negative index. */ diff --git a/Include/listobject.h b/Include/listobject.h index 2c3a2fdd730c3e..8628f8cdd76dc5 100644 --- a/Include/listobject.h +++ b/Include/listobject.h @@ -52,6 +52,7 @@ PyAPI_DATA(PyTypeObject) PySortWrapper_Type; PyAPI_FUNC(PyObject *) PyList_New(Py_ssize_t size); PyAPI_FUNC(Py_ssize_t) PyList_Size(PyObject *); PyAPI_FUNC(PyObject *) PyList_GetItem(PyObject *, Py_ssize_t); +PyAPI_FUNC(PyObject *) PyList_GetItemRef(PyObject *, Py_ssize_t); PyAPI_FUNC(int) PyList_SetItem(PyObject *, Py_ssize_t, PyObject *); PyAPI_FUNC(int) PyList_Insert(PyObject *, Py_ssize_t, PyObject *); PyAPI_FUNC(int) PyList_Append(PyObject *, PyObject *); diff --git a/Include/object.h b/Include/object.h index 8fdf8f73f45d78..70cf281acfa6d3 100644 --- a/Include/object.h +++ b/Include/object.h @@ -455,10 +455,8 @@ typedef struct _typeobject { do { _Py_TYPE(ob) = (type); } while (0) #ifdef Py_NEWCAPI_NO_STRUCT -#ifdef Py_NEWCAPI_BORROWED_REF PyAPI_FUNC(PyTypeObject*) _Py_TYPE_impl(PyObject *op); #define Py_TYPE(ob) _Py_TYPE_impl((PyObject *)(ob)) -#endif #else #define Py_TYPE(ob) _Py_TYPE(ob) #endif diff --git a/Include/structseq.h b/Include/structseq.h index e5e5d5c5735e9d..0fe345d4c972aa 100644 --- a/Include/structseq.h +++ b/Include/structseq.h @@ -36,6 +36,7 @@ typedef PyTupleObject PyStructSequence; /* Macro, *only* to be used to fill in brand new objects */ #define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM(op, i, v) +#define PyStructSequence_SetItemRef(op, i, v) PyTuple_SetItemRef(op, i, v) #define PyStructSequence_GET_ITEM(op, i) PyTuple_GET_ITEM(op, i) #endif diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 4cf9ede86df53f..9697ddfb09617e 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -448,15 +448,19 @@ future_schedule_callbacks(FutureObj *fut) for (i = 0; i < len; i++) { PyObject *cb_tup = PyList_GET_ITEM(fut->fut_callbacks, i); - PyObject *cb = PyTuple_GET_ITEM(cb_tup, 0); - PyObject *ctx = PyTuple_GET_ITEM(cb_tup, 1); + PyObject *cb = PyTuple_GetItemRef(cb_tup, 0); + PyObject *ctx = PyTuple_GetItemRef(cb_tup, 1); if (call_soon(fut->fut_loop, cb, (PyObject *)fut, (PyContext *)ctx)) { + Py_DECREF(cb); + Py_DECREF(ctx); /* If an error occurs in pure-Python implementation, all callbacks are cleared. */ Py_CLEAR(fut->fut_callbacks); return -1; } + Py_DECREF(cb); + Py_DECREF(ctx); } Py_CLEAR(fut->fut_callbacks); @@ -666,10 +670,8 @@ future_add_done_callback(FutureObj *fut, PyObject *arg, PyContext *ctx) if (tup == NULL) { return NULL; } - Py_INCREF(arg); - PyTuple_SET_ITEM(tup, 0, arg); - Py_INCREF(ctx); - PyTuple_SET_ITEM(tup, 1, (PyObject *)ctx); + PyTuple_SetItemRef(tup, 0, arg); + PyTuple_SetItemRef(tup, 1, (PyObject *)ctx); if (fut->fut_callbacks != NULL) { int err = PyList_Append(fut->fut_callbacks, tup); @@ -964,8 +966,9 @@ _asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn) if (len == 1) { PyObject *cb_tup = PyList_GET_ITEM(self->fut_callbacks, 0); - int cmp = PyObject_RichCompareBool( - fn, PyTuple_GET_ITEM(cb_tup, 0), Py_EQ); + PyObject *arg = PyTuple_GetItemRef(cb_tup, 0); + int cmp = PyObject_RichCompareBool(fn, arg, Py_EQ); + Py_DECREF(arg); if (cmp == -1) { return NULL; } @@ -987,7 +990,9 @@ _asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn) int ret; PyObject *item = PyList_GET_ITEM(self->fut_callbacks, i); Py_INCREF(item); - ret = PyObject_RichCompareBool(fn, PyTuple_GET_ITEM(item, 0), Py_EQ); + PyObject *arg = PyTuple_GetItemRef(item, 0); + ret = PyObject_RichCompareBool(fn, arg, Py_EQ); + Py_DECREF(arg); if (ret == 0) { if (j < len) { PyList_SET_ITEM(newlist, j, item); @@ -1194,11 +1199,9 @@ FutureObj_get_callbacks(FutureObj *fut) return NULL; } - Py_INCREF(fut->fut_callback0); - PyTuple_SET_ITEM(tup0, 0, fut->fut_callback0); + PyTuple_SetItemRef(tup0, 0, fut->fut_callback0); assert(fut->fut_context0 != NULL); - Py_INCREF(fut->fut_context0); - PyTuple_SET_ITEM(tup0, 1, (PyObject *)fut->fut_context0); + PyTuple_SetItemRef(tup0, 1, (PyObject *)fut->fut_context0); PyList_SET_ITEM(new_list, 0, tup0); @@ -3286,7 +3289,8 @@ module_init(void) if (context_str == NULL) { goto fail; } - PyTuple_SET_ITEM(context_kwname, 0, context_str); + PyTuple_SetItemRef(context_kwname, 0, context_str); + Py_DECREF(context_str); #define WITH_MOD(NAME) \ Py_CLEAR(module); \ diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 98173328cf9884..c91e1b5f187994 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -962,17 +962,20 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyObject *proto; PyObject *typedict; - typedict = PyTuple_GetItem(args, 2); - if (!typedict) + typedict = PyTuple_GetItemRef(args, 2); + if (!typedict) { return NULL; + } /* stgdict items size, align, length contain info about pointers itself, stgdict->proto has info about the pointed to type! */ stgdict = (StgDictObject *)PyObject_CallObject( (PyObject *)&PyCStgDict_Type, NULL); - if (!stgdict) + if (!stgdict) { + Py_DECREF(typedict); return NULL; + } stgdict->size = sizeof(void *); stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment; stgdict->length = 1; @@ -981,6 +984,7 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) stgdict->flags |= TYPEFLAG_ISPOINTER; proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */ + Py_DECREF(typedict); if (proto && -1 == PyCPointerType_SetProto(stgdict, proto)) { Py_DECREF((PyObject *)stgdict); return NULL; @@ -1835,7 +1839,6 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject { PyTypeObject *result; StgDictObject *stgdict; - PyObject *name = PyTuple_GET_ITEM(args, 0); PyObject *newname; PyObject *swapped_args; static PyObject *suffix; @@ -1852,17 +1855,20 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject suffix = PyUnicode_InternFromString("_be"); #endif + PyObject *name = PyTuple_GetItemRef(args, 0); newname = PyUnicode_Concat(name, suffix); + Py_DECREF(name); if (newname == NULL) { Py_DECREF(swapped_args); return NULL; } - PyTuple_SET_ITEM(swapped_args, 0, newname); + PyTuple_SetItemRef(swapped_args, 0, newname); + Py_DECREF(newname); for (i=1; ib_ptr = ptr; - return (PyObject *)ob; + if (1 == PyTuple_GET_SIZE(args)) { + arg = PyTuple_GetItemRef(args, 0); + if (PyLong_Check(arg)) { + Py_DECREF(arg); + CDataObject *ob; + PyObject *arg = PyTuple_GetItemRef(args, 0); + void *ptr = PyLong_AsVoidPtr(arg); + Py_DECREF(arg); + if (ptr == NULL && PyErr_Occurred()) + return NULL; + ob = (CDataObject *)GenericPyCData_new(type, args, kwds); + if (ob == NULL) + return NULL; + *(void **)ob->b_ptr = ptr; + return (PyObject *)ob; + } + Py_DECREF(arg); } if (!PyArg_ParseTuple(args, "O", &callable)) @@ -3585,9 +3614,8 @@ _get_arg(int *pindex, PyObject *name, PyObject *defval, PyObject *inargs, PyObje PyObject *v; if (*pindex < PyTuple_GET_SIZE(inargs)) { - v = PyTuple_GET_ITEM(inargs, *pindex); + v = PyTuple_GetItemRef(inargs, *pindex); ++*pindex; - Py_INCREF(v); return v; } if (kwds && name && (v = PyDict_GetItem(kwds, name))) { @@ -3668,7 +3696,8 @@ _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes, } #endif for (i = 0; i < len; ++i) { - PyObject *item = PyTuple_GET_ITEM(paramflags, i); + PyObject *item = PyTuple_GetItemRef(paramflags, i); + Py_DECREF(item); PyObject *ob; int flag; PyObject *name = NULL; @@ -3678,9 +3707,19 @@ _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes, calls below. */ /* We HAVE already checked that the tuple can be parsed with "i|ZO", so... */ Py_ssize_t tsize = PyTuple_GET_SIZE(item); - flag = PyLong_AS_LONG(PyTuple_GET_ITEM(item, 0)); - name = tsize > 1 ? PyTuple_GET_ITEM(item, 1) : NULL; - defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL; + PyObject *item0 = PyTuple_GetItemRef(item, 0); + flag = PyLong_AS_LONG(item0); + Py_DECREF(item0); + name = NULL; + defval = NULL; + if (tsize > 1) { + name = PyTuple_GetItemRef(item, 1); + Py_DECREF(name); + } + if (tsize > 2) { + defval = PyTuple_GetItemRef(item, 2); + Py_DECREF(defval); + } switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) { case PARAMFLAG_FIN | PARAMFLAG_FLCID: @@ -3689,7 +3728,8 @@ _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes, if (defval == NULL) defval = _PyLong_Zero; Py_INCREF(defval); - PyTuple_SET_ITEM(callargs, i, defval); + PyTuple_SetItemRef(callargs, i, defval); + Py_DECREF(defval); break; case (PARAMFLAG_FIN | PARAMFLAG_FOUT): *pinoutmask |= (1 << i); /* mark as inout arg */ @@ -3701,7 +3741,8 @@ _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes, ob =_get_arg(&inargs_index, name, defval, inargs, kwds); if (ob == NULL) goto error; - PyTuple_SET_ITEM(callargs, i, ob); + PyTuple_SetItemRef(callargs, i, ob); + Py_DECREF(ob); break; case PARAMFLAG_FOUT: /* XXX Refactor this code into a separate function. */ @@ -3715,14 +3756,14 @@ _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes, /* XXX Using mutable objects as defval will make the function non-threadsafe, unless we copy the object in each invocation */ - Py_INCREF(defval); - PyTuple_SET_ITEM(callargs, i, defval); + PyTuple_SetItemRef(callargs, i, defval); *poutmask |= (1 << i); /* mark as out arg */ (*pnumretvals)++; break; } - ob = PyTuple_GET_ITEM(argtypes, i); + ob = PyTuple_GetItemRef(argtypes, i); dict = PyType_stgdict(ob); + Py_DECREF(ob); if (dict == NULL) { /* Cannot happen: _validate_paramflags() would not accept such an object */ @@ -3752,7 +3793,8 @@ _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes, goto error; /* The .from_param call that will occur later will pass this as a byref parameter. */ - PyTuple_SET_ITEM(callargs, i, ob); + PyTuple_SetItemRef(callargs, i, ob); + Py_DECREF(ob); *poutmask |= (1 << i); /* mark as out arg */ (*pnumretvals)++; break; @@ -3826,24 +3868,26 @@ _build_result(PyObject *result, PyObject *callargs, for (bit = 1, i = 0; i < 32; ++i, bit <<= 1) { PyObject *v; if (bit & inoutmask) { - v = PyTuple_GET_ITEM(callargs, i); - Py_INCREF(v); + v = PyTuple_GetItemRef(callargs, i); if (numretvals == 1) { Py_DECREF(callargs); return v; } - PyTuple_SET_ITEM(tup, index, v); + PyTuple_SetItemRef(tup, index, v); + Py_DECREF(v); index++; } else if (bit & outmask) { _Py_IDENTIFIER(__ctypes_from_outparam__); - v = PyTuple_GET_ITEM(callargs, i); + v = PyTuple_GetItemRef(callargs, i); + Py_DECREF(v); v = _PyObject_CallMethodId(v, &PyId___ctypes_from_outparam__, NULL); if (v == NULL || numretvals == 1) { Py_DECREF(callargs); return v; } - PyTuple_SET_ITEM(tup, index, v); + PyTuple_SetItemRef(tup, index, v); + Py_DECREF(v); index++; } if (index == numretvals) @@ -4148,7 +4192,8 @@ _init_pos_args(PyObject *self, PyTypeObject *type, Py_DECREF(pair); return -1; } - val = PyTuple_GET_ITEM(args, i + index); + val = PyTuple_GetItemRef(args, i + index); + Py_DECREF(val); if (kwds && PyDict_GetItem(kwds, name)) { PyErr_Format(PyExc_TypeError, "duplicate values for field %R", @@ -4304,9 +4349,12 @@ Array_init(CDataObject *self, PyObject *args, PyObject *kw) n = PyTuple_GET_SIZE(args); for (i = 0; i < n; ++i) { PyObject *v; - v = PyTuple_GET_ITEM(args, i); - if (-1 == PySequence_SetItem((PyObject *)self, i, v)) + v = PyTuple_GetItemRef(args, i); + if (-1 == PySequence_SetItem((PyObject *)self, i, v)) { + Py_DECREF(v); return -1; + } + Py_DECREF(v); } return 0; } diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index d579291b62fea6..98b456684b7fd8 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -171,7 +171,8 @@ static void _CallPythonObject(void *mem, Py_DECREF(cnv); goto Done; } - PyTuple_SET_ITEM(arglist, i, v); + PyTuple_SetItemRef(arglist, i, v); + Py_DECREF(v); /* XXX XXX XX We have the problem that c_byte or c_short have dict->size of 1 resp. 4, but these parameters are pushed as sizeof(int) bytes. @@ -192,7 +193,8 @@ static void _CallPythonObject(void *mem, goto Done; } memcpy(obj->b_ptr, *pArgs, dict->size); - PyTuple_SET_ITEM(arglist, i, (PyObject *)obj); + PyTuple_SetItemRef(arglist, i, (PyObject*)obj); + Py_DECREF(obj); #ifdef MS_WIN32 TryAddRef(dict, obj); #endif diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index bdc372811598e5..621c7b36bef5e1 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -1093,15 +1093,17 @@ PyObject *_ctypes_callproc(PPROC pProc, PyObject *arg; int err; - arg = PyTuple_GET_ITEM(argtuple, i); /* borrowed ref */ + arg = PyTuple_GetItemRef(argtuple, i); /* borrowed ref */ + Py_DECREF(arg); /* For cdecl functions, we allow more actual arguments than the length of the argtypes tuple. This is checked in _ctypes::PyCFuncPtr_Call */ if (argtypes && argtype_count > i) { PyObject *v; - converter = PyTuple_GET_ITEM(argtypes, i); + converter = PyTuple_GetItemRef(argtypes, i); v = PyObject_CallFunctionObjArgs(converter, arg, NULL); + Py_DECREF(converter); if (v == NULL) { _ctypes_extend_error(PyExc_ArgError, "argument %d: ", i+1); goto cleanup; @@ -1762,8 +1764,11 @@ buffer_info(PyObject *self, PyObject *arg) shape = PyTuple_New(dict->ndim); if (shape == NULL) return NULL; - for (i = 0; i < (int)dict->ndim; ++i) - PyTuple_SET_ITEM(shape, i, PyLong_FromSsize_t(dict->shape[i])); + for (i = 0; i < (int)dict->ndim; ++i) { + PyObject *arg = PyLong_FromSsize_t(dict->shape[i]); + PyTuple_SetItemRef(shape, i, arg); + Py_DECREF(arg); + } if (PyErr_Occurred()) { Py_DECREF(shape); diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index 25656ff878759c..1aaa9498859ede 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -217,15 +217,17 @@ MakeFields(PyObject *type, CFieldObject *descr, return -1; for (i = 0; i < PySequence_Fast_GET_SIZE(fieldlist); ++i) { - PyObject *pair = PySequence_Fast_GET_ITEM(fieldlist, i); /* borrowed */ PyObject *fname, *ftype, *bits; CFieldObject *fdescr; CFieldObject *new_descr; /* Convert to PyArg_UnpackTuple... */ + PyObject *pair = PySequence_Fast_GetItemRef(fieldlist, i); if (!PyArg_ParseTuple(pair, "OO|O", &fname, &ftype, &bits)) { + Py_DECREF(pair); Py_DECREF(fieldlist); return -1; } + Py_DECREF(pair); fdescr = (CFieldObject *)PyObject_GetAttr(descr->proto, fname); if (fdescr == NULL) { Py_DECREF(fieldlist); @@ -296,8 +298,9 @@ MakeAnonFields(PyObject *type) return -1; for (i = 0; i < PySequence_Fast_GET_SIZE(anon_names); ++i) { - PyObject *fname = PySequence_Fast_GET_ITEM(anon_names, i); /* borrowed */ + PyObject *fname = PySequence_Fast_GetItemRef(anon_names, i); /* borrowed */ CFieldObject *descr = (CFieldObject *)PyObject_GetAttr(type, fname); + Py_DECREF(fname); if (descr == NULL) { Py_DECREF(anon_names); return -1; diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 07679447882cfd..ac3f64e07264ba 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -175,8 +175,7 @@ divide_nearest(PyObject *m, PyObject *n) temp = _PyLong_DivmodNear(m, n); if (temp == NULL) return NULL; - result = PyTuple_GET_ITEM(temp, 0); - Py_INCREF(result); + result = PyTuple_GetItemRef(temp, 0); Py_DECREF(temp); return result; @@ -1790,11 +1789,11 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type) if (tuple == NULL) goto Done; - num = PyTuple_GetItem(tuple, 1); /* us */ + num = PyTuple_GetItemRef(tuple, 1); /* us */ if (num == NULL) goto Done; temp = PyLong_AsLong(num); - num = NULL; + Py_CLEAR(num); if (temp == -1 && PyErr_Occurred()) goto Done; assert(0 <= temp && temp < 1000000); @@ -1805,10 +1804,9 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type) goto Done; } - num = PyTuple_GetItem(tuple, 0); /* leftover seconds */ + num = PyTuple_GetItemRef(tuple, 0); /* leftover seconds */ if (num == NULL) goto Done; - Py_INCREF(num); Py_DECREF(tuple); tuple = PyNumber_Divmod(num, seconds_per_day); @@ -1816,11 +1814,11 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type) goto Done; Py_DECREF(num); - num = PyTuple_GetItem(tuple, 1); /* seconds */ + num = PyTuple_GetItemRef(tuple, 1); /* seconds */ if (num == NULL) goto Done; temp = PyLong_AsLong(num); - num = NULL; + Py_CLEAR(num); if (temp == -1 && PyErr_Occurred()) goto Done; assert(0 <= temp && temp < 24*3600); @@ -1832,10 +1830,9 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type) goto Done; } - num = PyTuple_GetItem(tuple, 0); /* leftover days */ + num = PyTuple_GetItemRef(tuple, 0); /* leftover days */ if (num == NULL) goto Done; - Py_INCREF(num); temp = PyLong_AsLong(num); if (temp == -1 && PyErr_Occurred()) goto Done; @@ -1911,6 +1908,7 @@ multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, PyObject *result = NULL; PyObject *pyus_in = NULL, *temp, *pyus_out; PyObject *ratio = NULL; + PyObject *num; pyus_in = delta_to_microseconds(delta); if (pyus_in == NULL) @@ -1919,12 +1917,16 @@ multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, if (ratio == NULL) { goto error; } - temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op)); + num = PyTuple_GetItemRef(ratio, op); + temp = PyNumber_Multiply(pyus_in, num); + Py_DECREF(num); Py_DECREF(pyus_in); pyus_in = NULL; if (temp == NULL) goto error; - pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op)); + num = PyTuple_GetItemRef(ratio, !op); + pyus_out = divide_nearest(temp, num); + Py_DECREF(num); Py_DECREF(temp); if (pyus_out == NULL) goto error; @@ -2278,12 +2280,16 @@ delta_divmod(PyObject *left, PyObject *right) return NULL; assert(PyTuple_Size(divmod) == 2); - delta = microseconds_to_delta(PyTuple_GET_ITEM(divmod, 1)); + PyObject *mod = PyTuple_GetItemRef(divmod, 1); + delta = microseconds_to_delta(mod); + Py_DECREF(mod); if (delta == NULL) { Py_DECREF(divmod); return NULL; } - result = PyTuple_Pack(2, PyTuple_GET_ITEM(divmod, 0), delta); + PyObject *quotient = PyTuple_GetItemRef(divmod, 0); + result = PyTuple_Pack(2, quotient, delta); + Py_DECREF(quotient); Py_DECREF(delta); Py_DECREF(divmod); return result; @@ -2755,36 +2761,57 @@ static PyGetSetDef date_getset[] = { static char *date_kws[] = {"year", "month", "day", NULL}; +static int +date_new1(PyTypeObject *type, PyObject *args, PyObject **objp) +{ + if (PyTuple_GET_SIZE(args) != 1) { + return 0; + } + PyObject *state = PyTuple_GetItemRef(args, 0); + if (!(PyBytes_Check(state) + && PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE + && MONTH_IS_SANE(PyBytes_AS_STRING(state)[2]))) { + Py_DECREF(state); + return 0; + } + + PyDateTime_Date *me = (PyDateTime_Date *) (type->tp_alloc(type, 0)); + if (me == NULL) { + Py_DECREF(state); + *objp = NULL; + return -1; + } + + char *pdata = PyBytes_AS_STRING(state); + memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE); + Py_DECREF(state); + me->hashcode = -1; + *objp = (PyObject *)me; + return 1; +} + + static PyObject * date_new(PyTypeObject *type, PyObject *args, PyObject *kw) { - PyObject *self = NULL; - PyObject *state; - int year; - int month; - int day; /* Check for invocation from pickle with __getstate__ state */ - if (PyTuple_GET_SIZE(args) == 1 && - PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) && - PyBytes_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE && - MONTH_IS_SANE(PyBytes_AS_STRING(state)[2])) - { - PyDateTime_Date *me; - - me = (PyDateTime_Date *) (type->tp_alloc(type, 0)); - if (me != NULL) { - char *pdata = PyBytes_AS_STRING(state); - memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE); - me->hashcode = -1; - } - return (PyObject *)me; + PyObject *self; + if (date_new1(type, args, &self)) { + return self; } + int year; + int month; + int day; + if (PyArg_ParseTupleAndKeywords(args, kw, "iii", date_kws, &year, &month, &day)) { self = new_date_ex(year, month, day, type); } + else { + self = NULL; + } return self; } @@ -3860,6 +3887,28 @@ static PyGetSetDef time_getset[] = { * Constructors. */ +static int +check_time_state_args(PyObject *args) +{ + if (!(PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2)) { + return 0; + } + PyObject *state = PyTuple_GetItemRef(args, 0); + if (!PyBytes_Check(state)) { + goto fail; + } + if (PyBytes_GET_SIZE(state) != _PyDateTime_TIME_DATASIZE) { + goto fail; + } + unsigned char hours = (0x7F & ((unsigned char)(PyBytes_AS_STRING(state)[0]))); + Py_DECREF(state); + return (hours < 24); + +fail: + Py_DECREF(state); + return 0; +} + static char *time_kws[] = {"hour", "minute", "second", "microsecond", "tzinfo", "fold", NULL}; @@ -3876,22 +3925,21 @@ time_new(PyTypeObject *type, PyObject *args, PyObject *kw) int fold = 0; /* Check for invocation from pickle with __getstate__ state */ - if (PyTuple_GET_SIZE(args) >= 1 && - PyTuple_GET_SIZE(args) <= 2 && - PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) && - PyBytes_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE && - (0x7F & ((unsigned char) (PyBytes_AS_STRING(state)[0]))) < 24) - { + if (check_time_state_args(args)) { + state = PyTuple_GetItemRef(args, 0); PyDateTime_Time *me; char aware; if (PyTuple_GET_SIZE(args) == 2) { - tzinfo = PyTuple_GET_ITEM(args, 1); + tzinfo = PyTuple_GetItemRef(args, 1); if (check_tzinfo_subclass(tzinfo) < 0) { + Py_DECREF(tzinfo); + Py_DECREF(state); PyErr_SetString(PyExc_TypeError, "bad " "tzinfo state arg"); return NULL; } + Py_DECREF(tzinfo); } aware = (char)(tzinfo != Py_None); me = (PyDateTime_Time *) (type->tp_alloc(type, aware)); @@ -3913,6 +3961,7 @@ time_new(PyTypeObject *type, PyObject *args, PyObject *kw) me->fold = 0; } } + Py_DECREF(state); return (PyObject *)me; } @@ -4499,11 +4548,74 @@ static char *datetime_kws[] = { "microsecond", "tzinfo", "fold", NULL }; +/* Check for invocation from pickle with __getstate__ state */ +static PyObject * +datetime_new1(PyTypeObject *type, PyObject *args, PyObject **objp) +{ + if (!(PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2)) { + return 0; + } + + PyObject *state = PyTuple_GetItemRef(args, 0); + if (!(PyBytes_Check(state) + && PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE + && MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F))) { + Py_DECREF(state); + return 0; + } + + char aware; + + PyObject *tzinfo = Py_None; + if (PyTuple_GET_SIZE(args) == 2) { + tzinfo = PyTuple_GetItemRef(args, 1); + if (check_tzinfo_subclass(tzinfo) < 0) { + Py_DECREF(tzinfo); + Py_DECREF(state); + PyErr_SetString(PyExc_TypeError, "bad tzinfo state arg"); + *objp = NULL; + return -1; + } + Py_DECREF(tzinfo); + } + + aware = (char)(tzinfo != Py_None); + PyDateTime_DateTime *me = (PyDateTime_DateTime *)(type->tp_alloc(type , aware)); + if (me == NULL) { + Py_DECREF(state); + *objp = NULL; + return -1; + } + + char *pdata = PyBytes_AS_STRING(state); + memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE); + me->hashcode = -1; + me->hastzinfo = aware; + if (aware) { + Py_INCREF(tzinfo); + me->tzinfo = tzinfo; + } + if (pdata[2] & (1 << 7)) { + me->data[2] -= 128; + me->fold = 1; + } + else { + me->fold = 0; + } + + Py_DECREF(state); + *objp = (PyObject *)me; + return 1; +} + static PyObject * datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw) { - PyObject *self = NULL; - PyObject *state; + PyObject *self; + if (datetime_new1(type, args, &self)) { + return self; + } + int year; int month; int day; @@ -4514,54 +4626,16 @@ datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw) int fold = 0; PyObject *tzinfo = Py_None; - /* Check for invocation from pickle with __getstate__ state */ - if (PyTuple_GET_SIZE(args) >= 1 && - PyTuple_GET_SIZE(args) <= 2 && - PyBytes_Check(state = PyTuple_GET_ITEM(args, 0)) && - PyBytes_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE && - MONTH_IS_SANE(PyBytes_AS_STRING(state)[2] & 0x7F)) - { - PyDateTime_DateTime *me; - char aware; - - if (PyTuple_GET_SIZE(args) == 2) { - tzinfo = PyTuple_GET_ITEM(args, 1); - if (check_tzinfo_subclass(tzinfo) < 0) { - PyErr_SetString(PyExc_TypeError, "bad " - "tzinfo state arg"); - return NULL; - } - } - aware = (char)(tzinfo != Py_None); - me = (PyDateTime_DateTime *) (type->tp_alloc(type , aware)); - if (me != NULL) { - char *pdata = PyBytes_AS_STRING(state); - - memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE); - me->hashcode = -1; - me->hastzinfo = aware; - if (aware) { - Py_INCREF(tzinfo); - me->tzinfo = tzinfo; - } - if (pdata[2] & (1 << 7)) { - me->data[2] -= 128; - me->fold = 1; - } - else { - me->fold = 0; - } - } - return (PyObject *)me; - } - if (PyArg_ParseTupleAndKeywords(args, kw, "iii|iiiiO$i", datetime_kws, &year, &month, &day, &hour, &minute, &second, &usecond, &tzinfo, &fold)) { - self = new_datetime_ex2(year, month, day, + return new_datetime_ex2(year, month, day, hour, minute, second, usecond, tzinfo, fold, type); } + else { + return NULL; + } return self; } diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index eaccc26d241cec..02ecffd5099812 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -2145,8 +2145,10 @@ PyDecType_FromFloatExact(PyTypeObject *type, PyObject *v, if (n_d == NULL) { return NULL; } - n = PyTuple_GET_ITEM(n_d, 0); - d = PyTuple_GET_ITEM(n_d, 1); + n = PyTuple_GetItemRef(n_d, 0); + d = PyTuple_GetItemRef(n_d, 1); + Py_DECREF(n); + Py_DECREF(d); tmp = _py_long_bit_length(d, NULL); if (tmp == NULL) { @@ -2292,13 +2294,15 @@ dectuple_as_str(PyObject *dectuple) } /* sign */ - tmp = PyTuple_GET_ITEM(dectuple, 0); + tmp = PyTuple_GetItemRef(dectuple, 0); if (!PyLong_Check(tmp)) { + Py_DECREF(tmp); PyErr_SetString(PyExc_ValueError, "sign must be an integer with the value 0 or 1"); goto error; } sign = PyLong_AsLong(tmp); + Py_DECREF(tmp); if (sign == -1 && PyErr_Occurred()) { goto error; } @@ -2311,7 +2315,7 @@ dectuple_as_str(PyObject *dectuple) sign_special[1] = '\0'; /* exponent or encoding for a special number */ - tmp = PyTuple_GET_ITEM(dectuple, 2); + tmp = PyTuple_GetItemRef(dectuple, 2); if (PyUnicode_Check(tmp)) { /* special */ if (PyUnicode_CompareWithASCIIString(tmp, "F") == 0) { @@ -2325,6 +2329,7 @@ dectuple_as_str(PyObject *dectuple) strcat(sign_special, "sNaN"); } else { + Py_DECREF(tmp); PyErr_SetString(PyExc_ValueError, "string argument in the third position " "must be 'F', 'n' or 'N'"); @@ -2334,19 +2339,24 @@ dectuple_as_str(PyObject *dectuple) else { /* exponent */ if (!PyLong_Check(tmp)) { + Py_DECREF(tmp); PyErr_SetString(PyExc_ValueError, "exponent must be an integer"); goto error; } exp = PyLong_AsSsize_t(tmp); if (exp == -1 && PyErr_Occurred()) { + Py_DECREF(tmp); goto error; } } + Py_DECREF(tmp); /* coefficient */ - digits = sequence_as_tuple(PyTuple_GET_ITEM(dectuple, 1), PyExc_ValueError, + PyObject *arg = PyTuple_GetItemRef(dectuple, 1); + digits = sequence_as_tuple(arg, PyExc_ValueError, "coefficient must be a tuple of digits"); + Py_DECREF(arg); if (digits == NULL) { goto error; } @@ -2373,13 +2383,15 @@ dectuple_as_str(PyObject *dectuple) *cp++ = '0'; } for (i = 0; i < tsize; i++) { - tmp = PyTuple_GET_ITEM(digits, i); + tmp = PyTuple_GetItemRef(digits, i); if (!PyLong_Check(tmp)) { + Py_DECREF(tmp); PyErr_SetString(PyExc_ValueError, "coefficient must be a tuple of digits"); goto error; } l = PyLong_AsLong(tmp); + Py_DECREF(tmp); if (l == -1 && PyErr_Occurred()) { goto error; } @@ -3595,7 +3607,8 @@ PyDec_AsTuple(PyObject *dec, PyObject *dummy UNUSED) if (tmp == NULL) { goto out; } - PyTuple_SET_ITEM(coeff, i, tmp); + PyTuple_SetItemRef(coeff, i, tmp); + Py_DECREF(tmp); } } else { @@ -5676,7 +5689,8 @@ PyInit__decimal(void) /* add to signal tuple */ Py_INCREF(cm->ex); - PyTuple_SET_ITEM(SignalTuple, i, cm->ex); + PyTuple_SetItemRef(SignalTuple, i, cm->ex); + Py_DECREF(cm->ex); } /* diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 02781d5d892b99..119c9fdf4f82e3 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -1130,8 +1130,7 @@ _elementtree_Element_extend(ElementObject *self, PyObject *elements) } for (i = 0; i < PySequence_Fast_GET_SIZE(seq); i++) { - PyObject* element = PySequence_Fast_GET_ITEM(seq, i); - Py_INCREF(element); + PyObject* element = PySequence_Fast_GetItemRef(seq, i); if (!PyObject_TypeCheck(element, (PyTypeObject *)&Element_Type)) { PyErr_Format( PyExc_TypeError, @@ -1923,8 +1922,7 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value) /* replace the slice */ for (cur = start, i = 0; i < newlen; cur += step, i++) { - PyObject* element = PySequence_Fast_GET_ITEM(seq, i); - Py_INCREF(element); + PyObject* element = PySequence_Fast_GetItemRef(seq, i); self->extra->children[cur] = element; } @@ -3636,7 +3634,7 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self, } for (i = 0; i < PySequence_Fast_GET_SIZE(events_seq); ++i) { - PyObject *event_name_obj = PySequence_Fast_GET_ITEM(events_seq, i); + PyObject *event_name_obj = PySequence_Fast_GetItemRef(events_seq, i); const char *event_name = NULL; if (PyUnicode_Check(event_name_obj)) { event_name = PyUnicode_AsUTF8(event_name_obj); @@ -3644,12 +3642,12 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self, event_name = PyBytes_AS_STRING(event_name_obj); } if (event_name == NULL) { + Py_DECREF(event_name_obj); Py_DECREF(events_seq); PyErr_Format(PyExc_ValueError, "invalid events sequence"); return NULL; } - Py_INCREF(event_name_obj); if (strcmp(event_name, "start") == 0) { Py_XSETREF(target->start_event_obj, event_name_obj); } else if (strcmp(event_name, "end") == 0) { diff --git a/Modules/_json.c b/Modules/_json.c index 5a9464e34fb7f3..c54de0a3e389f5 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -377,8 +377,10 @@ _build_rval_index_tuple(PyObject *rval, Py_ssize_t idx) { Py_DECREF(rval); return NULL; } - PyTuple_SET_ITEM(tpl, 0, rval); - PyTuple_SET_ITEM(tpl, 1, pyidx); + PyTuple_SetItemRef(tpl, 0, rval); + Py_DECREF(rval); + PyTuple_SetItemRef(tpl, 1, pyidx); + Py_DECREF(pyidx); return tpl; } @@ -1622,13 +1624,13 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, PyErr_SetString(PyExc_ValueError, "items must return 2-tuples"); goto bail; } - key = PyTuple_GET_ITEM(item, 0); + key = PyTuple_GetItemRef(item, 0); if (PyUnicode_Check(key)) { - Py_INCREF(key); kstr = key; } else if (PyFloat_Check(key)) { kstr = encoder_encode_float(s, key); + Py_DECREF(key); if (kstr == NULL) goto bail; } @@ -1636,16 +1638,19 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, /* This must come before the PyLong_Check because True and False are also 1 and 0.*/ kstr = _encoded_const(key); + Py_DECREF(key); if (kstr == NULL) goto bail; } else if (PyLong_Check(key)) { kstr = PyLong_Type.tp_str(key); + Py_DECREF(key); if (kstr == NULL) { goto bail; } } else if (s->skipkeys) { + Py_DECREF(key); Py_DECREF(item); continue; } @@ -1653,6 +1658,7 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, PyErr_Format(PyExc_TypeError, "keys must be str, int, float, bool or None, " "not %.100s", key->ob_type->tp_name); + Py_DECREF(key); goto bail; } @@ -1673,9 +1679,12 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, if (_PyAccu_Accumulate(acc, s->key_separator)) goto bail; - value = PyTuple_GET_ITEM(item, 1); - if (encoder_listencode_obj(s, acc, value, indent_level)) + value = PyTuple_GetItemRef(item, 1); + if (encoder_listencode_obj(s, acc, value, indent_level)) { + Py_DECREF(value); goto bail; + } + Py_DECREF(value); idx += 1; Py_DECREF(item); } @@ -1763,13 +1772,16 @@ encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, */ } for (i = 0; i < PySequence_Fast_GET_SIZE(s_fast); i++) { - PyObject *obj = PySequence_Fast_GET_ITEM(s_fast, i); if (i) { if (_PyAccu_Accumulate(acc, s->item_separator)) goto bail; } - if (encoder_listencode_obj(s, acc, obj, indent_level)) + PyObject *obj = PySequence_Fast_GetItemRef(s_fast, i); + if (encoder_listencode_obj(s, acc, obj, indent_level)) { + Py_DECREF(obj); goto bail; + } + Py_DECREF(obj); } if (ident != NULL) { if (PyDict_DelItem(s->markers, ident)) diff --git a/Modules/_pickle.c b/Modules/_pickle.c index c8f4e86fb1416b..fd73d84a5ce503 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -572,8 +572,10 @@ Pdata_poptuple(Pdata *self, Py_ssize_t start) tuple = PyTuple_New(len); if (tuple == NULL) return NULL; - for (i = start, j = 0; j < len; i++, j++) - PyTuple_SET_ITEM(tuple, j, self->data[i]); + for (i = start, j = 0; j < len; i++, j++) { + PyTuple_SetItemRef(tuple, j, self->data[i]); + Py_DECREF(self->data[i]); + } _Py_SET_SIZE(self, start); return tuple; @@ -2467,10 +2469,11 @@ store_tuple_elements(PicklerObject *self, PyObject *t, Py_ssize_t len) assert(PyTuple_Size(t) == len); for (i = 0; i < len; i++) { - PyObject *element = PyTuple_GET_ITEM(t, i); - + PyObject *element = PyTuple_GetItemRef(t, i); if (element == NULL) return -1; + /* XXX: pass a borrowed reference to save() */ + Py_DECREF(element); if (save(self, element, 0) < 0) return -1; } @@ -2852,9 +2855,14 @@ batch_dict(PicklerObject *self, PyObject *iter) "iterator must return 2-tuples"); return -1; } - i = save(self, PyTuple_GET_ITEM(obj, 0), 0); - if (i >= 0) - i = save(self, PyTuple_GET_ITEM(obj, 1), 0); + PyObject *arg = PyTuple_GetItemRef(obj, 0); + i = save(self, arg, 0); + Py_DECREF(arg); + if (i >= 0) { + arg = PyTuple_GetItemRef(obj, 1); + i = save(self, arg, 0); + Py_DECREF(arg); + } Py_DECREF(obj); if (i < 0) return -1; @@ -2888,10 +2896,20 @@ batch_dict(PicklerObject *self, PyObject *iter) goto error; /* Only one item to write */ - if (save(self, PyTuple_GET_ITEM(firstitem, 0), 0) < 0) + PyObject *arg = PyTuple_GetItemRef(firstitem, 0); + if (save(self, arg, 0) < 0) { + Py_DECREF(arg); goto error; - if (save(self, PyTuple_GET_ITEM(firstitem, 1), 0) < 0) + } + Py_DECREF(arg); + + arg = PyTuple_GetItemRef(firstitem, 1); + if (save(self, arg, 0) < 0) { + Py_DECREF(arg); goto error; + } + Py_DECREF(arg); + if (_Pickler_Write(self, &setitem_op, 1) < 0) goto error; Py_CLEAR(firstitem); @@ -2904,10 +2922,19 @@ batch_dict(PicklerObject *self, PyObject *iter) if (_Pickler_Write(self, &mark_op, 1) < 0) goto error; - if (save(self, PyTuple_GET_ITEM(firstitem, 0), 0) < 0) + PyObject *arg = PyTuple_GetItemRef(firstitem, 0); + if (save(self, arg, 0) < 0) { + Py_DECREF(arg); goto error; - if (save(self, PyTuple_GET_ITEM(firstitem, 1), 0) < 0) + } + Py_DECREF(arg); + + arg = PyTuple_GetItemRef(firstitem, 1); + if (save(self, arg, 0) < 0) { + Py_DECREF(arg); goto error; + } + Py_DECREF(arg); Py_CLEAR(firstitem); n = 1; @@ -2918,9 +2945,15 @@ batch_dict(PicklerObject *self, PyObject *iter) "iterator must return 2-tuples"); goto error; } - if (save(self, PyTuple_GET_ITEM(obj, 0), 0) < 0 || - save(self, PyTuple_GET_ITEM(obj, 1), 0) < 0) + PyObject *arg0 = PyTuple_GetItemRef(obj, 0); + PyObject *arg1 = PyTuple_GetItemRef(obj, 1); + if (save(self, arg0, 0) < 0 || save(self, arg1, 0) < 0) { + Py_DECREF(arg0); + Py_DECREF(arg1); goto error; + } + Py_DECREF(arg0); + Py_DECREF(arg1); Py_CLEAR(obj); n += 1; @@ -3248,10 +3281,12 @@ fix_imports(PyObject **module_name, PyObject **global_name) Py_TYPE(item)->tp_name); return -1; } - fixed_module_name = PyTuple_GET_ITEM(item, 0); - fixed_global_name = PyTuple_GET_ITEM(item, 1); + fixed_module_name = PyTuple_GetItemRef(item, 0); + fixed_global_name = PyTuple_GetItemRef(item, 1); if (!PyUnicode_Check(fixed_module_name) || !PyUnicode_Check(fixed_global_name)) { + Py_DECREF(fixed_module_name); + Py_DECREF(fixed_global_name); PyErr_Format(PyExc_RuntimeError, "_compat_pickle.REVERSE_NAME_MAPPING values " "should be pairs of str, not (%.200s, %.200s)", @@ -3262,8 +3297,6 @@ fix_imports(PyObject **module_name, PyObject **global_name) Py_CLEAR(*module_name); Py_CLEAR(*global_name); - Py_INCREF(fixed_module_name); - Py_INCREF(fixed_global_name); *module_name = fixed_module_name; *global_name = fixed_global_name; return 0; @@ -3740,27 +3773,36 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) return -1; } - cls = PyTuple_GET_ITEM(argtup, 0); + cls = PyTuple_GetItemRef(argtup, 0); if (!PyType_Check(cls)) { + Py_DECREF(cls); PyErr_Format(st->PicklingError, "first item from NEWOBJ_EX argument tuple must " "be a class, not %.200s", Py_TYPE(cls)->tp_name); return -1; } - args = PyTuple_GET_ITEM(argtup, 1); + args = PyTuple_GetItemRef(argtup, 1); if (!PyTuple_Check(args)) { + Py_DECREF(cls); + Py_DECREF(args); PyErr_Format(st->PicklingError, "second item from NEWOBJ_EX argument tuple must " "be a tuple, not %.200s", Py_TYPE(args)->tp_name); return -1; } - kwargs = PyTuple_GET_ITEM(argtup, 2); + kwargs = PyTuple_GetItemRef(argtup, 2); if (!PyDict_Check(kwargs)) { + Py_DECREF(cls); + Py_DECREF(args); + Py_DECREF(kwargs); PyErr_Format(st->PicklingError, "third item from NEWOBJ_EX argument tuple must " "be a dict, not %.200s", Py_TYPE(kwargs)->tp_name); return -1; } + Py_DECREF(cls); + Py_DECREF(args); + Py_DECREF(kwargs); if (self->proto >= 4) { if (save(self, cls, 0) < 0 || @@ -3785,13 +3827,13 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) Py_DECREF(newargs); return -1; } - PyTuple_SET_ITEM(newargs, 0, cls_new); - Py_INCREF(cls); - PyTuple_SET_ITEM(newargs, 1, cls); + PyTuple_SetItemRef(newargs, 0, cls_new); + Py_DECREF(cls_new); + PyTuple_SetItemRef(newargs, 1, cls); for (i = 0; i < PyTuple_GET_SIZE(args); i++) { - PyObject *item = PyTuple_GET_ITEM(args, i); - Py_INCREF(item); - PyTuple_SET_ITEM(newargs, i + 2, item); + PyObject *item = PyTuple_GetItemRef(args, i); + PyTuple_SetItemRef(newargs, i + 2, item); + Py_DECREF(item); } callable = PyObject_Call(st->partial, newargs, kwargs); @@ -3828,12 +3870,14 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) return -1; } - cls = PyTuple_GET_ITEM(argtup, 0); + cls = PyTuple_GetItemRef(argtup, 0); if (!PyType_Check(cls)) { + Py_DECREF(cls); PyErr_SetString(st->PicklingError, "args[0] from " "__newobj__ args is not a type"); return -1; } + Py_DECREF(cls); if (obj != NULL) { obj_class = get_class(obj); @@ -4474,10 +4518,11 @@ _pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self) Py_DECREF(reduce_value); return NULL; } - PyTuple_SET_ITEM(dict_args, 0, contents); - Py_INCREF((PyObject *)&PyDict_Type); - PyTuple_SET_ITEM(reduce_value, 0, (PyObject *)&PyDict_Type); - PyTuple_SET_ITEM(reduce_value, 1, dict_args); + PyTuple_SetItemRef(dict_args, 0, contents); + Py_DECREF(contents); + PyTuple_SetItemRef(reduce_value, 0, (PyObject *)&PyDict_Type); + PyTuple_SetItemRef(reduce_value, 1, dict_args); + Py_DECREF(dict_args); return reduce_value; } @@ -4600,12 +4645,17 @@ Pickler_set_memo(PicklerObject *self, PyObject *obj) "'memo' values must be 2-item tuples"); goto error; } - memo_id = PyLong_AsSsize_t(PyTuple_GET_ITEM(value, 0)); + PyObject *arg = PyTuple_GetItemRef(value, 0); + memo_id = PyLong_AsSsize_t(arg); + Py_DECREF(arg); if (memo_id == -1 && PyErr_Occurred()) goto error; - memo_obj = PyTuple_GET_ITEM(value, 1); - if (PyMemoTable_Set(new_memo, memo_obj, memo_id) < 0) + memo_obj = PyTuple_GetItemRef(value, 1); + if (PyMemoTable_Set(new_memo, memo_obj, memo_id) < 0) { + Py_DECREF(memo_obj); goto error; + } + Py_DECREF(memo_obj); } } else { @@ -5856,9 +5906,17 @@ load_extension(UnpicklerObject *self, int nbytes) /* Since the extension registry is manipulable via Python code, * confirm that pair is really a 2-tuple of strings. */ - if (!PyTuple_Check(pair) || PyTuple_Size(pair) != 2 || - !PyUnicode_Check(module_name = PyTuple_GET_ITEM(pair, 0)) || - !PyUnicode_Check(class_name = PyTuple_GET_ITEM(pair, 1))) { + int invalid = (!PyTuple_Check(pair) || PyTuple_Size(pair) != 2); + if (!invalid) { + module_name = PyTuple_GetItemRef(pair, 0); + class_name = PyTuple_GetItemRef(pair, 1); + if (!PyUnicode_Check(module_name) || !PyUnicode_Check(class_name)) { + invalid = 1; + } + } + if (invalid) { + Py_DECREF(module_name); + Py_DECREF(class_name); Py_DECREF(py_code); PyErr_Format(PyExc_ValueError, "_inverted_registry[%ld] " "isn't a 2-tuple of strings", code); @@ -5866,6 +5924,8 @@ load_extension(UnpicklerObject *self, int nbytes) } /* Load the object. */ obj = find_class(self, module_name, class_name); + Py_DECREF(module_name); + Py_DECREF(class_name); if (obj == NULL) { Py_DECREF(py_code); return -1; @@ -6210,10 +6270,8 @@ load_build(UnpicklerObject *self) if (PyTuple_Check(state) && PyTuple_GET_SIZE(state) == 2) { PyObject *tmp = state; - state = PyTuple_GET_ITEM(tmp, 0); - slotstate = PyTuple_GET_ITEM(tmp, 1); - Py_INCREF(state); - Py_INCREF(slotstate); + state = PyTuple_GetItemRef(tmp, 0); + slotstate = PyTuple_GetItemRef(tmp, 1); Py_DECREF(tmp); } else @@ -6590,10 +6648,12 @@ _pickle_Unpickler_find_class_impl(UnpicklerObject *self, "2-tuples, not %.200s", Py_TYPE(item)->tp_name); return NULL; } - module_name = PyTuple_GET_ITEM(item, 0); - global_name = PyTuple_GET_ITEM(item, 1); + module_name = PyTuple_GetItemRef(item, 0); + global_name = PyTuple_GetItemRef(item, 1); if (!PyUnicode_Check(module_name) || !PyUnicode_Check(global_name)) { + Py_DECREF(module_name); + Py_DECREF(global_name); PyErr_Format(PyExc_RuntimeError, "_compat_pickle.NAME_MAPPING values should be " "pairs of str, not (%.200s, %.200s)", @@ -6601,6 +6661,8 @@ _pickle_Unpickler_find_class_impl(UnpicklerObject *self, Py_TYPE(global_name)->tp_name); return NULL; } + Py_DECREF(module_name); + Py_DECREF(global_name); } else if (PyErr_Occurred()) { return NULL; @@ -6898,10 +6960,11 @@ _pickle_UnpicklerMemoProxy___reduce___impl(UnpicklerMemoProxyObject *self) Py_DECREF(reduce_value); return NULL; } - PyTuple_SET_ITEM(constructor_args, 0, contents); - Py_INCREF((PyObject *)&PyDict_Type); - PyTuple_SET_ITEM(reduce_value, 0, (PyObject *)&PyDict_Type); - PyTuple_SET_ITEM(reduce_value, 1, constructor_args); + PyTuple_SetItemRef(constructor_args, 0, contents); + Py_DECREF(contents); + PyTuple_SetItemRef(reduce_value, 0, (PyObject *)&PyDict_Type); + PyTuple_SetItemRef(reduce_value, 1, constructor_args); + Py_DECREF(constructor_args); return reduce_value; } diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index 0150fcb0970c0e..1fd2e55bf341b2 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -114,7 +114,8 @@ _sanity_check_python_fd_sequence(PyObject *fd_sequence) Py_ssize_t seq_idx; long prev_fd = -1; for (seq_idx = 0; seq_idx < PyTuple_GET_SIZE(fd_sequence); ++seq_idx) { - PyObject* py_fd = PyTuple_GET_ITEM(fd_sequence, seq_idx); + PyObject* py_fd = PyTuple_GetItemRef(fd_sequence, seq_idx); + Py_DECREF(py_fd); long iter_fd; if (!PyLong_Check(py_fd)) { return 1; @@ -141,7 +142,9 @@ _is_fd_in_sorted_fd_sequence(int fd, PyObject *fd_sequence) return 0; do { long middle = (search_min + search_max) / 2; - long middle_fd = PyLong_AsLong(PyTuple_GET_ITEM(fd_sequence, middle)); + PyObject *fdobj = PyTuple_GetItemRef(fd_sequence, middle); + long middle_fd = PyLong_AsLong(fdobj); + Py_DECREF(fdobj); if (fd == middle_fd) return 1; if (fd > middle_fd) @@ -159,8 +162,9 @@ make_inheritable(PyObject *py_fds_to_keep, int errpipe_write) len = PyTuple_GET_SIZE(py_fds_to_keep); for (i = 0; i < len; ++i) { - PyObject* fdobj = PyTuple_GET_ITEM(py_fds_to_keep, i); + PyObject* fdobj = PyTuple_GetItemRef(py_fds_to_keep, i); long fd = PyLong_AsLong(fdobj); + Py_DECREF(fdobj); assert(!PyErr_Occurred()); assert(0 <= fd && fd <= INT_MAX); if (fd == errpipe_write) { @@ -222,8 +226,9 @@ _close_fds_by_brute_force(long start_fd, PyObject *py_fds_to_keep) /* As py_fds_to_keep is sorted we can loop through the list closing * fds in between any in the keep list falling within our range. */ for (keep_seq_idx = 0; keep_seq_idx < num_fds_to_keep; ++keep_seq_idx) { - PyObject* py_keep_fd = PyTuple_GET_ITEM(py_fds_to_keep, keep_seq_idx); + PyObject* py_keep_fd = PyTuple_GetItemRef(py_fds_to_keep, keep_seq_idx); int keep_fd = PyLong_AsLong(py_keep_fd); + Py_DECREF(py_keep_fd); if (keep_fd < start_fd) continue; for (fd_num = start_fd; fd_num < keep_fd; ++fd_num) { @@ -632,10 +637,14 @@ subprocess_fork_exec(PyObject* self, PyObject *args) PyErr_SetString(PyExc_RuntimeError, "args changed during iteration"); goto cleanup; } - borrowed_arg = PySequence_Fast_GET_ITEM(fast_args, arg_num); - if (PyUnicode_FSConverter(borrowed_arg, &converted_arg) == 0) + PyObject *arg = PySequence_Fast_GetItemRef(fast_args, arg_num); + if (PyUnicode_FSConverter(arg, &converted_arg) == 0) { + Py_DECREF(arg); goto cleanup; - PyTuple_SET_ITEM(converted_args, arg_num, converted_arg); + } + Py_DECREF(arg); + PyTuple_SetItemRef(converted_args, arg_num, converted_arg); + Py_DECREF(converted_arg); } argv = _PySequence_BytesToCharpArray(converted_args); diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index dae9d42fcb225c..428d56a0372e51 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -332,12 +332,14 @@ random_getstate(RandomObject *self, PyObject *Py_UNUSED(ignored)) element = PyLong_FromUnsignedLong(self->state[i]); if (element == NULL) goto Fail; - PyTuple_SET_ITEM(state, i, element); + PyTuple_SetItemRef(state, i, element); + Py_DECREF(element); } element = PyLong_FromLong((long)(self->index)); if (element == NULL) goto Fail; - PyTuple_SET_ITEM(state, i, element); + PyTuple_SetItemRef(state, i, element); + Py_DECREF(element); return state; Fail: @@ -352,6 +354,7 @@ random_setstate(RandomObject *self, PyObject *state) unsigned long element; long index; uint32_t new_state[N]; + PyObject *item; if (!PyTuple_Check(state)) { PyErr_SetString(PyExc_TypeError, @@ -365,13 +368,17 @@ random_setstate(RandomObject *self, PyObject *state) } for (i=0; i N) { diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 5b15d1d930a398..f1043d52ff886c 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -585,7 +585,8 @@ PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_ return NULL; } - PyTuple_SetItem(args, i, cur_py_value); + PyTuple_SetItemRef(args, i, cur_py_value); + Py_DECREF(cur_py_value); } @@ -1465,8 +1466,8 @@ pysqlite_connection_iterdump(pysqlite_Connection* self, PyObject* args) if (!args) { goto finally; } - Py_INCREF(self); - PyTuple_SetItem(args, 0, (PyObject*)self); + PyTuple_SetItemRef(args, 0, (PyObject *)self); + retval = PyObject_CallObject(pyfn_iterdump, args); finally: diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index c62ad5d64eecc1..cd5a32c8ec1097 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -330,10 +330,10 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) } if (converted) { - PyTuple_SetItem(row, i, converted); + PyTuple_SetItemRef(row, i, converted); + Py_DECREF(converted); } else { - Py_INCREF(Py_None); - PyTuple_SetItem(row, i, Py_None); + PyTuple_SetItemRef(row, i, Py_None); } } @@ -468,8 +468,7 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* if (!func_args) { goto error; } - Py_INCREF(operation); - if (PyTuple_SetItem(func_args, 0, operation) != 0) { + if (PyTuple_SetItemRef(func_args, 0, operation) != 0) { goto error; } @@ -560,14 +559,17 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* if (!descriptor) { goto error; } - PyTuple_SetItem(descriptor, 0, _pysqlite_build_column_name(sqlite3_column_name(self->statement->st, i))); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 1, Py_None); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 2, Py_None); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 3, Py_None); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 4, Py_None); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 5, Py_None); - Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 6, Py_None); - PyTuple_SetItem(self->description, i, descriptor); + PyObject *name = _pysqlite_build_column_name(sqlite3_column_name(self->statement->st, i)); + PyTuple_SetItemRef(descriptor, 0, name); + Py_DECREF(name); + PyTuple_SetItemRef(descriptor, 1, Py_None); + PyTuple_SetItemRef(descriptor, 2, Py_None); + PyTuple_SetItemRef(descriptor, 3, Py_None); + PyTuple_SetItemRef(descriptor, 4, Py_None); + PyTuple_SetItemRef(descriptor, 5, Py_None); + PyTuple_SetItemRef(descriptor, 6, Py_None); + PyTuple_SetItemRef(self->description, i, descriptor); + Py_DECREF(descriptor); } } diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c index 2fc26a8822dcea..53b68a7076a4f4 100644 --- a/Modules/_sqlite/row.c +++ b/Modules/_sqlite/row.c @@ -71,9 +71,7 @@ pysqlite_row_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) PyObject* pysqlite_row_item(pysqlite_Row* self, Py_ssize_t idx) { - PyObject* item = PyTuple_GetItem(self->data, idx); - Py_XINCREF(item); - return item; + return PyTuple_GetItemRef(self->data, idx); } PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx) @@ -94,9 +92,7 @@ PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx) return NULL; if (_idx < 0) _idx += PyTuple_GET_SIZE(self->data); - item = PyTuple_GetItem(self->data, _idx); - Py_XINCREF(item); - return item; + return PyTuple_GetItemRef(self->data, _idx); } else if (PyUnicode_Check(idx)) { key = PyUnicode_AsUTF8(idx); if (key == NULL) @@ -106,8 +102,10 @@ PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx) for (i = 0; i < nitems; i++) { PyObject *obj; - obj = PyTuple_GET_ITEM(self->description, i); - obj = PyTuple_GET_ITEM(obj, 0); + obj = PyTuple_GetItemRef(self->description, i); + Py_DECREF(obj); + obj = PyTuple_GetItemRef(obj, 0); + Py_DECREF(obj); compare_key = PyUnicode_AsUTF8(obj); if (!compare_key) { return NULL; @@ -131,9 +129,7 @@ PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx) if ((*p1 == (char)0) && (*p2 == (char)0)) { /* found item */ - item = PyTuple_GetItem(self->data, i); - Py_INCREF(item); - return item; + return PyTuple_GetItemRef(self->data, i); } } @@ -167,10 +163,15 @@ PyObject* pysqlite_row_keys(pysqlite_Row* self, PyObject *Py_UNUSED(ignored)) nitems = PyTuple_Size(self->description); for (i = 0; i < nitems; i++) { - if (PyList_Append(list, PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->description, i), 0)) != 0) { + PyObject *arg0 = PyTuple_GetItemRef(self->description, i); + PyObject *arg = PyTuple_GetItemRef(arg0, 0); + Py_DECREF(arg0); + if (PyList_Append(list, arg) != 0) { + Py_DECREF(arg); Py_DECREF(list); return NULL; } + Py_DECREF(arg); } return list; diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index 38690884227e68..d4564d0bdd730f 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -235,8 +235,7 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para } for (i = 0; i < num_params; i++) { if (PyTuple_CheckExact(parameters)) { - current_param = PyTuple_GET_ITEM(parameters, i); - Py_XINCREF(current_param); + current_param = PyTuple_GetItemRef(parameters, i); } else if (PyList_CheckExact(parameters)) { current_param = PyList_GET_ITEM(parameters, i); Py_XINCREF(current_param); diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 2bce4816d26fe7..067f113d3f9ed1 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1266,14 +1266,16 @@ _get_peer_alt_names (X509 *certificate) { Py_DECREF(t); goto fail; } - PyTuple_SET_ITEM(t, 0, v); + PyTuple_SetItemRef(t, 0, v); + Py_DECREF(v); v = _create_tuple_for_X509_NAME (name->d.dirn); if (v == NULL) { Py_DECREF(t); goto fail; } - PyTuple_SET_ITEM(t, 1, v); + PyTuple_SetItemRef(t, 1, v); + Py_DECREF(v); break; case GEN_EMAIL: @@ -1302,14 +1304,16 @@ _get_peer_alt_names (X509 *certificate) { Py_DECREF(t); goto fail; } - PyTuple_SET_ITEM(t, 0, v); + PyTuple_SetItemRef(t, 0, v); + Py_DECREF(v); v = PyUnicode_FromStringAndSize((char *)ASN1_STRING_data(as), ASN1_STRING_length(as)); if (v == NULL) { Py_DECREF(t); goto fail; } - PyTuple_SET_ITEM(t, 1, v); + PyTuple_SetItemRef(t, 1, v); + Py_DECREF(v); break; case GEN_RID: @@ -1322,7 +1326,8 @@ _get_peer_alt_names (X509 *certificate) { Py_DECREF(t); goto fail; } - PyTuple_SET_ITEM(t, 0, v); + PyTuple_SetItemRef(t, 0, v); + Py_DECREF(v); len = i2t_ASN1_OBJECT(buf, sizeof(buf)-1, name->d.rid); if (len < 0) { @@ -1338,7 +1343,8 @@ _get_peer_alt_names (X509 *certificate) { Py_DECREF(t); goto fail; } - PyTuple_SET_ITEM(t, 1, v); + PyTuple_SetItemRef(t, 1, v); + Py_DECREF(v); break; default: @@ -1381,14 +1387,16 @@ _get_peer_alt_names (X509 *certificate) { Py_DECREF(t); goto fail; } - PyTuple_SET_ITEM(t, 0, v); + PyTuple_SetItemRef(t, 0, v); + Py_DECREF(v); v = PyUnicode_FromStringAndSize((vptr + 1), (len - (vptr - buf + 1))); if (v == NULL) { Py_DECREF(t); goto fail; } - PyTuple_SET_ITEM(t, 1, v); + PyTuple_SetItemRef(t, 1, v); + Py_DECREF(v); break; } @@ -1819,30 +1827,31 @@ cipher_to_tuple(const SSL_CIPHER *cipher) cipher_name = SSL_CIPHER_get_name(cipher); if (cipher_name == NULL) { - Py_INCREF(Py_None); - PyTuple_SET_ITEM(retval, 0, Py_None); + PyTuple_SetItemRef(retval, 0, Py_None); } else { v = PyUnicode_FromString(cipher_name); if (v == NULL) goto fail; - PyTuple_SET_ITEM(retval, 0, v); + PyTuple_SetItemRef(retval, 0, v); + Py_DECREF(v); } cipher_protocol = SSL_CIPHER_get_version(cipher); if (cipher_protocol == NULL) { - Py_INCREF(Py_None); - PyTuple_SET_ITEM(retval, 1, Py_None); + PyTuple_SetItemRef(retval, 1, Py_None); } else { v = PyUnicode_FromString(cipher_protocol); if (v == NULL) goto fail; - PyTuple_SET_ITEM(retval, 1, v); + PyTuple_SetItemRef(retval, 1, v); + Py_DECREF(v); } v = PyLong_FromLong(SSL_CIPHER_get_bits(cipher, NULL)); if (v == NULL) goto fail; - PyTuple_SET_ITEM(retval, 2, v); + PyTuple_SetItemRef(retval, 2, v); + Py_DECREF(v); return retval; @@ -5339,12 +5348,12 @@ _ssl_enum_certificates_impl(PyObject *module, const char *store_name) Py_CLEAR(result); break; } - PyTuple_SET_ITEM(tup, 0, cert); - cert = NULL; - PyTuple_SET_ITEM(tup, 1, enc); - enc = NULL; - PyTuple_SET_ITEM(tup, 2, keyusage); - keyusage = NULL; + PyTuple_SetItemRef(tup, 0, cert); + Py_CLEAR(cert); + PyTuple_SetItemRef(tup, 1, enc); + Py_CLEAR(enc); + PyTuple_SetItemRef(tup, 2, keyusage); + Py_CLEAR(keyusage); if (PyList_Append(result, tup) < 0) { Py_CLEAR(result); break; @@ -5418,10 +5427,10 @@ _ssl_enum_crls_impl(PyObject *module, const char *store_name) Py_CLEAR(result); break; } - PyTuple_SET_ITEM(tup, 0, crl); - crl = NULL; - PyTuple_SET_ITEM(tup, 1, enc); - enc = NULL; + PyTuple_SetItemRef(tup, 0, crl); + Py_CLEAR(crl; + PyTuple_SetItemRef(tup, 1, enc); + Py_CLEAR(enc); if (PyList_Append(result, tup) < 0) { Py_CLEAR(result); diff --git a/Modules/_struct.c b/Modules/_struct.c index d2dc66536f8616..d9bee15694b8ff 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -1503,7 +1503,8 @@ s_unpack_internal(PyStructObject *soself, const char *startfrom) { } if (v == NULL) goto fail; - PyTuple_SET_ITEM(result, i++, v); + PyTuple_SetItemRef(result, i++, v); + Py_DECREF(v); res += code->size; } } diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index 010fba6ef8368c..afce8d50189377 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -337,9 +337,11 @@ pack_from_list(PyObject *obj, PyObject *items, PyObject *format, offset = NULL; for (i = 0; i < nitems; i++) { /* Loop invariant: args[j] are borrowed references or NULL. */ - PyTuple_SET_ITEM(args, 0, obj); - for (j = 1; j < 2+nmemb; j++) - PyTuple_SET_ITEM(args, j, NULL); + PyTuple_SetItemRef(args, 0, obj); + Py_DECREF(obj); + for (j = 1; j < 2+nmemb; j++) { + PyTuple_SetItemRef(args, j, NULL); + } Py_XDECREF(offset); offset = PyLong_FromSsize_t(i*itemsize); @@ -347,21 +349,28 @@ pack_from_list(PyObject *obj, PyObject *items, PyObject *format, ret = -1; break; } - PyTuple_SET_ITEM(args, 1, offset); + PyTuple_SetItemRef(args, 1, offset); + Py_DECREF(offset); - item = PySequence_Fast_GET_ITEM(items, i); + item = PySequence_Fast_GetItemRef(items, i); if ((PyBytes_Check(item) || PyLong_Check(item) || PyFloat_Check(item)) && nmemb == 1) { - PyTuple_SET_ITEM(args, 2, item); + PyTuple_SetItemRef(args, 2, item); + Py_DECREF(item); + Py_DECREF(item); } else if ((PyList_Check(item) || PyTuple_Check(item)) && PySequence_Length(item) == nmemb) { for (j = 0; j < nmemb; j++) { - tmp = PySequence_Fast_GET_ITEM(item, j); - PyTuple_SET_ITEM(args, 2+j, tmp); + tmp = PySequence_Fast_GetItemRef(item, j); + PyTuple_SetItemRef(args, 2+j, tmp); + Py_DECREF(tmp); + Py_DECREF(tmp); } + Py_DECREF(item); } else { + Py_DECREF(item); PyErr_SetString(PyExc_ValueError, "mismatch between initializer element and format string"); ret = -1; @@ -379,8 +388,7 @@ pack_from_list(PyObject *obj, PyObject *items, PyObject *format, Py_INCREF(obj); /* args[0] */ /* args[1]: offset is either NULL or should be dealloc'd */ for (i = 2; i < 2+nmemb; i++) { - tmp = PyTuple_GET_ITEM(args, i); - Py_XINCREF(tmp); + tmp = PyTuple_GetItemRef(args, i); } Py_DECREF(args); @@ -429,18 +437,23 @@ pack_single(char *ptr, PyObject *item, const char *fmt, Py_ssize_t itemsize) if (args == NULL) goto out; - PyTuple_SET_ITEM(args, 0, mview); - PyTuple_SET_ITEM(args, 1, zero); + PyTuple_SetItemRef(args, 0, mview); + Py_DECREF(mview); + PyTuple_SetItemRef(args, 1, zero); + Py_DECREF(zero); if ((PyBytes_Check(item) || PyLong_Check(item) || PyFloat_Check(item)) && nmemb == 1) { - PyTuple_SET_ITEM(args, 2, item); + PyTuple_SetItemRef(args, 2, item); + Py_DECREF(item); } else if ((PyList_Check(item) || PyTuple_Check(item)) && PySequence_Length(item) == nmemb) { for (i = 0; i < nmemb; i++) { - x = PySequence_Fast_GET_ITEM(item, i); - PyTuple_SET_ITEM(args, 2+i, x); + x = PySequence_Fast_GetItemRef(item, i); + PyTuple_SetItemRef(args, 2+i, x); + Py_DECREF(x); + Py_DECREF(x); } } else { @@ -457,8 +470,10 @@ pack_single(char *ptr, PyObject *item, const char *fmt, Py_ssize_t itemsize) args_out: - for (i = 0; i < 2+nmemb; i++) - Py_XINCREF(PyTuple_GET_ITEM(args, i)); + for (i = 0; i < 2+nmemb; i++) { + /* increment the reference counter */ + PyTuple_GetItemRef(args, i); + } Py_XDECREF(args); out: Py_XDECREF(pack_into); @@ -595,8 +610,7 @@ unpack_single(char *ptr, const char *fmt, Py_ssize_t itemsize) return NULL; if (PyTuple_GET_SIZE(x) == 1) { - PyObject *tmp = PyTuple_GET_ITEM(x, 0); - Py_INCREF(tmp); + PyObject *tmp = PyTuple_GetItemRef(x, 0); Py_DECREF(x); return tmp; } @@ -624,8 +638,7 @@ unpack_rec(PyObject *unpack_from, char *ptr, PyObject *mview, char *item, if (x == NULL) return NULL; if (PyTuple_GET_SIZE(x) == 1) { - PyObject *tmp = PyTuple_GET_ITEM(x, 0); - Py_INCREF(tmp); + PyObject *tmp = PyTuple_GetItemRef(x, 0); Py_DECREF(x); return tmp; } @@ -858,8 +871,9 @@ seq_as_ssize_array(PyObject *seq, Py_ssize_t len, int is_shape) } for (i = 0; i < len; i++) { - PyObject *tmp = PySequence_Fast_GET_ITEM(seq, i); + PyObject *tmp = PySequence_Fast_GetItemRef(seq, i); if (!PyLong_Check(tmp)) { + Py_DECREF(tmp); PyErr_Format(PyExc_ValueError, "elements of %s must be integers", is_shape ? "shape" : "strides"); @@ -867,6 +881,7 @@ seq_as_ssize_array(PyObject *seq, Py_ssize_t len, int is_shape) return NULL; } x = PyLong_AsSsize_t(tmp); + Py_DECREF(tmp); if (PyErr_Occurred()) { PyMem_Free(dest); return NULL; @@ -1836,11 +1851,16 @@ ndarray_subscript(NDArrayObject *self, PyObject *key) n = PyTuple_GET_SIZE(tuple); for (i = 0; i < n; i++) { - key = PyTuple_GET_ITEM(tuple, i); - if (!PySlice_Check(key)) + key = PyTuple_GetItemRef(tuple, i); + if (!PySlice_Check(key)) { + Py_DECREF(key); goto type_error; - if (init_slice(base, key, (int)i) < 0) + } + if (init_slice(base, key, (int)i) < 0) { + Py_DECREF(key); goto err_occurred; + } + Py_DECREF(key); } } else { @@ -1948,7 +1968,8 @@ slice_indices(PyObject *self, PyObject *args) tmp = PyLong_FromSsize_t(s[i]); if (tmp == NULL) goto error; - PyTuple_SET_ITEM(ret, i, tmp); + PyTuple_SetItemRef(ret, i, tmp); + Py_DECREF(tmp); } return ret; @@ -1996,7 +2017,8 @@ ssize_array_as_tuple(Py_ssize_t *array, Py_ssize_t len) Py_DECREF(tuple); return NULL; } - PyTuple_SET_ITEM(tuple, i, x); + PyTuple_SetItemRef(tuple, i, x); + Py_DECREF(x); } return tuple; @@ -2333,8 +2355,9 @@ get_pointer(PyObject *self, PyObject *args) } for (i = 0; i < view.ndim; i++) { - PyObject *x = PySequence_Fast_GET_ITEM(seq, i); + PyObject *x = PySequence_Fast_GetItemRef(seq, i); indices[i] = PyLong_AsSsize_t(x); + Py_DECREF(x); if (PyErr_Occurred()) goto out; if (indices[i] < 0 || indices[i] >= view.shape[i]) { diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 7b796fd7b28e5c..c2cc5d1b6954fc 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -8,6 +8,7 @@ #define PY_SSIZE_T_CLEAN /* _testcapi.c relies on many low-level functions of the C API */ +#undef Py_NEWCAPI #undef Py_NEWCAPI_NO_MACRO #undef Py_NEWCAPI_NO_STRUCT diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 93d4dbc5f659a0..ce2abac13b3567 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -444,7 +444,8 @@ Split(const char *list) v = NULL; break; } - PyTuple_SET_ITEM(v, i, w); + PyTuple_SetItemRef(v, i, w); + Py_DECREF(w); } } Tcl_Free(FREECAST argv); @@ -468,8 +469,9 @@ SplitObj(PyObject *arg) If this does not return a new object, no action is needed. */ for(i = 0; i < size; i++) { - elem = PyTuple_GET_ITEM(arg, i); + elem = PyTuple_GetItemRef(arg, i); newelem = SplitObj(elem); + Py_DECREF(elem); if (!newelem) { Py_XDECREF(result); return NULL; @@ -484,12 +486,13 @@ SplitObj(PyObject *arg) if (!result) return NULL; for(k = 0; k < i; k++) { - elem = PyTuple_GET_ITEM(arg, k); - Py_INCREF(elem); - PyTuple_SET_ITEM(result, k, elem); + elem = PyTuple_GetItemRef(arg, k); + PyTuple_SetItemRef(result, k, elem); + Py_DECREF(elem); } } - PyTuple_SET_ITEM(result, i, newelem); + PyTuple_SetItemRef(result, i, newelem); + Py_DECREF(newelem); } if (result) return result; @@ -511,7 +514,8 @@ SplitObj(PyObject *arg) Py_XDECREF(result); return NULL; } - PyTuple_SET_ITEM(result, i, newelem); + PyTuple_SetItemRef(result, i, newelem); + Py_DECREF(newelem); } return result; } @@ -1042,8 +1046,11 @@ AsObj(PyObject *value) PyErr_NoMemory(); return NULL; } - for (i = 0; i < size; i++) - argv[i] = AsObj(PySequence_Fast_GET_ITEM(value,i)); + for (i = 0; i < size; i++) { + PyObject *arg = PySequence_Fast_GetItemRef(value,i); + argv[i] = AsObj(arg); + Py_DECREF(arg); + } result = Tcl_NewListObj((int)size, argv); PyMem_Free(argv); return result; @@ -1252,7 +1259,8 @@ FromObj(PyObject* tkapp, Tcl_Obj *value) Py_DECREF(result); return NULL; } - PyTuple_SET_ITEM(result, i, elem); + PyTuple_SetItemRef(result, i, elem); + Py_DECREF(elem); } return result; } @@ -1348,12 +1356,14 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc) } for (i = 0; i < objc; i++) { - PyObject *v = PySequence_Fast_GET_ITEM(args, i); + PyObject *v = PySequence_Fast_GetItemRef(args, i); if (v == Py_None) { + Py_DECREF(v); objc = i; break; } objv[i] = AsObj(v); + Py_DECREF(v); if (!objv[i]) { /* Reset objc, so it attempts to clear objects only up to i. */ @@ -1460,7 +1470,8 @@ Tkapp_Call(PyObject *selfptr, PyObject *args) /* If args is a single tuple, replace with contents of tuple */ if (PyTuple_GET_SIZE(args) == 1) { - PyObject *item = PyTuple_GET_ITEM(args, 0); + PyObject *item = PyTuple_GetItemRef(args, 0); + Py_DECREF(item); if (PyTuple_Check(item)) args = item; } @@ -2212,7 +2223,8 @@ _tkinter_tkapp_splitlist(TkappObject *self, PyObject *arg) Py_DECREF(v); return NULL; } - PyTuple_SET_ITEM(v, i, s); + PyTuple_SetItemRef(v, i, s); + Py_DECREF(s); } return v; } @@ -2248,7 +2260,8 @@ _tkinter_tkapp_splitlist(TkappObject *self, PyObject *arg) v = NULL; goto finally; } - PyTuple_SET_ITEM(v, i, s); + PyTuple_SetItemRef(v, i, s); + Py_DECREF(s); } finally: @@ -2293,7 +2306,8 @@ _tkinter_tkapp_split(TkappObject *self, PyObject *arg) Py_DECREF(v); return NULL; } - PyTuple_SET_ITEM(v, i, s); + PyTuple_SetItemRef(v, i, s); + Py_DECREF(s); } return v; } @@ -2359,7 +2373,8 @@ PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[ Py_DECREF(arg); return PythonCmd_Error(interp); } - PyTuple_SET_ITEM(arg, i, s); + PyTuple_SetItemRef(arg, i, s); + Py_DECREF(s); } res = PyObject_Call(func, arg, NULL); Py_DECREF(arg); @@ -3068,7 +3083,8 @@ _flatten1(FlattenContext* context, PyObject* item, int depth) return 0; /* copy items to output tuple */ for (i = 0; i < size; i++) { - PyObject *o = PySequence_Fast_GET_ITEM(item, i); + PyObject *o = PySequence_Fast_GetItemRef(item, i); + Py_DECREF(o); if (PyList_Check(o) || PyTuple_Check(o)) { if (!_flatten1(context, o, depth + 1)) return 0; @@ -3077,8 +3093,9 @@ _flatten1(FlattenContext* context, PyObject* item, int depth) !_bump(context, 1)) return 0; Py_INCREF(o); - PyTuple_SET_ITEM(context->tuple, - context->size++, o); + PyTuple_SetItemRef(context->tuple, + context->size++, o); + Py_DECREF(o); } } } else { diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 3dd537f58c07f4..eed2e7ae0f86aa 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -1294,14 +1294,16 @@ array_array_buffer_info_impl(arrayobject *self) Py_DECREF(retval); return NULL; } - PyTuple_SET_ITEM(retval, 0, v); + PyTuple_SetItemRef(retval, 0, v); + Py_DECREF(v); v = PyLong_FromSsize_t(Py_SIZE(self)); if (v == NULL) { Py_DECREF(retval); return NULL; } - PyTuple_SET_ITEM(retval, 1, v); + PyTuple_SetItemRef(retval, 1, v); + Py_DECREF(v); return retval; } @@ -1933,8 +1935,10 @@ make_array(PyTypeObject *arraytype, char typecode, PyObject *items) return NULL; } Py_INCREF(items); - PyTuple_SET_ITEM(new_args, 0, typecode_obj); - PyTuple_SET_ITEM(new_args, 1, items); + PyTuple_SetItemRef(new_args, 0, typecode_obj); + Py_DECREF(typecode_obj); + PyTuple_SetItemRef(new_args, 1, items); + Py_DECREF(items); array_obj = array_new(arraytype, new_args, NULL); Py_DECREF(new_args); diff --git a/Modules/audioop.c b/Modules/audioop.c index f4fdeb23ffa95a..1b4c147aa0cb79 100644 --- a/Modules/audioop.c +++ b/Modules/audioop.c @@ -1374,8 +1374,9 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width, goto exit; } for (chan = 0; chan < nchannels; chan++) { - channel = PyTuple_GetItem(samps, chan); + channel = PyTuple_GetItemRef(samps, chan); if (!PyTuple_Check(channel)) { + Py_DECREF(channel); PyErr_SetString(PyExc_TypeError, "ratecv(): illegal state argument"); goto exit; @@ -1384,8 +1385,10 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width, "ii;ratecv(): illegal state argument", &prev_i[chan], &cur_i[chan])) { + Py_DECREF(channel); goto exit; } + Py_DECREF(channel); } } @@ -1422,11 +1425,12 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width, samps = PyTuple_New(nchannels); if (samps == NULL) goto exit; - for (chan = 0; chan < nchannels; chan++) - PyTuple_SetItem(samps, chan, - Py_BuildValue("(ii)", - prev_i[chan], - cur_i[chan])); + for (chan = 0; chan < nchannels; chan++) { + PyObject *obj = Py_BuildValue("(ii)", + prev_i[chan], cur_i[chan]); + PyTuple_SetItemRef(samps, chan, obj); + Py_DECREF(obj); + } if (PyErr_Occurred()) goto exit; /* We have checked before that the length diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 22172b043bcd88..eb9a9a25380bfd 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -53,14 +53,16 @@ make_tuple(PyObject *object, Py_ssize_t len) Py_DECREF(object); return NULL; } - PyTuple_SET_ITEM(v, 0, object); + PyTuple_SetItemRef(v, 0, object); + Py_DECREF(object); w = PyLong_FromSsize_t(len); if (w == NULL) { Py_DECREF(v); return NULL; } - PyTuple_SET_ITEM(v, 1, w); + PyTuple_SetItemRef(v, 1, w); + Py_DECREF(w); return v; } @@ -98,7 +100,8 @@ call_error_callback(PyObject *errors, PyObject *exc) return NULL; } - PyTuple_SET_ITEM(args, 0, exc); + PyTuple_SetItemRef(args, 0, exc); + Py_DECREF(exc); Py_INCREF(exc); r = PyObject_CallObject(cb, args); @@ -200,7 +203,7 @@ multibytecodec_encerror(MultibyteCodec *codec, MultibyteEncodeBuffer *buf, PyObject *errors, Py_ssize_t e) { - PyObject *retobj = NULL, *retstr = NULL, *tobj; + PyObject *retobj = NULL, *retstr = NULL, *tobj, *arg; Py_ssize_t retstrsize, newpos; Py_ssize_t esize, start, end; const char *reason; @@ -296,14 +299,25 @@ multibytecodec_encerror(MultibyteCodec *codec, if (retobj == NULL) goto errorexit; - if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 || - (!PyUnicode_Check((tobj = PyTuple_GET_ITEM(retobj, 0))) && !PyBytes_Check(tobj)) || - !PyLong_Check(PyTuple_GET_ITEM(retobj, 1))) { + int invalid = (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2); + if (!invalid) { + tobj = PyTuple_GetItemRef(retobj, 0); + arg = PyTuple_GetItemRef(retobj, 1); + invalid = ((!PyUnicode_Check(tobj) && !PyBytes_Check(tobj)) || + !PyLong_Check(arg)); + if (invalid) { + Py_DECREF(tobj); + Py_DECREF(arg); + } + } + if (invalid) { PyErr_SetString(PyExc_TypeError, "encoding error handler must return " "(str, int) tuple"); goto errorexit; } + Py_DECREF(tobj); + Py_DECREF(arg); if (PyUnicode_Check(tobj)) { Py_ssize_t inpos; @@ -327,7 +341,9 @@ multibytecodec_encerror(MultibyteCodec *codec, buf->outbuf += retstrsize; } - newpos = PyLong_AsSsize_t(PyTuple_GET_ITEM(retobj, 1)); + arg = PyTuple_GetItemRef(retobj, 1); + newpos = PyLong_AsSsize_t(arg); + Py_DECREF(arg); if (newpos < 0 && !PyErr_Occurred()) newpos += (Py_ssize_t)buf->inlen; if (newpos < 0 || newpos > buf->inlen) { @@ -355,7 +371,7 @@ multibytecodec_decerror(MultibyteCodec *codec, MultibyteDecodeBuffer *buf, PyObject *errors, Py_ssize_t e) { - PyObject *retobj = NULL, *retuni = NULL; + PyObject *retobj = NULL, *retuni = NULL, *arg; Py_ssize_t newpos; const char *reason; Py_ssize_t esize, start, end; @@ -422,19 +438,31 @@ multibytecodec_decerror(MultibyteCodec *codec, if (retobj == NULL) goto errorexit; - if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 || - !PyUnicode_Check((retuni = PyTuple_GET_ITEM(retobj, 0))) || - !PyLong_Check(PyTuple_GET_ITEM(retobj, 1))) { + int invalid = (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2); + if (!invalid) { + retuni = PyTuple_GetItemRef(retobj, 0); + arg = PyTuple_GetItemRef(retobj, 1); + invalid = (!PyUnicode_Check(retuni) || !PyLong_Check(arg)); + if (invalid) { + Py_DECREF(retuni); + Py_DECREF(arg); + } + } + if (invalid) { PyErr_SetString(PyExc_TypeError, "decoding error handler must return " "(str, int) tuple"); goto errorexit; } + Py_DECREF(retuni); + Py_DECREF(arg); if (_PyUnicodeWriter_WriteStr(&buf->writer, retuni) < 0) goto errorexit; - newpos = PyLong_AsSsize_t(PyTuple_GET_ITEM(retobj, 1)); + arg = PyTuple_GetItemRef(retobj, 1); + newpos = PyLong_AsSsize_t(arg); + Py_DECREF(arg); if (newpos < 0 && !PyErr_Occurred()) newpos += (Py_ssize_t)(buf->inbuf_end - buf->inbuf_top); if (newpos < 0 || buf->inbuf_top + newpos > buf->inbuf_end) { diff --git a/Modules/grpmodule.c b/Modules/grpmodule.c index f577fd3ab4ec3b..4419c75521fbcc 100644 --- a/Modules/grpmodule.c +++ b/Modules/grpmodule.c @@ -62,7 +62,7 @@ mkgrent(struct group *p) Py_DECREF(x); } -#define SET(i,val) PyStructSequence_SET_ITEM(v, i, val) +#define SET(i,val) do { PyStructSequence_SetItemRef(v, i, val); Py_DECREF(val); } while (0) SET(setIndex++, PyUnicode_DecodeFSDefault(p->gr_name)); if (p->gr_passwd) SET(setIndex++, PyUnicode_DecodeFSDefault(p->gr_passwd)); diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 37934f60e9c401..728552cf7d0609 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2139,20 +2139,24 @@ math_dist_impl(PyObject *module, PyObject *p, PyObject *q) } } for (i=0 ; ist_node, - PyTuple_New, PyTuple_SetItem, line_info, col_info); + PyTuple_New, node_PyTuple_SetItem, line_info, col_info); } return (res); } diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index c8a01d4e088ece..abb7c32a2a0254 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -274,7 +274,8 @@ call_character_handler(xmlparseobject *self, const XML_Char *buffer, int len) noop_character_data_handler); return -1; } - PyTuple_SET_ITEM(args, 0, temp); + PyTuple_SetItemRef(args, 0, temp); + Py_DECREF(temp); /* temp is now a borrowed reference; consider it unused. */ self->in_callback = 1; temp = call_with_frame("CharacterData", __LINE__, @@ -526,7 +527,8 @@ conv_content_model(XML_Content * const model, Py_XDECREF(children); return NULL; } - PyTuple_SET_ITEM(children, i, child); + PyTuple_SetItemRef(children, i, child); + Py_DECREF(child); } result = Py_BuildValue("(iiO&N)", model->type, model->quant, diff --git a/Modules/resource.c b/Modules/resource.c index e59280f249dfe4..d3a58d590d191e 100644 --- a/Modules/resource.c +++ b/Modules/resource.c @@ -98,6 +98,9 @@ resource_getrusage_impl(PyObject *module, int who) if (!result) return NULL; +#define PyStructSequence_SET_ITEM(result, i, val) \ + do { PyStructSequence_SetItemRef(result, i, val); Py_XDECREF(val); } while (0) + PyStructSequence_SET_ITEM(result, 0, PyFloat_FromDouble(doubletime(ru.ru_utime))); PyStructSequence_SET_ITEM(result, 1, @@ -117,6 +120,8 @@ resource_getrusage_impl(PyObject *module, int who) PyStructSequence_SET_ITEM(result, 14, PyLong_FromLong(ru.ru_nvcsw)); PyStructSequence_SET_ITEM(result, 15, PyLong_FromLong(ru.ru_nivcsw)); +#undef PyStructSequence_SET_ITEM + if (PyErr_Occurred()) { Py_DECREF(result); return NULL; @@ -128,7 +133,7 @@ resource_getrusage_impl(PyObject *module, int who) static int py2rlimit(PyObject *limits, struct rlimit *rl_out) { - PyObject *curobj, *maxobj; + PyObject *curobj = NULL, *maxobj = NULL; limits = PySequence_Tuple(limits); if (!limits) /* Here limits is a borrowed reference */ @@ -139,8 +144,8 @@ py2rlimit(PyObject *limits, struct rlimit *rl_out) "expected a tuple of 2 integers"); goto error; } - curobj = PyTuple_GET_ITEM(limits, 0); - maxobj = PyTuple_GET_ITEM(limits, 1); + curobj = PyTuple_GetItemRef(limits, 0); + maxobj = PyTuple_GetItemRef(limits, 1); #if !defined(HAVE_LARGEFILE_SUPPORT) rl_out->rlim_cur = PyLong_AsLong(curobj); if (rl_out->rlim_cur == (rlim_t)-1 && PyErr_Occurred()) @@ -158,12 +163,16 @@ py2rlimit(PyObject *limits, struct rlimit *rl_out) goto error; #endif + Py_DECREF(curobj); + Py_DECREF(maxobj); Py_DECREF(limits); rl_out->rlim_cur = rl_out->rlim_cur & RLIM_INFINITY; rl_out->rlim_max = rl_out->rlim_max & RLIM_INFINITY; return 0; error: + Py_XDECREF(curobj); + Py_XDECREF(maxobj); Py_DECREF(limits); return -1; } diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index b9439add939d76..b1b9952b3a5acb 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -127,12 +127,14 @@ seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1]) SOCKET v; /* any intervening fileno() calls could decr this refcnt */ - if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i))) + o = PySequence_Fast_GetItemRef(fast_seq, i); + if (!o) { goto finally; - - Py_INCREF(o); - v = PyObject_AsFileDescriptor( o ); - if (v == -1) goto finally; + } + v = PyObject_AsFileDescriptor(o); + if (v == -1) { + goto finally; + } #if defined(_MSC_VER) max = 0; /* not used for Win32 */ @@ -677,7 +679,8 @@ select_poll_poll_impl(pollObject *self, PyObject *timeout_obj) Py_DECREF(value); goto error; } - PyTuple_SET_ITEM(value, 0, num); + PyTuple_SetItemRef(value, 0, num); + Py_DECREF(num); /* The &0xffff is a workaround for AIX. 'revents' is a 16-bit short, and IBM assigned POLLNVAL @@ -688,7 +691,8 @@ select_poll_poll_impl(pollObject *self, PyObject *timeout_obj) Py_DECREF(value); goto error; } - PyTuple_SET_ITEM(value, 1, num); + PyTuple_SetItemRef(value, 1, num); + Py_DECREF(num); if ((PyList_SetItem(result_list, j, value)) == -1) { Py_DECREF(value); goto error; diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 906416cf9f6c3f..562919f651f264 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -3841,11 +3841,15 @@ sock_recvmsg_into(PySocketSockObject *s, PyObject *args) goto finally; } for (; nbufs < nitems; nbufs++) { - if (!PyArg_Parse(PySequence_Fast_GET_ITEM(fast, nbufs), + PyObject *arg = PySequence_Fast_GetItemRef(fast, nbufs); + if (!PyArg_Parse(arg, "w*;recvmsg_into() argument 1 must be an iterable " "of single-segment read-write buffers", - &bufs[nbufs])) + &bufs[nbufs])) { + Py_DECREF(arg); goto finally; + } + Py_DECREF(arg); iovs[nbufs].iov_base = bufs[nbufs].buf; iovs[nbufs].iov_len = bufs[nbufs].len; } @@ -4173,11 +4177,15 @@ sock_sendmsg_iovec(PySocketSockObject *s, PyObject *data_arg, } } for (; ndatabufs < ndataparts; ndatabufs++) { - if (!PyArg_Parse(PySequence_Fast_GET_ITEM(data_fast, ndatabufs), + PyObject *arg = PySequence_Fast_GetItemRef(data_fast, ndatabufs); + if (!PyArg_Parse(arg, "y*;sendmsg() argument 1 must be an iterable of " "bytes-like objects", - &databufs[ndatabufs])) + &databufs[ndatabufs])) { + Py_DECREF(arg); goto finally; + } + Py_DECREF(arg); iovs[ndatabufs].iov_base = databufs[ndatabufs].buf; iovs[ndatabufs].iov_len = databufs[ndatabufs].len; } @@ -4268,12 +4276,16 @@ sock_sendmsg(PySocketSockObject *s, PyObject *args) while (ncmsgbufs < ncmsgs) { size_t bufsize, space; - if (!PyArg_Parse(PySequence_Fast_GET_ITEM(cmsg_fast, ncmsgbufs), + PyObject *arg = PySequence_Fast_GetItemRef(cmsg_fast, ncmsgbufs); + if (!PyArg_Parse(arg, "(iiy*):[sendmsg() ancillary data items]", &cmsgs[ncmsgbufs].level, &cmsgs[ncmsgbufs].type, - &cmsgs[ncmsgbufs].data)) + &cmsgs[ncmsgbufs].data)) { + Py_DECREF(arg); goto finally; + } + Py_DECREF(arg); bufsize = cmsgs[ncmsgbufs++].data.len; #ifdef CMSG_SPACE diff --git a/Modules/spwdmodule.c b/Modules/spwdmodule.c index 1601ec0f2fc4e7..55128e1cf485ae 100644 --- a/Modules/spwdmodule.c +++ b/Modules/spwdmodule.c @@ -68,10 +68,10 @@ sets(PyObject *v, int i, const char* val) { if (val) { PyObject *o = PyUnicode_DecodeFSDefault(val); - PyStructSequence_SET_ITEM(v, i, o); + PyStructSequence_SetItemRef(v, i, o); + Py_DECREF(o); } else { - PyStructSequence_SET_ITEM(v, i, Py_None); - Py_INCREF(Py_None); + PyStructSequence_SetItemRef(v, i, Py_None); } } @@ -82,7 +82,7 @@ static PyObject *mkspent(struct spwd *p) if (v == NULL) return NULL; -#define SETI(i,val) PyStructSequence_SET_ITEM(v, i, PyLong_FromLong((long) val)) +#define SETI(i,val) do { PyObject *item = PyLong_FromLong((long) val); PyStructSequence_SetItemRef(v, i, item); Py_DECREF(item); } while (0) #define SETS(i,val) sets(v, i, val) SETS(setIndex++, p->sp_namp); diff --git a/Objects/listobject.c b/Objects/listobject.c index d59b5e45fa1c55..a51614849f3b06 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -230,6 +230,15 @@ PyList_GetItem(PyObject *op, Py_ssize_t i) return ((PyListObject *)op) -> ob_item[i]; } +PyObject * +PyList_GetItemRef(PyObject *op, Py_ssize_t i) +{ + PyObject *item = PyList_GetItem(op, i); + Py_XINCREF(item); + return item; +} + + int PyList_SetItem(PyObject *op, Py_ssize_t i, PyObject *newitem) diff --git a/TODO.rst b/TODO.rst index 85e5ab5d9299cd..28ecd40df17668 100644 --- a/TODO.rst +++ b/TODO.rst @@ -4,6 +4,7 @@ TODO list for new Python C API * capi_tests: check for reference leaks * Modify PyObject_INIT(op, type) macro to return op again? use an inlined function? +* Do we need ``PySequence_Fast_GetItemRef()``? Issues ====== diff --git a/setup.py b/setup.py index 367180f4f98cf7..38f234bf6e28cd 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ # modules (Issue #21121). cflags = sysconfig.get_config_var('CFLAGS') py_cflags_nodist = sysconfig.get_config_var('PY_CFLAGS_NODIST') -sysconfig.get_config_vars()['CFLAGS'] = cflags + ' ' + py_cflags_nodist + ' -D Py_NEWCAPI_NO_STRUCT' +sysconfig.get_config_vars()['CFLAGS'] = cflags + ' ' + py_cflags_nodist + ' -D Py_NEWCAPI' class Dummy: """Hack for parallel build""" From 4401d0d12e906a429a699cb6766e1c8644610001 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Sep 2018 23:39:31 +0200 Subject: [PATCH 40/50] fix test_buffer --- Modules/_testbuffer.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index afce8d50189377..4a25943c10bab3 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -337,11 +337,9 @@ pack_from_list(PyObject *obj, PyObject *items, PyObject *format, offset = NULL; for (i = 0; i < nitems; i++) { /* Loop invariant: args[j] are borrowed references or NULL. */ - PyTuple_SetItemRef(args, 0, obj); - Py_DECREF(obj); - for (j = 1; j < 2+nmemb; j++) { - PyTuple_SetItemRef(args, j, NULL); - } + PyTuple_SET_ITEM(args, 0, obj); + for (j = 1; j < 2+nmemb; j++) + PyTuple_SET_ITEM(args, j, NULL); Py_XDECREF(offset); offset = PyLong_FromSsize_t(i*itemsize); From 8b2676a5c5eb0a4b8d96674e8f26aeb0ea8366cf Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Sep 2018 23:55:55 +0200 Subject: [PATCH 41/50] Fix _testbuffer.c --- Modules/_testbuffer.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index 4a25943c10bab3..3bb6ebe5893c6d 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -337,25 +337,25 @@ pack_from_list(PyObject *obj, PyObject *items, PyObject *format, offset = NULL; for (i = 0; i < nitems; i++) { /* Loop invariant: args[j] are borrowed references or NULL. */ - PyTuple_SET_ITEM(args, 0, obj); - for (j = 1; j < 2+nmemb; j++) - PyTuple_SET_ITEM(args, j, NULL); + PyTuple_SetItemRef(args, 0, obj); + for (j = 1; j < 2+nmemb; j++) { + PyTuple_SetItemRef(args, j, NULL); + } - Py_XDECREF(offset); + assert(offset == NULL); offset = PyLong_FromSsize_t(i*itemsize); if (offset == NULL) { ret = -1; break; } PyTuple_SetItemRef(args, 1, offset); - Py_DECREF(offset); + Py_CLEAR(offset); item = PySequence_Fast_GetItemRef(items, i); if ((PyBytes_Check(item) || PyLong_Check(item) || PyFloat_Check(item)) && nmemb == 1) { PyTuple_SetItemRef(args, 2, item); Py_DECREF(item); - Py_DECREF(item); } else if ((PyList_Check(item) || PyTuple_Check(item)) && PySequence_Length(item) == nmemb) { @@ -363,7 +363,6 @@ pack_from_list(PyObject *obj, PyObject *items, PyObject *format, tmp = PySequence_Fast_GetItemRef(item, j); PyTuple_SetItemRef(args, 2+j, tmp); Py_DECREF(tmp); - Py_DECREF(tmp); } Py_DECREF(item); } @@ -383,11 +382,6 @@ pack_from_list(PyObject *obj, PyObject *items, PyObject *format, Py_DECREF(tmp); } - Py_INCREF(obj); /* args[0] */ - /* args[1]: offset is either NULL or should be dealloc'd */ - for (i = 2; i < 2+nmemb; i++) { - tmp = PyTuple_GetItemRef(args, i); - } Py_DECREF(args); Py_DECREF(pack_into); From 64f77f8d9297572439e4fa982eb18be1121c5dd7 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 5 Sep 2018 00:03:33 +0200 Subject: [PATCH 42/50] TODO: Py_TYPE() --- TODO.rst | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/TODO.rst b/TODO.rst index 28ecd40df17668..54f668a1105da5 100644 --- a/TODO.rst +++ b/TODO.rst @@ -6,6 +6,33 @@ TODO list for new Python C API function? * Do we need ``PySequence_Fast_GetItemRef()``? +Remove Py_TYPE()? +================= + +Error:: + + PyErr_Format(PyExc_TypeError, + "Struct() argument 1 must be a str or bytes object, " + "not %.200s", + Py_TYPE(format)->tp_name); + +Dealloc:: + + static void + s_dealloc(PyStructObject *s) + { + ... + Py_TYPE(s)->tp_free((PyObject *)s); + } + +Object size:: + + Py_ssize_t size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode); + +Check type:: + + #define PyStruct_CheckExact(op) (Py_TYPE(op) == &PyStructType) + Issues ====== From 2ca0f52583d96464d698bb4683bb155d9c98ac76 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 5 Sep 2018 12:40:56 +0200 Subject: [PATCH 43/50] PyUnicode_FromFormat(): add %T format --- Doc/c-api/unicode.rst | 6 ++++++ Include/object.h | 6 +++--- Lib/test/test_unicode.py | 4 ++++ Objects/unicodeobject.c | 16 ++++++++++++++++ TODO.rst | 8 ++++---- 5 files changed, 33 insertions(+), 7 deletions(-) diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index 92e22b16a4ef29..044f4605b969c2 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -519,6 +519,9 @@ APIs: | :attr:`%R` | PyObject\* | The result of calling | | | | :c:func:`PyObject_Repr`. | +-------------------+---------------------+--------------------------------+ + | :attr:`%T` | PyObject\* | Object type name, equivalent | + | | | to ``Py_TYPE(op)->tp_name``. | + +-------------------+---------------------+--------------------------------+ An unrecognized format character causes all the rest of the format string to be copied as-is to the result string, and any extra arguments discarded. @@ -543,6 +546,9 @@ APIs: Support width and precision formatter for ``"%s"``, ``"%A"``, ``"%U"``, ``"%V"``, ``"%S"``, ``"%R"`` added. + .. versionchanged:: 3.7 + Support for ``"%T"`` added. + .. c:function:: PyObject* PyUnicode_FromFormatV(const char *format, va_list vargs) diff --git a/Include/object.h b/Include/object.h index 70cf281acfa6d3..0cb379b2704862 100644 --- a/Include/object.h +++ b/Include/object.h @@ -455,10 +455,10 @@ typedef struct _typeobject { do { _Py_TYPE(ob) = (type); } while (0) #ifdef Py_NEWCAPI_NO_STRUCT -PyAPI_FUNC(PyTypeObject*) _Py_TYPE_impl(PyObject *op); -#define Py_TYPE(ob) _Py_TYPE_impl((PyObject *)(ob)) + PyAPI_FUNC(PyTypeObject*) _Py_TYPE_impl(PyObject *op); +# define Py_TYPE(ob) _Py_TYPE_impl((PyObject *)(ob)) #else -#define Py_TYPE(ob) _Py_TYPE(ob) +# define Py_TYPE(ob) _Py_TYPE(ob) #endif diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index fb7bb2d523fe6e..73111f1c24a20b 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -2655,6 +2655,10 @@ def check_format(expected, format, *args): check_format(r"%A:'abc\xe9\uabcd\U0010ffff'", b'%%A:%A', 'abc\xe9\uabcd\U0010ffff') + # test %T (object type name) + check_format(r"type name: str", + b'type name: %T', 'text') + # test %V check_format('repr=abc', b'repr=%V', 'abc', b'xyz') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 8b0fb36f43fd3d..48876e0ba0d1b8 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -2825,6 +2825,21 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, break; } + case 'T': + { + PyObject *obj = va_arg(*vargs, PyObject *); + PyTypeObject *type = Py_TYPE(obj); + Py_INCREF(type); + const char *type_name = type->tp_name; + size_t len = strlen(type_name); + if (unicode_fromformat_write_cstr(writer, type_name, -1, -1) < 0) { + Py_DECREF(type); + return NULL; + } + Py_DECREF(type); + break; + } + case '%': if (_PyUnicodeWriter_WriteCharInline(writer, '%') < 0) return NULL; @@ -13693,6 +13708,7 @@ _PyUnicodeWriter_WriteLatin1String(_PyUnicodeWriter *writer, const char *str, Py_ssize_t len) { Py_UCS4 maxchar; + assert(len >= 0); maxchar = ucs1lib_find_max_char((Py_UCS1*)str, (Py_UCS1*)str + len); if (_PyUnicodeWriter_Prepare(writer, len, maxchar) == -1) diff --git a/TODO.rst b/TODO.rst index 54f668a1105da5..f1c48fe655fb65 100644 --- a/TODO.rst +++ b/TODO.rst @@ -11,10 +11,10 @@ Remove Py_TYPE()? Error:: - PyErr_Format(PyExc_TypeError, - "Struct() argument 1 must be a str or bytes object, " - "not %.200s", - Py_TYPE(format)->tp_name); + PyErr_Format(PyExc_TypeError, + "Struct() argument 1 must be a str or bytes object, " + "not %.200s", + Py_TYPE(format)->tp_name); Dealloc:: From e8c499ae0cea823ac5e05a1cbc1a55ca843a48a6 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 5 Sep 2018 13:03:25 +0200 Subject: [PATCH 44/50] Add Py_GetType(), remove Py_TYPE() from Py_NEWCAPI --- Include/object.h | 12 +++++++++-- Objects/object.c | 11 ++++++++++ Objects/unicodeobject.c | 3 +-- TODO.rst | 46 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 4 deletions(-) diff --git a/Include/object.h b/Include/object.h index 0cb379b2704862..2314b86c359b91 100644 --- a/Include/object.h +++ b/Include/object.h @@ -449,18 +449,26 @@ typedef struct _typeobject { #endif +PyAPI_FUNC(PyTypeObject*) _Py_GetType(PyObject *op); +#define Py_GetType(ob) _Py_GetType((PyObject *)(ob)) #define _Py_TYPE(ob) (((PyObject*)(ob))->ob_type) #define _Py_SET_TYPE(ob, type) \ do { _Py_TYPE(ob) = (type); } while (0) #ifdef Py_NEWCAPI_NO_STRUCT - PyAPI_FUNC(PyTypeObject*) _Py_TYPE_impl(PyObject *op); -# define Py_TYPE(ob) _Py_TYPE_impl((PyObject *)(ob)) + /* Py_TYPE() is not part of the Py_NEWCAPI because it returns a borrowed + reference */ +# ifndef Py_NEWCAPI + PyAPI_FUNC(PyTypeObject*) _Py_TYPE_impl(PyObject *op); +# define Py_TYPE(ob) _Py_TYPE_impl((PyObject *)(ob)) +# endif #else # define Py_TYPE(ob) _Py_TYPE(ob) #endif +#define Py_TYPE_IS(ob, type) (_Py_TYPE(ob) == (type)) + typedef struct{ int slot; /* slot id, see below */ diff --git a/Objects/object.c b/Objects/object.c index 8fd075436a2a2b..bba3fe58048dd5 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -47,6 +47,17 @@ _Py_REFCNT_impl(PyObject *op) } +PyTypeObject* +_Py_GetType(PyObject *op) +{ + PyTypeObject *type = _Py_TYPE(op); + assert(type != NULL); + Py_INCREF(type); + return type; +} + + + PyTypeObject* _Py_TYPE_impl(PyObject *op) { diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 48876e0ba0d1b8..bfd1381a2937fa 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -2828,8 +2828,7 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, case 'T': { PyObject *obj = va_arg(*vargs, PyObject *); - PyTypeObject *type = Py_TYPE(obj); - Py_INCREF(type); + PyTypeObject *type = Py_GetType(obj); const char *type_name = type->tp_name; size_t len = strlen(type_name); if (unicode_fromformat_write_cstr(writer, type_name, -1, -1) < 0) { diff --git a/TODO.rst b/TODO.rst index f1c48fe655fb65..583c535da8adb9 100644 --- a/TODO.rst +++ b/TODO.rst @@ -6,6 +6,52 @@ TODO list for new Python C API function? * Do we need ``PySequence_Fast_GetItemRef()``? +Replace Py_TYPE() +=================o + +Dealloc:: + + Py_TYPE(op)->tp_free((PyObject *)op); + +becomes:: + + PyTypeObject *type = Py_GetType(op); + type->tp_free((PyObject *)op); + Py_DECREF(type); + +Size:: + + res = _PyObject_SIZE(Py_TYPE(self)) + self->allocated * self->ob_descr->itemsize; + +becomes:: + + PyTypeObject *type = Py_GetType(self); + res = _PyObject_SIZE(type) + self->allocated * self->ob_descr->itemsize; + Py_DECREF(type); + +Error:: + + PyErr_Format(PyExc_TypeError, + "first argument must be a type object, not %.200s", + Py_TYPE(arraytype)->tp_name); + +becomes:: + + PyErr_Format(PyExc_TypeError, + "first argument must be a type object, not %T", + arraytype); + +Py_BuildValue:: + + result = Py_BuildValue( + "N(CO)O", Py_GetType(self), typecode, list, dict); + +becomes:: + + result = Py_BuildValue( + "N(CO)O", Py_GetType(self), typecode, list, dict); + + Remove Py_TYPE()? ================= From 790f9689e14842052d4ddd653c84638c08c9ee7e Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 5 Sep 2018 13:03:56 +0200 Subject: [PATCH 45/50] Use Py_GetType() and %T format --- Modules/_asynciomodule.c | 42 ++++++--- Modules/_blake2/blake2b_impl.c | 5 +- Modules/_blake2/blake2s_impl.c | 6 +- Modules/_bz2module.c | 16 ++-- Modules/_csv.c | 4 +- Modules/_ctypes/_ctypes.c | 110 ++++++++++++++--------- Modules/_ctypes/callproc.c | 22 +++-- Modules/_ctypes/stgdict.c | 6 +- Modules/_cursesmodule.c | 16 ++-- Modules/_datetimemodule.c | 134 ++++++++++++++++------------- Modules/_decimal/_decimal.c | 22 +++-- Modules/_elementtree.c | 40 +++++---- Modules/_gdbmmodule.c | 2 +- Modules/_json.c | 34 ++++---- Modules/_lsprof.c | 10 ++- Modules/_lzmamodule.c | 16 ++-- Modules/_pickle.c | 100 +++++++++++---------- Modules/_queuemodule.c | 4 +- Modules/_sha3/sha3module.c | 8 +- Modules/_sqlite/cache.c | 8 +- Modules/_sqlite/connection.c | 12 +-- Modules/_sqlite/cursor.c | 4 +- Modules/_sqlite/prepare_protocol.c | 4 +- Modules/_sqlite/row.c | 8 +- Modules/_sqlite/statement.c | 4 +- Modules/_ssl.c | 14 +-- Modules/_struct.c | 13 +-- Modules/_testbuffer.c | 2 +- Modules/_tkinter.c | 9 +- Modules/_xxsubinterpretersmodule.c | 29 +++++-- Modules/arraymodule.c | 44 ++++++---- Modules/binascii.c | 4 +- Modules/cjkcodecs/multibytecodec.c | 16 +++- Modules/clinic/_bz2module.c.h | 6 +- Modules/mathmodule.c | 12 ++- Modules/mmapmodule.c | 8 +- Modules/parsermodule.c | 16 ++-- Modules/pyexpat.c | 4 +- Modules/selectmodule.c | 12 ++- Modules/sha256module.c | 2 +- Modules/socketmodule.c | 41 +++++---- Modules/unicodedata.c | 2 +- Objects/unicodeobject.c | 20 +++-- TODO.rst | 7 +- 44 files changed, 550 insertions(+), 348 deletions(-) diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 9697ddfb09617e..3fd830b5d1783c 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -111,8 +111,8 @@ static PyTypeObject TaskType; static PyTypeObject PyRunningLoopHolder_Type; -#define Future_CheckExact(obj) (Py_TYPE(obj) == &FutureType) -#define Task_CheckExact(obj) (Py_TYPE(obj) == &TaskType) +#define Future_CheckExact(obj) (Py_TYPE_IS(obj, &FutureType)) +#define Task_CheckExact(obj) (Py_TYPE_IS(obj, &TaskType)) #define Future_Check(obj) PyObject_TypeCheck(obj, &FutureType) #define Task_Check(obj) PyObject_TypeCheck(obj, &TaskType) @@ -158,9 +158,12 @@ _is_coroutine(PyObject *coro) positive types. That shouldn't ever happen, unless someone stressing the system on purpose. */ - if (PySet_Add(iscoroutine_typecache, (PyObject*) Py_TYPE(coro))) { + PyTypeObject *type = Py_GetType(coro); + if (PySet_Add(iscoroutine_typecache, (PyObject*)type)) { + Py_DECREF(type); return -1; } + Py_DECREF(type); } return 1; @@ -183,8 +186,9 @@ is_coroutine(PyObject *coro) This cache allows us to avoid the cost of even calling a pure-Python function in 99.9% cases. */ - int has_it = PySet_Contains( - iscoroutine_typecache, (PyObject*) Py_TYPE(coro)); + PyTypeObject *type = Py_GetType(coro); + int has_it = PySet_Contains(iscoroutine_typecache, (PyObject*) type); + Py_DECREF(type); if (has_it == 0) { /* type(coro) is not in iscoroutine_typecache */ return _is_coroutine(coro); @@ -255,7 +259,7 @@ get_running_loop(PyObject **loop) cached_running_holder_tsid = ts->id; } - assert(Py_TYPE(rl) == &PyRunningLoopHolder_Type); + assert(Py_TYPE_IS(rl, &PyRunningLoopHolder_Type)); PyObject *running_loop = ((PyRunningLoopHolder *)rl)->rl_loop; if (running_loop == Py_None) { @@ -577,7 +581,7 @@ future_set_exception(FutureObj *fut, PyObject *exc) PyErr_SetString(PyExc_TypeError, "invalid exception object"); return NULL; } - if ((PyObject*)Py_TYPE(exc_val) == PyExc_StopIteration) { + if (Py_TYPE_IS(exc_val, (PyTypeObject*)PyExc_StopIteration)) { Py_DECREF(exc_val); PyErr_SetString(PyExc_TypeError, "StopIteration interacts badly with generators " @@ -1308,8 +1312,10 @@ FutureObj_repr(FutureObj *fut) } PyObject *rstr = NULL; - PyObject *type_name = PyObject_GetAttrString((PyObject*)Py_TYPE(fut), + PyTypeObject *type = Py_GetType(fut); + PyObject *type_name = PyObject_GetAttrString((PyObject*)type, "__name__"); + Py_DECREF(type); if (type_name != NULL) { rstr = PyUnicode_FromFormat("<%S %U>", type_name, rinfo_s); Py_DECREF(type_name); @@ -1347,7 +1353,9 @@ FutureObj_finalize(FutureObj *fut) goto finally; } - type_name = PyObject_GetAttrString((PyObject*)Py_TYPE(fut), "__name__"); + PyTypeObject *type = Py_GetType(fut); + type_name = PyObject_GetAttrString((PyObject*)type, "__name__"); + Py_DECREF(type); if (type_name == NULL) { goto finally; } @@ -1476,7 +1484,9 @@ FutureObj_dealloc(PyObject *self) } (void)FutureObj_clear(fut); - Py_TYPE(fut)->tp_free(fut); + PyTypeObject *type = Py_GetType(fut); + type->tp_free(fut); + Py_DECREF(type); } @@ -1702,7 +1712,9 @@ TaskStepMethWrapper_dealloc(TaskStepMethWrapper *o) { PyObject_GC_UnTrack(o); (void)TaskStepMethWrapper_clear(o); - Py_TYPE(o)->tp_free(o); + PyTypeObject *type = Py_GetType(o); + type->tp_free(o); + Py_DECREF(type); } static PyObject * @@ -1816,7 +1828,9 @@ TaskWakeupMethWrapper_dealloc(TaskWakeupMethWrapper *o) { PyObject_GC_UnTrack(o); (void)TaskWakeupMethWrapper_clear(o); - Py_TYPE(o)->tp_free(o); + PyTypeObject *type = Py_GetType(o); + type->tp_free(o); + Py_DECREF(type); } static PyTypeObject TaskWakeupMethWrapper_Type = { @@ -2503,7 +2517,9 @@ TaskObj_dealloc(PyObject *self) } (void)TaskObj_clear(task); - Py_TYPE(task)->tp_free(task); + PyTypeObject *type = Py_GetType(task); + type->tp_free(task); + Py_DECREF(type); } static int diff --git a/Modules/_blake2/blake2b_impl.c b/Modules/_blake2/blake2b_impl.c index 7ad4b650b3254a..daef327e4a80d0 100644 --- a/Modules/_blake2/blake2b_impl.c +++ b/Modules/_blake2/blake2b_impl.c @@ -249,7 +249,10 @@ _blake2_blake2b_copy_impl(BLAKE2bObject *self) { BLAKE2bObject *cpy; - if ((cpy = new_BLAKE2bObject(Py_TYPE(self))) == NULL) + PyTypeObject *type = Py_GetType(self); + cpy = new_BLAKE2bObject(type); + Py_DECREF(type); + if (cpy == NULL) return NULL; ENTER_HASHLIB(self); diff --git a/Modules/_blake2/blake2s_impl.c b/Modules/_blake2/blake2s_impl.c index 8864fd82978730..b31fe4a1d5817c 100644 --- a/Modules/_blake2/blake2s_impl.c +++ b/Modules/_blake2/blake2s_impl.c @@ -249,8 +249,12 @@ _blake2_blake2s_copy_impl(BLAKE2sObject *self) { BLAKE2sObject *cpy; - if ((cpy = new_BLAKE2sObject(Py_TYPE(self))) == NULL) + PyTypeObject *type = Py_GetType(self); + if ((cpy = new_BLAKE2sObject(type)) == NULL) { + Py_DECREF(type); return NULL; + } + Py_DECREF(type); ENTER_HASHLIB(self); cpy->param = self->param; diff --git a/Modules/_bz2module.c b/Modules/_bz2module.c index 3890b60b1b87b3..a563bbe7f13f9b 100644 --- a/Modules/_bz2module.c +++ b/Modules/_bz2module.c @@ -267,8 +267,8 @@ _bz2_BZ2Compressor_flush_impl(BZ2Compressor *self) static PyObject * BZ2Compressor_getstate(BZ2Compressor *self, PyObject *noargs) { - PyErr_Format(PyExc_TypeError, "cannot serialize '%s' object", - Py_TYPE(self)->tp_name); + PyErr_Format(PyExc_TypeError, "cannot serialize %T object", + self); return NULL; } @@ -341,7 +341,9 @@ BZ2Compressor_dealloc(BZ2Compressor *self) BZ2_bzCompressEnd(&self->bzs); if (self->lock != NULL) PyThread_free_lock(self->lock); - Py_TYPE(self)->tp_free((PyObject *)self); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject *)self); + Py_DECREF(type); } static PyMethodDef BZ2Compressor_methods[] = { @@ -615,8 +617,8 @@ _bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor *self, Py_buffer *data, static PyObject * BZ2Decompressor_getstate(BZ2Decompressor *self, PyObject *noargs) { - PyErr_Format(PyExc_TypeError, "cannot serialize '%s' object", - Py_TYPE(self)->tp_name); + PyErr_Format(PyExc_TypeError, "cannot serialize %T object", + self); return NULL; } @@ -674,7 +676,9 @@ BZ2Decompressor_dealloc(BZ2Decompressor *self) Py_CLEAR(self->unused_data); if (self->lock != NULL) PyThread_free_lock(self->lock); - Py_TYPE(self)->tp_free((PyObject *)self); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject *)self); + Py_DECREF(type); } static PyMethodDef BZ2Decompressor_methods[] = { diff --git a/Modules/_csv.c b/Modules/_csv.c index 4cc1f7c88d8779..28dcdf8caf20b4 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -312,7 +312,9 @@ static void Dialect_dealloc(DialectObj *self) { Py_XDECREF(self->lineterminator); - Py_TYPE(self)->tp_free((PyObject *)self); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject *)self); + Py_DECREF(type); } static char *dialect_kws[] = { diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index c91e1b5f187994..161ed05fcdf3e4 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -142,7 +142,9 @@ _DictRemover_dealloc(PyObject *myself) DictRemoverObject *self = (DictRemoverObject *)myself; Py_XDECREF(self->key); Py_XDECREF(self->dict); - Py_TYPE(self)->tp_free(myself); + PyTypeObject *type = Py_GetType(self); + type->tp_free(myself); + Py_DECREF(type); } static PyObject * @@ -704,7 +706,6 @@ CDataType_from_param(PyObject *type, PyObject *value) if (PyCArg_CheckExact(value)) { PyCArgObject *p = (PyCArgObject *)value; PyObject *ob = p->obj; - const char *ob_name; StgDictObject *dict; dict = PyType_stgdict(type); @@ -719,10 +720,9 @@ CDataType_from_param(PyObject *type, PyObject *value) return value; } } - ob_name = (ob) ? Py_TYPE(ob)->tp_name : "???"; PyErr_Format(PyExc_TypeError, - "expected %s instance instead of pointer to %s", - ((PyTypeObject *)type)->tp_name, ob_name); + "expected %s instance instead of pointer to %T", + ((PyTypeObject *)type)->tp_name, ob); return NULL; } @@ -733,9 +733,9 @@ CDataType_from_param(PyObject *type, PyObject *value) return value; } PyErr_Format(PyExc_TypeError, - "expected %s instance instead of %s", + "expected %s instance instead of %T", ((PyTypeObject *)type)->tp_name, - Py_TYPE(value)->tp_name); + value); return NULL; } @@ -1221,8 +1221,8 @@ CharArray_set_value(CDataObject *self, PyObject *value) if (!PyBytes_Check(value)) { PyErr_Format(PyExc_TypeError, - "bytes expected instead of %s instance", - Py_TYPE(value)->tp_name); + "bytes expected instead of %T instance", + value); return -1; } else Py_INCREF(value); @@ -1277,8 +1277,8 @@ WCharArray_set_value(CDataObject *self, PyObject *value) } if (!PyUnicode_Check(value)) { PyErr_Format(PyExc_TypeError, - "unicode string expected instead of %s instance", - Py_TYPE(value)->tp_name); + "unicode string expected instead of %T instance", + value); return -1; } else Py_INCREF(value); @@ -2588,7 +2588,9 @@ static void PyCData_dealloc(PyObject *self) { PyCData_clear((CDataObject *)self); - Py_TYPE(self)->tp_free(self); + PyTypeObject *type = Py_GetType(self); + type->tp_free(self); + Py_DECREF(type); } static PyMemberDef PyCData_members[] = { @@ -2658,9 +2660,9 @@ PyCData_reduce(PyObject *myself, PyObject *args) "ctypes objects containing pointers cannot be pickled"); return NULL; } - return Py_BuildValue("O(O(NN))", + return Py_BuildValue("O(N(NN))", _unpickle, - Py_TYPE(myself), + Py_GetType(myself), PyObject_GetAttrString(myself, "__dict__"), PyBytes_FromStringAndSize(self->b_ptr, self->b_size)); } @@ -2687,8 +2689,8 @@ PyCData_setstate(PyObject *myself, PyObject *args) } if (!PyDict_Check(mydict)) { PyErr_Format(PyExc_TypeError, - "%.200s.__dict__ must be a dictionary, not %.200s", - Py_TYPE(myself)->tp_name, Py_TYPE(mydict)->tp_name); + "%T.__dict__ must be a dictionary, not %T", + myself, mydict); Py_DECREF(mydict); return NULL; } @@ -2921,9 +2923,9 @@ _PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, Py_RETURN_NONE; } else { PyErr_Format(PyExc_TypeError, - "expected %s instance, got %s", + "expected %s instance, got %T", ((PyTypeObject *)type)->tp_name, - Py_TYPE(value)->tp_name); + value); return NULL; } } @@ -2960,8 +2962,8 @@ _PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, if (p1->proto != p2->proto) { PyErr_Format(PyExc_TypeError, - "incompatible types, %s instance instead of %s instance", - Py_TYPE(value)->tp_name, + "incompatible types, %T instance instead of %s instance", + value, ((PyTypeObject *)type)->tp_name); return NULL; } @@ -2982,8 +2984,8 @@ _PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, return PyTuple_Pack(2, keep, value); } PyErr_Format(PyExc_TypeError, - "incompatible types, %s instance instead of %s instance", - Py_TYPE(value)->tp_name, + "incompatible types, %T instance instead of %s instance", + value, ((PyTypeObject *)type)->tp_name); return NULL; } @@ -3228,11 +3230,11 @@ _check_outarg_type(PyObject *arg, Py_ssize_t index) } PyErr_Format(PyExc_TypeError, - "'out' parameter %d must be a pointer type, not %s", + "'out' parameter %d must be a pointer type, not %T", Py_SAFE_DOWNCAST(index, Py_ssize_t, int), PyType_Check(arg) ? ((PyTypeObject *)arg)->tp_name : - Py_TYPE(arg)->tp_name); + arg); return 0; } @@ -4062,7 +4064,9 @@ static void PyCFuncPtr_dealloc(PyCFuncPtrObject *self) { PyCFuncPtr_clear(self); - Py_TYPE(self)->tp_free((PyObject *)self); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject *)self); + Py_DECREF(type); } static PyObject * @@ -4070,14 +4074,13 @@ PyCFuncPtr_repr(PyCFuncPtrObject *self) { #ifdef MS_WIN32 if (self->index) - return PyUnicode_FromFormat("", + return PyUnicode_FromFormat("", self->index - 0x1000, - Py_TYPE(self)->tp_name, + self, self); #endif - return PyUnicode_FromFormat("<%s object at %p>", - Py_TYPE(self)->tp_name, - self); + return PyUnicode_FromFormat("<%T object at %p>", + self, self); } static int @@ -4224,8 +4227,10 @@ Struct_init(PyObject *self, PyObject *args, PyObject *kwds) return -1; } if (PyTuple_GET_SIZE(args)) { - Py_ssize_t res = _init_pos_args(self, Py_TYPE(self), + PyTypeObject *type = Py_GetType(self); + Py_ssize_t res = _init_pos_args(self, type, args, kwds, 0); + Py_DECREF(type); if (res == -1) return -1; if (res < PyTuple_GET_SIZE(args)) { @@ -4768,10 +4773,13 @@ static PyGetSetDef Simple_getsets[] = { static PyObject * Simple_from_outparm(PyObject *self, PyObject *args) { - if (_ctypes_simple_instance((PyObject *)Py_TYPE(self))) { + PyTypeObject *type = Py_GetType(self); + if (_ctypes_simple_instance((PyObject *)type)) { + Py_DECREF(type); Py_INCREF(self); return self; } + Py_DECREF(type); /* call stgdict->getfunc */ return Simple_get_value((CDataObject *)self); } @@ -4805,17 +4813,20 @@ Simple_repr(CDataObject *self) { PyObject *val, *result; - if (Py_TYPE(self)->tp_base != &Simple_Type) { - return PyUnicode_FromFormat("<%s object at %p>", - Py_TYPE(self)->tp_name, self); + PyTypeObject *type = Py_GetType(self); + if (type->tp_base != &Simple_Type) { + Py_DECREF(type); + return PyUnicode_FromFormat("<%T object at %p>", + self, self); } + Py_DECREF(type); val = Simple_get_value(self); if (val == NULL) return NULL; - result = PyUnicode_FromFormat("%s(%R)", - Py_TYPE(self)->tp_name, val); + result = PyUnicode_FromFormat("%T(%R)", + self, val); Py_DECREF(val); return result; } @@ -4974,9 +4985,9 @@ Pointer_set_contents(CDataObject *self, PyObject *value, void *closure) return -1; if (!res) { PyErr_Format(PyExc_TypeError, - "expected %s instead of %s", + "expected %s instead of %T", ((PyTypeObject *)(stgdict->proto))->tp_name, - Py_TYPE(value)->tp_name); + value); return -1; } } @@ -5265,8 +5276,12 @@ comerror_init(PyObject *self, PyObject *args, PyObject *kwds) PyObject *a; int status; - if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds)) + PyTypeObject *type = Py_GetType(self); + if (!_PyArg_NoKeywords(type->tp_name, kwds)) { + Py_DECREF(type); return -1; + } + Py_DECREF(type); if (!PyArg_ParseTuple(args, "OOO:COMError", &hresult, &text, &details)) return -1; @@ -5374,11 +5389,20 @@ cast_check_pointertype(PyObject *arg) return 1; } } + PyTypeObject *type; + const char *tp_name; + if (PyType_Check(arg)) { + type = NULL; + tp_name = ((PyTypeObject *)arg)->tp_name; + } + else { + type = Py_GetType(arg); + tp_name = type->tp_name; + } PyErr_Format(PyExc_TypeError, "cast() argument 2 must be a pointer type, not %s", - PyType_Check(arg) - ? ((PyTypeObject *)arg)->tp_name - : Py_TYPE(arg)->tp_name); + tp_name); + Py_XDECREF(type); return 0; } diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 621c7b36bef5e1..138d8d9c87dbea 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -1517,8 +1517,8 @@ byref(PyObject *self, PyObject *args) } if (!CDataObject_Check(obj)) { PyErr_Format(PyExc_TypeError, - "byref() argument must be a ctypes instance, not '%s'", - Py_TYPE(obj)->tp_name); + "byref() argument must be a ctypes instance, not '%T'", + obj); return NULL; } @@ -1689,10 +1689,12 @@ POINTER(PyObject *self, PyObject *cls) if (buf == NULL) return PyErr_NoMemory(); sprintf(buf, "LP_%s", name); - result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type), + PyTypeObject *type = Py_GetType(&PyCPointer_Type); + result = PyObject_CallFunction((PyObject *)type, "s(O){}", buf, &PyCPointer_Type); + Py_DECREF(type); PyMem_Free(buf); if (result == NULL) return result; @@ -1707,11 +1709,13 @@ POINTER(PyObject *self, PyObject *cls) if (buf == NULL) return PyErr_NoMemory(); sprintf(buf, "LP_%s", typ->tp_name); - result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type), + PyTypeObject *type = Py_GetType(&PyCPointer_Type); + result = PyObject_CallFunction((PyObject *)type, "s(O){sO}", buf, &PyCPointer_Type, "_type_", cls); + Py_DECREF(type); PyMem_Free(buf); if (result == NULL) return result; @@ -1736,10 +1740,14 @@ pointer(PyObject *self, PyObject *arg) PyObject *result; PyObject *typ; - typ = PyDict_GetItem(_ctypes_ptrtype_cache, (PyObject *)Py_TYPE(arg)); - if (typ) + PyTypeObject *arg_type = Py_GetType(arg); + typ = PyDict_GetItem(_ctypes_ptrtype_cache, (PyObject *)arg_type); + if (typ) { + Py_DECREF(arg_type); return PyObject_CallFunctionObjArgs(typ, arg, NULL); - typ = POINTER(NULL, (PyObject *)Py_TYPE(arg)); + } + typ = POINTER(NULL, (PyObject *)arg_type); + Py_DECREF(arg_type); if (typ == NULL) return NULL; result = PyObject_CallFunctionObjArgs(typ, arg, NULL); diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index 1aaa9498859ede..9a6418b1ee50a8 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -233,7 +233,7 @@ MakeFields(PyObject *type, CFieldObject *descr, Py_DECREF(fieldlist); return -1; } - if (Py_TYPE(fdescr) != &PyCField_Type) { + if (!Py_TYPE_IS(fdescr, &PyCField_Type)) { PyErr_SetString(PyExc_TypeError, "unexpected type"); Py_DECREF(fdescr); Py_DECREF(fieldlist); @@ -256,7 +256,7 @@ MakeFields(PyObject *type, CFieldObject *descr, Py_DECREF(fieldlist); return -1; } - assert(Py_TYPE(new_descr) == &PyCField_Type); + assert(Py_TYPE_IS(new_descr, &PyCField_Type)); new_descr->size = fdescr->size; new_descr->offset = fdescr->offset + offset; new_descr->index = fdescr->index + index; @@ -305,7 +305,7 @@ MakeAnonFields(PyObject *type) Py_DECREF(anon_names); return -1; } - if (Py_TYPE(descr) != &PyCField_Type) { + if (!Py_TYPE_IS(descr, &PyCField_Type)) { PyErr_Format(PyExc_AttributeError, "'%U' is specified in _anonymous_ but not in " "_fields_", diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index a728a24f6caef9..04fe4dfc698cb2 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -247,8 +247,8 @@ PyCurses_ConvertToChtype(PyCursesWindowObject *win, PyObject *obj, chtype *ch) } else { PyErr_Format(PyExc_TypeError, - "expect bytes or str of length 1, or int, got %s", - Py_TYPE(obj)->tp_name); + "expect bytes or str of length 1, or int, got %T", + obj); return 0; } *ch = (chtype)value; @@ -315,8 +315,8 @@ PyCurses_ConvertToCchar_t(PyCursesWindowObject *win, PyObject *obj, } else { PyErr_Format(PyExc_TypeError, - "expect bytes or str of length 1, or int, got %s", - Py_TYPE(obj)->tp_name); + "expect bytes or str of length 1, or int, got %T", + obj); return 0; } @@ -370,8 +370,8 @@ PyCurses_ConvertToString(PyCursesWindowObject *win, PyObject *obj, return 1; } - PyErr_Format(PyExc_TypeError, "expect bytes or str, got %s", - Py_TYPE(obj)->tp_name); + PyErr_Format(PyExc_TypeError, "expect bytes or str, got %T", + obj); return 0; } @@ -4203,8 +4203,8 @@ PyCurses_ConvertToWchar_t(PyObject *obj, } else { PyErr_Format(PyExc_TypeError, - "expect bytes or str of length 1, or int, got %s", - Py_TYPE(obj)->tp_name); + "expect bytes or str of length 1, or int, got %T", + obj); return 0; } } diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index ac3f64e07264ba..5976b2f1462e98 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -1100,8 +1100,8 @@ check_tzinfo_subclass(PyObject *p) return 0; PyErr_Format(PyExc_TypeError, "tzinfo argument must be None or of a tzinfo subclass, " - "not type '%s'", - Py_TYPE(p)->tp_name); + "not type %T", + p); return -1; } @@ -1156,8 +1156,8 @@ call_tzinfo_method(PyObject *tzinfo, const char *name, PyObject *tzinfoarg) else { PyErr_Format(PyExc_TypeError, "tzinfo.%s() must return None or " - "timedelta, not '%.200s'", - name, Py_TYPE(offset)->tp_name); + "timedelta, not %T", + name, offset); Py_DECREF(offset); return NULL; } @@ -1220,8 +1220,8 @@ call_tzname(PyObject *tzinfo, PyObject *tzinfoarg) if (!PyUnicode_Check(result)) { PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must " - "return None or a string, not '%s'", - Py_TYPE(result)->tp_name); + "return None or a string, not %T", + result); Py_DECREF(result); result = NULL; } @@ -1689,8 +1689,8 @@ static PyObject * cmperror(PyObject *a, PyObject *b) { PyErr_Format(PyExc_TypeError, - "can't compare %s to %s", - Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name); + "can't compare %T to %T", + a, b); return NULL; } @@ -1887,8 +1887,8 @@ get_float_as_integer_ratio(PyObject *floatobj) if (!PyTuple_Check(ratio)) { PyErr_Format(PyExc_TypeError, "unexpected return type from as_integer_ratio(): " - "expected tuple, got '%.200s'", - Py_TYPE(ratio)->tp_name); + "expected tuple, got %T", + ratio); Py_DECREF(ratio); return NULL; } @@ -2383,8 +2383,8 @@ accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor, } PyErr_Format(PyExc_TypeError, - "unsupported type for timedelta %s component: %s", - tag, Py_TYPE(num)->tp_name); + "unsupported type for timedelta %s component: %T", + tag, num); return NULL; } @@ -2552,8 +2552,7 @@ delta_repr(PyDateTime_Delta *self) } } - PyObject *repr = PyUnicode_FromFormat("%s(%S)", Py_TYPE(self)->tp_name, - args); + PyObject *repr = PyUnicode_FromFormat("%T(%S)", self, args); Py_DECREF(args); return repr; } @@ -2617,7 +2616,7 @@ delta_total_seconds(PyObject *self, PyObject *Py_UNUSED(ignored)) static PyObject * delta_reduce(PyDateTime_Delta* self, PyObject *Py_UNUSED(ignored)) { - return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self)); + return Py_BuildValue("NN", Py_GetType(self), delta_getstate(self)); } #define OFFSET(field) offsetof(PyDateTime_Delta, field) @@ -3021,8 +3020,8 @@ date_subtract(PyObject *left, PyObject *right) static PyObject * date_repr(PyDateTime_Date *self) { - return PyUnicode_FromFormat("%s(%d, %d, %d)", - Py_TYPE(self)->tp_name, + return PyUnicode_FromFormat("%T(%d, %d, %d)", + self, GET_YEAR(self), GET_MONTH(self), GET_DAY(self)); } @@ -3159,7 +3158,9 @@ date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw) tuple = Py_BuildValue("iii", year, month, day); if (tuple == NULL) return NULL; - clone = date_new(Py_TYPE(self), tuple, NULL); + PyTypeObject *type = Py_GetType(self); + clone = date_new(type, tuple, NULL); + Py_DECREF(type); Py_DECREF(tuple); return clone; } @@ -3214,7 +3215,7 @@ date_getstate(PyDateTime_Date *self) static PyObject * date_reduce(PyDateTime_Date *self, PyObject *arg) { - return Py_BuildValue("(ON)", Py_TYPE(self), date_getstate(self)); + return Py_BuildValue("(NN)", Py_GetType(self), date_getstate(self)); } static PyMethodDef date_methods[] = { @@ -3517,10 +3518,10 @@ tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) if (state == Py_None) { Py_DECREF(state); - return Py_BuildValue("(ON)", Py_TYPE(self), args); + return Py_BuildValue("(NN)", Py_GetType(self), args); } else - return Py_BuildValue("(ONN)", Py_TYPE(self), args, state); + return Py_BuildValue("(NNN)", Py_GetType(self), args, state); } static PyMethodDef tzinfo_methods[] = { @@ -3608,7 +3609,9 @@ timezone_dealloc(PyDateTime_TimeZone *self) { Py_CLEAR(self->offset); Py_CLEAR(self->name); - Py_TYPE(self)->tp_free((PyObject *)self); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject *)self); + Py_DECREF(type); } static PyObject * @@ -3617,7 +3620,7 @@ timezone_richcompare(PyDateTime_TimeZone *self, { if (op != Py_EQ && op != Py_NE) Py_RETURN_NOTIMPLEMENTED; - if (Py_TYPE(other) != &PyDateTime_TimeZoneType) { + if (!Py_TYPE_IS(other, &PyDateTime_TimeZoneType)) { if (op == Py_EQ) Py_RETURN_FALSE; else @@ -3642,7 +3645,7 @@ _timezone_check_argument(PyObject *dt, const char *meth) if (dt == Py_None || PyDateTime_Check(dt)) return 0; PyErr_Format(PyExc_TypeError, "%s(dt) argument must be a datetime instance" - " or None, not %.200s", meth, Py_TYPE(dt)->tp_name); + " or None, not %T", meth, dt); return -1; } @@ -3650,16 +3653,15 @@ static PyObject * timezone_repr(PyDateTime_TimeZone *self) { /* Note that although timezone is not subclassable, it is convenient - to use Py_TYPE(self)->tp_name here. */ - const char *type_name = Py_TYPE(self)->tp_name; + to use %T format here. */ if (((PyObject *)self) == PyDateTime_TimeZone_UTC) - return PyUnicode_FromFormat("%s.utc", type_name); + return PyUnicode_FromFormat("%T.utc", self); if (self->name == NULL) - return PyUnicode_FromFormat("%s(%R)", type_name, self->offset); + return PyUnicode_FromFormat("%T(%R)", self, self->offset); - return PyUnicode_FromFormat("%s(%R, %R)", type_name, self->offset, + return PyUnicode_FromFormat("%T(%R, %R)", self, self->offset, self->name); } @@ -3984,7 +3986,9 @@ time_dealloc(PyDateTime_Time *self) if (HASTZINFO(self)) { Py_XDECREF(self->tzinfo); } - Py_TYPE(self)->tp_free((PyObject *)self); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject *)self); + Py_DECREF(type); } /* @@ -4014,7 +4018,6 @@ time_tzname(PyDateTime_Time *self, PyObject *unused) { static PyObject * time_repr(PyDateTime_Time *self) { - const char *type_name = Py_TYPE(self)->tp_name; int h = TIME_GET_HOUR(self); int m = TIME_GET_MINUTE(self); int s = TIME_GET_SECOND(self); @@ -4023,13 +4026,13 @@ time_repr(PyDateTime_Time *self) PyObject *result = NULL; if (us) - result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)", - type_name, h, m, s, us); + result = PyUnicode_FromFormat("%T(%d, %d, %d, %d)", + self, h, m, s, us); else if (s) - result = PyUnicode_FromFormat("%s(%d, %d, %d)", - type_name, h, m, s); + result = PyUnicode_FromFormat("%T(%d, %d, %d)", + self, h, m, s); else - result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m); + result = PyUnicode_FromFormat("%T(%d, %d)", self, h, m); if (result != NULL && HASTZINFO(self)) result = append_keyword_tzinfo(result, self->tzinfo); if (result != NULL && fold) @@ -4222,12 +4225,14 @@ time_hash(PyDateTime_Time *self) if (self->hashcode == -1) { PyObject *offset, *self0; if (TIME_GET_FOLD(self)) { + PyTypeObject *type = Py_GetType(self); self0 = new_time_ex2(TIME_GET_HOUR(self), TIME_GET_MINUTE(self), TIME_GET_SECOND(self), TIME_GET_MICROSECOND(self), HASTZINFO(self) ? self->tzinfo : Py_None, - 0, Py_TYPE(self)); + 0, type); + Py_DECREF(type); if (self0 == NULL) return -1; } @@ -4296,7 +4301,9 @@ time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw) tuple = Py_BuildValue("iiiiO", hh, mm, ss, us, tzinfo); if (tuple == NULL) return NULL; - clone = time_new(Py_TYPE(self), tuple, NULL); + PyTypeObject *type = Py_GetType(self); + clone = time_new(type, tuple, NULL); + Py_DECREF(type); if (clone != NULL) { TIME_SET_FOLD(clone, fold); } @@ -4389,13 +4396,13 @@ time_reduce_ex(PyDateTime_Time *self, PyObject *args) if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto)) return NULL; - return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, proto)); + return Py_BuildValue("(NN)", Py_GetType(self), time_getstate(self, proto)); } static PyObject * time_reduce(PyDateTime_Time *self, PyObject *arg) { - return Py_BuildValue("(ON)", Py_TYPE(self), time_getstate(self, 2)); + return Py_BuildValue("(NN)", Py_GetType(self), time_getstate(self, 2)); } static PyMethodDef time_methods[] = { @@ -4549,7 +4556,7 @@ static char *datetime_kws[] = { }; /* Check for invocation from pickle with __getstate__ state */ -static PyObject * +static int datetime_new1(PyTypeObject *type, PyObject *args, PyObject **objp) { if (!(PyTuple_GET_SIZE(args) >= 1 && PyTuple_GET_SIZE(args) <= 2)) { @@ -5050,7 +5057,9 @@ datetime_dealloc(PyDateTime_DateTime *self) if (HASTZINFO(self)) { Py_XDECREF(self->tzinfo); } - Py_TYPE(self)->tp_free((PyObject *)self); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject *)self); + Py_DECREF(type); } /* @@ -5220,13 +5229,12 @@ datetime_subtract(PyObject *left, PyObject *right) static PyObject * datetime_repr(PyDateTime_DateTime *self) { - const char *type_name = Py_TYPE(self)->tp_name; PyObject *baserepr; if (DATE_GET_MICROSECOND(self)) { baserepr = PyUnicode_FromFormat( - "%s(%d, %d, %d, %d, %d, %d, %d)", - type_name, + "%T(%d, %d, %d, %d, %d, %d, %d)", + self, GET_YEAR(self), GET_MONTH(self), GET_DAY(self), DATE_GET_HOUR(self), DATE_GET_MINUTE(self), DATE_GET_SECOND(self), @@ -5234,16 +5242,16 @@ datetime_repr(PyDateTime_DateTime *self) } else if (DATE_GET_SECOND(self)) { baserepr = PyUnicode_FromFormat( - "%s(%d, %d, %d, %d, %d, %d)", - type_name, + "%T(%d, %d, %d, %d, %d, %d)", + self, GET_YEAR(self), GET_MONTH(self), GET_DAY(self), DATE_GET_HOUR(self), DATE_GET_MINUTE(self), DATE_GET_SECOND(self)); } else { baserepr = PyUnicode_FromFormat( - "%s(%d, %d, %d, %d, %d)", - type_name, + "%T(%d, %d, %d, %d, %d)", + self, GET_YEAR(self), GET_MONTH(self), GET_DAY(self), DATE_GET_HOUR(self), DATE_GET_MINUTE(self)); } @@ -5341,7 +5349,9 @@ datetime_ctime(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) static PyObject * flip_fold(PyObject *dt) { - return new_datetime_ex2(GET_YEAR(dt), + PyObject *res; + PyTypeObject *type = Py_GetType(dt); + res = new_datetime_ex2(GET_YEAR(dt), GET_MONTH(dt), GET_DAY(dt), DATE_GET_HOUR(dt), @@ -5351,7 +5361,9 @@ flip_fold(PyObject *dt) HASTZINFO(dt) ? ((PyDateTime_DateTime *)dt)->tzinfo : Py_None, !DATE_GET_FOLD(dt), - Py_TYPE(dt)); + type); + Py_DECREF(type); + return res; } static PyObject * @@ -5505,6 +5517,7 @@ datetime_hash(PyDateTime_DateTime *self) if (self->hashcode == -1) { PyObject *offset, *self0; if (DATE_GET_FOLD(self)) { + PyTypeObject *type = Py_GetType(self); self0 = new_datetime_ex2(GET_YEAR(self), GET_MONTH(self), GET_DAY(self), @@ -5513,7 +5526,8 @@ datetime_hash(PyDateTime_DateTime *self) DATE_GET_SECOND(self), DATE_GET_MICROSECOND(self), HASTZINFO(self) ? self->tzinfo : Py_None, - 0, Py_TYPE(self)); + 0, type); + Py_DECREF(type); if (self0 == NULL) return -1; } @@ -5591,7 +5605,9 @@ datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) tuple = Py_BuildValue("iiiiiiiO", y, m, d, hh, mm, ss, us, tzinfo); if (tuple == NULL) return NULL; - clone = datetime_new(Py_TYPE(self), tuple, NULL); + PyTypeObject *type = Py_GetType(self); + clone = datetime_new(type, tuple, NULL); + Py_DECREF(type); if (clone != NULL) { DATE_SET_FOLD(clone, fold); } @@ -5758,8 +5774,8 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) } else if (!PyDelta_Check(offset)) { Py_DECREF(offset); - PyErr_Format(PyExc_TypeError, "utcoffset() returned %.200s," - " expected timedelta or None", Py_TYPE(offset)->tp_name); + PyErr_Format(PyExc_TypeError, "utcoffset() returned %T," + " expected timedelta or None", offset); return NULL; } /* result = self - offset */ @@ -5772,6 +5788,7 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) /* Make sure result is aware and UTC. */ if (!HASTZINFO(result)) { temp = (PyObject *)result; + PyTypeObject *type = Py_GetType(result); result = (PyDateTime_DateTime *) new_datetime_ex2(GET_YEAR(result), GET_MONTH(result), @@ -5782,7 +5799,8 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) DATE_GET_MICROSECOND(result), PyDateTime_TimeZone_UTC, DATE_GET_FOLD(result), - Py_TYPE(result)); + type); + Py_DECREF(type); Py_DECREF(temp); if (result == NULL) return NULL; @@ -6028,13 +6046,13 @@ datetime_reduce_ex(PyDateTime_DateTime *self, PyObject *args) if (!PyArg_ParseTuple(args, "i:__reduce_ex__", &proto)) return NULL; - return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, proto)); + return Py_BuildValue("(NN)", Py_GetType(self), datetime_getstate(self, proto)); } static PyObject * datetime_reduce(PyDateTime_DateTime *self, PyObject *arg) { - return Py_BuildValue("(ON)", Py_TYPE(self), datetime_getstate(self, 2)); + return Py_BuildValue("(NN)", Py_GetType(self), datetime_getstate(self, 2)); } static PyMethodDef datetime_methods[] = { diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 02ecffd5099812..7ae58f0659f39f 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -96,9 +96,9 @@ static PyTypeObject PyDec_Type; static PyTypeObject *PyDecSignalDict_Type; static PyTypeObject PyDecContext_Type; static PyTypeObject PyDecContextManager_Type; -#define PyDec_CheckExact(v) (Py_TYPE(v) == &PyDec_Type) +#define PyDec_CheckExact(v) Py_TYPE_IS(v, &PyDec_Type) #define PyDec_Check(v) PyObject_TypeCheck(v, &PyDec_Type) -#define PyDecSignalDict_Check(v) (Py_TYPE(v) == PyDecSignalDict_Type) +#define PyDecSignalDict_Check(v) Py_TYPE_IS(v, PyDecSignalDict_Type) #define PyDecContext_Check(v) PyObject_TypeCheck(v, &PyDecContext_Type) #define MPD(v) (&((PyDecObject *)v)->dec) #define SdFlagAddr(v) (((PyDecSignalDictObject *)v)->flags) @@ -1219,7 +1219,9 @@ context_dealloc(PyDecContextObject *self) { Py_XDECREF(self->traps); Py_XDECREF(self->flags); - Py_TYPE(self)->tp_free(self); + PyTypeObject *type = Py_GetType(self); + type->tp_free(self); + Py_DECREF(type); } static int @@ -1433,8 +1435,8 @@ context_reduce(PyObject *self, PyObject *args UNUSED) } ret = Py_BuildValue( - "O(nsnniiOO)", - Py_TYPE(self), + "N(nsnniiOO)", + Py_GetType(self), ctx->prec, mpd_round_string[ctx->round], ctx->emin, ctx->emax, CtxCaps(self), ctx->clamp, flags, traps ); @@ -1727,7 +1729,9 @@ static void dec_dealloc(PyObject *dec) { mpd_del(MPD(dec)); - Py_TYPE(dec)->tp_free(dec); + PyTypeObject *type = Py_GetType(dec); + type->tp_free(dec); + Py_DECREF(type); } @@ -4512,7 +4516,7 @@ dec_reduce(PyObject *self, PyObject *dummy UNUSED) return NULL; } - result = Py_BuildValue("O(O)", Py_TYPE(self), str); + result = Py_BuildValue("N(O)", Py_GetType(self), str); Py_DECREF(str); return result; @@ -4524,7 +4528,9 @@ dec_sizeof(PyObject *v, PyObject *dummy UNUSED) { Py_ssize_t res; - res = _PyObject_SIZE(Py_TYPE(v)); + PyTypeObject *type = Py_GetType(v); + res = _PyObject_SIZE(type); + Py_DECREF(type); if (mpd_isdynamic_data(MPD(v))) { res += MPD(v)->alloc * sizeof(mpd_uint_t); } diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 119c9fdf4f82e3..13fca1ab14764a 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -203,7 +203,7 @@ typedef struct { } ElementObject; -#define Element_CheckExact(op) (Py_TYPE(op) == &Element_Type) +#define Element_CheckExact(op) (Py_TYPE_IS(op, &Element_Type)) /* -------------------------------------------------------------------- */ /* Element constructors and destructor */ @@ -332,8 +332,8 @@ get_attrib_from_keywords(PyObject *kwds) */ if (!PyDict_Check(attrib)) { Py_DECREF(attrib_str); - PyErr_Format(PyExc_TypeError, "attrib must be dict, not %.100s", - Py_TYPE(attrib)->tp_name); + PyErr_Format(PyExc_TypeError, "attrib must be dict, not %T", + attrib); return NULL; } attrib = PyDict_Copy(attrib); @@ -641,7 +641,9 @@ element_dealloc(ElementObject* self) element_gc_clear(self); RELEASE(sizeof(ElementObject), "destroy element"); - Py_TYPE(self)->tp_free((PyObject *)self); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject *)self); + Py_DECREF(type); Py_TRASHCAN_SAFE_END(self) } @@ -873,7 +875,9 @@ static Py_ssize_t _elementtree_Element___sizeof___impl(ElementObject *self) /*[clinic end generated code: output=bf73867721008000 input=70f4b323d55a17c1]*/ { - Py_ssize_t result = _PyObject_SIZE(Py_TYPE(self)); + PyTypeObject *type = Py_GetType(self); + Py_ssize_t result = _PyObject_SIZE(type); + Py_DECREF(type); if (self->extra) { result += sizeof(ElementObjectExtra); if (self->extra->children != self->extra->_children) @@ -1124,7 +1128,7 @@ _elementtree_Element_extend(ElementObject *self, PyObject *elements) if (!seq) { PyErr_Format( PyExc_TypeError, - "expected sequence, not \"%.200s\"", Py_TYPE(elements)->tp_name + "expected sequence, not \"%T\"", elements ); return NULL; } @@ -1134,8 +1138,8 @@ _elementtree_Element_extend(ElementObject *self, PyObject *elements) if (!PyObject_TypeCheck(element, (PyTypeObject *)&Element_Type)) { PyErr_Format( PyExc_TypeError, - "expected an Element, not \"%.200s\"", - Py_TYPE(element)->tp_name); + "expected an Element, not \"%T\"", + element); Py_DECREF(seq); Py_DECREF(element); return NULL; @@ -1648,8 +1652,8 @@ element_repr(ElementObject* self) } if (status > 0) PyErr_Format(PyExc_RuntimeError, - "reentrant call inside %s.__repr__", - Py_TYPE(self)->tp_name); + "reentrant call inside %T.__repr__", + self); return NULL; } @@ -1870,7 +1874,7 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value) if (!seq) { PyErr_Format( PyExc_TypeError, - "expected sequence, not \"%.200s\"", Py_TYPE(value)->tp_name + "expected sequence, not \"%T\"", value ); return -1; } @@ -2173,8 +2177,8 @@ elementiter_next(ElementIterObject *it) if (!PyObject_TypeCheck(extra->children[child_index], &Element_Type)) { PyErr_Format(PyExc_AttributeError, - "'%.100s' object has no attribute 'iter'", - Py_TYPE(extra->children[child_index])->tp_name); + "'%T' object has no attribute 'iter'", + extra->children[child_index]); return NULL; } elem = (ElementObject *)extra->children[child_index]; @@ -2330,7 +2334,7 @@ typedef struct { PyObject *end_ns_event_obj; } TreeBuilderObject; -#define TreeBuilder_CheckExact(op) (Py_TYPE(op) == &TreeBuilder_Type) +#define TreeBuilder_CheckExact(op) (Py_TYPE_IS(op, &TreeBuilder_Type)) /* -------------------------------------------------------------------- */ /* constructor and destructor */ @@ -2419,7 +2423,9 @@ treebuilder_dealloc(TreeBuilderObject *self) { PyObject_GC_UnTrack(self); treebuilder_gc_clear(self); - Py_TYPE(self)->tp_free((PyObject *)self); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject *)self); + Py_DECREF(type); } /* -------------------------------------------------------------------- */ @@ -3396,7 +3402,9 @@ xmlparser_dealloc(XMLParserObject* self) { PyObject_GC_UnTrack(self); xmlparser_gc_clear(self); - Py_TYPE(self)->tp_free((PyObject *)self); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject *)self); + Py_DECREF(type); } LOCAL(PyObject*) diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c index 10560040e446b3..d8cf76b64bed70 100644 --- a/Modules/_gdbmmodule.c +++ b/Modules/_gdbmmodule.c @@ -44,7 +44,7 @@ static PyTypeObject Dbmtype; #include "clinic/_gdbmmodule.c.h" -#define is_dbmobject(v) (Py_TYPE(v) == &Dbmtype) +#define is_dbmobject(v) (Py_TYPE_IS(v, &Dbmtype)) #define check_dbmobject_open(v) if ((v)->di_dbm == NULL) \ { PyErr_SetString(DbmError, "GDBM object has already been closed"); \ return NULL; } diff --git a/Modules/_json.c b/Modules/_json.c index c54de0a3e389f5..07a909726f2b8a 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -16,9 +16,9 @@ #endif #define PyScanner_Check(op) PyObject_TypeCheck(op, &PyScannerType) -#define PyScanner_CheckExact(op) (Py_TYPE(op) == &PyScannerType) +#define PyScanner_CheckExact(op) (Py_TYPE_IS(op, &PyScannerType)) #define PyEncoder_Check(op) PyObject_TypeCheck(op, &PyEncoderType) -#define PyEncoder_CheckExact(op) (Py_TYPE(op) == &PyEncoderType) +#define PyEncoder_CheckExact(op) (Py_TYPE_IS(op, &PyEncoderType)) static PyTypeObject PyScannerType; static PyTypeObject PyEncoderType; @@ -605,8 +605,8 @@ py_scanstring(PyObject* self UNUSED, PyObject *args) } else { PyErr_Format(PyExc_TypeError, - "first argument must be a string, not %.80s", - Py_TYPE(pystr)->tp_name); + "first argument must be a string, not %T", + pystr); return NULL; } return _build_rval_index_tuple(rval, next_end); @@ -629,8 +629,8 @@ py_encode_basestring_ascii(PyObject* self UNUSED, PyObject *pystr) } else { PyErr_Format(PyExc_TypeError, - "first argument must be a string, not %.80s", - Py_TYPE(pystr)->tp_name); + "first argument must be a string, not %T", + pystr); return NULL; } return rval; @@ -654,8 +654,8 @@ py_encode_basestring(PyObject* self UNUSED, PyObject *pystr) } else { PyErr_Format(PyExc_TypeError, - "first argument must be a string, not %.80s", - Py_TYPE(pystr)->tp_name); + "first argument must be a string, not %T", + pystr); return NULL; } return rval; @@ -667,7 +667,9 @@ scanner_dealloc(PyObject *self) /* bpo-31095: UnTrack is needed before calling any callbacks */ PyObject_GC_UnTrack(self); scanner_clear(self); - Py_TYPE(self)->tp_free(self); + PyTypeObject *type = Py_GetType(self); + type->tp_free(self); + Py_DECREF(type); } static int @@ -1183,8 +1185,8 @@ scanner_call(PyObject *self, PyObject *args, PyObject *kwds) } else { PyErr_Format(PyExc_TypeError, - "first argument must be a string, not %.80s", - Py_TYPE(pystr)->tp_name); + "first argument must be a string, not %T", + pystr); return NULL; } PyDict_Clear(s->memo); @@ -1308,7 +1310,7 @@ encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (markers != Py_None && !PyDict_Check(markers)) { PyErr_Format(PyExc_TypeError, "make_encoder() argument 1 must be dict or None, " - "not %.200s", Py_TYPE(markers)->tp_name); + "not %T", markers); return NULL; } @@ -1439,8 +1441,8 @@ encoder_encode_string(PyEncoderObject *s, PyObject *obj) encoded = PyObject_CallFunctionObjArgs(s->encoder, obj, NULL); if (encoded != NULL && !PyUnicode_Check(encoded)) { PyErr_Format(PyExc_TypeError, - "encoder() must return a string, not %.80s", - Py_TYPE(encoded)->tp_name); + "encoder() must return a string, not %T", + encoded); Py_DECREF(encoded); return NULL; } @@ -1812,7 +1814,9 @@ encoder_dealloc(PyObject *self) /* bpo-31095: UnTrack is needed before calling any callbacks */ PyObject_GC_UnTrack(self); encoder_clear(self); - Py_TYPE(self)->tp_free(self); + PyTypeObject *type = Py_GetType(self); + type->tp_free(self); + Py_DECREF(type); } static int diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index 233f62fe2f14e9..11e3740c68a8fe 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -110,7 +110,7 @@ typedef struct { static PyTypeObject PyProfiler_Type; #define PyProfiler_Check(op) PyObject_TypeCheck(op, &PyProfiler_Type) -#define PyProfiler_CheckExact(op) (Py_TYPE(op) == &PyProfiler_Type) +#define PyProfiler_CheckExact(op) (Py_TYPE_IS(op, &PyProfiler_Type)) /*** External Timers ***/ @@ -201,7 +201,9 @@ normalizeUserObj(PyObject *obj) PyObject *modname = fn->m_module; if (name != NULL) { - PyObject *mo = _PyType_Lookup(Py_TYPE(self), name); + PyTypeObject *type = Py_GetType(self); + PyObject *mo = _PyType_Lookup(type, name); + Py_DECREF(type); Py_XINCREF(mo); Py_DECREF(name); if (mo != NULL) { @@ -749,7 +751,9 @@ profiler_dealloc(ProfilerObject *op) flush_unmatched(op); clearEntries(op); Py_XDECREF(op->externalTimer); - Py_TYPE(op)->tp_free(op); + PyTypeObject *type = Py_GetType(op); + type->tp_free(op); + Py_DECREF(type); } static int diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c index 7b501d8202d8b9..0274b1d7bc06f3 100644 --- a/Modules/_lzmamodule.c +++ b/Modules/_lzmamodule.c @@ -594,8 +594,8 @@ _lzma_LZMACompressor_flush_impl(Compressor *self) static PyObject * Compressor_getstate(Compressor *self, PyObject *noargs) { - PyErr_Format(PyExc_TypeError, "cannot serialize '%s' object", - Py_TYPE(self)->tp_name); + PyErr_Format(PyExc_TypeError, "cannot serialize %T object", + self); return NULL; } @@ -788,7 +788,9 @@ Compressor_dealloc(Compressor *self) lzma_end(&self->lzs); if (self->lock != NULL) PyThread_free_lock(self->lock); - Py_TYPE(self)->tp_free((PyObject *)self); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject *)self); + Py_DECREF(type); } static PyMethodDef Compressor_methods[] = { @@ -1081,8 +1083,8 @@ _lzma_LZMADecompressor_decompress_impl(Decompressor *self, Py_buffer *data, static PyObject * Decompressor_getstate(Decompressor *self, PyObject *noargs) { - PyErr_Format(PyExc_TypeError, "cannot serialize '%s' object", - Py_TYPE(self)->tp_name); + PyErr_Format(PyExc_TypeError, "cannot serialize %T object", + self); return NULL; } @@ -1230,7 +1232,9 @@ Decompressor_dealloc(Decompressor *self) Py_CLEAR(self->unused_data); if (self->lock != NULL) PyThread_free_lock(self->lock); - Py_TYPE(self)->tp_free((PyObject *)self); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject *)self); + Py_DECREF(type); } static PyMethodDef Decompressor_methods[] = { diff --git a/Modules/_pickle.c b/Modules/_pickle.c index fd73d84a5ce503..c7861f7ef18b12 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -231,8 +231,8 @@ _Pickle_InitState(PickleState *st) goto error; if (!PyDict_CheckExact(st->dispatch_table)) { PyErr_Format(PyExc_RuntimeError, - "copyreg.dispatch_table should be a dict, not %.200s", - Py_TYPE(st->dispatch_table)->tp_name); + "copyreg.dispatch_table should be a dict, not %T", + st->dispatch_table); goto error; } st->extension_registry = \ @@ -242,7 +242,7 @@ _Pickle_InitState(PickleState *st) if (!PyDict_CheckExact(st->extension_registry)) { PyErr_Format(PyExc_RuntimeError, "copyreg._extension_registry should be a dict, " - "not %.200s", Py_TYPE(st->extension_registry)->tp_name); + "not %T", st->extension_registry); goto error; } st->inverted_registry = \ @@ -252,7 +252,7 @@ _Pickle_InitState(PickleState *st) if (!PyDict_CheckExact(st->inverted_registry)) { PyErr_Format(PyExc_RuntimeError, "copyreg._inverted_registry should be a dict, " - "not %.200s", Py_TYPE(st->inverted_registry)->tp_name); + "not %T", st->inverted_registry); goto error; } st->extension_cache = PyObject_GetAttrString(copyreg, "_extension_cache"); @@ -261,7 +261,7 @@ _Pickle_InitState(PickleState *st) if (!PyDict_CheckExact(st->extension_cache)) { PyErr_Format(PyExc_RuntimeError, "copyreg._extension_cache should be a dict, " - "not %.200s", Py_TYPE(st->extension_cache)->tp_name); + "not %T", st->extension_cache); goto error; } Py_CLEAR(copyreg); @@ -277,7 +277,7 @@ _Pickle_InitState(PickleState *st) if (!PyDict_CheckExact(st->name_mapping_2to3)) { PyErr_Format(PyExc_RuntimeError, "_compat_pickle.NAME_MAPPING should be a dict, not %.200s", - Py_TYPE(st->name_mapping_2to3)->tp_name); + st->name_mapping_2to3); goto error; } st->import_mapping_2to3 = \ @@ -287,7 +287,7 @@ _Pickle_InitState(PickleState *st) if (!PyDict_CheckExact(st->import_mapping_2to3)) { PyErr_Format(PyExc_RuntimeError, "_compat_pickle.IMPORT_MAPPING should be a dict, " - "not %.200s", Py_TYPE(st->import_mapping_2to3)->tp_name); + "not %T", st->import_mapping_2to3); goto error; } /* ... and the 3.x -> 2.x mapping tables */ @@ -298,7 +298,7 @@ _Pickle_InitState(PickleState *st) if (!PyDict_CheckExact(st->name_mapping_3to2)) { PyErr_Format(PyExc_RuntimeError, "_compat_pickle.REVERSE_NAME_MAPPING should be a dict, " - "not %.200s", Py_TYPE(st->name_mapping_3to2)->tp_name); + "not %T", st->name_mapping_3to2); goto error; } st->import_mapping_3to2 = \ @@ -308,7 +308,7 @@ _Pickle_InitState(PickleState *st) if (!PyDict_CheckExact(st->import_mapping_3to2)) { PyErr_Format(PyExc_RuntimeError, "_compat_pickle.REVERSE_IMPORT_MAPPING should be a dict, " - "not %.200s", Py_TYPE(st->import_mapping_3to2)->tp_name); + "not %T", st->import_mapping_3to2); goto error; } Py_CLEAR(compat_pickle); @@ -323,7 +323,7 @@ _Pickle_InitState(PickleState *st) if (!PyCallable_Check(st->codecs_encode)) { PyErr_Format(PyExc_RuntimeError, "codecs.encode should be a callable, not %.200s", - Py_TYPE(st->codecs_encode)->tp_name); + st->codecs_encode); goto error; } Py_CLEAR(codecs); @@ -3277,8 +3277,8 @@ fix_imports(PyObject **module_name, PyObject **global_name) if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) { PyErr_Format(PyExc_RuntimeError, "_compat_pickle.REVERSE_NAME_MAPPING values " - "should be 2-tuples, not %.200s", - Py_TYPE(item)->tp_name); + "should be 2-tuples, not %T", + item); return -1; } fixed_module_name = PyTuple_GetItemRef(item, 0); @@ -3289,9 +3289,9 @@ fix_imports(PyObject **module_name, PyObject **global_name) Py_DECREF(fixed_global_name); PyErr_Format(PyExc_RuntimeError, "_compat_pickle.REVERSE_NAME_MAPPING values " - "should be pairs of str, not (%.200s, %.200s)", - Py_TYPE(fixed_module_name)->tp_name, - Py_TYPE(fixed_global_name)->tp_name); + "should be pairs of str, not (%T, %T)", + fixed_module_name, + fixed_global_name); return -1; } @@ -3310,8 +3310,8 @@ fix_imports(PyObject **module_name, PyObject **global_name) if (!PyUnicode_Check(item)) { PyErr_Format(PyExc_RuntimeError, "_compat_pickle.REVERSE_IMPORT_MAPPING values " - "should be strings, not %.200s", - Py_TYPE(item)->tp_name); + "should be strings, not %T", + item); return -1; } Py_INCREF(item); @@ -3673,8 +3673,7 @@ get_class(PyObject *obj) _Py_IDENTIFIER(__class__); if (_PyObject_LookupAttrId(obj, &PyId___class__, &cls) == 0) { - cls = (PyObject *) Py_TYPE(obj); - Py_INCREF(cls); + cls = (PyObject *) Py_GetType(obj); } return cls; } @@ -3728,8 +3727,8 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) listitems = NULL; else if (!PyIter_Check(listitems)) { PyErr_Format(st->PicklingError, "fourth element of the tuple " - "returned by __reduce__ must be an iterator, not %s", - Py_TYPE(listitems)->tp_name); + "returned by __reduce__ must be an iterator, not %T", + listitems); return -1; } @@ -3737,8 +3736,8 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) dictitems = NULL; else if (!PyIter_Check(dictitems)) { PyErr_Format(st->PicklingError, "fifth element of the tuple " - "returned by __reduce__ must be an iterator, not %s", - Py_TYPE(dictitems)->tp_name); + "returned by __reduce__ must be an iterator, not %T", + dictitems); return -1; } @@ -3778,7 +3777,7 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) Py_DECREF(cls); PyErr_Format(st->PicklingError, "first item from NEWOBJ_EX argument tuple must " - "be a class, not %.200s", Py_TYPE(cls)->tp_name); + "be a class, not %T", cls); return -1; } args = PyTuple_GetItemRef(argtup, 1); @@ -3787,7 +3786,7 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) Py_DECREF(args); PyErr_Format(st->PicklingError, "second item from NEWOBJ_EX argument tuple must " - "be a tuple, not %.200s", Py_TYPE(args)->tp_name); + "be a tuple, not %T", args); return -1; } kwargs = PyTuple_GetItemRef(argtup, 2); @@ -3797,7 +3796,7 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) Py_DECREF(kwargs); PyErr_Format(st->PicklingError, "third item from NEWOBJ_EX argument tuple must " - "be a dict, not %.200s", Py_TYPE(kwargs)->tp_name); + "be a dict, not %T", kwargs); return -1; } Py_DECREF(cls); @@ -4000,7 +3999,8 @@ save(PicklerObject *self, PyObject *obj, int pers_save) return status; } - type = Py_TYPE(obj); + type = Py_GetType(obj); + Py_DECREF(type); /* The old cPickle had an optimization that used switch-case statement dispatching on the first letter of the type name. This has was removed @@ -4247,8 +4247,8 @@ _pickle_Pickler_dump(PicklerObject *self, PyObject *obj) if (self->write == NULL) { PickleState *st = _Pickle_GetGlobalState(); PyErr_Format(st->PicklingError, - "Pickler.__init__() was not called by %s.__init__()", - Py_TYPE(self)->tp_name); + "Pickler.__init__() was not called by %T.__init__()", + self); return NULL; } @@ -4277,7 +4277,9 @@ _pickle_Pickler___sizeof___impl(PicklerObject *self) { Py_ssize_t res, s; - res = _PyObject_SIZE(Py_TYPE(self)); + PyTypeObject *type = Py_GetType(self); + res = _PyObject_SIZE(type); + Py_DECREF(type); if (self->memo != NULL) { res += sizeof(PyMemoTable); res += self->memo->mt_allocated * sizeof(PyMemoEntry); @@ -4311,7 +4313,9 @@ Pickler_dealloc(PicklerObject *self) PyMemoTable_Del(self->memo); - Py_TYPE(self)->tp_free((PyObject *)self); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject *)self); + Py_DECREF(type); } static int @@ -4620,7 +4624,7 @@ Pickler_set_memo(PicklerObject *self, PyObject *obj) return -1; } - if (Py_TYPE(obj) == &PicklerMemoProxyType) { + if (Py_TYPE_IS(obj, &PicklerMemoProxyType)) { PicklerObject *pickler = ((PicklerMemoProxyObject *)obj)->pickler; @@ -4661,7 +4665,7 @@ Pickler_set_memo(PicklerObject *self, PyObject *obj) else { PyErr_Format(PyExc_TypeError, "'memo' attribute must be a PicklerMemoProxy object" - "or dict, not %.200s", Py_TYPE(obj)->tp_name); + "or dict, not %T", obj); return -1; } @@ -5559,8 +5563,8 @@ load_newobj_ex(UnpicklerObject *self) Py_DECREF(kwargs); Py_DECREF(args); PyErr_Format(st->UnpicklingError, - "NEWOBJ_EX class argument must be a type, not %.200s", - Py_TYPE(cls)->tp_name); + "NEWOBJ_EX class argument must be a type, not %T", + cls); Py_DECREF(cls); return -1; } @@ -6587,8 +6591,8 @@ _pickle_Unpickler_load_impl(UnpicklerObject *self) if (unpickler->read == NULL) { PickleState *st = _Pickle_GetGlobalState(); PyErr_Format(st->UnpicklingError, - "Unpickler.__init__() was not called by %s.__init__()", - Py_TYPE(unpickler)->tp_name); + "Unpickler.__init__() was not called by %T.__init__()", + unpickler); return NULL; } @@ -6645,7 +6649,7 @@ _pickle_Unpickler_find_class_impl(UnpicklerObject *self, if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) { PyErr_Format(PyExc_RuntimeError, "_compat_pickle.NAME_MAPPING values should be " - "2-tuples, not %.200s", Py_TYPE(item)->tp_name); + "2-tuples, not %T", item); return NULL; } module_name = PyTuple_GetItemRef(item, 0); @@ -6656,9 +6660,9 @@ _pickle_Unpickler_find_class_impl(UnpicklerObject *self, Py_DECREF(global_name); PyErr_Format(PyExc_RuntimeError, "_compat_pickle.NAME_MAPPING values should be " - "pairs of str, not (%.200s, %.200s)", - Py_TYPE(module_name)->tp_name, - Py_TYPE(global_name)->tp_name); + "pairs of str, not (%T, %T)", + module_name, + global_name); return NULL; } Py_DECREF(module_name); @@ -6674,7 +6678,7 @@ _pickle_Unpickler_find_class_impl(UnpicklerObject *self, if (!PyUnicode_Check(item)) { PyErr_Format(PyExc_RuntimeError, "_compat_pickle.IMPORT_MAPPING values should be " - "strings, not %.200s", Py_TYPE(item)->tp_name); + "strings, not %T", item); return NULL; } module_name = item; @@ -6711,7 +6715,9 @@ _pickle_Unpickler___sizeof___impl(UnpicklerObject *self) { Py_ssize_t res; - res = _PyObject_SIZE(Py_TYPE(self)); + PyTypeObject *type = Py_GetType(self); + res = _PyObject_SIZE(type); + Py_DECREF(type); if (self->memo != NULL) res += self->memo_size * sizeof(PyObject *); if (self->marks != NULL) @@ -6752,7 +6758,9 @@ Unpickler_dealloc(UnpicklerObject *self) PyMem_Free(self->encoding); PyMem_Free(self->errors); - Py_TYPE(self)->tp_free((PyObject *)self); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject *)self); + Py_DECREF(type); } static int @@ -7066,7 +7074,7 @@ Unpickler_set_memo(UnpicklerObject *self, PyObject *obj) return -1; } - if (Py_TYPE(obj) == &UnpicklerMemoProxyType) { + if (Py_TYPE_IS(obj, &UnpicklerMemoProxyType)) { UnpicklerObject *unpickler = ((UnpicklerMemoProxyObject *)obj)->unpickler; @@ -7111,7 +7119,7 @@ Unpickler_set_memo(UnpicklerObject *self, PyObject *obj) else { PyErr_Format(PyExc_TypeError, "'memo' attribute must be an UnpicklerMemoProxy object" - "or dict, not %.200s", Py_TYPE(obj)->tp_name); + "or dict, not %T", obj); return -1; } diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index 0eb99302745940..7e461700111dca 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -36,7 +36,9 @@ simplequeue_dealloc(simplequeueobject *self) Py_XDECREF(self->lst); if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) self); - Py_TYPE(self)->tp_free(self); + PyTypeObject *type = Py_GetType(self); + type->tp_free(self); + Py_DECREF(type); } static int diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c index 8bc697d1ec47e5..bf8611b641726d 100644 --- a/Modules/_sha3/sha3module.c +++ b/Modules/_sha3/sha3module.c @@ -278,7 +278,10 @@ _sha3_sha3_224_copy_impl(SHA3object *self) { SHA3object *newobj; - if ((newobj = newSHA3object(Py_TYPE(self))) == NULL) { + PyTypeObject *type = Py_GetType(self); + newobj = newSHA3object(type); + Py_DECREF(type); + if (newobj == NULL) { return NULL; } ENTER_HASHLIB(self); @@ -412,7 +415,8 @@ SHA3_get_block_size(SHA3object *self, void *closure) static PyObject * SHA3_get_name(SHA3object *self, void *closure) { - PyTypeObject *type = Py_TYPE(self); + PyTypeObject *type = Py_GetType(self); + Py_DECREF(type); if (type == &SHA3_224type) { return PyUnicode_FromString("sha3_224"); } else if (type == &SHA3_256type) { diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index 72b1f2c5614bf4..191bd5ddecb647 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -51,7 +51,9 @@ void pysqlite_node_dealloc(pysqlite_Node* self) Py_DECREF(self->key); Py_DECREF(self->data); - Py_TYPE(self)->tp_free((PyObject*)self); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject*)self); + Py_DECREF(type); } int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs) @@ -109,7 +111,9 @@ void pysqlite_cache_dealloc(pysqlite_Cache* self) } Py_DECREF(self->mapping); - Py_TYPE(self)->tp_free((PyObject*)self); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject*)self); + Py_DECREF(type); } PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* args) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index f1043d52ff886c..28a45a87e279e8 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -262,7 +262,9 @@ void pysqlite_connection_dealloc(pysqlite_Connection* self) Py_XDECREF(self->statements); Py_XDECREF(self->cursors); - Py_TYPE(self)->tp_free((PyObject*)self); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject*)self); + Py_DECREF(type); } /* @@ -315,8 +317,8 @@ PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args, return NULL; if (!PyObject_TypeCheck(cursor, &pysqlite_CursorType)) { PyErr_Format(PyExc_TypeError, - "factory must return a cursor, not %.100s", - Py_TYPE(cursor)->tp_name); + "factory must return a cursor, not %T", + cursor); Py_DECREF(cursor); return NULL; } @@ -1181,8 +1183,8 @@ static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, Py if (!PyUnicode_Check(isolation_level)) { PyErr_Format(PyExc_TypeError, - "isolation_level must be a string or None, not %.100s", - Py_TYPE(isolation_level)->tp_name); + "isolation_level must be a string or None, not %T", + isolation_level); return -1; } diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index cd5a32c8ec1097..b82e5ca194cc11 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -91,7 +91,9 @@ static void pysqlite_cursor_dealloc(pysqlite_Cursor* self) PyObject_ClearWeakRefs((PyObject*)self); } - Py_TYPE(self)->tp_free((PyObject*)self); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject*)self); + Py_DECREF(type); } PyObject* _pysqlite_get_converter(PyObject* key) diff --git a/Modules/_sqlite/prepare_protocol.c b/Modules/_sqlite/prepare_protocol.c index da812af919f13d..f75570a951489a 100644 --- a/Modules/_sqlite/prepare_protocol.c +++ b/Modules/_sqlite/prepare_protocol.c @@ -30,7 +30,9 @@ int pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol* self, PyObject* arg void pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol* self) { - Py_TYPE(self)->tp_free((PyObject*)self); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject*)self); + Py_DECREF(type); } PyTypeObject pysqlite_PrepareProtocolType= { diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c index 53b68a7076a4f4..c20e47269695af 100644 --- a/Modules/_sqlite/row.c +++ b/Modules/_sqlite/row.c @@ -29,7 +29,9 @@ void pysqlite_row_dealloc(pysqlite_Row* self) Py_XDECREF(self->data); Py_XDECREF(self->description); - Py_TYPE(self)->tp_free((PyObject*)self); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject*)self); + Py_DECREF(type); } static PyObject * @@ -192,7 +194,9 @@ static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other, if (opid != Py_EQ && opid != Py_NE) Py_RETURN_NOTIMPLEMENTED; - if (PyType_IsSubtype(Py_TYPE(_other), &pysqlite_RowType)) { + PyTypeObject *other_type = Py_GetType(_other); + Py_DECREF(other_type); + if (PyType_IsSubtype(other_type, &pysqlite_RowType)) { pysqlite_Row *other = (pysqlite_Row *)_other; PyObject *res = PyObject_RichCompare(self->description, other->description, opid); if ((opid == Py_EQ && res == Py_True) diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index d4564d0bdd730f..a8de5c72fbfbcd 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -375,7 +375,9 @@ void pysqlite_statement_dealloc(pysqlite_Statement* self) PyObject_ClearWeakRefs((PyObject*)self); } - Py_TYPE(self)->tp_free((PyObject*)self); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject*)self); + Py_DECREF(type); } /* diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 067f113d3f9ed1..a62651344d58f6 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -485,9 +485,9 @@ static int PySSL_select(PySocketSockObject *s, int writing, _PyTime_t timeout); static int PySSL_set_owner(PySSLSocket *, PyObject *, void *); static int PySSL_set_session(PySSLSocket *, PyObject *, void *); -#define PySSLSocket_Check(v) (Py_TYPE(v) == &PySSLSocket_Type) -#define PySSLMemoryBIO_Check(v) (Py_TYPE(v) == &PySSLMemoryBIO_Type) -#define PySSLSession_Check(v) (Py_TYPE(v) == &PySSLSession_Type) +#define PySSLSocket_Check(v) (Py_TYPE_IS(v, &PySSLSocket_Type)) +#define PySSLMemoryBIO_Check(v) (Py_TYPE_IS(v, &PySSLMemoryBIO_Type)) +#define PySSLSession_Check(v) (Py_TYPE_IS(v, &PySSLSession_Type)) typedef enum { SOCKET_IS_NONBLOCKING, @@ -3099,7 +3099,9 @@ context_dealloc(PySSLContext *self) #if HAVE_ALPN PyMem_FREE(self->alpn_protocols); #endif - Py_TYPE(self)->tp_free(self); + PyTypeObject *type = Py_GetType(self); + type->tp_free(self); + Py_DECREF(type); } /*[clinic input] @@ -4575,7 +4577,9 @@ static void memory_bio_dealloc(PySSLMemoryBIO *self) { BIO_free(self->bio); - Py_TYPE(self)->tp_free(self); + PyTypeObject *type = Py_GetType(self); + type->tp_free(self); + Py_DECREF(type); } static PyObject * diff --git a/Modules/_struct.c b/Modules/_struct.c index d9bee15694b8ff..eedfe6afeb2305 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -47,7 +47,7 @@ typedef struct { #define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType) -#define PyStruct_CheckExact(op) (Py_TYPE(op) == &PyStructType) +#define PyStruct_CheckExact(op) Py_TYPE_IS((op), &PyStructType) /* Exception */ @@ -1454,8 +1454,7 @@ Struct___init___impl(PyStructObject *self, PyObject *format) Py_DECREF(format); PyErr_Format(PyExc_TypeError, "Struct() argument 1 must be a str or bytes object, " - "not %.200s", - Py_TYPE(format)->tp_name); + "not %T", format); return -1; } @@ -1474,7 +1473,9 @@ s_dealloc(PyStructObject *s) PyMem_FREE(s->s_codes); } Py_DECREF(s->s_format); - Py_TYPE(s)->tp_free((PyObject *)s); + PyTypeObject *type = Py_GetType(s); + type->tp_free((PyObject *)s); + Py_DECREF(type); } static PyObject * @@ -1997,7 +1998,9 @@ s_sizeof(PyStructObject *self, void *unused) Py_ssize_t size; formatcode *code; - size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode); + PyTypeObject *type = Py_GetType(self); + size = _PyObject_SIZE(type) + sizeof(formatcode); + Py_DECREF(type); for (code = self->s_codes; code->fmtdef != NULL; code++) size += sizeof(formatcode); return PyLong_FromSsize_t(size); diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index 3bb6ebe5893c6d..a3eeb9f1b08f2f 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -24,7 +24,7 @@ static PyObject *simple_format = NULL; /**************************************************************************/ static PyTypeObject NDArray_Type; -#define NDArray_Check(v) (Py_TYPE(v) == &NDArray_Type) +#define NDArray_Check(v) (Py_TYPE_IS(v, &NDArray_Type)) #define CHECK_LIST_OR_TUPLE(v) \ if (!PyList_Check(v) && !PyTuple_Check(v)) { \ diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index ce2abac13b3567..3af106a5e5b1ae 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -816,11 +816,12 @@ newPyTclObject(Tcl_Obj *arg) static void PyTclObject_dealloc(PyTclObject *self) { - PyObject *tp = (PyObject *) Py_TYPE(self); + PyObject *tp = (PyObject *) Py_GetType(self); Tcl_DecrRefCount(self->value); Py_XDECREF(self->string); PyObject_Del(self); Py_DECREF(tp); + Py_DECREF(tp); } static const char * @@ -2755,12 +2756,13 @@ Tktt_Dealloc(PyObject *self) { TkttObject *v = (TkttObject *)self; PyObject *func = v->func; - PyObject *tp = (PyObject *) Py_TYPE(self); + PyObject *tp = (PyObject *) Py_GetType(self); Py_XDECREF(func); PyObject_Del(self); Py_DECREF(tp); + Py_DECREF(tp); } static PyObject * @@ -3028,13 +3030,14 @@ _tkinter_tkapp_willdispatch_impl(TkappObject *self) static void Tkapp_Dealloc(PyObject *self) { - PyObject *tp = (PyObject *) Py_TYPE(self); + PyObject *tp = (PyObject *) Py_GetType(self); /*CHECK_TCL_APPARTMENT;*/ ENTER_TCL Tcl_DeleteInterp(Tkapp_Interp(self)); LEAVE_TCL PyObject_Del(self); Py_DECREF(tp); + Py_DECREF(tp); DisableEventHook(); } diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c index 7b2cda218309f4..1c4ed262c4bad3 100644 --- a/Modules/_xxsubinterpretersmodule.c +++ b/Modules/_xxsubinterpretersmodule.c @@ -1512,7 +1512,9 @@ channelid_dealloc(PyObject *v) { int64_t cid = ((channelid *)v)->id; _channels *channels = ((channelid *)v)->channels; - Py_TYPE(v)->tp_free(v); + PyTypeObject *type = Py_GetType(v); + type->tp_free(v); + Py_DECREF(type); _channels_drop_id_object(channels, cid); } @@ -1520,8 +1522,9 @@ channelid_dealloc(PyObject *v) static PyObject * channelid_repr(PyObject *self) { - PyTypeObject *type = Py_TYPE(self); + PyTypeObject *type = Py_GetType(self); const char *name = _PyType_Name(type); + PyObject *repr; channelid *cid = (channelid *)self; const char *fmt; @@ -1534,7 +1537,9 @@ channelid_repr(PyObject *self) else { fmt = "%s(%" PRId64 ")"; } - return PyUnicode_FromFormat(fmt, name, cid->id); + repr = PyUnicode_FromFormat(fmt, name, cid->id); + Py_DECREF(type); + return repr; } static PyObject * @@ -1732,8 +1737,12 @@ channelid_end(PyObject *self, void *end) int force = 1; channelid *cid = (channelid *)self; if (end != NULL) { - return (PyObject *)newchannelid(Py_TYPE(self), cid->id, *(int *)end, - cid->channels, force, cid->resolve); + PyTypeObject *type = Py_GetType(self); + PyObject *res; + res = (PyObject *)newchannelid(type, cid->id, *(int *)end, + cid->channels, force, cid->resolve); + Py_DECREF(type); + return res; } if (cid->end == CHANNEL_SEND) { @@ -2046,16 +2055,20 @@ interpid_dealloc(PyObject *v) // already deleted PyErr_Clear(); } - Py_TYPE(v)->tp_free(v); + PyTypeObject *type = Py_GetType(v); + type->tp_free(v); + Py_DECREF(type); } static PyObject * interpid_repr(PyObject *self) { - PyTypeObject *type = Py_TYPE(self); + PyTypeObject *type = Py_GetType(self); const char *name = _PyType_Name(type); interpid *id = (interpid *)self; - return PyUnicode_FromFormat("%s(%" PRId64 ")", name, id->id); + PyObject *repr = PyUnicode_FromFormat("%s(%" PRId64 ")", name, id->id); + Py_DECREF(type); + return repr; } static PyObject * diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index eed2e7ae0f86aa..1ba26fd8fd15ce 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -106,7 +106,7 @@ enum machine_format_code { #include "clinic/arraymodule.c.h" #define array_Check(op) PyObject_TypeCheck(op, &Arraytype) -#define array_CheckExact(op) (Py_TYPE(op) == &Arraytype) +#define array_CheckExact(op) Py_TYPE_IS((op), &Arraytype) static int array_resize(arrayobject *self, Py_ssize_t newsize) @@ -659,7 +659,9 @@ array_dealloc(arrayobject *op) PyObject_ClearWeakRefs((PyObject *) op); if (op->ob_item != NULL) PyMem_DEL(op->ob_item); - Py_TYPE(op)->tp_free((PyObject *)op); + PyTypeObject *type = Py_GetType(op); + type->tp_free((PyObject *)op); + Py_DECREF(type); } static PyObject * @@ -851,8 +853,7 @@ array_concat(arrayobject *a, PyObject *bb) arrayobject *np; if (!array_Check(bb)) { PyErr_Format(PyExc_TypeError, - "can only append array (not \"%.200s\") to array", - Py_TYPE(bb)->tp_name); + "can only append array (not %T) to array", bb); return NULL; } #define b ((arrayobject *)bb) @@ -1029,8 +1030,7 @@ array_inplace_concat(arrayobject *self, PyObject *bb) { if (!array_Check(bb)) { PyErr_Format(PyExc_TypeError, - "can only extend array with array (not \"%.200s\")", - Py_TYPE(bb)->tp_name); + "can only extend array with array (not %T)", bb); return NULL; } if (array_do_extend(self, bb) == -1) @@ -1768,7 +1768,9 @@ array_array___sizeof___impl(arrayobject *self) /*[clinic end generated code: output=d8e1c61ebbe3eaed input=805586565bf2b3c6]*/ { Py_ssize_t res; - res = _PyObject_SIZE(Py_TYPE(self)) + self->allocated * self->ob_descr->itemsize; + PyTypeObject *type = Py_GetType(self); + res = _PyObject_SIZE(type) + self->allocated * self->ob_descr->itemsize; + Py_DECREF(type); return PyLong_FromSsize_t(res); } @@ -1977,8 +1979,8 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, if (!PyType_Check(arraytype)) { PyErr_Format(PyExc_TypeError, - "first argument must be a type object, not %.200s", - Py_TYPE(arraytype)->tp_name); + "first argument must be a type object, not %T", + arraytype); return NULL; } if (!PyType_IsSubtype(arraytype, &Arraytype)) { @@ -2004,8 +2006,8 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, } if (!PyBytes_Check(items)) { PyErr_Format(PyExc_TypeError, - "fourth argument should be bytes, not %.200s", - Py_TYPE(items)->tp_name); + "fourth argument should be bytes, not %T", + items); return NULL; } @@ -2235,7 +2237,7 @@ array_array___reduce_ex__(arrayobject *self, PyObject *value) return NULL; } result = Py_BuildValue( - "O(CO)O", Py_TYPE(self), typecode, list, dict); + "N(CO)O", Py_GetType(self), typecode, list, dict); Py_DECREF(list); Py_DECREF(dict); return result; @@ -2247,7 +2249,7 @@ array_array___reduce_ex__(arrayobject *self, PyObject *value) return NULL; } result = Py_BuildValue( - "O(OCiN)O", array_reconstructor, Py_TYPE(self), typecode, + "O(NCiN)O", array_reconstructor, Py_GetType(self), typecode, mformat_code, array_str, dict); Py_DECREF(dict); return result; @@ -2308,12 +2310,16 @@ array_repr(arrayobject *a) char typecode; PyObject *s, *v = NULL; Py_ssize_t len; + PyTypeObject *type; len = Py_SIZE(a); typecode = a->ob_descr->typecode; if (len == 0) { - return PyUnicode_FromFormat("%s('%c')", - _PyType_Name(Py_TYPE(a)), (int)typecode); + type = Py_GetType(a); + s = PyUnicode_FromFormat("%s('%c')", + _PyType_Name(type), (int)typecode); + Py_DECREF(type); + return s; } if (typecode == 'u') { v = array_array_tounicode_impl(a); @@ -2323,8 +2329,10 @@ array_repr(arrayobject *a) if (v == NULL) return NULL; + type = Py_GetType(a); s = PyUnicode_FromFormat("%s('%c', %R)", - _PyType_Name(Py_TYPE(a)), (int)typecode, v); + _PyType_Name(type), (int)typecode, v); + Py_DECREF(type); Py_DECREF(v); return s; } @@ -2454,8 +2462,8 @@ array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value) } else { PyErr_Format(PyExc_TypeError, - "can only assign array (not \"%.200s\") to array slice", - Py_TYPE(value)->tp_name); + "can only assign array (not %T) to array slice", + value); return -1; } itemsize = self->ob_descr->itemsize; diff --git a/Modules/binascii.c b/Modules/binascii.c index 5667018d6e1bfa..3930beaed13ab7 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -228,13 +228,13 @@ ascii_buffer_converter(PyObject *arg, Py_buffer *buf) if (PyObject_GetBuffer(arg, buf, PyBUF_SIMPLE) != 0) { PyErr_Format(PyExc_TypeError, "argument should be bytes, buffer or ASCII string, " - "not '%.100s'", Py_TYPE(arg)->tp_name); + "not %T", arg); return 0; } if (!PyBuffer_IsContiguous(buf, 'C')) { PyErr_Format(PyExc_TypeError, "argument should be a contiguous buffer, " - "not '%.100s'", Py_TYPE(arg)->tp_name); + "not %T", arg); PyBuffer_Release(buf); return 0; } diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index eb9a9a25380bfd..432422a8a608ad 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -1012,7 +1012,9 @@ mbiencoder_dealloc(MultibyteIncrementalEncoderObject *self) { PyObject_GC_UnTrack(self); ERROR_DECREF(self->errors); - Py_TYPE(self)->tp_free(self); + PyTypeObject *type = Py_GetType(self); + type->tp_free(self); + Py_DECREF(type); } static PyTypeObject MultibyteIncrementalEncoder_Type = { @@ -1230,7 +1232,9 @@ mbidecoder_dealloc(MultibyteIncrementalDecoderObject *self) { PyObject_GC_UnTrack(self); ERROR_DECREF(self->errors); - Py_TYPE(self)->tp_free(self); + PyTypeObject *type = Py_GetType(self); + type->tp_free(self); + Py_DECREF(type); } static PyTypeObject MultibyteIncrementalDecoder_Type = { @@ -1577,7 +1581,9 @@ mbstreamreader_dealloc(MultibyteStreamReaderObject *self) PyObject_GC_UnTrack(self); ERROR_DECREF(self->errors); Py_XDECREF(self->stream); - Py_TYPE(self)->tp_free(self); + PyTypeObject *type = Py_GetType(self); + type->tp_free(self); + Py_DECREF(type); } static PyTypeObject MultibyteStreamReader_Type = { @@ -1809,7 +1815,9 @@ mbstreamwriter_dealloc(MultibyteStreamWriterObject *self) PyObject_GC_UnTrack(self); ERROR_DECREF(self->errors); Py_XDECREF(self->stream); - Py_TYPE(self)->tp_free(self); + PyTypeObject *type = Py_GetType(self); + type->tp_free(self); + Py_DECREF(type); } static struct PyMethodDef mbstreamwriter_methods[] = { diff --git a/Modules/clinic/_bz2module.c.h b/Modules/clinic/_bz2module.c.h index 601bcc690d9558..6b7f56588d4376 100644 --- a/Modules/clinic/_bz2module.c.h +++ b/Modules/clinic/_bz2module.c.h @@ -81,7 +81,7 @@ _bz2_BZ2Compressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) int return_value = -1; int compresslevel = 9; - if ((Py_TYPE(self) == &BZ2Compressor_Type) && + if (Py_TYPE_IS(self, &BZ2Compressor_Type) && !_PyArg_NoKeywords("BZ2Compressor", kwargs)) { goto exit; } @@ -161,11 +161,11 @@ _bz2_BZ2Decompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - if ((Py_TYPE(self) == &BZ2Decompressor_Type) && + if (Py_TYPE_IS(self, &BZ2Decompressor_Type) && !_PyArg_NoPositional("BZ2Decompressor", args)) { goto exit; } - if ((Py_TYPE(self) == &BZ2Decompressor_Type) && + if (Py_TYPE_IS(self, &BZ2Decompressor_Type) && !_PyArg_NoKeywords("BZ2Decompressor", kwargs)) { goto exit; } diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 728552cf7d0609..a3274428a13c87 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -1729,17 +1729,21 @@ math_trunc(PyObject *module, PyObject *x) _Py_IDENTIFIER(__trunc__); PyObject *trunc, *result; - if (Py_TYPE(x)->tp_dict == NULL) { - if (PyType_Ready(Py_TYPE(x)) < 0) + PyTypeObject *type = Py_GetType(x); + if (type->tp_dict == NULL) { + if (PyType_Ready(type) < 0) { + Py_DECREF(type); return NULL; + } } + Py_DECREF(type); trunc = _PyObject_LookupSpecial(x, &PyId___trunc__); if (trunc == NULL) { if (!PyErr_Occurred()) PyErr_Format(PyExc_TypeError, - "type %.100s doesn't define __trunc__ method", - Py_TYPE(x)->tp_name); + "type %T doesn't define __trunc__ method", + x); return NULL; } result = _PyObject_CallNoArg(trunc); diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index af9cd7e2be8cc5..d0d20e47b790af 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -138,7 +138,9 @@ mmap_object_dealloc(mmap_object *m_obj) if (m_obj->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) m_obj); - Py_TYPE(m_obj)->tp_free((PyObject*)m_obj); + PyTypeObject *type = Py_GetType(m_obj); + type->tp_free((PyObject*)m_obj); + Py_DECREF(type); } static PyObject * @@ -688,7 +690,9 @@ mmap__sizeof__method(mmap_object *self, void *unused) { Py_ssize_t res; - res = _PyObject_SIZE(Py_TYPE(self)); + PyTypeObject *type = Py_GetType(self); + res = _PyObject_SIZE(type); + Py_DECREF(type); if (self->tagname) res += strlen(self->tagname) + 1; return PyLong_FromSsize_t(res); diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index fdc1c769b56eae..c023c2ec1cd797 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -374,7 +374,9 @@ parser_sizeof(PyST_Object *st, void *unused) { Py_ssize_t res; - res = _PyObject_SIZE(Py_TYPE(st)) + _PyNode_SizeOf(st->st_node); + PyTypeObject *type = Py_GetType(st); + res = _PyObject_SIZE(type) + _PyNode_SizeOf(st->st_node); + Py_DECREF(type); return PyLong_FromSsize_t(res); } @@ -866,8 +868,8 @@ build_node_children(PyObject *tuple, node *root, int *line_num) if (!PyUnicode_Check(temp)) { PyErr_Format(parser_error, "second item in terminal node must be a string," - " found %s", - Py_TYPE(temp)->tp_name); + " found %T", + temp); Py_DECREF(temp); Py_DECREF(elem); return NULL; @@ -892,8 +894,8 @@ build_node_children(PyObject *tuple, node *root, int *line_num) else { PyErr_Format(parser_error, "third item in terminal node must be an" - " integer, found %s", - Py_TYPE(temp)->tp_name); + " integer, found %T", + temp); Py_DECREF(o); Py_DECREF(temp); Py_DECREF(elem); @@ -995,8 +997,8 @@ build_node_tree(PyObject *tuple) } if (!PyUnicode_Check(encoding)) { PyErr_Format(parser_error, - "encoding must be a string, found %.200s", - Py_TYPE(encoding)->tp_name); + "encoding must be a string, found %T", + encoding); Py_DECREF(encoding); return NULL; } diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index abb7c32a2a0254..ee17a0fbd2cc37 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -778,8 +778,8 @@ readinst(char *buf, int buf_size, PyObject *meth) ptr = PyByteArray_AS_STRING(str); else { PyErr_Format(PyExc_TypeError, - "read() did not return a bytes object (type=%.400s)", - Py_TYPE(str)->tp_name); + "read() did not return a bytes object (type=%T)", + str); goto error; } len = Py_SIZE(str); diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index b1b9952b3a5acb..8d742a7e2da0ae 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -1312,7 +1312,9 @@ static void pyepoll_dealloc(pyEpoll_Object *self) { (void)pyepoll_internal_close(self); - Py_TYPE(self)->tp_free(self); + PyTypeObject *type = Py_GetType(self); + type->tp_free(self); + Py_DECREF(type); } /*[clinic input] @@ -1952,7 +1954,9 @@ static void kqueue_queue_dealloc(kqueue_queue_Object *self) { kqueue_queue_internal_close(self); - Py_TYPE(self)->tp_free(self); + PyTypeObject *type = Py_GetType(self); + type->tp_free(self); + Py_DECREF(type); } /*[clinic input] @@ -2068,8 +2072,8 @@ select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist, otimeout, _PyTime_ROUND_TIMEOUT) < 0) { PyErr_Format(PyExc_TypeError, "timeout argument must be a number " - "or None, got %.200s", - Py_TYPE(otimeout)->tp_name); + "or None, got %T", + otimeout); return NULL; } diff --git a/Modules/sha256module.c b/Modules/sha256module.c index 97be36ea66caf3..6082faec8eed46 100644 --- a/Modules/sha256module.c +++ b/Modules/sha256module.c @@ -413,7 +413,7 @@ SHA256Type_copy_impl(SHAobject *self) { SHAobject *newobj; - if (Py_TYPE(self) == &SHA256type) { + if (Py_TYPE_IS(self, &SHA256type)) { if ( (newobj = newSHA256object())==NULL) return NULL; } else { diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 562919f651f264..8ceecce2ce4881 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -1647,8 +1647,8 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, PyErr_Format( PyExc_TypeError, "getsockaddrarg: " - "AF_NETLINK address must be tuple, not %.500s", - Py_TYPE(args)->tp_name); + "AF_NETLINK address must be tuple, not %T", + args); return 0; } if (!PyArg_ParseTuple(args, "II:getsockaddrarg", &pid, &groups)) @@ -1672,8 +1672,8 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, PyErr_Format( PyExc_TypeError, "getsockaddrarg: " - "AF_VSOCK address must be tuple, not %.500s", - Py_TYPE(args)->tp_name); + "AF_VSOCK address must be tuple, not %T", + args); return 0; } if (!PyArg_ParseTuple(args, "II:getsockaddrarg", &cid, &port)) @@ -1701,8 +1701,8 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, PyErr_Format( PyExc_TypeError, "getsockaddrarg: " - "AF_INET address must be tuple, not %.500s", - Py_TYPE(args)->tp_name); + "AF_INET address must be tuple, not %T", + args); return 0; } if (!PyArg_ParseTuple(args, "O&i:getsockaddrarg", @@ -1738,8 +1738,8 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, PyErr_Format( PyExc_TypeError, "getsockaddrarg: " - "AF_INET6 address must be tuple, not %.500s", - Py_TYPE(args)->tp_name); + "AF_INET6 address must be tuple, not %T", + args); return 0; } if (!PyArg_ParseTuple(args, "O&i|II", @@ -1885,8 +1885,8 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, PyErr_Format( PyExc_TypeError, "getsockaddrarg: " - "AF_PACKET address must be tuple, not %.500s", - Py_TYPE(args)->tp_name); + "AF_PACKET address must be tuple, not %T", + args); return 0; } if (!PyArg_ParseTuple(args, "si|iiy*", &interfaceName, @@ -1942,8 +1942,8 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, PyErr_Format( PyExc_TypeError, "getsockaddrarg: " - "AF_TIPC address must be tuple, not %.500s", - Py_TYPE(args)->tp_name); + "AF_TIPC address must be tuple, not %T", + args); return 0; } @@ -2779,13 +2779,16 @@ sock_setsockopt(PySocketSockObject *s, PyObject *args) PyErr_Clear(); /* setsockopt(level, opt, None, flag) */ + PyTypeObject *none_type = Py_GetType(Py_None); if (PyArg_ParseTuple(args, "iiO!I:setsockopt", - &level, &optname, Py_TYPE(Py_None), &none, &optlen)) { + &level, &optname, none_type, &none, &optlen)) { + Py_DECREF(none_type); assert(sizeof(socklen_t) >= sizeof(unsigned int)); res = setsockopt(s->sock_fd, level, optname, NULL, (socklen_t)optlen); goto done; } + Py_DECREF(none_type); PyErr_Clear(); /* setsockopt(level, opt, buffer) */ @@ -4813,7 +4816,9 @@ sock_dealloc(PySocketSockObject *s) if (PyObject_CallFinalizerFromDealloc((PyObject *)s) < 0) return; - Py_TYPE(s)->tp_free((PyObject *)s); + PyTypeObject *type = Py_GetType(s); + type->tp_free((PyObject *)s); + Py_DECREF(type); } @@ -5884,8 +5889,8 @@ socket_ntohl(PyObject *self, PyObject *arg) } else return PyErr_Format(PyExc_TypeError, - "expected int, %s found", - Py_TYPE(arg)->tp_name); + "expected int, %T found", + arg); return PyLong_FromUnsignedLong(ntohl(x)); } @@ -5955,8 +5960,8 @@ socket_htonl(PyObject *self, PyObject *arg) } else return PyErr_Format(PyExc_TypeError, - "expected int, %s found", - Py_TYPE(arg)->tp_name); + "expected int, %T found", + arg); return PyLong_FromUnsignedLong(htonl((unsigned long)x)); } diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index c4a27ff61879d6..c7628abb0e6932 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -85,7 +85,7 @@ static PyMemberDef DB_members[] = { /* forward declaration */ static PyTypeObject UCD_Type; -#define UCD_Check(o) (Py_TYPE(o)==&UCD_Type) +#define UCD_Check(o) (Py_TYPE_IS(o, &UCD_Type)) static PyObject* new_previous_version(const char*name, const change_record* (*getrecord)(Py_UCS4), diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index bfd1381a2937fa..322291eae47995 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -2828,14 +2828,22 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, case 'T': { PyObject *obj = va_arg(*vargs, PyObject *); - PyTypeObject *type = Py_GetType(obj); - const char *type_name = type->tp_name; - size_t len = strlen(type_name); - if (unicode_fromformat_write_cstr(writer, type_name, -1, -1) < 0) { + if (obj != NULL) { + PyTypeObject *type = Py_GetType(obj); + const char *type_name = type->tp_name; + if (unicode_fromformat_write_cstr(writer, type_name, -1, -1) < 0) { + Py_DECREF(type); + return NULL; + } Py_DECREF(type); - return NULL; } - Py_DECREF(type); + else { + const char *null = ""; + const size_t len = strlen(null); + if (_PyUnicodeWriter_WriteASCIIString(writer, null, len) < 0) { + return NULL; + } + } break; } diff --git a/TODO.rst b/TODO.rst index 583c535da8adb9..16bf7c47eaf9ff 100644 --- a/TODO.rst +++ b/TODO.rst @@ -1,6 +1,7 @@ TODO list for new Python C API ============================== +* Write a tool to automate migration from the old C API to the new C API * capi_tests: check for reference leaks * Modify PyObject_INIT(op, type) macro to return op again? use an inlined function? @@ -11,12 +12,12 @@ Replace Py_TYPE() Dealloc:: - Py_TYPE(op)->tp_free((PyObject *)op); + Py_TYPE(self)->tp_free((PyObject *)self); becomes:: - PyTypeObject *type = Py_GetType(op); - type->tp_free((PyObject *)op); + PyTypeObject *type = Py_GetType(self); + type->tp_free((PyObject *)self); Py_DECREF(type); Size:: From 096e7fb558343785267aba6536ada20d817b89e6 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 5 Sep 2018 22:37:35 +0200 Subject: [PATCH 46/50] TODO --- TODO.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO.rst b/TODO.rst index 16bf7c47eaf9ff..e0ea6923f76b97 100644 --- a/TODO.rst +++ b/TODO.rst @@ -6,6 +6,7 @@ TODO list for new Python C API * Modify PyObject_INIT(op, type) macro to return op again? use an inlined function? * Do we need ``PySequence_Fast_GetItemRef()``? +* Enhance documentation to document reference counting Replace Py_TYPE() =================o From 05f670c5348df1c9bd29e56055c11c9e88d017e5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 11 Sep 2018 02:35:49 +0200 Subject: [PATCH 47/50] README: document C defines --- Include/pyport.h | 2 +- README.rst | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Include/pyport.h b/Include/pyport.h index 881c80db692fa7..e9bf91a9de8c90 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -806,7 +806,7 @@ extern _invalid_parameter_handler _Py_silent_invalid_parameter_handler; * * Py_NEWCAPI_BORROWED_REF: declare functions/macros using * borrowed references -- enabled by Py_NEWCAPI_NO_MACRO - * and Py_NEWCAPI_NO_STRUCT. + * and Py_NEWCAPI_NO_STRUCT, but not by Py_NEWCAPI. */ #if defined(Py_NEWCAPI) diff --git a/README.rst b/README.rst index 96e9184e0cd8e3..47ffcb5d095816 100644 --- a/README.rst +++ b/README.rst @@ -20,7 +20,25 @@ Build and run unit tests:: If you want to help, look at ``TODO.rst``. -The changes live in the **pythoncapi** branch. See also: +The changes live in the **pythoncapi** branch. + +New C API defines: + +* ``Py_NEWCAPI_NO_MACRO``: replace macros with function calls + ``PyTuple_GET_SIZE()`` becomes ``PyTuple_Size()`` +* ``Py_NEWCAPI_NO_STRUCT``: must not use ``PyObject.ob_refcnt`` or any other + field of Python object structures; structures should hide their fields: + compilation error. +* ``Py_NEWCAPI``: new C API without borrowed references, without macro, + without struct + +Related defines: + +* ``Py_NEWCAPI_BORROWED_REF``: declare functions/macros using + borrowed references -- enabled by ``Py_NEWCAPI_NO_MACRO`` + and ``Py_NEWCAPI_NO_STRUCT``, but not by ``Py_NEWCAPI``. + +See also: * `github.com/pythoncapi/cpython `_ * `capi-sig mailing list From f80dea2b6c3590553fd3b4499fad5b393ad4d697 Mon Sep 17 00:00:00 2001 From: Dino Viehland Date: Tue, 11 Sep 2018 16:39:02 -0700 Subject: [PATCH 48/50] Add PyDict_GetItemRef --- Include/dictobject.h | 6 +++++- Modules/_csv.c | 4 +--- Modules/_ctypes/_ctypes.c | 37 +++++++++++++++++++------------- Modules/_ctypes/callproc.c | 13 +++++------ Modules/_elementtree.c | 29 +++++++++++++------------ Modules/_json.c | 3 +-- Modules/_sqlite/cache.c | 4 +++- Modules/_sqlite/cursor.c | 8 +++---- Modules/_sqlite/microprotocols.c | 3 ++- Modules/_sre.c | 3 ++- Modules/_ssl.c | 16 +++++++++----- Modules/_struct.c | 3 +-- Modules/_testmultiphase.c | 3 +-- Modules/_threadmodule.c | 19 ++++++++++------ Modules/posixmodule.c | 8 +++++-- Modules/pyexpat.c | 11 ++++++---- Modules/selectmodule.c | 4 +++- Modules/xxlimited.c | 3 +-- Modules/xxmodule.c | 3 +-- Modules/zipimport.c | 24 +++++++++++++-------- Objects/dictobject.c | 16 ++++++++++++++ PC/python3.def | 2 ++ 22 files changed, 138 insertions(+), 84 deletions(-) diff --git a/Include/dictobject.h b/Include/dictobject.h index 6bc96aa6f7dfb6..2ac5bc4b7d33d8 100644 --- a/Include/dictobject.h +++ b/Include/dictobject.h @@ -67,7 +67,12 @@ PyAPI_DATA(PyTypeObject) PyDictValues_Type; PyAPI_FUNC(PyObject *) PyDict_New(void); +#ifndef Py_NEWCAPI PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key); +PyAPI_FUNC(PyObject *) PyDict_GetItemString(PyObject *dp, const char *key); +#endif +PyAPI_FUNC(PyObject *) PyDict_GetItemRef(PyObject *mp, PyObject *key); +PyAPI_FUNC(PyObject *) PyDict_GetItemRefString(PyObject *dp, const char *key); #ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key, Py_hash_t hash); @@ -155,7 +160,6 @@ PyAPI_FUNC(int) PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override); -PyAPI_FUNC(PyObject *) PyDict_GetItemString(PyObject *dp, const char *key); #ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PyDict_GetItemId(PyObject *dp, struct _Py_Identifier *key); #endif /* !Py_LIMITED_API */ diff --git a/Modules/_csv.c b/Modules/_csv.c index 28dcdf8caf20b4..95af3979b04cf1 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -132,13 +132,11 @@ get_dialect_from_registry(PyObject * name_obj) { PyObject *dialect_obj; - dialect_obj = PyDict_GetItem(_csvstate_global->dialects, name_obj); + dialect_obj = PyDict_GetItemRef(_csvstate_global->dialects, name_obj); if (dialect_obj == NULL) { if (!PyErr_Occurred()) PyErr_Format(_csvstate_global->error_obj, "unknown dialect"); } - else - Py_INCREF(dialect_obj); return dialect_obj; } diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 161ed05fcdf3e4..263996fa806f69 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -238,15 +238,19 @@ PyObject * PyDict_GetItemProxy(PyObject *dict, PyObject *key) { PyObject *result; - PyObject *item = PyDict_GetItem(dict, key); + PyObject *item = PyDict_GetItemRef(dict, key); if (item == NULL) return NULL; - if (!PyWeakref_CheckProxy(item)) - return item; - result = PyWeakref_GET_OBJECT(item); - if (result == Py_None) - return NULL; + if (!PyWeakref_CheckProxy(item)) { + result = item; + } else { + result = PyWeakref_GET_OBJECT(item); + if (result == Py_None) + result = NULL; + } + + Py_DECREF(item); return result; } @@ -3620,9 +3624,8 @@ _get_arg(int *pindex, PyObject *name, PyObject *defval, PyObject *inargs, PyObje ++*pindex; return v; } - if (kwds && name && (v = PyDict_GetItem(kwds, name))) { + if (kwds && name && (v = PyDict_GetItemRef(kwds, name))) { ++*pindex; - Py_INCREF(v); return v; } if (defval) { @@ -4197,13 +4200,17 @@ _init_pos_args(PyObject *self, PyTypeObject *type, } val = PyTuple_GetItemRef(args, i + index); Py_DECREF(val); - if (kwds && PyDict_GetItem(kwds, name)) { - PyErr_Format(PyExc_TypeError, - "duplicate values for field %R", - name); - Py_DECREF(pair); - Py_DECREF(name); - return -1; + if (kwds) { + PyObject *existing = PyDict_GetItemRef(kwds, name); + if (existing) { + PyErr_Format(PyExc_TypeError, + "duplicate values for field %R", + name); + Py_DECREF(existing); + Py_DECREF(pair); + Py_DECREF(name); + return -1; + } } res = PyObject_SetAttr(self, name, val); diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 138d8d9c87dbea..ec594b4ea34b23 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -142,14 +142,14 @@ _ctypes_get_errobj(int **pspace) if (error_object_name == NULL) return NULL; } - errobj = PyDict_GetItem(dict, error_object_name); + errobj = PyDict_GetItemRef(dict, error_object_name); if (errobj) { if (!PyCapsule_IsValid(errobj, CTYPES_CAPSULE_NAME_PYMEM)) { + Py_DECREF(errobj); PyErr_SetString(PyExc_RuntimeError, "ctypes.error_object is an invalid capsule"); return NULL; } - Py_INCREF(errobj); } else { void *space = PyMem_Malloc(sizeof(int) * 2); @@ -1676,9 +1676,8 @@ POINTER(PyObject *self, PyObject *cls) PyObject *key; char *buf; - result = PyDict_GetItem(_ctypes_ptrtype_cache, cls); + result = PyDict_GetItemRef(_ctypes_ptrtype_cache, cls); if (result) { - Py_INCREF(result); return result; } if (PyUnicode_CheckExact(cls)) { @@ -1741,10 +1740,12 @@ pointer(PyObject *self, PyObject *arg) PyObject *typ; PyTypeObject *arg_type = Py_GetType(arg); - typ = PyDict_GetItem(_ctypes_ptrtype_cache, (PyObject *)arg_type); + typ = PyDict_GetItemRef(_ctypes_ptrtype_cache, (PyObject *)arg_type); if (typ) { Py_DECREF(arg_type); - return PyObject_CallFunctionObjArgs(typ, arg, NULL); + result = PyObject_CallFunctionObjArgs(typ, arg, NULL); + Py_DECREF(typ); + return result; } typ = POINTER(NULL, (PyObject *)arg_type); Py_DECREF(arg_type); diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 13fca1ab14764a..e30b13b1a92839 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -324,19 +324,22 @@ static PyObject* get_attrib_from_keywords(PyObject *kwds) { PyObject *attrib_str = PyUnicode_FromString("attrib"); - PyObject *attrib = PyDict_GetItem(kwds, attrib_str); + PyObject *attrib = PyDict_GetItemRef(kwds, attrib_str); if (attrib) { /* If attrib was found in kwds, copy its value and remove it from * kwds */ if (!PyDict_Check(attrib)) { + Py_DECREF(attrib); Py_DECREF(attrib_str); PyErr_Format(PyExc_TypeError, "attrib must be dict, not %T", attrib); return NULL; } - attrib = PyDict_Copy(attrib); + PyObject *copy = PyDict_Copy(attrib); + Py_DECREF(attrib); + attrib = copy; PyDict_DelItem(kwds, attrib_str); } else { attrib = PyDict_New(); @@ -1341,17 +1344,16 @@ _elementtree_Element_get_impl(ElementObject *self, PyObject *key, PyObject *default_value) /*[clinic end generated code: output=523c614142595d75 input=ee153bbf8cdb246e]*/ { - PyObject* value; + PyObject* value = NULL; - if (!self->extra || self->extra->attrib == Py_None) + if (self->extra && self->extra->attrib != Py_None) + value = PyDict_GetItemRef(self->extra->attrib, key); + + if (!value) { value = default_value; - else { - value = PyDict_GetItem(self->extra->attrib, key); - if (!value) - value = default_value; + Py_INCREF(value); } - Py_INCREF(value); return value; } @@ -2790,11 +2792,9 @@ makeuniversal(XMLParserObject* self, const char* string) if (!key) return NULL; - value = PyDict_GetItem(self->names, key); + value = PyDict_GetItemRef(self->names, key); - if (value) { - Py_INCREF(value); - } else { + if (!value) { /* new name. convert to universal name, and decode as necessary */ @@ -2916,7 +2916,7 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in, if (!key) return; - value = PyDict_GetItem(self->entity, key); + value = PyDict_GetItemRef(self->entity, key); if (value) { if (TreeBuilder_CheckExact(self->target)) @@ -2927,6 +2927,7 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in, res = PyObject_CallFunctionObjArgs(self->handle_data, value, NULL); else res = NULL; + Py_DECREF(value); Py_XDECREF(res); } else if (!PyErr_Occurred()) { /* Report the first error, not the last */ diff --git a/Modules/_json.c b/Modules/_json.c index 07a909726f2b8a..d78fcdc54edcbe 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -750,9 +750,8 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss key = scanstring_unicode(pystr, idx + 1, s->strict, &next_idx); if (key == NULL) goto bail; - memokey = PyDict_GetItem(s->memo, key); + memokey = PyDict_GetItemRef(s->memo, key); if (memokey != NULL) { - Py_INCREF(memokey); Py_DECREF(key); key = memokey; } diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index 191bd5ddecb647..f24540fa4ee294 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -123,7 +123,7 @@ PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* args) pysqlite_Node* ptr; PyObject* data; - node = (pysqlite_Node*)PyDict_GetItem(self->mapping, key); + node = (pysqlite_Node*)PyDict_GetItemRef(self->mapping, key); if (node) { /* an entry for this key already exists in the cache */ @@ -160,6 +160,8 @@ PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* args) self->first = node; } ptr->prev = node; + + Py_DECREF(node); // linked list has a ref } } else { /* There is no entry for this key in the cache, yet. We'll insert a new diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index b82e5ca194cc11..f5af4d5e776de7 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -107,7 +107,7 @@ PyObject* _pysqlite_get_converter(PyObject* key) return NULL; } - retval = PyDict_GetItem(_pysqlite_converters, upcase_key); + retval = PyDict_GetItemRef(_pysqlite_converters, upcase_key); Py_DECREF(upcase_key); return retval; @@ -181,16 +181,16 @@ int pysqlite_build_row_cast_map(pysqlite_Cursor* self) if (!converter) { converter = Py_None; + Py_INCREF(converter); } if (PyList_Append(self->row_cast_map, converter) != 0) { - if (converter != Py_None) { - Py_DECREF(converter); - } + Py_DECREF(converter); Py_CLEAR(self->row_cast_map); return -1; } + Py_DECREF(converter); } return 0; diff --git a/Modules/_sqlite/microprotocols.c b/Modules/_sqlite/microprotocols.c index 3d01872322c335..ec89d13113197d 100644 --- a/Modules/_sqlite/microprotocols.c +++ b/Modules/_sqlite/microprotocols.c @@ -86,10 +86,11 @@ pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt) if (!key) { return NULL; } - adapter = PyDict_GetItem(psyco_adapters, key); + adapter = PyDict_GetItemRef(psyco_adapters, key); Py_DECREF(key); if (adapter) { PyObject *adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL); + Py_DECREF(adapter); return adapted; } diff --git a/Modules/_sre.c b/Modules/_sre.c index b6be6f6ffa6063..e50a27265bcf8e 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -1953,10 +1953,11 @@ match_getindex(MatchObject* self, PyObject* index) i = -1; if (self->pattern->groupindex) { - index = PyDict_GetItem(self->pattern->groupindex, index); + index = PyDict_GetItemRef(self->pattern->groupindex, index); if (index && PyLong_Check(index)) { i = PyLong_AsSsize_t(index); } + Py_XDECREF(index); } return i; diff --git a/Modules/_ssl.c b/Modules/_ssl.c index a62651344d58f6..27c1f20d9f04e9 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -583,7 +583,7 @@ fill_and_set_sslerror(PySSLSocket *sslsock, PyObject *type, int ssl_errno, key = Py_BuildValue("ii", lib, reason); if (key == NULL) goto fail; - reason_obj = PyDict_GetItem(err_codes_to_names, key); + reason_obj = PyDict_GetItemRef(err_codes_to_names, key); Py_DECREF(key); if (reason_obj == NULL) { /* XXX if reason < 100, it might reflect a library number (!!) */ @@ -592,7 +592,7 @@ fill_and_set_sslerror(PySSLSocket *sslsock, PyObject *type, int ssl_errno, key = PyLong_FromLong(lib); if (key == NULL) goto fail; - lib_obj = PyDict_GetItem(lib_codes_to_names, key); + lib_obj = PyDict_GetItemRef(lib_codes_to_names, key); Py_DECREF(key); if (lib_obj == NULL) { PyErr_Clear(); @@ -671,13 +671,17 @@ fill_and_set_sslerror(PySSLSocket *sslsock, PyObject *type, int ssl_errno, if (err_value == NULL) goto fail; - if (reason_obj == NULL) + if (!reason_obj) { reason_obj = Py_None; + Py_INCREF(reason_obj); + } if (_PyObject_SetAttrId(err_value, &PyId_reason, reason_obj)) goto fail; - if (lib_obj == NULL) + if (!lib_obj) { lib_obj = Py_None; + Py_INCREF(lib_obj); + } if (_PyObject_SetAttrId(err_value, &PyId_library, lib_obj)) goto fail; @@ -692,6 +696,8 @@ fill_and_set_sslerror(PySSLSocket *sslsock, PyObject *type, int ssl_errno, PyErr_SetObject(type, err_value); fail: + Py_XDECREF(reason_obj); + Py_XDECREF(lib_obj); Py_XDECREF(err_value); Py_XDECREF(verify_code_obj); Py_XDECREF(verify_obj); @@ -5432,7 +5438,7 @@ _ssl_enum_crls_impl(PyObject *module, const char *store_name) break; } PyTuple_SetItemRef(tup, 0, crl); - Py_CLEAR(crl; + Py_CLEAR(crl); PyTuple_SetItemRef(tup, 1, enc); Py_CLEAR(enc); diff --git a/Modules/_struct.c b/Modules/_struct.c index eedfe6afeb2305..5cc3395eeb88dd 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -2092,9 +2092,8 @@ cache_struct_converter(PyObject *fmt, PyObject **ptr) return 0; } - s_object = PyDict_GetItem(cache, fmt); + s_object = PyDict_GetItemRef(cache, fmt); if (s_object != NULL) { - Py_INCREF(s_object); *ptr = s_object; return Py_CLEANUP_SUPPORTED; } diff --git a/Modules/_testmultiphase.c b/Modules/_testmultiphase.c index 5776df7d765db9..b16d2ce82bd9f8 100644 --- a/Modules/_testmultiphase.c +++ b/Modules/_testmultiphase.c @@ -53,9 +53,8 @@ static PyObject * Example_getattro(ExampleObject *self, PyObject *name) { if (self->x_attr != NULL) { - PyObject *v = PyDict_GetItem(self->x_attr, name); + PyObject *v = PyDict_GetItemRef(self->x_attr, name); if (v != NULL) { - Py_INCREF(v); return v; } } diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index f6b39defbc8070..ccf42032bb3c9e 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -777,9 +777,13 @@ local_clear(localobject *self) for(tstate = PyInterpreterState_ThreadHead(tstate->interp); tstate; tstate = PyThreadState_Next(tstate)) - if (tstate->dict && - PyDict_GetItem(tstate->dict, self->key)) - PyDict_DelItem(tstate->dict, self->key); + if (tstate->dict) { + PyObject *existing = PyDict_GetItemRef(tstate->dict, self->key); + if (existing) { + Py_DECREF(existing); + PyDict_DelItem(tstate->dict, self->key); + } + } } return 0; } @@ -812,7 +816,7 @@ _ldict(localobject *self) return NULL; } - dummy = PyDict_GetItem(tdict, self->key); + dummy = PyDict_GetItemRef(tdict, self->key); if (dummy == NULL) { ldict = _local_create_dummy(self); if (ldict == NULL) @@ -831,6 +835,7 @@ _ldict(localobject *self) else { assert(Py_TYPE(dummy) == &localdummytype); ldict = ((localdummyobject *) dummy)->localdict; + Py_DECREF(dummy); } return ldict; @@ -929,13 +934,12 @@ local_getattro(localobject *self, PyObject *name) (PyObject *)self, name, ldict, 0); /* Optimization: just look in dict ourselves */ - value = PyDict_GetItem(ldict, name); + value = PyDict_GetItemRef(ldict, name); if (value == NULL) /* Fall back on generic to get __class__ and __dict__ */ return _PyObject_GenericGetAttrWithDict( (PyObject *)self, name, ldict, 0); - Py_INCREF(value); return value; } @@ -956,9 +960,10 @@ _localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref) self = (localobject *) obj; if (self->dummies != NULL) { PyObject *ldict; - ldict = PyDict_GetItem(self->dummies, dummyweakref); + ldict = PyDict_GetItemRef(self->dummies, dummyweakref); if (ldict != NULL) { PyDict_DelItem(self->dummies, dummyweakref); + Py_DECREF(ldict); } if (PyErr_Occurred()) PyErr_WriteUnraisable(obj); diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 7f13735eadc8bd..4218ac46f461bf 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1409,10 +1409,12 @@ convertenviron(void) Py_DECREF(k); continue; } - if (PyDict_GetItem(d, k) == NULL) { + PyObject* e = PyDict_GetItemRef(d, k); + if (e == NULL) { if (PyDict_SetItem(d, k, v) != 0) PyErr_Clear(); } + Py_XDECREF(e); Py_DECREF(k); Py_DECREF(v); } @@ -1437,10 +1439,12 @@ convertenviron(void) Py_DECREF(k); continue; } - if (PyDict_GetItem(d, k) == NULL) { + PyObject* e = PyDict_GetItemRef(d, k); + if (e == NULL) { if (PyDict_SetItem(d, k, v) != 0) PyErr_Clear(); } + Py_XDECREF(e); Py_DECREF(k); Py_DECREF(v); } diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index ee17a0fbd2cc37..e025135ee9e1a7 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -239,14 +239,13 @@ string_intern(xmlparseobject *self, const char* str) return result; if (!self->intern) return result; - value = PyDict_GetItem(self->intern, result); + value = PyDict_GetItemRef(self->intern, result); if (!value) { if (PyDict_SetItem(self->intern, result, result) == 0) return result; else return NULL; } - Py_INCREF(value); Py_DECREF(result); return value; } @@ -1699,7 +1698,7 @@ MODULE_INITFUNC(void) Py_DECREF(m); return NULL; } - errors_module = PyDict_GetItem(d, errmod_name); + errors_module = PyDict_GetItemRef(d, errmod_name); if (errors_module == NULL) { errors_module = PyModule_New(MODULE_NAME ".errors"); if (errors_module != NULL) { @@ -1707,9 +1706,11 @@ MODULE_INITFUNC(void) /* gives away the reference to errors_module */ PyModule_AddObject(m, "errors", errors_module); } + } else { + Py_DECREF(errors_module); } Py_DECREF(errmod_name); - model_module = PyDict_GetItem(d, modelmod_name); + model_module = PyDict_GetItemRef(d, modelmod_name); if (model_module == NULL) { model_module = PyModule_New(MODULE_NAME ".model"); if (model_module != NULL) { @@ -1717,6 +1718,8 @@ MODULE_INITFUNC(void) /* gives away the reference to model_module */ PyModule_AddObject(m, "model", model_module); } + } else { + Py_XDECREF(model_module); } Py_DECREF(modelmod_name); if (errors_module == NULL || model_module == NULL) { diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 8d742a7e2da0ae..9dc34b9a6e5e2e 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -497,12 +497,14 @@ select_poll_modify_impl(pollObject *self, int fd, unsigned short eventmask) key = PyLong_FromLong(fd); if (key == NULL) return NULL; - if (PyDict_GetItem(self->dict, key) == NULL) { + PyObject *e = PyDict_GetItemRef(self->dict, key); + if (e == NULL) { errno = ENOENT; PyErr_SetFromErrno(PyExc_OSError); Py_DECREF(key); return NULL; } + Py_DECREF(e); value = PyLong_FromLong(eventmask); if (value == NULL) { Py_DECREF(key); diff --git a/Modules/xxlimited.c b/Modules/xxlimited.c index 5586989d039cfe..8564dcdf6924d6 100644 --- a/Modules/xxlimited.c +++ b/Modules/xxlimited.c @@ -78,9 +78,8 @@ static PyObject * Xxo_getattro(XxoObject *self, PyObject *name) { if (self->x_attr != NULL) { - PyObject *v = PyDict_GetItem(self->x_attr, name); + PyObject *v = PyDict_GetItemRef(self->x_attr, name); if (v != NULL) { - Py_INCREF(v); return v; } } diff --git a/Modules/xxmodule.c b/Modules/xxmodule.c index c0564ea9674eac..c4fe1147cb4968 100644 --- a/Modules/xxmodule.c +++ b/Modules/xxmodule.c @@ -66,9 +66,8 @@ static PyObject * Xxo_getattro(XxoObject *self, PyObject *name) { if (self->x_attr != NULL) { - PyObject *v = PyDict_GetItem(self->x_attr, name); + PyObject *v = PyDict_GetItemRef(self->x_attr, name); if (v != NULL) { - Py_INCREF(v); return v; } } diff --git a/Modules/zipimport.c b/Modules/zipimport.c index 4df4ba9f8b8229..26e3e821842593 100644 --- a/Modules/zipimport.c +++ b/Modules/zipimport.c @@ -154,7 +154,7 @@ zipimport_zipimporter___init___impl(ZipImporter *self, PyObject *path) if (PyUnicode_READY(filename) < 0) goto error; - files = PyDict_GetItem(zip_directory_cache, filename); + files = PyDict_GetItemRef(zip_directory_cache, filename); if (files == NULL) { files = read_directory(filename); if (files == NULL) @@ -162,8 +162,6 @@ zipimport_zipimporter___init___impl(ZipImporter *self, PyObject *path) if (PyDict_SetItem(zip_directory_cache, filename, files) != 0) goto error; } - else - Py_INCREF(files); Py_XSETREF(self->files, files); /* Transfer reference */ @@ -343,9 +341,10 @@ get_module_info(ZipImporter *self, PyObject *fullname) Py_DECREF(path); return MI_ERROR; } - item = PyDict_GetItem(self->files, fullpath); + item = PyDict_GetItemRef(self->files, fullpath); Py_DECREF(fullpath); if (item != NULL) { + Py_DECREF(item); Py_DECREF(path); if (zso->type & IS_PACKAGE) return MI_PACKAGE; @@ -687,7 +686,7 @@ zipimport_zipimporter_get_data_impl(ZipImporter *self, PyObject *path) key = PyUnicode_Substring(path, path_start, path_len); if (key == NULL) goto error; - toc_entry = PyDict_GetItem(self->files, key); + toc_entry = PyDict_GetItemRef(self->files, key); if (toc_entry == NULL) { PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, key); Py_DECREF(key); @@ -695,7 +694,9 @@ zipimport_zipimporter_get_data_impl(ZipImporter *self, PyObject *path) } Py_DECREF(key); Py_DECREF(path); - return get_data(self->archive, toc_entry); + PyObject *data = get_data(self->archive, toc_entry); + Py_DECREF(toc_entry); + return data; error: Py_DECREF(path); return NULL; @@ -766,11 +767,12 @@ zipimport_zipimporter_get_source_impl(ZipImporter *self, PyObject *fullname) if (fullpath == NULL) return NULL; - toc_entry = PyDict_GetItem(self->files, fullpath); + toc_entry = PyDict_GetItemRef(self->files, fullpath); Py_DECREF(fullpath); if (toc_entry != NULL) { PyObject *res, *bytes; bytes = get_data(self->archive, toc_entry); + Py_DECREF(toc_entry); if (bytes == NULL) return NULL; res = PyUnicode_FromStringAndSize(PyBytes_AS_STRING(bytes), @@ -1482,7 +1484,7 @@ get_mtime_of_source(ZipImporter *self, PyObject *path) if (stripped == NULL) return (time_t)-1; - toc_entry = PyDict_GetItem(self->files, stripped); + toc_entry = PyDict_GetItemRef(self->files, stripped); Py_DECREF(stripped); if (toc_entry != NULL && PyTuple_Check(toc_entry) && PyTuple_Size(toc_entry) == 8) { @@ -1494,6 +1496,7 @@ get_mtime_of_source(ZipImporter *self, PyObject *path) mtime = parse_dostime(time, date); } else mtime = 0; + Py_XDECREF(toc_entry); return mtime; } @@ -1553,7 +1556,7 @@ get_module_code(ZipImporter *self, PyObject *fullname, if (Py_VerboseFlag > 1) PySys_FormatStderr("# trying %U%c%U\n", self->archive, (int)SEP, fullpath); - toc_entry = PyDict_GetItem(self->files, fullpath); + toc_entry = PyDict_GetItemRef(self->files, fullpath); if (toc_entry != NULL) { time_t mtime = 0; int ispackage = zso->type & IS_PACKAGE; @@ -1562,6 +1565,7 @@ get_module_code(ZipImporter *self, PyObject *fullname, if (isbytecode) { mtime = get_mtime_of_source(self, fullpath); if (mtime == (time_t)-1 && PyErr_Occurred()) { + Py_DECREF(toc_entry); goto exit; } } @@ -1574,6 +1578,7 @@ get_module_code(ZipImporter *self, PyObject *fullname, if (code == Py_None) { /* bad magic number or non-matching mtime in byte code, try next */ + Py_DECREF(toc_entry); Py_DECREF(code); continue; } @@ -1581,6 +1586,7 @@ get_module_code(ZipImporter *self, PyObject *fullname, *p_modpath = PyTuple_GetItem(toc_entry, 0); Py_INCREF(*p_modpath); } + Py_DECREF(toc_entry); goto exit; } else diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 413557d6674127..fd4caca6e34ade 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -1331,6 +1331,14 @@ PyDict_GetItem(PyObject *op, PyObject *key) return value; } +PyObject * +PyDict_GetItemRef(PyObject *op, PyObject *key) +{ + PyObject* value = PyDict_GetItem(op, key); + Py_XINCREF(value); + return value; +} + /* Same as PyDict_GetItemWithError() but with hash supplied by caller. This returns NULL *with* an exception set if an exception occurred. It returns NULL *without* an exception set if the key wasn't present. @@ -3267,6 +3275,14 @@ PyDict_GetItemString(PyObject *v, const char *key) return rv; } +PyObject * +PyDict_GetItemRefString(PyObject *v, const char *key) +{ + PyObject *value = PyDict_GetItemString(v, key); + Py_XINCREF(value); + return value; +} + int _PyDict_SetItemId(PyObject *v, struct _Py_Identifier *key, PyObject *item) { diff --git a/PC/python3.def b/PC/python3.def index 5d93c18af87ec2..a7b89374a0306a 100644 --- a/PC/python3.def +++ b/PC/python3.def @@ -98,7 +98,9 @@ EXPORTS PyDict_DelItem=python38.PyDict_DelItem PyDict_DelItemString=python38.PyDict_DelItemString PyDict_GetItem=python38.PyDict_GetItem + PyDict_GetItemRef=python38.PyDict_GetItemRef PyDict_GetItemString=python38.PyDict_GetItemString + PyDict_GetItemRefString=python38.PyDict_GetItemRefString PyDict_GetItemWithError=python38.PyDict_GetItemWithError PyDict_Items=python38.PyDict_Items PyDict_Keys=python38.PyDict_Keys From 80b0a0875f4e38476f1d33ee148e0ea043e2767f Mon Sep 17 00:00:00 2001 From: Dino Viehland Date: Thu, 13 Sep 2018 10:01:00 -0700 Subject: [PATCH 49/50] Updates for PyDict_GetItemRefString --- Modules/_ctypes/_ctypes.c | 55 ++++++++++++++++++++++++------------ Modules/_ctypes/callbacks.c | 5 ++-- Modules/_decimal/_decimal.c | 19 +++++++++---- Modules/_pickle.c | 3 +- Modules/_sqlite/connection.c | 3 +- Modules/_sqlite/statement.c | 3 +- Modules/itertoolsmodule.c | 9 ++++-- Modules/main.c | 4 ++- Modules/signalmodule.c | 3 +- Modules/socketmodule.c | 8 ++++-- 10 files changed, 72 insertions(+), 40 deletions(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 263996fa806f69..bd3025c8dd6555 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -440,8 +440,11 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt return NULL; /* keep this for bw compatibility */ - if (PyDict_GetItemString(result->tp_dict, "_abstract_")) + PyObject *abstract = PyDict_GetItemRefString(result->tp_dict, "_abstract_"); + if (abstract) { + Py_DECREF(abstract); return (PyObject *)result; + } dict = (StgDictObject *)_PyObject_CallNoArg((PyObject *)&PyCStgDict_Type); if (!dict) { @@ -464,7 +467,7 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt dict->paramfunc = StructUnionType_paramfunc; - fields = PyDict_GetItemString((PyObject *)dict, "_fields_"); + fields = PyDict_GetItemRefString((PyObject *)dict, "_fields_"); if (!fields) { StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base); @@ -482,8 +485,10 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt if (-1 == PyObject_SetAttrString((PyObject *)result, "_fields_", fields)) { Py_DECREF(result); + Py_DECREF(fields); return NULL; } + Py_DECREF(fields); return (PyObject *)result; } @@ -987,10 +992,11 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) stgdict->paramfunc = PyCPointerType_paramfunc; stgdict->flags |= TYPEFLAG_ISPOINTER; - proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */ + proto = PyDict_GetItemRefString(typedict, "_type_"); Py_DECREF(typedict); if (proto && -1 == PyCPointerType_SetProto(stgdict, proto)) { Py_DECREF((PyObject *)stgdict); + Py_DECREF(proto); return NULL; } @@ -1014,8 +1020,10 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } if (stgdict->format == NULL) { Py_DECREF((PyObject *)stgdict); + Py_DECREF(proto); return NULL; } + Py_DECREF(proto); } /* create the new instance (which is a class, @@ -2298,47 +2306,50 @@ make_funcptrtype_dict(StgDictObject *stgdict) stgdict->getfunc = NULL; stgdict->ffi_type_pointer = ffi_type_pointer; - ob = PyDict_GetItemString((PyObject *)stgdict, "_flags_"); + ob = PyDict_GetItemRefString((PyObject *)stgdict, "_flags_"); if (!ob || !PyLong_Check(ob)) { + Py_XDECREF(ob); PyErr_SetString(PyExc_TypeError, "class must define _flags_ which must be an integer"); return -1; } stgdict->flags = PyLong_AS_LONG(ob) | TYPEFLAG_ISPOINTER; + Py_DECREF(ob); /* _argtypes_ is optional... */ - ob = PyDict_GetItemString((PyObject *)stgdict, "_argtypes_"); + ob = PyDict_GetItemRefString((PyObject *)stgdict, "_argtypes_"); if (ob) { converters = converters_from_argtypes(ob); - if (!converters) + if (!converters) { + Py_DECREF(ob); goto error; - Py_INCREF(ob); + } stgdict->argtypes = ob; stgdict->converters = converters; } - ob = PyDict_GetItemString((PyObject *)stgdict, "_restype_"); + ob = PyDict_GetItemRefString((PyObject *)stgdict, "_restype_"); if (ob) { if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) { + Py_DECREF(ob); PyErr_SetString(PyExc_TypeError, "_restype_ must be a type, a callable, or None"); return -1; } - Py_INCREF(ob); stgdict->restype = ob; stgdict->checker = PyObject_GetAttrString(ob, "_check_retval_"); if (stgdict->checker == NULL) PyErr_Clear(); } /* XXX later, maybe. - ob = PyDict_GetItemString((PyObject *)stgdict, "_errcheck_"); + ob = PyDict_GetItemRefString((PyObject *)stgdict, "_errcheck_"); if (ob) { if (!PyCallable_Check(ob)) { PyErr_SetString(PyExc_TypeError, "_errcheck_ must be callable"); + Py_DECREF(ob); return -1; } - Py_INCREF(ob); stgdict->errcheck = ob; } */ @@ -3546,7 +3557,11 @@ PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) like that. */ /* - if (kwds && PyDict_GetItemString(kwds, "options")) { + if (kwds) { + PyObject *options = PyDict_GetItemRefString(kwds, "options"); + if (options) { + Py_DECREF(options); + } ... } */ @@ -4181,7 +4196,7 @@ _init_pos_args(PyObject *self, PyTypeObject *type, } dict = PyType_stgdict((PyObject *)type); - fields = PyDict_GetItemString((PyObject *)dict, "_fields_"); + fields = PyDict_GetItemRefString((PyObject *)dict, "_fields_"); if (fields == NULL) return index; @@ -4192,14 +4207,13 @@ _init_pos_args(PyObject *self, PyTypeObject *type, PyObject *name, *val; int res; if (!pair) - return -1; + goto error; name = PySequence_GetItem(pair, 0); if (!name) { Py_DECREF(pair); - return -1; + goto error; } val = PyTuple_GetItemRef(args, i + index); - Py_DECREF(val); if (kwds) { PyObject *existing = PyDict_GetItemRef(kwds, name); if (existing) { @@ -4209,17 +4223,22 @@ _init_pos_args(PyObject *self, PyTypeObject *type, Py_DECREF(existing); Py_DECREF(pair); Py_DECREF(name); - return -1; + Py_DECREF(val); + goto error; } } res = PyObject_SetAttr(self, name, val); + Py_DECREF(val); Py_DECREF(pair); Py_DECREF(name); if (res == -1) - return -1; + goto error; } return index + dict->length; +error: + Py_DECREF(fields); + return -1; } static int diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index 98b456684b7fd8..5a11a7c75b803c 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -108,9 +108,10 @@ TryAddRef(StgDictObject *dict, CDataObject *obj) { IUnknown *punk; - if (NULL == PyDict_GetItemString((PyObject *)dict, "_needs_com_addref_")) + PyObject *add_ref = PyDict_GetItemRefString((PyObject *)dict, "_needs_com_addref_"); + if (NULL == add_ref) return; - + Py_DECREF(add_ref); punk = *(IUnknown **)obj->b_ptr; if (punk) punk->lpVtbl->AddRef(punk); diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 7ae58f0659f39f..2920da7dfd669c 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -3125,22 +3125,29 @@ dec_format(PyObject *dec, PyObject *args) "optional argument must be a dict"); goto finish; } - if ((dot = PyDict_GetItemString(override, "decimal_point"))) { - if ((dot = PyUnicode_AsUTF8String(dot)) == NULL) { + PyObject *tmp; + if ((dot = PyDict_GetItemRefString(override, "decimal_point"))) { + if ((tmp = PyUnicode_AsUTF8String(dot)) == NULL) { goto finish; } + Py_DECREF(dot); + dot = tmp; spec.dot = PyBytes_AS_STRING(dot); } - if ((sep = PyDict_GetItemString(override, "thousands_sep"))) { - if ((sep = PyUnicode_AsUTF8String(sep)) == NULL) { + if ((sep = PyDict_GetItemRefString(override, "thousands_sep"))) { + if ((tmp = PyUnicode_AsUTF8String(sep)) == NULL) { goto finish; } + Py_DECREF(sep); + sep = tmp; spec.sep = PyBytes_AS_STRING(sep); } - if ((grouping = PyDict_GetItemString(override, "grouping"))) { - if ((grouping = PyUnicode_AsUTF8String(grouping)) == NULL) { + if ((grouping = PyDict_GetItemRefString(override, "grouping"))) { + if ((tmp = PyUnicode_AsUTF8String(grouping)) == NULL) { goto finish; } + Py_DECREF(grouping); + grouping = tmp; spec.grouping = PyBytes_AS_STRING(grouping); } if (mpd_validate_lconv(&spec) < 0) { diff --git a/Modules/_pickle.c b/Modules/_pickle.c index c7861f7ef18b12..8fca08f281b704 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -218,10 +218,9 @@ _Pickle_InitState(PickleState *st) builtins = PyEval_GetBuiltins(); if (builtins == NULL) goto error; - st->getattr = PyDict_GetItemString(builtins, "getattr"); + st->getattr = PyDict_GetItemRefString(builtins, "getattr"); if (st->getattr == NULL) goto error; - Py_INCREF(st->getattr); copyreg = PyImport_ImportModule("copyreg"); if (!copyreg) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 28a45a87e279e8..946ca81133af7e 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1458,7 +1458,7 @@ pysqlite_connection_iterdump(pysqlite_Connection* self, PyObject* args) goto finally; } - pyfn_iterdump = PyDict_GetItemString(module_dict, "_iterdump"); + pyfn_iterdump = PyDict_GetItemRefString(module_dict, "_iterdump"); if (!pyfn_iterdump) { PyErr_SetString(pysqlite_OperationalError, "Failed to obtain _iterdump() reference"); goto finally; @@ -1473,6 +1473,7 @@ pysqlite_connection_iterdump(pysqlite_Connection* self, PyObject* args) retval = PyObject_CallObject(pyfn_iterdump, args); finally: + Py_XDECREF(pyfn_iterdump); Py_XDECREF(args); Py_XDECREF(module); return retval; diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index a8de5c72fbfbcd..e730abc85eee6b 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -281,8 +281,7 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para binding_name++; /* skip first char (the colon) */ if (PyDict_CheckExact(parameters)) { - current_param = PyDict_GetItemString(parameters, binding_name); - Py_XINCREF(current_param); + current_param = PyDict_GetItemRefString(parameters, binding_name); } else { current_param = PyMapping_GetItemString(parameters, binding_name); } diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index b19e2951138c06..0be9f583fca952 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -4351,16 +4351,20 @@ zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) Py_ssize_t i; PyObject *ittuple; /* tuple of iterators */ PyObject *result; - PyObject *fillvalue = Py_None; + PyObject *fillvalue; Py_ssize_t tuplesize; if (kwds != NULL && PyDict_CheckExact(kwds) && PyDict_GET_SIZE(kwds) > 0) { - fillvalue = PyDict_GetItemString(kwds, "fillvalue"); + fillvalue = PyDict_GetItemRefString(kwds, "fillvalue"); if (fillvalue == NULL || PyDict_GET_SIZE(kwds) > 1) { + Py_XDECREF(fillvalue); PyErr_SetString(PyExc_TypeError, "zip_longest() got an unexpected keyword argument"); return NULL; } + } else { + fillvalue = Py_None; + Py_INCREF(fillvalue); } /* args must be a tuple */ @@ -4407,7 +4411,6 @@ zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) lz->tuplesize = tuplesize; lz->numactive = tuplesize; lz->result = result; - Py_INCREF(fillvalue); lz->fillvalue = fillvalue; return (PyObject *)lz; } diff --git a/Modules/main.c b/Modules/main.c index 1ab555b42de49f..c1c03fc62ac482 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -501,7 +501,7 @@ pymain_sys_path_add_path0(PyInterpreterState *interp, PyObject *path0) PyObject *sys_path; PyObject *sysdict = interp->sysdict; if (sysdict != NULL) { - sys_path = PyDict_GetItemString(sysdict, "path"); + sys_path = PyDict_GetItemRefString(sysdict, "path"); } else { sys_path = NULL; @@ -512,8 +512,10 @@ pymain_sys_path_add_path0(PyInterpreterState *interp, PyObject *path0) } if (PyList_Insert(sys_path, 0, path0)) { + Py_DECREF(sys_path); goto error; } + Py_DECREF(sys_path); return 0; error: diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index d1209485827331..8c89914f518ce6 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -1325,10 +1325,9 @@ PyInit__signal(void) goto finally; #endif - x = IntHandler = PyDict_GetItemString(d, "default_int_handler"); + x = IntHandler = PyDict_GetItemRefString(d, "default_int_handler"); if (!x) goto finally; - Py_INCREF(IntHandler); _Py_atomic_store_relaxed(&Handlers[0].tripped, 0); for (i = 1; i < NSIG; i++) { diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 8ceecce2ce4881..161ff5d478dbdd 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -358,9 +358,11 @@ remove_unusable_flags(PyObject *m) break; } else { - if (PyDict_GetItemString( - dict, - win_runtime_flags[i].flag_name) != NULL) { + PyObject *flag = PyDict_GetItemRefString( + dict, + win_runtime_flags[i].flag_name); + if (flag != NULL) { + Py_DECREF(flag); PyDict_DelItemString( dict, win_runtime_flags[i].flag_name); From 52590bc9adc811e18e7e805a4b71157e97f396fa Mon Sep 17 00:00:00 2001 From: Dino Viehland Date: Fri, 14 Sep 2018 15:18:48 -0700 Subject: [PATCH 50/50] Remove PyModule_GetDict from new C API --- Include/moduleobject.h | 2 + Modules/_curses_panel.c | 11 +- Modules/_cursesmodule.c | 26 +- Modules/_dbmmodule.c | 7 +- Modules/_lsprof.c | 5 +- Modules/_sqlite/connection.c | 8 +- Modules/_sqlite/microprotocols.c | 4 +- Modules/_sqlite/microprotocols.h | 2 +- Modules/_sqlite/module.c | 42 ++- Modules/_sre.c | 12 +- Modules/_ssl.c | 25 +- Modules/_threadmodule.c | 7 +- Modules/_winapi.c | 6 +- Modules/audioop.c | 7 +- Modules/binascii.c | 8 +- Modules/errnomodule.c | 523 +++++++++++++++---------------- Modules/grpmodule.c | 3 +- Modules/mmapmodule.c | 43 ++- Modules/nismodule.c | 5 +- Modules/overlapped.c | 6 +- Modules/pyexpat.c | 11 +- Modules/signalmodule.c | 12 +- Modules/socketmodule.c | 14 +- Modules/zipimport.c | 7 +- 24 files changed, 373 insertions(+), 423 deletions(-) diff --git a/Include/moduleobject.h b/Include/moduleobject.h index 48b07229873852..409ff55d4a8654 100644 --- a/Include/moduleobject.h +++ b/Include/moduleobject.h @@ -20,7 +20,9 @@ PyAPI_FUNC(PyObject *) PyModule_NewObject( PyAPI_FUNC(PyObject *) PyModule_New( const char *name /* UTF-8 encoded string */ ); +#ifndef Py_NEWCAPI PyAPI_FUNC(PyObject *) PyModule_GetDict(PyObject *); +#endif #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(PyObject *) PyModule_GetNameObject(PyObject *); #endif diff --git a/Modules/_curses_panel.c b/Modules/_curses_panel.c index 609718f65f15ab..683239c4b4150b 100644 --- a/Modules/_curses_panel.c +++ b/Modules/_curses_panel.c @@ -628,13 +628,12 @@ static struct PyModuleDef _curses_panelmodule = { PyMODINIT_FUNC PyInit__curses_panel(void) { - PyObject *m, *d, *v; + PyObject *m, *v; /* Create the module and add the functions */ m = PyModule_Create(&_curses_panelmodule); if (m == NULL) goto fail; - d = PyModule_GetDict(m); /* Initialize object type */ v = PyType_FromSpec(&PyCursesPanel_Type_spec); @@ -649,16 +648,16 @@ PyInit__curses_panel(void) /* For exception _curses_panel.error */ _curses_panelstate(m)->PyCursesError = PyErr_NewException("_curses_panel.error", NULL, NULL); - PyDict_SetItemString(d, "error", _curses_panelstate(m)->PyCursesError); + PyObject_SetAttrString(m, "error", _curses_panelstate(m)->PyCursesError); /* Make the version available */ v = PyUnicode_FromString(PyCursesVersion); - PyDict_SetItemString(d, "version", v); - PyDict_SetItemString(d, "__version__", v); + PyObject_SetAttrString(m, "version", v); + PyObject_SetAttrString(m, "__version__", v); Py_DECREF(v); Py_INCREF(_curses_panelstate(m)->PyCursesPanel_Type); - PyModule_AddObject(m, "panel", (PyObject *)_curses_panelstate(m)->PyCursesPanel_Type); + PyObject_SetAttrString(m, "panel", (PyObject *)_curses_panelstate(m)->PyCursesPanel_Type); return m; fail: Py_XDECREF(m); diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 04fe4dfc698cb2..e660fd5e0a78c4 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -3071,8 +3071,6 @@ _curses_init_pair_impl(PyObject *module, short pair_number, short fg, return PyCursesCheckERR(init_pair(pair_number, fg, bg), "init_pair"); } -static PyObject *ModDict; - /*[clinic input] _curses.initscr @@ -3107,7 +3105,7 @@ _curses_initscr_impl(PyObject *module) #define SetDictInt(string,ch) \ do { \ PyObject *o = PyLong_FromLong((long) (ch)); \ - if (o && PyDict_SetItemString(ModDict, string, o) == 0) { \ + if (o && PyObject_SetAttrString(module, string, o) == 0) { \ Py_DECREF(o); \ } \ } while (0) @@ -3697,7 +3695,7 @@ _curses_qiflush_impl(PyObject *module, int flag) * and _curses.COLS */ #if defined(HAVE_CURSES_RESIZETERM) || defined(HAVE_CURSES_RESIZE_TERM) static int -update_lines_cols(void) +update_lines_cols(PyObject *module) { PyObject *o; PyObject *m = PyImport_ImportModuleNoBlock("curses"); @@ -3718,7 +3716,7 @@ update_lines_cols(void) return 0; } /* PyId_LINES.object will be initialized here. */ - if (PyDict_SetItem(ModDict, PyId_LINES.object, o)) { + if (PyObject_SetAttrString(module, PyId_LINES.object, o)) { Py_DECREF(m); Py_DECREF(o); return 0; @@ -3734,7 +3732,7 @@ update_lines_cols(void) Py_DECREF(o); return 0; } - if (PyDict_SetItem(ModDict, PyId_COLS.object, o)) { + if (PyObject_SetAttrString(module, PyId_COLS.object, o)) { Py_DECREF(m); Py_DECREF(o); return 0; @@ -3753,7 +3751,7 @@ static int _curses_update_lines_cols_impl(PyObject *module) /*[clinic end generated code: output=0345e7f072ea711a input=3a87760f7d5197f0]*/ { - return update_lines_cols(); + return update_lines_cols(module); } #endif @@ -3837,7 +3835,7 @@ _curses_resizeterm_impl(PyObject *module, int nlines, int ncols) result = PyCursesCheckERR(resizeterm(nlines, ncols), "resizeterm"); if (!result) return NULL; - if (!update_lines_cols()) + if (!update_lines_cols(module)) return NULL; return result; } @@ -3874,7 +3872,7 @@ _curses_resize_term_impl(PyObject *module, int nlines, int ncols) result = PyCursesCheckERR(resize_term(nlines, ncols), "resize_term"); if (!result) return NULL; - if (!update_lines_cols()) + if (!update_lines_cols(module)) return NULL; return result; } @@ -3946,12 +3944,12 @@ _curses_start_color_impl(PyObject *module) c = PyLong_FromLong((long) COLORS); if (c == NULL) return NULL; - PyDict_SetItemString(ModDict, "COLORS", c); + PyObject_SetAttrString(module, "COLORS", c); Py_DECREF(c); cp = PyLong_FromLong((long) COLOR_PAIRS); if (cp == NULL) return NULL; - PyDict_SetItemString(ModDict, "COLOR_PAIRS", cp); + PyObject_SetAttrString(module, "COLOR_PAIRS", cp); Py_DECREF(cp); Py_RETURN_NONE; } else { @@ -4387,7 +4385,7 @@ static struct PyModuleDef _cursesmodule = { PyMODINIT_FUNC PyInit__curses(void) { - PyObject *m, *d, *v, *c_api_object; + PyObject *m, *v, *c_api_object; static void *PyCurses_API[PyCurses_API_pointers]; /* Initialize object type */ @@ -4406,10 +4404,6 @@ PyInit__curses(void) return NULL; /* Add some symbolic constants to the module */ - d = PyModule_GetDict(m); - if (d == NULL) - return NULL; - ModDict = d; /* For PyCurses_InitScr to use later */ /* Add a capsule for the C API */ c_api_object = PyCapsule_New(PyCurses_API, PyCurses_CAPSULE_NAME, NULL); diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c index 65761d83d380f7..5797c7e8569290 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -486,24 +486,23 @@ static struct PyModuleDef _dbmmodule = { PyMODINIT_FUNC PyInit__dbm(void) { - PyObject *m, *d, *s; + PyObject *m, *s; if (PyType_Ready(&Dbmtype) < 0) return NULL; m = PyModule_Create(&_dbmmodule); if (m == NULL) return NULL; - d = PyModule_GetDict(m); if (DbmError == NULL) DbmError = PyErr_NewException("_dbm.error", PyExc_OSError, NULL); s = PyUnicode_FromString(which_dbm); if (s != NULL) { - PyDict_SetItemString(d, "library", s); + PyObject_SetAttrString(m, "library", s); Py_DECREF(s); } if (DbmError != NULL) - PyDict_SetItemString(d, "error", DbmError); + PyObject_SetAttrString(m, "error", DbmError); if (PyErr_Occurred()) { Py_DECREF(m); m = NULL; diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index 11e3740c68a8fe..d4d2d1673f5a4d 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -863,14 +863,13 @@ static struct PyModuleDef _lsprofmodule = { PyMODINIT_FUNC PyInit__lsprof(void) { - PyObject *module, *d; + PyObject *module; module = PyModule_Create(&_lsprofmodule); if (module == NULL) return NULL; - d = PyModule_GetDict(module); if (PyType_Ready(&PyProfiler_Type) < 0) return NULL; - PyDict_SetItemString(d, "Profiler", (PyObject *)&PyProfiler_Type); + PyObject_SetAttrString(module, "Profiler", (PyObject *)&PyProfiler_Type); if (!initialized) { if (PyStructSequence_InitType2(&StatsEntryType, diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 946ca81133af7e..92ab8fdd94c974 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1441,7 +1441,6 @@ pysqlite_connection_iterdump(pysqlite_Connection* self, PyObject* args) { PyObject* retval = NULL; PyObject* module = NULL; - PyObject* module_dict; PyObject* pyfn_iterdump; if (!pysqlite_check_connection(self)) { @@ -1453,12 +1452,7 @@ pysqlite_connection_iterdump(pysqlite_Connection* self, PyObject* args) goto finally; } - module_dict = PyModule_GetDict(module); - if (!module_dict) { - goto finally; - } - - pyfn_iterdump = PyDict_GetItemRefString(module_dict, "_iterdump"); + pyfn_iterdump = PyObject_GetAttrString(module, "_iterdump"); if (!pyfn_iterdump) { PyErr_SetString(pysqlite_OperationalError, "Failed to obtain _iterdump() reference"); goto finally; diff --git a/Modules/_sqlite/microprotocols.c b/Modules/_sqlite/microprotocols.c index ec89d13113197d..e67a201c8ee565 100644 --- a/Modules/_sqlite/microprotocols.c +++ b/Modules/_sqlite/microprotocols.c @@ -38,14 +38,14 @@ static PyObject *psyco_adapters = NULL; /* pysqlite_microprotocols_init - initialize the adapters dictionary */ int -pysqlite_microprotocols_init(PyObject *dict) +pysqlite_microprotocols_init(PyObject *module) { /* create adapters dictionary and put it in module namespace */ if ((psyco_adapters = PyDict_New()) == NULL) { return -1; } - return PyDict_SetItemString(dict, "adapters", psyco_adapters); + return PyObject_SetAttrString(module, "adapters", psyco_adapters); } diff --git a/Modules/_sqlite/microprotocols.h b/Modules/_sqlite/microprotocols.h index 99ff6f642b25eb..f1e149ade30d3d 100644 --- a/Modules/_sqlite/microprotocols.h +++ b/Modules/_sqlite/microprotocols.h @@ -37,7 +37,7 @@ /** exported functions **/ /* used by module.c to init the microprotocols system */ -extern int pysqlite_microprotocols_init(PyObject *dict); +extern int pysqlite_microprotocols_init(PyObject *module); extern int pysqlite_microprotocols_add( PyTypeObject *type, PyObject *proto, PyObject *cast); extern PyObject *pysqlite_microprotocols_adapt( diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index db2b4958b1463e..0119382799303b 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -234,14 +234,14 @@ PyDoc_STRVAR(enable_callback_tracebacks_doc, \n\ Enable or disable callback functions throwing errors to stderr."); -static void converters_init(PyObject* dict) +static void converters_init(PyObject* module) { _pysqlite_converters = PyDict_New(); if (!_pysqlite_converters) { return; } - PyDict_SetItemString(dict, "converters", _pysqlite_converters); + PyObject_SetAttrString(module, "converters", _pysqlite_converters); } static PyMethodDef module_methods[] = { @@ -344,7 +344,7 @@ static struct PyModuleDef _sqlite3module = { PyMODINIT_FUNC PyInit__sqlite3(void) { - PyObject *module, *dict; + PyObject *module; PyObject *tmp_obj; int i; @@ -375,65 +375,61 @@ PyMODINIT_FUNC PyInit__sqlite3(void) Py_INCREF(&pysqlite_RowType); PyModule_AddObject(module, "Row", (PyObject*) &pysqlite_RowType); - if (!(dict = PyModule_GetDict(module))) { - goto error; - } - /*** Create DB-API Exception hierarchy */ if (!(pysqlite_Error = PyErr_NewException(MODULE_NAME ".Error", PyExc_Exception, NULL))) { goto error; } - PyDict_SetItemString(dict, "Error", pysqlite_Error); + PyObject_SetAttrString(module, "Error", pysqlite_Error); if (!(pysqlite_Warning = PyErr_NewException(MODULE_NAME ".Warning", PyExc_Exception, NULL))) { goto error; } - PyDict_SetItemString(dict, "Warning", pysqlite_Warning); + PyObject_SetAttrString(module, "Warning", pysqlite_Warning); /* Error subclasses */ if (!(pysqlite_InterfaceError = PyErr_NewException(MODULE_NAME ".InterfaceError", pysqlite_Error, NULL))) { goto error; } - PyDict_SetItemString(dict, "InterfaceError", pysqlite_InterfaceError); + PyObject_SetAttrString(module, "InterfaceError", pysqlite_InterfaceError); if (!(pysqlite_DatabaseError = PyErr_NewException(MODULE_NAME ".DatabaseError", pysqlite_Error, NULL))) { goto error; } - PyDict_SetItemString(dict, "DatabaseError", pysqlite_DatabaseError); + PyObject_SetAttrString(module, "DatabaseError", pysqlite_DatabaseError); /* pysqlite_DatabaseError subclasses */ if (!(pysqlite_InternalError = PyErr_NewException(MODULE_NAME ".InternalError", pysqlite_DatabaseError, NULL))) { goto error; } - PyDict_SetItemString(dict, "InternalError", pysqlite_InternalError); + PyObject_SetAttrString(module, "InternalError", pysqlite_InternalError); if (!(pysqlite_OperationalError = PyErr_NewException(MODULE_NAME ".OperationalError", pysqlite_DatabaseError, NULL))) { goto error; } - PyDict_SetItemString(dict, "OperationalError", pysqlite_OperationalError); + PyObject_SetAttrString(module, "OperationalError", pysqlite_OperationalError); if (!(pysqlite_ProgrammingError = PyErr_NewException(MODULE_NAME ".ProgrammingError", pysqlite_DatabaseError, NULL))) { goto error; } - PyDict_SetItemString(dict, "ProgrammingError", pysqlite_ProgrammingError); + PyObject_SetAttrString(module, "ProgrammingError", pysqlite_ProgrammingError); if (!(pysqlite_IntegrityError = PyErr_NewException(MODULE_NAME ".IntegrityError", pysqlite_DatabaseError,NULL))) { goto error; } - PyDict_SetItemString(dict, "IntegrityError", pysqlite_IntegrityError); + PyObject_SetAttrString(module, "IntegrityError", pysqlite_IntegrityError); if (!(pysqlite_DataError = PyErr_NewException(MODULE_NAME ".DataError", pysqlite_DatabaseError, NULL))) { goto error; } - PyDict_SetItemString(dict, "DataError", pysqlite_DataError); + PyObject_SetAttrString(module, "DataError", pysqlite_DataError); if (!(pysqlite_NotSupportedError = PyErr_NewException(MODULE_NAME ".NotSupportedError", pysqlite_DatabaseError, NULL))) { goto error; } - PyDict_SetItemString(dict, "NotSupportedError", pysqlite_NotSupportedError); + PyObject_SetAttrString(module, "NotSupportedError", pysqlite_NotSupportedError); /* In Python 2.x, setting Connection.text_factory to OptimizedUnicode caused Unicode objects to be returned for @@ -441,7 +437,7 @@ PyMODINIT_FUNC PyInit__sqlite3(void) Now OptimizedUnicode is an alias for str, so it has no effect. */ Py_INCREF((PyObject*)&PyUnicode_Type); - PyDict_SetItemString(dict, "OptimizedUnicode", (PyObject*)&PyUnicode_Type); + PyObject_SetAttrString(module, "OptimizedUnicode", (PyObject*)&PyUnicode_Type); /* Set integer constants */ for (i = 0; _int_constants[i].constant_name != NULL; i++) { @@ -449,27 +445,27 @@ PyMODINIT_FUNC PyInit__sqlite3(void) if (!tmp_obj) { goto error; } - PyDict_SetItemString(dict, _int_constants[i].constant_name, tmp_obj); + PyObject_SetAttrString(module, _int_constants[i].constant_name, tmp_obj); Py_DECREF(tmp_obj); } if (!(tmp_obj = PyUnicode_FromString(PYSQLITE_VERSION))) { goto error; } - PyDict_SetItemString(dict, "version", tmp_obj); + PyObject_SetAttrString(module, "version", tmp_obj); Py_DECREF(tmp_obj); if (!(tmp_obj = PyUnicode_FromString(sqlite3_libversion()))) { goto error; } - PyDict_SetItemString(dict, "sqlite_version", tmp_obj); + PyObject_SetAttrString(module, "sqlite_version", tmp_obj); Py_DECREF(tmp_obj); /* initialize microprotocols layer */ - pysqlite_microprotocols_init(dict); + pysqlite_microprotocols_init(module); /* initialize the default converters */ - converters_init(dict); + converters_init(module); error: if (PyErr_Occurred()) diff --git a/Modules/_sre.c b/Modules/_sre.c index e50a27265bcf8e..bfcf6533e7f430 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -2782,7 +2782,6 @@ static struct PyModuleDef sremodule = { PyMODINIT_FUNC PyInit__sre(void) { PyObject* m; - PyObject* d; PyObject* x; /* Patch object types */ @@ -2793,35 +2792,34 @@ PyMODINIT_FUNC PyInit__sre(void) m = PyModule_Create(&sremodule); if (m == NULL) return NULL; - d = PyModule_GetDict(m); x = PyLong_FromLong(SRE_MAGIC); if (x) { - PyDict_SetItemString(d, "MAGIC", x); + PyObject_SetAttrString(m, "MAGIC", x); Py_DECREF(x); } x = PyLong_FromLong(sizeof(SRE_CODE)); if (x) { - PyDict_SetItemString(d, "CODESIZE", x); + PyObject_SetAttrString(m, "CODESIZE", x); Py_DECREF(x); } x = PyLong_FromUnsignedLong(SRE_MAXREPEAT); if (x) { - PyDict_SetItemString(d, "MAXREPEAT", x); + PyObject_SetAttrString(m, "MAXREPEAT", x); Py_DECREF(x); } x = PyLong_FromUnsignedLong(SRE_MAXGROUPS); if (x) { - PyDict_SetItemString(d, "MAXGROUPS", x); + PyObject_SetAttrString(m, "MAXGROUPS", x); Py_DECREF(x); } x = PyUnicode_FromString(copyright); if (x) { - PyDict_SetItemString(d, "copyright", x); + PyObject_SetAttrString(m, "copyright", x); Py_DECREF(x); } return m; diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 27c1f20d9f04e9..ad69da28fd2c1f 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -5609,7 +5609,7 @@ parse_openssl_version(unsigned long libver, PyMODINIT_FUNC PyInit__ssl(void) { - PyObject *m, *d, *r, *bases; + PyObject *m, *r, *bases; unsigned long libver; unsigned int major, minor, fix, patch, status; PySocketModule_APIObject *socket_api; @@ -5629,7 +5629,6 @@ PyInit__ssl(void) m = PyModule_Create(&_sslmodule); if (m == NULL) return NULL; - d = PyModule_GetDict(m); /* Load _socket module and its C API */ socket_api = PySocketModule_ImportModuleAndAPI(); @@ -5691,25 +5690,25 @@ PyInit__ssl(void) || PySSLSyscallErrorObject == NULL || PySSLEOFErrorObject == NULL) return NULL; - if (PyDict_SetItemString(d, "SSLError", PySSLErrorObject) != 0 - || PyDict_SetItemString(d, "SSLCertVerificationError", + if (PyObject_SetAttrString(m, "SSLError", PySSLErrorObject) != 0 + || PyObject_SetAttrString(m, "SSLCertVerificationError", PySSLCertVerificationErrorObject) != 0 - || PyDict_SetItemString(d, "SSLZeroReturnError", PySSLZeroReturnErrorObject) != 0 - || PyDict_SetItemString(d, "SSLWantReadError", PySSLWantReadErrorObject) != 0 - || PyDict_SetItemString(d, "SSLWantWriteError", PySSLWantWriteErrorObject) != 0 - || PyDict_SetItemString(d, "SSLSyscallError", PySSLSyscallErrorObject) != 0 - || PyDict_SetItemString(d, "SSLEOFError", PySSLEOFErrorObject) != 0) + || PyObject_SetAttrString(m, "SSLZeroReturnError", PySSLZeroReturnErrorObject) != 0 + || PyObject_SetAttrString(m, "SSLWantReadError", PySSLWantReadErrorObject) != 0 + || PyObject_SetAttrString(m, "SSLWantWriteError", PySSLWantWriteErrorObject) != 0 + || PyObject_SetAttrString(m, "SSLSyscallError", PySSLSyscallErrorObject) != 0 + || PyObject_SetAttrString(m, "SSLEOFError", PySSLEOFErrorObject) != 0) return NULL; - if (PyDict_SetItemString(d, "_SSLContext", + if (PyObject_SetAttrString(m, "_SSLContext", (PyObject *)&PySSLContext_Type) != 0) return NULL; - if (PyDict_SetItemString(d, "_SSLSocket", + if (PyObject_SetAttrString(m, "_SSLSocket", (PyObject *)&PySSLSocket_Type) != 0) return NULL; - if (PyDict_SetItemString(d, "MemoryBIO", + if (PyObject_SetAttrString(m, "MemoryBIO", (PyObject *)&PySSLMemoryBIO_Type) != 0) return NULL; - if (PyDict_SetItemString(d, "SSLSession", + if (PyObject_SetAttrString(m, "SSLSession", (PyObject *)&PySSLSession_Type) != 0) return NULL; diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index ccf42032bb3c9e..97baa55884119d 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -1350,7 +1350,7 @@ static struct PyModuleDef threadmodule = { PyMODINIT_FUNC PyInit__thread(void) { - PyObject *m, *d, *v; + PyObject *m, *v; double time_max; double timeout_max; PyInterpreterState *interp = _PyInterpreterState_Get(); @@ -1383,14 +1383,13 @@ PyInit__thread(void) return NULL; /* Add a symbolic constant */ - d = PyModule_GetDict(m); ThreadError = PyExc_RuntimeError; Py_INCREF(ThreadError); - PyDict_SetItemString(d, "error", ThreadError); + PyObject_SetAttrString(m, "error", ThreadError); Locktype.tp_doc = lock_doc; Py_INCREF(&Locktype); - PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype); + PyObject_SetAttrString(m, "LockType", (PyObject *)&Locktype); Py_INCREF(&RLocktype); if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0) diff --git a/Modules/_winapi.c b/Modules/_winapi.c index 30f269fbdccdad..b9e7459af7c669 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -1741,12 +1741,11 @@ static struct PyModuleDef winapi_module = { }; #define WINAPI_CONSTANT(fmt, con) \ - PyDict_SetItemString(d, #con, Py_BuildValue(fmt, con)) + PyObject_SetAttrString(m, #con, Py_BuildValue(fmt, con)) PyMODINIT_FUNC PyInit__winapi(void) { - PyObject *d; PyObject *m; if (PyType_Ready(&OverlappedType) < 0) @@ -1755,9 +1754,8 @@ PyInit__winapi(void) m = PyModule_Create(&winapi_module); if (m == NULL) return NULL; - d = PyModule_GetDict(m); - PyDict_SetItemString(d, "Overlapped", (PyObject *) &OverlappedType); + PyObject_SetAttrString(m, "Overlapped", (PyObject *) &OverlappedType); /* constants */ WINAPI_CONSTANT(F_DWORD, CREATE_NEW_CONSOLE); diff --git a/Modules/audioop.c b/Modules/audioop.c index 1b4c147aa0cb79..23a04eee30bb83 100644 --- a/Modules/audioop.c +++ b/Modules/audioop.c @@ -1917,15 +1917,12 @@ static struct PyModuleDef audioopmodule = { PyMODINIT_FUNC PyInit_audioop(void) { - PyObject *m, *d; + PyObject *m; m = PyModule_Create(&audioopmodule); if (m == NULL) return NULL; - d = PyModule_GetDict(m); - if (d == NULL) - return NULL; AudioopError = PyErr_NewException("audioop.error", NULL, NULL); if (AudioopError != NULL) - PyDict_SetItemString(d,"error",AudioopError); + PyObject_SetAttrString(m, "error", AudioopError); return m; } diff --git a/Modules/binascii.c b/Modules/binascii.c index 3930beaed13ab7..ccaa32314ce7a5 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -1557,19 +1557,17 @@ static struct PyModuleDef binasciimodule = { PyMODINIT_FUNC PyInit_binascii(void) { - PyObject *m, *d; + PyObject *m; /* Create the module and add the functions */ m = PyModule_Create(&binasciimodule); if (m == NULL) return NULL; - d = PyModule_GetDict(m); - Error = PyErr_NewException("binascii.Error", PyExc_ValueError, NULL); - PyDict_SetItemString(d, "Error", Error); + PyObject_SetAttrString(m, "Error", Error); Incomplete = PyErr_NewException("binascii.Incomplete", NULL, NULL); - PyDict_SetItemString(d, "Incomplete", Incomplete); + PyObject_SetAttrString(m, "Incomplete", Incomplete); if (PyErr_Occurred()) { Py_DECREF(m); m = NULL; diff --git a/Modules/errnomodule.c b/Modules/errnomodule.c index 06ed53a64dbdc1..84d468f63e6b08 100644 --- a/Modules/errnomodule.c +++ b/Modules/errnomodule.c @@ -47,7 +47,7 @@ static PyMethodDef errno_methods[] = { /* Helper function doing the dictionary inserting */ static void -_inscode(PyObject *d, PyObject *de, const char *name, int code) +_inscode(PyObject *m, PyObject *de, const char *name, int code) { PyObject *u = PyUnicode_FromString(name); PyObject *v = PyLong_FromLong((long) code); @@ -58,7 +58,7 @@ _inscode(PyObject *d, PyObject *de, const char *name, int code) */ if (u && v) { /* insert in modules dict */ - PyDict_SetItem(d, u, v); + PyObject_SetAttr(m, u, v); /* insert in errorcode dict */ PyDict_SetItem(de, v, u); } @@ -95,17 +95,16 @@ static struct PyModuleDef errnomodule = { PyMODINIT_FUNC PyInit_errno(void) { - PyObject *m, *d, *de; + PyObject *m, *de; m = PyModule_Create(&errnomodule); if (m == NULL) return NULL; - d = PyModule_GetDict(m); de = PyDict_New(); - if (!d || !de || PyDict_SetItemString(d, "errorcode", de) < 0) + if (!de || PyObject_SetAttrString(m, "errorcode", de) < 0) return NULL; /* Macro so I don't have to edit each and every line below... */ -#define inscode(d, ds, de, name, code, comment) _inscode(d, de, name, code) +#define inscode(m, ds, de, name, code, comment) _inscode(m, de, name, code) /* * The names and comments are borrowed from linux/include/errno.h, @@ -116,818 +115,818 @@ PyInit_errno(void) */ #ifdef ENODEV - inscode(d, ds, de, "ENODEV", ENODEV, "No such device"); + inscode(m, ds, de, "ENODEV", ENODEV, "No such device"); #endif #ifdef ENOCSI - inscode(d, ds, de, "ENOCSI", ENOCSI, "No CSI structure available"); + inscode(m, ds, de, "ENOCSI", ENOCSI, "No CSI structure available"); #endif #ifdef EHOSTUNREACH - inscode(d, ds, de, "EHOSTUNREACH", EHOSTUNREACH, "No route to host"); + inscode(m, ds, de, "EHOSTUNREACH", EHOSTUNREACH, "No route to host"); #else #ifdef WSAEHOSTUNREACH - inscode(d, ds, de, "EHOSTUNREACH", WSAEHOSTUNREACH, "No route to host"); + inscode(m, ds, de, "EHOSTUNREACH", WSAEHOSTUNREACH, "No route to host"); #endif #endif #ifdef ENOMSG - inscode(d, ds, de, "ENOMSG", ENOMSG, "No message of desired type"); + inscode(m, ds, de, "ENOMSG", ENOMSG, "No message of desired type"); #endif #ifdef EUCLEAN - inscode(d, ds, de, "EUCLEAN", EUCLEAN, "Structure needs cleaning"); + inscode(m, ds, de, "EUCLEAN", EUCLEAN, "Structure needs cleaning"); #endif #ifdef EL2NSYNC - inscode(d, ds, de, "EL2NSYNC", EL2NSYNC, "Level 2 not synchronized"); + inscode(m, ds, de, "EL2NSYNC", EL2NSYNC, "Level 2 not synchronized"); #endif #ifdef EL2HLT - inscode(d, ds, de, "EL2HLT", EL2HLT, "Level 2 halted"); + inscode(m, ds, de, "EL2HLT", EL2HLT, "Level 2 halted"); #endif #ifdef ENODATA - inscode(d, ds, de, "ENODATA", ENODATA, "No data available"); + inscode(m, ds, de, "ENODATA", ENODATA, "No data available"); #endif #ifdef ENOTBLK - inscode(d, ds, de, "ENOTBLK", ENOTBLK, "Block device required"); + inscode(m, ds, de, "ENOTBLK", ENOTBLK, "Block device required"); #endif #ifdef ENOSYS - inscode(d, ds, de, "ENOSYS", ENOSYS, "Function not implemented"); + inscode(m, ds, de, "ENOSYS", ENOSYS, "Function not implemented"); #endif #ifdef EPIPE - inscode(d, ds, de, "EPIPE", EPIPE, "Broken pipe"); + inscode(m, ds, de, "EPIPE", EPIPE, "Broken pipe"); #endif #ifdef EINVAL - inscode(d, ds, de, "EINVAL", EINVAL, "Invalid argument"); + inscode(m, ds, de, "EINVAL", EINVAL, "Invalid argument"); #else #ifdef WSAEINVAL - inscode(d, ds, de, "EINVAL", WSAEINVAL, "Invalid argument"); + inscode(m, ds, de, "EINVAL", WSAEINVAL, "Invalid argument"); #endif #endif #ifdef EOVERFLOW - inscode(d, ds, de, "EOVERFLOW", EOVERFLOW, "Value too large for defined data type"); + inscode(m, ds, de, "EOVERFLOW", EOVERFLOW, "Value too large for defined data type"); #endif #ifdef EADV - inscode(d, ds, de, "EADV", EADV, "Advertise error"); + inscode(m, ds, de, "EADV", EADV, "Advertise error"); #endif #ifdef EINTR - inscode(d, ds, de, "EINTR", EINTR, "Interrupted system call"); + inscode(m, ds, de, "EINTR", EINTR, "Interrupted system call"); #else #ifdef WSAEINTR - inscode(d, ds, de, "EINTR", WSAEINTR, "Interrupted system call"); + inscode(m, ds, de, "EINTR", WSAEINTR, "Interrupted system call"); #endif #endif #ifdef EUSERS - inscode(d, ds, de, "EUSERS", EUSERS, "Too many users"); + inscode(m, ds, de, "EUSERS", EUSERS, "Too many users"); #else #ifdef WSAEUSERS - inscode(d, ds, de, "EUSERS", WSAEUSERS, "Too many users"); + inscode(m, ds, de, "EUSERS", WSAEUSERS, "Too many users"); #endif #endif #ifdef ENOTEMPTY - inscode(d, ds, de, "ENOTEMPTY", ENOTEMPTY, "Directory not empty"); + inscode(m, ds, de, "ENOTEMPTY", ENOTEMPTY, "Directory not empty"); #else #ifdef WSAENOTEMPTY - inscode(d, ds, de, "ENOTEMPTY", WSAENOTEMPTY, "Directory not empty"); + inscode(m, ds, de, "ENOTEMPTY", WSAENOTEMPTY, "Directory not empty"); #endif #endif #ifdef ENOBUFS - inscode(d, ds, de, "ENOBUFS", ENOBUFS, "No buffer space available"); + inscode(m, ds, de, "ENOBUFS", ENOBUFS, "No buffer space available"); #else #ifdef WSAENOBUFS - inscode(d, ds, de, "ENOBUFS", WSAENOBUFS, "No buffer space available"); + inscode(m, ds, de, "ENOBUFS", WSAENOBUFS, "No buffer space available"); #endif #endif #ifdef EPROTO - inscode(d, ds, de, "EPROTO", EPROTO, "Protocol error"); + inscode(m, ds, de, "EPROTO", EPROTO, "Protocol error"); #endif #ifdef EREMOTE - inscode(d, ds, de, "EREMOTE", EREMOTE, "Object is remote"); + inscode(m, ds, de, "EREMOTE", EREMOTE, "Object is remote"); #else #ifdef WSAEREMOTE - inscode(d, ds, de, "EREMOTE", WSAEREMOTE, "Object is remote"); + inscode(m, ds, de, "EREMOTE", WSAEREMOTE, "Object is remote"); #endif #endif #ifdef ENAVAIL - inscode(d, ds, de, "ENAVAIL", ENAVAIL, "No XENIX semaphores available"); + inscode(m, ds, de, "ENAVAIL", ENAVAIL, "No XENIX semaphores available"); #endif #ifdef ECHILD - inscode(d, ds, de, "ECHILD", ECHILD, "No child processes"); + inscode(m, ds, de, "ECHILD", ECHILD, "No child processes"); #endif #ifdef ELOOP - inscode(d, ds, de, "ELOOP", ELOOP, "Too many symbolic links encountered"); + inscode(m, ds, de, "ELOOP", ELOOP, "Too many symbolic links encountered"); #else #ifdef WSAELOOP - inscode(d, ds, de, "ELOOP", WSAELOOP, "Too many symbolic links encountered"); + inscode(m, ds, de, "ELOOP", WSAELOOP, "Too many symbolic links encountered"); #endif #endif #ifdef EXDEV - inscode(d, ds, de, "EXDEV", EXDEV, "Cross-device link"); + inscode(m, ds, de, "EXDEV", EXDEV, "Cross-device link"); #endif #ifdef E2BIG - inscode(d, ds, de, "E2BIG", E2BIG, "Arg list too long"); + inscode(m, ds, de, "E2BIG", E2BIG, "Arg list too long"); #endif #ifdef ESRCH - inscode(d, ds, de, "ESRCH", ESRCH, "No such process"); + inscode(m, ds, de, "ESRCH", ESRCH, "No such process"); #endif #ifdef EMSGSIZE - inscode(d, ds, de, "EMSGSIZE", EMSGSIZE, "Message too long"); + inscode(m, ds, de, "EMSGSIZE", EMSGSIZE, "Message too long"); #else #ifdef WSAEMSGSIZE - inscode(d, ds, de, "EMSGSIZE", WSAEMSGSIZE, "Message too long"); + inscode(m, ds, de, "EMSGSIZE", WSAEMSGSIZE, "Message too long"); #endif #endif #ifdef EAFNOSUPPORT - inscode(d, ds, de, "EAFNOSUPPORT", EAFNOSUPPORT, "Address family not supported by protocol"); + inscode(m, ds, de, "EAFNOSUPPORT", EAFNOSUPPORT, "Address family not supported by protocol"); #else #ifdef WSAEAFNOSUPPORT - inscode(d, ds, de, "EAFNOSUPPORT", WSAEAFNOSUPPORT, "Address family not supported by protocol"); + inscode(m, ds, de, "EAFNOSUPPORT", WSAEAFNOSUPPORT, "Address family not supported by protocol"); #endif #endif #ifdef EBADR - inscode(d, ds, de, "EBADR", EBADR, "Invalid request descriptor"); + inscode(m, ds, de, "EBADR", EBADR, "Invalid request descriptor"); #endif #ifdef EHOSTDOWN - inscode(d, ds, de, "EHOSTDOWN", EHOSTDOWN, "Host is down"); + inscode(m, ds, de, "EHOSTDOWN", EHOSTDOWN, "Host is down"); #else #ifdef WSAEHOSTDOWN - inscode(d, ds, de, "EHOSTDOWN", WSAEHOSTDOWN, "Host is down"); + inscode(m, ds, de, "EHOSTDOWN", WSAEHOSTDOWN, "Host is down"); #endif #endif #ifdef EPFNOSUPPORT - inscode(d, ds, de, "EPFNOSUPPORT", EPFNOSUPPORT, "Protocol family not supported"); + inscode(m, ds, de, "EPFNOSUPPORT", EPFNOSUPPORT, "Protocol family not supported"); #else #ifdef WSAEPFNOSUPPORT - inscode(d, ds, de, "EPFNOSUPPORT", WSAEPFNOSUPPORT, "Protocol family not supported"); + inscode(m, ds, de, "EPFNOSUPPORT", WSAEPFNOSUPPORT, "Protocol family not supported"); #endif #endif #ifdef ENOPROTOOPT - inscode(d, ds, de, "ENOPROTOOPT", ENOPROTOOPT, "Protocol not available"); + inscode(m, ds, de, "ENOPROTOOPT", ENOPROTOOPT, "Protocol not available"); #else #ifdef WSAENOPROTOOPT - inscode(d, ds, de, "ENOPROTOOPT", WSAENOPROTOOPT, "Protocol not available"); + inscode(m, ds, de, "ENOPROTOOPT", WSAENOPROTOOPT, "Protocol not available"); #endif #endif #ifdef EBUSY - inscode(d, ds, de, "EBUSY", EBUSY, "Device or resource busy"); + inscode(m, ds, de, "EBUSY", EBUSY, "Device or resource busy"); #endif #ifdef EWOULDBLOCK - inscode(d, ds, de, "EWOULDBLOCK", EWOULDBLOCK, "Operation would block"); + inscode(m, ds, de, "EWOULDBLOCK", EWOULDBLOCK, "Operation would block"); #else #ifdef WSAEWOULDBLOCK - inscode(d, ds, de, "EWOULDBLOCK", WSAEWOULDBLOCK, "Operation would block"); + inscode(m, ds, de, "EWOULDBLOCK", WSAEWOULDBLOCK, "Operation would block"); #endif #endif #ifdef EBADFD - inscode(d, ds, de, "EBADFD", EBADFD, "File descriptor in bad state"); + inscode(m, ds, de, "EBADFD", EBADFD, "File descriptor in bad state"); #endif #ifdef EDOTDOT - inscode(d, ds, de, "EDOTDOT", EDOTDOT, "RFS specific error"); + inscode(m, ds, de, "EDOTDOT", EDOTDOT, "RFS specific error"); #endif #ifdef EISCONN - inscode(d, ds, de, "EISCONN", EISCONN, "Transport endpoint is already connected"); + inscode(m, ds, de, "EISCONN", EISCONN, "Transport endpoint is already connected"); #else #ifdef WSAEISCONN - inscode(d, ds, de, "EISCONN", WSAEISCONN, "Transport endpoint is already connected"); + inscode(m, ds, de, "EISCONN", WSAEISCONN, "Transport endpoint is already connected"); #endif #endif #ifdef ENOANO - inscode(d, ds, de, "ENOANO", ENOANO, "No anode"); + inscode(m, ds, de, "ENOANO", ENOANO, "No anode"); #endif #ifdef ESHUTDOWN - inscode(d, ds, de, "ESHUTDOWN", ESHUTDOWN, "Cannot send after transport endpoint shutdown"); + inscode(m, ds, de, "ESHUTDOWN", ESHUTDOWN, "Cannot send after transport endpoint shutdown"); #else #ifdef WSAESHUTDOWN - inscode(d, ds, de, "ESHUTDOWN", WSAESHUTDOWN, "Cannot send after transport endpoint shutdown"); + inscode(m, ds, de, "ESHUTDOWN", WSAESHUTDOWN, "Cannot send after transport endpoint shutdown"); #endif #endif #ifdef ECHRNG - inscode(d, ds, de, "ECHRNG", ECHRNG, "Channel number out of range"); + inscode(m, ds, de, "ECHRNG", ECHRNG, "Channel number out of range"); #endif #ifdef ELIBBAD - inscode(d, ds, de, "ELIBBAD", ELIBBAD, "Accessing a corrupted shared library"); + inscode(m, ds, de, "ELIBBAD", ELIBBAD, "Accessing a corrupted shared library"); #endif #ifdef ENONET - inscode(d, ds, de, "ENONET", ENONET, "Machine is not on the network"); + inscode(m, ds, de, "ENONET", ENONET, "Machine is not on the network"); #endif #ifdef EBADE - inscode(d, ds, de, "EBADE", EBADE, "Invalid exchange"); + inscode(m, ds, de, "EBADE", EBADE, "Invalid exchange"); #endif #ifdef EBADF - inscode(d, ds, de, "EBADF", EBADF, "Bad file number"); + inscode(m, ds, de, "EBADF", EBADF, "Bad file number"); #else #ifdef WSAEBADF - inscode(d, ds, de, "EBADF", WSAEBADF, "Bad file number"); + inscode(m, ds, de, "EBADF", WSAEBADF, "Bad file number"); #endif #endif #ifdef EMULTIHOP - inscode(d, ds, de, "EMULTIHOP", EMULTIHOP, "Multihop attempted"); + inscode(m, ds, de, "EMULTIHOP", EMULTIHOP, "Multihop attempted"); #endif #ifdef EIO - inscode(d, ds, de, "EIO", EIO, "I/O error"); + inscode(m, ds, de, "EIO", EIO, "I/O error"); #endif #ifdef EUNATCH - inscode(d, ds, de, "EUNATCH", EUNATCH, "Protocol driver not attached"); + inscode(m, ds, de, "EUNATCH", EUNATCH, "Protocol driver not attached"); #endif #ifdef EPROTOTYPE - inscode(d, ds, de, "EPROTOTYPE", EPROTOTYPE, "Protocol wrong type for socket"); + inscode(m, ds, de, "EPROTOTYPE", EPROTOTYPE, "Protocol wrong type for socket"); #else #ifdef WSAEPROTOTYPE - inscode(d, ds, de, "EPROTOTYPE", WSAEPROTOTYPE, "Protocol wrong type for socket"); + inscode(m, ds, de, "EPROTOTYPE", WSAEPROTOTYPE, "Protocol wrong type for socket"); #endif #endif #ifdef ENOSPC - inscode(d, ds, de, "ENOSPC", ENOSPC, "No space left on device"); + inscode(m, ds, de, "ENOSPC", ENOSPC, "No space left on device"); #endif #ifdef ENOEXEC - inscode(d, ds, de, "ENOEXEC", ENOEXEC, "Exec format error"); + inscode(m, ds, de, "ENOEXEC", ENOEXEC, "Exec format error"); #endif #ifdef EALREADY - inscode(d, ds, de, "EALREADY", EALREADY, "Operation already in progress"); + inscode(m, ds, de, "EALREADY", EALREADY, "Operation already in progress"); #else #ifdef WSAEALREADY - inscode(d, ds, de, "EALREADY", WSAEALREADY, "Operation already in progress"); + inscode(m, ds, de, "EALREADY", WSAEALREADY, "Operation already in progress"); #endif #endif #ifdef ENETDOWN - inscode(d, ds, de, "ENETDOWN", ENETDOWN, "Network is down"); + inscode(m, ds, de, "ENETDOWN", ENETDOWN, "Network is down"); #else #ifdef WSAENETDOWN - inscode(d, ds, de, "ENETDOWN", WSAENETDOWN, "Network is down"); + inscode(m, ds, de, "ENETDOWN", WSAENETDOWN, "Network is down"); #endif #endif #ifdef ENOTNAM - inscode(d, ds, de, "ENOTNAM", ENOTNAM, "Not a XENIX named type file"); + inscode(m, ds, de, "ENOTNAM", ENOTNAM, "Not a XENIX named type file"); #endif #ifdef EACCES - inscode(d, ds, de, "EACCES", EACCES, "Permission denied"); + inscode(m, ds, de, "EACCES", EACCES, "Permission denied"); #else #ifdef WSAEACCES - inscode(d, ds, de, "EACCES", WSAEACCES, "Permission denied"); + inscode(m, ds, de, "EACCES", WSAEACCES, "Permission denied"); #endif #endif #ifdef ELNRNG - inscode(d, ds, de, "ELNRNG", ELNRNG, "Link number out of range"); + inscode(m, ds, de, "ELNRNG", ELNRNG, "Link number out of range"); #endif #ifdef EILSEQ - inscode(d, ds, de, "EILSEQ", EILSEQ, "Illegal byte sequence"); + inscode(m, ds, de, "EILSEQ", EILSEQ, "Illegal byte sequence"); #endif #ifdef ENOTDIR - inscode(d, ds, de, "ENOTDIR", ENOTDIR, "Not a directory"); + inscode(m, ds, de, "ENOTDIR", ENOTDIR, "Not a directory"); #endif #ifdef ENOTUNIQ - inscode(d, ds, de, "ENOTUNIQ", ENOTUNIQ, "Name not unique on network"); + inscode(m, ds, de, "ENOTUNIQ", ENOTUNIQ, "Name not unique on network"); #endif #ifdef EPERM - inscode(d, ds, de, "EPERM", EPERM, "Operation not permitted"); + inscode(m, ds, de, "EPERM", EPERM, "Operation not permitted"); #endif #ifdef EDOM - inscode(d, ds, de, "EDOM", EDOM, "Math argument out of domain of func"); + inscode(m, ds, de, "EDOM", EDOM, "Math argument out of domain of func"); #endif #ifdef EXFULL - inscode(d, ds, de, "EXFULL", EXFULL, "Exchange full"); + inscode(m, ds, de, "EXFULL", EXFULL, "Exchange full"); #endif #ifdef ECONNREFUSED - inscode(d, ds, de, "ECONNREFUSED", ECONNREFUSED, "Connection refused"); + inscode(m, ds, de, "ECONNREFUSED", ECONNREFUSED, "Connection refused"); #else #ifdef WSAECONNREFUSED - inscode(d, ds, de, "ECONNREFUSED", WSAECONNREFUSED, "Connection refused"); + inscode(m, ds, de, "ECONNREFUSED", WSAECONNREFUSED, "Connection refused"); #endif #endif #ifdef EISDIR - inscode(d, ds, de, "EISDIR", EISDIR, "Is a directory"); + inscode(m, ds, de, "EISDIR", EISDIR, "Is a directory"); #endif #ifdef EPROTONOSUPPORT - inscode(d, ds, de, "EPROTONOSUPPORT", EPROTONOSUPPORT, "Protocol not supported"); + inscode(m, ds, de, "EPROTONOSUPPORT", EPROTONOSUPPORT, "Protocol not supported"); #else #ifdef WSAEPROTONOSUPPORT - inscode(d, ds, de, "EPROTONOSUPPORT", WSAEPROTONOSUPPORT, "Protocol not supported"); + inscode(m, ds, de, "EPROTONOSUPPORT", WSAEPROTONOSUPPORT, "Protocol not supported"); #endif #endif #ifdef EROFS - inscode(d, ds, de, "EROFS", EROFS, "Read-only file system"); + inscode(m, ds, de, "EROFS", EROFS, "Read-only file system"); #endif #ifdef EADDRNOTAVAIL - inscode(d, ds, de, "EADDRNOTAVAIL", EADDRNOTAVAIL, "Cannot assign requested address"); + inscode(m, ds, de, "EADDRNOTAVAIL", EADDRNOTAVAIL, "Cannot assign requested address"); #else #ifdef WSAEADDRNOTAVAIL - inscode(d, ds, de, "EADDRNOTAVAIL", WSAEADDRNOTAVAIL, "Cannot assign requested address"); + inscode(m, ds, de, "EADDRNOTAVAIL", WSAEADDRNOTAVAIL, "Cannot assign requested address"); #endif #endif #ifdef EIDRM - inscode(d, ds, de, "EIDRM", EIDRM, "Identifier removed"); + inscode(m, ds, de, "EIDRM", EIDRM, "Identifier removed"); #endif #ifdef ECOMM - inscode(d, ds, de, "ECOMM", ECOMM, "Communication error on send"); + inscode(m, ds, de, "ECOMM", ECOMM, "Communication error on send"); #endif #ifdef ESRMNT - inscode(d, ds, de, "ESRMNT", ESRMNT, "Srmount error"); + inscode(m, ds, de, "ESRMNT", ESRMNT, "Srmount error"); #endif #ifdef EREMOTEIO - inscode(d, ds, de, "EREMOTEIO", EREMOTEIO, "Remote I/O error"); + inscode(m, ds, de, "EREMOTEIO", EREMOTEIO, "Remote I/O error"); #endif #ifdef EL3RST - inscode(d, ds, de, "EL3RST", EL3RST, "Level 3 reset"); + inscode(m, ds, de, "EL3RST", EL3RST, "Level 3 reset"); #endif #ifdef EBADMSG - inscode(d, ds, de, "EBADMSG", EBADMSG, "Not a data message"); + inscode(m, ds, de, "EBADMSG", EBADMSG, "Not a data message"); #endif #ifdef ENFILE - inscode(d, ds, de, "ENFILE", ENFILE, "File table overflow"); + inscode(m, ds, de, "ENFILE", ENFILE, "File table overflow"); #endif #ifdef ELIBMAX - inscode(d, ds, de, "ELIBMAX", ELIBMAX, "Attempting to link in too many shared libraries"); + inscode(m, ds, de, "ELIBMAX", ELIBMAX, "Attempting to link in too many shared libraries"); #endif #ifdef ESPIPE - inscode(d, ds, de, "ESPIPE", ESPIPE, "Illegal seek"); + inscode(m, ds, de, "ESPIPE", ESPIPE, "Illegal seek"); #endif #ifdef ENOLINK - inscode(d, ds, de, "ENOLINK", ENOLINK, "Link has been severed"); + inscode(m, ds, de, "ENOLINK", ENOLINK, "Link has been severed"); #endif #ifdef ENETRESET - inscode(d, ds, de, "ENETRESET", ENETRESET, "Network dropped connection because of reset"); + inscode(m, ds, de, "ENETRESET", ENETRESET, "Network dropped connection because of reset"); #else #ifdef WSAENETRESET - inscode(d, ds, de, "ENETRESET", WSAENETRESET, "Network dropped connection because of reset"); + inscode(m, ds, de, "ENETRESET", WSAENETRESET, "Network dropped connection because of reset"); #endif #endif #ifdef ETIMEDOUT - inscode(d, ds, de, "ETIMEDOUT", ETIMEDOUT, "Connection timed out"); + inscode(m, ds, de, "ETIMEDOUT", ETIMEDOUT, "Connection timed out"); #else #ifdef WSAETIMEDOUT - inscode(d, ds, de, "ETIMEDOUT", WSAETIMEDOUT, "Connection timed out"); + inscode(m, ds, de, "ETIMEDOUT", WSAETIMEDOUT, "Connection timed out"); #endif #endif #ifdef ENOENT - inscode(d, ds, de, "ENOENT", ENOENT, "No such file or directory"); + inscode(m, ds, de, "ENOENT", ENOENT, "No such file or directory"); #endif #ifdef EEXIST - inscode(d, ds, de, "EEXIST", EEXIST, "File exists"); + inscode(m, ds, de, "EEXIST", EEXIST, "File exists"); #endif #ifdef EDQUOT - inscode(d, ds, de, "EDQUOT", EDQUOT, "Quota exceeded"); + inscode(m, ds, de, "EDQUOT", EDQUOT, "Quota exceeded"); #else #ifdef WSAEDQUOT - inscode(d, ds, de, "EDQUOT", WSAEDQUOT, "Quota exceeded"); + inscode(m, ds, de, "EDQUOT", WSAEDQUOT, "Quota exceeded"); #endif #endif #ifdef ENOSTR - inscode(d, ds, de, "ENOSTR", ENOSTR, "Device not a stream"); + inscode(m, ds, de, "ENOSTR", ENOSTR, "Device not a stream"); #endif #ifdef EBADSLT - inscode(d, ds, de, "EBADSLT", EBADSLT, "Invalid slot"); + inscode(m, ds, de, "EBADSLT", EBADSLT, "Invalid slot"); #endif #ifdef EBADRQC - inscode(d, ds, de, "EBADRQC", EBADRQC, "Invalid request code"); + inscode(m, ds, de, "EBADRQC", EBADRQC, "Invalid request code"); #endif #ifdef ELIBACC - inscode(d, ds, de, "ELIBACC", ELIBACC, "Can not access a needed shared library"); + inscode(m, ds, de, "ELIBACC", ELIBACC, "Can not access a needed shared library"); #endif #ifdef EFAULT - inscode(d, ds, de, "EFAULT", EFAULT, "Bad address"); + inscode(m, ds, de, "EFAULT", EFAULT, "Bad address"); #else #ifdef WSAEFAULT - inscode(d, ds, de, "EFAULT", WSAEFAULT, "Bad address"); + inscode(m, ds, de, "EFAULT", WSAEFAULT, "Bad address"); #endif #endif #ifdef EFBIG - inscode(d, ds, de, "EFBIG", EFBIG, "File too large"); + inscode(m, ds, de, "EFBIG", EFBIG, "File too large"); #endif #ifdef EDEADLK - inscode(d, ds, de, "EDEADLK", EDEADLK, "Resource deadlock would occur"); + inscode(m, ds, de, "EDEADLK", EDEADLK, "Resource deadlock would occur"); #endif #ifdef ENOTCONN - inscode(d, ds, de, "ENOTCONN", ENOTCONN, "Transport endpoint is not connected"); + inscode(m, ds, de, "ENOTCONN", ENOTCONN, "Transport endpoint is not connected"); #else #ifdef WSAENOTCONN - inscode(d, ds, de, "ENOTCONN", WSAENOTCONN, "Transport endpoint is not connected"); + inscode(m, ds, de, "ENOTCONN", WSAENOTCONN, "Transport endpoint is not connected"); #endif #endif #ifdef EDESTADDRREQ - inscode(d, ds, de, "EDESTADDRREQ", EDESTADDRREQ, "Destination address required"); + inscode(m, ds, de, "EDESTADDRREQ", EDESTADDRREQ, "Destination address required"); #else #ifdef WSAEDESTADDRREQ - inscode(d, ds, de, "EDESTADDRREQ", WSAEDESTADDRREQ, "Destination address required"); + inscode(m, ds, de, "EDESTADDRREQ", WSAEDESTADDRREQ, "Destination address required"); #endif #endif #ifdef ELIBSCN - inscode(d, ds, de, "ELIBSCN", ELIBSCN, ".lib section in a.out corrupted"); + inscode(m, ds, de, "ELIBSCN", ELIBSCN, ".lib section in a.out corrupted"); #endif #ifdef ENOLCK - inscode(d, ds, de, "ENOLCK", ENOLCK, "No record locks available"); + inscode(m, ds, de, "ENOLCK", ENOLCK, "No record locks available"); #endif #ifdef EISNAM - inscode(d, ds, de, "EISNAM", EISNAM, "Is a named type file"); + inscode(m, ds, de, "EISNAM", EISNAM, "Is a named type file"); #endif #ifdef ECONNABORTED - inscode(d, ds, de, "ECONNABORTED", ECONNABORTED, "Software caused connection abort"); + inscode(m, ds, de, "ECONNABORTED", ECONNABORTED, "Software caused connection abort"); #else #ifdef WSAECONNABORTED - inscode(d, ds, de, "ECONNABORTED", WSAECONNABORTED, "Software caused connection abort"); + inscode(m, ds, de, "ECONNABORTED", WSAECONNABORTED, "Software caused connection abort"); #endif #endif #ifdef ENETUNREACH - inscode(d, ds, de, "ENETUNREACH", ENETUNREACH, "Network is unreachable"); + inscode(m, ds, de, "ENETUNREACH", ENETUNREACH, "Network is unreachable"); #else #ifdef WSAENETUNREACH - inscode(d, ds, de, "ENETUNREACH", WSAENETUNREACH, "Network is unreachable"); + inscode(m, ds, de, "ENETUNREACH", WSAENETUNREACH, "Network is unreachable"); #endif #endif #ifdef ESTALE - inscode(d, ds, de, "ESTALE", ESTALE, "Stale NFS file handle"); + inscode(m, ds, de, "ESTALE", ESTALE, "Stale NFS file handle"); #else #ifdef WSAESTALE - inscode(d, ds, de, "ESTALE", WSAESTALE, "Stale NFS file handle"); + inscode(m, ds, de, "ESTALE", WSAESTALE, "Stale NFS file handle"); #endif #endif #ifdef ENOSR - inscode(d, ds, de, "ENOSR", ENOSR, "Out of streams resources"); + inscode(m, ds, de, "ENOSR", ENOSR, "Out of streams resources"); #endif #ifdef ENOMEM - inscode(d, ds, de, "ENOMEM", ENOMEM, "Out of memory"); + inscode(m, ds, de, "ENOMEM", ENOMEM, "Out of memory"); #endif #ifdef ENOTSOCK - inscode(d, ds, de, "ENOTSOCK", ENOTSOCK, "Socket operation on non-socket"); + inscode(m, ds, de, "ENOTSOCK", ENOTSOCK, "Socket operation on non-socket"); #else #ifdef WSAENOTSOCK - inscode(d, ds, de, "ENOTSOCK", WSAENOTSOCK, "Socket operation on non-socket"); + inscode(m, ds, de, "ENOTSOCK", WSAENOTSOCK, "Socket operation on non-socket"); #endif #endif #ifdef ESTRPIPE - inscode(d, ds, de, "ESTRPIPE", ESTRPIPE, "Streams pipe error"); + inscode(m, ds, de, "ESTRPIPE", ESTRPIPE, "Streams pipe error"); #endif #ifdef EMLINK - inscode(d, ds, de, "EMLINK", EMLINK, "Too many links"); + inscode(m, ds, de, "EMLINK", EMLINK, "Too many links"); #endif #ifdef ERANGE - inscode(d, ds, de, "ERANGE", ERANGE, "Math result not representable"); + inscode(m, ds, de, "ERANGE", ERANGE, "Math result not representable"); #endif #ifdef ELIBEXEC - inscode(d, ds, de, "ELIBEXEC", ELIBEXEC, "Cannot exec a shared library directly"); + inscode(m, ds, de, "ELIBEXEC", ELIBEXEC, "Cannot exec a shared library directly"); #endif #ifdef EL3HLT - inscode(d, ds, de, "EL3HLT", EL3HLT, "Level 3 halted"); + inscode(m, ds, de, "EL3HLT", EL3HLT, "Level 3 halted"); #endif #ifdef ECONNRESET - inscode(d, ds, de, "ECONNRESET", ECONNRESET, "Connection reset by peer"); + inscode(m, ds, de, "ECONNRESET", ECONNRESET, "Connection reset by peer"); #else #ifdef WSAECONNRESET - inscode(d, ds, de, "ECONNRESET", WSAECONNRESET, "Connection reset by peer"); + inscode(m, ds, de, "ECONNRESET", WSAECONNRESET, "Connection reset by peer"); #endif #endif #ifdef EADDRINUSE - inscode(d, ds, de, "EADDRINUSE", EADDRINUSE, "Address already in use"); + inscode(m, ds, de, "EADDRINUSE", EADDRINUSE, "Address already in use"); #else #ifdef WSAEADDRINUSE - inscode(d, ds, de, "EADDRINUSE", WSAEADDRINUSE, "Address already in use"); + inscode(m, ds, de, "EADDRINUSE", WSAEADDRINUSE, "Address already in use"); #endif #endif #ifdef EOPNOTSUPP - inscode(d, ds, de, "EOPNOTSUPP", EOPNOTSUPP, "Operation not supported on transport endpoint"); + inscode(m, ds, de, "EOPNOTSUPP", EOPNOTSUPP, "Operation not supported on transport endpoint"); #else #ifdef WSAEOPNOTSUPP - inscode(d, ds, de, "EOPNOTSUPP", WSAEOPNOTSUPP, "Operation not supported on transport endpoint"); + inscode(m, ds, de, "EOPNOTSUPP", WSAEOPNOTSUPP, "Operation not supported on transport endpoint"); #endif #endif #ifdef EREMCHG - inscode(d, ds, de, "EREMCHG", EREMCHG, "Remote address changed"); + inscode(m, ds, de, "EREMCHG", EREMCHG, "Remote address changed"); #endif #ifdef EAGAIN - inscode(d, ds, de, "EAGAIN", EAGAIN, "Try again"); + inscode(m, ds, de, "EAGAIN", EAGAIN, "Try again"); #endif #ifdef ENAMETOOLONG - inscode(d, ds, de, "ENAMETOOLONG", ENAMETOOLONG, "File name too long"); + inscode(m, ds, de, "ENAMETOOLONG", ENAMETOOLONG, "File name too long"); #else #ifdef WSAENAMETOOLONG - inscode(d, ds, de, "ENAMETOOLONG", WSAENAMETOOLONG, "File name too long"); + inscode(m, ds, de, "ENAMETOOLONG", WSAENAMETOOLONG, "File name too long"); #endif #endif #ifdef ENOTTY - inscode(d, ds, de, "ENOTTY", ENOTTY, "Not a typewriter"); + inscode(m, ds, de, "ENOTTY", ENOTTY, "Not a typewriter"); #endif #ifdef ERESTART - inscode(d, ds, de, "ERESTART", ERESTART, "Interrupted system call should be restarted"); + inscode(m, ds, de, "ERESTART", ERESTART, "Interrupted system call should be restarted"); #endif #ifdef ESOCKTNOSUPPORT - inscode(d, ds, de, "ESOCKTNOSUPPORT", ESOCKTNOSUPPORT, "Socket type not supported"); + inscode(m, ds, de, "ESOCKTNOSUPPORT", ESOCKTNOSUPPORT, "Socket type not supported"); #else #ifdef WSAESOCKTNOSUPPORT - inscode(d, ds, de, "ESOCKTNOSUPPORT", WSAESOCKTNOSUPPORT, "Socket type not supported"); + inscode(m, ds, de, "ESOCKTNOSUPPORT", WSAESOCKTNOSUPPORT, "Socket type not supported"); #endif #endif #ifdef ETIME - inscode(d, ds, de, "ETIME", ETIME, "Timer expired"); + inscode(m, ds, de, "ETIME", ETIME, "Timer expired"); #endif #ifdef EBFONT - inscode(d, ds, de, "EBFONT", EBFONT, "Bad font file format"); + inscode(m, ds, de, "EBFONT", EBFONT, "Bad font file format"); #endif #ifdef EDEADLOCK - inscode(d, ds, de, "EDEADLOCK", EDEADLOCK, "Error EDEADLOCK"); + inscode(m, ds, de, "EDEADLOCK", EDEADLOCK, "Error EDEADLOCK"); #endif #ifdef ETOOMANYREFS - inscode(d, ds, de, "ETOOMANYREFS", ETOOMANYREFS, "Too many references: cannot splice"); + inscode(m, ds, de, "ETOOMANYREFS", ETOOMANYREFS, "Too many references: cannot splice"); #else #ifdef WSAETOOMANYREFS - inscode(d, ds, de, "ETOOMANYREFS", WSAETOOMANYREFS, "Too many references: cannot splice"); + inscode(m, ds, de, "ETOOMANYREFS", WSAETOOMANYREFS, "Too many references: cannot splice"); #endif #endif #ifdef EMFILE - inscode(d, ds, de, "EMFILE", EMFILE, "Too many open files"); + inscode(m, ds, de, "EMFILE", EMFILE, "Too many open files"); #else #ifdef WSAEMFILE - inscode(d, ds, de, "EMFILE", WSAEMFILE, "Too many open files"); + inscode(m, ds, de, "EMFILE", WSAEMFILE, "Too many open files"); #endif #endif #ifdef ETXTBSY - inscode(d, ds, de, "ETXTBSY", ETXTBSY, "Text file busy"); + inscode(m, ds, de, "ETXTBSY", ETXTBSY, "Text file busy"); #endif #ifdef EINPROGRESS - inscode(d, ds, de, "EINPROGRESS", EINPROGRESS, "Operation now in progress"); + inscode(m, ds, de, "EINPROGRESS", EINPROGRESS, "Operation now in progress"); #else #ifdef WSAEINPROGRESS - inscode(d, ds, de, "EINPROGRESS", WSAEINPROGRESS, "Operation now in progress"); + inscode(m, ds, de, "EINPROGRESS", WSAEINPROGRESS, "Operation now in progress"); #endif #endif #ifdef ENXIO - inscode(d, ds, de, "ENXIO", ENXIO, "No such device or address"); + inscode(m, ds, de, "ENXIO", ENXIO, "No such device or address"); #endif #ifdef ENOPKG - inscode(d, ds, de, "ENOPKG", ENOPKG, "Package not installed"); + inscode(m, ds, de, "ENOPKG", ENOPKG, "Package not installed"); #endif #ifdef WSASY - inscode(d, ds, de, "WSASY", WSASY, "Error WSASY"); + inscode(m, ds, de, "WSASY", WSASY, "Error WSASY"); #endif #ifdef WSAEHOSTDOWN - inscode(d, ds, de, "WSAEHOSTDOWN", WSAEHOSTDOWN, "Host is down"); + inscode(m, ds, de, "WSAEHOSTDOWN", WSAEHOSTDOWN, "Host is down"); #endif #ifdef WSAENETDOWN - inscode(d, ds, de, "WSAENETDOWN", WSAENETDOWN, "Network is down"); + inscode(m, ds, de, "WSAENETDOWN", WSAENETDOWN, "Network is down"); #endif #ifdef WSAENOTSOCK - inscode(d, ds, de, "WSAENOTSOCK", WSAENOTSOCK, "Socket operation on non-socket"); + inscode(m, ds, de, "WSAENOTSOCK", WSAENOTSOCK, "Socket operation on non-socket"); #endif #ifdef WSAEHOSTUNREACH - inscode(d, ds, de, "WSAEHOSTUNREACH", WSAEHOSTUNREACH, "No route to host"); + inscode(m, ds, de, "WSAEHOSTUNREACH", WSAEHOSTUNREACH, "No route to host"); #endif #ifdef WSAELOOP - inscode(d, ds, de, "WSAELOOP", WSAELOOP, "Too many symbolic links encountered"); + inscode(m, ds, de, "WSAELOOP", WSAELOOP, "Too many symbolic links encountered"); #endif #ifdef WSAEMFILE - inscode(d, ds, de, "WSAEMFILE", WSAEMFILE, "Too many open files"); + inscode(m, ds, de, "WSAEMFILE", WSAEMFILE, "Too many open files"); #endif #ifdef WSAESTALE - inscode(d, ds, de, "WSAESTALE", WSAESTALE, "Stale NFS file handle"); + inscode(m, ds, de, "WSAESTALE", WSAESTALE, "Stale NFS file handle"); #endif #ifdef WSAVERNOTSUPPORTED - inscode(d, ds, de, "WSAVERNOTSUPPORTED", WSAVERNOTSUPPORTED, "Error WSAVERNOTSUPPORTED"); + inscode(m, ds, de, "WSAVERNOTSUPPORTED", WSAVERNOTSUPPORTED, "Error WSAVERNOTSUPPORTED"); #endif #ifdef WSAENETUNREACH - inscode(d, ds, de, "WSAENETUNREACH", WSAENETUNREACH, "Network is unreachable"); + inscode(m, ds, de, "WSAENETUNREACH", WSAENETUNREACH, "Network is unreachable"); #endif #ifdef WSAEPROCLIM - inscode(d, ds, de, "WSAEPROCLIM", WSAEPROCLIM, "Error WSAEPROCLIM"); + inscode(m, ds, de, "WSAEPROCLIM", WSAEPROCLIM, "Error WSAEPROCLIM"); #endif #ifdef WSAEFAULT - inscode(d, ds, de, "WSAEFAULT", WSAEFAULT, "Bad address"); + inscode(m, ds, de, "WSAEFAULT", WSAEFAULT, "Bad address"); #endif #ifdef WSANOTINITIALISED - inscode(d, ds, de, "WSANOTINITIALISED", WSANOTINITIALISED, "Error WSANOTINITIALISED"); + inscode(m, ds, de, "WSANOTINITIALISED", WSANOTINITIALISED, "Error WSANOTINITIALISED"); #endif #ifdef WSAEUSERS - inscode(d, ds, de, "WSAEUSERS", WSAEUSERS, "Too many users"); + inscode(m, ds, de, "WSAEUSERS", WSAEUSERS, "Too many users"); #endif #ifdef WSAMAKEASYNCREPL - inscode(d, ds, de, "WSAMAKEASYNCREPL", WSAMAKEASYNCREPL, "Error WSAMAKEASYNCREPL"); + inscode(m, ds, de, "WSAMAKEASYNCREPL", WSAMAKEASYNCREPL, "Error WSAMAKEASYNCREPL"); #endif #ifdef WSAENOPROTOOPT - inscode(d, ds, de, "WSAENOPROTOOPT", WSAENOPROTOOPT, "Protocol not available"); + inscode(m, ds, de, "WSAENOPROTOOPT", WSAENOPROTOOPT, "Protocol not available"); #endif #ifdef WSAECONNABORTED - inscode(d, ds, de, "WSAECONNABORTED", WSAECONNABORTED, "Software caused connection abort"); + inscode(m, ds, de, "WSAECONNABORTED", WSAECONNABORTED, "Software caused connection abort"); #endif #ifdef WSAENAMETOOLONG - inscode(d, ds, de, "WSAENAMETOOLONG", WSAENAMETOOLONG, "File name too long"); + inscode(m, ds, de, "WSAENAMETOOLONG", WSAENAMETOOLONG, "File name too long"); #endif #ifdef WSAENOTEMPTY - inscode(d, ds, de, "WSAENOTEMPTY", WSAENOTEMPTY, "Directory not empty"); + inscode(m, ds, de, "WSAENOTEMPTY", WSAENOTEMPTY, "Directory not empty"); #endif #ifdef WSAESHUTDOWN - inscode(d, ds, de, "WSAESHUTDOWN", WSAESHUTDOWN, "Cannot send after transport endpoint shutdown"); + inscode(m, ds, de, "WSAESHUTDOWN", WSAESHUTDOWN, "Cannot send after transport endpoint shutdown"); #endif #ifdef WSAEAFNOSUPPORT - inscode(d, ds, de, "WSAEAFNOSUPPORT", WSAEAFNOSUPPORT, "Address family not supported by protocol"); + inscode(m, ds, de, "WSAEAFNOSUPPORT", WSAEAFNOSUPPORT, "Address family not supported by protocol"); #endif #ifdef WSAETOOMANYREFS - inscode(d, ds, de, "WSAETOOMANYREFS", WSAETOOMANYREFS, "Too many references: cannot splice"); + inscode(m, ds, de, "WSAETOOMANYREFS", WSAETOOMANYREFS, "Too many references: cannot splice"); #endif #ifdef WSAEACCES - inscode(d, ds, de, "WSAEACCES", WSAEACCES, "Permission denied"); + inscode(m, ds, de, "WSAEACCES", WSAEACCES, "Permission denied"); #endif #ifdef WSATR - inscode(d, ds, de, "WSATR", WSATR, "Error WSATR"); + inscode(m, ds, de, "WSATR", WSATR, "Error WSATR"); #endif #ifdef WSABASEERR - inscode(d, ds, de, "WSABASEERR", WSABASEERR, "Error WSABASEERR"); + inscode(m, ds, de, "WSABASEERR", WSABASEERR, "Error WSABASEERR"); #endif #ifdef WSADESCRIPTIO - inscode(d, ds, de, "WSADESCRIPTIO", WSADESCRIPTIO, "Error WSADESCRIPTIO"); + inscode(m, ds, de, "WSADESCRIPTIO", WSADESCRIPTIO, "Error WSADESCRIPTIO"); #endif #ifdef WSAEMSGSIZE - inscode(d, ds, de, "WSAEMSGSIZE", WSAEMSGSIZE, "Message too long"); + inscode(m, ds, de, "WSAEMSGSIZE", WSAEMSGSIZE, "Message too long"); #endif #ifdef WSAEBADF - inscode(d, ds, de, "WSAEBADF", WSAEBADF, "Bad file number"); + inscode(m, ds, de, "WSAEBADF", WSAEBADF, "Bad file number"); #endif #ifdef WSAECONNRESET - inscode(d, ds, de, "WSAECONNRESET", WSAECONNRESET, "Connection reset by peer"); + inscode(m, ds, de, "WSAECONNRESET", WSAECONNRESET, "Connection reset by peer"); #endif #ifdef WSAGETSELECTERRO - inscode(d, ds, de, "WSAGETSELECTERRO", WSAGETSELECTERRO, "Error WSAGETSELECTERRO"); + inscode(m, ds, de, "WSAGETSELECTERRO", WSAGETSELECTERRO, "Error WSAGETSELECTERRO"); #endif #ifdef WSAETIMEDOUT - inscode(d, ds, de, "WSAETIMEDOUT", WSAETIMEDOUT, "Connection timed out"); + inscode(m, ds, de, "WSAETIMEDOUT", WSAETIMEDOUT, "Connection timed out"); #endif #ifdef WSAENOBUFS - inscode(d, ds, de, "WSAENOBUFS", WSAENOBUFS, "No buffer space available"); + inscode(m, ds, de, "WSAENOBUFS", WSAENOBUFS, "No buffer space available"); #endif #ifdef WSAEDISCON - inscode(d, ds, de, "WSAEDISCON", WSAEDISCON, "Error WSAEDISCON"); + inscode(m, ds, de, "WSAEDISCON", WSAEDISCON, "Error WSAEDISCON"); #endif #ifdef WSAEINTR - inscode(d, ds, de, "WSAEINTR", WSAEINTR, "Interrupted system call"); + inscode(m, ds, de, "WSAEINTR", WSAEINTR, "Interrupted system call"); #endif #ifdef WSAEPROTOTYPE - inscode(d, ds, de, "WSAEPROTOTYPE", WSAEPROTOTYPE, "Protocol wrong type for socket"); + inscode(m, ds, de, "WSAEPROTOTYPE", WSAEPROTOTYPE, "Protocol wrong type for socket"); #endif #ifdef WSAHOS - inscode(d, ds, de, "WSAHOS", WSAHOS, "Error WSAHOS"); + inscode(m, ds, de, "WSAHOS", WSAHOS, "Error WSAHOS"); #endif #ifdef WSAEADDRINUSE - inscode(d, ds, de, "WSAEADDRINUSE", WSAEADDRINUSE, "Address already in use"); + inscode(m, ds, de, "WSAEADDRINUSE", WSAEADDRINUSE, "Address already in use"); #endif #ifdef WSAEADDRNOTAVAIL - inscode(d, ds, de, "WSAEADDRNOTAVAIL", WSAEADDRNOTAVAIL, "Cannot assign requested address"); + inscode(m, ds, de, "WSAEADDRNOTAVAIL", WSAEADDRNOTAVAIL, "Cannot assign requested address"); #endif #ifdef WSAEALREADY - inscode(d, ds, de, "WSAEALREADY", WSAEALREADY, "Operation already in progress"); + inscode(m, ds, de, "WSAEALREADY", WSAEALREADY, "Operation already in progress"); #endif #ifdef WSAEPROTONOSUPPORT - inscode(d, ds, de, "WSAEPROTONOSUPPORT", WSAEPROTONOSUPPORT, "Protocol not supported"); + inscode(m, ds, de, "WSAEPROTONOSUPPORT", WSAEPROTONOSUPPORT, "Protocol not supported"); #endif #ifdef WSASYSNOTREADY - inscode(d, ds, de, "WSASYSNOTREADY", WSASYSNOTREADY, "Error WSASYSNOTREADY"); + inscode(m, ds, de, "WSASYSNOTREADY", WSASYSNOTREADY, "Error WSASYSNOTREADY"); #endif #ifdef WSAEWOULDBLOCK - inscode(d, ds, de, "WSAEWOULDBLOCK", WSAEWOULDBLOCK, "Operation would block"); + inscode(m, ds, de, "WSAEWOULDBLOCK", WSAEWOULDBLOCK, "Operation would block"); #endif #ifdef WSAEPFNOSUPPORT - inscode(d, ds, de, "WSAEPFNOSUPPORT", WSAEPFNOSUPPORT, "Protocol family not supported"); + inscode(m, ds, de, "WSAEPFNOSUPPORT", WSAEPFNOSUPPORT, "Protocol family not supported"); #endif #ifdef WSAEOPNOTSUPP - inscode(d, ds, de, "WSAEOPNOTSUPP", WSAEOPNOTSUPP, "Operation not supported on transport endpoint"); + inscode(m, ds, de, "WSAEOPNOTSUPP", WSAEOPNOTSUPP, "Operation not supported on transport endpoint"); #endif #ifdef WSAEISCONN - inscode(d, ds, de, "WSAEISCONN", WSAEISCONN, "Transport endpoint is already connected"); + inscode(m, ds, de, "WSAEISCONN", WSAEISCONN, "Transport endpoint is already connected"); #endif #ifdef WSAEDQUOT - inscode(d, ds, de, "WSAEDQUOT", WSAEDQUOT, "Quota exceeded"); + inscode(m, ds, de, "WSAEDQUOT", WSAEDQUOT, "Quota exceeded"); #endif #ifdef WSAENOTCONN - inscode(d, ds, de, "WSAENOTCONN", WSAENOTCONN, "Transport endpoint is not connected"); + inscode(m, ds, de, "WSAENOTCONN", WSAENOTCONN, "Transport endpoint is not connected"); #endif #ifdef WSAEREMOTE - inscode(d, ds, de, "WSAEREMOTE", WSAEREMOTE, "Object is remote"); + inscode(m, ds, de, "WSAEREMOTE", WSAEREMOTE, "Object is remote"); #endif #ifdef WSAEINVAL - inscode(d, ds, de, "WSAEINVAL", WSAEINVAL, "Invalid argument"); + inscode(m, ds, de, "WSAEINVAL", WSAEINVAL, "Invalid argument"); #endif #ifdef WSAEINPROGRESS - inscode(d, ds, de, "WSAEINPROGRESS", WSAEINPROGRESS, "Operation now in progress"); + inscode(m, ds, de, "WSAEINPROGRESS", WSAEINPROGRESS, "Operation now in progress"); #endif #ifdef WSAGETSELECTEVEN - inscode(d, ds, de, "WSAGETSELECTEVEN", WSAGETSELECTEVEN, "Error WSAGETSELECTEVEN"); + inscode(m, ds, de, "WSAGETSELECTEVEN", WSAGETSELECTEVEN, "Error WSAGETSELECTEVEN"); #endif #ifdef WSAESOCKTNOSUPPORT - inscode(d, ds, de, "WSAESOCKTNOSUPPORT", WSAESOCKTNOSUPPORT, "Socket type not supported"); + inscode(m, ds, de, "WSAESOCKTNOSUPPORT", WSAESOCKTNOSUPPORT, "Socket type not supported"); #endif #ifdef WSAGETASYNCERRO - inscode(d, ds, de, "WSAGETASYNCERRO", WSAGETASYNCERRO, "Error WSAGETASYNCERRO"); + inscode(m, ds, de, "WSAGETASYNCERRO", WSAGETASYNCERRO, "Error WSAGETASYNCERRO"); #endif #ifdef WSAMAKESELECTREPL - inscode(d, ds, de, "WSAMAKESELECTREPL", WSAMAKESELECTREPL, "Error WSAMAKESELECTREPL"); + inscode(m, ds, de, "WSAMAKESELECTREPL", WSAMAKESELECTREPL, "Error WSAMAKESELECTREPL"); #endif #ifdef WSAGETASYNCBUFLE - inscode(d, ds, de, "WSAGETASYNCBUFLE", WSAGETASYNCBUFLE, "Error WSAGETASYNCBUFLE"); + inscode(m, ds, de, "WSAGETASYNCBUFLE", WSAGETASYNCBUFLE, "Error WSAGETASYNCBUFLE"); #endif #ifdef WSAEDESTADDRREQ - inscode(d, ds, de, "WSAEDESTADDRREQ", WSAEDESTADDRREQ, "Destination address required"); + inscode(m, ds, de, "WSAEDESTADDRREQ", WSAEDESTADDRREQ, "Destination address required"); #endif #ifdef WSAECONNREFUSED - inscode(d, ds, de, "WSAECONNREFUSED", WSAECONNREFUSED, "Connection refused"); + inscode(m, ds, de, "WSAECONNREFUSED", WSAECONNREFUSED, "Connection refused"); #endif #ifdef WSAENETRESET - inscode(d, ds, de, "WSAENETRESET", WSAENETRESET, "Network dropped connection because of reset"); + inscode(m, ds, de, "WSAENETRESET", WSAENETRESET, "Network dropped connection because of reset"); #endif #ifdef WSAN - inscode(d, ds, de, "WSAN", WSAN, "Error WSAN"); + inscode(m, ds, de, "WSAN", WSAN, "Error WSAN"); #endif #ifdef ENOMEDIUM - inscode(d, ds, de, "ENOMEDIUM", ENOMEDIUM, "No medium found"); + inscode(m, ds, de, "ENOMEDIUM", ENOMEDIUM, "No medium found"); #endif #ifdef EMEDIUMTYPE - inscode(d, ds, de, "EMEDIUMTYPE", EMEDIUMTYPE, "Wrong medium type"); + inscode(m, ds, de, "EMEDIUMTYPE", EMEDIUMTYPE, "Wrong medium type"); #endif #ifdef ECANCELED - inscode(d, ds, de, "ECANCELED", ECANCELED, "Operation Canceled"); + inscode(m, ds, de, "ECANCELED", ECANCELED, "Operation Canceled"); #endif #ifdef ENOKEY - inscode(d, ds, de, "ENOKEY", ENOKEY, "Required key not available"); + inscode(m, ds, de, "ENOKEY", ENOKEY, "Required key not available"); #endif #ifdef EKEYEXPIRED - inscode(d, ds, de, "EKEYEXPIRED", EKEYEXPIRED, "Key has expired"); + inscode(m, ds, de, "EKEYEXPIRED", EKEYEXPIRED, "Key has expired"); #endif #ifdef EKEYREVOKED - inscode(d, ds, de, "EKEYREVOKED", EKEYREVOKED, "Key has been revoked"); + inscode(m, ds, de, "EKEYREVOKED", EKEYREVOKED, "Key has been revoked"); #endif #ifdef EKEYREJECTED - inscode(d, ds, de, "EKEYREJECTED", EKEYREJECTED, "Key was rejected by service"); + inscode(m, ds, de, "EKEYREJECTED", EKEYREJECTED, "Key was rejected by service"); #endif #ifdef EOWNERDEAD - inscode(d, ds, de, "EOWNERDEAD", EOWNERDEAD, "Owner died"); + inscode(m, ds, de, "EOWNERDEAD", EOWNERDEAD, "Owner died"); #endif #ifdef ENOTRECOVERABLE - inscode(d, ds, de, "ENOTRECOVERABLE", ENOTRECOVERABLE, "State not recoverable"); + inscode(m, ds, de, "ENOTRECOVERABLE", ENOTRECOVERABLE, "State not recoverable"); #endif #ifdef ERFKILL - inscode(d, ds, de, "ERFKILL", ERFKILL, "Operation not possible due to RF-kill"); + inscode(m, ds, de, "ERFKILL", ERFKILL, "Operation not possible due to RF-kill"); #endif /* Solaris-specific errnos */ #ifdef ECANCELED - inscode(d, ds, de, "ECANCELED", ECANCELED, "Operation canceled"); + inscode(m, ds, de, "ECANCELED", ECANCELED, "Operation canceled"); #endif #ifdef ENOTSUP - inscode(d, ds, de, "ENOTSUP", ENOTSUP, "Operation not supported"); + inscode(m, ds, de, "ENOTSUP", ENOTSUP, "Operation not supported"); #endif #ifdef EOWNERDEAD - inscode(d, ds, de, "EOWNERDEAD", EOWNERDEAD, "Process died with the lock"); + inscode(m, ds, de, "EOWNERDEAD", EOWNERDEAD, "Process died with the lock"); #endif #ifdef ENOTRECOVERABLE - inscode(d, ds, de, "ENOTRECOVERABLE", ENOTRECOVERABLE, "Lock is not recoverable"); + inscode(m, ds, de, "ENOTRECOVERABLE", ENOTRECOVERABLE, "Lock is not recoverable"); #endif #ifdef ELOCKUNMAPPED - inscode(d, ds, de, "ELOCKUNMAPPED", ELOCKUNMAPPED, "Locked lock was unmapped"); + inscode(m, ds, de, "ELOCKUNMAPPED", ELOCKUNMAPPED, "Locked lock was unmapped"); #endif #ifdef ENOTACTIVE - inscode(d, ds, de, "ENOTACTIVE", ENOTACTIVE, "Facility is not active"); + inscode(m, ds, de, "ENOTACTIVE", ENOTACTIVE, "Facility is not active"); #endif /* MacOSX specific errnos */ #ifdef EAUTH - inscode(d, ds, de, "EAUTH", EAUTH, "Authentication error"); + inscode(m, ds, de, "EAUTH", EAUTH, "Authentication error"); #endif #ifdef EBADARCH - inscode(d, ds, de, "EBADARCH", EBADARCH, "Bad CPU type in executable"); + inscode(m, ds, de, "EBADARCH", EBADARCH, "Bad CPU type in executable"); #endif #ifdef EBADEXEC - inscode(d, ds, de, "EBADEXEC", EBADEXEC, "Bad executable (or shared library)"); + inscode(m, ds, de, "EBADEXEC", EBADEXEC, "Bad executable (or shared library)"); #endif #ifdef EBADMACHO - inscode(d, ds, de, "EBADMACHO", EBADMACHO, "Malformed Mach-o file"); + inscode(m, ds, de, "EBADMACHO", EBADMACHO, "Malformed Mach-o file"); #endif #ifdef EBADRPC - inscode(d, ds, de, "EBADRPC", EBADRPC, "RPC struct is bad"); + inscode(m, ds, de, "EBADRPC", EBADRPC, "RPC struct is bad"); #endif #ifdef EDEVERR - inscode(d, ds, de, "EDEVERR", EDEVERR, "Device error"); + inscode(m, ds, de, "EDEVERR", EDEVERR, "Device error"); #endif #ifdef EFTYPE - inscode(d, ds, de, "EFTYPE", EFTYPE, "Inappropriate file type or format"); + inscode(m, ds, de, "EFTYPE", EFTYPE, "Inappropriate file type or format"); #endif #ifdef ENEEDAUTH - inscode(d, ds, de, "ENEEDAUTH", ENEEDAUTH, "Need authenticator"); + inscode(m, ds, de, "ENEEDAUTH", ENEEDAUTH, "Need authenticator"); #endif #ifdef ENOATTR - inscode(d, ds, de, "ENOATTR", ENOATTR, "Attribute not found"); + inscode(m, ds, de, "ENOATTR", ENOATTR, "Attribute not found"); #endif #ifdef ENOPOLICY - inscode(d, ds, de, "ENOPOLICY", ENOPOLICY, "Policy not found"); + inscode(m, ds, de, "ENOPOLICY", ENOPOLICY, "Policy not found"); #endif #ifdef EPROCLIM - inscode(d, ds, de, "EPROCLIM", EPROCLIM, "Too many processes"); + inscode(m, ds, de, "EPROCLIM", EPROCLIM, "Too many processes"); #endif #ifdef EPROCUNAVAIL - inscode(d, ds, de, "EPROCUNAVAIL", EPROCUNAVAIL, "Bad procedure for program"); + inscode(m, ds, de, "EPROCUNAVAIL", EPROCUNAVAIL, "Bad procedure for program"); #endif #ifdef EPROGMISMATCH - inscode(d, ds, de, "EPROGMISMATCH", EPROGMISMATCH, "Program version wrong"); + inscode(m, ds, de, "EPROGMISMATCH", EPROGMISMATCH, "Program version wrong"); #endif #ifdef EPROGUNAVAIL - inscode(d, ds, de, "EPROGUNAVAIL", EPROGUNAVAIL, "RPC prog. not avail"); + inscode(m, ds, de, "EPROGUNAVAIL", EPROGUNAVAIL, "RPC prog. not avail"); #endif #ifdef EPWROFF - inscode(d, ds, de, "EPWROFF", EPWROFF, "Device power is off"); + inscode(m, ds, de, "EPWROFF", EPWROFF, "Device power is off"); #endif #ifdef ERPCMISMATCH - inscode(d, ds, de, "ERPCMISMATCH", ERPCMISMATCH, "RPC version wrong"); + inscode(m, ds, de, "ERPCMISMATCH", ERPCMISMATCH, "RPC version wrong"); #endif #ifdef ESHLIBVERS - inscode(d, ds, de, "ESHLIBVERS", ESHLIBVERS, "Shared library version mismatch"); + inscode(m, ds, de, "ESHLIBVERS", ESHLIBVERS, "Shared library version mismatch"); #endif Py_DECREF(de); diff --git a/Modules/grpmodule.c b/Modules/grpmodule.c index 4419c75521fbcc..536ac2fb4abf83 100644 --- a/Modules/grpmodule.c +++ b/Modules/grpmodule.c @@ -242,13 +242,12 @@ PyInit_grp(void) m = PyModule_Create(&grpmodule); if (m == NULL) return NULL; - d = PyModule_GetDict(m); if (!initialized) { if (PyStructSequence_InitType2(&StructGrpType, &struct_group_type_desc) < 0) return NULL; } - if (PyDict_SetItemString(d, "struct_group", + if (PyObject_SetAttrString(m, "struct_group", (PyObject *)&StructGrpType) < 0) return NULL; initialized = 1; diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index d0d20e47b790af..1b384498bdd655 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -1394,10 +1394,10 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) #endif /* MS_WINDOWS */ static void -setint(PyObject *d, const char *name, long value) +setint(PyObject *m, const char *name, long value) { PyObject *o = PyLong_FromLong(value); - if (o && PyDict_SetItemString(d, name, o) == 0) { + if (o && PyObject_SetAttrString(m, name, o) == 0) { Py_DECREF(o); } } @@ -1418,7 +1418,7 @@ static struct PyModuleDef mmapmodule = { PyMODINIT_FUNC PyInit_mmap(void) { - PyObject *dict, *module; + PyObject *module; if (PyType_Ready(&mmap_object_type) < 0) return NULL; @@ -1426,45 +1426,42 @@ PyInit_mmap(void) module = PyModule_Create(&mmapmodule); if (module == NULL) return NULL; - dict = PyModule_GetDict(module); - if (!dict) - return NULL; - PyDict_SetItemString(dict, "error", PyExc_OSError); - PyDict_SetItemString(dict, "mmap", (PyObject*) &mmap_object_type); + PyObject_SetAttrString(module, "error", PyExc_OSError); + PyObject_SetAttrString(module, "mmap", (PyObject*) &mmap_object_type); #ifdef PROT_EXEC - setint(dict, "PROT_EXEC", PROT_EXEC); + setint(module, "PROT_EXEC", PROT_EXEC); #endif #ifdef PROT_READ - setint(dict, "PROT_READ", PROT_READ); + setint(module, "PROT_READ", PROT_READ); #endif #ifdef PROT_WRITE - setint(dict, "PROT_WRITE", PROT_WRITE); + setint(module, "PROT_WRITE", PROT_WRITE); #endif #ifdef MAP_SHARED - setint(dict, "MAP_SHARED", MAP_SHARED); + setint(module, "MAP_SHARED", MAP_SHARED); #endif #ifdef MAP_PRIVATE - setint(dict, "MAP_PRIVATE", MAP_PRIVATE); + setint(module, "MAP_PRIVATE", MAP_PRIVATE); #endif #ifdef MAP_DENYWRITE - setint(dict, "MAP_DENYWRITE", MAP_DENYWRITE); + setint(module, "MAP_DENYWRITE", MAP_DENYWRITE); #endif #ifdef MAP_EXECUTABLE - setint(dict, "MAP_EXECUTABLE", MAP_EXECUTABLE); + setint(module, "MAP_EXECUTABLE", MAP_EXECUTABLE); #endif #ifdef MAP_ANONYMOUS - setint(dict, "MAP_ANON", MAP_ANONYMOUS); - setint(dict, "MAP_ANONYMOUS", MAP_ANONYMOUS); + setint(module, "MAP_ANON", MAP_ANONYMOUS); + setint(module, "MAP_ANONYMOUS", MAP_ANONYMOUS); #endif - setint(dict, "PAGESIZE", (long)my_getpagesize()); + setint(module, "PAGESIZE", (long)my_getpagesize()); - setint(dict, "ALLOCATIONGRANULARITY", (long)my_getallocationgranularity()); + setint(module, "ALLOCATIONGRANULARITY", (long)my_getallocationgranularity()); - setint(dict, "ACCESS_DEFAULT", ACCESS_DEFAULT); - setint(dict, "ACCESS_READ", ACCESS_READ); - setint(dict, "ACCESS_WRITE", ACCESS_WRITE); - setint(dict, "ACCESS_COPY", ACCESS_COPY); + setint(module, "ACCESS_DEFAULT", ACCESS_DEFAULT); + setint(module, "ACCESS_READ", ACCESS_READ); + setint(module, "ACCESS_WRITE", ACCESS_WRITE); + setint(module, "ACCESS_COPY", ACCESS_COPY); return module; } diff --git a/Modules/nismodule.c b/Modules/nismodule.c index 1a538dc3b2332d..4ba4b54bf08240 100644 --- a/Modules/nismodule.c +++ b/Modules/nismodule.c @@ -456,13 +456,12 @@ static struct PyModuleDef nismodule = { PyMODINIT_FUNC PyInit_nis(void) { - PyObject *m, *d; + PyObject *m; m = PyModule_Create(&nismodule); if (m == NULL) return NULL; - d = PyModule_GetDict(m); NisError = PyErr_NewException("nis.error", NULL, NULL); if (NisError != NULL) - PyDict_SetItemString(d, "error", NisError); + PyObject_SetAttrString(m, "error", NisError); return m; } diff --git a/Modules/overlapped.c b/Modules/overlapped.c index 69875a7f37da51..59cf69041aa485 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -1469,12 +1469,12 @@ static struct PyModuleDef overlapped_module = { }; #define WINAPI_CONSTANT(fmt, con) \ - PyDict_SetItemString(d, #con, Py_BuildValue(fmt, con)) + PyObject_SetAttrString(m, #con, Py_BuildValue(fmt, con)) PyMODINIT_FUNC PyInit__overlapped(void) { - PyObject *m, *d; + PyObject *m; /* Ensure WSAStartup() called before initializing function pointers */ m = PyImport_ImportModule("_socket"); @@ -1492,8 +1492,6 @@ PyInit__overlapped(void) if (PyModule_AddObject(m, "Overlapped", (PyObject *)&OverlappedType) < 0) return NULL; - d = PyModule_GetDict(m); - WINAPI_CONSTANT(F_DWORD, ERROR_IO_PENDING); WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED); WINAPI_CONSTANT(F_DWORD, ERROR_OPERATION_ABORTED); diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index e025135ee9e1a7..671ccb2e88cc51 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -1639,7 +1639,7 @@ static struct PyModuleDef pyexpatmodule = { PyMODINIT_FUNC MODULE_INITFUNC(void) { - PyObject *m, *d; + PyObject *m; PyObject *errmod_name = PyUnicode_FromString(MODULE_NAME ".errors"); PyObject *errors_module; PyObject *modelmod_name; @@ -1693,12 +1693,7 @@ MODULE_INITFUNC(void) */ PyModule_AddStringConstant(m, "native_encoding", "UTF-8"); - d = PyModule_GetDict(m); - if (d == NULL) { - Py_DECREF(m); - return NULL; - } - errors_module = PyDict_GetItemRef(d, errmod_name); + errors_module = PyObject_GetAttr(m, errmod_name); if (errors_module == NULL) { errors_module = PyModule_New(MODULE_NAME ".errors"); if (errors_module != NULL) { @@ -1710,7 +1705,7 @@ MODULE_INITFUNC(void) Py_DECREF(errors_module); } Py_DECREF(errmod_name); - model_module = PyDict_GetItemRef(d, modelmod_name); + model_module = PyObject_GetAttr(m, modelmod_name); if (model_module == NULL) { model_module = PyModule_New(MODULE_NAME ".model"); if (model_module != NULL) { diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 8c89914f518ce6..320c0391b69376 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -1275,7 +1275,7 @@ static struct PyModuleDef signalmodule = { PyMODINIT_FUNC PyInit__signal(void) { - PyObject *m, *d, *x; + PyObject *m, *x; int i; main_thread = PyThread_get_thread_ident(); @@ -1297,18 +1297,16 @@ PyInit__signal(void) #endif /* Add some symbolic constants to the module */ - d = PyModule_GetDict(m); - x = DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL); - if (!x || PyDict_SetItemString(d, "SIG_DFL", x) < 0) + if (!x || PyObject_SetAttrString(m, "SIG_DFL", x) < 0) goto finally; x = IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN); - if (!x || PyDict_SetItemString(d, "SIG_IGN", x) < 0) + if (!x || PyObject_SetAttrString(m, "SIG_IGN", x) < 0) goto finally; x = PyLong_FromLong((long)NSIG); - if (!x || PyDict_SetItemString(d, "NSIG", x) < 0) + if (!x || PyObject_SetAttrString(m, "NSIG", x) < 0) goto finally; Py_DECREF(x); @@ -1325,7 +1323,7 @@ PyInit__signal(void) goto finally; #endif - x = IntHandler = PyDict_GetItemRefString(d, "default_int_handler"); + x = IntHandler = PyObject_GetAttrString(m, "default_int_handler"); if (!x) goto finally; diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 161ff5d478dbdd..e7062d5fc8b142 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -326,15 +326,9 @@ static FlagRuntimeInfo win_runtime_flags[] = { static void remove_unusable_flags(PyObject *m) { - PyObject *dict; OSVERSIONINFOEX info; DWORDLONG dwlConditionMask; - dict = PyModule_GetDict(m); - if (dict == NULL) { - return; - } - /* set to Windows 10, except BuildNumber. */ memset(&info, 0, sizeof(info)); info.dwOSVersionInfoSize = sizeof(info); @@ -358,13 +352,13 @@ remove_unusable_flags(PyObject *m) break; } else { - PyObject *flag = PyDict_GetItemRefString( - dict, + PyObject *flag = PyObject_GetAttrString( + m, win_runtime_flags[i].flag_name); if (flag != NULL) { Py_DECREF(flag); - PyDict_DelItemString( - dict, + PyObject_DelAttrString( + m, win_runtime_flags[i].flag_name); } } diff --git a/Modules/zipimport.c b/Modules/zipimport.c index 26e3e821842593..06923b7bae7c25 100644 --- a/Modules/zipimport.c +++ b/Modules/zipimport.c @@ -520,7 +520,7 @@ static PyObject * zipimport_zipimporter_load_module_impl(ZipImporter *self, PyObject *fullname) /*[clinic end generated code: output=7303cebf88d47953 input=c236e2e8621f04ef]*/ { - PyObject *code = NULL, *mod, *dict; + PyObject *code = NULL, *mod; PyObject *modpath = NULL; int ispackage; @@ -534,10 +534,9 @@ zipimport_zipimporter_load_module_impl(ZipImporter *self, PyObject *fullname) mod = PyImport_AddModuleObject(fullname); if (mod == NULL) goto error; - dict = PyModule_GetDict(mod); /* mod.__loader__ = self */ - if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0) + if (PyObject_SetAttrString(mod, "__loader__", (PyObject *)self) != 0) goto error; if (ispackage) { @@ -560,7 +559,7 @@ zipimport_zipimporter_load_module_impl(ZipImporter *self, PyObject *fullname) pkgpath = Py_BuildValue("[N]", fullpath); if (pkgpath == NULL) goto error; - err = PyDict_SetItemString(dict, "__path__", pkgpath); + err = PyObject_SetAttrString(mod, "__path__", pkgpath); Py_DECREF(pkgpath); if (err != 0) goto error;