181

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?

3
  • 4
    Just use the latest version of packages as far as you can.
    – MaGaroo
    Commented Mar 30, 2022 at 7:55
  • 1
    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. Commented Apr 24, 2022 at 9:19
  • 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 verion
    – Fontanka16
    Commented Mar 25 at 8:19

6 Answers 6

234

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.

0
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.

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
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

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"]
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

Not the answer you're looking for? Browse other questions tagged or ask your own question.