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

Added FuncAlias #5366

Merged
merged 54 commits into from May 13, 2024
Merged

Added FuncAlias #5366

merged 54 commits into from May 13, 2024

Conversation

anki-code
Copy link
Member

@anki-code anki-code commented Apr 25, 2024

Goals

Exception

Before

aliases['cd']
# <function xonsh.dirstack.cd>

aliases['trace']
# <function xonsh.aliases.trace>

aliases['null'] = lambda: 1/0
null
# ZeroDivisionError: division by zero

@aliases.register('catch')
@aliases.register('me')
@aliases.register('if')
@aliases.register('you')
@aliases.register('can')
def _exc(args, stdin, stdout):
    for line in stdin.readlines():
        print(line.strip() + '!', file=stdout, flush=True)
    return 1/0 if 'i' in $__ALIAS_NAME else 0

echo hey | catch | me | if | you | can
# ZeroDivisionError: division by zero      <--- ???
# hey!!!!!

After

aliases['cd']
# FuncAlias({'name': 'cd', 'func': 'cd'})

aliases['trace']
# FuncAlias({'name': 'trace', 'func': 'trace', '__xonsh_threadable__': False})

$XONSH_SHOW_TRACEBACK=False
$RAISE_SUBPROC_ERROR = False
aliases['null'] = lambda: 1/0
null
#Exception in thread {'cls': 'ProcProxyThread', 'name': 'Thread-15', 'func': FuncAlias({'name': 'null', 'func': '<lambda>'}), 'alias': 'null', 'pid': None}
#ZeroDivisionError: division by zero



@aliases.register('catch')
@aliases.register('me')
@aliases.register('if')
@aliases.register('you')
@aliases.register('can')
def _exc(args, stdin, stdout):
    for line in stdin.readlines():
        print(line.strip() + '!', file=stdout, flush=True)
    return 1/0 if 'i' in $__ALIAS_NAME else 0
echo hey | catch | me | if | you | can
# Exception in thread {'cls': 'ProcProxyThread', 'name': 'Thread-8', 'func': FuncAlias({'name': 'if', 'func': '_exc'}), 'alias': 'if', 'pid': None}
# ZeroDivisionError: division by zero
# hey!!!!!

Superhelp

Before

@aliases.register("hello")
def _alias_hello():
    """Show world."""
    print('world')

hello?
# No manual entry for hello

After

@aliases.register("hello")
def _alias_hello():
    """Show world."""
    print('world')

hello?
# FuncAlias({'name': 'hello', 'func': '_alias_hello'}):
# Show world.

For community

⬇️ Please click the 👍 reaction instead of leaving a +1 or 👍 comment

xonsh/aliases.py Outdated Show resolved Hide resolved
@anki-code
Copy link
Member Author

@jnoortheen what do you think?

@jnoortheen
Copy link
Member

  1. Catching errors can be made configurable? I am not sure about the behaviour. It already handles, error message when the return is a 3 tuple value (like [return_code, stdout_msg, stderr_msg])
  2. The help on aliases can be made to work with current code as it is.

@anki-code
Copy link
Member Author

@jnoortheen sorry, I'm not clearly understand what you mean. Please give me some pointers.

  1. "message when the return is a 3 tuple value" - but the goal is to catch exception, isn't it?
  2. You mean alias? - this is just a side fix of this pr.

@jnoortheen
Copy link
Member

  1. pls refer the tutorial secion - https://xon.sh/tutorial.html#callable-aliases
# Lastly, a 3-tuple return value can be used to include an integer
    # return code indicating failure (> 0 return code). In the previous
    # examples the return code would be 0/success.
    return (None, "I failed", 2)
  1. Yes I mean the help(alias) function handling

@anki-code
Copy link
Member Author

anki-code commented May 2, 2024

@jnoortheen Thank you for the link! Why we are talking about return if this PR is to capture the Exception and show what alias raised it?

@jnoortheen
Copy link
Member

It shows the error message in a specific way. e.g. alias-name: error: msg. Also Hiding tracebacks should be configurable.

@anki-code anki-code requested a review from gforsyth May 7, 2024 22:51
@anki-code
Copy link
Member Author

anki-code commented May 7, 2024

@gforsyth It's ready to review. One question: what do you think is it possible to print full traceback with the error line?

@gforsyth
Copy link
Collaborator

gforsyth commented May 7, 2024

what do you think is it possible to print full traceback with the error line?

Can you give me an example of what you're thinking of?

@anki-code
Copy link
Member Author

@gforsyth yep, I mean when I'm doing this:

def f():
    1/0
class qwe:
    def __init__(self,g):
        self.f=g
    def __call__(self):
        self.f()
try:
    qwe(f)()
except Exception:
    raise

I have full traceback in Python:

Traceback (most recent call last):
  File "/private/tmp/1.py", line 9, in <module>
    qwe(f)()
  File "/private/tmp/1.py", line 7, in __call__
    self.f()
  File "/private/tmp/1.py", line 2, in f
    1/0
    ~^~
ZeroDivisionError: division by zero

But:

$XONSH_SHOW_TRACEBACK = True
@aliases.register('f')
def _f():
    1/0
echo f1f1f1 ; f ; echo f2f2f2

Returns only:

Traceback (most recent call last):
  File "/Users/pc/git/xonsh/xonsh/procs/proxies.py", line 475, in run
    r = self.f(self.args, sp_stdin, sp_stdout, sp_stderr, spec, spec.stack)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/pc/git/xonsh/xonsh/aliases.py", line 87, in __call__
    return self.func(*func_args)
           ^^^^^^^^^^^^^^^^^^^^^

@gforsyth
Copy link
Collaborator

gforsyth commented May 8, 2024

There's probably a way to do that by intercepting the traceback and then adding to it with with_traceback(), but I haven't dug around in traceback mutations in a long while.

Copy link
Collaborator

@gforsyth gforsyth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't had time to figure out where this bug is coming from, but this PR introduces a strange behavior where we swallow the first traceback after setting $XONSH_SHOW_TRACEBACK=True

gil@stravaig ~ @ def _f():
................     1 / 0
................
gil@stravaig ~ @ aliases['f'] = _f
gil@stravaig ~ @ f
xonsh: For full traceback set: $XONSH_SHOW_TRACEBACK = True
ZeroDivisionError: division by zero
Exception in FuncAlias({'name': 'f', 'func': <function _f at 0x7def51916c20>})
gil@stravaig ~ @ $XONSH_SHOW_TRACEBACK = True
gil@stravaig ~ @ f    # <- Notice no output here
gil@stravaig ~ @ f
xonsh: To log full traceback to a file set: $XONSH_TRACEBACK_LOGFILE = <filename>
Traceback (most recent call last):
  File "/home/gil/mambaforge/lib/python3.10/site-packages/xonsh/aliases.py", line 87, in __call__
    return self.func(*func_args)
  File "<stdin>", line 2, in _f
ZeroDivisionError: division by zero
Exception in FuncAlias({'name': 'f', 'func': <function _f at 0x7def51916c20>})

@anki-code
Copy link
Member Author

anki-code commented May 8, 2024

@gforsyth I think this behavior is not from this PR. There is general issue around raising exception from alias and having hard exception from closed descriptor - #5393
I think this swallowing comes from the situation when descriptor is lost.
Could you please try to repeat 5393 on your main (not from this PR) xonsh session. The expect script pinned in the issue.

@gforsyth
Copy link
Collaborator

gforsyth commented May 8, 2024

This is on current main:

gil@stravaig ~ @ xonfig
+-----------------------------+---------------------+
| xonsh                       | 0.16.0.dev91        |
| Git SHA                     | 4a2cfc64            |
| Commit Date                 | May 6 14:20:34 2024 |
| Python                      | 3.10.12             |
| PLY                         | 3.11                |
| have readline               | True                |
| prompt toolkit              | 3.0.39              |
| shell type                  | prompt_toolkit      |
| history backend             | json                |
| pygments                    | 2.16.1              |
| on posix                    | True                |
| on linux                    | True                |
| distro                      | ubuntu              |
| on wsl                      | False               |
| on darwin                   | False               |
| on windows                  | False               |
| on cygwin                   | False               |
| on msys2                    | False               |
| is superuser                | False               |
| default encoding            | utf-8               |
| xonsh encoding              | utf-8               |
| encoding errors             | surrogateescape     |
| xontrib                     | []                  |
| RC file                     | []                  |
| UPDATE_OS_ENVIRON           | False               |
| XONSH_CAPTURE_ALWAYS        | False               |
| XONSH_SUBPROC_OUTPUT_FORMAT | stream_lines        |
| THREAD_SUBPROCS             | True                |
| XONSH_CACHE_SCRIPTS         | True                |
+-----------------------------+---------------------+
gil@stravaig ~ @ def _f():
................     1 / 0
gil@stravaig ~ @ aliases['f'] = _f
gil@stravaig ~ @ f
xonsh: For full traceback set: $XONSH_SHOW_TRACEBACK = True
Exception in thread {'cls': 'ProcProxyThread', 'name': 'Thread-15', 'func': '_f', 'alias': 'f', 'pid': None}
ZeroDivisionError: division by zero
gil@stravaig ~ [1] @ $XONSH_SHOW_TRACEBACK = True
gil@stravaig ~ @ f
Exception in thread {'cls': 'ProcProxyThread', 'name': 'Thread-22', 'func': '_f', 'alias': 'f', 'pid': None}
xonsh: To log full traceback to a file set: $XONSH_TRACEBACK_LOGFILE = <filename>
Traceback (most recent call last):
  File "/home/gil/mambaforge/lib/python3.10/site-packages/xonsh/procs/proxies.py", line 540, in run
    r = self.f(self.args, sp_stdin, sp_stdout, sp_stderr, spec, spec.stack)
  File "/home/gil/mambaforge/lib/python3.10/site-packages/xonsh/procs/proxies.py", line 290, in proxy_zero
    return f()
  File "<stdin>", line 2, in _f
ZeroDivisionError: division by zero

gil@stravaig ~ [1] @ f
Exception in thread {'cls': 'ProcProxyThread', 'name': 'Thread-27', 'func': '_f', 'alias': 'f', 'pid': None}
xonsh: To log full traceback to a file set: $XONSH_TRACEBACK_LOGFILE = <filename>
Traceback (most recent call last):
  File "/home/gil/mambaforge/lib/python3.10/site-packages/xonsh/procs/proxies.py", line 540, in run
    r = self.f(self.args, sp_stdin, sp_stdout, sp_stderr, spec, spec.stack)
  File "/home/gil/mambaforge/lib/python3.10/site-packages/xonsh/procs/proxies.py", line 290, in proxy_zero
    return f()
  File "<stdin>", line 2, in _f
ZeroDivisionError: division by zero

This is on this PR branch:

gil@stravaig ~ @ xonfig
+-----------------------------+---------------------+
| xonsh                       | 0.16.0.dev134       |
| Git SHA                     | 1b5c30b9            |
| Commit Date                 | May 7 18:45:11 2024 |
| Python                      | 3.10.12             |
| PLY                         | 3.11                |
| have readline               | True                |
| prompt toolkit              | 3.0.39              |
| shell type                  | prompt_toolkit      |
| history backend             | json                |
| pygments                    | 2.16.1              |
| on posix                    | True                |
| on linux                    | True                |
| distro                      | ubuntu              |
| on wsl                      | False               |
| on darwin                   | False               |
| on windows                  | False               |
| on cygwin                   | False               |
| on msys2                    | False               |
| is superuser                | False               |
| default encoding            | utf-8               |
| xonsh encoding              | utf-8               |
| encoding errors             | surrogateescape     |
| xontrib                     | []                  |
| RC file                     | []                  |
| UPDATE_OS_ENVIRON           | False               |
| XONSH_CAPTURE_ALWAYS        | False               |
| XONSH_SUBPROC_OUTPUT_FORMAT | stream_lines        |
| THREAD_SUBPROCS             | True                |
| XONSH_CACHE_SCRIPTS         | True                |
+-----------------------------+---------------------+
gil@stravaig ~ @ def _f():
................     1 / 0
................
gil@stravaig ~ @ aliases['f'] = _f
gil@stravaig ~ @ f
xonsh: For full traceback set: $XONSH_SHOW_TRACEBACK = True
ZeroDivisionError: division by zero
Exception in FuncAlias({'name': 'f', 'func': <function _f at 0x77d7466c3370>})
gil@stravaig ~ @ $XONSH_SHOW_TRACEBACK = True
gil@stravaig ~ @ f
gil@stravaig ~ @ f
xonsh: To log full traceback to a file set: $XONSH_TRACEBACK_LOGFILE = <filename>
Traceback (most recent call last):
  File "/home/gil/mambaforge/lib/python3.10/site-packages/xonsh/aliases.py", line 87, in __call__
    return self.func(*func_args)
  File "<stdin>", line 2, in _f
ZeroDivisionError: division by zero
Exception in FuncAlias({'name': 'f', 'func': <function _f at 0x77d7466c3370>})

@anki-code anki-code marked this pull request as draft May 8, 2024 15:43
@anki-code anki-code marked this pull request as ready for review May 11, 2024 10:19
@anki-code anki-code requested a review from gforsyth May 11, 2024 10:19
@anki-code
Copy link
Member Author

@gforsyth hey!

  1. I traced the issue you faced with and made notes in feat: make stack trace behave like in python #4662 (comment) and created task print_exception: rewrite deprecated code #5405

  2. I changed the code in this PR to have soft workaround of this issue. I noticed that I already show the alias name and additional print_exception is not needed.

  3. I added full integration test coverage for printing messages.

  4. It's ready to review.

Thanks!

Copy link
Collaborator

@gforsyth gforsyth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work on this, @anki-code !

@gforsyth gforsyth merged commit bb394a8 into main May 13, 2024
15 checks passed
@gforsyth gforsyth deleted the func_alias branch May 13, 2024 13:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Show alias function description using superhelp
3 participants