ImportError: cannot import name '_unicodefun' from 'click'
Asked Answered
H

6

179

When running our lint checks with the Python Black package, an error comes up:

ImportError: cannot import name '_unicodefun' from 'click' (/Users/robot/.cache/pre-commit/repo3u71ccm2/py_env-python3.9/lib/python3.9/site-packages/click/init.py)`

In researching this, I found the following related issues:

How can I solve this problem? Is this a false positive from the linter? Do I need to modify my code?

Hukill answered 30/3, 2022 at 7:46 Comment(3)
Just use the latest version of packages as far as you can.Imbricate
Can you please edit the question to clarify the versions being used here? Apparently, this bug was already fixed by the most recent black version 2 days before the question was even asked, so not even "the most recent version at that time" is a sensible guess.Hamelin
If you come here from following the Hypermodern Python article series, the solution is to update the version (rev) of black in the .pre-commit-config.yaml file to a recent verionAbstract
H
232

This has been fixed by Black 22.3.0. Versions before that won't work with click 8.1.0.

Incompatible with click 8.1.0 (ImportError: cannot import name '_unicodefun' from 'click') #2964

E.g.: black.yml

          python-version: 3.8
      - name: install black
        run: |
-          pip install black==20.8b1
+          pip install black==22.3.0
      - name: run black
        run: |
          black . --check --line-length 100

https://github.com/Clinical-Genomics/cgbeacon2/pull/221/files

As a workaround, pin click to the last version via pip install --upgrade click==8.0.2.

Hukill answered 30/3, 2022 at 8:58 Comment(0)
P
40

If you're using black as part of a pre-commit hook's YAML, you can update the pre-commit file (often .pre-commit-config.yaml) to reference the more recent versions of black (>=22.3.0), e.g.

# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v3.2.0
    hooks:
    -   id: trailing-whitespace
    -   id: end-of-file-fixer
    -   id: check-yaml
    -   id: check-added-large-files
-   repo: https://github.com/psf/black
    rev: 22.3.0
    hooks:
    -   id: black
        exclude: ^dist/

Running pip install of a new version of black won't be sufficient for command-line pre-commit hooks if the YAML file pins black itself to a particular version... which pre-commit does by default. See also Black's GitHub Issue Tracker.

Please answered 13/5, 2022 at 20:59 Comment(0)
P
18

If none of the above works, you might have some trouble-making cache from previous changes in your code. Try running:

pre-commit clean
pre-commit autoupdate
Phyllode answered 20/6, 2022 at 21:39 Comment(0)
W
7

Fixes

Here are a couple common use cases:

Addressing error in pre-commit yaml

.pre-commit-config.yaml

- repo: https://github.com/psf/black
  rev: 22.3.0
  hooks:
    - id: black

If the issue persists in pre-commit, it's likely because an old version is being cached (as suggested here). Run pre-commit clean then pre-commit install to reset

Addressing error in pyprojct toml

pyproject.toml

[tool.poetry.dev-dependencies]
black = {version = "^22.3.0", allow-prereleases = true}

[tool.black]
# https://github.com/psf/black
target-version = ["py39"]
line-length = 120
color = true

Example

requires pyproject.toml above

Using Makefile & Poetry

Makefile

#* Poetry
.PHONY: poetry-download
poetry-download:
    curl -sSL https://install.python-poetry.org | $(PYTHON) -

.PHONY: pre-commit-install
pre-commit-install:
    poetry run pre-commit install

#* Formatters
.PHONY: codestyle
codestyle:
    poetry run black --config pyproject.toml ./

.pre-commit-config.yaml

default_language_version:
  python: python3.9

default_stages: [commit, push]

repos:
  - repo: local
    hooks:
      - id: black
        name: black
        entry: poetry run black --config pyproject.toml
        types: [python]
        language: system

GitHub links

The dependency conflict is described in detail in the following links

Waldenburg answered 16/10, 2022 at 11:45 Comment(0)
F
2

You need to specify a click version of 8.0.2 in the additional_dependencies section for black revision 20.8b1 (which is capable of cleaning python27 code), e.g

- repo: https://github.com/psf/black
  rev: 20.8b1
  hooks:
    - id: black
      name: Blacken python source
      additional_dependencies: ["click==8.0.2"]
Fyrd answered 24/2, 2023 at 10:47 Comment(0)
W
0

Try to install click==8.0.4 in case you are using black to format Python 2.7 code and black update is not an option for you due to dropped Python 2.7 support. Below is .github/workflows/black.yml for the GitHub action I used for a legacy python 2.7 project.

name: Black check

on: [pull_request]

jobs:
  black-check:
    runs-on: ubuntu-22.04
    name: Black
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@master
        with:
          python-version: 3.8
      - name: install black
        run: |
          pip install click==8.0.4 black==21.9b0
      - name: run black
        run: |
          black . -t py27 --check
Wryneck answered 17/1, 2023 at 10:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.