superduper
superduper copied to clipboard
Handle `super()` doc-string parameters in a clever/ simple way.
We currently have custom formatting statements __doc__ = __doc__.format(...)
. This should be handled in a simple way.
Yes, we need to do this. Something like this
import re
import inspect
def extract_params(docstring):
"""Extract :param lines from a docstring with their indentation."""
if not docstring:
return []
return re.findall(r'(\s*:param [^:]+: [^\n]+)', docstring)
def merge_docs(cls):
"""Decorator to merge :param lines from all parent classes."""
parent_params = set()
for base in inspect.getmro(cls)[1:]:
if base.__doc__:
parent_params.update(extract_params(base.__doc__))
if cls.__doc__:
cls_params = set(extract_params(cls.__doc__))
else:
cls_params = set()
unique_params = parent_params - cls_params
# Combine the class's original docstring with the new parameters
combined_doc = cls.__doc__ or ""
if combined_doc and unique_params:
combined_doc = combined_doc.rstrip() + "\n\n"
combined_doc += "\n".join(unique_params)
cls.__doc__ = combined_doc
return cls
@merge_docs
class OpenAI:
"""OpenAI base class.
:param api_key: The API key for authentication.
:param timeout: The timeout for API requests.
"""
def __init__(self, api_key, timeout):
self.api_key = api_key
self.timeout = timeout
@merge_docs
class OpenAIAudioTranslation(OpenAI):
"""OpenAI audio translation predictor.
:param takes_context: Whether the model takes context into account.
:param prompt: The prompt to guide the model's style. Should contain ``{context}``.
"""
def __init__(self, api_key, timeout, takes_context, prompt):
super().__init__(api_key, timeout)
self.takes_context = takes_context
self.prompt = prompt
# Print the updated __doc__ for the subclass
print(OpenAIAudioTranslation.__doc__)