Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hangs property inspection of an object #1729

Closed
Eseeelil-dev opened this issue Nov 12, 2024 · 1 comment
Closed

Hangs property inspection of an object #1729

Eseeelil-dev opened this issue Nov 12, 2024 · 1 comment
Assignees
Labels
needs repro Issue has not been reproduced yet

Comments

@Eseeelil-dev
Copy link

Type: Bug

Behaviour

A variable inspection hangs if the variable has a property that has long time execution.

Steps to reproduce:

  1. Enable Python and Python Debugger extentions
  2. Create a test.py file with next content:
import time

class A:
    @property
    def long_timeout_value(self):
        # This property represents the case where it has a long waiting time to get something. 
	# As an example: WebDriver element evaluation, API call (to super slow system) and any other long operation
        time.sleep(10000)


a = A()
print('Set a brakepoint here')
  1. Set a brakepoint on print line in the code above
  2. Create simple launch config:
{
    "name": "Python Debugger: Current File",
    "type": "debugpy",
    "request": "launch",
    "program": "${file}",
    "console": "integratedTerminal"
}
  1. Run test.py and wait until code run to brakepoint
  2. In the "Run and Debug" panel, inspect a variable of an object of class A

Expected result

After some time, for example 30 seconds (or a setting from the configuration file), if the a value could not be inspected then show an error and stop trying to inspect it.

Actual result

There is an infinite attempt to inspect the value of a. This may block further debugging.

Image

Diagnostic data

Output for Python in the Output panel (ViewOutput, change the drop-down the upper-right of the Output panel to Python)

2024-11-12 18:36:36.465 [info] Experiment 'pythonRecommendTensorboardExt' is active
2024-11-12 18:36:36.465 [info] Experiment 'pythonTerminalEnvVarActivation' is active
2024-11-12 18:36:36.465 [info] Experiment 'pythonTestAdapter' is active
2024-11-12 18:36:36.466 [info] Native locator: Refresh started
2024-11-12 18:36:36.508 [info] Python interpreter path: ~\AppData\Local\Programs\Python\Python311\python.exe
2024-11-12 18:36:36.517 [info] > pyenv which python
2024-11-12 18:36:36.517 [info] cwd: .
2024-11-12 18:36:36.799 [info] Native locator: Refresh finished in 359 ms
2024-11-12 18:36:37.451 [info] Starting Jedi language server for test.

Extension version: 2024.18.1
VS Code version: Code 1.95.2 (e8653663e8840adaf45af01eab5c627a5af81807, 2024-11-07T11:07:22.054Z)
OS version: Windows_NT x64 10.0.19045
Modes:

  • Python version (& distribution if applicable, e.g. Anaconda): 3.11.4
  • Type of virtual environment used (e.g. conda, venv, virtualenv, etc.): System
  • Value of the python.languageServer setting: Default
User Settings


languageServer: "Jedi"

Installed Extensions
Extension Name Extension Id Version
JavaScript Debugger ms-vscode.js-debug 1.95.2
JavaScript Debugger Companion Extension ms-vscode.js-debug-companion 1.1.3
Python ms-python.python 2024.18.1
Python Debugger ms-python.debugpy 2024.12.0
Remote - SSH ms-vscode-remote.remote-ssh 0.115.0
Remote - SSH: Editing Configuration Files ms-vscode-remote.remote-ssh-edit 0.87.0
Remote Explorer ms-vscode.remote-explorer 0.4.3
Table Visualizer for JavaScript Profiles ms-vscode.vscode-js-profile-table 1.0.10
System Info
Item Value
CPUs Intel(R) Core(TM) i7-9700 CPU @ 3.00GHz (8 x 3000)
GPU Status 2d_canvas: enabled
canvas_oop_rasterization: enabled_on
direct_rendering_display_compositor: disabled_off_ok
gpu_compositing: enabled
multiple_raster_threads: enabled_on
opengl: enabled_on
rasterization: enabled
raw_draw: disabled_off_ok
skia_graphite: disabled_off
video_decode: enabled
video_encode: enabled
vulkan: disabled_off
webgl: enabled
webgl2: enabled
webgpu: enabled
webnn: disabled_off
Load (avg) undefined
Memory (System) 31.94GB (26.77GB free)
Process Argv --crash-reporter-id e78784ee-1300-4192-bbeb-4026df619cd9
Screen Reader no
VM 57%
A/B Experiments
vsliv368cf:30146710
vspor879:30202332
vspor708:30202333
vspor363:30204092
vscod805cf:30301675
binariesv615:30325510
vsaa593cf:30376535
py29gd2263:31024239
vscaat:30438848
c4g48928:30535728
azure-dev_surveyone:30548225
962ge761:30959799
pythonnoceb:30805159
asynctok:30898717
pythonmypyd1:30879173
h48ei257:31000450
pythontbext0:30879054
cppperfnew:31000557
dsvsc020:30976470
pythonait:31006305
dsvsc021:30996838
724cj586:31013169
dvdeprecation:31068756
dwnewjupyter:31046869
newcmakeconfigv2:31071590
impr_priority:31102340
nativerepl2:31139839
pythonrstrctxt:31112756
nativeloc1:31134641
cf971741:31144450
iacca1:31171482
notype1:31157159
5fd0e150:31155592
dwcopilot:31170013
j44ff735:31179530

@karthiknadig karthiknadig transferred this issue from microsoft/vscode-python Nov 12, 2024
@github-actions github-actions bot added the needs repro Issue has not been reproduced yet label Nov 12, 2024
@rchiodo
Copy link
Contributor

rchiodo commented Nov 12, 2024

Thanks for the issue.

I don't think debugpy would be able to implement this though.

We currently use exec to run evaluation. That's how we get the variable properties of a in this example. Exec has no way to interrupt it.

Exec also has to run in the same frame that the debugger is stopped at (so that it gets all the necessary information in order to evaluate the expression). Meaning this thread can't be torn down. It's the actual thread in your application - one solution might be to just kill the thread after a timeout.

I'll move this to a discussion. Maybe somebody else has a different suggestion on how to implement this.

There's a possible alternative. You make things that take too long be async. Then when we eval them we don't actually evaluate the result, we just return the coroutine.

Something like this:

import asyncio

class A:
    @property
    async def long_timeout_value(self):
        # This property represents the case where it has a long waiting time to get something. 
	# As an example: WebDriver element evaluation, API call (to super slow system) and any other long operation
        await asyncio.sleep(1)
        return 10


a = A()
x = asyncio.run(a.long_timeout_value)
print('Set a brakepoint here')

But that doesn't really meet the need to not have debugging break if some property happens to take a long time. You'd have to know ahead of time.

@microsoft microsoft locked and limited conversation to collaborators Nov 12, 2024
@rchiodo rchiodo converted this issue into discussion #1730 Nov 12, 2024

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
needs repro Issue has not been reproduced yet
Projects
None yet
Development

No branches or pull requests

2 participants