0

I have a method which inspects and processes the source of arbitrary classes (classes only, not class instances or any other non-class types). The classes can be from any standard library, or 3rd party library, or user-defined classes.

But don't know of a correct way of annotating the type of the class argument using the typing module. I don't think typing.Type is the right one because it also applies to objects:

>>> class A: pass
>>> a = A()

>>> def test(cl: typing.Type) -> typing.Type:
...     return type(cl)

>>> test(A)
>>> type
>>> isinstance(A, typing.Type)
>>> True

>>> test(a)
>>> type
>>> isinstance(A, typing.Type)
>>> False

>>> test('A')
>>> str
>>> isinstance(A, typing.Type)
>>> False

Should annotations work this way? Isn't the point that annotated arguments should restrict the calling of the method to recognise only the correct types of arguments?

7
  • 1
    Type hints are just that......hints.....they hint to things like your IDE the type that the object may be. But they are not part of the runtime code they dont force that an objects type must be specific Commented Feb 28, 2020 at 15:05
  • Thanks, that's fine. I thought perhaps it would be useful to have a special type hint applicable to classes only. Commented Feb 28, 2020 at 15:10
  • In the same way that there are separate type hints for generators (typing.Generator) and iterators (typing.Iterator), even though a generator is an iterator. Commented Feb 28, 2020 at 15:12
  • isinstance((x for x in range(10)), typing.Iterator) -> True Commented Feb 28, 2020 at 15:19
  • Sorry i removed my comment to rewrite it, geneartors return iterators, but they are not in them self iteraotrs Commented Feb 28, 2020 at 15:20

1 Answer 1

2

'Type' is indeed the right thing to use. For example, if you try type checking the following program using a type checker such as mypy...

from typing import Type

class A: pass

# To be even more precise, have the type signature be
# '(cls: Type[T]) -> Type[Type[T]]' where T is some TypeVar.
def test(cls: Type) -> Type:
    return type(cls)

a = A()

test(A)
test(a)
test('A')

...you end up with the following errors, which I believe is what you were expecting:

test.py:13: error: Argument 1 to "test" has incompatible type "A"; expected "Type[Any]"
test.py:14: error: Argument 1 to "test" has incompatible type "str"; expected "Type[Any]"
Found 2 errors in 1 file (checked 1 source file)

If you are asking why these type hints are not being checked by Python itself and why you need to use a 3rd party type checker, see What are type hints in Python 3.5?.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.