Skip to content

Commit

Permalink
Merge 41836bd into d260411
Browse files Browse the repository at this point in the history
  • Loading branch information
moylop260 committed May 24, 2022
2 parents d260411 + 41836bd commit fae9a11
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 1 deletion.
48 changes: 47 additions & 1 deletion pylint_odoo/checkers/no_modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@
'str-format-used',
settings.DESC_DFLT
),
'E%d06' % settings.BASE_NOMODULE_ID: (
'Use of external request method `%s` without timeout. '
'It could wait for a long time',
'external-request-timeout',
settings.DESC_DFLT
),
'C%d01' % settings.BASE_NOMODULE_ID: (
'One of the following authors must be present in manifest: %s',
'manifest-required-author',
Expand Down Expand Up @@ -415,6 +421,14 @@ class NoModuleChecker(misc.PylintOdooChecker):
}),
)

def visit_module(self, node):
"""Initialize dictionary to store imported nodes names"""
self.imported_names = {}

def leave_module(self, node):
"""Clear variables"""
self.imported_names = {}

def open(self):
super(NoModuleChecker, self).open()
self.config.deprecated_field_parameters = \
Expand Down Expand Up @@ -589,6 +603,7 @@ def visit_print(self, node):
'translation-contains-variable',
'print-used', 'translation-positional-used',
'str-format-used', 'context-overridden',
'external-request-timeout',
)
def visit_call(self, node):
infer_node = utils.safe_infer(node.func)
Expand Down Expand Up @@ -750,6 +765,29 @@ def visit_call(self, node):
if self._check_sql_injection_risky(node):
self.add_message('sql-injection', node=node)

# requests calls
func_name = self.get_func_name(node.func)
request_meth_timeout = [
'requests.delete', 'requests.get', 'requests.head',
'requests.options', 'requests.patch', 'requests.post',
'requests.put', 'requests.request',
'suds.client.Client',
'urllib.request.urlopen',
'http.client.HTTPConnection', 'http.client.HTTPSConnection',
# TODO: Consider serial.Serial, iap.jsonrpc, smtplib.SMTP, lock.acquire,
]
lib_func = (self.imported_names.get(func_name) or
"%s.%s" % (self.get_func_lib(node.func), func_name))
if lib_func in request_meth_timeout:
for argument in misc.join_node_args_kwargs(node):
if not isinstance(argument, astroid.Keyword):
continue
if argument.arg == 'timeout':
break
else:
self.add_message(
'external-request-timeout', node=node, args=(lib_func,))

@utils.check_messages(
'license-allowed', 'manifest-author-string', 'manifest-deprecated-key',
'manifest-required-author', 'manifest-required-key',
Expand Down Expand Up @@ -911,12 +949,20 @@ def visit_functiondef(self, node):
node.name not in self.config.no_missing_return:
self.add_message('missing-return', node=node, args=(node.name))

@utils.check_messages('openerp-exception-warning')
@utils.check_messages('openerp-exception-warning', 'external-request-timeout')
def visit_importfrom(self, node):
if node.modname == 'openerp.exceptions':
for (import_name, import_as_name) in node.names:
if import_name == 'Warning' and import_as_name != 'UserError':
self.add_message('openerp-exception-warning', node=node)
# Fill dict "self.imported_names" to know the source library imported
request_libs = ['requests', 'urllib.request', 'suds.client', 'http.client']
if node.modname in request_libs:
self.imported_names.update({
alias or name: "%s.%s" % (node.modname, name)
for name, alias in node.names
# "import requests" will be detected with "requests.get"
if not (name in request_libs and not alias)})

@utils.check_messages('class-camelcase')
def visit_classdef(self, node):
Expand Down
1 change: 1 addition & 0 deletions pylint_odoo/test/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
'duplicate-po-message-definition': 2,
'duplicate-xml-fields': 9,
'duplicate-xml-record-id': 2,
'external-request-timeout': 36,
'file-not-used': 6,
'incoherent-interpreter-exec-perm': 3,
'invalid-commit': 4,
Expand Down
115 changes: 115 additions & 0 deletions pylint_odoo/test_repo/broken_module/models/broken_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,28 @@
import psycopg2
from psycopg2 import sql
from psycopg2.sql import SQL, Identifier
import requests
from requests import (
delete, get, head, options, patch, post, put, request)
from requests import (
delete as delete_r, get as get_r, head as head_r,
options as options_r, patch as patch_r, post as post_r,
put as put_r, request as request_r)

import urllib
from urllib.request import urlopen
from urllib.request import urlopen as urlopen_r

import suds.client
from suds.client import Client
from suds.client import Client as Client_r

import http.client
from http.client import HTTPConnection, HTTPSConnection
from http.client import (
HTTPConnection as HTTPConnection_r,
HTTPSConnection as HTTPSConnection_r,
)

from openerp import fields, models, _
from openerp.exceptions import Warning as UserError
Expand Down Expand Up @@ -537,6 +559,99 @@ def func(self, a):
length = len(a)
return length

def requests_test(self):
# requests without timeout
requests.delete('http://localhost')
requests.get('http://localhost')
requests.head('http://localhost')
requests.options('http://localhost')
requests.patch('http://localhost')
requests.post('http://localhost')
requests.put('http://localhost')
requests.request('call', 'http://localhost')

delete_r('http://localhost')
get_r('http://localhost')
head_r('http://localhost')
options_r('http://localhost')
patch_r('http://localhost')
post_r('http://localhost')
put_r('http://localhost')
request_r('call', 'http://localhost')

delete('http://localhost')
get('http://localhost')
head('http://localhost')
options('http://localhost')
patch('http://localhost')
post('http://localhost')
put('http://localhost')
request('call', 'http://localhost')

# urllib without timeout
urllib.request.urlopen('http://localhost')
urlopen('http://localhost')
urlopen_r('http://localhost')

# suds without timeout
suds.client.Client('http://localhost')
Client('http://localhost')
Client_r('http://localhost')

# http.client without timeout
http.client.HTTPConnection('http://localhost')
http.client.HTTPSConnection('http://localhost')
HTTPConnection('http://localhost')
HTTPSConnection('http://localhost')
HTTPConnection_r('http://localhost')
HTTPSConnection_r('http://localhost')

# requests valid cases
requests.delete('http://localhost', timeout=10)
requests.get('http://localhost', timeout=10)
requests.head('http://localhost', timeout=10)
requests.options('http://localhost', timeout=10)
requests.patch('http://localhost', timeout=10)
requests.post('http://localhost', timeout=10)
requests.put('http://localhost', timeout=10)
requests.request('call', 'http://localhost', timeout=10)

delete_r('http://localhost', timeout=10)
get_r('http://localhost', timeout=10)
head_r('http://localhost', timeout=10)
options_r('http://localhost', timeout=10)
patch_r('http://localhost', timeout=10)
post_r('http://localhost', timeout=10)
put_r('http://localhost', timeout=10)
request_r('call', 'http://localhost', timeout=10)

delete('http://localhost', timeout=10)
get('http://localhost', timeout=10)
head('http://localhost', timeout=10)
options('http://localhost', timeout=10)
patch('http://localhost', timeout=10)
post('http://localhost', timeout=10)
put('http://localhost', timeout=10)
request('call', 'http://localhost', timeout=10)

# urllib valid cases
urllib.request.urlopen('http://localhost', timeout=10)
urlopen('http://localhost', timeout=10)
urlopen_r('http://localhost', timeout=10)

# suds valid cases
suds.client.Client('http://localhost', timeout=10)
Client('http://localhost', timeout=10)
Client_r('http://localhost', timeout=10)

# http.client valid cases
http.client.HTTPConnection('http://localhost', timeout=10)
http.client.HTTPSConnection('http://localhost', timeout=10)
HTTPConnection('http://localhost', timeout=10)
HTTPSConnection('http://localhost', timeout=10)
HTTPConnection_r('http://localhost', timeout=10)
HTTPSConnection_r('http://localhost', timeout=10)


class NoOdoo(object):
length = 0
Expand Down

0 comments on commit fae9a11

Please sign in to comment.