We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Python 3.4 no longer supported?
Hi all,

First of all, thank you all for your great work. 

I have noticed that the version bump to 0.5.7 introduced a call to `os.scandir` which is not supported by Python <3.5 afaik. As I am still using Ubuntu 14.04 with Python 3.4 on a few machines, this is a little bit of a headache... I don't know the codebase, but it looks like `xonsh.platform.scandir` could be used instead?

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `xonsh/prompt/vc.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 """Prompt formatter for simple version control branchs"""
3 # pylint:disable=no-member, invalid-name
4 
5 import os
6 import sys
7 import queue
8 import builtins
9 import threading
10 import subprocess
11 
12 import xonsh.tools as xt
13 
14 
15 def _get_git_branch(q):
16     try:
17         branches = xt.decode_bytes(subprocess.check_output(
18             ['git', 'branch'],
19             stderr=subprocess.DEVNULL
20         )).splitlines()
21     except (subprocess.CalledProcessError, OSError, FileNotFoundError):
22         q.put(None)
23     else:
24         for branch in branches:
25             if not branch.startswith('* '):
26                 continue
27             elif branch.endswith(')'):
28                 branch = branch.split()[-1][:-1]
29             else:
30                 branch = branch.split()[-1]
31 
32             q.put(branch)
33             break
34         else:
35             q.put(None)
36 
37 
38 def get_git_branch():
39     """Attempts to find the current git branch. If this could not
40     be determined (timeout, not in a git repo, etc.) then this returns None.
41     """
42     branch = None
43     timeout = builtins.__xonsh_env__.get('VC_BRANCH_TIMEOUT')
44     q = queue.Queue()
45 
46     t = threading.Thread(target=_get_git_branch, args=(q,))
47     t.start()
48     t.join(timeout=timeout)
49     try:
50         branch = q.get_nowait()
51     except queue.Empty:
52         branch = None
53     return branch
54 
55 
56 def _get_hg_root(q):
57     _curpwd = builtins.__xonsh_env__['PWD']
58     while True:
59         if not os.path.isdir(_curpwd):
60             return False
61         if any([b.name == '.hg' for b in os.scandir(_curpwd)]):
62             q.put(_curpwd)
63             break
64         else:
65             _oldpwd = _curpwd
66             _curpwd = os.path.split(_curpwd)[0]
67             if _oldpwd == _curpwd:
68                 return False
69 
70 
71 def get_hg_branch(root=None):
72     """Try to get the mercurial branch of the current directory,
73     return None if not in a repo or subprocess.TimeoutExpired if timed out.
74     """
75     env = builtins.__xonsh_env__
76     timeout = env['VC_BRANCH_TIMEOUT']
77     q = queue.Queue()
78     t = threading.Thread(target=_get_hg_root, args=(q,))
79     t.start()
80     t.join(timeout=timeout)
81     try:
82         root = q.get_nowait()
83     except queue.Empty:
84         return None
85     if env.get('VC_HG_SHOW_BRANCH'):
86         # get branch name
87         branch_path = os.path.sep.join([root, '.hg', 'branch'])
88         if os.path.exists(branch_path):
89             with open(branch_path, 'r') as branch_file:
90                 branch = branch_file.read()
91         else:
92             branch = 'default'
93     else:
94         branch = ''
95     # add bookmark, if we can
96     bookmark_path = os.path.sep.join([root, '.hg', 'bookmarks.current'])
97     if os.path.exists(bookmark_path):
98         with open(bookmark_path, 'r') as bookmark_file:
99             active_bookmark = bookmark_file.read()
100         if env.get('VC_HG_SHOW_BRANCH') is True:
101             branch = "{0}, {1}".format(*(b.strip(os.linesep) for b in
102                                          (branch, active_bookmark)))
103         else:
104             branch = active_bookmark.strip(os.linesep)
105     else:
106         branch = branch.strip(os.linesep)
107     return branch
108 
109 
110 _FIRST_BRANCH_TIMEOUT = True
111 
112 
113 def _first_branch_timeout_message():
114     global _FIRST_BRANCH_TIMEOUT
115     sbtm = builtins.__xonsh_env__['SUPPRESS_BRANCH_TIMEOUT_MESSAGE']
116     if not _FIRST_BRANCH_TIMEOUT or sbtm:
117         return
118     _FIRST_BRANCH_TIMEOUT = False
119     print('xonsh: branch timeout: computing the branch name, color, or both '
120           'timed out while formatting the prompt. You may avoid this by '
121           'increasing the value of $VC_BRANCH_TIMEOUT or by removing branch '
122           'fields, like {curr_branch}, from your $PROMPT. See the FAQ '
123           'for more details. This message will be suppressed for the remainder '
124           'of this session. To suppress this message permanently, set '
125           '$SUPPRESS_BRANCH_TIMEOUT_MESSAGE = True in your xonshrc file.',
126           file=sys.stderr)
127 
128 
129 def current_branch():
130     """Gets the branch for a current working directory. Returns an empty string
131     if the cwd is not a repository.  This currently only works for git and hg
132     and should be extended in the future.  If a timeout occurred, the string
133     '<branch-timeout>' is returned.
134     """
135     branch = None
136     cmds = builtins.__xonsh_commands_cache__
137     # check for binary only once
138     if cmds.is_empty():
139         has_git = bool(cmds.locate_binary('git', ignore_alias=True))
140         has_hg = bool(cmds.locate_binary('hg', ignore_alias=True))
141     else:
142         has_git = bool(cmds.lazy_locate_binary('git', ignore_alias=True))
143         has_hg = bool(cmds.lazy_locate_binary('hg', ignore_alias=True))
144     if has_git:
145         branch = get_git_branch()
146     if not branch and has_hg:
147         branch = get_hg_branch()
148     if isinstance(branch, subprocess.TimeoutExpired):
149         branch = '<branch-timeout>'
150         _first_branch_timeout_message()
151     return branch or None
152 
153 
154 def _git_dirty_working_directory(q, include_untracked):
155     status = None
156     try:
157         cmd = ['git', 'status', '--porcelain']
158         if include_untracked:
159             cmd.append('--untracked-files=normal')
160         else:
161             cmd.append('--untracked-files=no')
162         status = subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
163     except (subprocess.CalledProcessError, OSError, FileNotFoundError):
164         q.put(None)
165     if status is not None:
166         return q.put(bool(status))
167 
168 
169 def git_dirty_working_directory(include_untracked=False):
170     """Returns whether or not the git directory is dirty. If this could not
171     be determined (timeout, file not found, etc.) then this returns None.
172     """
173     timeout = builtins.__xonsh_env__.get("VC_BRANCH_TIMEOUT")
174     q = queue.Queue()
175     t = threading.Thread(target=_git_dirty_working_directory,
176                          args=(q, include_untracked))
177     t.start()
178     t.join(timeout=timeout)
179     try:
180         return q.get_nowait()
181     except queue.Empty:
182         return None
183 
184 
185 def hg_dirty_working_directory():
186     """Computes whether or not the mercurial working directory is dirty or not.
187     If this cannot be determined, None is returned.
188     """
189     env = builtins.__xonsh_env__
190     cwd = env['PWD']
191     denv = env.detype()
192     vcbt = env['VC_BRANCH_TIMEOUT']
193     # Override user configurations settings and aliases
194     denv['HGRCPATH'] = ''
195     try:
196         s = subprocess.check_output(['hg', 'identify', '--id'],
197                                     stderr=subprocess.PIPE, cwd=cwd,
198                                     timeout=vcbt, universal_newlines=True,
199                                     env=denv)
200         return s.strip(os.linesep).endswith('+')
201     except (subprocess.CalledProcessError, subprocess.TimeoutExpired,
202             FileNotFoundError):
203         return None
204 
205 
206 def dirty_working_directory():
207     """Returns a boolean as to whether there are uncommitted files in version
208     control repository we are inside. If this cannot be determined, returns
209     None. Currently supports git and hg.
210     """
211     dwd = None
212     cmds = builtins.__xonsh_commands_cache__
213     if cmds.lazy_locate_binary('git'):
214         dwd = git_dirty_working_directory()
215     if cmds.lazy_locate_binary('hg') and dwd is None:
216         dwd = hg_dirty_working_directory()
217     return dwd
218 
219 
220 def branch_color():
221     """Return red if the current branch is dirty, yellow if the dirtiness can
222     not be determined, and green if it clean. These are bold, intense colors
223     for the foreground.
224     """
225     dwd = dirty_working_directory()
226     if dwd is None:
227         color = '{BOLD_INTENSE_YELLOW}'
228     elif dwd:
229         color = '{BOLD_INTENSE_RED}'
230     else:
231         color = '{BOLD_INTENSE_GREEN}'
232     return color
233 
234 
235 def branch_bg_color():
236     """Return red if the current branch is dirty, yellow if the dirtiness can
237     not be determined, and green if it clean. These are bacground colors.
238     """
239     dwd = dirty_working_directory()
240     if dwd is None:
241         color = '{BACKGROUND_YELLOW}'
242     elif dwd:
243         color = '{BACKGROUND_RED}'
244     else:
245         color = '{BACKGROUND_GREEN}'
246     return color
247
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/xonsh/prompt/vc.py b/xonsh/prompt/vc.py
--- a/xonsh/prompt/vc.py
+++ b/xonsh/prompt/vc.py
@@ -58,7 +58,7 @@
     while True:
         if not os.path.isdir(_curpwd):
             return False
-        if any([b.name == '.hg' for b in os.scandir(_curpwd)]):
+        if any([b.name == '.hg' for b in xt.scandir(_curpwd)]):
             q.put(_curpwd)
             break
         else:

{"golden_diff": "diff --git a/xonsh/prompt/vc.py b/xonsh/prompt/vc.py\n--- a/xonsh/prompt/vc.py\n+++ b/xonsh/prompt/vc.py\n@@ -58,7 +58,7 @@\n     while True:\n         if not os.path.isdir(_curpwd):\n             return False\n-        if any([b.name == '.hg' for b in os.scandir(_curpwd)]):\n+        if any([b.name == '.hg' for b in xt.scandir(_curpwd)]):\n             q.put(_curpwd)\n             break\n         else:\n", "issue": "Python 3.4 no longer supported?\nHi all,\r\n\r\nFirst of all, thank you all for your great work. \r\n\r\nI have noticed that the version bump to 0.5.7 introduced a call to `os.scandir` which is not supported by Python <3.5 afaik. As I am still using Ubuntu 14.04 with Python 3.4 on a few machines, this is a little bit of a headache... I don't know the codebase, but it looks like `xonsh.platform.scandir` could be used instead?\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"Prompt formatter for simple version control branchs\"\"\"\n# pylint:disable=no-member, invalid-name\n\nimport os\nimport sys\nimport queue\nimport builtins\nimport threading\nimport subprocess\n\nimport xonsh.tools as xt\n\n\ndef _get_git_branch(q):\n    try:\n        branches = xt.decode_bytes(subprocess.check_output(\n            ['git', 'branch'],\n            stderr=subprocess.DEVNULL\n        )).splitlines()\n    except (subprocess.CalledProcessError, OSError, FileNotFoundError):\n        q.put(None)\n    else:\n        for branch in branches:\n            if not branch.startswith('* '):\n                continue\n            elif branch.endswith(')'):\n                branch = branch.split()[-1][:-1]\n            else:\n                branch = branch.split()[-1]\n\n            q.put(branch)\n            break\n        else:\n            q.put(None)\n\n\ndef get_git_branch():\n    \"\"\"Attempts to find the current git branch. If this could not\n    be determined (timeout, not in a git repo, etc.) then this returns None.\n    \"\"\"\n    branch = None\n    timeout = builtins.__xonsh_env__.get('VC_BRANCH_TIMEOUT')\n    q = queue.Queue()\n\n    t = threading.Thread(target=_get_git_branch, args=(q,))\n    t.start()\n    t.join(timeout=timeout)\n    try:\n        branch = q.get_nowait()\n    except queue.Empty:\n        branch = None\n    return branch\n\n\ndef _get_hg_root(q):\n    _curpwd = builtins.__xonsh_env__['PWD']\n    while True:\n        if not os.path.isdir(_curpwd):\n            return False\n        if any([b.name == '.hg' for b in os.scandir(_curpwd)]):\n            q.put(_curpwd)\n            break\n        else:\n            _oldpwd = _curpwd\n            _curpwd = os.path.split(_curpwd)[0]\n            if _oldpwd == _curpwd:\n                return False\n\n\ndef get_hg_branch(root=None):\n    \"\"\"Try to get the mercurial branch of the current directory,\n    return None if not in a repo or subprocess.TimeoutExpired if timed out.\n    \"\"\"\n    env = builtins.__xonsh_env__\n    timeout = env['VC_BRANCH_TIMEOUT']\n    q = queue.Queue()\n    t = threading.Thread(target=_get_hg_root, args=(q,))\n    t.start()\n    t.join(timeout=timeout)\n    try:\n        root = q.get_nowait()\n    except queue.Empty:\n        return None\n    if env.get('VC_HG_SHOW_BRANCH'):\n        # get branch name\n        branch_path = os.path.sep.join([root, '.hg', 'branch'])\n        if os.path.exists(branch_path):\n            with open(branch_path, 'r') as branch_file:\n                branch = branch_file.read()\n        else:\n            branch = 'default'\n    else:\n        branch = ''\n    # add bookmark, if we can\n    bookmark_path = os.path.sep.join([root, '.hg', 'bookmarks.current'])\n    if os.path.exists(bookmark_path):\n        with open(bookmark_path, 'r') as bookmark_file:\n            active_bookmark = bookmark_file.read()\n        if env.get('VC_HG_SHOW_BRANCH') is True:\n            branch = \"{0}, {1}\".format(*(b.strip(os.linesep) for b in\n                                         (branch, active_bookmark)))\n        else:\n            branch = active_bookmark.strip(os.linesep)\n    else:\n        branch = branch.strip(os.linesep)\n    return branch\n\n\n_FIRST_BRANCH_TIMEOUT = True\n\n\ndef _first_branch_timeout_message():\n    global _FIRST_BRANCH_TIMEOUT\n    sbtm = builtins.__xonsh_env__['SUPPRESS_BRANCH_TIMEOUT_MESSAGE']\n    if not _FIRST_BRANCH_TIMEOUT or sbtm:\n        return\n    _FIRST_BRANCH_TIMEOUT = False\n    print('xonsh: branch timeout: computing the branch name, color, or both '\n          'timed out while formatting the prompt. You may avoid this by '\n          'increasing the value of $VC_BRANCH_TIMEOUT or by removing branch '\n          'fields, like {curr_branch}, from your $PROMPT. See the FAQ '\n          'for more details. This message will be suppressed for the remainder '\n          'of this session. To suppress this message permanently, set '\n          '$SUPPRESS_BRANCH_TIMEOUT_MESSAGE = True in your xonshrc file.',\n          file=sys.stderr)\n\n\ndef current_branch():\n    \"\"\"Gets the branch for a current working directory. Returns an empty string\n    if the cwd is not a repository.  This currently only works for git and hg\n    and should be extended in the future.  If a timeout occurred, the string\n    '<branch-timeout>' is returned.\n    \"\"\"\n    branch = None\n    cmds = builtins.__xonsh_commands_cache__\n    # check for binary only once\n    if cmds.is_empty():\n        has_git = bool(cmds.locate_binary('git', ignore_alias=True))\n        has_hg = bool(cmds.locate_binary('hg', ignore_alias=True))\n    else:\n        has_git = bool(cmds.lazy_locate_binary('git', ignore_alias=True))\n        has_hg = bool(cmds.lazy_locate_binary('hg', ignore_alias=True))\n    if has_git:\n        branch = get_git_branch()\n    if not branch and has_hg:\n        branch = get_hg_branch()\n    if isinstance(branch, subprocess.TimeoutExpired):\n        branch = '<branch-timeout>'\n        _first_branch_timeout_message()\n    return branch or None\n\n\ndef _git_dirty_working_directory(q, include_untracked):\n    status = None\n    try:\n        cmd = ['git', 'status', '--porcelain']\n        if include_untracked:\n            cmd.append('--untracked-files=normal')\n        else:\n            cmd.append('--untracked-files=no')\n        status = subprocess.check_output(cmd, stderr=subprocess.DEVNULL)\n    except (subprocess.CalledProcessError, OSError, FileNotFoundError):\n        q.put(None)\n    if status is not None:\n        return q.put(bool(status))\n\n\ndef git_dirty_working_directory(include_untracked=False):\n    \"\"\"Returns whether or not the git directory is dirty. If this could not\n    be determined (timeout, file not found, etc.) then this returns None.\n    \"\"\"\n    timeout = builtins.__xonsh_env__.get(\"VC_BRANCH_TIMEOUT\")\n    q = queue.Queue()\n    t = threading.Thread(target=_git_dirty_working_directory,\n                         args=(q, include_untracked))\n    t.start()\n    t.join(timeout=timeout)\n    try:\n        return q.get_nowait()\n    except queue.Empty:\n        return None\n\n\ndef hg_dirty_working_directory():\n    \"\"\"Computes whether or not the mercurial working directory is dirty or not.\n    If this cannot be determined, None is returned.\n    \"\"\"\n    env = builtins.__xonsh_env__\n    cwd = env['PWD']\n    denv = env.detype()\n    vcbt = env['VC_BRANCH_TIMEOUT']\n    # Override user configurations settings and aliases\n    denv['HGRCPATH'] = ''\n    try:\n        s = subprocess.check_output(['hg', 'identify', '--id'],\n                                    stderr=subprocess.PIPE, cwd=cwd,\n                                    timeout=vcbt, universal_newlines=True,\n                                    env=denv)\n        return s.strip(os.linesep).endswith('+')\n    except (subprocess.CalledProcessError, subprocess.TimeoutExpired,\n            FileNotFoundError):\n        return None\n\n\ndef dirty_working_directory():\n    \"\"\"Returns a boolean as to whether there are uncommitted files in version\n    control repository we are inside. If this cannot be determined, returns\n    None. Currently supports git and hg.\n    \"\"\"\n    dwd = None\n    cmds = builtins.__xonsh_commands_cache__\n    if cmds.lazy_locate_binary('git'):\n        dwd = git_dirty_working_directory()\n    if cmds.lazy_locate_binary('hg') and dwd is None:\n        dwd = hg_dirty_working_directory()\n    return dwd\n\n\ndef branch_color():\n    \"\"\"Return red if the current branch is dirty, yellow if the dirtiness can\n    not be determined, and green if it clean. These are bold, intense colors\n    for the foreground.\n    \"\"\"\n    dwd = dirty_working_directory()\n    if dwd is None:\n        color = '{BOLD_INTENSE_YELLOW}'\n    elif dwd:\n        color = '{BOLD_INTENSE_RED}'\n    else:\n        color = '{BOLD_INTENSE_GREEN}'\n    return color\n\n\ndef branch_bg_color():\n    \"\"\"Return red if the current branch is dirty, yellow if the dirtiness can\n    not be determined, and green if it clean. These are bacground colors.\n    \"\"\"\n    dwd = dirty_working_directory()\n    if dwd is None:\n        color = '{BACKGROUND_YELLOW}'\n    elif dwd:\n        color = '{BACKGROUND_RED}'\n    else:\n        color = '{BACKGROUND_GREEN}'\n    return color\n", "path": "xonsh/prompt/vc.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"Prompt formatter for simple version control branchs\"\"\"\n# pylint:disable=no-member, invalid-name\n\nimport os\nimport sys\nimport queue\nimport builtins\nimport threading\nimport subprocess\n\nimport xonsh.tools as xt\n\n\ndef _get_git_branch(q):\n    try:\n        branches = xt.decode_bytes(subprocess.check_output(\n            ['git', 'branch'],\n            stderr=subprocess.DEVNULL\n        )).splitlines()\n    except (subprocess.CalledProcessError, OSError, FileNotFoundError):\n        q.put(None)\n    else:\n        for branch in branches:\n            if not branch.startswith('* '):\n                continue\n            elif branch.endswith(')'):\n                branch = branch.split()[-1][:-1]\n            else:\n                branch = branch.split()[-1]\n\n            q.put(branch)\n            break\n        else:\n            q.put(None)\n\n\ndef get_git_branch():\n    \"\"\"Attempts to find the current git branch. If this could not\n    be determined (timeout, not in a git repo, etc.) then this returns None.\n    \"\"\"\n    branch = None\n    timeout = builtins.__xonsh_env__.get('VC_BRANCH_TIMEOUT')\n    q = queue.Queue()\n\n    t = threading.Thread(target=_get_git_branch, args=(q,))\n    t.start()\n    t.join(timeout=timeout)\n    try:\n        branch = q.get_nowait()\n    except queue.Empty:\n        branch = None\n    return branch\n\n\ndef _get_hg_root(q):\n    _curpwd = builtins.__xonsh_env__['PWD']\n    while True:\n        if not os.path.isdir(_curpwd):\n            return False\n        if any([b.name == '.hg' for b in xt.scandir(_curpwd)]):\n            q.put(_curpwd)\n            break\n        else:\n            _oldpwd = _curpwd\n            _curpwd = os.path.split(_curpwd)[0]\n            if _oldpwd == _curpwd:\n                return False\n\n\ndef get_hg_branch(root=None):\n    \"\"\"Try to get the mercurial branch of the current directory,\n    return None if not in a repo or subprocess.TimeoutExpired if timed out.\n    \"\"\"\n    env = builtins.__xonsh_env__\n    timeout = env['VC_BRANCH_TIMEOUT']\n    q = queue.Queue()\n    t = threading.Thread(target=_get_hg_root, args=(q,))\n    t.start()\n    t.join(timeout=timeout)\n    try:\n        root = q.get_nowait()\n    except queue.Empty:\n        return None\n    if env.get('VC_HG_SHOW_BRANCH'):\n        # get branch name\n        branch_path = os.path.sep.join([root, '.hg', 'branch'])\n        if os.path.exists(branch_path):\n            with open(branch_path, 'r') as branch_file:\n                branch = branch_file.read()\n        else:\n            branch = 'default'\n    else:\n        branch = ''\n    # add bookmark, if we can\n    bookmark_path = os.path.sep.join([root, '.hg', 'bookmarks.current'])\n    if os.path.exists(bookmark_path):\n        with open(bookmark_path, 'r') as bookmark_file:\n            active_bookmark = bookmark_file.read()\n        if env.get('VC_HG_SHOW_BRANCH') is True:\n            branch = \"{0}, {1}\".format(*(b.strip(os.linesep) for b in\n                                         (branch, active_bookmark)))\n        else:\n            branch = active_bookmark.strip(os.linesep)\n    else:\n        branch = branch.strip(os.linesep)\n    return branch\n\n\n_FIRST_BRANCH_TIMEOUT = True\n\n\ndef _first_branch_timeout_message():\n    global _FIRST_BRANCH_TIMEOUT\n    sbtm = builtins.__xonsh_env__['SUPPRESS_BRANCH_TIMEOUT_MESSAGE']\n    if not _FIRST_BRANCH_TIMEOUT or sbtm:\n        return\n    _FIRST_BRANCH_TIMEOUT = False\n    print('xonsh: branch timeout: computing the branch name, color, or both '\n          'timed out while formatting the prompt. You may avoid this by '\n          'increasing the value of $VC_BRANCH_TIMEOUT or by removing branch '\n          'fields, like {curr_branch}, from your $PROMPT. See the FAQ '\n          'for more details. This message will be suppressed for the remainder '\n          'of this session. To suppress this message permanently, set '\n          '$SUPPRESS_BRANCH_TIMEOUT_MESSAGE = True in your xonshrc file.',\n          file=sys.stderr)\n\n\ndef current_branch():\n    \"\"\"Gets the branch for a current working directory. Returns an empty string\n    if the cwd is not a repository.  This currently only works for git and hg\n    and should be extended in the future.  If a timeout occurred, the string\n    '<branch-timeout>' is returned.\n    \"\"\"\n    branch = None\n    cmds = builtins.__xonsh_commands_cache__\n    # check for binary only once\n    if cmds.is_empty():\n        has_git = bool(cmds.locate_binary('git', ignore_alias=True))\n        has_hg = bool(cmds.locate_binary('hg', ignore_alias=True))\n    else:\n        has_git = bool(cmds.lazy_locate_binary('git', ignore_alias=True))\n        has_hg = bool(cmds.lazy_locate_binary('hg', ignore_alias=True))\n    if has_git:\n        branch = get_git_branch()\n    if not branch and has_hg:\n        branch = get_hg_branch()\n    if isinstance(branch, subprocess.TimeoutExpired):\n        branch = '<branch-timeout>'\n        _first_branch_timeout_message()\n    return branch or None\n\n\ndef _git_dirty_working_directory(q, include_untracked):\n    status = None\n    try:\n        cmd = ['git', 'status', '--porcelain']\n        if include_untracked:\n            cmd.append('--untracked-files=normal')\n        else:\n            cmd.append('--untracked-files=no')\n        status = subprocess.check_output(cmd, stderr=subprocess.DEVNULL)\n    except (subprocess.CalledProcessError, OSError, FileNotFoundError):\n        q.put(None)\n    if status is not None:\n        return q.put(bool(status))\n\n\ndef git_dirty_working_directory(include_untracked=False):\n    \"\"\"Returns whether or not the git directory is dirty. If this could not\n    be determined (timeout, file not found, etc.) then this returns None.\n    \"\"\"\n    timeout = builtins.__xonsh_env__.get(\"VC_BRANCH_TIMEOUT\")\n    q = queue.Queue()\n    t = threading.Thread(target=_git_dirty_working_directory,\n                         args=(q, include_untracked))\n    t.start()\n    t.join(timeout=timeout)\n    try:\n        return q.get_nowait()\n    except queue.Empty:\n        return None\n\n\ndef hg_dirty_working_directory():\n    \"\"\"Computes whether or not the mercurial working directory is dirty or not.\n    If this cannot be determined, None is returned.\n    \"\"\"\n    env = builtins.__xonsh_env__\n    cwd = env['PWD']\n    denv = env.detype()\n    vcbt = env['VC_BRANCH_TIMEOUT']\n    # Override user configurations settings and aliases\n    denv['HGRCPATH'] = ''\n    try:\n        s = subprocess.check_output(['hg', 'identify', '--id'],\n                                    stderr=subprocess.PIPE, cwd=cwd,\n                                    timeout=vcbt, universal_newlines=True,\n                                    env=denv)\n        return s.strip(os.linesep).endswith('+')\n    except (subprocess.CalledProcessError, subprocess.TimeoutExpired,\n            FileNotFoundError):\n        return None\n\n\ndef dirty_working_directory():\n    \"\"\"Returns a boolean as to whether there are uncommitted files in version\n    control repository we are inside. If this cannot be determined, returns\n    None. Currently supports git and hg.\n    \"\"\"\n    dwd = None\n    cmds = builtins.__xonsh_commands_cache__\n    if cmds.lazy_locate_binary('git'):\n        dwd = git_dirty_working_directory()\n    if cmds.lazy_locate_binary('hg') and dwd is None:\n        dwd = hg_dirty_working_directory()\n    return dwd\n\n\ndef branch_color():\n    \"\"\"Return red if the current branch is dirty, yellow if the dirtiness can\n    not be determined, and green if it clean. These are bold, intense colors\n    for the foreground.\n    \"\"\"\n    dwd = dirty_working_directory()\n    if dwd is None:\n        color = '{BOLD_INTENSE_YELLOW}'\n    elif dwd:\n        color = '{BOLD_INTENSE_RED}'\n    else:\n        color = '{BOLD_INTENSE_GREEN}'\n    return color\n\n\ndef branch_bg_color():\n    \"\"\"Return red if the current branch is dirty, yellow if the dirtiness can\n    not be determined, and green if it clean. These are bacground colors.\n    \"\"\"\n    dwd = dirty_working_directory()\n    if dwd is None:\n        color = '{BACKGROUND_YELLOW}'\n    elif dwd:\n        color = '{BACKGROUND_RED}'\n    else:\n        color = '{BACKGROUND_GREEN}'\n    return color\n", "path": "xonsh/prompt/vc.py"}]}