Skip to content

Commit c68e78f

Browse files
committed
Fix handling of malformed lines
1 parent ae1f1a9 commit c68e78f

4 files changed

Lines changed: 16 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ Changelog
1919
Latest
2020
-----
2121

22-
- ...
22+
- Fix handling of malformed lines and lines without a value:
23+
- Don't print warning when key has no value.
24+
- Reject more malformed lines (e.g. "A: B").
2325

2426
0.10.4
2527
-----

src/dotenv/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
def with_warn_for_invalid_lines(mappings):
3838
# type: (Iterator[Binding]) -> Iterator[Binding]
3939
for mapping in mappings:
40-
if mapping.key is None or mapping.value is None:
40+
if mapping.key is None:
4141
logger.warning(
4242
"Python-dotenv could not parse statement starting at line %s",
4343
mapping.original.line,

src/dotenv/parser.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,17 @@ def make_regex(string, extra_flags=0):
1616

1717

1818
_newline = make_regex(r"(\r\n|\n|\r)")
19-
_whitespace = make_regex(r"\s*", extra_flags=re.MULTILINE)
19+
_multiline_whitespace = make_regex(r"\s*", extra_flags=re.MULTILINE)
20+
_whitespace = make_regex(r"[^\S\r\n]*")
2021
_export = make_regex(r"(?:export[^\S\r\n]+)?")
2122
_single_quoted_key = make_regex(r"'([^']+)'")
2223
_unquoted_key = make_regex(r"([^=\#\s]+)")
23-
_equal_sign = make_regex(r"([^\S\r\n]*=[^\S\r\n]*)?")
24+
_equal_sign = make_regex(r"(=[^\S\r\n]*)")
2425
_single_quoted_value = make_regex(r"'((?:\\'|[^'])*)'")
2526
_double_quoted_value = make_regex(r'"((?:\\"|[^"])*)"')
2627
_unquoted_value_part = make_regex(r"([^ \r\n]*)")
2728
_comment = make_regex(r"(?:\s*#[^\r\n]*)?")
28-
_end_of_line = make_regex(r"[^\S\r\n]*(?:\r\n|\n|\r)?")
29+
_end_of_line = make_regex(r"[^\S\r\n]*(?:\r\n|\n|\r|$)")
2930
_rest_of_line = make_regex(r"[^\r\n]*(?:\r|\n|\r\n)?")
3031
_double_quote_escapes = make_regex(r"\\[\\'\"abfnrtv]")
3132
_single_quote_escapes = make_regex(r"\\[\\']")
@@ -191,11 +192,15 @@ def parse_binding(reader):
191192
# type: (Reader) -> Binding
192193
reader.set_mark()
193194
try:
194-
reader.read_regex(_whitespace)
195+
reader.read_regex(_multiline_whitespace)
195196
reader.read_regex(_export)
196197
key = parse_key(reader)
197-
(sign,) = reader.read_regex(_equal_sign)
198-
value = parse_value(reader) if sign else None
198+
reader.read_regex(_whitespace)
199+
if reader.peek(1) == "=":
200+
reader.read_regex(_equal_sign)
201+
value = parse_value(reader) # type: Optional[Text]
202+
else:
203+
value = None
199204
reader.read_regex(_comment)
200205
reader.read_regex(_end_of_line)
201206
return Binding(

tests/test_parser.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
(u"a=à", [Binding(key=u"a", value=u"à", original=Original(string=u"a=à", line=1))]),
3737
(u'a="à"', [Binding(key=u"a", value=u"à", original=Original(string=u'a="à"', line=1))]),
3838
(u'no_value_var', [Binding(key=u'no_value_var', value=None, original=Original(string=u"no_value_var", line=1))]),
39+
(u'a: b', [Binding(key=None, value=None, original=Original(string=u"a: b", line=1))]),
3940
(
4041
u"a=b\nc=d",
4142
[

0 commit comments

Comments
 (0)