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

__hash__ implemented inBaseModel subclass no longer called with functools.cache #6786

Closed
1 task done
d-chambers opened this issue Jul 20, 2023 · 2 comments · Fixed by #6789
Closed
1 task done

__hash__ implemented inBaseModel subclass no longer called with functools.cache #6786

d-chambers opened this issue Jul 20, 2023 · 2 comments · Fixed by #6789
Assignees
Labels
bug V2 Bug related to Pydantic V2 unconfirmed Bug not yet confirmed as valid/applicable

Comments

@d-chambers
Copy link

d-chambers commented Jul 20, 2023

Initial Checks

  • I confirm that I'm using Pydantic V2

Description

In V1 I was able to overwrite the default __hash__ method such that functools.cache would work for models that have mutable parameters (numpy array, which had its write flag set to False). This no longer works in V2.

Related issues: #2423, #1880

Example Code

from functools import _lru_cache_wrapper, cached_property, cache

import numpy as np
from pydantic import ConfigDict, BaseModel


class MyBaseModel(BaseModel):
    """A base model with sensible configurations."""
    model_config = ConfigDict(
        ignored_types=(cached_property, _lru_cache_wrapper),
        frozen=True,
        arbitrary_types_allowed=True,
    )

    def __hash__(self):
        return hash(id(self))


class MySubClass(MyBaseModel):
    ar: np.ndarray

    @cached_property
    def cached_prop(self):
        return self.ar.shape

    @cache
    def cached_method(self):
        return self.ar.size


my_instance = MySubClass(ar=np.ones(10))

my_instance.cached_prop

my_instance.cached_method()

Python, Pydantic & OS Version

pydantic version: 2.0.3
        pydantic-core version: 2.3.0 release build profile
                 install path: /home/derrick/anaconda3/envs/dascore/lib/python3.10/site-packages/pydantic
               python version: 3.10.11 | packaged by conda-forge | (main, May 10 2023, 18:58:44) [GCC 11.3.0]
                     platform: Linux-5.15.0-76-generic-x86_64-with-glibc2.31
     optional deps. installed: ['typing-extensions']

Selected Assignee: @adriangb

@d-chambers d-chambers added bug V2 Bug related to Pydantic V2 unconfirmed Bug not yet confirmed as valid/applicable labels Jul 20, 2023
@d-chambers
Copy link
Author

I should say, this raises this exception:

  File ".../lib/python3.10/site-packages/pydantic/_internal/_model_construction.py", line 122, in hash_func
    return hash(self.__class__) + hash(tuple(self.__dict__.values()))
TypeError: unhashable type: 'numpy.ndarray'

@d-chambers d-chambers changed the title __hash__ no longer called __hash__ implemented inBaseModel subclass no longer called with functools.cache Jul 20, 2023
@dmontagu
Copy link
Contributor

I think I see a fix for this; I think a short-term work-around may be to do __hash__ = MyBaseModel.__hash__ in the definition of MySubClass, but I'll work on fixing so this isn't necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug V2 Bug related to Pydantic V2 unconfirmed Bug not yet confirmed as valid/applicable
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants