Sync latest pydevd -> debugpy.

This commit is contained in:
Fabio Zadrozny 2020-09-23 10:01:22 -03:00
parent 18c0c282ff
commit cf65911a7a
7 changed files with 79 additions and 38 deletions

View file

@ -24,7 +24,7 @@
{
"Component": {
"Type": "pip",
"pip": { "Name": "pydevd", "Version": "1.9.2" }
"pip": { "Name": "pydevd", "Version": "2.0.0" }
},
"DevelopmentDependency": false
},

View file

@ -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"""

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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))

View file

@ -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={