Read the contract beyond the function name
A signature tells you how to call an operation. It rarely tells you everything needed to use the answer safely.
| Part of the contract | Question for a quote interface |
|---|---|
| Name and signature | Which operation is public? Which arguments are positional, named or optional? |
| Inputs and outputs | What identifies the instrument? Does the result contain one mark, a bid–ask pair or a series? |
| Error semantics | Does an unknown symbol raise an exception, return a missing value or produce a documented error object? |
| Meaning and units | Is the price per share or per contract? Which currency, quote time and price convention apply? |
| Version and compatibility | Which contract is the caller using, and what changes require an update? |
A local quote interface
"ABC". The function returns a frozen mark of 100 USD per share as an integer; an unrecognised symbol raises LookupError, and a non-string input raises TypeError. It performs no network request and returns no live market observation.def quote_usd_per_share(symbol: str) -> int:
"""Return a fictional frozen mark in whole USD per share; ABC only."""
if not isinstance(symbol, str):
raise TypeError("symbol must be a string")
if symbol != "ABC":
raise LookupError("unknown symbol")
return 100
price = quote_usd_per_share("ABC")
quantity = 2 # shares
value_usd = quantity * price
print(f"{quantity} shares at USD {price}/share = USD {value_usd}")
# 2 shares at USD 100/share = USD 200
try:
quote_usd_per_share("XYZ")
except LookupError as exc:
print(type(exc).__name__ + ": " + str(exc))
# LookupError: unknown symbolThe annotations describe expected types; they do not enforce them at runtime. The explicit checks enforce this example's input restrictions. Returning zero for an unknown symbol would violate its stated error contract and could make a missing quote look like a worthless holding. Callers should handle the documented failure rather than silently substitute a price.
This deliberately narrow API supplies a fixed teaching mark, without timestamps, bid–ask information or fees. A live quote contract must define those relevant fields and freshness rules before a valuation can rely on it. Receiving the expected data type does not establish economic validity.
Changes can preserve syntax and break meaning
An internal lookup can change while the public operation keeps its agreed behaviour. But changing the result from USD per share to cents per share would break the caller's interpretation even if the function name, arguments and integer return type stayed identical. Changing a documented exception can also break error handling.
Versioning identifies the contract being used; it does not by itself guarantee compatibility. Read the provider's change and deprecation policy, check units and failure behaviour, and test the integration when upgrading. Python's compatibility policy is an example of one project's explicit rules, rather than a universal guarantee for every API.
Sources
- Python PEP 387: Backwards Compatibility Rules, including the scope of public APIs and their behavioural contracts.
- Python 3.14 tutorial: Defining Functions, covering parameters, calls, docstrings and return values.
- Python 3.14 tutorial: Errors and Exceptions, covering runtime failures and selected exception handling. The example above was executed with Python 3.14.4; the checked 3.14 documentation currently identifies itself as 3.14.10.