fix deconstruct_function for python 3.11 (#17534)

This commit is contained in:
chenyu
2026-08-14 13:38:34 -04:00
committed by GitHub
parent 80169c6758
commit ac7067ac60
2 changed files with 9 additions and 4 deletions
+6 -1
View File
@@ -2,7 +2,7 @@ import unittest, pickle, types, tracemalloc
import numpy as np
from tinygrad import Tensor, Device, TinyJit, Variable, dtypes
from tinygrad.helpers import GlobalCounters, ContextVar, Context, DEV
from tinygrad.uop.ops import PatternMatcher, UPat, UOp
from tinygrad.uop.ops import PatternMatcher, UPat, UOp, deconstruct_function
class TestPickle(unittest.TestCase):
def test_pickle_code_object(self):
@@ -11,6 +11,11 @@ class TestPickle(unittest.TestCase):
fxn = types.FunctionType(pickle.loads(code_str), globals())
self.assertEqual(fxn(2), 4)
def test_deconstruct_function_nested_comprehension(self):
# pre PEP 709, each comprehension is its own code object, so dtypes here is referenced two code objects deep
def fxn(): return [[dtypes.int for _ in range(2)] for _ in range(2)]
self.assertEqual(types.FunctionType(*deconstruct_function(fxn))(), fxn())
def test_pickle_pattern_matcher(self):
pm = PatternMatcher([(UPat.cvar('x'), lambda x: x*2)])
sink = UOp.const(2)
+3 -3
View File
@@ -1423,9 +1423,9 @@ class UPat(OpMixin):
return res
def deconstruct_function(fxn:Callable) -> tuple:
new_globals = {k:v for k,v in fxn.__globals__.items() if k in fxn.__code__.co_names}
for co in fxn.__code__.co_consts:
if isinstance(co, types.CodeType): new_globals.update({k:v for k,v in fxn.__globals__.items() if k in co.co_names})
# globals can be referenced from arbitrarily nested code objects (comprehensions/lambdas, pre PEP 709)
def names(co:types.CodeType) -> set: return set(co.co_names).union(*(names(c) for c in co.co_consts if isinstance(c, types.CodeType)))
new_globals = {k:v for k,v in fxn.__globals__.items() if k in names(fxn.__code__)}
# NOTE: optional round trip through pickle!
assert fxn.__closure__ is None, "closures are not supported in pattern matchers"
ret = fxn.__code__, new_globals, fxn.__name__, fxn.__defaults__