Skip to content

Commit 9c8a0a8

Browse files
authored
Merge pull request #147 from bz2/cleanup_unrepr
Cleanup unrepr function and related code
2 parents 505f459 + 5092f37 commit 9c8a0a8

File tree

2 files changed

+31
-31
lines changed

2 files changed

+31
-31
lines changed

src/configobj/__init__.py

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@
3333

3434
from ._version import __version__
3535

36-
# imported lazily to avoid startup performance hit if it isn't used
37-
compiler = None
38-
3936
# A dictionary mapping BOM to
4037
# the encoding to decode with, and what to set the
4138
# encoding attribute to.
@@ -107,7 +104,6 @@ def match_utf8(encoding):
107104
'RepeatSectionError',
108105
'ReloadError',
109106
'UnreprError',
110-
'UnknownType',
111107
'flatten_errors',
112108
'get_extra_values'
113109
)
@@ -132,30 +128,23 @@ def match_utf8(encoding):
132128
'write_empty_values': False,
133129
}
134130

135-
# this could be replaced if six is used for compatibility, or there are no
136-
# more assertions about items being a string
137-
138-
139-
def getObj(s):
140-
global compiler
141-
if compiler is None:
142-
import compiler
143-
s = "a=" + s
144-
p = compiler.parse(s)
145-
return p.getChildren()[1].getChildren()[0].getChildren()[1]
146131

132+
_literal_eval = None
147133

148-
class UnknownType(Exception):
149-
pass
150134

135+
def unrepr(string):
136+
"""Return given string evaluated to a Python literal."""
137+
if not string:
138+
return string
151139

152-
def unrepr(s):
153-
if not s:
154-
return s
140+
# Lazy import of ast - may not really be needed as much lighter than old
141+
# compile module was, but unrepr is only required by some configobj users.
142+
global _literal_eval
143+
if _literal_eval is None:
144+
import ast
145+
_literal_eval = ast.literal_eval
155146

156-
# this is supposed to be safe
157-
import ast
158-
return ast.literal_eval(s)
147+
return _literal_eval(string)
159148

160149

161150
class ConfigObjError(SyntaxError):
@@ -1623,10 +1612,7 @@ def _parse(self, infile):
16231612
try:
16241613
value = unrepr(value)
16251614
except Exception as cause:
1626-
if isinstance(cause, UnknownType):
1627-
msg = 'Unknown name or type in value'
1628-
else:
1629-
msg = 'Parse error from unrepr-ing multiline value'
1615+
msg = 'Parse error from unrepr-ing multiline value'
16301616
self._handle_error(msg, UnreprError, infile, cur_index)
16311617
continue
16321618
else:
@@ -1635,10 +1621,7 @@ def _parse(self, infile):
16351621
try:
16361622
value = unrepr(value)
16371623
except Exception as cause:
1638-
if isinstance(cause, UnknownType):
1639-
msg = 'Unknown name or type in value'
1640-
else:
1641-
msg = 'Parse error from unrepr-ing value'
1624+
msg = 'Parse error from unrepr-ing value'
16421625
self._handle_error(msg, UnreprError, infile, cur_index)
16431626
continue
16441627
else:

src/tests/test_configobj.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,23 @@ def test_with_hash(self):
628628
'key4': [1, 2, 3, 'a mixed list#']
629629
}
630630

631+
def test_empty_value(self):
632+
cfg = ConfigObj(['k = '], unrepr=True)
633+
assert cfg == {'k': ''}
634+
635+
def test_unclosed_quote(self):
636+
with pytest.raises(co.UnreprError) as excinfo:
637+
ConfigObj(['k = "'], unrepr=True)
638+
assert str(excinfo.value) == (
639+
"Parse error from unrepr-ing value at line 1.")
640+
641+
def test_multiline_string_empty(self):
642+
config = ['k = """', '"""']
643+
with pytest.raises(co.UnreprError) as excinfo:
644+
ConfigObj(config, unrepr=True)
645+
assert str(excinfo.value) == (
646+
"Parse error from unrepr-ing multiline value at line 2.")
647+
631648

632649
class TestValueErrors(object):
633650
def test_bool(self, empty_cfg):

0 commit comments

Comments
 (0)