See my very detailed posts on EXACTLY the concepts you discuss.

"whether 'bar' is a name"? It is definitely a name, what you have no means to know is whether it has been assigned a value. I suspect you're trying to do the thing some people do where they insist on 'name' to avoid using the term 'variable'

I have no idea what you are trying to make "is a name" mean.  In an ordinary and Python sense, an unbound "name" isn't a name.  I guess you can say "variable" if that makes you happier somehow.  I'm not sure if you are trying to make some hair-splitting distinction between a UnboundLocalError and a NameError.

>>> def fun():
...     if False: x = 1
...     print('x' in locals())
...     print('x' in globals())
...     try:
...         x
...     except Exception as err:
...         print(err)
>>> fun()
False
False
local variable 'x' referenced before assignment