complete doc

This commit is contained in:
cclecle
2023-04-01 00:52:42 +01:00
parent 131e4bcf16
commit 838a800c70
4 changed files with 344 additions and 115 deletions

View File

@@ -23,9 +23,183 @@ From master git repository:
Add this line on the top of your python script:
```py
from pysimpleini import pysimpleini
from pysimpleini import PySimpleINI
```
## Basic API
TO DO
### Sample INI File:
```console
[testsection]
key1=test1
key2=test2
key3=test3
key3=test31
[testsection2]
key10=test10
```
### Load the INI File:
```py
myini:PySimpleINI = PySimpleINI("myinifile.ini")
```
### Access simple key values:
```py
print(myini.getkeyvalue("testsection", "key1"))
```
```console
test1
```
```py
print(myini.getkeyvalue("testsection", "key2"))
```
```console
test2
```
```py
print(myini.getkeyvalue("testsection", "key3"))
```
```console
['test3','test31']
```
```py
print(myini.getkeyvalue("testsection", "key3"))
```
```console
['test3','test31']
```
### Access key values with specified index:
```py
print(myini.getkeyvalue_ex("testsection", "key3",0))
```
```console
test3
```
```py
print(myini.getkeyvalue_ex("testsection", "key3",1))
```
```console
test31
```
### list keys name:
```py
print(myini.getallkeynames("testsection"))
```
```console
['key1', 'key2', 'key3', 'key3']
```
### list sections name:
```py
print(myini.getallsectionnames())
```
```console
['testsection', 'testsection2']
```
### add a new key:
```py
myini.setaddkeyvalue("testsection2","key11","test11")
print(myini.format())
```
```console
[testsection]
key1=test1
key2=test2
key3=test3
key3=test31
[testsection2]
key10=test10
key11=test11
```
### update a key value:
```py
myini.setaddkeyvalue("testsection2","key11","test13")
print(myini.format())
```
```console
[testsection]
key1=test1
key2=test2
key3=test3
key3=test31
[testsection2]
key10=test10
key11=test13
```
### create a new key with same name:
```py
myini.setaddkeyvalue("testsection2","key11","test14",True)
print(myini.format())
```
```console
[testsection]
key1=test1
key2=test2
key3=test3
key3=test31
[testsection2]
key10=test10
key11=test13
key11=test14
```
### create a new empty section
```py
myini.addsection("testsection3")
print(myini.format())
```
```console
[testsection]
key1=test1
key2=test2
key3=test3
key3=test31
[testsection2]
key10=test10
key11=test13
key11=test14
[testsection3]
```
### save your file
```py
myini.writefile()
```
### save to a new file
```py
myini.filepath = "somedir/somefile.ini"
myini.writefile()
```
__Read the API documentation and the unit test for more informations __
## limitations
There is some known limitations.
1. File is only written when writefile() is called.
2. Support for more than one section with the same name is incomplete using setaddkeyvalue() / getkeyvalue_ex() / getkey_ex() / delkey_ex() because the index argument is only for keys.
If more precise section selection is needed, please use getsection() to get the correct section object and then use the underlying methods.

View File

@@ -17,6 +17,9 @@ from typing import TYPE_CHECKING
from re import search as RE_search
from .walker import Walker
from .exceptions import SectionNotFoundError
from .sections import (
SectionBase,
Section,
@@ -52,6 +55,104 @@ class Document:
"""reset sections list"""
self._sections = []
def addsection(self, name: str) -> Section:
"""Create and Add a new Section.
Args:
name: The new section name
Returns:
The new section
"""
section = Section(name, -1)
self.sections.append(section)
return section
def addcommentsection(self, value: str) -> SectionComment:
"""Create and Add a new Comment Section.
Args:
value: Comment value
Returns:
The new section
"""
section = SectionComment(-1)
section.append_commentkey(self.sectioncomment_tags[0], value, -1)
self.sections.append(section)
return section
def addblanksection(self) -> SectionBlanck:
"""Create and Add a new Blank Section (newline).
Returns:
The new section
"""
section = SectionBlanck(-1)
section.append_blanckkey(-1)
self.sections.append(section)
return section
def delsection(self, name: str, index: Optional[int] = None) -> int:
"""Delete an existing Section.
- If index is set, this filter will be applied.
///warning
An exception will be raised if the Section isn't found.
///
Args:
name: The Section name
index: The Section instance index (in case of multiple section with same name)
Returns:
Number of deleted sections
"""
walker = Walker[SectionBase](targetname=name, targetindex=index, targettypes=Section)
walker.walk(self.sections, self.sections.remove)
ndeleted: int = walker.num_matched
if ndeleted == 0:
raise SectionNotFoundError()
return ndeleted
def getallsectionnames(self) -> list[str]:
"""Retrieve a list of sections names.
Returns:
List of section names.
"""
result = []
walker = Walker[SectionBase](targettypes=Section)
walker.walk(self.sections, lambda x: result.append(x.getname()))
return result
def getsection(self, name: str, index: Optional[int] = None) -> list[Section]:
"""Get one or more sections objects.
///Note
An exception will be raised if the Section isn't found.
///
Args:
name: Name of the section to retrieve.
index: The Section instance index (in case of multiple section with same name)
Returns:
The section object or a list of section object
"""
result: List[Section] = []
walker = Walker[SectionBase](targetname=name, targetindex=index, targettypes=Section)
walker.walk(self.sections, result.append)
if len(result) == 0:
raise SectionNotFoundError()
return result
class DocumentParser(Document):
"""Document Parser class"""

View File

@@ -22,7 +22,7 @@ from pathlib import Path
from .document import DocumentParser, DocumentFormater
from .walker import Walker
from .sections import Section, SectionComment, SectionBlanck, SectionBase
from .sections import Section, SectionBase
from .keys import Key
from .exceptions import SectionNotFoundError, KeyNotFoundError
@@ -90,67 +90,6 @@ class PySimpleINI(DocumentParser, DocumentFormater):
self.parse(file.read())
return self
def delsection(self, name: str, index: Optional[int] = None) -> int:
"""Delete an existing Section.
- If index is set, this filter will be applied.
///warning
An exception will be raised if the Section isn't found.
///
Args:
name: The Section name
index: The Section instance index (in case of multiple section with same name)
Returns:
Number of deleted sections
"""
walker = Walker[SectionBase](targetname=name, targetindex=index, targettypes=Section)
walker.walk(self.sections, self.sections.remove)
ndeleted: int = walker.num_matched
if ndeleted == 0:
raise SectionNotFoundError()
return ndeleted
def addsection(self, name: str) -> Section:
"""Create and Add a new Section.
Args:
name: The new sectio nname
Returns:
The new section
"""
section = Section(name, -1)
self.sections.append(section)
return section
def addcommentsection(self, value: str) -> SectionComment:
"""Create and Add a new Comment Section.
Args:
value: Comment value
Returns:
The new section
"""
section = SectionComment(-1)
section.append_commentkey(self.sectioncomment_tags[0], value, -1)
self.sections.append(section)
return section
def addblanksection(self) -> SectionBlanck:
"""Create and Add a new Blank Section (newline).
Returns:
The new section
"""
section = SectionBlanck(-1)
section.append_blanckkey(-1)
self.sections.append(section)
return section
def writefile(self, bBeautify: bool = False, bWipeComments: bool = False) -> None:
"""Actually write the INI object to the file.
@@ -162,44 +101,6 @@ class PySimpleINI(DocumentParser, DocumentFormater):
with open(self._filepath, "w", encoding="utf-8") as file:
file.write(self.format(bBeautify, bWipeComments))
def getallsectionnames(self) -> list[str]:
"""Retrieve a list of sections names.
Returns:
List of section names.
"""
result = []
walker = Walker[SectionBase](targettypes=Section)
walker.walk(self.sections, lambda x: result.append(x.getname()))
return result
def getsection(self, name: str) -> Section | list[Section]:
"""Get one or more sections objects.
///Note
An exception will be raised if the Section isn't found.
///
Args:
name: Name of the section to retrieve.
Returns:
The section object or a list of section object
"""
result: List[Section] = []
walker = Walker[SectionBase](targetname=name, targettypes=Section)
walker.walk(self.sections, result.append)
if len(result) == 0:
raise SectionNotFoundError()
if not self._bForceAlwaysOutputArrays and (len(result) == 1):
return result[0]
return result
def getallkeynames(self, sectionName: str) -> list[str]:
"""Get a list of Keys in a defined Section.
@@ -207,6 +108,10 @@ class PySimpleINI(DocumentParser, DocumentFormater):
An exception will be raised if the Key or Section isn't found.
///
///Note
All section with given name will be considered.
///
Args:
sectionName: The Section name
Returns:
@@ -222,10 +127,14 @@ class PySimpleINI(DocumentParser, DocumentFormater):
def delkey(self, sectionName: str, keyName: str) -> int:
"""Delete an existing Key from Section.
///Note
///warning
An exception will be raised if the Key or Section isn't found.
///
///Note
All section with given name will be considered.
///
Args:
sectionName: The Section name
keyName: The Key name
@@ -242,7 +151,11 @@ class PySimpleINI(DocumentParser, DocumentFormater):
- Both filter can be enabled together (value appyed first)
///warning
An exception will be raised if the Section isn't found.
An exception will be raised if the Key or Section isn't found.
///
///Note
index only apply to keys index, not to section. All section with given name will be considered.
///
Args:
@@ -279,10 +192,14 @@ class PySimpleINI(DocumentParser, DocumentFormater):
def getkey(self, sectionName: str, keyName: str) -> Key | List[Key]:
"""Get one or more Key from Section.
///Note
///warning
An exception will be raised if the Key or Section isn't found.
///
///Note
All section with given name will be considered.
///
Args:
sectionName: The Section name
keyName: The Key name
@@ -298,10 +215,19 @@ class PySimpleINI(DocumentParser, DocumentFormater):
- If index is set, this filter will be applied.
- Both filter can be enabled together (value appyed first)
///Note
///warning
An exception will be raised if the Key or Section isn't found.
///
///Note
index only apply to keys index, not to section. All section with given name will be considered.
///
///Note
If this Lib is not initialized with bForceAlwaysOutputArrays set,
this function will output a single object on single match (not a list).
///
Args:
sectionName: The Section name
keyName: The Key name
@@ -343,10 +269,14 @@ class PySimpleINI(DocumentParser, DocumentFormater):
def getkeyvalue(self, sectionName: str, keyName: str) -> str | list[str]:
"""Get one or more Key's values from Section.
///Note
///warning
An exception will be raised if the Key or Section isn't found.
///
///Note
All section with given name will be considered.
///
Args:
sectionName: The Section name
keyName: The Key name
@@ -362,10 +292,14 @@ class PySimpleINI(DocumentParser, DocumentFormater):
- If index is set, this filter will be applied.
- Both filter can be enabled together (value appyed first)
///Note
///warning
An exception will be raised if the Key or Section isn't found.
///
///Note
index only apply to keys index, not to section. All section with given name will be considered.
///
Args:
sectionName: The Section name
keyName: The Key name
@@ -385,6 +319,10 @@ class PySimpleINI(DocumentParser, DocumentFormater):
) -> None:
"""Set or Add a new key with value.
///warning
In case of multiple section with the same name, only the last one will be considered.
///
Args:
sectionName: The Section name
keyName: Key's name
@@ -392,16 +330,13 @@ class PySimpleINI(DocumentParser, DocumentFormater):
bForceAddKey: Force to add a new Key, even if the name already exists
bForceAddSection: Force to add a new Section, even if the name already exists
"""
sections: Section | List[Section]
sections: List[Section]
if bForceAddSection is True:
sections = self.addsection(sectionName)
sections = [self.addsection(sectionName)]
else:
try:
sections = self.getsection(sectionName)
except SectionNotFoundError:
sections = self.addsection(sectionName)
sections = [self.addsection(sectionName)]
if isinstance(sections, Section):
sections.setaddkeyvalue(keyName, keyValue, bForceAddKey)
else: # array: in this case we set value of the last section
sections[-1].setaddkeyvalue(keyName, keyValue, bForceAddKey)
sections[-1].setaddkeyvalue(keyName, keyValue, bForceAddKey)

View File

@@ -276,3 +276,22 @@ class Test_PySimpleINI_base(unittest.TestCase):
def test_inputForeighKeys(self):
inputstring = "testkey1=valuetestkey1\n" "testkey2=valuetestkey2\n" "testkey3=valuetestkey3.1\n" "testkey3=valuetestkey3.2\n"
self.Gen_test_inputstring(inputstring)
def test_doc_usage(self):
inputstring = "[testsection]\n" "key1=test1\n" "key2=test2\n" "key3=test3\n" "key3=test31\n" "[testsection2]\n" "key10=test10\n"
myini = PySimpleINI().parse(inputstring)
print(myini.getkeyvalue("testsection", "key1"))
print(myini.getkeyvalue("testsection", "key2"))
print(myini.getkeyvalue("testsection", "key3"))
print(myini.getkeyvalue_ex("testsection", "key3", 0))
print(myini.getkeyvalue_ex("testsection", "key3", 1))
print(myini.getallkeynames("testsection"))
print(myini.getallsectionnames())
myini.setaddkeyvalue("testsection2", "key11", "test11")
print(myini.format())
myini.setaddkeyvalue("testsection2", "key11", "test13")
print(myini.format())
myini.setaddkeyvalue("testsection2", "key11", "test14", True)
print(myini.format())
myini.addsection("testsection3")
print(myini.format())