Yapf complains about spacing inconsistencies around assignment operators in function calls, fix that.
Assisted-by: unsloth/Qwen3.6-35B-A3B-GGUF:IQ4_NL with pi.dev v0.80.2Signed-off-by: Jan Lindemann <jan@janware.com>
265 lines
7 KiB
Python
265 lines
7 KiB
Python
import os
|
|
import tempfile
|
|
from jw.pkg.lib.ProjectConf import ProjectConf
|
|
|
|
# -- Helper: create temp file and read it --
|
|
|
|
_tmpfiles: list[str] = []
|
|
|
|
def _load(text: str) -> ProjectConf:
|
|
with tempfile.NamedTemporaryFile(mode = 'w', suffix = '.conf', delete = False) as f:
|
|
f.write(text)
|
|
f.flush()
|
|
_tmpfiles.append(f.name)
|
|
return ProjectConf.read(f.name)
|
|
|
|
|
|
def _cleanup():
|
|
for _p in _tmpfiles:
|
|
os.unlink(_p)
|
|
del _p
|
|
_tmpfiles.clear()
|
|
|
|
# -- Basic construction --
|
|
|
|
pc = _load('[section]\nkey = value\n')
|
|
assert pc.get_str('section', 'key') == 'value'
|
|
|
|
# -- get_section returns raw section text --
|
|
|
|
pc = _load('[meta]\n# header comment\nkey = val\n\n')
|
|
section = pc.get_section('meta')
|
|
assert section is not None
|
|
assert '# header comment' in section
|
|
assert 'key = val' in section
|
|
|
|
# -- get_section returns None for missing section --
|
|
|
|
pc = _load('[section]\nkey = value\n')
|
|
assert pc.get_section('nonexistent') is None
|
|
|
|
# -- get_str returns unquoted value --
|
|
|
|
pc = _load('[section]\nkey = "hello world"\n')
|
|
assert pc.get_str('section', 'key') == 'hello world'
|
|
|
|
# -- get_str returns raw value when not quoted --
|
|
|
|
pc = _load('[section]\nkey = plain value\n')
|
|
assert pc.get_str('section', 'key') == 'plain value'
|
|
|
|
# -- get_str raises Error when key missing --
|
|
|
|
pc = _load('[section]\nother = val\n')
|
|
try:
|
|
pc.get_str('section', 'missing')
|
|
assert False, 'Should have raised'
|
|
except ProjectConf.Error:
|
|
pass
|
|
|
|
# -- get_str raises Error when section missing --
|
|
|
|
pc = _load('[section]\nkey = val\n')
|
|
try:
|
|
pc.get_str('nonexistent', 'key')
|
|
assert False, 'Should have raised'
|
|
except ProjectConf.Error:
|
|
pass
|
|
|
|
# -- get_str_or_none returns None for missing key --
|
|
|
|
pc = _load('[section]\nother = val\n')
|
|
assert pc.get_str_or_none('section', 'missing') is None
|
|
|
|
# -- get_str_or_none returns None for missing section --
|
|
|
|
pc = _load('[section]\nkey = val\n')
|
|
assert pc.get_str_or_none('nonexistent', 'key') is None
|
|
|
|
# -- get_str returns string with trailing whitespace stripped --
|
|
|
|
pc = _load('[section]\nkey = value \n')
|
|
assert pc.get_str('section', 'key') == 'value'
|
|
|
|
# -- Quoted value with spaces preserved --
|
|
|
|
pc = _load('[section]\nkey = " spaced "\n')
|
|
assert pc.get_str('section', 'key') == ' spaced '
|
|
|
|
# -- Quoted hash inside quotes is preserved --
|
|
|
|
pc = _load('[section]\nkey = "value # not a comment"\n')
|
|
assert pc.get_str('section', 'key') == 'value # not a comment'
|
|
|
|
# -- Inline comment outside quotes --
|
|
|
|
pc = _load('[section]\nkey = value # this is a comment\n')
|
|
assert pc.get_str('section', 'key') == 'value'
|
|
|
|
# -- Quoted value containing an inline comment delimiter --
|
|
|
|
pc = _load('[section]\nkey = "has # inside"\n')
|
|
assert pc.get_str('section', 'key') == 'has # inside'
|
|
|
|
# -- get_list returns split values --
|
|
|
|
pc = _load('[section]\nlist = a, b, c\n')
|
|
assert pc.get_list('section', 'list') == ['a', 'b', 'c']
|
|
|
|
# -- get_list returns single value --
|
|
|
|
pc = _load('[section]\nlist = single\n')
|
|
assert pc.get_list('section', 'list') == ['single']
|
|
|
|
# -- get_list_or_none returns None for missing key --
|
|
|
|
pc = _load('[section]\nother = val\n')
|
|
assert pc.get_list_or_none('section', 'missing') is None
|
|
|
|
# -- get_list raises Error when missing key --
|
|
|
|
pc = _load('[section]\nother = val\n')
|
|
try:
|
|
pc.get_list('section', 'missing')
|
|
assert False, 'Should have raised'
|
|
except ProjectConf.Error:
|
|
pass
|
|
|
|
# -- get_list handles quoted commas --
|
|
|
|
pc = _load('[section]\nlist = "a, b", c, "d, e"\n')
|
|
assert pc.get_list('section', 'list') == ['a, b', 'c', 'd, e']
|
|
|
|
# -- get_list returns empty list for empty value --
|
|
|
|
pc = _load('[section]\nlist = \n')
|
|
assert pc.get_list('section', 'list') == []
|
|
|
|
# -- get_list_or_none returns empty list for empty value --
|
|
|
|
pc = _load('[section]\nlist = \n')
|
|
assert pc.get_list_or_none('section', 'list') == []
|
|
|
|
# -- Unclosed quote in list raises --
|
|
|
|
pc = _load('[section]\nlist = "unclosed, b\n')
|
|
try:
|
|
pc.get_list('section', 'list')
|
|
assert False, 'Should have raised'
|
|
except ProjectConf.Error as exc:
|
|
assert 'Unclosed quote' in str(exc)
|
|
|
|
# -- Line continuation --
|
|
|
|
pc = _load('[section]\nkey = first \\\n second \\\n third\n')
|
|
assert pc.get_str('section', 'key') == 'first second third'
|
|
|
|
# -- Line continuation with inline comment at end --
|
|
|
|
pc = _load('[section]\nkey = first \\\n second # comment\n')
|
|
assert pc.get_str('section', 'key') == 'first second'
|
|
|
|
# -- get_section returns None for non-existent section --
|
|
|
|
pc = _load('[section]\nkey = val\n')
|
|
assert pc.get_section('does_not_exist') is None
|
|
|
|
# -- Multiple keys in same section --
|
|
|
|
pc = _load('[section]\nfirst = one\nsecond = two\nthird = three\n')
|
|
assert pc.get_str('section', 'first') == 'one'
|
|
assert pc.get_str('section', 'second') == 'two'
|
|
assert pc.get_str('section', 'third') == 'three'
|
|
|
|
# -- get_str_or_none does not raise for missing section --
|
|
|
|
pc = _load('[section]\nkey = val\n')
|
|
assert pc.get_str_or_none('nope', 'key') is None
|
|
|
|
# -- get_list_or_none does not raise for missing section --
|
|
|
|
pc = _load('[section]\nkey = val\n')
|
|
assert pc.get_list_or_none('nope', 'key') is None
|
|
|
|
# -- get_list_or_none does not raise for missing key --
|
|
|
|
pc = _load('[section]\nother = val\n')
|
|
assert pc.get_list_or_none('section', 'nope') is None
|
|
|
|
# -- Empty key raises --
|
|
|
|
pc = _load('[section]\n= value\n')
|
|
try:
|
|
pc.get_str('section', '')
|
|
assert False, 'Should have raised'
|
|
except ProjectConf.Error:
|
|
pass
|
|
|
|
# -- Not an assignment raises --
|
|
|
|
pc = _load('[section]\nnot an assignment\n')
|
|
try:
|
|
pc.get_str('section', 'not an assignment')
|
|
assert False, 'Should have raised'
|
|
except ProjectConf.Error:
|
|
pass
|
|
|
|
# -- Unfinished continuation raises --
|
|
|
|
pc = _load('[section]\nkey = value \\\n')
|
|
try:
|
|
pc.get_str('section', 'key')
|
|
assert False, 'Should have raised'
|
|
except ProjectConf.Error:
|
|
pass
|
|
|
|
# -- Error class is ValueError --
|
|
|
|
pc = _load('[section]\nkey = val\n')
|
|
try:
|
|
pc.get_str('missing', 'key')
|
|
except ValueError as e:
|
|
assert isinstance(e, ValueError)
|
|
else:
|
|
assert False, 'Should have raised ValueError'
|
|
|
|
# -- Whitespace around key and value --
|
|
|
|
pc = _load('[section]\n key = value \n')
|
|
assert pc.get_str('section', 'key') == 'value'
|
|
|
|
# -- Whitespace around key in list --
|
|
|
|
pc = _load('[section]\nlist = a , b , c \n')
|
|
assert pc.get_list('section', 'list') == ['a', 'b', 'c']
|
|
|
|
# -- Multiple sections --
|
|
|
|
pc = _load('[one]\nkey = val1\n[two]\nkey = val2\n')
|
|
assert pc.get_str('one', 'key') == 'val1'
|
|
assert pc.get_str('two', 'key') == 'val2'
|
|
|
|
# -- Section with only comments and blanks --
|
|
|
|
pc = _load('[empty]\n# just a comment\n\n')
|
|
section = pc.get_section('empty')
|
|
assert section is not None
|
|
assert pc.get_str_or_none('empty', 'key') is None
|
|
|
|
# -- Section with trailing comment on section header line --
|
|
|
|
pc = _load('[section] # inline comment\nkey = val\n')
|
|
assert pc.get_str('section', 'key') == 'val'
|
|
|
|
# -- Value that looks like a section header --
|
|
|
|
pc = _load('[section]\nnot_a_key = [bracket]\n')
|
|
assert pc.get_str('section', 'not_a_key') == '[bracket]'
|
|
|
|
# -- Multiple values with trailing backslash comments --
|
|
|
|
pc = _load('[section]\nlist = "a", "b", "c"\n')
|
|
assert pc.get_list('section', 'list') == ['a', 'b', 'c']
|
|
|
|
_cleanup()
|
|
print('All ProjectConf tests passed')
|