From e80cbdc3224297ee57667e4000f1a671af05f520 Mon Sep 17 00:00:00 2001 From: Raphaël Barrois Date: Mon, 9 Apr 2012 01:10:42 +0200 Subject: Move ATTR_SPLITTER logic to a dedicated module. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Raphaël Barrois --- factory/utils.py | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 factory/utils.py (limited to 'factory/utils.py') diff --git a/factory/utils.py b/factory/utils.py new file mode 100644 index 0000000..6c6fd7d --- /dev/null +++ b/factory/utils.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2010 Mark Sandstrom +# Copyright (c) 2011 Raphaël Barrois +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + + +#: String for splitting an attribute name into a +#: (subfactory_name, subfactory_field) tuple. +ATTR_SPLITTER = '__' + +def extract_dict(prefix, kwargs, pop=True): + """Extracts all values beginning with a given prefix from a dict. + + Can either 'pop' or 'get' them; + + Args: + prefix (str): the prefix to use for lookups + kwargs (dict): the dict from which values should be extracted + pop (bool): whether to use pop (True) or get (False) + + Returns: + A new dict, containing values from kwargs and beginning with + prefix + ATTR_SPLITTER. That full prefix is removed from the keys + of the returned dict. + """ + prefix = prefix + ATTR_SPLITTER + extracted = {} + for key in kwargs.keys(): + if key.startswith(prefix): + new_key = key[len(prefix):] + if pop: + value = kwargs.pop(key) + else: + value = kwargs[key] + extracted[new_key] = value + return extracted + + +def declength_compare(a, b): + """Compare objects, choosing longest first.""" + if len(a) > len(b): + return -1 + elif len(a) < len(b): + return 1 + else: + return cmp(a, b) + + +def multi_extract_dict(prefixes, kwargs, pop=True): + """Extracts all values from a given list of prefixes.""" + results = {} + for prefix in sorted(prefixes, cmp=declength_compare): + extracted = extract_dict(prefix, kwargs, pop=pop) + results[prefix] = extracted + return results -- cgit v1.2.3