mirror of
https://github.com/microsoft/debugpy.git
synced 2025-12-23 08:48:12 +00:00
Sync latest pydevd -> debugpy.
This commit is contained in:
parent
18c0c282ff
commit
cf65911a7a
7 changed files with 79 additions and 38 deletions
|
|
@ -24,7 +24,7 @@
|
|||
{
|
||||
"Component": {
|
||||
"Type": "pip",
|
||||
"pip": { "Name": "pydevd", "Version": "1.9.2" }
|
||||
"pip": { "Name": "pydevd", "Version": "2.0.0" }
|
||||
},
|
||||
"DevelopmentDependency": false
|
||||
},
|
||||
|
|
|
|||
|
|
@ -105,6 +105,11 @@ class PyDevIPCompleter6(IPCompleter):
|
|||
self.dict_key_matches,
|
||||
]
|
||||
|
||||
@matchers.setter
|
||||
def matchers(self, value):
|
||||
# To stop the init in IPCompleter raising an AttributeError we now have to specify a setter as it's now a property in the superclass.
|
||||
return
|
||||
|
||||
class PyDevTerminalInteractiveShell(TerminalInteractiveShell):
|
||||
banner1 = Unicode(default_pydev_banner, config=True,
|
||||
help="""The part of the banner to be printed before the profile"""
|
||||
|
|
|
|||
|
|
@ -109,13 +109,23 @@ def _pydevd_log(level, msg, *args):
|
|||
msg = '%s - %s' % (msg, args)
|
||||
msg = '%s\n' % (msg,)
|
||||
try:
|
||||
initialize_debug_stream() # Do it as late as possible
|
||||
_LoggingGlobals._debug_stream.write(msg)
|
||||
except TypeError:
|
||||
if isinstance(msg, bytes):
|
||||
# Depending on the StringIO flavor, it may only accept unicode.
|
||||
msg = msg.decode('utf-8', 'replace')
|
||||
try:
|
||||
initialize_debug_stream() # Do it as late as possible
|
||||
_LoggingGlobals._debug_stream.write(msg)
|
||||
except TypeError:
|
||||
if isinstance(msg, bytes):
|
||||
# Depending on the StringIO flavor, it may only accept unicode.
|
||||
msg = msg.decode('utf-8', 'replace')
|
||||
_LoggingGlobals._debug_stream.write(msg)
|
||||
except UnicodeEncodeError:
|
||||
# When writing to the stream it's possible that the string can't be represented
|
||||
# in the encoding expected (in this case, convert it to the stream encoding
|
||||
# or ascii if we can't find one suitable using a suitable replace).
|
||||
encoding = getattr(_LoggingGlobals._debug_stream, 'encoding', 'ascii')
|
||||
msg = msg.encode(encoding, 'backslashreplace')
|
||||
msg = msg.decode(encoding)
|
||||
_LoggingGlobals._debug_stream.write(msg)
|
||||
|
||||
_LoggingGlobals._debug_stream.flush()
|
||||
except:
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import sys
|
|||
from _pydev_runfiles import pydev_runfiles_xml_rpc
|
||||
import time
|
||||
from _pydev_runfiles.pydev_runfiles_coverage import start_coverage_support
|
||||
from contextlib import contextmanager
|
||||
|
||||
|
||||
#=======================================================================================================================
|
||||
# PydevPlugin
|
||||
|
|
@ -14,13 +16,11 @@ class PydevPlugin(Plugin):
|
|||
self.configuration = configuration
|
||||
Plugin.__init__(self)
|
||||
|
||||
|
||||
def begin(self):
|
||||
# Called before any test is run (it's always called, with multiprocess or not)
|
||||
self.start_time = time.time()
|
||||
self.coverage_files, self.coverage = start_coverage_support(self.configuration)
|
||||
|
||||
|
||||
def finalize(self, result):
|
||||
# Called after all tests are run (it's always called, with multiprocess or not)
|
||||
self.coverage.stop()
|
||||
|
|
@ -28,28 +28,54 @@ class PydevPlugin(Plugin):
|
|||
|
||||
pydev_runfiles_xml_rpc.notifyTestRunFinished('Finished in: %.2f secs.' % (time.time() - self.start_time,))
|
||||
|
||||
|
||||
|
||||
#===================================================================================================================
|
||||
# Methods below are not called with multiprocess (so, we monkey-patch MultiProcessTestRunner.consolidate
|
||||
# so that they're called, but unfortunately we loose some info -- i.e.: the time for each test in this
|
||||
# process).
|
||||
#===================================================================================================================
|
||||
|
||||
class Sentinel(object):
|
||||
pass
|
||||
|
||||
def report_cond(self, cond, test, captured_output, error=''):
|
||||
'''
|
||||
@param cond: fail, error, ok
|
||||
'''
|
||||
@contextmanager
|
||||
def _without_user_address(self, test):
|
||||
# #PyDev-1095: Conflict between address in test and test.address() in PydevPlugin().report_cond()
|
||||
user_test_instance = test.test
|
||||
user_address = self.Sentinel
|
||||
user_class_address = self.Sentinel
|
||||
try:
|
||||
if 'address' in user_test_instance.__dict__:
|
||||
user_address = user_test_instance.__dict__.pop('address')
|
||||
except:
|
||||
# Just ignore anything here.
|
||||
pass
|
||||
try:
|
||||
user_class_address = user_test_instance.__class__.address
|
||||
del user_test_instance.__class__.address
|
||||
except:
|
||||
# Just ignore anything here.
|
||||
pass
|
||||
|
||||
# test.address() is something as:
|
||||
# ('D:\\workspaces\\temp\\test_workspace\\pytesting1\\src\\mod1\\hello.py', 'mod1.hello', 'TestCase.testMet1')
|
||||
#
|
||||
# and we must pass: location, test
|
||||
# E.g.: ['D:\\src\\mod1\\hello.py', 'TestCase.testMet1']
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
if user_address is not self.Sentinel:
|
||||
user_test_instance.__dict__['address'] = user_address
|
||||
|
||||
if user_class_address is not self.Sentinel:
|
||||
user_test_instance.__class__.address = user_class_address
|
||||
|
||||
def _get_test_address(self, test):
|
||||
try:
|
||||
if hasattr(test, 'address'):
|
||||
address = test.address()
|
||||
with self._without_user_address(test):
|
||||
address = test.address()
|
||||
|
||||
# test.address() is something as:
|
||||
# ('D:\\workspaces\\temp\\test_workspace\\pytesting1\\src\\mod1\\hello.py', 'mod1.hello', 'TestCase.testMet1')
|
||||
#
|
||||
# and we must pass: location, test
|
||||
# E.g.: ['D:\\src\\mod1\\hello.py', 'TestCase.testMet1']
|
||||
address = address[0], address[2]
|
||||
else:
|
||||
# multiprocess
|
||||
|
|
@ -68,6 +94,14 @@ class PydevPlugin(Plugin):
|
|||
import traceback;traceback.print_exc()
|
||||
sys.stderr.write("\n\n\n")
|
||||
address = '?', '?'
|
||||
return address
|
||||
|
||||
def report_cond(self, cond, test, captured_output, error=''):
|
||||
'''
|
||||
@param cond: fail, error, ok
|
||||
'''
|
||||
|
||||
address = self._get_test_address(test)
|
||||
|
||||
error_contents = self.get_io_from_error(error)
|
||||
try:
|
||||
|
|
@ -77,18 +111,11 @@ class PydevPlugin(Plugin):
|
|||
|
||||
pydev_runfiles_xml_rpc.notifyTest(cond, captured_output, error_contents, address[0], address[1], time_str)
|
||||
|
||||
|
||||
def startTest(self, test):
|
||||
test._pydev_start_time = time.time()
|
||||
if hasattr(test, 'address'):
|
||||
address = test.address()
|
||||
file, test = address[0], address[2]
|
||||
else:
|
||||
# multiprocess
|
||||
file, test = test
|
||||
file, test = self._get_test_address(test)
|
||||
pydev_runfiles_xml_rpc.notifyStartTest(file, test)
|
||||
|
||||
|
||||
def get_io_from_error(self, err):
|
||||
if type(err) == type(()):
|
||||
if len(err) != 3:
|
||||
|
|
@ -104,13 +131,11 @@ class PydevPlugin(Plugin):
|
|||
return s.getvalue()
|
||||
return err
|
||||
|
||||
|
||||
def get_captured_output(self, test):
|
||||
if hasattr(test, 'capturedOutput') and test.capturedOutput:
|
||||
return test.capturedOutput
|
||||
return ''
|
||||
|
||||
|
||||
def addError(self, test, err):
|
||||
self.report_cond(
|
||||
'error',
|
||||
|
|
@ -119,7 +144,6 @@ class PydevPlugin(Plugin):
|
|||
err,
|
||||
)
|
||||
|
||||
|
||||
def addFailure(self, test, err):
|
||||
self.report_cond(
|
||||
'fail',
|
||||
|
|
@ -128,7 +152,6 @@ class PydevPlugin(Plugin):
|
|||
err,
|
||||
)
|
||||
|
||||
|
||||
def addSuccess(self, test):
|
||||
self.report_cond(
|
||||
'ok',
|
||||
|
|
@ -139,15 +162,17 @@ class PydevPlugin(Plugin):
|
|||
|
||||
|
||||
PYDEV_NOSE_PLUGIN_SINGLETON = None
|
||||
|
||||
|
||||
def start_pydev_nose_plugin_singleton(configuration):
|
||||
global PYDEV_NOSE_PLUGIN_SINGLETON
|
||||
PYDEV_NOSE_PLUGIN_SINGLETON = PydevPlugin(configuration)
|
||||
return PYDEV_NOSE_PLUGIN_SINGLETON
|
||||
|
||||
|
||||
|
||||
|
||||
original = MultiProcessTestRunner.consolidate
|
||||
|
||||
|
||||
#=======================================================================================================================
|
||||
# new_consolidate
|
||||
#=======================================================================================================================
|
||||
|
|
@ -176,7 +201,7 @@ def new_consolidate(self, result, batch_result):
|
|||
else:
|
||||
PYDEV_NOSE_PLUGIN_SINGLETON.report_cond('ok', addr, output)
|
||||
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
MultiProcessTestRunner.consolidate = new_consolidate
|
||||
|
|
|
|||
|
|
@ -211,6 +211,6 @@ dir dist
|
|||
# Note: uploading with twine gives an error in the end, but apparently it works (check final result in pypi).
|
||||
twine upload dist/pydevd*
|
||||
|
||||
git tag pydev_debugger_1_9_0 -a -m "PyDev.Debugger 1.9.0"
|
||||
git tag pydev_debugger_2_0_0 -a -m "PyDev.Debugger 2.0.0"
|
||||
git push --tags
|
||||
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ from _pydevd_bundle.pydevd_thread_lifecycle import suspend_all_threads, mark_thr
|
|||
if USE_CUSTOM_SYS_CURRENT_FRAMES_MAP:
|
||||
from _pydevd_bundle.pydevd_constants import constructed_tid_to_last_frame
|
||||
|
||||
__version_info__ = (1, 3, 3)
|
||||
__version_info__ = (2, 0, 0)
|
||||
__version_info_str__ = []
|
||||
for v in __version_info__:
|
||||
__version_info_str__.append(str(v))
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ args = dict(
|
|||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Software Development :: Debuggers',
|
||||
],
|
||||
entry_points={
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue