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

TypeError: unhashable type: 'PosixPath' when collecting conftest #8330

Closed
joshfriend opened this issue Feb 8, 2021 · 4 comments
Closed

TypeError: unhashable type: 'PosixPath' when collecting conftest #8330

joshfriend opened this issue Feb 8, 2021 · 4 comments
Labels
status: needs information reporter needs to provide more information; can be closed after 2 or more weeks of inactivity topic: collection related to the collection phase

Comments

@joshfriend
Copy link

Environment details:

  • macOS 10.14.6
  • python 3.8.5
  • pytest 6.2.2

I'm facing a completely inscrutable error which I cannot for the life of me figure out. If I have pathlib.Path as a type hint on a class, I get the following error from pytest:

Traceback (most recent call last):
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/_pytest/config/__init__.py", line 480, in _importconftest
    return self._conftestpath2mod[key]
KeyError: PosixPath()

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/josh/someproject/.venv/bin/pytest", line 8, in <module>
    sys.exit(main())
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/_pytest/config/__init__.py", line 90, in main
    config = _prepareconfig(args, plugins)
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/_pytest/config/__init__.py", line 242, in _prepareconfig
    return pluginmanager.hook.pytest_cmdline_parse(
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/pluggy/hooks.py", line 286, in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/pluggy/manager.py", line 93, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/pluggy/manager.py", line 84, in <lambda>
    self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/pluggy/callers.py", line 203, in _multicall
    gen.send(outcome)
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/_pytest/helpconfig.py", line 90, in pytest_cmdline_parse
    config = outcome.get_result()
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/pluggy/callers.py", line 80, in get_result
    raise ex[1].with_traceback(ex[2])
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/pluggy/callers.py", line 187, in _multicall
    res = hook_impl.function(*args)
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/_pytest/config/__init__.py", line 822, in pytest_cmdline_parse
    self.parse(args)
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/_pytest/config/__init__.py", line 1030, in parse
    self._preparse(args, addopts=addopts)
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/_pytest/config/__init__.py", line 987, in _preparse
    self.hook.pytest_load_initial_conftests(
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/pluggy/hooks.py", line 286, in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/pluggy/manager.py", line 93, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/pluggy/manager.py", line 84, in <lambda>
    self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/pluggy/callers.py", line 208, in _multicall
    return outcome.get_result()
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/pluggy/callers.py", line 80, in get_result
    raise ex[1].with_traceback(ex[2])
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/pluggy/callers.py", line 187, in _multicall
    res = hook_impl.function(*args)
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/_pytest/config/__init__.py", line 885, in pytest_load_initial_conftests
    self.pluginmanager._set_initial_conftests(early_config.known_args_namespace)
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/_pytest/config/__init__.py", line 426, in _set_initial_conftests
    self._try_load_conftest(anchor)
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/_pytest/config/__init__.py", line 432, in _try_load_conftest
    self._getconftestmodules(anchor)
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/_pytest/config/__init__.py", line 458, in _getconftestmodules
    mod = self._importconftest(conftestpath)
  File "</Users/josh/someproject/.venv/lib/python3.8>/site-packages/_pytest/config/__init__.py", line 498, in _importconftest
    self._conftestpath2mod[key] = mod
TypeError: unhashable type: 'PosixPath'

I have searched the issues list and found a similar error showed up in #6925, but I do not use xdist. If i replace type hints of Path with os.PathLike the problem is "fixed". If i use pathlib.PurePath, I get this error:

Traceback (most recent call last):
  File "/Users/josh/someproject/.venv/bin/pytest", line 8, in <module>
    sys.exit(console_main())
  File "/Users/josh/someproject/.venv/lib/python3.8/site-packages/_pytest/config/__init__.py", line 185, in console_main
    code = main()
  File "/Users/josh/someproject/.venv/lib/python3.8/site-packages/_pytest/config/__init__.py", line 148, in main
    exc_info.traceback = exc_info.traceback.filter(
  File "/Users/josh/someproject/.venv/lib/python3.8/site-packages/_pytest/_code/code.py", line 395, in filter
    return Traceback(filter(fn, self), self._excinfo)
  File "/Users/josh/someproject/.venv/lib/python3.8/site-packages/_pytest/_code/code.py", line 335, in __init__
    super().__init__(tb)
  File "/Users/josh/someproject/.venv/lib/python3.8/site-packages/_pytest/config/__init__.py", line 127, in filter_traceback_for_conftest_import_failure
    return filter_traceback(entry) and "importlib" not in str(entry.path).split(os.sep)
  File "/Users/josh/someproject/.venv/lib/python3.8/site-packages/_pytest/_code/code.py", line 1249, in filter_traceback
    p = Path(entry.path)
TypeError: __init__() takes 1 positional argument but 2 were given
$ pip list
Package               Version
--------------------- -------
apispec               3.3.2
APScheduler           3.7.0
astroid               2.4.2
attrs                 20.3.0
basicauth             0.4.1
bitarray              1.6.3
click                 7.1.2
colorzero             1.1
coverage              5.4
Flask                 1.1.2
Flask-Cors            3.0.10
Flask-SocketIO        4.3.2
freezegun             0.3.15
gevent                21.1.2
gpiozero              1.5.1
greenlet              1.0.0
gunicorn              20.0.4
isort                 5.7.0
itsdangerous          1.1.0
Jinja2                2.11.3
lazy-object-proxy     1.4.3
MarkupSafe            1.1.1
marshmallow           3.10.0
marshmallow-dataclass 6.1.0
mccabe                0.6.1
more-itertools        8.7.0
mypy-extensions       0.4.3
packaging             20.9
pip                   21.0.1
pluggy                0.13.1
py                    1.10.0
PyJWT                 1.7.1
pylint                2.6.0
pylint-flask          0.6
pylint-plugin-utils   0.6
pyparsing             2.4.7
pyserial              3.5
pytest                5.4.3
pytest-cov            2.11.1
pytest-mock           1.13.0
pytest-random-order   1.0.4
python-dateutil       2.8.1
python-engineio       3.14.2
python-socketio       4.6.1
pytz                  2020.5
services              0.1.0
setuptools            52.0.0
simplejson            3.17.2
six                   1.15.0
toml                  0.10.2
typing-extensions     3.7.4.3
typing-inspect        0.6.0
tzlocal               2.1
wcwidth               0.2.5
webargs               5.5.3
Werkzeug              1.0.1
wheel                 0.36.2
wrapt                 1.12.1
zope.event            4.5.0
zope.interface        5.2.0
@The-Compiler
Copy link
Member

Could you show the code causing this, rather than describing it?

@asottile asottile added the status: needs information reporter needs to provide more information; can be closed after 2 or more weeks of inactivity label Feb 8, 2021
@joshfriend
Copy link
Author

Yeah, sorry. It seems pretty innocuous, adding this to my project causes the unhashable type error:

from pathlib import Path
from dataclasses import dataclass
@dataclass
class Example:
    foo: Path

Can't share the entire project unfortunately, but the reason I think it might have something to do with pytest is that the app runs fine with this code, but test collection blows up with the errors I posted earlier.

@nicoddemus
Copy link
Member

Hi @joshfriend,

Thanks for posting an example, however this passes for me (in 5.4.3 and 6.2.2):

λ pytest foo.py --no-header
======================================= test session starts =======================================
collected 0 items

======================================== warnings summary =========================================
foo.py:4
  d:\projects\pytest\.tmp\foo.py:4: PytestCollectionWarning: cannot collect test class 'TestExample' because it has a __init__ constructor (from: foo.py)
    class TestExample:

-- Docs: https://docs.pytest.org/en/stable/warnings.html
======================================= 1 warning in 0.01s ========================================

(I renamed Example to TestExample so pytest would try to collect it as a test).

Can you reproduce the problem in a minimal example, like the one you posted but that fails when executed by pytest?

@Zac-HD Zac-HD added the topic: collection related to the collection phase label Feb 9, 2021
@Zac-HD
Copy link
Member

Zac-HD commented Nov 29, 2021

Closing because there's not much we can do without a reproducing example.

@Zac-HD Zac-HD closed this as completed Nov 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: needs information reporter needs to provide more information; can be closed after 2 or more weeks of inactivity topic: collection related to the collection phase
Projects
None yet
Development

No branches or pull requests

5 participants