nix-archive-1(type directoryentry(namelibnode(type directoryentry(name python3.10node(type directoryentry(name site-packagesnode(type directoryentry(name iniconfignode(type directoryentry(name __init__.pynode(typeregularcontentsX""" brain-dead simple parser for ini-style files. (C) Ronny Pfannschmidt, Holger Krekel -- MIT licensed """ __all__ = ['IniConfig', 'ParseError'] COMMENTCHARS = "#;" class ParseError(Exception): def __init__(self, path, lineno, msg): Exception.__init__(self, path, lineno, msg) self.path = path self.lineno = lineno self.msg = msg def __str__(self): return "%s:%s: %s" % (self.path, self.lineno+1, self.msg) class SectionWrapper(object): def __init__(self, config, name): self.config = config self.name = name def lineof(self, name): return self.config.lineof(self.name, name) def get(self, key, default=None, convert=str): return self.config.get(self.name, key, convert=convert, default=default) def __getitem__(self, key): return self.config.sections[self.name][key] def __iter__(self): section = self.config.sections.get(self.name, []) def lineof(key): return self.config.lineof(self.name, key) for name in sorted(section, key=lineof): yield name def items(self): for name in self: yield name, self[name] class IniConfig(object): def __init__(self, path, data=None): self.path = str(path) # convenience if data is None: f = open(self.path) try: tokens = self._parse(iter(f)) finally: f.close() else: tokens = self._parse(data.splitlines(True)) self._sources = {} self.sections = {} for lineno, section, name, value in tokens: if section is None: self._raise(lineno, 'no section header defined') self._sources[section, name] = lineno if name is None: if section in self.sections: self._raise(lineno, 'duplicate section %r' % (section, )) self.sections[section] = {} else: if name in self.sections[section]: self._raise(lineno, 'duplicate name %r' % (name, )) self.sections[section][name] = value def _raise(self, lineno, msg): raise ParseError(self.path, lineno, msg) def _parse(self, line_iter): result = [] section = None for lineno, line in enumerate(line_iter): name, data = self._parseline(line, lineno) # new value if name is not None and data is not None: result.append((lineno, section, name, data)) # new section elif name is not None and data is None: if not name: self._raise(lineno, 'empty section name') section = name result.append((lineno, section, None, None)) # continuation elif name is None and data is not None: if not result: self._raise(lineno, 'unexpected value continuation') last = result.pop() last_name, last_data = last[-2:] if last_name is None: self._raise(lineno, 'unexpected value continuation') if last_data: data = '%s\n%s' % (last_data, data) result.append(last[:-1] + (data,)) return result def _parseline(self, line, lineno): # blank lines if iscommentline(line): line = "" else: line = line.rstrip() if not line: return None, None # section if line[0] == '[': realline = line for c in COMMENTCHARS: line = line.split(c)[0].rstrip() if line[-1] == "]": return line[1:-1], None return None, realline.strip() # value elif not line[0].isspace(): try: name, value = line.split('=', 1) if ":" in name: raise ValueError() except ValueError: try: name, value = line.split(":", 1) except ValueError: self._raise(lineno, 'unexpected line: %r' % line) return name.strip(), value.strip() # continuation else: return None, line.strip() def lineof(self, section, name=None): lineno = self._sources.get((section, name)) if lineno is not None: return lineno + 1 def get(self, section, name, default=None, convert=str): try: return convert(self.sections[section][name]) except KeyError: return default def __getitem__(self, name): if name not in self.sections: raise KeyError(name) return SectionWrapper(self, name) def __iter__(self): for name in sorted(self.sections, key=self.lineof): yield SectionWrapper(self, name) def __contains__(self, arg): return arg in self.sections def iscommentline(line): c = line.lstrip()[:1] return c in COMMENTCHARS ))entry(name __init__.pyinode(typeregularcontentsfrom typing import Callable, Iterator, Mapping, Optional, Tuple, TypeVar, Union from typing_extensions import Final _D = TypeVar('_D') _T = TypeVar('_T') class ParseError(Exception): # Private __init__. path: Final[str] lineno: Final[int] msg: Final[str] class SectionWrapper: # Private __init__. config: Final[IniConfig] name: Final[str] def __getitem__(self, key: str) -> str: ... def __iter__(self) -> Iterator[str]: ... def get(self, key: str, default: _D = ..., convert: Callable[[str], _T] = ...) -> Union[_T, _D]: ... def items(self) -> Iterator[Tuple[str, str]]: ... def lineof(self, name: str) -> Optional[int]: ... class IniConfig: path: Final[str] sections: Final[Mapping[str, Mapping[str, str]]] def __init__(self, path: str, data: Optional[str] = None): ... def __contains__(self, arg: str) -> bool: ... def __getitem__(self, name: str) -> SectionWrapper: ... def __iter__(self) -> Iterator[SectionWrapper]: ... def get(self, section: str, name: str, default: _D = ..., convert: Callable[[str], _T] = ...) -> Union[_T, _D]: ... def lineof(self, section: str, name: Optional[str] = ...) -> Optional[int]: ... ))entry(name __pycache__node(type directoryentry(name__init__.cpython-310.pycnode(typeregularcontentso ސfp+F @sLdZddgZdZGdddeZGdddeZGdddeZdd Zd S) ze brain-dead simple parser for ini-style files. (C) Ronny Pfannschmidt, Holger Krekel -- MIT licensed IniConfig ParseErrorz#;c@seZdZddZddZdS)rcCs&t||||||_||_||_dSN) Exception__init__pathlinenomsg)selfrrrr u/gnu/store/9fc1281c0mfqkv09742yvq10dw1fhjy4-python-iniconfig-1.1.1/lib/python3.10/site-packages/iniconfig/__init__.pyr s zParseError.__init__cCsd|j|jd|jfS)Nz %s:%s: %s)rrrr r r r __str__szParseError.__str__N)__name__ __module__ __qualname__rrr r r r r s c@sBeZdZddZddZdefddZdd Zd d Zd d Z dS)SectionWrappercCs||_||_dSr)configname)r rrr r r rs zSectionWrapper.__init__cCs|j|j|Srrlineofrr rr r r rzSectionWrapper.lineofNcCs|jj|j|||dS)N)convertdefault)rgetr)r keyrrr r r rs zSectionWrapper.getcCs|jj|j|Sr)rsectionsr)r rr r r __getitem__ szSectionWrapper.__getitem__c#s<jjjg}fdd}t||dD]}|VqdS)Ncsjj|Srrrr r r r&rz'SectionWrapper.__iter__..lineofr)rrrrsorted)r sectionrrr r r __iter__#s  zSectionWrapper.__iter__ccs|D] }|||fVqdSrr rr r r items+szSectionWrapper.items) rrrrrstrrrr"r#r r r r rs rc@s^eZdZdddZddZddZdd Zdd d Zdefd d Z ddZ ddZ ddZ dS)rNc Cst||_|dur!t|j}z |t|}W|n |w||d}i|_i|_|D]F\}}}}|durA| |d||j||f<|dur`||jvrZ| |d|fi|j|<q1||j|vrp| |d|f||j||<q1dS)NTzno section header definedzduplicate section %rzduplicate name %r) r$ropen_parseiterclose splitlines_sourcesr_raise) r rdataftokensrr!rvaluer r r r1s*     zIniConfig.__init__cCst|j||r)rr)r rrr r r r+LszIniConfig._raisec Csg}d}t|D]t\}}|||\}}|dur&|dur&|||||fq|durB|durB|s6||d|}|||ddfq|dur||dur||sR||d|}|dd\} } | durh||d| rpd| |f}||dd|fq|S)Nzempty section namezunexpected value continuationz%s %s) enumerate _parselineappendr+pop) r line_iterresultr!rlinerr,last last_name last_datar r r r&Os.    zIniConfig._parsec Cst|rd}n|}|sdS|ddkr9|}tD] }||d}q|ddkr3|dddfSd|fS|ds~z|dd\}}d |vrOtWn%tyuz |d d\}}Wntyr||d |YnwYnw||fSd|fS) N)NN[r1]r =:zunexpected line: %r) iscommentlinerstrip COMMENTCHARSsplitstripisspace ValueErrorr+)r r8rreallinecrr/r r r r3ks8       zIniConfig._parselinecCs$|j||f}|dur|dSdSNr )r*r)r r!rrr r r rszIniConfig.lineofcCs,z ||j||WSty|YSwr)rKeyError)r r!rrrr r r rs  z IniConfig.getcCs||jvr t|t||Sr)rrLrrr r r rs  zIniConfig.__getitem__ccs(t|j|jdD]}t||Vq dS)Nr)r rrrrr r r r"szIniConfig.__iter__cCs ||jvSr)r)r argr r r __contains__s zIniConfig.__contains__r) rrrrr+r&r3rr$rrr"rNr r r r r0s   cCs|dd}|tvSrK)lstriprD)r8rJr r r rBsrBN) __doc____all__rDrrobjectrrrBr r r r s  s))))entry(namepy.typednode(typeregularcontents))))entry(nameiniconfig-0.0.0-py3.10.egg-infonode(type directoryentry(namePKG-INFOnode(typeregularcontentsy Metadata-Version: 2.1 Name: iniconfig Version: 0.0.0 Summary: iniconfig: brain-dead simple config-ini parsing Home-page: http://github.com/RonnyPfannschmidt/iniconfig Author: Ronny Pfannschmidt, Holger Krekel Author-email: opensource@ronnypfannschmidt.de, holger.krekel@gmail.com License: MIT License Platform: unix Platform: linux Platform: osx Platform: cygwin Platform: win32 Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: POSIX Classifier: Operating System :: Microsoft :: Windows Classifier: Operating System :: MacOS :: MacOS X Classifier: Topic :: Software Development :: Libraries Classifier: Topic :: Utilities Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 3 License-File: LICENSE iniconfig: brain-dead simple parsing of ini files ======================================================= iniconfig is a small and simple INI-file parser module having a unique set of features: * tested against Python2.4 across to Python3.2, Jython, PyPy * maintains order of sections and entries * supports multi-line values with or without line-continuations * supports "#" comments everywhere * raises errors with proper line-numbers * no bells and whistles like automatic substitutions * iniconfig raises an Error if two sections have the same name. If you encounter issues or have feature wishes please report them to: http://github.com/RonnyPfannschmidt/iniconfig/issues Basic Example =================================== If you have an ini file like this:: # content of example.ini [section1] # comment name1=value1 # comment name1b=value1,value2 # comment [section2] name2= line1 line2 then you can do:: >>> import iniconfig >>> ini = iniconfig.IniConfig("example.ini") >>> ini['section1']['name1'] # raises KeyError if not exists 'value1' >>> ini.get('section1', 'name1b', [], lambda x: x.split(",")) ['value1', 'value2'] >>> ini.get('section1', 'notexist', [], lambda x: x.split(",")) [] >>> [x.name for x in list(ini)] ['section1', 'section2'] >>> list(list(ini)[0].items()) [('name1', 'value1'), ('name1b', 'value1,value2')] >>> 'section1' in ini True >>> 'inexistendsection' in ini False ))entry(name SOURCES.txtnode(typeregularcontents.gitignore .hgignore .landscape.yml .travis.yml CHANGELOG LICENSE MANIFEST.in README.txt example.ini pyproject.toml setup.cfg setup.py tox.ini src/iniconfig/__init__.py src/iniconfig/__init__.pyi src/iniconfig/py.typed src/iniconfig.egg-info/PKG-INFO src/iniconfig.egg-info/SOURCES.txt src/iniconfig.egg-info/dependency_links.txt src/iniconfig.egg-info/not-zip-safe src/iniconfig.egg-info/top_level.txt testing/conftest.py testing/test_iniconfig.py))entry(namedependency_links.txtnode(typeregularcontents ))entry(name not-zip-safenode(typeregularcontents ))entry(name top_level.txtnode(typeregularcontents iniconfig ))))))))))entry(namesharenode(type directoryentry(namedocnode(type directoryentry(namepython-iniconfig-1.1.1node(type directoryentry(nameLICENSEnode(typeregularcontents% 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. )))))))))