# Str.format for type

**URL:** <https://discuss.python.org/t/str-format-for-type/57778>\
**Category:** Ideas\
**Created:** [July 10, 2024, 4:04am UTC](https://discuss.python.org/t/str-format-for-type/57778 "2024-07-10T04:04:20Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [July 10, 2024, 4:04am UTC](https://discuss.python.org/t/str-format-for-type/57778/1 "2024-07-10T04:04:20Z")

</div>

My error messages most often simply print out the code that failed:

```python
a = 1
if not isinstance(a, str | tuple):
    raise TypeError(f'not isinstance({a=}, {str | tuple})')
# 'not isinstance(a=1, str | tuple)'

```

The issue is that `f'{a=}'` doesn’t completely describe the value. If both: `repr` and `type` were printed it would add much to clarity of the message.

So what I would like to have is:

```python
'not isinstance((int)a=1, str | tuple)'

```

Then I could write:

```python
if not isinstance(a, str | tuple):
    raise TypeError(f'not isinstance(({type(a). __name__ }){a=}, {str | tuple})')

```

But I ended up writing so many of these that I could really use a more convenient way.

So, I would like to inquire if anyone else would find string formatting for type name useful.

The best I came up with is:

```python
a = 1
print('{a!t}') # int

```

This way, full message would look like:

```python
if not isinstance(a, str | tuple):
    raise TypeError(f'not isinstance(({a!t}){a=}, {str | tuple})')

```

Would anyone else find this convenient?

---

<div class="post-metadata">

**Author:** ![GotoRoto](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/gotoroto/32/20308_2.png) [@GotoRoto](https://discuss.python.org/u/GotoRoto)\
**Post date:** [July 10, 2024, 4:42am UTC](https://discuss.python.org/t/str-format-for-type/57778/2 "2024-07-10T04:42:33Z")

</div>

If you find yourself requiring to include the repr and type of an object in an error message, what is stopping you from using a function like below?

```python
from typing import Any

def describer(obj: Any) -> str:
  return f'{repr(obj)} of type {type(obj). __name__ }'

a = 1 
if not isinstance(a, str | tuple):
  print(f'{describer(a)} is not a string or tuple')

```

Python already has enough special symbols for strings. This proposal would add nothing of value and would just confuse users with new syntax.

---

<div class="post-metadata">

**Author:** ![cameron](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/cameron/32/2658_2.png) [@cameron](https://discuss.python.org/u/cameron)\
**Post date:** [July 10, 2024, 5:04am UTC](https://discuss.python.org/t/str-format-for-type/57778/3 "2024-07-10T05:04:43Z")

</div>

Personally, I just keep a couple of functions around: `r(obj)` which  
returns `f'{type(obj). __name__ }:{obj!r}'` and a similar `s(obj)` which  
uses `str` instead of `repr`. Then I can just use `{r(obj)}` as desired.  
I generally don’t care about the variable name - that will often be  
obvious in the code, and I can always mention it if it seems useful.

So I just go:

```
 from cs.lex import r, s

```

and get on with my life.

I would not be in favour of a bunch of special purpose format thingies.  
There’s too many tiny things we’d all bikeshed about and it is pretty  
easy to roll things which get you 90% of the way there.

---

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [July 10, 2024, 5:22am UTC](https://discuss.python.org/t/str-format-for-type/57778/4 "2024-07-10T05:22:12Z")

</div>

It is a suggestion if more people are in need of this.

There is one issue with external function.

One can not use `f"{arg=}"`, so extra argument is needed to input the name.

`{obj!?}` has only 3 options now. If there was something useful for a lot of people, I don’t see why a sensible addition can not be considered.

---

<div class="post-metadata">

**Author:** ![storchaka](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/storchaka/32/217_2.png) [@storchaka](https://discuss.python.org/u/storchaka)\
**Post date:** [July 10, 2024, 6:15am UTC](https://discuss.python.org/t/str-format-for-type/57778/5 "2024-07-10T06:15:20Z")

</div>

Do not use a feature purposed for debugging to format a user facing error message.

---

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [July 10, 2024, 6:34am UTC](https://discuss.python.org/t/str-format-for-type/57778/6 "2024-07-10T06:34:12Z")

</div>

What are the reasons for not doing that? Are there any risks?

---

<div class="post-metadata">

**Author:** ![storchaka](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/storchaka/32/217_2.png) [@storchaka](https://discuss.python.org/u/storchaka)\
**Post date:** [July 10, 2024, 8:25am UTC](https://discuss.python.org/t/str-format-for-type/57778/7 "2024-07-10T08:25:59Z")

</div>

You expose an implementation detail (variable name). After refactoring the behavior of your program will change.

---

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [July 10, 2024, 8:53am UTC](https://discuss.python.org/t/str-format-for-type/57778/8 "2024-07-10T08:53:14Z")

</div>

I think it is a thin line here.

E.g. function argument name is the name of the variable, but it is reported in error messages.

Also, refactoring will change the variable name and error message will change with it, I don’t see what is wrong with it as long as it is a sensible variable name to report.

Also, the end user of software will never see these messages anyway. This is for low level code, which ideally should be as performant as possible.

Thus, writing complicated wrappers for these is not an option as it is often used in frameworks that extensively make use of error catching.

But this is my case and I can always make optimal compromise with existing features. And it is going to be ok. But with this it could be simpler and faster. So just thought maybe it could be of help to others too.

I realise now that it is a bit much - 1 function call and 1 method call. Nevertheless, I think this might be in at least top 5 of most used constructs in string formatting.

E.g. all ` __repr__ ` methods:

```python
def __repr__ (self):
    return f'{type(self). __name__ }(...)'
# TO->
def __repr__ (self):
    return f'{self:t}(...)'

```

---

<div class="post-metadata">

**Author:** ![MegaIng](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/megaing/32/16162_2.png) [@MegaIng](https://discuss.python.org/u/MegaIng)\
**Post date:** [July 10, 2024, 9:06am UTC](https://discuss.python.org/t/str-format-for-type/57778/9 "2024-07-10T09:06:42Z")

</div>

Also see [Enhance type name formatting when raising an exception: add %T format in C, and add type.\_\_fullyqualname\_\_](https://discuss.python.org/t/enhance-type-name-formatting-when-raising-an-exception-add-t-format-in-c-and-add-type-fullyqualname/38129)

---

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [July 10, 2024, 9:22am UTC](https://discuss.python.org/t/str-format-for-type/57778/10 "2024-07-10T09:22:28Z")

</div>

Much thanks, so what I have proposed is implemented and merged into main.

And apologies. This is lack of research on my part.

---

<div class="post-metadata">

**Author:** ![MegaIng](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/megaing/32/16162_2.png) [@MegaIng](https://discuss.python.org/u/MegaIng)\
**Post date:** [July 10, 2024, 9:23am UTC](https://discuss.python.org/t/str-format-for-type/57778/11 "2024-07-10T09:23:49Z")

</div>

Is it merged? I thought that part of the proposal was rejected.

---

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [July 10, 2024, 9:24am UTC](https://discuss.python.org/t/str-format-for-type/57778/12 "2024-07-10T09:24:25Z")

</div>

> <https://github.com/python/cpython/pull/116839>
>
> \<!--
> Thanks for your contribution!
> Please read this comment in its entirety. I…t's quite important.
> 
> \# Pull Request title
> 
> It should be in the following format:
> 
> \`\`\`
> gh-NNNNN: Summary of the changes made
> \`\`\`
> 
> Where: gh-NNNNN refers to the GitHub issue number.
> 
> Most PRs will require an issue number. Trivial changes, like fixing a typo, do not need an issue.
> 
> \# Backport Pull Request title
> 
> If this is a backport PR (PR made against branches other than \`main\`),
> please ensure that the PR title is in the following format:
> 
> \`\`\`
> \[X.Y\] \<title from the original PR\> (GH-NNNN)
> \`\`\`
> 
> Where: \[X.Y\] is the branch name, e.g. \[3.6\].
> 
> GH-NNNN refers to the PR number from \`main\`.
> 
> \--\>
> 
> 
> 
> \* Issue: gh-111696
> 
> 
> 
> 
> \----
> 📚 Documentation preview 📚: https://cpython-previews--116839.org.readthedocs.build/

---

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [July 10, 2024, 9:26am UTC](https://discuss.python.org/t/str-format-for-type/57778/13 "2024-07-10T09:26:15Z")

</div>

No, it seems you are right. It is C only.

---

<div class="post-metadata">

**Author:** ![xitop](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/xitop/32/13242_2.png) [@xitop](https://discuss.python.org/u/xitop)\
**Post date:** [July 10, 2024, 8:30pm UTC](https://discuss.python.org/t/str-format-for-type/57778/14 "2024-07-10T20:30:58Z")

</div>

Of course one can write `{type(var). __name__ }:{var}` or use a helper, but take a look from the opposite perspective. People don’t do that every time they should. Introducing any short and easy way for printing the type could help to create “the one and obvious way” to print an offending variable in all messages like this:

```
TypeError(f"Expected an integer, but got {arg}")

```

---

<div class="post-metadata">

**Author:** ![ilotoki0804](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/ilotoki0804/32/14237_2.png) [@ilotoki0804](https://discuss.python.org/u/ilotoki0804)\
**Post date:** [July 13, 2024, 1:25pm UTC](https://discuss.python.org/t/str-format-for-type/57778/15 "2024-07-13T13:25:46Z")

</div>

I really like this proposal. The `type(...). __name__ ` is used a lot. According to GitHub search results, it’s used 1.23 times more than `!r` and 8.14 times more than `!a`, so I think `!t` is worth it.

- Search results for `type(...). __name__ `: [Code search results · GitHub](https://github.com/search?q=language%3APython+%2Ftype%5C%28.*%5C%29%5C. __name__ %2F&type=code)

- Search results for `!r`: [Code search results · GitHub](https://github.com/search?q=language%3APython++%22%21r%22&type=code)

- Search results for `!a`: [Code search results · GitHub](https://github.com/search?q=language%3APython++%22%21a%22&type=code)

The code search results show many different ways to use `type(...). __name__ `. It might be worth checking them out.

In addition, I think we should also implement `!tr` and `!ta`, which would be `repr(type(...). __name__ )` and `ascii(type(...). __name__ )` respectively.

---

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [July 13, 2024, 5:19pm UTC](https://discuss.python.org/t/str-format-for-type/57778/16 "2024-07-13T17:19:59Z")

</div>

Your `a!` search has many false positives:  
[This might be more accurate](https://github.com/search?q=language%3APython++%22%21a%7D%22&type=code)

---

<div class="post-metadata">

**Author:** ![GotoRoto](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/gotoroto/32/20308_2.png) [@GotoRoto](https://discuss.python.org/u/GotoRoto)\
**Post date:** [July 13, 2024, 8:16pm UTC](https://discuss.python.org/t/str-format-for-type/57778/17 "2024-07-13T20:16:42Z")

</div>

Isn’t writing `f"{type(var). __name__ }:{var}"` or using a helper function already obvious though? I think most IDEs would allow developers to infer that the dunder name attribute is the name of a type. Even if the attribute wasn’t too intuitive, couldn’t one also write `f"{var=} of {type(var}“, which is equivalent to f”{var=} of \<class ‘{type(a). **name** }’\>". If some developers didn’t see the benefits of using the obvious solutions, they wouldn’t use the less obvious solution that is the proposed syntax. I also think that the developers who found they needed such solutions would find using functions and/or f-string expressions, the pre-existing solutions, to be more obvious than using some new specialized syntax.

---

<div class="post-metadata">

**Author:** ![ilotoki0804](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/ilotoki0804/32/14237_2.png) [@ilotoki0804](https://discuss.python.org/u/ilotoki0804)\
**Post date:** [July 13, 2024, 9:11pm UTC](https://discuss.python.org/t/str-format-for-type/57778/18 "2024-07-13T21:11:01Z")

</div>

@GotoRoto Isn’t `f"{repr(...)}"` also quite obvious? Your argument seems to be more of a questioning of the `!` syntax itself.

---

<div class="post-metadata">

**Author:** ![GotoRoto](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/gotoroto/32/20308_2.png) [@GotoRoto](https://discuss.python.org/u/GotoRoto)\
**Post date:** [July 13, 2024, 9:47pm UTC](https://discuss.python.org/t/str-format-for-type/57778/19 "2024-07-13T21:47:14Z")

</div>

I suppose that expression is also another obvious, socially established option. You’re correct in saying that my argument questions the `!` syntax. The expression also strengthens my argument, which is that the proposed `!` syntax currently doesn’t have a lot of usecases because they’re already taken up by the more obvious, socially established solutions.

---

<div class="post-metadata">

**Author:** ![davidism](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/davidism/32/3295_2.png) [@davidism](https://discuss.python.org/u/davidism)\
**Post date:** [July 13, 2024, 11:14pm UTC](https://discuss.python.org/t/str-format-for-type/57778/24 "2024-07-13T23:14:45Z")

</div>

Move back to discussing the actual topic, stop arguing, or this will be closed.

[Next page](https://discuss.python.org/t/str-format-for-type/57778.md?page=2)
