ImportError: cannot import name 'get_terminal_size' from 'click.termui'
First Check
- [X] I added a very descriptive title to this issue.
- [X] I used the GitHub search to find a similar issue and didn't find it.
- [X] I searched the Typer documentation, with the integrated search.
- [X] I already searched in Google "How to X in Typer" and didn't find any information.
- [X] I already read and followed all the tutorial in the docs and didn't find an answer.
- [X] I already checked if it is not related to Typer but to Click.
Commit to Help
- [X] I commit to help with one of those options 👆
Example Code
import typer
Description
- Install latest versions of
typer(0.4.0) andclick(8.1.0) - Run script with single line
import typer - Import fails due to method
get_terminal_sizehaving been removed in click 8.1.0 (https://github.com/pallets/click/pull/2130)
Traceback (most recent call last):
File "test.py", line 1, in <module>
import typer
File "/.venv/lib/python3.8/site-packages/typer/__init__.py", line 12, in <module>
from click.termui import get_terminal_size as get_terminal_size
ImportError: cannot import name 'get_terminal_size' from 'click.termui' (/.venv/lib/python3.8/site-packages/click/termui.py)
Operating System
Linux
Operating System Details
Ubunutu 20.04
Typer Version
0.4.0
Python Version
Python 3.8.10
Additional Context
No response
I think that'll be fixed in #375
confirm the problem appeared on import
import spacy

Same here, also running into this exception with import spacy for spacy version 3.2.3. Reverting to spacy version 3.1.3 "solves" the problem for now.
CORRECTION:
It wasn't the spacy version... It's click (direct dependency from typer).
In both projects I have typer version 0.4.0 installed, the one which installed the newer click version 8.1.0 (and spacy 3.2.3) doesn't work, the older one (spacy 3.1.3) which installed click version 8.0.4 works.
tl;dr: Check your click version and force it <8.1.0.
Same issue also with the minimal example from the docs on a clean Conda environment with Python 3.9.11. Actually, the error is raised when merely running import typer in the Python console:
➜ python
Python 3.9.11 (main, Mar 28 2022, 05:06:49)
[Clang 12.0.0 ] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import typer
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/drorata/anaconda3/envs/foo/lib/python3.9/site-packages/typer/__init__.py", line 12, in <module>
from click.termui import get_terminal_size as get_terminal_size
ImportError: cannot import name 'get_terminal_size' from 'click.termui' (/Users/drorata/anaconda3/envs/foo/lib/python3.9/site-packages/click/termui.py)
Exactly the same error for me with Python 3.7.13 :
Python 3.7.13 (default, Mar 18 2022, 17:46:12)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import typer
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/var/www/ai/env/lib/python3.7/site-packages/typer/__init__.py", line 12, in <module>
from click.termui import get_terminal_size as get_terminal_size
ImportError: cannot import name 'get_terminal_size' from 'click.termui' (/var/www/ai/env/lib/python3.7/site-packages/click/termui.py)
After downgrading Typer to 0.3.2 the problem is gone.
After downgrading Click to 0.4.1 the problem is gone.
This temporary solution : https://github.com/explosion/spaCy/issues/10564#issuecomment-1081570327 works for me → pip install click==8.0.4
This temporary solution : explosion/spaCy#10564 (comment) works for me →
pip install click==8.0.4
That correct !! I just fix the same your way. I downgrade click from 8.1.0 to 8.0.4 It's working now.
I am seeing the same on a dependabot PR proposing to update the click version to 8.1 All my "import typer" statements fail with this error:
.tox/py3/lib/python3.8/site-packages/typer/__init__.py:12: in <module>
from click.termui import get_terminal_size as get_terminal_size
E ImportError: cannot import name 'get_terminal_size' from 'click.termui' (/home/feganj/wip/.tox/py3/lib/python3.8/
This temporary solution : explosion/spaCy#10564 (comment) works for me →
pip install click==8.0.4
Thanks, I uninstall click and install again with 8.0.4 and works
Click makes deprecation warning one minor version ahead for functions that do reimport and could be working for years.
That's a terrible management for such a wide dependency, and now all tools are split into demanding click <8.1, demanding 7.* and demanding > 8.1.
If you fix black, prefect and typer are still not working. 😠
@arogozhnikov I understand the frustration; we've been impacted at work too. However, I think the reaction you had could be a bit more tempered.
The decision may have been disruptive, and the points you make after your first line are valid (even if worded strongly), but I disagree with the act of calling Click an "absolutely terrible dependency". That act is disheartening for an OSS dev, for which I am one myself, and my heart sank when I read your comment, even though I don't maintain Click or Typer myself. Having provided so much value to the community, it is my opinion that the dev team does not deserve that initial reaction you posted. If you would be open to tempering your comment for posterity, I think that would reflect positively on your character as a fellow OSS user, scientist, and developer.
I removed that first line.
disagree with the act of calling Click an "absolutely terrible dependency".
if it shatters environment (as I point, not the first time), that's a bad dependency. Your best move is to untie from it as there is no reason to expect this won't repeat.
Click does not use any sophisticated building process neither has too hard nor fragile dependencies. Multiple python packages are in times harder position (all scientific stack basically) but their devs are careful about deprecation cycles and warnings.
Typer previous time was broken for like a year because of click changes. Now we're back here again (fix is trivial, but tiangolo and other people have their schedule - why shouldn't they?).
So maybe @ericmjl you suggest a way that I can use other libraries (like typer) and not be affected by click API changes?
If not, that gets to initial point - I'm asking for minimizing / removing dependency on click, as multiple tools can't change simultaneously, but click does not provide any alternative plan for them.
I think the basic point is that Click has caused problems for their consumers, including typer, by breaking backward compatibility without a lot of warning or prep time. Have you (or anyone) reported that to the Click project? Maybe they would choose to reintroduce this symbol in a 8.1.1 to restore compatibility, and then set about removing it again in a more controlled fashion. That seems the best solution to me. As far as the typer project goes... I don't know the history, but if Click do this sort of thing a lot then I agree it would make sense for their consumers to try to limit vulnerability to it where possible.
@jofegan yes, that was done before me several times. You can track their reaction is the Click repo.
Maybe they would choose to reintroduce this symbol in a 8.1.1 to restore compatibility
That what I expected being done. You're very welcome to suggest this to click team.
Maybe they would choose to reintroduce this symbol in a 8.1.1 to restore compatibility, and then set about removing it again in a more controlled fashion.
But we did remove it in a controlled fashion. Using this function issued a DeprecationWarning starting in 8.0, released 10 months ago. The deprecation was mentioned high up in the changelog, as was the removal. If projects didn't respond to the deprecation yet, why would adding it back in and then removing it again change anything? It would just delay the same events, and then when we removed it again we'd be in the same situation.
It doesn't matter how long we provided warning, because Typer (and apparently no one using Typer either) wasn't testing with deprecation warnings treated as errors, so they would never have been able to proactively respond to the deprecation. I've opened #379 to show how that can be enabled. This is not a problem specific to Click: Python itself, or any libraries used in test/docs environments, can also be issuing deprecation warnings that Typer (or applications using it) is unaware of right now.
One way you, or applications you use, can control this is to use a project management tool like pip-tools, pipenv, pdm, or poetry to pin your dependencies and control when updates are seen and applied. Again, this is not specific to Click. If you pin any dependency (or if a library you use doesn't proactively test warnings), then you need to pin your entire dependency tree to avoid one library updating while another is pinned or not updated yet.
I'm sorry this was disruptive, I get the frustration. Controlling updates is a general problem in Python packaging. It's something everyone's going to run into, whether with this library or another, eventually.
I know @tiangolo is aware of this, although he's currently at a conference right now, but I'm sure he will make a release when he is able.
It doesn't matter how long we provided warning, because Typer (and apparently no one using Typer either) wasn't testing with deprecation warnings treated as errors, so they would never have been able to proactively respond to the deprecation.
If nobody does, you still insist that's the way?
I know most of my projects just can't pass such testing because click is not the only dependency, and there are always some things that are not yet fixed in the freshest versions of deps (pandas-depending stack, numba-depending stack, torch and tf are other snowflakes).
Once again, you can just reintroduce function because its existence does not break anything and unlikely will. Absence of it already breaks a lot.
@davidism please verbalize your position, that was your diff. Thumbs are not an argument.
I hear what you're saying. In my case, the package versions are pinned and all that has happened is that dependabot proposed an upgrade to Click 8.1.0 and that PR failed CI because it would break Typer. Not a big deal; there's nothing in 8.1.0 that I specifically need and that's just my pins and CI doing their job and stopping me from breaking my own build. But this incompatibility does mean that I won't be able to accept any future updates to Click at all until Typer makes a change to compensate. That can be the tricky part - if one of the affected packages isn't well maintained I may be stuck on the old click version for a long time. But it sounds like that will be okay here.
But it sounds like that will be okay here.
Unless other project you depend critically on requires fresh black (updated after recent Click update), which requires fresh Click. Which typer can't work with.
Thanks for the report @jmhummel!
And thanks everyone for the conversation.
I just released Typer 0.4.1 that should handle this. :rocket: :nerd_face:
Thank you very much for the understanding, in particular to those showing your support to these free, open source projects, and the maintainers, like David and me. :heart: :bow:
I'm sorry this made your lives and work difficult for these last couple of days. What happened was that Typer was importing and exporting that utility function from Click just as a convenience for users, but it wasn't used internally, it wasn't called, and that way I didn't catch the deprecation warning.
It was unfortunate indeed, but I wouldn't actually think it's something worth shaming me very aggressively and even less the maintainer(s) of Click that always do an amazing and thorough job.
These types of errors and accidents happen, they happen in open source and even more in closed source, they happen to projects of all sizes and types. The best we can do is to continue to try and make the whole community a welcoming place where we try to help each other instead of blaming and shaming others.
@jmhummel if you confirm that the new release solves your problem you can then close this issue. :nerd_face:
Thank you!
I can happily confirm that the issue mentioned in this comment above is removed once updating typer to 0.4.1. Thanks!
Apologies to add to noise. Reinforcing @drorata's comment that upgrading Typer to 0.4.1 resolved the issue and managed not to break any other dependencies in my gcp + pandas data pipeline.
Assuming the original issue was solved, it will be automatically closed now. But feel free to add more comments or create new issues.
Bot closed this but it appears to be unresolved.
Here's the definition of the missing function at the time of removal:
def get_terminal_size() -> os.terminal_size: """Returns the current size of the terminal as tuple in the form ``(width, height)`` in columns and rows. .. deprecated:: 8.0 Will be removed in Click 8.1. Use :func:`shutil.get_terminal_size` instead. """ import shutil import warnings warnings.warn( "'click.get_terminal_size()' is deprecated and will be removed" " in Click 8.1. Use 'shutil.get_terminal_size()' instead.", DeprecationWarning, stacklevel=2, ) return shutil.get_terminal_size()
I believe it should be trivial to fix this particular issue (and it wouldn't even break compatibility with click-8.0).