gnu: Add python-debugpy.
* gnu/packages/python-xyz.scm (python-debugpy): New variable. * gnu/packages/patches/python-debugpy-unbundle-pydevd.patch: New file. * gnu/local.mk: Register it.master
parent
61c8a13f50
commit
08199a93c8
|
@ -1681,6 +1681,7 @@ dist_patch_DATA = \
|
||||||
%D%/packages/patches/python-argcomplete-1.11.1-fish31.patch \
|
%D%/packages/patches/python-argcomplete-1.11.1-fish31.patch \
|
||||||
%D%/packages/patches/python-cross-compile.patch \
|
%D%/packages/patches/python-cross-compile.patch \
|
||||||
%D%/packages/patches/python-configobj-setuptools.patch \
|
%D%/packages/patches/python-configobj-setuptools.patch \
|
||||||
|
%D%/packages/patches/python-debugpy-unbundle-pydevd.patch \
|
||||||
%D%/packages/patches/python-docopt-pytest6-compat.patch \
|
%D%/packages/patches/python-docopt-pytest6-compat.patch \
|
||||||
%D%/packages/patches/python-execnet-read-only-fix.patch \
|
%D%/packages/patches/python-execnet-read-only-fix.patch \
|
||||||
%D%/packages/patches/python-fixtures-remove-monkeypatch-test.patch \
|
%D%/packages/patches/python-fixtures-remove-monkeypatch-test.patch \
|
||||||
|
|
|
@ -0,0 +1,254 @@
|
||||||
|
Allow using pydevd as a regular dependency.
|
||||||
|
Submitted upstream at: https://github.com/microsoft/debugpy/pull/902
|
||||||
|
|
||||||
|
diff --git a/setup.py b/setup.py
|
||||||
|
index 5fc40070..3a530a29 100644
|
||||||
|
--- a/setup.py
|
||||||
|
+++ b/setup.py
|
||||||
|
@@ -11,6 +11,9 @@ import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
+DEBUGPY_BUNDLING_DISABLED = bool(os.getenv('DEBUGPY_BUNDLING_DISABLED'))
|
||||||
|
+
|
||||||
|
+
|
||||||
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
import versioneer # noqa
|
||||||
|
|
||||||
|
@@ -18,12 +21,15 @@ del sys.path[0]
|
||||||
|
|
||||||
|
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "src"))
|
||||||
|
import debugpy
|
||||||
|
-import debugpy._vendored
|
||||||
|
+
|
||||||
|
+if not DEBUGPY_BUNDLING_DISABLED:
|
||||||
|
+ import debugpy._vendored
|
||||||
|
|
||||||
|
del sys.path[0]
|
||||||
|
|
||||||
|
|
||||||
|
-PYDEVD_ROOT = debugpy._vendored.project_root("pydevd")
|
||||||
|
+PYDEVD_ROOT = (None if DEBUGPY_BUNDLING_DISABLED else
|
||||||
|
+ debugpy._vendored.project_root("pydevd"))
|
||||||
|
DEBUGBY_ROOT = os.path.dirname(os.path.abspath(debugpy.__file__))
|
||||||
|
|
||||||
|
|
||||||
|
@@ -67,7 +73,7 @@ def iter_vendored_files():
|
||||||
|
# relevant setuptools versions.
|
||||||
|
class ExtModules(list):
|
||||||
|
def __bool__(self):
|
||||||
|
- return True
|
||||||
|
+ return not DEBUGPY_BUNDLING_DISABLED
|
||||||
|
|
||||||
|
|
||||||
|
def override_build(cmds):
|
||||||
|
@@ -133,9 +139,24 @@ with open("DESCRIPTION.md", "r") as fh:
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
- if not os.getenv("SKIP_CYTHON_BUILD"):
|
||||||
|
+ if not (os.getenv("SKIP_CYTHON_BUILD") or DEBUGPY_BUNDLING_DISABLED):
|
||||||
|
cython_build()
|
||||||
|
|
||||||
|
+ # Etch bundling status in the source.
|
||||||
|
+ if debugpy.__bundling_disabled__ != DEBUGPY_BUNDLING_DISABLED:
|
||||||
|
+
|
||||||
|
+ with open(os.path.join(DEBUGBY_ROOT, '__init__.py'), 'r') as f:
|
||||||
|
+ lines = f.readlines()
|
||||||
|
+ with open(os.path.join(DEBUGBY_ROOT, '__init__.py'), 'w') as f:
|
||||||
|
+ edited = []
|
||||||
|
+ for line in lines:
|
||||||
|
+ if line.startswith('__bundling_disabled__'):
|
||||||
|
+ edited.append(
|
||||||
|
+ f'__bundling_disabled__ = {DEBUGPY_BUNDLING_DISABLED}\n')
|
||||||
|
+ else:
|
||||||
|
+ edited.append(line)
|
||||||
|
+ f.writelines(edited)
|
||||||
|
+
|
||||||
|
extras = {}
|
||||||
|
platforms = get_buildplatform()
|
||||||
|
if platforms is not None:
|
||||||
|
@@ -145,6 +166,18 @@ if __name__ == "__main__":
|
||||||
|
override_build(cmds)
|
||||||
|
override_build_py(cmds)
|
||||||
|
|
||||||
|
+ data = {"debugpy": ["ThirdPartyNotices.txt"]}
|
||||||
|
+ packages = [
|
||||||
|
+ "debugpy",
|
||||||
|
+ "debugpy.adapter",
|
||||||
|
+ "debugpy.common",
|
||||||
|
+ "debugpy.launcher",
|
||||||
|
+ "debugpy.server",
|
||||||
|
+ ]
|
||||||
|
+ if not DEBUGPY_BUNDLING_DISABLED:
|
||||||
|
+ data.update({"debugpy._vendored": list(iter_vendored_files())})
|
||||||
|
+ packages.append("debugpy._vendored")
|
||||||
|
+
|
||||||
|
setuptools.setup(
|
||||||
|
name="debugpy",
|
||||||
|
version=versioneer.get_version(),
|
||||||
|
@@ -173,20 +206,10 @@ if __name__ == "__main__":
|
||||||
|
"License :: OSI Approved :: MIT License",
|
||||||
|
],
|
||||||
|
package_dir={"": "src"},
|
||||||
|
- packages=[
|
||||||
|
- "debugpy",
|
||||||
|
- "debugpy.adapter",
|
||||||
|
- "debugpy.common",
|
||||||
|
- "debugpy.launcher",
|
||||||
|
- "debugpy.server",
|
||||||
|
- "debugpy._vendored",
|
||||||
|
- ],
|
||||||
|
- package_data={
|
||||||
|
- "debugpy": ["ThirdPartyNotices.txt"],
|
||||||
|
- "debugpy._vendored": list(iter_vendored_files()),
|
||||||
|
- },
|
||||||
|
+ packages=packages,
|
||||||
|
+ package_data=data,
|
||||||
|
ext_modules=ExtModules(),
|
||||||
|
- has_ext_modules=lambda: True,
|
||||||
|
+ has_ext_modules=lambda: not DEBUGPY_BUNDLING_DISABLED,
|
||||||
|
cmdclass=cmds,
|
||||||
|
**extras
|
||||||
|
)
|
||||||
|
diff --git a/src/debugpy/__init__.py b/src/debugpy/__init__.py
|
||||||
|
index baa5a7c5..7b7a29aa 100644
|
||||||
|
--- a/src/debugpy/__init__.py
|
||||||
|
+++ b/src/debugpy/__init__.py
|
||||||
|
@@ -206,6 +206,8 @@ def trace_this_thread(should_trace):
|
||||||
|
|
||||||
|
__version__ = _version.get_versions()["version"]
|
||||||
|
|
||||||
|
+__bundling_disabled__ = False
|
||||||
|
+
|
||||||
|
# Force absolute path on Python 2.
|
||||||
|
__file__ = os.path.abspath(__file__)
|
||||||
|
|
||||||
|
diff --git a/src/debugpy/server/__init__.py b/src/debugpy/server/__init__.py
|
||||||
|
index e6a1ad66..5f29a87a 100644
|
||||||
|
--- a/src/debugpy/server/__init__.py
|
||||||
|
+++ b/src/debugpy/server/__init__.py
|
||||||
|
@@ -4,6 +4,50 @@
|
||||||
|
|
||||||
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
|
+from importlib import import_module
|
||||||
|
+import os
|
||||||
|
+
|
||||||
|
# "force_pydevd" must be imported first to ensure (via side effects)
|
||||||
|
# that the debugpy-vendored copy of pydevd gets used.
|
||||||
|
-import debugpy._vendored.force_pydevd # noqa
|
||||||
|
+import debugpy
|
||||||
|
+if debugpy.__bundling_disabled__:
|
||||||
|
+ # Do what force_pydevd.py does, but using the system-provided
|
||||||
|
+ # pydevd.
|
||||||
|
+
|
||||||
|
+ # XXX: This is copied here so that the whole '_vendored' directory
|
||||||
|
+ # can be deleted when DEBUGPY_BUNDLING_DISABLED is set.
|
||||||
|
+
|
||||||
|
+ # If debugpy logging is enabled, enable it for pydevd as well
|
||||||
|
+ if "DEBUGPY_LOG_DIR" in os.environ:
|
||||||
|
+ os.environ[str("PYDEVD_DEBUG")] = str("True")
|
||||||
|
+ os.environ[str("PYDEVD_DEBUG_FILE")] = \
|
||||||
|
+ os.environ["DEBUGPY_LOG_DIR"] + str("/debugpy.pydevd.log")
|
||||||
|
+
|
||||||
|
+ # Work around https://github.com/microsoft/debugpy/issues/346.
|
||||||
|
+ # Disable pydevd frame-eval optimizations only if unset, to allow opt-in.
|
||||||
|
+ if "PYDEVD_USE_FRAME_EVAL" not in os.environ:
|
||||||
|
+ os.environ[str("PYDEVD_USE_FRAME_EVAL")] = str("NO")
|
||||||
|
+
|
||||||
|
+ # Constants must be set before importing any other pydevd module
|
||||||
|
+ # due to heavy use of "from" in them.
|
||||||
|
+ pydevd_constants = import_module('_pydevd_bundle.pydevd_constants')
|
||||||
|
+ # The default pydevd value is 1000.
|
||||||
|
+ pydevd_constants.MAXIMUM_VARIABLE_REPRESENTATION_SIZE = 2 ** 32
|
||||||
|
+
|
||||||
|
+ # When pydevd is imported it sets the breakpoint behavior, but it needs to be
|
||||||
|
+ # overridden because by default pydevd will connect to the remote debugger using
|
||||||
|
+ # its own custom protocol rather than DAP.
|
||||||
|
+ import pydevd # noqa
|
||||||
|
+ import debugpy # noqa
|
||||||
|
+
|
||||||
|
+ def debugpy_breakpointhook():
|
||||||
|
+ debugpy.breakpoint()
|
||||||
|
+
|
||||||
|
+ pydevd.install_breakpointhook(debugpy_breakpointhook)
|
||||||
|
+
|
||||||
|
+ # Ensure that pydevd uses JSON protocol
|
||||||
|
+ from _pydevd_bundle import pydevd_constants
|
||||||
|
+ from _pydevd_bundle import pydevd_defaults
|
||||||
|
+ pydevd_defaults.PydevdCustomization.DEFAULT_PROTOCOL = pydevd_constants.HTTP_JSON_PROTOCOL
|
||||||
|
+else:
|
||||||
|
+ import debugpy._vendored.force_pydevd # noqa
|
||||||
|
diff --git a/src/debugpy/server/attach_pid_injected.py b/src/debugpy/server/attach_pid_injected.py
|
||||||
|
index e6345996..87cfdd53 100644
|
||||||
|
--- a/src/debugpy/server/attach_pid_injected.py
|
||||||
|
+++ b/src/debugpy/server/attach_pid_injected.py
|
||||||
|
@@ -8,6 +8,7 @@ from __future__ import absolute_import, division, print_function, unicode_litera
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
+import debugpy
|
||||||
|
|
||||||
|
__file__ = os.path.abspath(__file__)
|
||||||
|
_debugpy_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
|
||||||
|
@@ -30,25 +31,29 @@ def attach(setup):
|
||||||
|
def on_critical(msg):
|
||||||
|
print(msg, file=sys.stderr)
|
||||||
|
|
||||||
|
- pydevd_attach_to_process_path = os.path.join(
|
||||||
|
- _debugpy_dir,
|
||||||
|
- "debugpy",
|
||||||
|
- "_vendored",
|
||||||
|
- "pydevd",
|
||||||
|
- "pydevd_attach_to_process",
|
||||||
|
- )
|
||||||
|
- assert os.path.exists(pydevd_attach_to_process_path)
|
||||||
|
- sys.path.insert(0, pydevd_attach_to_process_path)
|
||||||
|
-
|
||||||
|
- # NOTE: that it's not a part of the pydevd PYTHONPATH
|
||||||
|
- import attach_script
|
||||||
|
+ if debugpy.__bundling_disabled__:
|
||||||
|
+ from pydevd_attach_to_process import attach_script
|
||||||
|
+ else:
|
||||||
|
+ pydevd_attach_to_process_path = os.path.join(
|
||||||
|
+ _debugpy_dir,
|
||||||
|
+ "debugpy",
|
||||||
|
+ "_vendored",
|
||||||
|
+ "pydevd",
|
||||||
|
+ "pydevd_attach_to_process",
|
||||||
|
+ )
|
||||||
|
+ assert os.path.exists(pydevd_attach_to_process_path)
|
||||||
|
+ sys.path.insert(0, pydevd_attach_to_process_path)
|
||||||
|
+
|
||||||
|
+ # NOTE: that it's not a part of the pydevd PYTHONPATH
|
||||||
|
+ import attach_script
|
||||||
|
|
||||||
|
attach_script.fix_main_thread_id(
|
||||||
|
on_warn=on_warn, on_exception=on_exception, on_critical=on_critical
|
||||||
|
)
|
||||||
|
|
||||||
|
- # NOTE: At this point it should be safe to remove this.
|
||||||
|
- sys.path.remove(pydevd_attach_to_process_path)
|
||||||
|
+ if not debugpy.__bundling_disabled__:
|
||||||
|
+ # NOTE: At this point it should be safe to remove this.
|
||||||
|
+ sys.path.remove(pydevd_attach_to_process_path)
|
||||||
|
except:
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
diff --git a/tests/tests/test_vendoring.py b/tests/tests/test_vendoring.py
|
||||||
|
index dd6c4269..28c03702 100644
|
||||||
|
--- a/tests/tests/test_vendoring.py
|
||||||
|
+++ b/tests/tests/test_vendoring.py
|
||||||
|
@@ -1,3 +1,8 @@
|
||||||
|
+import pytest
|
||||||
|
+
|
||||||
|
+import debugpy
|
||||||
|
+
|
||||||
|
+@pytest.mark.skipif(debugpy.__bundling_disabled__, reason='Bundling disabled')
|
||||||
|
def test_vendoring(pyfile):
|
||||||
|
@pyfile
|
||||||
|
def import_debugpy():
|
||||||
|
--
|
||||||
|
2.34.0
|
||||||
|
|
|
@ -13134,6 +13134,78 @@ libmagic.")))
|
||||||
and other @acronym{IDEs, Integrated Development Environments}.")
|
and other @acronym{IDEs, Integrated Development Environments}.")
|
||||||
(license license:epl1.0))))
|
(license license:epl1.0))))
|
||||||
|
|
||||||
|
(define-public python-debugpy
|
||||||
|
(package
|
||||||
|
(name "python-debugpy")
|
||||||
|
(version "1.6.0")
|
||||||
|
(source
|
||||||
|
(origin
|
||||||
|
(method git-fetch)
|
||||||
|
(uri (git-reference ;no tests in PyPI archive
|
||||||
|
(url "https://github.com/microsoft/debugpy")
|
||||||
|
(commit (string-append "v" version))))
|
||||||
|
(file-name (git-file-name name version))
|
||||||
|
(modules '((guix build utils)))
|
||||||
|
;; Remove the bundled PyDev-Debugger copy, including its pre-built
|
||||||
|
;; attach binary.
|
||||||
|
(snippet '(delete-file-recursively "src/debugpy/_vendored"))
|
||||||
|
(patches (search-patches "python-debugpy-unbundle-pydevd.patch"))
|
||||||
|
(sha256
|
||||||
|
(base32
|
||||||
|
"1dpfzs3p51648i7f3fz8dw5d0vrj39iwn1jhn0226idc02ybyqih"))))
|
||||||
|
(build-system python-build-system)
|
||||||
|
(arguments
|
||||||
|
(list
|
||||||
|
#:phases
|
||||||
|
#~(modify-phases %standard-phases
|
||||||
|
(add-after 'unpack 'patch-sh-in-tests
|
||||||
|
(lambda _
|
||||||
|
(substitute* "tests/debugpy/test_run.py"
|
||||||
|
(("#!/bin/sh")
|
||||||
|
(string-append "#!" (which "sh"))))))
|
||||||
|
(add-after 'unpack 'fix-version
|
||||||
|
;; Versioneer is useless when there is no git metadata.
|
||||||
|
(lambda _
|
||||||
|
(substitute* "setup.py"
|
||||||
|
(("version=versioneer.get_version\\(),")
|
||||||
|
(format #f "version=~s," #$version)))))
|
||||||
|
(add-before 'build 'configure
|
||||||
|
(lambda _
|
||||||
|
;; This adjusts the behavior of debugpy to load pydevd from
|
||||||
|
;; Python site packages.
|
||||||
|
(setenv "DEBUGPY_BUNDLING_DISABLED" "1")))
|
||||||
|
(replace 'check
|
||||||
|
(lambda* (#:key tests? #:allow-other-keys)
|
||||||
|
(invoke "pytest" "-vv"
|
||||||
|
"-n" (number->string (parallel-job-count))
|
||||||
|
"-k"
|
||||||
|
(string-append
|
||||||
|
;; These tests cannot be run in parallel because their
|
||||||
|
;; test data would not be copied by xdist and lead to
|
||||||
|
;; import errors. (see:
|
||||||
|
;; https://github.com/microsoft/debugpy/issues/342 and
|
||||||
|
;; https://github.com/microsoft/debugpy/issues/880).
|
||||||
|
"not test_custom_python_args "
|
||||||
|
"and not test_autokill ")))))))
|
||||||
|
(native-inputs
|
||||||
|
;; See: https://raw.githubusercontent.com/microsoft/debugpy/
|
||||||
|
;; main/tests/requirements.txt.
|
||||||
|
(list python-django
|
||||||
|
python-gevent
|
||||||
|
python-flask
|
||||||
|
python-psutil
|
||||||
|
python-pytest
|
||||||
|
python-pytest-cov
|
||||||
|
python-pytest-timeout
|
||||||
|
python-pytest-xdist
|
||||||
|
python-requests))
|
||||||
|
(propagated-inputs (list python-pydevd))
|
||||||
|
(home-page "https://aka.ms/debugpy")
|
||||||
|
(synopsis "Debug Adapter Protocol Python implementation")
|
||||||
|
(description "An implementation of the Debug Adapter Protocol for
|
||||||
|
Python.")
|
||||||
|
(license license:expat)))
|
||||||
|
|
||||||
(define-public python-debian
|
(define-public python-debian
|
||||||
(package
|
(package
|
||||||
(name "python-debian")
|
(name "python-debian")
|
||||||
|
|
Reference in New Issue