
'''Various helpers for doing advanced things with dictionaries.'''

def get_fields(s):
    '''Return a set of field names referenced as formatting keys in the given
    string. I thought there would be an easier way to get this, but I can't
    find one. E.g. get_fields('%(hello)s %(world)s') returns
    set('hello', 'world').'''
    class FakeDict(dict):
        def __init__(self):
            super(FakeDict, self).__init__()
            self.referenced = set()
        def __getitem__(self, key):
            self.referenced.add(key)
            return ''
    f = FakeDict()
    s % f # Value deliberately discarded
    return f.referenced

class Guard(object):
    '''Representation of a condition required for some action. See usage in
    Template.py.'''
    def __init__(self, guard_fn):
        self.guard_fn = guard_fn

    def __call__(self, arg):
        return self.guard_fn(arg)


'''Various helpers for doing advanced things with dictionaries.'''

import re

def get_fields(s):
    '''Return a set of field names referenced as formatting keys in the given
    string. I thought there would be an easier way to get this, but I can't
    find one. E.g. get_fields('%(hello)s %(world)s') returns
    set('hello', 'world').'''
    return set(re.findall(r'%\(([^)]+)\)', s))

class Guard(object):
    '''Representation of a condition required for some action. See usage in
    Template.py.'''
    def __init__(self, guard_fn):
        self.guard_fn = guard_fn

    def __call__(self, arg):
        return self.guard_fn(arg)

Support non-string formats in `get_fields`.
Support non-string formats in `get_fields`.

This commit rewrites the `get_fields` function to be simpler and more general.
The previous implementation relied on ad hoc dict mocking and only supported
format strings involving string-valued formats ('%(name)s'). From this commit
other formats (e.g. '%(name)04d') are supported. The motivation for this is
upcoming changes to how the DMA pool frames are named.

  
  '''Various helpers for doing advanced things with dictionaries.'''
+ 
+ import re
  
  def get_fields(s):
      '''Return a set of field names referenced as formatting keys in the given
      string. I thought there would be an easier way to get this, but I can't
      find one. E.g. get_fields('%(hello)s %(world)s') returns
      set('hello', 'world').'''
+     return set(re.findall(r'%\(([^)]+)\)', s))
-     class FakeDict(dict):
-         def __init__(self):
-             super(FakeDict, self).__init__()
-             self.referenced = set()
-         def __getitem__(self, key):
-             self.referenced.add(key)
-             return ''
-     f = FakeDict()
-     s % f # Value deliberately discarded
-     return f.referenced
  
  class Guard(object):
      '''Representation of a condition required for some action. See usage in
      Template.py.'''
      def __init__(self, guard_fn):
          self.guard_fn = guard_fn
  
      def __call__(self, arg):
          return self.guard_fn(arg)
  
Support non-string formats in `get_fields`.
## Code Before:

'''Various helpers for doing advanced things with dictionaries.'''

def get_fields(s):
    '''Return a set of field names referenced as formatting keys in the given
    string. I thought there would be an easier way to get this, but I can't
    find one. E.g. get_fields('%(hello)s %(world)s') returns
    set('hello', 'world').'''
    class FakeDict(dict):
        def __init__(self):
            super(FakeDict, self).__init__()
            self.referenced = set()
        def __getitem__(self, key):
            self.referenced.add(key)
            return ''
    f = FakeDict()
    s % f # Value deliberately discarded
    return f.referenced

class Guard(object):
    '''Representation of a condition required for some action. See usage in
    Template.py.'''
    def __init__(self, guard_fn):
        self.guard_fn = guard_fn

    def __call__(self, arg):
        return self.guard_fn(arg)

## Instruction:
Support non-string formats in `get_fields`.
## Code After:

'''Various helpers for doing advanced things with dictionaries.'''

import re

def get_fields(s):
    '''Return a set of field names referenced as formatting keys in the given
    string. I thought there would be an easier way to get this, but I can't
    find one. E.g. get_fields('%(hello)s %(world)s') returns
    set('hello', 'world').'''
    return set(re.findall(r'%\(([^)]+)\)', s))

class Guard(object):
    '''Representation of a condition required for some action. See usage in
    Template.py.'''
    def __init__(self, guard_fn):
        self.guard_fn = guard_fn

    def __call__(self, arg):
        return self.guard_fn(arg)
