code: def obfuscate_builtins(module, tokens, name_generator, table=None):
      
      used_builtins = analyze.enumerate_builtins(tokens)
      obfuscated_assignments = remap_name(name_generator, used_builtins, table)
      replacements = []
      for assignment in obfuscated_assignments.split('\n'):
          replacements.append(assignment.split('=')[0])
      replacement_dict = dict(zip(used_builtins, replacements))
      if table:
          table[0].update(replacement_dict)
      iter_replacements = iter(replacements)
      for builtin in used_builtins:
          replace_obfuscatables(
              module, tokens, obfuscate_unique, builtin, iter_replacements)
      # Check for shebangs and encodings before we do anything else
      skip_tokens = 0
      matched_shebang = False
      matched_encoding = False
      for tok in tokens[0:4]: # Will always be in the first four tokens
          line = tok[4]
          if analyze.shebang.match(line): # (e.g. '#!/usr/bin/env python')
              if not matched_shebang:
                  matched_shebang = True
                  skip_tokens += 1
          elif analyze.encoding.match(line): # (e.g. '# -*- coding: utf-8 -*-')
              if not matched_encoding:
                  matched_encoding = True
                  skip_tokens += 1
      insert_in_next_line(tokens, skip_tokens, obfuscated_assignments)
docs: Inserts an assignment, '<obfuscated identifier> = <builtin function>'  at
      the beginning of *tokens* (after the shebang and encoding if present) for
      every Python built-in function that is used inside *tokens*.  Also, replaces
      all of said builti-in functions in *tokens* with each respective obfuscated
      identifer.
  
      Obfuscated identifier names are pulled out of name_generator via next().
  
      If *table* is provided, replacements will be looked up there before
      generating a new unique name.