summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml36
-rw-r--r--pytest.ini6
-rw-r--r--sqlparse/__init__.py5
-rw-r--r--sqlparse/engine/__init__.py20
-rw-r--r--sqlparse/engine/filter.py2
-rw-r--r--sqlparse/engine/grouping.py9
-rw-r--r--sqlparse/filters.py26
-rw-r--r--sqlparse/sql.py2
-rw-r--r--sqlparse/tokens.py32
-rw-r--r--tests/test_functions.py3
-rw-r--r--tests/test_regressions.py4
-rw-r--r--tox.ini39
12 files changed, 84 insertions, 100 deletions
diff --git a/.travis.yml b/.travis.yml
index febc5bd..6453a5d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,23 +1,31 @@
language: python
+python: 3.5
-python:
- - "3.5"
- - "3.4"
- - "3.3"
- - "2.7"
- - "pypy"
- - "pypy3"
- - "nightly"
+env:
+ - TOXENV=flake8
+ - TOXENV=py27
+ - TOXENV=py33
+ - TOXENV=py34
+ - TOXENV=py35
+ - TOXENV=pypy
+ - TOXENV=pypy3
matrix:
- allow_failures:
- - python: "nightly"
+ fast_finish: true
+
+ include:
+ - python: "nightly"
+ env: TOXENV=py36
+
+ allow_failures:
+ - python: "nightly"
install:
- - pip install pytest pytest-cov coveralls
- - pip install -e .
+ - pip install tox coveralls
-script: py.test --cov=sqlparse
+script:
+ - tox
after_success:
- coveralls
+ - coveralls
+ - bash <(curl -s https://codecov.io/bash)
diff --git a/pytest.ini b/pytest.ini
deleted file mode 100644
index a2cbd90..0000000
--- a/pytest.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[pytest]
-pep8ignore =
- extras/* ALL
- examples/* ALL
- docs/* ALL
- * E125 E127
diff --git a/sqlparse/__init__.py b/sqlparse/__init__.py
index e5f4f03..794bf57 100644
--- a/sqlparse/__init__.py
+++ b/sqlparse/__init__.py
@@ -35,11 +35,11 @@ def parsestream(stream, encoding=None):
:returns: A generator of :class:`~sqlparse.sql.Statement` instances.
"""
stack = engine.FilterStack()
- stack.full_analyze()
+ stack.enable_grouping()
return stack.run(stream, encoding)
-def format(sql, **options):
+def format(sql, encoding=None, **options):
"""Format *sql* according to *options*.
Available options are documented in :ref:`formatting`.
@@ -49,7 +49,6 @@ def format(sql, **options):
:returns: The formatted SQL statement as string.
"""
- encoding = options.pop('encoding', None)
stack = engine.FilterStack()
options = formatter.validate_options(options)
stack = formatter.build_filter_stack(stack, options)
diff --git a/sqlparse/engine/__init__.py b/sqlparse/engine/__init__.py
index 4d7fe88..c6b8b0c 100644
--- a/sqlparse/engine/__init__.py
+++ b/sqlparse/engine/__init__.py
@@ -9,9 +9,6 @@ from sqlparse import lexer
from sqlparse.engine import grouping
from sqlparse.engine.filter import StatementFilter
-# XXX remove this when cleanup is complete
-Filter = object
-
class FilterStack(object):
@@ -22,20 +19,9 @@ class FilterStack(object):
self.split_statements = False
self._grouping = False
- def _flatten(self, stream):
- for token in stream:
- if token.is_group():
- for t in self._flatten(token.tokens):
- yield t
- else:
- yield token
-
def enable_grouping(self):
self._grouping = True
- def full_analyze(self):
- self.enable_grouping()
-
def run(self, sql, encoding=None):
stream = lexer.tokenize(sql, encoding)
# Process token stream
@@ -43,8 +29,8 @@ class FilterStack(object):
for filter_ in self.preprocess:
stream = filter_.process(self, stream)
- if self.stmtprocess or self.postprocess or self.split_statements \
- or self._grouping:
+ if (self.stmtprocess or self.postprocess or
+ self.split_statements or self._grouping):
splitter = StatementFilter()
stream = splitter.process(self, stream)
@@ -71,7 +57,7 @@ class FilterStack(object):
def _run2(stream):
for stmt in stream:
- stmt.tokens = list(self._flatten(stmt.tokens))
+ stmt.tokens = list(stmt.flatten())
for filter_ in self.postprocess:
stmt = filter_.process(self, stmt)
yield stmt
diff --git a/sqlparse/engine/filter.py b/sqlparse/engine/filter.py
index 360ff9b..adf48ad 100644
--- a/sqlparse/engine/filter.py
+++ b/sqlparse/engine/filter.py
@@ -4,7 +4,7 @@ from sqlparse.sql import Statement, Token
from sqlparse import tokens as T
-class StatementFilter:
+class StatementFilter(object):
"Filter that split stream at individual statements"
def __init__(self):
diff --git a/sqlparse/engine/grouping.py b/sqlparse/engine/grouping.py
index f7953e7..7a93b5e 100644
--- a/sqlparse/engine/grouping.py
+++ b/sqlparse/engine/grouping.py
@@ -27,15 +27,16 @@ def _group_left_right(tlist, m, cls,
if valid_left(left) and valid_right(right):
if semicolon:
+ # only overwrite if a semicolon present.
sright = tlist.token_next_by(m=M_SEMICOLON, idx=right)
- right = sright or right # only overwrite if a semicolon present.
+ right = sright or right
tokens = tlist.tokens_between(left, right)
token = tlist.group_tokens(cls, tokens, extend=True)
token = tlist.token_next_by(m=m, idx=token)
def _group_matching(tlist, cls):
- """Groups Tokens that have beginning and end. ie. parenthesis, brackets.."""
+ """Groups Tokens that have beginning and end."""
idx = 1 if imt(tlist, i=cls) else 0
token = tlist.token_next_by(m=cls.M_OPEN, idx=idx)
@@ -223,9 +224,9 @@ def group_functions(tlist):
has_create = False
has_table = False
for tmp_token in tlist.tokens:
- if tmp_token.value == u'CREATE':
+ if tmp_token.value == 'CREATE':
has_create = True
- if tmp_token.value == u'TABLE':
+ if tmp_token.value == 'TABLE':
has_table = True
if has_create and has_table:
return
diff --git a/sqlparse/filters.py b/sqlparse/filters.py
index 72f17d0..f5719e7 100644
--- a/sqlparse/filters.py
+++ b/sqlparse/filters.py
@@ -17,7 +17,7 @@ from sqlparse.utils import split_unquoted_newlines
# --------------------------
# token process
-class _CaseFilter:
+class _CaseFilter(object):
ttype = None
@@ -48,7 +48,7 @@ class IdentifierCaseFilter(_CaseFilter):
yield ttype, value
-class TruncateStringFilter:
+class TruncateStringFilter(object):
def __init__(self, width, char):
self.width = max(width, 1)
@@ -69,7 +69,7 @@ class TruncateStringFilter:
yield ttype, value
-class GetComments:
+class GetComments(object):
"""Get the comments from a stack"""
def process(self, stack, stream):
for token_type, value in stream:
@@ -77,7 +77,7 @@ class GetComments:
yield token_type, value
-class StripComments:
+class StripComments(object):
"""Strip the comments from a stack"""
def process(self, stack, stream):
for token_type, value in stream:
@@ -113,7 +113,7 @@ def StripWhitespace(stream):
last_type = token_type
-class IncludeStatement:
+class IncludeStatement(object):
"""Filter that enable a INCLUDE statement"""
def __init__(self, dirpath=".", maxrecursive=10, raiseexceptions=False):
@@ -196,7 +196,7 @@ class IncludeStatement:
# ----------------------
# statement process
-class StripCommentsFilter:
+class StripCommentsFilter(object):
def _get_next_comment(self, tlist):
# TODO(andi) Comment types should be unified, see related issue38
@@ -225,7 +225,7 @@ class StripCommentsFilter:
self._process(stmt)
-class StripWhitespaceFilter:
+class StripWhitespaceFilter(object):
def _stripws(self, tlist):
func_name = '_stripws_%s' % tlist.__class__.__name__.lower()
@@ -277,7 +277,7 @@ class StripWhitespaceFilter:
stmt.tokens.pop(-1)
-class ReindentFilter:
+class ReindentFilter(object):
def __init__(self, width=2, char=' ', line_width=None):
self.width = width
@@ -471,7 +471,7 @@ class ReindentFilter:
# FIXME: Doesn't work ;)
-class RightMarginFilter:
+class RightMarginFilter(object):
keep_together = (
# sql.TypeCast, sql.Identifier, sql.Alias,
@@ -509,7 +509,7 @@ class RightMarginFilter:
group.tokens = self._process(stack, group, group.tokens)
-class ColumnsSelect:
+class ColumnsSelect(object):
"""Get the columns names of a SELECT query"""
def process(self, stack, stream):
mode = 0
@@ -563,7 +563,7 @@ class ColumnsSelect:
# ---------------------------
# postprocess
-class SerializerUnicode:
+class SerializerUnicode(object):
def process(self, stack, stmt):
raw = u(stmt)
@@ -581,7 +581,7 @@ def Tokens2Unicode(stream):
return result
-class OutputFilter:
+class OutputFilter(object):
varname_prefix = ''
def __init__(self, varname='sql'):
@@ -695,7 +695,7 @@ class OutputPHPFilter(OutputFilter):
yield sql.Token(T.Punctuation, ';')
-class Limit:
+class Limit(object):
"""Get the LIMIT of a query.
If not defined, return -1 (SQL specification for no LIMIT query)
diff --git a/sqlparse/sql.py b/sqlparse/sql.py
index 9afdac3..3177831 100644
--- a/sqlparse/sql.py
+++ b/sqlparse/sql.py
@@ -316,7 +316,7 @@ class TokenList(Token):
def token_index(self, token, start=0):
"""Return list index of token."""
- start = self.token_index(start) if not isinstance(start, int) else start
+ start = start if isinstance(start, int) else self.token_index(start)
return start + self.tokens[start:].index(token)
def tokens_between(self, start, end, include_end=True):
diff --git a/sqlparse/tokens.py b/sqlparse/tokens.py
index 98fa8a6..b259627 100644
--- a/sqlparse/tokens.py
+++ b/sqlparse/tokens.py
@@ -13,31 +13,18 @@
class _TokenType(tuple):
parent = None
- def split(self):
- buf = []
- node = self
- while node is not None:
- buf.append(node)
- node = node.parent
- buf.reverse()
- return buf
+ def __contains__(self, item):
+ return item is not None and (self is item or item[:len(self)] == self)
- def __contains__(self, val):
- return val is not None and (self is val or val[:len(self)] == self)
-
- def __getattr__(self, val):
- if not val or not val[0].isupper():
- return tuple.__getattribute__(self, val)
- new = _TokenType(self + (val,))
- setattr(self, val, new)
+ def __getattr__(self, name):
+ new = _TokenType(self + (name,))
+ setattr(self, name, new)
new.parent = self
return new
- def __hash__(self):
- return hash(tuple(self))
-
def __repr__(self):
- return 'Token' + (self and '.' or '') + '.'.join(self)
+ # self can be False only if its the `root` ie. Token itself
+ return 'Token' + ('.' if self else '') + '.'.join(self)
Token = _TokenType()
@@ -77,8 +64,3 @@ DML = Keyword.DML
DDL = Keyword.DDL
CTE = Keyword.CTE
Command = Keyword.Command
-
-Group = Token.Group
-Group.Parenthesis = Token.Group.Parenthesis
-Group.Comment = Token.Group.Comment
-Group.Where = Token.Group.Where
diff --git a/tests/test_functions.py b/tests/test_functions.py
index 9207815..fd2774e 100644
--- a/tests/test_functions.py
+++ b/tests/test_functions.py
@@ -8,9 +8,6 @@ from unittest import main, TestCase
from sqlparse.filters import IncludeStatement, Tokens2Unicode
from sqlparse.lexer import tokenize
-import sys
-sys.path.insert(0, '..')
-
from sqlparse.filters import compact
from sqlparse.functions import getcolumns, getlimit, IsType
from tests.utils import FILES_DIR
diff --git a/tests/test_regressions.py b/tests/test_regressions.py
index c66a42d..13ca04b 100644
--- a/tests/test_regressions.py
+++ b/tests/test_regressions.py
@@ -7,7 +7,6 @@ from tests.utils import TestCaseBase, load_file
import sqlparse
from sqlparse import sql
from sqlparse import tokens as T
-from sqlparse.compat import u
class RegressionTests(TestCaseBase):
@@ -296,7 +295,8 @@ def test_issue213_leadingws():
def test_issue227_gettype_cte():
select_stmt = sqlparse.parse('SELECT 1, 2, 3 FROM foo;')
assert select_stmt[0].get_type() == 'SELECT'
- with_stmt = sqlparse.parse('WITH foo AS (SELECT 1, 2, 3) SELECT * FROM foo;')
+ with_stmt = sqlparse.parse('WITH foo AS (SELECT 1, 2, 3)'
+ 'SELECT * FROM foo;')
assert with_stmt[0].get_type() == 'SELECT'
with2_stmt = sqlparse.parse('''
WITH foo AS (SELECT 1 AS abc, 2 AS def),
diff --git a/tox.ini b/tox.ini
index 41f8240..265cc3c 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,18 +1,35 @@
[tox]
-envlist=flake8,py27,py33,py34,py35,pypy,pypy3
+envlist =
+ py27,
+ py33,
+ py34,
+ py35,
+ py36,
+ pypy,
+ pypy3,
+ flake8
[testenv]
-deps=
- pytest
- pytest-cov
-commands=
- sqlformat --version # Sanity check.
- py.test --cov=sqlparse/ tests
+deps =
+ pytest
+ pytest-cov
+ pytest-travis-fold
+passenv =
+ TRAVIS
+commands =
+ python --version
+ sqlformat --version
+ py.test --cov=sqlparse
[testenv:flake8]
-basepython=python3.5
-deps=flake8
-commands=flake8 sqlparse
+deps =
+ flake8
+commands =
+ flake8 sqlparse tests setup.py
[flake8]
-ignore = W503
+exclude =
+ sqlparse/compat.py
+ignore =
+ W503,
+ E731