{"id":13746322,"url":"https://github.com/lonetwin/pythonrc","last_synced_at":"2025-05-09T07:30:33.183Z","repository":{"id":48097815,"uuid":"79644426","full_name":"lonetwin/pythonrc","owner":"lonetwin","description":"lonetwin's pimped-up pythonrc","archived":false,"fork":false,"pushed_at":"2022-08-29T09:05:44.000Z","size":219,"stargazers_count":131,"open_issues_count":4,"forks_count":15,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-11-15T19:37:24.363Z","etag":null,"topics":["dotfiles","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lonetwin.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-01-21T12:31:03.000Z","updated_at":"2024-08-28T14:19:34.000Z","dependencies_parsed_at":"2022-08-12T18:31:48.349Z","dependency_job_id":null,"html_url":"https://github.com/lonetwin/pythonrc","commit_stats":null,"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lonetwin%2Fpythonrc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lonetwin%2Fpythonrc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lonetwin%2Fpythonrc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lonetwin%2Fpythonrc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lonetwin","download_url":"https://codeload.github.com/lonetwin/pythonrc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253209230,"owners_count":21871612,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dotfiles","python"],"created_at":"2024-08-03T06:00:51.710Z","updated_at":"2025-05-09T07:30:32.982Z","avatar_url":"https://github.com/lonetwin.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"=============================\nlonetwin's pimped-up pythonrc\n=============================\n\nWhat is this ?\n==============\n\nThis is a python script intended to improve on the default Python interactive\nshell experience.\n\nUnlike ipython_, bpython_ or any of the many other options out there, this is\nnot designed to be used as a separate interactive environment. The intent is to\nkeep it as a single file and use it as any other rcfile. This script relies\nsolely on the standard python library and will always remain that way.\n\n---------\n\n.. note::\n\n    The `pythonrc.py` file here targets **python-3.8+**. If you wish to use/try\n    this out with an earlier version of python please use the `pythonrc_pre38.py`\n    file instead. Any new development will be done on this version but I'm\n    happy to fix any reported bugs for either.\n\n---------\n\nDemo\n=====\n|demo|\n\nUsage\n=====\n\nThe `pythonrc` file will be executed when the Python interactive shell is\nstarted, if `$PYTHONSTARTUP` is in your environment and points to the file (see\nnote about version above).\n\nYou could also simply make the file executable and call it directly.\n\nAdditionally, this file will in turn, execute a virtualenv specific rc file [#]_\nif it exists, for the current session, enabling you to *pre-populate* sessions\nspecific to virtual environments.\n\nFeatures\n========\n\nThe file creates an InteractiveConsole_ instance and executes it. This instance\nprovides:\n\n  * execution history\n  * colored prompts and pretty printing\n  * auto-indentation\n  * intelligent tab completion [#]_\n\n    - without preceding text four spaces\n    - with preceding text\n\n      + names in the current namespace\n      + for objects, their attributes/methods\n      + for strings with a `/`, pathname completion\n      + module name completion in an import statement\n\n  * edit the session or a file in your `$EDITOR` (the ``\\e`` command)\n\n    - with no arguments, opens your `$EDITOR` with the session hstory\n    - with filename argument, opens the file in your `$EDITOR`\n    - with object as an argument, opens the source code for the object in `$EDITOR`\n\n  * list the source code for objects when available (the ``\\l`` command)\n  * temporary escape to `$SHELL` or ability to execute a shell command and\n    capturing the output in to the `_` variable (the ``!`` command)\n  * convenient printing of doc stings (the ``?`` command) and search for entries in\n    online docs (the ``??`` command)\n  * auto-execution of a virtual env specific (`.venv_rc.py`) file at startup\n\nIf you have any other good ideas please feel free to submit pull requests or issues.\nThere's an section below which shows you how to add new commands.\n\n\nConfiguration\n=============\n\nThe code attempts to be easy to read and modify to suit personal preferences.\nYou can change any of the `commands` or the options like the path to the history\nfile, its size etc in the config dict at the top of the rc file. For instance,\nif you prefer to set the default edit command to `%edit` instead of the default\n``\\e``, you just have to change the entry in the config dict.\n\nNote that, the `init_readline()` method also reads your `.inputrc` file if it\nexists. This allows you to share the same `readline` behavior as all other tools\nthat use readline. For instance, in my personal `~/.inputrc` I have the\nfollowing::\n\n    # - when performing completion in the middle of a word, do not insert characters\n    # from the completion that match characters after point in the word being\n    # completed\n    set skip-completed-text on\n\n    # - displays possible completions using different colors according to file type.\n    set colored-stats on\n\n    # - show completed prefix in a different color\n    set colored-completion-prefix on\n\n    # - jump temporarily to matching open parenthesis\n    set blink-matching-paren on\n\n    set expand-tilde on\n    set history-size -1\n    set history-preserve-point on\n\n    \"\\e[A\": history-search-backward\n    \"\\e[B\": history-search-forward\n\n\nAdding new commands\n===================\n\nIt is relatively simple to add new commands to the `ImprovedConsole` class:\n\n1. Add the string that would invoke your new command to the `config` dict.\n2. Create a method in the `ImprovedConsole` class which receives a string\n   argument and returns either a string that can be evaluated as a python\n   expression or `None`. The method may do anything it fancies.\n3. Add an entry mapping the command to the method in the `commands` dict.\n\nThat's all !\n\nThe way commands work is, the text entered at the prompt is examined against the\n`commands_re` regular expression. This regular expression is simply the grouping\nof all valid commands, obtained from the keys of the `commands` dict.\n\nIf a match is found the corresponding function from the `commands` dict is\ncalled with the rest of the text following the command provided as the argument\nto the function.\n\nYou may choose to resolve this string argument to an object in the session\nnamespace by using the helper function `lookup()`.\n\nWhatever text is returned by the function is then passed on for further\nevaluation by the python interpreter.\n\nVarious helper functions exist like all the globally defined color functions\n(initialized by the `init_colors` method), the `_doc_to_usage` decorator,\n`_mktemp_buffer` and `_exec_from_file` whose intent ought to be hopefully\nobvious.\n\nHere's a complete example demonstrating the idea, by specifying a new command\n``\\s`` which prints the size of the specified object or of all objects in the\ncurrent namespace.\n\n::\n\n    config = dict(\n        ...\n        SIZE_OF = '\\s',\n    )\n    ...\n\n    class ImprovedConsole(...)\n        ...\n\n        def __init__(...):\n           ...\n           self.commands = {\n               ...\n               config['SIZE_OF']: self.print_sizeof,\n               ...\n           }\n        ...\n\n\n        @_doc_to_usage\n        def print_sizeof(self, arg=''):\n            \"\"\"{SIZE_OF} \u003cobject\u003e\n\n            Print the size of specified object or of all objects in current\n            namespace\n            \"\"\"\n            if arg:\n                obj = self.lookup(arg)\n                if obj:\n                    return print(sys.getsizeof(obj))\n                else:\n                    return self.print_sizeof('-h')\n            print({k: sys.getsizeof(v) for k, v in self.locals.items()})\n\n\nA little history\n================\n\nEver since around 2005_, I've been obsessed with tweaking my python interactive\nconsole to have it behave the way I prefer. Despite multiple attempts I've failed to\nembrace ipython on the command line because some of ipython's approach just\ndon't *fit my head*. Additionally, ipython is a full environment and I just need\nsome conveniences added to the default environment. This is why I started\nmaintaining my own pythonrc. I started eventually sharing it as a gist_ back in\n2014 and now about 38 revisions later, I think it might just make sense to set\nit up as a project so that I can accept pull requests, bug reports or\nsuggestions in case somebody bothers to use it and contribute back.\n\n\nKnown Issue\n===========\n\nThe console is *not* `__main__`. The issue was first reported by @deeenes in the\ngist_ I used to maintain. In essence, this code fails::\n\n    \u003e\u003e\u003e import timeit\n    \u003e\u003e\u003e\n    \u003e\u003e\u003e def getExecutionTime():\n    ...     t = timeit.Timer(\"sayHello()\", \"from __main__ import sayHello\")\n    ...     return t.timeit(2)\n    ...\n    \u003e\u003e\u003e def sayHello():\n    ...     print(\"Hello\")\n    ...\n    \u003e\u003e\u003e print(getExecutionTime())\n    Traceback (most recent call last):\n      File \"\u003cconsole\u003e\", line 1, in \u003cmodule\u003e\n      File \"\u003cconsole\u003e\", line 3, in getExecutionTime\n      File \"/usr/lib64/python2.7/timeit.py\", line 202, in timeit\n        timing = self.inner(it, self.timer)\n      File \"\u003ctimeit-src\u003e\", line 3, in inner\n    ImportError: cannot import name sayHello\n    \u003e\u003e\u003e\n\nThere are two possible workarounds for this:\n\n* When within the console, if you have to reference local names via\n  `__main__`, remember to do it via `__main__.pymp.locals` instead, something\n  like (for the example above)::\n\n      ...\n      def getExecutionTime():\n          t = timeit.Timer(\"sayHello()\", \"from __main__ import pymp; sayHello = pymp.locals['sayHello']\")\n      ...\n\n* Or in the pythonrc file, change the initialization of `ImprovedConsole` to\n  accept `locals()`. That is something like this::\n\n      pymp = ImprovedConsole(locals=locals())\n\n  Although the downside of this is, doing it will pollute your console\n  namespace with everything in the pythonrc file.\n\n\n.. [#] Named `.venv_rc.py` by default, but like almost everything else, is configurable\n.. [#] Since python 3.4 the default interpreter also has tab completion enabled however it does not do pathname completion\n.. _ipython: https://ipython.org/\n.. _bpython: https://bpython-interpreter.org/\n.. _InteractiveConsole: https://docs.python.org/3.6/library/code.html#code.InteractiveConsole\n.. _2005: http://code.activestate.com/recipes/438813/\n.. _gist: https://gist.github.com/lonetwin/5902720\n.. |demo| image:: https://asciinema.org/a/134711.png\n          :target: https://asciinema.org/a/134711?speed=2\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flonetwin%2Fpythonrc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flonetwin%2Fpythonrc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flonetwin%2Fpythonrc/lists"}