Skip to content
This repository has been archived by the owner on Dec 29, 2022. It is now read-only.

Add pylint support to travis. #16

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,17 @@ before-install:

install:
- pip install -r requirements.txt
- git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git

script:
# Run the unittests
- python -m unittest discover --start-directory stl/ --pattern "*_test.py"
- python -m unittest discover --start-directory example/ --pattern "*_test.py"

# Run the linter
- depot_tools/pylint stl --ignore=parsetab.py,parser_test_proto_pb2.py
- depot_tools/pylint example --ignore=example_pb2.py

notification:
email:
- sprockets-eng@googlegroups.com
30 changes: 30 additions & 0 deletions stl/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ def __init__(self, name):
def __eq__(self, other):
return NamedObject.__eq__(self, other) and self.params == other.params

def Resolve(self, env, resolved_params):
raise NotImplementedError('Resolved() is not needed: ' + self.name)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it necessary while NapeObject.Resolve() exists?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's an quirk of how pylint works. Pylint sees that NameObject.Resolve just does a raise NotImplementedError, so pylint considers that method to be abstract. Then it doesn't see an overrdie in the child class, so it throws an unimplemented abstract method warning.

Another option would be to just disable the warning in this file

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about:

if True:
raise NotImplementedError('Resolved() is not needed: ' + self.name)

in base class? Would "if True" do some trick?


class TypedObject(NamedObject):
"""Base class for all object with a type and name.
Expand All @@ -104,6 +107,9 @@ def __init__(self, name, type_):
def __eq__(self, other):
return NamedObject.__eq__(self, other) and self.type_ == other.type_

def Resolve(self, env, resolved_params):
raise NotImplementedError('Resolved() is not needed: ' + self.name)


class Const(TypedObject):
"""Constants.
Expand Down Expand Up @@ -333,6 +339,9 @@ def __init__(self, name, type_):
def __str__(self):
return 'PARAM %s(%s)' % (self.name, self.type_)

def Resolve(self, env, resolved_params):
raise NotImplementedError('Resolved() is not needed: ' + self.name)


class LocalVar(TypedObject):
"""Local variables.
Expand All @@ -352,6 +361,9 @@ def __init__(self, name, type_):
def __str__(self):
return 'LOCAL %s(%s)' % (self.name, self.type_)

def Resolve(self, env, resolved_params):
raise NotImplementedError('Resolved() is not needed: ' + self.name)


class Field(TypedObject):
"""Fields in messages or in roles.
Expand Down Expand Up @@ -384,6 +396,9 @@ def __str__(self):
return 'FIELD-OPTIONAL %s(%s)' % (self.name, self.type_)
return 'FIELD %s(%s)' % (self.name, self.type_)

def Resolve(self, env, resolved_params):
raise NotImplementedError('Resolved() is not needed: ' + self.name)


class Role(NamedObject):
"""Roles.
Expand Down Expand Up @@ -522,6 +537,9 @@ def Run(self):
raise RuntimeError('Func does not contain a runnable function.')
return self.func(*self.args)

def Resolve(self, env, resolved_params):
raise NotImplementedError('Resolved() is not needed: ' + self.name)


class FuncNoOp(Func):
"""External function doing nothing."""
Expand All @@ -532,6 +550,9 @@ def __init__(self, name):
def Run(self):
return True

def Resolve(self, env, resolved_params):
raise NotImplementedError('Resolved() is not needed: ' + self.name)


class FuncGetField(Func):
"""External function to get the value of a field either of Role or dictionary.
Expand All @@ -555,6 +576,9 @@ def __str__(self):
def Run(self):
return self.obj[self.field]

def Resolve(self, env, resolved_params):
raise NotImplementedError('Resolved() is not needed: ' + self.name)


class FuncSet(Func):
"""External function to set a value to a field of Role or to a LocalVar.
Expand Down Expand Up @@ -603,6 +627,9 @@ def SetValue(self, value):
else:
raise TypeError('Cannot SetValue on type %s' % type(self.obj))

def Resolve(self, env, resolved_params):
raise NotImplementedError('Resolved() is not needed: ' + self.name)


class FuncWithContext(Func):
"""External event function with context.
Expand Down Expand Up @@ -651,3 +678,6 @@ def Run(self):
if self.context.test_source:
return self.event.Wait(*new_args)
return self.event.Fire(*new_args)

def Resolve(self, env, resolved_params):
raise NotImplementedError('Resolved() is not needed: ' + self.name)
15 changes: 4 additions & 11 deletions stl/lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,10 @@

"""Lexing (tokenizing) a state transition (STL) spec."""

# pylint: disable=g-doc-args
# pylint: disable=g-docstring-missing-newline
# pylint: disable=g-docstring-quotes
# pylint: disable=g-no-space-after-docstring-summary
# pylint: disable=g-short-docstring-punctuation
# pylint: disable=g-short-docstring-space
# pylint: disable=invalid-name
# pylint: disable=unused-variable

import logging
import ply.lex # pylint: disable=g-bad-import-order

import ply.lex


class StlSyntaxError(SyntaxError):
Expand Down Expand Up @@ -136,7 +129,7 @@ def t_error(self, t):
t.value[0])
t.lexer.skip(1)

def debug(data):
"""Print out all the tokens in |data|."""
def debug(self):
"""Print out all the tokens from the lexer|."""
for token in self.lexer.tokens():
print token
4 changes: 2 additions & 2 deletions stl/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,11 +293,11 @@ class DifferentFrom(Qualifier):
def __init__(self):
Qualifier.__init__(self)

def Validate(self, value, prev):
def Validate(self, value, prev): # pylint: disable=arguments-differ
# This value must not match the previous one.
return value != prev

def Generate(self, prev):
def Generate(self, prev): # pylint: disable=arguments-differ
rand = random.randint(0, 999999)
if 'random-%s' % rand == prev:
rand += 1
Expand Down
5 changes: 3 additions & 2 deletions stl/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@

import importlib
import logging

from google.protobuf import message
from google.protobuf import reflection

import stl.base # pylint: disable=g-bad-import-order
import stl.lib # pylint: disable=g-bad-import-order
import stl.base
import stl.lib


class Message(stl.base.NamedObject):
Expand Down
27 changes: 12 additions & 15 deletions stl/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,12 @@
# limitations under the License.
"""Parsing a state transition spec."""

# pylint: disable=g-doc-args
# pylint: disable=g-docstring-missing-newline
# pylint: disable=g-docstring-quotes
# pylint: disable=g-no-space-after-docstring-summary
# pylint: disable=g-short-docstring-punctuation
# pylint: disable=g-short-docstring-space
# pylint: disable=invalid-name
# pylint: disable=unused-variable

import logging
import ply.yacc # pylint: disable=g-bad-import-order
import pprint
import sys

import ply.yacc

import stl.base
import stl.event
import stl.lexer
Expand Down Expand Up @@ -98,19 +90,22 @@ def p_const_def(self, p):
"""const_def : CONST type NAME ';'
| CONST type NAME '=' value ';' """
if self._local_env['_curr_module'].HasDefinition(p[3]):
logging.error('[%s:%d] Duplicated const: %s', self._filename, p.lineno(3), p[3])
logging.error(
'[%s:%d] Duplicated const: %s', self._filename, p.lineno(3), p[3])
return
# TODO(byungchul): Type checking
if len(p) == 5:
self._local_env['_curr_module'].consts[p[3]] = stl.base.Const(p[3], p[2])
else:
self._local_env['_curr_module'].consts[p[3]] = stl.base.Const(p[3], p[2], p[5])
self._local_env['_curr_module'].consts[p[3]] = (
stl.base.Const(p[3], p[2], p[5]))

def p_role_def(self, p):
"""role_def : ROLE NAME '{' '}'
| ROLE NAME '{' role_fields '}' """
if self._local_env['_curr_module'].HasDefinition(p[2]):
logging.error('[%s:%d] Duplicated role: %s', self._filename, p.lineno(2), p[2])
logging.error(
'[%s:%d] Duplicated role: %s', self._filename, p.lineno(2), p[2])
return
role = stl.base.Role(p[2])
if len(p) >= 6:
Expand Down Expand Up @@ -142,7 +137,8 @@ def p_state_def(self, p):
"""state_def : STATE NAME params '{' names '}'
| STATE NAME params '{' names ',' '}' """
if self._local_env['_curr_module'].HasDefinition(p[2]):
logging.error('[%s:%d] Duplicated state: %s', self._filename, p.lineno(2), p[2])
logging.error(
'[%s:%d] Duplicated state: %s', self._filename, p.lineno(2), p[2])
return
state_ = stl.state.State(p[2])
state_.params = p[3]
Expand Down Expand Up @@ -249,7 +245,8 @@ def p_field_property_list(self, p):
assert isinstance(p[1], dict)
key, val = p[3]
if key in p[1]:
logging.error('[%s:%d] Duplicated key: %s', self._filename, p.lineno(3), key)
logging.error(
'[%s:%d] Duplicated key: %s', self._filename, p.lineno(3), key)
return
p[1][key] = val
p[0] = p[1]
Expand Down
1 change: 1 addition & 0 deletions stl/qualifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,6 @@ def __str__(self):
return '%s b(%s)' % (Qualifier.__str__(self), self.external_name)

def Resolve(self, env, resolved_params):
del env, resolved_params # Unused.
logging.log(1, 'Resolving ' + self.name)
return self.external