omry / omegaconf

Flexible Python configuration system. The last one you will ever need.
BSD 3-Clause "New" or "Revised" License
1.94k stars 105 forks source link

module 'attr' has no attribute 'has' #1055

Closed gummz closed 1 year ago

gummz commented 1 year ago

Describe the bug A clear and concise description of what the bug is.

File "/home/ghb/project/repro.py", line 9, in <module>
    import hydra
  File "/home/ghb/anaconda3/envs/aisc/lib/python3.9/site-packages/hydra/__init__.py", line 5, in <module>
    from hydra import utils
  File "/home/ghb/anaconda3/envs/aisc/lib/python3.9/site-packages/hydra/utils.py", line 8, in <module>
    import hydra._internal.instantiate._instantiate2
  File "/home/ghb/anaconda3/envs/aisc/lib/python3.9/site-packages/hydra/_internal/instantiate/_instantiate2.py", line 12, in <module>
    from hydra._internal.utils import _locate
  File "/home/ghb/anaconda3/envs/aisc/lib/python3.9/site-packages/hydra/_internal/utils.py", line 18, in <module>
    from hydra.core.utils import get_valid_filename, validate_config_path
  File "/home/ghb/anaconda3/envs/aisc/lib/python3.9/site-packages/hydra/core/utils.py", line 20, in <module>
    from hydra.core.hydra_config import HydraConfig
  File "/home/ghb/anaconda3/envs/aisc/lib/python3.9/site-packages/hydra/core/hydra_config.py", line 6, in <module>
    from hydra.conf import HydraConf
  File "/home/ghb/anaconda3/envs/aisc/lib/python3.9/site-packages/hydra/conf/__init__.py", line 179, in <module>
    cs.store(
  File "/home/ghb/anaconda3/envs/aisc/lib/python3.9/site-packages/hydra/core/config_store.py", line 85, in store
    cfg = OmegaConf.structured(node)
  File "/home/ghb/anaconda3/envs/aisc/lib/python3.9/site-packages/omegaconf/omegaconf.py", line 125, in structured
    return OmegaConf.create(obj, parent, flags)
  File "/home/ghb/anaconda3/envs/aisc/lib/python3.9/site-packages/omegaconf/omegaconf.py", line 178, in create
    return OmegaConf._create_impl(
  File "/home/ghb/anaconda3/envs/aisc/lib/python3.9/site-packages/omegaconf/omegaconf.py", line 845, in _create_impl
    or is_structured_config(obj)
  File "/home/ghb/anaconda3/envs/aisc/lib/python3.9/site-packages/omegaconf/_utils.py", line 448, in is_structured_config
    return is_attr_class(obj) or is_dataclass(obj)
  File "/home/ghb/anaconda3/envs/aisc/lib/python3.9/site-packages/omegaconf/_utils.py", line 444, in is_attr_class
    return attr.has(obj)
AttributeError: module 'attr' has no attribute 'has'

To Reproduce Please provide a minimal repro. This can include a small Python file, and potentially a few small config files. If you have more than one file you can attach a zip file with everything to the issue.

conda create -n new_env python==3.9.15
conda activate new_env
pip install hydra-core attr
python run repro.py

repro.py:

import hydra
from omegaconf import DictConfig, OmegaConf

@hydra.main(version_base=None, config_path='configs_repro', config_name='config')
def main(args: DictConfig):
    print(OmegaConf.to_yaml(args))

if __name__ == "__main__":
    main()

configs_repro/config.yaml: test: True

Expected behavior A clear and concise description of what you expected to happen.

A successful initialization of my configs, and a returned namespace object.

Additional context

omry commented 1 year ago

Yes, it does: https://www.attrs.org/en/stable/api.html#attrs.has

Do you have another thing providing attr in your environment, or, are you using an old version of attr?

gummz commented 1 year ago

The former. Result of pip show attr:

Name: attr
Version: 0.3.2
Summary: Simple decorator to set attributes of target function or class in a DRY way.
Home-page: https://github.com/denis-ryzhkov/attr
Author: Denis Ryzhkov
Author-email: denisr@denisr.com
License: MIT
Location: /home/ghb/anaconda3/envs/aisc/lib/python3.9/site-packages
Requires: 
Required-by: 

I see here https://pypi.org/project/attrs/ that, in their example, the import is referred to as attrs. But in _utils.py it's referred to as attr.

Jasha10 commented 1 year ago

@gummz you want pip install attrs, not pip install attr.

gummz commented 1 year ago

I may be mistaken but I don't think that is the solution. There is a package called attr which is different from attrs. On attrs' project page, it is seen that they import it like import attrs, but you import it as import attr, which leads to a conflict with the package called attr, without the s.

I put pip install attr to reproduce the problem, which is that there is a conflict between attr and attrs, if you import attrs as import attr.

Jasha10 commented 1 year ago

The output of your pip show attr points to this package on pypi. That is not the right package. You need this package on pypi.

See also the attrs.org documentation, which says python -m pip install attrs is the way to go.

Both the attr and the attrs packages on pypi install a module called attr.

gummz commented 1 year ago

Ah ok that makes sense. Is there anything to do about a package conflict like this? I need attr for my project. To get it to work I had to return false instead of calling attr.has().

Jasha10 commented 1 year ago

Oh dear. Unfortunately, Python doesn't have great support for resolving such conflicts in the module namespace. I think this is a type of dependency hell.

To summarize the issue, the OmegaConf source has hardcoded a dependency on a module named attr, and you're using an unrelated package that also exports an attr module.

I can't think of any solution besides forking one of the packages involved and doing some renaming: