Noneis a singleton, so you can compare object identity (is/is not) instead of equality (==/!=) - whenever you access None, you are getting the same object.
For almost all other cases, you should use equality (see e.g. Why does comparing strings in Python using either '==' or 'is' sometimes produce a different result?). In terms of "avoid[ing] forced type conversion" - Python is strongly typed and will never implicitly convert. Also, you can't really "cast" a type in Python - converting e.g. an int to str creates a new, separate object.
This is particularly important as None is often used to mark no return - if False or 0 or [] or anything else that evaluates False-y is a valid return, evaluating "truthiness" will give misleading results.
def yes_or_no(s):
"""Convert 'yes' or 'no' to boolean, or implicitly return None."""
if s.lower() == "yes":
return True
elif s.lower() == "no":
return False
result = some_func("foo")
if result: # wrong, covers None and False
...
if result is not None: # right, covers None only
...
Per the style guide:
Comparisons to singletons like None should always be done with is or is not, never the equality operators.
Also, beware of writing if x when you really mean if x is not None -- e.g. when testing whether a variable or argument that defaults to None was set to some other value. The other value might have a type (such as a container) that could be false in a boolean context!
Note that you generally don't compare True or False. Again, from the style guide:
Don't compare boolean values to True or False using ==.
Yes: if greeting:
No: if greeting == True:
Worse: if greeting is True:
See also: Use of True, False, and None as return values in python functions