Naming is hard and obfuscating names for the computer is unfair to the author. In this notebook we explore naming
special strings that act as variables we. We acheive this by adding a transformer to ip.input_transformers_cleanup
.
import tokenize, io, IPython
import toolz.curried as toolz; import toolz.curried.operator as operator
ip = IPython.get_ipython()
tokenizer
is a utility function to create Python tokens from a string.
def tokenizer(str): return list(tokenize.generate_tokens(io.StringIO(str).readline))
replace_literal_strings
is the function inserted into ip.input_transformers_cleanup
. It transforms a string into an expression when:
def replace_literal_strings(str):
tokens = tokenizer(''.join(str))
for i, token in enumerate(tokens):
if token.type == tokenize.STRING and ' ' in token.string:
if ((i+1) < len(tokens) and tokens[i+1].string == '=') or (
token.string.strip(token.string[0]) in globals()):
tokens[i] = tokenize.TokenInfo(
token.type, f"globals()[{token.string}]",
token.start, token.end, token.line)
return tokenize.untokenize(tokens).splitlines(True)
Create the extensions.
def load_ipython_extension(ip):
unload_ipython_extension(ip) or ip.input_transformers_cleanup.insert(0, replace_literal_strings)
def unload_ipython_extension(ip):
for id, object in enumerate(ip.input_transformers_cleanup):
if object is replace_literal_strings: break
else: return
ip.input_transformers_cleanup.pop(id)
if __name__ == '__main__': load_ipython_extension(IPython.get_ipython())
The test is failing, but it work in the interactive context.
if __name__ == '__main__':
!ipython -m pytest -- 2018-10-10-Literal-String-Assign.ipynb -s
============================= test session starts ============================= platform win32 -- Python 3.6.6, pytest-3.5.1, py-1.5.3, pluggy-0.6.0 Matplotlib: 2.2.2 Freetype: 2.8.1 rootdir: C:\Users\deathbeds, inifile: plugins: xdist-1.22.5, testmon-0.9.12, remotedata-0.2.1, parallel-0.0.2, openfiles-0.3.0, mpl-0.9, localserver-0.4.1, forked-0.2, doctestplus-0.1.3, arraydiff-0.2, hypothesis-3.66.16, importnb-0.4.2 collected 1 item 2018-10-10-Literal-String-Assign.ipynb 11 this value F ================================== FAILURES =================================== _____________________________ test_literal_tokens _____________________________ def test_literal_tokens(): load_ipython_extension(IPython.get_ipython()) ip.run_cell("""'this value' = 11""") assert 'this value' in ip.user_ns ip.run_cell("""'another value' = 'this value' """) print(ip.user_ns['this value'], ip.user_ns['another value']) > assert ip.user_ns['this value'] == ip.user_ns['another value'] E AssertionError 2018-10-10-Literal-String-Assign.ipynb:131: AssertionError ========================== 1 failed in 0.39 seconds =========================== --------------------------------------------------------------------------- SystemExit Traceback (most recent call last) C:\Anaconda3\lib\runpy.py in run_module(mod_name, init_globals, run_name, alter_sys) 203 run_name = mod_name 204 if alter_sys: --> 205 return _run_module_code(code, init_globals, run_name, mod_spec) 206 else: 207 # Leave the sys module alone C:\Anaconda3\lib\runpy.py in _run_module_code(code, init_globals, mod_name, mod_spec, pkg_name, script_name) 94 mod_globals = temp_module.module.__dict__ 95 _run_code(code, mod_globals, init_globals, ---> 96 mod_name, mod_spec, pkg_name, script_name) 97 # Copy the globals of the temporary module, as they 98 # may be cleared when the temporary module goes away C:\Anaconda3\lib\runpy.py in _run_code(code, run_globals, init_globals, mod_name, mod_spec, pkg_name, script_name) 83 __package__ = pkg_name, 84 __spec__ = mod_spec) ---> 85 exec(code, run_globals) 86 return run_globals 87 C:\Anaconda3\lib\site-packages\pytest.py in <module> 72 # we trigger the below "else" condition by the following import 73 import pytest ---> 74 raise SystemExit(pytest.main()) 75 else: 76 SystemExit: 1
C:\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py:2788: UserWarning: Unknown failure executing module: <pytest> warn('Unknown failure executing module: <%s>' % mod_name)
def test_literal_tokens():
load_ipython_extension(IPython.get_ipython())
ip.run_cell("""'this value' = 11""")
assert 'this value' in ip.user_ns
ip.run_cell("""'another value' = 'this value' """)
print(ip.user_ns['this value'], ip.user_ns['another value'])
assert ip.user_ns['this value'] == ip.user_ns['another value']