Add type annotations to _pytest._code.code
This commit is contained in:
@@ -1,18 +1,19 @@
|
||||
import sys
|
||||
from types import FrameType
|
||||
from unittest import mock
|
||||
|
||||
import _pytest._code
|
||||
import pytest
|
||||
|
||||
|
||||
def test_ne():
|
||||
def test_ne() -> None:
|
||||
code1 = _pytest._code.Code(compile('foo = "bar"', "", "exec"))
|
||||
assert code1 == code1
|
||||
code2 = _pytest._code.Code(compile('foo = "baz"', "", "exec"))
|
||||
assert code2 != code1
|
||||
|
||||
|
||||
def test_code_gives_back_name_for_not_existing_file():
|
||||
def test_code_gives_back_name_for_not_existing_file() -> None:
|
||||
name = "abc-123"
|
||||
co_code = compile("pass\n", name, "exec")
|
||||
assert co_code.co_filename == name
|
||||
@@ -21,68 +22,67 @@ def test_code_gives_back_name_for_not_existing_file():
|
||||
assert code.fullsource is None
|
||||
|
||||
|
||||
def test_code_with_class():
|
||||
def test_code_with_class() -> None:
|
||||
class A:
|
||||
pass
|
||||
|
||||
pytest.raises(TypeError, _pytest._code.Code, A)
|
||||
|
||||
|
||||
def x():
|
||||
def x() -> None:
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
def test_code_fullsource():
|
||||
def test_code_fullsource() -> None:
|
||||
code = _pytest._code.Code(x)
|
||||
full = code.fullsource
|
||||
assert "test_code_fullsource()" in str(full)
|
||||
|
||||
|
||||
def test_code_source():
|
||||
def test_code_source() -> None:
|
||||
code = _pytest._code.Code(x)
|
||||
src = code.source()
|
||||
expected = """def x():
|
||||
expected = """def x() -> None:
|
||||
raise NotImplementedError()"""
|
||||
assert str(src) == expected
|
||||
|
||||
|
||||
def test_frame_getsourcelineno_myself():
|
||||
def func():
|
||||
def test_frame_getsourcelineno_myself() -> None:
|
||||
def func() -> FrameType:
|
||||
return sys._getframe(0)
|
||||
|
||||
f = func()
|
||||
f = _pytest._code.Frame(f)
|
||||
f = _pytest._code.Frame(func())
|
||||
source, lineno = f.code.fullsource, f.lineno
|
||||
assert source is not None
|
||||
assert source[lineno].startswith(" return sys._getframe(0)")
|
||||
|
||||
|
||||
def test_getstatement_empty_fullsource():
|
||||
def func():
|
||||
def test_getstatement_empty_fullsource() -> None:
|
||||
def func() -> FrameType:
|
||||
return sys._getframe(0)
|
||||
|
||||
f = func()
|
||||
f = _pytest._code.Frame(f)
|
||||
f = _pytest._code.Frame(func())
|
||||
with mock.patch.object(f.code.__class__, "fullsource", None):
|
||||
assert f.statement == ""
|
||||
|
||||
|
||||
def test_code_from_func():
|
||||
def test_code_from_func() -> None:
|
||||
co = _pytest._code.Code(test_frame_getsourcelineno_myself)
|
||||
assert co.firstlineno
|
||||
assert co.path
|
||||
|
||||
|
||||
def test_unicode_handling():
|
||||
def test_unicode_handling() -> None:
|
||||
value = "ąć".encode()
|
||||
|
||||
def f():
|
||||
def f() -> None:
|
||||
raise Exception(value)
|
||||
|
||||
excinfo = pytest.raises(Exception, f)
|
||||
str(excinfo)
|
||||
|
||||
|
||||
def test_code_getargs():
|
||||
def test_code_getargs() -> None:
|
||||
def f1(x):
|
||||
raise NotImplementedError()
|
||||
|
||||
@@ -108,26 +108,26 @@ def test_code_getargs():
|
||||
assert c4.getargs(var=True) == ("x", "y", "z")
|
||||
|
||||
|
||||
def test_frame_getargs():
|
||||
def f1(x):
|
||||
def test_frame_getargs() -> None:
|
||||
def f1(x) -> FrameType:
|
||||
return sys._getframe(0)
|
||||
|
||||
fr1 = _pytest._code.Frame(f1("a"))
|
||||
assert fr1.getargs(var=True) == [("x", "a")]
|
||||
|
||||
def f2(x, *y):
|
||||
def f2(x, *y) -> FrameType:
|
||||
return sys._getframe(0)
|
||||
|
||||
fr2 = _pytest._code.Frame(f2("a", "b", "c"))
|
||||
assert fr2.getargs(var=True) == [("x", "a"), ("y", ("b", "c"))]
|
||||
|
||||
def f3(x, **z):
|
||||
def f3(x, **z) -> FrameType:
|
||||
return sys._getframe(0)
|
||||
|
||||
fr3 = _pytest._code.Frame(f3("a", b="c"))
|
||||
assert fr3.getargs(var=True) == [("x", "a"), ("z", {"b": "c"})]
|
||||
|
||||
def f4(x, *y, **z):
|
||||
def f4(x, *y, **z) -> FrameType:
|
||||
return sys._getframe(0)
|
||||
|
||||
fr4 = _pytest._code.Frame(f4("a", "b", c="d"))
|
||||
@@ -135,7 +135,7 @@ def test_frame_getargs():
|
||||
|
||||
|
||||
class TestExceptionInfo:
|
||||
def test_bad_getsource(self):
|
||||
def test_bad_getsource(self) -> None:
|
||||
try:
|
||||
if False:
|
||||
pass
|
||||
@@ -145,13 +145,13 @@ class TestExceptionInfo:
|
||||
exci = _pytest._code.ExceptionInfo.from_current()
|
||||
assert exci.getrepr()
|
||||
|
||||
def test_from_current_with_missing(self):
|
||||
def test_from_current_with_missing(self) -> None:
|
||||
with pytest.raises(AssertionError, match="no current exception"):
|
||||
_pytest._code.ExceptionInfo.from_current()
|
||||
|
||||
|
||||
class TestTracebackEntry:
|
||||
def test_getsource(self):
|
||||
def test_getsource(self) -> None:
|
||||
try:
|
||||
if False:
|
||||
pass
|
||||
@@ -161,12 +161,13 @@ class TestTracebackEntry:
|
||||
exci = _pytest._code.ExceptionInfo.from_current()
|
||||
entry = exci.traceback[0]
|
||||
source = entry.getsource()
|
||||
assert source is not None
|
||||
assert len(source) == 6
|
||||
assert "assert False" in source[5]
|
||||
|
||||
|
||||
class TestReprFuncArgs:
|
||||
def test_not_raise_exception_with_mixed_encoding(self, tw_mock):
|
||||
def test_not_raise_exception_with_mixed_encoding(self, tw_mock) -> None:
|
||||
from _pytest._code.code import ReprFuncArgs
|
||||
|
||||
args = [("unicode_string", "São Paulo"), ("utf8_string", b"S\xc3\xa3o Paulo")]
|
||||
|
||||
@@ -3,6 +3,7 @@ import os
|
||||
import queue
|
||||
import sys
|
||||
import textwrap
|
||||
from typing import Union
|
||||
|
||||
import py
|
||||
|
||||
@@ -224,23 +225,25 @@ class TestTraceback_f_g_h:
|
||||
repr = excinfo.getrepr()
|
||||
assert "RuntimeError: hello" in str(repr.reprcrash)
|
||||
|
||||
def test_traceback_no_recursion_index(self):
|
||||
def do_stuff():
|
||||
def test_traceback_no_recursion_index(self) -> None:
|
||||
def do_stuff() -> None:
|
||||
raise RuntimeError
|
||||
|
||||
def reraise_me():
|
||||
def reraise_me() -> None:
|
||||
import sys
|
||||
|
||||
exc, val, tb = sys.exc_info()
|
||||
assert val is not None
|
||||
raise val.with_traceback(tb)
|
||||
|
||||
def f(n):
|
||||
def f(n: int) -> None:
|
||||
try:
|
||||
do_stuff()
|
||||
except: # noqa
|
||||
reraise_me()
|
||||
|
||||
excinfo = pytest.raises(RuntimeError, f, 8)
|
||||
assert excinfo is not None
|
||||
traceback = excinfo.traceback
|
||||
recindex = traceback.recursionindex()
|
||||
assert recindex is None
|
||||
@@ -596,7 +599,6 @@ raise ValueError()
|
||||
assert lines[3] == "E world"
|
||||
assert not lines[4:]
|
||||
|
||||
loc = repr_entry.reprlocals is not None
|
||||
loc = repr_entry.reprfileloc
|
||||
assert loc.path == mod.__file__
|
||||
assert loc.lineno == 3
|
||||
@@ -1286,9 +1288,10 @@ raise ValueError()
|
||||
@pytest.mark.parametrize("style", ["short", "long"])
|
||||
@pytest.mark.parametrize("encoding", [None, "utf8", "utf16"])
|
||||
def test_repr_traceback_with_unicode(style, encoding):
|
||||
msg = "☹"
|
||||
if encoding is not None:
|
||||
msg = msg.encode(encoding)
|
||||
if encoding is None:
|
||||
msg = "☹" # type: Union[str, bytes]
|
||||
else:
|
||||
msg = "☹".encode(encoding)
|
||||
try:
|
||||
raise RuntimeError(msg)
|
||||
except RuntimeError:
|
||||
|
||||
@@ -4,13 +4,16 @@
|
||||
import ast
|
||||
import inspect
|
||||
import sys
|
||||
from typing import Any
|
||||
from typing import Dict
|
||||
from typing import Optional
|
||||
|
||||
import _pytest._code
|
||||
import pytest
|
||||
from _pytest._code import Source
|
||||
|
||||
|
||||
def test_source_str_function():
|
||||
def test_source_str_function() -> None:
|
||||
x = Source("3")
|
||||
assert str(x) == "3"
|
||||
|
||||
@@ -25,7 +28,7 @@ def test_source_str_function():
|
||||
assert str(x) == "\n3"
|
||||
|
||||
|
||||
def test_unicode():
|
||||
def test_unicode() -> None:
|
||||
x = Source("4")
|
||||
assert str(x) == "4"
|
||||
co = _pytest._code.compile('"å"', mode="eval")
|
||||
@@ -33,12 +36,12 @@ def test_unicode():
|
||||
assert isinstance(val, str)
|
||||
|
||||
|
||||
def test_source_from_function():
|
||||
def test_source_from_function() -> None:
|
||||
source = _pytest._code.Source(test_source_str_function)
|
||||
assert str(source).startswith("def test_source_str_function():")
|
||||
assert str(source).startswith("def test_source_str_function() -> None:")
|
||||
|
||||
|
||||
def test_source_from_method():
|
||||
def test_source_from_method() -> None:
|
||||
class TestClass:
|
||||
def test_method(self):
|
||||
pass
|
||||
@@ -47,13 +50,13 @@ def test_source_from_method():
|
||||
assert source.lines == ["def test_method(self):", " pass"]
|
||||
|
||||
|
||||
def test_source_from_lines():
|
||||
def test_source_from_lines() -> None:
|
||||
lines = ["a \n", "b\n", "c"]
|
||||
source = _pytest._code.Source(lines)
|
||||
assert source.lines == ["a ", "b", "c"]
|
||||
|
||||
|
||||
def test_source_from_inner_function():
|
||||
def test_source_from_inner_function() -> None:
|
||||
def f():
|
||||
pass
|
||||
|
||||
@@ -63,7 +66,7 @@ def test_source_from_inner_function():
|
||||
assert str(source).startswith("def f():")
|
||||
|
||||
|
||||
def test_source_putaround_simple():
|
||||
def test_source_putaround_simple() -> None:
|
||||
source = Source("raise ValueError")
|
||||
source = source.putaround(
|
||||
"try:",
|
||||
@@ -85,7 +88,7 @@ else:
|
||||
)
|
||||
|
||||
|
||||
def test_source_putaround():
|
||||
def test_source_putaround() -> None:
|
||||
source = Source()
|
||||
source = source.putaround(
|
||||
"""
|
||||
@@ -96,28 +99,29 @@ def test_source_putaround():
|
||||
assert str(source).strip() == "if 1:\n x=1"
|
||||
|
||||
|
||||
def test_source_strips():
|
||||
def test_source_strips() -> None:
|
||||
source = Source("")
|
||||
assert source == Source()
|
||||
assert str(source) == ""
|
||||
assert source.strip() == source
|
||||
|
||||
|
||||
def test_source_strip_multiline():
|
||||
def test_source_strip_multiline() -> None:
|
||||
source = Source()
|
||||
source.lines = ["", " hello", " "]
|
||||
source2 = source.strip()
|
||||
assert source2.lines == [" hello"]
|
||||
|
||||
|
||||
def test_syntaxerror_rerepresentation():
|
||||
def test_syntaxerror_rerepresentation() -> None:
|
||||
ex = pytest.raises(SyntaxError, _pytest._code.compile, "xyz xyz")
|
||||
assert ex is not None
|
||||
assert ex.value.lineno == 1
|
||||
assert ex.value.offset in {5, 7} # cpython: 7, pypy3.6 7.1.1: 5
|
||||
assert ex.value.text.strip(), "x x"
|
||||
assert ex.value.text == "xyz xyz\n"
|
||||
|
||||
|
||||
def test_isparseable():
|
||||
def test_isparseable() -> None:
|
||||
assert Source("hello").isparseable()
|
||||
assert Source("if 1:\n pass").isparseable()
|
||||
assert Source(" \nif 1:\n pass").isparseable()
|
||||
@@ -127,7 +131,7 @@ def test_isparseable():
|
||||
|
||||
|
||||
class TestAccesses:
|
||||
def setup_class(self):
|
||||
def setup_class(self) -> None:
|
||||
self.source = Source(
|
||||
"""\
|
||||
def f(x):
|
||||
@@ -137,26 +141,26 @@ class TestAccesses:
|
||||
"""
|
||||
)
|
||||
|
||||
def test_getrange(self):
|
||||
def test_getrange(self) -> None:
|
||||
x = self.source[0:2]
|
||||
assert x.isparseable()
|
||||
assert len(x.lines) == 2
|
||||
assert str(x) == "def f(x):\n pass"
|
||||
|
||||
def test_getline(self):
|
||||
def test_getline(self) -> None:
|
||||
x = self.source[0]
|
||||
assert x == "def f(x):"
|
||||
|
||||
def test_len(self):
|
||||
def test_len(self) -> None:
|
||||
assert len(self.source) == 4
|
||||
|
||||
def test_iter(self):
|
||||
def test_iter(self) -> None:
|
||||
values = [x for x in self.source]
|
||||
assert len(values) == 4
|
||||
|
||||
|
||||
class TestSourceParsingAndCompiling:
|
||||
def setup_class(self):
|
||||
def setup_class(self) -> None:
|
||||
self.source = Source(
|
||||
"""\
|
||||
def f(x):
|
||||
@@ -166,19 +170,19 @@ class TestSourceParsingAndCompiling:
|
||||
"""
|
||||
).strip()
|
||||
|
||||
def test_compile(self):
|
||||
def test_compile(self) -> None:
|
||||
co = _pytest._code.compile("x=3")
|
||||
d = {}
|
||||
d = {} # type: Dict[str, Any]
|
||||
exec(co, d)
|
||||
assert d["x"] == 3
|
||||
|
||||
def test_compile_and_getsource_simple(self):
|
||||
def test_compile_and_getsource_simple(self) -> None:
|
||||
co = _pytest._code.compile("x=3")
|
||||
exec(co)
|
||||
source = _pytest._code.Source(co)
|
||||
assert str(source) == "x=3"
|
||||
|
||||
def test_compile_and_getsource_through_same_function(self):
|
||||
def test_compile_and_getsource_through_same_function(self) -> None:
|
||||
def gensource(source):
|
||||
return _pytest._code.compile(source)
|
||||
|
||||
@@ -199,7 +203,7 @@ class TestSourceParsingAndCompiling:
|
||||
source2 = inspect.getsource(co2)
|
||||
assert "ValueError" in source2
|
||||
|
||||
def test_getstatement(self):
|
||||
def test_getstatement(self) -> None:
|
||||
# print str(self.source)
|
||||
ass = str(self.source[1:])
|
||||
for i in range(1, 4):
|
||||
@@ -208,7 +212,7 @@ class TestSourceParsingAndCompiling:
|
||||
# x = s.deindent()
|
||||
assert str(s) == ass
|
||||
|
||||
def test_getstatementrange_triple_quoted(self):
|
||||
def test_getstatementrange_triple_quoted(self) -> None:
|
||||
# print str(self.source)
|
||||
source = Source(
|
||||
"""hello('''
|
||||
@@ -219,7 +223,7 @@ class TestSourceParsingAndCompiling:
|
||||
s = source.getstatement(1)
|
||||
assert s == str(source)
|
||||
|
||||
def test_getstatementrange_within_constructs(self):
|
||||
def test_getstatementrange_within_constructs(self) -> None:
|
||||
source = Source(
|
||||
"""\
|
||||
try:
|
||||
@@ -241,7 +245,7 @@ class TestSourceParsingAndCompiling:
|
||||
# assert source.getstatementrange(5) == (0, 7)
|
||||
assert source.getstatementrange(6) == (6, 7)
|
||||
|
||||
def test_getstatementrange_bug(self):
|
||||
def test_getstatementrange_bug(self) -> None:
|
||||
source = Source(
|
||||
"""\
|
||||
try:
|
||||
@@ -255,7 +259,7 @@ class TestSourceParsingAndCompiling:
|
||||
assert len(source) == 6
|
||||
assert source.getstatementrange(2) == (1, 4)
|
||||
|
||||
def test_getstatementrange_bug2(self):
|
||||
def test_getstatementrange_bug2(self) -> None:
|
||||
source = Source(
|
||||
"""\
|
||||
assert (
|
||||
@@ -272,7 +276,7 @@ class TestSourceParsingAndCompiling:
|
||||
assert len(source) == 9
|
||||
assert source.getstatementrange(5) == (0, 9)
|
||||
|
||||
def test_getstatementrange_ast_issue58(self):
|
||||
def test_getstatementrange_ast_issue58(self) -> None:
|
||||
source = Source(
|
||||
"""\
|
||||
|
||||
@@ -286,38 +290,44 @@ class TestSourceParsingAndCompiling:
|
||||
assert getstatement(2, source).lines == source.lines[2:3]
|
||||
assert getstatement(3, source).lines == source.lines[3:4]
|
||||
|
||||
def test_getstatementrange_out_of_bounds_py3(self):
|
||||
def test_getstatementrange_out_of_bounds_py3(self) -> None:
|
||||
source = Source("if xxx:\n from .collections import something")
|
||||
r = source.getstatementrange(1)
|
||||
assert r == (1, 2)
|
||||
|
||||
def test_getstatementrange_with_syntaxerror_issue7(self):
|
||||
def test_getstatementrange_with_syntaxerror_issue7(self) -> None:
|
||||
source = Source(":")
|
||||
pytest.raises(SyntaxError, lambda: source.getstatementrange(0))
|
||||
|
||||
def test_compile_to_ast(self):
|
||||
def test_compile_to_ast(self) -> None:
|
||||
source = Source("x = 4")
|
||||
mod = source.compile(flag=ast.PyCF_ONLY_AST)
|
||||
assert isinstance(mod, ast.Module)
|
||||
compile(mod, "<filename>", "exec")
|
||||
|
||||
def test_compile_and_getsource(self):
|
||||
def test_compile_and_getsource(self) -> None:
|
||||
co = self.source.compile()
|
||||
exec(co, globals())
|
||||
f(7)
|
||||
excinfo = pytest.raises(AssertionError, f, 6)
|
||||
f(7) # type: ignore
|
||||
excinfo = pytest.raises(AssertionError, f, 6) # type: ignore
|
||||
assert excinfo is not None
|
||||
frame = excinfo.traceback[-1].frame
|
||||
assert isinstance(frame.code.fullsource, Source)
|
||||
stmt = frame.code.fullsource.getstatement(frame.lineno)
|
||||
assert str(stmt).strip().startswith("assert")
|
||||
|
||||
@pytest.mark.parametrize("name", ["", None, "my"])
|
||||
def test_compilefuncs_and_path_sanity(self, name):
|
||||
def test_compilefuncs_and_path_sanity(self, name: Optional[str]) -> None:
|
||||
def check(comp, name):
|
||||
co = comp(self.source, name)
|
||||
if not name:
|
||||
expected = "codegen %s:%d>" % (mypath, mylineno + 2 + 2)
|
||||
expected = "codegen %s:%d>" % (mypath, mylineno + 2 + 2) # type: ignore
|
||||
else:
|
||||
expected = "codegen %r %s:%d>" % (name, mypath, mylineno + 2 + 2)
|
||||
expected = "codegen %r %s:%d>" % (
|
||||
name,
|
||||
mypath, # type: ignore
|
||||
mylineno + 2 + 2, # type: ignore
|
||||
) # type: ignore
|
||||
fn = co.co_filename
|
||||
assert fn.endswith(expected)
|
||||
|
||||
@@ -332,9 +342,9 @@ class TestSourceParsingAndCompiling:
|
||||
pytest.raises(SyntaxError, _pytest._code.compile, "lambda a,a: 0", mode="eval")
|
||||
|
||||
|
||||
def test_getstartingblock_singleline():
|
||||
def test_getstartingblock_singleline() -> None:
|
||||
class A:
|
||||
def __init__(self, *args):
|
||||
def __init__(self, *args) -> None:
|
||||
frame = sys._getframe(1)
|
||||
self.source = _pytest._code.Frame(frame).statement
|
||||
|
||||
@@ -344,22 +354,22 @@ def test_getstartingblock_singleline():
|
||||
assert len(values) == 1
|
||||
|
||||
|
||||
def test_getline_finally():
|
||||
def c():
|
||||
def test_getline_finally() -> None:
|
||||
def c() -> None:
|
||||
pass
|
||||
|
||||
with pytest.raises(TypeError) as excinfo:
|
||||
teardown = None
|
||||
try:
|
||||
c(1)
|
||||
c(1) # type: ignore
|
||||
finally:
|
||||
if teardown:
|
||||
teardown()
|
||||
source = excinfo.traceback[-1].statement
|
||||
assert str(source).strip() == "c(1)"
|
||||
assert str(source).strip() == "c(1) # type: ignore"
|
||||
|
||||
|
||||
def test_getfuncsource_dynamic():
|
||||
def test_getfuncsource_dynamic() -> None:
|
||||
source = """
|
||||
def f():
|
||||
raise ValueError
|
||||
@@ -368,11 +378,13 @@ def test_getfuncsource_dynamic():
|
||||
"""
|
||||
co = _pytest._code.compile(source)
|
||||
exec(co, globals())
|
||||
assert str(_pytest._code.Source(f)).strip() == "def f():\n raise ValueError"
|
||||
assert str(_pytest._code.Source(g)).strip() == "def g(): pass"
|
||||
f_source = _pytest._code.Source(f) # type: ignore
|
||||
g_source = _pytest._code.Source(g) # type: ignore
|
||||
assert str(f_source).strip() == "def f():\n raise ValueError"
|
||||
assert str(g_source).strip() == "def g(): pass"
|
||||
|
||||
|
||||
def test_getfuncsource_with_multine_string():
|
||||
def test_getfuncsource_with_multine_string() -> None:
|
||||
def f():
|
||||
c = """while True:
|
||||
pass
|
||||
@@ -387,7 +399,7 @@ def test_getfuncsource_with_multine_string():
|
||||
assert str(_pytest._code.Source(f)) == expected.rstrip()
|
||||
|
||||
|
||||
def test_deindent():
|
||||
def test_deindent() -> None:
|
||||
from _pytest._code.source import deindent as deindent
|
||||
|
||||
assert deindent(["\tfoo", "\tbar"]) == ["foo", "bar"]
|
||||
@@ -401,7 +413,7 @@ def test_deindent():
|
||||
assert lines == ["def f():", " def g():", " pass"]
|
||||
|
||||
|
||||
def test_source_of_class_at_eof_without_newline(tmpdir, _sys_snapshot):
|
||||
def test_source_of_class_at_eof_without_newline(tmpdir, _sys_snapshot) -> None:
|
||||
# this test fails because the implicit inspect.getsource(A) below
|
||||
# does not return the "x = 1" last line.
|
||||
source = _pytest._code.Source(
|
||||
@@ -423,7 +435,7 @@ if True:
|
||||
pass
|
||||
|
||||
|
||||
def test_getsource_fallback():
|
||||
def test_getsource_fallback() -> None:
|
||||
from _pytest._code.source import getsource
|
||||
|
||||
expected = """def x():
|
||||
@@ -432,7 +444,7 @@ def test_getsource_fallback():
|
||||
assert src == expected
|
||||
|
||||
|
||||
def test_idem_compile_and_getsource():
|
||||
def test_idem_compile_and_getsource() -> None:
|
||||
from _pytest._code.source import getsource
|
||||
|
||||
expected = "def x(): pass"
|
||||
@@ -441,15 +453,16 @@ def test_idem_compile_and_getsource():
|
||||
assert src == expected
|
||||
|
||||
|
||||
def test_findsource_fallback():
|
||||
def test_findsource_fallback() -> None:
|
||||
from _pytest._code.source import findsource
|
||||
|
||||
src, lineno = findsource(x)
|
||||
assert src is not None
|
||||
assert "test_findsource_simple" in str(src)
|
||||
assert src[lineno] == " def x():"
|
||||
|
||||
|
||||
def test_findsource():
|
||||
def test_findsource() -> None:
|
||||
from _pytest._code.source import findsource
|
||||
|
||||
co = _pytest._code.compile(
|
||||
@@ -460,19 +473,21 @@ def test_findsource():
|
||||
)
|
||||
|
||||
src, lineno = findsource(co)
|
||||
assert src is not None
|
||||
assert "if 1:" in str(src)
|
||||
|
||||
d = {}
|
||||
d = {} # type: Dict[str, Any]
|
||||
eval(co, d)
|
||||
src, lineno = findsource(d["x"])
|
||||
assert src is not None
|
||||
assert "if 1:" in str(src)
|
||||
assert src[lineno] == " def x():"
|
||||
|
||||
|
||||
def test_getfslineno():
|
||||
def test_getfslineno() -> None:
|
||||
from _pytest._code import getfslineno
|
||||
|
||||
def f(x):
|
||||
def f(x) -> None:
|
||||
pass
|
||||
|
||||
fspath, lineno = getfslineno(f)
|
||||
@@ -498,40 +513,40 @@ def test_getfslineno():
|
||||
assert getfslineno(B)[1] == -1
|
||||
|
||||
|
||||
def test_code_of_object_instance_with_call():
|
||||
def test_code_of_object_instance_with_call() -> None:
|
||||
class A:
|
||||
pass
|
||||
|
||||
pytest.raises(TypeError, lambda: _pytest._code.Source(A()))
|
||||
|
||||
class WithCall:
|
||||
def __call__(self):
|
||||
def __call__(self) -> None:
|
||||
pass
|
||||
|
||||
code = _pytest._code.Code(WithCall())
|
||||
assert "pass" in str(code.source())
|
||||
|
||||
class Hello:
|
||||
def __call__(self):
|
||||
def __call__(self) -> None:
|
||||
pass
|
||||
|
||||
pytest.raises(TypeError, lambda: _pytest._code.Code(Hello))
|
||||
|
||||
|
||||
def getstatement(lineno, source):
|
||||
def getstatement(lineno: int, source) -> Source:
|
||||
from _pytest._code.source import getstatementrange_ast
|
||||
|
||||
source = _pytest._code.Source(source, deindent=False)
|
||||
ast, start, end = getstatementrange_ast(lineno, source)
|
||||
return source[start:end]
|
||||
src = _pytest._code.Source(source, deindent=False)
|
||||
ast, start, end = getstatementrange_ast(lineno, src)
|
||||
return src[start:end]
|
||||
|
||||
|
||||
def test_oneline():
|
||||
def test_oneline() -> None:
|
||||
source = getstatement(0, "raise ValueError")
|
||||
assert str(source) == "raise ValueError"
|
||||
|
||||
|
||||
def test_comment_and_no_newline_at_end():
|
||||
def test_comment_and_no_newline_at_end() -> None:
|
||||
from _pytest._code.source import getstatementrange_ast
|
||||
|
||||
source = Source(
|
||||
@@ -545,12 +560,12 @@ def test_comment_and_no_newline_at_end():
|
||||
assert end == 2
|
||||
|
||||
|
||||
def test_oneline_and_comment():
|
||||
def test_oneline_and_comment() -> None:
|
||||
source = getstatement(0, "raise ValueError\n#hello")
|
||||
assert str(source) == "raise ValueError"
|
||||
|
||||
|
||||
def test_comments():
|
||||
def test_comments() -> None:
|
||||
source = '''def test():
|
||||
"comment 1"
|
||||
x = 1
|
||||
@@ -576,7 +591,7 @@ comment 4
|
||||
assert str(getstatement(line, source)) == '"""\ncomment 4\n"""'
|
||||
|
||||
|
||||
def test_comment_in_statement():
|
||||
def test_comment_in_statement() -> None:
|
||||
source = """test(foo=1,
|
||||
# comment 1
|
||||
bar=2)
|
||||
@@ -588,17 +603,17 @@ def test_comment_in_statement():
|
||||
)
|
||||
|
||||
|
||||
def test_single_line_else():
|
||||
def test_single_line_else() -> None:
|
||||
source = getstatement(1, "if False: 2\nelse: 3")
|
||||
assert str(source) == "else: 3"
|
||||
|
||||
|
||||
def test_single_line_finally():
|
||||
def test_single_line_finally() -> None:
|
||||
source = getstatement(1, "try: 1\nfinally: 3")
|
||||
assert str(source) == "finally: 3"
|
||||
|
||||
|
||||
def test_issue55():
|
||||
def test_issue55() -> None:
|
||||
source = (
|
||||
"def round_trip(dinp):\n assert 1 == dinp\n"
|
||||
'def test_rt():\n round_trip("""\n""")\n'
|
||||
@@ -607,7 +622,7 @@ def test_issue55():
|
||||
assert str(s) == ' round_trip("""\n""")'
|
||||
|
||||
|
||||
def test_multiline():
|
||||
def test_multiline() -> None:
|
||||
source = getstatement(
|
||||
0,
|
||||
"""\
|
||||
@@ -621,7 +636,7 @@ x = 3
|
||||
|
||||
|
||||
class TestTry:
|
||||
def setup_class(self):
|
||||
def setup_class(self) -> None:
|
||||
self.source = """\
|
||||
try:
|
||||
raise ValueError
|
||||
@@ -631,25 +646,25 @@ else:
|
||||
raise KeyError()
|
||||
"""
|
||||
|
||||
def test_body(self):
|
||||
def test_body(self) -> None:
|
||||
source = getstatement(1, self.source)
|
||||
assert str(source) == " raise ValueError"
|
||||
|
||||
def test_except_line(self):
|
||||
def test_except_line(self) -> None:
|
||||
source = getstatement(2, self.source)
|
||||
assert str(source) == "except Something:"
|
||||
|
||||
def test_except_body(self):
|
||||
def test_except_body(self) -> None:
|
||||
source = getstatement(3, self.source)
|
||||
assert str(source) == " raise IndexError(1)"
|
||||
|
||||
def test_else(self):
|
||||
def test_else(self) -> None:
|
||||
source = getstatement(5, self.source)
|
||||
assert str(source) == " raise KeyError()"
|
||||
|
||||
|
||||
class TestTryFinally:
|
||||
def setup_class(self):
|
||||
def setup_class(self) -> None:
|
||||
self.source = """\
|
||||
try:
|
||||
raise ValueError
|
||||
@@ -657,17 +672,17 @@ finally:
|
||||
raise IndexError(1)
|
||||
"""
|
||||
|
||||
def test_body(self):
|
||||
def test_body(self) -> None:
|
||||
source = getstatement(1, self.source)
|
||||
assert str(source) == " raise ValueError"
|
||||
|
||||
def test_finally(self):
|
||||
def test_finally(self) -> None:
|
||||
source = getstatement(3, self.source)
|
||||
assert str(source) == " raise IndexError(1)"
|
||||
|
||||
|
||||
class TestIf:
|
||||
def setup_class(self):
|
||||
def setup_class(self) -> None:
|
||||
self.source = """\
|
||||
if 1:
|
||||
y = 3
|
||||
@@ -677,24 +692,24 @@ else:
|
||||
y = 7
|
||||
"""
|
||||
|
||||
def test_body(self):
|
||||
def test_body(self) -> None:
|
||||
source = getstatement(1, self.source)
|
||||
assert str(source) == " y = 3"
|
||||
|
||||
def test_elif_clause(self):
|
||||
def test_elif_clause(self) -> None:
|
||||
source = getstatement(2, self.source)
|
||||
assert str(source) == "elif False:"
|
||||
|
||||
def test_elif(self):
|
||||
def test_elif(self) -> None:
|
||||
source = getstatement(3, self.source)
|
||||
assert str(source) == " y = 5"
|
||||
|
||||
def test_else(self):
|
||||
def test_else(self) -> None:
|
||||
source = getstatement(5, self.source)
|
||||
assert str(source) == " y = 7"
|
||||
|
||||
|
||||
def test_semicolon():
|
||||
def test_semicolon() -> None:
|
||||
s = """\
|
||||
hello ; pytest.skip()
|
||||
"""
|
||||
@@ -702,7 +717,7 @@ hello ; pytest.skip()
|
||||
assert str(source) == s.strip()
|
||||
|
||||
|
||||
def test_def_online():
|
||||
def test_def_online() -> None:
|
||||
s = """\
|
||||
def func(): raise ValueError(42)
|
||||
|
||||
@@ -713,7 +728,7 @@ def something():
|
||||
assert str(source) == "def func(): raise ValueError(42)"
|
||||
|
||||
|
||||
def XXX_test_expression_multiline():
|
||||
def XXX_test_expression_multiline() -> None:
|
||||
source = """\
|
||||
something
|
||||
'''
|
||||
@@ -722,7 +737,7 @@ something
|
||||
assert str(result) == "'''\n'''"
|
||||
|
||||
|
||||
def test_getstartingblock_multiline():
|
||||
def test_getstartingblock_multiline() -> None:
|
||||
class A:
|
||||
def __init__(self, *args):
|
||||
frame = sys._getframe(1)
|
||||
|
||||
Reference in New Issue
Block a user