We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
"Running tests with cocotb ... from Unknown"
In e.g. https://asciinema.org/a/316949, we can see the line
```
0.00ns INFO  cocotb  __init__.py:144  in _initialise_testbench  Running tests with cocotb v1.4.0.dev0 from Unknown
```

@themperek suggested using ``__file__`` in https://github.com/cocotb/cocotb/blob/09effc69f914820d4aa50217b9fad6ba29c4248f/cocotb/__init__.py#L139-L144 instead of ``export``ing ``COCOTB_PY_DIR`` in https://github.com/cocotb/cocotb/blob/67bf79b997b630416b1f98742fbeab09d9e90fef/cocotb/share/makefiles/Makefile.inc#L33

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `cocotb/__init__.py`
Content:
```
1 # Copyright (c) 2013 Potential Ventures Ltd
2 # Copyright (c) 2013 SolarFlare Communications Inc
3 # All rights reserved.
4 
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are met:
7 #     * Redistributions of source code must retain the above copyright
8 #       notice, this list of conditions and the following disclaimer.
9 #     * Redistributions in binary form must reproduce the above copyright
10 #       notice, this list of conditions and the following disclaimer in the
11 #       documentation and/or other materials provided with the distribution.
12 #     * Neither the name of Potential Ventures Ltd,
13 #       SolarFlare Communications Inc nor the
14 #       names of its contributors may be used to endorse or promote products
15 #       derived from this software without specific prior written permission.
16 
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 # DISCLAIMED. IN NO EVENT SHALL POTENTIAL VENTURES LTD BE LIABLE FOR ANY
21 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 """
29 Cocotb is a coroutine, cosimulation framework for writing testbenches in Python.
30 
31 See http://cocotb.readthedocs.org for full documentation
32 """
33 import os
34 import sys
35 import logging
36 import threading
37 import random
38 import time
39 import warnings
40 
41 import cocotb.handle
42 import cocotb.log
43 from cocotb.scheduler import Scheduler
44 from cocotb.regression import RegressionManager
45 
46 
47 # Things we want in the cocotb namespace
48 from cocotb.decorators import test, coroutine, hook, function, external  # noqa: F401
49 
50 # Singleton scheduler instance
51 # NB this cheekily ensures a singleton since we're replacing the reference
52 # so that cocotb.scheduler gives you the singleton instance and not the
53 # scheduler package
54 
55 from ._version import __version__
56 
57 # GPI logging instance
58 if "COCOTB_SIM" in os.environ:
59 
60     def _reopen_stream_with_buffering(stream_name):
61         try:
62             if not getattr(sys, stream_name).isatty():
63                 setattr(sys, stream_name, os.fdopen(getattr(sys, stream_name).fileno(), 'w', 1))
64                 return True
65             return False
66         except Exception as e:
67             return e
68 
69     # If stdout/stderr are not TTYs, Python may not have opened them with line
70     # buffering. In that case, try to reopen them with line buffering
71     # explicitly enabled. This ensures that prints such as stack traces always
72     # appear. Continue silently if this fails.
73     _stdout_buffer_result = _reopen_stream_with_buffering('stdout')
74     _stderr_buffer_result = _reopen_stream_with_buffering('stderr')
75 
76     # Don't set the logging up until we've attempted to fix the standard IO,
77     # otherwise it will end up connected to the unfixed IO.
78     cocotb.log.default_config()
79     log = logging.getLogger(__name__)
80 
81     # we can't log these things until the logging is set up!
82     if _stderr_buffer_result is True:
83         log.debug("Reopened stderr with line buffering")
84     if _stdout_buffer_result is True:
85         log.debug("Reopened stdout with line buffering")
86     if isinstance(_stdout_buffer_result, Exception) or isinstance(_stderr_buffer_result, Exception):
87         if isinstance(_stdout_buffer_result, Exception):
88             log.warning("Failed to ensure that stdout is line buffered", exc_info=_stdout_buffer_result)
89         if isinstance(_stderr_buffer_result, Exception):
90             log.warning("Failed to ensure that stderr is line buffered", exc_info=_stderr_buffer_result)
91         log.warning("Some stack traces may not appear because of this.")
92 
93     del _stderr_buffer_result, _stdout_buffer_result
94 
95     # From https://www.python.org/dev/peps/pep-0565/#recommended-filter-settings-for-test-runners
96     # If the user doesn't want to see these, they can always change the global
97     # warning settings in their test module.
98     if not sys.warnoptions:
99         warnings.simplefilter("default")
100 
101 scheduler = Scheduler()
102 """The global scheduler instance."""
103 
104 regression_manager = None
105 
106 plusargs = {}
107 """A dictionary of "plusargs" handed to the simulation."""
108 
109 # To save typing provide an alias to scheduler.add
110 fork = scheduler.add
111 
112 # FIXME is this really required?
113 _rlock = threading.RLock()
114 
115 
116 def mem_debug(port):
117     import cocotb.memdebug
118     cocotb.memdebug.start(port)
119 
120 
121 def _initialise_testbench(root_name):
122     """Initialize testbench.
123 
124     This function is called after the simulator has elaborated all
125     entities and is ready to run the test.
126 
127     The test must be defined by the environment variables
128     :envvar:`MODULE` and :envvar:`TESTCASE`.
129 
130     The environment variable :envvar:`COCOTB_HOOKS`, if present, contains a
131     comma-separated list of modules to be executed before the first test.
132     """
133     _rlock.acquire()
134 
135     memcheck_port = os.getenv('MEMCHECK')
136     if memcheck_port is not None:
137         mem_debug(int(memcheck_port))
138 
139     exec_path = os.getenv('COCOTB_PY_DIR')
140     if exec_path is None:
141         exec_path = 'Unknown'
142 
143     log.info("Running tests with cocotb v%s from %s" %
144              (__version__, exec_path))
145 
146     # Create the base handle type
147 
148     process_plusargs()
149 
150     # Seed the Python random number generator to make this repeatable
151     global RANDOM_SEED
152     RANDOM_SEED = os.getenv('RANDOM_SEED')
153 
154     if RANDOM_SEED is None:
155         if 'ntb_random_seed' in plusargs:
156             RANDOM_SEED = eval(plusargs['ntb_random_seed'])
157         elif 'seed' in plusargs:
158             RANDOM_SEED = eval(plusargs['seed'])
159         else:
160             RANDOM_SEED = int(time.time())
161         log.info("Seeding Python random module with %d" % (RANDOM_SEED))
162     else:
163         RANDOM_SEED = int(RANDOM_SEED)
164         log.info("Seeding Python random module with supplied seed %d" % (RANDOM_SEED))
165     random.seed(RANDOM_SEED)
166 
167     module_str = os.getenv('MODULE')
168     test_str = os.getenv('TESTCASE')
169     hooks_str = os.getenv('COCOTB_HOOKS', '')
170 
171     if not module_str:
172         raise ImportError("Environment variables defining the module(s) to " +
173                           "execute not defined.  MODULE=\"%s\"" % (module_str))
174 
175     modules = module_str.split(',')
176     hooks = hooks_str.split(',') if hooks_str else []
177 
178     global regression_manager
179 
180     regression_manager = RegressionManager(root_name, modules, tests=test_str, seed=RANDOM_SEED, hooks=hooks)
181     regression_manager.initialise()
182     regression_manager.execute()
183 
184     _rlock.release()
185     return True
186 
187 
188 def _sim_event(level, message):
189     """Function that can be called externally to signal an event."""
190     SIM_INFO = 0
191     SIM_TEST_FAIL = 1
192     SIM_FAIL = 2
193     from cocotb.result import TestFailure, SimFailure
194 
195     if level is SIM_TEST_FAIL:
196         scheduler.log.error("Failing test at simulator request")
197         scheduler.finish_test(TestFailure("Failure from external source: %s" %
198                               message))
199     elif level is SIM_FAIL:
200         # We simply return here as the simulator will exit
201         # so no cleanup is needed
202         msg = ("Failing test at simulator request before test run completion: "
203                "%s" % message)
204         scheduler.log.error(msg)
205         scheduler.finish_scheduler(SimFailure(msg))
206     else:
207         scheduler.log.error("Unsupported sim event")
208 
209     return True
210 
211 
212 def process_plusargs():
213 
214     global plusargs
215 
216     plusargs = {}
217 
218     for option in cocotb.argv:
219         if option.startswith('+'):
220             if option.find('=') != -1:
221                 (name, value) = option[1:].split('=')
222                 plusargs[name] = value
223             else:
224                 plusargs[option[1:]] = True
225
```
--- 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/cocotb/__init__.py b/cocotb/__init__.py
--- a/cocotb/__init__.py
+++ b/cocotb/__init__.py
@@ -136,12 +136,8 @@
     if memcheck_port is not None:
         mem_debug(int(memcheck_port))
 
-    exec_path = os.getenv('COCOTB_PY_DIR')
-    if exec_path is None:
-        exec_path = 'Unknown'
-
     log.info("Running tests with cocotb v%s from %s" %
-             (__version__, exec_path))
+             (__version__, os.path.dirname(__file__)))
 
     # Create the base handle type

{"golden_diff": "diff --git a/cocotb/__init__.py b/cocotb/__init__.py\n--- a/cocotb/__init__.py\n+++ b/cocotb/__init__.py\n@@ -136,12 +136,8 @@\n     if memcheck_port is not None:\n         mem_debug(int(memcheck_port))\n \n-    exec_path = os.getenv('COCOTB_PY_DIR')\n-    if exec_path is None:\n-        exec_path = 'Unknown'\n-\n     log.info(\"Running tests with cocotb v%s from %s\" %\n-             (__version__, exec_path))\n+             (__version__, os.path.dirname(__file__)))\n \n     # Create the base handle type\n", "issue": "\"Running tests with cocotb ... from Unknown\"\nIn e.g. https://asciinema.org/a/316949, we can see the line\r\n```\r\n0.00ns INFO  cocotb  __init__.py:144  in _initialise_testbench  Running tests with cocotb v1.4.0.dev0 from Unknown\r\n```\r\n\r\n@themperek suggested using ``__file__`` in https://github.com/cocotb/cocotb/blob/09effc69f914820d4aa50217b9fad6ba29c4248f/cocotb/__init__.py#L139-L144 instead of ``export``ing ``COCOTB_PY_DIR`` in https://github.com/cocotb/cocotb/blob/67bf79b997b630416b1f98742fbeab09d9e90fef/cocotb/share/makefiles/Makefile.inc#L33\n", "before_files": [{"content": "# Copyright (c) 2013 Potential Ventures Ltd\n# Copyright (c) 2013 SolarFlare Communications Inc\n# All rights reserved.\n\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions are met:\n#     * Redistributions of source code must retain the above copyright\n#       notice, this list of conditions and the following disclaimer.\n#     * Redistributions in binary form must reproduce the above copyright\n#       notice, this list of conditions and the following disclaimer in the\n#       documentation and/or other materials provided with the distribution.\n#     * Neither the name of Potential Ventures Ltd,\n#       SolarFlare Communications Inc nor the\n#       names of its contributors may be used to endorse or promote products\n#       derived from this software without specific prior written permission.\n\n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n# DISCLAIMED. IN NO EVENT SHALL POTENTIAL VENTURES LTD BE LIABLE FOR ANY\n# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n\"\"\"\nCocotb is a coroutine, cosimulation framework for writing testbenches in Python.\n\nSee http://cocotb.readthedocs.org for full documentation\n\"\"\"\nimport os\nimport sys\nimport logging\nimport threading\nimport random\nimport time\nimport warnings\n\nimport cocotb.handle\nimport cocotb.log\nfrom cocotb.scheduler import Scheduler\nfrom cocotb.regression import RegressionManager\n\n\n# Things we want in the cocotb namespace\nfrom cocotb.decorators import test, coroutine, hook, function, external  # noqa: F401\n\n# Singleton scheduler instance\n# NB this cheekily ensures a singleton since we're replacing the reference\n# so that cocotb.scheduler gives you the singleton instance and not the\n# scheduler package\n\nfrom ._version import __version__\n\n# GPI logging instance\nif \"COCOTB_SIM\" in os.environ:\n\n    def _reopen_stream_with_buffering(stream_name):\n        try:\n            if not getattr(sys, stream_name).isatty():\n                setattr(sys, stream_name, os.fdopen(getattr(sys, stream_name).fileno(), 'w', 1))\n                return True\n            return False\n        except Exception as e:\n            return e\n\n    # If stdout/stderr are not TTYs, Python may not have opened them with line\n    # buffering. In that case, try to reopen them with line buffering\n    # explicitly enabled. This ensures that prints such as stack traces always\n    # appear. Continue silently if this fails.\n    _stdout_buffer_result = _reopen_stream_with_buffering('stdout')\n    _stderr_buffer_result = _reopen_stream_with_buffering('stderr')\n\n    # Don't set the logging up until we've attempted to fix the standard IO,\n    # otherwise it will end up connected to the unfixed IO.\n    cocotb.log.default_config()\n    log = logging.getLogger(__name__)\n\n    # we can't log these things until the logging is set up!\n    if _stderr_buffer_result is True:\n        log.debug(\"Reopened stderr with line buffering\")\n    if _stdout_buffer_result is True:\n        log.debug(\"Reopened stdout with line buffering\")\n    if isinstance(_stdout_buffer_result, Exception) or isinstance(_stderr_buffer_result, Exception):\n        if isinstance(_stdout_buffer_result, Exception):\n            log.warning(\"Failed to ensure that stdout is line buffered\", exc_info=_stdout_buffer_result)\n        if isinstance(_stderr_buffer_result, Exception):\n            log.warning(\"Failed to ensure that stderr is line buffered\", exc_info=_stderr_buffer_result)\n        log.warning(\"Some stack traces may not appear because of this.\")\n\n    del _stderr_buffer_result, _stdout_buffer_result\n\n    # From https://www.python.org/dev/peps/pep-0565/#recommended-filter-settings-for-test-runners\n    # If the user doesn't want to see these, they can always change the global\n    # warning settings in their test module.\n    if not sys.warnoptions:\n        warnings.simplefilter(\"default\")\n\nscheduler = Scheduler()\n\"\"\"The global scheduler instance.\"\"\"\n\nregression_manager = None\n\nplusargs = {}\n\"\"\"A dictionary of \"plusargs\" handed to the simulation.\"\"\"\n\n# To save typing provide an alias to scheduler.add\nfork = scheduler.add\n\n# FIXME is this really required?\n_rlock = threading.RLock()\n\n\ndef mem_debug(port):\n    import cocotb.memdebug\n    cocotb.memdebug.start(port)\n\n\ndef _initialise_testbench(root_name):\n    \"\"\"Initialize testbench.\n\n    This function is called after the simulator has elaborated all\n    entities and is ready to run the test.\n\n    The test must be defined by the environment variables\n    :envvar:`MODULE` and :envvar:`TESTCASE`.\n\n    The environment variable :envvar:`COCOTB_HOOKS`, if present, contains a\n    comma-separated list of modules to be executed before the first test.\n    \"\"\"\n    _rlock.acquire()\n\n    memcheck_port = os.getenv('MEMCHECK')\n    if memcheck_port is not None:\n        mem_debug(int(memcheck_port))\n\n    exec_path = os.getenv('COCOTB_PY_DIR')\n    if exec_path is None:\n        exec_path = 'Unknown'\n\n    log.info(\"Running tests with cocotb v%s from %s\" %\n             (__version__, exec_path))\n\n    # Create the base handle type\n\n    process_plusargs()\n\n    # Seed the Python random number generator to make this repeatable\n    global RANDOM_SEED\n    RANDOM_SEED = os.getenv('RANDOM_SEED')\n\n    if RANDOM_SEED is None:\n        if 'ntb_random_seed' in plusargs:\n            RANDOM_SEED = eval(plusargs['ntb_random_seed'])\n        elif 'seed' in plusargs:\n            RANDOM_SEED = eval(plusargs['seed'])\n        else:\n            RANDOM_SEED = int(time.time())\n        log.info(\"Seeding Python random module with %d\" % (RANDOM_SEED))\n    else:\n        RANDOM_SEED = int(RANDOM_SEED)\n        log.info(\"Seeding Python random module with supplied seed %d\" % (RANDOM_SEED))\n    random.seed(RANDOM_SEED)\n\n    module_str = os.getenv('MODULE')\n    test_str = os.getenv('TESTCASE')\n    hooks_str = os.getenv('COCOTB_HOOKS', '')\n\n    if not module_str:\n        raise ImportError(\"Environment variables defining the module(s) to \" +\n                          \"execute not defined.  MODULE=\\\"%s\\\"\" % (module_str))\n\n    modules = module_str.split(',')\n    hooks = hooks_str.split(',') if hooks_str else []\n\n    global regression_manager\n\n    regression_manager = RegressionManager(root_name, modules, tests=test_str, seed=RANDOM_SEED, hooks=hooks)\n    regression_manager.initialise()\n    regression_manager.execute()\n\n    _rlock.release()\n    return True\n\n\ndef _sim_event(level, message):\n    \"\"\"Function that can be called externally to signal an event.\"\"\"\n    SIM_INFO = 0\n    SIM_TEST_FAIL = 1\n    SIM_FAIL = 2\n    from cocotb.result import TestFailure, SimFailure\n\n    if level is SIM_TEST_FAIL:\n        scheduler.log.error(\"Failing test at simulator request\")\n        scheduler.finish_test(TestFailure(\"Failure from external source: %s\" %\n                              message))\n    elif level is SIM_FAIL:\n        # We simply return here as the simulator will exit\n        # so no cleanup is needed\n        msg = (\"Failing test at simulator request before test run completion: \"\n               \"%s\" % message)\n        scheduler.log.error(msg)\n        scheduler.finish_scheduler(SimFailure(msg))\n    else:\n        scheduler.log.error(\"Unsupported sim event\")\n\n    return True\n\n\ndef process_plusargs():\n\n    global plusargs\n\n    plusargs = {}\n\n    for option in cocotb.argv:\n        if option.startswith('+'):\n            if option.find('=') != -1:\n                (name, value) = option[1:].split('=')\n                plusargs[name] = value\n            else:\n                plusargs[option[1:]] = True\n", "path": "cocotb/__init__.py"}], "after_files": [{"content": "# Copyright (c) 2013 Potential Ventures Ltd\n# Copyright (c) 2013 SolarFlare Communications Inc\n# All rights reserved.\n\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions are met:\n#     * Redistributions of source code must retain the above copyright\n#       notice, this list of conditions and the following disclaimer.\n#     * Redistributions in binary form must reproduce the above copyright\n#       notice, this list of conditions and the following disclaimer in the\n#       documentation and/or other materials provided with the distribution.\n#     * Neither the name of Potential Ventures Ltd,\n#       SolarFlare Communications Inc nor the\n#       names of its contributors may be used to endorse or promote products\n#       derived from this software without specific prior written permission.\n\n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n# DISCLAIMED. IN NO EVENT SHALL POTENTIAL VENTURES LTD BE LIABLE FOR ANY\n# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n\"\"\"\nCocotb is a coroutine, cosimulation framework for writing testbenches in Python.\n\nSee http://cocotb.readthedocs.org for full documentation\n\"\"\"\nimport os\nimport sys\nimport logging\nimport threading\nimport random\nimport time\nimport warnings\n\nimport cocotb.handle\nimport cocotb.log\nfrom cocotb.scheduler import Scheduler\nfrom cocotb.regression import RegressionManager\n\n\n# Things we want in the cocotb namespace\nfrom cocotb.decorators import test, coroutine, hook, function, external  # noqa: F401\n\n# Singleton scheduler instance\n# NB this cheekily ensures a singleton since we're replacing the reference\n# so that cocotb.scheduler gives you the singleton instance and not the\n# scheduler package\n\nfrom ._version import __version__\n\n# GPI logging instance\nif \"COCOTB_SIM\" in os.environ:\n\n    def _reopen_stream_with_buffering(stream_name):\n        try:\n            if not getattr(sys, stream_name).isatty():\n                setattr(sys, stream_name, os.fdopen(getattr(sys, stream_name).fileno(), 'w', 1))\n                return True\n            return False\n        except Exception as e:\n            return e\n\n    # If stdout/stderr are not TTYs, Python may not have opened them with line\n    # buffering. In that case, try to reopen them with line buffering\n    # explicitly enabled. This ensures that prints such as stack traces always\n    # appear. Continue silently if this fails.\n    _stdout_buffer_result = _reopen_stream_with_buffering('stdout')\n    _stderr_buffer_result = _reopen_stream_with_buffering('stderr')\n\n    # Don't set the logging up until we've attempted to fix the standard IO,\n    # otherwise it will end up connected to the unfixed IO.\n    cocotb.log.default_config()\n    log = logging.getLogger(__name__)\n\n    # we can't log these things until the logging is set up!\n    if _stderr_buffer_result is True:\n        log.debug(\"Reopened stderr with line buffering\")\n    if _stdout_buffer_result is True:\n        log.debug(\"Reopened stdout with line buffering\")\n    if isinstance(_stdout_buffer_result, Exception) or isinstance(_stderr_buffer_result, Exception):\n        if isinstance(_stdout_buffer_result, Exception):\n            log.warning(\"Failed to ensure that stdout is line buffered\", exc_info=_stdout_buffer_result)\n        if isinstance(_stderr_buffer_result, Exception):\n            log.warning(\"Failed to ensure that stderr is line buffered\", exc_info=_stderr_buffer_result)\n        log.warning(\"Some stack traces may not appear because of this.\")\n\n    del _stderr_buffer_result, _stdout_buffer_result\n\n    # From https://www.python.org/dev/peps/pep-0565/#recommended-filter-settings-for-test-runners\n    # If the user doesn't want to see these, they can always change the global\n    # warning settings in their test module.\n    if not sys.warnoptions:\n        warnings.simplefilter(\"default\")\n\nscheduler = Scheduler()\n\"\"\"The global scheduler instance.\"\"\"\n\nregression_manager = None\n\nplusargs = {}\n\"\"\"A dictionary of \"plusargs\" handed to the simulation.\"\"\"\n\n# To save typing provide an alias to scheduler.add\nfork = scheduler.add\n\n# FIXME is this really required?\n_rlock = threading.RLock()\n\n\ndef mem_debug(port):\n    import cocotb.memdebug\n    cocotb.memdebug.start(port)\n\n\ndef _initialise_testbench(root_name):\n    \"\"\"Initialize testbench.\n\n    This function is called after the simulator has elaborated all\n    entities and is ready to run the test.\n\n    The test must be defined by the environment variables\n    :envvar:`MODULE` and :envvar:`TESTCASE`.\n\n    The environment variable :envvar:`COCOTB_HOOKS`, if present, contains a\n    comma-separated list of modules to be executed before the first test.\n    \"\"\"\n    _rlock.acquire()\n\n    memcheck_port = os.getenv('MEMCHECK')\n    if memcheck_port is not None:\n        mem_debug(int(memcheck_port))\n\n    log.info(\"Running tests with cocotb v%s from %s\" %\n             (__version__, os.path.dirname(__file__)))\n\n    # Create the base handle type\n\n    process_plusargs()\n\n    # Seed the Python random number generator to make this repeatable\n    global RANDOM_SEED\n    RANDOM_SEED = os.getenv('RANDOM_SEED')\n\n    if RANDOM_SEED is None:\n        if 'ntb_random_seed' in plusargs:\n            RANDOM_SEED = eval(plusargs['ntb_random_seed'])\n        elif 'seed' in plusargs:\n            RANDOM_SEED = eval(plusargs['seed'])\n        else:\n            RANDOM_SEED = int(time.time())\n        log.info(\"Seeding Python random module with %d\" % (RANDOM_SEED))\n    else:\n        RANDOM_SEED = int(RANDOM_SEED)\n        log.info(\"Seeding Python random module with supplied seed %d\" % (RANDOM_SEED))\n    random.seed(RANDOM_SEED)\n\n    module_str = os.getenv('MODULE')\n    test_str = os.getenv('TESTCASE')\n    hooks_str = os.getenv('COCOTB_HOOKS', '')\n\n    if not module_str:\n        raise ImportError(\"Environment variables defining the module(s) to \" +\n                          \"execute not defined.  MODULE=\\\"%s\\\"\" % (module_str))\n\n    modules = module_str.split(',')\n    hooks = hooks_str.split(',') if hooks_str else []\n\n    global regression_manager\n\n    regression_manager = RegressionManager(root_name, modules, tests=test_str, seed=RANDOM_SEED, hooks=hooks)\n    regression_manager.initialise()\n    regression_manager.execute()\n\n    _rlock.release()\n    return True\n\n\ndef _sim_event(level, message):\n    \"\"\"Function that can be called externally to signal an event.\"\"\"\n    SIM_INFO = 0\n    SIM_TEST_FAIL = 1\n    SIM_FAIL = 2\n    from cocotb.result import TestFailure, SimFailure\n\n    if level is SIM_TEST_FAIL:\n        scheduler.log.error(\"Failing test at simulator request\")\n        scheduler.finish_test(TestFailure(\"Failure from external source: %s\" %\n                              message))\n    elif level is SIM_FAIL:\n        # We simply return here as the simulator will exit\n        # so no cleanup is needed\n        msg = (\"Failing test at simulator request before test run completion: \"\n               \"%s\" % message)\n        scheduler.log.error(msg)\n        scheduler.finish_scheduler(SimFailure(msg))\n    else:\n        scheduler.log.error(\"Unsupported sim event\")\n\n    return True\n\n\ndef process_plusargs():\n\n    global plusargs\n\n    plusargs = {}\n\n    for option in cocotb.argv:\n        if option.startswith('+'):\n            if option.find('=') != -1:\n                (name, value) = option[1:].split('=')\n                plusargs[name] = value\n            else:\n                plusargs[option[1:]] = True\n", "path": "cocotb/__init__.py"}]}