mirror of
https://github.com/microsoft/debugpy.git
synced 2025-12-23 08:48:12 +00:00
Assorted fixes for Python 3.10 support:
Split test/requirements.txt into two different lists, one for py2, and the other for py3; update package versions in py3 list as needed to support py3.10. Fix usage of deprecated threading functions getName(), setName(), isDaemon(), and currentThread(). Refactor test_invalid_breakpoints to be more declarative to handle Python version differences more easily and clearly, and fix it for py3.10. Disable Django tests on py3.10 (#689). Disable gevent tests on py3.10 (#688).
This commit is contained in:
parent
0e5b8f7a7c
commit
3a9f7d64c4
23 changed files with 131 additions and 79 deletions
|
|
@ -559,7 +559,7 @@ class BaseInterpreterInterface:
|
|||
|
||||
from _pydevd_bundle.pydevd_constants import set_thread_id
|
||||
from _pydev_bundle import pydev_localhost
|
||||
set_thread_id(threading.currentThread(), "console_main")
|
||||
set_thread_id(threading.current_thread(), "console_main")
|
||||
|
||||
VIRTUAL_FRAME_ID = "1" # matches PyStackFrameConsole.java
|
||||
VIRTUAL_CONSOLE_ID = "console_main" # matches PyThreadConsole.java
|
||||
|
|
|
|||
|
|
@ -1032,12 +1032,12 @@ class _NewThreadStartupWithTrace:
|
|||
# Note: if this is a thread from threading.py, we're too early in the boostrap process (because we mocked
|
||||
# the start_new_thread internal machinery and thread._bootstrap has not finished), so, the code below needs
|
||||
# to make sure that we use the current thread bound to the original function and not use
|
||||
# threading.currentThread() unless we're sure it's a dummy thread.
|
||||
# current_thread() unless we're sure it's a dummy thread.
|
||||
t = getattr(self.original_func, '__self__', getattr(self.original_func, 'im_self', None))
|
||||
if not isinstance(t, threading.Thread):
|
||||
# This is not a threading.Thread but a Dummy thread (so, get it as a dummy thread using
|
||||
# currentThread).
|
||||
t = threading.currentThread()
|
||||
t = threading.current_thread()
|
||||
|
||||
if not getattr(t, 'is_pydev_daemon_thread', False):
|
||||
thread_id = get_current_thread_id(t)
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ class ReaderThread(PyDBDaemonThread):
|
|||
|
||||
self.sock = sock
|
||||
self._buffer = b''
|
||||
self.setName("pydevd.Reader")
|
||||
self.name = "pydevd.Reader"
|
||||
self.process_net_command = process_net_command
|
||||
self.process_net_command_json = PyDevJsonCommandProcessor(self._from_json).process_net_command_json
|
||||
|
||||
|
|
@ -323,7 +323,7 @@ class FSNotifyThread(PyDBDaemonThread):
|
|||
def __init__(self, py_db, api, watch_dirs):
|
||||
PyDBDaemonThread.__init__(self, py_db)
|
||||
self.api = api
|
||||
self.setName("pydevd.FSNotifyThread")
|
||||
self.name = "pydevd.FSNotifyThread"
|
||||
self.watcher = fsnotify.Watcher()
|
||||
self.watch_dirs = watch_dirs
|
||||
|
||||
|
|
@ -359,7 +359,7 @@ class WriterThread(PyDBDaemonThread):
|
|||
PyDBDaemonThread.__init__(self, py_db)
|
||||
self.sock = sock
|
||||
self.__terminate_on_socket_close = terminate_on_socket_close
|
||||
self.setName("pydevd.Writer")
|
||||
self.name = "pydevd.Writer"
|
||||
self._cmd_queue = _queue.Queue()
|
||||
if pydevd_vm_type.get_vm_type() == 'python':
|
||||
self.timeout = 0
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ def add_custom_frame(frame, name, thread_id):
|
|||
Returns the custom thread id which will be used to show the given frame paused.
|
||||
'''
|
||||
with CustomFramesContainer.custom_frames_lock:
|
||||
curr_thread_id = get_current_thread_id(threading.currentThread())
|
||||
curr_thread_id = get_current_thread_id(threading.current_thread())
|
||||
next_id = CustomFramesContainer._next_frame_id = CustomFramesContainer._next_frame_id + 1
|
||||
|
||||
# Note: the frame id kept contains an id and thread information on the thread where the frame was added
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class PyDBDaemonThread(threading.Thread):
|
|||
created_pydb_daemon[self] = 1
|
||||
try:
|
||||
try:
|
||||
if IS_JYTHON and not isinstance(threading.currentThread(), threading._MainThread):
|
||||
if IS_JYTHON and not isinstance(threading.current_thread(), threading._MainThread):
|
||||
# we shouldn't update sys.modules for the main thread, cause it leads to the second importing 'threading'
|
||||
# module, and the new instance of main thread is created
|
||||
ss = JyCore.PySystemState()
|
||||
|
|
@ -59,7 +59,7 @@ class PyDBDaemonThread(threading.Thread):
|
|||
|
||||
def do_kill_pydev_thread(self):
|
||||
if not self._kill_received:
|
||||
pydev_log.debug('%s received kill signal', self.getName())
|
||||
pydev_log.debug('%s received kill signal', self.name)
|
||||
self._kill_received = True
|
||||
|
||||
def _stop_trace(self):
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ class NetCommandFactoryJson(NetCommandFactory):
|
|||
# Notify that it's created (no-op if we already notified before).
|
||||
py_db.notify_thread_created(thread_id, thread)
|
||||
|
||||
thread_schema = pydevd_schema.Thread(id=thread_id, name=thread.getName())
|
||||
thread_schema = pydevd_schema.Thread(id=thread_id, name=thread.name)
|
||||
threads.append(thread_schema.to_dict())
|
||||
|
||||
body = pydevd_schema.ThreadsResponseBody(threads)
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ class NetCommandFactory(object):
|
|||
|
||||
def _thread_to_xml(self, thread):
|
||||
""" thread information as XML """
|
||||
name = pydevd_xml.make_valid_xml_value(thread.getName())
|
||||
name = pydevd_xml.make_valid_xml_value(thread.name)
|
||||
cmdText = '<thread name="%s" id="%s" />' % (quote(name), get_thread_id(thread))
|
||||
return cmdText
|
||||
|
||||
|
|
|
|||
|
|
@ -448,4 +448,3 @@ def interrupt_main_thread(main_thread):
|
|||
main_thread._thread.interrupt() # Jython
|
||||
except:
|
||||
pydev_log.exception('Error on interrupt main thread fallback.')
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ def iter_frames(frame):
|
|||
|
||||
def dump_frames(thread_id):
|
||||
sys.stdout.write('dumping frames\n')
|
||||
if thread_id != get_current_thread_id(threading.currentThread()):
|
||||
if thread_id != get_current_thread_id(threading.current_thread()):
|
||||
raise VariableError("find_frame: must execute on same thread")
|
||||
|
||||
frame = get_frame()
|
||||
|
|
@ -65,7 +65,7 @@ def getVariable(dbg, thread_id, frame_id, scope, attrs):
|
|||
not the frame (as we don't care about the frame in this case).
|
||||
"""
|
||||
if scope == 'BY_ID':
|
||||
if thread_id != get_current_thread_id(threading.currentThread()):
|
||||
if thread_id != get_current_thread_id(current_thread()):
|
||||
raise VariableError("getVariable: must execute on same thread")
|
||||
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ def _get_line_for_frame(frame):
|
|||
def _pydev_stop_at_break(line):
|
||||
frame = sys._getframe(1)
|
||||
# print('pydevd SET TRACING at ', line, 'curr line', frame.f_lineno)
|
||||
t = threading.currentThread()
|
||||
t = threading.current_thread()
|
||||
try:
|
||||
additional_info = t.additional_info
|
||||
except:
|
||||
|
|
@ -73,7 +73,7 @@ def _pydev_needs_stop_at_break(line):
|
|||
# then, proceed to go to the current line
|
||||
# (which will then trigger a line event).
|
||||
'''
|
||||
t = threading.currentThread()
|
||||
t = threading.current_thread()
|
||||
try:
|
||||
additional_info = t.additional_info
|
||||
except:
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ if __name__ == '__main__':
|
|||
sys.exit = skip_successful_exit
|
||||
|
||||
connect_status_queue = _queue.Queue()
|
||||
interpreter = InterpreterInterface(host, int(client_port), threading.currentThread(), connect_status_queue=connect_status_queue)
|
||||
interpreter = InterpreterInterface(host, int(client_port), threading.current_thread(), connect_status_queue=connect_status_queue)
|
||||
|
||||
server_thread = threading.Thread(target=start_console_server,
|
||||
name='ServerThread',
|
||||
|
|
|
|||
|
|
@ -440,7 +440,7 @@ def start_server(host, port, client_port):
|
|||
# note that this does not work in jython!!! (sys method can't be replaced).
|
||||
sys.exit = do_exit
|
||||
|
||||
interpreter = InterpreterInterface(host, client_port, threading.currentThread())
|
||||
interpreter = InterpreterInterface(host, client_port, threading.current_thread())
|
||||
|
||||
start_new_thread(start_console_server, (host, port, interpreter))
|
||||
|
||||
|
|
@ -457,7 +457,7 @@ def get_interpreter():
|
|||
try:
|
||||
interpreterInterface = getattr(__builtin__, 'interpreter')
|
||||
except AttributeError:
|
||||
interpreterInterface = InterpreterInterface(None, None, threading.currentThread())
|
||||
interpreterInterface = InterpreterInterface(None, None, threading.current_thread())
|
||||
__builtin__.interpreter = interpreterInterface
|
||||
sys.stderr.write(interpreterInterface.get_greeting_msg())
|
||||
sys.stderr.flush()
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ if SUPPORT_PLUGINS:
|
|||
from _pydevd_bundle.pydevd_plugin_utils import PluginManager
|
||||
|
||||
threadingEnumerate = threading.enumerate
|
||||
threadingCurrentThread = threading.currentThread
|
||||
threadingCurrentThread = threading.current_thread
|
||||
|
||||
try:
|
||||
'dummy'.encode('utf-8') # Added because otherwise Jython 2.2.1 wasn't finding the encoding (if it wasn't loaded in the main thread).
|
||||
|
|
@ -179,7 +179,7 @@ class PyDBCommandThread(PyDBDaemonThread):
|
|||
def __init__(self, py_db):
|
||||
PyDBDaemonThread.__init__(self, py_db)
|
||||
self._py_db_command_thread_event = py_db._py_db_command_thread_event
|
||||
self.setName('pydevd.CommandThread')
|
||||
self.name = 'pydevd.CommandThread'
|
||||
|
||||
@overrides(PyDBDaemonThread._on_run)
|
||||
def _on_run(self):
|
||||
|
|
@ -223,7 +223,7 @@ class CheckAliveThread(PyDBDaemonThread):
|
|||
|
||||
def __init__(self, py_db):
|
||||
PyDBDaemonThread.__init__(self, py_db)
|
||||
self.setName('pydevd.CheckAliveThread')
|
||||
self.name = 'pydevd.CheckAliveThread'
|
||||
self.daemon = False
|
||||
self._wait_event = threading.Event()
|
||||
|
||||
|
|
@ -1317,7 +1317,7 @@ class PyDB(object):
|
|||
'Error in debugger: Found PyDBDaemonThread not marked with is_pydev_daemon_thread=True.\n')
|
||||
|
||||
if is_thread_alive(t):
|
||||
if not t.isDaemon() or hasattr(t, "__pydevd_main_thread"):
|
||||
if not t.daemon or hasattr(t, "__pydevd_main_thread"):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
|
@ -2159,8 +2159,8 @@ class PyDB(object):
|
|||
break
|
||||
time.sleep(1 / 10.)
|
||||
else:
|
||||
thread_names = [t.getName() for t in get_pydb_daemon_threads_to_wait()]
|
||||
if thread_names:
|
||||
thread_names = [t.name for t in get_pydb_daemon_threads_to_wait()]
|
||||
if thread_names:
|
||||
pydev_log.debug("The following pydb threads may not have finished correctly: %s",
|
||||
', '.join(thread_names))
|
||||
finally:
|
||||
|
|
@ -2345,8 +2345,8 @@ class PyDB(object):
|
|||
if self.thread_analyser is not None:
|
||||
wrap_threads()
|
||||
self.thread_analyser.set_start_time(cur_time())
|
||||
send_concurrency_message("threading_event", 0, t.getName(), thread_id, "thread", "start", file, 1, None, parent=thread_id)
|
||||
|
||||
send_concurrency_message("threading_event", 0, t.name, thread_id, "thread", "start", file, 1, None, parent=thread_id)
|
||||
|
||||
if self.asyncio_analyser is not None:
|
||||
# we don't have main thread in asyncio graph, so we should add a fake event
|
||||
send_concurrency_message("asyncio_event", 0, "Task", "Task", "thread", "stop", file, 1, frame=None, parent=None)
|
||||
|
|
@ -2400,7 +2400,7 @@ class PyDB(object):
|
|||
def wait_for_commands(self, globals):
|
||||
self._activate_mpl_if_needed()
|
||||
|
||||
thread = threading.currentThread()
|
||||
thread = threading.current_thread()
|
||||
from _pydevd_bundle import pydevd_frame_utils
|
||||
frame = pydevd_frame_utils.Frame(None, -1, pydevd_frame_utils.FCode("Console",
|
||||
os.path.abspath(os.path.dirname(__file__))), globals, globals)
|
||||
|
|
@ -2926,7 +2926,7 @@ class DispatchReader(ReaderThread):
|
|||
|
||||
@overrides(ReaderThread._on_run)
|
||||
def _on_run(self):
|
||||
dummy_thread = threading.currentThread()
|
||||
dummy_thread = threading.current_thread()
|
||||
dummy_thread.is_pydev_daemon_thread = False
|
||||
return ReaderThread._on_run(self)
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ try:
|
|||
except:
|
||||
from urllib.parse import quote # @UnresolvedImport
|
||||
|
||||
threadingCurrentThread = threading.currentThread
|
||||
threadingCurrentThread = threading.current_thread
|
||||
|
||||
DONT_TRACE_THREADING = ['threading.py', 'pydevd.py']
|
||||
INNER_METHODS = ['_stop']
|
||||
|
|
@ -105,7 +105,7 @@ def send_concurrency_message(event_class, time, name, thread_id, type, event, fi
|
|||
|
||||
def log_new_thread(global_debugger, t):
|
||||
event_time = cur_time() - global_debugger.thread_analyser.start_time
|
||||
send_concurrency_message("threading_event", event_time, t.getName(), get_thread_id(t), "thread",
|
||||
send_concurrency_message("threading_event", event_time, t.name, get_thread_id(t), "thread",
|
||||
"start", "code_name", 0, None, parent=get_thread_id(t))
|
||||
|
||||
|
||||
|
|
@ -162,7 +162,7 @@ class ThreadingLogger:
|
|||
if not self_obj.is_alive():
|
||||
return
|
||||
thread_id = get_thread_id(t)
|
||||
name = t.getName()
|
||||
name = t.name
|
||||
self_obj._pydev_join_called = True
|
||||
|
||||
if real_method == "start":
|
||||
|
|
@ -200,7 +200,7 @@ class ThreadingLogger:
|
|||
# back_back_base is the file, where the method was called froms
|
||||
return
|
||||
if method_name == "__init__":
|
||||
send_concurrency_message("threading_event", event_time, t.getName(), get_thread_id(t), "lock",
|
||||
send_concurrency_message("threading_event", event_time, t.name, get_thread_id(t), "lock",
|
||||
method_name, back.f_code.co_filename, back.f_lineno, back, lock_id=str(id(frame.f_locals["self"])))
|
||||
if "attr" in frame.f_locals and \
|
||||
(frame.f_locals["attr"] in LOCK_METHODS or
|
||||
|
|
@ -215,14 +215,14 @@ class ThreadingLogger:
|
|||
if real_method == "release_end":
|
||||
# do not log release end. Maybe use it later
|
||||
return
|
||||
send_concurrency_message("threading_event", event_time, t.getName(), get_thread_id(t), "lock",
|
||||
send_concurrency_message("threading_event", event_time, t.name, get_thread_id(t), "lock",
|
||||
real_method, back.f_code.co_filename, back.f_lineno, back, lock_id=str(id(self_obj)))
|
||||
|
||||
if real_method in ("put_end", "get_end"):
|
||||
# fake release for queue, cause we don't call it directly
|
||||
send_concurrency_message("threading_event", event_time, t.getName(), get_thread_id(t), "lock",
|
||||
send_concurrency_message("threading_event", event_time, t.name, get_thread_id(t), "lock",
|
||||
"release", back.f_code.co_filename, back.f_lineno, back, lock_id=str(id(self_obj)))
|
||||
# print(event_time, t.getName(), get_thread_id(t), "lock",
|
||||
# print(event_time, t.name, get_thread_id(t), "lock",
|
||||
# real_method, back.f_code.co_filename, back.f_lineno)
|
||||
|
||||
except Exception:
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class Test(unittest.TestCase):
|
|||
time.sleep(.3) # let's give it some time to start the threads
|
||||
|
||||
from _pydev_bundle import pydev_localhost
|
||||
interpreter = pydevconsole.InterpreterInterface(pydev_localhost.get_localhost(), client_port, threading.currentThread())
|
||||
interpreter = pydevconsole.InterpreterInterface(pydev_localhost.get_localhost(), client_port, threading.current_thread())
|
||||
|
||||
(result,) = interpreter.hello("Hello pydevconsole")
|
||||
self.assertEqual(result, "Hello eclipse")
|
||||
|
|
@ -53,7 +53,7 @@ class Test(unittest.TestCase):
|
|||
from _pydev_bundle import pydev_localhost
|
||||
from _pydev_bundle.pydev_console_utils import CodeFragment
|
||||
|
||||
interpreter = pydevconsole.InterpreterInterface(pydev_localhost.get_localhost(), client_port, threading.currentThread())
|
||||
interpreter = pydevconsole.InterpreterInterface(pydev_localhost.get_localhost(), client_port, threading.current_thread())
|
||||
sys.stdout = pydevd_io.IOBuf()
|
||||
interpreter.add_exec(CodeFragment('class Foo:\n CONSTANT=1\n'))
|
||||
interpreter.add_exec(CodeFragment('foo=Foo()'))
|
||||
|
|
|
|||
|
|
@ -21,11 +21,11 @@ def get_marked_line_numbers(path):
|
|||
|
||||
print(1) # @foo
|
||||
print(2)
|
||||
print(3) # @bar
|
||||
print(3) # @bar,baz
|
||||
|
||||
the function will return::
|
||||
|
||||
{"foo": 1, "bar": 3}
|
||||
{"foo": 1, "bar": 3, "baz": 3}
|
||||
"""
|
||||
|
||||
if isinstance(path, py.path.local):
|
||||
|
|
@ -40,10 +40,11 @@ def get_marked_line_numbers(path):
|
|||
with open(path, "rb") as f:
|
||||
lines = {}
|
||||
for i, line in enumerate(f):
|
||||
match = re.search(br"#\s*@\s*(.+?)\s*$", line)
|
||||
match = re.search(br"#\s*@(.+?)\s*$", line)
|
||||
if match:
|
||||
marker = compat.force_unicode(match.group(1), "ascii")
|
||||
lines[marker] = i + 1
|
||||
markers = compat.force_unicode(match.group(1), "ascii")
|
||||
for marker in markers.split(","):
|
||||
lines[marker] = i + 1
|
||||
|
||||
_marked_line_numbers_cache[path] = lines
|
||||
return lines
|
||||
|
|
|
|||
|
|
@ -328,46 +328,46 @@ def test_invalid_breakpoints(pyfile, target, run):
|
|||
|
||||
debuggee.setup()
|
||||
|
||||
# For markers below, rN = requested breakpoint, eN = expected breakpoint.
|
||||
# If there's no eN for some rN, it's assumed to be the same line.
|
||||
# fmt: off
|
||||
b = True
|
||||
while b: # @bp1-expected
|
||||
pass # @bp1-requested
|
||||
while b: # @e0-27,e0-35,e0-36,e0-37,e0-38,e0-39
|
||||
pass # @r0
|
||||
break
|
||||
|
||||
print() # @bp2-expected
|
||||
[ # @bp2-requested
|
||||
1, 2, 3, # @bp3-expected
|
||||
] # @bp3-requested
|
||||
print() # @e1-27,e1-35,e1-36,e1-37
|
||||
[ # @r1,e2
|
||||
1, 2, 3, # @e2-27,e2-35,e2-36,e2-37,e2-38
|
||||
] # @r2
|
||||
|
||||
# Python 2.7 only.
|
||||
print() # @bp4-expected
|
||||
print(1, # @bp4-requested-1
|
||||
2, 3, # @bp4-requested-2
|
||||
print() # @e3,e4
|
||||
print(1, # @r3
|
||||
2, 3, # @r4
|
||||
4, 5, 6)
|
||||
# fmt: on
|
||||
|
||||
with debug.Session() as session:
|
||||
with run(session, target(code_to_debug)):
|
||||
bp_markers = ["bp1-requested", "bp2-requested", "bp3-requested"]
|
||||
if sys.version_info < (3,):
|
||||
bp_markers += ["bp4-requested-1", "bp4-requested-2"]
|
||||
count = 5 if sys.version_info < (3,) else 3
|
||||
requested_markers = ["r" + str(i) for i in range(0, count)]
|
||||
|
||||
bps = session.set_breakpoints(code_to_debug, bp_markers)
|
||||
bps = session.set_breakpoints(code_to_debug, requested_markers)
|
||||
actual_lines = [bp["line"] for bp in bps]
|
||||
|
||||
if sys.version_info >= (3, 9):
|
||||
expected_markers = ["bp1-expected", "bp2-requested", "bp2-requested"]
|
||||
elif sys.version_info >= (3, 8):
|
||||
# See: https://bugs.python.org/issue38508
|
||||
expected_markers = ["bp1-expected", "bp2-requested", "bp3-expected"]
|
||||
else:
|
||||
expected_markers = ["bp1-expected", "bp2-expected", "bp3-expected"]
|
||||
if sys.version_info < (3,):
|
||||
expected_markers += ["bp4-expected", "bp4-expected"]
|
||||
expected_markers = []
|
||||
for r in requested_markers:
|
||||
e_generic = "e" + r[1:]
|
||||
e_versioned = e_generic + "-" + str(sys.version_info.major) + str(sys.version_info.minor)
|
||||
for e in e_versioned, e_generic, r:
|
||||
if e in code_to_debug.lines:
|
||||
expected_markers.append(e)
|
||||
break
|
||||
|
||||
expected_lines = [
|
||||
code_to_debug.lines[marker] for marker in expected_markers
|
||||
]
|
||||
|
||||
assert actual_lines == expected_lines
|
||||
|
||||
# Now let's make sure that we hit all of the expected breakpoints,
|
||||
|
|
@ -377,10 +377,9 @@ def test_invalid_breakpoints(pyfile, target, run):
|
|||
# so remove duplicates first.
|
||||
expected_lines = sorted(set(expected_lines))
|
||||
if (3, 8) <= sys.version_info < (3, 9):
|
||||
# We'll actually hit @bp3-expected and later @bp2-requested
|
||||
# (there's a line event when the list creation is finished
|
||||
# at the start of the list creation on 3.8).
|
||||
# See: https://bugs.python.org/issue38508
|
||||
# We'll actually hit @e2-38 first, and only then @r1, because there's
|
||||
# a line event for [ when the list creation is finished on 3.8).
|
||||
# See https://bugs.python.org/issue38508 for details.
|
||||
expected_lines[1], expected_lines[2] = expected_lines[2], expected_lines[1]
|
||||
|
||||
while expected_lines:
|
||||
|
|
|
|||
|
|
@ -5,13 +5,17 @@
|
|||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
import pytest
|
||||
import sys
|
||||
|
||||
from debugpy.common import compat
|
||||
from tests import code, debug, log, net, test_data
|
||||
from tests.debug import runners, targets
|
||||
from tests.patterns import some
|
||||
|
||||
pytestmark = pytest.mark.timeout(60)
|
||||
pytestmark = [
|
||||
pytest.mark.timeout(60),
|
||||
pytest.mark.skipif(sys.version_info >= (3, 10), reason="https://github.com/microsoft/debugpy/issues/689"),
|
||||
]
|
||||
|
||||
django_server = net.WebServer(net.get_test_server_port(8000, 8100))
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,14 @@
|
|||
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
import pytest
|
||||
import sys
|
||||
|
||||
from tests import debug
|
||||
from tests.patterns import some
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.version_info >= (3, 10), reason="https://github.com/microsoft/debugpy/issues/688")
|
||||
def test_gevent(pyfile, target, run):
|
||||
@pyfile
|
||||
def code_to_debug():
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
setuptools>=57.4.0
|
||||
|
||||
## Used to run the tests:
|
||||
|
||||
# pytest>=5 does not support Python 2.7
|
||||
pytest<5
|
||||
|
||||
# pytest-xdist>=2 does not support Python 2.7
|
||||
pytest-xdist<2
|
||||
|
||||
pytest
|
||||
pytest-xdist
|
||||
pytest-cov
|
||||
pytest-timeout
|
||||
tox
|
||||
|
|
@ -19,5 +17,4 @@ psutil
|
|||
django
|
||||
requests
|
||||
gevent
|
||||
|
||||
flask>=1.1.2
|
||||
|
|
|
|||
22
tests/requirements27.txt
Normal file
22
tests/requirements27.txt
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
## Used to run the tests:
|
||||
|
||||
# pytest>=5 does not support Python 2.7
|
||||
pytest<5
|
||||
|
||||
# pytest-xdist>=2 does not support Python 2.7
|
||||
pytest-xdist<2
|
||||
|
||||
pytest-cov
|
||||
pytest-timeout
|
||||
tox
|
||||
|
||||
## Used by test helpers:
|
||||
|
||||
psutil
|
||||
|
||||
## Used in Python code that is run/debugged by the tests:
|
||||
|
||||
django
|
||||
requests
|
||||
gevent
|
||||
flask>=1.1.2
|
||||
20
tests/requirements35.txt
Normal file
20
tests/requirements35.txt
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
setuptools
|
||||
|
||||
## Used to run the tests:
|
||||
|
||||
pytest
|
||||
pytest-xdist
|
||||
pytest-cov
|
||||
pytest-timeout
|
||||
tox
|
||||
|
||||
## Used by test helpers:
|
||||
|
||||
psutil
|
||||
|
||||
## Used in Python code that is run/debugged by the tests:
|
||||
|
||||
django
|
||||
requests
|
||||
gevent
|
||||
flask>=1.1.2
|
||||
8
tox.ini
8
tox.ini
|
|
@ -1,5 +1,5 @@
|
|||
[tox]
|
||||
envlist = py{27,35,36,37,38}{,-cov}
|
||||
envlist = py{27,35,36,37,38,39,310}{,-cov}
|
||||
|
||||
[testenv]
|
||||
deps = -rtests/requirements.txt
|
||||
|
|
@ -9,3 +9,9 @@ setenv =
|
|||
commands =
|
||||
!cov: pytest {posargs}
|
||||
cov: pytest --cov --cov-append --cov-config=.coveragerc {posargs}
|
||||
|
||||
[testenv:py27]
|
||||
deps = -rtests/requirements27.txt
|
||||
|
||||
[testenv:py35]
|
||||
deps = -rtests/requirements35.txt
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue