Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cli attempt #2

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 25 additions & 4 deletions coding_assistant/__init__.py
@@ -1,9 +1,15 @@
# type: ignore
import sys
import traceback


class AssistantException(Exception):
...


_old_hook = sys.excepthook

# I don't want to be sued my MS so I'll use a single 'p'
# I don't want to be sued by MS so I'll use a single 'p'
clipy = """
_-_ | /
/_ \\ |/
Expand All @@ -14,11 +20,26 @@
¯--¯"""


def pathname(obj):
"""Create qualified pathname for objs. eg. module.sub.obj, module.sub.inner.obj"""

module = obj.__module__

# TB doesn't include builtin path
if module is None or module == "builtins":
return obj.__name__
return module + '.' + obj.__name__


def assistant_print(type_, value, tb):
_old_hook(type_, value, tb)
width = len(f"{type_.__qualname__}{f': {value}' if value else ''}")-2
print(f"\\{'_'*width}/" + clipy)

# Traceback is inconsistent about which path to use, `format_exception_only` displays relative paths,
# dropping magic roots, eg. "__main__" but still formatting necessary message information
# When the exception hook uses them, it drops absolute paths, eg. "__main__.Super.Sub" becomes "__main__.Sub"
message = traceback.format_exception_only(value).pop().strip().split(": ", 1)
message[0] = pathname(type_)
width = len(": ".join(message)) - 2
print(f"\\{'_' * width}/" + clipy, file=sys.stderr)


sys.excepthook = assistant_print
44 changes: 44 additions & 0 deletions coding_assistant/__main__.py
@@ -0,0 +1,44 @@
import sys
from pathlib import Path
from subprocess import Popen, PIPE

import coding_assistant


# Hardcoded values, helps refactoring for multiple assistants down the line
PATH_IDX = 1
ARGS_IDX = 2
ASSISTANT = coding_assistant.clipy


def cli():
try:
path = Path(sys.argv[PATH_IDX]).resolve()
except IndexError:
raise coding_assistant.AssistantException("Path to file is missing!") from None
args = sys.argv[ARGS_IDX:]

# Path to Python Interpreter
python = sys.executable
p = Popen([python, path, *args], text=True, stdin=sys.stdin, stdout=sys.stdout, stderr=PIPE)
_, err = p.communicate()
if err:
# Normal encoding of the ASCII art was causing errors, this is Windows-1252, a legacy encoding scheme
err = err

# Break into lines
split_assistant = ASSISTANT.splitlines()
split_err = err.splitlines()

# Prevent double assistant by comparing lines that should be equivalent
# Skip first line due to funky spacing of decoded characters
if split_assistant[1:] != split_err[-len(split_assistant)+1:]:
width = len(split_err[-1]) - 2
err += f"\\{'_' * width}/" + ASSISTANT

print(err, file=sys.stderr)
return p.returncode


if __name__ == '__main__':
sys.exit(cli())
4 changes: 4 additions & 0 deletions setup.py
Expand Up @@ -25,4 +25,8 @@
"Operating System :: OS Independent",
],
python_requires='>=3.9',
entry_points={'console_scripts': [
'assistant = coding_assistant.__main__:cli',
],
}
)