When changing code that affects a public interface (method signatures, CLI command arguments, plugin discovery, type/subscriptable behavior), treat it as an API contract: keep existing call patterns working, and ensure runtime semantics match the intended contract.
Practical rules:
__class_getitem__ / subscripting), ensure the runtime object you return matches the expected semantics (e.g., types.GenericAlias) and add a small runtime test.Example (signature stability):
class EagerResult:
# Keep legacy parameters in the signature even if the internal behavior no longer needs them.
def get(self, timeout=None, propagate=True, disable_sync_subtasks=True, **kwargs):
if self.successful():
return self.result
if self.state in states.PROPAGATE_STATES:
if propagate:
raise self.result if isinstance(self.result, Exception) else Exception(self.result)
return self.result
Example (CLI input contract parsing):
def revoke_by_stamped_header(state, header, terminate=False, signal=None, **kwargs):
# Support either a list of headers or a list containing header=value pairs.
headers = header if isinstance(header, list) else [header]
parsed = []
for h in headers:
if '=' in h:
k, v = h.split('=', 1)
parsed.append((k, v))
else:
parsed.append(h)
# ... use `parsed` with clear semantics
Add/adjust unit tests to lock in the contract (signature compatibility, parsing shapes, and runtime return types).
Enter the URL of a public GitHub repository