Skip to content

Commit

Permalink
[ADD] except-pass: Emit message If a except:pass is used fix OCA#252
Browse files Browse the repository at this point in the history
[FIX] pylint-odoo: Best use of if clause

[FIX] pylint-odoo: Validate the body contain only one line

[FIX] pylint-odoo: Avoid use \ better use (

[REF] incoherent-interpreter-exec-perm: Better message (Vauxoo#106)

[ADD] xml-attribute-translatable: Check XML attribute without translation parameter (Vauxoo#105)

Close OCA#104

[REF] javascript-lint: Use eslint instead of jshint (Vauxoo#97)

[ADD] renamed-field-parameter: Detect deprecated field values (digits_compute, select) (Vauxoo#99)

[FIX] Pep8 check and bad index for ODOO_MSGS

[ADD] attribute-string-redundant: Check if "string" parameter is equal to variable name (Vauxoo#100)

[FIX] attribute-string-redundant: Add "isinstance" validation for nodes

Fix OCA#109

[IMP] Exclude exception when use as assignation

[FIX] Pep8 check local variable 'exception'

[FIX] Pep8 blank line at end of file

[FIX] Adding more cases of test

[REF] Supporting more cases of exception

[FIX] Modify file main.py for adding new case of except-pass

[IMP] Adding another tests case

[FIX] Adding another test case and better validation

[FIX] Delete unnecessary condition of if

[FIX] Fix comment line
  • Loading branch information
JesusZapata committed Jan 31, 2017
1 parent fc548e2 commit 24fd5fb
Show file tree
Hide file tree
Showing 16 changed files with 699 additions and 27 deletions.
7 changes: 4 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ addons:
apt:
packages:
- python-lxml # because pip installation is slow
- nodejs

virtualenv:
system_site_packages: true
Expand All @@ -25,9 +24,11 @@ matrix:
TOXENV=py27-pylint20

install:
- nvm install 6 # Update nodejs version to 6.latest, required by eslint
# Remove packages installed from addons-apt-packages of travis file
- find -L ${TRAVIS_BUILD_DIR} -name requirements.txt -exec sed -i '/lxml/d' {} \;
- find -L ${TRAVIS_BUILD_DIR} -name install.sh -exec sed -i '/node/d' {} \;
- sed -i '/lxml/d' ${TRAVIS_BUILD_DIR}/requirements.txt
- sed -i '/node/d' ${TRAVIS_BUILD_DIR}/install.sh
- sed -i '/pip install ./d' ${TRAVIS_BUILD_DIR}/install.sh

# Install dependencies
- ${TRAVIS_BUILD_DIR}/install.sh
Expand Down
2 changes: 1 addition & 1 deletion install.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
wget -qO- https://deb.nodesource.com/setup | bash - \
&& apt-get install nodejs
npm install -g jshint
npm install -g eslint
pip install .
11 changes: 8 additions & 3 deletions pylint_odoo/checkers/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@
settings.DESC_DFLT
),
'W%d01' % settings.BASE_FORMAT_ID: (
'Incoherent interpreter comment and executable permission. '
'Interpreter: [%s] Exec perm: %s',
'You have a python file with execution permissions but you don\'t '
'have a interpreter magic comment. '
'If you really needs a execution permission then add a magic comment '
'( https://en.wikipedia.org/wiki/Shebang_(Unix) ). '
'If you don\'t needs a execution permission then remove it with: '
'chmod -x %s',
'incoherent-interpreter-exec-perm',
settings.DESC_DFLT
),
Expand Down Expand Up @@ -84,4 +88,5 @@ def process_tokens(self, tokens):
if bool(interpreter_content) != access_x:
self.add_message(
'incoherent-interpreter-exec-perm',
line=line_num, args=(interpreter_content, access_x))
line=line_num, args=(
os.path.basename(self.linter.current_file)))
49 changes: 48 additions & 1 deletion pylint_odoo/checkers/modules_odoo.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,17 @@
'missing-manifest-dependency',
settings.DESC_DFLT
),
'W%d38' % settings.BASE_OMODULE_ID: (
'pass into block except. '
'If you really need to use the pass consider logging that exception',
'except-pass',
settings.DESC_DFLT
),
'W%d37' % settings.BASE_OMODULE_ID: (
'%s The xml attribute is missing the translation="off" tag %s',
'xml-attribute-translatable',
settings.DESC_DFLT
),
}


Expand All @@ -143,6 +154,10 @@
'unittest2', 'usb', 'vatnumber', 'vobject', 'werkzeug',
'wsgiref', 'xlsxwriter', 'xlwt', 'yaml',
]
DFTL_JSLINTRC = os.path.join(
os.path.dirname(os.path.dirname(os.path.realpath(__file__))),
'examples', '.jslintrc'
)


class ModuleChecker(misc.WrapperModuleChecker):
Expand Down Expand Up @@ -181,6 +196,14 @@ class ModuleChecker(misc.WrapperModuleChecker):
'help': 'List of known import dependencies of odoo,'
' separated by a comma.'
}),
('jslintrc', {
'type': 'string',
'metavar': '<path to file>',
'default': os.environ.get('PYLINT_ODOO_JSLINTRC') or DFTL_JSLINTRC,
'help': ('A path to a file that contains a configuration file of '
'javascript lint. You can use the environment variable '
'"PYLINT_ODOO_JSLINTRC" too. Default: %s' % DFTL_JSLINTRC)
}),
)

class_inherit_names = []
Expand Down Expand Up @@ -334,6 +357,15 @@ def visit_import(self, node):
if isinstance(node.scope(), astroid.Module):
self._check_imported_packages(node, name)

@utils.check_messages('except-pass')
def visit_tryexcept(self, node):
"""Visit block try except"""
for handler in node.handlers:
if (not handler.name and
len(handler.body) == 1 and
isinstance(handler.body[0], astroid.node_classes.Pass)):
self.add_message('except-pass', node=handler)

def _check_rst_syntax_error(self):
"""Check if rst file there is syntax error
:return: False if exists errors and
Expand Down Expand Up @@ -612,7 +644,7 @@ def _check_javascript_lint(self):
self.msg_args = []
for js_file_rel in self.filter_files_ext('js', relpath=True):
js_file = os.path.join(self.module_path, js_file_rel)
errors = self.check_js_lint(js_file)
errors = self.check_js_lint(js_file, self.config.jslintrc)
for error in errors:
self.msg_args.append((js_file_rel + error,))
if self.msg_args:
Expand Down Expand Up @@ -706,3 +738,18 @@ def _check_file_not_used(self):
if self.msg_args:
return False
return True

def _check_xml_attribute_translatable(self):
"""The xml attribute is missing the translation="off" tag
Example <attribute name="groups">sale.group</attribute>
"""
self.msg_args = []
for xml_file in self.filter_files_ext('xml', relpath=True):
for record in self.get_xml_records(
os.path.join(self.module_path, xml_file), None,
'//attribute[not(@translation)]'):
self.msg_args.append(
("%s:%d" % (xml_file, record.sourceline), 'xml_id'))
if self.msg_args:
return False
return True
88 changes: 88 additions & 0 deletions pylint_odoo/checkers/no_modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,21 @@
settings.DESC_DFLT
),
'W%d11' % settings.BASE_NOMODULE_ID: (
'Field parameter "%s" is no longer supported. Use "%s" instead.',
'renamed-field-parameter',
settings.DESC_DFLT
),
'W%d12' % settings.BASE_NOMODULE_ID: (
'"eval" referenced detected.',
'eval-referenced',
settings.DESC_DFLT
),
'W%d13' % settings.BASE_NOMODULE_ID: (
'The attribute string is redundant. '
'String parameter equal to name of variable',
'attribute-string-redundant',
settings.DESC_DFLT
),
}

DFTL_MANIFEST_REQUIRED_KEYS = ['license']
Expand Down Expand Up @@ -226,6 +237,17 @@
DFTL_NO_MISSING_RETURN = [
'__init__', 'setUp', 'tearDown',
]
FIELDS_METHOD = {
'Many2many': 4,
'One2many': 2,
'Many2one': 1,
'Reference': 1,
'Selection': 1,
}
DFTL_DEPRECATED_FIELD_PARAMETERS = [
# From odoo/odoo 10.0: odoo/odoo/fields.py:29
'digits_compute:digits', 'select:index'
]


class NoModuleChecker(BaseChecker):
Expand Down Expand Up @@ -269,6 +291,19 @@ class NoModuleChecker(BaseChecker):
'help': 'List of attributes deprecated, ' +
'separated by a comma.'
}),
('deprecated_field_parameters', {
'type': 'csv',
'metavar': '<comma separated values>',
'default': DFTL_DEPRECATED_FIELD_PARAMETERS,
'help': 'List of deprecated field parameters, separated by a '
'comma. If the param was renamed, separate the old and '
'new name with a colon. If the param was removed, keep '
'the right side of the colon empty. '
'"deprecated_param:" means that "deprecated_param" was '
'deprecated and it doesn\'t have a new alternative. '
'"deprecated_param:new_param" means that it was '
'deprecated and renamed as "new_param". '
}),
('method_required_super', {
'type': 'csv',
'metavar': '<comma separated values>',
Expand Down Expand Up @@ -311,28 +346,81 @@ class NoModuleChecker(BaseChecker):
}),
)

def open(self):
super(NoModuleChecker, self).open()
self.config.deprecated_field_parameters = \
self.colon_list_to_dict(self.config.deprecated_field_parameters)

def colon_list_to_dict(self, colon_list):
"""Converts a colon list to a dictionary.
:param colon_list: A list of strings representing keys and values,
separated with a colon. If a key doesn't have a value, keep the
right side of the colon empty.
:type colon_list: list
:returns: A dictionary with the values assigned to corresponding keys.
:rtype: dict
:Example:
>>> self.colon_list_to_dict(['colon:list', 'empty_key:'])
{'colon': 'list', 'empty_key': ''}
"""
return dict(item.split(":") for item in colon_list)

@utils.check_messages('translation-field', 'invalid-commit',
'method-compute', 'method-search', 'method-inverse',
'sql-injection',
'attribute-string-redundant',
'renamed-field-parameter'
)
def visit_call(self, node):
if node.as_string().lower().startswith('fields.'):
args = misc.join_node_args_kwargs(node)
index = 0
field_name = ''
if (isinstance(node.parent, astroid.Assign) and
node.parent.targets and
isinstance(node.parent.targets[0], astroid.AssignName)):
field_name = (node.parent.targets[0].name
.replace('_', ' '))
for argument in args:
argument_aux = argument
# Check this 'name = fields.Char("name")'
if (isinstance(argument, astroid.Const) and
(index ==
FIELDS_METHOD.get(argument.parent.func.attrname, 0)) and
(argument.value in
[field_name.capitalize(), field_name.title()])):
self.add_message('attribute-string-redundant', node=node)
if isinstance(argument, astroid.Keyword):
argument_aux = argument.value
deprecated = self.config.deprecated_field_parameters
if argument.arg in ['compute', 'search', 'inverse'] and \
isinstance(argument_aux, astroid.Const) and \
isinstance(argument_aux.value, string_types) and \
not argument_aux.value.startswith(
'_' + argument.arg + '_'):
self.add_message('method-' + argument.arg,
node=argument_aux)
# Check if the param string is equal to the name
# of variable
elif argument.arg == 'string' and \
(isinstance(argument_aux, astroid.Const) and
argument_aux.value in
[field_name.capitalize(), field_name.title()]):
self.add_message(
'attribute-string-redundant', node=node)
elif (argument.arg in deprecated):
self.add_message(
'renamed-field-parameter', node=node,
args=(argument.arg, deprecated[argument.arg])
)
if isinstance(argument_aux, astroid.CallFunc) and \
isinstance(argument_aux.func, astroid.Name) and \
argument_aux.func.name == '_':
self.add_message('translation-field', node=argument_aux)
index += 1
# Check cr.commit()
if isinstance(node, astroid.CallFunc) and \
isinstance(node.func, astroid.Getattr) and \
Expand Down
Loading

0 comments on commit 24fd5fb

Please sign in to comment.