We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Automatically use Python 3 if available
As discussed during today's BoF, some people would like Spack to use Python 3 if available. Since we cannot depend on any version of Python being available on all systems, this needs a slightly complex approach: The spack binary is moved to spack-real and replaced by a shell script that checks for available versions of Python (preferring Python 3) and invokes spack-real accordingly.

This should also take care of the situation where no python binary is available (as will be on RHEL 8 by default).

Not sure if this is really the best way to go but I have been meaning to take a stab at this for a while now. (Only tested on Linux.)
@tgamblin @alalazo @becker33 @adamjstewart

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `lib/spack/spack/cmd/license.py`
Content:
```
1 # Copyright 2013-2019 Lawrence Livermore National Security, LLC and other
2 # Spack Project Developers. See the top-level COPYRIGHT file for details.
3 #
4 # SPDX-License-Identifier: (Apache-2.0 OR MIT)
5 
6 from __future__ import print_function
7 
8 import os
9 import re
10 from collections import defaultdict
11 
12 import llnl.util.tty as tty
13 
14 import spack.paths
15 from spack.util.executable import which
16 
17 description = 'list and check license headers on files in spack'
18 section = "developer"
19 level = "long"
20 
21 #: need the git command to check new files
22 git = which('git')
23 
24 #: SPDX license id must appear in the first <license_lines> lines of a file
25 license_lines = 6
26 
27 #: Spack's license identifier
28 apache2_mit_spdx = "(Apache-2.0 OR MIT)"
29 
30 #: regular expressions for licensed files.
31 licensed_files = [
32     # spack scripts
33     r'^bin/spack$',
34     r'^bin/spack-python$',
35     r'^bin/sbang$',
36 
37     # all of spack core
38     r'^lib/spack/spack/.*\.py$',
39     r'^lib/spack/spack/.*\.sh$',
40     r'^lib/spack/llnl/.*\.py$',
41     r'^lib/spack/env/cc$',
42 
43     # rst files in documentation
44     r'^lib/spack/docs/(?!command_index|spack|llnl).*\.rst$',
45     r'^lib/spack/docs/.*\.py$',
46 
47     # 2 files in external
48     r'^lib/spack/external/__init__.py$',
49     r'^lib/spack/external/ordereddict_backport.py$',
50 
51     # shell scripts in share
52     r'^share/spack/.*\.sh$',
53     r'^share/spack/.*\.bash$',
54     r'^share/spack/.*\.csh$',
55     r'^share/spack/qa/run-[^/]*$',
56 
57     # all packages
58     r'^var/spack/repos/.*/package.py$'
59 ]
60 
61 #: licensed files that can have LGPL language in them
62 #: so far, just this command -- so it can find LGPL things elsewhere
63 lgpl_exceptions = [
64     r'lib/spack/spack/cmd/license.py',
65     r'lib/spack/spack/test/cmd/license.py',
66 ]
67 
68 
69 def _all_spack_files(root=spack.paths.prefix):
70     """Generates root-relative paths of all files in the spack repository."""
71     visited = set()
72     for cur_root, folders, files in os.walk(root):
73         for filename in files:
74             path = os.path.realpath(os.path.join(cur_root, filename))
75 
76             if path not in visited:
77                 yield os.path.relpath(path, root)
78                 visited.add(path)
79 
80 
81 def _licensed_files(root=spack.paths.prefix):
82     for relpath in _all_spack_files(root):
83         if any(regex.match(relpath) for regex in licensed_files):
84             yield relpath
85 
86 
87 def list_files(args):
88     """list files in spack that should have license headers"""
89     for relpath in sorted(_licensed_files()):
90         print(os.path.join(spack.paths.spack_root, relpath))
91 
92 
93 # Error codes for license verification. All values are chosen such that
94 # bool(value) evaluates to True
95 OLD_LICENSE, SPDX_MISMATCH, GENERAL_MISMATCH = range(1, 4)
96 
97 
98 class LicenseError(object):
99     def __init__(self):
100         self.error_counts = defaultdict(int)
101 
102     def add_error(self, error):
103         self.error_counts[error] += 1
104 
105     def has_errors(self):
106         return sum(self.error_counts.values()) > 0
107 
108     def error_messages(self):
109         total = sum(self.error_counts.values())
110         missing = self.error_counts[GENERAL_MISMATCH]
111         spdx_mismatch = self.error_counts[SPDX_MISMATCH]
112         old_license = self.error_counts[OLD_LICENSE]
113         return (
114             '%d improperly licensed files' % (total),
115             'files with wrong SPDX-License-Identifier:   %d' % spdx_mismatch,
116             'files with old license header:              %d' % old_license,
117             'files not containing expected license:      %d' % missing)
118 
119 
120 def _check_license(lines, path):
121     license_lines = [
122         r'Copyright 2013-(?:201[789]|202\d) Lawrence Livermore National Security, LLC and other',  # noqa: E501
123         r'Spack Project Developers\. See the top-level COPYRIGHT file for details.',  # noqa: E501
124         r'SPDX-License-Identifier: \(Apache-2\.0 OR MIT\)'
125     ]
126 
127     strict_date = r'Copyright 2013-2019'
128 
129     found = []
130 
131     for line in lines:
132         line = re.sub(r'^[\s#\.]*', '', line)
133         line = line.rstrip()
134         for i, license_line in enumerate(license_lines):
135             if re.match(license_line, line):
136                 # The first line of the license contains the copyright date.
137                 # We allow it to be out of date but print a warning if it is
138                 # out of date.
139                 if i == 0:
140                     if not re.search(strict_date, line):
141                         tty.debug('{0}: copyright date mismatch'.format(path))
142                 found.append(i)
143 
144     if len(found) == len(license_lines) and found == list(sorted(found)):
145         return
146 
147     def old_license(line, path):
148         if re.search('This program is free software', line):
149             print('{0}: has old LGPL license header'.format(path))
150             return OLD_LICENSE
151 
152     # If the SPDX identifier is present, then there is a mismatch (since it
153     # did not match the above regex)
154     def wrong_spdx_identifier(line, path):
155         m = re.search(r'SPDX-License-Identifier: ([^\n]*)', line)
156         if m and m.group(1) != apache2_mit_spdx:
157             print('{0}: SPDX license identifier mismatch'
158                   '(expecting {1}, found {2})'
159                   .format(path, apache2_mit_spdx, m.group(1)))
160             return SPDX_MISMATCH
161 
162     checks = [old_license, wrong_spdx_identifier]
163 
164     for line in lines:
165         for check in checks:
166             error = check(line, path)
167             if error:
168                 return error
169 
170     print('{0}: the license does not match the expected format'.format(path))
171     return GENERAL_MISMATCH
172 
173 
174 def verify(args):
175     """verify that files in spack have the right license header"""
176 
177     license_errors = LicenseError()
178 
179     for relpath in _licensed_files(args.root):
180         path = os.path.join(args.root, relpath)
181         with open(path) as f:
182             lines = [line for line in f][:license_lines]
183 
184         error = _check_license(lines, path)
185         if error:
186             license_errors.add_error(error)
187 
188     if license_errors.has_errors():
189         tty.die(*license_errors.error_messages())
190     else:
191         tty.msg('No license issues found.')
192 
193 
194 def setup_parser(subparser):
195     sp = subparser.add_subparsers(metavar='SUBCOMMAND', dest='license_command')
196     sp.add_parser('list-files', help=list_files.__doc__)
197 
198     verify_parser = sp.add_parser('verify', help=verify.__doc__)
199     verify_parser.add_argument(
200         '--root', action='store', default=spack.paths.prefix,
201         help='scan a different prefix for license issues')
202 
203 
204 def license(parser, args):
205     if not git:
206         tty.die('spack license requires git in your environment')
207 
208     licensed_files[:] = [re.compile(regex) for regex in licensed_files]
209 
210     commands = {
211         'list-files': list_files,
212         'verify': verify,
213     }
214     return commands[args.license_command](args)
215
```
--- 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/lib/spack/spack/cmd/license.py b/lib/spack/spack/cmd/license.py
--- a/lib/spack/spack/cmd/license.py
+++ b/lib/spack/spack/cmd/license.py
@@ -22,7 +22,7 @@
 git = which('git')
 
 #: SPDX license id must appear in the first <license_lines> lines of a file
-license_lines = 6
+license_lines = 7
 
 #: Spack's license identifier
 apache2_mit_spdx = "(Apache-2.0 OR MIT)"

{"golden_diff": "diff --git a/lib/spack/spack/cmd/license.py b/lib/spack/spack/cmd/license.py\n--- a/lib/spack/spack/cmd/license.py\n+++ b/lib/spack/spack/cmd/license.py\n@@ -22,7 +22,7 @@\n git = which('git')\n \n #: SPDX license id must appear in the first <license_lines> lines of a file\n-license_lines = 6\n+license_lines = 7\n \n #: Spack's license identifier\n apache2_mit_spdx = \"(Apache-2.0 OR MIT)\"\n", "issue": "Automatically use Python 3 if available\nAs discussed during today's BoF, some people would like Spack to use Python 3 if available. Since we cannot depend on any version of Python being available on all systems, this needs a slightly complex approach: The spack binary is moved to spack-real and replaced by a shell script that checks for available versions of Python (preferring Python 3) and invokes spack-real accordingly.\r\n\r\nThis should also take care of the situation where no python binary is available (as will be on RHEL 8 by default).\r\n\r\nNot sure if this is really the best way to go but I have been meaning to take a stab at this for a while now. (Only tested on Linux.)\r\n@tgamblin @alalazo @becker33 @adamjstewart\n", "before_files": [{"content": "# Copyright 2013-2019 Lawrence Livermore National Security, LLC and other\n# Spack Project Developers. See the top-level COPYRIGHT file for details.\n#\n# SPDX-License-Identifier: (Apache-2.0 OR MIT)\n\nfrom __future__ import print_function\n\nimport os\nimport re\nfrom collections import defaultdict\n\nimport llnl.util.tty as tty\n\nimport spack.paths\nfrom spack.util.executable import which\n\ndescription = 'list and check license headers on files in spack'\nsection = \"developer\"\nlevel = \"long\"\n\n#: need the git command to check new files\ngit = which('git')\n\n#: SPDX license id must appear in the first <license_lines> lines of a file\nlicense_lines = 6\n\n#: Spack's license identifier\napache2_mit_spdx = \"(Apache-2.0 OR MIT)\"\n\n#: regular expressions for licensed files.\nlicensed_files = [\n    # spack scripts\n    r'^bin/spack$',\n    r'^bin/spack-python$',\n    r'^bin/sbang$',\n\n    # all of spack core\n    r'^lib/spack/spack/.*\\.py$',\n    r'^lib/spack/spack/.*\\.sh$',\n    r'^lib/spack/llnl/.*\\.py$',\n    r'^lib/spack/env/cc$',\n\n    # rst files in documentation\n    r'^lib/spack/docs/(?!command_index|spack|llnl).*\\.rst$',\n    r'^lib/spack/docs/.*\\.py$',\n\n    # 2 files in external\n    r'^lib/spack/external/__init__.py$',\n    r'^lib/spack/external/ordereddict_backport.py$',\n\n    # shell scripts in share\n    r'^share/spack/.*\\.sh$',\n    r'^share/spack/.*\\.bash$',\n    r'^share/spack/.*\\.csh$',\n    r'^share/spack/qa/run-[^/]*$',\n\n    # all packages\n    r'^var/spack/repos/.*/package.py$'\n]\n\n#: licensed files that can have LGPL language in them\n#: so far, just this command -- so it can find LGPL things elsewhere\nlgpl_exceptions = [\n    r'lib/spack/spack/cmd/license.py',\n    r'lib/spack/spack/test/cmd/license.py',\n]\n\n\ndef _all_spack_files(root=spack.paths.prefix):\n    \"\"\"Generates root-relative paths of all files in the spack repository.\"\"\"\n    visited = set()\n    for cur_root, folders, files in os.walk(root):\n        for filename in files:\n            path = os.path.realpath(os.path.join(cur_root, filename))\n\n            if path not in visited:\n                yield os.path.relpath(path, root)\n                visited.add(path)\n\n\ndef _licensed_files(root=spack.paths.prefix):\n    for relpath in _all_spack_files(root):\n        if any(regex.match(relpath) for regex in licensed_files):\n            yield relpath\n\n\ndef list_files(args):\n    \"\"\"list files in spack that should have license headers\"\"\"\n    for relpath in sorted(_licensed_files()):\n        print(os.path.join(spack.paths.spack_root, relpath))\n\n\n# Error codes for license verification. All values are chosen such that\n# bool(value) evaluates to True\nOLD_LICENSE, SPDX_MISMATCH, GENERAL_MISMATCH = range(1, 4)\n\n\nclass LicenseError(object):\n    def __init__(self):\n        self.error_counts = defaultdict(int)\n\n    def add_error(self, error):\n        self.error_counts[error] += 1\n\n    def has_errors(self):\n        return sum(self.error_counts.values()) > 0\n\n    def error_messages(self):\n        total = sum(self.error_counts.values())\n        missing = self.error_counts[GENERAL_MISMATCH]\n        spdx_mismatch = self.error_counts[SPDX_MISMATCH]\n        old_license = self.error_counts[OLD_LICENSE]\n        return (\n            '%d improperly licensed files' % (total),\n            'files with wrong SPDX-License-Identifier:   %d' % spdx_mismatch,\n            'files with old license header:              %d' % old_license,\n            'files not containing expected license:      %d' % missing)\n\n\ndef _check_license(lines, path):\n    license_lines = [\n        r'Copyright 2013-(?:201[789]|202\\d) Lawrence Livermore National Security, LLC and other',  # noqa: E501\n        r'Spack Project Developers\\. See the top-level COPYRIGHT file for details.',  # noqa: E501\n        r'SPDX-License-Identifier: \\(Apache-2\\.0 OR MIT\\)'\n    ]\n\n    strict_date = r'Copyright 2013-2019'\n\n    found = []\n\n    for line in lines:\n        line = re.sub(r'^[\\s#\\.]*', '', line)\n        line = line.rstrip()\n        for i, license_line in enumerate(license_lines):\n            if re.match(license_line, line):\n                # The first line of the license contains the copyright date.\n                # We allow it to be out of date but print a warning if it is\n                # out of date.\n                if i == 0:\n                    if not re.search(strict_date, line):\n                        tty.debug('{0}: copyright date mismatch'.format(path))\n                found.append(i)\n\n    if len(found) == len(license_lines) and found == list(sorted(found)):\n        return\n\n    def old_license(line, path):\n        if re.search('This program is free software', line):\n            print('{0}: has old LGPL license header'.format(path))\n            return OLD_LICENSE\n\n    # If the SPDX identifier is present, then there is a mismatch (since it\n    # did not match the above regex)\n    def wrong_spdx_identifier(line, path):\n        m = re.search(r'SPDX-License-Identifier: ([^\\n]*)', line)\n        if m and m.group(1) != apache2_mit_spdx:\n            print('{0}: SPDX license identifier mismatch'\n                  '(expecting {1}, found {2})'\n                  .format(path, apache2_mit_spdx, m.group(1)))\n            return SPDX_MISMATCH\n\n    checks = [old_license, wrong_spdx_identifier]\n\n    for line in lines:\n        for check in checks:\n            error = check(line, path)\n            if error:\n                return error\n\n    print('{0}: the license does not match the expected format'.format(path))\n    return GENERAL_MISMATCH\n\n\ndef verify(args):\n    \"\"\"verify that files in spack have the right license header\"\"\"\n\n    license_errors = LicenseError()\n\n    for relpath in _licensed_files(args.root):\n        path = os.path.join(args.root, relpath)\n        with open(path) as f:\n            lines = [line for line in f][:license_lines]\n\n        error = _check_license(lines, path)\n        if error:\n            license_errors.add_error(error)\n\n    if license_errors.has_errors():\n        tty.die(*license_errors.error_messages())\n    else:\n        tty.msg('No license issues found.')\n\n\ndef setup_parser(subparser):\n    sp = subparser.add_subparsers(metavar='SUBCOMMAND', dest='license_command')\n    sp.add_parser('list-files', help=list_files.__doc__)\n\n    verify_parser = sp.add_parser('verify', help=verify.__doc__)\n    verify_parser.add_argument(\n        '--root', action='store', default=spack.paths.prefix,\n        help='scan a different prefix for license issues')\n\n\ndef license(parser, args):\n    if not git:\n        tty.die('spack license requires git in your environment')\n\n    licensed_files[:] = [re.compile(regex) for regex in licensed_files]\n\n    commands = {\n        'list-files': list_files,\n        'verify': verify,\n    }\n    return commands[args.license_command](args)\n", "path": "lib/spack/spack/cmd/license.py"}], "after_files": [{"content": "# Copyright 2013-2019 Lawrence Livermore National Security, LLC and other\n# Spack Project Developers. See the top-level COPYRIGHT file for details.\n#\n# SPDX-License-Identifier: (Apache-2.0 OR MIT)\n\nfrom __future__ import print_function\n\nimport os\nimport re\nfrom collections import defaultdict\n\nimport llnl.util.tty as tty\n\nimport spack.paths\nfrom spack.util.executable import which\n\ndescription = 'list and check license headers on files in spack'\nsection = \"developer\"\nlevel = \"long\"\n\n#: need the git command to check new files\ngit = which('git')\n\n#: SPDX license id must appear in the first <license_lines> lines of a file\nlicense_lines = 7\n\n#: Spack's license identifier\napache2_mit_spdx = \"(Apache-2.0 OR MIT)\"\n\n#: regular expressions for licensed files.\nlicensed_files = [\n    # spack scripts\n    r'^bin/spack$',\n    r'^bin/spack-python$',\n    r'^bin/sbang$',\n\n    # all of spack core\n    r'^lib/spack/spack/.*\\.py$',\n    r'^lib/spack/spack/.*\\.sh$',\n    r'^lib/spack/llnl/.*\\.py$',\n    r'^lib/spack/env/cc$',\n\n    # rst files in documentation\n    r'^lib/spack/docs/(?!command_index|spack|llnl).*\\.rst$',\n    r'^lib/spack/docs/.*\\.py$',\n\n    # 2 files in external\n    r'^lib/spack/external/__init__.py$',\n    r'^lib/spack/external/ordereddict_backport.py$',\n\n    # shell scripts in share\n    r'^share/spack/.*\\.sh$',\n    r'^share/spack/.*\\.bash$',\n    r'^share/spack/.*\\.csh$',\n    r'^share/spack/qa/run-[^/]*$',\n\n    # all packages\n    r'^var/spack/repos/.*/package.py$'\n]\n\n#: licensed files that can have LGPL language in them\n#: so far, just this command -- so it can find LGPL things elsewhere\nlgpl_exceptions = [\n    r'lib/spack/spack/cmd/license.py',\n    r'lib/spack/spack/test/cmd/license.py',\n]\n\n\ndef _all_spack_files(root=spack.paths.prefix):\n    \"\"\"Generates root-relative paths of all files in the spack repository.\"\"\"\n    visited = set()\n    for cur_root, folders, files in os.walk(root):\n        for filename in files:\n            path = os.path.realpath(os.path.join(cur_root, filename))\n\n            if path not in visited:\n                yield os.path.relpath(path, root)\n                visited.add(path)\n\n\ndef _licensed_files(root=spack.paths.prefix):\n    for relpath in _all_spack_files(root):\n        if any(regex.match(relpath) for regex in licensed_files):\n            yield relpath\n\n\ndef list_files(args):\n    \"\"\"list files in spack that should have license headers\"\"\"\n    for relpath in sorted(_licensed_files()):\n        print(os.path.join(spack.paths.spack_root, relpath))\n\n\n# Error codes for license verification. All values are chosen such that\n# bool(value) evaluates to True\nOLD_LICENSE, SPDX_MISMATCH, GENERAL_MISMATCH = range(1, 4)\n\n\nclass LicenseError(object):\n    def __init__(self):\n        self.error_counts = defaultdict(int)\n\n    def add_error(self, error):\n        self.error_counts[error] += 1\n\n    def has_errors(self):\n        return sum(self.error_counts.values()) > 0\n\n    def error_messages(self):\n        total = sum(self.error_counts.values())\n        missing = self.error_counts[GENERAL_MISMATCH]\n        spdx_mismatch = self.error_counts[SPDX_MISMATCH]\n        old_license = self.error_counts[OLD_LICENSE]\n        return (\n            '%d improperly licensed files' % (total),\n            'files with wrong SPDX-License-Identifier:   %d' % spdx_mismatch,\n            'files with old license header:              %d' % old_license,\n            'files not containing expected license:      %d' % missing)\n\n\ndef _check_license(lines, path):\n    license_lines = [\n        r'Copyright 2013-(?:201[789]|202\\d) Lawrence Livermore National Security, LLC and other',  # noqa: E501\n        r'Spack Project Developers\\. See the top-level COPYRIGHT file for details.',  # noqa: E501\n        r'SPDX-License-Identifier: \\(Apache-2\\.0 OR MIT\\)'\n    ]\n\n    strict_date = r'Copyright 2013-2019'\n\n    found = []\n\n    for line in lines:\n        line = re.sub(r'^[\\s#\\.]*', '', line)\n        line = line.rstrip()\n        for i, license_line in enumerate(license_lines):\n            if re.match(license_line, line):\n                # The first line of the license contains the copyright date.\n                # We allow it to be out of date but print a warning if it is\n                # out of date.\n                if i == 0:\n                    if not re.search(strict_date, line):\n                        tty.debug('{0}: copyright date mismatch'.format(path))\n                found.append(i)\n\n    if len(found) == len(license_lines) and found == list(sorted(found)):\n        return\n\n    def old_license(line, path):\n        if re.search('This program is free software', line):\n            print('{0}: has old LGPL license header'.format(path))\n            return OLD_LICENSE\n\n    # If the SPDX identifier is present, then there is a mismatch (since it\n    # did not match the above regex)\n    def wrong_spdx_identifier(line, path):\n        m = re.search(r'SPDX-License-Identifier: ([^\\n]*)', line)\n        if m and m.group(1) != apache2_mit_spdx:\n            print('{0}: SPDX license identifier mismatch'\n                  '(expecting {1}, found {2})'\n                  .format(path, apache2_mit_spdx, m.group(1)))\n            return SPDX_MISMATCH\n\n    checks = [old_license, wrong_spdx_identifier]\n\n    for line in lines:\n        for check in checks:\n            error = check(line, path)\n            if error:\n                return error\n\n    print('{0}: the license does not match the expected format'.format(path))\n    return GENERAL_MISMATCH\n\n\ndef verify(args):\n    \"\"\"verify that files in spack have the right license header\"\"\"\n\n    license_errors = LicenseError()\n\n    for relpath in _licensed_files(args.root):\n        path = os.path.join(args.root, relpath)\n        with open(path) as f:\n            lines = [line for line in f][:license_lines]\n\n        error = _check_license(lines, path)\n        if error:\n            license_errors.add_error(error)\n\n    if license_errors.has_errors():\n        tty.die(*license_errors.error_messages())\n    else:\n        tty.msg('No license issues found.')\n\n\ndef setup_parser(subparser):\n    sp = subparser.add_subparsers(metavar='SUBCOMMAND', dest='license_command')\n    sp.add_parser('list-files', help=list_files.__doc__)\n\n    verify_parser = sp.add_parser('verify', help=verify.__doc__)\n    verify_parser.add_argument(\n        '--root', action='store', default=spack.paths.prefix,\n        help='scan a different prefix for license issues')\n\n\ndef license(parser, args):\n    if not git:\n        tty.die('spack license requires git in your environment')\n\n    licensed_files[:] = [re.compile(regex) for regex in licensed_files]\n\n    commands = {\n        'list-files': list_files,\n        'verify': verify,\n    }\n    return commands[args.license_command](args)\n", "path": "lib/spack/spack/cmd/license.py"}]}