[Python-ideas] Proposal for special name and qualname symbols

Steven D'Aprano steve at pearwood.info
Wed Jun 8 12:09:04 EDT 2016


This is an new thread inspired by the "Quick idea: defining variables 
from functions that take the variable name" thread.

For the benefit of those who haven't read that thread, in a nutshell, 
there are some functions or classes that find it useful or necessary to 
know their own name or qualified name. At the moment, apart from a few 
special cases where the compiler does the work behind the scenes 
(function and class definitions), the only way to do this is to 
hard-code the name/qualname as a string.

The classic example from the standard library is namedtuple:

Record = namedtuple('Record', fields)

Proposal: we introduce two special symbols to represent the name and 
qualname at any point. They can be used anywhere an identifier can be 
used.

We could use special dunder names, let's say __NAME__ and __QNAME__, but 
for now I'm going to use two special symbols:

@ for the unqualified bare name;
@@ for the qualified name.

The namedtuple example would become:

Record = namedtuple(@, fields)

If your function takes its name parameter somewhere other than the first 
argument, that's not a problem:

MyClass = make_a_class(spam, eggs, name=@, fnord=True)

'@' takes on the name, or dotted name, on the left-hand side of an 
assignment:

x = function(@)       # @ == 'x'
spam.x = function(@)  # @ == 'spam.x'

If there are multiple targets, and they are all simple or dotted names, 
@ is a tuple of names:

a, b, c.d = function(@)    # @ == ('a', 'b', 'c.d')
a = b = c.d = function(@)  # @ == ('a', 'b', 'c.d')

Those two cases are indistinguishable by @. I'm not sure if that's a bug 
or a feature :-)

For now, any other assignment target will be a syntax error. That 
restriction may be relaxed in the future, if necessary.

spam['key'] = function(@)  # SyntaxError


@ is not restricted to appear inside function calls:

element = mapping[@]  # like mapping['element']


The qualified name @@ gets the module name:

x = function(@@)  # @@ = 'module.x'

or, inside a class or function, the class/function name:

class K:
   attr = @@   # 'module.K.attr'
   def method(self):
       x = @@  # 'module.K.method.x'


Whether dunder names or symbols, assignment to them will be illegal:

@ = "myname"  # SyntaxError


Questions and answers:

Q: Why @ rather than $? 

A: $ is too similar to S for my liking, and I believe that Guido has 
said that $ will never be used for syntax in Python.

Q: What's the use-case for qualified names?

A: Classes need to know their qualified name for pickling.

Q: Isn't this rather magical?

A: Of course it is, but the `def` and `class` statements already make 
use of that compile magic, this just extends it to other things.

Q: Are you sure about the module being part of the qualified name?

A: I'm not wedded to that idea. If it's not necessary, take it out.

Q: Wait a minute, isn't @ used for matrix multiplication now? And @@ may 
be used for matrix exponentiation in the future?

A: Oh yeah, I forgot that. Damn. Guess we'll have to use the dunder 
names then.

Q: But the dunder names are too long to type.

A: Then think of your own symbols and propose them :-)



-- 
Steve


More information about the Python-ideas mailing list