Skip to content

Move custom code to dedicated files and cleanup v1 vs v2 checks#331

Merged
pirate merged 3 commits intopydantic-extractfrom
pydantic-extract-cleanup
Apr 1, 2026
Merged

Move custom code to dedicated files and cleanup v1 vs v2 checks#331
pirate merged 3 commits intopydantic-extractfrom
pydantic-extract-cleanup

Conversation

@pirate
Copy link
Copy Markdown
Member

@pirate pirate commented Apr 1, 2026

Summary by cubic

Moved Pydantic extract logic into a dedicated module and auto-patched Session/AsyncSession to use it. Hard-required pydantic v2 at import time and added tests for extract behavior.

  • Refactors

    • Added src/stagehand/_session_extract.py and auto-installed the extract patch in sessions_helpers.
    • Centralized Pydantic response validation in _pydantic_extract.py with cached model config and strict_response_validation.
    • Enforced pydantic v2 in _compat.py with a clear ImportError.
    • Simplified session.py by delegating extract logic and removing v1/v2 conditionals; added focused tests for session extract.
  • Migration

    • stagehand now requires pydantic>=2,<3. Install or upgrade to v2.
    • Removed the pydantic-v2 extra from pyproject.toml; use standard pydantic v2 installation.

Written for commit 297fe85. Summary will update on new commits. Review in cubic

@pirate pirate merged commit 64c1b15 into pydantic-extract Apr 1, 2026
3 of 4 checks passed
@pirate pirate mentioned this pull request Apr 1, 2026
1 task
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 9 files

Confidence score: 4/5

  • This PR looks safe to merge; the only issue is a test skip reason string mismatch, which is low impact and mostly clarity/documentation.
  • In tests/test_models.py, the skip reason references TypeAliasType but the test is unrelated, which could confuse future maintenance or test intent.
  • Pay close attention to tests/test_models.py - ensure the skip reason accurately reflects why the test is skipped on v1.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="tests/test_models.py">

<violation number="1" location="tests/test_models.py:836">
P2: Incorrect skip reason: this test has nothing to do with `TypeAliasType`. The reason string was copy-pasted from `test_type_alias_type` above. If skipping on v1 is intentional, update the reason to explain the actual incompatibility (e.g., `cls` field handling).</violation>
</file>
Architecture diagram
sequenceDiagram
    participant User as Client Code
    participant Session as Session / AsyncSession
    participant Patch as Session Extract Patch
    participant PydanticUtil as Pydantic Extract Utility
    participant API as Stagehand API
    participant Pydantic as Pydantic V2

    Note over Session, Patch: NEW: Patch installed via sessions_helpers.py

    User->>Session: extract(schema=MyModel, ...)
    Session->>Patch: NEW: _sync_extract / _async_extract

    alt Schema is Pydantic Model
        Patch->>PydanticUtil: is_pydantic_model(schema)
        PydanticUtil-->>Patch: True
        Patch->>PydanticUtil: pydantic_model_to_json_schema(MyModel)
        PydanticUtil->>Pydantic: model_json_schema()
        Pydantic-->>Patch: JSON Schema dict
    end

    Patch->>API: POST /v1/sessions/{id}/extract (with JSON schema)
    API-->>Patch: SessionExtractResponse (raw JSON result)

    Note right of Patch: CHANGED: Extract logic moved from Session to Patch

    alt Pydantic Model used & Response exists
        Patch->>PydanticUtil: NEW: validate_extract_response(result, MyModel)
        
        PydanticUtil->>PydanticUtil: NEW: _validation_schema(cache lookup)
        Note over PydanticUtil: Applies strict_response_validation flag
        
        PydanticUtil->>Pydantic: model_validate(result)
        
        alt Validation Fails
            PydanticUtil->>PydanticUtil: _convert_dict_keys_to_snake_case()
            PydanticUtil->>Pydantic: model_validate(normalized_result)
        end
        
        PydanticUtil-->>Patch: MyModel Instance (or raw data if fail)
    end

    Patch-->>User: SessionExtractResponse (data.result = MyModel)

    Note over PydanticUtil, Pydantic: CHANGED: Pydantic v2 is now strictly required
Loading

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

assert DISCRIMINATOR_CACHE.get(UnionType) is discriminator


@pytest.mark.skipif(PYDANTIC_V1, reason="TypeAliasType is not supported in Pydantic v1")
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot Apr 2, 2026

Choose a reason for hiding this comment

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

P2: Incorrect skip reason: this test has nothing to do with TypeAliasType. The reason string was copy-pasted from test_type_alias_type above. If skipping on v1 is intentional, update the reason to explain the actual incompatibility (e.g., cls field handling).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tests/test_models.py, line 836:

<comment>Incorrect skip reason: this test has nothing to do with `TypeAliasType`. The reason string was copy-pasted from `test_type_alias_type` above. If skipping on v1 is intentional, update the reason to explain the actual incompatibility (e.g., `cls` field handling).</comment>

<file context>
@@ -791,6 +833,7 @@ class B(BaseModel):
     assert DISCRIMINATOR_CACHE.get(UnionType) is discriminator
 
 
+@pytest.mark.skipif(PYDANTIC_V1, reason="TypeAliasType is not supported in Pydantic v1")
 def test_type_alias_type() -> None:
     Alias = TypeAliasType("Alias", str)  # pyright: ignore
</file context>
Suggested change
@pytest.mark.skipif(PYDANTIC_V1, reason="TypeAliasType is not supported in Pydantic v1")
@pytest.mark.skipif(PYDANTIC_V1, reason="field named 'cls' is not supported in Pydantic v1")
Fix with Cubic

pirate added a commit that referenced this pull request Apr 2, 2026
* Support pydantic models as schemas for extract

* pop schema

* bump pydantic dep and linting fixes

* update tests to remove pydantic v1 tests

* Move custom code to dedicated files and cleanup v1 vs v2 checks (#331)

* move custom code to dedicated files and cleanup v1 vs v2 checks

* hard-require pydantic v2 or greater

* lint

* lint fixes after merge

* Centralize extract patching in sessions helpers

* Bound extract validation schema cache

---------

Co-authored-by: Nick Sweeting <github@sweeting.me>
Co-authored-by: Nick Sweeting <git@sweeting.me>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant