Skip to content

Commit 25850bb

Browse files
committed
Add a Symbol abstraction
1 parent f665325 commit 25850bb

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

unpythonic/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
from .seq import *
3737
from .singleton import *
3838
from .slicing import *
39+
from .symbol import *
3940
from .tco import *
4041

4142
# HACK: break dependency loop

unpythonic/symbol.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# -*- coding: utf-8; -*-
2+
"""A lispy symbol type for Python."""
3+
4+
__all__ = ["Symbol"]
5+
6+
_symbols = {}
7+
8+
class Symbol:
9+
def __new__(cls, name): # This covers unpickling, too.
10+
if name not in _symbols:
11+
_symbols[name] = super().__new__(cls)
12+
return _symbols[name]
13+
def __init__(self, name):
14+
self.name = name
15+
16+
# pickle support
17+
def __getnewargs__(self):
18+
return (self.name,)
19+
20+
def __str__(self):
21+
return self.name
22+
def __repr__(self):
23+
return 'Symbol("{}")'.format(self.name)

unpythonic/test/test_symbol.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# -*- coding: utf-8; -*-
2+
3+
import pickle
4+
5+
from ..symbol import Symbol as S
6+
7+
def test():
8+
# Basic idea: lightweight, human-readable, process-wide unique marker,
9+
# that can be quickly compared by object identity.
10+
assert S("foo") is S("foo")
11+
12+
# Works even if pickled.
13+
sym = S("foo")
14+
s = pickle.dumps(sym)
15+
o = pickle.loads(s)
16+
assert o is sym
17+
assert o is S("foo")
18+
19+
# str() returns the human-readable name as a string.
20+
assert str(S("foo")) == "foo"
21+
22+
# Has nothing to do with string interning.
23+
assert "λ" * 80 is not "λ" * 80
24+
assert S("λ" * 80) is S("λ" * 80)
25+
26+
print("All tests PASSED")
27+
28+
if __name__ == '__main__':
29+
test()

0 commit comments

Comments
 (0)