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

Improve error message on PEP 440 constraint parsing failure #4597

Closed
2 tasks done
roganartu opened this issue Oct 5, 2021 · 16 comments · Fixed by python-poetry/poetry-core#514
Closed
2 tasks done
Labels
area/core Related to the poetry-core library area/error-handling Bad error messages/insufficient error handling kind/enhancement Not a bug or feature, but improves usability or performance

Comments

@roganartu
Copy link

roganartu commented Oct 5, 2021

  • I have searched the issues of this repo and believe that this is not a duplicate.
  • I have searched the documentation and believe that my question is not covered.

Feature Request

Poetry version: 1.2.0a2

Problem

When any dependency in the dependency tree contains an invalid PEP 440 constraint, Poetry fails with the following error:

❯ poetry lock  
Updating dependencies
Resolving dependencies... (14.1s)

  InvalidVersion

  Invalid PEP 440 version: '3.5.'

  at /usr/scratch/xar/2ce5d136/lib/python3.8/site-packages/poetry/core/version/pep440/parser.py:67 in parse
       63│     @classmethod
       64│     def parse(cls, value: str, version_class: Optional[Type["PEP440Version"]] = None):
       65│         match = cls._regex.search(value) if value else None
       66│         if not match:
    →  67│             raise InvalidVersion(f"Invalid PEP 440 version: '{value}'")
       68│ 
       69│         if version_class is None:
       70│             from poetry.core.version.pep440.version import PEP440Version
       71│ 

The following error occurred when trying to handle this error:


  ValueError

  Could not parse version constraint: >=3.5.*

  at /usr/scratch/xar/2ce5d136/lib/python3.8/site-packages/poetry/core/semver/helpers.py:139 in parse_single_constraint
      135│ 
      136│         try:
      137│             version = Version.parse(version)
      138│         except ValueError:
    → 139│             raise ValueError(
      140│                 "Could not parse version constraint: {}".format(constraint)
      141│             )
      142│ 
      143│         if op == "<":

There is no mention of which package Poetry is attempting to parse the constraint for. This makes it extremely difficult to find out where the problem lies. In a project with even ten dependencies there could be hundreds of derived dependencies, and it could be any one of those which is failing.

I have attempted to increase the verbosity, but it is still rather difficult to work with. One needs to look at the dependencies that appear last in the output and then look for them in the output of poetry show --tree and then go looking up the setup.py for each of those until you find one with a constraint that matches the error.

Proposal

I propose that Poetry add the package name and version being parsed to this error message. eg:

  Could not parse version constraint: >=3.5.* from foo==1.2.3 (derived from bar=1.2.3)

Workaround

You can use pdb to find the package and version causing you problems, though it's non-obvious and has some issues so it's not really a workable solution for most users.

  1. startup pdb with poetry (you may need to specify absolute paths to poetry here)
✗❯ python -m pdb poetry lock
> /usr/scratch/xar/2ce5d136/bin/poetry(3)<module>()
-> import re
  1. set a breakpoint. We're running poetry==1.2.0a2 and the constraint exception raises from here:
(Pdb) b poetry/core/semver/helpers.py:139
  1. let poetry run. It will be slower because pdb slows runtime down
(Pdb) c
  1. This is where it gets tricky. The progress output continues printing, so you need to type pdb commands through it as they will get overwritten by shell escape sequences. When you see the following, you are actually getting a pdb prompt and can enter commands:
(Pdb) c
Updating dependencies
Resolving dependencies... (46.1s)> /path/to/python/lib/python3.8/site-packages/poetry/core/semver/helpers.py(139)parse_single_constraint()
-> raise ValueError(
Resolving dependencies... (109.8s) 
  1. send the pdb commands up and args a few times to walk back up the stack, until you see something like this:
Resolving dependencies... (137.8s)
constraint = '>=3.5.*'
Resolving dependencies... (143.0s)
> /path/to/python/lib/python3.8/site-packages/poetry/core/semver/helpers.py(35)parse_constraint()
-> constraint_objects.append(parse_single_constraint(and_constraints[0]))
Resolving dependencies... (145.4s)
constraints = '>=3.5.*'
Resolving dependencies... (147.2s)
> /path/to/python/lib/python3.8/site-packages/poetry/core/packages/package.py(253)python_versions()
-> self._python_constraint = parse_constraint(value)
Resolving dependencies... (148.3s)
self = Package('pylint', '2.6.2')
value = '>=3.5.*'

Voila! This is the package that triggered the constraint exception. Bump it or pin it to a version that has a valid constraint (and if it's the latest release for that package, help out the maintainer with an issue or PR to fix it up!).
7. Send the q pdb command twice to exit the interpreter.

@roganartu roganartu added kind/feature Feature requests/implementations status/triage This issue needs to be triaged labels Oct 5, 2021
@drcongo

This comment was marked as off-topic.

@drcongo

This comment was marked as off-topic.

@drcongo

This comment was marked as off-topic.

@drcongo

This comment was marked as off-topic.

@neersighted

This comment was marked as off-topic.

@drcongo

This comment was marked as off-topic.

@neersighted

This comment was marked as off-topic.

@neersighted neersighted added area/error-handling Bad error messages/insufficient error handling area/core Related to the poetry-core library kind/enhancement Not a bug or feature, but improves usability or performance and removed kind/feature Feature requests/implementations status/triage This issue needs to be triaged labels Oct 5, 2022
@idantene
Copy link

I'm also hitting this head-on and have to resort to source .venv/bin/activate first. Installed with a basic pip install poetry on the user-level, and anything following that (e.g. poetry install in a repo with poetry.lock) fails.

@neersighted
Copy link
Member

You haven't provided sufficient detail to understand your particular scenario, but it sounds like you may be trying to install Poetry and your project both outside a virtual environment. That is full of foot-guns and ill-advised. Use of a virtual environment is strongly suggested and protects you against all manner of surprises.

@idantene
Copy link

I'm not sure I follow. Running poetry install creates the virtual environment and installs the dependencies in it.

Poetry itself is installed in the user space via pip.

@neersighted
Copy link
Member

You mentioned manually managing a virtual environment -- without individual steps and command, what workflow you are using/what problem you are running into is unclear.

@robtaylor
Copy link

I'm still seeing the old error message as of head today:
poetry --version
Poetry (version 1.3.0.dev0)
poetry self show

Invalid PEP 440 version: '0.23ubuntu1'

@neersighted
Copy link
Member

You're not on a HEAD version of poetry-core.

@robtaylor
Copy link

ahah, thank you!

@robtaylor
Copy link

robtaylor commented Nov 4, 2022

Ok, defintely on head python-core now, Still same behaviour.
Looks like the try needs to move further up, as the exception is thrown on line 219: if not isinstance(version, Version):

> /home/robtaylor/.local/lib/python3.9/site-packages/poetry/core/packages/package.py(81)__init__()
->
  /home/robtaylor/.local/lib/python3.9/site-packages/poetry/core/packages/package.py(219)_set_version()
-> if not isinstance(version, Version):
  /home/robtaylor/.local/lib/python3.9/site-packages/poetry/core/version/pep440/version.py(182)parse()
-> return parse_pep440(value, cls)
  /home/robtaylor/.local/lib/python3.9/site-packages/poetry/core/version/pep440/parser.py(83)parse_pep440()
-> return PEP440Parser.parse(value, version_class)
  /home/robtaylor/.local/lib/python3.9/site-packages/poetry/core/version/pep440/parser.py(69)parse()
-> raise InvalidVersion(f"Invalid PEP 440 version: '{value}'")

Copy link

github-actions bot commented Mar 1, 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 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area/core Related to the poetry-core library area/error-handling Bad error messages/insufficient error handling kind/enhancement Not a bug or feature, but improves usability or performance
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants