We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Handle ufunc coverage wrappers more robustly
ref: https://github.com/nv-legate/cunumeric/pull/268/files#r846513290

As noted in the above conversation, the generic callable wrapping for adding coverage reporting is not sufficient. 

Numpy (and thus cunumeric) `ufunc` are objects with their own API (https://numpy.org/doc/stable/reference/ufuncs.html) and just using a plain function wrapper makes those methods invisible. Some requirements to decide first:

* Do all the methods of a `ufunc` need to be included in coverage reporting? Or just its `__call__`

If yes, we will need to resort to a wrapping object (and then: is it sufficient to just create a purpose-built `ufunc_wrapper` or do we need a generic forwarding wrapper?)

If not, we may be able to just wrap and replace `__call__` using the function wrappers similar to the existing ones.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `cunumeric/coverage.py`
Content:
```
1 # Copyright 2021-2022 NVIDIA Corporation
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 #
15 from __future__ import annotations
16 
17 import warnings
18 from functools import wraps
19 from types import FunctionType, MethodDescriptorType, MethodType, ModuleType
20 from typing import Any, Callable, Container, Optional, cast
21 
22 from typing_extensions import Protocol
23 
24 from .runtime import runtime
25 from .utils import find_last_user_frames, find_last_user_stacklevel
26 
27 __all__ = ("clone_module",)
28 
29 FALLBACK_WARNING = (
30     "cuNumeric has not implemented {name} "
31     + "and is falling back to canonical numpy. "
32     + "You may notice significantly decreased performance "
33     + "for this function call."
34 )
35 
36 MOD_INTERNAL = {"__dir__", "__getattr__"}
37 
38 NDARRAY_INTERNAL = {
39     "__array_finalize__",
40     "__array_function__",
41     "__array_interface__",
42     "__array_prepare__",
43     "__array_priority__",
44     "__array_struct__",
45     "__array_ufunc__",
46     "__array_wrap__",
47 }
48 
49 
50 def filter_namespace(
51     ns: dict[str, Any],
52     *,
53     omit_names: Optional[Container[str]] = None,
54     omit_types: tuple[type, ...] = (),
55 ) -> dict[str, Any]:
56     omit_names = omit_names or set()
57     return {
58         attr: value
59         for attr, value in ns.items()
60         if attr not in omit_names and not isinstance(value, omit_types)
61     }
62 
63 
64 class AnyCallable(Protocol):
65     def __call__(self, *args: Any, **kwargs: Any) -> Any:
66         ...
67 
68 
69 class CuWrapped(Protocol):
70     _cunumeric_implemented: bool
71 
72     def __call__(self, *args: Any, **kwargs: Any) -> Any:
73         ...
74 
75 
76 def implemented(
77     func: AnyCallable, prefix: str, name: str, *, reporting: bool = True
78 ) -> CuWrapped:
79     name = f"{prefix}.{name}"
80 
81     wrapper: CuWrapped
82 
83     if reporting:
84 
85         @wraps(func)
86         def wrapper(*args: Any, **kwargs: Any) -> Any:
87             location = find_last_user_frames(not runtime.report_dump_callstack)
88             runtime.record_api_call(
89                 name=name, location=location, implemented=True
90             )
91             return func(*args, **kwargs)
92 
93     else:
94 
95         wrapper = cast(CuWrapped, func)
96 
97     wrapper._cunumeric_implemented = True
98 
99     return wrapper
100 
101 
102 def unimplemented(
103     func: AnyCallable, prefix: str, name: str, *, reporting: bool = True
104 ) -> CuWrapped:
105     name = f"{prefix}.{name}"
106 
107     wrapper: CuWrapped
108 
109     if reporting:
110 
111         @wraps(func)
112         def wrapper(*args: Any, **kwargs: Any) -> Any:
113             location = find_last_user_frames(not runtime.report_dump_callstack)
114             runtime.record_api_call(
115                 name=name, location=location, implemented=False
116             )
117             return func(*args, **kwargs)
118 
119     else:
120 
121         @wraps(func)
122         def wrapper(*args: Any, **kwargs: Any) -> Any:
123             stacklevel = find_last_user_stacklevel()
124             warnings.warn(
125                 FALLBACK_WARNING.format(name=name),
126                 stacklevel=stacklevel,
127                 category=RuntimeWarning,
128             )
129             return func(*args, **kwargs)
130 
131     wrapper._cunumeric_implemented = False
132 
133     return wrapper
134 
135 
136 def clone_module(
137     origin_module: ModuleType, new_globals: dict[str, Any]
138 ) -> None:
139     """Copy attributes from one module to another, excluding submodules
140 
141     Function types are wrapped with a decorator to report API calls. All
142     other values are copied as-is.
143 
144     Parameters
145     ----------
146     origin_module : ModuleTpe
147         Existing module to clone attributes from
148 
149     new_globals : dict
150         a globals() dict for the new module to clone into
151 
152     Returns
153     -------
154     None
155 
156     """
157     mod_name = origin_module.__name__
158 
159     missing = filter_namespace(
160         origin_module.__dict__,
161         omit_names=set(new_globals).union(MOD_INTERNAL),
162         omit_types=(ModuleType,),
163     )
164 
165     from numpy import ufunc as npufunc
166 
167     from ._ufunc.ufunc import ufunc as lgufunc
168 
169     reporting = runtime.report_coverage
170 
171     for attr, value in new_globals.items():
172         if isinstance(value, (FunctionType, lgufunc)):
173             wrapped = implemented(
174                 cast(AnyCallable, value), mod_name, attr, reporting=reporting
175             )
176             new_globals[attr] = wrapped
177 
178     for attr, value in missing.items():
179         if isinstance(value, (FunctionType, npufunc)):
180             wrapped = unimplemented(value, mod_name, attr, reporting=reporting)
181             new_globals[attr] = wrapped
182         else:
183             new_globals[attr] = value
184 
185 
186 def clone_class(origin_class: type) -> Callable[[type], type]:
187     """Copy attributes from one class to another
188 
189     Method types are wrapped with a decorator to report API calls. All
190     other values are copied as-is.
191 
192     Parameters
193     ----------
194     origin_class : type
195         Existing class type to clone attributes from
196 
197     """
198 
199     def should_wrap(obj: object) -> bool:
200         return isinstance(
201             obj, (FunctionType, MethodType, MethodDescriptorType)
202         )
203 
204     def decorator(cls: type) -> type:
205         class_name = f"{origin_class.__module__}.{origin_class.__name__}"
206 
207         missing = filter_namespace(
208             origin_class.__dict__,
209             # this simply omits ndarray internal methods for any class. If
210             # we ever need to wrap more classes we may need to generalize to
211             # per-class specification of internal names to skip
212             omit_names=set(cls.__dict__).union(NDARRAY_INTERNAL),
213         )
214 
215         reporting = runtime.report_coverage
216 
217         for attr, value in cls.__dict__.items():
218             if should_wrap(value):
219                 wrapped = implemented(
220                     value, class_name, attr, reporting=reporting
221                 )
222                 setattr(cls, attr, wrapped)
223 
224         for attr, value in missing.items():
225             if should_wrap(value):
226                 wrapped = unimplemented(
227                     value, class_name, attr, reporting=reporting
228                 )
229                 setattr(cls, attr, wrapped)
230             else:
231                 setattr(cls, attr, value)
232 
233         return cls
234 
235     return decorator
236
```
--- 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/cunumeric/coverage.py b/cunumeric/coverage.py
--- a/cunumeric/coverage.py
+++ b/cunumeric/coverage.py
@@ -24,7 +24,7 @@
 from .runtime import runtime
 from .utils import find_last_user_frames, find_last_user_stacklevel
 
-__all__ = ("clone_module",)
+__all__ = ("clone_class", "clone_module")
 
 FALLBACK_WARNING = (
     "cuNumeric has not implemented {name} "
@@ -66,12 +66,9 @@
         ...
 
 
-class CuWrapped(Protocol):
+class CuWrapped(AnyCallable, Protocol):
     _cunumeric_implemented: bool
 
-    def __call__(self, *args: Any, **kwargs: Any) -> Any:
-        ...
-
 
 def implemented(
     func: AnyCallable, prefix: str, name: str, *, reporting: bool = True
@@ -92,7 +89,9 @@
 
     else:
 
-        wrapper = cast(CuWrapped, func)
+        @wraps(func)
+        def wrapper(*args: Any, **kwargs: Any) -> Any:
+            return func(*args, **kwargs)
 
     wrapper._cunumeric_implemented = True
 
@@ -162,12 +161,10 @@
         omit_types=(ModuleType,),
     )
 
-    from numpy import ufunc as npufunc
+    reporting = runtime.report_coverage
 
     from ._ufunc.ufunc import ufunc as lgufunc
 
-    reporting = runtime.report_coverage
-
     for attr, value in new_globals.items():
         if isinstance(value, (FunctionType, lgufunc)):
             wrapped = implemented(
@@ -175,6 +172,8 @@
             )
             new_globals[attr] = wrapped
 
+    from numpy import ufunc as npufunc
+
     for attr, value in missing.items():
         if isinstance(value, (FunctionType, npufunc)):
             wrapped = unimplemented(value, mod_name, attr, reporting=reporting)

{"golden_diff": "diff --git a/cunumeric/coverage.py b/cunumeric/coverage.py\n--- a/cunumeric/coverage.py\n+++ b/cunumeric/coverage.py\n@@ -24,7 +24,7 @@\n from .runtime import runtime\n from .utils import find_last_user_frames, find_last_user_stacklevel\n \n-__all__ = (\"clone_module\",)\n+__all__ = (\"clone_class\", \"clone_module\")\n \n FALLBACK_WARNING = (\n     \"cuNumeric has not implemented {name} \"\n@@ -66,12 +66,9 @@\n         ...\n \n \n-class CuWrapped(Protocol):\n+class CuWrapped(AnyCallable, Protocol):\n     _cunumeric_implemented: bool\n \n-    def __call__(self, *args: Any, **kwargs: Any) -> Any:\n-        ...\n-\n \n def implemented(\n     func: AnyCallable, prefix: str, name: str, *, reporting: bool = True\n@@ -92,7 +89,9 @@\n \n     else:\n \n-        wrapper = cast(CuWrapped, func)\n+        @wraps(func)\n+        def wrapper(*args: Any, **kwargs: Any) -> Any:\n+            return func(*args, **kwargs)\n \n     wrapper._cunumeric_implemented = True\n \n@@ -162,12 +161,10 @@\n         omit_types=(ModuleType,),\n     )\n \n-    from numpy import ufunc as npufunc\n+    reporting = runtime.report_coverage\n \n     from ._ufunc.ufunc import ufunc as lgufunc\n \n-    reporting = runtime.report_coverage\n-\n     for attr, value in new_globals.items():\n         if isinstance(value, (FunctionType, lgufunc)):\n             wrapped = implemented(\n@@ -175,6 +172,8 @@\n             )\n             new_globals[attr] = wrapped\n \n+    from numpy import ufunc as npufunc\n+\n     for attr, value in missing.items():\n         if isinstance(value, (FunctionType, npufunc)):\n             wrapped = unimplemented(value, mod_name, attr, reporting=reporting)\n", "issue": "Handle ufunc coverage wrappers more robustly\nref: https://github.com/nv-legate/cunumeric/pull/268/files#r846513290\r\n\r\nAs noted in the above conversation, the generic callable wrapping for adding coverage reporting is not sufficient. \r\n\r\nNumpy (and thus cunumeric) `ufunc` are objects with their own API (https://numpy.org/doc/stable/reference/ufuncs.html) and just using a plain function wrapper makes those methods invisible. Some requirements to decide first:\r\n\r\n* Do all the methods of a `ufunc` need to be included in coverage reporting? Or just its `__call__`\r\n\r\nIf yes, we will need to resort to a wrapping object (and then: is it sufficient to just create a purpose-built `ufunc_wrapper` or do we need a generic forwarding wrapper?)\r\n\r\nIf not, we may be able to just wrap and replace `__call__` using the function wrappers similar to the existing ones.\n", "before_files": [{"content": "# Copyright 2021-2022 NVIDIA Corporation\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nfrom __future__ import annotations\n\nimport warnings\nfrom functools import wraps\nfrom types import FunctionType, MethodDescriptorType, MethodType, ModuleType\nfrom typing import Any, Callable, Container, Optional, cast\n\nfrom typing_extensions import Protocol\n\nfrom .runtime import runtime\nfrom .utils import find_last_user_frames, find_last_user_stacklevel\n\n__all__ = (\"clone_module\",)\n\nFALLBACK_WARNING = (\n    \"cuNumeric has not implemented {name} \"\n    + \"and is falling back to canonical numpy. \"\n    + \"You may notice significantly decreased performance \"\n    + \"for this function call.\"\n)\n\nMOD_INTERNAL = {\"__dir__\", \"__getattr__\"}\n\nNDARRAY_INTERNAL = {\n    \"__array_finalize__\",\n    \"__array_function__\",\n    \"__array_interface__\",\n    \"__array_prepare__\",\n    \"__array_priority__\",\n    \"__array_struct__\",\n    \"__array_ufunc__\",\n    \"__array_wrap__\",\n}\n\n\ndef filter_namespace(\n    ns: dict[str, Any],\n    *,\n    omit_names: Optional[Container[str]] = None,\n    omit_types: tuple[type, ...] = (),\n) -> dict[str, Any]:\n    omit_names = omit_names or set()\n    return {\n        attr: value\n        for attr, value in ns.items()\n        if attr not in omit_names and not isinstance(value, omit_types)\n    }\n\n\nclass AnyCallable(Protocol):\n    def __call__(self, *args: Any, **kwargs: Any) -> Any:\n        ...\n\n\nclass CuWrapped(Protocol):\n    _cunumeric_implemented: bool\n\n    def __call__(self, *args: Any, **kwargs: Any) -> Any:\n        ...\n\n\ndef implemented(\n    func: AnyCallable, prefix: str, name: str, *, reporting: bool = True\n) -> CuWrapped:\n    name = f\"{prefix}.{name}\"\n\n    wrapper: CuWrapped\n\n    if reporting:\n\n        @wraps(func)\n        def wrapper(*args: Any, **kwargs: Any) -> Any:\n            location = find_last_user_frames(not runtime.report_dump_callstack)\n            runtime.record_api_call(\n                name=name, location=location, implemented=True\n            )\n            return func(*args, **kwargs)\n\n    else:\n\n        wrapper = cast(CuWrapped, func)\n\n    wrapper._cunumeric_implemented = True\n\n    return wrapper\n\n\ndef unimplemented(\n    func: AnyCallable, prefix: str, name: str, *, reporting: bool = True\n) -> CuWrapped:\n    name = f\"{prefix}.{name}\"\n\n    wrapper: CuWrapped\n\n    if reporting:\n\n        @wraps(func)\n        def wrapper(*args: Any, **kwargs: Any) -> Any:\n            location = find_last_user_frames(not runtime.report_dump_callstack)\n            runtime.record_api_call(\n                name=name, location=location, implemented=False\n            )\n            return func(*args, **kwargs)\n\n    else:\n\n        @wraps(func)\n        def wrapper(*args: Any, **kwargs: Any) -> Any:\n            stacklevel = find_last_user_stacklevel()\n            warnings.warn(\n                FALLBACK_WARNING.format(name=name),\n                stacklevel=stacklevel,\n                category=RuntimeWarning,\n            )\n            return func(*args, **kwargs)\n\n    wrapper._cunumeric_implemented = False\n\n    return wrapper\n\n\ndef clone_module(\n    origin_module: ModuleType, new_globals: dict[str, Any]\n) -> None:\n    \"\"\"Copy attributes from one module to another, excluding submodules\n\n    Function types are wrapped with a decorator to report API calls. All\n    other values are copied as-is.\n\n    Parameters\n    ----------\n    origin_module : ModuleTpe\n        Existing module to clone attributes from\n\n    new_globals : dict\n        a globals() dict for the new module to clone into\n\n    Returns\n    -------\n    None\n\n    \"\"\"\n    mod_name = origin_module.__name__\n\n    missing = filter_namespace(\n        origin_module.__dict__,\n        omit_names=set(new_globals).union(MOD_INTERNAL),\n        omit_types=(ModuleType,),\n    )\n\n    from numpy import ufunc as npufunc\n\n    from ._ufunc.ufunc import ufunc as lgufunc\n\n    reporting = runtime.report_coverage\n\n    for attr, value in new_globals.items():\n        if isinstance(value, (FunctionType, lgufunc)):\n            wrapped = implemented(\n                cast(AnyCallable, value), mod_name, attr, reporting=reporting\n            )\n            new_globals[attr] = wrapped\n\n    for attr, value in missing.items():\n        if isinstance(value, (FunctionType, npufunc)):\n            wrapped = unimplemented(value, mod_name, attr, reporting=reporting)\n            new_globals[attr] = wrapped\n        else:\n            new_globals[attr] = value\n\n\ndef clone_class(origin_class: type) -> Callable[[type], type]:\n    \"\"\"Copy attributes from one class to another\n\n    Method types are wrapped with a decorator to report API calls. All\n    other values are copied as-is.\n\n    Parameters\n    ----------\n    origin_class : type\n        Existing class type to clone attributes from\n\n    \"\"\"\n\n    def should_wrap(obj: object) -> bool:\n        return isinstance(\n            obj, (FunctionType, MethodType, MethodDescriptorType)\n        )\n\n    def decorator(cls: type) -> type:\n        class_name = f\"{origin_class.__module__}.{origin_class.__name__}\"\n\n        missing = filter_namespace(\n            origin_class.__dict__,\n            # this simply omits ndarray internal methods for any class. If\n            # we ever need to wrap more classes we may need to generalize to\n            # per-class specification of internal names to skip\n            omit_names=set(cls.__dict__).union(NDARRAY_INTERNAL),\n        )\n\n        reporting = runtime.report_coverage\n\n        for attr, value in cls.__dict__.items():\n            if should_wrap(value):\n                wrapped = implemented(\n                    value, class_name, attr, reporting=reporting\n                )\n                setattr(cls, attr, wrapped)\n\n        for attr, value in missing.items():\n            if should_wrap(value):\n                wrapped = unimplemented(\n                    value, class_name, attr, reporting=reporting\n                )\n                setattr(cls, attr, wrapped)\n            else:\n                setattr(cls, attr, value)\n\n        return cls\n\n    return decorator\n", "path": "cunumeric/coverage.py"}], "after_files": [{"content": "# Copyright 2021-2022 NVIDIA Corporation\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nfrom __future__ import annotations\n\nimport warnings\nfrom functools import wraps\nfrom types import FunctionType, MethodDescriptorType, MethodType, ModuleType\nfrom typing import Any, Callable, Container, Optional, cast\n\nfrom typing_extensions import Protocol\n\nfrom .runtime import runtime\nfrom .utils import find_last_user_frames, find_last_user_stacklevel\n\n__all__ = (\"clone_class\", \"clone_module\")\n\nFALLBACK_WARNING = (\n    \"cuNumeric has not implemented {name} \"\n    + \"and is falling back to canonical numpy. \"\n    + \"You may notice significantly decreased performance \"\n    + \"for this function call.\"\n)\n\nMOD_INTERNAL = {\"__dir__\", \"__getattr__\"}\n\nNDARRAY_INTERNAL = {\n    \"__array_finalize__\",\n    \"__array_function__\",\n    \"__array_interface__\",\n    \"__array_prepare__\",\n    \"__array_priority__\",\n    \"__array_struct__\",\n    \"__array_ufunc__\",\n    \"__array_wrap__\",\n}\n\n\ndef filter_namespace(\n    ns: dict[str, Any],\n    *,\n    omit_names: Optional[Container[str]] = None,\n    omit_types: tuple[type, ...] = (),\n) -> dict[str, Any]:\n    omit_names = omit_names or set()\n    return {\n        attr: value\n        for attr, value in ns.items()\n        if attr not in omit_names and not isinstance(value, omit_types)\n    }\n\n\nclass AnyCallable(Protocol):\n    def __call__(self, *args: Any, **kwargs: Any) -> Any:\n        ...\n\n\nclass CuWrapped(AnyCallable, Protocol):\n    _cunumeric_implemented: bool\n\n\ndef implemented(\n    func: AnyCallable, prefix: str, name: str, *, reporting: bool = True\n) -> CuWrapped:\n    name = f\"{prefix}.{name}\"\n\n    wrapper: CuWrapped\n\n    if reporting:\n\n        @wraps(func)\n        def wrapper(*args: Any, **kwargs: Any) -> Any:\n            location = find_last_user_frames(not runtime.report_dump_callstack)\n            runtime.record_api_call(\n                name=name, location=location, implemented=True\n            )\n            return func(*args, **kwargs)\n\n    else:\n\n        @wraps(func)\n        def wrapper(*args: Any, **kwargs: Any) -> Any:\n            return func(*args, **kwargs)\n\n    wrapper._cunumeric_implemented = True\n\n    return wrapper\n\n\ndef unimplemented(\n    func: AnyCallable, prefix: str, name: str, *, reporting: bool = True\n) -> CuWrapped:\n    name = f\"{prefix}.{name}\"\n\n    wrapper: CuWrapped\n\n    if reporting:\n\n        @wraps(func)\n        def wrapper(*args: Any, **kwargs: Any) -> Any:\n            location = find_last_user_frames(not runtime.report_dump_callstack)\n            runtime.record_api_call(\n                name=name, location=location, implemented=False\n            )\n            return func(*args, **kwargs)\n\n    else:\n\n        @wraps(func)\n        def wrapper(*args: Any, **kwargs: Any) -> Any:\n            stacklevel = find_last_user_stacklevel()\n            warnings.warn(\n                FALLBACK_WARNING.format(name=name),\n                stacklevel=stacklevel,\n                category=RuntimeWarning,\n            )\n            return func(*args, **kwargs)\n\n    wrapper._cunumeric_implemented = False\n\n    return wrapper\n\n\ndef clone_module(\n    origin_module: ModuleType, new_globals: dict[str, Any]\n) -> None:\n    \"\"\"Copy attributes from one module to another, excluding submodules\n\n    Function types are wrapped with a decorator to report API calls. All\n    other values are copied as-is.\n\n    Parameters\n    ----------\n    origin_module : ModuleTpe\n        Existing module to clone attributes from\n\n    new_globals : dict\n        a globals() dict for the new module to clone into\n\n    Returns\n    -------\n    None\n\n    \"\"\"\n    mod_name = origin_module.__name__\n\n    missing = filter_namespace(\n        origin_module.__dict__,\n        omit_names=set(new_globals).union(MOD_INTERNAL),\n        omit_types=(ModuleType,),\n    )\n\n    reporting = runtime.report_coverage\n\n    from ._ufunc.ufunc import ufunc as lgufunc\n\n    for attr, value in new_globals.items():\n        if isinstance(value, (FunctionType, lgufunc)):\n            wrapped = implemented(\n                cast(AnyCallable, value), mod_name, attr, reporting=reporting\n            )\n            new_globals[attr] = wrapped\n\n    from numpy import ufunc as npufunc\n\n    for attr, value in missing.items():\n        if isinstance(value, (FunctionType, npufunc)):\n            wrapped = unimplemented(value, mod_name, attr, reporting=reporting)\n            new_globals[attr] = wrapped\n        else:\n            new_globals[attr] = value\n\n\ndef clone_class(origin_class: type) -> Callable[[type], type]:\n    \"\"\"Copy attributes from one class to another\n\n    Method types are wrapped with a decorator to report API calls. All\n    other values are copied as-is.\n\n    Parameters\n    ----------\n    origin_class : type\n        Existing class type to clone attributes from\n\n    \"\"\"\n\n    def should_wrap(obj: object) -> bool:\n        return isinstance(\n            obj, (FunctionType, MethodType, MethodDescriptorType)\n        )\n\n    def decorator(cls: type) -> type:\n        class_name = f\"{origin_class.__module__}.{origin_class.__name__}\"\n\n        missing = filter_namespace(\n            origin_class.__dict__,\n            # this simply omits ndarray internal methods for any class. If\n            # we ever need to wrap more classes we may need to generalize to\n            # per-class specification of internal names to skip\n            omit_names=set(cls.__dict__).union(NDARRAY_INTERNAL),\n        )\n\n        reporting = runtime.report_coverage\n\n        for attr, value in cls.__dict__.items():\n            if should_wrap(value):\n                wrapped = implemented(\n                    value, class_name, attr, reporting=reporting\n                )\n                setattr(cls, attr, wrapped)\n\n        for attr, value in missing.items():\n            if should_wrap(value):\n                wrapped = unimplemented(\n                    value, class_name, attr, reporting=reporting\n                )\n                setattr(cls, attr, wrapped)\n            else:\n                setattr(cls, attr, value)\n\n        return cls\n\n    return decorator\n", "path": "cunumeric/coverage.py"}]}