Remove code paths for unsupported Python versions.

This commit is contained in:
Pavel Minaev 2022-04-08 14:40:50 -07:00 committed by Pavel Minaev
parent e87017e0b3
commit 98087352cb
16 changed files with 78 additions and 231 deletions

View file

@ -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} " + (

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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