Repository: planetlabs/planet-client-python
Pull request #558 (2022-05-18 19:58:33)

Use shutil.get_terminal_size
click.termui.get_terminal_size is no more.

Resolves #529

sgillies: I just noticed that shutil added get_terminal_size in Python 3.3. I'll find a way to keep using click's method for older Python versions. Click 8 dropped support for Python 2.x and 3.5, so we can pin the Python client to `click<8` for those versions.
sgillies: Complication: the tests of v1 don't exercise the code I patched, so we'll need some more tests.

Patch:
diff --git a/CHANGES.txt b/CHANGES.txt
index 9aa9491..021791d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,7 +1,8 @@
 # Changes.txt
 
-Next (TBD)
+1.4.10 (2022-05-18)
 
+- Fix: restore compatibility with click versions >= 8.1.0.
 - Fix: handle FeedSource array in analytics API.
 
 1.4.9 (2021-12-07)
diff --git a/planet/api/__version__.py b/planet/api/__version__.py
index 0e0c880..4b922b3 100644
--- a/planet/api/__version__.py
+++ b/planet/api/__version__.py
@@ -1,1 +1,1 @@
-__version__ = '1.4.9'
+__version__ = '1.4.10'
diff --git a/planet/scripts/util.py b/planet/scripts/util.py
index f06b402..488a999 100644
--- a/planet/scripts/util.py
+++ b/planet/scripts/util.py
@@ -30,6 +30,15 @@ from click import termui
 from planet import api
 from planet.api import filters
 
+# get_terminal_size was removed from click.termui in click 8.1.0.
+# Previously, click delegated to shutil.get_terminal_size for Python
+# versions >= 3.3. This import dance allows us to *not* pin the Python
+# Client's click dependency for any version of Python.
+try:
+    from shutil import get_terminal_size
+except ImportError:
+    from click.termui import get_terminal_size
+
 
 def _split(value):
     '''return input split on any whitespace or comma'''
@@ -314,7 +323,7 @@ class AnsiOutput(_BaseOutput):
         #
         # scrolling log output
         # ...
-        width, height = click.termui.get_terminal_size()
+        width, height = get_terminal_size()
         wrapper = textwrap.TextWrapper(width=width)
         self._stats['elapsed'] = '%d' % (time.time() - self._start)
         stats = ['%s: %s' % (k, v) for k, v in sorted(self._stats.items())]
@@ -337,7 +346,12 @@ class AnsiOutput(_BaseOutput):
 
 def downloader_output(dl, disable_ansi=False):
     thread = threading.current_thread()
-    # do fancy output if we can or not explicitly disabled
+    # Do fancy output if we can or not explicitly disabled.
+    # Attention: the click project deprecated a method in its termui
+    # module in 8.0.0 and removed it in 8.1.0. If support for v1 of the
+    # Python client continues, we should keep an eye on termui's WIN
+    # attribute, which looks like an incidental part of click's API
+    # (it's not imported into click/__init__.py).
     if sys.stdout.isatty() and not disable_ansi and not termui.WIN:
         return AnsiOutput(thread, dl)
     # work around for lack of nice output for downloader on windows:
diff --git a/setup.py b/setup.py
index 9a03d6d..b5cdc65 100644
--- a/setup.py
+++ b/setup.py
@@ -74,7 +74,7 @@ setup(name='planet',
       install_requires=[
           'click',
           'requests',
-          'requests_futures == 0.9.7',
+          'requests_futures',
           'pywin32 >= 1.0;platform_system=="Windows"'
       ],
       extras_require={
diff --git a/tox.ini b/tox.ini
index 5fa597f..8e9b620 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
 [tox]
-envlist = py27, py36, py37
+envlist = py27, py36
 
 [gh-actions]
 python =
@@ -14,4 +14,4 @@ python =
 deps = pytest
 commands =
     python -m pip install -e .[dev]
-    python -m pytest -v -rxXs --doctest-modules --cov planet --cov-report term-missing planet tests
+    python -Werror -m pytest -v -rxXs --doctest-modules --cov planet --cov-report term-missing planet tests


Test patch:
diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml
index a673970..2272810 100644
--- a/.github/workflows/tests.yaml
+++ b/.github/workflows/tests.yaml
@@ -3,9 +3,11 @@ name: "CI for v1"
 
 on:
   push:
-    branches: ["master"]
+    branches: ["v1"]
   pull_request:
-    branches: ["master"]
+    branches: ["v1"]
+  schedule:
+    - cron: '0 0 * * 0'
   workflow_dispatch:
 
 jobs:
@@ -16,7 +18,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        python-version: ["2.7", "3.6", "3.7"]
+        python-version: ["2.7", "3.6", "3.7", "3.8", "3.9"]
 
     steps:
       - uses: "actions/checkout@v2"
diff --git a/tests/test_cli.py b/tests/test_cli.py
index c6d5de0..e4dec48 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -136,3 +136,10 @@ def test_api_key_flag():
     run_cli(['-k', 'shazbot', 'help'])
     assert 'api_key' in cli.client_params
     assert cli.client_params['api_key'] == 'shazbot'
+
+
+def test_get_terminal_size():
+    """Check compatibility of get_terminal_size (see gh-529)."""
+    columns, rows = util.get_terminal_size()
+    assert isinstance(columns, int)
+    assert isinstance(rows, int)