Skip to content

Commit

Permalink
Replace unsafe PY_*_VERSION comparisons to fix for Python 4.0 (#14280)
Browse files Browse the repository at this point in the history
`#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 7`

For example, this is true for Python 3.7-3.11 but also true for Python
4.7-4.11. Instead, `PY_VERSION_HEX` should be used.

https://docs.python.org/3.11/c-api/apiabiversion.html

```c
/* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2.
   Use this for numeric comparisons, e.g. #if PY_VERSION_HEX >= ... */
```

https://github.com/python/cpython/blob/2e279e85fece187b6058718ac7e82d1692461e26/Include/patchlevel.h#L29-L30

Remove compatibility code that only applied to EOL and unsupported
Python versions (<= 3.6)
  • Loading branch information
hugovk authored Dec 12, 2022
1 parent b0003af commit 42dc1c4
Show file tree
Hide file tree
Showing 5 changed files with 7 additions and 51 deletions.
3 changes: 0 additions & 3 deletions mypy/stubtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -1533,9 +1533,6 @@ def get_typeshed_stdlib_modules(
stdlib_py_versions = mypy.modulefinder.load_stdlib_py_versions(custom_typeshed_dir)
if version_info is None:
version_info = sys.version_info[0:2]
# Typeshed's minimum supported Python 3 is Python 3.7
if sys.version_info < (3, 7):
version_info = (3, 7)

def exists_in_version(module: str) -> bool:
assert version_info is not None
Expand Down
12 changes: 2 additions & 10 deletions mypyc/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,6 @@

PLATFORM_SIZE = 4 if IS_32_BIT_PLATFORM else 8

# Python 3.5 on macOS uses a hybrid 32/64-bit build that requires some workarounds.
# The same generated C will be compiled in both 32 and 64 bit modes when building mypy
# wheels (for an unknown reason).
#
# Note that we use "in ['darwin']" because of https://github.com/mypyc/mypyc/issues/761.
IS_MIXED_32_64_BIT_BUILD: Final = sys.platform in ["darwin"] and sys.version_info < (3, 6)

# Maximum value for a short tagged integer.
MAX_SHORT_INT: Final = 2 ** (8 * int(SIZEOF_SIZE_T) - 2) - 1

Expand All @@ -59,9 +52,8 @@

# Maximum value for a short tagged integer represented as a C integer literal.
#
# Note: Assume that the compiled code uses the same bit width as mypyc, except for
# Python 3.5 on macOS.
MAX_LITERAL_SHORT_INT: Final = MAX_SHORT_INT if not IS_MIXED_32_64_BIT_BUILD else 2**30 - 1
# Note: Assume that the compiled code uses the same bit width as mypyc
MAX_LITERAL_SHORT_INT: Final = MAX_SHORT_INT
MIN_LITERAL_SHORT_INT: Final = -MAX_LITERAL_SHORT_INT - 1

# Decription of the C type used to track the definedness of attributes and
Expand Down
9 changes: 2 additions & 7 deletions mypyc/lib-rt/CPy.h
Original file line number Diff line number Diff line change
Expand Up @@ -499,13 +499,8 @@ static inline bool CPy_KeepPropagating(void) {
}
// We want to avoid the public PyErr_GetExcInfo API for these because
// it requires a bunch of spurious refcount traffic on the parts of
// the triple we don't care about. Unfortunately the layout of the
// data structure changed in 3.7 so we need to handle that.
#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 7
// the triple we don't care about.
#define CPy_ExcState() PyThreadState_GET()->exc_info
#else
#define CPy_ExcState() PyThreadState_GET()
#endif

void CPy_Raise(PyObject *exc);
void CPy_Reraise(void);
Expand All @@ -527,7 +522,7 @@ void CPy_AttributeError(const char *filename, const char *funcname, const char *

// Misc operations

#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 8
#if PY_VERSION_HEX >= 0x03080000
#define CPy_TRASHCAN_BEGIN(op, dealloc) Py_TRASHCAN_BEGIN(op, dealloc)
#define CPy_TRASHCAN_END(op) Py_TRASHCAN_END
#else
Expand Down
5 changes: 0 additions & 5 deletions mypyc/lib-rt/getargsfast.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
#include <Python.h>
#include "CPy.h"

/* None of this is supported on Python 3.6 or earlier */
#if PY_VERSION_HEX >= 0x03070000

#define PARSER_INITED(parser) ((parser)->kwtuple != NULL)

/* Forward */
Expand Down Expand Up @@ -570,5 +567,3 @@ skipitem_fast(const char **p_format, va_list *p_va)

*p_format = format;
}

#endif
29 changes: 3 additions & 26 deletions mypyc/lib-rt/pythonsupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ extern "C" {

/////////////////////////////////////////
// Adapted from bltinmodule.c in Python 3.7.0
#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 7
_Py_IDENTIFIER(__mro_entries__);
static PyObject*
update_bases(PyObject *bases)
Expand Down Expand Up @@ -96,16 +95,8 @@ update_bases(PyObject *bases)
Py_XDECREF(new_bases);
return NULL;
}
#else
static PyObject*
update_bases(PyObject *bases)
{
return bases;
}
#endif

// From Python 3.7's typeobject.c
#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 6
_Py_IDENTIFIER(__init_subclass__);
static int
init_subclass(PyTypeObject *type, PyObject *kwds)
Expand Down Expand Up @@ -134,14 +125,6 @@ init_subclass(PyTypeObject *type, PyObject *kwds)
return 0;
}

#else
static int
init_subclass(PyTypeObject *type, PyObject *kwds)
{
return 0;
}
#endif

// Adapted from longobject.c in Python 3.7.0

/* This function adapted from PyLong_AsLongLongAndOverflow, but with
Expand Down Expand Up @@ -306,7 +289,7 @@ list_count(PyListObject *self, PyObject *value)
return CPyTagged_ShortFromSsize_t(count);
}

#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION < 8
#if PY_VERSION_HEX < 0x03080000
static PyObject *
_PyDict_GetItemStringWithError(PyObject *v, const char *key)
{
Expand All @@ -321,13 +304,7 @@ _PyDict_GetItemStringWithError(PyObject *v, const char *key)
}
#endif

#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION < 6
/* _PyUnicode_EqualToASCIIString got added in 3.5.3 (argh!) so we can't actually know
* whether it will be present at runtime, so we just assume we don't have it in 3.5. */
#define CPyUnicode_EqualToASCIIString(x, y) (PyUnicode_CompareWithASCIIString((x), (y)) == 0)
#elif PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 6
#define CPyUnicode_EqualToASCIIString(x, y) _PyUnicode_EqualToASCIIString(x, y)
#endif

// Adapted from genobject.c in Python 3.7.2
// Copied because it wasn't in 3.5.2 and it is undocumented anyways.
Expand Down Expand Up @@ -390,7 +367,7 @@ _CPyDictView_New(PyObject *dict, PyTypeObject *type)
}
#endif

#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >=10
#if PY_VERSION_HEX >= 0x030A0000 // 3.10
static int
_CPyObject_HasAttrId(PyObject *v, _Py_Identifier *name) {
PyObject *tmp = NULL;
Expand All @@ -404,7 +381,7 @@ _CPyObject_HasAttrId(PyObject *v, _Py_Identifier *name) {
#define _CPyObject_HasAttrId _PyObject_HasAttrId
#endif

#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION < 9
#if PY_VERSION_HEX < 0x03090000
// OneArgs and NoArgs functions got added in 3.9
#define _PyObject_CallMethodIdNoArgs(self, name) \
_PyObject_CallMethodIdObjArgs((self), (name), NULL)
Expand Down

0 comments on commit 42dc1c4

Please sign in to comment.