Skip to content

Commit

Permalink
Fix xonsh line numbers
Browse files Browse the repository at this point in the history
Resolves   #726.
  • Loading branch information
evhub committed Apr 11, 2023
1 parent 1801648 commit 34c9568
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 33 deletions.
55 changes: 37 additions & 18 deletions coconut/integrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,36 @@ class CoconutXontribLoader(object):
runner = None
timing_info = []

def __call__(self, xsh, **kwargs):
def new_parse(self, parser, code, mode="exec", *args, **kwargs):
"""Coconut-aware version of xonsh's _parse."""
# hide imports to avoid circular dependencies
from coconut.exceptions import CoconutException
from coconut.terminal import format_error
from coconut.util import get_clock_time

if mode not in disabled_xonsh_modes:
parse_start_time = get_clock_time()
try:
code = self.compiler.parse_xonsh(code, keep_state=True)
except CoconutException as err:
err_str = format_error(err).splitlines()[0]
code += " #" + err_str
self.timing_info.append(("parse", get_clock_time() - parse_start_time))
return parser.__class__.parse(parser, code, mode=mode, *args, **kwargs)

def new_try_subproc_toks(self, ctxtransformer, *args, **kwargs):
"""Version of try_subproc_toks that handles the fact that Coconut
code may have different columns than Python code."""
mode, ctxtransformer.mode = ctxtransformer.mode, "eval"
try:
return ctxtransformer.__class__.try_subproc_toks(ctxtransformer, *args, **kwargs)
finally:
ctxtransformer.mode = mode

def __call__(self, xsh, **kwargs):
# hide imports to avoid circular dependencies
from coconut.util import get_clock_time

start_time = get_clock_time()

if self.compiler is None:
Expand All @@ -112,42 +136,37 @@ def __call__(self, xsh, **kwargs):

self.runner.update_vars(xsh.ctx)

def new_parse(execer, code, mode="exec", *args, **kwargs):
"""Coconut-aware version of xonsh's _parse."""
if mode not in disabled_xonsh_modes:
parse_start_time = get_clock_time()
try:
code = self.compiler.parse_xonsh(code, keep_state=True)
except CoconutException as err:
err_str = format_error(err).splitlines()[0]
code += " #" + err_str
self.timing_info.append(("parse", get_clock_time() - parse_start_time))
return execer.__class__.parse(execer, code, mode=mode, *args, **kwargs)

main_parser = xsh.execer.parser
main_parser._coconut_old_parse = main_parser.parse
main_parser.parse = MethodType(new_parse, main_parser)
main_parser.parse = MethodType(self.new_parse, main_parser)

ctx_parser = xsh.execer.ctxtransformer.parser
ctxtransformer = xsh.execer.ctxtransformer
ctx_parser = ctxtransformer.parser
ctx_parser._coconut_old_parse = ctx_parser.parse
ctx_parser.parse = MethodType(new_parse, ctx_parser)
ctx_parser.parse = MethodType(self.new_parse, ctx_parser)

ctxtransformer._coconut_old_try_subproc_toks = ctxtransformer.try_subproc_toks
ctxtransformer.try_subproc_toks = MethodType(self.new_try_subproc_toks, ctxtransformer)

self.timing_info.append(("load", get_clock_time() - start_time))

return self.runner.vars

def unload(self, xsh):
# import here to avoid circular dependencies
# hide imports to avoid circular dependencies
from coconut.exceptions import CoconutException

main_parser = xsh.execer.parser
if not hasattr(main_parser, "_coconut_old_parse"):
raise CoconutException("attempting to unload Coconut xontrib but it was never loaded")
main_parser.parser = main_parser._coconut_old_parse

ctx_parser = xsh.execer.ctxtransformer.parser
ctxtransformer = xsh.execer.ctxtransformer
ctx_parser = ctxtransformer.parser
ctx_parser.parse = ctx_parser._coconut_old_parse

ctxtransformer.try_subproc_toks = ctxtransformer._coconut_old_try_subproc_toks


_load_xontrib_ = CoconutXontribLoader()

Expand Down
2 changes: 1 addition & 1 deletion coconut/root.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
VERSION = "3.0.0"
VERSION_NAME = None
# False for release, int >= 1 for develop
DEVELOP = 20
DEVELOP = 21
ALPHA = True # for pre releases rather than post releases

# -----------------------------------------------------------------------------------------------------------------------
Expand Down
18 changes: 9 additions & 9 deletions coconut/tests/src/cocotest/agnostic/suite.coco
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ def suite_test() -> bool:
assert not is_one([])
assert is_one([1])
assert trilen(3, 4).h == 5 == datamaker(trilen)(5).h
assert A().true() is True
assert clsA().true() is True
inh_a = inh_A()
assert inh_a.true() is True
assert inh_a.inh_true1() is True
Expand Down Expand Up @@ -437,7 +437,7 @@ def suite_test() -> bool:
assert myreduce((+), (1, 2, 3)) == 6
assert recurse_n_times(10000)
assert fake_recurse_n_times(10000)
a = A()
a = clsA()
assert ((not)..a.true)() is False
assert 10 % 4 % 3 == 2 == 10 `mod` 4 `mod` 3
assert square_times2_plus1(3) == 19 == square_times2_plus1_(3)
Expand Down Expand Up @@ -706,7 +706,7 @@ def suite_test() -> bool:
m = methtest2()
assert m.inf_rec(5) == 10 == m.inf_rec_(5)
assert reqs(lazy_client)$[:10] |> list == range(10) |> list == reqs(lazy_client_)$[:10] |> list
class T(A, B, *(C, D), metaclass=Meta, e=5) # type: ignore
class T(clsA, clsB, *(clsC, clsD), metaclass=Meta, e=5) # type: ignore
assert T.a == 1
assert T.b == 2
assert T.c == 3
Expand Down Expand Up @@ -743,8 +743,8 @@ def suite_test() -> bool:
assert just_it_of_int(1) |> list == [1] == just_it_of_int_(1) |> list
assert must_be_int(4) == 4 == must_be_int_(4)
assert typed_plus(1, 2) == 3
(class inh_A() `isinstance` A) `isinstance` object = inh_A()
class inh_A() `isinstance` A `isinstance` object = inh_A()
(class inh_A() `isinstance` clsA) `isinstance` object = inh_A()
class inh_A() `isinstance` clsA `isinstance` object = inh_A()
for maxdiff in (maxdiff1, maxdiff2, maxdiff3, maxdiff_):
assert maxdiff([7,1,4,5]) == 4, "failed for " + repr(maxdiff)
assert all(r == 4 for r in parallel_map(call$(?, [7,1,4,5]), [maxdiff1, maxdiff2, maxdiff3]))
Expand Down Expand Up @@ -919,12 +919,12 @@ forward 2""") == 900
)
),
))
A(.a=1) = A()
match A(.a=2) in A():
clsA(.a=1) = clsA()
match clsA(.a=2) in clsA():
assert False
assert_raises((def -> A(.b=1) = A()), AttributeError)
assert_raises((def -> clsA(.b=1) = clsA()), AttributeError)
assert MySubExc("derp") `isinstance` Exception
assert A().not_super() is True
assert clsA().not_super() is True
match class store.A(1) = store.A(1)
match data store.A(1) = store.A(1)
match store.A(1) = store.A(1)
Expand Down
10 changes: 5 additions & 5 deletions coconut/tests/src/cocotest/agnostic/util.coco
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,7 @@ data trilen(h):
return (a**2 + b**2)**0.5 |> datamaker(cls)

# Inheritance:
class A:
class clsA:
a = 1
def true(self):
return True
Expand All @@ -838,7 +838,7 @@ class A:
return super().true()
@classmethod
def cls_true(cls) = True
class inh_A(A):
class inh_A(clsA):
def inh_true1(self) =
super().true()
def inh_true2(self) =
Expand All @@ -850,11 +850,11 @@ class inh_A(A):
inh_true5 = def (self) -> super().true()
@classmethod
def inh_cls_true(cls) = super().cls_true()
class B:
class clsB:
b = 2
class C:
class clsC:
c = 3
class D:
class clsD:
d = 4

class MyExc(Exception):
Expand Down

0 comments on commit 34c9568

Please sign in to comment.