{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Naming is hard and obfuscating names for the computer is unfair to the author. In this notebook we explore naming \n", "special strings that act as variables we. We acheive this by adding a transformer to `ip.input_transformers_cleanup`." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ " import tokenize, io, IPython\n", " import toolz.curried as toolz; import toolz.curried.operator as operator\n", " ip = IPython.get_ipython()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`tokenizer` is a utility function to create Python tokens from a string." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ " def tokenizer(str): return list(tokenize.generate_tokens(io.StringIO(str).readline))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`replace_literal_strings` is the function inserted into `ip.input_transformers_cleanup`. It transforms a string into an expression when:\n", " \n", "* There is a string following be equal sign.\n", "* The string is available in the global scope." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ " def replace_literal_strings(str):\n", " tokens = tokenizer(''.join(str))\n", "\n", " for i, token in enumerate(tokens):\n", " if token.type == tokenize.STRING and ' ' in token.string:\n", " if ((i+1) < len(tokens) and tokens[i+1].string == '=') or (\n", " token.string.strip(token.string[0]) in globals()):\n", " tokens[i] = tokenize.TokenInfo(\n", " token.type, f\"globals()[{token.string}]\", \n", " token.start, token.end, token.line)\n", " \n", " return tokenize.untokenize(tokens).splitlines(True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create the extensions." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ " def load_ipython_extension(ip): \n", " unload_ipython_extension(ip) or ip.input_transformers_cleanup.insert(0, replace_literal_strings)\n", " \n", " def unload_ipython_extension(ip): \n", " for id, object in enumerate(ip.input_transformers_cleanup):\n", " if object is replace_literal_strings: break\n", " else: return\n", " ip.input_transformers_cleanup.pop(id)\n", " if __name__ == '__main__': load_ipython_extension(IPython.get_ipython())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The test is failing, but it work in the interactive context." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "============================= test session starts =============================\n", "platform win32 -- Python 3.6.6, pytest-3.5.1, py-1.5.3, pluggy-0.6.0\n", "Matplotlib: 2.2.2\n", "Freetype: 2.8.1\n", "rootdir: C:\\Users\\deathbeds, inifile:\n", "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\n", "collected 1 item\n", "\n", "2018-10-10-Literal-String-Assign.ipynb 11 this value\n", "F\n", "\n", "================================== FAILURES ===================================\n", "_____________________________ test_literal_tokens _____________________________\n", "\n", " def test_literal_tokens():\n", " load_ipython_extension(IPython.get_ipython())\n", " ip.run_cell(\"\"\"'this value' = 11\"\"\")\n", " assert 'this value' in ip.user_ns\n", " ip.run_cell(\"\"\"'another value' = 'this value' \"\"\")\n", " print(ip.user_ns['this value'], ip.user_ns['another value'])\n", "> assert ip.user_ns['this value'] == ip.user_ns['another value']\n", "E AssertionError\n", "\n", "2018-10-10-Literal-String-Assign.ipynb:131: AssertionError\n", "========================== 1 failed in 0.39 seconds ===========================\n", "---------------------------------------------------------------------------\n", "SystemExit Traceback (most recent call last)\n", "C:\\Anaconda3\\lib\\runpy.py in run_module(mod_name, init_globals, run_name, alter_sys)\n", " 203 run_name = mod_name\n", " 204 if alter_sys:\n", "--> 205 return _run_module_code(code, init_globals, run_name, mod_spec)\n", " 206 else:\n", " 207 # Leave the sys module alone\n", "\n", "C:\\Anaconda3\\lib\\runpy.py in _run_module_code(code, init_globals, mod_name, mod_spec, pkg_name, script_name)\n", " 94 mod_globals = temp_module.module.__dict__\n", " 95 _run_code(code, mod_globals, init_globals,\n", "---> 96 mod_name, mod_spec, pkg_name, script_name)\n", " 97 # Copy the globals of the temporary module, as they\n", " 98 # may be cleared when the temporary module goes away\n", "\n", "C:\\Anaconda3\\lib\\runpy.py in _run_code(code, run_globals, init_globals, mod_name, mod_spec, pkg_name, script_name)\n", " 83 __package__ = pkg_name,\n", " 84 __spec__ = mod_spec)\n", "---> 85 exec(code, run_globals)\n", " 86 return run_globals\n", " 87 \n", "\n", "C:\\Anaconda3\\lib\\site-packages\\pytest.py in \n", " 72 # we trigger the below \"else\" condition by the following import\n", " 73 import pytest\n", "---> 74 raise SystemExit(pytest.main())\n", " 75 else:\n", " 76 \n", "\n", "SystemExit: 1\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "C:\\Anaconda3\\lib\\site-packages\\IPython\\core\\interactiveshell.py:2788: UserWarning: Unknown failure executing module: \n", " warn('Unknown failure executing module: <%s>' % mod_name)\n" ] } ], "source": [ " if __name__ == '__main__': \n", " !ipython -m pytest -- 2018-10-10-Literal-String-Assign.ipynb -s" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ " def test_literal_tokens():\n", " load_ipython_extension(IPython.get_ipython())\n", " ip.run_cell(\"\"\"'this value' = 11\"\"\")\n", " assert 'this value' in ip.user_ns\n", " ip.run_cell(\"\"\"'another value' = 'this value' \"\"\")\n", " print(ip.user_ns['this value'], ip.user_ns['another value'])\n", " assert ip.user_ns['this value'] == ip.user_ns['another value']" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.6" } }, "nbformat": 4, "nbformat_minor": 2 }