Skip to content

Commit 86e3cc7

Browse files
authored
Add a kwarg to munge to disallow builtins in munged names (#78)
1 parent db4798f commit 86e3cc7

File tree

4 files changed

+44
-32
lines changed

4 files changed

+44
-32
lines changed

basilisp/compiler.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
import basilisp.reader as reader
2929
from basilisp.lang.runtime import Var
3030
from basilisp.lang.typing import LispForm
31-
from basilisp.lang.util import genname
32-
from basilisp.util import Maybe, munge
31+
from basilisp.lang.util import genname, munge
32+
from basilisp.util import Maybe
3333

3434
_CORE_NS = 'basilisp.core'
3535
_DEFAULT_FN = '__lisp_expr__'

basilisp/lang/util.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import builtins
12
import datetime
3+
import keyword
24
import re
35
import uuid
46
from typing import Pattern
@@ -30,6 +32,39 @@ def lrepr(f) -> str:
3032
return repr(f)
3133

3234

35+
_MUNGE_REPLACEMENTS = {
36+
'+': '__PLUS__',
37+
'-': '_',
38+
'*': '__STAR__',
39+
'/': '__DIV__',
40+
'>': '__GT__',
41+
'<': '__LT__',
42+
'!': '__BANG__',
43+
'=': '__EQ__',
44+
'?': '__Q__',
45+
'\\': '__IDIV__',
46+
'&': '__AMP__'
47+
}
48+
49+
50+
def munge(s: str, allow_builtins: bool = True) -> str:
51+
"""Replace characters which are not valid in Python symbols
52+
with valid replacement strings."""
53+
new_str = []
54+
for c in s:
55+
new_str.append(_MUNGE_REPLACEMENTS.get(c, c))
56+
57+
new_s = ''.join(new_str)
58+
59+
if keyword.iskeyword(new_s):
60+
return f"{new_s}_"
61+
62+
if not allow_builtins and new_s in builtins.__dict__:
63+
return f"{new_s}_"
64+
65+
return new_s
66+
67+
3368
# Use an atomically incremented integer as a suffix for all
3469
# user-defined function and variable names compiled into Python
3570
# code so no conflicts occur

basilisp/util.py

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import functools
22
import inspect
3-
import keyword
43
import os.path
54
from typing import Optional, Callable, TypeVar, Generic
65

@@ -9,20 +8,6 @@
98

109
from basilisp.lang.util import lrepr
1110

12-
_MUNGE_REPLACEMENTS = {
13-
'+': '__PLUS__',
14-
'-': '_',
15-
'*': '__STAR__',
16-
'/': '__DIV__',
17-
'>': '__GT__',
18-
'<': '__LT__',
19-
'!': '__BANG__',
20-
'=': '__EQ__',
21-
'?': '__Q__',
22-
'\\': '__IDIV__',
23-
'&': '__AMP__'
24-
}
25-
2611

2712
def trace(f):
2813
@functools.wraps(f)
@@ -102,17 +87,3 @@ def stream(self) -> Sequence:
10287
@property
10388
def is_present(self) -> bool:
10489
return self._inner is not None
105-
106-
107-
def munge(s: str) -> str:
108-
"""Replace characters which are not valid in Python symbols
109-
with valid replacement strings."""
110-
new_str = []
111-
for c in s:
112-
new_str.append(_MUNGE_REPLACEMENTS.get(c, c))
113-
114-
new_s = ''.join(new_str)
115-
116-
if keyword.iskeyword(new_s):
117-
return f"{new_s}_"
118-
return new_s

tests/munge_test.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import builtins
12
import keyword
23

3-
from basilisp.util import munge
4+
from basilisp.lang.util import munge
45

56

67
def test_munge_disallows_syms():
@@ -17,6 +18,11 @@ def test_munge_disallows_syms():
1718
assert "__AMP__form" == munge("&form")
1819

1920

21+
def test_munge_disallows_python_builtins():
22+
for name in builtins.__dict__.keys():
23+
assert f"{name}_" == munge(name, allow_builtins=False)
24+
25+
2026
def test_munge_disallows_python_kws():
2127
for kw in keyword.kwlist:
2228
assert f"{kw}_" == munge(kw)

0 commit comments

Comments
 (0)