black icon indicating copy to clipboard operation
black copied to clipboard

please support use of the system black installation

Open bugfood opened this issue 3 years ago • 4 comments

Is your feature request related to a problem? Please describe.

As a new user of black, I installed the black package from my distribution to try it out. After that, I wanted to integrate it into vim. I set up the plugin, but discovered that the plugin requires building a virtualenv within which to install black. Using a virtualenv is undesirable to me for the following reasons:

  • I already have black installed; there should be no need to install it again.
  • The virtualenv adds clutter to my ~/.vim directory.
  • I'd prefer to upgrade/manage black via my distribution's package manager.
  • In order to use a virtualenv, I would need to install additional python packages for which I have no other immediate use.

Describe the solution you'd like

I'd prefer the vim plugin to use the system installation of black. Since having a virtualenv is apparently desirable to other people, this should be configurable.

Describe alternatives you've considered

I've considered using the virtualenv.

Additional context

Please review the PR which I will submit shortly.

Thanks, Corey

bugfood avatar Oct 04 '22 00:10 bugfood

Doesn't setting g:black_virtualenv = "/usr/local/" somewhere in vim startup files (or specifically for python files) do that? The path may vary depending on your distribution, it will search for the site-packages below that point (see _get_virtualenv_site_packages function)

krowbar avatar Oct 13 '22 15:10 krowbar

Doesn't setting g:black_virtualenv = "/usr/local/" somewhere in vim startup files (or specifically for python files) do that? The path may vary depending on your distribution, it will search for the site-packages below that point (see _get_virtualenv_site_packages function)

Hmm. I hadn't looked at that before now, but I don't think it's suitable. I'll elaborate below.

That function is:

def _get_virtualenv_site_packages(venv_path, pyver):
  if sys.platform[:3] == "win":
    return venv_path / 'Lib' / 'site-packages'
  return venv_path / 'lib' / f'python{pyver[0]}.{pyver[1]}' / 'site-packages'

...and it's called as (abridged):

  virtualenv_path = Path(vim.eval("g:black_virtualenv")).expanduser()
  virtualenv_site_packages = str(_get_virtualenv_site_packages(virtualenv_path, pyver))
  if not virtualenv_path.is_dir():
    # (set up black virtualenv)...

So it looks like g:black_virtualenv needs to refer to a directory that has subdirectories lib/python3.10/site-packages, at least for my python version.

This doesn't match anything in the Debian package structure.

$ dpkg -L black
/.
/usr
/usr/bin
/usr/bin/black
/usr/lib
/usr/lib/python3
/usr/lib/python3/dist-packages
/usr/lib/python3/dist-packages/_black_version.py
/usr/lib/python3/dist-packages/black
/usr/lib/python3/dist-packages/black/__init__.py
/usr/lib/python3/dist-packages/black/__main__.py
/usr/lib/python3/dist-packages/black/brackets.py
/usr/lib/python3/dist-packages/black/cache.py
/usr/lib/python3/dist-packages/black/comments.py
/usr/lib/python3/dist-packages/black/concurrency.py
/usr/lib/python3/dist-packages/black/const.py
/usr/lib/python3/dist-packages/black/debug.py
/usr/lib/python3/dist-packages/black/files.py
/usr/lib/python3/dist-packages/black/handle_ipynb_magics.py
/usr/lib/python3/dist-packages/black/linegen.py
/usr/lib/python3/dist-packages/black/lines.py
/usr/lib/python3/dist-packages/black/mode.py
/usr/lib/python3/dist-packages/black/nodes.py
/usr/lib/python3/dist-packages/black/numerics.py
/usr/lib/python3/dist-packages/black/output.py
/usr/lib/python3/dist-packages/black/parsing.py
/usr/lib/python3/dist-packages/black/py.typed
/usr/lib/python3/dist-packages/black/report.py
/usr/lib/python3/dist-packages/black/rusty.py
/usr/lib/python3/dist-packages/black/strings.py
/usr/lib/python3/dist-packages/black/trans.py
/usr/lib/python3/dist-packages/black-22.8.0.dist-info
/usr/lib/python3/dist-packages/black-22.8.0.dist-info/AUTHORS.md
/usr/lib/python3/dist-packages/black-22.8.0.dist-info/METADATA
/usr/lib/python3/dist-packages/black-22.8.0.dist-info/RECORD
/usr/lib/python3/dist-packages/black-22.8.0.dist-info/WHEEL
/usr/lib/python3/dist-packages/black-22.8.0.dist-info/entry_points.txt
/usr/lib/python3/dist-packages/black-22.8.0.dist-info/top_level.txt
/usr/lib/python3/dist-packages/blackd
/usr/lib/python3/dist-packages/blackd/__init__.py
/usr/lib/python3/dist-packages/blackd/__main__.py
/usr/lib/python3/dist-packages/blackd/middlewares.py
/usr/lib/python3/dist-packages/blib2to3
/usr/lib/python3/dist-packages/blib2to3/Grammar.txt
/usr/lib/python3/dist-packages/blib2to3/PatternGrammar.txt
/usr/lib/python3/dist-packages/blib2to3/__init__.py
/usr/lib/python3/dist-packages/blib2to3/pgen2
/usr/lib/python3/dist-packages/blib2to3/pgen2/__init__.py
/usr/lib/python3/dist-packages/blib2to3/pgen2/conv.py
/usr/lib/python3/dist-packages/blib2to3/pgen2/driver.py
/usr/lib/python3/dist-packages/blib2to3/pgen2/grammar.py
/usr/lib/python3/dist-packages/blib2to3/pgen2/literals.py
/usr/lib/python3/dist-packages/blib2to3/pgen2/parse.py
/usr/lib/python3/dist-packages/blib2to3/pgen2/pgen.py
/usr/lib/python3/dist-packages/blib2to3/pgen2/token.py
/usr/lib/python3/dist-packages/blib2to3/pgen2/tokenize.py
/usr/lib/python3/dist-packages/blib2to3/pygram.py
/usr/lib/python3/dist-packages/blib2to3/pytree.py
/usr/share
/usr/share/bash-completion
/usr/share/bash-completion/completions
/usr/share/bash-completion/completions/black
/usr/share/doc
/usr/share/doc/black
/usr/share/doc/black/README.Debian
/usr/share/doc/black/changelog.Debian.gz
/usr/share/doc/black/changelog.gz
/usr/share/doc/black/copyright
/usr/share/man
/usr/share/man/man1
/usr/share/man/man1/black-primer.1.gz
/usr/share/man/man1/black.1.gz

I can trick the plugin by making an empty dir, e.g.:

mkdir -p /tmp/black/lib/python3.10/site-packages/

...and then setting in vim:

:let g:black_virtualenv = "/tmp/black"

...but that seems hackish, and it will break upon my next python version upgrade or if the plugin is ever modified to do any other validation of the virtualenv.

bugfood avatar Oct 14 '22 22:10 bugfood

g:black_virtualenv = "/usr/local/" worked (at least for me) under 22.8.0, but failed like you predicted with 22.10.0 requiring access python site-packages directory.

It's (at least partly) related to the CACHE_DIR (or setting BLACK_CACHE_DIR environment variable). ... File "/usr/local/lib/python3.9/site-packages/black/nodes.py", line 25, in <module> pygram.initialize(CACHE_DIR) ... FileNotFoundError: [Errno 2] No such file or directory: /usr/local/lib/python3.9/sitepackages/blib2to3/home/rkruus/.cache/black/22.10.0/

That cache is now being being forced under the site-packages directory, even when setting BLACK_CACHE_DIR -- BLACK_CACHE_DIR is appended to site-packages. Explicitly setting that variable that uses an absolute path may work? Or test for write in the CACHE_DIR and fallback to $HOME/.cache/black?

The previous default behaviour was to to use (as can be seen in the error message above): $HOME/.cache/black/VERSION

krowbar avatar Oct 17 '22 15:10 krowbar

g:black_virtualenv = "/usr/local/" worked (at least for me) under 22.8.0, but failed like you predicted with 22.10.0 requiring access python site-packages directory.

Not to contradict you, but to clarify a bit, the failure I'm getting happens earlier than what you are seeing.

For your environment, this line returns a directory that exists:

return venv_path / 'lib' / f'python{pyver[0]}.{pyver[1]}' / 'site-packages'

For my environment, no such directory exists.

Either way, I think that g:black_virtualenv is too fragile to be a usable workaround.

bugfood avatar Oct 17 '22 17:10 bugfood