NVIDIA / NVIDIA/cuopt

[FEA] Enforce input types across the routing Python API (type hints + centralized validation)

Open
#1,547 3 comments 0 reactions 1 assignee View on GitHub

@chris-maes is already working on this.

Since Jul 9, 2026.

awaiting response feature request
Dominant language
Cuda
Stars
1k
Forks
233
Avg merge
4d 4h
Merged PRs (30d)
95

Description

Is your feature request related to a problem? Please describe.

The routing Python API (DataModel setters, Solve, SolverSettings, Assignment) does not enforce input types consistently:

  • Historically, inputs had to be cuDF but were only checked incidentally — e.g. a numpy/pandas input failed with a cryptic AttributeError: 'numpy.ndarray' object has no attribute '__cuda_array_interface__' rather than a clear type error.
  • PR #1546 added numpy/pandas support via shared helpers (type_cast / prepare_matrix) that normalize numpy/pandas/cuDF and reject Python lists — but enforcement is per-setter and easy to bypass. That work uncovered set_order_prizes silently bypassing the shared type_cast (it called .astype() directly), which only surfaced through a comprehensive cross-backend test, not any type check.
  • There are no PEP 484 type annotations on the public API, so IDEs/mypy cannot catch wrong types, and error messages are inconsistent.

Describe the solution you'd like

Consistent, centralized type enforcement for the routing Python API:

  1. Route every array/scalar parameter through one shared validate-and-normalize helper — no setter may access the device pointer without going through it.
  2. Add PEP 484 type hints to the public classes/methods (DataModel, SolverSettings, Solve, Assignment) declaring accepted types (numpy.ndarray, pandas.Series/DataFrame, cudf.Series/DataFrame), checkable by mypy/IDEs.
  3. Fail fast with a consistent TypeError/ValueError on unsupported types (e.g. Python lists/tuples), wrong dtype, or wrong shape.
  4. Add a test/lint guard that fails if a setter dereferences __cuda_array_interface__ / builds a device pointer without going through the shared helper — preventing future set_order_prizes-style bypasses.

Describe alternatives you've considered

  • Docstring-only documentation of accepted types (current state) — not enforced, no tooling support.
  • Per-setter ad-hoc isinstance checks — inconsistent and prone to drift (this is what caused the set_order_prizes gap).
  • Runtime validation decorator vs. typing.get_type_hints introspection for the enforcement mechanism — to be decided during design.

Additional context

  • Related PR: #1546 (numpy/pandas input support in routing DataModel).
  • Shared helpers today: type_cast / prepare_matrix in python/cuopt/cuopt/routing/vehicle_routing_wrapper.pyx; validators in python/cuopt/cuopt/routing/validation.py.
  • Consider extending the same policy to the LP/MILP/QP (numerical optimization) Python API for API consistency.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.