def walk_packages(b, managername=None, **kwargs):
    """
    Walk a package tree and execute callbacks along the way.  This is a bit
    like iteration but can't match the iterator protocol due to the varying
    argument lists given to each type of callback.  The available callbacks
    are:

    * `before_packages(manager):`
      Executed before a package manager's dependencies are enumerated.
    * `package(manager, package, version):`
      Executed when a package version is enumerated.
    * `after_packages(manager):`
      Executed after a package manager's dependencies are enumerated.
    """

    # Walking begins with the system package managers, `apt`, `rpm`,
    # and `yum`.
    if managername is None:
        walk_packages(b, 'apt', **kwargs)
        walk_packages(b, 'rpm', **kwargs)
        walk_packages(b, 'yum', **kwargs)
        return

    # Get the full manager from its name.
    manager = managers.PackageManager(managername)

    # Give the manager a chance to setup for its dependencies.
    kwargs.get('before_packages', lambda *args: None)(manager)

    # Each package gets its chance to take action.  Note which packages
    # are themselves managers so they may be visited recursively later.
    next_managers = []
    callable = kwargs.get('package', lambda *args: None)
    for package, versions in sorted(b.get('packages',
                                          {}).get(manager,
                                                  {}).iteritems()):
        if 0 == len(versions):
            callable(manager, package, None)
        elif isinstance(versions, basestring):
            callable(manager, package, versions)
        else:
            for version in versions:
                callable(manager, package, version)
        if managername != package and b.get('packages', {}) in package:
            next_managers.append(package)

    # Give the manager a change to cleanup after itself.
    kwargs.get('after_packages', lambda *args: None)(manager)

    # Now recurse into each manager that was just installed.  Recursing
    # here is safer because there may be secondary dependencies that are
    # not expressed in the hierarchy (for example the `mysql2` gem
    # depends on `libmysqlclient-dev` in addition to its manager).
    for managername in next_managers:
        walk_packages(b, managername, **kwargs)
dataset/ETHPy150Open devstructure/blueprint/blueprint/walk.py/walk_packages/swapped operands of `in`