From 3600d788695b6c0147f8ed50771e5e6b8d7f51a8 Mon Sep 17 00:00:00 2001
From: Brian Goins <340396+briangoins@users.noreply.github.com>
Date: Mon, 26 Jan 2026 15:54:23 -0500
Subject: [PATCH 1/6] CASSANDRA-17684 bundling CQL.html as Python package
resource
---
.gitignore | 2 +
build.xml | 15 ++-
pylib/cqlshlib/cqlshmain.py | 59 +++++++++--
pylib/cqlshlib/resources/__init__.py | 24 +++++
pylib/cqlshlib/test/test_docspath.py | 140 +++++++++++++++++++++++++++
pylib/setup.py | 6 +-
6 files changed, 236 insertions(+), 10 deletions(-)
create mode 100644 pylib/cqlshlib/resources/__init__.py
create mode 100644 pylib/cqlshlib/test/test_docspath.py
diff --git a/.gitignore b/.gitignore
index c8cd6ac29a86..a1722e9e6ab3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,8 @@ data/
conf/hotspot_compiler
doc/cql3/CQL.html
doc/build/
+pylib/cqlshlib/resources/CQL.html
+pylib/cqlshlib/resources/CQL.css
lib/
pylib/src/
**/cqlshlib.xml
diff --git a/build.xml b/build.xml
index 832a9d86bb3f..78f54c03797d 100644
--- a/build.xml
+++ b/build.xml
@@ -65,6 +65,7 @@
+
@@ -458,6 +459,8 @@
+
+
@@ -506,6 +509,16 @@
+
+
+
+
+
+
+
+
+
@@ -586,7 +599,7 @@
-
diff --git a/pylib/cqlshlib/cqlshmain.py b/pylib/cqlshlib/cqlshmain.py
index 8b26e3307884..2bd2cc9303b0 100755
--- a/pylib/cqlshlib/cqlshmain.py
+++ b/pylib/cqlshlib/cqlshmain.py
@@ -2125,14 +2125,57 @@ def read_options(cmdlineargs, parser, config_file, cql_dir, environment=os.envir
def get_docspath(path):
- cqldocs_url = Shell.DEFAULT_CQLDOCS_URL
- if os.path.exists(path + '/doc/cql3/CQL.html'):
- # default location of local CQL.html
- cqldocs_url = 'file://' + path + '/doc/cql3/CQL.html'
- elif os.path.exists('/usr/share/doc/cassandra/CQL.html'):
- # fallback to package file
- cqldocs_url = 'file:///usr/share/doc/cassandra/CQL.html'
- return cqldocs_url
+ """
+ Determine the URL for CQL documentation.
+
+ Priority order:
+ 1. Local development/tarball path: {path}/doc/cql3/CQL.html
+ 2. Linux package path: /usr/share/doc/cassandra/CQL.html
+ 3. macOS path: /usr/local/share/doc/cassandra/CQL.html
+ 4. Bundled package resource (for pip installs, etc.)
+ 5. Online documentation URL (fallback)
+ """
+ # Check local dev/tarball path
+ local_path = os.path.join(path, 'doc', 'cql3', 'CQL.html')
+ if os.path.exists(local_path):
+ return 'file://' + os.path.abspath(local_path)
+
+ # Check system package installation paths
+ for system_path in ['/usr/share/doc/cassandra/CQL.html',
+ '/usr/local/share/doc/cassandra/CQL.html']:
+ if os.path.exists(system_path):
+ return 'file://' + system_path
+
+ # Try to load from package resources
+ resource_url = _get_docs_from_package_resource()
+ if resource_url:
+ return resource_url
+
+ # Fall back to online documentation
+ return Shell.DEFAULT_CQLDOCS_URL
+
+
+def _get_docs_from_package_resource():
+ """
+ Attempt to load CQL documentation from package resources.
+ Returns a file:// URL to the resource, or None if unavailable.
+ """
+ try:
+ if sys.version_info >= (3, 9):
+ from importlib.resources import files, as_file
+ resource = files('cqlshlib.resources').joinpath('CQL.html')
+ with as_file(resource) as path:
+ if path.exists():
+ return 'file://' + str(path.resolve())
+ else:
+ # Python 3.8 compatibility
+ from importlib.resources import path as resource_path
+ with resource_path('cqlshlib.resources', 'CQL.html') as path:
+ if path.exists():
+ return 'file://' + str(path.resolve())
+ except Exception:
+ pass
+ return None
def insert_driver_hooks():
diff --git a/pylib/cqlshlib/resources/__init__.py b/pylib/cqlshlib/resources/__init__.py
new file mode 100644
index 000000000000..d4cd24963b28
--- /dev/null
+++ b/pylib/cqlshlib/resources/__init__.py
@@ -0,0 +1,24 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Bundled resources for cqlshlib.
+
+This package contains static resources (like CQL documentation) that are
+bundled with cqlshlib for distribution as a Python package. These resources
+are used as fallbacks when the documentation cannot be found in the standard
+installation paths.
+"""
diff --git a/pylib/cqlshlib/test/test_docspath.py b/pylib/cqlshlib/test/test_docspath.py
new file mode 100644
index 000000000000..e4cca349e257
--- /dev/null
+++ b/pylib/cqlshlib/test/test_docspath.py
@@ -0,0 +1,140 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import tempfile
+from unittest.mock import patch
+
+from .basecase import BaseTestCase
+from cqlshlib.cqlshmain import get_docspath, _get_docs_from_package_resource, Shell
+
+
+class TestGetDocspath(BaseTestCase):
+ """
+ Tests for the get_docspath() function.
+
+ Verifies that CQL documentation paths are resolved according to the
+ function's priority logic.
+ """
+
+ def test_local_dev_path(self):
+ """Local doc/cql3/CQL.html takes precedence over all other paths."""
+ with tempfile.TemporaryDirectory() as tmpdir:
+ docs_dir = os.path.join(tmpdir, 'doc', 'cql3')
+ os.makedirs(docs_dir)
+ docs_file = os.path.join(docs_dir, 'CQL.html')
+ with open(docs_file, 'w') as f:
+ f.write('')
+
+ result = get_docspath(tmpdir)
+
+ self.assertTrue(result.startswith('file://'))
+ self.assertIn('doc/cql3/CQL.html', result)
+ self.assertEqual(result, 'file://' + os.path.abspath(docs_file))
+
+ def test_linux_package_path(self):
+ """Linux package path when local path doesn't exist."""
+ with tempfile.TemporaryDirectory() as tmpdir:
+ with patch('os.path.exists') as mock_exists:
+ def exists_side_effect(path):
+ if path == os.path.join(tmpdir, 'doc', 'cql3', 'CQL.html'):
+ return False
+ if path == '/usr/share/doc/cassandra/CQL.html':
+ return True
+ return False
+
+ mock_exists.side_effect = exists_side_effect
+
+ result = get_docspath(tmpdir)
+
+ self.assertEqual(result, 'file:///usr/share/doc/cassandra/CQL.html')
+
+ def test_macos_path(self):
+ """macOS path when local and Linux paths don't exist."""
+ with tempfile.TemporaryDirectory() as tmpdir:
+ with patch('os.path.exists') as mock_exists:
+ def exists_side_effect(path):
+ if path == os.path.join(tmpdir, 'doc', 'cql3', 'CQL.html'):
+ return False
+ if path == '/usr/share/doc/cassandra/CQL.html':
+ return False
+ if path == '/usr/local/share/doc/cassandra/CQL.html':
+ return True
+ return False
+
+ mock_exists.side_effect = exists_side_effect
+
+ result = get_docspath(tmpdir)
+
+ self.assertEqual(result, 'file:///usr/local/share/doc/cassandra/CQL.html')
+
+ def test_package_resource(self):
+ """Package resource when filesystem paths don't exist."""
+ with tempfile.TemporaryDirectory() as tmpdir:
+ with patch('os.path.exists', return_value=False):
+ with patch('cqlshlib.cqlshmain._get_docs_from_package_resource') as mock_resource:
+ mock_resource.return_value = 'file:///some/resource/path/CQL.html'
+
+ result = get_docspath(tmpdir)
+
+ self.assertEqual(result, 'file:///some/resource/path/CQL.html')
+ mock_resource.assert_called_once()
+
+ def test_online_url_fallback(self):
+ """Online documentation URL when all local paths fail."""
+ with tempfile.TemporaryDirectory() as tmpdir:
+ with patch('os.path.exists', return_value=False):
+ with patch('cqlshlib.cqlshmain._get_docs_from_package_resource', return_value=None):
+ result = get_docspath(tmpdir)
+
+ self.assertEqual(result, Shell.DEFAULT_CQLDOCS_URL)
+
+
+class TestGetDocsFromPackageResource(BaseTestCase):
+ """Tests for the _get_docs_from_package_resource() function."""
+
+ def test_returns_none_on_import_error(self):
+ """Should return None if importlib.resources is not available."""
+ with patch.dict('sys.modules', {'importlib.resources': None}):
+ with patch('cqlshlib.cqlshmain.sys.version_info', (3, 9)):
+ with patch('builtins.__import__', side_effect=ImportError):
+ result = _get_docs_from_package_resource()
+ self.assertIsNone(result)
+
+ def test_returns_none_when_resource_not_found(self):
+ """Should return None if the resource file doesn't exist."""
+ from unittest.mock import MagicMock
+ from contextlib import contextmanager
+
+ @contextmanager
+ def mock_as_file(resource):
+ mock_path = MagicMock()
+ mock_path.exists.return_value = False
+ yield mock_path
+
+ with patch('cqlshlib.cqlshmain.sys.version_info', (3, 9)):
+ with patch('importlib.resources.files') as mock_files:
+ with patch('importlib.resources.as_file', mock_as_file):
+ mock_files.return_value.joinpath.return_value = MagicMock()
+ result = _get_docs_from_package_resource()
+ self.assertIsNone(result)
+
+ def test_exception_handling(self):
+ """Should handle exceptions gracefully and return None."""
+ with patch('cqlshlib.cqlshmain.sys.version_info', (3, 9)):
+ with patch('importlib.resources.files', side_effect=Exception("Test error")):
+ result = _get_docs_from_package_resource()
+ self.assertIsNone(result)
diff --git a/pylib/setup.py b/pylib/setup.py
index 1dfd8cdc89a0..c04827fde782 100755
--- a/pylib/setup.py
+++ b/pylib/setup.py
@@ -30,6 +30,10 @@ def get_extensions():
setup(
name="cassandra-pylib",
description="Cassandra Python Libraries",
- packages=["cqlshlib"],
+ packages=["cqlshlib", "cqlshlib.resources"],
+ package_data={
+ "cqlshlib.resources": ["CQL.html", "CQL.css"],
+ },
+ include_package_data=True,
ext_modules=get_extensions(),
)
From b954e0cd461dec6596823432b265fb958d7a94c6 Mon Sep 17 00:00:00 2001
From: Brian Goins <340396+briangoins@users.noreply.github.com>
Date: Thu, 29 Jan 2026 19:26:49 -0500
Subject: [PATCH 2/6] test python 3.8 compatibility code for get_docspath
---
pylib/cqlshlib/test/test_docspath.py | 49 ++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/pylib/cqlshlib/test/test_docspath.py b/pylib/cqlshlib/test/test_docspath.py
index e4cca349e257..8f363fac0ee0 100644
--- a/pylib/cqlshlib/test/test_docspath.py
+++ b/pylib/cqlshlib/test/test_docspath.py
@@ -138,3 +138,52 @@ def test_exception_handling(self):
with patch('importlib.resources.files', side_effect=Exception("Test error")):
result = _get_docs_from_package_resource()
self.assertIsNone(result)
+
+ def test_python38_returns_none_on_import_error(self):
+ """Should return None if importlib.resources is not available on Python 3.8."""
+ with patch.dict('sys.modules', {'importlib.resources': None}):
+ with patch('cqlshlib.cqlshmain.sys.version_info', (3, 8)):
+ with patch('builtins.__import__', side_effect=ImportError):
+ result = _get_docs_from_package_resource()
+ self.assertIsNone(result)
+
+ def test_python38_returns_none_when_resource_not_found(self):
+ """Should return None if the resource file doesn't exist on Python 3.8."""
+ from unittest.mock import MagicMock
+ from contextlib import contextmanager
+
+ @contextmanager
+ def mock_resource_path(package, resource):
+ mock_path = MagicMock()
+ mock_path.exists.return_value = False
+ yield mock_path
+
+ with patch('cqlshlib.cqlshmain.sys.version_info', (3, 8)):
+ with patch('importlib.resources.path', mock_resource_path):
+ result = _get_docs_from_package_resource()
+ self.assertIsNone(result)
+
+ def test_python38_exception_handling(self):
+ """Should handle exceptions gracefully and return None on Python 3.8."""
+ with patch('cqlshlib.cqlshmain.sys.version_info', (3, 8)):
+ with patch('importlib.resources.path', side_effect=Exception("Test error")):
+ result = _get_docs_from_package_resource()
+ self.assertIsNone(result)
+
+ def test_python38_returns_file_url_when_resource_exists(self):
+ """Should return file:// URL when resource exists on Python 3.8."""
+ from unittest.mock import MagicMock
+ from contextlib import contextmanager
+ from pathlib import Path
+
+ @contextmanager
+ def mock_resource_path(package, resource):
+ mock_path = MagicMock(spec=Path)
+ mock_path.exists.return_value = True
+ mock_path.resolve.return_value = Path('/fake/path/CQL.html')
+ yield mock_path
+
+ with patch('cqlshlib.cqlshmain.sys.version_info', (3, 8)):
+ with patch('importlib.resources.path', mock_resource_path):
+ result = _get_docs_from_package_resource()
+ self.assertEqual(result, 'file:///fake/path/CQL.html')
From 4576fa9ca5e8f048dcf6df76e28cb2e195ecf89e Mon Sep 17 00:00:00 2001
From: Brian Goins <340396+briangoins@users.noreply.github.com>
Date: Thu, 29 Jan 2026 19:27:37 -0500
Subject: [PATCH 3/6] remove redundant package directive
---
pylib/setup.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/pylib/setup.py b/pylib/setup.py
index c04827fde782..c23b13c708b4 100755
--- a/pylib/setup.py
+++ b/pylib/setup.py
@@ -34,6 +34,5 @@ def get_extensions():
package_data={
"cqlshlib.resources": ["CQL.html", "CQL.css"],
},
- include_package_data=True,
ext_modules=get_extensions(),
)
From 92131e157404da74e0517b26c21e2a12338b99c7 Mon Sep 17 00:00:00 2001
From: Brian Goins <340396+briangoins@users.noreply.github.com>
Date: Thu, 29 Jan 2026 19:31:11 -0500
Subject: [PATCH 4/6] mkdir on `copy-cql-docs-to-pylib` task
---
build.xml | 1 +
1 file changed, 1 insertion(+)
diff --git a/build.xml b/build.xml
index 78f54c03797d..03aec6ad1da8 100644
--- a/build.xml
+++ b/build.xml
@@ -511,6 +511,7 @@
+
From 01d604e98d78dae12d98757a532f271265554fe0 Mon Sep 17 00:00:00 2001
From: Brian Goins <340396+briangoins@users.noreply.github.com>
Date: Thu, 29 Jan 2026 19:42:51 -0500
Subject: [PATCH 5/6] fix context manager pattern
---
pylib/cqlshlib/cqlshmain.py | 26 +++++----
pylib/cqlshlib/test/test_docspath.py | 81 +++++++++++++++-------------
2 files changed, 61 insertions(+), 46 deletions(-)
diff --git a/pylib/cqlshlib/cqlshmain.py b/pylib/cqlshlib/cqlshmain.py
index 2bd2cc9303b0..5f8ccff509d8 100755
--- a/pylib/cqlshlib/cqlshmain.py
+++ b/pylib/cqlshlib/cqlshmain.py
@@ -2159,20 +2159,28 @@ def _get_docs_from_package_resource():
"""
Attempt to load CQL documentation from package resources.
Returns a file:// URL to the resource, or None if unavailable.
+
+ Note: This only works for packages installed on the filesystem.
+ For zipped packages, returns None and the caller falls back to online docs.
"""
try:
+ from pathlib import Path
if sys.version_info >= (3, 9):
- from importlib.resources import files, as_file
+ from importlib.resources import files
resource = files('cqlshlib.resources').joinpath('CQL.html')
- with as_file(resource) as path:
- if path.exists():
- return 'file://' + str(path.resolve())
+ # Convert to path and check if it exists on the real filesystem.
+ # For zipped packages, this path won't exist, so we fall back to online docs.
+ resource_path = Path(str(resource))
+ if resource_path.is_file():
+ return 'file://' + str(resource_path.resolve())
else:
- # Python 3.8 compatibility
- from importlib.resources import path as resource_path
- with resource_path('cqlshlib.resources', 'CQL.html') as path:
- if path.exists():
- return 'file://' + str(path.resolve())
+ # Python 3.8 compatibility: locate the package directory directly
+ import importlib.util
+ spec = importlib.util.find_spec('cqlshlib.resources')
+ if spec and spec.origin:
+ resource_path = Path(spec.origin).parent / 'CQL.html'
+ if resource_path.is_file():
+ return 'file://' + str(resource_path.resolve())
except Exception:
pass
return None
diff --git a/pylib/cqlshlib/test/test_docspath.py b/pylib/cqlshlib/test/test_docspath.py
index 8f363fac0ee0..7d465f40942a 100644
--- a/pylib/cqlshlib/test/test_docspath.py
+++ b/pylib/cqlshlib/test/test_docspath.py
@@ -115,22 +115,27 @@ def test_returns_none_on_import_error(self):
self.assertIsNone(result)
def test_returns_none_when_resource_not_found(self):
- """Should return None if the resource file doesn't exist."""
+ """Should return None if the resource file doesn't exist on filesystem."""
from unittest.mock import MagicMock
- from contextlib import contextmanager
-
- @contextmanager
- def mock_as_file(resource):
- mock_path = MagicMock()
- mock_path.exists.return_value = False
- yield mock_path
with patch('cqlshlib.cqlshmain.sys.version_info', (3, 9)):
with patch('importlib.resources.files') as mock_files:
- with patch('importlib.resources.as_file', mock_as_file):
- mock_files.return_value.joinpath.return_value = MagicMock()
+ mock_files.return_value.joinpath.return_value = '/wrong/path/CQL.html'
+ result = _get_docs_from_package_resource()
+ self.assertIsNone(result)
+
+ def test_returns_file_url_when_resource_exists(self):
+ """Should return file:// URL when resource exists on filesystem."""
+ with tempfile.TemporaryDirectory() as tmpdir:
+ resource_file = os.path.join(tmpdir, 'CQL.html')
+ with open(resource_file, 'w') as f:
+ f.write('')
+
+ with patch('cqlshlib.cqlshmain.sys.version_info', (3, 9)):
+ with patch('importlib.resources.files') as mock_files:
+ mock_files.return_value.joinpath.return_value = resource_file
result = _get_docs_from_package_resource()
- self.assertIsNone(result)
+ self.assertEqual(result, 'file://' + os.path.realpath(resource_file))
def test_exception_handling(self):
"""Should handle exceptions gracefully and return None."""
@@ -140,50 +145,52 @@ def test_exception_handling(self):
self.assertIsNone(result)
def test_python38_returns_none_on_import_error(self):
- """Should return None if importlib.resources is not available on Python 3.8."""
- with patch.dict('sys.modules', {'importlib.resources': None}):
+ """Should return None if importlib.util is not available on Python 3.8."""
+ with patch.dict('sys.modules', {'importlib.util': None}):
with patch('cqlshlib.cqlshmain.sys.version_info', (3, 8)):
with patch('builtins.__import__', side_effect=ImportError):
result = _get_docs_from_package_resource()
self.assertIsNone(result)
+ def test_python38_returns_none_when_spec_not_found(self):
+ """Should return None if package spec is not found on Python 3.8."""
+ with patch('cqlshlib.cqlshmain.sys.version_info', (3, 8)):
+ with patch('importlib.util.find_spec', return_value=None):
+ result = _get_docs_from_package_resource()
+ self.assertIsNone(result)
+
def test_python38_returns_none_when_resource_not_found(self):
"""Should return None if the resource file doesn't exist on Python 3.8."""
from unittest.mock import MagicMock
- from contextlib import contextmanager
- @contextmanager
- def mock_resource_path(package, resource):
- mock_path = MagicMock()
- mock_path.exists.return_value = False
- yield mock_path
+ mock_spec = MagicMock()
+ mock_spec.origin = '/wrong/package/__init__.py'
with patch('cqlshlib.cqlshmain.sys.version_info', (3, 8)):
- with patch('importlib.resources.path', mock_resource_path):
- result = _get_docs_from_package_resource()
- self.assertIsNone(result)
-
- def test_python38_exception_handling(self):
- """Should handle exceptions gracefully and return None on Python 3.8."""
- with patch('cqlshlib.cqlshmain.sys.version_info', (3, 8)):
- with patch('importlib.resources.path', side_effect=Exception("Test error")):
+ with patch('importlib.util.find_spec', return_value=mock_spec):
result = _get_docs_from_package_resource()
self.assertIsNone(result)
def test_python38_returns_file_url_when_resource_exists(self):
"""Should return file:// URL when resource exists on Python 3.8."""
from unittest.mock import MagicMock
- from contextlib import contextmanager
- from pathlib import Path
- @contextmanager
- def mock_resource_path(package, resource):
- mock_path = MagicMock(spec=Path)
- mock_path.exists.return_value = True
- mock_path.resolve.return_value = Path('/fake/path/CQL.html')
- yield mock_path
+ with tempfile.TemporaryDirectory() as tmpdir:
+ resource_file = os.path.join(tmpdir, 'CQL.html')
+ with open(resource_file, 'w') as f:
+ f.write('')
+
+ mock_spec = MagicMock()
+ mock_spec.origin = os.path.join(tmpdir, '__init__.py')
+
+ with patch('cqlshlib.cqlshmain.sys.version_info', (3, 8)):
+ with patch('importlib.util.find_spec', return_value=mock_spec):
+ result = _get_docs_from_package_resource()
+ self.assertEqual(result, 'file://' + os.path.realpath(resource_file))
+ def test_python38_exception_handling(self):
+ """Should handle exceptions gracefully and return None on Python 3.8."""
with patch('cqlshlib.cqlshmain.sys.version_info', (3, 8)):
- with patch('importlib.resources.path', mock_resource_path):
+ with patch('importlib.util.find_spec', side_effect=Exception("Test error")):
result = _get_docs_from_package_resource()
- self.assertEqual(result, 'file:///fake/path/CQL.html')
+ self.assertIsNone(result)
From 37e5ab759f7f8ddbfe0a3170d1efff55e37e2772 Mon Sep 17 00:00:00 2001
From: Brian Goins <340396+briangoins@users.noreply.github.com>
Date: Thu, 29 Jan 2026 19:43:02 -0500
Subject: [PATCH 6/6] explanatory comment for exception
---
pylib/cqlshlib/cqlshmain.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/pylib/cqlshlib/cqlshmain.py b/pylib/cqlshlib/cqlshmain.py
index 5f8ccff509d8..e8412995e5d7 100755
--- a/pylib/cqlshlib/cqlshmain.py
+++ b/pylib/cqlshlib/cqlshmain.py
@@ -2182,6 +2182,8 @@ def _get_docs_from_package_resource():
if resource_path.is_file():
return 'file://' + str(resource_path.resolve())
except Exception:
+ # Any error while loading the bundled CQL docs is non-fatal;
+ # pass to fall back to other locations.
pass
return None