We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add some basic assert methods ?
```
assertEqual(a, b) 
assertNotEqual(a, b) 
assertTrue(x) 
assertFalse(x)
```

It would potentially make logging easier/better.

Based on https://docs.python.org/3/library/unittest.html#unittest.TestCase.debug

--- 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 https://docs.cocotb.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 from typing import Dict, List, Union
41 from collections.abc import Coroutine
42 
43 import cocotb.handle
44 import cocotb.log
45 from cocotb.scheduler import Scheduler
46 from cocotb.regression import RegressionManager
47 from cocotb.decorators import RunningTask
48 
49 # Things we want in the cocotb namespace
50 from cocotb.decorators import test, coroutine, hook, function, external  # noqa: F401
51 
52 from ._version import __version__
53 
54 
55 def _setup_logging():
56     global log
57 
58     def _reopen_stream_with_buffering(stream_name):
59         try:
60             if not getattr(sys, stream_name).isatty():
61                 setattr(sys, stream_name, os.fdopen(getattr(sys, stream_name).fileno(), 'w', 1))
62                 return True
63             return False
64         except Exception as e:
65             return e
66 
67     # If stdout/stderr are not TTYs, Python may not have opened them with line
68     # buffering. In that case, try to reopen them with line buffering
69     # explicitly enabled. This ensures that prints such as stack traces always
70     # appear. Continue silently if this fails.
71     _stdout_buffer_result = _reopen_stream_with_buffering('stdout')
72     _stderr_buffer_result = _reopen_stream_with_buffering('stderr')
73 
74     # Don't set the logging up until we've attempted to fix the standard IO,
75     # otherwise it will end up connected to the unfixed IO.
76     cocotb.log.default_config()
77     log = logging.getLogger(__name__)
78 
79     # we can't log these things until the logging is set up!
80     if _stderr_buffer_result is True:
81         log.debug("Reopened stderr with line buffering")
82     if _stdout_buffer_result is True:
83         log.debug("Reopened stdout with line buffering")
84     if isinstance(_stdout_buffer_result, Exception) or isinstance(_stderr_buffer_result, Exception):
85         if isinstance(_stdout_buffer_result, Exception):
86             log.warning("Failed to ensure that stdout is line buffered", exc_info=_stdout_buffer_result)
87         if isinstance(_stderr_buffer_result, Exception):
88             log.warning("Failed to ensure that stderr is line buffered", exc_info=_stderr_buffer_result)
89         log.warning("Some stack traces may not appear because of this.")
90 
91     del _stderr_buffer_result, _stdout_buffer_result
92 
93 
94 # Singleton scheduler instance
95 # NB this cheekily ensures a singleton since we're replacing the reference
96 # so that cocotb.scheduler gives you the singleton instance and not the
97 # scheduler package
98 
99 scheduler = None  # type: cocotb.scheduler.Scheduler
100 """The global scheduler instance."""
101 
102 regression_manager = None  # type: cocotb.regression.RegressionManager
103 """The global regression manager instance."""
104 
105 argv = None  # type: List[str]
106 """The argument list as seen by the simulator"""
107 
108 argc = None  # type: int
109 """The length of :data:`cocotb.argv`"""
110 
111 plusargs = None  # type: Dict[str, Union[bool, str]]
112 """A dictionary of "plusargs" handed to the simulation. See :make:var:`PLUSARGS` for details."""
113 
114 LANGUAGE = os.getenv("TOPLEVEL_LANG")  # type: str
115 """The value of :make:var:`TOPLEVEL_LANG`"""
116 
117 SIM_NAME = None  # type: str
118 """The running simulator product information. ``None`` if :mod:`cocotb` was not loaded from a simulator"""
119 
120 SIM_VERSION = None  # type: str
121 """The version of the running simulator. ``None`` if :mod:`cocotb` was not loaded from a simulator"""
122 
123 RANDOM_SEED = None  # type: int
124 """
125 The value passed to the Python default random number generator.
126 See :envvar:`RANDOM_SEED` for details on how the value is computed.
127 """
128 
129 _library_coverage = None
130 """ used for cocotb library coverage """
131 
132 top = None  # type: cocotb.handle.SimHandleBase
133 r"""
134 A handle to the :envvar:`TOPLEVEL` entity/module.
135 
136 This is equivalent to the :term:`DUT` parameter given to cocotb tests, so it can be used wherever that variable can be used.
137 It is particularly useful for extracting information about the :term:`DUT` in module-level class and function definitions;
138 and in parameters to :class:`.TestFactory`\ s.
139 ``None`` if :mod:`cocotb` was not loaded from a simulator.
140 """
141 
142 
143 def fork(coro: Union[RunningTask, Coroutine]) -> RunningTask:
144     """ Schedule a coroutine to be run concurrently. See :ref:`coroutines` for details on its use. """
145     return scheduler.add(coro)
146 
147 
148 # FIXME is this really required?
149 _rlock = threading.RLock()
150 
151 
152 def mem_debug(port):
153     import cocotb.memdebug
154     cocotb.memdebug.start(port)
155 
156 
157 def _initialise_testbench(argv_):
158     """Initialize testbench.
159 
160     This function is called after the simulator has elaborated all
161     entities and is ready to run the test.
162 
163     The test must be defined by the environment variables
164     :envvar:`MODULE` and :envvar:`TESTCASE`.
165 
166     The environment variable :envvar:`COCOTB_HOOKS`, if present, contains a
167     comma-separated list of modules to be executed before the first test.
168     """
169     _rlock.acquire()
170 
171     if "COCOTB_LIBRARY_COVERAGE" in os.environ:
172         import coverage
173 
174         global _library_coverage
175         _library_coverage = coverage.coverage(
176             data_file=".coverage.cocotb",
177             branch=True,
178             include=["{}/*".format(os.path.dirname(__file__))])
179         _library_coverage.start()
180 
181     global argc, argv
182     argv = argv_
183     argc = len(argv)
184 
185     root_name = os.getenv("TOPLEVEL")
186     if root_name is not None:
187         if root_name == "":
188             root_name = None
189         elif '.' in root_name:
190             # Skip any library component of the toplevel
191             root_name = root_name.split(".", 1)[1]
192 
193     # sys.path normally includes "" (the current directory), but does not appear to when python is embedded.
194     # Add it back because users expect to be able to import files in their test directory.
195     # TODO: move this to gpi_embed.cpp
196     sys.path.insert(0, "")
197 
198     _setup_logging()
199 
200     # From https://www.python.org/dev/peps/pep-0565/#recommended-filter-settings-for-test-runners
201     # If the user doesn't want to see these, they can always change the global
202     # warning settings in their test module.
203     if not sys.warnoptions:
204         warnings.simplefilter("default")
205 
206     from cocotb import simulator
207 
208     global SIM_NAME, SIM_VERSION
209     SIM_NAME = simulator.get_simulator_product().strip()
210     SIM_VERSION = simulator.get_simulator_version().strip()
211 
212     cocotb.log.info("Running on {} version {}".format(SIM_NAME, SIM_VERSION))
213 
214     memcheck_port = os.getenv('MEMCHECK')
215     if memcheck_port is not None:
216         mem_debug(int(memcheck_port))
217 
218     log.info("Running tests with cocotb v%s from %s" %
219              (__version__, os.path.dirname(__file__)))
220 
221     # Create the base handle type
222 
223     process_plusargs()
224 
225     global scheduler
226     scheduler = Scheduler()
227 
228     # Seed the Python random number generator to make this repeatable
229     global RANDOM_SEED
230     RANDOM_SEED = os.getenv('RANDOM_SEED')
231 
232     if RANDOM_SEED is None:
233         if 'ntb_random_seed' in plusargs:
234             RANDOM_SEED = eval(plusargs['ntb_random_seed'])
235         elif 'seed' in plusargs:
236             RANDOM_SEED = eval(plusargs['seed'])
237         else:
238             RANDOM_SEED = int(time.time())
239         log.info("Seeding Python random module with %d" % (RANDOM_SEED))
240     else:
241         RANDOM_SEED = int(RANDOM_SEED)
242         log.info("Seeding Python random module with supplied seed %d" % (RANDOM_SEED))
243     random.seed(RANDOM_SEED)
244 
245     # Setup DUT object
246     from cocotb import simulator
247 
248     handle = simulator.get_root_handle(root_name)
249     if not handle:
250         raise RuntimeError("Can not find root handle ({})".format(root_name))
251 
252     global top
253     top = cocotb.handle.SimHandle(handle)
254 
255     # start Regression Manager
256     global regression_manager
257     regression_manager = RegressionManager.from_discovery(top)
258     regression_manager.execute()
259 
260     _rlock.release()
261     return True
262 
263 
264 def _sim_event(level, message):
265     """Function that can be called externally to signal an event."""
266     # SIM_INFO = 0
267     SIM_TEST_FAIL = 1
268     SIM_FAIL = 2
269     from cocotb.result import TestFailure, SimFailure
270 
271     if level is SIM_TEST_FAIL:
272         scheduler.log.error("Failing test at simulator request")
273         scheduler.finish_test(TestFailure("Failure from external source: %s" %
274                               message))
275     elif level is SIM_FAIL:
276         # We simply return here as the simulator will exit
277         # so no cleanup is needed
278         msg = ("Failing test at simulator request before test run completion: "
279                "%s" % message)
280         scheduler.log.error(msg)
281         scheduler.finish_scheduler(SimFailure(msg))
282     else:
283         scheduler.log.error("Unsupported sim event")
284 
285     return True
286 
287 
288 def process_plusargs():
289 
290     global plusargs
291 
292     plusargs = {}
293 
294     for option in cocotb.argv:
295         if option.startswith('+'):
296             if option.find('=') != -1:
297                 (name, value) = option[1:].split('=')
298                 plusargs[name] = value
299             else:
300                 plusargs[option[1:]] = True
301
```
--- 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
@@ -240,6 +240,23 @@
 
     dut = cocotb.handle.SimHandle(handle)
 
+    try:
+        import pytest
+    except ImportError:
+        log.warning("Pytest not found, assertion rewriting will not occur")
+    else:
+        try:
+            # Install the assertion rewriting hook, which must be done before we
+            # import the test modules.
+            from _pytest.config import Config
+            from _pytest.assertion import install_importhook
+            pytest_conf = Config.fromdictargs([], {})
+            install_importhook(pytest_conf)
+        except Exception:
+            log.exception(
+                "Configuring the assertion rewrite hook using pytest {} failed. "
+                "Please file a bug report!".format(pytest.__version__))
+
     # start Regression Manager
     global regression_manager
     regression_manager = RegressionManager.from_discovery(dut)

{"golden_diff": "diff --git a/cocotb/__init__.py b/cocotb/__init__.py\n--- a/cocotb/__init__.py\n+++ b/cocotb/__init__.py\n@@ -240,6 +240,23 @@\n \n     dut = cocotb.handle.SimHandle(handle)\n \n+    try:\n+        import pytest\n+    except ImportError:\n+        log.warning(\"Pytest not found, assertion rewriting will not occur\")\n+    else:\n+        try:\n+            # Install the assertion rewriting hook, which must be done before we\n+            # import the test modules.\n+            from _pytest.config import Config\n+            from _pytest.assertion import install_importhook\n+            pytest_conf = Config.fromdictargs([], {})\n+            install_importhook(pytest_conf)\n+        except Exception:\n+            log.exception(\n+                \"Configuring the assertion rewrite hook using pytest {} failed. \"\n+                \"Please file a bug report!\".format(pytest.__version__))\n+\n     # start Regression Manager\n     global regression_manager\n     regression_manager = RegressionManager.from_discovery(dut)\n", "issue": "Add some basic assert methods ?\n```\r\nassertEqual(a,\u00a0b) \r\nassertNotEqual(a,\u00a0b) \r\nassertTrue(x) \r\nassertFalse(x)\r\n```\r\n\r\nIt would potentially make logging easier/better.\r\n\r\nBased on https://docs.python.org/3/library/unittest.html#unittest.TestCase.debug\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 https://docs.cocotb.org for full documentation\n\"\"\"\nimport os\nimport sys\nimport logging\nimport threading\nimport random\nimport time\nimport warnings\nfrom typing import Dict, List, Union\nfrom collections.abc import Coroutine\n\nimport cocotb.handle\nimport cocotb.log\nfrom cocotb.scheduler import Scheduler\nfrom cocotb.regression import RegressionManager\nfrom cocotb.decorators import RunningTask\n\n# Things we want in the cocotb namespace\nfrom cocotb.decorators import test, coroutine, hook, function, external  # noqa: F401\n\nfrom ._version import __version__\n\n\ndef _setup_logging():\n    global log\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\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\nscheduler = None  # type: cocotb.scheduler.Scheduler\n\"\"\"The global scheduler instance.\"\"\"\n\nregression_manager = None  # type: cocotb.regression.RegressionManager\n\"\"\"The global regression manager instance.\"\"\"\n\nargv = None  # type: List[str]\n\"\"\"The argument list as seen by the simulator\"\"\"\n\nargc = None  # type: int\n\"\"\"The length of :data:`cocotb.argv`\"\"\"\n\nplusargs = None  # type: Dict[str, Union[bool, str]]\n\"\"\"A dictionary of \"plusargs\" handed to the simulation. See :make:var:`PLUSARGS` for details.\"\"\"\n\nLANGUAGE = os.getenv(\"TOPLEVEL_LANG\")  # type: str\n\"\"\"The value of :make:var:`TOPLEVEL_LANG`\"\"\"\n\nSIM_NAME = None  # type: str\n\"\"\"The running simulator product information. ``None`` if :mod:`cocotb` was not loaded from a simulator\"\"\"\n\nSIM_VERSION = None  # type: str\n\"\"\"The version of the running simulator. ``None`` if :mod:`cocotb` was not loaded from a simulator\"\"\"\n\nRANDOM_SEED = None  # type: int\n\"\"\"\nThe value passed to the Python default random number generator.\nSee :envvar:`RANDOM_SEED` for details on how the value is computed.\n\"\"\"\n\n_library_coverage = None\n\"\"\" used for cocotb library coverage \"\"\"\n\ntop = None  # type: cocotb.handle.SimHandleBase\nr\"\"\"\nA handle to the :envvar:`TOPLEVEL` entity/module.\n\nThis is equivalent to the :term:`DUT` parameter given to cocotb tests, so it can be used wherever that variable can be used.\nIt is particularly useful for extracting information about the :term:`DUT` in module-level class and function definitions;\nand in parameters to :class:`.TestFactory`\\ s.\n``None`` if :mod:`cocotb` was not loaded from a simulator.\n\"\"\"\n\n\ndef fork(coro: Union[RunningTask, Coroutine]) -> RunningTask:\n    \"\"\" Schedule a coroutine to be run concurrently. See :ref:`coroutines` for details on its use. \"\"\"\n    return scheduler.add(coro)\n\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(argv_):\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    if \"COCOTB_LIBRARY_COVERAGE\" in os.environ:\n        import coverage\n\n        global _library_coverage\n        _library_coverage = coverage.coverage(\n            data_file=\".coverage.cocotb\",\n            branch=True,\n            include=[\"{}/*\".format(os.path.dirname(__file__))])\n        _library_coverage.start()\n\n    global argc, argv\n    argv = argv_\n    argc = len(argv)\n\n    root_name = os.getenv(\"TOPLEVEL\")\n    if root_name is not None:\n        if root_name == \"\":\n            root_name = None\n        elif '.' in root_name:\n            # Skip any library component of the toplevel\n            root_name = root_name.split(\".\", 1)[1]\n\n    # sys.path normally includes \"\" (the current directory), but does not appear to when python is embedded.\n    # Add it back because users expect to be able to import files in their test directory.\n    # TODO: move this to gpi_embed.cpp\n    sys.path.insert(0, \"\")\n\n    _setup_logging()\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\n    from cocotb import simulator\n\n    global SIM_NAME, SIM_VERSION\n    SIM_NAME = simulator.get_simulator_product().strip()\n    SIM_VERSION = simulator.get_simulator_version().strip()\n\n    cocotb.log.info(\"Running on {} version {}\".format(SIM_NAME, SIM_VERSION))\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    global scheduler\n    scheduler = Scheduler()\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    # Setup DUT object\n    from cocotb import simulator\n\n    handle = simulator.get_root_handle(root_name)\n    if not handle:\n        raise RuntimeError(\"Can not find root handle ({})\".format(root_name))\n\n    global top\n    top = cocotb.handle.SimHandle(handle)\n\n    # start Regression Manager\n    global regression_manager\n    regression_manager = RegressionManager.from_discovery(top)\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 https://docs.cocotb.org for full documentation\n\"\"\"\nimport os\nimport sys\nimport logging\nimport threading\nimport random\nimport time\nimport warnings\nfrom typing import Dict, List, Union\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\nfrom ._version import __version__\n\n\ndef _setup_logging():\n    global log\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\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\nscheduler = None  # type: cocotb.scheduler.Scheduler\n\"\"\"The global scheduler instance.\"\"\"\n\nregression_manager = None  # type: cocotb.regression.RegressionManager\n\"\"\"The global regression manager instance.\"\"\"\n\nargv = None  # type: List[str]\n\"\"\"The argument list as seen by the simulator\"\"\"\n\nargc = None  # type: int\n\"\"\"The length of :data:`cocotb.argv`\"\"\"\n\nplusargs = None  # type: Dict[str, Union[bool, str]]\n\"\"\"A dictionary of \"plusargs\" handed to the simulation. See :make:var:`PLUSARGS` for details.\"\"\"\n\nLANGUAGE = os.getenv(\"TOPLEVEL_LANG\")  # type: str\n\"\"\"The value of :make:var:`TOPLEVEL_LANG`\"\"\"\n\nSIM_NAME = None  # type: str\n\"\"\"The running simulator product information. ``None`` if :mod:`cocotb` was not loaded from a simulator\"\"\"\n\nSIM_VERSION = None  # type: str\n\"\"\"The version of the running simulator. ``None`` if :mod:`cocotb` was not loaded from a simulator\"\"\"\n\nRANDOM_SEED = None  # type: int\n\"\"\"\nThe value passed to the Python default random number generator.\nSee :envvar:`RANDOM_SEED` for details on how the value is computed.\n\"\"\"\n\n_library_coverage = None\n\"\"\" used for cocotb library coverage \"\"\"\n\n\ndef fork(coro):\n    \"\"\" Schedule a coroutine to be run concurrently. See :ref:`coroutines` for details on its use. \"\"\"\n    return scheduler.add(coro)\n\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(argv_):\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    if \"COCOTB_LIBRARY_COVERAGE\" in os.environ:\n        import coverage\n\n        global _library_coverage\n        _library_coverage = coverage.coverage(\n            data_file=\".coverage.cocotb\",\n            branch=True,\n            include=[\"{}/*\".format(os.path.dirname(__file__))])\n        _library_coverage.start()\n\n    global argc, argv\n    argv = argv_\n    argc = len(argv)\n\n    root_name = os.getenv(\"TOPLEVEL\")\n    if root_name is not None:\n        if root_name == \"\":\n            root_name = None\n        elif '.' in root_name:\n            # Skip any library component of the toplevel\n            root_name = root_name.split(\".\", 1)[1]\n\n    # sys.path normally includes \"\" (the current directory), but does not appear to when python is embedded.\n    # Add it back because users expect to be able to import files in their test directory.\n    # TODO: move this to gpi_embed.cpp\n    sys.path.insert(0, \"\")\n\n    _setup_logging()\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\n    from cocotb import simulator\n\n    global SIM_NAME, SIM_VERSION\n    SIM_NAME = simulator.get_simulator_product().strip()\n    SIM_VERSION = simulator.get_simulator_version().strip()\n\n    cocotb.log.info(\"Running on {} version {}\".format(SIM_NAME, SIM_VERSION))\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    global scheduler\n    scheduler = Scheduler()\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    # Setup DUT object\n    from cocotb import simulator\n\n    handle = simulator.get_root_handle(root_name)\n    if not handle:\n        raise RuntimeError(\"Can not find root handle ({})\".format(root_name))\n\n    dut = cocotb.handle.SimHandle(handle)\n\n    try:\n        import pytest\n    except ImportError:\n        log.warning(\"Pytest not found, assertion rewriting will not occur\")\n    else:\n        try:\n            # Install the assertion rewriting hook, which must be done before we\n            # import the test modules.\n            from _pytest.config import Config\n            from _pytest.assertion import install_importhook\n            pytest_conf = Config.fromdictargs([], {})\n            install_importhook(pytest_conf)\n        except Exception:\n            log.exception(\n                \"Configuring the assertion rewrite hook using pytest {} failed. \"\n                \"Please file a bug report!\".format(pytest.__version__))\n\n    # start Regression Manager\n    global regression_manager\n    regression_manager = RegressionManager.from_discovery(dut)\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"}]}