]> granicus.if.org Git - python/commitdiff
bpo-35134: Create Include/cpython/ subdirectory (GH-10624)
authorVictor Stinner <vstinner@redhat.com>
Fri, 23 Nov 2018 16:00:00 +0000 (17:00 +0100)
committerGitHub <noreply@github.com>
Fri, 23 Nov 2018 16:00:00 +0000 (17:00 +0100)
Include/*.h should be the "portable Python API", whereas
Include/cpython/*.h should be the "CPython API": CPython
implementation details.

Changes:

* Create Include/cpython/ subdirectory
* "make install" now creates $prefix/include/cpython and copy
  Include/cpython/* to $prefix/include/cpython
* Create Include/cpython/objimpl.h: move objimpl.h code
  surrounded by "#ifndef Py_LIMITED_API" to cpython/objimpl.h.
* objimpl.h now includes cpython/objimpl.h
* Windows installer (MSI) now also install Include/ subdirectories:
  Include/cpython/ and Include/internal/.

Include/cpython/objimpl.h [new file with mode: 0644]
Include/objimpl.h
Makefile.pre.in
Misc/NEWS.d/next/C API/2018-11-01-13-58-37.bpo-35134.SbZo0o.rst [new file with mode: 0644]
PCbuild/pythoncore.vcxproj
PCbuild/pythoncore.vcxproj.filters
Tools/msi/dev/dev.wixproj

diff --git a/Include/cpython/objimpl.h b/Include/cpython/objimpl.h
new file mode 100644 (file)
index 0000000..f121922
--- /dev/null
@@ -0,0 +1,113 @@
+#ifndef Py_CPYTHON_OBJIMPL_H
+#  error "this header file must not be included directly"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This function returns the number of allocated memory blocks, regardless of size */
+PyAPI_FUNC(Py_ssize_t) _Py_GetAllocatedBlocks(void);
+
+/* Macros */
+#ifdef WITH_PYMALLOC
+PyAPI_FUNC(int) _PyObject_DebugMallocStats(FILE *out);
+#endif
+
+
+typedef struct {
+    /* user context passed as the first argument to the 2 functions */
+    void *ctx;
+
+    /* allocate an arena of size bytes */
+    void* (*alloc) (void *ctx, size_t size);
+
+    /* free an arena */
+    void (*free) (void *ctx, void *ptr, size_t size);
+} PyObjectArenaAllocator;
+
+/* Get the arena allocator. */
+PyAPI_FUNC(void) PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator);
+
+/* Set the arena allocator. */
+PyAPI_FUNC(void) PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator);
+
+
+PyAPI_FUNC(Py_ssize_t) _PyGC_CollectNoFail(void);
+PyAPI_FUNC(Py_ssize_t) _PyGC_CollectIfEnabled(void);
+
+
+/* Test if an object has a GC head */
+#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)))
+
+/* GC information is stored BEFORE the object structure. */
+typedef struct {
+    // Pointer to next object in the list.
+    // 0 means the object is not tracked
+    uintptr_t _gc_next;
+
+    // Pointer to previous object in the list.
+    // Lowest two bits are used for flags documented later.
+    uintptr_t _gc_prev;
+} PyGC_Head;
+
+#define _Py_AS_GC(o) ((PyGC_Head *)(o)-1)
+
+/* True if the object is currently tracked by the GC. */
+#define _PyObject_GC_IS_TRACKED(o) (_Py_AS_GC(o)->_gc_next != 0)
+
+/* True if the object may be tracked by the GC in the future, or already is.
+   This can be useful to implement some optimizations. */
+#define _PyObject_GC_MAY_BE_TRACKED(obj) \
+    (PyObject_IS_GC(obj) && \
+        (!PyTuple_CheckExact(obj) || _PyObject_GC_IS_TRACKED(obj)))
+
+
+/* Bit flags for _gc_prev */
+/* Bit 0 is set when tp_finalize is called */
+#define _PyGC_PREV_MASK_FINALIZED  (1)
+/* Bit 1 is set when the object is in generation which is GCed currently. */
+#define _PyGC_PREV_MASK_COLLECTING (2)
+/* The (N-2) most significant bits contain the real address. */
+#define _PyGC_PREV_SHIFT           (2)
+#define _PyGC_PREV_MASK            (((uintptr_t) -1) << _PyGC_PREV_SHIFT)
+
+// Lowest bit of _gc_next is used for flags only in GC.
+// But it is always 0 for normal code.
+#define _PyGCHead_NEXT(g)        ((PyGC_Head*)(g)->_gc_next)
+#define _PyGCHead_SET_NEXT(g, p) ((g)->_gc_next = (uintptr_t)(p))
+
+// Lowest two bits of _gc_prev is used for _PyGC_PREV_MASK_* flags.
+#define _PyGCHead_PREV(g) ((PyGC_Head*)((g)->_gc_prev & _PyGC_PREV_MASK))
+#define _PyGCHead_SET_PREV(g, p) do { \
+    assert(((uintptr_t)p & ~_PyGC_PREV_MASK) == 0); \
+    (g)->_gc_prev = ((g)->_gc_prev & ~_PyGC_PREV_MASK) \
+        | ((uintptr_t)(p)); \
+    } while (0)
+
+#define _PyGCHead_FINALIZED(g) \
+    (((g)->_gc_prev & _PyGC_PREV_MASK_FINALIZED) != 0)
+#define _PyGCHead_SET_FINALIZED(g) \
+    ((g)->_gc_prev |= _PyGC_PREV_MASK_FINALIZED)
+
+#define _PyGC_FINALIZED(o) \
+    _PyGCHead_FINALIZED(_Py_AS_GC(o))
+#define _PyGC_SET_FINALIZED(o) \
+    _PyGCHead_SET_FINALIZED(_Py_AS_GC(o))
+
+
+PyAPI_FUNC(PyObject *) _PyObject_GC_Malloc(size_t size);
+PyAPI_FUNC(PyObject *) _PyObject_GC_Calloc(size_t size);
+
+
+/* Test if a type supports weak references */
+#define PyType_SUPPORTS_WEAKREFS(t) ((t)->tp_weaklistoffset > 0)
+
+#define PyObject_GET_WEAKREFS_LISTPTR(o) \
+    ((PyObject **) (((char *) (o)) + Py_TYPE(o)->tp_weaklistoffset))
+
+#ifdef __cplusplus
+}
+#endif
index aee3fdc3747a97e4f937f5e92d6a20e095789019..f475ed001d02f80d047fc22f466c270e9a161cf4 100644 (file)
@@ -101,17 +101,6 @@ PyAPI_FUNC(void *) PyObject_Calloc(size_t nelem, size_t elsize);
 PyAPI_FUNC(void *) PyObject_Realloc(void *ptr, size_t new_size);
 PyAPI_FUNC(void) PyObject_Free(void *ptr);
 
-#ifndef Py_LIMITED_API
-/* This function returns the number of allocated memory blocks, regardless of size */
-PyAPI_FUNC(Py_ssize_t) _Py_GetAllocatedBlocks(void);
-#endif /* !Py_LIMITED_API */
-
-/* Macros */
-#ifdef WITH_PYMALLOC
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(int) _PyObject_DebugMallocStats(FILE *out);
-#endif /* #ifndef Py_LIMITED_API */
-#endif
 
 /* Macros */
 #define PyObject_MALLOC         PyObject_Malloc
@@ -226,24 +215,6 @@ _PyObject_INIT_VAR(PyVarObject *op, PyTypeObject *typeobj, Py_ssize_t size)
    constructor you would start directly with PyObject_Init/InitVar
 */
 
-#ifndef Py_LIMITED_API
-typedef struct {
-    /* user context passed as the first argument to the 2 functions */
-    void *ctx;
-
-    /* allocate an arena of size bytes */
-    void* (*alloc) (void *ctx, size_t size);
-
-    /* free an arena */
-    void (*free) (void *ctx, void *ptr, size_t size);
-} PyObjectArenaAllocator;
-
-/* Get the arena allocator. */
-PyAPI_FUNC(void) PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator);
-
-/* Set the arena allocator. */
-PyAPI_FUNC(void) PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator);
-#endif
 
 
 /*
@@ -254,11 +225,6 @@ PyAPI_FUNC(void) PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator);
 /* C equivalent of gc.collect() which ignores the state of gc.enabled. */
 PyAPI_FUNC(Py_ssize_t) PyGC_Collect(void);
 
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(Py_ssize_t) _PyGC_CollectNoFail(void);
-PyAPI_FUNC(Py_ssize_t) _PyGC_CollectIfEnabled(void);
-#endif
-
 /* Test if a type has a GC head */
 #define PyType_IS_GC(t) PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC)
 
@@ -267,72 +233,7 @@ PyAPI_FUNC(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, Py_ssize_t);
                 ( (type *) _PyObject_GC_Resize(_PyVarObject_CAST(op), (n)) )
 
 
-#ifndef Py_LIMITED_API
-/* Test if an object has a GC head */
-#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)))
-
-/* GC information is stored BEFORE the object structure. */
-typedef struct {
-    // Pointer to next object in the list.
-    // 0 means the object is not tracked
-    uintptr_t _gc_next;
-
-    // Pointer to previous object in the list.
-    // Lowest two bits are used for flags documented later.
-    uintptr_t _gc_prev;
-} PyGC_Head;
-
-#define _Py_AS_GC(o) ((PyGC_Head *)(o)-1)
-
-/* True if the object is currently tracked by the GC. */
-#define _PyObject_GC_IS_TRACKED(o) (_Py_AS_GC(o)->_gc_next != 0)
-
-/* True if the object may be tracked by the GC in the future, or already is.
-   This can be useful to implement some optimizations. */
-#define _PyObject_GC_MAY_BE_TRACKED(obj) \
-    (PyObject_IS_GC(obj) && \
-        (!PyTuple_CheckExact(obj) || _PyObject_GC_IS_TRACKED(obj)))
-
-
-/* Bit flags for _gc_prev */
-/* Bit 0 is set when tp_finalize is called */
-#define _PyGC_PREV_MASK_FINALIZED  (1)
-/* Bit 1 is set when the object is in generation which is GCed currently. */
-#define _PyGC_PREV_MASK_COLLECTING (2)
-/* The (N-2) most significant bits contain the real address. */
-#define _PyGC_PREV_SHIFT           (2)
-#define _PyGC_PREV_MASK            (((uintptr_t) -1) << _PyGC_PREV_SHIFT)
-
-// Lowest bit of _gc_next is used for flags only in GC.
-// But it is always 0 for normal code.
-#define _PyGCHead_NEXT(g)        ((PyGC_Head*)(g)->_gc_next)
-#define _PyGCHead_SET_NEXT(g, p) ((g)->_gc_next = (uintptr_t)(p))
-
-// Lowest two bits of _gc_prev is used for _PyGC_PREV_MASK_* flags.
-#define _PyGCHead_PREV(g) ((PyGC_Head*)((g)->_gc_prev & _PyGC_PREV_MASK))
-#define _PyGCHead_SET_PREV(g, p) do { \
-    assert(((uintptr_t)p & ~_PyGC_PREV_MASK) == 0); \
-    (g)->_gc_prev = ((g)->_gc_prev & ~_PyGC_PREV_MASK) \
-        | ((uintptr_t)(p)); \
-    } while (0)
-
-#define _PyGCHead_FINALIZED(g) \
-    (((g)->_gc_prev & _PyGC_PREV_MASK_FINALIZED) != 0)
-#define _PyGCHead_SET_FINALIZED(g) \
-    ((g)->_gc_prev |= _PyGC_PREV_MASK_FINALIZED)
-
-#define _PyGC_FINALIZED(o) \
-    _PyGCHead_FINALIZED(_Py_AS_GC(o))
-#define _PyGC_SET_FINALIZED(o) \
-    _PyGCHead_SET_FINALIZED(_Py_AS_GC(o))
-#endif   /* !defined(Py_LIMITED_API) */
 
-#ifndef Py_LIMITED_API
-PyAPI_FUNC(PyObject *) _PyObject_GC_Malloc(size_t size);
-PyAPI_FUNC(PyObject *) _PyObject_GC_Calloc(size_t size);
-#endif /* !Py_LIMITED_API */
 PyAPI_FUNC(PyObject *) _PyObject_GC_New(PyTypeObject *);
 PyAPI_FUNC(PyVarObject *) _PyObject_GC_NewVar(PyTypeObject *, Py_ssize_t);
 
@@ -368,13 +269,10 @@ PyAPI_FUNC(void) PyObject_GC_Del(void *);
         }                                                               \
     } while (0)
 
-
-/* Test if a type supports weak references */
 #ifndef Py_LIMITED_API
-#define PyType_SUPPORTS_WEAKREFS(t) ((t)->tp_weaklistoffset > 0)
-
-#define PyObject_GET_WEAKREFS_LISTPTR(o) \
-    ((PyObject **) (((char *) (o)) + Py_TYPE(o)->tp_weaklistoffset))
+#  define Py_CPYTHON_OBJIMPL_H
+#  include  "cpython/objimpl.h"
+#  undef Py_CPYTHON_OBJIMPL_H
 #endif
 
 #ifdef __cplusplus
index 5a21adb7e9b18123250625085e27a027c5e4050d..d0e915a00ae08ec1e6104b346bd94585193b2eee 100644 (file)
@@ -1021,9 +1021,13 @@ PYTHON_HEADERS= \
                $(srcdir)/Include/unicodeobject.h \
                $(srcdir)/Include/warnings.h \
                $(srcdir)/Include/weakrefobject.h \
+               \
                pyconfig.h \
                $(PARSER_HEADERS) \
                $(srcdir)/Include/Python-ast.h \
+               \
+               $(srcdir)/Include/cpython/objimpl.h \
+               \
                $(srcdir)/Include/internal/pycore_accu.h \
                $(srcdir)/Include/internal/pycore_atomic.h \
                $(srcdir)/Include/internal/pycore_ceval.h \
@@ -1446,6 +1450,11 @@ inclinstall:
                else    true; \
                fi; \
        done
+       @if test ! -d $(DESTDIR)$(INCLUDEPY)/cpython; then \
+               echo "Creating directory $(DESTDIR)$(INCLUDEPY)/cpython"; \
+               $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$(INCLUDEPY)/cpython; \
+       else    true; \
+       fi
        @if test ! -d $(DESTDIR)$(INCLUDEPY)/internal; then \
                echo "Creating directory $(DESTDIR)$(INCLUDEPY)/internal"; \
                $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$(INCLUDEPY)/internal; \
@@ -1456,6 +1465,11 @@ inclinstall:
                echo $(INSTALL_DATA) $$i $(INCLUDEPY); \
                $(INSTALL_DATA) $$i $(DESTDIR)$(INCLUDEPY); \
        done
+       @for i in $(srcdir)/Include/cpython/*.h; \
+       do \
+               echo $(INSTALL_DATA) $$i $(INCLUDEPY)/cpython; \
+               $(INSTALL_DATA) $$i $(DESTDIR)$(INCLUDEPY)/cpython; \
+       done
        @for i in $(srcdir)/Include/internal/*.h; \
        do \
                echo $(INSTALL_DATA) $$i $(INCLUDEPY)/internal; \
diff --git a/Misc/NEWS.d/next/C API/2018-11-01-13-58-37.bpo-35134.SbZo0o.rst b/Misc/NEWS.d/next/C API/2018-11-01-13-58-37.bpo-35134.SbZo0o.rst
new file mode 100644 (file)
index 0000000..c486a29
--- /dev/null
@@ -0,0 +1 @@
+Creation of a new ``Include/cpython/`` subdirectory.
index 885d602b3f0eee75b1684781581b91fac4191499..34cd3796888cfc1deff4c380697100ade5ea693c 100644 (file)
@@ -95,6 +95,7 @@
     <ClInclude Include="..\Include\complexobject.h" />
     <ClInclude Include="..\Include\context.h" />
     <ClInclude Include="..\Include\coreconfig.h" />
+    <ClInclude Include="..\Include\cpython\objimpl.h" />
     <ClInclude Include="..\Include\datetime.h" />
     <ClInclude Include="..\Include\descrobject.h" />
     <ClInclude Include="..\Include\dictobject.h" />
index 2af11c943ae2b4443f8b9cf69335f5066c2600b3..ebe5e8a169fdc9673992ce1e327791965a39ed93 100644 (file)
@@ -84,6 +84,9 @@
     <ClInclude Include="..\Include\coreconfig.h">
       <Filter>Include</Filter>
     </ClInclude>
+    <ClInclude Include="..\Include\cpython\objimpl.h">
+      <Filter>Include</Filter>
+    </ClInclude>
     <ClInclude Include="..\Include\datetime.h">
       <Filter>Include</Filter>
     </ClInclude>
index 682b66031f1e77c029d9bfbc6220a4e94ae09839..bc3a19ce33ca38c875ac2ef4228fd985ab060323 100644 (file)
@@ -21,7 +21,7 @@
         <EmbeddedResource Include="*.wxl" />
     </ItemGroup>
     <ItemGroup>
-        <InstallFiles Include="$(PySourcePath)include\*.h">
+        <InstallFiles Include="$(PySourcePath)include\**\*.h">
             <SourceBase>$(PySourcePath)</SourceBase>
             <Source>!(bindpath.src)</Source>
             <TargetBase>$(PySourcePath)</TargetBase>
@@ -29,7 +29,7 @@
             <Group>dev_include</Group>
         </InstallFiles>
     </ItemGroup>
-    
+
     <Target Name="BuildMinGWLib"
             Inputs="$(BuildPath)$(PyDllName).dll"
             Outputs="$(BuildPath)lib$(PyDllName).a"
@@ -46,4 +46,4 @@
     </Target>
 
     <Import Project="..\msi.targets" />
-</Project>
\ No newline at end of file
+</Project>