{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# `python-varname` playground" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.383587Z", "iopub.status.busy": "2021-08-13T18:11:04.382842Z", "iopub.status.idle": "2021-08-13T18:11:04.392820Z", "shell.execute_reply": "2021-08-13T18:11:04.392339Z" } }, "outputs": [], "source": [ "from contextlib import contextmanager\n", "\n", "from varname import (\n", " varname, nameof, will, argname,\n", " config,\n", " ImproperUseError, VarnameRetrievingError, QualnameNonUniqueError\n", ")\n", "from varname.helpers import Wrapper, register, debug, jsobj, exec_code\n", "\n", "@contextmanager\n", "def enable_debug():\n", " try:\n", " config.debug = True\n", " yield\n", " finally:\n", " config.debug = False\n", "\n", "@contextmanager\n", "def expect_raising(error):\n", " try:\n", " yield\n", " except error as exc:\n", " print(f'{error.__name__} raised!')\n", " else:\n", " raise Exception(f'{error.__name__!r} NOT raised!')" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Usage of `varname`" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Basic usage" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.397299Z", "iopub.status.busy": "2021-08-13T18:11:04.396854Z", "iopub.status.idle": "2021-08-13T18:11:04.440391Z", "shell.execute_reply": "2021-08-13T18:11:04.440717Z" } }, "outputs": [ { "data": { "text/plain": [ "'f'" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def func():\n", " return varname()\n", "\n", "f = func()\n", "f" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.446930Z", "iopub.status.busy": "2021-08-13T18:11:04.446505Z", "iopub.status.idle": "2021-08-13T18:11:04.454169Z", "shell.execute_reply": "2021-08-13T18:11:04.453664Z" } }, "outputs": [ { "data": { "text/plain": [ "'foo'" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "class Foo:\n", " def __init__(self):\n", " self.id = varname()\n", "\n", "foo = Foo()\n", "foo.id" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Some unusual tweaks" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.459948Z", "iopub.status.busy": "2021-08-13T18:11:04.459447Z", "iopub.status.idle": "2021-08-13T18:11:04.493291Z", "shell.execute_reply": "2021-08-13T18:11:04.492853Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 func\n", "2 ['func']\n", "3 ['func', 'func']\n", "4 ('func',)\n", "5 ('func', 'func')\n", "6 func\n", "7 func\n" ] } ], "source": [ "def function():\n", " return varname(strict=False)\n", "\n", "func = function()\n", "print(1, func)\n", "\n", "func = [function()]\n", "print(2, func)\n", "\n", "func = [function(), function()]\n", "print(3, func)\n", "\n", "func = (function(), )\n", "print(4, func)\n", "\n", "func = (function(), function())\n", "print(5, func)\n", "\n", "func_suffix = function()[:-7]\n", "print(6, func_suffix)\n", "\n", "alias = function\n", "func = alias()\n", "print(7, func)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### `varname` not called directly" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.498984Z", "iopub.status.busy": "2021-08-13T18:11:04.498569Z", "iopub.status.idle": "2021-08-13T18:11:04.507301Z", "shell.execute_reply": "2021-08-13T18:11:04.507597Z" } }, "outputs": [ { "data": { "text/plain": [ "'f'" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def func():\n", " return varname(frame=2)\n", "\n", "def func2():\n", " return func()\n", "\n", "f = func2()\n", "f" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.513453Z", "iopub.status.busy": "2021-08-13T18:11:04.512934Z", "iopub.status.idle": "2021-08-13T18:11:04.521674Z", "shell.execute_reply": "2021-08-13T18:11:04.521967Z" } }, "outputs": [ { "data": { "text/plain": [ "'foo'" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "class Foo:\n", " def __init__(self):\n", " self.id = varname(frame=2)\n", "\n", "def wrapper():\n", " return Foo()\n", "\n", "foo = wrapper()\n", "foo.id" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Using `ignore` argument to ignore intermediate calls" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.528098Z", "iopub.status.busy": "2021-08-13T18:11:04.527614Z", "iopub.status.idle": "2021-08-13T18:11:04.534133Z", "shell.execute_reply": "2021-08-13T18:11:04.534540Z" } }, "outputs": [ { "data": { "text/plain": [ "'f'" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def func():\n", " return varname(ignore=func2)\n", "\n", "def func2():\n", " return func()\n", "\n", "f = func2()\n", "f" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "You can also use a tuple of module and the qualified name of the function" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.541190Z", "iopub.status.busy": "2021-08-13T18:11:04.540661Z", "iopub.status.idle": "2021-08-13T18:11:04.548599Z", "shell.execute_reply": "2021-08-13T18:11:04.548941Z" } }, "outputs": [ { "data": { "text/plain": [ "'f'" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import __main__\n", "\n", "def func():\n", " return varname(ignore=(__main__, 'func2'))\n", "\n", "def func2():\n", " return func()\n", "\n", "f = func2()\n", "f" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Pay attention to decorated functions:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.555760Z", "iopub.status.busy": "2021-08-13T18:11:04.553555Z", "iopub.status.idle": "2021-08-13T18:11:04.563021Z", "shell.execute_reply": "2021-08-13T18:11:04.562685Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ImproperUseError raised!\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/workspaces/python-varname/varname/ignore.py:175: MaybeDecoratedFunctionWarning: You asked varname to ignore function 'wrapper', which may be decorated. If it is not intended, you may need to ignore all intermediate frames with a tuple of the function and the number of its decorators.\n", " warnings.warn(\n" ] } ], "source": [ "def decor(f):\n", " def wrapper():\n", " return f()\n", " return wrapper\n", "\n", "def func():\n", " return varname(ignore=func2)\n", "\n", "@decor\n", "def func2():\n", " return func()\n", "\n", "with expect_raising(ImproperUseError):\n", " f = func2()\n", "\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.570085Z", "iopub.status.busy": "2021-08-13T18:11:04.569646Z", "iopub.status.idle": "2021-08-13T18:11:04.578014Z", "shell.execute_reply": "2021-08-13T18:11:04.577579Z" } }, "outputs": [ { "data": { "text/plain": [ "'f'" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def decor(f):\n", " def wrapper():\n", " return f()\n", " return wrapper\n", "\n", "def func():\n", " # tell varname that func2 has 1 decorator\n", " return varname(ignore=(func2, 1))\n", "\n", "@decor\n", "def func2():\n", " return func()\n", "\n", "f = func2()\n", "f" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Ignore calls from an entire module and its submodules" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.582068Z", "iopub.status.busy": "2021-08-13T18:11:04.581474Z", "iopub.status.idle": "2021-08-13T18:11:04.594343Z", "shell.execute_reply": "2021-08-13T18:11:04.594680Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "[varname] DEBUG: >>> IgnoreList initiated <<<\n", "[varname] DEBUG: Ignored by IgnoreModule('varname') [In 'varname' at /workspaces/python-varname/varname/core.py:105]\n", "[varname] DEBUG: Ignored by IgnoreModule('module_all_calls') [In 'func' at /workspaces/python-varname/playground/module_all_calls.py:6]\n", "[varname] DEBUG: Ignored by IgnoreModule('module_all_calls') [In 'func2' at /workspaces/python-varname/playground/module_all_calls.py:9]\n", "[varname] DEBUG: Ignored by IgnoreModule('module_all_calls') [In 'func3' at /workspaces/python-varname/playground/module_all_calls.py:12]\n", "[varname] DEBUG: Skipping (0 more to skip) [In 'func' at /tmp/ipykernel_16149/3068660293.py:4]\n", "[varname] DEBUG: Gotcha! [In '' at /tmp/ipykernel_16149/3068660293.py:7]\n" ] }, { "data": { "text/plain": [ "'f'" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import module_all_calls\n", "\n", "def func():\n", " return module_all_calls.func3()\n", "\n", "with enable_debug():\n", " f = func()\n", "\n", "f" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Ignore some calls using module and a glob-style qualname" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.598845Z", "iopub.status.busy": "2021-08-13T18:11:04.598348Z", "iopub.status.idle": "2021-08-13T18:11:04.608687Z", "shell.execute_reply": "2021-08-13T18:11:04.609035Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "[varname] DEBUG: >>> IgnoreList initiated <<<\n", "[varname] DEBUG: Ignored by IgnoreModule('varname') [In 'varname' at /workspaces/python-varname/varname/core.py:105]\n", "[varname] DEBUG: Ignored by IgnoreModuleQualname('module_glob_qualname', '_func*') [In '_func' at /workspaces/python-varname/playground/module_glob_qualname.py:6]\n", "[varname] DEBUG: Ignored by IgnoreModuleQualname('module_glob_qualname', '_func*') [In '_func2' at /workspaces/python-varname/playground/module_glob_qualname.py:9]\n", "[varname] DEBUG: Skipping (0 more to skip) [In 'func3' at /workspaces/python-varname/playground/module_glob_qualname.py:12]\n", "[varname] DEBUG: Gotcha! [In '' at /tmp/ipykernel_16149/491507787.py:4]\n" ] }, { "data": { "text/plain": [ "'f'" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import module_glob_qualname\n", "\n", "with enable_debug():\n", " f = module_glob_qualname.func3()\n", "\n", "f" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Note that when using an exact qualname, it has to be unique in the module" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.612652Z", "iopub.status.busy": "2021-08-13T18:11:04.612124Z", "iopub.status.idle": "2021-08-13T18:11:04.616719Z", "shell.execute_reply": "2021-08-13T18:11:04.617282Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "QualnameNonUniqueError raised!\n" ] } ], "source": [ "import module_dual_qualnames\n", "\n", "with expect_raising(QualnameNonUniqueError):\n", " f = module_dual_qualnames.func3()" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "`lambda` functions are automatically ignored" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.623827Z", "iopub.status.busy": "2021-08-13T18:11:04.623229Z", "iopub.status.idle": "2021-08-13T18:11:04.631820Z", "shell.execute_reply": "2021-08-13T18:11:04.632182Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "[varname] DEBUG: >>> IgnoreList initiated <<<\n", "[varname] DEBUG: Ignored by IgnoreModule('varname') [In 'varname' at /workspaces/python-varname/varname/core.py:105]\n", "[varname] DEBUG: Skipping (0 more to skip) [In 'func' at /tmp/ipykernel_16149/2761136102.py:2]\n", "[varname] DEBUG: Ignored by IgnoreOnlyQualname(None, '*') [In '' at /tmp/ipykernel_16149/2761136102.py:4]\n", "[varname] DEBUG: Gotcha! [In '' at /tmp/ipykernel_16149/2761136102.py:7]\n" ] }, { "data": { "text/plain": [ "'f'" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def func():\n", " return varname()\n", "\n", "func2 = lambda: func()\n", "\n", "with enable_debug():\n", " f = func2()\n", "f" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Calls from standard libraries are automatically ignored" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.639182Z", "iopub.status.busy": "2021-08-13T18:11:04.638642Z", "iopub.status.idle": "2021-08-13T18:11:04.648615Z", "shell.execute_reply": "2021-08-13T18:11:04.648217Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "[varname] DEBUG: >>> IgnoreList initiated <<<\n", "[varname] DEBUG: Ignored by IgnoreModule('varname') [In 'varname' at /workspaces/python-varname/varname/core.py:105]\n", "[varname] DEBUG: Skipping (0 more to skip) [In '__init__' at /tmp/ipykernel_16149/641638691.py:8]\n", "[varname] DEBUG: Ignored by IgnoreStdlib('/usr/local/python/3.10.13/lib/python3.10/') [In '__call__' at /home/codespace/.python/current/lib/python3.10/typing.py:957]\n", "[varname] DEBUG: Gotcha! [In '' at /tmp/ipykernel_16149/641638691.py:11]\n" ] }, { "data": { "text/plain": [ "'foo'" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import typing\n", "from typing import Generic, TypeVar\n", "\n", "T = TypeVar(\"T\")\n", "\n", "class Foo(Generic[T]):\n", " def __init__(self):\n", " self.id = varname(ignore=[typing])\n", "\n", "with enable_debug():\n", " foo:Foo = Foo[str]()\n", "\n", "foo.id\n" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.654739Z", "iopub.status.busy": "2021-08-13T18:11:04.654275Z", "iopub.status.idle": "2021-08-13T18:11:04.662766Z", "shell.execute_reply": "2021-08-13T18:11:04.662323Z" } }, "outputs": [ { "data": { "text/plain": [ "'foo'" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "class Foo(Generic[T]):\n", " def __init__(self):\n", " self.id = varname()\n", "\n", "foo: Foo = Foo[str]()\n", "\n", "foo.id" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Filename can also be used instead of the module itself" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.667523Z", "iopub.status.busy": "2021-08-13T18:11:04.667108Z", "iopub.status.idle": "2021-08-13T18:11:04.678091Z", "shell.execute_reply": "2021-08-13T18:11:04.677699Z" } }, "outputs": [ { "data": { "text/plain": [ "'f'" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "source = '''\n", "def foo():\n", " return bar()\n", "'''\n", "\n", "code = compile(source, '', 'exec')\n", "\n", "def bar():\n", " return varname(ignore='')\n", " # can also be used together with qualname\n", " # return varname(ignore=('', 'bar'))\n", "\n", "globs = {'bar': bar}\n", "exec(code, globs)\n", "\n", "foo = globs['foo']\n", "\n", "f = foo()\n", "f" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Mixed use of `frame` and `ignore`" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.686748Z", "iopub.status.busy": "2021-08-13T18:11:04.686276Z", "iopub.status.idle": "2021-08-13T18:11:04.698813Z", "shell.execute_reply": "2021-08-13T18:11:04.698318Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "[varname] DEBUG: >>> IgnoreList initiated <<<\n", "[varname] DEBUG: Ignored by IgnoreModule('varname') [In 'varname' at /workspaces/python-varname/varname/core.py:105]\n", "[varname] DEBUG: Ignored by IgnoreDecorated('wrapper', 2) [In 'func' at /tmp/ipykernel_16149/652967550.py:2]\n", "[varname] DEBUG: Skipping (1 more to skip) [In 'wrapper' at /tmp/ipykernel_16149/652967550.py:9]\n", "[varname] DEBUG: Skipping (0 more to skip) [In 'func3' at /tmp/ipykernel_16149/652967550.py:18]\n", "[varname] DEBUG: Gotcha! [In '' at /tmp/ipykernel_16149/652967550.py:21]\n" ] }, { "data": { "text/plain": [ "'f'" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def func():\n", " return varname(\n", " frame=2, # skip func3\n", " ignore=(func2, 2) # ignore func2 and its decorators\n", " )\n", "\n", "def decor(f):\n", " def wrapper():\n", " return f()\n", " return wrapper\n", "\n", "@decor\n", "@decor\n", "def func2():\n", " return func()\n", "\n", "def func3():\n", " return func2()\n", "\n", "with enable_debug():\n", " f = func3()\n", "f" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Multiple variables assigned on left-hand side" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.706523Z", "iopub.status.busy": "2021-08-13T18:11:04.706046Z", "iopub.status.idle": "2021-08-13T18:11:04.730564Z", "shell.execute_reply": "2021-08-13T18:11:04.730917Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 (a, b) = ('a', 'b')\n", "2 (a, b) = ('a', 'b')\n", "3 a = ('a',)\n", "4 (a, b, c) = ('a', 'b', 'c')\n", "5 (a, b, x.c) = ('a', 'b', 'c')\n", "ImproperUseError raised!\n" ] } ], "source": [ "def function():\n", " return varname(multi_vars=True)\n", "\n", "a, b = function()\n", "print(1, '(a, b) =', (a, b))\n", "\n", "[a, b] = function()\n", "print(2, '(a, b) =', (a, b))\n", "\n", "a = function()\n", "print(3, 'a =', a)\n", "\n", "# hierarchy\n", "a, (b, c) = function()\n", "print(4, '(a, b, c) =', (a, b, c))\n", "\n", "# with attributes\n", "x = lambda: 1\n", "a, (b, x.c) = function()\n", "print(5, '(a, b, x.c) =', (a, b, x.c))\n", "\n", "with expect_raising(ImproperUseError):\n", " a, b[0] = function()" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Argument `raise_exc`" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.737764Z", "iopub.status.busy": "2021-08-13T18:11:04.735635Z", "iopub.status.idle": "2021-08-13T18:11:04.750698Z", "shell.execute_reply": "2021-08-13T18:11:04.750266Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "VarnameRetrievingError raised!\n" ] }, { "data": { "text/plain": [ "'None'" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def func_raise():\n", " return varname(raise_exc=True) # default\n", "\n", "def func_silent():\n", " return varname(raise_exc=False) # will return None if failed\n", "\n", "with expect_raising(VarnameRetrievingError):\n", " exec('f = func_raise()')\n", "\n", "gvars = {'func_silent': func_silent}\n", "exec('f = func_silent()', gvars)\n", "repr(gvars['f'])" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Multiple targets in assignment" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.754849Z", "iopub.status.busy": "2021-08-13T18:11:04.754316Z", "iopub.status.idle": "2021-08-13T18:11:04.762648Z", "shell.execute_reply": "2021-08-13T18:11:04.762269Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "f1 = 'f2', f2 = 'f2'\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/workspaces/python-varname/varname/core.py:124: MultiTargetAssignmentWarning: Multiple targets in assignment, variable name on the very right is used. \n", " warnings.warn(\n" ] } ], "source": [ "def func():\n", " return varname()\n", "\n", "f1 = f2 = func()\n", "print(f'f1 = {f1!r}, f2 = {f2!r}')\n", "# f1 == f2 == 'f1' when varname < 0.8" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Use of `nameof`" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.767662Z", "iopub.status.busy": "2021-08-13T18:11:04.767117Z", "iopub.status.idle": "2021-08-13T18:11:04.772991Z", "shell.execute_reply": "2021-08-13T18:11:04.773352Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x\n" ] } ], "source": [ "x = lambda: None\n", "print(nameof(x))" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Get full name of a chain of attributes" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.778858Z", "iopub.status.busy": "2021-08-13T18:11:04.777851Z", "iopub.status.idle": "2021-08-13T18:11:04.797968Z", "shell.execute_reply": "2021-08-13T18:11:04.797563Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x.a\n", "x.a.b\n", "('x.a', 'x.a.b')\n", "x.a()\n" ] } ], "source": [ "x.a = x\n", "x.a.b = x\n", "\n", "print(nameof(x.a, vars_only=False))\n", "print(nameof(x.a.b, vars_only=False))\n", "print(nameof(x.a, x.a.b, vars_only=False))\n", "print(nameof(x.a(), vars_only=False))" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "If you want to wrap `nameof`" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.803768Z", "iopub.status.busy": "2021-08-13T18:11:04.803314Z", "iopub.status.idle": "2021-08-13T18:11:04.811178Z", "shell.execute_reply": "2021-08-13T18:11:04.810839Z" } }, "outputs": [ { "data": { "text/plain": [ "'x'" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def nameof2(var, *more_vars):\n", " return nameof(var, *more_vars, frame=2)\n", "\n", "nameof2(x)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Use of `will`" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.816768Z", "iopub.status.busy": "2021-08-13T18:11:04.815180Z", "iopub.status.idle": "2021-08-13T18:11:04.827213Z", "shell.execute_reply": "2021-08-13T18:11:04.826863Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "AttributeError raised!\n" ] } ], "source": [ "class Namespace:\n", " public = 1\n", " _private = 2\n", "\n", "def func():\n", " w = will()\n", " if w.startswith('_'):\n", " raise AttributeError('Unable to access private attributes.')\n", "\n", " return Namespace\n", "\n", "print(func().public)\n", "with expect_raising(AttributeError):\n", " func()._private\n" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Use of `argname`" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.833103Z", "iopub.status.busy": "2021-08-13T18:11:04.831505Z", "iopub.status.idle": "2021-08-13T18:11:04.847826Z", "shell.execute_reply": "2021-08-13T18:11:04.848121Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x\n", "('y', 'x')\n", "('x+y', 'y+x')\n", "('x', 'z')\n", "(\"'a'\", '1')\n" ] } ], "source": [ "# argname is superseded by argname\n", "def func(a, b=1):\n", " # print(argname(a)) varname < 0.8\n", " print(argname('a'))\n", "\n", "x = y = z = 2\n", "func(x)\n", "\n", "def func2(a, b=1):\n", " # print(argname(a, b))\n", " print(argname('a', 'b'))\n", "func2(y, b=x)\n", "\n", "# allow expressions\n", "def func3(a, b=1):\n", " # print(argname(a, b, vars_only=False))\n", " print(argname('a', 'b', vars_only=False))\n", "func3(x+y, y+x)\n", "\n", "# positional and keyword arguments\n", "def func4(*args, **kwargs):\n", " # print(argname(args[1], kwargs['c']))\n", " print(argname('args[1]', 'kwargs[c]'))\n", "func4(y, x, c=z)\n", "\n", "# As of 0.9.0\n", "# Can also fetch the source of the argument for\n", "# __getattr__/__getitem__/__setattr/__setitem__/__add__/__lt__, etc.\n", "class Foo:\n", " def __setattr__(self, name, value):\n", " print(argname(\"name\", \"value\", func=self.__setattr__))\n", "\n", "Foo().a = 1 # prints: {_out}" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.854380Z", "iopub.status.busy": "2021-08-13T18:11:04.853952Z", "iopub.status.idle": "2021-08-13T18:11:04.860015Z", "shell.execute_reply": "2021-08-13T18:11:04.860341Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('x', 'y')\n" ] } ], "source": [ "# It is easier to wrap argname\n", "# You don't have to use the exact signature\n", "def argname3(*args):\n", " return argname(*args, frame=2)\n", "\n", "def func(a, b):\n", " return argname3('a', 'b')\n", "\n", "print(func(x, y))" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Use of helper functions" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### User of `Wrapper`" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.865673Z", "iopub.status.busy": "2021-08-13T18:11:04.865086Z", "iopub.status.idle": "2021-08-13T18:11:04.875523Z", "shell.execute_reply": "2021-08-13T18:11:04.875111Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "True\n", "True\n" ] } ], "source": [ "value1 = True\n", "value2 = {'a': 1}\n", "\n", "wrapped1 = Wrapper(True)\n", "wrapped2 = Wrapper(value2)\n", "\n", "print(repr(wrapped1))\n", "print(repr(wrapped2))\n", "\n", "print(wrapped1.value is value1)\n", "print(wrapped2.value is value2)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "You can wrap `Wrapper`:" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.881609Z", "iopub.status.busy": "2021-08-13T18:11:04.881091Z", "iopub.status.idle": "2021-08-13T18:11:04.890359Z", "shell.execute_reply": "2021-08-13T18:11:04.890852Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "True\n", "True\n" ] } ], "source": [ "def wrap(value):\n", " return Wrapper(value, frame=2)\n", "\n", "wrapped3 = wrap(value1)\n", "wrapped4 = wrap(value2)\n", "\n", "print(repr(wrapped3))\n", "print(repr(wrapped4))\n", "\n", "print(wrapped3.value is value1)\n", "print(wrapped4.value is value2)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Use of `register`" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Register `__varname__` to function" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.895641Z", "iopub.status.busy": "2021-08-13T18:11:04.895176Z", "iopub.status.idle": "2021-08-13T18:11:04.902402Z", "shell.execute_reply": "2021-08-13T18:11:04.901819Z" } }, "outputs": [ { "data": { "text/plain": [ "'f'" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@register\n", "def func():\n", " return __varname__\n", "\n", "f = func()\n", "f" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Register `__varname__` to class" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.907363Z", "iopub.status.busy": "2021-08-13T18:11:04.905999Z", "iopub.status.idle": "2021-08-13T18:11:04.912603Z", "shell.execute_reply": "2021-08-13T18:11:04.912900Z" } }, "outputs": [ { "data": { "text/plain": [ "'foo'" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@register\n", "class Foo:\n", " pass\n", "\n", "foo = Foo()\n", "foo.__varname__" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Use of `jsobj`" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'a': 1, 'b': 2}\n", "{'a': 1, 'b': 2, 'c': 3}\n" ] } ], "source": [ "a = 1\n", "b = 2\n", "print(jsobj(a, b))\n", "print(jsobj(a, b, c=3))" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Use of `debug`" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "execution": { "iopub.execute_input": "2021-08-13T18:11:04.919563Z", "iopub.status.busy": "2021-08-13T18:11:04.919106Z", "iopub.status.idle": "2021-08-13T18:11:04.938311Z", "shell.execute_reply": "2021-08-13T18:11:04.938681Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "DEBUG: a='1'\n", "DEBUG: b='2'\n", "DEBUG: a='1'\n", "DEBUG: b='2'\n", "DEBUG: a='1', b='2'\n", "DEBUG: a=1, b=2\n", "DEBUG VARS: a='1', b='2'\n", "DEBUG: a+b='12'\n", "DEBUG: a+b:'12'\n" ] } ], "source": [ "a = '1'\n", "b = '2'\n", "\n", "debug(a)\n", "debug(b)\n", "debug(a, b)\n", "debug(a, b, merge=True)\n", "debug(a, b, merge=True, repr=False)\n", "debug(a, b, merge=True, prefix='DEBUG VARS: ')\n", "debug(a+b, vars_only=False)\n", "debug(a+b, sep=':', vars_only=False)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Use of `exec_code`" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['1', '2']" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "class Obj:\n", " def __init__(self):\n", " self.argnames = []\n", "\n", " def receive(self, arg):\n", " self.argnames.append(argname('arg', func=self.receive))\n", "\n", "obj = Obj()\n", "# exec('obj.receive(1)') # Error\n", "exec_code('obj.receive(1)')\n", "exec_code('obj.receive(2)')\n", "obj.argnames" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3.9.5 ('base')", "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.10.13" }, "vscode": { "interpreter": { "hash": "9ed5c94d10bf621c6841991b7e31ffd0f3c8de8ec4167710459737a50edc58e4" } } }, "nbformat": 4, "nbformat_minor": 2 }