From 7ca01fb2dedaf22e8c0c1d4069a305b117a018dd Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Thu, 19 Apr 2018 18:20:06 -0600 Subject: [PATCH] Clean up handling of vendored projects. (#383) * Clean up handling of vendored projects. * Add the ptvsd._vendored package. * Try the new location and fall back to the old one. * Fix a typo. * Add ptvsd._vendored.list_all(). * Fix setup.py and tests/__main__.py. * Exclude .pyc files (from python 2). * Deal with implicit relative imports in 2.7. --- ptvsd/__init__.py | 44 +----- ptvsd/_vendored/__init__.py | 124 ++++++++++++++++ ptvsd/_vendored/_pydevd_packaging.py | 44 ++++++ ptvsd/_vendored/_util.py | 56 +++++++ ptvsd/_vendored/force_pydevd.py | 30 ++++ setup.py | 100 ++++++------- tests/__main__.py | 27 ++-- tests/test_setup.py | 214 +++++++++++++++++++++++++++ 8 files changed, 543 insertions(+), 96 deletions(-) create mode 100644 ptvsd/_vendored/__init__.py create mode 100644 ptvsd/_vendored/_pydevd_packaging.py create mode 100644 ptvsd/_vendored/_util.py create mode 100644 ptvsd/_vendored/force_pydevd.py create mode 100644 tests/test_setup.py diff --git a/ptvsd/__init__.py b/ptvsd/__init__.py index b8f633fa..bd04bc05 100644 --- a/ptvsd/__init__.py +++ b/ptvsd/__init__.py @@ -3,46 +3,16 @@ # for license information. __all__ = [ + '__version__', '__author__', 'enable_attach', 'wait_for_attach', 'break_into_debugger', 'is_attached', ] -import sys -import os.path - -from ptvsd.version import __version__, __author__ # noqa - -PYDEVD_ROOT = os.path.join(os.path.dirname(__file__), 'pydevd') -del os - -# Ensure that pydevd is our vendored copy. -for modname in sys.modules: - if not modname.startswith('pydev') and not modname.startswith('_pydev'): - continue - mod = sys.modules[modname] - if hasattr(mod, '__file__') and not mod.__file__.startswith(PYDEVD_ROOT): - print(mod.__file__) - #raise ImportError('incompatible copy of pydevd already imported') - -# Add our vendored pydevd directory to path, so that it gets found first. -sys.path.insert(0, PYDEVD_ROOT) - -# Now make sure all the top-level modules and packages in pydevd are loaded. -import _pydev_bundle # noqa -import _pydev_imps # noqa -import _pydev_runfiles # noqa -import _pydevd_bundle # noqa -import _pydevd_frame_eval # noqa -import pydev_ipython # noqa -import pydevd_concurrency_analyser # noqa -import pydevd_plugins # noqa -import pydevd # noqa +# "force_pydevd" must be imported first to ensure (via side effects) +# that the ptvsd-vendored copy of pydevd gets used. +from ._vendored import force_pydevd +from ptvsd.version import __version__, __author__ from ptvsd.attach_server import ( enable_attach, wait_for_attach, break_into_debugger, is_attached, -) # noqa - -# Remove sys.path entry added above - any pydevd modules that aren't -# loaded at this point, will be loaded using their parent package's -# __path__. -del sys.path[0] -del sys +) +del force_pydevd diff --git a/ptvsd/_vendored/__init__.py b/ptvsd/_vendored/__init__.py new file mode 100644 index 00000000..0d9a3262 --- /dev/null +++ b/ptvsd/_vendored/__init__.py @@ -0,0 +1,124 @@ +import contextlib +from importlib import import_module +import os +import os.path +import sys + +from . import _util + + +VENDORED_ROOT = os.path.dirname(os.path.abspath(__file__)) +# TODO: Move the "pydevd" git submodule to the ptvsd/_vendored directory +# and then drop the following fallback. +if 'pydevd' not in os.listdir(VENDORED_ROOT): + VENDORED_ROOT = os.path.dirname(VENDORED_ROOT) + + +def list_all(resolve=False): + """Return the list of vendored projects.""" + # TODO: Derive from os.listdir(VENDORED_ROOT)? + projects = [ + 'pydevd', + ] + if not resolve: + return projects + return [project_root(name) for name in projects] + + +def project_root(project): + """Return the path the root dir of the vendored project. + + If "project" is an empty string then the path prefix for vendored + projects (e.g. "ptvsd/_vendored/") will be returned. + """ + if not project: + project = '' + return os.path.join(VENDORED_ROOT, project) + + +def iter_project_files(project, relative=False, **kwargs): + """Yield (dirname, basename, filename) for all files in the project.""" + if relative: + with _util.cwd(VENDORED_ROOT): + for result in _util.iter_all_files(project, **kwargs): + yield result + else: + root = project_root(project) + for result in _util.iter_all_files(root, **kwargs): + yield result + + +def iter_packaging_files(project): + """Yield the filenames for all files in the project. + + The filenames are relative to "ptvsd/_vendored". This is most + useful for the "package data" in a setup.py. + """ + # TODO: Use default filters? __pycache__ and .pyc? + prune_dir = None + exclude_file = None + try: + mod = import_module('._{}_packaging'.format(project), __name__) + except ImportError: + pass + else: + prune_dir = getattr(mod, 'prune_dir', prune_dir) + exclude_file = getattr(mod, 'exclude_file', exclude_file) + results = iter_project_files( + project, + relative=True, + prune_dir=prune_dir, + exclude_file=exclude_file, + ) + for _, _, filename in results: + yield filename + + +def prefix_matcher(*prefixes): + """Return a module match func that matches any of the given prefixes.""" + assert prefixes + + def match(name, module): + for prefix in prefixes: + if name.startswith(prefix): + return True + else: + return False + return match + + +def check_modules(project, match, root=None): + """Verify that only vendored modules have been imported.""" + if root is None: + root = project_root(project) + extensions = [] + unvendored = {} + for modname, mod in sys.modules.items(): + if not match(modname, mod): + continue + if not hasattr(mod, '__file__'): # extension module + extensions.append(modname) + elif not mod.__file__.startswith(root): + unvendored[modname] = mod.__file__ + return unvendored, extensions + + +@contextlib.contextmanager +def vendored(project, root=None): + """A context manager under which the vendored project will be imported.""" + if root is None: + root = project_root(project) + # Add the vendored project directory, so that it gets tried first. + sys.path.insert(0, root) + try: + yield root + finally: + #del sys.path[0] + sys.path.remove(root) + + +def preimport(project, modules, **kwargs): + """Import each of the named modules out of the vendored project.""" + with vendored(project, **kwargs): + for name in modules: + import_module(name) diff --git a/ptvsd/_vendored/_pydevd_packaging.py b/ptvsd/_vendored/_pydevd_packaging.py new file mode 100644 index 00000000..2a713309 --- /dev/null +++ b/ptvsd/_vendored/_pydevd_packaging.py @@ -0,0 +1,44 @@ +from . import VENDORED_ROOT +from ._util import cwd, iter_all_files + + +INCLUDES = [ + 'setup_cython.py', +] + + +def iter_files(): + # From the root of pydevd repo, we want only scripts and + # subdirectories that constitute the package itself (not helper + # scripts, tests etc). But when walking down into those + # subdirectories, we want everything below. + + with cwd(VENDORED_ROOT): + return iter_all_files('pydevd', prune_dir, exclude_file) + + +def prune_dir(dirname, basename): + if basename == '__pycache__': + return True + elif dirname != 'pydevd': + return False + elif basename.startswith('pydev'): + return False + elif basename.startswith('_pydev'): + return False + return True + + +def exclude_file(dirname, basename): + if dirname == 'pydevd': + if basename in INCLUDES: + return False + elif not basename.endswith('.py'): + return True + elif 'pydev' not in basename: + return True + return False + + if basename.endswith('.pyc'): + return True + return False diff --git a/ptvsd/_vendored/_util.py b/ptvsd/_vendored/_util.py new file mode 100644 index 00000000..7ac4d37a --- /dev/null +++ b/ptvsd/_vendored/_util.py @@ -0,0 +1,56 @@ +import contextlib +import os +import os.path + + +@contextlib.contextmanager +def cwd(dirname): + """A context manager for operating in a different directory.""" + orig = os.getcwd() + os.chdir(dirname) + try: + yield orig + finally: + os.chdir(orig) + + +def iter_all_files(root, prune_dir=None, exclude_file=None): + """Yield (dirname, basename, filename) for each file in the tree. + + This is an alternative to os.walk() that flattens out the tree and + with filtering. + """ + pending = [root] + while pending: + dirname = pending.pop(0) + for result in _iter_files(dirname, pending, prune_dir, exclude_file): + yield result + + +def iter_tree(root, prune_dir=None, exclude_file=None): + """Yield (dirname, files) for each directory in the tree. + + The list of files is actually a list of (basename, filename). + + This is an alternative to os.walk() with filtering.""" + pending = [root] + while pending: + dirname = pending.pop(0) + files = [] + for _, b, f in _iter_files(dirname, pending, prune_dir, exclude_file): + files.append((b, f)) + yield dirname, files + + +def _iter_files(dirname, subdirs, prune_dir, exclude_file): + for basename in os.listdir(dirname): + filename = os.path.join(dirname, basename) + if os.path.isdir(filename): + if prune_dir is not None and prune_dir(dirname, basename): + continue + subdirs.append(filename) + else: + # TODO: Use os.path.isfile() to narrow it down? + if exclude_file is not None and exclude_file(dirname, basename): + continue + yield dirname, basename, filename diff --git a/ptvsd/_vendored/force_pydevd.py b/ptvsd/_vendored/force_pydevd.py new file mode 100644 index 00000000..3a1f1969 --- /dev/null +++ b/ptvsd/_vendored/force_pydevd.py @@ -0,0 +1,30 @@ +import warnings + +from . import check_modules, prefix_matcher, preimport + + +# Ensure that pydevd is our vendored copy. +_unvendored, _ = check_modules('pydevd', + prefix_matcher('pydev', '_pydev')) +if _unvendored: + _unvendored = sorted(_unvendored.values()) + msg = 'incompatible copy of pydevd already imported' + #raise ImportError(msg) + warnings.warn(msg + ':\n {}'.format('\n '.join(_unvendored))) + + +# Now make sure all the top-level modules and packages in pydevd are +# loaded. Any pydevd modules that aren't loaded at this point, will +# be loaded using their parent package's __path__ (i.e. one of the +# following). +preimport('pydevd', [ + '_pydev_bundle', + '_pydev_imps', + '_pydev_runfiles', + '_pydevd_bundle', + '_pydevd_frame_eval', + 'pydev_ipython', + 'pydevd_concurrency_analyser', + 'pydevd_plugins', + 'pydevd', +]) diff --git a/setup.py b/setup.py index 434583b8..7169e4ab 100644 --- a/setup.py +++ b/setup.py @@ -12,61 +12,61 @@ import sys from setuptools import setup import versioneer +import ptvsd +import ptvsd._vendored -if not os.getenv('SKIP_CYTHON_BUILD'): +PYDEVD_ROOT = ptvsd._vendored.project_root('pydevd') +PTVSD_ROOT = os.path.dirname(os.path.abspath(ptvsd.__file__)) + + +def cython_build(): print('Compiling extension modules (set SKIP_CYTHON_BUILD=1 to omit)') - subprocess.call( - [sys.executable, 'ptvsd/pydevd/setup_cython.py', 'build_ext', '-i']) - -ROOT = os.path.dirname(os.path.abspath(__file__)) + subprocess.call([ + sys.executable, + os.path.join(PYDEVD_ROOT, 'setup_cython.py'), + 'build_ext', + '-i', + ]) -# Add pydevd files as data files for this package. They are not treated -# as a package of their own, because we don't actually want to provide -# pydevd - just use our own copy internally. -def get_pydevd_package_data(): - ptvsd_prefix = os.path.join(ROOT, 'ptvsd') - pydevd_prefix = os.path.join(ptvsd_prefix, 'pydevd') - for root, dirs, files in os.walk(pydevd_prefix): - # From the root of pydevd repo, we want only scripts and - # subdirectories that constitute the package itself (not helper - # scripts, tests etc). But when walking down into those - # subdirectories, we want everything below. - if os.path.normcase(root) == os.path.normcase(pydevd_prefix): - dirs[:] = [d - for d in dirs - if d.startswith('pydev') or d.startswith('_pydev')] - files[:] = [f - for f in files - if f.endswith('.py') and (f in ['setup_cython.py'] or 'pydev' in f)] # noqa - dirs[:] = [d for d in dirs if d != '__pycache__'] - for f in files: - yield os.path.join(root[len(ptvsd_prefix) + 1:], f) +def iter_vendored_files(): + # Add pydevd files as data files for this package. They are not + # treated as a package of their own, because we don't actually + # want to provide pydevd - just use our own copy internally. + for project in ptvsd._vendored.list_all(): + for filename in ptvsd._vendored.iter_packaging_files(project): + yield filename -PACKAGE_DATA = { - 'ptvsd': list(get_pydevd_package_data()) + ['ThirdPartyNotices.txt'], -} +if __name__ == '__main__': + if not os.getenv('SKIP_CYTHON_BUILD'): + cython_build() -setup( - name='ptvsd', - version=versioneer.get_version(), - description='Remote debugging server for Python support in Visual Studio and Visual Studio Code', # noqa - #long_description=open('DESCRIPTION.md').read(), - #long_description_content_type='text/markdown', - license='MIT', - author='Microsoft Corporation', - author_email='ptvshelp@microsoft.com', - url='https://aka.ms/ptvs', - classifiers=[ - 'Development Status :: 3 - Alpha', - 'Programming Language :: Python', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 3', - 'License :: OSI Approved :: MIT License', - ], - packages=['ptvsd'], - package_data=PACKAGE_DATA, - cmdclass=versioneer.get_cmdclass(), -) + setup( + name='ptvsd', + version=versioneer.get_version(), + description='Remote debugging server for Python support in Visual Studio and Visual Studio Code', # noqa + #long_description=open('DESCRIPTION.md').read(), + #long_description_content_type='text/markdown', + license='MIT', + author='Microsoft Corporation', + author_email='ptvshelp@microsoft.com', + url='https://aka.ms/ptvs', + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 3', + 'License :: OSI Approved :: MIT License', + ], + packages=[ + 'ptvsd', + 'ptvsd._vendored', + ], + package_data={ + 'ptvsd': ['ThirdPartyNotices.txt'], + 'ptvsd._vendored': list(iter_vendored_files()), + }, + cmdclass=versioneer.get_cmdclass(), + ) diff --git a/tests/__main__.py b/tests/__main__.py index 35cd5fdc..4f82c7f0 100644 --- a/tests/__main__.py +++ b/tests/__main__.py @@ -1,13 +1,17 @@ +from __future__ import absolute_import + import os import os.path import subprocess import sys import unittest +from ptvsd._vendored import list_all as vendored + TEST_ROOT = os.path.dirname(__file__) PROJECT_ROOT = os.path.dirname(TEST_ROOT) -PYDEVD_ROOT = os.path.join(PROJECT_ROOT, 'ptvsd', 'pydevd') +VENDORED_ROOTS = vendored(resolve=True) def convert_argv(argv): @@ -88,10 +92,9 @@ def convert_argv(argv): def fix_sys_path(): - if not sys.path[0] or sys.path[0] == '.': - sys.path.insert(1, PYDEVD_ROOT) - else: - sys.path.insert(0, PYDEVD_ROOT) + pos = 1 if (not sys.path[0] or sys.path[0] == '.') else 0 + for projectroot in VENDORED_ROOTS: + sys.path.insert(pos, projectroot) def check_lint(): @@ -100,7 +103,7 @@ def check_lint(): sys.executable, '-m', 'flake8', '--ignore', 'E24,E121,E123,E125,E126,E221,E226,E266,E704,E265', - '--exclude', 'ptvsd/pydevd', + '--exclude', ','.join(VENDORED_ROOTS), PROJECT_ROOT, ] rc = subprocess.call(args) @@ -113,16 +116,22 @@ def check_lint(): def run_tests(argv, env, coverage=False): print('running tests...') if coverage: + omissions = [os.path.join(root, '*') for root in VENDORED_ROOTS] + # TODO: Drop the explicit pydevd omit once we move the subtree. + omissions.append(os.path.join('ptvsd', 'pydevd', '*')) + ver = 3 if sys.version_info < (3,) else 2 + omissions.append(os.path.join('ptvsd', 'reraise{}.py'.format(ver))) args = [ sys.executable, '-m', 'coverage', 'run', - '--include', 'ptvsd/*.py', - '--omit', 'ptvsd/pydevd/*.py', + # We use --source instead of "--include ptvsd/*". + '--source', 'ptvsd', + '--omit', ','.join(omissions), '-m', 'unittest', ] + argv[1:] assert 'PYTHONPATH' not in env - env['PYTHONPATH'] = PYDEVD_ROOT + env['PYTHONPATH'] = os.pathsep.join(VENDORED_ROOTS) rc = subprocess.call(args, env=env) if rc != 0: print('...coverage failed!') diff --git a/tests/test_setup.py b/tests/test_setup.py new file mode 100644 index 00000000..7eed3a88 --- /dev/null +++ b/tests/test_setup.py @@ -0,0 +1,214 @@ +import unittest + +from setup import iter_vendored_files + + +class IterVendoredFilesTests(unittest.TestCase): + + def test_all(self): + filenames = set(iter_vendored_files()) + + self.assertEqual(filenames, VENDORED) + + +VENDORED = { + 'pydevd/pydev_run_in_console.py', + 'pydevd/setup_cython.py', + 'pydevd/pydev_app_engine_debug_startup.py', + 'pydevd/pydevd_tracing.py', + 'pydevd/pydev_pysrc.py', + 'pydevd/pydevconsole.py', + 'pydevd/pydevd.py', + 'pydevd/pydev_coverage.py', + 'pydevd/pydevd_file_utils.py', + 'pydevd/pydevd_attach_to_process/attach_linux_x86.so', + 'pydevd/pydevd_attach_to_process/attach_pydevd.py', + 'pydevd/pydevd_attach_to_process/attach_amd64.dll', + 'pydevd/pydevd_attach_to_process/_test_attach_to_process.py', + 'pydevd/pydevd_attach_to_process/attach_linux_amd64.so', + 'pydevd/pydevd_attach_to_process/attach_x86.dll', + 'pydevd/pydevd_attach_to_process/_always_live_program.py', + 'pydevd/pydevd_attach_to_process/attach_x86.dylib', + 'pydevd/pydevd_attach_to_process/_check.py', + 'pydevd/pydevd_attach_to_process/README.txt', + 'pydevd/pydevd_attach_to_process/add_code_to_python_process.py', + 'pydevd/pydevd_attach_to_process/attach_x86_64.dylib', + 'pydevd/pydevd_attach_to_process/attach_script.py', + 'pydevd/pydevd_attach_to_process/_test_attach_to_process_linux.py', + 'pydevd/pydevd_attach_to_process/dll/attach.h', + 'pydevd/pydevd_attach_to_process/dll/python.h', + 'pydevd/pydevd_attach_to_process/dll/attach.cpp', + 'pydevd/pydevd_attach_to_process/dll/stdafx.h', + 'pydevd/pydevd_attach_to_process/dll/compile_dll.bat', + 'pydevd/pydevd_attach_to_process/dll/stdafx.cpp', + 'pydevd/pydevd_attach_to_process/dll/targetver.h', + 'pydevd/pydevd_attach_to_process/winappdbg/module.py', + 'pydevd/pydevd_attach_to_process/winappdbg/event.py', + 'pydevd/pydevd_attach_to_process/winappdbg/process.py', + 'pydevd/pydevd_attach_to_process/winappdbg/thread.py', + 'pydevd/pydevd_attach_to_process/winappdbg/disasm.py', + 'pydevd/pydevd_attach_to_process/winappdbg/textio.py', + 'pydevd/pydevd_attach_to_process/winappdbg/sql.py', + 'pydevd/pydevd_attach_to_process/winappdbg/util.py', + 'pydevd/pydevd_attach_to_process/winappdbg/crash.py', + 'pydevd/pydevd_attach_to_process/winappdbg/registry.py', + 'pydevd/pydevd_attach_to_process/winappdbg/breakpoint.py', + 'pydevd/pydevd_attach_to_process/winappdbg/search.py', + 'pydevd/pydevd_attach_to_process/winappdbg/compat.py', + 'pydevd/pydevd_attach_to_process/winappdbg/window.py', + 'pydevd/pydevd_attach_to_process/winappdbg/interactive.py', + 'pydevd/pydevd_attach_to_process/winappdbg/__init__.py', + 'pydevd/pydevd_attach_to_process/winappdbg/system.py', + 'pydevd/pydevd_attach_to_process/winappdbg/debug.py', + 'pydevd/pydevd_attach_to_process/winappdbg/win32/shlwapi.py', + 'pydevd/pydevd_attach_to_process/winappdbg/win32/kernel32.py', + 'pydevd/pydevd_attach_to_process/winappdbg/win32/advapi32.py', + 'pydevd/pydevd_attach_to_process/winappdbg/win32/__init__.py', + 'pydevd/pydevd_attach_to_process/winappdbg/win32/psapi.py', + 'pydevd/pydevd_attach_to_process/winappdbg/win32/defines.py', + 'pydevd/pydevd_attach_to_process/winappdbg/win32/user32.py', + 'pydevd/pydevd_attach_to_process/winappdbg/win32/dbghelp.py', + 'pydevd/pydevd_attach_to_process/winappdbg/win32/version.py', + 'pydevd/pydevd_attach_to_process/winappdbg/win32/peb_teb.py', + 'pydevd/pydevd_attach_to_process/winappdbg/win32/context_amd64.py', + 'pydevd/pydevd_attach_to_process/winappdbg/win32/shell32.py', + 'pydevd/pydevd_attach_to_process/winappdbg/win32/ntdll.py', + 'pydevd/pydevd_attach_to_process/winappdbg/win32/wtsapi32.py', + 'pydevd/pydevd_attach_to_process/winappdbg/win32/context_i386.py', + 'pydevd/pydevd_attach_to_process/winappdbg/win32/gdi32.py', + 'pydevd/pydevd_attach_to_process/winappdbg/plugins/__init__.py', + 'pydevd/pydevd_attach_to_process/winappdbg/plugins/do_symfix.py', + 'pydevd/pydevd_attach_to_process/winappdbg/plugins/README', + 'pydevd/pydevd_attach_to_process/winappdbg/plugins/do_exchain.py', + 'pydevd/pydevd_attach_to_process/winappdbg/plugins/do_example.py', + 'pydevd/pydevd_attach_to_process/winappdbg/plugins/do_exploitable.py', + 'pydevd/pydevd_attach_to_process/linux/gdb_threads_settrace.py', + 'pydevd/pydevd_attach_to_process/linux/compile_mac.sh', + 'pydevd/pydevd_attach_to_process/linux/Makefile', + 'pydevd/pydevd_attach_to_process/linux/lldb_prepare.py', + 'pydevd/pydevd_attach_to_process/linux/compile_so.sh', + 'pydevd/pydevd_attach_to_process/linux/python.h', + 'pydevd/pydevd_attach_to_process/linux/attach_linux.c', + 'pydevd/pydevd_attach_to_process/linux/lldb_threads_settrace.py', + 'pydevd/_pydev_bundle/_pydev_imports_tipper.py', + 'pydevd/_pydev_bundle/_pydev_getopt.py', + 'pydevd/_pydev_bundle/pydev_umd.py', + 'pydevd/_pydev_bundle/fix_getpass.py', + 'pydevd/_pydev_bundle/pydev_is_thread_alive.py', + 'pydevd/_pydev_bundle/pydev_ipython_console.py', + 'pydevd/_pydev_bundle/_pydev_jy_imports_tipper.py', + 'pydevd/_pydev_bundle/pydev_imports.py', + 'pydevd/_pydev_bundle/pydev_override.py', + 'pydevd/_pydev_bundle/pydev_monkey.py', + 'pydevd/_pydev_bundle/pydev_localhost.py', + 'pydevd/_pydev_bundle/pydev_log.py', + 'pydevd/_pydev_bundle/pydev_ipython_console_011.py', + 'pydevd/_pydev_bundle/_pydev_tipper_common.py', + 'pydevd/_pydev_bundle/pydev_monkey_qt.py', + 'pydevd/_pydev_bundle/_pydev_log.py', + 'pydevd/_pydev_bundle/_pydev_filesystem_encoding.py', + 'pydevd/_pydev_bundle/pydev_versioncheck.py', + 'pydevd/_pydev_bundle/__init__.py', + 'pydevd/_pydev_bundle/_pydev_completer.py', + 'pydevd/_pydev_bundle/pydev_import_hook.py', + 'pydevd/_pydev_bundle/pydev_console_utils.py', + 'pydevd/_pydev_bundle/_pydev_calltip_util.py', + 'pydevd/pydevd_plugins/jinja2_debug.py', + 'pydevd/pydevd_plugins/django_debug.py', + 'pydevd/pydevd_plugins/__init__.py', + 'pydevd/pydevd_plugins/extensions/README.md', + 'pydevd/pydevd_plugins/extensions/__init__.py', + 'pydevd/pydevd_plugins/extensions/types/pydevd_plugin_numpy_types.py', + 'pydevd/pydevd_plugins/extensions/types/__init__.py', + 'pydevd/pydevd_plugins/extensions/types/pydevd_helpers.py', + 'pydevd/pydevd_plugins/extensions/types/pydevd_plugins_django_form_str.py', + 'pydevd/_pydev_runfiles/pydev_runfiles_coverage.py', + 'pydevd/_pydev_runfiles/pydev_runfiles_nose.py', + 'pydevd/_pydev_runfiles/pydev_runfiles_parallel.py', + 'pydevd/_pydev_runfiles/pydev_runfiles_pytest2.py', + 'pydevd/_pydev_runfiles/pydev_runfiles.py', + 'pydevd/_pydev_runfiles/pydev_runfiles_parallel_client.py', + 'pydevd/_pydev_runfiles/__init__.py', + 'pydevd/_pydev_runfiles/pydev_runfiles_xml_rpc.py', + 'pydevd/_pydev_runfiles/pydev_runfiles_unittest.py', + 'pydevd/pydevd_concurrency_analyser/pydevd_concurrency_logger.py', + 'pydevd/pydevd_concurrency_analyser/pydevd_thread_wrappers.py', + 'pydevd/pydevd_concurrency_analyser/__init__.py', + 'pydevd/_pydev_imps/_pydev_xmlrpclib.py', + 'pydevd/_pydev_imps/_pydev_execfile.py', + 'pydevd/_pydev_imps/_pydev_SimpleXMLRPCServer.py', + 'pydevd/_pydev_imps/_pydev_saved_modules.py', + 'pydevd/_pydev_imps/_pydev_sys_patch.py', + 'pydevd/_pydev_imps/_pydev_inspect.py', + 'pydevd/_pydev_imps/_pydev_SocketServer.py', + 'pydevd/_pydev_imps/_pydev_BaseHTTPServer.py', + 'pydevd/_pydev_imps/__init__.py', + 'pydevd/_pydev_imps/_pydev_pkgutil_old.py', + 'pydevd/_pydev_imps/_pydev_uuid_old.py', + 'pydevd/_pydevd_frame_eval/pydevd_frame_eval_cython_wrapper.py', + 'pydevd/_pydevd_frame_eval/pydevd_frame_evaluator.c', + 'pydevd/_pydevd_frame_eval/pydevd_modify_bytecode.py', + 'pydevd/_pydevd_frame_eval/pydevd_frame_evaluator.pyx', + 'pydevd/_pydevd_frame_eval/__init__.py', + 'pydevd/_pydevd_frame_eval/pydevd_frame_eval_main.py', + 'pydevd/_pydevd_frame_eval/pydevd_frame_evaluator.pxd', + 'pydevd/_pydevd_frame_eval/pydevd_frame_tracing.py', + 'pydevd/pydev_ipython/inputhookpyglet.py', + 'pydevd/pydev_ipython/inputhookgtk3.py', + 'pydevd/pydev_ipython/inputhookqt5.py', + 'pydevd/pydev_ipython/inputhookglut.py', + 'pydevd/pydev_ipython/matplotlibtools.py', + 'pydevd/pydev_ipython/inputhookqt4.py', + 'pydevd/pydev_ipython/inputhookwx.py', + 'pydevd/pydev_ipython/__init__.py', + 'pydevd/pydev_ipython/qt_loaders.py', + 'pydevd/pydev_ipython/inputhook.py', + 'pydevd/pydev_ipython/README', + 'pydevd/pydev_ipython/version.py', + 'pydevd/pydev_ipython/qt_for_kernel.py', + 'pydevd/pydev_ipython/inputhooktk.py', + 'pydevd/pydev_ipython/qt.py', + 'pydevd/pydev_ipython/inputhookgtk.py', + 'pydevd/_pydevd_bundle/pydevd_vm_type.py', + 'pydevd/_pydevd_bundle/pydevd_additional_thread_info_regular.py', + 'pydevd/_pydevd_bundle/pydevd_reload.py', + 'pydevd/_pydevd_bundle/pydevd_trace_dispatch_regular.py', + 'pydevd/_pydevd_bundle/pydevd_cython.pyx', + 'pydevd/_pydevd_bundle/pydevd_extension_utils.py', + 'pydevd/_pydevd_bundle/pydevd_stackless.py', + 'pydevd/_pydevd_bundle/pydevd_constants.py', + 'pydevd/_pydevd_bundle/pydevd_frame_utils.py', + 'pydevd/_pydevd_bundle/pydevd_dont_trace_files.py', + 'pydevd/_pydevd_bundle/pydevd_frame.py', + 'pydevd/_pydevd_bundle/pydevd_xml.py', + 'pydevd/_pydevd_bundle/pydevd_extension_api.py', + 'pydevd/_pydevd_bundle/pydevd_comm.py', + 'pydevd/_pydevd_bundle/pydevd_kill_all_pydevd_threads.py', + 'pydevd/_pydevd_bundle/pydevd_traceproperty.py', + 'pydevd/_pydevd_bundle/pydevd_command_line_handling.py', + 'pydevd/_pydevd_bundle/pydevd_io.py', + 'pydevd/_pydevd_bundle/pydevd_dont_trace.py', + 'pydevd/_pydevd_bundle/pydevd_trace_dispatch.py', + 'pydevd/_pydevd_bundle/pydevd_signature.py', + 'pydevd/_pydevd_bundle/pydevd_import_class.py', + 'pydevd/_pydevd_bundle/pydevd_custom_frames.py', + 'pydevd/_pydevd_bundle/pydevd_additional_thread_info.py', + 'pydevd/_pydevd_bundle/pydevd_exec.py', + 'pydevd/_pydevd_bundle/pydevd_vars.py', + 'pydevd/_pydevd_bundle/pydevd_exec2.py', + 'pydevd/_pydevd_bundle/pydevd_cython_wrapper.py', + 'pydevd/_pydevd_bundle/pydevd_plugin_utils.py', + 'pydevd/_pydevd_bundle/pydevconsole_code_for_ironpython.py', + 'pydevd/_pydevd_bundle/pydevd_process_net_command.py', + 'pydevd/_pydevd_bundle/pydevd_resolver.py', + 'pydevd/_pydevd_bundle/pydevd_utils.py', + 'pydevd/_pydevd_bundle/pydevd_console.py', + 'pydevd/_pydevd_bundle/pydevd_referrers.py', + 'pydevd/_pydevd_bundle/pydevd_cython.c', + 'pydevd/_pydevd_bundle/pydevd_breakpoints.py', + 'pydevd/_pydevd_bundle/__init__.py', + 'pydevd/_pydevd_bundle/pydevd_trace_api.py', + 'pydevd/_pydevd_bundle/pydevd_save_locals.py', + 'pydevd/pydev_sitecustomize/sitecustomize.py', + 'pydevd/pydev_sitecustomize/__not_in_default_pythonpath.txt', +}