Title: enable embedding: declare/#define only py* symbols in #includes
Type: enhancement Stage: resolved
Components: Interpreter Core Versions: Python 3.2
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: ajaksu2, bruno.dupuis, hfuru, loewis, vstinner
Priority: normal Keywords:

Created on 2008-05-19 21:29 by hfuru, last changed 2019-05-15 02:42 by vstinner. This issue is now closed.

Messages (6)
msg67078 - (view) Author: Hallvard B Furuseth (hfuru) Date: 2008-05-19 21:29
It can be cumbersome to embed Python in a program which also #includes
a config.h from autoconf, because Python's and the program's autoconf
macros may interfere with each other.  Assuming it compiles at all,
both could define the same features, sometimes the same way and
sometimes differently.  Or one could be compiled with a feature macro
undefined and another with it defined, resulting in binary
incompatibility with the library which was compiled with the macro

So one has to do something like: put the Python calls in one set of
files, the calls to the embedding program in another set, and make
them communicate via some glue code.

For this reason, please do not declare/#define symbols other than
those starting with 'py' in the include files that an embedded program
needs.  Thus, do not #include at least pyconfig.h, pymath.h and
pyport.h as they are today.

Or to keep backwards compatibility, wrap such definitions in
which an application can #define before #including Python files.

Instead, you can #define/declare symbols that match the current
autoconf symbols but are prefixed with PY_, and make use of those in
#ifdefs in the include files.  The files defining this can hopefully
be autogenerated, e.g. generate a .c file like

    #include "pyconfig.h"
    int main() {
    #ifdef HAVE_WHATEVER

Things like acosh() from pymath.h which you define if the system lacks
it, could become something like this:

    #include <math.h> /* get acosh etc */
    extern double py_acosh(double); /* always present in python */
    #if !defined(PYTHON_NAMESPACE_ONLY) && !defined(HAVE_ACOSH)
    /* an other package's autoconf might do the same, so hide this
     * if requested */
    extern double acosh(double);
    #if !defined(PYTHON_NAMESPACE_ONLY) || defined(HAVE_ACOSH)
    #define py_acosh acosh /* optimization - hide wrapper function */
msg67126 - (view) Author: Hallvard B Furuseth (hfuru) Date: 2008-05-20 13:25
Duh, I should of course have said defined(PY_HAVE_ACOSH)
and not defined(HAVE_ACOSH), that was the whole point:-)
And the puts() should print "#define PY_HAVE_WHATEVER 1".

Hopefully there are not too many #defines which would
need to get corresponding PY_* variants.

For that matter, PYTHON_NAMESPACE_ONLY could offer a
reduced Python C API - omitting parts it would be
cumbersome to get right with only py* symbols.
msg87915 - (view) Author: Daniel Diniz (ajaksu2) (Python triager) Date: 2009-05-16 19:39
Would this break existing code? Are the benefits worth it?
msg87933 - (view) Author: Hallvard B Furuseth (hfuru) Date: 2009-05-16 21:12
Daniel Diniz writes:
> Would this break existing code?

Source code?  Not if you use the PYTHON_NAMESPACE_ONLY trick.  Old
programs will receive all old definitions in addition to the new
autoconf symbols, since they didn't #define PYTHON_NAMESPACE_ONLY.

Programs that do #define PYTHON_NAMESPACE_ONLY will lose symbols you
can't offer because you couldn't be bothered to make them independent
of autoconf.  BTW, another "reduced API" variant would be to throw
autoconf-independent symbols out to separate .h files.  #include those
files from the .h files they come from, and document that programs can
#include them instead of Python.h.
msg87939 - (view) Author: Daniel Diniz (ajaksu2) (Python triager) Date: 2009-05-16 22:08
There is ongoing discussion on separating public and private headers:

Also see #2897, #4805, #5748 and #896330 for (sometimes slightly)
related issues.
msg342537 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2019-05-15 02:42
Since this issue has been reported, a lot of work has been done to cleanup Python header files. In Python 3.8, we created Include/cpython/ and Include/internal/ subdirectories to clarify the intent and usage of header files. I close this issue.

See bpo-2897 for the specific case of structmember.h.
Date User Action Args
2019-05-15 02:42:41vstinnersetstatus: open -> closed
messages: + msg342537

dependencies: - Deprecate structmember.h
resolution: fixed
stage: resolved
2012-11-30 21:30:46bruno.dupuissetnosy: + bruno.dupuis
2010-11-04 11:57:25vstinnersetnosy: + vstinner
2010-08-09 18:36:55terry.reedysetversions: - Python 2.7
2009-05-16 22:08:37ajaksu2setnosy: + loewis
dependencies: + Deprecate structmember.h
messages: + msg87939
2009-05-16 21:12:36hfurusetmessages: + msg87933
2009-05-16 19:39:26ajaksu2setpriority: normal
versions: + Python 2.7, Python 3.2, - Python 2.6
nosy: + ajaksu2

messages: + msg87915
2008-05-20 13:25:59hfurusetmessages: + msg67126
2008-05-19 21:32:04benjamin.petersonsetcomponents: + Interpreter Core, - None
2008-05-19 21:29:22hfurucreate