refactor pydoc: inline into tools.py with @in_separate_process decorator for subprocess isolation
This commit is contained in:
parent
7e758b4da5
commit
3925ded957
6 changed files with 59 additions and 32 deletions
|
|
@ -1,24 +0,0 @@
|
|||
|
||||
import pydoc
|
||||
import sys
|
||||
|
||||
import termstr
|
||||
|
||||
|
||||
class TermDoc(pydoc.TextDoc):
|
||||
|
||||
def bold(self, text):
|
||||
return str(termstr.TermStr(text, is_bold=True))
|
||||
|
||||
|
||||
def main():
|
||||
path = sys.argv[1]
|
||||
try:
|
||||
print(pydoc.render_doc(pydoc.importfile(path), renderer=TermDoc()))
|
||||
except pydoc.ErrorDuringImport as e:
|
||||
print(e)
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
|
||||
import ast
|
||||
import concurrent.futures
|
||||
import contextlib
|
||||
import enum
|
||||
import functools
|
||||
|
|
@ -103,6 +104,30 @@ def deps(**kwargs):
|
|||
return decorating_func
|
||||
|
||||
|
||||
def _call_in_process(module_name, func_name, *args, **kwargs):
|
||||
import importlib
|
||||
fn = getattr(importlib.import_module(module_name), func_name)
|
||||
return fn(*args, **kwargs)
|
||||
|
||||
|
||||
def in_separate_process(func):
|
||||
mangled = f"_original_{func.__name__}"
|
||||
sys.modules[func.__module__].__dict__[mangled] = func
|
||||
|
||||
@functools.wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
with concurrent.futures.ProcessPoolExecutor(max_workers=1) as executor:
|
||||
future = executor.submit(
|
||||
_call_in_process, func.__module__, mangled, *args, **kwargs)
|
||||
return future.result()
|
||||
|
||||
for attr in ('deps', 'url', 'executables'):
|
||||
if hasattr(func, attr):
|
||||
setattr(wrapper, attr, getattr(func, attr))
|
||||
return wrapper
|
||||
|
||||
|
||||
|
||||
def _syntax_highlight(text, lexer, style):
|
||||
@functools.lru_cache(maxsize=500)
|
||||
def _parse_rgb(hex_rgb):
|
||||
|
|
@ -199,6 +224,25 @@ def metadata(path):
|
|||
return Status.ok, termstr.join("", text)
|
||||
|
||||
|
||||
@deps(url="https://docs.python.org/3/library/pydoc.html")
|
||||
@in_separate_process
|
||||
def pydoc(path):
|
||||
import os
|
||||
import pydoc
|
||||
|
||||
class TermDoc(pydoc.TextDoc):
|
||||
def bold(self, text):
|
||||
import termstr
|
||||
return str(termstr.TermStr(text, is_bold=True))
|
||||
|
||||
try:
|
||||
doc = pydoc.render_doc(pydoc.importfile(path), renderer=TermDoc())
|
||||
except pydoc.ErrorDuringImport as e:
|
||||
return Status.not_applicable, str(e)
|
||||
doc = doc.replace(os.path.abspath(path), path)
|
||||
return Status.ok, termstr.TermStr.from_term(doc)
|
||||
|
||||
|
||||
@deps(deps={"python3-pygments"}, url="http://pygments.org/")
|
||||
def contents(path):
|
||||
with open(path) as file_:
|
||||
|
|
|
|||
|
|
@ -61,13 +61,6 @@ tools_for_extensions = [
|
|||
url = "https://en.wikipedia.org/wiki/Python_syntax_and_semantics"
|
||||
command = "python3 -m py_compile"
|
||||
|
||||
[pydoc]
|
||||
dependencies = []
|
||||
url = "https://docs.python.org/3/library/pydoc.html"
|
||||
command = "pydoc_color"
|
||||
error_status = "not_applicable"
|
||||
has_color = true
|
||||
timeout = 60
|
||||
|
||||
[pycodestyle]
|
||||
dependencies = ["python3-pycodestyle"]
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ dependencies = [
|
|||
eris = "eris.__main__:entry_point"
|
||||
eris-worker = "eris.worker:main"
|
||||
eris-webserver = "eris.webserver:main"
|
||||
pydoc_color = "eris.pydoc_color:main"
|
||||
|
||||
[project.urls]
|
||||
homepage = "https://github.com/ahamilton/eris"
|
||||
|
|
|
|||
12
tests/golden-files/results/pydoc-hi3_py
Normal file
12
tests/golden-files/results/pydoc-hi3_py
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
[m[38;2;255;255;255m[48;2;0;0;0mPython Library Documentation: module hi3
|
||||
|
||||
[m[38;2;255;255;255m[48;2;0;0;0m[1mNAME[m[38;2;255;255;255m[48;2;0;0;0m
|
||||
hi3
|
||||
|
||||
[m[38;2;255;255;255m[48;2;0;0;0m[1mFUNCTIONS[m[38;2;255;255;255m[48;2;0;0;0m
|
||||
[m[38;2;255;255;255m[48;2;0;0;0m[1mhi[m[38;2;255;255;255m[48;2;0;0;0m()
|
||||
|
||||
[m[38;2;255;255;255m[48;2;0;0;0m[1mFILE[m[38;2;255;255;255m[48;2;0;0;0m
|
||||
./input/hi3.py
|
||||
|
||||
[m
|
||||
|
|
@ -134,6 +134,9 @@ class ToolsTestCase(unittest.TestCase):
|
|||
for extension in ["png", "jpg", "gif", "bmp", "ppm", "tiff", "tga"]:
|
||||
self._test_tool(tools.pil, [("circle." + extension, tools.Status.ok)])
|
||||
|
||||
def test_pydoc(self):
|
||||
self._test_tool(tools.pydoc, [("hi3.py", tools.Status.ok)])
|
||||
|
||||
|
||||
class LruCacheWithEvictionTestCase(unittest.TestCase):
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue