# Inconsistencies between \`Type\` and \`type\`

**URL:** <https://discuss.python.org/t/inconsistencies-between-type-and-type/37404>\
**Category:** Typing\
**Tags:** typing-spec\
**Created:** [October 28, 2023, 7:40pm UTC](https://discuss.python.org/t/inconsistencies-between-type-and-type/37404 "2023-10-28T19:40:57Z")\
**Posts on this page:** 1\
**Showing post:** 2

<div class="post-metadata">

**Author:** ![Jelle](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/jelle/32/1049_2.png) [@Jelle](https://discuss.python.org/u/Jelle)\
**Post date:** [October 28, 2023, 9:14pm UTC](https://discuss.python.org/t/inconsistencies-between-type-and-type/37404/2 "2023-10-28T21:14:26Z")

</div>

The behavior here is indeed confusing and inconsistent. This would be a good area to address by the Typing Council as a spec clarification once the Council is constituted.

I think there are two things that `type`/`type[Any]` could mean:

- An object that only allows operations that are valid on all types (analogous to `object`). With this interpretation, we should allow operations like `t. __name__ ` that work on all types, but we should not allow accessing attributes like `t.x` that don’t exist on all types. Both mypy and pyright allow spelling this as `type[object]` or `Type[object]` (and so do pyanalyze and pytype, but pyre treats type and Type differently).
- An object that is a type, but allows any operation that might be valid on some type (analogous to `Any`). This is how mypy treats `type[Any]`: for a variable `t` of type `type[Any]`, `t. __name__ ` is `str` (because that attribute is present for any type), but `t.x` is `Any`. I’ll call this “`type[Any]`”, though not all type checkers treat `type[Any]` this way.

For completeness, I’ll note that pyre, pytype, and pyanalyze all produce no errors on your code sample, though they differ in exactly what types they infer.

The text of PEP 484 seems to say that `type`/`Type`/`Type[Any]` should all be equivalent and mean `type[object]` as I defined it above. However, that’s not what any type checker has actually implemented.

Now, how should type checkers behave?

First, `type` and `Type` should mean exactly the same thing. That’s how all other pre-PEP 585 aliases behave, and it’s confusing for `type` to be different. That means both mypy and pyright have a bug in this area.

Next, `type[Any]` probably should have the behavior I outlined above for it (an object that is a type but also allows any operation that might be valid on some type). That’s how most type checkers except pyright treat it. I’m not sure how useful this behavior is, though, and it does create a weird entry in the type system, an “Any for types”.

Last, should plain `type` be equivalent to `type[Any]` or `type[object]`? The former is more consistent with the rest of the type system, and with the current text of PEP 484.

So I would say that your code sample should produce no errors: all of these annotations are equivalent to `type[Any]` and should allow arbitrary attributes.

---

_[View the full topic](https://discuss.python.org/t/inconsistencies-between-type-and-type/37404)._
