facebook / facebook/pyrefly

Pydantic PrivateAttr fields should be writable?

Open
#4,400 2 comments 0 reactions 0 assignees View on GitHub
pydantic
Dominant language
Rust
Stars
7k
Forks
516
PR merge metrics
No merged PRs in 30d

Description

### Describe the Bug

When a `pydantic.BaseModel` sets `frozen=True` in its configurations, `pyrefly` correctly recognizes that ordinary fields cannot be written to. But fields marked as `PrivateAttr` *should* be writable, since `pydantic` itself permits it at runtime.

Example:

```python
from pydantic import BaseModel, ConfigDict, PrivateAttr

class Model(BaseModel):
model_config = ConfigDict(frozen=True)
public: int = 0
_private: int = PrivateAttr(default=0)

model = Model()

# runtime error occurs
# both mypy and pyrefly mark this as an error
model.public = 1

# no runtime error
# mypy allows this
# pyrefly marks as "read-only" error
model._private = 1
```

### Sandbox Link

_No response_

### (Only applicable for extension issues) IDE Information

_No response_

Contributor guide

Open the contributing guide

Research direction

Start with the provided Python reproducer and trace how pyrefly handles assignment to frozen-model attributes, comparing ordinary fields with Pydantic PrivateAttr fields. Look for the relevant type-checker tests or assignment-analysis entry point, then add coverage showing that private attributes remain writable while public fields remain read-only.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.