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

Python: not configured with Tk and break matplotlib #11256

Open
Char-Aznable opened this issue Jan 16, 2019 · 12 comments

Comments

@Char-Aznable
Copy link
Contributor

commented Jan 16, 2019

Please note we will close your issue without comment if you delete, do not read or do not fill out the issue checklist below and provide ALL the requested information. If you repeatedly fail to use the issue template, we will block you from ever submitting issues to Homebrew again.

  • have a problem with brew install (or upgrade, reinstall) a single formula? If it's a general brew problem please file this issue at Linuxbrew/brew: https://github.com/Linuxbrew/brew/issues/new/choose. If it's a tap (e.g. Brewsci/homebrew-bio) problem please file this issue at the tap.
  • ran brew update and can still reproduce the problem?
  • ran brew doctor, fixed all issues and can still reproduce the problem?
  • ran brew gist-logs <formula> (where <formula> is the name of the formula that failed) and included the output link?
  • if brew gist-logs didn't work: ran brew config and brew doctor and included their output with your issue?

To help us debug your issue please explain:

  • What you were trying to do (and why)
    Install and use matplotlib in python3
  • What happened (include command output)
    After pip3 install matplotlib, I can't use the TkAgg backend because of python3 is not configured with Tk:
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/linuxbrew/.linuxbrew/Cellar/python/3.7.2_1/lib/python3.7/site-packages/matplotlib/pyplot.py", line 2374, in <module>
    switch_backend(rcParams["backend"])
  File "/home/linuxbrew/.linuxbrew/Cellar/python/3.7.2_1/lib/python3.7/site-packages/matplotlib/pyplot.py", line 207, in switch_backend
    backend_mod = importlib.import_module(backend_name)
  File "/home/linuxbrew/.linuxbrew/bin/../Cellar/python/3.7.2_1/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "/home/linuxbrew/.linuxbrew/Cellar/python/3.7.2_1/lib/python3.7/site-packages/matplotlib/backends/backend_tkagg.py", line 1, in <module>
    from . import _backend_tk
  File "/home/linuxbrew/.linuxbrew/Cellar/python/3.7.2_1/lib/python3.7/site-packages/matplotlib/backends/_backend_tk.py", line 5, in <module>
    import tkinter as Tk
  File "/home/linuxbrew/.linuxbrew/Cellar/python/3.7.2_1/lib/python3.7/tkinter/__init__.py", line 36, in <module>
    import _tkinter # If this fails your Python may not be configured for Tk
ModuleNotFoundError: No module named '_tkinter'
brew install python3
pip3 install matplotlib
python3 -c "import matplotlib.pyplot as plt"
python3 -c "import _tkinter"
@Char-Aznable

This comment has been minimized.

Copy link
Contributor Author

commented Jan 16, 2019

I can fix the issue by adding the config option when building python from source:

diff --git a/Formula/python.rb b/Formula/python.rb
index c6afd1c300..3b51fe512c 100644
--- a/Formula/python.rb
+++ b/Formula/python.rb
@@ -92,6 +92,8 @@ class Python < Formula
       --enable-loadable-sqlite-extensions
       --without-ensurepip
       --with-openssl=#{Formula["openssl"].opt_prefix}
+      --with-tcltk-includes="-I#{Formula["tcl-tk"].opt_include}"
+      --with-tcltk-libs="-L#{Formula["tcl-tk"].opt_lib}"
     ]
     args << "--with-dtrace" unless OS.linux?

I can see that there would be a cyclic dependency issue if python depends on tcl-tk. However, a lot of python applications depends on matplotlib and python would lose an arm and a leg without it. Is there a workaround for this?

@iMichka

This comment has been minimized.

Copy link
Member

commented Jan 16, 2019

That's exactly the reason why that option is not enabled. I already tried to enable it and it only brought problems.

The only way out in my opinion is the following: we need a minimal python formula (called python-minimal for example), that just installs a python binary. The formula should not install anything else, and should not conflict with other python formulae. The binary could maybe even be called something else (instead of calling python, we could call python-minimal). We could then use that binary to break the dependency cycle and build either python or tcl-tk.

This is just a hypothesis, not sure it will work. Having the separate build-time only python binary would also help fix other dependency cycles (I think there was another one involving libxml2).

@Char-Aznable

This comment has been minimized.

Copy link
Contributor Author

commented Jan 16, 2019

Well, I think it's easier if we don't explicit specify the dependency of python3 on tcl-tk but use the config option anyway. Python will ignore that option if no tcl-tk is found. As a result, when the user doesn't have tcl-tk installed, we have the crippled python as the current version (no tkinter module); when the user does install tcl-tk, we have the working python. We document this in the caveat and let the user know

@iMichka In any case, we need to document that the current python is without tkinter module -- which I think no one wants to use

@Char-Aznable

This comment has been minimized.

Copy link
Contributor Author

commented Jan 22, 2019

diff --git a/Formula/python.rb b/Formula/python.rb
index c6afd1c300..3b51fe512c 100644
--- a/Formula/python.rb
+++ b/Formula/python.rb
@@ -92,6 +92,8 @@ class Python < Formula
       --enable-loadable-sqlite-extensions
       --without-ensurepip
       --with-openssl=#{Formula["openssl"].opt_prefix}
+      --with-tcltk-includes="-I#{Formula["tcl-tk"].opt_include}"
+      --with-tcltk-libs="-L#{Formula["tcl-tk"].opt_lib}"
     ]
     args << "--with-dtrace" unless OS.linux?

@iMichka Is it OK for me to the submit this as a PR? This is a temporary solution -- it will default to the current bottled version if no tcl-tk found or build with tcl-tk if found.

@stale

This comment has been minimized.

Copy link

commented Feb 12, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

@stale stale bot added the stale label Feb 12, 2019

@stale stale bot closed this Feb 19, 2019

@iMichka iMichka reopened this Feb 20, 2019

@stale stale bot removed the stale label Feb 20, 2019

@iMichka iMichka self-assigned this Feb 20, 2019

@stale

This comment has been minimized.

Copy link

commented Mar 13, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

@stale stale bot added the stale label Mar 13, 2019

@stale stale bot closed this Mar 20, 2019

@iMichka iMichka reopened this Mar 20, 2019

@stale stale bot removed the stale label Mar 20, 2019

@iMichka

This comment has been minimized.

Copy link
Member

commented Mar 26, 2019

I have 3 pull requests open to clean up a little bit the dependency tree:
util-linux should not depend on Python2: #12232
libxcb and xcb-proto can be simplified and will not depend on Python anymore (only on minimal-python): Linuxbrew/homebrew-xorg#455
libxt should not depend on glib, as this is only needed for the tests: Linuxbrew/homebrew-xorg#483

With all this I was able to get a xorg formula which does not depend on Python/Python2

@root42

This comment has been minimized.

Copy link

commented Mar 29, 2019

I have the same problem as OP: Trying to get some pandas examples to run, which in turn use matplotlib. However matplotlib complains about _tkinter not being available:

>>> import pandas as pd
>>> california_housing_dataframe = pd.read_csv("https://download.mlcc.google.com/mledu-datasets/california_housing_train.csv", sep=",")
>>> california_housing_dataframe.hist('housing_median_age')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/linuxbrew/.linuxbrew/Cellar/python/3.7.2_2/lib/python3.7/site-packages/pandas/plotting/_core.py", line 2405, in hist_frame
    layout=layout)
  File "/home/linuxbrew/.linuxbrew/Cellar/python/3.7.2_2/lib/python3.7/site-packages/pandas/plotting/_tools.py", line 191, in _subplots
    import matplotlib.pyplot as plt
  File "/home/linuxbrew/.linuxbrew/Cellar/python/3.7.2_2/lib/python3.7/site-packages/matplotlib/pyplot.py", line 2372, in <module>
    switch_backend(rcParams["backend"])
  File "/home/linuxbrew/.linuxbrew/Cellar/python/3.7.2_2/lib/python3.7/site-packages/matplotlib/pyplot.py", line 207, in switch_backend
    backend_mod = importlib.import_module(backend_name)
  File "/home/linuxbrew/.linuxbrew/Cellar/python/3.7.2_2/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "/home/linuxbrew/.linuxbrew/Cellar/python/3.7.2_2/lib/python3.7/site-packages/matplotlib/backends/backend_tkagg.py", line 1, in <module>
    from . import _backend_tk
  File "/home/linuxbrew/.linuxbrew/Cellar/python/3.7.2_2/lib/python3.7/site-packages/matplotlib/backends/_backend_tk.py", line 5, in <module>
    import tkinter as Tk
  File "/home/linuxbrew/.linuxbrew/Cellar/python/3.7.2_2/lib/python3.7/tkinter/__init__.py", line 36, in <module>
    import _tkinter # If this fails your Python may not be configured for Tk
ModuleNotFoundError: No module named '_tkinter'
@mistler

This comment has been minimized.

Copy link

commented Apr 5, 2019

I have this problem too. Reproduces with this dockerfile:

FROM ubuntu:18.04                                                                  
                                                                                   
RUN apt clean && apt update && apt upgrade -y                                      
RUN apt update && apt install -y build-essential cargo curl make file wget openvpn easy-rsa exuberant-ctags git
                                                      
RUN groupadd -r mistler && useradd --no-log-init -r -g mistler mistler             
RUN usermod -aG sudo mistler                                                       
WORKDIR /home/mistler                                                              
RUN chown mistler:mistler /home/mistler                                            
USER mistler                                                                       
                                                                                   
RUN mkdir ~/.linuxbrew && (cd ~/.linuxbrew && mkdir -p etc include bin lib opt sbin share var/homebrew/linked Cellar)                                                                                                                         
RUN git clone https://github.com/Homebrew/brew ~/.linuxbrew/Homebrew && ln -s ../Homebrew/bin/brew ~/.linuxbrew/bin && eval $(~/.linuxbrew/bin/brew shellenv)
                                                                                   
ENV PATH="/home/mistler/.linuxbrew/bin:$PATH"                                      
                                                                                   
RUN brew update && brew install pyenv git
@iltommi

This comment has been minimized.

Copy link
Contributor

commented Apr 25, 2019

@iMichka , the gentlest of bumps on this.
You had time to progress in sorting out this python-tcl/tk intertwined dependency tree?
Thanks and sorry for the noise

@iMichka

This comment has been minimized.

Copy link
Member

commented Apr 26, 2019

The discussions has stalled on this PR: Linuxbrew/homebrew-xorg#455

We did not agree on a strategy right now. So this is on hold.

@Char-Aznable

This comment has been minimized.

Copy link
Contributor Author

commented May 13, 2019

@iMichka Should we revive #11417 as a temporary solution because it doesn't seem a more systematic solution would happen soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.