code: def dict_diff(dold, dnew, indent=0):
      """Helper to log what actually changed from old to new values of
      dictionaries.
  
      typical use -- log difference for hashed_inputs
      """
      try:
          dnew, dold = dict(dnew), dict(dold)
      except Exception:
          return textwrap.indent(
              f"""\
  Diff between nipype inputs failed:
  * Cached inputs: {dold}
  * New inputs: {dnew}""",
              " " * indent,
          )
  
      # Compare against hashed_inputs
      # Keys: should rarely differ
      new_keys = set(dnew.keys())
      old_keys = set(dold.keys())
  
      diff = []
      if new_keys - old_keys:
          diff += [
              "  * keys not previously seen: %s" % (new_keys - old_keys)
          ]
  
      if old_keys - new_keys:
          diff += [
              "  * keys not presently seen: %s" % (old_keys - new_keys)
          ]
  
      # Add topical message
      if diff:
          diff.insert(0, "Dictionaries had differing keys:")
  
      diffkeys = len(diff)
  
      def _shorten(value):
          if isinstance(value, str) and len(value) > 50:
              return f"{value[:10]}...{value[-10:]}"
          if isinstance(value, (tuple, list)) and len(value) > 10:
              return tuple(list(value[:2]) + ["..."] + list(value[-2:]))
          return value
  
      def _uniformize(val):
          if isinstance(val, dict):
              return {k: _uniformize(v) for k, v in val.items()}
          if isinstance(val, (list, tuple)):
              return tuple(_uniformize(el) for el in val)
          return val
  
      # Values in common keys would differ quite often,
      # so we need to join the messages together
      for k in new_keys.intersection(old_keys):
          # Reading from JSON produces lists, but internally we typically
          # use tuples. At this point these dictionary values can be
          # immutable (and therefore the preference for tuple).
          new = _uniformize(dnew[k])
          old = _uniformize(dold[k])
  
          if new != old:
              diff += [
                  f"  * {k}: {_shorten(new)!r} != {_shorten(old)!r}"
              ]
  
      if len(diff) > diffkeys:
          diff.insert(
              diffkeys, "Some dictionary entries had differing values:"
          )
  
      return textwrap.indent("\n".join(diff), " " * indent)
  
file_path: nipype/nipype/utils/misc.py
imports: import os
  import sys
  import re
  from collections.abc import Iterator
  from warnings import warn
  from looseversion import LooseVersion
  import numpy
  import textwrap
label_desc: Use image node_id 11 for calling a global function with example usage: dict_diff(dold, dnew, indent) and returns: textwrap, value, val, textwrap, value, str, value, tuple, unknown, tuple