Skip to content

Commit

Permalink
[codemod][py3.12] Convert dataclasses mutable default values to use d…
Browse files Browse the repository at this point in the history
…efault_factory

Summary:
As of [Python 3.11](https://docs.python.org/3.11/whatsnew/3.11.html#dataclasses), dataclasses now only allow defaults that are hashable. Using mutable (non-hashable) default values under Python 3.11+ will cause a runtime error:

```
ValueError: mutable default <class 'problematic.ClassName'> for field <field> is not allowed: use default_factory
```

This codemod attempts to automatically convert mutable defaults to use `default_factory`

NOTE: The change is not semantically equivalent to before the change. Before, all dataclass instances with a mutable default value were sharing the same instance. This change results each dataclass instance using a new instance of the mutable value. It is likely that the before state was a latent bug, but it's still a behavior change!

Reviewed By: itamaro

Differential Revision: D70448655

fbshipit-source-id: 09b49467f1fe54f5ea9669de401f4f9cceadc06e
  • Loading branch information
generatedunixname647790274085263 authored and facebook-github-bot committed Mar 3, 2025
1 parent 223b137 commit 3c541ee
Showing 1 changed file with 9 additions and 5 deletions.
14 changes: 9 additions & 5 deletions mmf/modules/encoders.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import re
from collections import OrderedDict
from copy import deepcopy
from dataclasses import asdict, dataclass
from dataclasses import asdict, dataclass, field
from enum import Enum
from typing import Any

Expand Down Expand Up @@ -591,11 +591,15 @@ class MultiModalEncoderBase(Encoder):
@dataclass
class Config(Encoder.Config):
# This actually is Union[ImageEncoderConfig, ImageFeatureEncoderConfig]
modal_encoder: EncoderFactory.Config = ImageEncoderFactory.Config(
type=ImageEncoderTypes.resnet152, params=ResNet152ImageEncoder.Config()
modal_encoder: EncoderFactory.Config = field(
default_factory=lambda: ImageEncoderFactory.Config(
type=ImageEncoderTypes.resnet152, params=ResNet152ImageEncoder.Config()
)
)
text_encoder: EncoderFactory.Config = TextEncoderFactory.Config(
type=TextEncoderTypes.transformer, params=TransformerEncoder.Config()
text_encoder: EncoderFactory.Config = field(
default_factory=lambda: TextEncoderFactory.Config(
type=TextEncoderTypes.transformer, params=TransformerEncoder.Config()
)
)
direct_features_input: bool = False
modal_hidden_size: int = 2048
Expand Down

0 comments on commit 3c541ee

Please sign in to comment.