@@ -168,7 +168,7 @@ def inject(obj: object) -> object:
168
168
169
169
def nameof (var , * more_vars , # pylint: disable=unused-argument
170
170
caller : int = 1 ,
171
- full : bool = False ) -> Union [str , Tuple [str ]]:
171
+ full : Optional [ bool ] = None ) -> Union [str , Tuple [str ]]:
172
172
"""Get the names of the variables passed in
173
173
174
174
Examples:
@@ -209,19 +209,36 @@ def nameof(var, *more_vars, # pylint: disable=unused-argument
209
209
"""
210
210
node = _get_node (caller - 1 , raise_exc = True )
211
211
if not node :
212
- if full :
212
+ # We can't retrieve the node by executing.
213
+ # It can be due to running code from python/shell, exec/eval or
214
+ # other environments where sourcecode cannot be reached
215
+ # make sure we keep it simple (only single variable passed and no
216
+ # full passed) to use _bytecode_nameof
217
+ if not more_vars and full is None :
218
+ return _bytecode_nameof (caller + 1 )
219
+
220
+ # We are anyway raising exceptions, no worries about additional burden
221
+ # of frame retrieval again
222
+
223
+ # may raise exception, just leave it as is
224
+ frame = _get_frame (caller )
225
+ source = frame .f_code .co_filename
226
+ if source == '<stdin>' :
227
+ raise VarnameRetrievingError (
228
+ "Are you trying to call nameof in REPL/python shell? "
229
+ "In such a case, nameof can only be called with single "
230
+ "argument and no keyword arguments."
231
+ )
232
+ if source == '<string>' :
213
233
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 ."
234
+ "Are you trying to call nameof from exec/eval? "
235
+ "In such a case, nameof can only be called with single "
236
+ "argument and no keyword arguments ."
217
237
)
218
- # only works with nameof(a) or nameof(a.b)
219
- # no keyword arguments is supposed to be passed in
220
- # that means we cannot retrieve the full name without
221
- # sourcecode available
222
- if not more_vars :
223
- return _bytecode_nameof (caller + 1 )
224
- raise VarnameRetrievingError ("Unable to retrieve callee's node." )
238
+ raise VarnameRetrievingError (
239
+ "Source code unavailable, nameof can only retrieve the name of "
240
+ "a single variable, and argument `full` should not be specified."
241
+ )
225
242
226
243
ret : List [str ] = []
227
244
for arg in node .args :
@@ -370,11 +387,10 @@ def _node_name(node: NodeType) -> str:
370
387
def _bytecode_nameof (caller : int = 1 ) -> str :
371
388
"""Bytecode version of nameof as a fallback"""
372
389
frame = _get_frame (caller )
373
- source = frame .f_code .co_filename
374
- return _bytecode_nameof_cached (frame .f_code , frame .f_lasti , source )
390
+ return _bytecode_nameof_cached (frame .f_code , frame .f_lasti )
375
391
376
392
@lru_cache ()
377
- def _bytecode_nameof_cached (code : CodeType , offset : int , source : str ) -> str :
393
+ def _bytecode_nameof_cached (code : CodeType , offset : int ) -> str :
378
394
"""Cached Bytecode version of nameof
379
395
380
396
We are trying this version only when the sourcecode is unavisible. In most
@@ -390,19 +406,7 @@ def _bytecode_nameof_cached(code: CodeType, offset: int, source: str) -> str:
390
406
)
391
407
392
408
if current_instruction .opname not in ("CALL_FUNCTION" , "CALL_METHOD" ):
393
- if source == '<stdin>' :
394
- raise VarnameRetrievingError (
395
- "Are you trying to call nameof in REPL/python shell? "
396
- "In such a case, nameof can only be called with single "
397
- "argument and no keyword arguments."
398
- )
399
- if source == '<string>' :
400
- raise VarnameRetrievingError (
401
- "Are you trying to call nameof from exec/eval? "
402
- "In such a case, nameof can only be called with single "
403
- "argument and no keyword arguments."
404
- )
405
- raise VarnameRetrievingError ("Did you call nameof in a weird way? " )
409
+ raise VarnameRetrievingError ("Did you call nameof in a weird way?" )
406
410
407
411
name_instruction = instructions [
408
412
current_instruction_index - 1
0 commit comments