Skip to content

Commit

Permalink
Remove special case for strings in pydevd_sys_monitoring
Browse files Browse the repository at this point in the history
  • Loading branch information
rchiodo authored Nov 9, 2024
1 parent cf2e47c commit 3e88fcc
Show file tree
Hide file tree
Showing 10 changed files with 4,457 additions and 3,077 deletions.
5 changes: 3 additions & 2 deletions _pydevd_bundle/pydevd_frame_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,15 @@ def short_frame(frame):

filename = frame.f_code.co_filename
name = splitext(basename(filename))[0]
return "%s::%s %s" % (name, frame.f_code.co_name, frame.f_lineno)
line = hasattr(frame, "f_lineno") and frame.f_lineno or 1
return "%s::%s %s" % (name, frame.f_code.co_name, line)


def short_stack(frame):
stack = []
while frame:
stack.append(short_frame(frame))
frame = frame.f_back
frame = frame.f_back if hasattr(frame, "f_back") else None
return "Stack: %s\n" % (" -> ".join(stack))


Expand Down
32 changes: 29 additions & 3 deletions _pydevd_sys_monitoring/_pydevd_sys_monitoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,15 +451,41 @@ def _get_thread_info(create: bool, depth: int) -> Optional[ThreadInfo]:
return _thread_local_info.thread_info


_CodeLineInfo = namedtuple("_CodeLineInfo", "line_to_offset, first_line, last_line")
# fmt: off
# IFDEF CYTHON
# cdef class _CodeLineInfo:
# cdef dict line_to_offset
# cdef int first_line
# cdef int last_line
# ELSE
class _CodeLineInfo:
line_to_offset: Dict[int, Any]
first_line: int
last_line: int
# ENDIF
# fmt: on

# fmt: off
# IFDEF CYTHON
# def __init__(self, dict line_to_offset, int first_line, int last_line):
# self.line_to_offset = line_to_offset
# self.first_line = first_line
# self.last_line = last_line
# ELSE
def __init__(self, line_to_offset, first_line, last_line):
self.line_to_offset = line_to_offset
self.first_line = first_line
self.last_line = last_line

# ENDIF
# fmt: on

# Note: this method has a version in cython too
# fmt: off
# IFDEF CYTHON
# cdef _get_code_line_info(code_obj, _cache={}):
# cdef _CodeLineInfo _get_code_line_info(code_obj, _cache={}):
# ELSE
def _get_code_line_info(code_obj, _cache={}):
def _get_code_line_info(code_obj, _cache={}) -> _CodeLineInfo:
# ENDIF
# fmt: on
try:
Expand Down
7,394 changes: 4,373 additions & 3,021 deletions _pydevd_sys_monitoring/_pydevd_sys_monitoring_cython.c

Large diffs are not rendered by default.

32 changes: 29 additions & 3 deletions _pydevd_sys_monitoring/_pydevd_sys_monitoring_cython.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -457,15 +457,41 @@ cdef _get_thread_info(bint create, int depth):
return _thread_local_info.thread_info


_CodeLineInfo = namedtuple("_CodeLineInfo", "line_to_offset, first_line, last_line")
# fmt: off
# IFDEF CYTHON -- DONT EDIT THIS FILE (it is automatically generated)
cdef class _CodeLineInfo:
cdef dict line_to_offset
cdef int first_line
cdef int last_line
# ELSE
# class _CodeLineInfo:
# line_to_offset: Dict[int, Any]
# first_line: int
# last_line: int
# ENDIF
# fmt: on

# fmt: off
# IFDEF CYTHON -- DONT EDIT THIS FILE (it is automatically generated)
def __init__(self, dict line_to_offset, int first_line, int last_line):
self.line_to_offset = line_to_offset
self.first_line = first_line
self.last_line = last_line
# ELSE
# def __init__(self, line_to_offset, first_line, last_line):
# self.line_to_offset = line_to_offset
# self.first_line = first_line
# self.last_line = last_line
#
# ENDIF
# fmt: on

# Note: this method has a version in cython too
# fmt: off
# IFDEF CYTHON -- DONT EDIT THIS FILE (it is automatically generated)
cdef _get_code_line_info(code_obj, _cache={}):
cdef _CodeLineInfo _get_code_line_info(code_obj, _cache={}):
# ELSE
# def _get_code_line_info(code_obj, _cache={}):
# def _get_code_line_info(code_obj, _cache={}) -> _CodeLineInfo:
# ENDIF
# fmt: on
try:
Expand Down
22 changes: 22 additions & 0 deletions pydev_ipython/qt_loaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,28 @@ def has_binding(api):
return check_version(mod.__version__, "1.0.3")
else:
return True

except ModuleNotFoundError:
from importlib import machinery

# importing top level PyQt4/PySide module is ok...
mod = __import__(module_name)

# ...importing submodules is not
loader_details = (machinery.ExtensionFileLoader, machinery.EXTENSION_SUFFIXES)
submod_finder = machinery.FileFinder(mod.__path__[0], loader_details)
submod_check = (
submod_finder.find_spec("QtCore") is not None
and submod_finder.find_spec("QtGui") is not None
and submod_finder.find_spec("QtSvg") is not None
)

# we can also safely check PySide version
if api == QT_API_PYSIDE:
return check_version(mod.__version__, '1.0.3') and submod_check
else:
return submod_check

except ImportError:
return False

Expand Down
11 changes: 0 additions & 11 deletions pydevd.py
Original file line number Diff line number Diff line change
Expand Up @@ -1073,17 +1073,6 @@ def get_file_type(self, frame, abs_real_path_and_basename=None, _cache_file_type
return _cache_file_type[cache_key]
except:
if abs_real_path_and_basename[0] == "<string>":
# TODO: This isn't ideal. We should make it so that "<string>" is
# never marked as pydevd (i.e.: investigate all the use cases
# where pydevd does this and actually mark it as "<pydevd-string>")

# Consider it an untraceable file unless there's no back frame (ignoring
# internal files and runpy.py).
if frame.f_back is not None and self.get_file_type(frame.f_back) == self.PYDEV_FILE:
# Special case, this is a string coming from pydevd itself. However we have to skip this logic for other
# files that are also marked as PYDEV_FILE (like external files marked this way)
return self.PYDEV_FILE

f = frame.f_back
while f is not None:
if self.get_file_type(f) != self.PYDEV_FILE and pydevd_file_utils.basename(f.f_code.co_filename) not in (
Expand Down
2 changes: 1 addition & 1 deletion pydevd_attach_to_process/windows/compile_windows.bat
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ cl -DUNICODE -D_UNICODE /EHsc /Zi /O1 /W3 /LD /MD /D BITS_32 /Qspectre run_code_
copy run_code_on_dllmain_x86.dll ..\run_code_on_dllmain_x86.dll /Y
copy run_code_on_dllmain_x86.pdb ..\run_code_on_dllmain_x86.pdb /Y

cl /EHsc /Zi /O1 /W3 /Qspectre inject_dll.cpp /link /PROFILE /GUARD:CF /out:inject_dll_x86.exe
cl /EHsc /Zi /O1 /W3 /Qspectre inject_dll.cpp /link /PROFILE /GUARD:CF /CETCOMPAT /out:inject_dll_x86.exe
copy inject_dll_x86.exe ..\inject_dll_x86.exe /Y
copy inject_dll_x86.pdb ..\inject_dll_x86.pdb /Y

Expand Down

This file was deleted.

12 changes: 0 additions & 12 deletions tests_python/resources/not_my_code/main_on_entry3.py

This file was deleted.

20 changes: 0 additions & 20 deletions tests_python/test_debugger_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -5739,26 +5739,6 @@ def test_stop_on_entry2(case_setup_dap):
writer.finished_ok = True


def test_stop_on_entry_verify_strings(case_setup_dap):
with case_setup_dap.test_file("not_my_code/main_on_entry3.py") as writer:
json_facade = JsonFacade(writer)
json_facade.write_set_debugger_property([], ["main_on_entry3.py", "_pydevd_string_breakpoint.py"])
json_facade.write_launch(
justMyCode=True,
stopOnEntry=True,
showReturnValue=True,
rules=[
{"path": "**/main_on_entry3.py", "include": False},
{"path": "**/_pydevd_string_breakpoint.py", "include": False},
],
)

json_facade.write_make_initial_run()
json_facade.wait_for_thread_stopped("breakpoint", file="empty_file.py")
json_facade.write_continue()
writer.finished_ok = True


@pytest.mark.parametrize("val", [True, False])
def test_debug_options(case_setup_dap, val):
with case_setup_dap.test_file("_debugger_case_debug_options.py") as writer:
Expand Down

0 comments on commit 3e88fcc

Please sign in to comment.