{ "cells": [ { "cell_type": "markdown", "id": "dirty-construction", "metadata": {}, "source": [ "# Rope\n", "\n", "[Rope](https://github.com/python-rope/rope) ist eine Python-Bibliothek für Refactoring." ] }, { "cell_type": "markdown", "id": "later-article", "metadata": {}, "source": [ "## Installation\n", "\n", "Rope lässt sich ganz einfach mit folgendem Befehl installieren:\n", "\n", "```bash\n", "$ uv add rope\n", "```" ] }, { "cell_type": "markdown", "id": "concrete-cover", "metadata": {}, "source": [ "## Verwendung\n", "\n", "Zunächst importieren wir den Typ `Project` und instanziieren ihn mit dem Pfad zum Projekt:" ] }, { "cell_type": "code", "execution_count": 1, "id": "floral-drinking", "metadata": { "execution": { "iopub.execute_input": "2026-05-20T17:38:43.453097Z", "iopub.status.busy": "2026-05-20T17:38:43.452674Z", "iopub.status.idle": "2026-05-20T17:38:43.575158Z", "shell.execute_reply": "2026-05-20T17:38:43.574795Z", "shell.execute_reply.started": "2026-05-20T17:38:43.453079Z" } }, "outputs": [], "source": [ "from rope.base.project import Project\n", "\n", "\n", "proj = Project(\"requests\")" ] }, { "cell_type": "markdown", "id": "nervous-university", "metadata": {}, "source": [ "Dadurch wird in unserem Projekt ein Projektordner mit dem Namen `.ropeproject` erstellt." ] }, { "cell_type": "code", "execution_count": 2, "id": "modular-dodge", "metadata": { "execution": { "iopub.execute_input": "2026-05-20T17:38:43.575789Z", "iopub.status.busy": "2026-05-20T17:38:43.575627Z", "iopub.status.idle": "2026-05-20T17:38:43.579982Z", "shell.execute_reply": "2026-05-20T17:38:43.579653Z", "shell.execute_reply.started": "2026-05-20T17:38:43.575775Z" } }, "outputs": [ { "data": { "text/plain": [ "['compat.py',\n", " 'cookies.py',\n", " '__init__.py',\n", " 'structures.py',\n", " 'hooks.py',\n", " 'adapters.py',\n", " 'sessions.py',\n", " 'utils.py',\n", " 'api.py',\n", " 'certs.py',\n", " 'models.py',\n", " '__version__.py',\n", " 'help.py',\n", " 'packages.py',\n", " '_internal_utils.py',\n", " 'exceptions.py',\n", " 'auth.py',\n", " 'status_codes.py']" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[f.name for f in proj.get_files()]" ] }, { "cell_type": "markdown", "id": "interested-basketball", "metadata": {}, "source": [ "Die Variable `proj` kann eine Reihe von Befehlen ausführen, wie beispielsweise `get_files` und `get_file`. Im folgenden Beispiel verwenden wir dies, um der Variablen `api` die Datei `api.py` zuzuweisen." ] }, { "cell_type": "code", "execution_count": 3, "id": "supreme-terrorist", "metadata": { "execution": { "iopub.execute_input": "2026-05-20T17:38:43.580694Z", "iopub.status.busy": "2026-05-20T17:38:43.580378Z", "iopub.status.idle": "2026-05-20T17:38:43.708768Z", "shell.execute_reply": "2026-05-20T17:38:43.708248Z", "shell.execute_reply.started": "2026-05-20T17:38:43.580683Z" } }, "outputs": [], "source": [ "!cp requests/api.py requests/api_v1.py" ] }, { "cell_type": "code", "execution_count": 4, "id": "heated-airline", "metadata": { "execution": { "iopub.execute_input": "2026-05-20T17:38:43.709483Z", "iopub.status.busy": "2026-05-20T17:38:43.709344Z", "iopub.status.idle": "2026-05-20T17:38:43.711708Z", "shell.execute_reply": "2026-05-20T17:38:43.711401Z", "shell.execute_reply.started": "2026-05-20T17:38:43.709463Z" } }, "outputs": [], "source": [ "api = proj.get_file(\"api.py\")" ] }, { "cell_type": "code", "execution_count": 5, "id": "choice-customer", "metadata": { "execution": { "iopub.execute_input": "2026-05-20T17:38:43.712203Z", "iopub.status.busy": "2026-05-20T17:38:43.712124Z", "iopub.status.idle": "2026-05-20T17:38:43.787764Z", "shell.execute_reply": "2026-05-20T17:38:43.787445Z", "shell.execute_reply.started": "2026-05-20T17:38:43.712196Z" } }, "outputs": [], "source": [ "from rope.refactor.rename import Rename\n", "\n", "\n", "change = Rename(proj, api).get_changes(\"api.py\")\n", "\n", "proj.do(change)" ] }, { "cell_type": "code", "execution_count": 6, "id": "reported-reproduction", "metadata": { "execution": { "iopub.execute_input": "2026-05-20T17:38:43.790440Z", "iopub.status.busy": "2026-05-20T17:38:43.790275Z", "iopub.status.idle": "2026-05-20T17:38:43.925129Z", "shell.execute_reply": "2026-05-20T17:38:43.924738Z", "shell.execute_reply.started": "2026-05-20T17:38:43.790422Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "On branch main\r\n", "Changes not staged for commit:\r\n", " (use \"git add ...\" to update what will be committed)\r\n", " (use \"git restore ...\" to discard changes in working directory)\r\n", "\t\u001b[31mmodified: __init__.py\u001b[m\r\n", "\r\n", "Untracked files:\r\n", " (use \"git add ...\" to include in what will be committed)\r\n", "\t\u001b[31m.ropeproject/\u001b[m\r\n", "\t\u001b[31mapi_v1.py\u001b[m\r\n", "\r\n", "Changes not staged for commit (use \"git add\" and/or \"git commit -a\")\r\n" ] } ], "source": [ "!cd requests && git status" ] }, { "cell_type": "code", "execution_count": 7, "id": "attempted-ratio", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1mdiff --git a/__init__.py b/__init__.py\u001b[m\r\n", "\u001b[1mindex f8f9429..502e33a 100644\u001b[m\r\n", "\u001b[1m--- a/__init__.py\u001b[m\r\n", "\u001b[1m+++ b/__init__.py\u001b[m\r\n", "\u001b[36m@@ -118,7 +118,7 @@\u001b[m \u001b[mfrom .__version__ import __copyright__, __cake__\u001b[m\r\n", " from . import utils\u001b[m\r\n", " from . import packages\u001b[m\r\n", " from .models import Request, Response, PreparedRequest\u001b[m\r\n", "\u001b[31m-from .api import request, get, head, post, patch, put, delete, options\u001b[m\r\n", "\u001b[32m+\u001b[m\u001b[32mfrom .api_v1 import request, get, head, post, patch, put, delete, options\u001b[m\r\n", " from .sessions import session, Session\u001b[m\r\n", " from .status_codes import codes\u001b[m\r\n", " from .exceptions import (\u001b[m\r\n" ] } ], "source": [ "!cd requests && git diff __init__.py" ] }, { "cell_type": "markdown", "id": "consolidated-rescue", "metadata": {}, "source": [ "Mit `proj.do(change)` wurde die Datei `requests/__init__.py` so geändert, dass nun aus `new_api` statt aus `api` importiert wird." ] }, { "cell_type": "markdown", "id": "adult-practitioner", "metadata": {}, "source": [ "Rope kann nicht nur zum Umbenennen von Dateien verwendet werden, sondern auch in vielen anderen Fällen; siehe auch [Rope Refactorings](https://rope.readthedocs.io/en/latest/overview.html#refactorings)." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3.13 Kernel", "language": "python", "name": "python313" }, "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.13.0" }, "latex_envs": { "LaTeX_envs_menu_present": true, "autoclose": false, "autocomplete": true, "bibliofile": "biblio.bib", "cite_by": "apalike", "current_citInitial": 1, "eqLabelWithNumbers": true, "eqNumInitial": 1, "hotkeys": { "equation": "Ctrl-E", "itemize": "Ctrl-I" }, "labels_anchors": false, "latex_user_defs": false, "report_style_numbering": false, "user_envs_cfg": false }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": {}, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 5 }