Extracts a tuple from a string.

    Args:
        str_in (string) that contains python tuple
    Returns:
        (dict) or None if no valid tuple was found
    Raises:
        -
11438
def str2tuple(str_in):
    '''
    
    '''
    tuple_out = safe_eval(str_in)
    if not isinstance(tuple_out, tuple):
        tuple_out = None
    return tuple_out
872252
def extract(self, optimized_str):
        

        logger.debug('START optimized_str ========================')
        logger.debug(optimized_str)
        logger.debug('END optimized_str ==========================')
        logger.debug(
            'Date parsing: languages=%s date_formats=%s',
            self.options['languages'],
            self.options['date_formats'],
        )
        logger.debug('Float parsing: decimal separator=%s', self.options['decimal_separator'])
        logger.debug("keywords=%s", self['keywords'])
        logger.debug(self.options)

        # Try to find data for each field.
        output = {}
        output['issuer'] = self['issuer']

        for k, v in self['fields'].items():
            if k.startswith('static_'):
                logger.debug("field=%s | static value=%s", k, v)
                output[k.replace('static_', '')] = v
            else:
                logger.debug("field=%s | regexp=%s", k, v)

                sum_field = False
                if k.startswith('sum_amount') and type(v) is list:
                    k = k[4:]  # remove 'sum_' prefix
                    sum_field = True
                # Fields can have multiple expressions
                if type(v) is list:
                    res_find = []
                    for v_option in v:
                        res_val = re.findall(v_option, optimized_str)
                        if res_val:
                            if sum_field:
                                res_find += res_val
                            else:
                                res_find.extend(res_val)
                else:
                    res_find = re.findall(v, optimized_str)
                if res_find:
                    logger.debug("res_find=%s", res_find)
                    if k.startswith('date') or k.endswith('date'):
                        output[k] = self.parse_date(res_find[0])
                        if not output[k]:
                            logger.error("Date parsing failed on date '%s'", res_find[0])
                            return None
                    elif k.startswith('amount'):
                        if sum_field:
                            output[k] = 0
                            for amount_to_parse in res_find:
                                output[k] += self.parse_number(amount_to_parse)
                        else:
                            output[k] = self.parse_number(res_find[0])
                    else:
                        res_find = list(set(res_find))
                        if len(res_find) == 1:
                            output[k] = res_find[0]
                        else:
                            output[k] = res_find
                else:
                    logger.warning("regexp for field %s didn't match", k)

        output['currency'] = self.options['currency']

        # Run plugins:
        for plugin_keyword, plugin_func in PLUGIN_MAPPING.items():
            if plugin_keyword in self.keys():
                plugin_func.extract(self, optimized_str, output)

        # If required fields were found, return output, else log error.
        if 'required_fields' not in self.keys():
            required_fields = ['date', 'amount', 'invoice_number', 'issuer']
        else:
            required_fields = []
            for v in self['required_fields']:
                required_fields.append(v)

        if set(required_fields).issubset(output.keys()):
            output['desc'] = 'Invoice from %s' % (self['issuer'])
            logger.debug(output)
            return output
        else:
            fields = list(set(output.keys()))
            logger.error(
                'Unable to match all required fields. '
                'The required fields are: {0}. '
                'Output contains the following fields: {1}.'.format(required_fields, fields)
            )
            return None
107509
def parse_tuple_type_str(old_from_type_str):
    
    @functools.wraps(old_from_type_str)
    def new_from_type_str(cls, type_str, registry):
        normalized_type_str = normalize(type_str)
        abi_type = parse(normalized_type_str)

        type_str_repr = repr(type_str)
        if type_str != normalized_type_str:
            type_str_repr = '{} (normalized to {})'.format(
                type_str_repr,
                repr(normalized_type_str),
            )

        if not isinstance(abi_type, TupleType):
            raise ValueError(
                'Cannot create {} for non-tuple type {}'.format(
                    cls.__name__,
                    type_str_repr,
                )
            )

        abi_type.validate()

        return old_from_type_str(cls, abi_type, registry)

    return classmethod(new_from_type_str)
1087001
def parse_string(str_, validate=False):
    
    result = pattern.parseString(str_)[0]
    if validate:
        result.validate()
    return result
360429
def kw_str_parse(a_string):
    """"""
    try:
        return dict((k, eval(v.rstrip(',')))
                    for k, v in kw_list_re.findall(a_string))
    except (AttributeError, TypeError):
        if isinstance(a_string, collections.Mapping):
            return a_string
        return {}
589827
def extract_keywords(func):
    
    if hasattr(func, 'im_func'):
        func = func.im_func

    try:
        return func.func_code.co_varnames[-len(func.func_defaults):]
    except (TypeError, ValueError, IndexError):
        return tuple()
1017696
def parse_dict_strings(code):
    

    i = 0
    level = 0
    chunk_start = 0
    curr_paren = None

    for i, char in enumerate(code):
        if char in ["(", "[", "{"] and curr_paren is None:
            level += 1
        elif char in [")", "]", "}"] and curr_paren is None:
            level -= 1
        elif char in ['"', "'"]:
            if curr_paren == char:
                curr_paren = None
            elif curr_paren is None:
                curr_paren = char

        if level == 0 and char in [':', ','] and curr_paren is None:
            yield code[chunk_start: i].strip()
            chunk_start = i + 1

    yield code[chunk_start:i + 1].strip()
230793
def parse(self, string, lexer=None):
        
        if not lexer:
            lexer = Lexer().lexer

        return self.parser.parse(string, lexer=lexer)
1119825
def from_tuples(cls, tups):
        
        ivs = [Interval(*t) for t in tups]
        return IntervalTree(ivs)
801672
def parse_str(self, s):
        
        root = ET.fromstring(s)
        return self._parse(root)
1215689
def from_string(cls, s: str) -> 'ComponentRef':
        

        components = s.split('.')
        return cls.from_tuple(components)
892886
def decode_input(text_in):
    
    
    if type(text_in) == list:
        text_out = u' '.join([t.decode('utf-8') for t in text_in])
    else:
        text_out = text_in.decode('utf-8')
    return text_out
718214
def from_json(cls, json_string):
        
        input_dict = json.loads(json_string)
        # convert index to tuple if required
        if input_dict['index'] and isinstance(input_dict['index'][0], list):
            input_dict['index'] = [tuple(x) for x in input_dict['index']]
        # convert index_name to tuple if required
        if isinstance(input_dict['meta_data']['index_name'], list):
            input_dict['meta_data']['index_name'] = tuple(input_dict['meta_data']['index_name'])
        data = input_dict['data'] if input_dict['data'] else None
        return cls(data=data, index=input_dict['index'], **input_dict['meta_data'])
819371
def extract_date(cls, date_str):
        
        if not date_str:
            raise DateTimeFormatterException('date_str must a valid string {}.'.format(date_str))

        try:
            return cls._extract_timestamp(date_str, cls.DATE_FORMAT)
        except (TypeError, ValueError):
            raise DateTimeFormatterException('Invalid date string {}.'.format(date_str))
807334
def __convert_string_type(self, p_c_tuple):
        # type: (Tuple[text_type,...])->Tuple[text_type]
        
        if not isinstance(p_c_tuple, tuple):
            raise Exception('Pos condition expects tuple of string. However = {}'.format(p_c_tuple))

        converted = [text_type] * len(p_c_tuple)
        for i, pos_element in enumerate(p_c_tuple):
            if six.PY2 and isinstance(pos_element, str):
                """str into unicode if python2.x"""
                converted[i] = pos_element.decode(self.string_encoding)
            elif six.PY2 and isinstance(pos_element, text_type):
                converted[i] = pos_element
            elif six.PY3:
                converted[i] = pos_element
            else:
                raise Exception()

        return tuple(converted)
1067946
def itersplit_to_fields(self, _str):
        
        if self.preparse:
            _str = self.preparse(_str)

        _fields = itersplit(_str, self.fsep)

        try:
            values = (
                t[1] for t in izip_longest(self._tuple._fields, _fields))
            return self._tuple(*values)
        except Exception as e:
            log.error(self._tuple)
            log.error(_fields)
            log.exception(e)
            raise
1073465
def string_in_list(tmp_str, strlist):
        # type: (AnyStr, List[AnyStr]) -> bool
        """"""
        new_str_list = strlist[:]
        for i, str_in_list in enumerate(new_str_list):
            new_str_list[i] = str_in_list.lower()
        return tmp_str.lower() in new_str_list