예제 #1
0
def get_breakpoint(plugin, py_db, pydb_frame, frame, event, args):
    py_db = args[0]
    _filename = args[1]
    info = args[2]
    break_type = 'jinja2'

    if event == 'line' and info.pydev_state != STATE_SUSPEND and py_db.jinja2_breakpoints and _is_jinja2_render_call(frame):

        jinja_template = frame.f_globals.get('__jinja_template__')
        if jinja_template is None:
            return False, None, None, break_type

        original_filename = _get_jinja2_template_original_filename(frame)
        if original_filename is not None:
            pydev_log.debug("Jinja2 is rendering a template: %s", original_filename)
            canonical_normalized_filename = canonical_normalized_path(original_filename)
            jinja2_breakpoints_for_file = py_db.jinja2_breakpoints.get(canonical_normalized_filename)

            if jinja2_breakpoints_for_file:

                jinja2_validation_info = py_db.jinja2_validation_info
                jinja2_validation_info.verify_breakpoints(py_db, canonical_normalized_filename, jinja2_breakpoints_for_file, jinja_template)

                template_lineno = _get_jinja2_template_line(frame)
                if template_lineno is not None:
                    jinja2_breakpoint = jinja2_breakpoints_for_file.get(template_lineno)
                    if jinja2_breakpoint is not None:
                        new_frame = Jinja2TemplateFrame(frame, original_filename, template_lineno)
                        return True, jinja2_breakpoint, new_frame, break_type

    return False, None, None, break_type
예제 #2
0
    def cmd_ignore_thrown_exception_at(self, py_db, cmd_id, seq, text):
        if text:
            replace = 'REPLACE:'  # Not all 3.x versions support u'REPLACE:', so, doing workaround.
            if not IS_PY3K:
                replace = unicode(replace)  # noqa

            if text.startswith(replace):
                text = text[8:]
                py_db.filename_to_lines_where_exceptions_are_ignored.clear()

            if text:
                for line in text.split('||'):  # Can be bulk-created (one in each line)
                    original_filename, line_number = line.split('|')
                    original_filename = self.api.filename_to_server(original_filename)

                    canonical_normalized_filename = pydevd_file_utils.canonical_normalized_path(original_filename)
                    absolute_filename = pydevd_file_utils.absolute_path(original_filename)

                    if os.path.exists(absolute_filename):
                        lines_ignored = py_db.filename_to_lines_where_exceptions_are_ignored.get(canonical_normalized_filename)
                        if lines_ignored is None:
                            lines_ignored = py_db.filename_to_lines_where_exceptions_are_ignored[canonical_normalized_filename] = {}
                        lines_ignored[int(line_number)] = 1
                    else:
                        sys.stderr.write('pydev debugger: warning: trying to ignore exception thrown'\
                            ' on file that does not exist: %s (will have no effect)\n' % (absolute_filename,))
예제 #3
0
파일: jinja2_debug.py 프로젝트: ZeeD/Pydev
def can_skip(plugin, pydb, frame):
    if pydb.jinja2_breakpoints and _is_jinja2_render_call(frame):
        filename = _get_jinja2_template_original_filename(frame)
        if filename is not None:
            canonical_normalized_filename = canonical_normalized_path(filename)
            jinja2_breakpoints_for_file = pydb.jinja2_breakpoints.get(canonical_normalized_filename)
            if jinja2_breakpoints_for_file:
                return False

    if pydb.jinja2_exception_break:
        name = frame.f_code.co_name

        if IS_PY2:
            if name == 'fail':
                module_name = frame.f_globals.get('__name__', '')
                if module_name == 'jinja2.parser':
                    return False
        else:
            # errors in compile time
            if name in ('template', 'top-level template code', '<module>') or name.startswith('block '):
                f_back = frame.f_back
                module_name = ''
                if f_back is not None:
                    module_name = f_back.f_globals.get('__name__', '')
                if module_name.startswith('jinja2.'):
                    return False

    return True
예제 #4
0
def get_breakpoint(plugin, pydb, pydb_frame, frame, event, args):
    pydb = args[0]
    _filename = args[1]
    info = args[2]
    new_frame = None
    jinja2_breakpoint = None
    flag = False
    break_type = 'jinja2'
    if event == 'line' and info.pydev_state != STATE_SUSPEND and \
            pydb.jinja2_breakpoints and _is_jinja2_render_call(frame):
        original_filename = _get_jinja2_template_original_filename(frame)
        if original_filename is not None:
            pydev_log.debug("Jinja2 is rendering a template: %s", original_filename)
            canonical_normalized_filename = canonical_normalized_path(original_filename)
            jinja2_breakpoints_for_file = pydb.jinja2_breakpoints.get(canonical_normalized_filename)

            if jinja2_breakpoints_for_file:
                template_lineno = _get_jinja2_template_line(frame)
                if template_lineno is not None:
                    jinja2_breakpoint = jinja2_breakpoints_for_file.get(template_lineno)
                    if jinja2_breakpoint is not None:
                        flag = True
                        new_frame = Jinja2TemplateFrame(frame, original_filename, template_lineno)

    return flag, jinja2_breakpoint, new_frame, break_type
예제 #5
0
def get_breakpoint(plugin, main_debugger, pydb_frame, frame, event, args):
    main_debugger = args[0]
    _filename = args[1]
    info = args[2]
    flag = False
    django_breakpoint = None
    new_frame = None
    breakpoint_type = 'django'

    if event == 'call' and info.pydev_state != STATE_SUSPEND and main_debugger.django_breakpoints and _is_django_render_call(
            frame):
        original_filename = _get_template_original_file_name_from_frame(frame)
        pydev_log.debug("Django is rendering a template: %s",
                        original_filename)

        canonical_normalized_filename = canonical_normalized_path(
            original_filename)
        django_breakpoints_for_file = main_debugger.django_breakpoints.get(
            canonical_normalized_filename)

        if django_breakpoints_for_file:
            pydev_log.debug("Breakpoints for that file: %s",
                            django_breakpoints_for_file)
            template_line = _get_template_line(frame)
            pydev_log.debug("Tracing template line: %s", template_line)

            if template_line in django_breakpoints_for_file:
                django_breakpoint = django_breakpoints_for_file[template_line]
                flag = True
                new_frame = DjangoTemplateFrame(frame)

    return flag, django_breakpoint, new_frame, breakpoint_type
예제 #6
0
    def remove_breakpoint(self, py_db, received_filename, breakpoint_type, breakpoint_id):
        '''
        :param str received_filename:
            Note: must be sent as it was received in the protocol. It may be translated in this
            function.

        :param str breakpoint_type:
            One of: 'python-line', 'django-line', 'jinja2-line'.

        :param int breakpoint_id:
        '''
        for key, val in dict_items(py_db.api_received_breakpoints):
            original_filename, existing_breakpoint_id = key
            _new_filename, _api_add_breakpoint_params = val
            if received_filename == original_filename and existing_breakpoint_id == breakpoint_id:
                del py_db.api_received_breakpoints[key]
                break
        else:
            pydev_log.info(
                'Did not find breakpoint to remove: %s (breakpoint id: %s)', received_filename, breakpoint_id)

        file_to_id_to_breakpoint = None
        received_filename = self.filename_to_server(received_filename)
        canonical_normalized_filename = pydevd_file_utils.canonical_normalized_path(received_filename)

        if breakpoint_type == 'python-line':
            breakpoints = py_db.breakpoints
            file_to_id_to_breakpoint = py_db.file_to_id_to_line_breakpoint

        elif py_db.plugin is not None:
            result = py_db.plugin.get_breakpoints(py_db, breakpoint_type)
            if result is not None:
                file_to_id_to_breakpoint = py_db.file_to_id_to_plugin_breakpoint
                breakpoints = result

        if file_to_id_to_breakpoint is None:
            pydev_log.critical('Error removing breakpoint. Cannot handle breakpoint of type %s', breakpoint_type)

        else:
            try:
                id_to_pybreakpoint = file_to_id_to_breakpoint.get(canonical_normalized_filename, {})
                if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
                    existing = id_to_pybreakpoint[breakpoint_id]
                    pydev_log.info('Removed breakpoint:%s - line:%s - func_name:%s (id: %s)\n' % (
                        canonical_normalized_filename, existing.line, existing.func_name.encode('utf-8'), breakpoint_id))

                del id_to_pybreakpoint[breakpoint_id]
                py_db.consolidate_breakpoints(canonical_normalized_filename, id_to_pybreakpoint, breakpoints)
                if py_db.plugin is not None:
                    py_db.has_plugin_line_breaks = py_db.plugin.has_line_breaks()

            except KeyError:
                pydev_log.info("Error removing breakpoint: Breakpoint id not found: %s id: %s. Available ids: %s\n",
                    canonical_normalized_filename, breakpoint_id, dict_keys(id_to_pybreakpoint))

        py_db.on_breakpoints_changed(removed=True)
def _load_filters():
    global py_test_accept_filter
    if py_test_accept_filter is None:
        py_test_accept_filter = os.environ.get('PYDEV_PYTEST_SKIP')
        if py_test_accept_filter:
            py_test_accept_filter = pickle.loads(
                zlib.decompress(base64.b64decode(py_test_accept_filter)))

            # Newer versions of pytest resolve symlinks, so, we
            # may need to filter with a resolved path too.
            new_dct = {}
            for filename, value in py_test_accept_filter.items():
                new_dct[canonical_normalized_path(str(
                    Path(filename).resolve()))] = value

            py_test_accept_filter.update(new_dct)

        else:
            py_test_accept_filter = {}
예제 #8
0
def get_breakpoint(plugin, py_db, pydb_frame, frame, event, args):
    py_db = args[0]
    _filename = args[1]
    info = args[2]
    breakpoint_type = 'django'

    if event == 'call' and info.pydev_state != STATE_SUSPEND and py_db.django_breakpoints and _is_django_render_call(
            frame):
        original_filename = _get_template_original_file_name_from_frame(frame)
        pydev_log.debug("Django is rendering a template: %s",
                        original_filename)

        canonical_normalized_filename = canonical_normalized_path(
            original_filename)
        django_breakpoints_for_file = py_db.django_breakpoints.get(
            canonical_normalized_filename)

        if django_breakpoints_for_file:

            # At this point, let's validate whether template lines are correct.
            if IS_DJANGO19_OR_HIGHER:
                django_validation_info = py_db.django_validation_info
                context = frame.f_locals['context']
                django_template = context.template
                django_validation_info.verify_breakpoints(
                    py_db, canonical_normalized_filename,
                    django_breakpoints_for_file, django_template)

            pydev_log.debug("Breakpoints for that file: %s",
                            django_breakpoints_for_file)
            template_line = _get_template_line(frame)
            pydev_log.debug("Tracing template line: %s", template_line)

            if template_line in django_breakpoints_for_file:
                django_breakpoint = django_breakpoints_for_file[template_line]
                new_frame = DjangoTemplateFrame(frame)
                return True, django_breakpoint, new_frame, breakpoint_type

    return False, None, None, breakpoint_type
def pytest_collection_modifyitems(session, config, items):
    # A note: in xdist, this is not called on the main process, only in the
    # secondary nodes, so, we'll actually make the filter and report it multiple
    # times.
    connect_to_server_for_communication_to_xml_rpc_on_xdist()

    _load_filters()
    if not py_test_accept_filter:
        pydev_runfiles_xml_rpc.notifyTestsCollected(len(items))
        return  # Keep on going (nothing to filter)

    new_items = []
    for item in items:
        f = canonical_normalized_path(str(item.parent.fspath))
        name = item.name

        if f not in py_test_accept_filter:
            # print('Skip file: %s' % (f,))
            continue  # Skip the file

        i = name.find('[')
        name_without_parametrize = None
        if i > 0:
            name_without_parametrize = name[:i]

        accept_tests = py_test_accept_filter[f]

        if item.cls is not None:
            class_name = item.cls.__name__
        else:
            class_name = None
        for test in accept_tests:
            if test == name:
                # Direct match of the test (just go on with the default
                # loading)
                new_items.append(item)
                break

            if name_without_parametrize is not None and test == name_without_parametrize:
                # This happens when parameterizing pytest tests on older versions
                # of pytest where the test name doesn't include the fixture name
                # in it.
                new_items.append(item)
                break

            if class_name is not None:
                if test == class_name + '.' + name:
                    new_items.append(item)
                    break

                if name_without_parametrize is not None and test == class_name + '.' + name_without_parametrize:
                    new_items.append(item)
                    break

                if class_name == test:
                    new_items.append(item)
                    break
        else:
            pass
            # print('Skip test: %s.%s. Accept: %s' % (class_name, name, accept_tests))

    # Modify the original list
    items[:] = new_items
    pydev_runfiles_xml_rpc.notifyTestsCollected(len(items))
예제 #10
0
    def add_breakpoint(self,
                       py_db,
                       original_filename,
                       breakpoint_type,
                       breakpoint_id,
                       line,
                       condition,
                       func_name,
                       expression,
                       suspend_policy,
                       hit_condition,
                       is_logpoint,
                       adjust_line=False):
        '''
        :param str original_filename:
            Note: must be sent as it was received in the protocol. It may be translated in this
            function and its final value will be available in the returned _AddBreakpointResult.

        :param str breakpoint_type:
            One of: 'python-line', 'django-line', 'jinja2-line'.

        :param int breakpoint_id:

        :param int line:
            Note: it's possible that a new line was actually used. If that's the case its
            final value will be available in the returned _AddBreakpointResult.

        :param condition:
            Either None or the condition to activate the breakpoint.

        :param str func_name:
            If "None" (str), may hit in any context.
            Empty string will hit only top level.
            Any other value must match the scope of the method to be matched.

        :param str expression:
            None or the expression to be evaluated.

        :param suspend_policy:
            Either "NONE" (to suspend only the current thread when the breakpoint is hit) or
            "ALL" (to suspend all threads when a breakpoint is hit).

        :param str hit_condition:
            An expression where `@HIT@` will be replaced by the number of hits.
            i.e.: `@HIT@ == x` or `@HIT@ >= x`

        :param bool is_logpoint:
            If True and an expression is passed, pydevd will create an io message command with the
            result of the evaluation.

        :return _AddBreakpointResult:
        '''
        assert original_filename.__class__ == str, 'Expected str, found: %s' % (
            original_filename.__class__, )  # i.e.: bytes on py2 and str on py3

        pydev_log.debug('Request for breakpoint in: %s line: %s',
                        original_filename, line)
        # Parameters to reapply breakpoint.
        api_add_breakpoint_params = (original_filename, breakpoint_type,
                                     breakpoint_id, line, condition, func_name,
                                     expression, suspend_policy, hit_condition,
                                     is_logpoint)

        translated_filename = self.filename_to_server(
            original_filename)  # Apply user path mapping.
        pydev_log.debug('Breakpoint (after path translation) in: %s line: %s',
                        translated_filename, line)
        func_name = self.to_str(func_name)

        assert translated_filename.__class__ == str  # i.e.: bytes on py2 and str on py3
        assert func_name.__class__ == str  # i.e.: bytes on py2 and str on py3

        # Apply source mapping (i.e.: ipython).
        source_mapped_filename, new_line, multi_mapping_applied = py_db.source_mapping.map_to_server(
            translated_filename, line)

        if multi_mapping_applied:
            pydev_log.debug(
                'Breakpoint (after source mapping) in: %s line: %s',
                source_mapped_filename, new_line)
            # Note that source mapping is internal and does not change the resulting filename nor line
            # (we want the outside world to see the line in the original file and not in the ipython
            # cell, otherwise the editor wouldn't be correct as the returned line is the line to
            # which the breakpoint will be moved in the editor).
            result = self._AddBreakpointResult(original_filename, line)

            # If a multi-mapping was applied, consider it the canonical / source mapped version (translated to ipython cell).
            translated_absolute_filename = source_mapped_filename
            canonical_normalized_filename = pydevd_file_utils.normcase(
                source_mapped_filename)
            line = new_line

        else:
            translated_absolute_filename = pydevd_file_utils.absolute_path(
                translated_filename)
            canonical_normalized_filename = pydevd_file_utils.canonical_normalized_path(
                translated_filename)

            if adjust_line and not translated_absolute_filename.startswith(
                    '<'):
                # Validate breakpoints and adjust their positions.
                try:
                    lines = sorted(
                        _get_code_lines(translated_absolute_filename))
                except Exception:
                    pass
                else:
                    if line not in lines:
                        # Adjust to the first preceding valid line.
                        idx = bisect.bisect_left(lines, line)
                        if idx > 0:
                            line = lines[idx - 1]

            result = self._AddBreakpointResult(original_filename, line)

        py_db.api_received_breakpoints[(original_filename, breakpoint_id)] = (
            canonical_normalized_filename, api_add_breakpoint_params)

        if not translated_absolute_filename.startswith('<'):
            # Note: if a mapping pointed to a file starting with '<', don't validate.

            if not pydevd_file_utils.exists(translated_absolute_filename):
                result.error_code = self.ADD_BREAKPOINT_FILE_NOT_FOUND
                return result

            if (py_db.is_files_filter_enabled
                    and not py_db.get_require_module_for_filters()
                    and py_db.apply_files_filter(
                        self._DummyFrame(translated_absolute_filename),
                        translated_absolute_filename, False)):
                # Note that if `get_require_module_for_filters()` returns False, we don't do this check.
                # This is because we don't have the module name given a file at this point (in
                # runtime it's gotten from the frame.f_globals).
                # An option could be calculate it based on the filename and current sys.path,
                # but on some occasions that may be wrong (for instance with `__main__` or if
                # the user dynamically changes the PYTHONPATH).

                # Note: depending on the use-case, filters may be changed, so, keep on going and add the
                # breakpoint even with the error code.
                result.error_code = self.ADD_BREAKPOINT_FILE_EXCLUDED_BY_FILTERS

        if breakpoint_type == 'python-line':
            added_breakpoint = LineBreakpoint(line,
                                              condition,
                                              func_name,
                                              expression,
                                              suspend_policy,
                                              hit_condition=hit_condition,
                                              is_logpoint=is_logpoint)
            breakpoints = py_db.breakpoints
            file_to_id_to_breakpoint = py_db.file_to_id_to_line_breakpoint
            supported_type = True

        else:
            add_plugin_breakpoint_result = None
            plugin = py_db.get_plugin_lazy_init()
            if plugin is not None:
                add_plugin_breakpoint_result = plugin.add_breakpoint(
                    'add_line_breakpoint',
                    py_db,
                    breakpoint_type,
                    canonical_normalized_filename,
                    line,
                    condition,
                    expression,
                    func_name,
                    hit_condition=hit_condition,
                    is_logpoint=is_logpoint)

            if add_plugin_breakpoint_result is not None:
                supported_type = True
                added_breakpoint, breakpoints = add_plugin_breakpoint_result
                file_to_id_to_breakpoint = py_db.file_to_id_to_plugin_breakpoint
            else:
                supported_type = False

        if not supported_type:
            raise NameError(breakpoint_type)

        if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
            pydev_log.debug('Added breakpoint:%s - line:%s - func_name:%s\n',
                            canonical_normalized_filename, line, func_name)

        if canonical_normalized_filename in file_to_id_to_breakpoint:
            id_to_pybreakpoint = file_to_id_to_breakpoint[
                canonical_normalized_filename]
        else:
            id_to_pybreakpoint = file_to_id_to_breakpoint[
                canonical_normalized_filename] = {}

        id_to_pybreakpoint[breakpoint_id] = added_breakpoint
        py_db.consolidate_breakpoints(canonical_normalized_filename,
                                      id_to_pybreakpoint, breakpoints)
        if py_db.plugin is not None:
            py_db.has_plugin_line_breaks = py_db.plugin.has_line_breaks()

        py_db.on_breakpoints_changed()
        return result
예제 #11
0
파일: runfiles.py 프로젝트: truenas/pydevd
def main():
    import sys

    # Separate the nose params and the pydev params.
    pydev_params = []
    other_test_framework_params = []
    found_other_test_framework_param = None

    NOSE_PARAMS = '--nose-params'
    PY_TEST_PARAMS = '--py-test-params'

    for arg in sys.argv[1:]:
        if not found_other_test_framework_param and arg != NOSE_PARAMS and arg != PY_TEST_PARAMS:
            pydev_params.append(arg)

        else:
            if not found_other_test_framework_param:
                found_other_test_framework_param = arg
            else:
                other_test_framework_params.append(arg)

    try:
        # Convert to the case stored in the filesystem
        import win32api
        def get_with_filesystem_case(f):
            return win32api.GetLongPathName(win32api.GetShortPathName(f))
    except:
        def get_with_filesystem_case(f):
            return f

    # Here we'll run either with nose or with the pydev_runfiles.
    from _pydev_runfiles import pydev_runfiles
    from _pydev_runfiles import pydev_runfiles_xml_rpc
    from _pydevd_bundle import pydevd_constants
    from pydevd_file_utils import canonical_normalized_path

    DEBUG = 0
    if DEBUG:
        sys.stdout.write('Received parameters: %s\n' % (sys.argv,))
        sys.stdout.write('Params for pydev: %s\n' % (pydev_params,))
        if found_other_test_framework_param:
            sys.stdout.write('Params for test framework: %s, %s\n' % (found_other_test_framework_param, other_test_framework_params))

    try:
        configuration = pydev_runfiles.parse_cmdline([sys.argv[0]] + pydev_params)
    except:
        sys.stderr.write('Command line received: %s\n' % (sys.argv,))
        raise
    pydev_runfiles_xml_rpc.initialize_server(configuration.port)  # Note that if the port is None, a Null server will be initialized.

    NOSE_FRAMEWORK = "nose"
    PY_TEST_FRAMEWORK = "py.test"
    test_framework = None  # Default (pydev)
    try:
        if found_other_test_framework_param:
            if found_other_test_framework_param == NOSE_PARAMS:
                test_framework = NOSE_FRAMEWORK
                import nose

            elif found_other_test_framework_param == PY_TEST_PARAMS:
                test_framework = PY_TEST_FRAMEWORK
                import pytest

            else:
                raise ImportError('Test framework: %s not supported.' % (found_other_test_framework_param,))

        else:
            raise ImportError()

    except ImportError:
        if found_other_test_framework_param:
            raise

        test_framework = None

    # Clear any exception that may be there so that clients don't see it.
    # See: https://sourceforge.net/tracker/?func=detail&aid=3408057&group_id=85796&atid=577329
    if hasattr(sys, 'exc_clear'):
        sys.exc_clear()

    if not test_framework:

        return pydev_runfiles.main(configuration)  # Note: still doesn't return a proper value.

    else:
        # We'll convert the parameters to what nose or py.test expects.
        # The supported parameters are:
        # runfiles.py  --config-file|-t|--tests <Test.test1,Test2>  dirs|files --nose-params xxx yyy zzz
        # (all after --nose-params should be passed directly to nose)

        # In java:
        # --tests = Constants.ATTR_UNITTEST_TESTS
        # --config-file = Constants.ATTR_UNITTEST_CONFIGURATION_FILE


        # The only thing actually handled here are the tests that we want to run, which we'll
        # handle and pass as what the test framework expects.

        py_test_accept_filter = {}
        files_to_tests = configuration.files_to_tests

        if files_to_tests:
            # Handling through the file contents (file where each line is a test)
            files_or_dirs = []
            for file, tests in files_to_tests.items():
                if test_framework == NOSE_FRAMEWORK:
                    for test in tests:
                        files_or_dirs.append(file + ':' + test)

                elif test_framework == PY_TEST_FRAMEWORK:
                    py_test_accept_filter[file] = tests
                    py_test_accept_filter[canonical_normalized_path(file)] = tests
                    files_or_dirs.append(file)

                else:
                    raise AssertionError('Cannot handle test framework: %s at this point.' % (test_framework,))

        else:
            if configuration.tests:
                # Tests passed (works together with the files_or_dirs)
                files_or_dirs = []
                for file in configuration.files_or_dirs:
                    if test_framework == NOSE_FRAMEWORK:
                        for t in configuration.tests:
                            files_or_dirs.append(file + ':' + t)

                    elif test_framework == PY_TEST_FRAMEWORK:
                        py_test_accept_filter[file] = configuration.tests
                        py_test_accept_filter[canonical_normalized_path(file)] = configuration.tests
                        files_or_dirs.append(file)

                    else:
                        raise AssertionError('Cannot handle test framework: %s at this point.' % (test_framework,))
            else:
                # Only files or dirs passed (let it do the test-loading based on those paths)
                files_or_dirs = configuration.files_or_dirs

        argv = other_test_framework_params + files_or_dirs


        if test_framework == NOSE_FRAMEWORK:
            # Nose usage: http://somethingaboutorange.com/mrl/projects/nose/0.11.2/usage.html
            # show_stdout_option = ['-s']
            # processes_option = ['--processes=2']
            argv.insert(0, sys.argv[0])
            if DEBUG:
                sys.stdout.write('Final test framework args: %s\n' % (argv[1:],))

            from _pydev_runfiles import pydev_runfiles_nose
            PYDEV_NOSE_PLUGIN_SINGLETON = pydev_runfiles_nose.start_pydev_nose_plugin_singleton(configuration)
            argv.append('--with-pydevplugin')
            # Return 'not' because it will return 'success' (so, exit == 0 if success)
            return not nose.run(argv=argv, addplugins=[PYDEV_NOSE_PLUGIN_SINGLETON])

        elif test_framework == PY_TEST_FRAMEWORK:

            if '--coverage_output_dir' in pydev_params and '--coverage_include' in pydev_params:
                coverage_output_dir = pydev_params[pydev_params.index('--coverage_output_dir') + 1]
                coverage_include = pydev_params[pydev_params.index('--coverage_include') + 1]
                try:
                    import pytest_cov
                except ImportError:
                    sys.stderr.write('To do a coverage run with pytest the pytest-cov library is needed (i.e.: pip install pytest-cov).\n\n')
                    raise

                argv.insert(0, '--cov-append')
                argv.insert(1, '--cov-report=')
                argv.insert(2, '--cov=%s' % (coverage_include,))

                import time
                os.environ['COVERAGE_FILE'] = os.path.join(coverage_output_dir, '.coverage.%s' % (time.time(),))

            if DEBUG:
                sys.stdout.write('Final test framework args: %s\n' % (argv,))
                sys.stdout.write('py_test_accept_filter: %s\n' % (py_test_accept_filter,))

            def dotted(p):
                # Helper to convert path to have dots instead of slashes
                return os.path.normpath(p).replace(os.sep, "/").replace('/', '.')

            curr_dir = os.path.realpath('.')
            curr_dotted = dotted(curr_dir) + '.'

            # Overcome limitation on py.test:
            # When searching conftest if we have a structure as:
            # /my_package
            # /my_package/conftest.py
            # /my_package/tests
            # /my_package/tests/test_my_package.py
            # The test_my_package won't have access to the conftest contents from the
            # test_my_package.py file unless the working dir is set to /my_package.
            #
            # See related issue (for which we work-around below):
            # https://bitbucket.org/hpk42/pytest/issue/639/conftest-being-loaded-twice-giving

            for path in sys.path:
                path_dotted = dotted(path)
                if curr_dotted.startswith(path_dotted):
                    os.chdir(path)
                    break

            remove = []
            for i in xrange(len(argv)):
                arg = argv[i]
                # Workaround bug in py.test: if we pass the full path it ends up importing conftest
                # more than once (so, always work with relative paths).
                if os.path.isfile(arg) or os.path.isdir(arg):
                    
                    # Args must be passed with the proper case in the filesystem (otherwise
                    # python itself may not recognize it).
                    arg = get_with_filesystem_case(arg)
                    argv[i] = arg

                    from os.path import relpath
                    try:
                        # May fail if on different drives
                        arg = relpath(arg)
                    except ValueError:
                        pass
                    else:
                        argv[i] = arg
                elif '<unable to get>' in arg:
                    remove.append(i)

            for i in reversed(remove):
                del argv[i]

            # To find our runfile helpers (i.e.: plugin)...
            d = os.path.dirname(__file__)
            if d not in sys.path:
                sys.path.insert(0, d)

            import pickle, zlib, base64

            # Update environment PYTHONPATH so that it finds our plugin if using xdist.
            os.environ['PYTHONPATH'] = os.pathsep.join(sys.path)

            # Set what should be skipped in the plugin through an environment variable
            s = base64.b64encode(zlib.compress(pickle.dumps(py_test_accept_filter)))
            if pydevd_constants.IS_PY3K:
                s = s.decode('ascii')  # Must be str in py3.
            os.environ['PYDEV_PYTEST_SKIP'] = s

            # Identifies the main pid (i.e.: if it's not the main pid it has to connect back to the
            # main pid to give xml-rpc notifications).
            os.environ['PYDEV_MAIN_PID'] = str(os.getpid())
            os.environ['PYDEV_PYTEST_SERVER'] = str(configuration.port)

            argv.append('-p')
            argv.append('_pydev_runfiles.pydev_runfiles_pytest2')
            return pytest.main(argv)

        else:
            raise AssertionError('Cannot handle test framework: %s at this point.' % (test_framework,))