Upload folder using huggingface_hub (part 2)
Browse files- venv/Lib/site-packages/iniconfig-2.3.0.dist-info/INSTALLER +1 -0
- venv/Lib/site-packages/iniconfig-2.3.0.dist-info/METADATA +79 -0
- venv/Lib/site-packages/iniconfig-2.3.0.dist-info/RECORD +15 -0
- venv/Lib/site-packages/iniconfig-2.3.0.dist-info/WHEEL +5 -0
- venv/Lib/site-packages/iniconfig-2.3.0.dist-info/licenses/LICENSE +21 -0
- venv/Lib/site-packages/iniconfig-2.3.0.dist-info/top_level.txt +1 -0
- venv/Lib/site-packages/iniconfig/__init__.py +249 -0
- venv/Lib/site-packages/iniconfig/_parse.py +163 -0
- venv/Lib/site-packages/iniconfig/_version.py +34 -0
- venv/Lib/site-packages/iniconfig/exceptions.py +16 -0
- venv/Lib/site-packages/iniconfig/py.typed +0 -0
venv/Lib/site-packages/iniconfig-2.3.0.dist-info/INSTALLER
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
pip
|
venv/Lib/site-packages/iniconfig-2.3.0.dist-info/METADATA
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Metadata-Version: 2.4
|
| 2 |
+
Name: iniconfig
|
| 3 |
+
Version: 2.3.0
|
| 4 |
+
Summary: brain-dead simple config-ini parsing
|
| 5 |
+
Author-email: Ronny Pfannschmidt <opensource@ronnypfannschmidt.de>, Holger Krekel <holger.krekel@gmail.com>
|
| 6 |
+
License-Expression: MIT
|
| 7 |
+
Project-URL: Homepage, https://github.com/pytest-dev/iniconfig
|
| 8 |
+
Classifier: Development Status :: 4 - Beta
|
| 9 |
+
Classifier: Intended Audience :: Developers
|
| 10 |
+
Classifier: Operating System :: MacOS :: MacOS X
|
| 11 |
+
Classifier: Operating System :: Microsoft :: Windows
|
| 12 |
+
Classifier: Operating System :: POSIX
|
| 13 |
+
Classifier: Programming Language :: Python :: 3 :: Only
|
| 14 |
+
Classifier: Programming Language :: Python :: 3.10
|
| 15 |
+
Classifier: Programming Language :: Python :: 3.11
|
| 16 |
+
Classifier: Programming Language :: Python :: 3.12
|
| 17 |
+
Classifier: Programming Language :: Python :: 3.13
|
| 18 |
+
Classifier: Programming Language :: Python :: 3.14
|
| 19 |
+
Classifier: Topic :: Software Development :: Libraries
|
| 20 |
+
Classifier: Topic :: Utilities
|
| 21 |
+
Requires-Python: >=3.10
|
| 22 |
+
Description-Content-Type: text/x-rst
|
| 23 |
+
License-File: LICENSE
|
| 24 |
+
Dynamic: license-file
|
| 25 |
+
|
| 26 |
+
iniconfig: brain-dead simple parsing of ini files
|
| 27 |
+
=======================================================
|
| 28 |
+
|
| 29 |
+
iniconfig is a small and simple INI-file parser module
|
| 30 |
+
having a unique set of features:
|
| 31 |
+
|
| 32 |
+
* maintains order of sections and entries
|
| 33 |
+
* supports multi-line values with or without line-continuations
|
| 34 |
+
* supports "#" comments everywhere
|
| 35 |
+
* raises errors with proper line-numbers
|
| 36 |
+
* no bells and whistles like automatic substitutions
|
| 37 |
+
* iniconfig raises an Error if two sections have the same name.
|
| 38 |
+
|
| 39 |
+
If you encounter issues or have feature wishes please report them to:
|
| 40 |
+
|
| 41 |
+
https://github.com/RonnyPfannschmidt/iniconfig/issues
|
| 42 |
+
|
| 43 |
+
Basic Example
|
| 44 |
+
===================================
|
| 45 |
+
|
| 46 |
+
If you have an ini file like this:
|
| 47 |
+
|
| 48 |
+
.. code-block:: ini
|
| 49 |
+
|
| 50 |
+
# content of example.ini
|
| 51 |
+
[section1] # comment
|
| 52 |
+
name1=value1 # comment
|
| 53 |
+
name1b=value1,value2 # comment
|
| 54 |
+
|
| 55 |
+
[section2]
|
| 56 |
+
name2=
|
| 57 |
+
line1
|
| 58 |
+
line2
|
| 59 |
+
|
| 60 |
+
then you can do:
|
| 61 |
+
|
| 62 |
+
.. code-block:: pycon
|
| 63 |
+
|
| 64 |
+
>>> import iniconfig
|
| 65 |
+
>>> ini = iniconfig.IniConfig("example.ini")
|
| 66 |
+
>>> ini['section1']['name1'] # raises KeyError if not exists
|
| 67 |
+
'value1'
|
| 68 |
+
>>> ini.get('section1', 'name1b', [], lambda x: x.split(","))
|
| 69 |
+
['value1', 'value2']
|
| 70 |
+
>>> ini.get('section1', 'notexist', [], lambda x: x.split(","))
|
| 71 |
+
[]
|
| 72 |
+
>>> [x.name for x in list(ini)]
|
| 73 |
+
['section1', 'section2']
|
| 74 |
+
>>> list(list(ini)[0].items())
|
| 75 |
+
[('name1', 'value1'), ('name1b', 'value1,value2')]
|
| 76 |
+
>>> 'section1' in ini
|
| 77 |
+
True
|
| 78 |
+
>>> 'inexistendsection' in ini
|
| 79 |
+
False
|
venv/Lib/site-packages/iniconfig-2.3.0.dist-info/RECORD
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
iniconfig-2.3.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
| 2 |
+
iniconfig-2.3.0.dist-info/METADATA,sha256=QNdz-E5OES9JW79PG-nL0tRWwK6271MR910b8yLyFls,2526
|
| 3 |
+
iniconfig-2.3.0.dist-info/RECORD,,
|
| 4 |
+
iniconfig-2.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
| 5 |
+
iniconfig-2.3.0.dist-info/licenses/LICENSE,sha256=NAn6kfes5VeJRjJnZlbjImT-XvdYFTVyXcmiN3RVG9Q,1098
|
| 6 |
+
iniconfig-2.3.0.dist-info/top_level.txt,sha256=7KfM0fugdlToj9UW7enKXk2HYALQD8qHiyKtjhSzgN8,10
|
| 7 |
+
iniconfig/__init__.py,sha256=XL5eqUYj4mskAOorZ5jfRAinJvJzTI-fJxpP4xfXtaw,7497
|
| 8 |
+
iniconfig/__pycache__/__init__.cpython-314.pyc,,
|
| 9 |
+
iniconfig/__pycache__/_parse.cpython-314.pyc,,
|
| 10 |
+
iniconfig/__pycache__/_version.cpython-314.pyc,,
|
| 11 |
+
iniconfig/__pycache__/exceptions.cpython-314.pyc,,
|
| 12 |
+
iniconfig/_parse.py,sha256=5ncBl7MAQiaPNnpRrs9FR4t6G6DkgOUs458OY_1CR28,5223
|
| 13 |
+
iniconfig/_version.py,sha256=KNFYe-Vtdt7Z-oHyl8jmDAQ9qXoCNMAEXigj6BR1QUI,704
|
| 14 |
+
iniconfig/exceptions.py,sha256=mipQ_aMxD9CvSvFWN1oTXY4QuRnKAMZ1f3sCdmjDTU0,399
|
| 15 |
+
iniconfig/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
venv/Lib/site-packages/iniconfig-2.3.0.dist-info/WHEEL
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Wheel-Version: 1.0
|
| 2 |
+
Generator: setuptools (80.9.0)
|
| 3 |
+
Root-Is-Purelib: true
|
| 4 |
+
Tag: py3-none-any
|
| 5 |
+
|
venv/Lib/site-packages/iniconfig-2.3.0.dist-info/licenses/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
The MIT License (MIT)
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2010 - 2023 Holger Krekel and others
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
| 6 |
+
this software and associated documentation files (the "Software"), to deal in
|
| 7 |
+
the Software without restriction, including without limitation the rights to
|
| 8 |
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
| 9 |
+
of the Software, and to permit persons to whom the Software is furnished to do
|
| 10 |
+
so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
venv/Lib/site-packages/iniconfig-2.3.0.dist-info/top_level.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
iniconfig
|
venv/Lib/site-packages/iniconfig/__init__.py
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""brain-dead simple parser for ini-style files.
|
| 2 |
+
(C) Ronny Pfannschmidt, Holger Krekel -- MIT licensed
|
| 3 |
+
"""
|
| 4 |
+
|
| 5 |
+
import os
|
| 6 |
+
from collections.abc import Callable
|
| 7 |
+
from collections.abc import Iterator
|
| 8 |
+
from collections.abc import Mapping
|
| 9 |
+
from typing import Final
|
| 10 |
+
from typing import TypeVar
|
| 11 |
+
from typing import overload
|
| 12 |
+
|
| 13 |
+
__all__ = ["IniConfig", "ParseError", "COMMENTCHARS", "iscommentline"]
|
| 14 |
+
|
| 15 |
+
from . import _parse
|
| 16 |
+
from ._parse import COMMENTCHARS
|
| 17 |
+
from ._parse import iscommentline
|
| 18 |
+
from .exceptions import ParseError
|
| 19 |
+
|
| 20 |
+
_D = TypeVar("_D")
|
| 21 |
+
_T = TypeVar("_T")
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
class SectionWrapper:
|
| 25 |
+
config: Final["IniConfig"]
|
| 26 |
+
name: Final[str]
|
| 27 |
+
|
| 28 |
+
def __init__(self, config: "IniConfig", name: str) -> None:
|
| 29 |
+
self.config = config
|
| 30 |
+
self.name = name
|
| 31 |
+
|
| 32 |
+
def lineof(self, name: str) -> int | None:
|
| 33 |
+
return self.config.lineof(self.name, name)
|
| 34 |
+
|
| 35 |
+
@overload
|
| 36 |
+
def get(self, key: str) -> str | None: ...
|
| 37 |
+
|
| 38 |
+
@overload
|
| 39 |
+
def get(
|
| 40 |
+
self,
|
| 41 |
+
key: str,
|
| 42 |
+
convert: Callable[[str], _T],
|
| 43 |
+
) -> _T | None: ...
|
| 44 |
+
|
| 45 |
+
@overload
|
| 46 |
+
def get(
|
| 47 |
+
self,
|
| 48 |
+
key: str,
|
| 49 |
+
default: None,
|
| 50 |
+
convert: Callable[[str], _T],
|
| 51 |
+
) -> _T | None: ...
|
| 52 |
+
|
| 53 |
+
@overload
|
| 54 |
+
def get(self, key: str, default: _D, convert: None = None) -> str | _D: ...
|
| 55 |
+
|
| 56 |
+
@overload
|
| 57 |
+
def get(
|
| 58 |
+
self,
|
| 59 |
+
key: str,
|
| 60 |
+
default: _D,
|
| 61 |
+
convert: Callable[[str], _T],
|
| 62 |
+
) -> _T | _D: ...
|
| 63 |
+
|
| 64 |
+
# TODO: investigate possible mypy bug wrt matching the passed over data
|
| 65 |
+
def get( # type: ignore [misc]
|
| 66 |
+
self,
|
| 67 |
+
key: str,
|
| 68 |
+
default: _D | None = None,
|
| 69 |
+
convert: Callable[[str], _T] | None = None,
|
| 70 |
+
) -> _D | _T | str | None:
|
| 71 |
+
return self.config.get(self.name, key, convert=convert, default=default)
|
| 72 |
+
|
| 73 |
+
def __getitem__(self, key: str) -> str:
|
| 74 |
+
return self.config.sections[self.name][key]
|
| 75 |
+
|
| 76 |
+
def __iter__(self) -> Iterator[str]:
|
| 77 |
+
section: Mapping[str, str] = self.config.sections.get(self.name, {})
|
| 78 |
+
|
| 79 |
+
def lineof(key: str) -> int:
|
| 80 |
+
return self.config.lineof(self.name, key) # type: ignore[return-value]
|
| 81 |
+
|
| 82 |
+
yield from sorted(section, key=lineof)
|
| 83 |
+
|
| 84 |
+
def items(self) -> Iterator[tuple[str, str]]:
|
| 85 |
+
for name in self:
|
| 86 |
+
yield name, self[name]
|
| 87 |
+
|
| 88 |
+
|
| 89 |
+
class IniConfig:
|
| 90 |
+
path: Final[str]
|
| 91 |
+
sections: Final[Mapping[str, Mapping[str, str]]]
|
| 92 |
+
_sources: Final[Mapping[tuple[str, str | None], int]]
|
| 93 |
+
|
| 94 |
+
def __init__(
|
| 95 |
+
self,
|
| 96 |
+
path: str | os.PathLike[str],
|
| 97 |
+
data: str | None = None,
|
| 98 |
+
encoding: str = "utf-8",
|
| 99 |
+
*,
|
| 100 |
+
_sections: Mapping[str, Mapping[str, str]] | None = None,
|
| 101 |
+
_sources: Mapping[tuple[str, str | None], int] | None = None,
|
| 102 |
+
) -> None:
|
| 103 |
+
self.path = os.fspath(path)
|
| 104 |
+
|
| 105 |
+
# Determine sections and sources
|
| 106 |
+
if _sections is not None and _sources is not None:
|
| 107 |
+
# Use provided pre-parsed data (called from parse())
|
| 108 |
+
sections_data = _sections
|
| 109 |
+
sources = _sources
|
| 110 |
+
else:
|
| 111 |
+
# Parse the data (backward compatible path)
|
| 112 |
+
if data is None:
|
| 113 |
+
with open(self.path, encoding=encoding) as fp:
|
| 114 |
+
data = fp.read()
|
| 115 |
+
|
| 116 |
+
# Use old behavior (no stripping) for backward compatibility
|
| 117 |
+
sections_data, sources = _parse.parse_ini_data(
|
| 118 |
+
self.path, data, strip_inline_comments=False
|
| 119 |
+
)
|
| 120 |
+
|
| 121 |
+
# Assign once to Final attributes
|
| 122 |
+
self._sources = sources
|
| 123 |
+
self.sections = sections_data
|
| 124 |
+
|
| 125 |
+
@classmethod
|
| 126 |
+
def parse(
|
| 127 |
+
cls,
|
| 128 |
+
path: str | os.PathLike[str],
|
| 129 |
+
data: str | None = None,
|
| 130 |
+
encoding: str = "utf-8",
|
| 131 |
+
*,
|
| 132 |
+
strip_inline_comments: bool = True,
|
| 133 |
+
strip_section_whitespace: bool = False,
|
| 134 |
+
) -> "IniConfig":
|
| 135 |
+
"""Parse an INI file.
|
| 136 |
+
|
| 137 |
+
Args:
|
| 138 |
+
path: Path to the INI file (used for error messages)
|
| 139 |
+
data: Optional INI content as string. If None, reads from path.
|
| 140 |
+
encoding: Encoding to use when reading the file (default: utf-8)
|
| 141 |
+
strip_inline_comments: Whether to strip inline comments from values
|
| 142 |
+
(default: True). When True, comments starting with # or ; are
|
| 143 |
+
removed from values, matching the behavior for section comments.
|
| 144 |
+
strip_section_whitespace: Whether to strip whitespace from section and key names
|
| 145 |
+
(default: False). When True, strips Unicode whitespace from section and key names,
|
| 146 |
+
addressing issue #4. When False, preserves existing behavior for backward compatibility.
|
| 147 |
+
|
| 148 |
+
Returns:
|
| 149 |
+
IniConfig instance with parsed configuration
|
| 150 |
+
|
| 151 |
+
Example:
|
| 152 |
+
# With comment stripping (default):
|
| 153 |
+
config = IniConfig.parse("setup.cfg")
|
| 154 |
+
# value = "foo" instead of "foo # comment"
|
| 155 |
+
|
| 156 |
+
# Without comment stripping (old behavior):
|
| 157 |
+
config = IniConfig.parse("setup.cfg", strip_inline_comments=False)
|
| 158 |
+
# value = "foo # comment"
|
| 159 |
+
|
| 160 |
+
# With section name stripping (opt-in for issue #4):
|
| 161 |
+
config = IniConfig.parse("setup.cfg", strip_section_whitespace=True)
|
| 162 |
+
# section names and keys have Unicode whitespace stripped
|
| 163 |
+
"""
|
| 164 |
+
fspath = os.fspath(path)
|
| 165 |
+
|
| 166 |
+
if data is None:
|
| 167 |
+
with open(fspath, encoding=encoding) as fp:
|
| 168 |
+
data = fp.read()
|
| 169 |
+
|
| 170 |
+
sections_data, sources = _parse.parse_ini_data(
|
| 171 |
+
fspath,
|
| 172 |
+
data,
|
| 173 |
+
strip_inline_comments=strip_inline_comments,
|
| 174 |
+
strip_section_whitespace=strip_section_whitespace,
|
| 175 |
+
)
|
| 176 |
+
|
| 177 |
+
# Call constructor with pre-parsed sections and sources
|
| 178 |
+
return cls(path=fspath, _sections=sections_data, _sources=sources)
|
| 179 |
+
|
| 180 |
+
def lineof(self, section: str, name: str | None = None) -> int | None:
|
| 181 |
+
lineno = self._sources.get((section, name))
|
| 182 |
+
return None if lineno is None else lineno + 1
|
| 183 |
+
|
| 184 |
+
@overload
|
| 185 |
+
def get(
|
| 186 |
+
self,
|
| 187 |
+
section: str,
|
| 188 |
+
name: str,
|
| 189 |
+
) -> str | None: ...
|
| 190 |
+
|
| 191 |
+
@overload
|
| 192 |
+
def get(
|
| 193 |
+
self,
|
| 194 |
+
section: str,
|
| 195 |
+
name: str,
|
| 196 |
+
convert: Callable[[str], _T],
|
| 197 |
+
) -> _T | None: ...
|
| 198 |
+
|
| 199 |
+
@overload
|
| 200 |
+
def get(
|
| 201 |
+
self,
|
| 202 |
+
section: str,
|
| 203 |
+
name: str,
|
| 204 |
+
default: None,
|
| 205 |
+
convert: Callable[[str], _T],
|
| 206 |
+
) -> _T | None: ...
|
| 207 |
+
|
| 208 |
+
@overload
|
| 209 |
+
def get(
|
| 210 |
+
self, section: str, name: str, default: _D, convert: None = None
|
| 211 |
+
) -> str | _D: ...
|
| 212 |
+
|
| 213 |
+
@overload
|
| 214 |
+
def get(
|
| 215 |
+
self,
|
| 216 |
+
section: str,
|
| 217 |
+
name: str,
|
| 218 |
+
default: _D,
|
| 219 |
+
convert: Callable[[str], _T],
|
| 220 |
+
) -> _T | _D: ...
|
| 221 |
+
|
| 222 |
+
def get( # type: ignore
|
| 223 |
+
self,
|
| 224 |
+
section: str,
|
| 225 |
+
name: str,
|
| 226 |
+
default: _D | None = None,
|
| 227 |
+
convert: Callable[[str], _T] | None = None,
|
| 228 |
+
) -> _D | _T | str | None:
|
| 229 |
+
try:
|
| 230 |
+
value: str = self.sections[section][name]
|
| 231 |
+
except KeyError:
|
| 232 |
+
return default
|
| 233 |
+
else:
|
| 234 |
+
if convert is not None:
|
| 235 |
+
return convert(value)
|
| 236 |
+
else:
|
| 237 |
+
return value
|
| 238 |
+
|
| 239 |
+
def __getitem__(self, name: str) -> SectionWrapper:
|
| 240 |
+
if name not in self.sections:
|
| 241 |
+
raise KeyError(name)
|
| 242 |
+
return SectionWrapper(self, name)
|
| 243 |
+
|
| 244 |
+
def __iter__(self) -> Iterator[SectionWrapper]:
|
| 245 |
+
for name in sorted(self.sections, key=self.lineof): # type: ignore
|
| 246 |
+
yield SectionWrapper(self, name)
|
| 247 |
+
|
| 248 |
+
def __contains__(self, arg: str) -> bool:
|
| 249 |
+
return arg in self.sections
|
venv/Lib/site-packages/iniconfig/_parse.py
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from collections.abc import Mapping
|
| 2 |
+
from typing import NamedTuple
|
| 3 |
+
|
| 4 |
+
from .exceptions import ParseError
|
| 5 |
+
|
| 6 |
+
COMMENTCHARS = "#;"
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
class ParsedLine(NamedTuple):
|
| 10 |
+
lineno: int
|
| 11 |
+
section: str | None
|
| 12 |
+
name: str | None
|
| 13 |
+
value: str | None
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def parse_ini_data(
|
| 17 |
+
path: str,
|
| 18 |
+
data: str,
|
| 19 |
+
*,
|
| 20 |
+
strip_inline_comments: bool,
|
| 21 |
+
strip_section_whitespace: bool = False,
|
| 22 |
+
) -> tuple[Mapping[str, Mapping[str, str]], Mapping[tuple[str, str | None], int]]:
|
| 23 |
+
"""Parse INI data and return sections and sources mappings.
|
| 24 |
+
|
| 25 |
+
Args:
|
| 26 |
+
path: Path for error messages
|
| 27 |
+
data: INI content as string
|
| 28 |
+
strip_inline_comments: Whether to strip inline comments from values
|
| 29 |
+
strip_section_whitespace: Whether to strip whitespace from section and key names
|
| 30 |
+
(default: False). When True, addresses issue #4 by stripping Unicode whitespace.
|
| 31 |
+
|
| 32 |
+
Returns:
|
| 33 |
+
Tuple of (sections_data, sources) where:
|
| 34 |
+
- sections_data: mapping of section -> {name -> value}
|
| 35 |
+
- sources: mapping of (section, name) -> line number
|
| 36 |
+
"""
|
| 37 |
+
tokens = parse_lines(
|
| 38 |
+
path,
|
| 39 |
+
data.splitlines(True),
|
| 40 |
+
strip_inline_comments=strip_inline_comments,
|
| 41 |
+
strip_section_whitespace=strip_section_whitespace,
|
| 42 |
+
)
|
| 43 |
+
|
| 44 |
+
sources: dict[tuple[str, str | None], int] = {}
|
| 45 |
+
sections_data: dict[str, dict[str, str]] = {}
|
| 46 |
+
|
| 47 |
+
for lineno, section, name, value in tokens:
|
| 48 |
+
if section is None:
|
| 49 |
+
raise ParseError(path, lineno, "no section header defined")
|
| 50 |
+
sources[section, name] = lineno
|
| 51 |
+
if name is None:
|
| 52 |
+
if section in sections_data:
|
| 53 |
+
raise ParseError(path, lineno, f"duplicate section {section!r}")
|
| 54 |
+
sections_data[section] = {}
|
| 55 |
+
else:
|
| 56 |
+
if name in sections_data[section]:
|
| 57 |
+
raise ParseError(path, lineno, f"duplicate name {name!r}")
|
| 58 |
+
assert value is not None
|
| 59 |
+
sections_data[section][name] = value
|
| 60 |
+
|
| 61 |
+
return sections_data, sources
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
def parse_lines(
|
| 65 |
+
path: str,
|
| 66 |
+
line_iter: list[str],
|
| 67 |
+
*,
|
| 68 |
+
strip_inline_comments: bool = False,
|
| 69 |
+
strip_section_whitespace: bool = False,
|
| 70 |
+
) -> list[ParsedLine]:
|
| 71 |
+
result: list[ParsedLine] = []
|
| 72 |
+
section = None
|
| 73 |
+
for lineno, line in enumerate(line_iter):
|
| 74 |
+
name, data = _parseline(
|
| 75 |
+
path, line, lineno, strip_inline_comments, strip_section_whitespace
|
| 76 |
+
)
|
| 77 |
+
# new value
|
| 78 |
+
if name is not None and data is not None:
|
| 79 |
+
result.append(ParsedLine(lineno, section, name, data))
|
| 80 |
+
# new section
|
| 81 |
+
elif name is not None and data is None:
|
| 82 |
+
if not name:
|
| 83 |
+
raise ParseError(path, lineno, "empty section name")
|
| 84 |
+
section = name
|
| 85 |
+
result.append(ParsedLine(lineno, section, None, None))
|
| 86 |
+
# continuation
|
| 87 |
+
elif name is None and data is not None:
|
| 88 |
+
if not result:
|
| 89 |
+
raise ParseError(path, lineno, "unexpected value continuation")
|
| 90 |
+
last = result.pop()
|
| 91 |
+
if last.name is None:
|
| 92 |
+
raise ParseError(path, lineno, "unexpected value continuation")
|
| 93 |
+
|
| 94 |
+
if last.value:
|
| 95 |
+
last = last._replace(value=f"{last.value}\n{data}")
|
| 96 |
+
else:
|
| 97 |
+
last = last._replace(value=data)
|
| 98 |
+
result.append(last)
|
| 99 |
+
return result
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
def _parseline(
|
| 103 |
+
path: str,
|
| 104 |
+
line: str,
|
| 105 |
+
lineno: int,
|
| 106 |
+
strip_inline_comments: bool,
|
| 107 |
+
strip_section_whitespace: bool,
|
| 108 |
+
) -> tuple[str | None, str | None]:
|
| 109 |
+
# blank lines
|
| 110 |
+
if iscommentline(line):
|
| 111 |
+
line = ""
|
| 112 |
+
else:
|
| 113 |
+
line = line.rstrip()
|
| 114 |
+
if not line:
|
| 115 |
+
return None, None
|
| 116 |
+
# section
|
| 117 |
+
if line[0] == "[":
|
| 118 |
+
realline = line
|
| 119 |
+
for c in COMMENTCHARS:
|
| 120 |
+
line = line.split(c)[0].rstrip()
|
| 121 |
+
if line[-1] == "]":
|
| 122 |
+
section_name = line[1:-1]
|
| 123 |
+
# Optionally strip whitespace from section name (issue #4)
|
| 124 |
+
if strip_section_whitespace:
|
| 125 |
+
section_name = section_name.strip()
|
| 126 |
+
return section_name, None
|
| 127 |
+
return None, realline.strip()
|
| 128 |
+
# value
|
| 129 |
+
elif not line[0].isspace():
|
| 130 |
+
try:
|
| 131 |
+
name, value = line.split("=", 1)
|
| 132 |
+
if ":" in name:
|
| 133 |
+
raise ValueError()
|
| 134 |
+
except ValueError:
|
| 135 |
+
try:
|
| 136 |
+
name, value = line.split(":", 1)
|
| 137 |
+
except ValueError:
|
| 138 |
+
raise ParseError(path, lineno, f"unexpected line: {line!r}") from None
|
| 139 |
+
|
| 140 |
+
# Strip key name (always for backward compatibility, optionally with unicode awareness)
|
| 141 |
+
key_name = name.strip()
|
| 142 |
+
|
| 143 |
+
# Strip value
|
| 144 |
+
value = value.strip()
|
| 145 |
+
# Strip inline comments from values if requested (issue #55)
|
| 146 |
+
if strip_inline_comments:
|
| 147 |
+
for c in COMMENTCHARS:
|
| 148 |
+
value = value.split(c)[0].rstrip()
|
| 149 |
+
|
| 150 |
+
return key_name, value
|
| 151 |
+
# continuation
|
| 152 |
+
else:
|
| 153 |
+
line = line.strip()
|
| 154 |
+
# Strip inline comments from continuations if requested (issue #55)
|
| 155 |
+
if strip_inline_comments:
|
| 156 |
+
for c in COMMENTCHARS:
|
| 157 |
+
line = line.split(c)[0].rstrip()
|
| 158 |
+
return None, line
|
| 159 |
+
|
| 160 |
+
|
| 161 |
+
def iscommentline(line: str) -> bool:
|
| 162 |
+
c = line.lstrip()[:1]
|
| 163 |
+
return c in COMMENTCHARS
|
venv/Lib/site-packages/iniconfig/_version.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# file generated by setuptools-scm
|
| 2 |
+
# don't change, don't track in version control
|
| 3 |
+
|
| 4 |
+
__all__ = [
|
| 5 |
+
"__version__",
|
| 6 |
+
"__version_tuple__",
|
| 7 |
+
"version",
|
| 8 |
+
"version_tuple",
|
| 9 |
+
"__commit_id__",
|
| 10 |
+
"commit_id",
|
| 11 |
+
]
|
| 12 |
+
|
| 13 |
+
TYPE_CHECKING = False
|
| 14 |
+
if TYPE_CHECKING:
|
| 15 |
+
from typing import Tuple
|
| 16 |
+
from typing import Union
|
| 17 |
+
|
| 18 |
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
| 19 |
+
COMMIT_ID = Union[str, None]
|
| 20 |
+
else:
|
| 21 |
+
VERSION_TUPLE = object
|
| 22 |
+
COMMIT_ID = object
|
| 23 |
+
|
| 24 |
+
version: str
|
| 25 |
+
__version__: str
|
| 26 |
+
__version_tuple__: VERSION_TUPLE
|
| 27 |
+
version_tuple: VERSION_TUPLE
|
| 28 |
+
commit_id: COMMIT_ID
|
| 29 |
+
__commit_id__: COMMIT_ID
|
| 30 |
+
|
| 31 |
+
__version__ = version = '2.3.0'
|
| 32 |
+
__version_tuple__ = version_tuple = (2, 3, 0)
|
| 33 |
+
|
| 34 |
+
__commit_id__ = commit_id = None
|
venv/Lib/site-packages/iniconfig/exceptions.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Final
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
class ParseError(Exception):
|
| 5 |
+
path: Final[str]
|
| 6 |
+
lineno: Final[int]
|
| 7 |
+
msg: Final[str]
|
| 8 |
+
|
| 9 |
+
def __init__(self, path: str, lineno: int, msg: str) -> None:
|
| 10 |
+
super().__init__(path, lineno, msg)
|
| 11 |
+
self.path = path
|
| 12 |
+
self.lineno = lineno
|
| 13 |
+
self.msg = msg
|
| 14 |
+
|
| 15 |
+
def __str__(self) -> str:
|
| 16 |
+
return f"{self.path}:{self.lineno + 1}: {self.msg}"
|
venv/Lib/site-packages/iniconfig/py.typed
ADDED
|
File without changes
|