diff --git a/src/debugpy/common/messaging.py b/src/debugpy/common/messaging.py index c854e0ab..6efc75e6 100644 --- a/src/debugpy/common/messaging.py +++ b/src/debugpy/common/messaging.py @@ -74,22 +74,8 @@ class JsonIOStream(object): def from_stdio(cls, name="stdio"): """Creates a new instance that receives messages from sys.stdin, and sends them to sys.stdout. - - On Win32, this also sets stdin and stdout to binary mode, since the protocol - requires that to work properly. """ - if sys.version_info >= (3,): - stdin = sys.stdin.buffer - stdout = sys.stdout.buffer - else: - stdin = sys.stdin - stdout = sys.stdout - if sys.platform == "win32": - import os, msvcrt - - msvcrt.setmode(stdin.fileno(), os.O_BINARY) - msvcrt.setmode(stdout.fileno(), os.O_BINARY) - return cls(stdin, stdout, name) + return cls(sys.stdin.buffer, sys.stdout.buffer, name) @classmethod def from_process(cls, process, name="stdio"): @@ -174,10 +160,7 @@ class JsonIOStream(object): # On Python 2, close() will raise an exception if there is a concurrent # read() or write(), which is a common and expected occurrence with # JsonMessageChannel, so don't even bother logging it. - if sys.version_info >= (3,): - log.reraise_exception( - "Error while closing {0} message stream", self.name - ) + log.reraise_exception("Error while closing {0} message stream", self.name) def _log_message(self, dir, data, logger=log.debug): format_string = "{0} {1} " + ( diff --git a/src/debugpy/common/timestamp.py b/src/debugpy/common/timestamp.py index 1101362a..2913b60c 100644 --- a/src/debugpy/common/timestamp.py +++ b/src/debugpy/common/timestamp.py @@ -5,25 +5,18 @@ """Provides monotonic timestamps with a resetable zero. """ -import sys import time __all__ = ["current", "reset"] -if sys.version_info >= (3, 5): - clock = time.monotonic -else: - clock = time.clock - - def current(): - return clock() - timestamp_zero + return time.monotonic() - timestamp_zero def reset(): global timestamp_zero - timestamp_zero = clock() + timestamp_zero = time.monotonic() reset() diff --git a/src/debugpy/launcher/handlers.py b/src/debugpy/launcher/handlers.py index 30125206..5b12849d 100644 --- a/src/debugpy/launcher/handlers.py +++ b/src/debugpy/launcher/handlers.py @@ -2,7 +2,6 @@ # Licensed under the MIT License. See LICENSE in the project root # for license information. -import functools import os import sys @@ -136,14 +135,6 @@ def launch_request(request): ) debuggee.wait_on_exit_predicates.append(lambda code: code != 0) - if sys.version_info < (3,): - # Popen() expects command line and environment to be bytes, not Unicode. - # Assume that values are filenames - it's usually either that, or numbers - - # but don't allow encoding to fail if we guessed wrong. - encode = functools.partial(compat.filename_bytes, errors="replace") - cmdline = [encode(s) for s in cmdline] - env = {encode(k): encode(v) for k, v in env.items()} - debuggee.spawn(process_name, cmdline, env, redirect_output) return {} diff --git a/src/debugpy/launcher/output.py b/src/debugpy/launcher/output.py index 94257a5b..cf3f7e5f 100644 --- a/src/debugpy/launcher/output.py +++ b/src/debugpy/launcher/output.py @@ -4,7 +4,6 @@ import codecs import os -import sys import threading from debugpy import launcher @@ -33,7 +32,7 @@ class CaptureOutput(object): # Can happen if running under pythonw.exe. self._stream = None else: - self._stream = stream if sys.version_info < (3,) else stream.buffer + self._stream = stream.buffer encoding = stream.encoding if encoding is None or encoding == "cp65001": encoding = "utf-8" diff --git a/src/debugpy/server/cli.py b/src/debugpy/server/cli.py index e74d435e..8dd79e71 100644 --- a/src/debugpy/server/cli.py +++ b/src/debugpy/server/cli.py @@ -7,6 +7,7 @@ import os import re import runpy import sys +from importlib.util import find_spec # debugpy.__main__ should have preloaded pydevd properly before importing this module. # Otherwise, some stdlib modules above might have had imported threading before pydevd @@ -289,20 +290,13 @@ def run_module(): sys.path.insert(0, str("")) # We want to do the same thing that run_module() would do here, without - # actually invoking it. On Python 3, it's exposed as a public API, but - # on Python 2, we have to invoke a private function in runpy for this. - # Either way, if it fails to resolve for any reason, just leave argv as is. + # actually invoking it. argv_0 = sys.argv[0] target_as_str = compat.filename_str(options.target) try: - if sys.version_info >= (3,): - from importlib.util import find_spec - - spec = find_spec(target_as_str) - if spec is not None: - argv_0 = spec.origin - else: - _, _, _, argv_0 = runpy._get_module_details(target_as_str) + spec = find_spec(target_as_str) + if spec is not None: + argv_0 = spec.origin except Exception: log.swallow_exception("Error determining module path for sys.argv") diff --git a/tests/debug/config.py b/tests/debug/config.py index fdf6b2d0..22428f47 100644 --- a/tests/debug/config.py +++ b/tests/debug/config.py @@ -3,12 +3,7 @@ # for license information. import os -import sys - -if sys.version_info >= (3, 3): - from collections.abc import MutableMapping, MutableSet -else: - from collections import MutableMapping, MutableSet +from collections.abc import MutableMapping, MutableSet class DebugConfig(MutableMapping): diff --git a/tests/debug/runners.py b/tests/debug/runners.py index af6b8462..826c8954 100644 --- a/tests/debug/runners.py +++ b/tests/debug/runners.py @@ -158,8 +158,6 @@ def _attach_common_config(session, target, cwd): @_runner @contextlib.contextmanager def attach_pid(session, target, cwd=None, wait=True): - if sys.version_info < (3,) and sys.platform == "darwin": - pytest.skip("https://github.com/microsoft/ptvsd/issues/1916") if wait and not sys.platform.startswith("linux"): pytest.skip("https://github.com/microsoft/ptvsd/issues/1926") diff --git a/tests/debugpy/test_breakpoints.py b/tests/debugpy/test_breakpoints.py index 104ad0ed..7c135c88 100644 --- a/tests/debugpy/test_breakpoints.py +++ b/tests/debugpy/test_breakpoints.py @@ -37,13 +37,6 @@ def test_path_with_ampersand(target, run): session.request_continue() -@pytest.mark.skipif( - sys.version_info < (3, 0), reason="Paths are not Unicode in Python 2.7" -) -@pytest.mark.skipif( - sys.platform == "win32" and sys.version_info < (3, 6), - reason="https://github.com/microsoft/ptvsd/issues/1124#issuecomment-459506802", -) @pytest.mark.parametrize("target", targets.all_named) def test_path_with_unicode(target, run): test_py = bp_root / "ನನ್ನ_ಸ್ಕ್ರಿಪ್ಟ್.py" @@ -349,8 +342,7 @@ def test_invalid_breakpoints(pyfile, target, run): with debug.Session() as session: with run(session, target(code_to_debug)): - count = 5 if sys.version_info < (3,) else 3 - requested_markers = ["r" + str(i) for i in range(0, count)] + requested_markers = ["r" + str(i) for i in range(0, 3)] bps = session.set_breakpoints(code_to_debug, requested_markers) actual_lines = [bp["line"] for bp in bps] @@ -430,9 +422,6 @@ def test_deep_stacks(pyfile, target, run): @pytest.mark.parametrize("target", targets.all) @pytest.mark.parametrize("func", ["breakpoint", "debugpy.breakpoint"]) def test_break_api(pyfile, target, run, func): - if func == "breakpoint" and sys.version_info < (3, 7): - pytest.skip("breakpoint() was introduced in Python 3.7") - @pyfile def code_to_debug(): import debuggee diff --git a/tests/debugpy/test_evaluate.py b/tests/debugpy/test_evaluate.py index d3b9f642..532a1782 100644 --- a/tests/debugpy/test_evaluate.py +++ b/tests/debugpy/test_evaluate.py @@ -3,7 +3,6 @@ # for license information. import pytest -import sys from tests import debug, timeline from tests.patterns import some @@ -176,26 +175,15 @@ def test_variable_sort(pyfile, target, run): "variables", {"variablesReference": b_test["variablesReference"]} )["variables"] var_names = [v["name"] for v in b_test_vars] - if sys.version_info[:2] >= (3, 6): - # Note that the special len() we manually create is not added to special variables. - expected = [ - "special variables", - "function variables", - "'spam'", - "'eggs'", - "'abcd'", - "len()", - ] - else: - expected = [ - "special variables", - "function variables", - "'abcd'", - "'eggs'", - "'spam'", - "len()", - ] - + # Note that the special len() we manually create is not added to special variables. + expected = [ + "special variables", + "function variables", + "'spam'", + "'eggs'", + "'abcd'", + "len()", + ] assert var_names == expected # Numeric dict keys must be sorted as numbers. @@ -309,10 +297,7 @@ def test_unicode(pyfile, target, run): eval = session.request( "evaluate", {"expression": "\u16A0", "frameId": stop.frame_id} ) - if sys.version_info >= (3,): - assert eval == some.dict.containing({"type": "int", "result": "123"}) - else: - assert eval == some.dict.containing({"type": "SyntaxError"}) + assert eval == some.dict.containing({"type": "int", "result": "123"}) session.request_continue() @@ -429,88 +414,46 @@ def test_hex_numbers(pyfile, target, run): "variables", {"variablesReference": c["variablesReference"], "format": {"hex": True}}, )["variables"] - if sys.version_info[:2] < (3, 6): - # Sorted dict keys by the name before Python 3.6. - assert c_vars == [ - some.dict.containing( - { - "name": "0x3e8", - "value": "0x3e8", - "type": "int", - "evaluateName": "c[1000]", - "variablesReference": 0, - } - ), - some.dict.containing( - { - "name": "0x64", - "value": "0x64", - "type": "int", - "evaluateName": "c[100]", - "variablesReference": 0, - } - ), - some.dict.containing( - { - "name": "0xa", - "value": "0xa", - "type": "int", - "evaluateName": "c[10]", - "variablesReference": 0, - } - ), - some.dict.containing( - { - "name": "len()", - "value": "0x3", - "type": "int", - "evaluateName": "len(c)", - "variablesReference": 0, - "presentationHint": {"attributes": ["readOnly"]}, - } - ), - ] - else: - # Use dict sequence on Python 3.6 onwards. - assert c_vars == [ - some.dict.containing( - { - "name": "0xa", - "value": "0xa", - "type": "int", - "evaluateName": "c[10]", - "variablesReference": 0, - } - ), - some.dict.containing( - { - "name": "0x64", - "value": "0x64", - "type": "int", - "evaluateName": "c[100]", - "variablesReference": 0, - } - ), - some.dict.containing( - { - "name": "0x3e8", - "value": "0x3e8", - "type": "int", - "evaluateName": "c[1000]", - "variablesReference": 0, - } - ), - some.dict.containing( - { - "name": "len()", - "value": "0x3", - "type": "int", - "evaluateName": "len(c)", - "variablesReference": 0, - "presentationHint": {"attributes": ["readOnly"]}, - } - ), - ] + # Use dict sequence on Python 3.6 onwards. + assert c_vars == [ + some.dict.containing( + { + "name": "0xa", + "value": "0xa", + "type": "int", + "evaluateName": "c[10]", + "variablesReference": 0, + } + ), + some.dict.containing( + { + "name": "0x64", + "value": "0x64", + "type": "int", + "evaluateName": "c[100]", + "variablesReference": 0, + } + ), + some.dict.containing( + { + "name": "0x3e8", + "value": "0x3e8", + "type": "int", + "evaluateName": "c[1000]", + "variablesReference": 0, + } + ), + some.dict.containing( + { + "name": "len()", + "value": "0x3", + "type": "int", + "evaluateName": "len(c)", + "variablesReference": 0, + "presentationHint": {"attributes": ["readOnly"]}, + } + ), + ] d_vars = session.request( "variables", diff --git a/tests/debugpy/test_exception.py b/tests/debugpy/test_exception.py index 8e309353..385f32b6 100644 --- a/tests/debugpy/test_exception.py +++ b/tests/debugpy/test_exception.py @@ -147,7 +147,7 @@ def test_vsc_exception_options_raise_without_except( @pytest.mark.skipif( - sys.platform == "darwin" and sys.version_info >= (3,), + sys.platform == "darwin", reason="https://github.com/microsoft/ptvsd/issues/1988", ) @pytest.mark.parametrize("target", targets.all_named) diff --git a/tests/debugpy/test_multiproc.py b/tests/debugpy/test_multiproc.py index 3f0e38ba..908b8592 100644 --- a/tests/debugpy/test_multiproc.py +++ b/tests/debugpy/test_multiproc.py @@ -40,11 +40,7 @@ def expected_subprocess_config(parent_session): @pytest.mark.parametrize( "start_method", - [""] - if sys.version_info < (3,) - else ["spawn"] - if sys.platform == "win32" - else ["spawn", "fork"], + ["spawn"] if sys.platform == "win32" else ["spawn", "fork"], ) def test_multiprocessing(pyfile, target, run, start_method): if start_method == "spawn" and sys.platform != "win32": @@ -404,8 +400,7 @@ def test_echo_and_shell(pyfile, target, run): cwd=os.path.dirname(os.path.abspath(__file__)), ) stdout, _stderr = p.communicate() - if sys.version_info[0] >= 3: - stdout = stdout.decode("utf-8") + stdout = stdout.decode("utf-8") if "code_to_run.py" not in stdout: raise AssertionError( diff --git a/tests/debugpy/test_output.py b/tests/debugpy/test_output.py index 403aab16..848ed571 100644 --- a/tests/debugpy/test_output.py +++ b/tests/debugpy/test_output.py @@ -134,10 +134,7 @@ def test_non_ascii_output(pyfile, target, run): debuggee.setup() a = b"\xc3\xa9 \xc3\xa0 \xc3\xb6 \xc3\xb9\n" - if sys.version_info[0] >= 3: - sys.stdout.buffer.write(a) - else: - sys.stdout.write(a) + sys.stdout.buffer.write(a) () # @wait_for_output with debug.Session() as session: diff --git a/tests/debugpy/test_run.py b/tests/debugpy/test_run.py index 1896e324..53876283 100644 --- a/tests/debugpy/test_run.py +++ b/tests/debugpy/test_run.py @@ -328,10 +328,6 @@ def test_frame_eval(pyfile, target, run, frame_eval): assert using_frame_eval == (frame_eval in ("yes", "")) -@pytest.mark.skipif( - not sys.version_info[0] >= 3, - reason="Test structure must still be updated to properly support Python 2 with unicode", -) @pytest.mark.parametrize("run", [runners.all_launch[0]]) def test_unicode_dir(tmpdir, run, target): from debugpy.common import compat diff --git a/tests/patterns/some.py b/tests/patterns/some.py index 06652bcd..62f3f95a 100644 --- a/tests/patterns/some.py +++ b/tests/patterns/some.py @@ -32,11 +32,8 @@ Usage:: assert object() == some.object.same_as(object()) assert b"abc" == some.bytes - assert u"abc" == some.str - if sys.version_info < (3,): - assert b"abc" == some.str - else: - assert b"abc" != some.str + assert "abc" == some.str + assert b"abc" != some.str assert "abbc" == some.str.starting_with("ab") assert "abbc" == some.str.ending_with("bc") @@ -84,7 +81,6 @@ __all__ = [ import numbers import re -import sys from debugpy.common.compat import builtins from tests.patterns import _impl @@ -111,13 +107,7 @@ bytes.ending_with = lambda suffix: bytes.matching(b".*" + re.escape(suffix), re. bytes.containing = lambda sub: bytes.matching(b".*" + re.escape(sub) + b".*", re.DOTALL) -"""In Python 2, matches both str and unicode. In Python 3, only matches str. -""" -if sys.version_info < (3,): - str = instanceof((builtins.str, builtins.unicode), "str") -else: - str = instanceof(builtins.str) - +str = instanceof(builtins.str) str.starting_with = lambda prefix: str.matching(re.escape(prefix) + ".*", re.DOTALL) str.ending_with = lambda suffix: str.matching(".*" + re.escape(suffix), re.DOTALL) str.containing = lambda sub: str.matching(".*" + re.escape(sub) + ".*", re.DOTALL) diff --git a/tests/test_data/django1/app.py b/tests/test_data/django1/app.py index ba8b35a8..76a5056b 100644 --- a/tests/test_data/django1/app.py +++ b/tests/test_data/django1/app.py @@ -80,26 +80,15 @@ def exit_app(request): return HttpResponse("Done") -if sys.version_info < (3, 0): - from django.conf.urls import url +from django.urls import path - urlpatterns = [ - url(r"home", home, name="home"), - url(r"^handled$", bad_route_handled, name="bad_route_handled"), - url(r"^unhandled$", bad_route_unhandled, name="bad_route_unhandled"), - url(r"badtemplate", bad_template, name="bad_template"), - url(r"exit", exit_app, name="exit_app"), - ] -else: - from django.urls import path - - urlpatterns = [ - path("home", home, name="home"), - path("handled", bad_route_handled, name="bad_route_handled"), - path("unhandled", bad_route_unhandled, name="bad_route_unhandled"), - path("badtemplate", bad_template, name="bad_template"), - path("exit", exit_app, name="exit_app"), - ] +urlpatterns = [ + path("home", home, name="home"), + path("handled", bad_route_handled, name="bad_route_handled"), + path("unhandled", bad_route_unhandled, name="bad_route_unhandled"), + path("badtemplate", bad_template, name="bad_template"), + path("exit", exit_app, name="exit_app"), +] if __name__ == "__main__": execute_from_command_line(sys.argv) diff --git a/tests/tests/test_patterns.py b/tests/tests/test_patterns.py index 07568862..dbd0cb98 100644 --- a/tests/tests/test_patterns.py +++ b/tests/tests/test_patterns.py @@ -3,7 +3,6 @@ # for license information. import pytest -import sys from debugpy.common import log from tests.patterns import some @@ -122,11 +121,7 @@ def test_in_range(): def test_str(): log_repr(some.str) assert some.str == "abc" - - if sys.version_info < (3,): - assert b"abc" == some.str - else: - assert b"abc" != some.str + assert b"abc" != some.str def test_matching():