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

The subclass of dict is not respected on >=2024.11.0 #8932

Open
emmaai opened this issue Nov 13, 2024 · 2 comments
Open

The subclass of dict is not respected on >=2024.11.0 #8932

emmaai opened this issue Nov 13, 2024 · 2 comments
Labels
bug Something is broken

Comments

@emmaai
Copy link

emmaai commented Nov 13, 2024

Describe the issue:
The subclass is not respected. I noticed the issue on subclass of dict, not sure if it's more general. See below for details.

Minimal Complete Verifiable Example:

from dask.distributed import Client, as_completed

class TestDict(dict):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def __getattr__(self, key: str):
        """ Allow access to items as attributes. """
        v = self.get(key, self)
        if v is self:
            raise AttributeError("has no attribute '{}'".format(key))
        return v

    def __repr__(self) -> str:
        return "(TestDict{})".format(super().__repr__())


def test_subclass(test_dict):
    print(f'input type {type(test_dict)}')
    print(f'get val {test_dict.a}')
    return 0


def main():
    client = Client()
    test_dict = TestDict(a=1)
    futures = [client.submit(test_subclass, test_dict)]
    for f in as_completed(futures):
        res = f.result()
        print(f"result {res}")


if __name__ == "__main__":
    main()

Anything else we need to know?:

The test code works as expected on <2024.11.0, which outputs

input type <class '__main__.TestDict'>
get val 1
result 0

on >=2024.11.0 outputs

input type <class 'dict'>
2024-11-13 05:01:36,954 - distributed.worker - ERROR - Compute Failed
Key:       test_subclass-e8dd185fef44ec112f057d9b352f913f
State:     executing
Task:  <Task 'test_subclass-e8dd185fef44ec112f057d9b352f913f' test_subclass(...)>
Exception: 'AttributeError("\'dict\' object has no attribute \'a\'")'
Traceback: '  File "/home/ubuntu/data/home/ubuntu/test_dask.py", line 20, in test_subclass\n    print(f\'get val {test_dict.a}\')\n'

Traceback (most recent call last):
  File "/home/ubuntu/data/home/ubuntu/test_dask.py", line 34, in <module>
    main()
  File "/home/ubuntu/data/home/ubuntu/test_dask.py", line 29, in main
    res = f.result()
  File "/home/ubuntu/.local/lib/python3.10/site-packages/distributed/client.py", line 402, in result
    return self.client.sync(self._result, callback_timeout=timeout)
  File "/home/ubuntu/data/home/ubuntu/test_dask.py", line 20, in test_subclass
    print(f'get val {test_dict.a}')

Environment:

  • Dask version: 2024.11.0
  • Python version: 3.10
  • Operating System: ubuntu 22.04
  • Install method (conda, pip, source): pip
@templiert
Copy link
Contributor

I am experiencing the same issue with DotMap objects, which are a dict subclass with dot-access.
It is probably covered by the good general MCVE exposed by @emmaai.
Below is a MCVE modified from @emmaai that breaks with DotMap objects.

from distributed import Client
from dotmap import DotMap


def test_subclass(test_dict):
    print(f"input type {type(test_dict)}")
    print(f"get val {test_dict.a}")
    return 0


def main():
    with Client() as client:
        print(client.submit(test_subclass, DotMap({"a": 1})).result())


if __name__ == "__main__":
    main()
input type <class 'dict'>
2024-11-18 12:33:05,966 - distributed.worker - ERROR - Compute Failed
Key:       test_subclass-fc48deb6364566a152c9e2cd5c01bf6d
State:     executing
Task:  <Task 'test_subclass-fc48deb6364566a152c9e2cd5c01bf6d' test_subclass(...)>
Exception: 'AttributeError("\'dict\' object has no attribute \'a\'")'
Traceback: '  File "C:\\software\\repos\\myapp\\tests\\dotmap_dask_202411.py", line 7, in test_subclass\n    print(f"get val {test_dict.a}")\n                     ^^^^^^^^^^^\n'

Traceback (most recent call last):
  File "C:\software\repos\myapp\tests\dotmap_dask_202411.py", line 17, in <module>
    main()
  File "C:\software\repos\myapp\tests\dotmap_dask_202411.py", line 13, in main
    print(client.submit(test_subclass, DotMap({"a": 1})).result())
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\software\miniforge\envs\ibeammsem\Lib\site-packages\distributed\client.py", line 402, in result
    return self.client.sync(self._result, callback_timeout=timeout)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\software\repos\myapp\tests\dotmap_dask_202411.py", line 7, in test_subclass
    print(f"get val {test_dict.a}")
      ^^^^^^^^^^^^^^^^^
AttributeError: 'dict' object has no attribute 'a'
INSTALLED VERSIONS
------------------
commit: None
python: 3.12.5 | packaged by conda-forge | (main, Aug  8 2024, 18:24:51) [MSC v.1940 64 bit (AMD64)]
python-bits: 64
OS: Windows
OS-release: 11
machine: AMD64
processor: Intel64 Family 6 Model 186 Stepping 2, GenuineIntel
byteorder: little
LC_ALL: None
LANG: None
LOCALE: ('English_United States', '1252')
libhdf5: None
libnetcdf: None

xarray: 2024.10.0
pandas: 2.2.2
numpy: 1.26.4
scipy: 1.14.0
netCDF4: None
pydap: None
h5netcdf: None
h5py: None
zarr: 2.18.3
cftime: None
nc_time_axis: None
iris: None
bottleneck: 1.4.2
dask: 2024.11.2
distributed: 2024.11.2
matplotlib: 3.9.2
cartopy: None
seaborn: None
numbagg: None
fsspec: 2024.6.1
cupy: None
pint: None
sparse: None
flox: None
numpy_groupies: None
setuptools: 72.1.0
pip: 24.2
conda: None
pytest: None
mypy: None
IPython: 8.26.0
sphinx: None

@jacobtomlinson
Copy link
Member

Looks like this bug was introduced in #8797. cc @fjetter

@jacobtomlinson jacobtomlinson added bug Something is broken and removed needs triage labels Nov 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something is broken
Projects
None yet
Development

No branches or pull requests

3 participants