Skip to content

Commit 44daf43

Browse files
authored
[eudsl-python-extras] better handle callable generics (#231)
This PR demos passing actual functions as generics (I don't have a fancy name for this...). There's no real new functionality, just better name mangling for such generics. Also drive-by changes: - enable testing on `3.10`, `3.11`, `3.12` for all of our python-esque tests (and fix `StrEnum` on `3.10` for eudsl-python-extras) - move to using `bytecode` from pypi instead of source. - fix some other GHA stuff
1 parent 5237833 commit 44daf43

File tree

11 files changed

+336
-59
lines changed

11 files changed

+336
-59
lines changed

.github/workflows/build_mlir_python_bindings_wheel.yml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ jobs:
206206
"windows-2022"
207207
]
208208
python-version: [
209-
# "3.10", "3.11", "3.12",
209+
"3.10", "3.11", "3.12",
210210
"3.13", "3.14", "3.14t"
211211
]
212212
include: [
@@ -230,6 +230,21 @@ jobs:
230230
- runs-on: macos-13
231231
python-version: "3.14t"
232232

233+
- runs-on: macos-14
234+
python-version: "3.10"
235+
236+
- runs-on: macos-14
237+
python-version: "3.11"
238+
239+
- runs-on: macos-14
240+
python-version: "3.12"
241+
242+
- runs-on: macos-14
243+
python-version: "3.13"
244+
245+
- runs-on: macos-14
246+
python-version: "3.14"
247+
233248
runs-on: ${{ matrix.runs-on }}
234249

235250
name: "Test mlir-python-bindings ${{ matrix.name }} ${{ matrix.python-version }}"

.github/workflows/build_test_release_eudsl.yml

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -277,8 +277,8 @@ jobs:
277277
# "macos-13",
278278
"macos-14", "windows-2022"]
279279
python-version: [
280-
# "3.9", "3.10", "3.11",
281-
"3.12", "3.13"
280+
"3.10", "3.11", "3.12",
281+
"3.13", "3.14", "3.14t"
282282
]
283283
include: [
284284
{runs-on: "ubuntu-22.04", name: "ubuntu_x86_64", os: "ubuntu"},
@@ -291,6 +291,21 @@ jobs:
291291
- runs-on: macos-13
292292
python-version: "3.13"
293293

294+
- runs-on: macos-14
295+
python-version: "3.10"
296+
297+
- runs-on: macos-14
298+
python-version: "3.11"
299+
300+
- runs-on: macos-14
301+
python-version: "3.12"
302+
303+
- runs-on: macos-14
304+
python-version: "3.13"
305+
306+
- runs-on: macos-14
307+
python-version: "3.14"
308+
294309
runs-on: ${{ matrix.runs-on }}
295310

296311
name: "Test tblgen ${{ matrix.name }} ${{ matrix.python-version }}"
@@ -306,7 +321,7 @@ jobs:
306321
submodules: false
307322

308323
- name: "Install Python"
309-
uses: actions/setup-python@v4
324+
uses: actions/setup-python@v6.0.0
310325
with:
311326
python-version: "${{ matrix.python-version }}"
312327

@@ -348,8 +363,11 @@ jobs:
348363
"windows-2022"
349364
]
350365
python-version: [
366+
# we only build 3.12 and up
351367
# "3.10", "3.11",
352-
"3.12", "3.13"
368+
"3.12", "3.13", "3.14",
369+
# stable abi doesn't support 3.14t?
370+
# "3.14t"
353371
]
354372
include: [
355373
{runs-on: "ubuntu-22.04", name: "ubuntu_x86_64", os: "ubuntu"},
@@ -362,6 +380,18 @@ jobs:
362380
- runs-on: macos-13
363381
python-version: "3.13"
364382

383+
- runs-on: macos-14
384+
python-version: "3.10"
385+
386+
- runs-on: macos-14
387+
python-version: "3.11"
388+
389+
- runs-on: macos-14
390+
python-version: "3.12"
391+
392+
- runs-on: macos-14
393+
python-version: "3.13"
394+
365395
runs-on: ${{ matrix.runs-on }}
366396

367397
name: "Test llvmpy ${{ matrix.name }} ${{ matrix.python-version }}"
@@ -377,7 +407,7 @@ jobs:
377407
submodules: false
378408

379409
- name: "Install Python"
380-
uses: actions/setup-python@v4
410+
uses: actions/setup-python@v6.0.0
381411
with:
382412
python-version: "${{ matrix.python-version }}"
383413

@@ -445,7 +475,7 @@ jobs:
445475

446476
if: (github.event_name == 'push' && github.ref_name == 'main') || github.event_name == 'workflow_dispatch'
447477

448-
needs: [test-eudsl-llvmpy, test-eudsl-tblgen]
478+
needs: [release-eudsl]
449479

450480
permissions:
451481
contents: read

.github/workflows/build_test_release_eudsl_python_extras.yml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ jobs:
9494
"windows-2022"
9595
]
9696
python-version: [
97-
# "3.10", "3.11", "3.12",
97+
"3.10", "3.11", "3.12",
9898
"3.13", "3.14", "3.14t"
9999
]
100100
include: [
@@ -118,6 +118,21 @@ jobs:
118118
- runs-on: macos-13
119119
python-version: "3.14t"
120120

121+
- runs-on: macos-14
122+
python-version: "3.10"
123+
124+
- runs-on: macos-14
125+
python-version: "3.11"
126+
127+
- runs-on: macos-14
128+
python-version: "3.12"
129+
130+
- runs-on: macos-14
131+
python-version: "3.13"
132+
133+
- runs-on: macos-14
134+
python-version: "3.14"
135+
121136
runs-on: ${{ matrix.runs-on }}
122137

123138
name: "Test eudsl-python-extras ${{ matrix.name }} ${{ matrix.python-version }}"

.github/workflows/clean_releases.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
uses: actions/checkout@v2
2222

2323
- name: Setup Python
24-
uses: actions/setup-python@v4
24+
uses: actions/setup-python@v6.0.0
2525
with:
2626
python-version: "3.10"
2727

projects/eudsl-llvmpy/src/llvm/function.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,17 @@ def __init__(self, body_builder, *, return_type=None, entry_bb_name="entry"):
6565

6666
def _is_decl(self):
6767
# magic constant found from looking at the code for an empty fn
68+
if sys.version_info.minor == 14:
69+
return self.body_builder.__code__.co_code == b"\x80\x00R\x00#\x00"
6870
if sys.version_info.minor == 13:
6971
return self.body_builder.__code__.co_code == b"\x95\x00g\x00"
70-
elif sys.version_info.minor == 12:
72+
if sys.version_info.minor == 12:
7173
return self.body_builder.__code__.co_code == b"\x97\x00y\x00"
72-
elif sys.version_info.minor == 11:
74+
if sys.version_info.minor == 11:
7375
return self.body_builder.__code__.co_code == b"\x97\x00d\x00S\x00"
74-
elif sys.version_info.minor in {8, 9, 10}:
76+
if sys.version_info.minor in {8, 9, 10}:
7577
return self.body_builder.__code__.co_code == b"d\x00S\x00"
76-
else:
77-
raise NotImplementedError(f"{sys.version_info.minor} not supported.")
78+
raise NotImplementedError(f"{sys.version_info.minor} not supported.")
7879

7980
def __str__(self):
8081
return str(f"{self.__class__} {self.__dict__}")

projects/eudsl-python-extras/mlir/extras/ast/util.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def replace_closure(code, new_closure: Dict):
9292
LOAD_DEREF = opmap["LOAD_DEREF"]
9393

9494
# get the orig localplus that will be loaded from by the orig bytecode LOAD_DEREF arg_i
95-
localsplus, localsplus_name_to_idx = get_localsplus_name_to_idx(code)
95+
localsplus, _localsplus_name_to_idx = get_localsplus_name_to_idx(code)
9696

9797
# closure vars go into co_freevars
9898
new_code = code.replace(co_freevars=tuple(new_closure.keys()))
@@ -130,18 +130,23 @@ def reducer_override(self, obj):
130130
return super().reducer_override(obj)
131131

132132

133+
def copy_object(obj):
134+
# see https://github.com/cloudpipe/cloudpickle/blob/f111f7ab6d302e9b1e2a568d0e4c574895db6a6e/cloudpickle/cloudpickle.py#L813
135+
# for how this trick is accomplished (dill and pickle both fail to pickle eg generic typevars)
136+
with io.BytesIO() as file:
137+
cp = MLIRTypePickler(file)
138+
cp.dump(obj)
139+
obj = cloudpickle.loads(file.getvalue())
140+
return obj
141+
142+
133143
# Based on http://stackoverflow.com/a/6528148/190597 (Glenn Maynard);
134144
# potentially more complete approach https://stackoverflow.com/a/56901529/9045206
135145
def copy_func(f, new_closure: Dict = None):
136146
if new_closure is not None:
137147
code, closure = replace_closure(f.__code__, new_closure)
138148
else:
139-
# see https://github.com/cloudpipe/cloudpickle/blob/f111f7ab6d302e9b1e2a568d0e4c574895db6a6e/cloudpickle/cloudpickle.py#L813
140-
# for how this trick is accomplished (dill and pickle both fail to pickle eg generic typevars)
141-
with io.BytesIO() as file:
142-
cp = MLIRTypePickler(file)
143-
cp.dump(f.__closure__)
144-
closure = cloudpickle.loads(file.getvalue())
149+
closure = copy_object(f.__closure__)
145150
code = f.__code__
146151

147152
g = types.FunctionType(

0 commit comments

Comments
 (0)