Skip to content

cuda.core: accept dict for XyzOptions that are extension types - #2634

Open
juenglin wants to merge 2 commits into
NVIDIA:mainfrom
juenglin:mr-options-backward-compatibility
Open

cuda.core: accept dict for XyzOptions that are extension types#2634
juenglin wants to merge 2 commits into
NVIDIA:mainfrom
juenglin:mr-options-backward-compatibility

Conversation

@juenglin

@juenglin juenglin commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Restores undocumented dict acceptance for options in several cuda.core constructors/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 plain dict into the options dataclass via cls(**options), so passing a dict for options has 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 def methods on cdef classes: when a parameter is annotated with an extension type, Cython emits a runtime isinstance check that rejects other types (including dict) with TypeError before 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 to check_or_create_options now 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 affected def method. The directive tells Cython to ignore the PEP-484 annotations for its own type analysis, so the parameter is treated as a generic object at the call boundary and dicts pass through to check_or_create_options. The annotations remain in the source and are still picked up by stubgen-pyx, so the generated .pyi stubs naturally show the clean XxxOptions | None signature — 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__; options annotation restored to XxxOptions | None = None.
  • cuda_core/cuda/core/_stream.pyx: @cython.annotation_typing(False) on Stream._init.
  • cuda_core/cuda/core/_context.pyx: @cython.annotation_typing(False) on Context.create_stream.
  • tests/memory/test_backward_compatibility.py: tests asserting each memory-resource constructor accepts a plain dict for options.
  • tests/test_stream.py: test asserting Device.create_stream accepts a plain dict for options.

Generated .pyi stubs are unchanged by re-running stubgen-pyx (idempotent): the directive is invisible to the stub generator and the source annotations are preserved verbatim.

closes #2248

@copy-pr-bot

copy-pr-bot Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

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.

@github-actions github-actions Bot added the cuda.core Everything related to the cuda.core module label Aug 14, 2026
@juenglin juenglin self-assigned this Aug 14, 2026
@juenglin juenglin added this to the cuda.core 1.2.0 milestone Aug 14, 2026
@juenglin

Copy link
Copy Markdown
Contributor Author

/ok to test 3c027ea

@github-actions

Copy link
Copy Markdown

@juenglin
juenglin requested review from leofang and mdboom and removed request for leofang August 14, 2026 20:25
@juenglin
juenglin marked this pull request as ready for review August 14, 2026 20:25
@juenglin juenglin added the documentation Improvements or additions to documentation label Aug 14, 2026
Comment thread toolshed/run_stubgen_pyx.py Outdated

@mdboom mdboom left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@juenglin

juenglin commented Aug 14, 2026

Copy link
Copy Markdown
Contributor Author

Cython doesn't care about the annotation, so we can just set them directly to what we want them to be in the .pyi.

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.

@mdboom

mdboom commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Cython doesn't care about the annotation, so we can just set them directly to what we want them to be in the .pyi.

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.

Ah, you are right. I was thinking of cdef functions/methods, not def ones.

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.

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.

@juenglin juenglin added the PR review get-together Mark PRs you'd like the team to review at the weekly PR review get-together. label Aug 17, 2026
@juenglin
juenglin marked this pull request as draft August 26, 2026 21:11
@juenglin
juenglin force-pushed the mr-options-backward-compatibility branch from 3c027ea to 4a030f2 Compare August 26, 2026 21:23
@juenglin juenglin changed the title cuda.core: accept dict for options in MemoryResource constructors cuda.core: accept dict for XyzOptions that are extension types Aug 26, 2026
@juenglin

Copy link
Copy Markdown
Contributor Author

/ok to test 4a030f2

@juenglin
juenglin requested a review from mdboom August 26, 2026 21:51
@juenglin
juenglin marked this pull request as ready for review August 26, 2026 21:51
@juenglin
juenglin enabled auto-merge (squash) August 26, 2026 22:48

@mdboom mdboom left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

  1. I think we should have one more quick round of discussion to make sure this is directionally where we want to go

  2. If this is, let's add some AGENTS.md comments recommending this annotation on cdef class methods that accept option classes (or whatever the exact "rule" we need to apply is).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cuda.core Everything related to the cuda.core module documentation Improvements or additions to documentation PR review get-together Mark PRs you'd like the team to review at the weekly PR review get-together.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[DOC]: cuda.core docs/type hints understate option params since dict is accepted at runtime but not documented

2 participants