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

'EmptyConstraint' object has no attribute 'min' with pytest and Python 2.7 #3862

Closed
3 tasks done
nikmolnar opened this issue Mar 31, 2021 · 20 comments · Fixed by python-poetry/poetry-core#155
Closed
3 tasks done
Labels
kind/bug Something isn't working as expected

Comments

@nikmolnar
Copy link
Contributor

  • I am on the latest Poetry version.
  • I have searched the issues of this repo and believe that this is not a duplicate.
  • If an exception occurs when executing a command, I executed it again in debug mode (-vvv option).

Issue

I've discovered a bug that arises when pytest is combined with Python ^2.7 in pyproject.toml. The Gist linked above provides a minimal example of this issue. Running poetry lock with the above file results in the following exception:

AttributeError

  'EmptyConstraint' object has no attribute 'min'

The error does not appear if either pytest is removed or the Python version is changed to ^3.6. I originally reported this as part of #2372, but then realized that that issue related to error handing in response to an error in pyproject.toml. As this error occurs in a correctly-formatted pyproject.toml, I believe it is a distinct issue.

@nikmolnar nikmolnar added kind/bug Something isn't working as expected status/triage This issue needs to be triaged labels Mar 31, 2021
@JennToo
Copy link

JennToo commented Mar 31, 2021

We started seeing this same error yesterday as well. I'm guessing some dependency in the tree did a release recently that is somehow exposing this bug.

@JennToo
Copy link

JennToo commented Mar 31, 2021

After some debugging I think I narrowed down the problem to a recent backports.functools-lru-cache package release. Changing the dev-deps to this still reproduces the problem:

[tool.poetry.dev-dependencies]
"backports.functools-lru-cache" = "*"

As a temporary workaround, you can pin this dependency back like this:

"backports.functools-lru-cache" = "1.6.1"

poetry seems to be tripping up on this line from their setup.cfg:

	pytest-mypy; python_implementation != "PyPy" and python_version < "3.10" and python_version > "3"

@nikmolnar
Copy link
Contributor Author

Thanks for the workaround, @Nitori- !

@pawamoy
Copy link

pawamoy commented Apr 1, 2021

Experiencing the same thing with python = "^3.6". I tried adding "backports.functools-lru-cache" = "1.6.1" to my deps or dev-deps, but it didn't solve the issue. You can see the failure on this CI pipeline.

@JennToo
Copy link

JennToo commented Apr 1, 2021

My suspicion is that there might be another dependency out in the wild that also exposes the bug. If you can get poetry onto a debugger that's how I found out that the lru-cache package was causing issues.

@pawamoy
Copy link

pawamoy commented Apr 1, 2021

I patched Poetry's source to catch the exception and print the package name:

~/.local/pipx/venvs/poetry/lib/python3.9/site-packages/poetry/core/packages/__init__.py line 219

        try:
            dep.python_versions = " || ".join(ors)
        except AttributeError:
            print(name)

The output showed pytest-mypy. Oh well I see now it was mentioned in your comments 😩

@JennToo
Copy link

JennToo commented Apr 1, 2021

If you jump up maybe 2-3 stacks, you'll see the package that was depending on pytest-mypy. That's probably the one that needs to get pinned.

@JennToo
Copy link

JennToo commented Apr 2, 2021

@pawamoy I did some digging and the issue you're seeing is from backports.entry_points_selectable. Unfortunately it looks like there is no release to pin back to, the very first release has the same problematic line as the other backports module I mentioned above. I think the only way to work around this one would be to find what's depending on this backports package and pin that instead.

Of course, all of this is just workarounds. It's still fundamentally a bug in poetry that can't seem to handle this dependency line:

	pytest-mypy; python_implementation != "PyPy" and python_version < "3.10" and python_version > "3"

@pawamoy
Copy link

pawamoy commented Apr 2, 2021

Damn, I can't work on any project now, nothing will resolve 😅
I'll have to debug this first! Thanks a lot for your help @Nitori-!

@pawamoy
Copy link

pawamoy commented Apr 2, 2021

I wonder if pytest-mypy; python_implementation != "PyPy" and python_version < "3.10" and python_version > "3" is valid though:

  • > "3" suggests strictly higher than version 3, and Poetry deduces >=4, which seems correct to me?
  • then < "3.10" makes it impossible

Poetry should maybe simply catch the AttributeError to re-raise an InvalidMarker exception that will make the parent function try again without the markers, or re-raise a ValueError instead, making it skip this dependency.

            try:
                # Attempt to parse the PEP-508 requirement string
                dependency = dependency_from_pep_508(req, relative_to=root_dir)
            except InvalidMarker:
                # Invalid marker, We strip the markers hoping for the best
                req = req.split(";")[0]
                dependency = dependency_from_pep_508(req, relative_to=root_dir)
            except ValueError:
                # Likely unable to parse constraint so we skip it
                self._log(
                    "Invalid constraint ({}) found in {}-{} dependencies, "
                    "skipping".format(req, package.name, package.version),
                    level="warning",
                )
                continue

@dkasak
Copy link

dkasak commented Apr 2, 2021

> "3" could also be understood as > "3.0", in which case the inequality makes sense so perhaps that was the intent? I agree >= "3" makes more sense, though.

@pawamoy
Copy link

pawamoy commented Apr 2, 2021

@dkasak maybe! However I think it's parsed as precision 1, entering this condition:

                    if parsed_version.precision == 1:
                        if op == "<=":
                            op = "<"
                            version = parsed_version.next_major.text
                        elif op == ">":
                            op = ">="
                            version = parsed_version.next_major.text

(and so it's changing it to >= with the next major version, which is 4)

I guess we'll need to read the spec to decide if it's correct or not!

@pawamoy
Copy link

pawamoy commented Apr 2, 2021

OK, PEP508 says versions comparison is done according to PEP440.

@pawamoy
Copy link

pawamoy commented Apr 2, 2021

And using PEP440 version parsing, it seems Poetry should not consider >3 to be >=4 since

>>> import packaging
>>> from packaging import version
>>> version.parse("3.6") > version.parse("3")
True
>>> version.parse("3.6") >= version.parse("4")
False

@pawamoy
Copy link

pawamoy commented Apr 2, 2021

Poetry core has a 1.1.0a1 release that refactored all this, I'll try it and report back.
UPDATE: well no, it suffers from the exact same issue.

@pawamoy
Copy link

pawamoy commented Apr 2, 2021

Ah, there's a related PR python-poetry/poetry-core#154

@pawamoy
Copy link

pawamoy commented Apr 2, 2021

I've identified the package who recently released a new version depending on backports.entry_points_selectable: pytest-randomly v3.6.0: pytest-dev/pytest-randomly@3.5.0...3.6.0 (look at requirements.in)

I was able to fix that issue in CI with the following hack:

    - name: Set up Poetry
      # HACK: https://github.com/python-poetry/poetry-core/pull/154
      run: |
        pip install git+https://github.com/python-poetry/poetry
        pip uninstall -y poetry-core
        pip install git+https://github.com/pbzweihander/poetry-core@resolve-invalid-python-version-constraint

But I guess I should simply downgrade and pin pytest-randomly to 3.5.0 🙂

@nikmolnar
Copy link
Contributor Author

Thanks for the quick work on this, @sdispater et. al!

@sobolevn
Copy link
Contributor

sobolevn commented Apr 4, 2021

I would love to see this fix released, as it hits me really hard in all (>50) of my projects.

clrpackages pushed a commit to clearlinux-pkgs/backports.entry_points_selectable that referenced this issue Apr 14, 2021
…version 1.0.3 to version 1.0.4

v1.0.4
======

#2: For test dependencies, when indicating Python 3, use ``>=3``
instead of ``>3`` to satisfy
`python-poetry/poetry#3862 <https://github.com/python-poetry/poetry/issues/3862>`_.
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this issue Apr 16, 2021
v1.6.4
For test dependencies, when indicating Python 3, use ``>=3``
instead of ``>3`` to satisfy
`python-poetry/poetry#3862 <https://github.com/python-poetry/poetry/issues/3862>`_.

v1.6.3
Restore universal wheel.

v1.6.2
Packaging refresh.
@abn abn removed the status/triage This issue needs to be triaged label Mar 3, 2022
Copy link

github-actions bot commented Mar 2, 2024

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 2, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
kind/bug Something isn't working as expected
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants