From ddcafa4fe148506acf973709417130243a92f36b Mon Sep 17 00:00:00 2001 From: Adam Yoblick Date: Tue, 15 Feb 2022 17:24:21 -0600 Subject: [PATCH 1/4] Add support for python 3.10. Compiles, no testing done yet. --- .../Interpreters/PythonLanguageVersion.cs | 4 +- .../Debugger.Concord/PythonRuntimeInfo.cs | 1 + .../ConfigurationExtension.xaml.cs | 2 + .../Product/PyDebugAttach/PyDebugAttach.cpp | 28 +- .../AddCondaEnvironmentControl.xaml | 3 + .../AddExistingEnvironmentView.cs | 2 + Python/Product/VsPyProf/PythonApi.cpp | 26 +- Python/Product/VsPyProf/python.h | 287 +++++++++++++++--- .../Utilities.Python.Analysis/PythonPaths.cs | 2 + 9 files changed, 289 insertions(+), 66 deletions(-) diff --git a/Python/Product/Cookiecutter/Shared/Interpreters/PythonLanguageVersion.cs b/Python/Product/Cookiecutter/Shared/Interpreters/PythonLanguageVersion.cs index 6e350ae5d7..73a200bf56 100644 --- a/Python/Product/Cookiecutter/Shared/Interpreters/PythonLanguageVersion.cs +++ b/Python/Product/Cookiecutter/Shared/Interpreters/PythonLanguageVersion.cs @@ -38,7 +38,8 @@ public enum PythonLanguageVersion { V36 = 0x0306, V37 = 0x0307, V38 = 0x0308, - V39 = 0x0309 + V39 = 0x0309, + V310 = 0x0310 } public static class PythonLanguageVersionExtensions { @@ -85,6 +86,7 @@ public static PythonLanguageVersion ToLanguageVersion(this Version version) { case 7: return PythonLanguageVersion.V37; case 8: return PythonLanguageVersion.V38; case 9: return PythonLanguageVersion.V39; + case 10: return PythonLanguageVersion.V310; } break; } diff --git a/Python/Product/Debugger.Concord/PythonRuntimeInfo.cs b/Python/Product/Debugger.Concord/PythonRuntimeInfo.cs index b1ee5b48b7..aefc17cafe 100644 --- a/Python/Product/Debugger.Concord/PythonRuntimeInfo.cs +++ b/Python/Product/Debugger.Concord/PythonRuntimeInfo.cs @@ -75,6 +75,7 @@ public static PythonLanguageVersion GetPythonLanguageVersion(DkmNativeModuleInst case "37": return PythonLanguageVersion.V37; case "38": return PythonLanguageVersion.V38; case "39": return PythonLanguageVersion.V39; + case "310": return PythonLanguageVersion.V310; default: return PythonLanguageVersion.None; } } diff --git a/Python/Product/EnvironmentsList/ConfigurationExtension.xaml.cs b/Python/Product/EnvironmentsList/ConfigurationExtension.xaml.cs index ffa08ea8db..173b181664 100644 --- a/Python/Product/EnvironmentsList/ConfigurationExtension.xaml.cs +++ b/Python/Product/EnvironmentsList/ConfigurationExtension.xaml.cs @@ -331,6 +331,8 @@ sealed class ConfigurationEnvironmentView : INotifyPropertyChanged { "3.6", "3.7", "3.8", + "3.9", + "3.10" }; private readonly EnvironmentView _view; diff --git a/Python/Product/PyDebugAttach/PyDebugAttach.cpp b/Python/Product/PyDebugAttach/PyDebugAttach.cpp index 913d0a18e3..051ecd03ba 100644 --- a/Python/Product/PyDebugAttach/PyDebugAttach.cpp +++ b/Python/Product/PyDebugAttach/PyDebugAttach.cpp @@ -659,6 +659,8 @@ DWORD GetPythonThreadId(PythonVersion version, PyThreadState* curThread) { threadId = (DWORD)((PyThreadState_34_36*)curThread)->thread_id; } else if (PyThreadState_37::IsFor(version)) { threadId = (DWORD)((PyThreadState_37*)curThread)->thread_id; + } else if (PyThreadState_310::IsFor(version)) { + threadId = (DWORD)((PyThreadState_310*)curThread)->thread_id; } return threadId; } @@ -1103,6 +1105,8 @@ bool DoAttach(HMODULE module, ConnectionInfo& connInfo, bool isDebug) { frame = ((PyThreadState_34_36*)curThread)->frame; } else if (PyThreadState_37::IsFor(version)) { frame = ((PyThreadState_37*)curThread)->frame; + } else if (PyThreadState_310::IsFor(version)) { + frame = ((PyThreadState_310*)curThread)->frame; } else { _ASSERTE(false); frame = nullptr; // prevent compiler warning @@ -1151,13 +1155,29 @@ bool DoAttach(HMODULE module, ConnectionInfo& connInfo, bool isDebug) { // update all of the frames so they have our trace func auto curFrame = (PyFrameObject*)GetPyObjectPointerNoDebugInfo(isDebug, frame); while (curFrame != nullptr) { + + PyObject **f_trace = nullptr; + + if (PyFrameObject25_33::IsFor(version)) { + f_trace = &((PyFrameObject25_33*)curFrame)->f_trace; + } else if (PyFrameObject34_36::IsFor(version)) { + f_trace = &((PyFrameObject34_36*)curFrame)->f_trace; + } else if (PyFrameObject37_39::IsFor(version)) { + f_trace = &((PyFrameObject37_39*)curFrame)->f_trace; + } else if (PyFrameObject310::IsFor(version)) { + f_trace = &((PyFrameObject310*)curFrame)->f_trace; + } else { + _ASSERTE(false); + break; + } + // Special case for CFrame objects // Stackless CFrame does not have a trace function // This will just prevent a crash on attach. if (((PyObject*)curFrame)->ob_type != PyCFrame_Type) { - DecRef(curFrame->f_trace, isDebug); + DecRef(*f_trace, isDebug); IncRef(*traceFunc); - curFrame->f_trace = traceFunc.ToPython(); + *f_trace = traceFunc.ToPython(); } curFrame = (PyFrameObject*)GetPyObjectPointerNoDebugInfo(isDebug, curFrame->f_back); } @@ -1312,6 +1332,8 @@ int TraceGeneral(int interpreterId, PyObject *obj, PyFrameObject *frame, int wha ((PyThreadState_34_36*)curThread)->c_tracefunc(((PyThreadState_34_36*)curThread)->c_traceobj, frame, what, arg); } else if (PyThreadState_37::IsFor(version)) { ((PyThreadState_37*)curThread)->c_tracefunc(((PyThreadState_37*)curThread)->c_traceobj, frame, what, arg); + } else if (PyThreadState_310::IsFor(version)) { + ((PyThreadState_310*)curThread)->c_tracefunc(((PyThreadState_310*)curThread)->c_traceobj, frame, what, arg); } } return 0; @@ -1359,6 +1381,8 @@ void SetInitialTraceFunc(DWORD interpreterId, PyThreadState *thread) { gilstate_counter = ((PyThreadState_34_36*)thread)->gilstate_counter; } else if (PyThreadState_37::IsFor(version)) { gilstate_counter = ((PyThreadState_37*)thread)->gilstate_counter; + } else if (PyThreadState_310::IsFor(version)) { + gilstate_counter = ((PyThreadState_310*)thread)->gilstate_counter; } if (gilstate_counter == 1) { diff --git a/Python/Product/PythonTools/PythonTools/Environments/AddCondaEnvironmentControl.xaml b/Python/Product/PythonTools/PythonTools/Environments/AddCondaEnvironmentControl.xaml index 0e4ef88b95..5880104b04 100644 --- a/Python/Product/PythonTools/PythonTools/Environments/AddCondaEnvironmentControl.xaml +++ b/Python/Product/PythonTools/PythonTools/Environments/AddCondaEnvironmentControl.xaml @@ -84,6 +84,9 @@ + + + diff --git a/Python/Product/PythonTools/PythonTools/Environments/AddExistingEnvironmentView.cs b/Python/Product/PythonTools/PythonTools/Environments/AddExistingEnvironmentView.cs index b5cf600c4e..12f453bdeb 100644 --- a/Python/Product/PythonTools/PythonTools/Environments/AddExistingEnvironmentView.cs +++ b/Python/Product/PythonTools/PythonTools/Environments/AddExistingEnvironmentView.cs @@ -63,6 +63,8 @@ ProjectView selectedProject "3.6", "3.7", "3.8", + "3.9", + "3.10" }; public static readonly DependencyProperty InterpretersProperty = diff --git a/Python/Product/VsPyProf/PythonApi.cpp b/Python/Product/VsPyProf/PythonApi.cpp index 6ba7e8a0a4..fb62eab252 100644 --- a/Python/Product/VsPyProf/PythonApi.cpp +++ b/Python/Product/VsPyProf/PythonApi.cpp @@ -80,22 +80,14 @@ VsPyProf* VsPyProf::Create(HMODULE pythonModule) { pyFuncType != NULL && pyModuleType != NULL) { auto version = getVersion(); if (version != NULL) { - // parse version like "2.7" - int major = atoi(version); - int minor = 0; - while (*version && *version >= '0' && *version <= '9') { - version++; - } - if (*version == '.') { - version++; - minor = atoi(version); - } - if ((major == 2 && (minor >= 4 && minor <= 7)) || - (major == 3 && (minor >= 0 && minor <= 9))) { + PythonVersionMajMin pythonVer = GetPythonVersionFromVersionString(version); + + if ((pythonVer.major == 2 && (pythonVer.minor >= 4 && pythonVer.minor <= 7)) || + (pythonVer.major == 3 && (pythonVer.minor >= 0 && pythonVer.minor <= 10))) { return new VsPyProf(pythonModule, - major, - minor, + pythonVer.major, + pythonVer.minor, enterFunction, exitFunction, nameToken, @@ -282,8 +274,10 @@ wstring VsPyProf::GetClassNameFromFrame(PyFrameObject* frameObj, PyObject *codeO self = ((PyFrameObject25_33*)frameObj)->f_localsplus[0]; } else if (PyFrameObject34_36::IsFor(MajorVersion, MinorVersion)) { self = ((PyFrameObject34_36*)frameObj)->f_localsplus[0]; - } else if (PyFrameObject37::IsFor(MajorVersion, MinorVersion)) { - self = ((PyFrameObject37*)frameObj)->f_localsplus[0]; + } else if (PyFrameObject37_39::IsFor(MajorVersion, MinorVersion)) { + self = ((PyFrameObject37_39*)frameObj)->f_localsplus[0]; + } else if (PyFrameObject310::IsFor(MajorVersion, MinorVersion)) { + self = ((PyFrameObject310*)frameObj)->f_localsplus[0]; } return GetClassNameFromSelf(self, codeObj); } diff --git a/Python/Product/VsPyProf/python.h b/Python/Product/VsPyProf/python.h index c7a0eb87bf..419283d74b 100644 --- a/Python/Product/VsPyProf/python.h +++ b/Python/Product/VsPyProf/python.h @@ -32,43 +32,81 @@ enum PythonVersion { PythonVersion_36 = 0x0306, PythonVersion_37 = 0x0307, PythonVersion_38 = 0x0308, - PythonVersion_39 = 0x0309 + PythonVersion_39 = 0x0309, + PythonVersion_310 = 0x0310 +}; + +struct PythonVersionMajMin { + int major; + int minor; }; typedef const char* (GetVersionFunc)(); +// Get the python version in major and minor parts from a version string +static PythonVersionMajMin GetPythonVersionFromVersionString(const char* version) { + + int major = atoi(version); + int minor = 0; + + while (*version && *version >= '0' && *version <= '9') { + version++; + } + if (*version == '.') { + version++; + minor = atoi(version); + } + + PythonVersionMajMin ver = {}; + ver.major = major; + ver.minor = minor; + + return ver; +} + static PythonVersion GetPythonVersion(HMODULE hMod) { auto versionFunc = (GetVersionFunc*)GetProcAddress(hMod, "Py_GetVersion"); - if (versionFunc != nullptr) { - auto version = versionFunc(); - if (version != nullptr && strlen(version) >= 3 && version[1] == '.') { - if (version[0] == '2') { - switch (version[2]) { - case '5': return PythonVersion_25; - case '6': return PythonVersion_26; - case '7': return PythonVersion_27; - } - } - else if (version[0] == '3') { - switch (version[2]) { - case '0': return PythonVersion_30; - case '1': return PythonVersion_31; - case '2': return PythonVersion_32; - case '3': return PythonVersion_33; - case '4': return PythonVersion_34; - case '5': return PythonVersion_35; - case '6': return PythonVersion_36; - case '7': return PythonVersion_37; - case '8': return PythonVersion_38; - case '9': return PythonVersion_39; - } - } + + // if we can't find the version function, we're done + if (versionFunc == nullptr) { + return PythonVersion_Unknown; + } + auto version = versionFunc(); + + // if the results of the version function are bad, we're done + if (version == nullptr || strlen(version) < 3 || version[1] != '.') { + return PythonVersion_Unknown; + } + + // get the python major and minor versions, parse them, and return the correct enum + PythonVersionMajMin pythonVer = GetPythonVersionFromVersionString(version); + + if (pythonVer.major == 2) { + switch (pythonVer.minor) { + case 5: return PythonVersion_25; + case 6: return PythonVersion_26; + case 7: return PythonVersion_27; } } + else if (pythonVer.major == 3) { + switch (pythonVer.minor) { + case 1: return PythonVersion_31; + case 2: return PythonVersion_32; + case 3: return PythonVersion_33; + case 4: return PythonVersion_34; + case 5: return PythonVersion_35; + case 6: return PythonVersion_36; + case 7: return PythonVersion_37; + case 8: return PythonVersion_38; + case 9: return PythonVersion_39; + case 10: return PythonVersion_310; + } + } + + // if we get here, the version doesn't match an expected value return PythonVersion_Unknown; } - // defines limited header of Python API for compatible access across a number of Pythons. class PyTypeObject; @@ -243,7 +281,7 @@ class PyCodeObject37 : public PyObject { } }; -// 3.8 - 3.9 +// 3.8 - 3.10 class PyCodeObject38 : public PyObject { public: int co_argcount; /* #arguments, except *args */ @@ -263,7 +301,10 @@ class PyCodeObject38 : public PyObject { 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) */ + union { + PyObject* co_lnotab; /* <= 3.9 string (encoding addr<->lineno mapping) */ + PyObject* co_linetable; /* >= 3.10 string (encoding addr<->lineno mapping) */ + }; void* co_zombieframe; /* for optimization only (see frameobject.c) */ static bool IsFor(int majorVersion, int minorVersion) { @@ -275,7 +316,8 @@ class PyCodeObject38 : public PyObject { } }; -// 2.5 - 3.9 +// 2.5 - 3.10 +// corresponds to the PyFunctionObject struct in include\funcobject.h in the CPython install class PyFunctionObject : public PyObject { public: PyObject *func_code; /* A code object */ @@ -298,7 +340,8 @@ class PyStringObject : public PyVarObject { */ }; -// 2.4 - 3.9 compatible +// 2.4 - 3.10 compatible +// corresponds to the PyASCIIObject struct in include\cpython\unicodeobject.h in the CPython install typedef struct { PyObject_HEAD size_t length; /* Length of raw Unicode data in buffer */ @@ -306,20 +349,16 @@ typedef struct { long hash; /* Hash value; -1 if not set */ } PyUnicodeObject; -// 2.4 - 3.9 compatible +// 2.4 - 3.10 compatible +// corresponds to the _frame struct in include\cpython\frameobject.h in the CPython install. class PyFrameObject : public PyVarObject { public: - PyFrameObject *f_back; /* previous frame, or NULL */ + PyFrameObject *f_back; /* previous frame, or NULL */ PyObject *f_code; /* code segment */ PyObject *f_builtins; /* builtin symbol table (PyDictObject) */ PyObject *f_globals; /* global symbol table (PyDictObject) */ PyObject *f_locals; /* local symbol table (any mapping) */ PyObject **f_valuestack; /* points after the last local */ - /* Next free slot in f_valuestack. Frame creation sets to f_valuestack. - Frame evaluation usually NULLs it, but a frame that yields sets it - to the current stack top. */ - PyObject **f_stacktop; - PyObject *f_trace; /* Trace function */ }; #define CO_MAXBLOCKS 20 @@ -331,6 +370,11 @@ typedef struct { class PyFrameObject25_33 : public PyFrameObject { public: + /* Next free slot in f_valuestack. Frame creation sets to f_valuestack. + Frame evaluation usually NULLs it, but a frame that yields sets it + to the current stack top. */ + PyObject **f_stacktop; + PyObject *f_trace; /* Trace function */ PyObject * f_exc_type, *f_exc_value, *f_exc_traceback; PyThreadState* f_tstate; int f_lasti; /* Last instruction if called */ @@ -345,10 +389,20 @@ class PyFrameObject25_33 : public PyFrameObject { return majorVersion == 2 && (minorVersion >= 5 && minorVersion <= 7) || majorVersion == 3 && (minorVersion >= 0 && minorVersion <= 3); } + + static bool IsFor(PythonVersion version) { + return ((version >= PythonVersion_25 && version <= PythonVersion_27) || + (version >= PythonVersion_30 && version <= PythonVersion_33)); + } }; class PyFrameObject34_36 : public PyFrameObject { public: + /* Next free slot in f_valuestack. Frame creation sets to f_valuestack. + Frame evaluation usually NULLs it, but a frame that yields sets it + to the current stack top. */ + PyObject **f_stacktop; + PyObject *f_trace; /* Trace function */ PyObject * f_exc_type, *f_exc_value, *f_exc_traceback; /* Borrowed reference to a generator, or NULL */ PyObject *f_gen; @@ -365,10 +419,20 @@ class PyFrameObject34_36 : public PyFrameObject { static bool IsFor(int majorVersion, int minorVersion) { return majorVersion == 3 && minorVersion >= 4 && minorVersion <= 6; } + + static bool IsFor(PythonVersion version) { + return version >= PythonVersion_34 && version <= PythonVersion_36; + } }; -class PyFrameObject37 : public PyFrameObject { +// 3.7 - 3.9 +class PyFrameObject37_39 : public PyFrameObject { public: + /* Next free slot in f_valuestack. Frame creation sets to f_valuestack. + Frame evaluation usually NULLs it, but a frame that yields sets it + to the current stack top. */ + PyObject **f_stacktop; + PyObject *f_trace; /* Trace function */ char f_trace_lines; /* Emit per-line trace events? */ char f_trace_opcodes; /* Emit per-opcode trace events? */ /* Borrowed reference to a generator, or NULL */ @@ -384,22 +448,73 @@ class PyFrameObject37 : public PyFrameObject { PyObject *f_localsplus[1]; /* locals+stack, dynamically sized */ static bool IsFor(int majorVersion, int minorVersion) { - return majorVersion == 3 && minorVersion >= 7; + return majorVersion == 3 && (minorVersion >= 7 && minorVersion <= 9); + } + + static bool IsFor(PythonVersion version) { + return version >= PythonVersion_37 && version <= PythonVersion_39; + } +}; + +enum _framestate { + FRAME_CREATED = -2, + FRAME_SUSPENDED = -1, + FRAME_EXECUTING = 0, + FRAME_RETURNED = 1, + FRAME_UNWINDING = 2, + FRAME_RAISED = 3, + FRAME_CLEARED = 4 +}; + +typedef signed char PyFrameState; + +// 3.10 +// corresponds to the _frame struct in include\cpython\frameobject.h in the CPython install. +class PyFrameObject310 : public PyFrameObject { +public: + PyObject *f_trace; /* Trace function */ + int f_stackdepth; /* Depth of value stack */ + char f_trace_lines; /* Emit per-line trace events? */ + char f_trace_opcodes; /* Emit per-opcode trace events? */ + + /* Borrowed reference to a generator, or NULL */ + PyObject *f_gen; + + int f_lasti; /* Last instruction if called */ + /* As of 2.3 f_lineno is only valid when tracing is active (i.e. when + f_trace is set) -- at other times use PyCode_Addr2Line instead. */ + int f_lineno; /* Current line number */ + int f_iblock; /* index in f_blockstack */ + PyFrameState f_state; /* What state the frame is in */ + PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */ + PyObject *f_localsplus[1]; /* locals+stack, dynamically sized */ + + static bool IsFor(int majorVersion, int minorVersion) { + return majorVersion == 3 && minorVersion >= 10; + } + + static bool IsFor(PythonVersion version) { + return version >= PythonVersion_310; } }; typedef void (*destructor)(PyObject *); -// 2.4 - 3.9 +// 2.4 - 3.10 +// corresponds to the PyMethodDef struct in include\methodobject.h in the CPython install class PyMethodDef { public: char *ml_name; /* The name of the built-in function/method */ + PyObject *m_self; + PyObject *m_module; + PyObject *m_reflist; }; // -// 2.5 - 3.9 +// 2.5 - 3.10 +// corresponds to the _typeobject struct in include\cpython\object.h in the CPython install // While these are compatible there are fields only available on later versions. class PyTypeObject : public PyVarObject { public: @@ -409,12 +524,15 @@ class PyTypeObject : public PyVarObject { /* Methods to implement standard operations */ destructor tp_dealloc; - void *tp_print; // 3.8: Py_ssize_t tp_vectorcall_offset; (same size as void*) + union { + void* tp_print; // < 3.8 + void* tp_vectorcall_offset; // >= 3.8 + }; void *tp_getattr; void *tp_setattr; union { void *tp_compare; /* 2.4 - 3.4 */ - void *tp_as_async; /* 3.5 - 3.7 */ + void *tp_as_async; /* > 3.5 */ }; void *tp_repr; @@ -484,7 +602,8 @@ class PyTypeObject : public PyVarObject { unsigned int tp_version_tag; }; -// 2.4 - 3.9 +// 2.4 - 3.10 +// corresponds to the PyTupleObject struct in include\cpython\tupleobject.h in the CPython install class PyTupleObject : public PyVarObject { public: PyObject *ob_item[1]; @@ -495,7 +614,8 @@ class PyTupleObject : public PyVarObject { */ }; -// 2.4 - 3.9 +// 2.4 - 3.10 +// corresponds to the PyCFunctionObject struct in include\cpython\methodobject.h in the CPython install class PyCFunctionObject : public PyObject { public: PyMethodDef *m_ml; /* Description of the C function to call */ @@ -680,6 +800,7 @@ struct _PyErr_StackItem { struct _PyErr_StackItem *previous_item; }; +// 3.7 - 3.9 class PyThreadState_37 : public PyThreadState { public: PyThreadState * prev; @@ -721,11 +842,83 @@ class PyThreadState_37 : public PyThreadState { unsigned long thread_id; /* Thread id where this tstate was created */ static bool IsFor(int majorVersion, int minorVersion) { - return majorVersion == 3 && minorVersion >= 7; + return majorVersion == 3 && (minorVersion >= 7 && minorVersion <= 9); + } + + static bool IsFor(PythonVersion version) { + return version >= PythonVersion_37 && version <= PythonVersion_39; + } +}; + +typedef struct _cframe { + /* This struct will be threaded through the C stack + * allowing fast access to per-thread state that needs + * to be accessed quickly by the interpreter, but can + * be modified outside of the interpreter. + * + * WARNING: This makes data on the C stack accessible from + * heap objects. Care must be taken to maintain stack + * discipline and make sure that instances of this struct cannot + * accessed outside of their lifetime. + */ + int use_tracing; + struct _cframe *previous; +} CFrame; + +// 3.10 +// corresponds to the _ts struct in include\cpython\pystate.h in the CPython install +class PyThreadState_310 : public PyThreadState { +public: + PyThreadState * prev; + PyThreadState *next; + PyInterpreterState *interp; + + PyFrameObject *frame; + int recursion_depth; + int recursion_headroom; /* Allow 50 more calls to handle any errors. */ + int stackcheck_counter; + + /* 'tracing' keeps track of the execution depth when tracing/profiling. + This is to prevent the actual trace/profile code from being recorded in + the trace/profile. */ + int tracing; + + /* Pointer to current CFrame in the C stack frame of the currently, + * or most recently, executing _PyEval_EvalFrameDefault. */ + CFrame *cframe; + + Py_tracefunc c_profilefunc; + Py_tracefunc c_tracefunc; + PyObject *c_profileobj; + PyObject *c_traceobj; + + /* The exception currently being raised */ + PyObject *curexc_type; + PyObject *curexc_value; + PyObject *curexc_traceback; + + /* The exception currently being handled, if no coroutines/generators + * are present. Always last element on the stack referred to be exc_info. + */ + _PyErr_StackItem exc_state; + + /* Pointer to the top of the stack of the exceptions currently + * being handled */ + _PyErr_StackItem *exc_info; + + PyObject *dict; /* Stores per-thread state */ + + int gilstate_counter; + + PyObject *async_exc; /* Asynchronous exception to raise */ + unsigned long thread_id; /* Thread id where this tstate was created */ + + static bool IsFor(int majorVersion, int minorVersion) { + return majorVersion == 3 && minorVersion >= 10; } static bool IsFor(PythonVersion version) { - return version >= PythonVersion_37; + return version >= PythonVersion_310; } }; diff --git a/Python/Tests/Utilities.Python.Analysis/PythonPaths.cs b/Python/Tests/Utilities.Python.Analysis/PythonPaths.cs index 77b38ac08a..d9c70d3808 100644 --- a/Python/Tests/Utilities.Python.Analysis/PythonPaths.cs +++ b/Python/Tests/Utilities.Python.Analysis/PythonPaths.cs @@ -45,12 +45,14 @@ public class PythonPaths { public static readonly PythonVersion Python37 = GetCPythonVersion(PythonLanguageVersion.V37, InterpreterArchitecture.x86); public static readonly PythonVersion Python38 = GetCPythonVersion(PythonLanguageVersion.V38, InterpreterArchitecture.x86); public static readonly PythonVersion Python39 = GetCPythonVersion(PythonLanguageVersion.V39, InterpreterArchitecture.x86); + public static readonly PythonVersion Python310 = GetCPythonVersion(PythonLanguageVersion.V310, InterpreterArchitecture.x86); public static readonly PythonVersion Python27_x64 = GetCPythonVersion(PythonLanguageVersion.V27, InterpreterArchitecture.x64); public static readonly PythonVersion Python35_x64 = GetCPythonVersion(PythonLanguageVersion.V35, InterpreterArchitecture.x64); public static readonly PythonVersion Python36_x64 = GetCPythonVersion(PythonLanguageVersion.V36, InterpreterArchitecture.x64); public static readonly PythonVersion Python37_x64 = GetCPythonVersion(PythonLanguageVersion.V37, InterpreterArchitecture.x64); public static readonly PythonVersion Python38_x64 = GetCPythonVersion(PythonLanguageVersion.V38, InterpreterArchitecture.x64); public static readonly PythonVersion Python39_x64 = GetCPythonVersion(PythonLanguageVersion.V39, InterpreterArchitecture.x64); + public static readonly PythonVersion Python310_x64 = GetCPythonVersion(PythonLanguageVersion.V310, InterpreterArchitecture.x64); public static readonly PythonVersion Anaconda27 = GetAnacondaVersion(PythonLanguageVersion.V27, InterpreterArchitecture.x86); public static readonly PythonVersion Anaconda27_x64 = GetAnacondaVersion(PythonLanguageVersion.V27, InterpreterArchitecture.x64); public static readonly PythonVersion Anaconda36 = GetAnacondaVersion(PythonLanguageVersion.V36, InterpreterArchitecture.x86); From c1e4e6f91f61fd5ed3ab87991a493c58a03b778b Mon Sep 17 00:00:00 2001 From: Adam Yoblick Date: Wed, 23 Feb 2022 15:09:39 -0600 Subject: [PATCH 2/4] Update Microsoft.Python.Parsing package version --- Build/17.0/packages.config | 2 +- Python/Product/Core/Properties/AssemblyInfo.cs | 2 +- package-lock.json | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Build/17.0/packages.config b/Build/17.0/packages.config index b698ec79af..10751171a5 100644 --- a/Build/17.0/packages.config +++ b/Build/17.0/packages.config @@ -12,7 +12,7 @@ - + diff --git a/Python/Product/Core/Properties/AssemblyInfo.cs b/Python/Product/Core/Properties/AssemblyInfo.cs index d8182edee0..c6604bbb74 100644 --- a/Python/Product/Core/Properties/AssemblyInfo.cs +++ b/Python/Product/Core/Properties/AssemblyInfo.cs @@ -56,7 +56,7 @@ internal static class ParserNuGetPackageInfo { // important: keep in sync with Build\17.0\package.config - public const string Version = "0.646.0"; + public const string Version = "0.655.0"; public const string Culture = "neutral"; public const string PublicKeyToken = "b03f5f7f11d50a3a"; } diff --git a/package-lock.json b/package-lock.json index d3340010e8..5e3b29e59d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,9 +4,9 @@ "lockfileVersion": 1, "dependencies": { "@pylance/pylance": { - "version": "2022.1.0", - "resolved": "https://pkgs.dev.azure.com/devdiv/_packaging/Pylance/npm/registry/@pylance/pylance/-/pylance-2022.1.0.tgz", - "integrity": "sha1-YaKAsjTqbj5fhbZ5/d3CYQ5sPpg=", + "version": "2022.2.3", + "resolved": "https://pkgs.dev.azure.com/devdiv/_packaging/Pylance/npm/registry/@pylance/pylance/-/pylance-2022.2.3.tgz", + "integrity": "sha1-egf5e5lpsNQm7b9VnUDi1qPkOV4=", "dev": true } } From eb84e8e4a5a59526d4ea3382bdd14a8ee0951933 Mon Sep 17 00:00:00 2001 From: Adam Yoblick Date: Wed, 23 Feb 2022 16:52:13 -0600 Subject: [PATCH 3/4] Rename PyThreadState_37 to 37_39 to be consistent with naming convention --- Python/Product/VsPyProf/python.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/Product/VsPyProf/python.h b/Python/Product/VsPyProf/python.h index 419283d74b..e3d6047a4a 100644 --- a/Python/Product/VsPyProf/python.h +++ b/Python/Product/VsPyProf/python.h @@ -801,7 +801,7 @@ struct _PyErr_StackItem { }; // 3.7 - 3.9 -class PyThreadState_37 : public PyThreadState { +class PyThreadState_37_39 : public PyThreadState { public: PyThreadState * prev; PyThreadState *next; From 5a3a6cbba56318526d9a3112e0af3e084422f43d Mon Sep 17 00:00:00 2001 From: Adam Yoblick Date: Wed, 23 Feb 2022 16:55:35 -0600 Subject: [PATCH 4/4] Rename PyThreadState_37 to 37_39 to be consistent with naming convention --- Python/Product/PyDebugAttach/PyDebugAttach.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Python/Product/PyDebugAttach/PyDebugAttach.cpp b/Python/Product/PyDebugAttach/PyDebugAttach.cpp index 051ecd03ba..ed038b7ffb 100644 --- a/Python/Product/PyDebugAttach/PyDebugAttach.cpp +++ b/Python/Product/PyDebugAttach/PyDebugAttach.cpp @@ -657,8 +657,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_39::IsFor(version)) { + threadId = (DWORD)((PyThreadState_37_39*)curThread)->thread_id; } else if (PyThreadState_310::IsFor(version)) { threadId = (DWORD)((PyThreadState_310*)curThread)->thread_id; } @@ -1103,8 +1103,8 @@ bool DoAttach(HMODULE module, ConnectionInfo& connInfo, bool isDebug) { frame = ((PyThreadState_30_33*)curThread)->frame; } else if (PyThreadState_34_36::IsFor(version)) { frame = ((PyThreadState_34_36*)curThread)->frame; - } else if (PyThreadState_37::IsFor(version)) { - frame = ((PyThreadState_37*)curThread)->frame; + } else if (PyThreadState_37_39::IsFor(version)) { + frame = ((PyThreadState_37_39*)curThread)->frame; } else if (PyThreadState_310::IsFor(version)) { frame = ((PyThreadState_310*)curThread)->frame; } else { @@ -1330,8 +1330,8 @@ int TraceGeneral(int interpreterId, PyObject *obj, PyFrameObject *frame, int wha ((PyThreadState_30_33*)curThread)->c_tracefunc(((PyThreadState_30_33*)curThread)->c_traceobj, frame, what, arg); } else if (PyThreadState_34_36::IsFor(version)) { ((PyThreadState_34_36*)curThread)->c_tracefunc(((PyThreadState_34_36*)curThread)->c_traceobj, frame, what, arg); - } else if (PyThreadState_37::IsFor(version)) { - ((PyThreadState_37*)curThread)->c_tracefunc(((PyThreadState_37*)curThread)->c_traceobj, frame, what, arg); + } else if (PyThreadState_37_39::IsFor(version)) { + ((PyThreadState_37_39*)curThread)->c_tracefunc(((PyThreadState_37_39*)curThread)->c_traceobj, frame, what, arg); } else if (PyThreadState_310::IsFor(version)) { ((PyThreadState_310*)curThread)->c_tracefunc(((PyThreadState_310*)curThread)->c_traceobj, frame, what, arg); } @@ -1379,8 +1379,8 @@ void SetInitialTraceFunc(DWORD interpreterId, PyThreadState *thread) { gilstate_counter = ((PyThreadState_30_33*)thread)->gilstate_counter; } else if (PyThreadState_34_36::IsFor(version)) { gilstate_counter = ((PyThreadState_34_36*)thread)->gilstate_counter; - } else if (PyThreadState_37::IsFor(version)) { - gilstate_counter = ((PyThreadState_37*)thread)->gilstate_counter; + } else if (PyThreadState_37_39::IsFor(version)) { + gilstate_counter = ((PyThreadState_37_39*)thread)->gilstate_counter; } else if (PyThreadState_310::IsFor(version)) { gilstate_counter = ((PyThreadState_310*)thread)->gilstate_counter; }