(root)/
Python-3.12.0/
Lib/
lib2to3/
fixes/
fix_map.py
       1  # Copyright 2007 Google, Inc. All Rights Reserved.
       2  # Licensed to PSF under a Contributor Agreement.
       3  
       4  """Fixer that changes map(F, ...) into list(map(F, ...)) unless there
       5  exists a 'from future_builtins import map' statement in the top-level
       6  namespace.
       7  
       8  As a special case, map(None, X) is changed into list(X).  (This is
       9  necessary because the semantics are changed in this case -- the new
      10  map(None, X) is equivalent to [(x,) for x in X].)
      11  
      12  We avoid the transformation (except for the special case mentioned
      13  above) if the map() call is directly contained in iter(<>), list(<>),
      14  tuple(<>), sorted(<>), ...join(<>), or for V in <>:.
      15  
      16  NOTE: This is still not correct if the original code was depending on
      17  map(F, X, Y, ...) to go on until the longest argument is exhausted,
      18  substituting None for missing values -- like zip(), it now stops as
      19  soon as the shortest argument is exhausted.
      20  """
      21  
      22  # Local imports
      23  from ..pgen2 import token
      24  from .. import fixer_base
      25  from ..fixer_util import Name, ArgList, Call, ListComp, in_special_context
      26  from ..pygram import python_symbols as syms
      27  from ..pytree import Node
      28  
      29  
      30  class ESC[4;38;5;81mFixMap(ESC[4;38;5;149mfixer_baseESC[4;38;5;149m.ESC[4;38;5;149mConditionalFix):
      31      BM_compatible = True
      32  
      33      PATTERN = """
      34      map_none=power<
      35          'map'
      36          trailer< '(' arglist< 'None' ',' arg=any [','] > ')' >
      37          [extra_trailers=trailer*]
      38      >
      39      |
      40      map_lambda=power<
      41          'map'
      42          trailer<
      43              '('
      44              arglist<
      45                  lambdef< 'lambda'
      46                           (fp=NAME | vfpdef< '(' fp=NAME ')'> ) ':' xp=any
      47                  >
      48                  ','
      49                  it=any
      50              >
      51              ')'
      52          >
      53          [extra_trailers=trailer*]
      54      >
      55      |
      56      power<
      57          'map' args=trailer< '(' [any] ')' >
      58          [extra_trailers=trailer*]
      59      >
      60      """
      61  
      62      skip_on = 'future_builtins.map'
      63  
      64      def transform(self, node, results):
      65          if self.should_skip(node):
      66              return
      67  
      68          trailers = []
      69          if 'extra_trailers' in results:
      70              for t in results['extra_trailers']:
      71                  trailers.append(t.clone())
      72  
      73          if node.parent.type == syms.simple_stmt:
      74              self.warning(node, "You should use a for loop here")
      75              new = node.clone()
      76              new.prefix = ""
      77              new = Call(Name("list"), [new])
      78          elif "map_lambda" in results:
      79              new = ListComp(results["xp"].clone(),
      80                             results["fp"].clone(),
      81                             results["it"].clone())
      82              new = Node(syms.power, [new] + trailers, prefix="")
      83  
      84          else:
      85              if "map_none" in results:
      86                  new = results["arg"].clone()
      87                  new.prefix = ""
      88              else:
      89                  if "args" in results:
      90                      args = results["args"]
      91                      if args.type == syms.trailer and \
      92                         args.children[1].type == syms.arglist and \
      93                         args.children[1].children[0].type == token.NAME and \
      94                         args.children[1].children[0].value == "None":
      95                          self.warning(node, "cannot convert map(None, ...) "
      96                                       "with multiple arguments because map() "
      97                                       "now truncates to the shortest sequence")
      98                          return
      99  
     100                      new = Node(syms.power, [Name("map"), args.clone()])
     101                      new.prefix = ""
     102  
     103                  if in_special_context(node):
     104                      return None
     105  
     106              new = Node(syms.power, [Name("list"), ArgList([new])] + trailers)
     107              new.prefix = ""
     108  
     109          new.prefix = node.prefix
     110          return new