From 12f74a28fada7badd7d7830611ba14b8a40e1dd1 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sun, 5 Jan 2020 14:12:40 -0300 Subject: [PATCH] Revert "Remove unused _pytest.code.Source.isparseable function" This reverts commit c627ac4e599464e9ce2d1b33d1139b9dcf89468a. --- changelog/6404.trivial.rst | 1 - src/_pytest/_code/source.py | 20 ++++++++++++++++++++ testing/code/test_source.py | 10 ++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) delete mode 100644 changelog/6404.trivial.rst diff --git a/changelog/6404.trivial.rst b/changelog/6404.trivial.rst deleted file mode 100644 index 5a60d01a4..000000000 --- a/changelog/6404.trivial.rst +++ /dev/null @@ -1 +0,0 @@ -Removed unused ``_pytest.code.Source.isparseable`` function. diff --git a/src/_pytest/_code/source.py b/src/_pytest/_code/source.py index 341462792..d7cef683d 100644 --- a/src/_pytest/_code/source.py +++ b/src/_pytest/_code/source.py @@ -136,6 +136,26 @@ class Source: newsource.lines[:] = deindent(self.lines) return newsource + def isparseable(self, deindent: bool = True) -> bool: + """ return True if source is parseable, heuristically + deindenting it by default. + """ + from parser import suite as syntax_checker + + if deindent: + source = str(self.deindent()) + else: + source = str(self) + try: + # compile(source+'\n', "x", "exec") + syntax_checker(source + "\n") + except KeyboardInterrupt: + raise + except Exception: + return False + else: + return True + def __str__(self) -> str: return "\n".join(self.lines) diff --git a/testing/code/test_source.py b/testing/code/test_source.py index 511626fa0..1390d8b0a 100644 --- a/testing/code/test_source.py +++ b/testing/code/test_source.py @@ -121,6 +121,15 @@ def test_syntaxerror_rerepresentation() -> None: assert ex.value.text == "xyz xyz\n" +def test_isparseable() -> None: + assert Source("hello").isparseable() + assert Source("if 1:\n pass").isparseable() + assert Source(" \nif 1:\n pass").isparseable() + assert not Source("if 1:\n").isparseable() + assert not Source(" \nif 1:\npass").isparseable() + assert not Source(chr(0)).isparseable() + + class TestAccesses: def setup_class(self) -> None: self.source = Source( @@ -134,6 +143,7 @@ class TestAccesses: 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"