datamodel-code-generator
datamodel-code-generator copied to clipboard
Regex pattern in JSON schema results in PyLance error
I believe the pattern matching described in #470 may no longer be compatible with PyLance. For example, creating a json schema like:
properties = {
'session': {
'type': 'string',
'pattern': '^((staging)|(production)):{0-9}+',
results in a PyDantic model:
class State(BaseModel):
session: Optional[constr(regex=r'^((staging)|(production)):{0-9}+')]
but this triggers
Call expression not allowed in type expression Pylance[reportInvalidTypeForm](https://github.com/microsoft/pyright/blob/main/docs/configuration.md#reportInvalidTypeForm).
See this issue via PyLance for more detail.
this happens with integer type when min/max is applied as well.
sample schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"adapter_port": {
"type": "integer",
"description": "The adapter's SHDR port",
"default": 7878,
"minimum": 1,
"maximum": 65535
},
"agent_port": {
"type": "integer",
"description": "MTConnect Agent port",
"default": 5000,
"minimum": 1,
"maximum": 65535
}
},
"required": [
"adapter_port",
"agent_port"
]
}
output:
# generated by datamodel-codegen:
# filename: schema.json
# timestamp: 2024-10-14T22:59:46+00:00
from __future__ import annotations
from pydantic import BaseModel, Field, conint
class Model(BaseModel):
adapter_port: conint(ge=1, le=65535) = Field(
..., description="The adapter's SHDR port"
)
agent_port: conint(ge=1, le=65535) = Field(..., description='MTConnect Agent port')
and pylance complains:
Edit to add the docs vscode shows me:
!!! warning "Discouraged"
This function is discouraged in favor of using Annotated with [Field][pydantic.fields.Field] instead. This function will be deprecated in Pydantic 3.0. The reason is that conint returns a type, which doesn't play well with static analysis tools. === ":x: Don't do this"
py from pydantic import BaseModel, conint class Foo(BaseModel): bar: conint(strict=True, gt=0) === ":white_check_mark: Do this" py from typing_extensions import Annotated from pydantic import BaseModel, Field class Foo(BaseModel): bar: Annotated[int, Field(strict=True, gt=0)]A wrapper around int that allows for additional constraints.
Args strict Whether to validate the integer in strict mode. Defaults to None.
gt The value must be greater than this.
ge The value must be greater than or equal to this.
lt The value must be less than this.
le The value must be less than or equal to this.
multiple_of The value must be a multiple of this.
Returns out The wrapped integer type.
py from pydantic import BaseModel, ValidationError, conint class ConstrainedExample(BaseModel): constrained_int: conint(gt=1) m = ConstrainedExample(constrained_int=2) print(repr(m)) #> ConstrainedExample(constrained_int=2) try: ConstrainedExample(constrained_int=0) except ValidationError as e: print(e.errors()) ''' [ { 'type': 'greater_than', 'loc': ('constrained_int',), 'msg': 'Input should be greater than 1', 'input': 0, 'ctx': {'gt': 1}, 'url': 'https://errors.pydantic.dev/2/v/greater_than', } ] '''
I was able to overcome this issue by passing --use-annotated and --field-constraints , with the mention that the docs for --use-annotated lead you to believe that field constraints is enabled by default. Maybe that's the case when using the CLI, but I was using the module programmatically