Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- First‑class support for **open‑source models via third‑party providers** (e.g. OpenRouter, Groq and similar gateways), alongside existing Ollama + cloud integrations.

### Fixed
- TBC
- Reject Python keywords as field names before generating DSPy signatures.

---

Expand Down
3 changes: 2 additions & 1 deletion dspy_code/validation/input_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
Provides validation methods for user input during interactive task collection.
"""

import keyword
from typing import Any


Expand All @@ -27,7 +28,7 @@ def validate_field_name(self, name: str) -> str:

# Check for valid Python identifier
name = name.strip()
if not name.isidentifier():
if not name.isidentifier() or keyword.iskeyword(name):
raise ValidationError(f"'{name}' is not a valid Python identifier")

return name
Expand Down
20 changes: 20 additions & 0 deletions tests/test_input_field_names.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""Field names must be usable in generated Python signatures."""

import keyword

import pytest

from dspy_code.validation.input_validator import InputValidator, ValidationError


@pytest.mark.parametrize("name", keyword.kwlist)
def test_field_name_rejects_python_keywords(name):
with pytest.raises(ValidationError, match="not a valid Python identifier"):
InputValidator().validate_field_name(name)


@pytest.mark.parametrize("name", ["question", "class_", "_answer", "café", "match", "case"])
def test_field_name_accepts_usable_identifiers(name):
validated = InputValidator().validate_field_name(" " + name + " ")
assert validated == name
compile(f"class Signature:\n {validated}: str\n", "<signature>", "exec")