diff --git a/CHANGELOG.md b/CHANGELOG.md index bf9a3b79b2..ec1c24b51b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fixed a crash when a `SelectionList` had a prompt wider than itself https://github.com/Textualize/textual/issues/2900 - Fixed a bug where `Click` events were bubbling up from `Switch` widgets https://github.com/Textualize/textual/issues/2366 +- Fixed a crash when using empty CSS variables https://github.com/Textualize/textual/issues/1849 ## [0.30.0] - 2023-07-17 diff --git a/src/textual/css/parse.py b/src/textual/css/parse.py index 13aeea4886..1b31e8b66b 100644 --- a/src/textual/css/parse.py +++ b/src/textual/css/parse.py @@ -269,6 +269,7 @@ def substitute_references( break if token.name == "variable_name": variable_name = token.value[1:-1] # Trim the $ and the :, i.e. "$x:" -> "x" + variable_tokens = variables.setdefault(variable_name, []) yield token while True: @@ -284,7 +285,7 @@ def substitute_references( if not token: break elif token.name == "whitespace": - variables.setdefault(variable_name, []).append(token) + variable_tokens.append(token) yield token elif token.name == "variable_value_end": yield token @@ -293,7 +294,6 @@ def substitute_references( elif token.name == "variable_ref": ref_name = token.value[1:] if ref_name in variables: - variable_tokens = variables.setdefault(variable_name, []) reference_tokens = variables[ref_name] variable_tokens.extend(reference_tokens) ref_location = token.location @@ -307,7 +307,7 @@ def substitute_references( else: _unresolved(ref_name, variables.keys(), token) else: - variables.setdefault(variable_name, []).append(token) + variable_tokens.append(token) yield token token = next(iter_tokens, None) elif token.name == "variable_ref": diff --git a/tests/css/test_parse.py b/tests/css/test_parse.py index fea7b3dadb..cb6e6aad0d 100644 --- a/tests/css/test_parse.py +++ b/tests/css/test_parse.py @@ -220,6 +220,22 @@ def test_undefined_variable(self): with pytest.raises(UnresolvedVariableError): list(substitute_references(tokenize(css, ""))) + def test_empty_variable(self): + css = "$x:\n* { background:$x; }" + result = list(substitute_references(tokenize(css, ""))) + assert [(t.name, t.value) for t in result] == [ + ("variable_name", "$x:"), + ("variable_value_end", "\n"), + ("selector_start_universal", "*"), + ("whitespace", " "), + ("declaration_set_start", "{"), + ("whitespace", " "), + ("declaration_name", "background:"), + ("declaration_end", ";"), + ("whitespace", " "), + ("declaration_set_end", "}"), + ] + def test_transitive_reference(self): css = "$x: 1\n$y: $x\n.thing { border: $y }" assert list(substitute_references(tokenize(css, ""))) == [