cuda.core: accept dict for XyzOptions that are extension types - #2634
cuda.core: accept dict for XyzOptions that are extension types#2634juenglin wants to merge 2 commits into
Conversation
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
|
/ok to test 3c027ea |
|
There was a problem hiding this comment.
I think the stubgen-pyx workaround is ultimately unnecessary. Cython doesn't care about the annotation, so we can just set them directly to what we want them to be in the .pyi.
We can declare or not declare whether we accept a dict in the type annotation (that's sort of a larger question we are trying to answer offline -- whether we want to /commit/ to that).
But the tests on their own if useful if we decide we want to accept dicts going forward.
I should add Cython is a weird tool and Python type annotations being informational-only are pretty unique among languages. When you put them together (Cython pre-dates Python type annotations by at least a decade), it's a very confusing mishmash.
That's not what I found. If you run the tests added by this PR against a main build, you will find that they are failing. I dislike this change also and would be happy to close this PR. But that requires that we accept the behavior change introduced by PR #2619. |
Ah, you are right. I was thinking of
Yeah, this is kind of a mess with the way Cython uses type annotations for runtime semantic behavior (which is not how Python works at all). We should probably discuss the best way forward at the next meeting. |
3c027ea to
4a030f2
Compare
|
/ok to test 4a030f2 |
There was a problem hiding this comment.
This is 100% a more manageable solution than the previous one, and I'd be fine merging this on a technical/maintenance level.
Not approving just yet because:
-
I think we should have one more quick round of discussion to make sure this is directionally where we want to go
-
If this is, let's add some AGENTS.md comments recommending this annotation on
cdef classmethods that accept option classes (or whatever the exact "rule" we need to apply is).
Restores undocumented dict acceptance for
optionsin severalcuda.coreconstructors/methods, which was inadvertently removed by #2619. Covers the three memory-resource constructors and the stream-creation path (Stream._init,Context.create_stream).Why this is necessary
check_or_create_options(cuda_core/cuda/core/_utils/cuda_utils.pyx) normalizes a plaindictinto the options dataclass viacls(**options), so passing a dict foroptionshas always worked at runtime. The options classes (DeviceMemoryResourceOptions,StreamOptions, etc.) are@dataclass cdef class— Cython extension types.Cython enforces PEP-484 parameter annotations at the call boundary of
defmethods oncdef classes: when a parameter is annotated with an extension type, Cython emits a runtimeisinstancecheck that rejects other types (includingdict) withTypeErrorbefore the method body runs. See the "Extension types and None" section of the Extension Types guide.#2619 removed
| dict[str, object]from these annotations so the public stubs would show only the typed dataclass. That was correct in spirit, but it turned the call-boundary check into a regression: dicts that previously flowed through tocheck_or_create_optionsnow get rejected at the boundary, silently breaking any code relying on the dict shorthand.What this PR does
Applies Cython's
@cython.annotation_typing(False)compiler directive to each affecteddefmethod. The directive tells Cython to ignore the PEP-484 annotations for its own type analysis, so the parameter is treated as a genericobjectat the call boundary and dicts pass through tocheck_or_create_options. The annotations remain in the source and are still picked up bystubgen-pyx, so the generated.pyistubs naturally show the cleanXxxOptions | Nonesignature — no stub postprocessor needed. See the "Disabling annotations" section of the Pure Python Mode guide.Changes
cuda_core/cuda/core/_memory/_device_memory_resource.pyx,_managed_memory_resource.pyx,_pinned_memory_resource.pyx:@cython.annotation_typing(False)on each__init__;optionsannotation restored toXxxOptions | None = None.cuda_core/cuda/core/_stream.pyx:@cython.annotation_typing(False)onStream._init.cuda_core/cuda/core/_context.pyx:@cython.annotation_typing(False)onContext.create_stream.tests/memory/test_backward_compatibility.py: tests asserting each memory-resource constructor accepts a plain dict foroptions.tests/test_stream.py: test assertingDevice.create_streamaccepts a plain dict foroptions.Generated
.pyistubs are unchanged by re-runningstubgen-pyx(idempotent): the directive is invisible to the stub generator and the source annotations are preserved verbatim.closes #2248