def sub_(m): txt = m.group(1).strip() try: v = eval_value(str(txt), globals, locals, encoding) _type = type(txt) if not isinstance(v, (str, text_type)): v = _type(v) elif not isinstance(v, _type): if _type is text_type: v = text_type(v, encoding) else: v = v.encode(encoding) except: print_exc() v = m.group() return v
def read(self, fobj, filename=''): encoding = None if isinstance(fobj, (str, text_type)): f = open(fobj, 'rb') text = f.read() f.close() else: text = fobj.read() text = text + b'\n' begin = 0 if text.startswith(codecs.BOM_UTF8): begin = 3 encoding = 'UTF-8' elif text.startswith(codecs.BOM_UTF16): begin = 2 encoding = 'UTF-16' if not encoding: try: text_type(text, 'UTF-8') encoding = 'UTF-8' except: encoding = defaultencoding self._encoding = encoding f = StringIO(text_type(text, 'utf-8')) f.seek(begin) lineno = 0 comments = [] section = None while 1: lastpos = f.tell() line = f.readline() lineno += 1 if not line: break line = line.strip() if line: if line.startswith(self._commentchar): if lineno == 1: #first comment line b = r_encoding.search(line[1:]) if b: self._encoding = b.groups()[0] continue comments.append(line) elif line.startswith('[') and line.endswith(']'): sec_name = line[1:-1].strip() #process include notation if sec_name.startswith('include:'): _filename = sec_name[8:].strip() _filename = os.path.abspath(_filename) if os.path.exists(_filename): old_encoding = self._encoding self.read(_filename) self._encoding = old_encoding else: import warnings warnings.warn(Warning("Can't find the file [%s], so just skip it" % _filename), stacklevel=2) continue info = RawValue(self._inifile, lineno, sec_name) section = self.add(sec_name, comments, info=info) comments = [] elif '=' in line: if section is None: raise Exception("No section found, please define it first in %s file" % self.filename) #if find <=, then it'll replace the old value for mutable variables #because the default behavior will merge list and dict pos = line.find('<=') if pos != -1: begin, end = pos, pos+2 replace_flag = True else: pos = line.find('=') begin, end = pos, pos+1 replace_flag = False keyname = line[:begin].strip() #check keyname if keyname in self._env: raise KeyError("Settings key %s is alread defined in env, please change it's name" % keyname) rest = line[end:].strip() #if key= then value will be set '' if rest == '': v = None else: f.seek(lastpos+end) try: value, iden_existed = self.__read_line(f) except Exception as e: print_exc() raise Exception("Parsing ini file error in %s:%d:%s" % (filename or self._inifile, lineno, line)) if self._lazy: if iden_existed: v = EvalValue(value, filename or self._inifile, lineno, line) else: v = value else: if self._raw: v = RawValue(self._inifile, lineno, value, replace_flag) else: try: v = eval_value(value, self.env(), self[sec_name], self._encoding) except Exception as e: print(e) print_exc() print_(dict(self)) raise Exception("Converting value (%s) error in %s:%d:%s" % (value, filename or self._inifile, lineno, line)) section.add(keyname, v, comments, replace=replace_flag) comments = [] else: comments.append(line)