diff --git a/docs/development.rst b/docs/development.rst
index 3dc86a70..7d8907ec 100644
--- a/docs/development.rst
+++ b/docs/development.rst
@@ -4,8 +4,5 @@ Development
yamllint provides both a script and a Python module. The latter can be used to
write your own linting tools:
-.. autoclass:: yamllint.errors.LintProblem
- :members:
-
-.. automodule:: yamllint
+.. automodule:: yamllint.linter
:members:
diff --git a/yamllint/__init__.py b/yamllint/__init__.py
index fbc3675e..df9e0f47 100644
--- a/yamllint/__init__.py
+++ b/yamllint/__init__.py
@@ -14,12 +14,6 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-import yaml
-
-from yamllint.errors import LintProblem
-from yamllint import parser
-
-
APP_NAME = 'yamllint'
APP_VERSION = '0.5.1'
APP_DESCRIPTION = 'A linter for YAML files.'
@@ -28,89 +22,3 @@
__copyright__ = u'Copyright 2016, Adrien Vergé'
__license__ = 'GPLv3'
__version__ = APP_VERSION
-
-
-def get_costemic_problems(buffer, conf):
- rules = conf.enabled_rules()
-
- # Split token rules from line rules
- token_rules = [r for r in rules if r.TYPE == 'token']
- line_rules = [r for r in rules if r.TYPE == 'line']
-
- context = {}
- for rule in token_rules:
- context[rule.ID] = {}
-
- for elem in parser.token_or_line_generator(buffer):
- if isinstance(elem, parser.Token):
- for rule in token_rules:
- rule_conf = conf.rules[rule.ID]
- for problem in rule.check(rule_conf,
- elem.curr, elem.prev, elem.next,
- context[rule.ID]):
- problem.rule = rule.ID
- problem.level = rule_conf['level']
- yield problem
- elif isinstance(elem, parser.Line):
- for rule in line_rules:
- rule_conf = conf.rules[rule.ID]
- for problem in rule.check(rule_conf, elem):
- problem.rule = rule.ID
- problem.level = rule_conf['level']
- yield problem
-
-
-def get_syntax_error(buffer):
- try:
- list(yaml.parse(buffer, Loader=yaml.BaseLoader))
- except yaml.error.MarkedYAMLError as e:
- problem = LintProblem(e.problem_mark.line + 1,
- e.problem_mark.column + 1,
- 'syntax error: ' + e.problem)
- problem.level = 'error'
- return problem
-
-
-def _lint(buffer, conf):
- # If the document contains a syntax error, save it and yield it at the
- # right line
- syntax_error = get_syntax_error(buffer)
-
- for problem in get_costemic_problems(buffer, conf):
- # Insert the syntax error (if any) at the right place...
- if (syntax_error and syntax_error.line <= problem.line and
- syntax_error.column <= problem.column):
- yield syntax_error
-
- # If there is already a yamllint error at the same place, discard
- # it as it is probably redundant (and maybe it's just a 'warning',
- # in which case the script won't even exit with a failure status).
- if (syntax_error.line == problem.line and
- syntax_error.column == problem.column):
- syntax_error = None
- continue
-
- syntax_error = None
-
- yield problem
-
- if syntax_error:
- yield syntax_error
-
-
-def lint(input, conf):
- """Lints a YAML source.
-
- Returns a generator of LintProblem objects.
-
- :param input: buffer, string or stream to read from
- :param conf: yamllint configuration object
- """
- if type(input) == str:
- return _lint(input, conf)
- elif hasattr(input, 'read'): # Python 2's file or Python 3's io.IOBase
- # We need to have everything in memory to parse correctly
- content = input.read()
- return _lint(content, conf)
- else:
- raise TypeError('input should be a string or a stream')
diff --git a/yamllint/cli.py b/yamllint/cli.py
index 0dc8511d..a1f7d68d 100644
--- a/yamllint/cli.py
+++ b/yamllint/cli.py
@@ -23,7 +23,7 @@
from yamllint import APP_DESCRIPTION, APP_NAME, APP_VERSION
from yamllint.config import YamlLintConfig, YamlLintConfigError
-from yamllint import lint
+from yamllint import linter
def find_files_recursively(items):
@@ -96,7 +96,7 @@ def run(argv):
try:
first = True
with open(file) as f:
- for problem in lint(f, conf):
+ for problem in linter.run(f, conf):
if args.format == 'parsable':
print(Format.parsable(problem, file))
else:
diff --git a/yamllint/errors.py b/yamllint/errors.py
deleted file mode 100644
index fa2f21b9..00000000
--- a/yamllint/errors.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (C) 2016 Adrien Vergé
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see .
-
-
-class LintProblem(object):
- """Represents a linting problem found by yamllint."""
- def __init__(self, line, column, desc='', rule=None):
- #: Line on which the problem was found (starting at 1)
- self.line = line
- #: Column on which the problem was found (starting at 1)
- self.column = column
- #: Human-readable description of the problem
- self.desc = desc
- #: Identifier of the rule that detected the problem
- self.rule = rule
- self.level = None
-
- @property
- def message(self):
- if self.rule is not None:
- return '%s (%s)' % (self.desc, self.rule)
- return self.desc
-
- def __eq__(self, other):
- return (self.line == other.line and
- self.column == other.column and
- self.rule == other.rule)
-
- def __lt__(self, other):
- return (self.line < other.line or
- (self.line == other.line and self.column < other.column))
-
- def __repr__(self):
- return '%d:%d: %s' % (self.line, self.column, self.message)
-
-
-class YamlLintError(Exception):
- pass
-
-
-class YamlLintConfigError(YamlLintError):
- pass
diff --git a/yamllint/linter.py b/yamllint/linter.py
new file mode 100644
index 00000000..414438e1
--- /dev/null
+++ b/yamllint/linter.py
@@ -0,0 +1,137 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2016 Adrien Vergé
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+import yaml
+
+from yamllint import parser
+
+
+class LintProblem(object):
+ """Represents a linting problem found by yamllint."""
+ def __init__(self, line, column, desc='', rule=None):
+ #: Line on which the problem was found (starting at 1)
+ self.line = line
+ #: Column on which the problem was found (starting at 1)
+ self.column = column
+ #: Human-readable description of the problem
+ self.desc = desc
+ #: Identifier of the rule that detected the problem
+ self.rule = rule
+ self.level = None
+
+ @property
+ def message(self):
+ if self.rule is not None:
+ return '%s (%s)' % (self.desc, self.rule)
+ return self.desc
+
+ def __eq__(self, other):
+ return (self.line == other.line and
+ self.column == other.column and
+ self.rule == other.rule)
+
+ def __lt__(self, other):
+ return (self.line < other.line or
+ (self.line == other.line and self.column < other.column))
+
+ def __repr__(self):
+ return '%d:%d: %s' % (self.line, self.column, self.message)
+
+
+def get_costemic_problems(buffer, conf):
+ rules = conf.enabled_rules()
+
+ # Split token rules from line rules
+ token_rules = [r for r in rules if r.TYPE == 'token']
+ line_rules = [r for r in rules if r.TYPE == 'line']
+
+ context = {}
+ for rule in token_rules:
+ context[rule.ID] = {}
+
+ for elem in parser.token_or_line_generator(buffer):
+ if isinstance(elem, parser.Token):
+ for rule in token_rules:
+ rule_conf = conf.rules[rule.ID]
+ for problem in rule.check(rule_conf,
+ elem.curr, elem.prev, elem.next,
+ context[rule.ID]):
+ problem.rule = rule.ID
+ problem.level = rule_conf['level']
+ yield problem
+ elif isinstance(elem, parser.Line):
+ for rule in line_rules:
+ rule_conf = conf.rules[rule.ID]
+ for problem in rule.check(rule_conf, elem):
+ problem.rule = rule.ID
+ problem.level = rule_conf['level']
+ yield problem
+
+
+def get_syntax_error(buffer):
+ try:
+ list(yaml.parse(buffer, Loader=yaml.BaseLoader))
+ except yaml.error.MarkedYAMLError as e:
+ problem = LintProblem(e.problem_mark.line + 1,
+ e.problem_mark.column + 1,
+ 'syntax error: ' + e.problem)
+ problem.level = 'error'
+ return problem
+
+
+def _run(buffer, conf):
+ # If the document contains a syntax error, save it and yield it at the
+ # right line
+ syntax_error = get_syntax_error(buffer)
+
+ for problem in get_costemic_problems(buffer, conf):
+ # Insert the syntax error (if any) at the right place...
+ if (syntax_error and syntax_error.line <= problem.line and
+ syntax_error.column <= problem.column):
+ yield syntax_error
+
+ # If there is already a yamllint error at the same place, discard
+ # it as it is probably redundant (and maybe it's just a 'warning',
+ # in which case the script won't even exit with a failure status).
+ if (syntax_error.line == problem.line and
+ syntax_error.column == problem.column):
+ syntax_error = None
+ continue
+
+ syntax_error = None
+
+ yield problem
+
+ if syntax_error:
+ yield syntax_error
+
+
+def run(input, conf):
+ """Lints a YAML source.
+
+ Returns a generator of LintProblem objects.
+
+ :param input: buffer, string or stream to read from
+ :param conf: yamllint configuration object
+ """
+ if type(input) == str:
+ return _run(input, conf)
+ elif hasattr(input, 'read'): # Python 2's file or Python 3's io.IOBase
+ # We need to have everything in memory to parse correctly
+ content = input.read()
+ return _run(content, conf)
+ else:
+ raise TypeError('input should be a string or a stream')
diff --git a/yamllint/rules/commas.py b/yamllint/rules/commas.py
index 3fbd9329..28997eea 100644
--- a/yamllint/rules/commas.py
+++ b/yamllint/rules/commas.py
@@ -64,7 +64,7 @@
import yaml
-from yamllint.errors import LintProblem
+from yamllint.linter import LintProblem
from yamllint.rules.common import spaces_after, spaces_before
diff --git a/yamllint/rules/comments.py b/yamllint/rules/comments.py
index 4ad224a5..112f6589 100644
--- a/yamllint/rules/comments.py
+++ b/yamllint/rules/comments.py
@@ -57,7 +57,7 @@
import yaml
-from yamllint.errors import LintProblem
+from yamllint.linter import LintProblem
from yamllint.rules.common import get_comments_between_tokens
diff --git a/yamllint/rules/comments_indentation.py b/yamllint/rules/comments_indentation.py
index 6fa80eb0..8bd0c568 100644
--- a/yamllint/rules/comments_indentation.py
+++ b/yamllint/rules/comments_indentation.py
@@ -77,7 +77,7 @@
import yaml
-from yamllint.errors import LintProblem
+from yamllint.linter import LintProblem
from yamllint.rules.common import get_line_indent, get_comments_between_tokens
diff --git a/yamllint/rules/common.py b/yamllint/rules/common.py
index 8de3b33d..2f99e848 100644
--- a/yamllint/rules/common.py
+++ b/yamllint/rules/common.py
@@ -16,7 +16,7 @@
import yaml
-from yamllint.errors import LintProblem
+from yamllint.linter import LintProblem
def spaces_after(token, prev, next, min=-1, max=-1,
diff --git a/yamllint/rules/document_end.py b/yamllint/rules/document_end.py
index 14417c49..ee62b672 100644
--- a/yamllint/rules/document_end.py
+++ b/yamllint/rules/document_end.py
@@ -76,7 +76,7 @@
import yaml
-from yamllint.errors import LintProblem
+from yamllint.linter import LintProblem
ID = 'document-end'
diff --git a/yamllint/rules/document_start.py b/yamllint/rules/document_start.py
index 7e3ff73c..70f511fc 100644
--- a/yamllint/rules/document_start.py
+++ b/yamllint/rules/document_start.py
@@ -66,7 +66,7 @@
import yaml
-from yamllint.errors import LintProblem
+from yamllint.linter import LintProblem
ID = 'document-start'
diff --git a/yamllint/rules/empty_lines.py b/yamllint/rules/empty_lines.py
index b8a9158a..6f5496cf 100644
--- a/yamllint/rules/empty_lines.py
+++ b/yamllint/rules/empty_lines.py
@@ -50,7 +50,7 @@
"""
-from yamllint.errors import LintProblem
+from yamllint.linter import LintProblem
ID = 'empty-lines'
diff --git a/yamllint/rules/indentation.py b/yamllint/rules/indentation.py
index 3edae82c..e51255fd 100644
--- a/yamllint/rules/indentation.py
+++ b/yamllint/rules/indentation.py
@@ -132,7 +132,7 @@
import yaml
-from yamllint.errors import LintProblem
+from yamllint.linter import LintProblem
from yamllint.rules.common import is_explicit_key
diff --git a/yamllint/rules/line_length.py b/yamllint/rules/line_length.py
index 5abb7ba4..a3c2cd7e 100644
--- a/yamllint/rules/line_length.py
+++ b/yamllint/rules/line_length.py
@@ -41,7 +41,7 @@
"""
-from yamllint.errors import LintProblem
+from yamllint.linter import LintProblem
ID = 'line-length'
diff --git a/yamllint/rules/new_line_at_end_of_file.py b/yamllint/rules/new_line_at_end_of_file.py
index f5770980..90b1cc2a 100644
--- a/yamllint/rules/new_line_at_end_of_file.py
+++ b/yamllint/rules/new_line_at_end_of_file.py
@@ -24,7 +24,7 @@
"""
-from yamllint.errors import LintProblem
+from yamllint.linter import LintProblem
ID = 'new-line-at-end-of-file'
diff --git a/yamllint/rules/new_lines.py b/yamllint/rules/new_lines.py
index d085c9cf..91adb4ef 100644
--- a/yamllint/rules/new_lines.py
+++ b/yamllint/rules/new_lines.py
@@ -24,7 +24,7 @@
"""
-from yamllint.errors import LintProblem
+from yamllint.linter import LintProblem
ID = 'new-lines'
diff --git a/yamllint/rules/trailing_spaces.py b/yamllint/rules/trailing_spaces.py
index ec215f83..2fc4bbba 100644
--- a/yamllint/rules/trailing_spaces.py
+++ b/yamllint/rules/trailing_spaces.py
@@ -39,7 +39,7 @@
import string
-from yamllint.errors import LintProblem
+from yamllint.linter import LintProblem
ID = 'trailing-spaces'