Skip to content

update_forward_refs modifies __dict__ of a module #1228

@Paul-Ilyin

Description

@Paul-Ilyin

Bug

OS: macOS Catalina 10.15.3  
python: 3.7.3
pydantic version: 1.1

After creating a BaseModel subclass and calling update_forward_ref() classmethod, pydantic can modify dict of a module in which the model was created if the model was declared inside some function of this module.

from typing import Optional, ForwardRef
from pydantic import BaseModel

def first_func():
    class Mod(BaseModel):
        field: Optional[ForwardRef("Mod")]
    Mod.update_forward_refs()
    return Mod

def second_func():
    class Mod(BaseModel):
        another_field: Optional[ForwardRef("Mod")]

    Mod.update_forward_refs()
    
    return Mod

first_model = first_func()
second_model = second_func()

print(second_model.__fields__["another_field"].type_)
# Output: <class '__main__.first_func.<locals>.Mod'>
# Expected: <class '__main__.second_func.<locals>.Mod'>

It happens because of these two lines: https://github.com/samuelcolvin/pydantic/blob/645e5fe6a0c74c95c24410571e9bb804af3eb677/pydantic/main.py#L632-L633
They can be fixed that way:

        globalns = sys.modules[cls.__module__].__dict__.copy()
        globalns.setdefault(cls.__name__, cls)

This bug can lead to errors when two different models with the same names are defined in two different test cases or some other errors which can be hard to debug.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug V1Bug related to Pydantic V1.X

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions