@@ -168,7 +168,7 @@ def inject(obj: object) -> object:
168168
169169def nameof (var , * more_vars , # pylint: disable=unused-argument
170170 caller : int = 1 ,
171- full : bool = False ) -> Union [str , Tuple [str ]]:
171+ full : Optional [ bool ] = None ) -> Union [str , Tuple [str ]]:
172172 """Get the names of the variables passed in
173173
174174 Examples:
@@ -209,19 +209,36 @@ def nameof(var, *more_vars, # pylint: disable=unused-argument
209209 """
210210 node = _get_node (caller - 1 , raise_exc = True )
211211 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>' :
213233 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 ."
217237 )
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+ )
225242
226243 ret : List [str ] = []
227244 for arg in node .args :
@@ -370,11 +387,10 @@ def _node_name(node: NodeType) -> str:
370387def _bytecode_nameof (caller : int = 1 ) -> str :
371388 """Bytecode version of nameof as a fallback"""
372389 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 )
375391
376392@lru_cache ()
377- def _bytecode_nameof_cached (code : CodeType , offset : int , source : str ) -> str :
393+ def _bytecode_nameof_cached (code : CodeType , offset : int ) -> str :
378394 """Cached Bytecode version of nameof
379395
380396 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:
390406 )
391407
392408 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?" )
406410
407411 name_instruction = instructions [
408412 current_instruction_index - 1
0 commit comments