Skip to content

Commit ab6c0af

Browse files
authored
fix: do not leak api wrappers (microsoft#495)
1 parent 63ea579 commit ab6c0af

File tree

1 file changed

+16
-14
lines changed

1 file changed

+16
-14
lines changed

playwright/_impl/_impl_to_api_mapping.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@
1414

1515
import inspect
1616
from typing import Any, Callable, Dict, List, Optional
17-
from weakref import WeakKeyDictionary
1817

1918
from playwright._impl._api_types import Error
2019

20+
INSTANCE_ATTR = "_pw_api_instance"
21+
2122

2223
class ImplWrapper:
2324
def __init__(self, impl_obj: Any) -> None:
@@ -27,7 +28,6 @@ def __init__(self, impl_obj: Any) -> None:
2728
class ImplToApiMapping:
2829
def __init__(self) -> None:
2930
self._mapping: Dict[type, type] = {}
30-
self._instances: WeakKeyDictionary[Any, Any] = WeakKeyDictionary()
3131

3232
def register(self, impl_class: type, api_class: type) -> None:
3333
self._mapping[impl_class] = api_class
@@ -39,13 +39,15 @@ def from_maybe_impl(self, obj: Any) -> Any:
3939
return {name: self.from_maybe_impl(value) for name, value in obj.items()}
4040
if isinstance(obj, list):
4141
return [self.from_maybe_impl(item) for item in obj]
42-
if obj not in self._instances:
43-
api_class = self._mapping.get(type(obj))
44-
if not api_class:
45-
return obj
46-
api_instance = api_class(obj)
47-
self._instances[obj] = api_instance
48-
return self._instances[obj]
42+
api_class = self._mapping.get(type(obj))
43+
if api_class:
44+
api_instance = getattr(obj, INSTANCE_ATTR, None)
45+
if not api_instance:
46+
api_instance = api_class(obj)
47+
setattr(obj, INSTANCE_ATTR, api_instance)
48+
return api_instance
49+
else:
50+
return obj
4951

5052
def from_impl(self, obj: Any) -> Any:
5153
assert obj
@@ -77,14 +79,14 @@ def to_impl(self, obj: Any) -> Any:
7779
raise Error("Maximum argument depth exceeded")
7880

7981
def wrap_handler(self, handler: Callable[..., None]) -> Callable[..., None]:
80-
if handler in self._instances:
81-
return self._instances[handler]
82-
83-
def wrapper(*args: Any) -> Any:
82+
def wrapper_func(*args: Any) -> Any:
8483
arg_count = len(inspect.signature(handler).parameters)
8584
return handler(
8685
*list(map(lambda a: self.from_maybe_impl(a), args))[:arg_count]
8786
)
8887

89-
self._instances[handler] = wrapper
88+
wrapper = getattr(handler, INSTANCE_ATTR, None)
89+
if not wrapper:
90+
wrapper = wrapper_func
91+
setattr(handler, INSTANCE_ATTR, wrapper)
9092
return wrapper

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy