<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;"># Copyright 2007 Google, Inc. All Rights Reserved.
# Licensed to PSF under a Contributor Agreement.

"""Fixer that changes map(F, ...) into list(map(F, ...)) unless there
exists a 'from future_builtins import map' statement in the top-level
namespace.

As a special case, map(None, X) is changed into list(X).  (This is
necessary because the semantics are changed in this case -- the new
map(None, X) is equivalent to [(x,) for x in X].)

We avoid the transformation (except for the special case mentioned
above) if the map() call is directly contained in iter(&lt;&gt;), list(&lt;&gt;),
tuple(&lt;&gt;), sorted(&lt;&gt;), ...join(&lt;&gt;), or for V in &lt;&gt;:.

NOTE: This is still not correct if the original code was depending on
map(F, X, Y, ...) to go on until the longest argument is exhausted,
substituting None for missing values -- like zip(), it now stops as
soon as the shortest argument is exhausted.
"""

# Local imports
from ..pgen2 import token
from .. import fixer_base
from ..fixer_util import Name, Call, ListComp, in_special_context
from ..pygram import python_symbols as syms

class FixMap(fixer_base.ConditionalFix):
    BM_compatible = True

    PATTERN = """
    map_none=power&lt;
        'map'
        trailer&lt; '(' arglist&lt; 'None' ',' arg=any [','] &gt; ')' &gt;
    &gt;
    |
    map_lambda=power&lt;
        'map'
        trailer&lt;
            '('
            arglist&lt;
                lambdef&lt; 'lambda'
                         (fp=NAME | vfpdef&lt; '(' fp=NAME ')'&gt; ) ':' xp=any
                &gt;
                ','
                it=any
            &gt;
            ')'
        &gt;
    &gt;
    |
    power&lt;
        'map' trailer&lt; '(' [arglist=any] ')' &gt;
    &gt;
    """

    skip_on = 'future_builtins.map'

    def transform(self, node, results):
        if self.should_skip(node):
            return

        if node.parent.type == syms.simple_stmt:
            self.warning(node, "You should use a for loop here")
            new = node.clone()
            new.prefix = u""
            new = Call(Name(u"list"), [new])
        elif "map_lambda" in results:
            new = ListComp(results["xp"].clone(),
                           results["fp"].clone(),
                           results["it"].clone())
        else:
            if "map_none" in results:
                new = results["arg"].clone()
            else:
                if "arglist" in results:
                    args = results["arglist"]
                    if args.type == syms.arglist and \
                       args.children[0].type == token.NAME and \
                       args.children[0].value == "None":
                        self.warning(node, "cannot convert map(None, ...) "
                                     "with multiple arguments because map() "
                                     "now truncates to the shortest sequence")
                        return
                if in_special_context(node):
                    return None
                new = node.clone()
            new.prefix = u""
            new = Call(Name(u"list"), [new])
        new.prefix = node.prefix
        return new
</pre></body></html>