mirror of https://github.com/apache/cassandra
Clean up obsolete functions and simplify cql_version handling in cqlsh
Patch by Brad Schoening; reviewed by brandonwilliams and edimitrova for CASSANDRA-18787
This commit is contained in:
parent
5aa7da5ebd
commit
abe09cff34
|
|
@ -1,4 +1,5 @@
|
||||||
5.1
|
5.1
|
||||||
|
* Clean up obsolete functions and simplify cql_version handling in cqlsh (CASSANDRA-18787)
|
||||||
Merged from 5.0:
|
Merged from 5.0:
|
||||||
* Fix Depends and Build-Depends for Java for Debian packages (CASSANDRA-18809)
|
* Fix Depends and Build-Depends for Java for Debian packages (CASSANDRA-18809)
|
||||||
* Update command line flags --add-exports and --add-opens for JDK17 (CASSANDRA-18439)
|
* Update command line flags --add-exports and --add-opens for JDK17 (CASSANDRA-18439)
|
||||||
|
|
|
||||||
|
|
@ -99,18 +99,11 @@ port = 9042
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[csv]
|
|
||||||
;; The size limit for parsed fields
|
|
||||||
; field_size_limit = 131072
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[tracing]
|
[tracing]
|
||||||
;; The max number of seconds to wait for a trace to complete
|
;; The max number of seconds to wait for a trace to complete
|
||||||
; max_trace_wait = 10.0
|
; max_trace_wait = 10.0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;[ssl]
|
;[ssl]
|
||||||
; certfile = ~/keys/cassandra.cert
|
; certfile = ~/keys/cassandra.cert
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
import cmd
|
import cmd
|
||||||
import codecs
|
import codecs
|
||||||
import configparser
|
import configparser
|
||||||
import csv
|
|
||||||
import getpass
|
import getpass
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
|
@ -277,22 +276,10 @@ class DecodeError(Exception):
|
||||||
return '<%s %s>' % (self.__class__.__name__, self.message())
|
return '<%s %s>' % (self.__class__.__name__, self.message())
|
||||||
|
|
||||||
|
|
||||||
def maybe_ensure_text(val):
|
|
||||||
return str(val) if val else val
|
|
||||||
|
|
||||||
|
|
||||||
class FormatError(DecodeError):
|
class FormatError(DecodeError):
|
||||||
verb = 'format'
|
verb = 'format'
|
||||||
|
|
||||||
|
|
||||||
def full_cql_version(ver):
|
|
||||||
while ver.count('.') < 2:
|
|
||||||
ver += '.0'
|
|
||||||
ver_parts = ver.split('-', 1) + ['']
|
|
||||||
vertuple = tuple(list(map(int, ver_parts[0].split('.'))) + [ver_parts[1]])
|
|
||||||
return ver, vertuple
|
|
||||||
|
|
||||||
|
|
||||||
def format_value(val, cqltype, encoding, addcolor=False, date_time_format=None,
|
def format_value(val, cqltype, encoding, addcolor=False, date_time_format=None,
|
||||||
float_precision=None, colormap=None, nullval=None):
|
float_precision=None, colormap=None, nullval=None):
|
||||||
if isinstance(val, DecodeError):
|
if isinstance(val, DecodeError):
|
||||||
|
|
@ -412,7 +399,7 @@ class Shell(cmd.Cmd):
|
||||||
self.session.row_factory = ordered_dict_factory
|
self.session.row_factory = ordered_dict_factory
|
||||||
self.session.default_consistency_level = cassandra.ConsistencyLevel.ONE
|
self.session.default_consistency_level = cassandra.ConsistencyLevel.ONE
|
||||||
self.get_connection_versions()
|
self.get_connection_versions()
|
||||||
self.set_expanded_cql_version(self.connection_versions['cql'])
|
self.set_cql_version(self.connection_versions['cql'])
|
||||||
|
|
||||||
self.current_keyspace = keyspace
|
self.current_keyspace = keyspace
|
||||||
|
|
||||||
|
|
@ -450,6 +437,13 @@ class Shell(cmd.Cmd):
|
||||||
self.single_statement = single_statement
|
self.single_statement = single_statement
|
||||||
self.is_subshell = is_subshell
|
self.is_subshell = is_subshell
|
||||||
|
|
||||||
|
self.cql_version = None
|
||||||
|
self.cql_version_str = None
|
||||||
|
|
||||||
|
# configure length of history shown
|
||||||
|
self.max_history_length_shown = 50
|
||||||
|
self.lastcmd = ""
|
||||||
|
|
||||||
def check_build_versions(self):
|
def check_build_versions(self):
|
||||||
baseversion = self.connection_versions['build']
|
baseversion = self.connection_versions['build']
|
||||||
extra = baseversion.rfind('-')
|
extra = baseversion.rfind('-')
|
||||||
|
|
@ -462,13 +456,12 @@ class Shell(cmd.Cmd):
|
||||||
def batch_mode(self):
|
def batch_mode(self):
|
||||||
return not self.tty
|
return not self.tty
|
||||||
|
|
||||||
def set_expanded_cql_version(self, ver):
|
def set_cql_version(self, ver):
|
||||||
ver, vertuple = full_cql_version(ver)
|
v = list(map(int, (ver.split("."))))
|
||||||
self.cql_version = ver
|
while (len(v) < 3):
|
||||||
self.cql_ver_tuple = vertuple
|
v.append(0)
|
||||||
|
self.cql_version = tuple(v)
|
||||||
def cqlver_atleast(self, major, minor=0, patch=0):
|
self.cql_version_str = ".".join(map(str, v))
|
||||||
return self.cql_ver_tuple[:3] >= (major, minor, patch)
|
|
||||||
|
|
||||||
def myformat_value(self, val, cqltype=None, **kwargs):
|
def myformat_value(self, val, cqltype=None, **kwargs):
|
||||||
if isinstance(val, DecodeError):
|
if isinstance(val, DecodeError):
|
||||||
|
|
@ -510,12 +503,8 @@ class Shell(cmd.Cmd):
|
||||||
self.port))
|
self.port))
|
||||||
|
|
||||||
def show_version(self):
|
def show_version(self):
|
||||||
vers = self.connection_versions.copy()
|
vers = self.connection_versions
|
||||||
vers['shver'] = version
|
print(f"[cqlsh {version} | Cassandra {vers['build']} | CQL spec {self.cql_version_str} | Native protocol v{vers['protocol']}]")
|
||||||
# system.Versions['cql'] apparently does not reflect changes with
|
|
||||||
# set_cql_version.
|
|
||||||
vers['cql'] = self.cql_version
|
|
||||||
print("[cqlsh %(shver)s | Cassandra %(build)s | CQL spec %(cql)s | Native protocol v%(protocol)s]" % vers)
|
|
||||||
|
|
||||||
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)
|
||||||
|
|
@ -1321,7 +1310,7 @@ class Shell(cmd.Cmd):
|
||||||
|
|
||||||
def describe_list(self, rows):
|
def describe_list(self, rows):
|
||||||
"""
|
"""
|
||||||
Print the output for all the DESCRIBE queries for element names (e.g DESCRIBE TABLES, DESCRIBE FUNCTIONS ...)
|
Print the output for all the DESCRIBE queries for element names (e.g. DESCRIBE TABLES, DESCRIBE FUNCTIONS ...)
|
||||||
"""
|
"""
|
||||||
keyspace = None
|
keyspace = None
|
||||||
names = list()
|
names = list()
|
||||||
|
|
@ -1348,7 +1337,7 @@ class Shell(cmd.Cmd):
|
||||||
|
|
||||||
def describe_element(self, rows):
|
def describe_element(self, rows):
|
||||||
"""
|
"""
|
||||||
Print the output for all the DESCRIBE queries where an element name as been specified (e.g DESCRIBE TABLE, DESCRIBE INDEX ...)
|
Print the output for all the DESCRIBE queries where an element name as been specified (e.g. DESCRIBE TABLE, DESCRIBE INDEX ...)
|
||||||
"""
|
"""
|
||||||
for row in rows:
|
for row in rows:
|
||||||
print('')
|
print('')
|
||||||
|
|
@ -1359,7 +1348,7 @@ class Shell(cmd.Cmd):
|
||||||
"""
|
"""
|
||||||
Print the output for a DESCRIBE CLUSTER query.
|
Print the output for a DESCRIBE CLUSTER query.
|
||||||
|
|
||||||
If a specified keyspace was in use the returned ResultSet will contains a 'range_ownership' column,
|
If a specified keyspace was in use the returned ResultSet will contain a 'range_ownership' column,
|
||||||
otherwise not.
|
otherwise not.
|
||||||
"""
|
"""
|
||||||
for row in rows:
|
for row in rows:
|
||||||
|
|
@ -1957,9 +1946,6 @@ class Shell(cmd.Cmd):
|
||||||
delims += '.'
|
delims += '.'
|
||||||
readline.set_completer_delims(delims)
|
readline.set_completer_delims(delims)
|
||||||
|
|
||||||
# configure length of history shown
|
|
||||||
self.max_history_length_shown = 50
|
|
||||||
|
|
||||||
def save_history(self):
|
def save_history(self):
|
||||||
if readline is not None:
|
if readline is not None:
|
||||||
try:
|
try:
|
||||||
|
|
@ -2057,8 +2043,7 @@ def should_use_color():
|
||||||
if int(stdout.strip()) < 8:
|
if int(stdout.strip()) < 8:
|
||||||
return False
|
return False
|
||||||
except (OSError, ImportError, ValueError):
|
except (OSError, ImportError, ValueError):
|
||||||
# oh well, we tried. at least we know there's a $TERM and it's
|
# at least it's a $TERM, and it's not "dumb".
|
||||||
# not "dumb".
|
|
||||||
pass
|
pass
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
@ -2100,7 +2085,6 @@ def read_options(cmdlineargs, environment=os.environ):
|
||||||
DEFAULT_FLOAT_PRECISION)
|
DEFAULT_FLOAT_PRECISION)
|
||||||
argvalues.double_precision = option_with_default(configs.getint, 'ui', 'double_precision',
|
argvalues.double_precision = option_with_default(configs.getint, 'ui', 'double_precision',
|
||||||
DEFAULT_DOUBLE_PRECISION)
|
DEFAULT_DOUBLE_PRECISION)
|
||||||
argvalues.field_size_limit = option_with_default(configs.getint, 'csv', 'field_size_limit', csv.field_size_limit())
|
|
||||||
argvalues.max_trace_wait = option_with_default(configs.getfloat, 'tracing', 'max_trace_wait',
|
argvalues.max_trace_wait = option_with_default(configs.getfloat, 'tracing', 'max_trace_wait',
|
||||||
DEFAULT_MAX_TRACE_WAIT)
|
DEFAULT_MAX_TRACE_WAIT)
|
||||||
argvalues.timezone = option_with_default(configs.get, 'ui', 'timezone', None)
|
argvalues.timezone = option_with_default(configs.get, 'ui', 'timezone', None)
|
||||||
|
|
@ -2166,15 +2150,12 @@ def read_options(cmdlineargs, environment=os.environ):
|
||||||
print("\nWarning: Using a password on the command line interface can be insecure."
|
print("\nWarning: Using a password on the command line interface can be insecure."
|
||||||
"\nRecommendation: use the credentials file to securely provide the password.\n", file=sys.stderr)
|
"\nRecommendation: use the credentials file to securely provide the password.\n", file=sys.stderr)
|
||||||
|
|
||||||
# Make sure some user values read from the command line are in unicode
|
|
||||||
options.execute = maybe_ensure_text(options.execute)
|
|
||||||
options.username = maybe_ensure_text(options.username)
|
|
||||||
options.password = maybe_ensure_text(options.password)
|
|
||||||
options.keyspace = maybe_ensure_text(options.keyspace)
|
|
||||||
|
|
||||||
hostname = option_with_default(configs.get, 'connection', 'hostname', DEFAULT_HOST)
|
hostname = option_with_default(configs.get, 'connection', 'hostname', DEFAULT_HOST)
|
||||||
port = option_with_default(configs.get, 'connection', 'port', DEFAULT_PORT)
|
port = option_with_default(configs.get, 'connection', 'port', DEFAULT_PORT)
|
||||||
|
|
||||||
|
hostname = environment.get('CQLSH_HOST', hostname)
|
||||||
|
port = environment.get('CQLSH_PORT', port)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
options.connect_timeout = int(options.connect_timeout)
|
options.connect_timeout = int(options.connect_timeout)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
|
@ -2187,9 +2168,6 @@ def read_options(cmdlineargs, environment=os.environ):
|
||||||
parser.error('"%s" is not a valid request timeout.' % (options.request_timeout,))
|
parser.error('"%s" is not a valid request timeout.' % (options.request_timeout,))
|
||||||
options.request_timeout = DEFAULT_REQUEST_TIMEOUT_SECONDS
|
options.request_timeout = DEFAULT_REQUEST_TIMEOUT_SECONDS
|
||||||
|
|
||||||
hostname = environment.get('CQLSH_HOST', hostname)
|
|
||||||
port = environment.get('CQLSH_PORT', port)
|
|
||||||
|
|
||||||
if len(arguments) > 0:
|
if len(arguments) > 0:
|
||||||
hostname = arguments[0]
|
hostname = arguments[0]
|
||||||
if len(arguments) > 1:
|
if len(arguments) > 1:
|
||||||
|
|
@ -2209,12 +2187,6 @@ def read_options(cmdlineargs, environment=os.environ):
|
||||||
else:
|
else:
|
||||||
options.color = should_use_color()
|
options.color = should_use_color()
|
||||||
|
|
||||||
if options.cqlversion is not None:
|
|
||||||
options.cqlversion, cqlvertup = full_cql_version(options.cqlversion)
|
|
||||||
if cqlvertup[0] < 3:
|
|
||||||
parser.error('%r is not a supported CQL version.' % options.cqlversion)
|
|
||||||
options.cqlmodule = cql3handling
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
port = int(port)
|
port = int(port)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
|
@ -2222,9 +2194,9 @@ def read_options(cmdlineargs, environment=os.environ):
|
||||||
return options, hostname, port
|
return options, hostname, port
|
||||||
|
|
||||||
|
|
||||||
def setup_cqlruleset(cqlmodule):
|
def setup_cqlruleset():
|
||||||
global cqlruleset
|
global cqlruleset
|
||||||
cqlruleset = cqlmodule.CqlRuleSet
|
cqlruleset = cql3handling.CqlRuleSet
|
||||||
cqlruleset.append_rules(cqlshhandling.cqlsh_extra_syntax_rules)
|
cqlruleset.append_rules(cqlshhandling.cqlsh_extra_syntax_rules)
|
||||||
for rulename, termname, func in cqlshhandling.cqlsh_syntax_completers:
|
for rulename, termname, func in cqlshhandling.cqlsh_syntax_completers:
|
||||||
cqlruleset.completer_for(rulename, termname)(func)
|
cqlruleset.completer_for(rulename, termname)(func)
|
||||||
|
|
@ -2253,7 +2225,7 @@ def insert_driver_hooks():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Display milliseconds when datetime overflows (CASSANDRA-10625), E.g., the year 10000.
|
# Display milliseconds when datetime overflows (CASSANDRA-10625), E.g., the year 10000.
|
||||||
# Native datetime types blow up outside of datetime.[MIN|MAX]_YEAR. We will fall back to an int timestamp
|
# Native datetime types blow up outside datetime.[MIN|MAX]_YEAR. We will fall back to an int timestamp
|
||||||
def deserialize_date_fallback_int(byts, protocol_version):
|
def deserialize_date_fallback_int(byts, protocol_version):
|
||||||
timestamp_ms = int64_unpack(byts)
|
timestamp_ms = int64_unpack(byts)
|
||||||
try:
|
try:
|
||||||
|
|
@ -2277,8 +2249,7 @@ def main(cmdline, pkgpath):
|
||||||
(options, hostname, port) = read_options(cmdline)
|
(options, hostname, port) = read_options(cmdline)
|
||||||
|
|
||||||
setup_docspath(pkgpath)
|
setup_docspath(pkgpath)
|
||||||
setup_cqlruleset(options.cqlmodule)
|
setup_cqlruleset()
|
||||||
csv.field_size_limit(options.field_size_limit)
|
|
||||||
|
|
||||||
if options.file is None:
|
if options.file is None:
|
||||||
stdin = None
|
stdin = None
|
||||||
|
|
@ -2331,7 +2302,7 @@ def main(cmdline, pkgpath):
|
||||||
except ImportError:
|
except ImportError:
|
||||||
sys.stderr.write("Warning: Timezone defined and 'pytz' module for timezone conversion not installed. Timestamps will be displayed in UTC timezone.\n\n")
|
sys.stderr.write("Warning: Timezone defined and 'pytz' module for timezone conversion not installed. Timestamps will be displayed in UTC timezone.\n\n")
|
||||||
|
|
||||||
# try auto-detect timezone if tzlocal is installed
|
# try to auto-detect timezone if tzlocal is installed
|
||||||
if not timezone:
|
if not timezone:
|
||||||
try:
|
try:
|
||||||
from tzlocal import get_localzone
|
from tzlocal import get_localzone
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,9 @@ from collections import defaultdict
|
||||||
from cassandra.cqltypes import EMPTY
|
from cassandra.cqltypes import EMPTY
|
||||||
from cassandra.util import datetime_from_timestamp
|
from cassandra.util import datetime_from_timestamp
|
||||||
from .displaying import colorme, get_str, FormattedValue, DEFAULT_VALUE_COLORS, NO_COLOR_MAP
|
from .displaying import colorme, get_str, FormattedValue, DEFAULT_VALUE_COLORS, NO_COLOR_MAP
|
||||||
from .util import UTC
|
|
||||||
|
|
||||||
unicode_controlchars_re = re.compile(r'[\x00-\x1f\x7f-\xa0]')
|
UNICODE_CONTROLCHARS_RE = re.compile(r'[\x00-\x1f\x7f-\xa0]')
|
||||||
controlchars_re = re.compile(r'[\x00-\x1f\x7f-\xff]')
|
CONTROLCHARS_RE = re.compile(r'[\x00-\x1f\x7f-\xff]')
|
||||||
|
|
||||||
|
|
||||||
def _show_control_chars(match):
|
def _show_control_chars(match):
|
||||||
|
|
@ -84,7 +83,7 @@ def format_by_type(val, cqltype, encoding, colormap=None, addcolor=False,
|
||||||
def color_text(bval, colormap, displaywidth=None):
|
def color_text(bval, colormap, displaywidth=None):
|
||||||
# note that here, we render natural backslashes as just backslashes,
|
# note that here, we render natural backslashes as just backslashes,
|
||||||
# in the same color as surrounding text, when using color. When not
|
# in the same color as surrounding text, when using color. When not
|
||||||
# using color, we need to double up the backslashes so it's not
|
# using color, we need to double up the backslashes, so it's not
|
||||||
# ambiguous. This introduces the unique difficulty of having different
|
# ambiguous. This introduces the unique difficulty of having different
|
||||||
# display widths for the colored and non-colored versions. To avoid
|
# display widths for the colored and non-colored versions. To avoid
|
||||||
# adding the smarts to handle that in to FormattedValue, we just
|
# adding the smarts to handle that in to FormattedValue, we just
|
||||||
|
|
@ -121,7 +120,7 @@ class DateTimeFormat:
|
||||||
class CqlType:
|
class CqlType:
|
||||||
"""
|
"""
|
||||||
A class for converting a string into a cql type name that can match a formatter
|
A class for converting a string into a cql type name that can match a formatter
|
||||||
and a list of its sub-types, if any.
|
and a list of its subtypes, if any.
|
||||||
"""
|
"""
|
||||||
pattern = re.compile('^([^<]*)<(.*)>$') # *<*>
|
pattern = re.compile('^([^<]*)<(.*)>$') # *<*>
|
||||||
|
|
||||||
|
|
@ -135,8 +134,8 @@ class CqlType:
|
||||||
|
|
||||||
def get_n_sub_types(self, num):
|
def get_n_sub_types(self, num):
|
||||||
"""
|
"""
|
||||||
Return the sub-types if the requested number matches the length of the sub-types (tuples)
|
Return the subtypes if the requested number matches the length of the subtypes (tuples)
|
||||||
or the first sub-type times the number requested if the length of the sub-types is one (list, set),
|
or the first subtype times the number requested if the length of the subtypes is one (list, set),
|
||||||
otherwise raise an exception
|
otherwise raise an exception
|
||||||
"""
|
"""
|
||||||
if len(self.sub_types) == num:
|
if len(self.sub_types) == num:
|
||||||
|
|
@ -202,7 +201,7 @@ class CqlType:
|
||||||
def format_value_default(val, colormap, **_):
|
def format_value_default(val, colormap, **_):
|
||||||
val = str(val)
|
val = str(val)
|
||||||
escapedval = val.replace('\\', '\\\\')
|
escapedval = val.replace('\\', '\\\\')
|
||||||
bval = controlchars_re.sub(_show_control_chars, escapedval)
|
bval = CONTROLCHARS_RE.sub(_show_control_chars, escapedval)
|
||||||
return bval if colormap is NO_COLOR_MAP else color_text(bval, colormap)
|
return bval if colormap is NO_COLOR_MAP else color_text(bval, colormap)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -359,7 +358,7 @@ formatter_for('timestamp')(format_value_timestamp)
|
||||||
|
|
||||||
def strftime(time_format, seconds, microseconds=0, timezone=None):
|
def strftime(time_format, seconds, microseconds=0, timezone=None):
|
||||||
ret_dt = datetime_from_timestamp(seconds) + datetime.timedelta(microseconds=microseconds)
|
ret_dt = datetime_from_timestamp(seconds) + datetime.timedelta(microseconds=microseconds)
|
||||||
ret_dt = ret_dt.replace(tzinfo=UTC())
|
ret_dt = ret_dt.replace(tzinfo=datetime.timezone.utc)
|
||||||
if timezone:
|
if timezone:
|
||||||
ret_dt = ret_dt.astimezone(timezone)
|
ret_dt = ret_dt.astimezone(timezone)
|
||||||
try:
|
try:
|
||||||
|
|
@ -475,7 +474,7 @@ def format_value_text(val, encoding, colormap, quote=False, **_):
|
||||||
escapedval = val.replace('\\', '\\\\')
|
escapedval = val.replace('\\', '\\\\')
|
||||||
if quote:
|
if quote:
|
||||||
escapedval = escapedval.replace("'", "''")
|
escapedval = escapedval.replace("'", "''")
|
||||||
escapedval = unicode_controlchars_re.sub(_show_control_chars, escapedval)
|
escapedval = UNICODE_CONTROLCHARS_RE.sub(_show_control_chars, escapedval)
|
||||||
bval = escapedval
|
bval = escapedval
|
||||||
if quote:
|
if quote:
|
||||||
bval = "'{}'".format(bval)
|
bval = "'{}'".format(bval)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import os
|
||||||
|
|
||||||
from .basecase import BaseTestCase
|
from .basecase import BaseTestCase
|
||||||
from .cassconnect import (get_cassandra_connection, create_keyspace, remove_db, testrun_cqlsh)
|
from .cassconnect import (get_cassandra_connection, create_keyspace, remove_db, testrun_cqlsh)
|
||||||
from cqlshlib.formatting import unicode_controlchars_re
|
from cqlshlib.formatting import UNICODE_CONTROLCHARS_RE
|
||||||
|
|
||||||
|
|
||||||
class TestCqlshUnicode(BaseTestCase):
|
class TestCqlshUnicode(BaseTestCase):
|
||||||
|
|
@ -77,4 +77,4 @@ class TestCqlshUnicode(BaseTestCase):
|
||||||
self.assertIn(v2, output)
|
self.assertIn(v2, output)
|
||||||
|
|
||||||
def test_unicode_esc(self): # CASSANDRA-17617
|
def test_unicode_esc(self): # CASSANDRA-17617
|
||||||
self.assertFalse(unicode_controlchars_re.match("01"))
|
self.assertFalse(UNICODE_CONTROLCHARS_RE.match("01"))
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ import os
|
||||||
import errno
|
import errno
|
||||||
import stat
|
import stat
|
||||||
|
|
||||||
from datetime import timedelta, tzinfo
|
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
@ -31,21 +30,6 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
HAS_LINE_PROFILER = False
|
HAS_LINE_PROFILER = False
|
||||||
|
|
||||||
ZERO = timedelta(0)
|
|
||||||
|
|
||||||
|
|
||||||
class UTC(tzinfo):
|
|
||||||
"""UTC"""
|
|
||||||
|
|
||||||
def utcoffset(self, dt):
|
|
||||||
return ZERO
|
|
||||||
|
|
||||||
def tzname(self, dt):
|
|
||||||
return "UTC"
|
|
||||||
|
|
||||||
def dst(self, dt):
|
|
||||||
return ZERO
|
|
||||||
|
|
||||||
|
|
||||||
def split_list(items, pred):
|
def split_list(items, pred):
|
||||||
"""
|
"""
|
||||||
|
|
@ -108,12 +92,6 @@ def identity(x):
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
|
||||||
def trim_if_present(s, prefix):
|
|
||||||
if s.startswith(prefix):
|
|
||||||
return s[len(prefix):]
|
|
||||||
return s
|
|
||||||
|
|
||||||
|
|
||||||
def is_file_secure(filename):
|
def is_file_secure(filename):
|
||||||
try:
|
try:
|
||||||
st = os.stat(filename)
|
st = os.stat(filename)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue