Skip to content

Commit 29f5d60

Browse files
committed
fix: support **kwargs in taskgraph.util.memoize
Previously this decorator only accepted `*args`, so any memoized function that used `**kwargs` could no longer be called via keyword arguments. This is handled by replacing our custom memoize implementation with the built-in `functools.lru_cache(maxsize=None)` which is equivalent.
1 parent 0cbd14a commit 29f5d60

File tree

5 files changed

+14
-112
lines changed

5 files changed

+14
-112
lines changed

src/taskgraph/transforms/run/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ def add_resource_monitor(config, tasks):
167167
config.graph_config, task["worker-type"]
168168
)
169169
# Normalise worker os so that linux-bitbar and similar use linux tools.
170-
worker_os = worker_os.split("-")[0]
170+
if worker_os:
171+
worker_os = worker_os.split("-")[0]
171172
if "win7" in task["worker-type"]:
172173
arch = "32"
173174
else:

src/taskgraph/util/memoize.py

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,6 @@
22
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
33
# You can obtain one at http://mozilla.org/MPL/2.0/.
44

5-
# Imported from
6-
# https://searchfox.org/mozilla-central/rev/c3ebaf6de2d481c262c04bb9657eaf76bf47e2ac/python/mozbuild/mozbuild/util.py#923-949
7-
8-
95
import functools
106

11-
12-
class memoize(dict):
13-
"""A decorator to memoize the results of function calls depending
14-
on its arguments.
15-
Both functions and instance methods are handled, although in the
16-
instance method case, the results are cache in the instance itself.
17-
"""
18-
19-
def __init__(self, func):
20-
self.func = func
21-
functools.update_wrapper(self, func)
22-
23-
def __call__(self, *args):
24-
if args not in self:
25-
self[args] = self.func(*args)
26-
return self[args]
27-
28-
def method_call(self, instance, *args):
29-
name = "_%s" % self.func.__name__
30-
if not hasattr(instance, name):
31-
setattr(instance, name, {})
32-
cache = getattr(instance, name)
33-
if args not in cache:
34-
cache[args] = self.func(instance, *args)
35-
return cache[args]
36-
37-
def __get__(self, instance, cls):
38-
return functools.update_wrapper(
39-
functools.partial(self.method_call, instance), self.func
40-
)
7+
memoize = functools.lru_cache(maxsize=None) # backwards compatibility shim

test/test_util_memoize.py

Lines changed: 0 additions & 66 deletions
This file was deleted.

test/test_util_parameterization.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ def assert_artifact_refs(monkeypatch):
150150

151151
def inner(input, output):
152152
# Clear memoized function
153-
get_root_url.clear()
153+
get_root_url.cache_clear()
154154
taskid_for_edge_name = {"edge%d" % n: "tid%d" % n for n in range(1, 4)}
155155
assert (
156156
resolve_task_references(

test/test_util_taskcluster.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,30 +28,30 @@ def mock_production_taskcluster_root_url(monkeypatch):
2828

2929
@pytest.fixture
3030
def root_url(mock_environ):
31-
tc.get_root_url.clear()
31+
tc.get_root_url.cache_clear()
3232
return tc.get_root_url(False)
3333

3434

3535
@pytest.fixture
3636
def proxy_root_url(monkeypatch, mock_environ):
3737
monkeypatch.setenv("TASK_ID", "123")
3838
monkeypatch.setenv("TASKCLUSTER_PROXY_URL", "https://taskcluster-proxy.net")
39-
tc.get_root_url.clear()
39+
tc.get_root_url.cache_clear()
4040
return tc.get_root_url(True)
4141

4242

4343
def test_get_root_url(monkeypatch):
44-
tc.get_root_url.clear()
44+
tc.get_root_url.cache_clear()
4545
assert tc.get_root_url(False) == tc.PRODUCTION_TASKCLUSTER_ROOT_URL
4646

4747
custom_url = "https://taskcluster-root.net"
4848
monkeypatch.setenv("TASKCLUSTER_ROOT_URL", custom_url)
49-
tc.get_root_url.clear()
49+
tc.get_root_url.cache_clear()
5050
assert tc.get_root_url(False) == custom_url
5151

5252
# trailing slash is normalized
5353
monkeypatch.setenv("TASKCLUSTER_ROOT_URL", custom_url + "/")
54-
tc.get_root_url.clear()
54+
tc.get_root_url.cache_clear()
5555
assert tc.get_root_url(False) == custom_url
5656

5757
with pytest.raises(RuntimeError):
@@ -66,7 +66,7 @@ def test_get_root_url(monkeypatch):
6666
proxy_url = "https://taskcluster-proxy.net"
6767
monkeypatch.setenv("TASKCLUSTER_PROXY_URL", proxy_url)
6868
assert tc.get_root_url(True) == proxy_url
69-
tc.get_root_url.clear()
69+
tc.get_root_url.cache_clear()
7070

7171
# no default set
7272
monkeypatch.setattr(tc, "PRODUCTION_TASKCLUSTER_ROOT_URL", None)
@@ -382,8 +382,8 @@ def test_list_task_group_incomplete_tasks(responses, root_url):
382382

383383

384384
def test_get_ancestors(responses, root_url):
385-
tc.get_task_definition.clear()
386-
tc._get_deps.clear()
385+
tc.get_task_definition.cache_clear()
386+
tc._get_deps.cache_clear()
387387
base_url = f"{root_url}/api/queue/v1/task"
388388
responses.add(
389389
responses.GET,
@@ -457,8 +457,8 @@ def test_get_ancestors(responses, root_url):
457457

458458

459459
def test_get_ancestors_string(responses, root_url):
460-
tc.get_task_definition.clear()
461-
tc._get_deps.clear()
460+
tc.get_task_definition.cache_clear()
461+
tc._get_deps.cache_clear()
462462
base_url = f"{root_url}/api/queue/v1/task"
463463
responses.add(
464464
responses.GET,

0 commit comments

Comments
 (0)