Yes, there is a difference. Although in Python 3, all objects are instances of object, including object itself, only Any documents that the return value should be disregarded by the typechecker.

The Any type docstring states that object is a subclass of Any and vice-versa:

>>> import typing
>>> print(typing.Any.__doc__)
Special type indicating an unconstrained type.

    - Any object is an instance of Any.
    - Any class is a subclass of Any.
    - As a special case, Any and object are subclasses of each other.

However, a proper typechecker (one that goes beyond isinstance() checks, and which inspects how the object is actually used in the function) can readily object to object where Any is always accepted.

From the Any type documentation:

Notice that no typechecking is performed when assigning a value of type Any to a more precise type.

and

Contrast the behavior of Any with the behavior of object. Similar to Any, every type is a subtype of object. However, unlike Any, the reverse is not true: object is not a subtype of every other type.

That means when the type of a value is object, a type checker will reject almost all operations on it, and assigning it to a variable (or using it as a return value) of a more specialized type is a type error.

and from the mypy documentation section Any vs. object:

The type object is another type that can have an instance of arbitrary type as a value. Unlike Any, object is an ordinary static type (it is similar to Object in Java), and only operations valid for all types are accepted for object values.

object can be cast to a more specific type, while Any really means anything goes and a type checker disengages from any use of the object (even if you later assign such an object to a name that is typechecked).

You already painted your function into a an un-typed corner by accepting list, which comes down to being the same thing as List[Any]. The typechecker disengaged there and the return value no longer matters, but since your function accepts a list containing Any objects, the proper return value would be Any here.

To properly participate in type-checked code, you need to mark your input as List[T] (a genericly typed container) for a typechecker to then be able to care about the return value. Which in your case would be T since you are retrieving a value from the list. Create T from a TypeVar:

from typing import TypeVar, List

T = TypeVar('T')

def get_item(L: List[T], i: int) -> T:
    return L[i]

or, using Python 3.12 or newer:

def get_itemT -> T:
    return L[i]
Answer from Martijn Pieters on Stack Overflow
🌐
Python documentation
docs.python.org › 3 › library › typing.html
typing — Support for type hints
>>> from typing import Annotated, get_type_hints >>> def func(x: Annotated[int, "metadata"]) -> None: pass ...
🌐
Mypy
mypy.readthedocs.io › en › stable › cheat_sheet_py3.html
Type hints cheat sheet - mypy 1.19.1 documentation
# For most types, just use the name of the type in the annotation # Note that mypy can usually infer the type of a variable from its value, # so technically these annotations are redundant x: int = 1 x: float = 1.0 x: bool = True x: str = "test" x: bytes = b"test" # For collections on Python 3.9+, the type of the collection item is in brackets x: list[int] = [1] x: set[int] = {6, 7} # For mappings, we need the types of both keys and values x: dict[str, float] = {"field": 2.0} # Python 3.9+ # For tuples of fixed size, we specify the types of all the elements x: tuple[int, str, float] = (3, "yes
Top answer
1 of 2
151

Yes, there is a difference. Although in Python 3, all objects are instances of object, including object itself, only Any documents that the return value should be disregarded by the typechecker.

The Any type docstring states that object is a subclass of Any and vice-versa:

>>> import typing
>>> print(typing.Any.__doc__)
Special type indicating an unconstrained type.

    - Any object is an instance of Any.
    - Any class is a subclass of Any.
    - As a special case, Any and object are subclasses of each other.

However, a proper typechecker (one that goes beyond isinstance() checks, and which inspects how the object is actually used in the function) can readily object to object where Any is always accepted.

From the Any type documentation:

Notice that no typechecking is performed when assigning a value of type Any to a more precise type.

and

Contrast the behavior of Any with the behavior of object. Similar to Any, every type is a subtype of object. However, unlike Any, the reverse is not true: object is not a subtype of every other type.

That means when the type of a value is object, a type checker will reject almost all operations on it, and assigning it to a variable (or using it as a return value) of a more specialized type is a type error.

and from the mypy documentation section Any vs. object:

The type object is another type that can have an instance of arbitrary type as a value. Unlike Any, object is an ordinary static type (it is similar to Object in Java), and only operations valid for all types are accepted for object values.

object can be cast to a more specific type, while Any really means anything goes and a type checker disengages from any use of the object (even if you later assign such an object to a name that is typechecked).

You already painted your function into a an un-typed corner by accepting list, which comes down to being the same thing as List[Any]. The typechecker disengaged there and the return value no longer matters, but since your function accepts a list containing Any objects, the proper return value would be Any here.

To properly participate in type-checked code, you need to mark your input as List[T] (a genericly typed container) for a typechecker to then be able to care about the return value. Which in your case would be T since you are retrieving a value from the list. Create T from a TypeVar:

from typing import TypeVar, List

T = TypeVar('T')

def get_item(L: List[T], i: int) -> T:
    return L[i]

or, using Python 3.12 or newer:

def get_itemT -> T:
    return L[i]
2 of 2
45

Any and object are superficially similar, but in fact are entirely opposite in meaning.

object is the root of Python's metaclass hierarchy. Every single class inherits from object. That means that object is in a certain sense the most restrictive type you can give values. If you have a value of type object, the only methods you are permitted to call are ones that are a part of every single object. For example:

foo: object = 3

# Error, not all objects have a method 'hello'
bar = foo.hello()   

# OK, all objects have a __str__ method
print(str(foo))   

In contrast, Any is an escape hatch meant to allow you to mix together dynamic and statically typed code. Any is the least restrictive type -- any possible method or operation is permitted on a value of type Any. For example:

from typing import Any
foo: Any = 3

# OK, foo could be any type, and that type might have a 'hello' method
# Since we have no idea what hello() is, `bar` will also have a type of Any
bar = foo.hello()

# Ok, for similar reasons
print(str(foo))

You should generally try and use Any only for cases where...

  1. As a way of mixing together dynamic and statically typed code. For example, if you have many dynamic and complex functions, and don't have time to fully statically type all of them, you could settle for just giving them a return type of Any to nominally bring them into the typechecked work. (Or to put it another way, Any is a useful tool for helping migrate an untypechecked codebase to a typed codebase in stages).
  2. As a way of giving a type to an expression that is difficult to type. For example, Python's type annotations currently do not support recursive types, which makes typing things like arbitrary JSON dicts difficult. As a temporary measure, you might want to give your JSON dicts a type of Dict[str, Any], which is a bit better then nothing.

In contrast, use object for cases where you want to indicate in a typesafe way that a value MUST literally work with any possible object in existence.

My recommendation is to avoid using Any except in cases where there is no alternative. Any is a concession -- a mechanism for allowing dynamism where we'd really rather live in a typesafe world.

For more information, see:

  • https://docs.python.org/3/library/typing.html#the-any-type
  • http://mypy.readthedocs.io/en/latest/kinds_of_types.html#the-any-type

For your particular example, I would use TypeVars, rather then either object or Any. What you want to do is to indicate that you want to return the type of whatever is contained within the list. If the list will always contain the same type (which is typically the case), you would want to do:

from typing import List, TypeVar

T = TypeVar('T')
def get_item(L: List[T], i: int) -> T:
    return L[i]

This way, your get_item function will return the most precise type as possible.

🌐
Python
peps.python.org › pep-0484
PEP 484 – Type Hints | peps.python.org
All newly introduced names used to support features described in following sections (such as Any and Union) are available in the typing module. When used in a type hint, the expression None is considered equivalent to type(None).
🌐
Dagster
dagster.io › blog › python-type-hinting
Using Type Hinting in Python Projects
Improved code readability: Type hints act as a form of documentation that helps developers understand the types of arguments a function expects and what it returns. This enhanced clarity makes the code more readable and easier to understand. Error detection: Tools like 'pyright' and mypy can be used to statically analyze your Python code.
🌐
FastAPI
fastapi.tiangolo.com › python-types
Python Types Intro - FastAPI
Python has support for optional "type hints" (also called "type annotations").
🌐
Reddit
reddit.com › r/python › why type hinting sucks!
r/Python on Reddit: Why Type Hinting Sucks!
February 13, 2023 -

Type hints are great! But I was playing Devil's advocate on a thread recently where I claimed actually type hinting can be legitimately annoying, especially to old school Python programmers.

But I think a lot of people were skeptical, so let's go through a made up scenario trying to type hint a simple Python package. Go to the end for a TL;DR.

The scenario

This is completely made up, all the events are fictitious unless explicitly stated otherwise (also editing this I realized attempts 4-6 have even more mistakes in them than intended but I'm not rewriting this again):

You maintain a popular third party library slowadd, your library has many supporting functions, decorators, classes, and metaclasses, but your main function is:

def slow_add(a, b):
    time.sleep(0.1)
    return a + b

You've always used traditional Python duck typing, if a and b don't add then the function throws an exception. But you just dropped support for Python 2 and your users are demanding type hinting, so it's your next major milestone.

First attempt at type hinting

You update your function:

def slow_add(a: int, b: int) -> int:
    time.sleep(0.1)
    return a + b

All your tests pass, mypy passes against your personal code base, so you ship with the release note "Type Hinting Support added!"

Second attempt at type hinting

Users immediately flood your GitHub issues with complaints! MyPy is now failing for them because they pass floats to slow_add, build processes are broken, they can't downgrade because of internal Enterprise policies of always having to increase type hint coverage, their weekend is ruined from this issue.

You do some investigating and find that MyPy supports Duck type compatibility for ints -> floats -> complex. That's cool! New release:

def slow_add(a: complex, b: complex) -> complex:
    time.sleep(0.1)
    return a + b

Funny that this is a MyPy note and not a PEP standard...

Third attempt at type hinting

Your users thank you for your quick release, but a couple of days later one user asks why you no longer support Decimal. You replace complex with Decimal but now your other MyPy tests are failing.

You remember Python 3 added Numeric abstract base classes, what a perfect use case, just type hint everything as numbers.Number.

Hmmm, MyPy doesn't consider any of integers, or floats, or Decimals to be numbers :(.

After reading through typing you guess you'll just Union in the Decimals:

def slow_add(
    a: Union[complex, Decimal], b: Union[complex, Decimal]
) -> Union[complex, Decimal]:
    time.sleep(0.1)
    return a + b

Oh no! MyPy is complaining that you can't add your other number types to Decimals, well that wasn't your intention anyway...

More reading later and you try overload:

@overload
def slow_add(a: Decimal, b: Decimal) -> Decimal:
    ...

@overload
def slow_add(a: complex, b: complex) -> complex:
    ...

def slow_add(a, b):
    time.sleep(0.1)
    return a + b

But MyPy on strict is complaining that slow_add is missing a type annotation, after reading this issue you realize that @overload is only useful for users of your function but the body of your function will not be tested using @overload. Fortunately in the discussion on that issue there is an alternative example of how to implement:

T = TypeVar("T", Decimal, complex)

def slow_add(a: T, b: T) -> T:
    time.sleep(0.1)
    return a + b

Fourth attempt at type hinting

You make a new release, and a few days later more users start complaining. A very passionate user explains the super critical use case of adding tuples, e.g. slow_add((1, ), (2, ))

You don't want to start adding each type one by one, there must be a better way! You learn about Protocols, and Type Variables, and positional only parameters, phew, this is a lot but this should be perfect now:

T = TypeVar("T")

class Addable(Protocol):
    def __add__(self: T, other: T, /) -> T:
        ...

def slow_add(a: Addable, b: Addable) -> Addable:
    time.sleep(0.1)
    return a + b

A mild diversion

You make a new release noting "now supports any addable type".

Immediately the tuple user complains again and says type hints don't work for longer Tuples: slow_add((1, 2), (3, 4)). That's weird because you tested multiple lengths of Tuples and MyPy was happy.

After debugging the users environment, via a series of "back and forth"s over GitHub issues, you discover that pyright is throwing this as an error but MyPy is not (even in strict mode). You assume MyPy is correct and move on in bliss ignoring there is actually a fundamental mistake in your approach so far.

(Author Side Note - It's not clear if MyPy is wrong but it defiantly makes sense for Pyright to throw an error here, I've filed issues against both projects and a pyright maintainer has explained the gory details if you're interested. Unfortunately this was not really addressed in this story until the "Seventh attempt")

Fifth attempt at type hinting

A week later a user files an issue, the most recent release said that "now supports any addable type" but they have a bunch of classes that can only be implemented using __radd__ and the new release throws typing errors.

You try a few approaches and find this seems to best solve it:

T = TypeVar("T")

class Addable(Protocol):
    def __add__(self: T, other: T, /) -> T:
        ...

class RAddable(Protocol):
    def __radd__(self: T, other: Any, /) -> T:
        ...

@overload
def slow_add(a: Addable, b: Addable) -> Addable:
    ...

@overload
def slow_add(a: Any, b: RAddable) -> RAddable:
    ...

def slow_add(a: Any, b: Any) -> Any:
    time.sleep(0.1)
    return a + b

Annoyingly there is now no consistent way for MyPy to do anything with the body of the function. Also you weren't able to fully express that when b is "RAddable" that "a" should not be the same type because Python type annotations don't yet support being able to exclude types.

Sixth attempt at type hinting

A couple of days later a new user complains they are getting type hint errors when trying to raise the output to a power, e.g. pow(slow_add(1, 1), slow_add(1, 1)). Actually this one isn't too bad, you quick realize the problem is your annotating Protocols, but really you need to be annotating Type Variables, easy fix:

T = TypeVar("T")

class Addable(Protocol):
    def __add__(self: T, other: T, /) -> T:
        ...

A = TypeVar("A", bound=Addable)

class RAddable(Protocol):
    def __radd__(self: T, other: Any, /) -> T:
        ...

R = TypeVar("R", bound=RAddable)

@overload
def slow_add(a: A, b: A) -> A:
    ...

@overload
def slow_add(a: Any, b: R) -> R:
    ...

def slow_add(a: Any, b: Any) -> Any:
    time.sleep(0.1)
    return a + b

Seventh attempt at type hinting

Tuple user returns! He says MyPy in strict mode is now complaining with the expression slow_add((1,), (2,)) == (1, 2) giving the error:

Non-overlapping equality check (left operand type: "Tuple[int]", right operand type: "Tuple[int, int]")

You realize you can't actually guarantee anything about the return type from some arbitrary __add__ or __radd__, so you starting throwing Any Liberally around:

class Addable(Protocol):
    def __add__(self: "Addable", other: Any, /) -> Any:
        ...

class RAddable(Protocol):
    def __radd__(self: "RAddable", other: Any, /) -> Any:
        ...

@overload
def slow_add(a: Addable, b: Any) -> Any:
    ...

@overload
def slow_add(a: Any, b: RAddable) -> Any:
    ...

def slow_add(a: Any, b: Any) -> Any:
    time.sleep(0.1)
    return a + b

Eighth attempt at type hinting

Users go crazy! The nice autosuggestions their IDE provided them in the previous release have all gone! Well you can't type hint the world, but I guess you could include type hints for the built-in types and maybe some Standard Library types like Decimal:

You think you can rely on some of that MyPy duck typing but you test:

@overload
def slow_add(a: complex, b: complex) -> complex:
    ...

And realize that MyPy throws an error on something like slow_add(1, 1.0).as_integer_ratio(). So much for that nice duck typing article on MyPy you read earlier.

So you end up implementing:

class Addable(Protocol):
    def __add__(self: "Addable", other: Any, /) -> Any:
        ...

class RAddable(Protocol):
    def __radd__(self: "RAddable", other: Any, /) -> Any:
        ...

@overload
def slow_add(a: int, b: int) -> int:
    ...

@overload
def slow_add(a: float, b: float) -> float:
    ...

@overload
def slow_add(a: complex, b: complex) -> complex:
    ...

@overload
def slow_add(a: str, b: str) -> str:
    ...

@overload
def slow_add(a: tuple[Any, ...], b: tuple[Any, ...]) -> tuple[Any, ...]:
    ...

@overload
def slow_add(a: list[Any], b: list[Any]) -> list[Any]:
    ...

@overload
def slow_add(a: Decimal, b: Decimal) -> Decimal:
    ...

@overload
def slow_add(a: Fraction, b: Fraction) -> Fraction:
    ...

@overload
def slow_add(a: Addable, b: Any) -> Any:
    ...

@overload
def slow_add(a: Any, b: RAddable) -> Any:
    ...

def slow_add(a: Any, b: Any) -> Any:
    time.sleep(0.1)
    return a + b

As discussed earlier MyPy doesn't use the signature of any of the overloads and compares them to the body of the function, so all these type hints have to manually validated as accurate by you.

Ninth attempt at type hinting

A few months later a user says they are using an embedded version of Python and it hasn't implemented the Decimal module, they don't understand why your package is even importing it given it doesn't use it. So finally your code looks like:

from __future__ import annotations

import time
from typing import TYPE_CHECKING, Any, Protocol, TypeVar, overload

if TYPE_CHECKING:
    from decimal import Decimal
    from fractions import Fraction


class Addable(Protocol):
    def __add__(self: "Addable", other: Any, /) -> Any:
        ...

class RAddable(Protocol):
    def __radd__(self: "RAddable", other: Any, /) -> Any:
        ...

@overload
def slow_add(a: int, b: int) -> int:
    ...

@overload
def slow_add(a: float, b: float) -> float:
    ...

@overload
def slow_add(a: complex, b: complex) -> complex:
    ...

@overload
def slow_add(a: str, b: str) -> str:
    ...

@overload
def slow_add(a: tuple[Any, ...], b: tuple[Any, ...]) -> tuple[Any, ...]:
    ...

@overload
def slow_add(a: list[Any], b: list[Any]) -> list[Any]:
    ...

@overload
def slow_add(a: Decimal, b: Decimal) -> Decimal:
    ...

@overload
def slow_add(a: Fraction, b: Fraction) -> Fraction:
    ...

@overload
def slow_add(a: Addable, b: Any) -> Any:
    ...

@overload
def slow_add(a: Any, b: RAddable) -> Any:
    ...

def slow_add(a: Any, b: Any) -> Any:
    time.sleep(0.1)
    return a + b

TL;DR

Turning even the simplest function that relied on Duck Typing into a Type Hinted function that is useful can be painfully difficult.

Please always put on your empathetic hat first when asking someone to update their code to how you think it should work.

In writing up this post I learnt a lot about type hinting, please try and find edge cases where my type hints are wrong or could be improved, it's a good exercise.

Edit: Had to fix a broken link.

Edit 2: It was late last night and I gave up on fixing everything, some smart people nicely spotted the errors!

I have a "tenth attempt" to address these error. But pyright complains about it because my overloads overlap, however I don't think there's a way to express what I want in Python annotations without overlap. Also Mypy complains about some of the user code I posted earlier giving the error comparison-overlap, interestingly though pyright seems to be able to detect here that the types don't overlap in the user code.

I'm going to file issues on pyright and mypy, but fundamentally they might be design choices rather than strictly bugs and therefore a limit on the current state of Python Type Hinting:

T = TypeVar("T")

class SameAddable(Protocol):
    def __add__(self: T, other: T, /) -> T:
        ...

class Addable(Protocol):
    def __add__(self: "Addable", other: Any, /) -> Any:
        ...

class SameRAddable(Protocol):
    def __radd__(self: T, other: Any, /) -> T:
        ...

class RAddable(Protocol):
    def __radd__(self: "RAddable", other: Any, /) -> Any:
        ...

SA = TypeVar("SA", bound=SameAddable)
RA = TypeVar("RA", bound=SameRAddable)


@overload
def slow_add(a: SA, b: SA) -> SA:
    ...

@overload
def slow_add(a: Addable, b: Any) -> Any:
    ...

@overload
def slow_add(a: Any, b: RA) -> RA:
    ...

@overload
def slow_add(a: Any, b: RAddable) -> Any:
    ...

def slow_add(a: Any, b: Any) -> Any:
    time.sleep(0.1)
    return a + b
🌐
Better Stack
betterstack.com › community › guides › scaling-python › python-type-hints
A Complete Guide to Python Type Hints | Better Stack Community
It's great for catching bugs early and keeping your code clean and easy to maintain. It's widely used in Python and is a common part of many professional projects. Python's type hints give you everything you'd expect from a modern type system — support for basic types, lists and dictionaries, custom classes, generics, and more.
Find elsewhere
🌐
Python.org
discuss.python.org › python help
Type hint for "Any But Not None" - Python Help - Discussions on Python.org
March 2, 2021 - Is there a way to specify that a certain parameter can be anything except None? Better still if we can specify a “Not one of these types” annotation.
🌐
Adam Johnson
adamj.eu › tech › 2021 › 05 › 07 › python-type-hints-use-object-instead-of-any
Python type hints: Use object instead of Any - Adam Johnson
If you’re using Any to mean “this object could be any type, and I don’t care what”, you probably want to use object instead. Every object in Python inherits from object, which makes it an “opaque” type that only allows operations common to everything.
Top answer
1 of 1
2

Depending on what exactly you want to use, there are two different options:

  1. If you want to basically opt-out of type-checking any_value completely and indicate it could be literally any type with zero restrictions, use typing.Any. Example:

    from typing import Any
    
    class MyThing:
        def update(self, col_name: str, new_value: Any) -> None:
            # Note: this typechecks; new_value can be anything, and 
            # that object might have a foo method
            new_value.foo()  
            # ...snip...
    
  2. If you want to indicate that new_value can be of any type, but also want to ensure that the update method only ever uses new_value in a fully typesafe way, I would use object, which is the base type of every type in Python:

    class MyThing:
        def update(self, col_name: str, new_value: object) -> None:
            # Note: this does not typecheck since new_value is of
            # type 'object', and 'object' is not guaranteed to have
            # a method named 'foo'
            new_value.foo()  
            # ...snip...
    

I personally bias towards using object -- Any is designed specifically as a "bridge" that lets you mix the typed and untyped worlds within your program. I personally think it's easier to reason about code if you keep those two worlds fairly distinct (e.g. by having a fully typed "core" possibly with a bunch of untyped code wrapping it) instead of a method that's both statically and dynamically typed.

Of course, it's not always possible to do this...

(We would like the type hint for documentation purposes, to make the code easier to read)

As an aside/as a suggestion, if you're going to use type hints, I would also strongly recommend going all the way and actually type-check your code using tools like mypy as a part of your development process.

Using type hints for documentation is great, but it can be very confusing if your code doesn't conform to the documentation. Since we have tools to automatically typecheck our code using those type hints, we might as well (and gain that extra guarantee).

(Pragmatically, trying to typecheck your entire codebase all at once can lead to a lot of noise -- what you can try and do instead is progressively typecheck your codebase. For example, you can configure mypy to typecheck only a set list of files (that you maybe grow over time?), make certain checks stricter or looser (perhaps on a per-file basis), and so forth. This works well with the "typed core, untyped wrapper" strategy mentioned above.)

🌐
Python
docs.python.org › 3.9 › library › typing.html
typing — Support for type hints — Python 3.9.24 documentation
The Python runtime does not enforce function and variable type annotations. They can be used by third party tools such as type checkers, IDEs, linters, etc. This module provides runtime support for type hints. The most fundamental support consists of the types Any, Union, Callable, TypeVar, and Generic.
🌐
Python Tutorial
pythontutorial.net › home › python basics › python type hints
Python Type Hints
April 2, 2025 - Besides the str type, you can use other built-in types such as int, float, bool, and bytes for type hintings. It’s important to note that the Python interpreter ignores type hints completely.
🌐
Python
docs.python.org › 3.8 › library › typing.html
typing — Support for type hints — Python 3.8.20 documentation
The most fundamental support consists of the types Any, Union, Tuple, Callable, TypeVar, and Generic. For full specification please see PEP 484. For a simplified introduction to type hints see PEP 483.
🌐
InfoWorld
infoworld.com › home › software development › programming languages › python
Get started with Python type hints | InfoWorld
June 18, 2025 - Python type hints are not used at runtime, at least not ordinarily. In fact, when your program runs, all the type information you’ve provided is ignored (although it is preserved in some form; more on this later).
🌐
Reddit
reddit.com › r/learnpython › what is the point of type hinting when python doesn't even respect it!?
r/learnpython on Reddit: What is the point of type hinting when Python doesn't even respect it!?
August 15, 2024 -

So infuriating because I feel like my function is lying to me when it ends up letting other objects through the parameter.

Now every function I created needs an instance check which is unintuitive, verbose, and easily forgotten.

def wtf(string: str, integer:int):
   return 'TYPE HINT DOESNT DO ANYTHING' 

print( wtf( 123, 'wtf')  )
>> 'TYPE HINT DOESNT DO ANYTHING'

EDIT:

Turns out it is a noob mistake. Type hint only functions as a signal for IDE, but developers get to do whatever they want to your parameter.

If you really must enforce it, you got to have the line

if not isinstance(string, str): 
  raise TypeError()

Still, I don't like that this behavior isn't taught until it happens. So much time wasted on debugging production code when you take for granted your function is accepting only restricted data when it doesn't.

🌐
Real Python
realpython.com › python-type-hints-multiple-types
How to Use Type Hints for Multiple Return Types in Python – Real Python
March 8, 2024 - If the argument doesn’t contain an at sign, then the return value is None, indicating an invalid email address. Note: In practice, the validation rules for email addresses are much more complicated. So, the return value of this function is either a string containing the username or None if the email address is incomplete. The type hint for the return value uses the pipe operator (|) to indicate alternative types of the single value that the function returns. To define the same function in Python versions older than 3.10, you can use an alternative syntax:
🌐
Real Python
realpython.com › lessons › type-hinting
Type Hinting (Video) – Real Python
Type hints will help document your code. And notice the idea of hints—they have no runtime effect, they’re only hints and are not enforced on their own. Type hints were first specified in PEP 484, like I mentioned in the previous video, and they were first introduced into Python in version 3.5.
Published   October 29, 2019
🌐
JetBrains
jetbrains.com › help › pycharm › type-hinting-in-product.html
Type hinting in PyCharm | PyCharm Documentation
Although PyCharm supports all methods for adding types supported in PEP 484, using type hints through intention actions is the most convenient way. Depending on the interpreter you use, the type is added as an annotation (Python 3) or as a comment (Python 2):
🌐
Inmanta
inmanta.com › 2021 › 10 › 20 › python-type-hinting-object-vs-any
Python Type Hinting - object vs Any | Inmanta
April 22, 2024 - In this post, we will be taking on Python type hinting and discuss the subtle differences between object and Any types and how static type checkers behave based on our instructions.