pylint/checkers/format.py
def _check_keyword_parentheses(self, tokens, start):
        """Check that there are not unnecessary parens after a keyword.

        Parens are unnecessary if there is exactly one balanced outer pair on a
        line, and it is followed by a colon, and contains no commas (i.e. is not a
        tuple).

        Args:
        tokens: list of Tokens; the entire list of Tokens.
        start: int; the position of the keyword in the token list.
        """
        # If the next token is not a paren, we're fine.
        if self._inside_brackets(":") and tokens[start][1] == "for":
            self._pop_token()
        if tokens[start + 1][1] != "(":
            return

        found_and_or = False
        depth = 0
        keyword_token = str(tokens[start][1])
        line_num = tokens[start][2][0]

        for i in range(start, len(tokens) - 1):
            token = tokens[i]

            # If we hit a newline, then assume any parens were for continuation.
            if token[0] == tokenize.NL:
                return

            if token[1] == "(":
                depth += 1
            elif token[1] == ")":
                depth -= 1
                if depth:
                    continue
                # ')' can't happen after if (foo), since it would be a syntax error.
                if tokens[i + 1][1] in (":", ")", "]", "}", "in") or tokens[i + 1][
                    0
                ] in (tokenize.NEWLINE, tokenize.ENDMARKER, tokenize.COMMENT):
                    # The empty tuple () is always accepted.
                    if i == start + 2:
                        return
                    if keyword_token == "not":
                        if not found_and_or:
                            self.add_message(
                                "superfluous-parens", line=line_num, args=keyword_token
                            )
                    elif keyword_token in ("return", "yield"):
                        self.add_message(
                            "superfluous-parens", line=line_num, args=keyword_token
                        )
                    elif keyword_token not in self._keywords_with_parens:
                        if not found_and_or:
                            self.add_message(
                                "superfluous-parens", line=line_num, args=keyword_token
                            )
                return
            elif depth == 1:
                # This is a tuple, which is always acceptable.
                if token[1] == ",":
                    return
                # 'and' and 'or' are the only boolean operators with lower precedence
                # than 'not', so parens are only required when they are found.
                if token[1] in ("and", "or"):
                    found_and_or = True
                # A yield inside an expression must always be in parentheses,
                # quit early without error.
                elif token[1] == "yield":
                    return
                # A generator expression always has a 'for' token in it, and
                # the 'for' token is only legal inside parens when it is in a
                # generator expression.  The parens are necessary here, so bail
                # without an error.
                elif token[1] == "for":
                    return
def _check_keyword_parentheses(self, tokens, start):
        # If the next token is not a paren, we're fine.
        if self._inside_brackets(":") and tokens[start][1] == "for":
            self._pop_token()
        if tokens[start + 1][1] != "(":
            return

        found_and_or = False
        depth = 0
        keyword_token = str(tokens[start][1])
        line_num = tokens[start][2][0]

        for i in range(start, len(tokens) - 1):
            token = tokens[i]

            # If we hit a newline, then assume any parens were for continuation.
            if token[0] == tokenize.NL:
                return

            if token[1] == "(":
                depth += 1
            elif token[1] == ")":
                depth -= 1
                if depth:
                    continue
                # ')' can't happen after if (foo), since it would be a syntax error.
                if tokens[i + 1][1] in (":", ")", "]", "}", "in") or tokens[i + 1][
                    0
                ] in (tokenize.NEWLINE, tokenize.ENDMARKER, tokenize.COMMENT):
                    # The empty tuple () is always accepted.
                    if i == start + 2:
                        return
                    if keyword_token == "not":
                        if not found_and_or:
                            self.add_message(
                                "superfluous-parens", line=line_num, args=keyword_token
                            )
                    elif keyword_token in ("return", "yield"):
                        self.add_message(
                            "superfluous-parens", line=line_num, args=keyword_token
                        )
                    elif keyword_token not in self._keywords_with_parens:
                        if not found_and_or:
                            self.add_message(
                                "superfluous-parens", line=line_num, args=keyword_token
                            )
                return
            elif depth == 1:
                # This is a tuple, which is always acceptable.
                if token[1] == ",":
                    return
                # 'and' and 'or' are the only boolean operators with lower precedence
                # than 'not', so parens are only required when they are found.
                if token[1] in ("and", "or"):
                    found_and_or = True
                # A yield inside an expression must always be in parentheses,
                # quit early without error.
                elif token[1] == "yield":
                    return
                # A generator expression always has a 'for' token in it, and
                # the 'for' token is only legal inside parens when it is in a
                # generator expression.  The parens are necessary here, so bail
                # without an error.
                elif token[1] == "for":
                    return
def _check_keyword_parentheses ( self , tokens , start ) : # If the next token is not a paren, we're fine. if self . _inside_brackets ( ":" ) and tokens [ start ] [ 1 ] == "for" : self . _pop_token ( ) if tokens [ start + 1 ] [ 1 ] != "(" : return found_and_or = False depth = 0 keyword_token = str ( tokens [ start ] [ 1 ] ) line_num = tokens [ start ] [ 2 ] [ 0 ] for i in range ( start , len ( tokens ) - 1 ) : token = tokens [ i ] # If we hit a newline, then assume any parens were for continuation. if token [ 0 ] == tokenize . NL : return if token [ 1 ] == "(" : depth += 1 elif token [ 1 ] == ")" : depth -= 1 if depth : continue # ')' can't happen after if (foo), since it would be a syntax error. if tokens [ i + 1 ] [ 1 ] in ( ":" , ")" , "]" , "}" , "in" ) or tokens [ i + 1 ] [ 0 ] in ( tokenize . NEWLINE , tokenize . ENDMARKER , tokenize . COMMENT ) : # The empty tuple () is always accepted. if i == start + 2 : return if keyword_token == "not" : if not found_and_or : self . add_message ( "superfluous-parens" , line = line_num , args = keyword_token ) elif keyword_token in ( "return" , "yield" ) : self . add_message ( "superfluous-parens" , line = line_num , args = keyword_token ) elif keyword_token not in self . _keywords_with_parens : if not found_and_or : self . add_message ( "superfluous-parens" , line = line_num , args = keyword_token ) return elif depth == 1 : # This is a tuple, which is always acceptable. if token [ 1 ] == "," : return # 'and' and 'or' are the only boolean operators with lower precedence # than 'not', so parens are only required when they are found. if token [ 1 ] in ( "and" , "or" ) : found_and_or = True # A yield inside an expression must always be in parentheses, # quit early without error. elif token [ 1 ] == "yield" : return # A generator expression always has a 'for' token in it, and # the 'for' token is only legal inside parens when it is in a # generator expression.  The parens are necessary here, so bail # without an error. elif token [ 1 ] == "for" : return
Check that there are not unnecessary parens after a keyword.

        Parens are unnecessary if there is exactly one balanced outer pair on a
        line, and it is followed by a colon, and contains no commas (i.e. is not a
        tuple).

        Args:
        tokens: list of Tokens; the entire list of Tokens.
        start: int; the position of the keyword in the token list.
Check that there are not unnecessary parens after a keyword .