Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up serialization warnings for invalid data in unions #1449

Merged
merged 4 commits into from
Sep 16, 2024

Conversation

sydney-runkle
Copy link
Member

@sydney-runkle sydney-runkle commented Sep 12, 2024

Fix pydantic/pydantic#10363
Fix pydantic/pydantic#10344

This makes it such that we report all warnings associated with union serialization. This is similar to union validation, where the errors can be quite verbose. One example that clearly demonstrates the change is the following. We used to raise one error saying expected Union[A, B], got C (or something similar). Now we report on all warnings.

from pydantic import BaseModel, TypeAdapter

class A(BaseModel):
    a: int

class B(BaseModel):
    b: int

class C(BaseModel):
    c: int

ta = TypeAdapter(A | B)
print(ta.dump_python(C(c=1)))

"""
PydanticSerializationUnexpectedValue: Expected `A` but got `C` with value `C(c=1)` - serialized value may not be as expected
PydanticSerializationUnexpectedValue: Expected `B` but got `C` with value `C(c=1)` - serialized value may not be as expected
"""

I think there's still more to improve here - we should probably group the errors more intuitively, and use shared logic across much of the PydanticSerializationUnexpectedValue initialization steps. Also, in the long term, we should remove the fallback to the union serializer for tagged unions and jump straight to inference instead. Will probably retain this for backwards compatibility for a few minor versions as we iron out small issues like this one.

Copy link

codspeed-hq bot commented Sep 12, 2024

CodSpeed Performance Report

Merging #1449 will not alter performance

Comparing warning-fix (d24aad5) with main (16331d7)

Summary

✅ 155 untouched benchmarks

@sydney-runkle sydney-runkle changed the title Fix errs -> warnings in union serialization Clean up serialization warnings for invalid data in unions Sep 13, 2024
@sydney-runkle
Copy link
Member Author

Currently, we don't warn on tagged unions. I'd like to move us to a place where we eventually don't fall back to untagged union serialization for tagged unions, at which point we can add in warnings for tagged unions.

@sydney-runkle
Copy link
Member Author

sydney-runkle commented Sep 16, 2024

A few test cases here:

from typing import Tuple

import pydantic


class Model(pydantic.BaseModel):
    values: Tuple[float, ...]


model = Model(values=(0, 1))
print(pydantic.__version__, repr(model), model.model_dump())
model = model.model_copy(deep=True, update={"values": [1, 2]})
print(pydantic.__version__, repr(model), model.model_dump())
model = model.model_validate(model)
print(pydantic.__version__, repr(model), model.model_dump())

"""
Model(values=(0.0, 1.0)) {'values': (0.0, 1.0)}
/Users/programming/pydantic_work/pydantic/pydantic/main.py:387: UserWarning: Pydantic serializer warnings:
  Expected `tuple[float, ...]` but got `list` with value `[1, 2]` - serialized value may not be as expected
  return self.__pydantic_serializer__.to_python(
Model(values=[1, 2]) {'values': [1, 2]}
Model(values=[1, 2]) {'values': [1, 2]}
"""
from pydantic import BaseModel, TypeAdapter

class A(BaseModel):
    a: int

class B(BaseModel):
    b: int

class C(BaseModel):
    c: int

ta = TypeAdapter(A | B)
print(ta.dump_python(C(c=1)))

"""
PydanticSerializationUnexpectedValue: Expected `A` but got `C` with value `C(c=1)` - serialized value may not be as expected
PydanticSerializationUnexpectedValue: Expected `B` but got `C` with value `C(c=1)` - serialized value may not be as expected
"""
from typing import Annotated, Literal, Union

from pydantic import BaseModel, Field


class Bar(BaseModel):
    discriminator_key: Literal["Bar"] = "Bar"
    name: str


class Foo(BaseModel):
    discriminator_key: Literal["Foo"] = "Foo"


class Container(BaseModel):

    prop: Annotated[Union[Bar, Foo], Field(..., discriminator="discriminator_key")]


bar = Bar.model_construct()
foo_child = Foo()
container = Container.model_construct(prop=bar)
print(bar.model_dump())
print(container.model_dump())

"""
PydanticSerializationUnexpectedValue: Expected 2 fields but got 1 for type `Bar` with value `Bar(discriminator_key='Bar')` - serialized value may not be as expected.
PydanticSerializationUnexpectedValue: Expected `Foo` but got `Bar` with value `Bar(discriminator_key='Bar')` - serialized value may not be as expected
"""

Comment on lines +395 to +403
let type_name = value
.get_type()
.qualname()
.unwrap_or_else(|_| PyString::new_bound(value.py(), "<unknown python object>"));

let value_str = truncate_safe_repr(value, None);
Err(PydanticSerializationUnexpectedValue::new_err(Some(format!(
"Expected `{field_type}` but got `{type_name}` with value `{value_str}` - serialized value may not be as expected"
))))
Copy link
Member Author

Choose a reason for hiding this comment

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

Admittedly is a bit redundant with existing code - would like to standardize how we raise serialization errors in pydantic-core for the v2.10 release :)

Copy link
Member Author

Choose a reason for hiding this comment

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

This case shows why we might want to do that - could probably minimize the duplicates here:

from typing import Annotated, FrozenSet, Union, Literal, List

from pydantic import BaseModel, PlainSerializer, IPvAnyAddress, Field
from ipaddress import IPv4Network

SortedFrozenNetworkSet = Annotated[
    FrozenSet[IPv4Network],
    PlainSerializer(
        lambda x: sorted(str(network) for network in x),
        return_type=FrozenSet[str],
    ),
]


class ModelA(BaseModel):
    type: Literal["A"]
    addresses: SortedFrozenNetworkSet


class ModelB(BaseModel):
    type: Literal["B"]
    hostname: str
    address: IPvAnyAddress


AnnotatedUnionType = Annotated[
    Union[ModelA, ModelB],
    Field(discriminator="type")
]


class CompositeModel(BaseModel):
    composite_field: AnnotatedUnionType


data = {"composite_field": {"type": "A", "addresses": ["192.168.1.0/24", "127.0.0.1"]}}
model = CompositeModel(**data)
print("Deserialized:", model.model_dump_json())

"""
PydanticSerializationUnexpectedValue: Expected `frozenset[str]` but got `list` with value `['127.0.0.1/32', '192.168.1.0/24']` - serialized value may not be as expected
PydanticSerializationUnexpectedValue: Expected `ModelB` but got `ModelA` with value `ModelA(type='A', addresse...twork('127.0.0.1/32')}))` - serialized value may not be as expected
Expected `frozenset[str]` but got `list` with value `['127.0.0.1/32', '192.168.1.0/24']` - serialized value may not be as expected
"""

@sydney-runkle
Copy link
Member Author

I've opened #1454 and #1455 to hold us accountable to the suggestions made above.

@sydney-runkle sydney-runkle merged commit 4a0c332 into main Sep 16, 2024
29 checks passed
@sydney-runkle sydney-runkle deleted the warning-fix branch September 16, 2024 15:31
renovate bot added a commit to spiraldb/ziggy-pydust that referenced this pull request Sep 17, 2024
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [pydantic](https://github.com/pydantic/pydantic)
([changelog](https://docs.pydantic.dev/latest/changelog/)) | `2.9.1` ->
`2.9.2` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/pydantic/2.9.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/pydantic/2.9.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/pydantic/2.9.1/2.9.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/pydantic/2.9.1/2.9.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>pydantic/pydantic (pydantic)</summary>

###
[`v2.9.2`](https://github.com/pydantic/pydantic/blob/HEAD/HISTORY.md#v292-2024-09-17)

[Compare
Source](https://github.com/pydantic/pydantic/compare/v2.9.1...v2.9.2)

[GitHub
release](https://github.com/pydantic/pydantic/releases/tag/v2.9.2)

##### What's Changed

##### Fixes

- Do not error when trying to evaluate annotations of private attributes
by [@&#8203;Viicos](https://github.com/Viicos) in
[#&#8203;10358](https://github.com/pydantic/pydantic/pull/10358)
- Adding notes on designing sound `Callable` discriminators by
[@&#8203;sydney-runkle](https://github.com/sydney-runkle) in
[#&#8203;10400](https://github.com/pydantic/pydantic/pull/10400)
- Fix serialization schema generation when using `PlainValidator` by
[@&#8203;Viicos](https://github.com/Viicos) in
[#&#8203;10427](https://github.com/pydantic/pydantic/pull/10427)
- Fix `Union` serialization warnings by
[@&#8203;sydney-runkle](https://github.com/sydney-runkle) in
[pydantic/pydantic-core#1449](https://github.com/pydantic/pydantic-core/pull/1449)
- Fix variance issue in `_IncEx` type alias, only allow `True` by
[@&#8203;Viicos](https://github.com/Viicos) in
[#&#8203;10414](https://github.com/pydantic/pydantic/pull/10414)
- Fix `ZoneInfo` validation with various invalid types by
[@&#8203;sydney-runkle](https://github.com/sydney-runkle) in
[#&#8203;10408](https://github.com/pydantic/pydantic/pull/10408)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/spiraldb/ziggy-pydust).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC44MC4wIiwidXBkYXRlZEluVmVyIjoiMzguODAuMCIsInRhcmdldEJyYW5jaCI6ImRldmVsb3AiLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
chouinar pushed a commit to HHS/simpler-grants-gov that referenced this pull request Sep 19, 2024
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [SQLAlchemy](https://www.sqlalchemy.org)
([changelog](https://docs.sqlalchemy.org/en/latest/changelog/)) |
`2.0.34` -> `2.0.35` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/SQLAlchemy/2.0.35?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/SQLAlchemy/2.0.35?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/SQLAlchemy/2.0.34/2.0.35?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/SQLAlchemy/2.0.34/2.0.35?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [boto3](https://github.com/boto/boto3) | `1.35.14` ->
`1.35.22` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/boto3/1.35.22?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/boto3/1.35.22?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/boto3/1.35.14/1.35.22?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/boto3/1.35.14/1.35.22?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [botocore](https://github.com/boto/botocore) | `1.35.14` ->
`1.35.22` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/botocore/1.35.22?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/botocore/1.35.22?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/botocore/1.35.14/1.35.22?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/botocore/1.35.14/1.35.22?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[marshmallow-dataclass](https://github.com/lovasoa/marshmallow_dataclass)
| `8.7.0` -> `8.7.1` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/marshmallow-dataclass/8.7.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/marshmallow-dataclass/8.7.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/marshmallow-dataclass/8.7.0/8.7.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/marshmallow-dataclass/8.7.0/8.7.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [psycopg](https://psycopg.org/psycopg3/)
([source](https://github.com/psycopg/psycopg),
[changelog](https://psycopg.org/psycopg3/docs/news.html)) | `3.2.1` ->
`3.2.2` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/psycopg/3.2.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/psycopg/3.2.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/psycopg/3.2.1/3.2.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/psycopg/3.2.1/3.2.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [pydantic](https://github.com/pydantic/pydantic)
([changelog](https://docs.pydantic.dev/latest/changelog/)) | `2.9.1` ->
`2.9.2` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/pydantic/2.9.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/pydantic/2.9.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/pydantic/2.9.1/2.9.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/pydantic/2.9.1/2.9.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[pydantic-settings](https://github.com/pydantic/pydantic-settings)
([changelog](https://github.com/pydantic/pydantic-settings/releases))
| `2.4.0` -> `2.5.2` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/pydantic-settings/2.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/pydantic-settings/2.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/pydantic-settings/2.4.0/2.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/pydantic-settings/2.4.0/2.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [ruff](https://docs.astral.sh/ruff)
([source](https://github.com/astral-sh/ruff),
[changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md))
| `^0.4.0` -> `^0.6.0` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/ruff/0.6.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/ruff/0.6.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/ruff/0.4.10/0.6.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/ruff/0.4.10/0.6.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

> [!WARNING]
> Some dependencies could not be looked up. Check the Dependency
Dashboard for more information.

---

### Release Notes

<details>
<summary>boto/boto3 (boto3)</summary>

###
[`v1.35.22`](https://github.com/boto/boto3/blob/HEAD/CHANGELOG.rst#13522)

[Compare
Source](https://github.com/boto/boto3/compare/1.35.21...1.35.22)

\=======

- api-change:`ce`: \[`botocore`] This release extends the
GetReservationPurchaseRecommendation API to support recommendations for
Amazon DynamoDB reservations.
- api-change:`ds`: \[`botocore`] Added new APIs for enabling, disabling,
and describing access to the AWS Directory Service Data API
- api-change:`ds-data`: \[`botocore`] Added new AWS Directory Service
Data API, enabling you to manage data stored in AWS Directory Service
directories. This includes APIs for creating, reading, updating, and
deleting directory users, groups, and group memberships.
- api-change:`guardduty`: \[`botocore`] Add `launchType` and `sourceIPs`
fields to GuardDuty findings.
- api-change:`mailmanager`: \[`botocore`] Introduce a new RuleSet
condition evaluation, where customers can set up a StringExpression with
a MimeHeader condition. This condition will perform the necessary
validation based on the X-header provided by customers.
- api-change:`rds`: \[`botocore`] Updates Amazon RDS documentation with
information upgrading snapshots with unsupported engine versions for RDS
for MySQL and RDS for PostgreSQL.
- api-change:`s3`: \[`botocore`] Added SSE-KMS support for directory
buckets.

###
[`v1.35.21`](https://github.com/boto/boto3/blob/HEAD/CHANGELOG.rst#13521)

[Compare
Source](https://github.com/boto/boto3/compare/1.35.20...1.35.21)

\=======

- api-change:`codebuild`: \[`botocore`] GitLab Enhancements - Add
support for Self-Hosted GitLab runners in CodeBuild. Add group webhooks
- api-change:`ecr`: \[`botocore`] The `DescribeImageScanning` API now
includes `fixAvailable`, `exploitAvailable`, and `fixedInVersion` fields
to provide more detailed information about the availability of fixes,
exploits, and fixed versions for identified image vulnerabilities.
- api-change:`ecs`: \[`botocore`] This is a documentation only release
to address various tickets.
- api-change:`lambda`: \[`botocore`] Support for JSON resource-based
policies and block public access
- api-change:`rds`: \[`botocore`] Updates Amazon RDS documentation with
configuration information about the BYOL model for RDS for Db2.
- api-change:`ssm`: \[`botocore`] Support for additional levels of
cross-account, cross-Region organizational units in Automation. Various
documentation updates.

###
[`v1.35.20`](https://github.com/boto/boto3/blob/HEAD/CHANGELOG.rst#13520)

[Compare
Source](https://github.com/boto/boto3/compare/1.35.19...1.35.20)

\=======

- api-change:`bedrock`: \[`botocore`] This feature adds cross account s3
bucket and VPC support to ModelInvocation jobs. To use a cross account
bucket, pass in the accountId of the bucket to s3BucketOwner in the
ModelInvocationJobInputDataConfig or ModelInvocationJobOutputDataConfig.
- api-change:`iot`: \[`botocore`] This release adds additional
enhancements to AWS IoT Device Management Software Package Catalog and
Jobs. It also adds SBOM support in Software Package Version.
- api-change:`medialive`: \[`botocore`] Removing the ON_PREMISE enum
from the input settings field.
- api-change:`organizations`: \[`botocore`] Doc only update for AWS
Organizations that fixes several customer-reported issues
- api-change:`pca-connector-scep`: \[`botocore`] This is a general
availability (GA) release of Connector for SCEP, a feature of AWS
Private CA. Connector for SCEP links your SCEP-enabled and mobile device
management systems to AWS Private CA for digital signature installation
and certificate management.
-   api-change:`rds`: \[`botocore`] Launching Global Cluster tagging.

###
[`v1.35.19`](https://github.com/boto/boto3/blob/HEAD/CHANGELOG.rst#13519)

[Compare
Source](https://github.com/boto/boto3/compare/1.35.18...1.35.19)

\=======

- api-change:`amplify`: \[`botocore`] Doc only update to Amplify to
explain platform setting for Next.js 14 SSG only applications
-   api-change:`ivs`: \[`botocore`] Updates to all tags descriptions.
- api-change:`ivschat`: \[`botocore`] Updates to all tags descriptions.

###
[`v1.35.18`](https://github.com/boto/boto3/blob/HEAD/CHANGELOG.rst#13518)

[Compare
Source](https://github.com/boto/boto3/compare/1.35.17...1.35.18)

\=======

- api-change:`cognito-idp`: \[`botocore`] Added email MFA option to user
pools with advanced security features.
- api-change:`elbv2`: \[`botocore`] Correct incorrectly mapped error in
ELBv2 waiters
- api-change:`emr`: \[`botocore`] Update APIs to allow modification of
ODCR options, allocation strategy, and InstanceTypeConfigs on running
InstanceFleet clusters.
- api-change:`glue`: \[`botocore`] AWS Glue is introducing two new
optimizers for Apache Iceberg tables: snapshot retention and orphan file
deletion. Customers can enable these optimizers and customize their
configurations to perform daily maintenance tasks on their Iceberg
tables based on their specific requirements.
- api-change:`mediaconvert`: \[`botocore`] This release includes support
for dynamic video overlay workflows, including picture-in-picture and
squeezeback
- api-change:`rds`: \[`botocore`] This release adds support for the
os-upgrade pending maintenance action for Amazon Aurora DB clusters.
- api-change:`storagegateway`: \[`botocore`] The S3 File Gateway now
supports DSSE-KMS encryption. A new parameter EncryptionType is added to
these APIs: CreateSmbFileShare, CreateNfsFileShare, UpdateSmbFileShare,
UpdateNfsFileShare, DescribeSmbFileShares, DescribeNfsFileShares. Also,
in favor of EncryptionType, KmsEncrypted is deprecated.
- api-change:`synthetics`: \[`botocore`] This release introduces two
features. The first is tag replication, which allows for the propagation
of canary tags onto Synthetics related resources, such as Lambda
functions. The second is a limit increase in canary name length, which
has now been increased from 21 to 255 characters.

###
[`v1.35.17`](https://github.com/boto/boto3/blob/HEAD/CHANGELOG.rst#13517)

[Compare
Source](https://github.com/boto/boto3/compare/1.35.16...1.35.17)

\=======

- api-change:`bedrock-agent`: \[`botocore`] Amazon Bedrock Knowledge
Bases now supports using inference profiles to increase throughput and
improve resilience.
- api-change:`bedrock-agent-runtime`: \[`botocore`] Amazon Bedrock
Knowledge Bases now supports using inference profiles to increase
throughput and improve resilience.
-   api-change:`ecr`: \[`botocore`] Added KMS_DSSE to EncryptionType
- api-change:`guardduty`: \[`botocore`] Add support for new statistic
types in GetFindingsStatistics.
- api-change:`lexv2-models`: \[`botocore`] Support new Polly voice
engines in VoiceSettings: long-form and generative
- api-change:`medialive`: \[`botocore`] Adds AV1 Codec support, SRT
ouputs, and MediaLive Anywhere support.

###
[`v1.35.16`](https://github.com/boto/boto3/blob/HEAD/CHANGELOG.rst#13516)

[Compare
Source](https://github.com/boto/boto3/compare/1.35.15...1.35.16)

\=======

- api-change:`chime-sdk-voice`: \[`botocore`] Documentation-only update
that clarifies the ValidateE911Address action of the Amazon Chime SDK
Voice APIs.
- api-change:`cognito-identity`: \[`botocore`] This release adds
sensitive trait to some required shapes.
- api-change:`pipes`: \[`botocore`] This release adds support for
customer managed KMS keys in Amazon EventBridge Pipe
- api-change:`securityhub`: \[`botocore`] Documentation update for
Security Hub
-   enhancement:AWSCRT: \[`botocore`] Update awscrt version to 0.21.5
- enhancement:`s3`: \[`botocore`] Adds logic to gracefully handle
invalid timestamps returned in the Expires header.

###
[`v1.35.15`](https://github.com/boto/boto3/blob/HEAD/CHANGELOG.rst#13515)

[Compare
Source](https://github.com/boto/boto3/compare/1.35.14...1.35.15)

\=======

- api-change:`dynamodb`: \[`botocore`] Doc-only update for DynamoDB.
Added information about async behavior for TagResource and UntagResource
APIs and updated the description of ResourceInUseException.
- api-change:`elbv2`: \[`botocore`] Add paginators for the ELBv2
DescribeListenerCertificates and DescribeRules APIs. Fix broken waiter
for the ELBv2 DescribeLoadBalancers API.
- api-change:`ivs-realtime`: \[`botocore`] IVS Real-Time now offers
customers the ability to broadcast to Stages using RTMP(S).
- api-change:`kafka`: \[`botocore`] Amazon MSK Replicator can now
replicate data to identically named topics between MSK clusters within
the same AWS Region or across different AWS Regions.
- api-change:`sagemaker`: \[`botocore`] Amazon Sagemaker supports
orchestrating SageMaker HyperPod clusters with Amazon EKS
- api-change:`sagemaker-runtime`: \[`botocore`] AWS SageMaker Runtime
feature: Add sticky routing to support stateful inference models.

</details>

<details>
<summary>boto/botocore (botocore)</summary>

###
[`v1.35.22`](https://github.com/boto/botocore/blob/HEAD/CHANGELOG.rst#13522)

[Compare
Source](https://github.com/boto/botocore/compare/1.35.21...1.35.22)

\=======

- api-change:`ce`: This release extends the
GetReservationPurchaseRecommendation API to support recommendations for
Amazon DynamoDB reservations.
- api-change:`ds`: Added new APIs for enabling, disabling, and
describing access to the AWS Directory Service Data API
- api-change:`ds-data`: Added new AWS Directory Service Data API,
enabling you to manage data stored in AWS Directory Service directories.
This includes APIs for creating, reading, updating, and deleting
directory users, groups, and group memberships.
- api-change:`guardduty`: Add `launchType` and `sourceIPs` fields to
GuardDuty findings.
- api-change:`mailmanager`: Introduce a new RuleSet condition
evaluation, where customers can set up a StringExpression with a
MimeHeader condition. This condition will perform the necessary
validation based on the X-header provided by customers.
- api-change:`rds`: Updates Amazon RDS documentation with information
upgrading snapshots with unsupported engine versions for RDS for MySQL
and RDS for PostgreSQL.
-   api-change:`s3`: Added SSE-KMS support for directory buckets.

###
[`v1.35.21`](https://github.com/boto/botocore/blob/HEAD/CHANGELOG.rst#13521)

[Compare
Source](https://github.com/boto/botocore/compare/1.35.20...1.35.21)

\=======

- api-change:`codebuild`: GitLab Enhancements - Add support for
Self-Hosted GitLab runners in CodeBuild. Add group webhooks
- api-change:`ecr`: The `DescribeImageScanning` API now includes
`fixAvailable`, `exploitAvailable`, and `fixedInVersion` fields to
provide more detailed information about the availability of fixes,
exploits, and fixed versions for identified image vulnerabilities.
- api-change:`ecs`: This is a documentation only release to address
various tickets.
- api-change:`lambda`: Support for JSON resource-based policies and
block public access
- api-change:`rds`: Updates Amazon RDS documentation with configuration
information about the BYOL model for RDS for Db2.
- api-change:`ssm`: Support for additional levels of cross-account,
cross-Region organizational units in Automation. Various documentation
updates.

###
[`v1.35.20`](https://github.com/boto/botocore/blob/HEAD/CHANGELOG.rst#13520)

[Compare
Source](https://github.com/boto/botocore/compare/1.35.19...1.35.20)

\=======

- api-change:`bedrock`: This feature adds cross account s3 bucket and
VPC support to ModelInvocation jobs. To use a cross account bucket, pass
in the accountId of the bucket to s3BucketOwner in the
ModelInvocationJobInputDataConfig or ModelInvocationJobOutputDataConfig.
- api-change:`iot`: This release adds additional enhancements to AWS IoT
Device Management Software Package Catalog and Jobs. It also adds SBOM
support in Software Package Version.
- api-change:`medialive`: Removing the ON_PREMISE enum from the input
settings field.
- api-change:`organizations`: Doc only update for AWS Organizations that
fixes several customer-reported issues
- api-change:`pca-connector-scep`: This is a general availability (GA)
release of Connector for SCEP, a feature of AWS Private CA. Connector
for SCEP links your SCEP-enabled and mobile device management systems to
AWS Private CA for digital signature installation and certificate
management.
-   api-change:`rds`: Launching Global Cluster tagging.

###
[`v1.35.19`](https://github.com/boto/botocore/blob/HEAD/CHANGELOG.rst#13519)

[Compare
Source](https://github.com/boto/botocore/compare/1.35.18...1.35.19)

\=======

- api-change:`amplify`: Doc only update to Amplify to explain platform
setting for Next.js 14 SSG only applications
-   api-change:`ivs`: Updates to all tags descriptions.
-   api-change:`ivschat`: Updates to all tags descriptions.

###
[`v1.35.18`](https://github.com/boto/botocore/blob/HEAD/CHANGELOG.rst#13518)

[Compare
Source](https://github.com/boto/botocore/compare/1.35.17...1.35.18)

\=======

- api-change:`cognito-idp`: Added email MFA option to user pools with
advanced security features.
- api-change:`elbv2`: Correct incorrectly mapped error in ELBv2 waiters
- api-change:`emr`: Update APIs to allow modification of ODCR options,
allocation strategy, and InstanceTypeConfigs on running InstanceFleet
clusters.
- api-change:`glue`: AWS Glue is introducing two new optimizers for
Apache Iceberg tables: snapshot retention and orphan file deletion.
Customers can enable these optimizers and customize their configurations
to perform daily maintenance tasks on their Iceberg tables based on
their specific requirements.
- api-change:`mediaconvert`: This release includes support for dynamic
video overlay workflows, including picture-in-picture and squeezeback
- api-change:`rds`: This release adds support for the os-upgrade pending
maintenance action for Amazon Aurora DB clusters.
- api-change:`storagegateway`: The S3 File Gateway now supports DSSE-KMS
encryption. A new parameter EncryptionType is added to these APIs:
CreateSmbFileShare, CreateNfsFileShare, UpdateSmbFileShare,
UpdateNfsFileShare, DescribeSmbFileShares, DescribeNfsFileShares. Also,
in favor of EncryptionType, KmsEncrypted is deprecated.
- api-change:`synthetics`: This release introduces two features. The
first is tag replication, which allows for the propagation of canary
tags onto Synthetics related resources, such as Lambda functions. The
second is a limit increase in canary name length, which has now been
increased from 21 to 255 characters.

###
[`v1.35.17`](https://github.com/boto/botocore/blob/HEAD/CHANGELOG.rst#13517)

[Compare
Source](https://github.com/boto/botocore/compare/1.35.16...1.35.17)

\=======

- api-change:`bedrock-agent`: Amazon Bedrock Knowledge Bases now
supports using inference profiles to increase throughput and improve
resilience.
- api-change:`bedrock-agent-runtime`: Amazon Bedrock Knowledge Bases now
supports using inference profiles to increase throughput and improve
resilience.
-   api-change:`ecr`: Added KMS_DSSE to EncryptionType
- api-change:`guardduty`: Add support for new statistic types in
GetFindingsStatistics.
- api-change:`lexv2-models`: Support new Polly voice engines in
VoiceSettings: long-form and generative
- api-change:`medialive`: Adds AV1 Codec support, SRT ouputs, and
MediaLive Anywhere support.

###
[`v1.35.16`](https://github.com/boto/botocore/blob/HEAD/CHANGELOG.rst#13516)

[Compare
Source](https://github.com/boto/botocore/compare/1.35.15...1.35.16)

\=======

- api-change:`chime-sdk-voice`: Documentation-only update that clarifies
the ValidateE911Address action of the Amazon Chime SDK Voice APIs.
- api-change:`cognito-identity`: This release adds sensitive trait to
some required shapes.
- api-change:`pipes`: This release adds support for customer managed KMS
keys in Amazon EventBridge Pipe
-   api-change:`securityhub`: Documentation update for Security Hub
-   enhancement:AWSCRT: Update awscrt version to 0.21.5
- enhancement:`s3`: Adds logic to gracefully handle invalid timestamps
returned in the Expires header.

###
[`v1.35.15`](https://github.com/boto/botocore/blob/HEAD/CHANGELOG.rst#13515)

[Compare
Source](https://github.com/boto/botocore/compare/1.35.14...1.35.15)

\=======

- api-change:`dynamodb`: Doc-only update for DynamoDB. Added information
about async behavior for TagResource and UntagResource APIs and updated
the description of ResourceInUseException.
- api-change:`elbv2`: Add paginators for the ELBv2
DescribeListenerCertificates and DescribeRules APIs. Fix broken waiter
for the ELBv2 DescribeLoadBalancers API.
- api-change:`ivs-realtime`: IVS Real-Time now offers customers the
ability to broadcast to Stages using RTMP(S).
- api-change:`kafka`: Amazon MSK Replicator can now replicate data to
identically named topics between MSK clusters within the same AWS Region
or across different AWS Regions.
- api-change:`sagemaker`: Amazon Sagemaker supports orchestrating
SageMaker HyperPod clusters with Amazon EKS
- api-change:`sagemaker-runtime`: AWS SageMaker Runtime feature: Add
sticky routing to support stateful inference models.

</details>

<details>
<summary>lovasoa/marshmallow_dataclass (marshmallow-dataclass)</summary>

###
[`v8.7.1`](https://github.com/lovasoa/marshmallow_dataclass/blob/HEAD/CHANGELOG.md#v871-2024-09-12)

[Compare
Source](https://github.com/lovasoa/marshmallow_dataclass/compare/v8.7.0...v8.7.1)

- Relax dependency pins for `typeguard` and `typing-inspect`.
([#&#8203;273], [#&#8203;272])

[#&#8203;272]:
https://github.com/lovasoa/marshmallow_dataclass/issues/272

[#&#8203;273]:
https://github.com/lovasoa/marshmallow_dataclass/pull/273

</details>

<details>
<summary>psycopg/psycopg (psycopg)</summary>

###
[`v3.2.2`](https://github.com/psycopg/psycopg/compare/3.2.1...3.2.2)

[Compare
Source](https://github.com/psycopg/psycopg/compare/3.2.1...3.2.2)

</details>

<details>
<summary>pydantic/pydantic (pydantic)</summary>

###
[`v2.9.2`](https://github.com/pydantic/pydantic/blob/HEAD/HISTORY.md#v292-2024-09-17)

[Compare
Source](https://github.com/pydantic/pydantic/compare/v2.9.1...v2.9.2)

[GitHub
release](https://github.com/pydantic/pydantic/releases/tag/v2.9.2)

##### What's Changed

##### Fixes

- Do not error when trying to evaluate annotations of private attributes
by [@&#8203;Viicos](https://github.com/Viicos) in
[#&#8203;10358](https://github.com/pydantic/pydantic/pull/10358)
- Adding notes on designing sound `Callable` discriminators by
[@&#8203;sydney-runkle](https://github.com/sydney-runkle) in
[#&#8203;10400](https://github.com/pydantic/pydantic/pull/10400)
- Fix serialization schema generation when using `PlainValidator` by
[@&#8203;Viicos](https://github.com/Viicos) in
[#&#8203;10427](https://github.com/pydantic/pydantic/pull/10427)
- Fix `Union` serialization warnings by
[@&#8203;sydney-runkle](https://github.com/sydney-runkle) in
[pydantic/pydantic-core#1449](https://github.com/pydantic/pydantic-core/pull/1449)
- Fix variance issue in `_IncEx` type alias, only allow `True` by
[@&#8203;Viicos](https://github.com/Viicos) in
[#&#8203;10414](https://github.com/pydantic/pydantic/pull/10414)
- Fix `ZoneInfo` validation with various invalid types by
[@&#8203;sydney-runkle](https://github.com/sydney-runkle) in
[#&#8203;10408](https://github.com/pydantic/pydantic/pull/10408)

</details>

<details>
<summary>pydantic/pydantic-settings (pydantic-settings)</summary>

###
[`v2.5.2`](https://github.com/pydantic/pydantic-settings/releases/tag/v2.5.2)

[Compare
Source](https://github.com/pydantic/pydantic-settings/compare/v2.5.1...v2.5.2)

#### What's Changed

- Second fix for the TypeError bug introduced in 2.5 by
[@&#8203;hramezani](https://github.com/hramezani) in
[https://github.com/pydantic/pydantic-settings/pull/396](https://github.com/pydantic/pydantic-settings/pull/396)

**Full Changelog**:
https://github.com/pydantic/pydantic-settings/compare/v2.5.1...v2.5.2

###
[`v2.5.1`](https://github.com/pydantic/pydantic-settings/releases/tag/v2.5.1)

[Compare
Source](https://github.com/pydantic/pydantic-settings/compare/v2.5.0...v2.5.1)

#### What's Changed

- Fix TypeError introduced in 2.5 by
[@&#8203;hramezani](https://github.com/hramezani) in
[https://github.com/pydantic/pydantic-settings/pull/392](https://github.com/pydantic/pydantic-settings/pull/392)

**Full Changelog**:
https://github.com/pydantic/pydantic-settings/compare/v2.5.0...v2.5.1

###
[`v2.5.0`](https://github.com/pydantic/pydantic-settings/releases/tag/v2.5.0)

[Compare
Source](https://github.com/pydantic/pydantic-settings/compare/v2.4.0...v2.5.0)

#### What's Changed

- Fix a bug in nested vanila dataclass by
[@&#8203;hramezani](https://github.com/hramezani) in
[https://github.com/pydantic/pydantic-settings/pull/357](https://github.com/pydantic/pydantic-settings/pull/357)
- CLI Improve Docstring Help Text by
[@&#8203;kschwab](https://github.com/kschwab) in
[https://github.com/pydantic/pydantic-settings/pull/359](https://github.com/pydantic/pydantic-settings/pull/359)
- Cli fix default or none object help text by
[@&#8203;kschwab](https://github.com/kschwab) in
[https://github.com/pydantic/pydantic-settings/pull/364](https://github.com/pydantic/pydantic-settings/pull/364)
- Determine RootModel complexity from root type by
[@&#8203;user1584](https://github.com/user1584) in
[https://github.com/pydantic/pydantic-settings/pull/344](https://github.com/pydantic/pydantic-settings/pull/344)
- Add CLI bool flags by
[@&#8203;kschwab](https://github.com/kschwab) in
[https://github.com/pydantic/pydantic-settings/pull/365](https://github.com/pydantic/pydantic-settings/pull/365)
- CLI arg list whitespaces fix. by
[@&#8203;kschwab](https://github.com/kschwab) in
[https://github.com/pydantic/pydantic-settings/pull/369](https://github.com/pydantic/pydantic-settings/pull/369)
- Add `nested_model_default_partial_update` flag and
`DefaultSettingsSource` by
[@&#8203;kschwab](https://github.com/kschwab) in
[https://github.com/pydantic/pydantic-settings/pull/348](https://github.com/pydantic/pydantic-settings/pull/348)
- Parse enum fixes. by
[@&#8203;kschwab](https://github.com/kschwab) in
[https://github.com/pydantic/pydantic-settings/pull/367](https://github.com/pydantic/pydantic-settings/pull/367)
- Fixes CLI help text for function types by
[@&#8203;kschwab](https://github.com/kschwab) in
[https://github.com/pydantic/pydantic-settings/pull/370](https://github.com/pydantic/pydantic-settings/pull/370)
- Add get_subcommand function. by
[@&#8203;kschwab](https://github.com/kschwab) in
[https://github.com/pydantic/pydantic-settings/pull/341](https://github.com/pydantic/pydantic-settings/pull/341)
- Cli prefix validation alias fix by
[@&#8203;kschwab](https://github.com/kschwab) in
[https://github.com/pydantic/pydantic-settings/pull/375](https://github.com/pydantic/pydantic-settings/pull/375)
- CLI ignore external parser list fix by
[@&#8203;kschwab](https://github.com/kschwab) in
[https://github.com/pydantic/pydantic-settings/pull/379](https://github.com/pydantic/pydantic-settings/pull/379)
- Enable multiple secrets dirs by
[@&#8203;makukha](https://github.com/makukha) in
[https://github.com/pydantic/pydantic-settings/pull/372](https://github.com/pydantic/pydantic-settings/pull/372)
- Add CLI subcommand union and alias support by
[@&#8203;kschwab](https://github.com/kschwab) in
[https://github.com/pydantic/pydantic-settings/pull/380](https://github.com/pydantic/pydantic-settings/pull/380)
- Fix dotenv settings source problem in handling extra variables with
same prefix in name by
[@&#8203;hramezani](https://github.com/hramezani) in
[https://github.com/pydantic/pydantic-settings/pull/386](https://github.com/pydantic/pydantic-settings/pull/386)

#### New Contributors

- [@&#8203;user1584](https://github.com/user1584) made their
first contribution in
[https://github.com/pydantic/pydantic-settings/pull/344](https://github.com/pydantic/pydantic-settings/pull/344)
- [@&#8203;makukha](https://github.com/makukha) made their
first contribution in
[https://github.com/pydantic/pydantic-settings/pull/372](https://github.com/pydantic/pydantic-settings/pull/372)

**Full Changelog**:
https://github.com/pydantic/pydantic-settings/compare/v2.4.0...v2.5.0

</details>

<details>
<summary>astral-sh/ruff (ruff)</summary>

###
[`v0.6.5`](https://github.com/astral-sh/ruff/blob/HEAD/CHANGELOG.md#065)

[Compare
Source](https://github.com/astral-sh/ruff/compare/0.6.4...0.6.5)

##### Preview features

- \[`pydoclint`] Ignore `DOC201` when function name is "**new**"
([#&#8203;13300](https://github.com/astral-sh/ruff/pull/13300))
- \[`refurb`] Implement `slice-to-remove-prefix-or-suffix` (`FURB188`)
([#&#8203;13256](https://github.com/astral-sh/ruff/pull/13256))

##### Rule changes

- \[`eradicate`] Ignore script-comments with multiple end-tags
(`ERA001`)
([#&#8203;13283](https://github.com/astral-sh/ruff/pull/13283))
- \[`pyflakes`] Improve error message for `UndefinedName` when a builtin
was added in a newer version than specified in Ruff config (`F821`)
([#&#8203;13293](https://github.com/astral-sh/ruff/pull/13293))

##### Server

- Add support for extensionless Python files for server
([#&#8203;13326](https://github.com/astral-sh/ruff/pull/13326))
- Fix configuration inheritance for configurations specified in the LSP
settings
([#&#8203;13285](https://github.com/astral-sh/ruff/pull/13285))

##### Bug fixes

- \[`ruff`] Handle unary operators in `decimal-from-float-literal`
(`RUF032`)
([#&#8203;13275](https://github.com/astral-sh/ruff/pull/13275))

##### CLI

- Only include rules with diagnostics in SARIF metadata
([#&#8203;13268](https://github.com/astral-sh/ruff/pull/13268))

##### Playground

- Add "Copy as pyproject.toml/ruff.toml" and "Paste from TOML"
([#&#8203;13328](https://github.com/astral-sh/ruff/pull/13328))
- Fix errors not shown for restored snippet on page load
([#&#8203;13262](https://github.com/astral-sh/ruff/pull/13262))

###
[`v0.6.4`](https://github.com/astral-sh/ruff/blob/HEAD/CHANGELOG.md#064)

[Compare
Source](https://github.com/astral-sh/ruff/compare/0.6.3...0.6.4)

##### Preview features

- \[`flake8-builtins`] Use dynamic builtins list based on Python version
([#&#8203;13172](https://github.com/astral-sh/ruff/pull/13172))
- \[`pydoclint`] Permit yielding `None` in `DOC402` and `DOC403`
([#&#8203;13148](https://github.com/astral-sh/ruff/pull/13148))
- \[`pylint`] Update diagnostic message for `PLW3201`
([#&#8203;13194](https://github.com/astral-sh/ruff/pull/13194))
- \[`ruff`] Implement `post-init-default` (`RUF033`)
([#&#8203;13192](https://github.com/astral-sh/ruff/pull/13192))
- \[`ruff`] Implement useless if-else (`RUF034`)
([#&#8203;13218](https://github.com/astral-sh/ruff/pull/13218))

##### Rule changes

- \[`flake8-pyi`] Respect `pep8_naming.classmethod-decorators` settings
when determining if a method is a classmethod in
`custom-type-var-return-type` (`PYI019`)
([#&#8203;13162](https://github.com/astral-sh/ruff/pull/13162))
- \[`flake8-pyi`] Teach various rules that annotations might be
stringized
([#&#8203;12951](https://github.com/astral-sh/ruff/pull/12951))
- \[`pylint`] Avoid `no-self-use` for `attrs`-style validators
([#&#8203;13166](https://github.com/astral-sh/ruff/pull/13166))
- \[`pylint`] Recurse into subscript subexpressions when searching for
list/dict lookups (`PLR1733`, `PLR1736`)
([#&#8203;13186](https://github.com/astral-sh/ruff/pull/13186))
- \[`pyupgrade`] Detect `aiofiles.open` calls in `UP015`
([#&#8203;13173](https://github.com/astral-sh/ruff/pull/13173))
- \[`pyupgrade`] Mark `sys.version_info[0] < 3` and similar comparisons
as outdated (`UP036`)
([#&#8203;13175](https://github.com/astral-sh/ruff/pull/13175))

##### CLI

- Enrich messages of SARIF results
([#&#8203;13180](https://github.com/astral-sh/ruff/pull/13180))
- Handle singular case for incompatible rules warning in `ruff format`
output
([#&#8203;13212](https://github.com/astral-sh/ruff/pull/13212))

##### Bug fixes

- \[`pydocstyle`] Improve heuristics for detecting Google-style
docstrings
([#&#8203;13142](https://github.com/astral-sh/ruff/pull/13142))
- \[`refurb`] Treat `sep` arguments with effects as unsafe removals
(`FURB105`)
([#&#8203;13165](https://github.com/astral-sh/ruff/pull/13165))

###
[`v0.6.3`](https://github.com/astral-sh/ruff/blob/HEAD/CHANGELOG.md#063)

[Compare
Source](https://github.com/astral-sh/ruff/compare/0.6.2...0.6.3)

##### Preview features

- \[`flake8-simplify`] Extend `open-file-with-context-handler` to work
with `dbm.sqlite3` (`SIM115`)
([#&#8203;13104](https://github.com/astral-sh/ruff/pull/13104))
- \[`pycodestyle`] Disable `E741` in stub files (`.pyi`)
([#&#8203;13119](https://github.com/astral-sh/ruff/pull/13119))
- \[`pydoclint`] Avoid `DOC201` on explicit returns in functions that
only return `None`
([#&#8203;13064](https://github.com/astral-sh/ruff/pull/13064))

##### Rule changes

- \[`flake8-async`] Disable check for `asyncio` before Python 3.11
(`ASYNC109`)
([#&#8203;13023](https://github.com/astral-sh/ruff/pull/13023))

##### Bug fixes

- \[`FastAPI`] Avoid introducing invalid syntax in fix for
`fast-api-non-annotated-dependency` (`FAST002`)
([#&#8203;13133](https://github.com/astral-sh/ruff/pull/13133))
- \[`flake8-implicit-str-concat`] Normalize octals before merging
concatenated strings in `single-line-implicit-string-concatenation`
(`ISC001`)
([#&#8203;13118](https://github.com/astral-sh/ruff/pull/13118))
- \[`flake8-pytest-style`] Improve help message for
`pytest-incorrect-mark-parentheses-style` (`PT023`)
([#&#8203;13092](https://github.com/astral-sh/ruff/pull/13092))
- \[`pylint`] Avoid autofix for calls that aren't `min` or `max` as
starred expression (`PLW3301`)
([#&#8203;13089](https://github.com/astral-sh/ruff/pull/13089))
- \[`ruff`] Add `datetime.time`, `datetime.tzinfo`, and
`datetime.timezone` as immutable function calls (`RUF009`)
([#&#8203;13109](https://github.com/astral-sh/ruff/pull/13109))
- \[`ruff`] Extend comment deletion for `RUF100` to include trailing
text from `noqa` directives while preserving any following comments on
the same line, if any
([#&#8203;13105](https://github.com/astral-sh/ruff/pull/13105))
- Fix dark theme on initial page load for the Ruff playground
([#&#8203;13077](https://github.com/astral-sh/ruff/pull/13077))

###
[`v0.6.2`](https://github.com/astral-sh/ruff/blob/HEAD/CHANGELOG.md#062)

[Compare
Source](https://github.com/astral-sh/ruff/compare/0.6.1...0.6.2)

##### Preview features

- \[`flake8-simplify`] Extend `open-file-with-context-handler` to work
with other standard-library IO modules (`SIM115`)
([#&#8203;12959](https://github.com/astral-sh/ruff/pull/12959))
- \[`ruff`] Avoid `unused-async` for functions with FastAPI route
decorator (`RUF029`)
([#&#8203;12938](https://github.com/astral-sh/ruff/pull/12938))
- \[`ruff`] Ignore `fstring-missing-syntax` (`RUF027`) for `fastAPI`
paths
([#&#8203;12939](https://github.com/astral-sh/ruff/pull/12939))
- \[`ruff`] Implement check for Decimal called with a float literal
(RUF032)
([#&#8203;12909](https://github.com/astral-sh/ruff/pull/12909))

##### Rule changes

- \[`flake8-bugbear`] Update diagnostic message when expression is at
the end of function (`B015`)
([#&#8203;12944](https://github.com/astral-sh/ruff/pull/12944))
- \[`flake8-pyi`] Skip type annotations in `string-or-bytes-too-long`
(`PYI053`)
([#&#8203;13002](https://github.com/astral-sh/ruff/pull/13002))
- \[`flake8-type-checking`] Always recognise relative imports as
first-party
([#&#8203;12994](https://github.com/astral-sh/ruff/pull/12994))
- \[`flake8-unused-arguments`] Ignore unused arguments on stub functions
(`ARG001`)
([#&#8203;12966](https://github.com/astral-sh/ruff/pull/12966))
- \[`pylint`] Ignore augmented assignment for `self-cls-assignment`
(`PLW0642`)
([#&#8203;12957](https://github.com/astral-sh/ruff/pull/12957))

##### Server

- Show full context in error log messages
([#&#8203;13029](https://github.com/astral-sh/ruff/pull/13029))

##### Bug fixes

- \[`pep8-naming`] Don't flag `from` imports following conventional
import names (`N817`)
([#&#8203;12946](https://github.com/astral-sh/ruff/pull/12946))
- \[`pylint`] - Allow `__new__` methods to have `cls` as their first
argument even if decorated with `@staticmethod` for
`bad-staticmethod-argument` (`PLW0211`)
([#&#8203;12958](https://github.com/astral-sh/ruff/pull/12958))

##### Documentation

- Add `hyperfine` installation instructions; update `hyperfine` code
samples
([#&#8203;13034](https://github.com/astral-sh/ruff/pull/13034))
- Expand note to use Ruff with other language server in Kate
([#&#8203;12806](https://github.com/astral-sh/ruff/pull/12806))
- Update example for `PT001` as per the new default behavior
([#&#8203;13019](https://github.com/astral-sh/ruff/pull/13019))
- \[`perflint`] Improve docs for `try-except-in-loop` (`PERF203`)
([#&#8203;12947](https://github.com/astral-sh/ruff/pull/12947))
- \[`pydocstyle`] Add reference to `lint.pydocstyle.ignore-decorators`
setting to rule docs
([#&#8203;12996](https://github.com/astral-sh/ruff/pull/12996))

###
[`v0.6.1`](https://github.com/astral-sh/ruff/blob/HEAD/CHANGELOG.md#061)

[Compare
Source](https://github.com/astral-sh/ruff/compare/0.6.0...0.6.1)

This is a hotfix release to address an issue with `ruff-pre-commit`. In
v0.6,
Ruff changed its behavior to lint and format Jupyter notebooks by
default;
however, due to an oversight, these files were still excluded by default
if
Ruff was run via pre-commit, leading to inconsistent behavior.
This has [now been
fixed](https://github.com/astral-sh/ruff-pre-commit/pull/96).

##### Preview features

- \[`fastapi`] Implement `fast-api-unused-path-parameter` (`FAST003`)
([#&#8203;12638](https://github.com/astral-sh/ruff/pull/12638))

##### Rule changes

- \[`pylint`] Rename `too-many-positional` to
`too-many-positional-arguments` (`R0917`)
([#&#8203;12905](https://github.com/astral-sh/ruff/pull/12905))

##### Server

- Fix crash when applying "fix-all" code-action to notebook cells
([#&#8203;12929](https://github.com/astral-sh/ruff/pull/12929))

##### Other changes

- \[`flake8-naming`]: Respect import conventions (`N817`)
([#&#8203;12922](https://github.com/astral-sh/ruff/pull/12922))

###
[`v0.6.0`](https://github.com/astral-sh/ruff/blob/HEAD/CHANGELOG.md#060)

[Compare
Source](https://github.com/astral-sh/ruff/compare/0.5.7...0.6.0)

Check out the [blog post](https://astral.sh/blog/ruff-v0.6.0) for a
migration guide and overview of the changes!

##### Breaking changes

See also, the "Remapped rules" section which may result in disabled
rules.

- Lint and format Jupyter Notebook by default
([#&#8203;12878](https://github.com/astral-sh/ruff/pull/12878)).
- Detect imports in `src` layouts by default for `isort` rules
([#&#8203;12848](https://github.com/astral-sh/ruff/pull/12848))
- The pytest rules `PT001` and `PT023` now default to omitting the
decorator parentheses when there are no arguments
([#&#8203;12838](https://github.com/astral-sh/ruff/pull/12838)).

##### Deprecations

The following rules are now deprecated:

-
[`pytest-missing-fixture-name-underscore`](https://docs.astral.sh/ruff/rules/pytest-missing-fixture-name-underscore/)
(`PT004`)
-
[`pytest-incorrect-fixture-name-underscore`](https://docs.astral.sh/ruff/rules/pytest-incorrect-fixture-name-underscore/)
(`PT005`)
-
[`unpacked-list-comprehension`](https://docs.astral.sh/ruff/rules/unpacked-list-comprehension/)
(`UP027`)

##### Remapped rules

The following rules have been remapped to new rule codes:

-
[`unnecessary-dict-comprehension-for-iterable`](https://docs.astral.sh/ruff/rules/unnecessary-dict-comprehension-for-iterable/):
`RUF025` to `C420`

##### Stabilization

The following rules have been stabilized and are no longer in preview:

-
[`singledispatch-method`](https://docs.astral.sh/ruff/rules/singledispatch-method/)
(`PLE1519`)
-
[`singledispatchmethod-function`](https://docs.astral.sh/ruff/rules/singledispatchmethod-function/)
(`PLE1520`)
-
[`bad-staticmethod-argument`](https://docs.astral.sh/ruff/rules/bad-staticmethod-argument/)
(`PLW0211`)
-
[`if-stmt-min-max`](https://docs.astral.sh/ruff/rules/if-stmt-min-max/)
(`PLR1730`)
-
[`invalid-bytes-return-type`](https://docs.astral.sh/ruff/rules/invalid-bytes-return-type/)
(`PLE0308`)
-
[`invalid-hash-return-type`](https://docs.astral.sh/ruff/rules/invalid-hash-return-type/)
(`PLE0309`)
-
[`invalid-index-return-type`](https://docs.astral.sh/ruff/rules/invalid-index-return-type/)
(`PLE0305`)
-
[`invalid-length-return-type`](https://docs.astral.sh/ruff/rules/invalid-length-return-type/)
(`E303`)
-
[`self-or-cls-assignment`](https://docs.astral.sh/ruff/rules/self-or-cls-assignment/)
(`PLW0642`)
-
[`byte-string-usage`](https://docs.astral.sh/ruff/rules/byte-string-usage/)
(`PYI057`)
-
[`duplicate-literal-member`](https://docs.astral.sh/ruff/rules/duplicate-literal-member/)
(`PYI062`)
-
[`redirected-noqa`](https://docs.astral.sh/ruff/rules/redirected-noqa/)
(`RUF101`)

The following behaviors have been stabilized:

-
[`cancel-scope-no-checkpoint`](https://docs.astral.sh/ruff/rules/cancel-scope-no-checkpoint/)
(`ASYNC100`): Support `asyncio` and `anyio` context mangers.
-
[`async-function-with-timeout`](https://docs.astral.sh/ruff/rules/async-function-with-timeout/)
(`ASYNC109`): Support `asyncio` and `anyio` context mangers.
-
[`async-busy-wait`](https://docs.astral.sh/ruff/rules/async-busy-wait/)
(`ASYNC110`): Support `asyncio` and `anyio` context mangers.
-
[`async-zero-sleep`](https://docs.astral.sh/ruff/rules/async-zero-sleep/)
(`ASYNC115`): Support `anyio` context mangers.
-
[`long-sleep-not-forever`](https://docs.astral.sh/ruff/rules/long-sleep-not-forever/)
(`ASYNC116`): Support `anyio` context mangers.

The following fixes have been stabilized:

-
[`superfluous-else-return`](https://docs.astral.sh/ruff/rules/superfluous-else-return/)
(`RET505`)
-
[`superfluous-else-raise`](https://docs.astral.sh/ruff/rules/superfluous-else-raise/)
(`RET506`)
-
[`superfluous-else-continue`](https://docs.astral.sh/ruff/rules/superfluous-else-continue/)
(`RET507`)
-
[`superfluous-else-break`](https://docs.astral.sh/ruff/rules/superfluous-else-break/)
(`RET508`)

##### Preview features

- \[`flake8-simplify`] Further simplify to binary in preview for
(`SIM108`)
([#&#8203;12796](https://github.com/astral-sh/ruff/pull/12796))
- \[`pyupgrade`] Show violations without auto-fix (`UP031`)
([#&#8203;11229](https://github.com/astral-sh/ruff/pull/11229))

##### Rule changes

- \[`flake8-import-conventions`] Add `xml.etree.ElementTree` to default
conventions
([#&#8203;12455](https://github.com/astral-sh/ruff/pull/12455))
- \[`flake8-pytest-style`] Add a space after comma in CSV output
(`PT006`)
([#&#8203;12853](https://github.com/astral-sh/ruff/pull/12853))

##### Server

- Show a message for incorrect settings
([#&#8203;12781](https://github.com/astral-sh/ruff/pull/12781))

##### Bug fixes

- \[`flake8-async`] Do not lint yield in context manager (`ASYNC100`)
([#&#8203;12896](https://github.com/astral-sh/ruff/pull/12896))
- \[`flake8-comprehensions`] Do not lint `async for` comprehensions
(`C419`)
([#&#8203;12895](https://github.com/astral-sh/ruff/pull/12895))
- \[`flake8-return`] Only add return `None` at end of a function
(`RET503`)
([#&#8203;11074](https://github.com/astral-sh/ruff/pull/11074))
- \[`flake8-type-checking`] Avoid treating `dataclasses.KW_ONLY` as
typing-only (`TCH003`)
([#&#8203;12863](https://github.com/astral-sh/ruff/pull/12863))
- \[`pep8-naming`] Treat `type(Protocol)` et al as metaclass base
(`N805`)
([#&#8203;12770](https://github.com/astral-sh/ruff/pull/12770))
- \[`pydoclint`] Don't enforce returns and yields in abstract methods
(`DOC201`, `DOC202`)
([#&#8203;12771](https://github.com/astral-sh/ruff/pull/12771))
- \[`ruff`] Skip tuples with slice expressions in (`RUF031`)
([#&#8203;12768](https://github.com/astral-sh/ruff/pull/12768))
- \[`ruff`] Ignore unparenthesized tuples in subscripts when the
subscript is a type annotation or type alias (`RUF031`)
([#&#8203;12762](https://github.com/astral-sh/ruff/pull/12762))
- \[`ruff`] Ignore template strings passed to logging and `builtins._()`
calls (`RUF027`)
([#&#8203;12889](https://github.com/astral-sh/ruff/pull/12889))
- \[`ruff`] Do not remove parens for tuples with starred expressions in
Python <=3.10 (`RUF031`)
([#&#8203;12784](https://github.com/astral-sh/ruff/pull/12784))
- Evaluate default parameter values for a function in that function's
enclosing scope
([#&#8203;12852](https://github.com/astral-sh/ruff/pull/12852))

##### Other changes

- Respect VS Code cell metadata when detecting the language of Jupyter
Notebook cells
([#&#8203;12864](https://github.com/astral-sh/ruff/pull/12864))
- Respect `kernelspec` notebook metadata when detecting the preferred
language for a Jupyter Notebook
([#&#8203;12875](https://github.com/astral-sh/ruff/pull/12875))

###
[`v0.5.7`](https://github.com/astral-sh/ruff/blob/HEAD/CHANGELOG.md#057)

[Compare
Source](https://github.com/astral-sh/ruff/compare/0.5.6...0.5.7)

##### Preview features

- \[`flake8-comprehensions`] Account for list and set comprehensions in
`unnecessary-literal-within-tuple-call` (`C409`)
([#&#8203;12657](https://github.com/astral-sh/ruff/pull/12657))
- \[`flake8-pyi`] Add autofix for `future-annotations-in-stub`
(`PYI044`)
([#&#8203;12676](https://github.com/astral-sh/ruff/pull/12676))
- \[`flake8-return`] Avoid syntax error when auto-fixing `RET505` with
mixed indentation (space and tabs)
([#&#8203;12740](https://github.com/astral-sh/ruff/pull/12740))
- \[`pydoclint`] Add `docstring-missing-yields` (`DOC402`) and
`docstring-extraneous-yields` (`DOC403`)
([#&#8203;12538](https://github.com/astral-sh/ruff/pull/12538))
- \[`pydoclint`] Avoid `DOC201` if docstring begins with "Return",
"Returns", "Yield", or "Yields"
([#&#8203;12675](https://github.com/astral-sh/ruff/pull/12675))
- \[`pydoclint`] Deduplicate collected exceptions after traversing
function bodies (`DOC501`)
([#&#8203;12642](https://github.com/astral-sh/ruff/pull/12642))
- \[`pydoclint`] Ignore `DOC` errors for stub functions
([#&#8203;12651](https://github.com/astral-sh/ruff/pull/12651))
- \[`pydoclint`] Teach rules to understand reraised exceptions as being
explicitly raised (`DOC501`, `DOC502`)
([#&#8203;12639](https://github.com/astral-sh/ruff/pull/12639))
- \[`ruff`] Implement `incorrectly-parenthesized-tuple-in-subscript`
(`RUF031`)
([#&#8203;12480](https://github.com/astral-sh/ruff/pull/12480))
- \[`ruff`] Mark `RUF023` fix as unsafe if `__slots__` is not a set and
the binding is used elsewhere
([#&#8203;12692](https://github.com/astral-sh/ruff/pull/12692))

##### Rule changes

- \[`refurb`] Add autofix for `implicit-cwd` (`FURB177`)
([#&#8203;12708](https://github.com/astral-sh/ruff/pull/12708))
- \[`ruff`] Add autofix for `zip-instead-of-pairwise` (`RUF007`)
([#&#8203;12663](https://github.com/astral-sh/ruff/pull/12663))
- \[`tryceratops`] Add `BaseException` to `raise-vanilla-class` rule
(`TRY002`)
([#&#8203;12620](https://github.com/astral-sh/ruff/pull/12620))

##### Server

- Ignore non-file workspace URL; Ruff will display a warning
notification in this case
([#&#8203;12725](https://github.com/astral-sh/ruff/pull/12725))

##### CLI

- Fix cache invalidation for nested `pyproject.toml` files
([#&#8203;12727](https://github.com/astral-sh/ruff/pull/12727))

##### Bug fixes

- \[`flake8-async`] Fix false positives with multiple `async with` items
(`ASYNC100`)
([#&#8203;12643](https://github.com/astral-sh/ruff/pull/12643))
- \[`flake8-bandit`] Avoid false-positives for list concatenations in
SQL construction (`S608`)
([#&#8203;12720](https://github.com/astral-sh/ruff/pull/12720))
- \[`flake8-bugbear`] Treat `return` as equivalent to `break` (`B909`)
([#&#8203;12646](https://github.com/astral-sh/ruff/pull/12646))
- \[`flake8-comprehensions`] Set comprehensions not a violation for
`sum` in `unnecessary-comprehension-in-call` (`C419`)
([#&#8203;12691](https://github.com/astral-sh/ruff/pull/12691))
- \[`flake8-simplify`] Parenthesize conditions based on precedence when
merging if arms (`SIM114`)
([#&#8203;12737](https://github.com/astral-sh/ruff/pull/12737))
- \[`pydoclint`] Try both 'Raises' section styles when convention is
unspecified (`DOC501`)
([#&#8203;12649](https://github.com/astral-sh/ruff/pull/12649))

###
[`v0.5.6`](https://github.com/astral-sh/ruff/blob/HEAD/CHANGELOG.md#056)

[Compare
Source](https://github.com/astral-sh/ruff/compare/0.5.5...0.5.6)

Ruff 0.5.6 automatically enables linting and formatting of notebooks in
*preview mode*.
You can opt-out of this behavior by adding `*.ipynb` to the
`extend-exclude` setting.

```toml
[tool.ruff]
extend-exclude = ["*.ipynb"]
```

##### Preview features

- Enable notebooks by default in preview mode
([#&#8203;12621](https://github.com/astral-sh/ruff/pull/12621))
- \[`flake8-builtins`] Implement import, lambda, and module shadowing
([#&#8203;12546](https://github.com/astral-sh/ruff/pull/12546))
- \[`pydoclint`] Add `docstring-missing-returns` (`DOC201`) and
`docstring-extraneous-returns` (`DOC202`)
([#&#8203;12485](https://github.com/astral-sh/ruff/pull/12485))

##### Rule changes

- \[`flake8-return`] Exempt cached properties and other property-like
decorators from explicit return rule (`RET501`)
([#&#8203;12563](https://github.com/astral-sh/ruff/pull/12563))

##### Server

- Make server panic hook more error resilient
([#&#8203;12610](https://github.com/astral-sh/ruff/pull/12610))
- Use `$/logTrace` for server trace logs in Zed and VS Code
([#&#8203;12564](https://github.com/astral-sh/ruff/pull/12564))
- Keep track of deleted cells for reorder change request
([#&#8203;12575](https://github.com/astral-sh/ruff/pull/12575))

##### Configuration

- \[`flake8-implicit-str-concat`] Always allow explicit multi-line
concatenations when implicit concatenations are banned
([#&#8203;12532](https://github.com/astral-sh/ruff/pull/12532))

##### Bug fixes

- \[`flake8-async`] Avoid flagging `asyncio.timeout`s as unused when the
context manager includes `asyncio.TaskGroup`
([#&#8203;12605](https://github.com/astral-sh/ruff/pull/12605))
- \[`flake8-slots`] Avoid recommending `__slots__` for classes that
inherit from more than `namedtuple`
([#&#8203;12531](https://github.com/astral-sh/ruff/pull/12531))
- \[`isort`] Avoid marking required imports as unused
([#&#8203;12537](https://github.com/astral-sh/ruff/pull/12537))
- \[`isort`] Preserve trailing inline comments on import-from statements
([#&#8203;12498](https://github.com/astral-sh/ruff/pull/12498))
- \[`pycodestyle`] Add newlines before comments (`E305`)
([#&#8203;12606](https://github.com/astral-sh/ruff/pull/12606))
- \[`pycodestyle`] Don't attach comments with mismatched indents
([#&#8203;12604](https://github.com/astral-sh/ruff/pull/12604))
- \[`pyflakes`] Fix preview-mode bugs in `F401` when attempting to
autofix unused first-party submodule imports in an `__init__.py` file
([#&#8203;12569](https://github.com/astral-sh/ruff/pull/12569))
- \[`pylint`] Respect start index in `unnecessary-list-index-lookup`
([#&#8203;12603](https://github.com/astral-sh/ruff/pull/12603))
- \[`pyupgrade`] Avoid recommending no-argument super in `slots=True`
dataclasses
([#&#8203;12530](https://github.com/astral-sh/ruff/pull/12530))
- \[`pyupgrade`] Use colon rather than dot formatting for integer-only
types
([#&#8203;12534](https://github.com/astral-sh/ruff/pull/12534))
- Fix NFKC normalization bug when removing unused imports
([#&#8203;12571](https://github.com/astral-sh/ruff/pull/12571))

##### Other changes

- Consider more stdlib decorators to be property-like
([#&#8203;12583](https://github.com/astral-sh/ruff/pull/12583))
- Improve handling of metaclasses in various linter rules
([#&#8203;12579](https://github.com/astral-sh/ruff/pull/12579))
- Improve consistency between linter rules in determining whether a
function is property
([#&#8203;12581](https://github.com/astral-sh/ruff/pull/12581))

###
[`v0.5.5`](https://github.com/astral-sh/ruff/blob/HEAD/CHANGELOG.md#055)

[Compare
Source](https://github.com/astral-sh/ruff/compare/0.5.4...0.5.5)

##### Preview features

- \[`fastapi`] Implement `fastapi-redundant-response-model` (`FAST001`)
and `fastapi-non-annotated-dependency`(`FAST002`)
([#&#8203;11579](https://github.com/astral-sh/ruff/pull/11579))
- \[`pydoclint`] Implement `docstring-missing-exception` (`DOC501`) and
`docstring-extraneous-exception` (`DOC502`)
([#&#8203;11471](https://github.com/astral-sh/ruff/pull/11471))

##### Rule changes

- \[`numpy`] Fix NumPy 2.0 rule for `np.alltrue` and `np.sometrue`
([#&#8203;12473](https://github.com/astral-sh/ruff/pull/12473))
- \[`numpy`] Ignore `NPY201` inside `except` blocks for compatibility
with older numpy versions
([#&#8203;12490](https://github.com/astral-sh/ruff/pull/12490))
- \[`pep8-naming`] Avoid applying `ignore-names` to `self` and `cls`
function names (`N804`, `N805`)
([#&#8203;12497](https://github.com/astral-sh/ruff/pull/12497))

##### Formatter

- Fix incorrect placement of leading function comment with type params
([#&#8203;12447](https://github.com/astral-sh/ruff/pull/12447))

##### Server

- Do not bail code action resolution when a quick fix is requested
([#&#8203;12462](https://github.com/astral-sh/ruff/pull/12462))

##### Bug fixes

- Fix `Ord` implementation of `cmp_fix`
([#&#8203;12471](https://github.com/astral-sh/ruff/pull/12471))
- Raise syntax error for unparenthesized generator expression in
multi-argument call
([#&#8203;12445](https://github.com/astral-sh/ruff/pull/12445))
- \[`pydoclint`] Fix panic in `DOC501` reported in
[#&#8203;12428](https://github.com/astral-sh/ruff/pull/12428)
([#&#8203;12435](https://github.com/astral-sh/ruff/pull/12435))
- \[`flake8-bugbear`] Allow singleton tuples with starred expressions in
`B013`
([#&#8203;12484](https://github.com/astral-sh/ruff/pull/12484))

##### Documentation

- Add Eglot setup guide for Emacs editor
([#&#8203;12426](https://github.com/astral-sh/ruff/pull/12426))
- Add note about the breaking change in `nvim-lspconfig`
([#&#8203;12507](https://github.com/astral-sh/ruff/pull/12507))
- Add note to include notebook files for native server
([#&#8203;12449](https://github.com/astral

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "on the 2nd and 4th day instance on
sunday after 9pm" in timezone America/New_York, Automerge - At any time
(no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/HHS/simpler-grants-gov).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4zNjguMTAiLCJ1cGRhdGVkSW5WZXIiOiIzOC44MC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
@lukas503
Copy link

lukas503 commented Sep 24, 2024

Unexpected Warning in Pydantic 2.9.2 with Discriminated Union and Overlapping Literal Names

I'm encountering a warning with the following code when using discriminated unions in Pydantic 2.9.2. While the code still behaves as expected, I am curious if the warning is intentional. Specifically, could the warning be due to multiple classes using the same Literal value for the name field? Is that correct usage? 🤔

from typing import Union, Literal, Annotated, Optional
from pydantic import BaseModel, Field, ConfigDict
import pydantic
print(pydantic.__version__)

class _BaseConfig(BaseModel):
    model_config = ConfigDict(
        extra="forbid"  # Don't allow extra values
    )

class A(_BaseConfig):
    c: int
    name: Literal["A"] = "A"
    
    def __repr__(self):
        return "ClassA"

class B(_BaseConfig):
    b: int
    name: Literal["B"] = "B"
    
    def __repr__(self):
        return "ClassB"

class C(_BaseConfig):
    c: int
    d: int
    name: Literal["A"] = "A"
        
    def __repr__(self):
        return "ClassC"

class D(_BaseConfig):
    c: int
    d: int
    name: Literal["B"] = "B"
    
    def __repr__(self):
        return "ClassD"

Var = Union[
    Annotated[A, Field(discriminator='name')], 
    Annotated[B, Field(discriminator='name')], 
    Annotated[C, Field(discriminator='name')], 
    Annotated[D, Field(discriminator='name')]
]

class T(BaseModel):
    a: Optional[Union[dict[str, Var], Var]] = None

model = T(a={"test": {"name": "A", "c": 1, "d": 2}})
print(model, model.model_dump(), T(**model.model_dump()))

model = T(a={"test": {"name": "A", "c": 1,}})
print(model, model.model_dump(), T(**model.model_dump()))

model = T(a={"test": {"name": "B", "b": 1,}})
print(model, model.model_dump(), T(**model.model_dump()))

model = T(a={"test": {"name": "B", "c": 1, "d": 5}})
print(model, model.model_dump(), T(**model.model_dump()))

model = T(a={"name": "B", "c": 1, "d": 2})
print(model, model.model_dump(), T(**model.model_dump()))

Output

2.9.2
a={'test': ClassC} {'a': {'test': {'c': 1, 'd': 2, 'name': 'A'}}} a={'test': ClassC}
a={'test': ClassA} {'a': {'test': {'c': 1, 'name': 'A'}}} a={'test': ClassA}
a={'test': ClassB} {'a': {'test': {'b': 1, 'name': 'B'}}} a={'test': ClassB}
a={'test': ClassD} {'a': {'test': {'c': 1, 'd': 5, 'name': 'B'}}} a={'test': ClassD}
a=ClassD {'a': {'c': 1, 'd': 2, 'name': 'B'}} a=ClassD
.../envs/dev_l1/lib/python3.9/site-packages/pydantic/main.py:390: UserWarning: Pydantic serializer warnings:
  PydanticSerializationUnexpectedValue: Expected `A` but got `C` with value `ClassC` - serialized value may not be as expected
  return self.__pydantic_serializer__.to_python(
.../envs/dev_l1/lib/python3.9/site-packages/pydantic/main.py:390: UserWarning: Pydantic serializer warnings:
  PydanticSerializationUnexpectedValue: Expected `A` but got `B` with value `ClassB` - serialized value may not be as expected
  return self.__pydantic_serializer__.to_python(
.../envs/dev_l1/lib/python3.9/site-packages/pydantic/main.py:390: UserWarning: Pydantic serializer warnings:
  PydanticSerializationUnexpectedValue: Expected `A` but got `D` with value `ClassD` - serialized value may not be as expected
  return self.__pydantic_serializer__.to_python(

My environment:

             pydantic version: 2.9.2
        pydantic-core version: 2.23.4
          pydantic-core build: profile=release pgo=false
                 install path: .../envs/dev_l1/lib/python3.9/site-packages/pydantic
               python version: 3.9.19 (main, May  6 2024, 19:43:03)  [GCC 11.2.0]
                     platform: Linux-6.5.0-1023-gcp-x86_64-with-glibc2.35
             related packages: typing_extensions-4.12.2 pyright-1.1.358

Question: Is the warning related to using the same literal value for multiple classes, or is this a bug in the Pydantic serialization process? Any insights into the cause of this behavior would be appreciated.

@davidhewitt
Copy link
Contributor

@lukas503 your use of discriminators is wrong, see pydantic/pydantic#10482. Indeed they should not be overlapping. It looks like we can help protect against this case better.

@lukas503
Copy link

Thanks. Better protection sounds helpful 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants