Support Python 3.8. Fixes #1845 (#1855)

This commit is contained in:
Fabio Zadrozny 2019-10-17 17:34:42 -03:00 committed by Karthik Nadig
parent 492e5e0f62
commit cd44e3b514
28 changed files with 355 additions and 149 deletions

View file

@ -4,10 +4,10 @@ sudo: required
cache: pip
python:
- "2.7"
- "3.4"
- "3.5"
- "3.6"
- "3.7"
- "3.8-dev"
stages:
- lint

View file

@ -30,73 +30,54 @@ matrix:
- PYDEVD_USE_CYTHON=NO
- PYDEVD_TEST_VM=PYPY
# Python 2.6 (with and without cython)
# Python 2.6
- python: 2.7
env:
- PYDEVD_PYTHON_VERSION=2.6
- PYDEVD_USE_CYTHON=NO
- PYDEVD_TEST_VM=CPYTHON
# - python: 2.7
# env:
# - PYDEVD_PYTHON_VERSION=2.6
# - PYDEVD_USE_CYTHON=YES
# - PYDEVD_TEST_VM=CPYTHON
# Python 2.7 (with and without cython)
# - python: 2.7
# env:
# - PYDEVD_PYTHON_VERSION=2.7
# - PYDEVD_USE_CYTHON=NO
# - PYDEVD_TEST_VM=CPYTHON
# Python 2.7
- python: 2.7
env:
- PYDEVD_PYTHON_VERSION=2.7
- PYDEVD_USE_CYTHON=YES
- PYDEVD_TEST_VM=CPYTHON
# Python 3.5 (with and without cython)
# - python: 2.7
# env:
# - PYDEVD_PYTHON_VERSION=3.5
# - PYDEVD_USE_CYTHON=NO
# - PYDEVD_TEST_VM=CPYTHON
- python: 2.7
env:
- PYDEVD_PYTHON_VERSION=3.5
- PYDEVD_USE_CYTHON=YES
- PYDEVD_TEST_VM=CPYTHON
# Python 3.5 (no longer tested by default).
# - python: 2.7
# env:
# - PYDEVD_PYTHON_VERSION=3.5
# - PYDEVD_USE_CYTHON=YES
# - PYDEVD_TEST_VM=CPYTHON
# Python 3.6 (with and without cython)
# Python 3.6
- python: 2.7
env:
- PYDEVD_PYTHON_VERSION=3.6
- PYDEVD_USE_CYTHON=NO
- PYDEVD_TEST_VM=CPYTHON
# - python: 2.7
# env:
# - PYDEVD_PYTHON_VERSION=3.6
# - PYDEVD_USE_CYTHON=YES
# - PYDEVD_TEST_VM=CPYTHON
# Python 3.7 (with and without cython)
# - python: 2.7
# env:
# - PYDEVD_PYTHON_VERSION=3.7
# - PYDEVD_USE_CYTHON=NO
# - PYDEVD_TEST_VM=CPYTHON
# Python 3.7
- python: 2.7
env:
- PYDEVD_PYTHON_VERSION=3.7
- PYDEVD_USE_CYTHON=YES
- PYDEVD_TEST_VM=CPYTHON
- python: 3.8-dev
env:
- PYDEVD_PYTHON_VERSION=3.8
- PYDEVD_USE_CYTHON=YES
- PYDEVD_TEST_VM=CPYTHON
before_install:
# CPython / Pypy setup
- if [[ "$PYDEVD_TEST_VM" == "CPYTHON" || "$PYDEVD_TEST_VM" == "PYPY" ]]; then wget http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh; fi
- if [[ "$PYDEVD_TEST_VM" == "CPYTHON" || "$PYDEVD_TEST_VM" == "PYPY" ]]; then chmod +x miniconda.sh; fi
- if [[ "$PYDEVD_TEST_VM" == "CPYTHON" || "$PYDEVD_TEST_VM" == "PYPY" ]]; then ./miniconda.sh -b; fi
- if [[ "$PYDEVD_TEST_VM" == "CPYTHON" || "$PYDEVD_TEST_VM" == "PYPY" ]]; then export PATH=/home/travis/miniconda2/bin:$PATH; fi
- if [[ "$PYDEVD_TEST_VM" == "CPYTHON" || "$PYDEVD_TEST_VM" == "PYPY" ]]; then conda update --yes conda; fi
- if [[ ("$PYDEVD_PYTHON_VERSION" != "3.8") && ("$PYDEVD_TEST_VM" == "CPYTHON" || "$PYDEVD_TEST_VM" == "PYPY") ]]; then wget http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh; fi
- if [[ ("$PYDEVD_PYTHON_VERSION" != "3.8") && ("$PYDEVD_TEST_VM" == "CPYTHON" || "$PYDEVD_TEST_VM" == "PYPY") ]]; then chmod +x miniconda.sh; fi
- if [[ ("$PYDEVD_PYTHON_VERSION" != "3.8") && ("$PYDEVD_TEST_VM" == "CPYTHON" || "$PYDEVD_TEST_VM" == "PYPY") ]]; then ./miniconda.sh -b; fi
- if [[ ("$PYDEVD_PYTHON_VERSION" != "3.8") && ("$PYDEVD_TEST_VM" == "CPYTHON" || "$PYDEVD_TEST_VM" == "PYPY") ]]; then export PATH=/home/travis/miniconda2/bin:$PATH; fi
- if [[ ("$PYDEVD_PYTHON_VERSION" != "3.8") && ("$PYDEVD_TEST_VM" == "CPYTHON" || "$PYDEVD_TEST_VM" == "PYPY") ]]; then conda update --yes conda; fi
# Jython setup
- if [ "$PYDEVD_TEST_VM" == "JYTHON" ]; then wget $JYTHON_URL -O jython_installer.jar; java -jar jython_installer.jar -s -d $HOME/jython; export PATH=$HOME/jython:$HOME/jython/bin:$PATH; fi
- if [ "$PYDEVD_TEST_VM" == "JYTHON" ]; then jython -c "print('')"; fi
@ -107,20 +88,21 @@ install:
- sudo sysctl kernel.yama.ptrace_scope=0
# Both
- export PYTHONPATH=.
# CPython setup
- if [ "$PYDEVD_TEST_VM" == "CPYTHON" ]; then conda create --yes -n build_env python=$PYDEVD_PYTHON_VERSION; fi
- if [ "$PYDEVD_TEST_VM" == "CPYTHON" ]; then source activate build_env; fi
- if [ "$PYDEVD_TEST_VM" == "CPYTHON" ]; then chmod +x ./.travis_install_python_deps.sh; fi
- if [ "$PYDEVD_TEST_VM" == "CPYTHON" ]; then ./.travis_install_python_deps.sh; fi
- if [ "$PYDEVD_TEST_VM" == "CPYTHON" ]; then source activate build_env; python build_tools/build.py; fi
# CPython setup (Note that for CPython 3.8 we'll use the system-installed version for now).
- if [[ ("$PYDEVD_TEST_VM" == "CPYTHON" && "$PYDEVD_PYTHON_VERSION" != "3.8") ]]; then conda create --yes -n build_env python=$PYDEVD_PYTHON_VERSION; fi
- if [[ ("$PYDEVD_TEST_VM" == "CPYTHON" && "$PYDEVD_PYTHON_VERSION" != "3.8") ]]; then source activate build_env; fi
- if [[ ("$PYDEVD_TEST_VM" == "CPYTHON") ]]; then chmod +x ./.travis_install_python_deps.sh; fi
- if [[ ("$PYDEVD_TEST_VM" == "CPYTHON") ]]; then ./.travis_install_python_deps.sh; fi
- if [[ ("$PYDEVD_TEST_VM" == "CPYTHON") ]]; then python build_tools/build.py; fi
- if [[ ("$PYDEVD_TEST_VM" == "CPYTHON" && "$PYDEVD_PYTHON_VERSION" != "3.8") ]]; then source activate build_env; python build_tools/build.py; fi
# Pypy setup
- if [ "$PYDEVD_TEST_VM" == "PYPY" ]; then conda create --yes -n build_env -c conda-forge pypy3.6; fi
- if [ "$PYDEVD_TEST_VM" == "PYPY" ]; then source activate build_env; fi
- if [ "$PYDEVD_TEST_VM" == "PYPY" ]; then chmod +x ./.travis_install_pypy_deps.sh; fi
- if [ "$PYDEVD_TEST_VM" == "PYPY" ]; then ./.travis_install_pypy_deps.sh; fi
- if [[ "$PYDEVD_TEST_VM" == "PYPY" ]]; then conda create --yes -n build_env -c conda-forge pypy3.6; fi
- if [[ "$PYDEVD_TEST_VM" == "PYPY" ]]; then source activate build_env; fi
- if [[ "$PYDEVD_TEST_VM" == "PYPY" ]]; then chmod +x ./.travis_install_pypy_deps.sh; fi
- if [[ "$PYDEVD_TEST_VM" == "PYPY" ]]; then ./.travis_install_pypy_deps.sh; fi
# Jython setup
- if [ "$PYDEVD_TEST_VM" == "JYTHON" ]; then chmod +x ./.travis_install_jython_deps.sh; fi
- if [ "$PYDEVD_TEST_VM" == "JYTHON" ]; then ./.travis_install_jython_deps.sh; fi
- if [[ "$PYDEVD_TEST_VM" == "JYTHON" ]]; then chmod +x ./.travis_install_jython_deps.sh; fi
- if [[ "$PYDEVD_TEST_VM" == "JYTHON" ]]; then ./.travis_install_jython_deps.sh; fi
# Run test
# On local machine with jython: c:\bin\jython2.7.0\bin\jython.exe -Dpython.path=.;jython_test_deps/ant.jar;jython_test_deps/junit.jar -m pytest
@ -128,7 +110,8 @@ install:
script:
# pytest-xdist not available for python == 2.6 and timing out without output with 2.7
- if [[ ("$PYDEVD_TEST_VM" == "CPYTHON") && ("$PYDEVD_PYTHON_VERSION" == "2.6" || "$PYDEVD_PYTHON_VERSION" == "2.7") ]]; then source activate build_env; python -m pytest; fi
- if [[ ("$PYDEVD_TEST_VM" == "CPYTHON") && ("$PYDEVD_PYTHON_VERSION" != "2.6" && "$PYDEVD_PYTHON_VERSION" != "2.7") ]]; then source activate build_env; python -m pytest -n auto; fi
- if [[ ("$PYDEVD_TEST_VM" == "CPYTHON") && ("$PYDEVD_PYTHON_VERSION" != "2.6" && "$PYDEVD_PYTHON_VERSION" != "2.7" && "$PYDEVD_PYTHON_VERSION" != "3.8") ]]; then source activate build_env; python -m pytest -n auto; fi
- if [[ ("$PYDEVD_TEST_VM" == "CPYTHON") && ("$PYDEVD_PYTHON_VERSION" == "3.8") ]]; then python -m pytest; fi
- if [ "$PYDEVD_TEST_VM" == "PYPY" ]; then source activate build_env; pypy3 -m pytest -n auto; fi
- if [ "$PYDEVD_TEST_VM" == "JYTHON" ]; then jython -Dpython.path=.:jython_test_deps/ant.jar:jython_test_deps/junit.jar -m pytest; fi

View file

@ -1,8 +1,10 @@
#!/bin/bash
set -ev
source activate build_env
conda install --yes numpy ipython pytest cython psutil
if [ "$PYDEVD_PYTHON_VERSION" != "3.8" ]; then
source activate build_env
conda install --yes numpy ipython pytest cython psutil
fi
if [ "$PYDEVD_PYTHON_VERSION" = "2.6" ]; then
conda install --yes pyqt=4
@ -39,5 +41,16 @@ if [ "$PYDEVD_PYTHON_VERSION" = "3.7" ]; then
pip install "cherrypy"
fi
if [ "$PYDEVD_PYTHON_VERSION" = "3.8" ]; then
pip install "pytest"
pip install "cython"
pip install "psutil"
pip install "numpy"
# Note: track the latest web framework versions.
pip install "django"
pip install "cherrypy"
fi
pip install untangle
pip install scapy==2.4.0

View file

@ -3,6 +3,7 @@ from opcode import HAVE_ARGUMENT, EXTENDED_ARG, hasconst, opname, hasname, hasjr
import dis
import sys
from collections import namedtuple
from _pydevd_bundle.pydevd_constants import IS_PY38_OR_GREATER
try:
xrange
@ -143,9 +144,14 @@ def collect_try_except_info(co, use_func_first_line=False):
for instruction in iter_in:
curr_op_name = instruction.opname
if curr_op_name == 'SETUP_EXCEPT':
if curr_op_name in ('SETUP_EXCEPT', 'SETUP_FINALLY'):
# We need to collect try..finally blocks too to make sure that
# the stack_in_setup we're using to collect info is correct.
# Note: On Py3.8 both except and finally statements use 'SETUP_FINALLY'.
try_except_info = TryExceptInfo(
_get_line(op_offset_to_line, instruction.offset, firstlineno, search=True))
_get_line(op_offset_to_line, instruction.offset, firstlineno, search=True),
is_finally=curr_op_name == 'SETUP_FINALLY'
)
try_except_info.except_bytecode_offset = instruction.argval
try_except_info.except_line = _get_line(
op_offset_to_line,
@ -155,12 +161,11 @@ def collect_try_except_info(co, use_func_first_line=False):
stack_in_setup.append(try_except_info)
elif curr_op_name == 'SETUP_FINALLY':
# We need to collect try..finally blocks too to make sure that
# the stack_in_setup we're using to collect info is correct.
try_except_info = TryExceptInfo(
_get_line(op_offset_to_line, instruction.offset, firstlineno, search=True), is_finally=True)
stack_in_setup.append(try_except_info)
elif curr_op_name == 'POP_EXCEPT':
# On Python 3.8 there's no SETUP_EXCEPT (both except and finally start with SETUP_FINALLY),
# so, we differentiate by a POP_EXCEPT.
if IS_PY38_OR_GREATER:
stack_in_setup[-1].is_finally = False
elif curr_op_name == 'RAISE_VARARGS':
# We want to know about reraises and returns inside of except blocks (unfortunately

View file

@ -116,6 +116,7 @@ IS_PY3K = False
IS_PY34_OR_GREATER = False
IS_PY36_OR_GREATER = False
IS_PY37_OR_GREATER = False
IS_PY38_OR_GREATER = False
IS_PY2 = True
IS_PY27 = False
IS_PY24 = False
@ -126,6 +127,7 @@ try:
IS_PY34_OR_GREATER = sys.version_info >= (3, 4)
IS_PY36_OR_GREATER = sys.version_info >= (3, 6)
IS_PY37_OR_GREATER = sys.version_info >= (3, 7)
IS_PY38_OR_GREATER = sys.version_info >= (3, 8)
elif sys.version_info[0] == 2 and sys.version_info[1] == 7:
IS_PY27 = True
elif sys.version_info[0] == 2 and sys.version_info[1] == 4:

View file

@ -1,4 +1,4 @@
/* Generated by Cython 0.29.8 */
/* Generated by Cython 0.29.13 */
/* BEGIN: Cython Metadata
{
@ -20,8 +20,8 @@ END: Cython Metadata */
#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000)
#error Cython requires Python 2.6+ or Python 3.3+.
#else
#define CYTHON_ABI "0_29_8"
#define CYTHON_HEX_VERSION 0x001D08F0
#define CYTHON_ABI "0_29_13"
#define CYTHON_HEX_VERSION 0x001D0DF0
#define CYTHON_FUTURE_DIVISION 0
#include <stddef.h>
#ifndef offsetof
@ -323,12 +323,12 @@ END: Cython Metadata */
#define __Pyx_DefaultClassType PyClass_Type
#else
#define __Pyx_BUILTIN_MODULE_NAME "builtins"
#if PY_VERSION_HEX < 0x030800A4
#define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\
PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
#else
#if PY_VERSION_HEX >= 0x030800A4 && PY_VERSION_HEX < 0x030800B2
#define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\
PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
#else
#define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\
PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
#endif
#define __Pyx_DefaultClassType PyType_Type
#endif
@ -1072,7 +1072,7 @@ static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name);
#define __Pyx_PyFunction_FastCall(func, args, nargs)\
__Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL)
#if 1 || PY_VERSION_HEX < 0x030600B1
static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, int nargs, PyObject *kwargs);
static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs);
#else
#define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs)
#endif
@ -30594,6 +30594,9 @@ static PyTypeObject __pyx_type_14_pydevd_bundle_13pydevd_cython_PyDBAdditionalTh
#if PY_VERSION_HEX >= 0x030400a1
0, /*tp_finalize*/
#endif
#if PY_VERSION_HEX >= 0x030800b1
0, /*tp_vectorcall*/
#endif
};
static struct __pyx_vtabstruct_14_pydevd_bundle_13pydevd_cython_PyDBFrame __pyx_vtable_14_pydevd_bundle_13pydevd_cython_PyDBFrame;
@ -30714,6 +30717,9 @@ static PyTypeObject __pyx_type_14_pydevd_bundle_13pydevd_cython_PyDBFrame = {
#if PY_VERSION_HEX >= 0x030400a1
0, /*tp_finalize*/
#endif
#if PY_VERSION_HEX >= 0x030800b1
0, /*tp_vectorcall*/
#endif
};
static PyObject *__pyx_tp_new_14_pydevd_bundle_13pydevd_cython_SafeCallWrapper(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
@ -30823,6 +30829,9 @@ static PyTypeObject __pyx_type_14_pydevd_bundle_13pydevd_cython_SafeCallWrapper
#if PY_VERSION_HEX >= 0x030400a1
0, /*tp_finalize*/
#endif
#if PY_VERSION_HEX >= 0x030800b1
0, /*tp_vectorcall*/
#endif
};
static PyObject *__pyx_tp_new_14_pydevd_bundle_13pydevd_cython_TopLevelThreadTracerOnlyUnhandledExceptions(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
@ -30951,6 +30960,9 @@ static PyTypeObject __pyx_type_14_pydevd_bundle_13pydevd_cython_TopLevelThreadTr
#if PY_VERSION_HEX >= 0x030400a1
0, /*tp_finalize*/
#endif
#if PY_VERSION_HEX >= 0x030800b1
0, /*tp_vectorcall*/
#endif
};
static PyObject *__pyx_tp_new_14_pydevd_bundle_13pydevd_cython_TopLevelThreadTracerNoBackFrame(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
@ -31182,6 +31194,9 @@ static PyTypeObject __pyx_type_14_pydevd_bundle_13pydevd_cython_TopLevelThreadTr
#if PY_VERSION_HEX >= 0x030400a1
0, /*tp_finalize*/
#endif
#if PY_VERSION_HEX >= 0x030800b1
0, /*tp_vectorcall*/
#endif
};
static PyObject *__pyx_tp_new_14_pydevd_bundle_13pydevd_cython_ThreadTracer(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
@ -31308,6 +31323,9 @@ static PyTypeObject __pyx_type_14_pydevd_bundle_13pydevd_cython_ThreadTracer = {
#if PY_VERSION_HEX >= 0x030400a1
0, /*tp_finalize*/
#endif
#if PY_VERSION_HEX >= 0x030800b1
0, /*tp_vectorcall*/
#endif
};
static PyMethodDef __pyx_methods[] = {
@ -31965,7 +31983,9 @@ static int __Pyx_modinit_type_init_code(void) {
__Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0);
/*--- Type init code ---*/
if (PyType_Ready(&__pyx_type_14_pydevd_bundle_13pydevd_cython_PyDBAdditionalThreadInfo) < 0) __PYX_ERR(0, 67, __pyx_L1_error)
#if PY_VERSION_HEX < 0x030800B1
__pyx_type_14_pydevd_bundle_13pydevd_cython_PyDBAdditionalThreadInfo.tp_print = 0;
#endif
if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_14_pydevd_bundle_13pydevd_cython_PyDBAdditionalThreadInfo.tp_dictoffset && __pyx_type_14_pydevd_bundle_13pydevd_cython_PyDBAdditionalThreadInfo.tp_getattro == PyObject_GenericGetAttr)) {
__pyx_type_14_pydevd_bundle_13pydevd_cython_PyDBAdditionalThreadInfo.tp_getattro = __Pyx_PyObject_GenericGetAttr;
}
@ -31975,7 +31995,9 @@ static int __Pyx_modinit_type_init_code(void) {
__pyx_vtabptr_14_pydevd_bundle_13pydevd_cython_PyDBFrame = &__pyx_vtable_14_pydevd_bundle_13pydevd_cython_PyDBFrame;
__pyx_vtable_14_pydevd_bundle_13pydevd_cython_PyDBFrame.trace_dispatch = (PyObject *(*)(struct __pyx_obj_14_pydevd_bundle_13pydevd_cython_PyDBFrame *, PyObject *, PyObject *, PyObject *, int __pyx_skip_dispatch))__pyx_f_14_pydevd_bundle_13pydevd_cython_9PyDBFrame_trace_dispatch;
if (PyType_Ready(&__pyx_type_14_pydevd_bundle_13pydevd_cython_PyDBFrame) < 0) __PYX_ERR(0, 212, __pyx_L1_error)
#if PY_VERSION_HEX < 0x030800B1
__pyx_type_14_pydevd_bundle_13pydevd_cython_PyDBFrame.tp_print = 0;
#endif
if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_14_pydevd_bundle_13pydevd_cython_PyDBFrame.tp_dictoffset && __pyx_type_14_pydevd_bundle_13pydevd_cython_PyDBFrame.tp_getattro == PyObject_GenericGetAttr)) {
__pyx_type_14_pydevd_bundle_13pydevd_cython_PyDBFrame.tp_getattro = __Pyx_PyObject_GenericGetAttr;
}
@ -31984,7 +32006,9 @@ static int __Pyx_modinit_type_init_code(void) {
if (__Pyx_setup_reduce((PyObject*)&__pyx_type_14_pydevd_bundle_13pydevd_cython_PyDBFrame) < 0) __PYX_ERR(0, 212, __pyx_L1_error)
__pyx_ptype_14_pydevd_bundle_13pydevd_cython_PyDBFrame = &__pyx_type_14_pydevd_bundle_13pydevd_cython_PyDBFrame;
if (PyType_Ready(&__pyx_type_14_pydevd_bundle_13pydevd_cython_SafeCallWrapper) < 0) __PYX_ERR(0, 962, __pyx_L1_error)
#if PY_VERSION_HEX < 0x030800B1
__pyx_type_14_pydevd_bundle_13pydevd_cython_SafeCallWrapper.tp_print = 0;
#endif
if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_14_pydevd_bundle_13pydevd_cython_SafeCallWrapper.tp_dictoffset && __pyx_type_14_pydevd_bundle_13pydevd_cython_SafeCallWrapper.tp_getattro == PyObject_GenericGetAttr)) {
__pyx_type_14_pydevd_bundle_13pydevd_cython_SafeCallWrapper.tp_getattro = __Pyx_PyObject_GenericGetAttr;
}
@ -31992,7 +32016,9 @@ static int __Pyx_modinit_type_init_code(void) {
if (__Pyx_setup_reduce((PyObject*)&__pyx_type_14_pydevd_bundle_13pydevd_cython_SafeCallWrapper) < 0) __PYX_ERR(0, 962, __pyx_L1_error)
__pyx_ptype_14_pydevd_bundle_13pydevd_cython_SafeCallWrapper = &__pyx_type_14_pydevd_bundle_13pydevd_cython_SafeCallWrapper;
if (PyType_Ready(&__pyx_type_14_pydevd_bundle_13pydevd_cython_TopLevelThreadTracerOnlyUnhandledExceptions) < 0) __PYX_ERR(0, 1115, __pyx_L1_error)
#if PY_VERSION_HEX < 0x030800B1
__pyx_type_14_pydevd_bundle_13pydevd_cython_TopLevelThreadTracerOnlyUnhandledExceptions.tp_print = 0;
#endif
if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_14_pydevd_bundle_13pydevd_cython_TopLevelThreadTracerOnlyUnhandledExceptions.tp_dictoffset && __pyx_type_14_pydevd_bundle_13pydevd_cython_TopLevelThreadTracerOnlyUnhandledExceptions.tp_getattro == PyObject_GenericGetAttr)) {
__pyx_type_14_pydevd_bundle_13pydevd_cython_TopLevelThreadTracerOnlyUnhandledExceptions.tp_getattro = __Pyx_PyObject_GenericGetAttr;
}
@ -32000,7 +32026,9 @@ static int __Pyx_modinit_type_init_code(void) {
if (__Pyx_setup_reduce((PyObject*)&__pyx_type_14_pydevd_bundle_13pydevd_cython_TopLevelThreadTracerOnlyUnhandledExceptions) < 0) __PYX_ERR(0, 1115, __pyx_L1_error)
__pyx_ptype_14_pydevd_bundle_13pydevd_cython_TopLevelThreadTracerOnlyUnhandledExceptions = &__pyx_type_14_pydevd_bundle_13pydevd_cython_TopLevelThreadTracerOnlyUnhandledExceptions;
if (PyType_Ready(&__pyx_type_14_pydevd_bundle_13pydevd_cython_TopLevelThreadTracerNoBackFrame) < 0) __PYX_ERR(0, 1145, __pyx_L1_error)
#if PY_VERSION_HEX < 0x030800B1
__pyx_type_14_pydevd_bundle_13pydevd_cython_TopLevelThreadTracerNoBackFrame.tp_print = 0;
#endif
if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_14_pydevd_bundle_13pydevd_cython_TopLevelThreadTracerNoBackFrame.tp_dictoffset && __pyx_type_14_pydevd_bundle_13pydevd_cython_TopLevelThreadTracerNoBackFrame.tp_getattro == PyObject_GenericGetAttr)) {
__pyx_type_14_pydevd_bundle_13pydevd_cython_TopLevelThreadTracerNoBackFrame.tp_getattro = __Pyx_PyObject_GenericGetAttr;
}
@ -32008,7 +32036,9 @@ static int __Pyx_modinit_type_init_code(void) {
if (__Pyx_setup_reduce((PyObject*)&__pyx_type_14_pydevd_bundle_13pydevd_cython_TopLevelThreadTracerNoBackFrame) < 0) __PYX_ERR(0, 1145, __pyx_L1_error)
__pyx_ptype_14_pydevd_bundle_13pydevd_cython_TopLevelThreadTracerNoBackFrame = &__pyx_type_14_pydevd_bundle_13pydevd_cython_TopLevelThreadTracerNoBackFrame;
if (PyType_Ready(&__pyx_type_14_pydevd_bundle_13pydevd_cython_ThreadTracer) < 0) __PYX_ERR(0, 1254, __pyx_L1_error)
#if PY_VERSION_HEX < 0x030800B1
__pyx_type_14_pydevd_bundle_13pydevd_cython_ThreadTracer.tp_print = 0;
#endif
if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_14_pydevd_bundle_13pydevd_cython_ThreadTracer.tp_dictoffset && __pyx_type_14_pydevd_bundle_13pydevd_cython_ThreadTracer.tp_getattro == PyObject_GenericGetAttr)) {
__pyx_type_14_pydevd_bundle_13pydevd_cython_ThreadTracer.tp_getattro = __Pyx_PyObject_GenericGetAttr;
}
@ -32262,9 +32292,9 @@ if (!__Pyx_RefNanny) {
}
#endif
/*--- Builtin init code ---*/
if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error)
if (__Pyx_InitCachedBuiltins() < 0) goto __pyx_L1_error;
/*--- Constants init code ---*/
if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error)
if (__Pyx_InitCachedConstants() < 0) goto __pyx_L1_error;
/*--- Global type/function init code ---*/
(void)__Pyx_modinit_global_init_code();
(void)__Pyx_modinit_variable_export_code();
@ -33811,7 +33841,7 @@ static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args
return result;
}
#if 1 || PY_VERSION_HEX < 0x030600B1
static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, int nargs, PyObject *kwargs) {
static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) {
PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);
PyObject *globals = PyFunction_GET_GLOBALS(func);
PyObject *argdefs = PyFunction_GET_DEFAULTS(func);
@ -33882,12 +33912,12 @@ static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args,
}
#if PY_MAJOR_VERSION >= 3
result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL,
args, nargs,
args, (int)nargs,
k, (int)nk,
d, (int)nd, kwdefs, closure);
#else
result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL,
args, nargs,
args, (int)nargs,
k, (int)nk,
d, (int)nd, closure);
#endif

View file

@ -8,6 +8,7 @@ import pydevd_file_utils
import json
from collections import namedtuple
from _pydev_imps._pydev_saved_modules import threading
from pydevd_file_utils import normcase
try:
xrange # noqa
@ -41,8 +42,8 @@ def _check_matches(patterns, paths):
if (not patterns and paths) or (patterns and not paths):
return False
pattern = patterns[0]
path = paths[0]
pattern = normcase(patterns[0])
path = normcase(paths[0])
if not glob.has_magic(pattern):

View file

@ -154,7 +154,7 @@ def notify_error(*args):
#=======================================================================================================================
def code_objects_equal(code0, code1):
for d in dir(code0):
if d.startswith('_') or 'lineno' in d:
if d.startswith('_') or 'lineno' in d or d == 'replace':
continue
if getattr(code0, d) != getattr(code1, d):
return False

View file

@ -1,4 +1,4 @@
/* Generated by Cython 0.29.8 */
/* Generated by Cython 0.29.13 */
/* BEGIN: Cython Metadata
{
@ -25,8 +25,8 @@ END: Cython Metadata */
#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000)
#error Cython requires Python 2.6+ or Python 3.3+.
#else
#define CYTHON_ABI "0_29_8"
#define CYTHON_HEX_VERSION 0x001D08F0
#define CYTHON_ABI "0_29_13"
#define CYTHON_HEX_VERSION 0x001D0DF0
#define CYTHON_FUTURE_DIVISION 0
#include <stddef.h>
#ifndef offsetof
@ -328,12 +328,12 @@ END: Cython Metadata */
#define __Pyx_DefaultClassType PyClass_Type
#else
#define __Pyx_BUILTIN_MODULE_NAME "builtins"
#if PY_VERSION_HEX < 0x030800A4
#define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\
PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
#else
#if PY_VERSION_HEX >= 0x030800A4 && PY_VERSION_HEX < 0x030800B2
#define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\
PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
#else
#define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\
PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
#endif
#define __Pyx_DefaultClassType PyType_Type
#endif
@ -615,6 +615,22 @@ static CYTHON_INLINE float __PYX_NAN() {
#include "release_mem.h"
#include "code.h"
#include "pystate.h"
#if PY_VERSION_HEX >= 0x03080000
#include "internal/pycore_pystate.h"
#endif
#if PY_VERSION_HEX >= 0x03080000
#include "internal/pycore_pystate.h"
#endif
#if PY_VERSION_HEX >= 0x03080000
#include "internal/pycore_pystate.h"
#endif
#if PY_VERSION_HEX >= 0x03080000
#include "internal/pycore_pystate.h"
#endif
#include "ceval.h"
#ifdef _OPENMP
#include <omp.h>
@ -1025,7 +1041,7 @@ static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name);
#define __Pyx_PyFunction_FastCall(func, args, nargs)\
__Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL)
#if 1 || PY_VERSION_HEX < 0x030600B1
static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, int nargs, PyObject *kwargs);
static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs);
#else
#define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs)
#endif
@ -8693,6 +8709,9 @@ static PyTypeObject __pyx_type_18_pydevd_frame_eval_22pydevd_frame_evaluator_Thr
#if PY_VERSION_HEX >= 0x030400a1
0, /*tp_finalize*/
#endif
#if PY_VERSION_HEX >= 0x030800b1
0, /*tp_vectorcall*/
#endif
};
static PyObject *__pyx_tp_new_18_pydevd_frame_eval_22pydevd_frame_evaluator_FuncCodeInfo(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
@ -8881,6 +8900,9 @@ static PyTypeObject __pyx_type_18_pydevd_frame_eval_22pydevd_frame_evaluator_Fun
#if PY_VERSION_HEX >= 0x030400a1
0, /*tp_finalize*/
#endif
#if PY_VERSION_HEX >= 0x030800b1
0, /*tp_vectorcall*/
#endif
};
static PyMethodDef __pyx_methods[] = {
@ -9192,7 +9214,9 @@ static int __Pyx_modinit_type_init_code(void) {
__Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0);
/*--- Type init code ---*/
if (PyType_Ready(&__pyx_type_18_pydevd_frame_eval_22pydevd_frame_evaluator_ThreadInfo) < 0) __PYX_ERR(0, 21, __pyx_L1_error)
#if PY_VERSION_HEX < 0x030800B1
__pyx_type_18_pydevd_frame_eval_22pydevd_frame_evaluator_ThreadInfo.tp_print = 0;
#endif
if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_18_pydevd_frame_eval_22pydevd_frame_evaluator_ThreadInfo.tp_dictoffset && __pyx_type_18_pydevd_frame_eval_22pydevd_frame_evaluator_ThreadInfo.tp_getattro == PyObject_GenericGetAttr)) {
__pyx_type_18_pydevd_frame_eval_22pydevd_frame_evaluator_ThreadInfo.tp_getattro = __Pyx_PyObject_GenericGetAttr;
}
@ -9200,7 +9224,9 @@ static int __Pyx_modinit_type_init_code(void) {
if (__Pyx_setup_reduce((PyObject*)&__pyx_type_18_pydevd_frame_eval_22pydevd_frame_evaluator_ThreadInfo) < 0) __PYX_ERR(0, 21, __pyx_L1_error)
__pyx_ptype_18_pydevd_frame_eval_22pydevd_frame_evaluator_ThreadInfo = &__pyx_type_18_pydevd_frame_eval_22pydevd_frame_evaluator_ThreadInfo;
if (PyType_Ready(&__pyx_type_18_pydevd_frame_eval_22pydevd_frame_evaluator_FuncCodeInfo) < 0) __PYX_ERR(0, 69, __pyx_L1_error)
#if PY_VERSION_HEX < 0x030800B1
__pyx_type_18_pydevd_frame_eval_22pydevd_frame_evaluator_FuncCodeInfo.tp_print = 0;
#endif
if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_18_pydevd_frame_eval_22pydevd_frame_evaluator_FuncCodeInfo.tp_dictoffset && __pyx_type_18_pydevd_frame_eval_22pydevd_frame_evaluator_FuncCodeInfo.tp_getattro == PyObject_GenericGetAttr)) {
__pyx_type_18_pydevd_frame_eval_22pydevd_frame_evaluator_FuncCodeInfo.tp_getattro = __Pyx_PyObject_GenericGetAttr;
}
@ -9430,9 +9456,9 @@ if (!__Pyx_RefNanny) {
}
#endif
/*--- Builtin init code ---*/
if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error)
if (__Pyx_InitCachedBuiltins() < 0) goto __pyx_L1_error;
/*--- Constants init code ---*/
if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error)
if (__Pyx_InitCachedConstants() < 0) goto __pyx_L1_error;
/*--- Global type/function init code ---*/
(void)__Pyx_modinit_global_init_code();
(void)__Pyx_modinit_variable_export_code();
@ -9938,7 +9964,7 @@ static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args
return result;
}
#if 1 || PY_VERSION_HEX < 0x030600B1
static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, int nargs, PyObject *kwargs) {
static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) {
PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);
PyObject *globals = PyFunction_GET_GLOBALS(func);
PyObject *argdefs = PyFunction_GET_DEFAULTS(func);
@ -10009,12 +10035,12 @@ static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args,
}
#if PY_MAJOR_VERSION >= 3
result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL,
args, nargs,
args, (int)nargs,
k, (int)nk,
d, (int)nd, kwdefs, closure);
#else
result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL,
args, nargs,
args, (int)nargs,
k, (int)nk,
d, (int)nd, closure);
#endif

View file

@ -2,6 +2,7 @@ import dis
from opcode import opmap, EXTENDED_ARG, HAVE_ARGUMENT
from types import CodeType
from _pydev_bundle import pydev_log
from _pydevd_bundle.pydevd_constants import IS_PY38_OR_GREATER
MAX_BYTE = 255
RETURN_VALUE_SIZE = 2
@ -270,8 +271,17 @@ def _insert_code(code_to_modify, code_to_insert, before_line):
pydev_log.exception()
return False, code_to_modify
new_code = CodeType(
args = [
code_to_modify.co_argcount, # integer
]
if IS_PY38_OR_GREATER:
# New argument on Python 3.8
args.append(
code_to_modify.co_posonlyargcount, # integer
)
args.extend((
code_to_modify.co_kwonlyargcount, # integer
len(new_vars), # integer
code_to_modify.co_stacksize, # integer
@ -286,5 +296,7 @@ def _insert_code(code_to_modify, code_to_insert, before_line):
new_lnotab, # bytes
code_to_modify.co_freevars, # tuple
code_to_modify.co_cellvars # tuple
)
))
new_code = CodeType(*args)
return True, new_code

View file

@ -27,8 +27,8 @@ DWORD GetPythonThreadId(PythonVersion version, PyThreadState* curThread) {
threadId = (DWORD)((PyThreadState_30_33*)curThread)->thread_id;
} else if (PyThreadState_34_36::IsFor(version)) {
threadId = (DWORD)((PyThreadState_34_36*)curThread)->thread_id;
} else if (PyThreadState_37::IsFor(version)) {
threadId = (DWORD)((PyThreadState_37*)curThread)->thread_id;
} else if (PyThreadState_37_38::IsFor(version)) {
threadId = (DWORD)((PyThreadState_37_38*)curThread)->thread_id;
}
return threadId;
}

View file

@ -149,7 +149,7 @@ InternalTraceTrampoline_37(PyObject *self, PyFrameObject *frame,
void InternalPySetTrace_37(PyThreadState* curThread, PyObjectHolder* traceFunc, bool isDebug)
{
PyThreadState_37* tstate = reinterpret_cast<PyThreadState_37*>(curThread);
PyThreadState_37_38* tstate = reinterpret_cast<PyThreadState_37_38*>(curThread);
PyObject *temp = tstate->c_traceobj;
// We can't increase _Py_TracingPossible. Everything else should be equal to CPython.

View file

@ -17,7 +17,8 @@ enum PythonVersion {
PythonVersion_34 = 0x0304,
PythonVersion_35 = 0x0305,
PythonVersion_36 = 0x0306,
PythonVersion_37 = 0x0307
PythonVersion_37 = 0x0307,
PythonVersion_38 = 0x0308
};
@ -65,6 +66,7 @@ static PythonVersion GetPythonVersion(void *module) {
case '5': return PythonVersion_35;
case '6': return PythonVersion_36;
case '7': return PythonVersion_37;
case '8': return PythonVersion_38;
}
}
}

View file

@ -191,14 +191,74 @@ public:
void *co_zombieframe; /* for optimization only (see frameobject.c) */
static bool IsFor(int majorVersion, int minorVersion) {
return majorVersion == 3 && minorVersion >= 7;
return majorVersion == 3 && minorVersion == 7;
}
static bool IsFor(PythonVersion version) {
return version >= PythonVersion_37;
return version == PythonVersion_37;
}
};
typedef struct _PyOpcache _PyOpcache;
// 3.8
class PyCodeObject38 : public PyObject {
public:
int co_argcount; /* #arguments, except *args */
int co_posonlyargcount; /* #positional only arguments */
int co_kwonlyargcount; /* #keyword only arguments */
int co_nlocals; /* #local variables */
int co_stacksize; /* #entries needed for evaluation stack */
int co_flags; /* CO_..., see below */
int co_firstlineno; /* first source line number */
PyObject *co_code; /* instruction opcodes */
PyObject *co_consts; /* list (constants used) */
PyObject *co_names; /* list of strings (names used) */
PyObject *co_varnames; /* tuple of strings (local variable names) */
PyObject *co_freevars; /* tuple of strings (free variable names) */
PyObject *co_cellvars; /* tuple of strings (cell variable names) */
/* The rest aren't used in either hash or comparisons, except for co_name,
used in both. This is done to preserve the name and line number
for tracebacks and debuggers; otherwise, constant de-duplication
would collapse identical functions/lambdas defined on different lines.
*/
SSIZE_T *co_cell2arg; /* Maps cell vars which are arguments. */
PyObject *co_filename; /* unicode (where it was loaded from) */
PyObject *co_name; /* unicode (name, for reference) */
PyObject *co_lnotab; /* string (encoding addr<->lineno mapping) See
Objects/lnotab_notes.txt for details. */
void *co_zombieframe; /* for optimization only (see frameobject.c) */
PyObject *co_weakreflist; /* to support weakrefs to code objects */
/* Scratch space for extra data relating to the code object.
Type is a void* to keep the format private in codeobject.c to force
people to go through the proper APIs. */
void *co_extra;
/* Per opcodes just-in-time cache
*
* To reduce cache size, we use indirect mapping from opcode index to
* cache object:
* cache = co_opcache[co_opcache_map[next_instr - first_instr] - 1]
*/
// co_opcache_map is indexed by (next_instr - first_instr).
// * 0 means there is no cache for this opcode.
// * n > 0 means there is cache in co_opcache[n-1].
unsigned char *co_opcache_map;
_PyOpcache *co_opcache;
int co_opcache_flag; // used to determine when create a cache.
unsigned char co_opcache_size; // length of co_opcache.
static bool IsFor(int majorVersion, int minorVersion) {
return majorVersion == 3 && minorVersion == 8;
}
static bool IsFor(PythonVersion version) {
return version == PythonVersion_38;
}
};
// 2.5 - 3.7
class PyFunctionObject : public PyObject {
public:
@ -291,7 +351,7 @@ public:
}
};
class PyFrameObject37 : public PyFrameObject {
class PyFrameObject37_38 : public PyFrameObject {
public:
char f_trace_lines; /* Emit per-line trace events? */
char f_trace_opcodes; /* Emit per-opcode trace events? */
@ -604,7 +664,7 @@ struct _PyErr_StackItem {
struct _PyErr_StackItem *previous_item;
};
class PyThreadState_37 : public PyThreadState {
class PyThreadState_37_38 : public PyThreadState {
public:
PyThreadState * prev;
PyThreadState *next;

View file

@ -109,7 +109,7 @@ def restore_sys_set_trace_func():
def load_python_helper_lib():
if not IS_CPYTHON or ctypes is None or sys.version_info[:2] > (3, 7):
if not IS_CPYTHON or ctypes is None or sys.version_info[:2] > (3, 8):
return None
if IS_WINDOWS:

View file

@ -66,19 +66,42 @@ def build_extension(dir_name, extension_name, target_pydevd_name, force_cython,
try:
if force_cython:
from Cython.Build import cythonize # @UnusedImport
ext_modules = cythonize([
# Generate the .c files in cythonize (will not compile at this point).
cythonize([
"%s/%s.pyx" % (dir_name, target_pydevd_name,),
])
else:
# Always compile the .c (and not the .pyx) file (which we should keep up-to-date by running build_tools/build.py).
from distutils.extension import Extension
ext_modules = [Extension("%s%s.%s" % (dir_name, "_ext" if extended else "", target_pydevd_name,),
[os.path.join(dir_name, "%s.c" % target_pydevd_name), ],
# uncomment to generate pdbs for visual studio.
# extra_compile_args=["-Zi", "/Od"],
# extra_link_args=["-debug"],
)]
# This is needed in CPython 3.8 to access PyInterpreterState.eval_frame.
# i.e.: we change #include "pystate.h" to also #include "internal/pycore_pystate.h"
# if compiling on Python 3.8.
c_files = [os.path.join(dir_name, "%s.c" % target_pydevd_name), ]
for c_file in c_files:
with open(c_file, 'r') as stream:
c_file_contents = stream.read()
c_file_contents = c_file_contents.replace('#include "pystate.h"', '''#include "pystate.h"
#if PY_VERSION_HEX >= 0x03080000
#include "internal/pycore_pystate.h"
#endif
''')
c_file_contents = c_file_contents.replace('\r\n', '\n').replace('\r', '\n')
with open(c_file, 'w') as stream:
stream.write(c_file_contents)
# Always compile the .c (and not the .pyx) file (which we should keep up-to-date by running build_tools/build.py).
from distutils.extension import Extension
ext_modules = [Extension("%s%s.%s" % (dir_name, "_ext" if extended else "", target_pydevd_name,),
c_files,
# uncomment to generate pdbs for visual studio.
# extra_compile_args=["-Zi", "/Od"],
# extra_link_args=["-debug"],
)]
# This is needed in CPython 3.8 to be able to include internal/pycore_pystate.h
# (needed to set PyInterpreterState.eval_frame).
for module in ext_modules:
module.define_macros = [('Py_BUILD_CORE_MODULE', '1')]
setup(
name='Cythonize',
ext_modules=ext_modules

View file

@ -7,31 +7,33 @@ from _pydev_imps._pydev_saved_modules import thread
start_new_thread = thread.start_new_thread
IS_PYTHON_3_ONWARDS = sys.version_info[0] >= 3
IS_JYTHON = sys.platform.find('java') != -1
try:
import __builtin__ #@UnusedImport
import __builtin__ # @UnusedImport
BUILTIN_MOD = '__builtin__'
except ImportError:
BUILTIN_MOD = 'builtins'
if not IS_JYTHON:
import pycompletionserver
import socket
if not IS_PYTHON_3_ONWARDS:
from urllib import quote_plus, unquote_plus
def send(s, msg):
s.send(msg)
else:
from urllib.parse import quote_plus, unquote_plus #Python 3.0
from urllib.parse import quote_plus, unquote_plus # Python 3.0
def send(s, msg):
s.send(bytearray(msg, 'utf-8'))
import unittest
@pytest.mark.skipif(IS_JYTHON, reason='Not applicable to Jython')
class TestCPython(unittest.TestCase):
@ -60,7 +62,7 @@ class TestCPython(unittest.TestCase):
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((pycompletionserver.HOST, 0))
server.listen(1) #socket to receive messages.
server.listen(1) # socket to receive messages.
t = pycompletionserver.CompletionServer(server.getsockname()[1])
t.exit_process_on_kill = False
@ -70,7 +72,6 @@ class TestCPython(unittest.TestCase):
return t, s
def read_msg(self):
finish = False
msg = ''
@ -93,21 +94,22 @@ class TestCPython(unittest.TestCase):
self.socket = socket
try:
#now that we have the connections all set up, check the code completion messages.
# now that we have the connections all set up, check the code completion messages.
msg = quote_plus('math')
send(socket, '@@IMPORTS:%sEND@@' % msg) #math completions
send(socket, '@@IMPORTS:%sEND@@' % msg) # math completions
completions = self.read_msg()
#print_ unquote_plus(completions)
# print_ unquote_plus(completions)
#math is a builtin and because of that, it starts with None as a file
# math is a builtin and because of that, it starts with None as a file
start = '@@COMPLETIONS(None,(__doc__,'
start_2 = '@@COMPLETIONS(None,(__name__,'
if ('/math.so,' in completions or
'/math.cpython-33m.so,' in completions or
'/math.cpython-34m.so,' in completions or
'math.cpython-35m' in completions or
'/math.cpython-33m.so,' in completions or
'/math.cpython-34m.so,' in completions or
'math.cpython-35m' in completions or
'math.cpython-36m' in completions or
'math.cpython-37m' in completions
'math.cpython-37m' in completions or
'math.cpython-38' in completions
):
return
self.assertTrue(completions.startswith(start) or completions.startswith(start_2), '%s DOESNT START WITH %s' % (completions, (start, start_2)))
@ -115,16 +117,15 @@ class TestCPython(unittest.TestCase):
self.assertTrue('@@COMPLETIONS' in completions)
self.assertTrue('END@@' in completions)
#now, test i
# now, test i
msg = quote_plus('%s.list' % BUILTIN_MOD)
send(socket, "@@IMPORTS:%s\nEND@@" % msg)
found = self.read_msg()
self.assertTrue('sort' in found, 'Could not find sort in: %s' % (found,))
#now, test search
# now, test search
msg = quote_plus('inspect.ismodule')
send(socket, '@@SEARCH%sEND@@' % msg) #math completions
send(socket, '@@SEARCH%sEND@@' % msg) # math completions
found = self.read_msg()
self.assertTrue('inspect.py' in found)
for i in range(33, 100):
@ -133,21 +134,21 @@ class TestCPython(unittest.TestCase):
else:
self.fail('Could not find the ismodule line in %s' % (found,))
#now, test search
# now, test search
msg = quote_plus('inspect.CO_NEWLOCALS')
send(socket, '@@SEARCH%sEND@@' % msg) #math completions
send(socket, '@@SEARCH%sEND@@' % msg) # math completions
found = self.read_msg()
self.assertTrue('inspect.py' in found)
self.assertTrue('CO_NEWLOCALS' in found)
#now, test search
# now, test search
msg = quote_plus('inspect.BlockFinder.tokeneater')
send(socket, '@@SEARCH%sEND@@' % msg)
found = self.read_msg()
self.assertTrue('inspect.py' in found)
# self.assertTrue('CO_NEWLOCALS' in found)
#reload modules test
# reload modules test
# send(socket, '@@RELOAD_MODULES_END@@')
# ok = self.read_msg()
# self.assertEqual('@@MSG_OK_END@@' , ok)
@ -158,11 +159,9 @@ class TestCPython(unittest.TestCase):
sys.stdout.write('succedded...sending kill msg\n')
self.send_kill_msg(socket)
# while not hasattr(t, 'ended'):
# pass #wait until it receives the message and quits.
socket.close()
self.socket.close()
except:
@ -171,4 +170,3 @@ class TestCPython(unittest.TestCase):
def send_kill_msg(self, socket):
socket.send(pycompletionserver.MSG_KILL_SERVER)

View file

@ -142,6 +142,7 @@ class TestCPython(unittest.TestCase):
'(o: object, name: str, val: object)',
'(source, filename, mode, flags, dont_inherit, optimize)',
'(source, filename, mode, flags, dont_inherit)',
'(source, filename, mode, flags, dont_inherit, optimize, _feature_version=-1)'
) # args
t = self.assert_in('setattr' , tip)
@ -171,7 +172,11 @@ class TestCPython(unittest.TestCase):
self.assert_args('walk', '(tree, visitor, walker, verbose)', tip)
self.assert_in('parseFile' , tip)
else:
self.assert_args('parse', '(source, filename, mode)', tip)
self.assert_args('parse', [
'(source, filename, mode)',
'(source, filename, mode, type_comments=False, feature_version=None)'
], tip
)
self.assert_args('walk', '(node)', tip)
self.assert_in('parse' , tip)
@ -182,10 +187,16 @@ class TestCPython(unittest.TestCase):
self.fail('Found: %s. Expected: %s' % (t[2], expected))
def assert_args(self, tok, args, tips):
if not isinstance(args, (list, tuple)):
args = (args,)
for a in tips[1]:
if tok == a[0]:
self.assertEqual(args, a[2])
return
for arg in args:
if arg == a[2]:
return
raise AssertionError('%s not in %s', a[2], args)
raise AssertionError('%s not in %s', tok, tips)
def assert_in(self, tok, tips):

View file

@ -164,11 +164,18 @@ def test_collect_try_except_info(data_regression):
if key.startswith('_method'):
info = collect_try_except_info(method.__code__, use_func_first_line=True)
if sys.version_info[:2] >= (3, 7):
for try_except_info in info:
# On 3.7 the last bytecode actually has a different start line.
if try_except_info.except_end_line == 8:
try_except_info.except_end_line = 9
if key == "_method_try_except":
if sys.version_info[:2] == (3, 7):
for try_except_info in info:
# On 3.7 the last bytecode actually has a different start line.
if try_except_info.except_end_line == 8:
try_except_info.except_end_line = 9
elif sys.version_info[:2] >= (3, 8):
for try_except_info in info:
# On 3.8 the last bytecode actually has a different start line.
if try_except_info.except_end_line == 7:
try_except_info.except_end_line = 9
method_to_info[key] = [str(x) for x in info]

View file

@ -1,3 +1,4 @@
from _pydevd_bundle.pydevd_constants import IS_WINDOWS
def test_in_project_roots(tmpdir):
@ -129,6 +130,10 @@ def test_glob_matching():
assert glob_matches_path(build('/a/b/c/d.py'), '/**/*.py', sep, altsep)
assert glob_matches_path(build('/a/b/c/d.py'), '**/c/*.py', sep, altsep)
if IS_WINDOWS:
assert glob_matches_path(build('/a/b/c/d.py'), '**/C/*.py', sep, altsep)
assert glob_matches_path(build('/a/b/C/d.py'), '**/c/*.py', sep, altsep)
# Expected not to match.
assert not glob_matches_path(build('/a/b/c/d'), '/**/d.py', sep, altsep)
assert not glob_matches_path(build('/a/b/c/d.pyx'), '/a/**/c/*.py', sep, altsep)

View file

@ -201,6 +201,18 @@ def _check_tracing_other_threads():
except ImportError:
import thread as _thread
# This method is called in a subprocess, so, make sure we exit properly even if we somehow
# deadlock somewhere else.
def dump_threads_and_kill_on_timeout():
time.sleep(10)
from _pydevd_bundle import pydevd_utils
pydevd_utils.dump_threads()
time.sleep(1)
import os
os._exit(77)
_thread.start_new_thread(dump_threads_and_kill_on_timeout, ())
def method():
while True:
trace_func = sys.gettrace()
@ -215,6 +227,7 @@ def _check_tracing_other_threads():
threads = []
threads.append(threading.Thread(target=method))
threads[-1].daemon = True
threads[-1].start()
_thread.start_new_thread(dummy_thread_method, ())

View file

@ -15,7 +15,6 @@ from tests import debug, test_data
from tests.debug import runners, targets
from tests.patterns import some
bp_root = test_data / "bp"
@ -102,6 +101,7 @@ def test_conditional_breakpoint(pyfile, target, run, condition_kind, condition):
def test_crossfile_breakpoint(pyfile, target, run):
@pyfile
def script1():
import debug_me # noqa
@ -171,6 +171,7 @@ def test_error_in_condition(pyfile, target, run, error_name):
@pytest.mark.parametrize("condition", ["condition", ""])
def test_log_point(pyfile, target, run, condition):
@pyfile
def code_to_debug():
import debug_me # noqa
@ -246,6 +247,7 @@ def test_package_launch(run):
def test_add_and_remove_breakpoint(pyfile, target, run):
@pyfile
def code_to_debug():
import debug_me # noqa
@ -277,6 +279,7 @@ def test_add_and_remove_breakpoint(pyfile, target, run):
def test_breakpoint_in_nonexistent_file(pyfile, target, run):
@pyfile
def code_to_debug():
import debug_me # noqa
@ -297,6 +300,7 @@ def test_breakpoint_in_nonexistent_file(pyfile, target, run):
def test_invalid_breakpoints(pyfile, target, run):
@pyfile
def code_to_debug():
import debug_me # noqa
@ -328,7 +332,11 @@ def test_invalid_breakpoints(pyfile, target, run):
bps = session.set_breakpoints(code_to_debug, bp_markers)
actual_lines = [bp["line"] for bp in bps]
expected_markers = ["bp1-expected", "bp2-expected", "bp3-expected"]
if sys.version_info >= (3, 8):
# See: https://bugs.python.org/issue38508
expected_markers = ["bp1-expected", "bp2-requested", "bp3-expected"]
else:
expected_markers = ["bp1-expected", "bp2-expected", "bp3-expected"]
if sys.version_info < (3,):
expected_markers += ["bp4-expected", "bp4-expected"]
expected_lines = [
@ -343,6 +351,12 @@ def test_invalid_breakpoints(pyfile, target, run):
# If there's multiple breakpoints on the same line, we only stop once,
# so remove duplicates first.
expected_lines = sorted(set(expected_lines))
if sys.version_info >= (3, 8):
# We'll actually hit @bp3-expected and later @bp2-requested
# (there's a line event when the list creation is finished
# at the start of the list creation on 3.8).
# See: https://bugs.python.org/issue38508
expected_lines[1], expected_lines[2] = expected_lines[2], expected_lines[1]
while expected_lines:
expected_line = expected_lines.pop(0)
@ -354,6 +368,7 @@ def test_invalid_breakpoints(pyfile, target, run):
def test_deep_stacks(pyfile, target, run):
@pyfile
def code_to_debug():
import debug_me # noqa