If a calculation function suddenly produces None, Python probably has not lost the value. More likely, the path that ran had no return. A Python function returns None when it reaches the end without explicitly returning a value.
def discount(price, member):
if member:
return price * 0.9
print(discount(100, False)) # NoneWhen member is True, the result is 90.0. When it is False, execution skips the conditional and reaches the end of the function. If nonmembers should still receive the original price, both paths need to be designed.
Check the return value on every path
Start by looking for any path that reaches the last line of the function. In the diagram, the result disappears at the end of the nonmember branch, not in the calculation.
For a price of 100, the member path returns the discounted value 90.0, while the nonmember path returns None because it has no return. The diagram depicts the original function; the correction appears below.
If the function should return the original price for a nonmember, add an else branch or a final return.
def discount(price, member):
if member:
return price * 0.9
return priceAfter the change, test the formerly missing path as well as the successful one.
assert discount(100, True) == 90.0
assert discount(100, False) == 100If the input itself may be missing, decide how to handle it explicitly. Returning None casually for every such input makes it hard to distinguish an invalid price from an ordinary lack of discount.
print and return do different jobs
Calling print(result) inside a function displays a value but does not pass it back to the caller. A test of the returned value must inspect the function call, not its printed output. Keep logging and data flow separate.
def discount_message(price):
print(price * 0.9)
result = discount_message(100) # Displays 90.0.
assert result is None # The caller receives no value.If a debugger shows None immediately after the call, follow every if and return path inside the function first. Small tests of each branch catch this mistake more reliably than adding print statements. Even with a return type annotation, Python does not automatically enforce it at runtime. Use static type checking together with branch tests.
Key takeaways
A Python function returns None when it does not explicitly return a value. Test every path in a conditional calculation function, and do not confuse print with return. A type hint can also make a possible None result clearer to callers.

