Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ In the case of a false positive, use the disable command to remove the pylint er


| Pylint checker name | How to fix this | How to disable this rule | Link to python guideline |
|----------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------| ------------------------------------------------------------------------------------------------------- |
|----------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------|
| client-method-should-not-use-static-method | Use module level functions instead. | # pylint:disable=client-method-should-not-use-static-method | [link](https://azure.github.io/azure-sdk/python_implementation.html#method-signatures) |
| missing-client-constructor-parameter-credential | Add a credential parameter to the client constructor. Do not use plural form "credentials". | # pylint:disable=missing-client-constructor-parameter-credential | [link](https://azure.github.io/azure-sdk/python_design.html#client-configuration) |
| missing-client-constructor-parameter-kwargs | Add a \*\*kwargs parameter to the client constructor. | # pylint:disable=missing-client-constructor-parameter-kwargs | [link](https://azure.github.io/azure-sdk/python_design.html#client-configuration) |
Expand Down Expand Up @@ -94,8 +94,10 @@ In the case of a false positive, use the disable command to remove the pylint er
| docstring-type-do-not-use-class | Docstring type is formatted incorrectly. Do not use `:class` in docstring type. | pylint:disable=docstring-type-do-not-use-class | [link](https://sphinx-rtd-tutorial.readthedocs.io/en/latest/docstrings.html) |
| no-typing-import-in-type-check | Do not import typing under TYPE_CHECKING. | pylint:disable=no-typing-import-in-type-check | No Link. |
| do-not-log-raised-errors | Do not log errors at `error` or `warning` level when error is raised in an exception block. | pylint:disable=do-not-log-raised-errors | No Link. |
| do-not-use-legacy-typing | Do not use legacy (<Python 3.8) type hinting comments | pylint:disable=do-not-use-legacy-typing | No Link.
| do-not-import-asyncio | Do not import asyncio directly. | pylint:disable=do-not-import-asyncio | No Link. || TODO | custom linter check for invalid use of @overload #3229 | | |
| do-not-use-legacy-typing | Do not use legacy (<Python 3.8) type hinting comments | pylint:disable=do-not-use-legacy-typing | No Link.
| do-not-import-asyncio | Do not import asyncio directly. | pylint:disable=do-not-import-asyncio | No Link. |
| TODO | custom linter check for invalid use of @overload #3229 | | |
| TODO | Custom Linter check for Exception Logging #3227 | | |
| TODO | Address Commented out Pylint Custom Plugin Checkers #3228 | | |
| TODO | Add a check for connection_verify hardcoded settings #35355 | | |
| do-not-hardcode-connection-verify | Do not hardcode a boolean value to connection_verify | pylint:disable=do-not-hardcode-connection-verify | No LInk. |

Original file line number Diff line number Diff line change
Expand Up @@ -2841,7 +2841,6 @@ class DoNotImportAsyncio(BaseChecker):

name = "do-not-import-asyncio"
priority = -1
# TODO Find message number
msgs = {
"C4763": (
"Do not import the asyncio package directly in your library",
Expand Down Expand Up @@ -2873,7 +2872,84 @@ def visit_import(self, node):
# [Pylint] custom linter check for invalid use of @overload #3229
# [Pylint] Custom Linter check for Exception Logging #3227
# [Pylint] Address Commented out Pylint Custom Plugin Checkers #3228
# [Pylint] Add a check for connection_verify hardcoded settings #35355

class DoNotHardcodeConnectionVerify(BaseChecker):

"""Rule to check that developers do not hardcode a boolean to connection_verify."""

name = "do-not-hardcode-connection-verify"
priority = -1
msgs = {
"C4767": (
"Do not hardcode a boolean value to connection_verify",
"do-not-hardcode-connection-verify",
"Do not hardcode a boolean value to connection_verify. It's up to customers who use the code to be able to set it",
),
}


def visit_call(self, node):
"""Visit function calls to ensure it isn't used as a parameter"""
try:
for keyword in node.keywords:
if keyword.arg == "connection_verify":
if type(keyword.value.value) == bool:
self.add_message(
msgid=f"do-not-hardcode-connection-verify",
node=keyword,
confidence=None,
)
except:
pass


def visit_assign(self, node):
"""Visiting variable Assignments"""
try: # Picks up self.connection_verify = True
if node.targets[0].attrname == "connection_verify":
if type(node.value.value) == bool:
self.add_message(
msgid=f"do-not-hardcode-connection-verify",
node=node,
confidence=None,
)
except:
try: # connection_verify = True
if node.targets[0].name == "connection_verify":
if type(node.value.value) == bool:
self.add_message(
msgid=f"do-not-hardcode-connection-verify",
node=node,
confidence=None,
)
except:
pass


def visit_annassign(self, node):
"""Visiting variable annotated assignments"""
try: # self.connection_verify: bool = True
if node.target.attrname == "connection_verify":
if type(node.value.value) == bool:
self.add_message(
msgid=f"do-not-hardcode-connection-verify",
node=node,
confidence=None,
)
except: # Picks up connection_verify: bool = True
try:
if node.target.name == "connection_verify":
if type(node.value.value) == bool:
self.add_message(
msgid=f"do-not-hardcode-connection-verify",
node=node,
confidence=None,
)
except:
pass



# [Pylint] Refactor test suite for custom pylint checkers to use files instead of docstrings #3233
# [Pylint] Investigate pylint rule around missing dependency #3231

Expand Down Expand Up @@ -2913,11 +2989,10 @@ def register(linter):
linter.register_checker(NoImportTypingFromTypeCheck(linter))
linter.register_checker(DoNotUseLegacyTyping(linter))
linter.register_checker(DoNotLogErrorsEndUpRaising(linter))

# [Pylint] custom linter check for invalid use of @overload #3229
# [Pylint] Custom Linter check for Exception Logging #3227
# [Pylint] Address Commented out Pylint Custom Plugin Checkers #3228
# [Pylint] Add a check for connection_verify hardcoded settings #35355
linter.register_checker(DoNotHardcodeConnectionVerify(linter))
# [Pylint] Refactor test suite for custom pylint checkers to use files instead of docstrings #3233
# [Pylint] Investigate pylint rule around missing dependency #3231

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
class InstanceVariableError:
def __init__(self):
self.connection_verify = None
self.self = self


class VariableError:
connection_verify = None


class FunctionArgumentsErrors:
def create(connection_verify):
pass

client = create(connection_verify=None)


class FunctionArgumentsInstanceErrors:
def __init__(self):
client = self.create_client_from_credential(connection_verify=None)


class ReturnErrorFunctionArgument:
def send(connection_verify):
pass

def sampleFunction(self):
return self.send(connection_verify=None)


class ReturnErrorDict:
def returnDict(self):

return dict(
connection_verify=None,
)

class AnnotatedAssignment:
connection_verify: bool = None

def __init__(self):
self.connection_verify: bool = None






Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
class InstanceVariableError:
def __init__(self):
self.connection_verify = True
self.self = self


class VariableError:
connection_verify = True


class FunctionArgumentsErrors:
def create(connection_verify):
pass

client = create(connection_verify=False)


class FunctionArgumentsInstanceErrors:
def __init__(self):
client = self.create_client_from_credential(connection_verify=False)


class ReturnErrorFunctionArgument:
def send(connection_verify):
pass

def sampleFunction(self):
return self.send(connection_verify=True)


class ReturnErrorDict:
def returnDict(self):

return dict(
connection_verify=False,
)

class AnnotatedAssignment:
connection_verify: bool = True

def __init__(self):
self.connection_verify: bool = True






Original file line number Diff line number Diff line change
Expand Up @@ -3651,7 +3651,131 @@ def function(x): #@
# [Pylint] custom linter check for invalid use of @overload #3229
# [Pylint] Custom Linter check for Exception Logging #3227
# [Pylint] Address Commented out Pylint Custom Plugin Checkers #3228


class TestDoNotHardcodeConnectionVerify(pylint.testutils.CheckerTestCase):
"""Test that we are not hard-coding a True or False to connection_verify"""

CHECKER_CLASS = checker.DoNotHardcodeConnectionVerify

def test_valid_connection_verify(self):
"""Check that valid connection_verify hard coding does not raise warnings"""
file = open(
os.path.join(
TEST_FOLDER, "test_files", "do_not_hardcode_connection_verify_acceptable.py"
)
)
node = astroid.parse(file.read())
file.close()

nodes = node.body
InstanceVariableError = nodes[0].body[0].body[0]
VariableError = nodes[1].body[0]
FunctionArgumentsErrors = nodes[2].body[1].value
FunctionArgumentsInstanceErrors = nodes[3].body[0].body[0].value
ReturnErrorFunctionArgument = nodes[4].body[1].body[0].value
ReturnErrorDict = nodes[5].body[0].body[0].value
AnnotatedAssignment = nodes[6].body[0]

with self.assertNoMessages():
self.checker.visit_assign(InstanceVariableError)
self.checker.visit_assign(VariableError)
self.checker.visit_call(FunctionArgumentsErrors)
self.checker.visit_call(FunctionArgumentsInstanceErrors)
self.checker.visit_call(ReturnErrorFunctionArgument)
self.checker.visit_call(ReturnErrorDict)
self.checker.visit_annassign(AnnotatedAssignment)


def test_invalid_connection_verify(self):
"""Check that hard-coding connection_verify to a bool raise warnings"""
file = open(
os.path.join(
TEST_FOLDER, "test_files", "do_not_hardcode_connection_verify_violation.py"
)
)
node = astroid.parse(file.read())
file.close()

nodes = node.body
InstanceVariableError = nodes[0].body[0].body[0]
VariableError = nodes[1].body[0]
FunctionArgumentsErrors = nodes[2].body[1].value
FunctionArgumentsInstanceErrors = nodes[3].body[0].body[0].value
ReturnErrorFunctionArgument = nodes[4].body[1].body[0].value
ReturnErrorDict = nodes[5].body[0].body[0].value
AnnotatedAssignment = nodes[6].body[0]

with self.assertAddsMessages(
pylint.testutils.MessageTest(
msg_id="do-not-hardcode-connection-verify",
line=3,
node=InstanceVariableError,
col_offset=8,
end_line=3,
end_col_offset=37,
),
pylint.testutils.MessageTest(
msg_id="do-not-hardcode-connection-verify",
line=8,
node=VariableError,
col_offset=4,
end_line=8,
end_col_offset=28,
),
pylint.testutils.MessageTest(
msg_id="do-not-hardcode-connection-verify",
line=15,
node=FunctionArgumentsErrors.keywords[0],
col_offset=20,
end_line=15,
end_col_offset=43,
),
pylint.testutils.MessageTest(
msg_id="do-not-hardcode-connection-verify",
line=20,
node=FunctionArgumentsInstanceErrors.keywords[0],
col_offset=52,
end_line=20,
end_col_offset=75,
),
pylint.testutils.MessageTest(
msg_id="do-not-hardcode-connection-verify",
line=28,
node=ReturnErrorFunctionArgument.keywords[0],
col_offset=25,
end_line=28,
end_col_offset=47,
),
pylint.testutils.MessageTest(
msg_id="do-not-hardcode-connection-verify",
line=35,
node=ReturnErrorDict.keywords[0],
col_offset=12,
end_line=35,
end_col_offset=35,
),
pylint.testutils.MessageTest(
msg_id="do-not-hardcode-connection-verify",
line=39,
node=AnnotatedAssignment,
col_offset=4,
end_line=39,
end_col_offset=34,
),
):


self.checker.visit_assign(InstanceVariableError)
self.checker.visit_assign(VariableError)
self.checker.visit_call(FunctionArgumentsErrors)
self.checker.visit_call(FunctionArgumentsInstanceErrors)
self.checker.visit_call(ReturnErrorFunctionArgument)
self.checker.visit_call(ReturnErrorDict)
self.checker.visit_annassign(AnnotatedAssignment)


# [Pylint] Add a check for connection_verify hardcoded settings #35355
# [Pylint] Refactor test suite for custom pylint checkers to use files instead of docstrings #3233
# [Pylint] Investigate pylint rule around missing dependency #3231