From 291847af15073ebe6300f935d74c18f493d211f8 Mon Sep 17 00:00:00 2001 From: Simon Gomizelj Date: Tue, 3 Apr 2018 23:36:10 -0400 Subject: [PATCH] Make HyKeyword constructor consistent The colon is now only part of its string representation and no longer accepted as part of the constructor: :foobar == HyKeyword("foobar") --- hy/compiler.py | 18 +++++++++--------- hy/core/language.hy | 2 +- hy/lex/parser.py | 2 +- hy/models.py | 18 ++++++++---------- tests/test_lex.py | 4 ++-- 5 files changed, 21 insertions(+), 23 deletions(-) diff --git a/hy/compiler.py b/hy/compiler.py index 2e278d8..b1ee4f2 100755 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -747,7 +747,7 @@ class HyASTCompiler(object): elif isinstance(form, HyString): x = [HySymbol(name), form] if form.brackets is not None: - x.extend([HyKeyword(":brackets"), form.brackets]) + x.extend([HyKeyword("brackets"), form.brackets]) return imports, HyExpression(x).replace(form), False return imports, HyExpression([HySymbol(name), @@ -811,7 +811,7 @@ class HyASTCompiler(object): ret += self.compile(expr.pop(0)) cause = None - if len(expr) == 2 and expr[0] == HyKeyword(":from"): + if len(expr) == 2 and expr[0] == HyKeyword("from"): if not PY3: raise HyCompileError( "raise from only supported in python 3") @@ -1170,7 +1170,7 @@ class HyASTCompiler(object): if isinstance(iexpr, HyList) and iexpr: module = iexpr.pop(0) entry = iexpr[0] - if entry == HyKeyword(":as"): + if entry == HyKeyword("as"): if not len(iexpr) == 2: raise HyTypeError(iexpr, "garbage after aliased import") @@ -1464,7 +1464,7 @@ class HyASTCompiler(object): else: assignments = {} while names: - if len(names) > 1 and names[1] == HyKeyword(":as"): + if len(names) > 1 and names[1] == HyKeyword("as"): k, _, v = names[:3] del names[:3] assignments[k] = v @@ -1473,7 +1473,7 @@ class HyASTCompiler(object): assignments[symbol] = symbol require(module, self.module_name, assignments=assignments) elif (isinstance(entry, HyList) and len(entry) == 3 - and entry[1] == HyKeyword(":as")): + and entry[1] == HyKeyword("as")): # e.g., (require [foo :as bar]) module, _, prefix = entry __import__(module) @@ -2190,12 +2190,12 @@ class HyASTCompiler(object): return asty.Name(symbol, id=ast_str(symbol), ctx=ast.Load()) @builds(HyKeyword) - def compile_keyword(self, string): + def compile_keyword(self, obj): ret = Result() ret += asty.Call( - string, - func=asty.Name(string, id="HyKeyword", ctx=ast.Load()), - args=[asty.Str(string, s=str_type(string))], + obj, + func=asty.Name(obj, id="HyKeyword", ctx=ast.Load()), + args=[asty.Str(obj, s=obj.name)], keywords=[]) ret.add_imports("hy", {"HyKeyword"}) return ret diff --git a/hy/core/language.hy b/hy/core/language.hy index b372ba8..0904b22 100644 --- a/hy/core/language.hy +++ b/hy/core/language.hy @@ -460,7 +460,7 @@ as EOF (defaults to an empty string)." Strings numbers and even objects with the __name__ magic will work." (if (keyword? value) - (HyKeyword (unmangle value)) + (HyKeyword (unmangle value.name)) (if (string? value) (HyKeyword (unmangle value)) (try diff --git a/hy/lex/parser.py b/hy/lex/parser.py index 1f5b2d8..e94e5a4 100755 --- a/hy/lex/parser.py +++ b/hy/lex/parser.py @@ -380,7 +380,7 @@ def symbol_like(obj): pass if obj.startswith(":") and "." not in obj: - return HyKeyword(obj) + return HyKeyword(obj[1:]) @pg.error diff --git a/hy/models.py b/hy/models.py index 3a4694d..5a16c02 100644 --- a/hy/models.py +++ b/hy/models.py @@ -124,34 +124,32 @@ _wrappers[type(None)] = lambda foo: HySymbol("None") class HyKeyword(HyObject): """Generic Hy Keyword object.""" - __slots__ = ['_value'] + __slots__ = ['name'] def __init__(self, value): - if value[0] != ':': - value = ':' + value - self._value = value + self.name = value def __repr__(self): - return "%s(%r)" % (self.__class__.__name__, self._value) + return "%s(%r)" % (self.__class__.__name__, self.name) def __str__(self): - return self._value + return ":%s" % self.name def __hash__(self): - return hash(self._value) + return hash(self.name) def __eq__(self, other): if not isinstance(other, HyKeyword): return NotImplemented - return self._value == other._value + return self.name == other.name def __ne__(self, other): if not isinstance(other, HyKeyword): return NotImplemented - return self._value != other._value + return self.name != other.name def __bool__(self): - return bool(self._value[1:]) + return bool(self.name) def strip_digit_separators(number): diff --git a/tests/test_lex.py b/tests/test_lex.py index 3fb94fd..ca06560 100644 --- a/tests/test_lex.py +++ b/tests/test_lex.py @@ -434,9 +434,9 @@ def test_discard(): assert tokenize("(#_foo)") == [HyExpression()] assert tokenize("(#_foo bar)") == [HyExpression([HySymbol("bar")])] assert tokenize("(foo #_bar)") == [HyExpression([HySymbol("foo")])] - assert tokenize("(foo :bar 1)") == [HyExpression([HySymbol("foo"), HyKeyword(":bar"), HyInteger(1)])] + assert tokenize("(foo :bar 1)") == [HyExpression([HySymbol("foo"), HyKeyword("bar"), HyInteger(1)])] assert tokenize("(foo #_:bar 1)") == [HyExpression([HySymbol("foo"), HyInteger(1)])] - assert tokenize("(foo :bar #_1)") == [HyExpression([HySymbol("foo"), HyKeyword(":bar")])] + assert tokenize("(foo :bar #_1)") == [HyExpression([HySymbol("foo"), HyKeyword("bar")])] # discard term with nesting assert tokenize("[1 2 #_[a b c [d e [f g] h]] 3 4]") == [ HyList([HyInteger(1), HyInteger(2), HyInteger(3), HyInteger(4)])