Merge branches/pep-0384.
diff --git a/Include/Python.h b/Include/Python.h
index a49753f..db33a76 100644
--- a/Include/Python.h
+++ b/Include/Python.h
@@ -66,6 +66,7 @@
 
 #include "object.h"
 #include "objimpl.h"
+#include "typeslots.h"
 
 #include "pydebug.h"
 
@@ -100,6 +101,7 @@
 #include "weakrefobject.h"
 #include "structseq.h"
 
+
 #include "codecs.h"
 #include "pyerrors.h"
 
@@ -130,7 +132,9 @@
 #endif
 
 /* _Py_Mangle is defined in compile.c */
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name);
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/Include/abstract.h b/Include/abstract.h
index 2399079..53c9dc7 100644
--- a/Include/abstract.h
+++ b/Include/abstract.h
@@ -387,7 +387,9 @@
      PyAPI_FUNC(Py_ssize_t) PyObject_Length(PyObject *o);
 #define PyObject_Length PyObject_Size
 
+#ifndef Py_LIMITED_API
      PyAPI_FUNC(Py_ssize_t) _PyObject_LengthHint(PyObject *o, Py_ssize_t);
+#endif
 
        /*
      Guess the size of object o using len(o) or o.__length_hint__().
@@ -765,9 +767,11 @@
      that can accept a char* naming integral's type.
        */
 
+#ifndef Py_LIMITED_API
      PyAPI_FUNC(PyObject *) _PyNumber_ConvertIntegralToInt(
          PyObject *integral,
          const char* error_format);
+#endif
 
        /*
     Returns the object converted to Py_ssize_t by going through
@@ -1057,11 +1061,13 @@
      Use __contains__ if possible, else _PySequence_IterSearch().
        */
 
+#ifndef Py_LIMITED_API
 #define PY_ITERSEARCH_COUNT    1
 #define PY_ITERSEARCH_INDEX    2
 #define PY_ITERSEARCH_CONTAINS 3
      PyAPI_FUNC(Py_ssize_t) _PySequence_IterSearch(PyObject *seq,
                                         PyObject *obj, int operation);
+#endif
     /*
       Iterate over seq.  Result depends on the operation:
       PY_ITERSEARCH_COUNT:  return # of times obj appears in seq; -1 if
@@ -1228,6 +1234,7 @@
       /* issubclass(object, typeorclass) */
 
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(int) _PyObject_RealIsInstance(PyObject *inst, PyObject *cls);
 
 PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls);
@@ -1235,6 +1242,7 @@
 PyAPI_FUNC(char *const *) _PySequence_BytesToCharpArray(PyObject* self);
 
 PyAPI_FUNC(void) _Py_FreeCharPArray(char *const array[]);
+#endif
 
 /* For internal use by buffer API functions */
 PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index,
diff --git a/Include/bytearrayobject.h b/Include/bytearrayobject.h
index e1281a6..eccd44c 100644
--- a/Include/bytearrayobject.h
+++ b/Include/bytearrayobject.h
@@ -19,6 +19,7 @@
  */
 
 /* Object layout */
+#ifndef Py_LIMITED_API
 typedef struct {
     PyObject_VAR_HEAD
     /* XXX(nnorwitz): should ob_exports be Py_ssize_t? */
@@ -26,6 +27,7 @@
     Py_ssize_t ob_alloc; /* How many bytes allocated */
     char *ob_bytes;
 } PyByteArrayObject;
+#endif
 
 /* Type object */
 PyAPI_DATA(PyTypeObject) PyByteArray_Type;
@@ -44,12 +46,14 @@
 PyAPI_FUNC(int) PyByteArray_Resize(PyObject *, Py_ssize_t);
 
 /* Macros, trading safety for speed */
+#ifndef Py_LIMITED_API
 #define PyByteArray_AS_STRING(self) \
     (assert(PyByteArray_Check(self)), \
      Py_SIZE(self) ? ((PyByteArrayObject *)(self))->ob_bytes : _PyByteArray_empty_string)
 #define PyByteArray_GET_SIZE(self)  (assert(PyByteArray_Check(self)),Py_SIZE(self))
 
 PyAPI_DATA(char) _PyByteArray_empty_string[];
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/Include/bytes_methods.h b/Include/bytes_methods.h
index d0a6242..1498b8f 100644
--- a/Include/bytes_methods.h
+++ b/Include/bytes_methods.h
@@ -1,3 +1,4 @@
+#ifndef Py_LIMITED_API
 #ifndef Py_BYTES_CTYPE_H
 #define Py_BYTES_CTYPE_H
 
@@ -42,3 +43,4 @@
 #define PyDoc_STRVAR_shared(name,str) const char name[] = PyDoc_STR(str)
 
 #endif /* !Py_BYTES_CTYPE_H */
+#endif /* !Py_LIMITED_API */
diff --git a/Include/bytesobject.h b/Include/bytesobject.h
index 3c69d25..e1af89f 100644
--- a/Include/bytesobject.h
+++ b/Include/bytesobject.h
@@ -27,6 +27,7 @@
 /* Caching the hash (ob_shash) saves recalculation of a string's hash value.
    This significantly speeds up dict lookups. */
 
+#ifndef Py_LIMITED_API
 typedef struct {
     PyObject_VAR_HEAD
     Py_hash_t ob_shash;
@@ -38,6 +39,7 @@
      *     ob_shash is the hash of the string or -1 if not computed yet.
      */
 } PyBytesObject;
+#endif
 
 PyAPI_DATA(PyTypeObject) PyBytes_Type;
 PyAPI_DATA(PyTypeObject) PyBytesIter_Type;
@@ -58,21 +60,27 @@
 PyAPI_FUNC(PyObject *) PyBytes_Repr(PyObject *, int);
 PyAPI_FUNC(void) PyBytes_Concat(PyObject **, PyObject *);
 PyAPI_FUNC(void) PyBytes_ConcatAndDel(PyObject **, PyObject *);
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(int) _PyBytes_Resize(PyObject **, Py_ssize_t);
 PyAPI_FUNC(PyObject *) _PyBytes_FormatLong(PyObject*, int, int,
 						  int, char**, int*);
+#endif
 PyAPI_FUNC(PyObject *) PyBytes_DecodeEscape(const char *, Py_ssize_t,
 						   const char *, Py_ssize_t,
 						   const char *);
 
 /* Macro, trading safety for speed */
+#ifndef Py_LIMITED_API
 #define PyBytes_AS_STRING(op) (assert(PyBytes_Check(op)), \
                                 (((PyBytesObject *)(op))->ob_sval))
 #define PyBytes_GET_SIZE(op)  (assert(PyBytes_Check(op)),Py_SIZE(op))
+#endif
 
 /* _PyBytes_Join(sep, x) is like sep.join(x).  sep must be PyBytesObject*,
    x must be an iterable object. */
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject *) _PyBytes_Join(PyObject *sep, PyObject *x);
+#endif
 
 /* Provides access to the internal data buffer and size of a string
    object or the default encoded version of an Unicode object. Passing
@@ -90,7 +98,7 @@
 /* Using the current locale, insert the thousands grouping
    into the string pointed to by buffer.  For the argument descriptions,
    see Objects/stringlib/localeutil.h */
-
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(Py_ssize_t) _PyBytes_InsertThousandsGroupingLocale(char *buffer,
                                                    Py_ssize_t n_buffer,
                                                    char *digits,
@@ -107,6 +115,7 @@
                                                    Py_ssize_t min_width,
                                                    const char *grouping,
                                                    const char *thousands_sep);
+#endif
 
 /* Flags used by string formatting */
 #define F_LJUST (1<<0)
diff --git a/Include/cellobject.h b/Include/cellobject.h
index c927ee5..a0aa4d9 100644
--- a/Include/cellobject.h
+++ b/Include/cellobject.h
@@ -1,5 +1,5 @@
 /* Cell object interface */
-
+#ifndef Py_LIMITED_API
 #ifndef Py_CELLOBJECT_H
 #define Py_CELLOBJECT_H
 #ifdef __cplusplus
@@ -26,3 +26,4 @@
 }
 #endif
 #endif /* !Py_TUPLEOBJECT_H */
+#endif /* Py_LIMITED_API */
diff --git a/Include/ceval.h b/Include/ceval.h
index 2acde13..6811367 100644
--- a/Include/ceval.h
+++ b/Include/ceval.h
@@ -20,8 +20,10 @@
                                          const char *methodname,
                                          const char *format, ...);
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *);
 PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *);
+#endif
 
 struct _frame; /* Avoid including frameobject.h */
 
@@ -33,7 +35,9 @@
 /* Look at the current frame's (if any) code's co_flags, and turn on
    the corresponding compiler flags in cf->cf_flags.  Return 1 if any
    flag was set, else return 0. */
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf);
+#endif
 
 PyAPI_FUNC(int) Py_AddPendingCall(int (*func)(void *), void *arg);
 PyAPI_FUNC(int) Py_MakePendingCalls(void);
@@ -167,8 +171,10 @@
 PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate);
 PyAPI_FUNC(void) PyEval_ReInitThreads(void);
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(void) _PyEval_SetSwitchInterval(unsigned long microseconds);
 PyAPI_FUNC(unsigned long) _PyEval_GetSwitchInterval(void);
+#endif
 
 #define Py_BEGIN_ALLOW_THREADS { \
                         PyThreadState *_save; \
@@ -187,8 +193,10 @@
 
 #endif /* !WITH_THREAD */
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *);
 PyAPI_FUNC(void) _PyEval_SignalAsyncExc(void);
+#endif
 
 
 #ifdef __cplusplus
diff --git a/Include/classobject.h b/Include/classobject.h
index b7eebe5..eeeb3e9 100644
--- a/Include/classobject.h
+++ b/Include/classobject.h
@@ -2,6 +2,7 @@
 
 /* Revealing some structures (not for general use) */
 
+#ifndef Py_LIMITED_API
 #ifndef Py_CLASSOBJECT_H
 #define Py_CLASSOBJECT_H
 #ifdef __cplusplus
@@ -54,3 +55,4 @@
 }
 #endif
 #endif /* !Py_CLASSOBJECT_H */
+#endif /* Py_LIMITED_API */
diff --git a/Include/code.h b/Include/code.h
index 11ecc95..e773b6a 100644
--- a/Include/code.h
+++ b/Include/code.h
@@ -1,5 +1,6 @@
 /* Definitions for bytecode */
 
+#ifndef Py_LIMITED_API
 #ifndef Py_CODE_H
 #define Py_CODE_H
 #ifdef __cplusplus
@@ -93,8 +94,10 @@
 /* Update *bounds to describe the first and one-past-the-last instructions in the
    same line as lasti.  Return the number of that line.
 */
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(int) _PyCode_CheckLineNumber(PyCodeObject* co,
                                         int lasti, PyAddrPair *bounds);
+#endif
 
 PyAPI_FUNC(PyObject*) PyCode_Optimize(PyObject *code, PyObject* consts,
                                       PyObject *names, PyObject *lineno_obj);
@@ -103,3 +106,4 @@
 }
 #endif
 #endif /* !Py_CODE_H */
+#endif /* Py_LIMITED_API */
diff --git a/Include/codecs.h b/Include/codecs.h
index 4ea934e..dff09e7 100644
--- a/Include/codecs.h
+++ b/Include/codecs.h
@@ -45,9 +45,11 @@
 
  */
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject *) _PyCodec_Lookup(
        const char *encoding
        );
+#endif
 
 /* Codec registry encoding check API.
 
diff --git a/Include/compile.h b/Include/compile.h
index 7c329b3..4a5ebe6 100644
--- a/Include/compile.h
+++ b/Include/compile.h
@@ -1,4 +1,4 @@
-
+#ifndef Py_LIMITED_API
 #ifndef Py_COMPILE_H
 #define Py_COMPILE_H
 
@@ -38,3 +38,4 @@
 }
 #endif
 #endif /* !Py_COMPILE_H */
+#endif /* !Py_LIMITED_API */
diff --git a/Include/complexobject.h b/Include/complexobject.h
index 8290a6d..c379b08 100644
--- a/Include/complexobject.h
+++ b/Include/complexobject.h
@@ -6,6 +6,7 @@
 extern "C" {
 #endif
 
+#ifndef Py_LIMITED_API
 typedef struct {
     double real;
     double imag;
@@ -28,7 +29,7 @@
 PyAPI_FUNC(Py_complex) c_quot(Py_complex, Py_complex);
 PyAPI_FUNC(Py_complex) c_pow(Py_complex, Py_complex);
 PyAPI_FUNC(double) c_abs(Py_complex);
-
+#endif
 
 /* Complex object interface */
 
@@ -36,29 +37,36 @@
 PyComplexObject represents a complex number with double-precision
 real and imaginary parts.
 */
-
+#ifndef Py_LIMITED_API
 typedef struct {
     PyObject_HEAD
     Py_complex cval;
-} PyComplexObject;     
+} PyComplexObject;
+#endif
 
 PyAPI_DATA(PyTypeObject) PyComplex_Type;
 
 #define PyComplex_Check(op) PyObject_TypeCheck(op, &PyComplex_Type)
 #define PyComplex_CheckExact(op) (Py_TYPE(op) == &PyComplex_Type)
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject *) PyComplex_FromCComplex(Py_complex);
+#endif
 PyAPI_FUNC(PyObject *) PyComplex_FromDoubles(double real, double imag);
 
 PyAPI_FUNC(double) PyComplex_RealAsDouble(PyObject *op);
 PyAPI_FUNC(double) PyComplex_ImagAsDouble(PyObject *op);
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(Py_complex) PyComplex_AsCComplex(PyObject *op);
+#endif
 
 /* Format the object based on the format_spec, as defined in PEP 3101
    (Advanced String Formatting). */
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject *) _PyComplex_FormatAdvanced(PyObject *obj,
                                                  Py_UNICODE *format_spec,
                                                  Py_ssize_t format_spec_len);
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/Include/datetime.h b/Include/datetime.h
index 2d71fce..db57a18 100644
--- a/Include/datetime.h
+++ b/Include/datetime.h
@@ -1,6 +1,6 @@
 /*  datetime.h
  */
-
+#ifndef Py_LIMITED_API
 #ifndef DATETIME_H
 #define DATETIME_H
 #ifdef __cplusplus
@@ -234,3 +234,4 @@
 }
 #endif
 #endif
+#endif /* !Py_LIMITED_API */
diff --git a/Include/descrobject.h b/Include/descrobject.h
index 4f0c693..f715fe1 100644
--- a/Include/descrobject.h
+++ b/Include/descrobject.h
@@ -16,6 +16,7 @@
     void *closure;
 } PyGetSetDef;
 
+#ifndef Py_LIMITED_API
 typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args,
                                  void *wrapped);
 
@@ -68,6 +69,7 @@
     struct wrapperbase *d_base;
     void *d_wrapped; /* This can be any function pointer */
 } PyWrapperDescrObject;
+#endif /* Py_LIMITED_API */
 
 PyAPI_DATA(PyTypeObject) PyClassMethodDescr_Type;
 PyAPI_DATA(PyTypeObject) PyGetSetDescr_Type;
@@ -78,13 +80,16 @@
 
 PyAPI_FUNC(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *);
 PyAPI_FUNC(PyObject *) PyDescr_NewClassMethod(PyTypeObject *, PyMethodDef *);
+struct PyMemberDef; /* forward declaration for following prototype */
 PyAPI_FUNC(PyObject *) PyDescr_NewMember(PyTypeObject *,
                                                struct PyMemberDef *);
 PyAPI_FUNC(PyObject *) PyDescr_NewGetSet(PyTypeObject *,
                                                struct PyGetSetDef *);
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *,
                                                 struct wrapperbase *, void *);
 #define PyDescr_IsData(d) (Py_TYPE(d)->tp_descr_set != NULL)
+#endif
 
 PyAPI_FUNC(PyObject *) PyDictProxy_New(PyObject *);
 PyAPI_FUNC(PyObject *) PyWrapper_New(PyObject *, PyObject *);
diff --git a/Include/dictobject.h b/Include/dictobject.h
index 024a688..b026785 100644
--- a/Include/dictobject.h
+++ b/Include/dictobject.h
@@ -45,6 +45,7 @@
  * majority of dicts (consisting mostly of usually-small instance dicts and
  * usually-small dicts created to pass keyword arguments).
  */
+#ifndef Py_LIMITED_API
 #define PyDict_MINSIZE 8
 
 typedef struct {
@@ -84,6 +85,7 @@
     PyDictEntry *(*ma_lookup)(PyDictObject *mp, PyObject *key, Py_hash_t hash);
     PyDictEntry ma_smalltable[PyDict_MINSIZE];
 };
+#endif /* Py_LIMITED_API */
 
 PyAPI_DATA(PyTypeObject) PyDict_Type;
 PyAPI_DATA(PyTypeObject) PyDictIterKey_Type;
@@ -112,18 +114,22 @@
 PyAPI_FUNC(void) PyDict_Clear(PyObject *mp);
 PyAPI_FUNC(int) PyDict_Next(
     PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value);
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(int) _PyDict_Next(
     PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash);
+#endif
 PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp);
 PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp);
 PyAPI_FUNC(PyObject *) PyDict_Items(PyObject *mp);
 PyAPI_FUNC(Py_ssize_t) PyDict_Size(PyObject *mp);
 PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp);
 PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key);
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, Py_hash_t hash);
 PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
 PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp);
 PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp);
+#endif
 
 /* PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */
 PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other);
diff --git a/Include/dtoa.h b/Include/dtoa.h
index 9b434b7..819bd0f 100644
--- a/Include/dtoa.h
+++ b/Include/dtoa.h
@@ -1,3 +1,4 @@
+#ifndef Py_LIMITED_API
 #ifndef PY_NO_SHORT_FLOAT_REPR
 #ifdef __cplusplus
 extern "C" {
@@ -13,3 +14,4 @@
 }
 #endif
 #endif
+#endif
diff --git a/Include/eval.h b/Include/eval.h
index 1d03c97..a1c6e81 100644
--- a/Include/eval.h
+++ b/Include/eval.h
@@ -7,9 +7,9 @@
 extern "C" {
 #endif
 
-PyAPI_FUNC(PyObject *) PyEval_EvalCode(PyCodeObject *, PyObject *, PyObject *);
+PyAPI_FUNC(PyObject *) PyEval_EvalCode(PyObject *, PyObject *, PyObject *);
 
-PyAPI_FUNC(PyObject *) PyEval_EvalCodeEx(PyCodeObject *co,
+PyAPI_FUNC(PyObject *) PyEval_EvalCodeEx(PyObject *co,
 					PyObject *globals,
 					PyObject *locals,
 					PyObject **args, int argc,
@@ -17,7 +17,9 @@
 					PyObject **defs, int defc,
 					PyObject *kwdefs, PyObject *closure);
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject *) _PyEval_CallTracing(PyObject *func, PyObject *args);
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/Include/fileobject.h b/Include/fileobject.h
index 20545fa..c4a2a2b 100644
--- a/Include/fileobject.h
+++ b/Include/fileobject.h
@@ -14,7 +14,9 @@
 PyAPI_FUNC(int) PyFile_WriteObject(PyObject *, PyObject *, int);
 PyAPI_FUNC(int) PyFile_WriteString(const char *, PyObject *);
 PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *);
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *);
+#endif
 
 /* The default encoding used by the platform file system APIs
    If non-NULL, this is different than the default encoding for strings
@@ -26,6 +28,7 @@
 
    The std printer acts as a preliminary sys.stderr until the new io
    infrastructure is in place. */
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject *) PyFile_NewStdPrinter(int);
 PyAPI_DATA(PyTypeObject) PyStdPrinter_Type;
 
@@ -39,6 +42,7 @@
 #else
 #define _PyVerify_fd(A) (1) /* dummy */
 #endif
+#endif /* Py_LIMITED_API */
 
 #ifdef __cplusplus
 }
diff --git a/Include/floatobject.h b/Include/floatobject.h
index 364b913..90f0a45 100644
--- a/Include/floatobject.h
+++ b/Include/floatobject.h
@@ -11,10 +11,12 @@
 extern "C" {
 #endif
 
+#ifndef Py_LIMITED_API
 typedef struct {
     PyObject_HEAD
     double ob_fval;
 } PyFloatObject;
+#endif
 
 PyAPI_DATA(PyTypeObject) PyFloat_Type;
 
@@ -45,8 +47,11 @@
 /* Extract C double from Python float.  The macro version trades safety for
    speed. */
 PyAPI_FUNC(double) PyFloat_AsDouble(PyObject *);
+#ifndef Py_LIMITED_API
 #define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval)
+#endif
 
+#ifndef Py_LIMITED_API
 /* _PyFloat_{Pack,Unpack}{4,8}
  *
  * The struct and pickle (at least) modules need an efficient platform-
@@ -110,6 +115,7 @@
 PyAPI_FUNC(PyObject *) _PyFloat_FormatAdvanced(PyObject *obj,
 					       Py_UNICODE *format_spec,
 					       Py_ssize_t format_spec_len);
+#endif /* Py_LIMITED_API */
 
 #ifdef __cplusplus
 }
diff --git a/Include/frameobject.h b/Include/frameobject.h
index 9440973..1fb64bb 100644
--- a/Include/frameobject.h
+++ b/Include/frameobject.h
@@ -1,6 +1,7 @@
 
 /* Frame object interface */
 
+#ifndef Py_LIMITED_API
 #ifndef Py_FRAMEOBJECT_H
 #define Py_FRAMEOBJECT_H
 #ifdef __cplusplus
@@ -85,3 +86,4 @@
 }
 #endif
 #endif /* !Py_FRAMEOBJECT_H */
+#endif /* Py_LIMITED_API */
diff --git a/Include/funcobject.h b/Include/funcobject.h
index 058c6bf..521d87b 100644
--- a/Include/funcobject.h
+++ b/Include/funcobject.h
@@ -1,6 +1,6 @@
 
 /* Function object interface */
-
+#ifndef Py_LIMITED_API
 #ifndef Py_FUNCOBJECT_H
 #define Py_FUNCOBJECT_H
 #ifdef __cplusplus
@@ -84,3 +84,4 @@
 }
 #endif
 #endif /* !Py_FUNCOBJECT_H */
+#endif /* Py_LIMITED_API */
diff --git a/Include/genobject.h b/Include/genobject.h
index 135561b..d29fb1e 100644
--- a/Include/genobject.h
+++ b/Include/genobject.h
@@ -1,6 +1,7 @@
 
 /* Generator object interface */
 
+#ifndef Py_LIMITED_API
 #ifndef Py_GENOBJECT_H
 #define Py_GENOBJECT_H
 #ifdef __cplusplus
@@ -38,3 +39,4 @@
 }
 #endif
 #endif /* !Py_GENOBJECT_H */
+#endif /* Py_LIMITED_API */
diff --git a/Include/import.h b/Include/import.h
index 3e81e78..2df94ff 100644
--- a/Include/import.h
+++ b/Include/import.h
@@ -30,6 +30,7 @@
 PyAPI_FUNC(void) PyImport_Cleanup(void);
 PyAPI_FUNC(int) PyImport_ImportFrozenModule(char *);
 
+#ifndef Py_LIMITED_API
 #ifdef WITH_THREAD
 PyAPI_FUNC(void) _PyImport_AcquireLock(void);
 PyAPI_FUNC(int) _PyImport_ReleaseLock(void);
@@ -49,13 +50,15 @@
     char *name;
     PyObject* (*initfunc)(void);
 };
+PyAPI_DATA(struct _inittab *) PyImport_Inittab;
+PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab);
+#endif /* Py_LIMITED_API */
 
 PyAPI_DATA(PyTypeObject) PyNullImporter_Type;
-PyAPI_DATA(struct _inittab *) PyImport_Inittab;
 
 PyAPI_FUNC(int) PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void));
-PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab);
 
+#ifndef Py_LIMITED_API
 struct _frozen {
     char *name;
     unsigned char *code;
@@ -66,6 +69,7 @@
    collection of frozen modules: */
 
 PyAPI_DATA(struct _frozen *) PyImport_FrozenModules;
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/Include/listobject.h b/Include/listobject.h
index 755fbbe..949b1a3 100644
--- a/Include/listobject.h
+++ b/Include/listobject.h
@@ -19,6 +19,7 @@
 extern "C" {
 #endif
 
+#ifndef Py_LIMITED_API
 typedef struct {
     PyObject_VAR_HEAD
     /* Vector of pointers to list elements.  list[0] is ob_item[0], etc. */
@@ -37,6 +38,7 @@
      */
     Py_ssize_t allocated;
 } PyListObject;
+#endif
 
 PyAPI_DATA(PyTypeObject) PyList_Type;
 PyAPI_DATA(PyTypeObject) PyListIter_Type;
@@ -58,12 +60,16 @@
 PyAPI_FUNC(int) PyList_Sort(PyObject *);
 PyAPI_FUNC(int) PyList_Reverse(PyObject *);
 PyAPI_FUNC(PyObject *) PyList_AsTuple(PyObject *);
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *);
+#endif
 
 /* Macro, trading safety for speed */
+#ifndef Py_LIMITED_API
 #define PyList_GET_ITEM(op, i) (((PyListObject *)(op))->ob_item[i])
 #define PyList_SET_ITEM(op, i, v) (((PyListObject *)(op))->ob_item[i] = (v))
 #define PyList_GET_SIZE(op)    Py_SIZE(op)
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/Include/longintrepr.h b/Include/longintrepr.h
index 3d71a35..b94f7b2 100644
--- a/Include/longintrepr.h
+++ b/Include/longintrepr.h
@@ -1,3 +1,4 @@
+#ifndef Py_LIMITED_API
 #ifndef Py_LONGINTREPR_H
 #define Py_LONGINTREPR_H
 #ifdef __cplusplus
@@ -99,3 +100,4 @@
 }
 #endif
 #endif /* !Py_LONGINTREPR_H */
+#endif /* Py_LIMITED_API */
diff --git a/Include/longobject.h b/Include/longobject.h
index 6adf262..c09565a 100644
--- a/Include/longobject.h
+++ b/Include/longobject.h
@@ -50,7 +50,9 @@
 #endif /* SIZEOF_PID_T */
 
 /* Used by Python/mystrtoul.c. */
+#ifndef Py_LIMITED_API
 PyAPI_DATA(unsigned char) _PyLong_DigitValue[256];
+#endif
 
 /* _PyLong_Frexp returns a double x and an exponent e such that the
    true value is approximately equal to x * 2**e.  e is >= 0.  x is
@@ -58,7 +60,9 @@
    zeroes); otherwise, 0.5 <= abs(x) < 1.0.  On overflow, which is
    possible if the number of bits doesn't fit into a Py_ssize_t, sets
    OverflowError and returns -1.0 for x, 0 for e. */
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(double) _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e);
+#endif
 
 PyAPI_FUNC(double) PyLong_AsDouble(PyObject *);
 PyAPI_FUNC(PyObject *) PyLong_FromVoidPtr(void *);
@@ -74,8 +78,11 @@
 #endif /* HAVE_LONG_LONG */
 
 PyAPI_FUNC(PyObject *) PyLong_FromString(char *, char **, int);
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject *) PyLong_FromUnicode(Py_UNICODE*, Py_ssize_t, int);
+#endif
 
+#ifndef Py_LIMITED_API
 /* _PyLong_Sign.  Return 0 if v is 0, -1 if v < 0, +1 if v > 0.
    v must not be NULL, and must be a normalized long.
    There are no error cases.
@@ -150,6 +157,7 @@
 PyAPI_FUNC(PyObject *) _PyLong_FormatAdvanced(PyObject *obj,
 					      Py_UNICODE *format_spec,
 					      Py_ssize_t format_spec_len);
+#endif /* Py_LIMITED_API */
 
 /* These aren't really part of the long object, but they're handy. The
    functions are in Python/mystrtoul.c.
diff --git a/Include/marshal.h b/Include/marshal.h
index 411fdca..e96d062 100644
--- a/Include/marshal.h
+++ b/Include/marshal.h
@@ -13,10 +13,12 @@
 PyAPI_FUNC(void) PyMarshal_WriteObjectToFile(PyObject *, FILE *, int);
 PyAPI_FUNC(PyObject *) PyMarshal_WriteObjectToString(PyObject *, int);
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(long) PyMarshal_ReadLongFromFile(FILE *);
 PyAPI_FUNC(int) PyMarshal_ReadShortFromFile(FILE *);
 PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromFile(FILE *);
 PyAPI_FUNC(PyObject *) PyMarshal_ReadLastObjectFromFile(FILE *);
+#endif
 PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(char *, Py_ssize_t);
 
 #ifdef __cplusplus
diff --git a/Include/memoryobject.h b/Include/memoryobject.h
index 5bbfb05..f763531 100644
--- a/Include/memoryobject.h
+++ b/Include/memoryobject.h
@@ -10,10 +10,12 @@
 
 #define PyMemoryView_Check(op) (Py_TYPE(op) == &PyMemoryView_Type)
 
+#ifndef Py_LIMITED_API
 /* Get a pointer to the underlying Py_buffer of a memoryview object. */
 #define PyMemoryView_GET_BUFFER(op) (&((PyMemoryViewObject *)(op))->view)
 /* Get a pointer to the PyObject from which originates a memoryview object. */
 #define PyMemoryView_GET_BASE(op) (((PyMemoryViewObject *)(op))->view.obj)
+#endif
 
 
 PyAPI_FUNC(PyObject *) PyMemoryView_GetContiguous(PyObject *base, 
@@ -61,11 +63,12 @@
 /* The struct is declared here so that macros can work, but it shouldn't
    be considered public. Don't access those fields directly, use the macros
    and functions instead! */
+#ifndef Py_LIMITED_API
 typedef struct {
     PyObject_HEAD
     Py_buffer view;
 } PyMemoryViewObject;
-
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/Include/methodobject.h b/Include/methodobject.h
index 81e84ce..7e67c0b 100644
--- a/Include/methodobject.h
+++ b/Include/methodobject.h
@@ -26,12 +26,14 @@
 
 /* Macros for direct access to these values. Type checks are *not*
    done, so use with care. */
+#ifndef Py_LIMITED_API
 #define PyCFunction_GET_FUNCTION(func) \
         (((PyCFunctionObject *)func) -> m_ml -> ml_meth)
 #define PyCFunction_GET_SELF(func) \
 	(((PyCFunctionObject *)func) -> m_self)
 #define PyCFunction_GET_FLAGS(func) \
 	(((PyCFunctionObject *)func) -> m_ml -> ml_flags)
+#endif
 PyAPI_FUNC(PyObject *) PyCFunction_Call(PyObject *, PyObject *, PyObject *);
 
 struct PyMethodDef {
@@ -68,12 +70,14 @@
 
 #define METH_COEXIST   0x0040
 
+#ifndef Py_LIMITED_API
 typedef struct {
     PyObject_HEAD
     PyMethodDef *m_ml; /* Description of the C function to call */
     PyObject    *m_self; /* Passed as 'self' arg to the C func, can be NULL */
     PyObject    *m_module; /* The __module__ attribute, can be anything */
 } PyCFunctionObject;
+#endif
 
 PyAPI_FUNC(int) PyCFunction_ClearFreeList(void);
 
diff --git a/Include/modsupport.h b/Include/modsupport.h
index 57886df..bf6478f 100644
--- a/Include/modsupport.h
+++ b/Include/modsupport.h
@@ -31,7 +31,9 @@
 PyAPI_FUNC(int) PyArg_UnpackTuple(PyObject *, const char *, Py_ssize_t, Py_ssize_t, ...);
 PyAPI_FUNC(PyObject *) Py_BuildValue(const char *, ...);
 PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...);
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(int) _PyArg_NoKeywords(const char *funcname, PyObject *kw);
+#endif
 
 PyAPI_FUNC(int) PyArg_VaParse(PyObject *, const char *, va_list);
 PyAPI_FUNC(int) PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,
@@ -92,6 +94,12 @@
    9-Jan-1995	GvR	Initial version (incompatible with older API)
 */
 
+/* The PYTHON_ABI_VERSION is introduced in PEP 384. For the lifetime of
+   Python 3, it will stay at the value of 3; changes to the limited API
+   must be performed in a strictly backwards-compatible manner. */
+#define PYTHON_ABI_VERSION 3
+#define PYTHON_ABI_STRING "3"
+
 #ifdef Py_TRACE_REFS
  /* When we are tracing reference counts, rename PyModule_Create2 so
     modules compiled with incompatible settings will generate a
@@ -102,10 +110,17 @@
 PyAPI_FUNC(PyObject *) PyModule_Create2(struct PyModuleDef*,
                                      int apiver);
 
+#ifdef Py_LIMITED_API
+#define PyModule_Create(module) \
+	PyModule_Create2(module, PYTHON_ABI_VERSION)
+#else
 #define PyModule_Create(module) \
 	PyModule_Create2(module, PYTHON_API_VERSION)
+#endif
 
+#ifndef Py_LIMITED_API
 PyAPI_DATA(char *) _Py_PackageContext;
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/Include/moduleobject.h b/Include/moduleobject.h
index 34fa810..338cf4b 100644
--- a/Include/moduleobject.h
+++ b/Include/moduleobject.h
@@ -17,7 +17,9 @@
 PyAPI_FUNC(const char *) PyModule_GetName(PyObject *);
 PyAPI_FUNC(const char *) PyModule_GetFilename(PyObject *);
 PyAPI_FUNC(PyObject *) PyModule_GetFilenameObject(PyObject *);
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(void) _PyModule_Clear(PyObject *);
+#endif
 PyAPI_FUNC(struct PyModuleDef*) PyModule_GetDef(PyObject*);
 PyAPI_FUNC(void*) PyModule_GetState(PyObject*);
 
diff --git a/Include/object.h b/Include/object.h
index bc528fd..78bb13b 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -61,6 +61,10 @@
 #define Py_REF_DEBUG
 #endif
 
+#if defined(Py_LIMITED_API) && defined(Py_REF_DEBUG)
+#error Py_LIMITED_API is incompatible with Py_DEBUG, Py_TRACE_REFS, and Py_REF_DEBUG
+#endif
+
 #ifdef Py_TRACE_REFS
 /* Define pointers to support a doubly-linked list of all live heap objects. */
 #define _PyObject_HEAD_EXTRA            \
@@ -196,6 +200,7 @@
 typedef int (*visitproc)(PyObject *, void *);
 typedef int (*traverseproc)(PyObject *, visitproc, void *);
 
+#ifndef Py_LIMITED_API
 typedef struct {
     /* Number implementations must check *both*
        arguments for proper type and implement the necessary conversions
@@ -265,10 +270,17 @@
      getbufferproc bf_getbuffer;
      releasebufferproc bf_releasebuffer;
 } PyBufferProcs;
+#endif /* Py_LIMITED_API */
 
 typedef void (*freefunc)(void *);
 typedef void (*destructor)(PyObject *);
+#ifndef Py_LIMITED_API
+/* We can't provide a full compile-time check that limited-API
+   users won't implement tp_print. However, not defining printfunc
+   and making tp_print of a different function pointer type
+   should at least cause a warning in most cases. */
 typedef int (*printfunc)(PyObject *, FILE *, int);
+#endif
 typedef PyObject *(*getattrfunc)(PyObject *, char *);
 typedef PyObject *(*getattrofunc)(PyObject *, PyObject *);
 typedef int (*setattrfunc)(PyObject *, char *, PyObject *);
@@ -284,6 +296,9 @@
 typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *);
 typedef PyObject *(*allocfunc)(struct _typeobject *, Py_ssize_t);
 
+#ifdef Py_LIMITED_API
+typedef struct _typeobject PyTypeObject; /* opaque */
+#else
 typedef struct _typeobject {
     PyObject_VAR_HEAD
     const char *tp_name; /* For printing, in format "<module>.<name>" */
@@ -371,8 +386,25 @@
     struct _typeobject *tp_next;
 #endif
 } PyTypeObject;
+#endif
 
+typedef struct{
+    int slot;    /* slot id, see below */
+    void *pfunc; /* function pointer */
+} PyType_Slot;
 
+typedef struct{
+    const char* name;
+    const char* doc;
+    int basicsize;
+    int itemsize;
+    int flags;
+    PyType_Slot *slots; /* terminated by slot==0. */
+} PyType_Spec;
+
+PyAPI_FUNC(PyObject*) PyType_FromSpec(PyType_Spec*);
+
+#ifndef Py_LIMITED_API
 /* The *real* layout of a type object when allocated on the heap */
 typedef struct _heaptypeobject {
     /* Note: there's a dependency on the order of these members
@@ -393,7 +425,7 @@
 /* access macro to the members which are floating "behind" the object */
 #define PyHeapType_GET_MEMBERS(etype) \
     ((PyMemberDef *)(((char *)etype) + Py_TYPE(etype)->tp_basicsize))
-
+#endif
 
 /* Generic type check */
 PyAPI_FUNC(int) PyType_IsSubtype(PyTypeObject *, PyTypeObject *);
@@ -412,15 +444,19 @@
 PyAPI_FUNC(PyObject *) PyType_GenericAlloc(PyTypeObject *, Py_ssize_t);
 PyAPI_FUNC(PyObject *) PyType_GenericNew(PyTypeObject *,
                                                PyObject *, PyObject *);
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *);
 PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, char *, PyObject **);
+#endif
 PyAPI_FUNC(unsigned int) PyType_ClearCache(void);
 PyAPI_FUNC(void) PyType_Modified(PyTypeObject *);
 
 /* Generic operations on objects */
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int);
 PyAPI_FUNC(void) _Py_BreakPoint(void);
 PyAPI_FUNC(void) _PyObject_Dump(PyObject *);
+#endif
 PyAPI_FUNC(PyObject *) PyObject_Repr(PyObject *);
 PyAPI_FUNC(PyObject *) PyObject_Str(PyObject *);
 PyAPI_FUNC(PyObject *) PyObject_ASCII(PyObject *);
@@ -433,9 +469,13 @@
 PyAPI_FUNC(PyObject *) PyObject_GetAttr(PyObject *, PyObject *);
 PyAPI_FUNC(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *);
 PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *);
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *);
+#endif
 PyAPI_FUNC(PyObject *) PyObject_SelfIter(PyObject *);
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject *) _PyObject_NextNotImplemented(PyObject *);
+#endif
 PyAPI_FUNC(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *);
 PyAPI_FUNC(int) PyObject_GenericSetAttr(PyObject *,
                                               PyObject *, PyObject *);
@@ -469,8 +509,10 @@
 PyAPI_FUNC(void) Py_ReprLeave(PyObject *);
 
 /* Helpers for hash functions */
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(Py_hash_t) _Py_HashDouble(double);
 PyAPI_FUNC(Py_hash_t) _Py_HashPointer(void*);
+#endif
 
 /* Helper for passing objects to printf and the like */
 #define PyObject_REPR(obj) _PyUnicode_AsString(PyObject_Repr(obj))
@@ -649,9 +691,13 @@
 
 #define _Py_ForgetReference(op) _Py_INC_TPFREES(op)
 
+#ifdef Py_LIMITED_API
+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)))
+#endif
 #endif /* !Py_TRACE_REFS */
 
 #define Py_INCREF(op) (                         \
diff --git a/Include/objimpl.h b/Include/objimpl.h
index 2980031..3fef376 100644
--- a/Include/objimpl.h
+++ b/Include/objimpl.h
@@ -246,6 +246,7 @@
 #define _PyObject_GC_Del PyObject_GC_Del
 
 /* GC information is stored BEFORE the object structure. */
+#ifndef Py_LIMITED_API
 typedef union _gc_head {
     struct {
         union _gc_head *gc_next;
@@ -298,7 +299,7 @@
 #define _PyObject_GC_MAY_BE_TRACKED(obj) \
     (PyObject_IS_GC(obj) && \
         (!PyTuple_CheckExact(obj) || _PyObject_GC_IS_TRACKED(obj)))
-
+#endif /* Py_LIMITED_API */
 
 PyAPI_FUNC(PyObject *) _PyObject_GC_Malloc(size_t);
 PyAPI_FUNC(PyObject *) _PyObject_GC_New(PyTypeObject *);
diff --git a/Include/parsetok.h b/Include/parsetok.h
index af80570..d183784 100644
--- a/Include/parsetok.h
+++ b/Include/parsetok.h
@@ -1,6 +1,6 @@
 
 /* Parser-tokenizer link interface */
-
+#ifndef Py_LIMITED_API
 #ifndef Py_PARSETOK_H
 #define Py_PARSETOK_H
 #ifdef __cplusplus
@@ -64,3 +64,4 @@
 }
 #endif
 #endif /* !Py_PARSETOK_H */
+#endif /* !Py_LIMITED_API */
diff --git a/Include/pyarena.h b/Include/pyarena.h
index 5f193fe..db3ad01 100644
--- a/Include/pyarena.h
+++ b/Include/pyarena.h
@@ -1,6 +1,7 @@
 /* An arena-like memory interface for the compiler.
  */
 
+#ifndef Py_LIMITED_API
 #ifndef Py_PYARENA_H
 #define Py_PYARENA_H
 
@@ -60,3 +61,4 @@
 #endif
 
 #endif /* !Py_PYARENA_H */
+#endif /* Py_LIMITED_API */
diff --git a/Include/pyatomic.h b/Include/pyatomic.h
index 7d3449d..b0028fd 100644
--- a/Include/pyatomic.h
+++ b/Include/pyatomic.h
@@ -1,3 +1,4 @@
+#ifndef Py_LIMITED_API
 #ifndef Py_ATOMIC_H
 #define Py_ATOMIC_H
 /* XXX: When compilers start offering a stdatomic.h with lock-free
@@ -177,3 +178,4 @@
 #endif
 
 #endif  /* Py_ATOMIC_H */
+#endif  /* Py_LIMITED_API */
diff --git a/Include/pyctype.h b/Include/pyctype.h
index c5cc614..787c1b9 100644
--- a/Include/pyctype.h
+++ b/Include/pyctype.h
@@ -1,3 +1,4 @@
+#ifndef Py_LIMITED_API
 #ifndef PYCTYPE_H
 #define PYCTYPE_H
 
@@ -29,3 +30,4 @@
 #define Py_TOUPPER(c) (_Py_ctype_toupper[Py_CHARMASK(c)])
 
 #endif /* !PYCTYPE_H */
+#endif /* !Py_LIMITED_API */
diff --git a/Include/pydebug.h b/Include/pydebug.h
index 0a31f5b..1cbb342 100644
--- a/Include/pydebug.h
+++ b/Include/pydebug.h
@@ -1,4 +1,4 @@
-
+#ifndef Py_LIMITED_API
 #ifndef Py_PYDEBUG_H
 #define Py_PYDEBUG_H
 #ifdef __cplusplus
@@ -31,3 +31,4 @@
 }
 #endif
 #endif /* !Py_PYDEBUG_H */
+#endif /* Py_LIMITED_API */
diff --git a/Include/pyerrors.h b/Include/pyerrors.h
index f717afa..d72ce07 100644
--- a/Include/pyerrors.h
+++ b/Include/pyerrors.h
@@ -6,6 +6,7 @@
 
 /* Error objects */
 
+#ifndef Py_LIMITED_API
 /* PyException_HEAD defines the initial segment of every exception class. */
 #define PyException_HEAD PyObject_HEAD PyObject *dict;\
              PyObject *args; PyObject *traceback;\
@@ -55,6 +56,7 @@
     PyObject *winerror;
 } PyWindowsErrorObject;
 #endif
+#endif
 
 /* Error handling definitions */
 
@@ -68,8 +70,9 @@
 PyAPI_FUNC(void) PyErr_Clear(void);
 PyAPI_FUNC(void) PyErr_Fetch(PyObject **, PyObject **, PyObject **);
 PyAPI_FUNC(void) PyErr_Restore(PyObject *, PyObject *, PyObject *);
+PyAPI_FUNC(void) Py_FatalError(const char *message);
 
-#ifdef Py_DEBUG
+#if defined(Py_DEBUG) || defined(Py_LIMITED_API)
 #define _PyErr_OCCURRED() PyErr_Occurred()
 #else
 #define _PyErr_OCCURRED() (_PyThreadState_Current->curexc_type)
@@ -183,7 +186,7 @@
     PyObject *exc,
     const char *filename   /* decoded from the filesystem encoding */
     );
-#ifdef MS_WINDOWS
+#if defined(MS_WINDOWS) && !defined(Py_LIMITED_API)
 PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithUnicodeFilename(
     PyObject *, const Py_UNICODE *);
 #endif /* MS_WINDOWS */
@@ -199,15 +202,20 @@
     int, const char *);
 PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithFilename(
     int, const char *);
+#ifndef Py_LIMITED_API
+/* XXX redeclare to use WSTRING */
 PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithUnicodeFilename(
     int, const Py_UNICODE *);
+#endif
 PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErr(int);
 PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilenameObject(
     PyObject *,int, PyObject *);
 PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilename(
     PyObject *,int, const char *);
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithUnicodeFilename(
     PyObject *,int, const Py_UNICODE *);
+#endif
 PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErr(PyObject *, int);
 #endif /* MS_WINDOWS */
 
@@ -230,7 +238,9 @@
 PyAPI_FUNC(void) PyErr_SetInterrupt(void);
 
 /* In signalmodule.c */
+#ifndef Py_LIMITED_API
 int PySignal_SetWakeupFd(int fd);
+#endif
 
 /* Support for adding program text to SyntaxErrors */
 PyAPI_FUNC(void) PyErr_SyntaxLocation(const char *, int);
@@ -245,12 +255,16 @@
     const char *, const char *, Py_ssize_t, Py_ssize_t, Py_ssize_t, const char *);
 
 /* create a UnicodeEncodeError object */
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_Create(
     const char *, const Py_UNICODE *, Py_ssize_t, Py_ssize_t, Py_ssize_t, const char *);
+#endif
 
 /* create a UnicodeTranslateError object */
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_Create(
     const Py_UNICODE *, Py_ssize_t, Py_ssize_t, Py_ssize_t, const char *);
+#endif
 
 /* get the encoding attribute */
 PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_GetEncoding(PyObject *);
diff --git a/Include/pygetopt.h b/Include/pygetopt.h
index 19e3fd1..4de8c00 100644
--- a/Include/pygetopt.h
+++ b/Include/pygetopt.h
@@ -5,9 +5,11 @@
 extern "C" {
 #endif
 
+#ifndef Py_LIMITED_API
 PyAPI_DATA(int) _PyOS_opterr;
 PyAPI_DATA(int) _PyOS_optind;
 PyAPI_DATA(wchar_t *) _PyOS_optarg;
+#endif
 
 PyAPI_FUNC(int) _PyOS_GetOpt(int argc, wchar_t **argv, wchar_t *optstring);
 
diff --git a/Include/pymath.h b/Include/pymath.h
index e3cf22b..b4eda66 100644
--- a/Include/pymath.h
+++ b/Include/pymath.h
@@ -67,6 +67,7 @@
    nothing. */
 
 /* we take double rounding as evidence of x87 usage */
+#ifndef Py_LIMITED_API
 #ifndef Py_FORCE_DOUBLE
 #  ifdef X87_DOUBLE_ROUNDING
 PyAPI_FUNC(double) _Py_force_double(double);
@@ -75,11 +76,14 @@
 #    define Py_FORCE_DOUBLE(X) (X)
 #  endif
 #endif
+#endif
 
+#ifndef Py_LIMITED_API
 #ifdef HAVE_GCC_ASM_FOR_X87
 PyAPI_FUNC(unsigned short) _Py_get_387controlword(void);
 PyAPI_FUNC(void) _Py_set_387controlword(unsigned short);
 #endif
+#endif
 
 /* Py_IS_NAN(X)
  * Return 1 if float or double arg is a NaN, else 0.
diff --git a/Include/pystate.h b/Include/pystate.h
index 7b6b602..50245c2 100644
--- a/Include/pystate.h
+++ b/Include/pystate.h
@@ -13,6 +13,9 @@
 struct _ts; /* Forward */
 struct _is; /* Forward */
 
+#ifdef Py_LIMITED_API
+typedef struct _is PyInterpreterState;
+#else
 typedef struct _is {
 
     struct _is *next;
@@ -37,12 +40,14 @@
 #endif
 
 } PyInterpreterState;
+#endif
 
 
 /* State unique per thread */
 
 struct _frame; /* Avoid including frameobject.h */
 
+#ifndef Py_LIMITED_API
 /* Py_tracefunc return -1 when raising an exception, or 0 for success. */
 typedef int (*Py_tracefunc)(PyObject *, struct _frame *, int, PyObject *);
 
@@ -54,7 +59,11 @@
 #define PyTrace_C_CALL 4
 #define PyTrace_C_EXCEPTION 5
 #define PyTrace_C_RETURN 6
+#endif
 
+#ifdef Py_LIMITED_API
+typedef struct _ts PyThreadState;
+#else
 typedef struct _ts {
     /* See Python/ceval.c for comments explaining most fields */
 
@@ -106,6 +115,7 @@
     /* XXX signal handlers should also be here */
 
 } PyThreadState;
+#endif
 
 
 PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_New(void);
@@ -133,9 +143,11 @@
 
 /* Assuming the current thread holds the GIL, this is the
    PyThreadState for the current thread. */
+#ifndef Py_LIMITED_API
 PyAPI_DATA(_Py_atomic_address) _PyThreadState_Current;
+#endif
 
-#ifdef Py_DEBUG
+#if defined(Py_DEBUG) || defined(Py_LIMITED_API)
 #define PyThreadState_GET() PyThreadState_Get()
 #else
 #define PyThreadState_GET() \
@@ -190,19 +202,25 @@
 /* The implementation of sys._current_frames()  Returns a dict mapping
    thread id to that thread's current frame.
 */
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject *) _PyThread_CurrentFrames(void);
+#endif
 
 /* Routines for advanced debuggers, requested by David Beazley.
    Don't use unless you know what you are doing! */
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Head(void);
 PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Next(PyInterpreterState *);
 PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(PyInterpreterState *);
 PyAPI_FUNC(PyThreadState *) PyThreadState_Next(PyThreadState *);
 
 typedef struct _frame *(*PyThreadFrameGetter)(PyThreadState *self_);
+#endif
 
 /* hook for PyEval_GetFrame(), requested for Psyco */
+#ifndef Py_LIMITED_API
 PyAPI_DATA(PyThreadFrameGetter) _PyThreadState_GetFrame;
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/Include/pystrtod.h b/Include/pystrtod.h
index d7bae12..23fd1c6 100644
--- a/Include/pystrtod.h
+++ b/Include/pystrtod.h
@@ -18,7 +18,9 @@
                                          int flags,
                                          int *type);
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(double) _Py_parse_inf_or_nan(const char *p, char **endptr);
+#endif
 
 
 /* PyOS_double_to_string's "flags" parameter can be set to 0 or more of: */
diff --git a/Include/pythonrun.h b/Include/pythonrun.h
index 108b647..95bdf9e 100644
--- a/Include/pythonrun.h
+++ b/Include/pythonrun.h
@@ -16,9 +16,11 @@
 #define PyCF_ONLY_AST 0x0400
 #define PyCF_IGNORE_COOKIE 0x0800
 
+#ifndef Py_LIMITED_API
 typedef struct {
     int cf_flags;  /* bitmask of CO_xxx flags relevant to future */
 } PyCompilerFlags;
+#endif
 
 PyAPI_FUNC(void) Py_SetProgramName(wchar_t *);
 PyAPI_FUNC(wchar_t *) Py_GetProgramName(void);
@@ -33,9 +35,10 @@
 PyAPI_FUNC(PyThreadState *) Py_NewInterpreter(void);
 PyAPI_FUNC(void) Py_EndInterpreter(PyThreadState *);
 
+#ifndef Py_LIMITED_API
+PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *);
 PyAPI_FUNC(int) PyRun_AnyFileFlags(FILE *, const char *, PyCompilerFlags *);
 PyAPI_FUNC(int) PyRun_AnyFileExFlags(FILE *, const char *, int, PyCompilerFlags *);
-PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *);
 PyAPI_FUNC(int) PyRun_SimpleFileExFlags(FILE *, const char *, int, PyCompilerFlags *);
 PyAPI_FUNC(int) PyRun_InteractiveOneFlags(FILE *, const char *, PyCompilerFlags *);
 PyAPI_FUNC(int) PyRun_InteractiveLoopFlags(FILE *, const char *, PyCompilerFlags *);
@@ -48,25 +51,35 @@
                                                char *, char *,
                                                PyCompilerFlags *, int *,
                                                PyArena *);
+#endif
+
+#ifndef PyParser_SimpleParseString
 #define PyParser_SimpleParseString(S, B) \
     PyParser_SimpleParseStringFlags(S, B, 0)
 #define PyParser_SimpleParseFile(FP, S, B) \
     PyParser_SimpleParseFileFlags(FP, S, B, 0)
+#endif
 PyAPI_FUNC(struct _node *) PyParser_SimpleParseStringFlags(const char *, int,
                                                           int);
 PyAPI_FUNC(struct _node *) PyParser_SimpleParseFileFlags(FILE *, const char *,
                                                         int, int);
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject *) PyRun_StringFlags(const char *, int, PyObject *,
                                          PyObject *, PyCompilerFlags *);
 
 PyAPI_FUNC(PyObject *) PyRun_FileExFlags(FILE *, const char *, int,
                                          PyObject *, PyObject *, int,
                                          PyCompilerFlags *);
+#endif
 
+#ifdef Py_LIMITED_API
+PyAPI_FUNC(PyObject *) Py_CompileStringFlags(const char *, const char *, int);
+#else
 #define Py_CompileString(str, p, s) Py_CompileStringFlags(str, p, s, NULL)
 PyAPI_FUNC(PyObject *) Py_CompileStringFlags(const char *, const char *, int,
                                              PyCompilerFlags *);
+#endif
 PyAPI_FUNC(struct symtable *) Py_SymtableString(const char *, const char *, int);
 
 PyAPI_FUNC(void) PyErr_Print(void);
@@ -76,19 +89,24 @@
 /* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level
  * exit functions.
  */
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(void) _Py_PyAtExit(void (*func)(void));
+#endif
 PyAPI_FUNC(int) Py_AtExit(void (*func)(void));
 
 PyAPI_FUNC(void) Py_Exit(int);
 
 /* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. */
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(void) _Py_RestoreSignals(void);
 
 PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *);
+#endif
 
 /* Bootstrap */
 PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv);
 
+#ifndef Py_LIMITED_API
 /* Use macros for a bunch of old variants */
 #define PyRun_String(str, s, g, l) PyRun_StringFlags(str, s, g, l, NULL)
 #define PyRun_AnyFile(fp, name) PyRun_AnyFileExFlags(fp, name, 0, NULL)
@@ -107,6 +125,7 @@
     PyRun_FileExFlags(fp, p, s, g, l, c, NULL)
 #define PyRun_FileFlags(fp, p, s, g, l, flags) \
     PyRun_FileExFlags(fp, p, s, g, l, 0, flags)
+#endif
 
 /* In getpath.c */
 PyAPI_FUNC(wchar_t *) Py_GetProgramFullPath(void);
@@ -114,6 +133,9 @@
 PyAPI_FUNC(wchar_t *) Py_GetExecPrefix(void);
 PyAPI_FUNC(wchar_t *) Py_GetPath(void);
 PyAPI_FUNC(void)      Py_SetPath(const wchar_t *);
+#ifdef MS_WINDOWS
+int _Py_CheckPython3();
+#endif
 
 /* In their own files */
 PyAPI_FUNC(const char *) Py_GetVersion(void);
@@ -121,11 +143,14 @@
 PyAPI_FUNC(const char *) Py_GetCopyright(void);
 PyAPI_FUNC(const char *) Py_GetCompiler(void);
 PyAPI_FUNC(const char *) Py_GetBuildInfo(void);
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(const char *) _Py_svnversion(void);
 PyAPI_FUNC(const char *) Py_SubversionRevision(void);
 PyAPI_FUNC(const char *) Py_SubversionShortBranch(void);
+#endif
 
 /* Internal -- various one-time initializations */
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject *) _PyBuiltin_Init(void);
 PyAPI_FUNC(PyObject *) _PySys_Init(void);
 PyAPI_FUNC(void) _PyImport_Init(void);
@@ -134,8 +159,10 @@
 PyAPI_FUNC(int) _PyFrame_Init(void);
 PyAPI_FUNC(void) _PyFloat_Init(void);
 PyAPI_FUNC(int) PyByteArray_Init(void);
+#endif
 
 /* Various internal finalizers */
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(void) _PyExc_Fini(void);
 PyAPI_FUNC(void) _PyImport_Fini(void);
 PyAPI_FUNC(void) PyMethod_Fini(void);
@@ -150,12 +177,17 @@
 PyAPI_FUNC(void) PyFloat_Fini(void);
 PyAPI_FUNC(void) PyOS_FiniInterrupts(void);
 PyAPI_FUNC(void) _PyGC_Fini(void);
+#endif
 
 /* Stuff with no proper home (yet) */
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(char *) PyOS_Readline(FILE *, FILE *, char *);
+#endif
 PyAPI_DATA(int) (*PyOS_InputHook)(void);
 PyAPI_DATA(char) *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, char *);
+#ifndef Py_LIMITED_API
 PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState;
+#endif
 
 /* Stack size, in "pointers" (so we get extra safety margins
    on 64-bit platforms).  On a 32-bit platform, this translates
diff --git a/Include/pytime.h b/Include/pytime.h
index 964d096..d707bdb 100644
--- a/Include/pytime.h
+++ b/Include/pytime.h
@@ -1,3 +1,4 @@
+#ifndef Py_LIMITED_API
 #ifndef Py_PYTIME_H
 #define Py_PYTIME_H
 
@@ -44,3 +45,4 @@
 #endif
 
 #endif /* Py_PYTIME_H */
+#endif /* Py_LIMITED_API */
diff --git a/Include/setobject.h b/Include/setobject.h
index 023c5fa..6234111 100644
--- a/Include/setobject.h
+++ b/Include/setobject.h
@@ -18,7 +18,7 @@
 hold a search finger.  The hash field of Unused or Dummy slots has
 no meaning otherwise.
 */
-
+#ifndef Py_LIMITED_API
 #define PySet_MINSIZE 8
 
 typedef struct {
@@ -56,6 +56,7 @@
     Py_hash_t hash;                  /* only used by frozenset objects */
     PyObject *weakreflist;      /* List of weak references */
 };
+#endif /* Py_LIMITED_API */
 
 PyAPI_DATA(PyTypeObject) PySet_Type;
 PyAPI_DATA(PyTypeObject) PyFrozenSet_Type;
@@ -85,14 +86,20 @@
 PyAPI_FUNC(PyObject *) PySet_New(PyObject *);
 PyAPI_FUNC(PyObject *) PyFrozenSet_New(PyObject *);
 PyAPI_FUNC(Py_ssize_t) PySet_Size(PyObject *anyset);
+#ifndef Py_LIMITED_API
 #define PySet_GET_SIZE(so) (((PySetObject *)(so))->used)
+#endif
 PyAPI_FUNC(int) PySet_Clear(PyObject *set);
 PyAPI_FUNC(int) PySet_Contains(PyObject *anyset, PyObject *key);
 PyAPI_FUNC(int) PySet_Discard(PyObject *set, PyObject *key);
 PyAPI_FUNC(int) PySet_Add(PyObject *set, PyObject *key);
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash);
+#endif
 PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set);
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable);
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/Include/sliceobject.h b/Include/sliceobject.h
index 8ab62dd..8bec179 100644
--- a/Include/sliceobject.h
+++ b/Include/sliceobject.h
@@ -18,11 +18,12 @@
 names are from range).  After much talk with Guido, it was decided to
 let these be any arbitrary python type.  Py_None stands for omitted values.
 */
-
+#ifndef Py_LIMITED_API
 typedef struct {
     PyObject_HEAD
     PyObject *start, *stop, *step;	/* not NULL */
 } PySliceObject;
+#endif
 
 PyAPI_DATA(PyTypeObject) PySlice_Type;
 PyAPI_DATA(PyTypeObject) PyEllipsis_Type;
@@ -31,10 +32,12 @@
 
 PyAPI_FUNC(PyObject *) PySlice_New(PyObject* start, PyObject* stop,
                                   PyObject* step);
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject *) _PySlice_FromIndices(Py_ssize_t start, Py_ssize_t stop);
-PyAPI_FUNC(int) PySlice_GetIndices(PySliceObject *r, Py_ssize_t length,
+#endif
+PyAPI_FUNC(int) PySlice_GetIndices(PyObject *r, Py_ssize_t length,
                                   Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step);
-PyAPI_FUNC(int) PySlice_GetIndicesEx(PySliceObject *r, Py_ssize_t length,
+PyAPI_FUNC(int) PySlice_GetIndicesEx(PyObject *r, Py_ssize_t length,
 				    Py_ssize_t *start, Py_ssize_t *stop, 
 				    Py_ssize_t *step, Py_ssize_t *slicelength);
 
diff --git a/Include/structseq.h b/Include/structseq.h
index a5d7b2e..30c52ac 100644
--- a/Include/structseq.h
+++ b/Include/structseq.h
@@ -21,18 +21,25 @@
 
 extern char* PyStructSequence_UnnamedField;
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(void) PyStructSequence_InitType(PyTypeObject *type,
                                            PyStructSequence_Desc *desc);
+#endif
+PyAPI_FUNC(PyTypeObject*) PyStructSequence_NewType(PyStructSequence_Desc *desc);
 
 PyAPI_FUNC(PyObject *) PyStructSequence_New(PyTypeObject* type);
 
+#ifndef Py_LIMITED_API
 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_GET_ITEM(op, i) PyTuple_GET_ITEM(op, i)
+#endif
 
+PyAPI_FUNC(void) PyStructSequence_SetItem(PyObject*, Py_ssize_t, PyObject*);
+PyAPI_FUNC(PyObject*) PyStructSequence_GetItem(PyObject*, Py_ssize_t);
 
 #ifdef __cplusplus
 }
diff --git a/Include/symtable.h b/Include/symtable.h
index 9b1b75b..2ad204d 100644
--- a/Include/symtable.h
+++ b/Include/symtable.h
@@ -1,3 +1,4 @@
+#ifndef Py_LIMITED_API
 #ifndef Py_SYMTABLE_H
 #define Py_SYMTABLE_H
 
@@ -102,3 +103,4 @@
 }
 #endif
 #endif /* !Py_SYMTABLE_H */
+#endif /* Py_LIMITED_API */
diff --git a/Include/sysmodule.h b/Include/sysmodule.h
index c00901b..010e6e0 100644
--- a/Include/sysmodule.h
+++ b/Include/sysmodule.h
@@ -20,7 +20,9 @@
 PyAPI_FUNC(void) PySys_FormatStdout(const char *format, ...);
 PyAPI_FUNC(void) PySys_FormatStderr(const char *format, ...);
 
+#ifndef Py_LIMITED_API
 PyAPI_DATA(PyObject *) _PySys_TraceFunc, *_PySys_ProfileFunc;
+#endif
 
 PyAPI_FUNC(void) PySys_ResetWarnOptions(void);
 PyAPI_FUNC(void) PySys_AddWarnOption(const wchar_t *);
diff --git a/Include/timefuncs.h b/Include/timefuncs.h
index 553142d..3c43575 100644
--- a/Include/timefuncs.h
+++ b/Include/timefuncs.h
@@ -14,7 +14,9 @@
  * to fit in a time_t.  ValueError is set on return iff the return
  * value is (time_t)-1 and PyErr_Occurred().
  */
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(time_t) _PyTime_DoubleToTimet(double x);
+#endif
 
 
 #ifdef __cplusplus
diff --git a/Include/token.h b/Include/token.h
index 9c19f5c..a462c64 100644
--- a/Include/token.h
+++ b/Include/token.h
@@ -1,6 +1,6 @@
 
 /* Token types */
-
+#ifndef Py_LIMITED_API
 #ifndef Py_TOKEN_H
 #define Py_TOKEN_H
 #ifdef __cplusplus
@@ -85,3 +85,4 @@
 }
 #endif
 #endif /* !Py_TOKEN_H */
+#endif /* Py_LIMITED_API */
diff --git a/Include/traceback.h b/Include/traceback.h
index fc0c586..69e3d05 100644
--- a/Include/traceback.h
+++ b/Include/traceback.h
@@ -8,7 +8,7 @@
 struct _frame;
 
 /* Traceback interface */
-
+#ifndef Py_LIMITED_API
 typedef struct _traceback {
     PyObject_HEAD
     struct _traceback *tb_next;
@@ -16,10 +16,13 @@
     int tb_lasti;
     int tb_lineno;
 } PyTracebackObject;
+#endif
 
 PyAPI_FUNC(int) PyTraceBack_Here(struct _frame *);
 PyAPI_FUNC(int) PyTraceBack_Print(PyObject *, PyObject *);
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int);
+#endif
 
 /* Reveal traceback type so we can typecheck traceback objects */
 PyAPI_DATA(PyTypeObject) PyTraceBack_Type;
diff --git a/Include/tupleobject.h b/Include/tupleobject.h
index 19fe7a5..f17b788 100644
--- a/Include/tupleobject.h
+++ b/Include/tupleobject.h
@@ -21,6 +21,7 @@
 returned item's reference count.
 */
 
+#ifndef Py_LIMITED_API
 typedef struct {
     PyObject_VAR_HEAD
     PyObject *ob_item[1];
@@ -30,6 +31,7 @@
      * the tuple is not yet visible outside the function that builds it.
      */
 } PyTupleObject;
+#endif
 
 PyAPI_DATA(PyTypeObject) PyTuple_Type;
 PyAPI_DATA(PyTypeObject) PyTupleIter_Type;
@@ -43,16 +45,22 @@
 PyAPI_FUNC(PyObject *) PyTuple_GetItem(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
 PyAPI_FUNC(int) _PyTuple_Resize(PyObject **, Py_ssize_t);
+#endif
 PyAPI_FUNC(PyObject *) PyTuple_Pack(Py_ssize_t, ...);
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *);
+#endif
 
 /* 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)    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)
+#endif
 
 PyAPI_FUNC(int) PyTuple_ClearFreeList(void);
 
diff --git a/Include/typeslots.h b/Include/typeslots.h
new file mode 100644
index 0000000..9ab9850
--- /dev/null
+++ b/Include/typeslots.h
@@ -0,0 +1,71 @@
+#define Py_bf_getbuffer 1
+#define Py_bf_releasebuffer 2
+#define Py_mp_ass_subscript 3
+#define Py_mp_length 4
+#define Py_mp_subscript 5
+#define Py_nb_absolute 6
+#define Py_nb_add 7
+#define Py_nb_and 8
+#define Py_nb_bool 9
+#define Py_nb_divmod 10
+#define Py_nb_float 11
+#define Py_nb_floor_divide 12
+#define Py_nb_index 13
+#define Py_nb_inplace_add 14
+#define Py_nb_inplace_and 15
+#define Py_nb_inplace_floor_divide 16
+#define Py_nb_inplace_lshift 17
+#define Py_nb_inplace_multiply 18
+#define Py_nb_inplace_or 19
+#define Py_nb_inplace_power 20
+#define Py_nb_inplace_remainder 21
+#define Py_nb_inplace_rshift 22
+#define Py_nb_inplace_subtract 23
+#define Py_nb_inplace_true_divide 24
+#define Py_nb_inplace_xor 25
+#define Py_nb_int 26
+#define Py_nb_invert 27
+#define Py_nb_lshift 28
+#define Py_nb_multiply 29
+#define Py_nb_negative 30
+#define Py_nb_or 31
+#define Py_nb_positive 32
+#define Py_nb_power 33
+#define Py_nb_remainder 34
+#define Py_nb_rshift 35
+#define Py_nb_subtract 36
+#define Py_nb_true_divide 37
+#define Py_nb_xor 38
+#define Py_sq_ass_item 39
+#define Py_sq_concat 40
+#define Py_sq_contains 41
+#define Py_sq_inplace_concat 42
+#define Py_sq_inplace_repeat 43
+#define Py_sq_item 44
+#define Py_sq_length 45
+#define Py_sq_repeat 46
+#define Py_tp_alloc 47
+#define Py_tp_base 48
+#define Py_tp_bases 49
+#define Py_tp_call 50
+#define Py_tp_clear 51
+#define Py_tp_dealloc 52
+#define Py_tp_del 53
+#define Py_tp_descr_get 54
+#define Py_tp_descr_set 55
+#define Py_tp_doc 56
+#define Py_tp_getattr 57
+#define Py_tp_getattro 58
+#define Py_tp_hash 59
+#define Py_tp_init 60
+#define Py_tp_is_gc 61
+#define Py_tp_iter 62
+#define Py_tp_iternext 63
+#define Py_tp_methods 64
+#define Py_tp_new 65
+#define Py_tp_repr 66
+#define Py_tp_richcompare 67
+#define Py_tp_setattr 68
+#define Py_tp_setattro 69
+#define Py_tp_str 70
+#define Py_tp_traverse 71
diff --git a/Include/ucnhash.h b/Include/ucnhash.h
index 69b7774..70fdf13 100644
--- a/Include/ucnhash.h
+++ b/Include/ucnhash.h
@@ -1,5 +1,5 @@
 /* Unicode name database interface */
-
+#ifndef Py_LIMITED_API
 #ifndef Py_UCNHASH_H
 #define Py_UCNHASH_H
 #ifdef __cplusplus
@@ -31,3 +31,4 @@
 }
 #endif
 #endif /* !Py_UCNHASH_H */
+#endif /* !Py_LIMITED_API */
diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h
index 2a20779..116bb82 100644
--- a/Include/unicodeobject.h
+++ b/Include/unicodeobject.h
@@ -131,7 +131,9 @@
    Python and represents a single Unicode element in the Unicode
    type. */
 
+#ifndef Py_LIMITED_API
 typedef PY_UNICODE_TYPE Py_UNICODE;
+#endif
 
 /* --- UCS-2/UCS-4 Name Mangling ------------------------------------------ */
 
@@ -318,6 +320,7 @@
    _Py_ascii_whitespace (see below) with an inlined check.
 
  */
+#ifndef Py_LIMITED_API
 #define Py_UNICODE_ISSPACE(ch) \
     ((ch) < 128U ? _Py_ascii_whitespace[(ch)] : _PyUnicode_IsWhitespace(ch))
 
@@ -362,6 +365,7 @@
     ((*((string)->str + (offset)) == *((substring)->str)) && \
     ((*((string)->str + (offset) + (substring)->length-1) == *((substring)->str + (substring)->length-1))) && \
      !memcmp((string)->str + (offset), (substring)->str, (substring)->length*sizeof(Py_UNICODE)))
+#endif /* Py_LIMITED_API */
 
 #ifdef __cplusplus
 extern "C" {
@@ -369,6 +373,7 @@
 
 /* --- Unicode Type ------------------------------------------------------- */
 
+#ifndef Py_LIMITED_API
 typedef struct {
     PyObject_HEAD
     Py_ssize_t length;          /* Length of raw Unicode data in buffer */
@@ -381,6 +386,7 @@
                                    string, or NULL; this is used for
                                    implementing the buffer protocol */
 } PyUnicodeObject;
+#endif
 
 PyAPI_DATA(PyTypeObject) PyUnicode_Type;
 PyAPI_DATA(PyTypeObject) PyUnicodeIter_Type;
@@ -394,6 +400,7 @@
 #define PyUnicode_CheckExact(op) (Py_TYPE(op) == &PyUnicode_Type)
 
 /* Fast access macros */
+#ifndef Py_LIMITED_API
 #define PyUnicode_GET_SIZE(op) \
     (assert(PyUnicode_Check(op)),(((PyUnicodeObject *)(op))->length))
 #define PyUnicode_GET_DATA_SIZE(op) \
@@ -402,6 +409,7 @@
     (assert(PyUnicode_Check(op)),(((PyUnicodeObject *)(op))->str))
 #define PyUnicode_AS_DATA(op) \
     (assert(PyUnicode_Check(op)),((const char *)((PyUnicodeObject *)(op))->str))
+#endif
 
 /* --- Constants ---------------------------------------------------------- */
 
@@ -426,10 +434,12 @@
 
    The buffer is copied into the new object. */
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject*) PyUnicode_FromUnicode(
     const Py_UNICODE *u,        /* Unicode buffer */
     Py_ssize_t size             /* size of buffer */
     );
+#endif
 
 /* Similar to PyUnicode_FromUnicode(), but u points to UTF-8 encoded bytes */
 PyAPI_FUNC(PyObject*) PyUnicode_FromStringAndSize(
@@ -446,9 +456,11 @@
 /* Return a read-only pointer to the Unicode object's internal
    Py_UNICODE buffer. */
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode(
     PyObject *unicode           /* Unicode object */
     );
+#endif
 
 /* Get the length of the Unicode object. */
 
@@ -456,8 +468,10 @@
     PyObject *unicode           /* Unicode object */
     );
 
+#ifndef Py_LIMITED_API
 /* Get the maximum ordinal for a Unicode character. */
 PyAPI_FUNC(Py_UNICODE) PyUnicode_GetMax(void);
+#endif
 
 /* Resize an already allocated Unicode object to the new size length.
 
@@ -527,16 +541,20 @@
     ...
     );
 
+#ifndef Py_LIMITED_API
 /* Format the object based on the format_spec, as defined in PEP 3101
    (Advanced String Formatting). */
 PyAPI_FUNC(PyObject *) _PyUnicode_FormatAdvanced(PyObject *obj,
                                                  Py_UNICODE *format_spec,
                                                  Py_ssize_t format_spec_len);
+#endif
 
 PyAPI_FUNC(void) PyUnicode_InternInPlace(PyObject **);
 PyAPI_FUNC(void) PyUnicode_InternImmortal(PyObject **);
 PyAPI_FUNC(PyObject *) PyUnicode_InternFromString(const char *);
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(void) _Py_ReleaseInternedUnicodeStrings(void);
+#endif
 
 /* Use only if you know it's a string */
 #define PyUnicode_CHECK_INTERNED(op) (((PyUnicodeObject *)(op))->state)
@@ -568,7 +586,7 @@
    error. */
 
 PyAPI_FUNC(Py_ssize_t) PyUnicode_AsWideChar(
-    PyUnicodeObject *unicode,   /* Unicode object */
+    PyObject *unicode,          /* Unicode object */
     register wchar_t *w,        /* wchar_t buffer */
     Py_ssize_t size             /* size of buffer */
     );
@@ -646,9 +664,11 @@
 
 */
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject *) _PyUnicode_AsDefaultEncodedString(
     PyObject *unicode,
     const char *errors);
+#endif
 
 /* Returns a pointer to the default encoding (UTF-8) of the
    Unicode object unicode and the size of the encoded representation
@@ -664,9 +684,11 @@
 
 */
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(char *) _PyUnicode_AsStringAndSize(
     PyObject *unicode,
     Py_ssize_t *size);
+#endif
 
 /* Returns a pointer to the default encoding (UTF-8) of the
    Unicode object unicode.
@@ -682,7 +704,9 @@
 
 */
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(char *) _PyUnicode_AsString(PyObject *unicode);
+#endif
 
 /* Returns "utf-8".  */
 
@@ -721,12 +745,14 @@
 /* Encodes a Py_UNICODE buffer of the given size and returns a
    Python string object. */
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject*) PyUnicode_Encode(
     const Py_UNICODE *s,        /* Unicode char buffer */
     Py_ssize_t size,            /* number of Py_UNICODE chars to encode */
     const char *encoding,       /* encoding */
     const char *errors          /* error handling */
     );
+#endif
 
 /* Encodes a Unicode object and returns the result as Python
    object. */
@@ -776,6 +802,7 @@
     Py_ssize_t *consumed        /* bytes consumed */
     );
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF7(
     const Py_UNICODE *data,     /* Unicode char buffer */
     Py_ssize_t length,          /* number of Py_UNICODE chars to encode */
@@ -783,6 +810,7 @@
     int base64WhiteSpace,       /* Encode whitespace (sp, ht, nl, cr) in base64 */
     const char *errors          /* error handling */
     );
+#endif
 
 /* --- UTF-8 Codecs ------------------------------------------------------- */
 
@@ -803,11 +831,13 @@
     PyObject *unicode           /* Unicode object */
     );
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF8(
     const Py_UNICODE *data,     /* Unicode char buffer */
     Py_ssize_t length,          /* number of Py_UNICODE chars to encode */
     const char *errors          /* error handling */
     );
+#endif
 
 /* --- UTF-32 Codecs ------------------------------------------------------ */
 
@@ -876,12 +906,14 @@
 
 */
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF32(
     const Py_UNICODE *data,     /* Unicode char buffer */
     Py_ssize_t length,          /* number of Py_UNICODE chars to encode */
     const char *errors,         /* error handling */
     int byteorder               /* byteorder to use 0=BOM+native;-1=LE,1=BE */
     );
+#endif
 
 /* --- UTF-16 Codecs ------------------------------------------------------ */
 
@@ -954,12 +986,14 @@
 
 */
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF16(
     const Py_UNICODE *data,     /* Unicode char buffer */
     Py_ssize_t length,          /* number of Py_UNICODE chars to encode */
     const char *errors,         /* error handling */
     int byteorder               /* byteorder to use 0=BOM+native;-1=LE,1=BE */
     );
+#endif
 
 /* --- Unicode-Escape Codecs ---------------------------------------------- */
 
@@ -973,10 +1007,12 @@
     PyObject *unicode           /* Unicode object */
     );
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject*) PyUnicode_EncodeUnicodeEscape(
     const Py_UNICODE *data,     /* Unicode char buffer */
     Py_ssize_t length           /* Number of Py_UNICODE chars to encode */
     );
+#endif
 
 /* --- Raw-Unicode-Escape Codecs ------------------------------------------ */
 
@@ -990,20 +1026,24 @@
     PyObject *unicode           /* Unicode object */
     );
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject*) PyUnicode_EncodeRawUnicodeEscape(
     const Py_UNICODE *data,     /* Unicode char buffer */
     Py_ssize_t length           /* Number of Py_UNICODE chars to encode */
     );
+#endif
 
 /* --- Unicode Internal Codec ---------------------------------------------
 
     Only for internal use in _codecsmodule.c */
 
+#ifndef Py_LIMITED_API
 PyObject *_PyUnicode_DecodeUnicodeInternal(
     const char *string,
     Py_ssize_t length,
     const char *errors
     );
+#endif
 
 /* --- Latin-1 Codecs -----------------------------------------------------
 
@@ -1021,11 +1061,13 @@
     PyObject *unicode           /* Unicode object */
     );
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject*) PyUnicode_EncodeLatin1(
     const Py_UNICODE *data,     /* Unicode char buffer */
     Py_ssize_t length,          /* Number of Py_UNICODE chars to encode */
     const char *errors          /* error handling */
     );
+#endif
 
 /* --- ASCII Codecs -------------------------------------------------------
 
@@ -1043,11 +1085,13 @@
     PyObject *unicode           /* Unicode object */
     );
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject*) PyUnicode_EncodeASCII(
     const Py_UNICODE *data,     /* Unicode char buffer */
     Py_ssize_t length,          /* Number of Py_UNICODE chars to encode */
     const char *errors          /* error handling */
     );
+#endif
 
 /* --- Character Map Codecs -----------------------------------------------
 
@@ -1085,6 +1129,7 @@
                                    (unicode ordinal -> char ordinal) */
     );
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject*) PyUnicode_EncodeCharmap(
     const Py_UNICODE *data,     /* Unicode char buffer */
     Py_ssize_t length,          /* Number of Py_UNICODE chars to encode */
@@ -1092,6 +1137,7 @@
                                    (unicode ordinal -> char ordinal) */
     const char *errors          /* error handling */
     );
+#endif
 
 /* Translate a Py_UNICODE buffer of the given length by applying a
    character mapping table to it and return the resulting Unicode
@@ -1106,12 +1152,14 @@
 
 */
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject *) PyUnicode_TranslateCharmap(
     const Py_UNICODE *data,     /* Unicode char buffer */
     Py_ssize_t length,          /* Number of Py_UNICODE chars to encode */
     PyObject *table,            /* Translate table */
     const char *errors          /* error handling */
     );
+#endif
 
 #ifdef MS_WIN32
 
@@ -1134,11 +1182,13 @@
     PyObject *unicode           /* Unicode object */
     );
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject*) PyUnicode_EncodeMBCS(
     const Py_UNICODE *data,     /* Unicode char buffer */
     Py_ssize_t length,          /* Number of Py_UNICODE chars to encode */
     const char *errors          /* error handling */
     );
+#endif
 
 #endif /* MS_WIN32 */
 
@@ -1166,12 +1216,14 @@
 
 */
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(int) PyUnicode_EncodeDecimal(
     Py_UNICODE *s,              /* Unicode buffer */
     Py_ssize_t length,          /* Number of Py_UNICODE chars to encode */
     char *output,               /* Output buffer; must have size >= length */
     const char *errors          /* error handling */
     );
+#endif
 
 /* --- File system encoding ---------------------------------------------- */
 
@@ -1438,26 +1490,31 @@
 
 PyAPI_FUNC(int) PyUnicode_IsIdentifier(PyObject *s);
 
+#ifndef Py_LIMITED_API
 /* Externally visible for str.strip(unicode) */
 PyAPI_FUNC(PyObject *) _PyUnicode_XStrip(
     PyUnicodeObject *self,
     int striptype,
     PyObject *sepobj
     );
+#endif
 
 /* Using the current locale, insert the thousands grouping
    into the string pointed to by buffer.  For the argument descriptions,
    see Objects/stringlib/localeutil.h */
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(Py_ssize_t) _PyUnicode_InsertThousandsGroupingLocale(Py_UNICODE *buffer,
                                                    Py_ssize_t n_buffer,
                                                    Py_UNICODE *digits,
                                                    Py_ssize_t n_digits,
                                                    Py_ssize_t min_width);
+#endif
 
 /* Using explicit passed-in values, insert the thousands grouping
    into the string pointed to by buffer.  For the argument descriptions,
    see Objects/stringlib/localeutil.h */
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(Py_ssize_t) _PyUnicode_InsertThousandsGrouping(Py_UNICODE *buffer,
                                                    Py_ssize_t n_buffer,
                                                    Py_UNICODE *digits,
@@ -1465,10 +1522,12 @@
                                                    Py_ssize_t min_width,
                                                    const char *grouping,
                                                    const char *thousands_sep);
+#endif
 /* === Characters Type APIs =============================================== */
 
 /* Helper array used by Py_UNICODE_ISSPACE(). */
 
+#ifndef Py_LIMITED_API
 PyAPI_DATA(const unsigned char) _Py_ascii_whitespace[];
 
 /* These should not be used directly. Use the Py_UNICODE_IS* and
@@ -1594,6 +1653,7 @@
 PyAPI_FUNC(Py_UNICODE*) PyUnicode_AsUnicodeCopy(
     PyObject *unicode
     );
+#endif /* Py_LIMITED_API */
 
 #ifdef __cplusplus
 }
diff --git a/Include/warnings.h b/Include/warnings.h
index c84cb9f..82abb11 100644
--- a/Include/warnings.h
+++ b/Include/warnings.h
@@ -4,7 +4,9 @@
 extern "C" {
 #endif
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(PyObject*) _PyWarnings_Init(void);
+#endif
 
 PyAPI_FUNC(int) PyErr_WarnEx(PyObject *, const char *, Py_ssize_t);
 PyAPI_FUNC(int) PyErr_WarnFormat(PyObject *, Py_ssize_t, const char *, ...);
@@ -12,7 +14,9 @@
                                     const char *, PyObject *);
 
 /* DEPRECATED: Use PyErr_WarnEx() instead. */
+#ifndef Py_LIMITED_API
 #define PyErr_Warn(category, msg) PyErr_WarnEx(category, msg, 1)
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/Include/weakrefobject.h b/Include/weakrefobject.h
index b201d08..7258387 100644
--- a/Include/weakrefobject.h
+++ b/Include/weakrefobject.h
@@ -12,6 +12,7 @@
 /* PyWeakReference is the base struct for the Python ReferenceType, ProxyType,
  * and CallableProxyType.
  */
+#ifndef Py_LIMITED_API
 struct _PyWeakReference {
     PyObject_HEAD
 
@@ -37,6 +38,7 @@
     PyWeakReference *wr_prev;
     PyWeakReference *wr_next;
 };
+#endif
 
 PyAPI_DATA(PyTypeObject) _PyWeakref_RefType;
 PyAPI_DATA(PyTypeObject) _PyWeakref_ProxyType;
@@ -62,9 +64,11 @@
                                                 PyObject *callback);
 PyAPI_FUNC(PyObject *) PyWeakref_GetObject(PyObject *ref);
 
+#ifndef Py_LIMITED_API
 PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head);
 
 PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self);
+#endif
 
 #define PyWeakref_GET_OBJECT(ref) (((PyWeakReference *)(ref))->wr_object)