summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml3
-rw-r--r--CHANGELOG5
-rw-r--r--README.rst9
-rw-r--r--docs/source/conf.py2
-rw-r--r--docs/source/intro.rst2
-rw-r--r--examples/column_defs_lowlevel.py1
-rw-r--r--examples/extract_table_names.py6
-rw-r--r--setup.cfg8
-rw-r--r--setup.py9
-rw-r--r--sqlparse/__init__.py6
-rw-r--r--sqlparse/__main__.py1
-rwxr-xr-xsqlparse/cli.py40
-rw-r--r--sqlparse/compat.py45
-rw-r--r--sqlparse/engine/__init__.py1
-rw-r--r--sqlparse/engine/filter_stack.py3
-rw-r--r--sqlparse/engine/grouping.py1
-rw-r--r--sqlparse/engine/statement_splitter.py3
-rw-r--r--sqlparse/exceptions.py1
-rw-r--r--sqlparse/filters/__init__.py1
-rw-r--r--sqlparse/filters/aligned_indent.py11
-rw-r--r--sqlparse/filters/others.py9
-rw-r--r--sqlparse/filters/output.py8
-rw-r--r--sqlparse/filters/reindent.py10
-rw-r--r--sqlparse/filters/right_margin.py8
-rw-r--r--sqlparse/filters/tokens.py8
-rw-r--r--sqlparse/formatter.py27
-rw-r--r--sqlparse/keywords.py1
-rw-r--r--sqlparse/lexer.py12
-rw-r--r--sqlparse/sql.py34
-rw-r--r--sqlparse/tokens.py1
-rw-r--r--sqlparse/utils.py4
-rw-r--r--tests/conftest.py6
-rw-r--r--tests/test_cli.py83
-rw-r--r--tests/test_format.py14
-rw-r--r--tests/test_grouping.py6
-rw-r--r--tests/test_keywords.py1
-rw-r--r--tests/test_parse.py16
-rw-r--r--tests/test_regressions.py31
-rw-r--r--tests/test_split.py18
-rw-r--r--tests/test_tokenize.py6
-rw-r--r--tox.ini7
41 files changed, 160 insertions, 308 deletions
diff --git a/.travis.yml b/.travis.yml
index cbf7bf9..9f8fb77 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,13 +1,10 @@
language: python
python:
- - "2.7"
- - "3.4"
- "3.5"
- "3.6"
- "3.7"
- "3.8"
- "nightly"
- - "pypy"
- "pypy3"
matrix:
diff --git a/CHANGELOG b/CHANGELOG
index 0382f9a..08121b2 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,7 +1,10 @@
Development Version
-------------------
-Nothing yet. ¯\_(ツ)_/¯
+Notable Changes
+
+* Remove support for end-of-life Python 2.7 and 3.4. Python 3.5+ is now
+ required.
Release 0.3.1 (Feb 29, 2020)
diff --git a/README.rst b/README.rst
index 2e38ebc..199b2b2 100644
--- a/README.rst
+++ b/README.rst
@@ -9,13 +9,8 @@ python-sqlparse - Parse SQL statements
sqlparse is a non-validating SQL parser for Python.
It provides support for parsing, splitting and formatting SQL statements.
-The module is compatible with Python 2.7 and Python 3 (>= 3.4)
-and released under the terms of the `New BSD license
-<https://opensource.org/licenses/BSD-3-Clause>`_.
-
-.. note::
-
- Support for Python<3.4 (including 2.x) will be dropped soon.
+The module is compatible with Python 3.5+ and released under the terms of the
+`New BSD license <https://opensource.org/licenses/BSD-3-Clause>`_.
Visit the project page at https://github.com/andialbrecht/sqlparse for
further information about this project.
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 70bd69a..a5be640 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
# python-sqlparse documentation build configuration file, created by
# sphinx-quickstart on Thu Feb 26 08:19:28 2009.
#
diff --git a/docs/source/intro.rst b/docs/source/intro.rst
index 330184a..41e4d23 100644
--- a/docs/source/intro.rst
+++ b/docs/source/intro.rst
@@ -120,7 +120,7 @@ To check out the latest sources of this module run
to check out the latest sources from the repository.
-:mod:`sqlparse` is currently tested under Python 2.7, >=3.4 and pypy. Tests are
+:mod:`sqlparse` is currently tested under Python 3.5+ and pypy. Tests are
automatically run on each commit and for each pull request on Travis:
https://travis-ci.org/andialbrecht/sqlparse
diff --git a/examples/column_defs_lowlevel.py b/examples/column_defs_lowlevel.py
index 6bd5072..2c5f3b8 100644
--- a/examples/column_defs_lowlevel.py
+++ b/examples/column_defs_lowlevel.py
@@ -1,5 +1,4 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
diff --git a/examples/extract_table_names.py b/examples/extract_table_names.py
index 8f0065e..4f6b4b0 100644
--- a/examples/extract_table_names.py
+++ b/examples/extract_table_names.py
@@ -1,5 +1,4 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
@@ -32,8 +31,7 @@ def extract_from_part(parsed):
for item in parsed.tokens:
if from_seen:
if is_subselect(item):
- for x in extract_from_part(item):
- yield x
+ yield from extract_from_part(item)
elif item.ttype is Keyword:
return
else:
@@ -67,4 +65,4 @@ if __name__ == '__main__':
"""
tables = ', '.join(extract_tables(sql))
- print('Tables: {0}'.format(tables))
+ print('Tables: {}'.format(tables))
diff --git a/setup.cfg b/setup.cfg
index 2ed296b..f3ddfa4 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,15 +1,7 @@
-[bdist_wheel]
-universal = 1
-
-[metadata]
-license_file = LICENSE
-
[tool:pytest]
xfail_strict = True
[flake8]
-exclude =
- sqlparse/compat.py
extend-ignore =
E731
diff --git a/setup.py b/setup.py
index 3de94e7..c23968b 100644
--- a/setup.py
+++ b/setup.py
@@ -1,5 +1,4 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
@@ -84,21 +83,21 @@ setup(
description='Non-validating SQL parser',
long_description=LONG_DESCRIPTION,
license='BSD',
- python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
+ python_requires=">=3.5",
classifiers=[
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Programming Language :: Python',
- 'Programming Language :: Python :: 2',
- 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.4',
+ 'Programming Language :: Python :: 3 :: Only',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Database',
'Topic :: Software Development',
],
diff --git a/sqlparse/__init__.py b/sqlparse/__init__.py
index b475061..5dcd982 100644
--- a/sqlparse/__init__.py
+++ b/sqlparse/__init__.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
@@ -16,7 +15,6 @@ from sqlparse import tokens
from sqlparse import filters
from sqlparse import formatter
-from sqlparse.compat import text_type
__version__ = '0.3.2.dev0'
__all__ = ['engine', 'filters', 'formatter', 'sql', 'tokens', 'cli']
@@ -58,7 +56,7 @@ def format(sql, encoding=None, **options):
options = formatter.validate_options(options)
stack = formatter.build_filter_stack(stack, options)
stack.postprocess.append(filters.SerializerUnicode())
- return u''.join(stack.run(sql, encoding))
+ return ''.join(stack.run(sql, encoding))
def split(sql, encoding=None):
@@ -69,4 +67,4 @@ def split(sql, encoding=None):
:returns: A list of strings.
"""
stack = engine.FilterStack()
- return [text_type(stmt).strip() for stmt in stack.run(sql, encoding)]
+ return [str(stmt).strip() for stmt in stack.run(sql, encoding)]
diff --git a/sqlparse/__main__.py b/sqlparse/__main__.py
index 867d75d..3e6d325 100644
--- a/sqlparse/__main__.py
+++ b/sqlparse/__main__.py
@@ -1,5 +1,4 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
diff --git a/sqlparse/cli.py b/sqlparse/cli.py
index 25555a5..957d220 100755
--- a/sqlparse/cli.py
+++ b/sqlparse/cli.py
@@ -1,5 +1,4 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
@@ -23,10 +22,8 @@ Why does this file exist, and why not put this in __main__?
import argparse
import sys
from io import TextIOWrapper
-from codecs import open, getreader
import sqlparse
-from sqlparse.compat import PY2
from sqlparse.exceptions import SQLParseError
@@ -62,16 +59,16 @@ def create_parser():
metavar='CHOICE',
dest='keyword_case',
choices=_CASE_CHOICES,
- help='change case of keywords, CHOICE is one of {0}'.format(
- ', '.join('"{0}"'.format(x) for x in _CASE_CHOICES)))
+ help='change case of keywords, CHOICE is one of {}'.format(
+ ', '.join('"{}"'.format(x) for x in _CASE_CHOICES)))
group.add_argument(
'-i', '--identifiers',
metavar='CHOICE',
dest='identifier_case',
choices=_CASE_CHOICES,
- help='change case of identifiers, CHOICE is one of {0}'.format(
- ', '.join('"{0}"'.format(x) for x in _CASE_CHOICES)))
+ help='change case of identifiers, CHOICE is one of {}'.format(
+ ', '.join('"{}"'.format(x) for x in _CASE_CHOICES)))
group.add_argument(
'-l', '--language',
@@ -153,7 +150,7 @@ def create_parser():
def _error(msg):
"""Print msg and optionally exit with return code exit_."""
- sys.stderr.write(u'[ERROR] {0}\n'.format(msg))
+ sys.stderr.write('[ERROR] {}\n'.format(msg))
return 1
@@ -162,29 +159,26 @@ def main(args=None):
args = parser.parse_args(args)
if args.filename == '-': # read from stdin
- if PY2:
- data = getreader(args.encoding)(sys.stdin).read()
- else:
- wrapper = TextIOWrapper(sys.stdin.buffer, encoding=args.encoding)
- try:
- data = wrapper.read()
- finally:
- wrapper.detach()
+ wrapper = TextIOWrapper(sys.stdin.buffer, encoding=args.encoding)
+ try:
+ data = wrapper.read()
+ finally:
+ wrapper.detach()
else:
try:
- with open(args.filename, 'r', args.encoding) as f:
+ with open(args.filename, encoding=args.encoding) as f:
data = ''.join(f.readlines())
- except IOError as e:
+ except OSError as e:
return _error(
- u'Failed to read {0}: {1}'.format(args.filename, e))
+ 'Failed to read {}: {}'.format(args.filename, e))
close_stream = False
if args.outfile:
try:
- stream = open(args.outfile, 'w', args.encoding)
+ stream = open(args.outfile, 'w', encoding=args.encoding)
close_stream = True
- except IOError as e:
- return _error(u'Failed to open {0}: {1}'.format(args.outfile, e))
+ except OSError as e:
+ return _error('Failed to open {}: {}'.format(args.outfile, e))
else:
stream = sys.stdout
@@ -192,7 +186,7 @@ def main(args=None):
try:
formatter_opts = sqlparse.formatter.validate_options(formatter_opts)
except SQLParseError as e:
- return _error(u'Invalid options: {0}'.format(e))
+ return _error('Invalid options: {}'.format(e))
s = sqlparse.format(data, **formatter_opts)
stream.write(s)
diff --git a/sqlparse/compat.py b/sqlparse/compat.py
deleted file mode 100644
index d2214be..0000000
--- a/sqlparse/compat.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright (C) 2009-2018 the sqlparse authors and contributors
-# <see AUTHORS file>
-#
-# This module is part of python-sqlparse and is released under
-# the BSD License: https://opensource.org/licenses/BSD-3-Clause
-
-"""Python 2/3 compatibility.
-
-This module only exists to avoid a dependency on six
-for very trivial stuff. We only need to take care of
-string types, buffers and metaclasses.
-
-Parts of the code is copied directly from six:
-https://bitbucket.org/gutworth/six
-"""
-
-import sys
-from io import TextIOBase
-
-PY2 = sys.version_info[0] == 2
-PY3 = sys.version_info[0] == 3
-
-
-if PY3:
- def unicode_compatible(cls):
- return cls
-
- text_type = str
- string_types = (str,)
- from io import StringIO
- file_types = (StringIO, TextIOBase)
-
-
-elif PY2:
- def unicode_compatible(cls):
- cls.__unicode__ = cls.__str__
- cls.__str__ = lambda x: x.__unicode__().encode('utf-8')
- return cls
-
- text_type = unicode
- string_types = (str, unicode,)
- from StringIO import StringIO
- file_types = (file, StringIO, TextIOBase)
diff --git a/sqlparse/engine/__init__.py b/sqlparse/engine/__init__.py
index 0b3f3eb..67ecc6e 100644
--- a/sqlparse/engine/__init__.py
+++ b/sqlparse/engine/__init__.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
diff --git a/sqlparse/engine/filter_stack.py b/sqlparse/engine/filter_stack.py
index fc77fd6..295c2c1 100644
--- a/sqlparse/engine/filter_stack.py
+++ b/sqlparse/engine/filter_stack.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
@@ -13,7 +12,7 @@ from sqlparse.engine import grouping
from sqlparse.engine.statement_splitter import StatementSplitter
-class FilterStack(object):
+class FilterStack:
def __init__(self):
self.preprocess = []
self.stmtprocess = []
diff --git a/sqlparse/engine/grouping.py b/sqlparse/engine/grouping.py
index e7a4211..e895ce0 100644
--- a/sqlparse/engine/grouping.py
+++ b/sqlparse/engine/grouping.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
diff --git a/sqlparse/engine/statement_splitter.py b/sqlparse/engine/statement_splitter.py
index 1e9af3c..fb22c65 100644
--- a/sqlparse/engine/statement_splitter.py
+++ b/sqlparse/engine/statement_splitter.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
@@ -9,7 +8,7 @@
from sqlparse import sql, tokens as T
-class StatementSplitter(object):
+class StatementSplitter:
"""Filter that split stream at individual statements"""
def __init__(self):
diff --git a/sqlparse/exceptions.py b/sqlparse/exceptions.py
index 01e60f7..687c20c 100644
--- a/sqlparse/exceptions.py
+++ b/sqlparse/exceptions.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
diff --git a/sqlparse/filters/__init__.py b/sqlparse/filters/__init__.py
index c60d84d..ced03ea 100644
--- a/sqlparse/filters/__init__.py
+++ b/sqlparse/filters/__init__.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
diff --git a/sqlparse/filters/aligned_indent.py b/sqlparse/filters/aligned_indent.py
index 85b11e5..445d022 100644
--- a/sqlparse/filters/aligned_indent.py
+++ b/sqlparse/filters/aligned_indent.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
@@ -7,11 +6,10 @@
# the BSD License: https://opensource.org/licenses/BSD-3-Clause
from sqlparse import sql, tokens as T
-from sqlparse.compat import text_type
from sqlparse.utils import offset, indent
-class AlignedIndentFilter(object):
+class AlignedIndentFilter:
join_words = (r'((LEFT\s+|RIGHT\s+|FULL\s+)?'
r'(INNER\s+|OUTER\s+|STRAIGHT\s+)?|'
r'(CROSS\s+|NATURAL\s+)?)?JOIN\b')
@@ -73,7 +71,7 @@ class AlignedIndentFilter(object):
end_token = tlist.token_next_by(m=(T.Keyword, 'END'))[1]
cases.append((None, [end_token]))
- condition_width = [len(' '.join(map(text_type, cond))) if cond else 0
+ condition_width = [len(' '.join(map(str, cond))) if cond else 0
for cond, _ in cases]
max_cond_width = max(condition_width)
@@ -82,8 +80,7 @@ class AlignedIndentFilter(object):
stmt = cond[0] if cond else value[0]
if i > 0:
- tlist.insert_before(stmt, self.nl(
- offset_ - len(text_type(stmt))))
+ tlist.insert_before(stmt, self.nl(offset_ - len(str(stmt))))
if cond:
ws = sql.Token(T.Whitespace, self.char * (
max_cond_width - condition_width[i]))
@@ -110,7 +107,7 @@ class AlignedIndentFilter(object):
):
token_indent = token.value.split()[0]
else:
- token_indent = text_type(token)
+ token_indent = str(token)
tlist.insert_before(token, self.nl(token_indent))
tidx += 1
tidx, token = self._next_token(tlist, tidx)
diff --git a/sqlparse/filters/others.py b/sqlparse/filters/others.py
index 52b8617..ff04b0e 100644
--- a/sqlparse/filters/others.py
+++ b/sqlparse/filters/others.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
@@ -10,7 +9,7 @@ from sqlparse import sql, tokens as T
from sqlparse.utils import split_unquoted_newlines
-class StripCommentsFilter(object):
+class StripCommentsFilter:
@staticmethod
def _process(tlist):
def get_next_comment():
@@ -45,7 +44,7 @@ class StripCommentsFilter(object):
return stmt
-class StripWhitespaceFilter(object):
+class StripWhitespaceFilter:
def _stripws(self, tlist):
func_name = '_stripws_{cls}'.format(cls=type(tlist).__name__)
func = getattr(self, func_name.lower(), self._stripws_default)
@@ -90,7 +89,7 @@ class StripWhitespaceFilter(object):
return stmt
-class SpacesAroundOperatorsFilter(object):
+class SpacesAroundOperatorsFilter:
@staticmethod
def _process(tlist):
@@ -118,7 +117,7 @@ class SpacesAroundOperatorsFilter(object):
# ---------------------------
# postprocess
-class SerializerUnicode(object):
+class SerializerUnicode:
@staticmethod
def process(stmt):
lines = split_unquoted_newlines(stmt)
diff --git a/sqlparse/filters/output.py b/sqlparse/filters/output.py
index 3fbc46d..f34b29f 100644
--- a/sqlparse/filters/output.py
+++ b/sqlparse/filters/output.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
@@ -7,10 +6,9 @@
# the BSD License: https://opensource.org/licenses/BSD-3-Clause
from sqlparse import sql, tokens as T
-from sqlparse.compat import text_type
-class OutputFilter(object):
+class OutputFilter:
varname_prefix = ''
def __init__(self, varname='sql'):
@@ -23,11 +21,11 @@ class OutputFilter(object):
def process(self, stmt):
self.count += 1
if self.count > 1:
- varname = u'{f.varname}{f.count}'.format(f=self)
+ varname = '{f.varname}{f.count}'.format(f=self)
else:
varname = self.varname
- has_nl = len(text_type(stmt).strip().splitlines()) > 1
+ has_nl = len(str(stmt).strip().splitlines()) > 1
stmt.tokens = self._process(stmt.tokens, varname, has_nl)
return stmt
diff --git a/sqlparse/filters/reindent.py b/sqlparse/filters/reindent.py
index acec8ca..2b0f106 100644
--- a/sqlparse/filters/reindent.py
+++ b/sqlparse/filters/reindent.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
@@ -7,11 +6,10 @@
# the BSD License: https://opensource.org/licenses/BSD-3-Clause
from sqlparse import sql, tokens as T
-from sqlparse.compat import text_type
from sqlparse.utils import offset, indent
-class ReindentFilter(object):
+class ReindentFilter:
def __init__(self, width=2, char=' ', wrap_after=0, n='\n',
comma_first=False, indent_after_first=False,
indent_columns=False):
@@ -42,7 +40,7 @@ class ReindentFilter(object):
return self.offset + self.indent * self.width
def _get_offset(self, token):
- raw = u''.join(map(text_type, self._flatten_up_to_token(token)))
+ raw = ''.join(map(str, self._flatten_up_to_token(token)))
line = (raw or '\n').splitlines()[-1]
# Now take current offset into account and return relative offset.
return len(line) - len(self.char * self.leading_ws)
@@ -71,7 +69,7 @@ class ReindentFilter(object):
tidx, token = self._next_token(tlist)
while token:
pidx, prev_ = tlist.token_prev(tidx, skip_ws=False)
- uprev = text_type(prev_)
+ uprev = str(prev_)
if prev_ and prev_.is_whitespace:
del tlist.tokens[pidx]
@@ -234,7 +232,7 @@ class ReindentFilter(object):
self._process(stmt)
if self._last_stmt is not None:
- nl = '\n' if text_type(self._last_stmt).endswith('\n') else '\n\n'
+ nl = '\n' if str(self._last_stmt).endswith('\n') else '\n\n'
stmt.tokens.insert(0, sql.Token(T.Whitespace, nl))
self._last_stmt = stmt
diff --git a/sqlparse/filters/right_margin.py b/sqlparse/filters/right_margin.py
index 1658138..e263718 100644
--- a/sqlparse/filters/right_margin.py
+++ b/sqlparse/filters/right_margin.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
@@ -9,11 +8,10 @@
import re
from sqlparse import sql, tokens as T
-from sqlparse.compat import text_type
# FIXME: Doesn't work
-class RightMarginFilter(object):
+class RightMarginFilter:
keep_together = (
# sql.TypeCast, sql.Identifier, sql.Alias,
)
@@ -32,14 +30,14 @@ class RightMarginFilter(object):
elif token.is_group and type(token) not in self.keep_together:
token.tokens = self._process(token, token.tokens)
else:
- val = text_type(token)
+ val = str(token)
if len(self.line) + len(val) > self.width:
match = re.search(r'^ +', self.line)
if match is not None:
indent = match.group()
else:
indent = ''
- yield sql.Token(T.Whitespace, '\n{0}'.format(indent))
+ yield sql.Token(T.Whitespace, '\n{}'.format(indent))
self.line = indent
self.line += val
yield token
diff --git a/sqlparse/filters/tokens.py b/sqlparse/filters/tokens.py
index 93182b1..a40f4b0 100644
--- a/sqlparse/filters/tokens.py
+++ b/sqlparse/filters/tokens.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
@@ -7,15 +6,14 @@
# the BSD License: https://opensource.org/licenses/BSD-3-Clause
from sqlparse import tokens as T
-from sqlparse.compat import text_type
-class _CaseFilter(object):
+class _CaseFilter:
ttype = None
def __init__(self, case=None):
case = case or 'upper'
- self.convert = getattr(text_type, case)
+ self.convert = getattr(str, case)
def process(self, stream):
for ttype, value in stream:
@@ -38,7 +36,7 @@ class IdentifierCaseFilter(_CaseFilter):
yield ttype, value
-class TruncateStringFilter(object):
+class TruncateStringFilter:
def __init__(self, width, char):
self.width = width
self.char = char
diff --git a/sqlparse/formatter.py b/sqlparse/formatter.py
index 8962759..8016f87 100644
--- a/sqlparse/formatter.py
+++ b/sqlparse/formatter.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
@@ -17,32 +16,32 @@ def validate_options(options):
kwcase = options.get('keyword_case')
if kwcase not in [None, 'upper', 'lower', 'capitalize']:
raise SQLParseError('Invalid value for keyword_case: '
- '{0!r}'.format(kwcase))
+ '{!r}'.format(kwcase))
idcase = options.get('identifier_case')
if idcase not in [None, 'upper', 'lower', 'capitalize']:
raise SQLParseError('Invalid value for identifier_case: '
- '{0!r}'.format(idcase))
+ '{!r}'.format(idcase))
ofrmt = options.get('output_format')
if ofrmt not in [None, 'sql', 'python', 'php']:
raise SQLParseError('Unknown output format: '
- '{0!r}'.format(ofrmt))
+ '{!r}'.format(ofrmt))
strip_comments = options.get('strip_comments', False)
if strip_comments not in [True, False]:
raise SQLParseError('Invalid value for strip_comments: '
- '{0!r}'.format(strip_comments))
+ '{!r}'.format(strip_comments))
space_around_operators = options.get('use_space_around_operators', False)
if space_around_operators not in [True, False]:
raise SQLParseError('Invalid value for use_space_around_operators: '
- '{0!r}'.format(space_around_operators))
+ '{!r}'.format(space_around_operators))
strip_ws = options.get('strip_whitespace', False)
if strip_ws not in [True, False]:
raise SQLParseError('Invalid value for strip_whitespace: '
- '{0!r}'.format(strip_ws))
+ '{!r}'.format(strip_ws))
truncate_strings = options.get('truncate_strings')
if truncate_strings is not None:
@@ -50,17 +49,17 @@ def validate_options(options):
truncate_strings = int(truncate_strings)
except (ValueError, TypeError):
raise SQLParseError('Invalid value for truncate_strings: '
- '{0!r}'.format(truncate_strings))
+ '{!r}'.format(truncate_strings))
if truncate_strings <= 1:
raise SQLParseError('Invalid value for truncate_strings: '
- '{0!r}'.format(truncate_strings))
+ '{!r}'.format(truncate_strings))
options['truncate_strings'] = truncate_strings
options['truncate_char'] = options.get('truncate_char', '[...]')
indent_columns = options.get('indent_columns', False)
if indent_columns not in [True, False]:
raise SQLParseError('Invalid value for indent_columns: '
- '{0!r}'.format(indent_columns))
+ '{!r}'.format(indent_columns))
elif indent_columns:
options['reindent'] = True # enforce reindent
options['indent_columns'] = indent_columns
@@ -68,27 +67,27 @@ def validate_options(options):
reindent = options.get('reindent', False)
if reindent not in [True, False]:
raise SQLParseError('Invalid value for reindent: '
- '{0!r}'.format(reindent))
+ '{!r}'.format(reindent))
elif reindent:
options['strip_whitespace'] = True
reindent_aligned = options.get('reindent_aligned', False)
if reindent_aligned not in [True, False]:
raise SQLParseError('Invalid value for reindent_aligned: '
- '{0!r}'.format(reindent))
+ '{!r}'.format(reindent))
elif reindent_aligned:
options['strip_whitespace'] = True
indent_after_first = options.get('indent_after_first', False)
if indent_after_first not in [True, False]:
raise SQLParseError('Invalid value for indent_after_first: '
- '{0!r}'.format(indent_after_first))
+ '{!r}'.format(indent_after_first))
options['indent_after_first'] = indent_after_first
indent_tabs = options.get('indent_tabs', False)
if indent_tabs not in [True, False]:
raise SQLParseError('Invalid value for indent_tabs: '
- '{0!r}'.format(indent_tabs))
+ '{!r}'.format(indent_tabs))
elif indent_tabs:
options['indent_char'] = '\t'
else:
diff --git a/sqlparse/keywords.py b/sqlparse/keywords.py
index 9c37e50..3123531 100644
--- a/sqlparse/keywords.py
+++ b/sqlparse/keywords.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
diff --git a/sqlparse/lexer.py b/sqlparse/lexer.py
index fd007a4..836d53d 100644
--- a/sqlparse/lexer.py
+++ b/sqlparse/lexer.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
@@ -13,13 +12,14 @@
# It's separated from the rest of pygments to increase performance
# and to allow some customizations.
+from io import TextIOBase
+
from sqlparse import tokens
from sqlparse.keywords import SQL_REGEX
-from sqlparse.compat import text_type, file_types
from sqlparse.utils import consume
-class Lexer(object):
+class Lexer:
"""Lexer
Empty class. Leaving for backwards-compatibility
"""
@@ -38,10 +38,10 @@ class Lexer(object):
``stack`` is the initial stack (default: ``['root']``)
"""
- if isinstance(text, file_types):
+ if isinstance(text, TextIOBase):
text = text.read()
- if isinstance(text, text_type):
+ if isinstance(text, str):
pass
elif isinstance(text, bytes):
if encoding:
@@ -52,7 +52,7 @@ class Lexer(object):
except UnicodeDecodeError:
text = text.decode('unicode-escape')
else:
- raise TypeError(u"Expected text or file-like object, got {!r}".
+ raise TypeError("Expected text or file-like object, got {!r}".
format(type(text)))
iterable = enumerate(text)
diff --git a/sqlparse/sql.py b/sqlparse/sql.py
index a942bcd..a9e11da 100644
--- a/sqlparse/sql.py
+++ b/sqlparse/sql.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
@@ -7,12 +6,10 @@
# the BSD License: https://opensource.org/licenses/BSD-3-Clause
"""This module contains classes representing syntactical elements of SQL."""
-from __future__ import print_function
import re
from sqlparse import tokens as T
-from sqlparse.compat import string_types, text_type, unicode_compatible
from sqlparse.utils import imt, remove_quotes
@@ -39,8 +36,7 @@ class NameAliasMixin:
return self._get_first_name(reverse=True)
-@unicode_compatible
-class Token(object):
+class Token:
"""Base class for all other classes in this module.
It represents a single token and has two instance attributes:
@@ -52,7 +48,7 @@ class Token(object):
'is_group', 'is_whitespace')
def __init__(self, ttype, value):
- value = text_type(value)
+ value = str(value)
self.value = value
self.ttype = ttype
self.parent = None
@@ -72,15 +68,15 @@ class Token(object):
cls = self._get_repr_name()
value = self._get_repr_value()
- q = u'"' if value.startswith("'") and value.endswith("'") else u"'"
- return u"<{cls} {q}{value}{q} at 0x{id:2X}>".format(
+ q = '"' if value.startswith("'") and value.endswith("'") else "'"
+ return "<{cls} {q}{value}{q} at 0x{id:2X}>".format(
id=id(self), **locals())
def _get_repr_name(self):
return str(self.ttype).split('.')[-1]
def _get_repr_value(self):
- raw = text_type(self)
+ raw = str(self)
if len(raw) > 7:
raw = raw[:6] + '...'
return re.sub(r'\s+', ' ', raw)
@@ -105,7 +101,7 @@ class Token(object):
if not type_matched or values is None:
return type_matched
- if isinstance(values, string_types):
+ if isinstance(values, str):
values = (values,)
if regex:
@@ -150,7 +146,6 @@ class Token(object):
return False
-@unicode_compatible
class TokenList(Token):
"""A group of tokens.
@@ -163,11 +158,11 @@ class TokenList(Token):
def __init__(self, tokens=None):
self.tokens = tokens or []
[setattr(token, 'parent', self) for token in self.tokens]
- super(TokenList, self).__init__(None, text_type(self))
+ super().__init__(None, str(self))
self.is_group = True
def __str__(self):
- return u''.join(token.value for token in self.flatten())
+ return ''.join(token.value for token in self.flatten())
# weird bug
# def __len__(self):
@@ -190,14 +185,14 @@ class TokenList(Token):
value = token._get_repr_value()
last = idx == (token_count - 1)
- pre = u'`- ' if last else u'|- '
+ pre = '`- ' if last else '|- '
- q = u'"' if value.startswith("'") and value.endswith("'") else u"'"
- print(u"{_pre}{pre}{idx} {cls} {q}{value}{q}"
+ q = '"' if value.startswith("'") and value.endswith("'") else "'"
+ print("{_pre}{pre}{idx} {cls} {q}{value}{q}"
.format(**locals()), file=f)
if token.is_group and (max_depth is None or depth < max_depth):
- parent_pre = u' ' if last else u'| '
+ parent_pre = ' ' if last else '| '
token._pprint_tree(max_depth, depth + 1, f, _pre + parent_pre)
def get_token_at_offset(self, offset):
@@ -216,8 +211,7 @@ class TokenList(Token):
"""
for token in self.tokens:
if token.is_group:
- for item in token.flatten():
- yield item
+ yield from token.flatten()
else:
yield token
@@ -328,7 +322,7 @@ class TokenList(Token):
grp = start
grp.tokens.extend(subtokens)
del self.tokens[start_idx + 1:end_idx]
- grp.value = text_type(start)
+ grp.value = str(start)
else:
subtokens = self.tokens[start_idx:end_idx]
grp = grp_cls(subtokens)
diff --git a/sqlparse/tokens.py b/sqlparse/tokens.py
index eefc0b4..193d100 100644
--- a/sqlparse/tokens.py
+++ b/sqlparse/tokens.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
diff --git a/sqlparse/utils.py b/sqlparse/utils.py
index 3283274..265378b 100644
--- a/sqlparse/utils.py
+++ b/sqlparse/utils.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2018 the sqlparse authors and contributors
# <see AUTHORS file>
@@ -10,7 +9,6 @@ import itertools
import re
from collections import deque
from contextlib import contextmanager
-from sqlparse.compat import text_type
# This regular expression replaces the home-cooked parser that was here before.
# It is much faster, but requires an extra post-processing step to get the
@@ -40,7 +38,7 @@ def split_unquoted_newlines(stmt):
Unlike str.splitlines(), this will ignore CR/LF/CR+LF if the requisite
character is inside of a string."""
- text = text_type(stmt)
+ text = str(stmt)
lines = SPLIT_REGEX.split(text)
outputlines = ['']
for line in lines:
diff --git a/tests/conftest.py b/tests/conftest.py
index f2473a4..939c481 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
"""Helpers for testing."""
import io
@@ -35,7 +33,7 @@ def load_file(filepath):
# https://stackoverflow.com/questions/18011902/py-test-pass-a-parameter-to-a-fixture-function/33879151#33879151
# Syntax is noisy and requires specific variable names
# And seems to be limited to only 1 argument.
- with io.open(filepath(filename), encoding=encoding) as f:
+ with open(filepath(filename), encoding=encoding) as f:
return f.read().strip()
return make_load_file
@@ -44,6 +42,6 @@ def load_file(filepath):
@pytest.fixture()
def get_stream(filepath):
def make_stream(filename, encoding='utf-8'):
- return io.open(filepath(filename), encoding=encoding)
+ return open(filepath(filename), encoding=encoding)
return make_stream
diff --git a/tests/test_cli.py b/tests/test_cli.py
index 5f1ea0e..f1c005d 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
import subprocess
import sys
@@ -71,75 +69,56 @@ def test_stdout(filepath, load_file, capsys):
def test_script():
# Call with the --help option as a basic sanity check.
- cmd = "{0:s} -m sqlparse.cli --help".format(sys.executable)
+ cmd = "{:s} -m sqlparse.cli --help".format(sys.executable)
assert subprocess.call(cmd.split()) == 0
-def test_encoding_utf8_stdout(filepath, load_file, capfd):
- path = filepath('encoding_utf8.sql')
- expected = load_file('encoding_utf8.sql', 'utf-8')
- sys.stdout.encoding = 'utf-8'
- sqlparse.cli.main([path])
- out, _ = capfd.readouterr()
- assert out == expected
-
-
-def test_encoding_utf8_output_file(filepath, load_file, tmpdir):
- in_path = filepath('encoding_utf8.sql')
- expected = load_file('encoding_utf8.sql', 'utf-8')
- out_path = tmpdir.dirname + '/encoding_utf8.out.sql'
- sqlparse.cli.main([in_path, '-o', out_path])
- out = load_file(out_path, 'utf-8')
- assert out == expected
-
-
-def test_encoding_gbk_stdout(filepath, load_file, capfd):
- path = filepath('encoding_gbk.sql')
- expected = load_file('encoding_gbk.sql', 'gbk')
- sys.stdout.encoding = 'gbk'
- sqlparse.cli.main([path, '--encoding', 'gbk'])
+@pytest.mark.parametrize('fpath, encoding', (
+ ('encoding_utf8.sql', 'utf-8'),
+ ('encoding_gbk.sql', 'gbk'),
+))
+def test_encoding_stdout(fpath, encoding, filepath, load_file, capfd):
+ path = filepath(fpath)
+ expected = load_file(fpath, encoding)
+ sys.stdout.reconfigure(encoding=encoding)
+ sqlparse.cli.main([path, '--encoding', encoding])
out, _ = capfd.readouterr()
assert out == expected
-def test_encoding_gbk_output_file(filepath, load_file, tmpdir):
- in_path = filepath('encoding_gbk.sql')
- expected = load_file('encoding_gbk.sql', 'gbk')
- out_path = tmpdir.dirname + '/encoding_gbk.out.sql'
- sqlparse.cli.main([in_path, '--encoding', 'gbk', '-o', out_path])
- out = load_file(out_path, 'gbk')
+@pytest.mark.parametrize('fpath, encoding', (
+ ('encoding_utf8.sql', 'utf-8'),
+ ('encoding_gbk.sql', 'gbk'),
+))
+def test_encoding_output_file(fpath, encoding, filepath, load_file, tmpdir):
+ in_path = filepath(fpath)
+ expected = load_file(fpath, encoding)
+ out_path = tmpdir.dirname + '/encoding_out.sql'
+ sqlparse.cli.main([in_path, '--encoding', encoding, '-o', out_path])
+ out = load_file(out_path, encoding)
assert out == expected
-def test_encoding_stdin_utf8(filepath, load_file, capfd):
- path = filepath('encoding_utf8.sql')
- expected = load_file('encoding_utf8.sql', 'utf-8')
+@pytest.mark.parametrize('fpath, encoding', (
+ ('encoding_utf8.sql', 'utf-8'),
+ ('encoding_gbk.sql', 'gbk'),
+))
+def test_encoding_stdin(fpath, encoding, filepath, load_file, capfd):
+ path = filepath(fpath)
+ expected = load_file(fpath, encoding)
old_stdin = sys.stdin
- with open(path, 'r') as f:
+ with open(path) as f:
sys.stdin = f
- sys.stdout.encoding = 'utf-8'
- sqlparse.cli.main(['-'])
+ sys.stdout.reconfigure(encoding=encoding)
+ sqlparse.cli.main(['-', '--encoding', encoding])
sys.stdin = old_stdin
out, _ = capfd.readouterr()
assert out == expected
-def test_encoding_stdin_gbk(filepath, load_file, capfd):
- path = filepath('encoding_gbk.sql')
- expected = load_file('encoding_gbk.sql', 'gbk')
- old_stdin = sys.stdin
- with open(path, 'r') as stream:
- sys.stdin = stream
- sys.stdout.encoding = 'gbk'
- sqlparse.cli.main(['-', '--encoding', 'gbk'])
- sys.stdin = old_stdin
- out, _ = capfd.readouterr()
- assert out == expected
-
-
def test_encoding(filepath, capsys):
path = filepath('test_cp1251.sql')
- expected = u'insert into foo values (1); -- Песня про надежду\n'
+ expected = 'insert into foo values (1); -- Песня про надежду\n'
sqlparse.cli.main([path, '--encoding=cp1251'])
out, _ = capsys.readouterr()
assert out == expected
diff --git a/tests/test_format.py b/tests/test_format.py
index 811e083..20390ff 100644
--- a/tests/test_format.py
+++ b/tests/test_format.py
@@ -1,12 +1,10 @@
-# -*- coding: utf-8 -*-
-
import pytest
import sqlparse
from sqlparse.exceptions import SQLParseError
-class TestFormat(object):
+class TestFormat:
def test_keywordcase(self):
sql = 'select * from bar; -- select foo\n'
res = sqlparse.format(sql, keyword_case='upper')
@@ -123,7 +121,7 @@ class TestFormat(object):
== "SELECT some_column LIKE 'value\\\\\\'\r' WHERE id = 1\n")
-class TestFormatReindentAligned(object):
+class TestFormatReindentAligned:
@staticmethod
def formatter(sql):
return sqlparse.format(sql, reindent_aligned=True)
@@ -294,7 +292,7 @@ class TestFormatReindentAligned(object):
' from table'])
-class TestSpacesAroundOperators(object):
+class TestSpacesAroundOperators:
@staticmethod
def formatter(sql):
return sqlparse.format(sql, use_space_around_operators=True)
@@ -321,7 +319,7 @@ class TestSpacesAroundOperators(object):
assert self.formatter(sql) == 'select a * b - c from table'
-class TestFormatReindent(object):
+class TestFormatReindent:
def test_option(self):
with pytest.raises(SQLParseError):
sqlparse.format('foo', reindent=2)
@@ -598,7 +596,7 @@ class TestFormatReindent(object):
' , (5, 6)'])
-class TestOutputFormat(object):
+class TestOutputFormat:
def test_python(self):
sql = 'select * from foo;'
f = lambda sql: sqlparse.format(sql, output_format='python')
@@ -663,7 +661,7 @@ def test_format_column_ordering():
def test_truncate_strings():
- sql = "update foo set value = '{0}';".format('x' * 1000)
+ sql = "update foo set value = '{}';".format('x' * 1000)
formatted = sqlparse.format(sql, truncate_strings=10)
assert formatted == "update foo set value = 'xxxxxxxxxx[...]';"
formatted = sqlparse.format(sql, truncate_strings=3, truncate_char='YYY')
diff --git a/tests/test_grouping.py b/tests/test_grouping.py
index 87dcf11..683954e 100644
--- a/tests/test_grouping.py
+++ b/tests/test_grouping.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
import pytest
import sqlparse
@@ -484,7 +482,7 @@ def test_comparison_with_parenthesis():
))
def test_comparison_with_strings(operator):
# issue148
- p = sqlparse.parse("foo {0} 'bar'".format(operator))[0]
+ p = sqlparse.parse("foo {} 'bar'".format(operator))[0]
assert len(p.tokens) == 1
assert isinstance(p.tokens[0], sql.Comparison)
assert p.tokens[0].right.value == "'bar'"
@@ -563,7 +561,7 @@ def test_comparison_with_typed_literal():
@pytest.mark.parametrize('start', ['FOR', 'FOREACH'])
def test_forloops(start):
- p = sqlparse.parse('{0} foo in bar LOOP foobar END LOOP'.format(start))[0]
+ p = sqlparse.parse('{} foo in bar LOOP foobar END LOOP'.format(start))[0]
assert (len(p.tokens)) == 1
assert isinstance(p.tokens[0], sql.For)
diff --git a/tests/test_keywords.py b/tests/test_keywords.py
index c197f36..d4ded4b 100644
--- a/tests/test_keywords.py
+++ b/tests/test_keywords.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
import pytest
from sqlparse import tokens
diff --git a/tests/test_parse.py b/tests/test_parse.py
index c28cb06..6cce909 100644
--- a/tests/test_parse.py
+++ b/tests/test_parse.py
@@ -1,12 +1,10 @@
-# -*- coding: utf-8 -*-
-
"""Tests sqlparse.parse()."""
+from io import StringIO
import pytest
import sqlparse
from sqlparse import sql, tokens as T
-from sqlparse.compat import StringIO, text_type
def test_parse_tokenize():
@@ -409,26 +407,26 @@ def test_dbldollar_as_literal(sql, is_literal):
def test_non_ascii():
- _test_non_ascii = u"insert into test (id, name) values (1, 'тест');"
+ _test_non_ascii = "insert into test (id, name) values (1, 'тест');"
s = _test_non_ascii
stmts = sqlparse.parse(s)
assert len(stmts) == 1
statement = stmts[0]
- assert text_type(statement) == s
+ assert str(statement) == s
assert statement._pprint_tree() is None
s = _test_non_ascii.encode('utf-8')
stmts = sqlparse.parse(s, 'utf-8')
assert len(stmts) == 1
statement = stmts[0]
- assert text_type(statement) == _test_non_ascii
+ assert str(statement) == _test_non_ascii
assert statement._pprint_tree() is None
def test_get_real_name():
# issue 369
- s = u"update a t set t.b=1"
+ s = "update a t set t.b=1"
stmts = sqlparse.parse(s)
assert len(stmts) == 1
assert 'a' == stmts[0].tokens[2].get_real_name()
@@ -437,14 +435,14 @@ def test_get_real_name():
def test_from_subquery():
# issue 446
- s = u'from(select 1)'
+ s = 'from(select 1)'
stmts = sqlparse.parse(s)
assert len(stmts) == 1
assert len(stmts[0].tokens) == 2
assert stmts[0].tokens[0].value == 'from'
assert stmts[0].tokens[0].ttype == T.Keyword
- s = u'from (select 1)'
+ s = 'from (select 1)'
stmts = sqlparse.parse(s)
assert len(stmts) == 1
assert len(stmts[0].tokens) == 3
diff --git a/tests/test_regressions.py b/tests/test_regressions.py
index 2ed0ff3..648cc4a 100644
--- a/tests/test_regressions.py
+++ b/tests/test_regressions.py
@@ -1,10 +1,7 @@
-# -*- coding: utf-8 -*-
-
import pytest
import sqlparse
from sqlparse import sql, tokens as T
-from sqlparse.compat import PY2
def test_issue9():
@@ -20,9 +17,9 @@ def test_issue9():
def test_issue13():
- parsed = sqlparse.parse(("select 'one';\n"
- "select 'two\\'';\n"
- "select 'three';"))
+ parsed = sqlparse.parse("select 'one';\n"
+ "select 'two\\'';\n"
+ "select 'three';")
assert len(parsed) == 3
assert str(parsed[1]).strip() == "select 'two\\'';"
@@ -73,8 +70,8 @@ def test_issue39():
def test_issue40():
# make sure identifier lists in subselects are grouped
- p = sqlparse.parse(('SELECT id, name FROM '
- '(SELECT id, name FROM bar) as foo'))[0]
+ p = sqlparse.parse('SELECT id, name FROM '
+ '(SELECT id, name FROM bar) as foo')[0]
assert len(p.tokens) == 7
assert p.tokens[2].__class__ == sql.IdentifierList
assert p.tokens[-1].__class__ == sql.Identifier
@@ -149,7 +146,7 @@ def test_issue83():
def test_comment_encoding_when_reindent():
# There was an UnicodeEncodeError in the reindent filter that
# casted every comment followed by a keyword to str.
- sql = u'select foo -- Comment containing Ümläuts\nfrom bar'
+ sql = 'select foo -- Comment containing Ümläuts\nfrom bar'
formatted = sqlparse.format(sql, reindent=True)
assert formatted == sql
@@ -158,11 +155,9 @@ def test_parse_sql_with_binary():
# See https://github.com/andialbrecht/sqlparse/pull/88
# digest = '‚|ËêŠplL4¡h‘øN{'
digest = '\x82|\xcb\x0e\xea\x8aplL4\xa1h\x91\xf8N{'
- sql = "select * from foo where bar = '{0}'".format(digest)
+ sql = "select * from foo where bar = '{}'".format(digest)
formatted = sqlparse.format(sql, reindent=True)
- tformatted = "select *\nfrom foo\nwhere bar = '{0}'".format(digest)
- if PY2:
- tformatted = tformatted.decode('unicode-escape')
+ tformatted = "select *\nfrom foo\nwhere bar = '{}'".format(digest)
assert formatted == tformatted
@@ -180,7 +175,7 @@ def test_format_accepts_encoding(load_file):
# issue20
sql = load_file('test_cp1251.sql', 'cp1251')
formatted = sqlparse.format(sql, reindent=True, encoding='cp1251')
- tformatted = u'insert into foo\nvalues (1); -- Песня про надежду'
+ tformatted = 'insert into foo\nvalues (1); -- Песня про надежду'
assert formatted == tformatted
@@ -275,7 +270,7 @@ def test_issue186_get_type():
def test_issue212_py2unicode():
- t1 = sql.Token(T.String, u'schöner ')
+ t1 = sql.Token(T.String, 'schöner ')
t2 = sql.Token(T.String, 'bug')
token_list = sql.TokenList([t1, t2])
assert str(token_list) == 'schöner bug'
@@ -337,11 +332,9 @@ def test_issue315_utf8_by_default():
'\x9b\xb2.'
'\xec\x82\xac\xeb\x9e\x91\xed\x95\xb4\xec\x9a\x94'
)
- sql = "select * from foo where bar = '{0}'".format(digest)
+ sql = "select * from foo where bar = '{}'".format(digest)
formatted = sqlparse.format(sql, reindent=True)
- tformatted = "select *\nfrom foo\nwhere bar = '{0}'".format(digest)
- if PY2:
- tformatted = tformatted.decode('utf-8')
+ tformatted = "select *\nfrom foo\nwhere bar = '{}'".format(digest)
assert formatted == tformatted
diff --git a/tests/test_split.py b/tests/test_split.py
index a93e3d4..8214756 100644
--- a/tests/test_split.py
+++ b/tests/test_split.py
@@ -1,13 +1,11 @@
-# -*- coding: utf-8 -*-
-
# Tests splitting functions.
import types
+from io import StringIO
import pytest
import sqlparse
-from sqlparse.compat import StringIO, text_type
def test_split_semicolon():
@@ -33,7 +31,7 @@ def test_split_create_function(load_file, fn):
sql = load_file(fn)
stmts = sqlparse.parse(sql)
assert len(stmts) == 1
- assert text_type(stmts[0]) == sql
+ assert str(stmts[0]) == sql
def test_split_dashcomments(load_file):
@@ -74,12 +72,12 @@ def test_split_dropif():
def test_split_comment_with_umlaut():
- sql = (u'select * from foo;\n'
- u'-- Testing an umlaut: ä\n'
- u'select * from bar;')
+ sql = ('select * from foo;\n'
+ '-- Testing an umlaut: ä\n'
+ 'select * from bar;')
stmts = sqlparse.parse(sql)
assert len(stmts) == 2
- assert ''.join(text_type(q) for q in stmts) == sql
+ assert ''.join(str(q) for q in stmts) == sql
def test_split_comment_end_of_line():
@@ -125,11 +123,11 @@ def test_split_stream():
def test_split_encoding_parsestream():
stream = StringIO("SELECT 1; SELECT 2;")
stmts = list(sqlparse.parsestream(stream))
- assert isinstance(stmts[0].tokens[0].value, text_type)
+ assert isinstance(stmts[0].tokens[0].value, str)
def test_split_unicode_parsestream():
- stream = StringIO(u'SELECT ö')
+ stream = StringIO('SELECT ö')
stmts = list(sqlparse.parsestream(stream))
assert str(stmts[0]) == 'SELECT ö'
diff --git a/tests/test_tokenize.py b/tests/test_tokenize.py
index 3e8831b..0d7f878 100644
--- a/tests/test_tokenize.py
+++ b/tests/test_tokenize.py
@@ -1,13 +1,11 @@
-# -*- coding: utf-8 -*-
-
import types
+from io import StringIO
import pytest
import sqlparse
from sqlparse import lexer
from sqlparse import sql, tokens as T
-from sqlparse.compat import StringIO
def test_tokenize_simple():
@@ -152,7 +150,7 @@ def test_stream_error():
'INNER JOIN',
'LEFT INNER JOIN'])
def test_parse_join(expr):
- p = sqlparse.parse('{0} foo'.format(expr))[0]
+ p = sqlparse.parse('{} foo'.format(expr))[0]
assert len(p.tokens) == 3
assert p.tokens[0].ttype is T.Keyword
diff --git a/tox.ini b/tox.ini
index 2e5010a..0087d50 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,22 +1,17 @@
[tox]
skip_missing_interpreters = True
envlist =
- py27
- py34
py35
py36
py37
py38
- pypy_54
+ pypy3
flake8
[testenv]
deps =
pytest
pytest-cov
- pytest-travis-fold
-passenv =
- TRAVIS
commands =
sqlformat --version
pytest --cov=sqlparse {posargs}