deprecate python2.7 for cqlsh

Patch by Adam Holmberg; reviewed by brandonwilliams for CASSANDRA-16414
This commit is contained in:
Adam Holmberg 2021-02-09 12:01:20 -06:00 committed by Brandon Williams
parent 425f750a6f
commit 72ca73fbc6
7 changed files with 44 additions and 29 deletions

View File

@ -124,6 +124,7 @@ New features
Upgrading Upgrading
--------- ---------
- cqlsh shell startup script now prefers 'python3' before 'python' when identifying a runtime.
- As part of the Internode Messaging improvement work in CASSANDRA-15066, matching response verbs for every request - As part of the Internode Messaging improvement work in CASSANDRA-15066, matching response verbs for every request
verb were introduced and verbs were renamed. DroppedMessageMetrics pre-4.0 are now available with _REQ suffix. As verb were introduced and verbs were renamed. DroppedMessageMetrics pre-4.0 are now available with _REQ suffix. As
part of CASSANDRA-16083, we added DroppedMessageMetrics backward compatibility layer which exposes the metrics with part of CASSANDRA-16083, we added DroppedMessageMetrics backward compatibility layer which exposes the metrics with
@ -290,6 +291,7 @@ Deprecation
- The JMX MBean org.apache.cassandra.db:type=BlacklistedDirectories has been - The JMX MBean org.apache.cassandra.db:type=BlacklistedDirectories has been
deprecated in favor of org.apache.cassandra.db:type=DisallowedDirectories deprecated in favor of org.apache.cassandra.db:type=DisallowedDirectories
and will be removed in a subsequent major version. and will be removed in a subsequent major version.
- cqlsh support of 2.7 is deprecated and will warn when running with Python 2.7.
Materialized Views Materialized Views
------------------- -------------------

View File

@ -12,7 +12,7 @@ For more information, see http://cassandra.apache.org/[the Apache Cassandra web
Requirements Requirements
------------ ------------
. Java >= 1.8 (OpenJDK and Oracle JVMS have been tested) . Java >= 1.8 (OpenJDK and Oracle JVMS have been tested)
. Python 2.7 (for cqlsh) . Python 3.6+ (for cqlsh; 2.7 works but is deprecated)
Getting started Getting started
--------------- ---------------

View File

@ -53,17 +53,16 @@ fi
# get a version string for a Python interpreter # get a version string for a Python interpreter
get_python_version() { get_python_version() {
interpreter=$1 interpreter=$1
version=$(command -v "$interpreter" > /dev/null 2>&1 && $interpreter -c "import os; print('{}.{}'.format(os.sys.version_info.major, os.sys.version_info.minor))") version=$($interpreter -c "import os; print('{}.{}'.format(os.sys.version_info.major, os.sys.version_info.minor))" 2> /dev/null)
echo "$version" echo "$version"
} }
# test whether a version string matches one of the supported versions for cqlsh # test whether a version string matches one of the supported versions for cqlsh
is_supported_version() { is_supported_version() {
version=$1 version=$1
# shellcheck disable=SC2039
# shellcheck disable=SC2072 # shellcheck disable=SC2072
# python2.7 or python3.6+ is supported # python3.6+ is supported. python2.7 is deprecated but still compatible.
if [ "$version" = "3.6" ] || [ "$version" \> "3.6" ] || [ "$version" = "2.7" ]; then if [ ! "$version" \< "3.6" ] || [ "$version" = "2.7" ]; then
echo "supported" echo "supported"
else else
echo "unsupported" echo "unsupported"
@ -88,8 +87,7 @@ if [ "$USER_SPECIFIED_PYTHON" != "" ]; then
# run a user specified Python interpreter # run a user specified Python interpreter
run_if_supported_version "$USER_SPECIFIED_PYTHON" "$@" run_if_supported_version "$USER_SPECIFIED_PYTHON" "$@"
else else
# try unqualified python first, then python3, then python2.7 for interpreter in python3 python python2.7; do
for interpreter in python python3 python2.7; do
run_if_supported_version "$interpreter" "$@" run_if_supported_version "$interpreter" "$@"
done done
fi fi

31
bin/cqlsh.py Normal file → Executable file
View File

@ -1,5 +1,4 @@
#!/bin/sh #!/usr/bin/python3
# -*- mode: Python -*-
# Licensed to the Apache Software Foundation (ASF) under one # Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file # or more contributor license agreements. See the NOTICE file
@ -17,20 +16,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
""":" from __future__ import division, unicode_literals, print_function
# bash code here; finds a suitable python interpreter and execs this file.
# this implementation of cqlsh is compatible with both Python 3 and Python 2.7.
# prefer unqualified "python" if suitable:
python -c 'import sys; sys.exit(not (0x020700b0 < sys.hexversion))' 2>/dev/null \
&& exec python "$0" "$@"
for pyver in 3 2.7; do
which python$pyver > /dev/null 2>&1 && exec python$pyver "$0" "$@"
done
echo "No appropriate python interpreter found." >&2
exit 1
":"""
from __future__ import division, unicode_literals
import cmd import cmd
import codecs import codecs
@ -48,8 +34,8 @@ from contextlib import contextmanager
from glob import glob from glob import glob
from uuid import UUID from uuid import UUID
if sys.version_info.major != 3 and (sys.version_info.major == 2 and sys.version_info.minor != 7): if sys.version_info < (3, 6) and sys.version_info[0:2] != (2, 7):
sys.exit("\nCQL Shell supports only Python 3 or Python 2.7\n") sys.exit("\ncqlsh requires Python 3.6+ or Python 2.7 (deprecated)\n")
# see CASSANDRA-10428 # see CASSANDRA-10428
if platform.python_implementation().startswith('Jython'): if platform.python_implementation().startswith('Jython'):
@ -532,6 +518,7 @@ class Shell(cmd.Cmd):
if tty: if tty:
self.reset_prompt() self.reset_prompt()
self.maybe_warn_py2()
self.report_connection() self.report_connection()
print('Use HELP for help.') print('Use HELP for help.')
else: else:
@ -605,7 +592,7 @@ class Shell(cmd.Cmd):
self.show_version() self.show_version()
def show_host(self): def show_host(self):
print("Connected to {0} at {1}:{2}." print("Connected to {0} at {1}:{2}"
.format(self.applycolor(self.get_cluster_name(), BLUE), .format(self.applycolor(self.get_cluster_name(), BLUE),
self.hostname, self.hostname,
self.port)) self.port))
@ -618,6 +605,12 @@ class Shell(cmd.Cmd):
vers['cql'] = self.cql_version vers['cql'] = self.cql_version
print("[cqlsh %(shver)s | Cassandra %(build)s | CQL spec %(cql)s | Native protocol v%(protocol)s]" % vers) print("[cqlsh %(shver)s | Cassandra %(build)s | CQL spec %(cql)s | Native protocol v%(protocol)s]" % vers)
def maybe_warn_py2(self):
py2_suppress_warn = 'CQLSH_NO_WARN_PY2'
if sys.version_info[0:2] == (2, 7) and not os.environ.get(py2_suppress_warn):
print("Python 2.7 support is deprecated. "
"Install Python 3.6+ or set %s to suppress this message.\n" % (py2_suppress_warn,))
def show_session(self, sessionid, partial_session=False): def show_session(self, sessionid, partial_session=False):
print_trace_session(self, self.session, sessionid, partial_session) print_trace_session(self, self.session, sessionid, partial_session)

View File

@ -43,7 +43,7 @@ Prerequisites
- **NOTE**: *Experimental* support for Java 11 was added in Cassandra 4.0 (`CASSANDRA-9608 <https://issues.apache.org/jira/browse/CASSANDRA-9608>`__). - **NOTE**: *Experimental* support for Java 11 was added in Cassandra 4.0 (`CASSANDRA-9608 <https://issues.apache.org/jira/browse/CASSANDRA-9608>`__).
Running Cassandra on Java 11 is *experimental*. Do so at your own risk. For more information, see Running Cassandra on Java 11 is *experimental*. Do so at your own risk. For more information, see
`NEWS.txt <https://github.com/apache/cassandra/blob/trunk/NEWS.txt>`__. `NEWS.txt <https://github.com/apache/cassandra/blob/trunk/NEWS.txt>`__.
- For using cqlsh, the latest version of `Python 2.7 <https://www.python.org/downloads/>`__ or Python 3.6+. To verify that you have - For using cqlsh, the latest version of `Python 3.6+ <https://www.python.org/downloads/>`__ or Python 2.7 (support deprecated). To verify that you have
the correct version of Python installed, type ``python --version``. the correct version of Python installed, type ``python --version``.
Choosing an installation method Choosing an installation method

View File

@ -13,7 +13,7 @@ the Python native protocol driver, and connects to the single node specified on
Compatibility Compatibility
^^^^^^^^^^^^^ ^^^^^^^^^^^^^
cqlsh is compatible with Python 2.7. cqlsh is compatible with Python 3.6+ (and 2.7, deprecated).
In general, a given version of cqlsh is only guaranteed to work with the version of Cassandra that it was released with. In general, a given version of cqlsh is only guaranteed to work with the version of Cassandra that it was released with.
In some cases, cqlsh make work with older or newer versions of Cassandra, but this is not officially supported. In some cases, cqlsh make work with older or newer versions of Cassandra, but this is not officially supported.

View File

@ -22,6 +22,7 @@ from __future__ import unicode_literals, with_statement
import locale import locale
import os import os
import re import re
import subprocess
import sys import sys
import unittest import unittest
@ -36,6 +37,9 @@ from .ansi_colors import (ColoredText, ansi_seq, lookup_colorcode,
CONTROL_C = '\x03' CONTROL_C = '\x03'
CONTROL_D = '\x04' CONTROL_D = '\x04'
has_python27 = not subprocess.call(['python2.7', '--version'])
has_python3 = not subprocess.call(['python3', '--version'])
class TestCqlshOutput(BaseTestCase): class TestCqlshOutput(BaseTestCase):
@classmethod @classmethod
@ -777,9 +781,27 @@ class TestCqlshOutput(BaseTestCase):
output = c.cmd_and_response('show host;') output = c.cmd_and_response('show host;')
self.assertHasColors(output) self.assertHasColors(output)
self.assertRegex(output, '^Connected to .* at %s:%d\.$' self.assertRegex(output, '^Connected to .* at %s:%d$'
% (re.escape(TEST_HOST), TEST_PORT)) % (re.escape(TEST_HOST), TEST_PORT))
@unittest.skipIf(not has_python27, 'Python 2.7 not available to test warning')
def test_warn_py2(self):
env = self.default_env.copy()
env['USER_SPECIFIED_PYTHON'] = 'python2.7'
# has the warning
with testrun_cqlsh(tty=True, env=env) as c:
self.assertIn('Python 2.7 support is deprecated.', c.output_header, 'cqlsh did not output expected warning.')
# can suppress
env['CQLSH_NO_WARN_PY2'] = '1'
with testrun_cqlsh(tty=True, env=env) as c:
self.assertNotIn('Python 2.7 support is deprecated.', c.output_header, 'cqlsh did not output expected warning.')
@unittest.skipIf(not (has_python27 and has_python3), 'Python 3 and 2.7 not available to test preference')
def test_no_warn_both_py_present(self):
with testrun_cqlsh(tty=True, env=self.default_env) as c:
self.assertNotIn('Python 2.7 support is deprecated.', c.output_header, 'cqlsh did not output expected warning.')
@unittest.skipIf(sys.platform == "win32", 'EOF signaling not supported on Windows') @unittest.skipIf(sys.platform == "win32", 'EOF signaling not supported on Windows')
def test_eof_prints_newline(self): def test_eof_prints_newline(self):
with testrun_cqlsh(tty=True, env=self.default_env) as c: with testrun_cqlsh(tty=True, env=self.default_env) as c: