internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: xonsh/xonsh

Issue:
`[], []` is parsed to `[[]]`
```
$ [], []
[[]]
```



Discussion:
Hey @blahgeek, thanks for reporting! This seems like a legitimate bug, it should rerurn a tuple with two empty lists. Are you on the 0.4.5 version of PyPI?

Yes, `xonsh --version` prints `xonsh/0.4.5`. My python version is 3.5.2

Also note these cases:

```
scopatz@artemis ~ $ [], [],
[[]]
scopatz@artemis ~ $ [1], []
[1, []]
scopatz@artemis ~ $ [1], [1]
[1, [1]]
scopatz@artemis ~ $ ([1], [1])
([1], [1])
```


Resolving patch:
diff --git a/xonsh/parsers/base.py b/xonsh/parsers/base.py
--- a/xonsh/parsers/base.py
+++ b/xonsh/parsers/base.py
@@ -1675,6 +1675,7 @@ def p_atom_lparen(self, p):
             # empty container atom
             p0 = ast.Tuple(elts=[], ctx=ast.Load(), lineno=self.lineno,
                            col_offset=self.col)
+            p0._real_tuple = True
         elif isinstance(p2, ast.AST):
             p0 = p2
             p0._lopen_lineno, p0._lopen_col = p1_tok.lineno, p1_tok.lexpos
@@ -1894,15 +1895,16 @@ def p_testlist_test(self, p):
         """testlist : test"""
         p1 = p[1]
         if isinstance(p1, ast.Tuple) and (hasattr(p1, '_real_tuple') and
-                                          p1._real_tuple):
+                                          p1._real_tuple and p1.elts):
             p1.lineno, p1.col_offset = lopen_loc(p1.elts[0])
         p[0] = p1
 
     def p_testlist_single(self, p):
         """testlist : test COMMA"""
         p1 = p[1]
-        if isinstance(p1, ast.Tuple) and (hasattr(p1, '_real_tuple') and
-                                          p1._real_tuple):
+        if isinstance(p1, ast.List) or (isinstance(p1, ast.Tuple) and
+                                        hasattr(p1, '_real_tuple') and
+                                        p1._real_tuple):
             lineno, col = lopen_loc(p1)
             p[0] = ast.Tuple(elts=[p1], ctx=ast.Load(),
                              lineno=p1.lineno, col_offset=p1.col_offset)
@@ -1914,8 +1916,9 @@ def p_testlist_many(self, p):
                     | test comma_test_list
         """
         p1 = p[1]
-        if isinstance(p1, ast.Tuple) and (hasattr(p1, '_real_tuple') and
-                                          p1._real_tuple):
+        if isinstance(p1, ast.List) or (isinstance(p1, ast.Tuple) and
+                                        hasattr(p1, '_real_tuple') and
+                                        p1._real_tuple):
             lineno, col = lopen_loc(p1)
             p1 = ast.Tuple(elts=[p1], ctx=ast.Load(),
                            lineno=p1.lineno, col_offset=p1.col_offset)


Test patch:
diff --git a/tests/test_parser.py b/tests/test_parser.py
--- a/tests/test_parser.py
+++ b/tests/test_parser.py
@@ -437,6 +437,16 @@ def test_tuple_three():
 def test_tuple_three_comma():
     check_ast('(1, 42, 65,)')
 
+def test_bare_tuple_of_tuples():
+    check_ast('(),')
+    check_ast('((),),(1,)')
+    check_ast('(),(),')
+    check_ast('[],')
+    check_ast('[],[]')
+    check_ast('[],()')
+    check_ast('(),[],')
+    check_ast('((),[()],)')
+
 def test_set_one():
     check_ast('{42}')
Repository: xonsh/xonsh

Issue:
sys.stdin tab completes to sys.stdin[
`sys.stdin` tab completes to `sys.stdin[`. I don't see why you would ever want to automatically complete a square bracket, but for sys.stdin it especially doesn't make sense, since it isn't indexable. 



Discussion:
Thanks for reporting, @asmeurer -- I think there's a bigger question here, too, of whether python-mode completions should extend to the opening container character, be it a `[` or a `(`.  

But yeah, I think square brackets shouldn't be part of the completion

I don't like that but maybe other people do. 

+1 for changing this

Pull requests welcome!


Resolving patch:
diff --git a/xonsh/completers/python.py b/xonsh/completers/python.py
--- a/xonsh/completers/python.py
+++ b/xonsh/completers/python.py
@@ -4,7 +4,7 @@
 import inspect
 import builtins
 import importlib
-import collections.abc as abc
+import collections.abc as cabc
 
 import xonsh.tools as xt
 import xonsh.lazyasd as xl
@@ -95,10 +95,13 @@ def attr_complete(prefix, ctx, filter_func):
         except:  # pylint:disable=bare-except
             continue
         a = getattr(val, opt)
-        if callable(a):
-            rpl = opt + '('
-        elif isinstance(a, abc.Iterable):
-            rpl = opt + '['
+        if builtins.__xonsh_env__['COMPLETIONS_BRACKETS']:
+            if callable(a):
+                rpl = opt + '('
+            elif isinstance(a, (cabc.Sequence, cabc.Mapping)):
+                rpl = opt + '['
+            else:
+                rpl = opt
         else:
             rpl = opt
         # note that prefix[:prelen-len(attr)] != prefix[:-len(attr)]
diff --git a/xonsh/environ.py b/xonsh/environ.py
--- a/xonsh/environ.py
+++ b/xonsh/environ.py
@@ -101,6 +101,7 @@ def DEFAULT_ENSURERS():
     re.compile('\w*DIRS$'): (is_env_path, str_to_env_path, env_path_to_str),
     'COLOR_INPUT': (is_bool, to_bool, bool_to_str),
     'COLOR_RESULTS': (is_bool, to_bool, bool_to_str),
+    'COMPLETIONS_BRACKETS': (is_bool, to_bool, bool_to_str),
     'COMPLETIONS_DISPLAY': (is_completions_display_value,
                             to_completions_display_value, str),
     'COMPLETIONS_MENU_ROWS': (is_int, int, str),
@@ -244,6 +245,7 @@ def DEFAULT_VALUES():
         'CDPATH': (),
         'COLOR_INPUT': True,
         'COLOR_RESULTS': True,
+        'COMPLETIONS_BRACKETS': True,
         'COMPLETIONS_DISPLAY': 'multi',
         'COMPLETIONS_MENU_ROWS': 5,
         'DIRSTACK_SIZE': 20,
@@ -377,6 +379,9 @@ def DEFAULT_DOCS():
         'with Bash, xonsh always prefer an existing relative path.'),
     'COLOR_INPUT': VarDocs('Flag for syntax highlighting interactive input.'),
     'COLOR_RESULTS': VarDocs('Flag for syntax highlighting return values.'),
+    'COMPLETIONS_BRACKETS': VarDocs(
+        'Flag to enable/disable inclusion of square brackets and parentheses '
+        'in Python attribute completions.', default='True'),
     'COMPLETIONS_DISPLAY': VarDocs(
         'Configure if and how Python completions are displayed by the '
         'prompt_toolkit shell.\n\nThis option does not affect Bash '


Test patch:
Repository: xonsh/xonsh

Issue:
Environment variable expansion
It is unclear to me whether this was a design choice or an oversight but current versions of xonsh require `ls "$FOO/bar"` whereas bash expands `ls $FOO/bar` naturally.



Discussion:
Thanks for reporting @seanfarley. I think this is a bug, and it is certainly annoying

`expandpath` works as expected

```
$ from xonsh.tools import expandpath
$ $FOO='test'
$ expandpath('$FOO/spam')
'test/spam'
```

maybe this is a parsing bug?

yeah, it is almoat certainly a parser bug where the parser is not generating and expandpath call in all cases.

I didn't know this was a feature. I just figured `$SPAM` was treated as a variable name.


Resolving patch:
diff --git a/xonsh/parsers/base.py b/xonsh/parsers/base.py
--- a/xonsh/parsers/base.py
+++ b/xonsh/parsers/base.py
@@ -2253,15 +2253,6 @@ def p_subproc_atom_redirect(self, p):
         p0._cliarg_action = 'append'
         p[0] = p0
 
-    def p_subproc_atom_dollar_name(self, p):
-        """subproc_atom : DOLLAR_NAME"""
-        p0 = self._envvar_getter_by_name(p[1][1:], lineno=self.lineno,
-                                         col=self.col)
-        p0 = xonsh_call('__xonsh_ensure_list_of_strs__', [p0],
-                        lineno=self.lineno, col=self.col)
-        p0._cliarg_action = 'extend'
-        p[0] = p0
-
     def p_subproc_atom_re(self, p):
         """subproc_atom : SEARCHPATH"""
         p0 = xonsh_pathsearch(p[1], pymode=False, lineno=self.lineno,
@@ -2323,6 +2314,7 @@ def p_subproc_arg_part(self, p):
                             | STRING
                             | COMMA
                             | QUESTION
+                            | DOLLAR_NAME
         """
         # Many tokens cannot be part of this list, such as $, ', ", ()
         # Use a string atom instead.


Test patch:
diff --git a/tests/test_parser.py b/tests/test_parser.py
--- a/tests/test_parser.py
+++ b/tests/test_parser.py
@@ -1641,6 +1641,9 @@ def test_uncaptured_sub():
 def test_hiddenobj_sub():
     check_xonsh_ast({}, '![ls]', False)
 
+def test_slash_envarv_echo():
+    check_xonsh_ast({}, '![echo $HOME/place]', False)
+
 def test_bang_two_cmds_one_pipe():
     check_xonsh_ast({}, '!(ls | grep wakka)', False)
Repository: xonsh/xonsh

Issue:
Autocomplete: don't display full path
Using  `prompt_kit`, when completing a path such as `/var/log/<TAB>`, the autocompletion menu shows fully prefixed entries. The problem is that when the path is very deep, the autocomplete panel starts to give unreadable results (see attached screenshot).

The proposed solution is to only display the `os.path.basename` of the autocompleted path, suffixed by `/` if it is a directory.

![screenshot from 2016-05-19 10-33-09](https://cloud.githubusercontent.com/assets/14598/15397392/1170b2b8-1dae-11e6-85b4-ea31504f9346.png)



Discussion:
maybe we could use my work in #899 to solve this problem ? 

Good call; thanks for bringing this up, @sebastien!

@GuillaumeLeclerc, that's an interesting idea.  Using `os.path.basename` would be consistent with what bash does, and would involve less clutter, so that probably gets my vote, but using the shortened path might be interesting, too.

The only case I see where `os.path.basename` does not work is that when you're completing from `CDPATH` and you might have more than one root for the completions. In that case, it would be good to use a path shortener to disambiguate the source.

The logic might be something like:
- If the expression to complete matches only one source, or is absolute, use `os.path.basename`
- If the expression to complete matches more than one source (ie, has at least one match in one of the CDPATH entries), then prefix these with a shortened path.

Thanks for reporting @sebastien!  While there are things that I think we can do on the xonsh side to make this less likely on to occur, there are probably going to be edge cases we can't anticipate (like tab completing long variable names in Python).

I think that this should probably be reported to prompt-toolkit, in order to get a more complete solution. But maybe we are just doing things wrong on our end too.  Thoughts @jonathanslenders?


Resolving patch:
diff --git a/xonsh/ptk/completer.py b/xonsh/ptk/completer.py
--- a/xonsh/ptk/completer.py
+++ b/xonsh/ptk/completer.py
@@ -40,7 +40,11 @@ def get_completions(self, document, complete_event):
                     pass
                 elif len(os.path.commonprefix(completions)) <= len(prefix):
                     self.reserve_space()
+                prefix, _, compprefix = prefix.rpartition('.')
                 for comp in completions:
+                    if comp.rsplit('.', 1)[0] in prefix:
+                        comp = comp.rsplit('.', 1)[-1]
+                    l = len(compprefix) if compprefix in comp else 0
                     yield Completion(comp, -l)
 
     def reserve_space(self):


Test patch:
Repository: xonsh/xonsh

Issue:
BaseShell.settitle() uses os.system()
And [arguments are inserted without escaping](https://github.com/xonsh/xonsh/blob/2e5234da02b5b6590c21dd932bc50b8f614ade9f/xonsh/base_shell.py#L292). EDIT: It does escape, making them safe. Probably. Hopefully.

Additionally, this only works under CMD, not PowerShell.

My recommendation is to call [SetConsoleTitleW()](https://msdn.microsoft.com/en-us/library/windows/desktop/ms686050%28v=vs.85%29.aspx) via [ctypes](https://docs.python.org/3/library/ctypes.html).



Discussion:
I left my work computer at work, so I won't be able to get to this until monday.

I think the line above the system call escapes the args.

@laerus Oh! Ok. So at least it's trying.

Any fix is most welcome!


Resolving patch:
diff --git a/xonsh/base_shell.py b/xonsh/base_shell.py
--- a/xonsh/base_shell.py
+++ b/xonsh/base_shell.py
@@ -16,6 +16,11 @@
 from xonsh.prompt.base import multiline_prompt, partial_format_prompt
 from xonsh.events import events
 
+if ON_WINDOWS:
+    import ctypes
+    kernel32 = ctypes.windll.kernel32
+    kernel32.SetConsoleTitleW.argtypes = [ctypes.c_wchar_p]
+
 
 class _TeeOut(object):
     """Tees stdout into the original sys.stdout and another buffer."""
@@ -288,8 +293,7 @@ def settitle(self):
             return
         t = partial_format_prompt(t)
         if ON_WINDOWS and 'ANSICON' not in env:
-            t = escape_windows_cmd_string(t)
-            os.system('title {}'.format(t))
+            kernel32.SetConsoleTitleW(t)
         else:
             with open(1, 'wb', closefd=False) as f:
                 # prevent xonsh from answering interative questions


Test patch:
Repository: xonsh/xonsh

Issue:
Prompt `curr_branch` breaks when git config has status.short
If git config contains:

``` ini
[status]
    short = true
```

then [the current method of getting the git branch](https://github.com/xonsh/xonsh/blob/619ae11486f2e4febfc2218c0d53c7b3f3c9ea49/xonsh/prompt/vc_branch.py#L16-L25) fails, even if `status.branch = true` is also set.

`git status` is a heavy-handed way of doing this anyway; better would be `git rev-parse --abbrev-ref HEAD` IMO. (PR to follow.)



Discussion:

Resolving patch:
diff --git a/xonsh/prompt/vc_branch.py b/xonsh/prompt/vc_branch.py
--- a/xonsh/prompt/vc_branch.py
+++ b/xonsh/prompt/vc_branch.py
@@ -15,15 +15,25 @@
 
 def _get_git_branch(q):
     try:
-        status = subprocess.check_output(['git', 'status'],
-                                         stderr=subprocess.DEVNULL)
+        branches = xt.decode_bytes(subprocess.check_output(
+            ['git', 'branch'],
+            stderr=subprocess.DEVNULL
+        )).splitlines()
     except (subprocess.CalledProcessError, OSError):
         q.put(None)
     else:
-        info = xt.decode_bytes(status)
-        branch = info.splitlines()[0].split()[-1]
-        q.put(branch)
-
+        for branch in branches:
+            if not branch.startswith('* '):
+                continue
+            elif branch.endswith(')'):
+                branch = branch.split()[-1][:-1]
+            else:
+                branch = branch.split()[-1]
+
+            q.put(branch)
+            break
+        else:
+            q.put(None)
 
 def get_git_branch():
     """Attempts to find the current git branch. If this could not


Test patch:
Repository: xonsh/xonsh

Issue:
No output from scp command
While running scp in xonsh, the progress does not showed up:

https://asciinema.org/a/322p80uvb0pjyaic2e51iqmhq

I'm using version 3f45378



Discussion:

Resolving patch:
diff --git a/xonsh/commands_cache.py b/xonsh/commands_cache.py
--- a/xonsh/commands_cache.py
+++ b/xonsh/commands_cache.py
@@ -258,6 +258,7 @@ def default_threadable_predictors():
         'less': predict_help_ver,
         'man': predict_help_ver,
         'more': predict_help_ver,
+        'scp': predict_false,
         'sh': predict_shell,
         'ssh': predict_false,
         'startx': predict_false,


Test patch:
Repository: xonsh/xonsh

Issue:
Completion for a line containing spaces does not work properly
[![asciicast](https://asciinema.org/a/5fokn5ihezmh12c0xz816cno9.png)](https://asciinema.org/a/5fokn5ihezmh12c0xz816cno9)

```
+------------------+-----------------+
| xonsh            | 0.4.7           |
| Git SHA          | None            |
| Python           | 3.4.2           |
| PLY              | 3.7             |
| have readline    | True            |
| prompt toolkit   | None            |
| shell type       | readline        |
| pygments         | 2.0.2           |
| on posix         | True            |
| on linux         | True            |
| distro           | debian          |
| on darwin        | False           |
| on windows       | False           |
| on cygwin        | False           |
| is superuser     | False           |
| default encoding | utf-8           |
| xonsh encoding   | utf-8           |
| encoding errors  | surrogateescape |
+------------------+-----------------+
```



Discussion:
Hi @Kilte, thanks for reporting!  I can confirm this bug on current master, but only on the readline backend.  prompt toolkit seems to work as expected.  


Resolving patch:
diff --git a/xonsh/readline_shell.py b/xonsh/readline_shell.py
--- a/xonsh/readline_shell.py
+++ b/xonsh/readline_shell.py
@@ -261,7 +261,7 @@ def completedefault(self, text, line, begidx, endidx):
         _rebind_case_sensitive_completions()
 
         line = builtins.aliases.expand_alias(line)
-        mline = line.partition(' ')[2]
+        mline = line.rpartition(' ')[2]
         offs = len(mline) - len(text)
         if self.completer is None:
             x = []


Test patch:
Repository: xonsh/xonsh

Issue:
proc signal issue
We may need more work here :)
```
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.5/bin/xonsh", line 3, in <module>
    main()
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/xonsh/main.py", line 221, in main
    shell.shell.cmdloop()
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/xonsh/readline_shell.py", line 399, in cmdloop
    self._cmdloop(intro=intro)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/xonsh/readline_shell.py", line 359, in _cmdloop
    line = self.singleline()
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/xonsh/readline_shell.py", line 249, in singleline
    rtn = input(self.prompt)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/xonsh/proc.py", line 759, in _signal_int
    if self.proc.poll() is not None:
AttributeError: 'NoneType' object has no attribute 'poll'
```


Discussion:

Resolving patch:
diff --git a/xonsh/proc.py b/xonsh/proc.py
--- a/xonsh/proc.py
+++ b/xonsh/proc.py
@@ -756,7 +756,7 @@ def _set_pty_size(self):
     def _signal_int(self, signum, frame):
         """Signal handler for SIGINT - Ctrl+C may have been pressed."""
         self.send_signal(signum)
-        if self.proc.poll() is not None:
+        if self.proc is not None and self.proc.poll() is not None:
             self._restore_sigint(frame=frame)
 
     def _restore_sigint(self, frame=None):


Test patch:
Repository: xonsh/xonsh

Issue:
Add `xip`
Add a core alias `xip` ("kip") that will always run pip in xonsh's python environment (as opposed to the system, the current venv, or any other).

The interface is exactly the same as `pip`.

This is a problem because some tools (eg, homebrew) will install xonsh in an isolated environment, which makes installing xontribs or shell-accessible modules challenging.

The goal is to make it so that eg `xip install requests` will make the `requests` module usable from the shell context.

As a bonus: This should also try to detect if a `sudo` is necessary and automatically use it.

The alias is approximately `@(sys.executable) -m pip @(argv)`.


Discussion:
(I'm really filing this so that I don't forget it. Although if someone else wants to take it, feel free.)
+1 to this!

Resolving patch:
diff --git a/xonsh/aliases.py b/xonsh/aliases.py
--- a/xonsh/aliases.py
+++ b/xonsh/aliases.py
@@ -380,6 +380,27 @@ def showcmd(args, stdin=None):
         sys.displayhook(args)
 
 
+def detect_xip_alias():
+    """
+    Determines the correct invokation to get xonsh's pip
+    """
+    if not getattr(sys, 'executable', None):
+        return lambda args, stdin=None: ("", "Sorry, unable to run pip on your system (missing sys.executable)", 1)
+
+    basecmd = [sys.executable, '-m', 'pip']
+    try:
+        if ON_WINDOWS:
+            # XXX: Does windows have an installation mode that requires UAC?
+            return basecmd
+        elif not os.access(os.path.dirname(sys.executable), os.W_OK):
+            return ['sudo'] + basecmd
+        else:
+            return basecmd
+    except Exception:
+        # Something freaky happened, return something that'll probably work
+        return basecmd
+
+
 def make_default_aliases():
     """Creates a new default aliases dictionary."""
     default_aliases = {
@@ -410,7 +431,8 @@ def make_default_aliases():
         'ipynb': ['jupyter', 'notebook', '--no-browser'],
         'which': xxw.which,
         'xontrib': xontribs_main,
-        'completer': xca.completer_alias
+        'completer': xca.completer_alias,
+        'xip': detect_xip_alias(),
     }
     if ON_WINDOWS:
         # Borrow builtin commands from cmd.exe.


Test patch:
Repository: xonsh/xonsh

Issue:
script that calls ssh gets interrupted
```
laerus@xonsh$ cat autossh 
ssh laerus@192.168.1.10
laerus@xonsh$ ./autossh 
^Z <--- didn't press anything here, this comes from xonsh or ssh
```

tried again with a non-lan remote
```
laerus@xonsh$ ./autossh
^Z
tcsetattr: Interrupted system call
```


Discussion:

Resolving patch:
diff --git a/xonsh/built_ins.py b/xonsh/built_ins.py
--- a/xonsh/built_ins.py
+++ b/xonsh/built_ins.py
@@ -535,6 +535,8 @@ def prep_preexec_fn(self, kwargs, pipeline_group=None):
         """Prepares the 'preexec_fn' keyword argument"""
         if not (ON_POSIX and self.cls is subprocess.Popen):
             return
+        if not builtins.__xonsh_env__.get('XONSH_INTERACTIVE'):
+            return
         if pipeline_group is None:
             xonsh_preexec_fn = no_pg_xonsh_preexec_fn
         else:


Test patch:
Repository: xonsh/xonsh

Issue:
git commit stuck on Mac
When type `git commit` without an `-m` will got xonsh stuck on Mac OS. It doesn't happen on Linux. (I'd say Linux is too kind for devs :))

Xonsh stuck is because the xonsh process has hand off the controlling terminal to git process, but it still want write something to stdout/stderr. Thus it got a SIGTTOU and stopped by OS.

```
USER   PID  PPID  PGID TPGID STAT COMMAND
hugo 23584 23583 23583 23601 T    Python -u xonsh
hugo 23601 23584 23601 23601 S+   git commit
hugo 23602 23601 23601 23601 S+   vim COMMIT_EDITMSG
```

This is a new issue introduced by #2177, my bad. Fix is on the way.



Discussion:

Resolving patch:
diff --git a/xonsh/main.py b/xonsh/main.py
--- a/xonsh/main.py
+++ b/xonsh/main.py
@@ -6,6 +6,7 @@
 import argparse
 import builtins
 import contextlib
+import signal
 import traceback
 
 from xonsh import __version__
@@ -340,6 +341,12 @@ def main(argv=None):
 
 def main_xonsh(args):
     """Main entry point for xonsh cli."""
+    if not ON_WINDOWS:
+        def func_sig_ttin_ttou(n, f):
+            pass
+        signal.signal(signal.SIGTTIN, func_sig_ttin_ttou)
+        signal.signal(signal.SIGTTOU, func_sig_ttin_ttou)
+
     events.on_post_init.fire()
     env = builtins.__xonsh_env__
     shell = builtins.__xonsh_shell__
diff --git a/xonsh/proc.py b/xonsh/proc.py
--- a/xonsh/proc.py
+++ b/xonsh/proc.py
@@ -838,7 +838,10 @@ def _disable_cbreak_stdin(self):
         new[LFLAG] |= termios.ECHO | termios.ICANON
         new[CC][termios.VMIN] = 1
         new[CC][termios.VTIME] = 0
-        termios.tcsetattr(self.stdin_fd, termios.TCSANOW, new)
+        try:
+            termios.tcsetattr(self.stdin_fd, termios.TCSANOW, new)
+        except termios.error:
+            pass
 
     #
     # Dispatch methods


Test patch: