@@ -180,7 +180,16 @@ def nameof(var, *more_vars, # pylint: disable=unused-argument
180180
181181 >>> x = lambda: None
182182 >>> x.y = 1
183- >>> nameof(x.y) # 'x.y'
183+ >>> nameof(x.y, full=True) # 'x.y'
184+
185+ Note:
186+ This function works with the environments where source code is
187+ available, in other words, the callee's node can be retrieved by
188+ `executing`. In some cases, for example, running code from python
189+ shell/REPL or from `exec`/`eval`, we try to fetch the variable name
190+ from the bytecode. This requires only a single variable name is passed
191+ to this function and no keyword arguments, meaning that getting full
192+ names of attribute calls are not supported in such cases.
184193
185194 Args:
186195 var: The variable to retrieve the name of
@@ -200,10 +209,16 @@ def nameof(var, *more_vars, # pylint: disable=unused-argument
200209 """
201210 node = _get_node (caller - 1 , raise_exc = True )
202211 if not node :
212+ if full :
213+ raise VarnameRetrievingError (
214+ "Cannot retrieve full name by nameof when called "
215+ "in shell/REPL, exec/eval or other situations "
216+ "where sourcecode is unavailable."
217+ )
203218 # only works with nameof(a) or nameof(a.b)
204219 # no keyword arguments is supposed to be passed in
205220 # that means we cannot retrieve the full name without
206- # soucecode available and you can't wrap this function in such a case
221+ # sourcecode available
207222 if not more_vars :
208223 return _bytecode_nameof (caller + 1 )
209224 raise VarnameRetrievingError ("Unable to retrieve callee's node." )
@@ -362,7 +377,7 @@ def _bytecode_nameof(caller: int = 1) -> str:
362377def _bytecode_nameof_cached (code : CodeType , offset : int , source : str ) -> str :
363378 """Cached Bytecode version of nameof
364379
365- We are trying this version only when the soucecode is unavisible. In most
380+ We are trying this version only when the sourcecode is unavisible. In most
366381 cases, this will happen when user is trying to run a script in REPL/
367382 python shell, with `eval`, or other circumstances where the code is
368383 manipulated to run but sourcecode is not available.
@@ -383,7 +398,7 @@ def _bytecode_nameof_cached(code: CodeType, offset: int, source: str) -> str:
383398 )
384399 if source == '<string>' :
385400 raise VarnameRetrievingError (
386- "Are you trying to call nameof from evaluation ? "
401+ "Are you trying to call nameof from exec/eval ? "
387402 "In such a case, nameof can only be called with single "
388403 "argument and no keyword arguments."
389404 )
@@ -392,6 +407,7 @@ def _bytecode_nameof_cached(code: CodeType, offset: int, source: str) -> str:
392407 name_instruction = instructions [
393408 current_instruction_index - 1
394409 ]
410+
395411 if not name_instruction .opname .startswith ("LOAD_" ):
396412 raise VarnameRetrievingError ("Argument must be a variable or attribute" )
397413
0 commit comments