Skip to content

Commit

Permalink
special comment language support in the REPL
Browse files Browse the repository at this point in the history
  • Loading branch information
pomponchik committed Nov 13, 2023
1 parent b4953bb commit 0e33b16
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 21 deletions.
11 changes: 6 additions & 5 deletions instld/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
from instld.cli.parsing_comments.get_options_from_comments import get_options_from_comments_by_frame
from instld.cli.parsing_arguments.get_python_file import get_python_file
from instld.cli.traceback_cutting.cutting import set_cutting_excepthook
from instld.state_management.storage import state_storage, RunType
from instld.errors import CommentFormatError


def main():
python_file = get_python_file()
state_storage.run_type = RunType.script

with instld() as context:
lock = RLock()
Expand Down Expand Up @@ -52,7 +54,6 @@ def import_wrapper(name, *args, **kwargs):

current_frame = inspect.currentframe()
options = get_options_from_comments_by_frame(current_frame.f_back)
#print('OPTIONS:', options)

package_name = options.pop('package', base_name)

Expand All @@ -74,7 +75,6 @@ def import_wrapper(name, *args, **kwargs):
try:
result = __import__(name, *args, **kwargs)
except (ModuleNotFoundError, ImportError) as e:
#print('OPTIONS>', options, package_name)
current_context.install(package_name, catch_output=catch_output, **options)
result = current_context.import_here(base_name)
sys.modules[base_name] = result
Expand All @@ -90,18 +90,19 @@ def import_wrapper(name, *args, **kwargs):

return result



if python_file is None:
try:
import readline
except ImportError:
pass

state_storage.run_type = RunType.REPL
builtins.__import__ = import_wrapper

class REPL(code.InteractiveConsole):
pass
def push(self, line):
state_storage.last_string = line
return super().push(line)


banner_strings = [
Expand Down
37 changes: 22 additions & 15 deletions instld/cli/parsing_comments/get_comment_string.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,39 @@
from functools import lru_cache

from instld.errors import InstallingPackageError
from instld.state_management.storage import state_storage, RunType


def get_comment_substring_from_string(string):
splitted_line = string.split('#')
right_part = splitted_line[1:]
right_part = '#'.join(right_part)
right_part = right_part.strip()
if right_part.startswith('instld:'):
right_part = right_part[7:].strip()
if right_part:
return right_part
else:
raise InstallingPackageError('An empty list of options in the comment.')

@lru_cache()
def get_comment_string_from_file(line_number, file_name):
try:
with open(file_name, 'r') as file:
for index, line in enumerate(file):
if index + 1 == line_number:
splitted_line = line.split('#')
right_part = splitted_line[1:]
right_part = '#'.join(right_part)
right_part = right_part.strip()
if right_part.startswith('instld:'):
right_part = right_part[7:].strip()
if right_part:
return right_part
else:
raise InstallingPackageError('An empty list of options in the comment.')
break
return get_comment_substring_from_string(line)

except (FileNotFoundError, OSError):
return None

def get_comment_string_by_frame(frame):
line_number = frame.f_lineno
code = frame.f_code
file_name = code.co_filename
if state_storage.run_type == RunType.script:
line_number = frame.f_lineno
code = frame.f_code
file_name = code.co_filename

return get_comment_string_from_file(line_number, file_name)

return get_comment_string_from_file(line_number, file_name)
elif state_storage.run_type == RunType.REPL:
return get_comment_substring_from_string(state_storage.last_string)
Empty file.
17 changes: 17 additions & 0 deletions instld/state_management/storage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from dataclasses import dataclass
from enum import IntEnum, auto
from typing import Optional


class RunType(IntEnum):
script = auto()
REPL = auto()
module = auto()

@dataclass
class StateStorage:
run_type: RunType = RunType.module
last_string: Optional[str] = None


state_storage = StateStorage()
10 changes: 9 additions & 1 deletion tests/units/cli/parsing_comments/test_get_comment_string.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import pytest

from instld.errors import InstallingPackageError
from instld.cli.parsing_comments.get_comment_string import get_comment_string_by_frame
from instld.cli.parsing_comments.get_comment_string import get_comment_string_by_frame, get_comment_substring_from_string


def test_get_comment_started_with_instld():
Expand All @@ -24,3 +24,11 @@ def test_get_comment_without_comment():
def test_get_comment_wrong():
with pytest.raises(InstallingPackageError):
comment = get_comment_string_by_frame(inspect.currentframe()) # instld:


def test_get_comment_substring_from_string():
assert get_comment_substring_from_string('a + b # kek') is None
assert get_comment_substring_from_string('a + b # instld: lol kek') == 'lol kek'

with pytest.raises(InstallingPackageError):
assert get_comment_substring_from_string('a + b # instld: ')

0 comments on commit 0e33b16

Please sign in to comment.