Re: addition of "nameof" operator

So this is not likely to ever work in IronPython or Jython.
There are no stability guarantees about the byte-code generated by CPython, so you may be chasing a moving target here.
You ought to test your code before posting, because I've tried it in 3.5, 3.7 and 3.8 and I get the same error each time:
TypeError: Expected maxsize to be an integer or None
which is a simple error in the call to the lru_cache decorator. After fixing that, I tried it again in 3.7 and I get this:
>>> x = 1 >>> nameof.nameof(x) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/srv-steve/python/nameof.py", line 7, in nameof return _nameof(frame.f_code, frame.f_lasti) File "/home/srv-steve/python/nameof.py", line 17, in _nameof assert current_instruction.opname == "CALL_FUNCTION" AssertionError
-- Steven
I wasn't expecting the Spanish Inquisition! This is not meant for serious use, just to help people interested in trying out the proposed functionality. But if you want to be serious, here you go: https://github.com/alexmojaki/nameof
This is properly tested with CPython 3.4+ and PyPy3. It's basically the same as the original version, I just tweaked the assertion to allow 'method' calls like nameof.nameof that you did which I wasn't expecting. The bytecode hasn't changed so drastically across Python versions that this is unstable.
Python 3.8 allows @lru_cache without arguments, I don't know why that didn't work for you.
On Sat, Feb 1, 2020 at 4:32 AM python-ideas-request@python.org wrote:
Send Python-ideas mailing list submissions to python-ideas@python.org
To subscribe or unsubscribe via the World Wide Web, visit https://mail.python.org/mailman3/lists/python-ideas.python.org/ or, via email, send a message with subject or body 'help' to python-ideas-request@python.org
You can reach the person managing the list at python-ideas-owner@python.org
When replying, please edit your Subject line so it is more specific than "Re: Contents of Python-ideas digest..."Today's Topics:
- Proposal for an additional type system (guenter-hofer@aon.at)
- Re: Proposal for an additional type system (Chris Angelico)
- Re: addition of "nameof" operator (Greg Ewing)
- Re: addition of "nameof" operator (Alex Hall)
- Re: addition of "nameof" operator (Steven D'Aprano)
- Re: addition of "nameof" operator (Christopher Barker)
---------- Forwarded message ---------- From: guenter-hofer@aon.at To: python-ideas@python.org Cc: Bcc: Date: Fri, 31 Jan 2020 23:45:47 +0100 (CET) Subject: [Python-ideas] Proposal for an additional type system The types in most programming languages are only technical types. If a variable has a type, you may know that it is of type integer or double, but you don't know if it's a length or an area. The types required are semantic types.
stypes: length area time speed scalar
allowed expressions: length = length length + length : length time = time time + time : time scalar * length : length scalar * time : time sqrt(area) : length speed = speed length / time : speed
foo : time bar : length baz : length
bar = 23 baz = 42.3 foo = 17.4 speed'variable = (bar + baz) / foo baz = length'5 bar = length'foo
Python's dynamic type checking remains.
These type names are all user defined. A type name with a tick before an expression means that this expression has the semantic type of the type name. The function names in the allowed expressions statement don't need to be names of existing functions.
---------- Forwarded message ---------- From: Chris Angelico rosuav@gmail.com To: python-ideas python-ideas@python.org Cc: Bcc: Date: Sat, 1 Feb 2020 10:22:13 +1100 Subject: [Python-ideas] Re: Proposal for an additional type system On Sat, Feb 1, 2020 at 10:06 AM guenter-hofer@aon.at wrote:
The types in most programming languages are only technical types. If a
variable has a type, you may know that it is of type integer or double, but you don't know if it's a length or an area.
The types required are semantic types.
stypes: length area time speed scalar
allowed expressions: length = length length + length : length time = time time + time : time scalar * length : length scalar * time : time sqrt(area) : length speed = speed length / time : speed
This doesn't need a dedicated type system. Those are actual types, representing units - though you've omitted the actual units. Create a system of classes with actual units, for instance:
class Meter(int): ...
class Second(int): ...
Define the operations that are valid on each of these, and what they return. Define the valid comparisons (for instance, 3 meters is not less than 4 seconds, and that doesn't make sense).
Python's normal type system is quite powerful, and can handle this smoothly.
(Once you've had a shot at building this yourself, poke around on PyPI and see what already exists.)
ChrisA
---------- Forwarded message ---------- From: Greg Ewing greg.ewing@canterbury.ac.nz To: python-ideas@python.org Cc: Bcc: Date: Sat, 01 Feb 2020 12:33:28 +1300 Subject: [Python-ideas] Re: addition of "nameof" operator On 1/02/20 6:15 am, Richard Damon wrote:
One issue I am seeing is that x = nameof(foo.bar) is crossing the line between compile time and run time behaviors. The resultant string, “bar” needs to be generated at compile time, but the operation still needs to do a check at run-time to determine if that IS the right result,
I don't think I would bother with the runtime check. This is mostly going to be used in a context where you're writing out the same thing again to get its value, e.g.
print("The value of", nameof(foo.bar), "is", foo.bar)
This can be translated to
print("The value of", "bar", "is", foo.bar)
and you'll still get an AttributeError if foo doesn't have a bar attribute.
-- Greg
---------- Forwarded message ---------- From: Alex Hall alex.mojaki@gmail.com To: python-ideas@python.org Cc: Bcc: Date: Sat, 1 Feb 2020 01:52:38 +0200 Subject: [Python-ideas] Re: addition of "nameof" operator Here's a simple runtime implementation that doesn't require any dependencies or source code access:
import dis import inspect from functools import lru_cache
def nameof(_): frame = inspect.currentframe().f_back return _nameof(frame.f_code, frame.f_lasti)
@lru_cache def _nameof(code, offset): instructions = list(dis.get_instructions(code)) (current_instruction_index, current_instruction), = ( (index, instruction) for index, instruction in enumerate(instructions) if instruction.offset == offset ) assert current_instruction.opname == "CALL_FUNCTION" name_instruction = instructions[current_instruction_index - 1] assert name_instruction.opname.startswith("LOAD_") return name_instruction.argrepr
def test(): print(nameof(dis)) print(nameof(dis.get_instructions)) x = 1 print(nameof(x))
if __name__ == '__main__': test()
---------- Forwarded message ---------- From: "Steven D'Aprano" steve@pearwood.info To: python-ideas@python.org Cc: Bcc: Date: Sat, 1 Feb 2020 11:52:21 +1100 Subject: [Python-ideas] Re: addition of "nameof" operator On Sat, Feb 01, 2020 at 01:52:38AM +0200, Alex Hall wrote:
Here's a simple runtime implementation that doesn't require any dependencies or source code access:
import dis
So this is not likely to ever work in IronPython or Jython.
There are no stability guarantees about the byte-code generated by CPython, so you may be chasing a moving target here.
You ought to test your code before posting, because I've tried it in 3.5, 3.7 and 3.8 and I get the same error each time:
TypeError: Expected maxsize to be an integer or None
which is a simple error in the call to the lru_cache decorator. After fixing that, I tried it again in 3.7 and I get this:
>>> x = 1 >>> nameof.nameof(x) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/srv-steve/python/nameof.py", line 7, in nameof return _nameof(frame.f_code, frame.f_lasti) File "/home/srv-steve/python/nameof.py", line 17, in _nameof assert current_instruction.opname == "CALL_FUNCTION" AssertionError
-- Steven
---------- Forwarded message ---------- From: Christopher Barker pythonchb@gmail.com To: "Steven D'Aprano" steve@pearwood.info Cc: python-ideas@python.org Bcc: Date: Fri, 31 Jan 2020 18:28:09 -0800 Subject: [Python-ideas] Re: addition of "nameof" operator I am really confused by this whole thread:
(I know this has all been said in this thread, but I’m summarizing to get us on the same page for the following comments)
Python has names, and it has values (objects, whatever) when we write Python, we bind names to values with the = operator. (And other namespace trickery). Some types of objects do have a __name__ attribute: classes, functions created with def.
But that name is only sometimes the same as the name(s) it might be bound to in any given namespace. So what the heck is nameof() supposed to mean? A few examples:
x = 5 nameof(x)
OK, I suppose that’s “x” — but what is the point of that? You have to know the name already.
What about:
y = 5 x = 5 (Or x = y)
What is nameof(x) And nameof(y)?
What about nameof(5)?
Now:
def fun(): pass
I suppose nameof(fun) is “fun”, but again, is that useful?
And now:
Fred = fun
What’s nameof(Fred)
If it’s “Fred” then again, useless.
If it’s “fun” then what about x and y before?
And:
def fun(): y = something return y
lst.append(fun())
nameof(lst[-1])
????
In short, if it means “what is the name of this name” that seems completely useless?
If it means: what name is this object bound to in this namespace? Than I can see how one might think that would be useful, but the answer could be:
No name at all More than one name A name different than the object’s __name__
And then there is the question of the local vs global namespace, the list goes on.
This thread has been going on a while:
What am I missing?
-CHB
-- Christopher Barker, PhD
Python Language Consulting
- Teaching
- Scientific Software Development
- Desktop GUI and Web Development
- wxPython, numpy, scipy, Cython
Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/

Alex, this is not ever going to be added to Python, no matter how well your hack seems to work. This is the main point of all the feedback you’re getting, even though it may be obscured by the critique of your example code.
Since at this point we’re debating a 3rd party extension, it is not appropriate to continue the discussion on python-ideas.
On Sat, Feb 1, 2020 at 02:49 Alex Hall alex.mojaki@gmail.com wrote:
So this is not likely to ever work in IronPython or Jython.
There are no stability guarantees about the byte-code generated by CPython, so you may be chasing a moving target here.
You ought to test your code before posting, because I've tried it in 3.5, 3.7 and 3.8 and I get the same error each time:
TypeError: Expected maxsize to be an integer or None
which is a simple error in the call to the lru_cache decorator. After fixing that, I tried it again in 3.7 and I get this:
>>> x = 1 >>> nameof.nameof(x) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/srv-steve/python/nameof.py", line 7, in nameof return _nameof(frame.f_code, frame.f_lasti) File "/home/srv-steve/python/nameof.py", line 17, in _nameof assert current_instruction.opname == "CALL_FUNCTION" AssertionError
-- Steven
I wasn't expecting the Spanish Inquisition! This is not meant for serious use, just to help people interested in trying out the proposed functionality. But if you want to be serious, here you go: https://github.com/alexmojaki/nameof
This is properly tested with CPython 3.4+ and PyPy3. It's basically the same as the original version, I just tweaked the assertion to allow 'method' calls like nameof.nameof that you did which I wasn't expecting. The bytecode hasn't changed so drastically across Python versions that this is unstable.
Python 3.8 allows @lru_cache without arguments, I don't know why that didn't work for you.
On Sat, Feb 1, 2020 at 4:32 AM python-ideas-request@python.org wrote:
Send Python-ideas mailing list submissions to python-ideas@python.org
To subscribe or unsubscribe via the World Wide Web, visit https://mail.python.org/mailman3/lists/python-ideas.python.org/ or, via email, send a message with subject or body 'help' to python-ideas-request@python.org
You can reach the person managing the list at python-ideas-owner@python.org
When replying, please edit your Subject line so it is more specific than "Re: Contents of Python-ideas digest..."Today's Topics:
- Proposal for an additional type system (guenter-hofer@aon.at)
- Re: Proposal for an additional type system (Chris Angelico)
- Re: addition of "nameof" operator (Greg Ewing)
- Re: addition of "nameof" operator (Alex Hall)
- Re: addition of "nameof" operator (Steven D'Aprano)
- Re: addition of "nameof" operator (Christopher Barker)
---------- Forwarded message ---------- From: guenter-hofer@aon.at To: python-ideas@python.org Cc: Bcc: Date: Fri, 31 Jan 2020 23:45:47 +0100 (CET) Subject: [Python-ideas] Proposal for an additional type system The types in most programming languages are only technical types. If a variable has a type, you may know that it is of type integer or double, but you don't know if it's a length or an area. The types required are semantic types.
stypes: length area time speed scalar
allowed expressions: length = length length + length : length time = time time + time : time scalar * length : length scalar * time : time sqrt(area) : length speed = speed length / time : speed
foo : time bar : length baz : length
bar = 23 baz = 42.3 foo = 17.4 speed'variable = (bar + baz) / foo baz = length'5 bar = length'foo
Python's dynamic type checking remains.
These type names are all user defined. A type name with a tick before an expression means that this expression has the semantic type of the type name. The function names in the allowed expressions statement don't need to be names of existing functions.
---------- Forwarded message ---------- From: Chris Angelico rosuav@gmail.com To: python-ideas python-ideas@python.org Cc: Bcc: Date: Sat, 1 Feb 2020 10:22:13 +1100 Subject: [Python-ideas] Re: Proposal for an additional type system On Sat, Feb 1, 2020 at 10:06 AM guenter-hofer@aon.at wrote:
The types in most programming languages are only technical types. If a
variable has a type, you may know that it is of type integer or double, but you don't know if it's a length or an area.
The types required are semantic types.
stypes: length area time speed scalar
allowed expressions: length = length length + length : length time = time time + time : time scalar * length : length scalar * time : time sqrt(area) : length speed = speed length / time : speed
This doesn't need a dedicated type system. Those are actual types, representing units - though you've omitted the actual units. Create a system of classes with actual units, for instance:
class Meter(int): ...
class Second(int): ...
Define the operations that are valid on each of these, and what they return. Define the valid comparisons (for instance, 3 meters is not less than 4 seconds, and that doesn't make sense).
Python's normal type system is quite powerful, and can handle this smoothly.
(Once you've had a shot at building this yourself, poke around on PyPI and see what already exists.)
ChrisA
---------- Forwarded message ---------- From: Greg Ewing greg.ewing@canterbury.ac.nz To: python-ideas@python.org Cc: Bcc: Date: Sat, 01 Feb 2020 12:33:28 +1300 Subject: [Python-ideas] Re: addition of "nameof" operator On 1/02/20 6:15 am, Richard Damon wrote:
One issue I am seeing is that x = nameof(foo.bar) is crossing the line between compile time and run time behaviors. The resultant string, “bar” needs to be generated at compile time, but the operation still needs to do a check at run-time to determine if that IS the right result,
I don't think I would bother with the runtime check. This is mostly going to be used in a context where you're writing out the same thing again to get its value, e.g.
print("The value of", nameof(foo.bar), "is", foo.bar)
This can be translated to
print("The value of", "bar", "is", foo.bar)
and you'll still get an AttributeError if foo doesn't have a bar attribute.
-- Greg
---------- Forwarded message ---------- From: Alex Hall alex.mojaki@gmail.com To: python-ideas@python.org Cc: Bcc: Date: Sat, 1 Feb 2020 01:52:38 +0200 Subject: [Python-ideas] Re: addition of "nameof" operator Here's a simple runtime implementation that doesn't require any dependencies or source code access:
import dis import inspect from functools import lru_cache
def nameof(_): frame = inspect.currentframe().f_back return _nameof(frame.f_code, frame.f_lasti)
@lru_cache def _nameof(code, offset): instructions = list(dis.get_instructions(code)) (current_instruction_index, current_instruction), = ( (index, instruction) for index, instruction in enumerate(instructions) if instruction.offset == offset ) assert current_instruction.opname == "CALL_FUNCTION" name_instruction = instructions[current_instruction_index - 1] assert name_instruction.opname.startswith("LOAD_") return name_instruction.argrepr
def test(): print(nameof(dis)) print(nameof(dis.get_instructions)) x = 1 print(nameof(x))
if __name__ == '__main__': test()
---------- Forwarded message ---------- From: "Steven D'Aprano" steve@pearwood.info To: python-ideas@python.org Cc: Bcc: Date: Sat, 1 Feb 2020 11:52:21 +1100 Subject: [Python-ideas] Re: addition of "nameof" operator On Sat, Feb 01, 2020 at 01:52:38AM +0200, Alex Hall wrote:
Here's a simple runtime implementation that doesn't require any dependencies or source code access:
import dis
So this is not likely to ever work in IronPython or Jython.
There are no stability guarantees about the byte-code generated by CPython, so you may be chasing a moving target here.
You ought to test your code before posting, because I've tried it in 3.5, 3.7 and 3.8 and I get the same error each time:
TypeError: Expected maxsize to be an integer or None
which is a simple error in the call to the lru_cache decorator. After fixing that, I tried it again in 3.7 and I get this:
>>> x = 1 >>> nameof.nameof(x) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/srv-steve/python/nameof.py", line 7, in nameof return _nameof(frame.f_code, frame.f_lasti) File "/home/srv-steve/python/nameof.py", line 17, in _nameof assert current_instruction.opname == "CALL_FUNCTION" AssertionError
-- Steven
---------- Forwarded message ---------- From: Christopher Barker pythonchb@gmail.com To: "Steven D'Aprano" steve@pearwood.info Cc: python-ideas@python.org Bcc: Date: Fri, 31 Jan 2020 18:28:09 -0800 Subject: [Python-ideas] Re: addition of "nameof" operator I am really confused by this whole thread:
(I know this has all been said in this thread, but I’m summarizing to get us on the same page for the following comments)
Python has names, and it has values (objects, whatever) when we write Python, we bind names to values with the = operator. (And other namespace trickery). Some types of objects do have a __name__ attribute: classes, functions created with def.
But that name is only sometimes the same as the name(s) it might be bound to in any given namespace. So what the heck is nameof() supposed to mean? A few examples:
x = 5 nameof(x)
OK, I suppose that’s “x” — but what is the point of that? You have to know the name already.
What about:
y = 5 x = 5 (Or x = y)
What is nameof(x) And nameof(y)?
What about nameof(5)?
Now:
def fun(): pass
I suppose nameof(fun) is “fun”, but again, is that useful?
And now:
Fred = fun
What’s nameof(Fred)
If it’s “Fred” then again, useless.
If it’s “fun” then what about x and y before?
And:
def fun(): y = something return y
lst.append(fun())
nameof(lst[-1])
????
In short, if it means “what is the name of this name” that seems completely useless?
If it means: what name is this object bound to in this namespace? Than I can see how one might think that would be useful, but the answer could be:
No name at all More than one name A name different than the object’s __name__
And then there is the question of the local vs global namespace, the list goes on.
This thread has been going on a while:
What am I missing?
-CHB
-- Christopher Barker, PhD
Python Language Consulting
- Teaching
- Scientific Software Development
- Desktop GUI and Web Development
- wxPython, numpy, scipy, Cython
Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/
Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/2PE5CD... Code of Conduct: http://python.org/psf/codeofconduct/

The whole feature.
On Sat, Feb 1, 2020 at 14:35 Greg Ewing greg.ewing@canterbury.ac.nz wrote:
On 2/02/20 6:12 am, Guido van Rossum wrote:
Alex, this is not ever going to be added to Python,
For clarity, are you rejecting the whole idea of a "nameof" feature, or just bytecode-hack implementations of it?
-- Greg _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/F7357T... Code of Conduct: http://python.org/psf/codeofconduct/

Hi Guido,
This thread had a lot of comments so far, both people that are pro and con. To be honest, a lot of you are a smarter and more experienced than me, so I receive all of it as learning moments.
What I am wondering about is your personal motivation to say the feature won't every be a part of Python. Would you mind to share that?
Kind regards,
Johan Vergeer

That's based on my observation of how the discussion went. I have been participating in such discussions for 30 years now and I can usually tell how it will end long before most other participants. So I actually cringe when I see discussion go on beyond the point of usefulness. This is such a case, where I feel it's fair to tell the participants to stop or take it elsewhere.
On Sun, Feb 2, 2020 at 01:39 Johan Vergeer johanvergeer@gmail.com wrote:
Hi Guido,
This thread had a lot of comments so far, both people that are pro and con. To be honest, a lot of you are a smarter and more experienced than me, so I receive all of it as learning moments.
What I am wondering about is your personal motivation to say the feature won't every be a part of Python. Would you mind to share that?
Kind regards,
Johan Vergeer _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/B6Q2LX... Code of Conduct: http://python.org/psf/codeofconduct/
participants (4)
-
Alex Hall
-
Greg Ewing
-
Guido van Rossum
-
Johan Vergeer