pylint/checkers/strings.py
def _check_new_format_specifiers(self, node, fields, named):
        """
        Check attribute and index access in the format
        string ("{0.a}" and "{0[a]}").
        """
        for key, specifiers in fields:
            # Obtain the argument. If it can't be obtained
            # or infered, skip this check.
            if key == "":
                # {[0]} will have an unnamed argument, defaulting
                # to 0. It will not be present in `named`, so use the value
                # 0 for it.
                key = 0
            if isinstance(key, numbers.Number):
                try:
                    argname = utils.get_argument_from_call(node, key)
                except utils.NoSuchArgumentError:
                    continue
            else:
                if key not in named:
                    continue
                argname = named[key]
            if argname in (astroid.Uninferable, None):
                continue
            try:
                argument = next(argname.infer())
            except astroid.InferenceError:
                continue
            if not specifiers or argument is astroid.Uninferable:
                # No need to check this key if it doesn't
                # use attribute / item access
                continue
            if argument.parent and isinstance(argument.parent, astroid.Arguments):
                # Ignore any object coming from an argument,
                # because we can't infer its value properly.
                continue
            previous = argument
            parsed = []
            for is_attribute, specifier in specifiers:
                if previous is astroid.Uninferable:
                    break
                parsed.append((is_attribute, specifier))
                if is_attribute:
                    try:
                        previous = previous.getattr(specifier)[0]
                    except astroid.NotFoundError:
                        if (
                            hasattr(previous, "has_dynamic_getattr")
                            and previous.has_dynamic_getattr()
                        ):
                            # Don't warn if the object has a custom __getattr__
                            break
                        path = get_access_path(key, parsed)
                        self.add_message(
                            "missing-format-attribute",
                            args=(specifier, path),
                            node=node,
                        )
                        break
                else:
                    warn_error = False
                    if hasattr(previous, "getitem"):
                        try:
                            previous = previous.getitem(astroid.Const(specifier))
                        except (
                            astroid.AstroidIndexError,
                            astroid.AstroidTypeError,
                            astroid.AttributeInferenceError,
                        ):
                            warn_error = True
                        except astroid.InferenceError:
                            break
                        if previous is astroid.Uninferable:
                            break
                    else:
                        try:
                            # Lookup __getitem__ in the current node,
                            # but skip further checks, because we can't
                            # retrieve the looked object
                            previous.getattr("__getitem__")
                            break
                        except astroid.NotFoundError:
                            warn_error = True
                    if warn_error:
                        path = get_access_path(key, parsed)
                        self.add_message(
                            "invalid-format-index", args=(specifier, path), node=node
                        )
                        break

                try:
                    previous = next(previous.infer())
                except astroid.InferenceError:
                    # can't check further if we can't infer it
                    break
def _check_new_format_specifiers(self, node, fields, named):
        """
        Check attribute and index access in the format
        string ("{0.a}" and "{0[a]}").
        """
        for key, specifiers in fields:
            # Obtain the argument. If it can't be obtained
            # or infered, skip this check.
            if key == "":
                # {[0]} will have an unnamed argument, defaulting
                # to 0. It will not be present in `named`, so use the value
                # 0 for it.
                key = 0
            if isinstance(key, numbers.Number):
                try:
                    argname = utils.get_argument_from_call(node, key)
                except utils.NoSuchArgumentError:
                    continue
            else:
                if key not in named:
                    continue
                argname = named[key]
            if argname in (astroid.Uninferable, None):
                continue
            try:
                argument = next(argname.infer())
            except astroid.InferenceError:
                continue
            if not specifiers or argument is astroid.Uninferable:
                # No need to check this key if it doesn't
                # use attribute / item access
                continue
            if argument.parent and isinstance(argument.parent, astroid.Arguments):
                # Ignore any object coming from an argument,
                # because we can't infer its value properly.
                continue
            previous = argument
            parsed = []
            for is_attribute, specifier in specifiers:
                if previous is astroid.Uninferable:
                    break
                parsed.append((is_attribute, specifier))
                if is_attribute:
                    try:
                        previous = previous.getattr(specifier)[0]
                    except astroid.NotFoundError:
                        if (
                            hasattr(previous, "has_dynamic_getattr")
                            and previous.has_dynamic_getattr()
                        ):
                            # Don't warn if the object has a custom __getattr__
                            break
                        path = get_access_path(key, parsed)
                        self.add_message(
                            "missing-format-attribute",
                            args=(specifier, path),
                            node=node,
                        )
                        break
                else:
                    warn_error = False
                    if hasattr(previous, "getitem"):
                        try:
                            previous = previous.getitem(astroid.Const(specifier))
                        except (
                            astroid.AstroidIndexError,
                            astroid.AstroidTypeError,
                            astroid.AttributeInferenceError,
                        ):
                            warn_error = True
                        except astroid.InferenceError:
                            break
                        if previous is astroid.Uninferable:
                            break
                    else:
                        try:
                            # Lookup __getitem__ in the current node,
                            # but skip further checks, because we can't
                            # retrieve the looked object
                            previous.getattr("__getitem__")
                            break
                        except astroid.NotFoundError:
                            warn_error = True
                    if warn_error:
                        path = get_access_path(key, parsed)
                        self.add_message(
                            "invalid-format-index", args=(specifier, path), node=node
                        )
                        break

                try:
                    previous = next(previous.infer())
                except astroid.InferenceError:
                    # can't check further if we can't infer it
                    break
def _check_new_format_specifiers ( self , node , fields , named ) : for key , specifiers in fields : # Obtain the argument. If it can't be obtained # or infered, skip this check. if key == "" : # {[0]} will have an unnamed argument, defaulting # to 0. It will not be present in `named`, so use the value # 0 for it. key = 0 if isinstance ( key , numbers . Number ) : try : argname = utils . get_argument_from_call ( node , key ) except utils . NoSuchArgumentError : continue else : if key not in named : continue argname = named [ key ] if argname in ( astroid . Uninferable , None ) : continue try : argument = next ( argname . infer ( ) ) except astroid . InferenceError : continue if not specifiers or argument is astroid . Uninferable : # No need to check this key if it doesn't # use attribute / item access continue if argument . parent and isinstance ( argument . parent , astroid . Arguments ) : # Ignore any object coming from an argument, # because we can't infer its value properly. continue previous = argument parsed = [ ] for is_attribute , specifier in specifiers : if previous is astroid . Uninferable : break parsed . append ( ( is_attribute , specifier ) ) if is_attribute : try : previous = previous . getattr ( specifier ) [ 0 ] except astroid . NotFoundError : if ( hasattr ( previous , "has_dynamic_getattr" ) and previous . has_dynamic_getattr ( ) ) : # Don't warn if the object has a custom __getattr__ break path = get_access_path ( key , parsed ) self . add_message ( "missing-format-attribute" , args = ( specifier , path ) , node = node , ) break else : warn_error = False if hasattr ( previous , "getitem" ) : try : previous = previous . getitem ( astroid . Const ( specifier ) ) except ( astroid . AstroidIndexError , astroid . AstroidTypeError , astroid . AttributeInferenceError , ) : warn_error = True except astroid . InferenceError : break if previous is astroid . Uninferable : break else : try : # Lookup __getitem__ in the current node, # but skip further checks, because we can't # retrieve the looked object previous . getattr ( "__getitem__" ) break except astroid . NotFoundError : warn_error = True if warn_error : path = get_access_path ( key , parsed ) self . add_message ( "invalid-format-index" , args = ( specifier , path ) , node = node ) break try : previous = next ( previous . infer ( ) ) except astroid . InferenceError : # can't check further if we can't infer it break
Check attribute and index access in the format
        string ("{0.a}" and "{0[a]}").
Check attribute and index access in the format string ( { 0 . a } and { 0 [ a ] } ) .