python-poetry / poetry

Python packaging and dependency management made easy
https://python-poetry.org
MIT License
31.08k stars 2.26k forks source link

EmptyKeyError when running poetry shell #2849

Closed jane-meichen-chen closed 4 years ago

jane-meichen-chen commented 4 years ago

Issue

When trying to run poetry shell, I get an EmptyKeyError:

% poetry shell

  EmptyKeyError

  Empty key at line 12 col 0

  at ~/.poetry/lib/poetry/_vendor/py3.7/tomlkit/parser.py:371 in _parse_key_value
       367│ 
       368│         # Key
       369│         key = self._parse_key()
       370│         if not key.key.strip():
    →  371│             raise self.parse_error(EmptyKeyError)
       372│ 
       373│         self.mark()
       374│ 
       375│         found_equals = self._current == "="

Please help. I don't seem to find any similar issue on the internet, and believe this is not a duplication of an existing question.

finswimmer commented 4 years ago

Hello @jane-meichen-chen ,

could you please show your complete pyproject.toml? It looks like there is something malformed. Especially around line 12.

fin swimmer

jane-meichen-chen commented 4 years ago

Hey @finswimmer Please see here for the complete pyproject with name and email removed. Thanks.

abn commented 4 years ago

@jane-meichen-chen I tried that pyproject.toml and could not reproduce the issue, can you confirm recreating that file does not cause the issue for you? It could also be because of the values you removed.

jane-meichen-chen commented 4 years ago

Hey @abn I still get the same error even when I start a new project. After running poetry init, poetry shell returns the same error in the original post.

% poetry shell                

  EmptyKeyError

  Empty key at line 12 col 0

  at ~/.poetry/lib/poetry/_vendor/py3.7/tomlkit/parser.py:371 in _parse_key_value
       367│ 
       368│         # Key
       369│         key = self._parse_key()
       370│         if not key.key.strip():
    →  371│             raise self.parse_error(EmptyKeyError)
       372│ 
       373│         self.mark()
       374│ 
       375│         found_equals = self._current == "="
abn commented 4 years ago

@jane-meichen-chen unfortunately there is not enough information here to help us help you. I have, once again attempted to reproduce this in a clean docker environment. See below for details. Your exception suggests that your toml file is corrupt. Maybe try poetry shell -vvv? That might provide a bit more details on the exception. If an empty key does not exist in the pyproject.toml file maybe it is in the poetry.lock file? Feel free to join our Discord server if you want more help debugging this.

$ docker run --rm -it --entrypoint bash python:3.7
root@e9c2399191b6:/# curl -sLO https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py
root@e9c2399191b6:/# python3.7 get-poetry.py --pre --yes
Retrieving Poetry metadata

# Welcome to Poetry!

This will download and install the latest version of Poetry,
a dependency and package manager for Python.

It will add the `poetry` command to Poetry's bin directory, located at:

$HOME/.poetry/bin

This path will then be added to your `PATH` environment variable by
modifying the profile file located at:

$HOME/.profile

You can uninstall at any time by executing this script with the --uninstall option,
and these changes will be reverted.

Installing version: 1.1.0b2
  - Downloading poetry-1.1.0b2-linux.tar.gz (57.18MB)

Poetry (1.1.0b2) is installed now. Great!

To get started you need Poetry's bin directory ($HOME/.poetry/bin) in your `PATH`
environment variable. Next time you log in this will be done
automatically.

To configure your current shell run `source $HOME/.poetry/env`

root@e9c2399191b6:/# source $HOME/.poetry/env 
root@e9c2399191b6:/# poetry new foobar
Created package foobar in foobar
root@e9c2399191b6:/# cd foobar/
root@e9c2399191b6:/foobar# poetry shell
Creating virtualenv foobar-lWDpn5M1-py3.7 in /root/.cache/pypoetry/virtualenvs
Spawning shell within /root/.cache/pypoetry/virtualenvs/foobar-lWDpn5M1-py3.7
root@e9c2399191b6:/foobar# . /root/.cache/pypoetry/virtualenvs/foobar-lWDpn5M1-py3.7/bin/activate
(foobar-lWDpn5M1-py3.7) root@e9c2399191b6:/foobar# exit
exit 

Try with poetry init.

root@e9c2399191b6:/foobar# poetry init
A pyproject.toml file already exists.
root@e9c2399191b6:/foobar# rm pyproject.toml 
root@e9c2399191b6:/foobar# poetry init

This command will guide you through creating your pyproject.toml config.

Package name [foobar]:  
Version [0.1.0]:  
Description []:  
Author [None, n to skip]:  n
License []:  
Compatible Python versions [^3.7]:  

Would you like to define your main dependencies interactively? (yes/no) [yes] no
Would you like to define your development dependencies interactively? (yes/no) [yes] no
Generated file

[tool.poetry]
name = "foobar"
version = "0.1.0"
description = ""
authors = ["Your Name <you@example.com>"]

[tool.poetry.dependencies]
python = "^3.7"

[tool.poetry.dev-dependencies]

[build-system]
requires = ["poetry-core>=1.0.0a5"]
build-backend = "poetry.core.masonry.api"

Do you confirm generation? (yes/no) [yes] yes
root@e9c2399191b6:/foobar# rm -rf $(poetry env info -p)
root@e9c2399191b6:/foobar# poetry shell
Creating virtualenv foobar-lWDpn5M1-py3.7 in /root/.cache/pypoetry/virtualenvs
Spawning shell within /root/.cache/pypoetry/virtualenvs/foobar-lWDpn5M1-py3.7
root@e9c2399191b6:/foobar# . /root/.cache/pypoetry/virtualenvs/foobar-lWDpn5M1-py3.7/bin/activate
(foobar-lWDpn5M1-py3.7) root@e9c2399191b6:/foobar# exit
exit

Let's try with the provided pyproject.toml.

root@e9c2399191b6:/foobar# curl -sL https://gist.githubusercontent.com/jane-meichen-chen/27b43f37d7cd851750009128aab45c3c/raw/0dc910cc2eb8735bf03bce131008a042abe354fc/pyproject.toml > pyproject.toml 
root@e9c2399191b6:/foobar# rm -rf $(poetry env info -p)
root@e9c2399191b6:/foobar# cat pyproject.toml 
[tool.poetry]
name = ""
version = "0.1.0"
description = ""
authors = [""]

[tool.poetry.dependencies]
python = "^3.7"
pandas = "^1.0.3"
numpy = "^1.18.4"
matplotlib = "^3.2.1"
seaborn = "^0.10.1"
statsmodels = "^0.11.1"
xlrd = "^1.2.0"
sqlalchemy = "^1.3.16"
pyodbc = "^4.0.30"
pyyaml = "^5.3.1"
openpyxl = "^3.0.3"

[tool.poetry.dev-dependencies]
pytest = "^5.2"

[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"
root@e9c2399191b6:/foobar# poetry shell
Creating virtualenv -lWDpn5M1-py3.7 in /root/.cache/pypoetry/virtualenvs
Spawning shell within /root/.cache/pypoetry/virtualenvs/-lWDpn5M1-py3.7
root@e9c2399191b6:/foobar# . /root/.cache/pypoetry/virtualenvs/-lWDpn5M1-py3.7/bin/activate
(-lWDpn5M1-py3.7) root@e9c2399191b6:/foobar# exit
exit
root@e9c2399191b6:/foobar# 
jane-meichen-chen commented 4 years ago

Hey @abn

Please see below for the output when I run poetry shell -vvv

% poetry shell -vvv

  Stack trace:

  14  ~/.poetry/lib/poetry/_vendor/py3.7/clikit/console_application.py:131 in run
       129│             parsed_args = resolved_command.args
       130│ 
     → 131│             status_code = command.handle(parsed_args, io)
       132│         except KeyboardInterrupt:
       133│             status_code = 1

  13  ~/.poetry/lib/poetry/_vendor/py3.7/clikit/api/command/command.py:120 in handle
       118│     def handle(self, args, io):  # type: (Args, IO) -> int
       119│         try:
     → 120│             status_code = self._do_handle(args, io)
       121│         except KeyboardInterrupt:
       122│             if io.is_debug():

  12  ~/.poetry/lib/poetry/_vendor/py3.7/clikit/api/command/command.py:163 in _do_handle
       161│         if self._dispatcher and self._dispatcher.has_listeners(PRE_HANDLE):
       162│             event = PreHandleEvent(args, io, self)
     → 163│             self._dispatcher.dispatch(PRE_HANDLE, event)
       164│ 
       165│             if event.is_handled():

  11  ~/.poetry/lib/poetry/_vendor/py3.7/clikit/api/event/event_dispatcher.py:22 in dispatch
        20│ 
        21│         if listeners:
     →  22│             self._do_dispatch(listeners, event_name, event)
        23│ 
        24│         return event

  10  ~/.poetry/lib/poetry/_vendor/py3.7/clikit/api/event/event_dispatcher.py:89 in _do_dispatch
        87│                 break
        88│ 
     →  89│             listener(event, event_name, self)
        90│ 
        91│     def _sort_listeners(self, event_name):  # type: (str) -> None

   9  ~/.poetry/lib/poetry/console/config/application_config.py:119 in set_env
       117│ 
       118│         env_manager = EnvManager(poetry)
     → 119│         env = env_manager.create_venv(io)
       120│ 
       121│         if env.is_venv() and io.is_verbose():

   8  ~/.poetry/lib/poetry/utils/env.py:510 in create_venv
        508│ 
        509│         cwd = self._poetry.file.parent
     →  510│         env = self.get(reload=True)
        511│ 
        512│         if not env.is_sane():

   7  ~/.poetry/lib/poetry/utils/env.py:334 in get
        332│         base_env_name = self.generate_env_name(self._poetry.package.name, str(cwd))
        333│         if envs_file.exists():
     →  334│             envs = envs_file.read()
        335│             env = envs.get(base_env_name)
        336│             if env:

   6  ~/.poetry/lib/poetry/_vendor/py3.7/tomlkit/toml_file.py:20 in read
       18│     def read(self):  # type: () -> TOMLDocument
       19│         with io.open(self._path, encoding="utf-8") as f:
     → 20│             return loads(f.read())
       21│ 
       22│     def write(self, data):  # type: (TOMLDocument) -> None

   5  ~/.poetry/lib/poetry/_vendor/py3.7/tomlkit/api.py:34 in loads
        32│     Alias for parse().
        33│     """
     →  34│     return parse(string)
        35│ 
        36│ 

   4  ~/.poetry/lib/poetry/_vendor/py3.7/tomlkit/api.py:51 in parse
        49│     Parses a string into a TOMLDocument.
        50│     """
     →  51│     return Parser(string).parse()
        52│ 
        53│ 

   3  ~/.poetry/lib/poetry/_vendor/py3.7/tomlkit/parser.py:153 in parse
        151│ 
        152│         while not self.end():
     →  153│             key, value = self._parse_table()
        154│             if isinstance(value, Table) and value.is_aot_element():
        155│                 # This is just the first table in an AoT. Parse the rest of the array

   2  ~/.poetry/lib/poetry/_vendor/py3.7/tomlkit/parser.py:1056 in _parse_table
       1054│ 
       1055│         while not self.end():
     → 1056│             item = self._parse_item()
       1057│             if item:
       1058│                 _key, item = item

   1  ~/.poetry/lib/poetry/_vendor/py3.7/tomlkit/parser.py:302 in _parse_item
        300│                     break
        301│ 
     →  302│         return self._parse_key_value(True)
        303│ 
        304│     def _parse_comment_trail(self):  # type: () -> Tuple[str, str, str]

  EmptyKeyError

  Empty key at line 12 col 0

  at ~/.poetry/lib/poetry/_vendor/py3.7/tomlkit/parser.py:371 in _parse_key_value
       367│ 
       368│         # Key
       369│         key = self._parse_key()
       370│         if not key.key.strip():
    →  371│             raise self.parse_error(EmptyKeyError)
       372│ 
       373│         self.mark()
       374│ 
       375│         found_equals = self._current == "="

I have tried uninstalling poetry and re-install. removing poetry.lock doesn't do anything either.

abn commented 4 years ago

Okay. This is better, the issue is triggered by this bit.

   7  ~/.poetry/lib/poetry/utils/env.py:334 in get
        332│         base_env_name = self.generate_env_name(self._poetry.package.name, str(cwd))
        333│         if envs_file.exists():
     →  334│             envs = envs_file.read()
        335│             env = envs.get(base_env_name)
        336│             if env:

Your envs.toml is somehow corrupt. Can you check the content of ~/.cache/pypoetry/virtualenvs/envs.toml for invalid toml, ie. a key/value pair with an empty key perhaps?

You can also just delete the file.

abn commented 4 years ago

The change in https://github.com/python-poetry/poetry-core/pull/70 should improve the error messages for these kind of issues.

jane-meichen-chen commented 4 years ago

Hey, i don't seem to find ~/.cache/pypoetry/virtualenvs/envs.toml anywhere, where does it suppose to live?

jane-meichen-chen commented 4 years ago

ah nvm, i find it now

jane-meichen-chen commented 4 years ago

thank you @abn , there was an extra " on line 12 in my envs.toml file. after removing that, everything is now back to normal!

albertoem77 commented 1 year ago

Hi I have a similar error could you help me out please: Stack trace:

12 /mnt/NAS/users/amedina/conda_envs/hgsoc_ml/lib/python3.10/site-packages/clikit/console_application.py:131 in run 129│ parsed_args = resolved_command.args 130│ → 131│ status_code = command.handle(parsed_args, io) 132│ except KeyboardInterrupt: 133│ status_code = 1

11 /mnt/NAS/users/amedina/conda_envs/hgsoc_ml/lib/python3.10/site-packages/clikit/api/command/command.py:120 in handle 118│ def handle(self, args, io): # type: (Args, IO) -> int 119│ try: → 120│ status_code = self._do_handle(args, io) 121│ except KeyboardInterrupt: 122│ if io.is_debug():

10 /mnt/NAS/users/amedina/conda_envs/hgsoc_ml/lib/python3.10/site-packages/clikit/api/command/command.py:163 in _do_handle 161│ if self._dispatcher and self._dispatcher.has_listeners(PRE_HANDLE): 162│ event = PreHandleEvent(args, io, self) → 163│ self._dispatcher.dispatch(PRE_HANDLE, event) 164│ 165│ if event.is_handled():

9 /mnt/NAS/users/amedina/conda_envs/hgsoc_ml/lib/python3.10/site-packages/clikit/api/event/event_dispatcher.py:22 in dispatch 20│ 21│ if listeners: → 22│ self._do_dispatch(listeners, event_name, event) 23│ 24│ return event

8 /mnt/NAS/users/amedina/conda_envs/hgsoc_ml/lib/python3.10/site-packages/clikit/api/event/event_dispatcher.py:89 in _do_dispatch 87│ break 88│ → 89│ listener(event, event_name, self) 90│ 91│ def _sort_listeners(self, event_name): # type: (str) -> None

7 /mnt/NAS/users/amedina/conda_envs/hgsoc_ml/lib/python3.10/site-packages/poetry/console/config/application_config.py:116 in set_env 114│ 115│ io = event.io → 116│ poetry = command.poetry 117│ 118│ env_manager = EnvManager(poetry)

6 /mnt/NAS/users/amedina/conda_envs/hgsoc_ml/lib/python3.10/site-packages/poetry/console/commands/command.py:10 in poetry 8│ @property 9│ def poetry(self): → 10│ return self.application.poetry 11│ 12│ def reset_poetry(self): # type: () -> None

5 /mnt/NAS/users/amedina/conda_envs/hgsoc_ml/lib/python3.10/site-packages/poetry/console/application.py:69 in poetry 67│ return self._poetry 68│ → 69│ self._poetry = Factory().create_poetry(Path.cwd()) 70│ 71│ return self._poetry

4 /mnt/NAS/users/amedina/conda_envs/hgsoc_ml/lib/python3.10/site-packages/poetry/factory.py:33 in create_poetry 31│ io = NullIO() 32│ → 33│ base_poetry = super(Factory, self).create_poetry(cwd) 34│ 35│ locker = Locker(

3 /mnt/NAS/users/amedina/conda_envs/hgsoc_ml/lib/python3.10/site-packages/poetry/core/factory.py:34 in create_poetry 32│ ): # type: (Optional[Path], bool) -> Poetry 33│ poetry_file = self.locate(cwd) → 34│ local_config = PyProjectTOML(path=poetry_file).poetry_config 35│ 36│ # Checking validity

2 /mnt/NAS/users/amedina/conda_envs/hgsoc_ml/lib/python3.10/site-packages/poetry/core/pyproject/toml.py:54 in poetry_config 52│ def poetry_config(self): # type: () -> Optional[TOMLDocument] 53│ if self._poetry_config is None: → 54│ self._poetry_config = self.data.get("tool", {}).get("poetry") 55│ if self._poetry_config is None: 56│ raise PyProjectException(

1 /mnt/NAS/users/amedina/conda_envs/hgsoc_ml/lib/python3.10/site-packages/poetry/core/pyproject/toml.py:31 in data 29│ self._data = TOMLDocument() 30│ else: → 31│ self._data = self._file.read() 32│ return self._data 33│

TOMLError

Invalid TOML file /home/amedina/project/bps-az-hgsoc/hgsoc_ml/pyproject.toml: Empty key at line 17 col 0

at /mnt/NAS/users/amedina/conda_envs/hgsoc_ml/lib/python3.10/site-packages/poetry/core/toml/file.py:34 in read 30│ def read(self): # type: () -> "TOMLDocument" 31│ try: 32│ return super(TOMLFile, self).read() 33│ except (ValueError, TOMLKitError) as e: → 34│ raise TOMLError("Invalid TOML file {}: {}".format(self.path.as_posix(), e)) 35│ 36│ def getattr(self, item): # type: (str) -> Any 37│ return getattr(self.__path, item)

neersighted commented 1 year ago

Your pyproject.toml is invalid -- all the information you need to locate the error is in the error message. You can also paste it in to a TOML validator tool for more guidance.

If you need support, please start a new Discussion or join Discord -- commenting on closed issues is counterproductive as people get needless notifications and visibility is low for those who would want to help.

albertoem77 commented 1 year ago

okay thanks you

github-actions[bot] commented 6 months ago

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.