Skip to content

Commit

Permalink
Merge pull request #147 from bz2/cleanup_unrepr
Browse files Browse the repository at this point in the history
Cleanup unrepr function and related code
  • Loading branch information
jelmer authored Nov 28, 2024
2 parents 505f459 + 5092f37 commit 9c8a0a8
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 31 deletions.
45 changes: 14 additions & 31 deletions src/configobj/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@

from ._version import __version__

# imported lazily to avoid startup performance hit if it isn't used
compiler = None

# A dictionary mapping BOM to
# the encoding to decode with, and what to set the
# encoding attribute to.
Expand Down Expand Up @@ -107,7 +104,6 @@ def match_utf8(encoding):
'RepeatSectionError',
'ReloadError',
'UnreprError',
'UnknownType',
'flatten_errors',
'get_extra_values'
)
Expand All @@ -132,30 +128,23 @@ def match_utf8(encoding):
'write_empty_values': False,
}

# this could be replaced if six is used for compatibility, or there are no
# more assertions about items being a string


def getObj(s):
global compiler
if compiler is None:
import compiler
s = "a=" + s
p = compiler.parse(s)
return p.getChildren()[1].getChildren()[0].getChildren()[1]

_literal_eval = None

class UnknownType(Exception):
pass

def unrepr(string):
"""Return given string evaluated to a Python literal."""
if not string:
return string

def unrepr(s):
if not s:
return s
# Lazy import of ast - may not really be needed as much lighter than old
# compile module was, but unrepr is only required by some configobj users.
global _literal_eval
if _literal_eval is None:
import ast
_literal_eval = ast.literal_eval

# this is supposed to be safe
import ast
return ast.literal_eval(s)
return _literal_eval(string)


class ConfigObjError(SyntaxError):
Expand Down Expand Up @@ -1623,10 +1612,7 @@ def _parse(self, infile):
try:
value = unrepr(value)
except Exception as cause:
if isinstance(cause, UnknownType):
msg = 'Unknown name or type in value'
else:
msg = 'Parse error from unrepr-ing multiline value'
msg = 'Parse error from unrepr-ing multiline value'
self._handle_error(msg, UnreprError, infile, cur_index)
continue
else:
Expand All @@ -1635,10 +1621,7 @@ def _parse(self, infile):
try:
value = unrepr(value)
except Exception as cause:
if isinstance(cause, UnknownType):
msg = 'Unknown name or type in value'
else:
msg = 'Parse error from unrepr-ing value'
msg = 'Parse error from unrepr-ing value'
self._handle_error(msg, UnreprError, infile, cur_index)
continue
else:
Expand Down
17 changes: 17 additions & 0 deletions src/tests/test_configobj.py
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,23 @@ def test_with_hash(self):
'key4': [1, 2, 3, 'a mixed list#']
}

def test_empty_value(self):
cfg = ConfigObj(['k = '], unrepr=True)
assert cfg == {'k': ''}

def test_unclosed_quote(self):
with pytest.raises(co.UnreprError) as excinfo:
ConfigObj(['k = "'], unrepr=True)
assert str(excinfo.value) == (
"Parse error from unrepr-ing value at line 1.")

def test_multiline_string_empty(self):
config = ['k = """', '"""']
with pytest.raises(co.UnreprError) as excinfo:
ConfigObj(config, unrepr=True)
assert str(excinfo.value) == (
"Parse error from unrepr-ing multiline value at line 2.")


class TestValueErrors(object):
def test_bool(self, empty_cfg):
Expand Down

0 comments on commit 9c8a0a8

Please sign in to comment.