projects/guix·blob java-team · refs

253 lines · 9.3 KiB

1Allow using pydevd as a regular dependency.
2Submitted upstream at: https://github.com/microsoft/debugpy/pull/902
3
4diff -rup a/setup.py b/setup.py
5--- a/setup.py 2024-11-29 23:38:58.549980612 +0100
6+++ b/setup.py 2024-11-30 00:04:14.281540335 +0100
7@@ -11,6 +11,9 @@ import subprocess
8 import sys
9
10
11+DEBUGPY_BUNDLING_DISABLED = bool(os.getenv('DEBUGPY_BUNDLING_DISABLED'))
12+
13+
14 sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
15 import versioneer # noqa
16
17@@ -18,12 +21,15 @@ del sys.path[0]
18
19 sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "src"))
20 import debugpy
21-import debugpy._vendored
22+
23+if not DEBUGPY_BUNDLING_DISABLED:
24+ import debugpy._vendored
25
26 del sys.path[0]
27
28
29-PYDEVD_ROOT = debugpy._vendored.project_root("pydevd")
30+PYDEVD_ROOT = (None if DEBUGPY_BUNDLING_DISABLED else
31+ debugpy._vendored.project_root("pydevd"))
32 DEBUGBY_ROOT = os.path.dirname(os.path.abspath(debugpy.__file__))
33
34
35@@ -46,7 +52,7 @@ def get_buildplatform():
36 # relevant setuptools versions.
37 class ExtModules(list):
38 def __bool__(self):
39- return True
40+ return not DEBUGPY_BUNDLING_DISABLED
41
42
43 def override_build(cmds):
44@@ -72,6 +78,8 @@ def override_build_py(cmds):
45 # in data files for binary builds.
46 def finalize_options(self):
47 original(self)
48+ if DEBUGPY_BUNDLING_DISABLED:
49+ return True
50
51 # Ensure that pydevd extensions are present for inclusion into data_files.
52 self.announce(
53@@ -140,6 +148,20 @@ with open("DESCRIPTION.md", "r") as fh:
54
55
56 if __name__ == "__main__":
57+ if debugpy.__bundling_disabled__ != DEBUGPY_BUNDLING_DISABLED:
58+
59+ with open(os.path.join(DEBUGBY_ROOT, '__init__.py'), 'r') as f:
60+ lines = f.readlines()
61+ with open(os.path.join(DEBUGBY_ROOT, '__init__.py'), 'w') as f:
62+ edited = []
63+ for line in lines:
64+ if line.startswith('__bundling_disabled__'):
65+ edited.append(
66+ f'__bundling_disabled__ = {DEBUGPY_BUNDLING_DISABLED}\n')
67+ else:
68+ edited.append(line)
69+ f.writelines(edited)
70+
71 extras = {}
72 platforms = get_buildplatform()
73 if platforms is not None:
74@@ -149,6 +171,18 @@ if __name__ == "__main__":
75 override_build(cmds)
76 override_build_py(cmds)
77
78+ data = {"debugpy": ["ThirdPartyNotices.txt"]}
79+ packages = [
80+ "debugpy",
81+ "debugpy.adapter",
82+ "debugpy.common",
83+ "debugpy.launcher",
84+ "debugpy.server",
85+ ]
86+ if not DEBUGPY_BUNDLING_DISABLED:
87+ data.update({"debugpy._vendored": list(iter_vendored_files())})
88+ packages.append("debugpy._vendored")
89+
90 setuptools.setup(
91 name="debugpy",
92 version=versioneer.get_version(),
93@@ -177,23 +211,10 @@ if __name__ == "__main__":
94 "License :: OSI Approved :: MIT License",
95 ],
96 package_dir={"": "src"},
97- packages=[
98- "debugpy",
99- "debugpy.adapter",
100- "debugpy.common",
101- "debugpy.launcher",
102- "debugpy.server",
103- "debugpy._vendored",
104- ],
105- package_data={
106- "debugpy": ["ThirdPartyNotices.txt"],
107- "debugpy._vendored": [
108- # pydevd extensions must be built before this list can be computed properly,
109- # so it is populated in the overridden build_py.finalize_options().
110- ],
111- },
112+ packages=packages,
113+ package_data=data,
114 ext_modules=ExtModules(),
115- has_ext_modules=lambda: True,
116+ has_ext_modules=lambda: not DEBUGPY_BUNDLING_DISABLED,
117 cmdclass=cmds,
118 # allow the user to call "debugpy" instead of "python -m debugpy"
119 entry_points={"console_scripts": ["debugpy = debugpy.server.cli:main"]},
120diff -rup a/src/debugpy/__init__.py b/src/debugpy/__init__.py
121--- a/src/debugpy/__init__.py 2024-11-29 23:38:58.553980600 +0100
122+++ b/src/debugpy/__init__.py 2024-11-29 23:49:38.776095806 +0100
123@@ -34,5 +34,6 @@ assert sys.version_info >= (3, 7), (
124 # SyntaxError on Python 2 and preventing the above version check from executing.
125 from debugpy.public_api import * # noqa
126 from debugpy.public_api import __version__
127+__bundling_disabled__ = False
128
129 del sys
130diff -rup a/src/debugpy/server/attach_pid_injected.py b/src/debugpy/server/attach_pid_injected.py
131--- a/src/debugpy/server/attach_pid_injected.py 2024-11-29 23:38:58.553980600 +0100
132+++ b/src/debugpy/server/attach_pid_injected.py 2024-11-29 23:39:48.933831730 +0100
133@@ -6,6 +6,7 @@
134
135 import os
136
137+import debugpy
138
139 __file__ = os.path.abspath(__file__)
140 _debugpy_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
141@@ -28,25 +29,29 @@ def attach(setup):
142 def on_critical(msg):
143 print(msg, file=sys.stderr)
144
145- pydevd_attach_to_process_path = os.path.join(
146- _debugpy_dir,
147- "debugpy",
148- "_vendored",
149- "pydevd",
150- "pydevd_attach_to_process",
151- )
152- assert os.path.exists(pydevd_attach_to_process_path)
153- sys.path.insert(0, pydevd_attach_to_process_path)
154+ if debugpy.__bundling_disabled__:
155+ from pydevd_attach_to_process import attach_script
156+ else:
157+ pydevd_attach_to_process_path = os.path.join(
158+ _debugpy_dir,
159+ "debugpy",
160+ "_vendored",
161+ "pydevd",
162+ "pydevd_attach_to_process",
163+ )
164+ assert os.path.exists(pydevd_attach_to_process_path)
165+ sys.path.insert(0, pydevd_attach_to_process_path)
166
167- # NOTE: that it's not a part of the pydevd PYTHONPATH
168- import attach_script
169+ # NOTE: that it's not a part of the pydevd PYTHONPATH
170+ import attach_script
171
172 attach_script.fix_main_thread_id(
173 on_warn=on_warn, on_exception=on_exception, on_critical=on_critical
174 )
175
176- # NOTE: At this point it should be safe to remove this.
177- sys.path.remove(pydevd_attach_to_process_path)
178+ if not debugpy.__bundling_disabled__:
179+ # NOTE: At this point it should be safe to remove this.
180+ sys.path.remove(pydevd_attach_to_process_path)
181 except:
182 import traceback
183
184diff -rup a/src/debugpy/server/__init__.py b/src/debugpy/server/__init__.py
185--- a/src/debugpy/server/__init__.py 2024-11-29 23:38:58.553980600 +0100
186+++ b/src/debugpy/server/__init__.py 2024-11-29 23:39:48.933831730 +0100
187@@ -2,6 +2,50 @@
188 # Licensed under the MIT License. See LICENSE in the project root
189 # for license information.
190
191+from importlib import import_module
192+import os
193+
194 # "force_pydevd" must be imported first to ensure (via side effects)
195 # that the debugpy-vendored copy of pydevd gets used.
196-import debugpy._vendored.force_pydevd # noqa
197+import debugpy
198+if debugpy.__bundling_disabled__:
199+ # Do what force_pydevd.py does, but using the system-provided
200+ # pydevd.
201+
202+ # XXX: This is copied here so that the whole '_vendored' directory
203+ # can be deleted when DEBUGPY_BUNDLING_DISABLED is set.
204+
205+ # If debugpy logging is enabled, enable it for pydevd as well
206+ if "DEBUGPY_LOG_DIR" in os.environ:
207+ os.environ[str("PYDEVD_DEBUG")] = str("True")
208+ os.environ[str("PYDEVD_DEBUG_FILE")] = \
209+ os.environ["DEBUGPY_LOG_DIR"] + str("/debugpy.pydevd.log")
210+
211+ # Work around https://github.com/microsoft/debugpy/issues/346.
212+ # Disable pydevd frame-eval optimizations only if unset, to allow opt-in.
213+ if "PYDEVD_USE_FRAME_EVAL" not in os.environ:
214+ os.environ[str("PYDEVD_USE_FRAME_EVAL")] = str("NO")
215+
216+ # Constants must be set before importing any other pydevd module
217+ # due to heavy use of "from" in them.
218+ pydevd_constants = import_module('_pydevd_bundle.pydevd_constants')
219+ # The default pydevd value is 1000.
220+ pydevd_constants.MAXIMUM_VARIABLE_REPRESENTATION_SIZE = 2 ** 32
221+
222+ # When pydevd is imported it sets the breakpoint behavior, but it needs to be
223+ # overridden because by default pydevd will connect to the remote debugger using
224+ # its own custom protocol rather than DAP.
225+ import pydevd # noqa
226+ import debugpy # noqa
227+
228+ def debugpy_breakpointhook():
229+ debugpy.breakpoint()
230+
231+ pydevd.install_breakpointhook(debugpy_breakpointhook)
232+
233+ # Ensure that pydevd uses JSON protocol
234+ from _pydevd_bundle import pydevd_constants
235+ from _pydevd_bundle import pydevd_defaults
236+ pydevd_defaults.PydevdCustomization.DEFAULT_PROTOCOL = pydevd_constants.HTTP_JSON_PROTOCOL
237+else:
238+ import debugpy._vendored.force_pydevd # noqa
239diff -rup a/tests/tests/test_vendoring.py b/tests/tests/test_vendoring.py
240--- a/tests/tests/test_vendoring.py 2024-11-29 23:38:58.549980612 +0100
241+++ b/tests/tests/test_vendoring.py 2024-11-29 23:50:22.879966500 +0100
242@@ -3,6 +3,11 @@
243 # for license information.
244
245
246+import pytest
247+
248+import debugpy
249+
250+@pytest.mark.skipif(debugpy.__bundling_disabled__, reason='Bundling disabled')
251 def test_vendoring(pyfile):
252 @pyfile
253 def import_debugpy():