diff --git a/hy/compiler.py b/hy/compiler.py index 35d8371..3a1fa92 100644 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -2588,6 +2588,19 @@ class HyASTCompiler(object): def compile_symbol(self, symbol): if "." in symbol: glob, local = symbol.rsplit(".", 1) + + if not glob: + raise HyTypeError(symbol, 'cannot access attribute on ' + 'anything other than a name ' + '(in order to get attributes of' + 'expressions, use ' + '`(. {attr})` or ' + '`(.{attr} )`)'.format( + attr=local)) + + if not local: + raise HyTypeError(symbol, 'cannot access empty attribute') + glob = HySymbol(glob).replace(symbol) ret = self.compile_symbol(glob) diff --git a/tests/compilers/test_ast.py b/tests/compilers/test_ast.py index 2e91662..9a1a05e 100644 --- a/tests/compilers/test_ast.py +++ b/tests/compilers/test_ast.py @@ -542,6 +542,15 @@ def test_attribute_access(): cant_compile("(. foo bar baz [0] quux {frob})") +def test_attribute_empty(): + """Ensure using dot notation with a non-expression is an error""" + cant_compile(".") + cant_compile("foo.") + cant_compile(".foo") + cant_compile('"bar".foo') + cant_compile('[2].foo') + + def test_cons_correct(): """Ensure cons gets compiled correctly""" can_compile("(cons a b)")