-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extended return #57
base: master
Are you sure you want to change the base?
Extended return #57
Conversation
I previously suggested setting up unittests. Returning the validation result along with the conversion will make it easier to write tests for the conversion process. |
Right. I believe that's how unit tests should be implemented. |
You are the owner of this project, which means you are responsible for maintaining a consistent structure. Users relying on the default settings might encounter issues if this implementation is merged directly. The return scheme you propose is quite common; I've seen it frequently in Deep Learning models. I understand your concerns. However, I personally disagree with them because many developers may have insufficient programming skills. The Hugging Face implementations are not entirely satisfactory either. |
Let's deal with the first problem. Case1 : If you want to preserve the behavior of the default setting.Please see the example below. from typing import overload, Tuple, Union, Any
class Model:
"""
Description About the Model.
"""
def func_from_model():
pass
class ValidationResult:
"""
Description About the ValidationResult.
"""
status: str
@overload
def validate(accessory:Any) -> Tuple[Model, ValidationResult]:
pass
@overload
def validate() -> Model:
pass
def validate(accessory) -> Union[Model, Tuple[Model, ValidationResult]]:
pass If we use the
However, it has a limitation. Regardless of the value of def common(accessory:bool):
if accessory is True:
return Model(), ValidationResult()
else:
return Model()
def current_case(accessory:Any = "None"):
"""
If the `accessory` arg is detected in the function call syntax,
The Accessory is also returned.
Otherwise, this function returns only the Model.
"""
if accessory is "None":
return Model()
else:
return Model(), ValidationResult() If we design the function like |
Case 2: If preserving the default behavior is not necessaryThis is actually a parallel topic. I'm not sure what you mean exactly by "unwieldy". Please see the example below: from typing import Tuple, Dict
class KerasModel:
pass
class PytorchNode:
pass
class ValidationResult:
pass
class ConversionResult:
pass
def pytorch_to_keras(
) -> Tuple[KerasModel, object, Dict[PytorchNode, ValidationResult], Dict[PytorchNode, ConversionResult]]:
"""
Parameters:
Description about the KerasModel.
Descriptions continued...
...
"""
output = pytorch_to_keras() Developers can read all the output types, and you can add additional descriptions as docstrings for more details. There are typically three options:
Tuple is not unwieldy, but it might not the best option either. Each has its pros and cons. Returning a consistent set of outputs (basically my argument, but enhanced by Sonnet3.5)I disagree that returning all outputs by default would be unwieldy. In fact, I believe it's more consistent and potentially less problematic. Here's why:
While Hugging Face's approach with Instead of controlling which outputs are returned, we could focus on providing clear documentation and type hints. This way, users can easily ignore the outputs they don't need, while still having access to all information if required. If memory usage is a concern in specific scenarios, we could provide separate methods or a context manager for memory-sensitive operations, rather than complicating the main API. ComparisonTuple Tuples are simple to implement. Neither the project owner nor users need to write any additional code. It's not ideal if we're likely to add more outputs in the future. Dict You need to define a dictionary. For users, At this cost, we gain better extensibility. Even if we add a new output, It sounds good, but I don't recommend it. Let me explain the reason. If you use the dictionary type, you'll type-hint like this: output: Dict[
Literal["model", "tensor", "validation_result", "conversion_result"],
Union[
KerasModel,
object,
Dict[PytorchNode, ValidationResult],
Dict[PytorchNode, ConversionResult]]
] If you check the autocompletion after BaseModel We can define the output in a more structured and detailed manner: class OutputProps(BaseModel):
output1: int
output2: str The IDE isn't confused about the type for each output name. There are two disadvantages:
RecommendationAs the If you're willing to use Tuple, I'd like you to check out one of my modules called intelli-type. It can be used to overcome some shortcomings of Tuple type output. |
There must be many unfamiliar aspects to you.
|
Developers will want to programmatically analyze the result of conversion in a more detailed manner. Therefore, I suggest returning the validation and conversion results as well after conversion.
From the perspective of Clean Code, it's better to return a consistent type. See the examples below. If we use a
Union
as the return type, your IDE will be confused about the type of the returned variables.In the case of
func
, thesecond
variable must be anint
, but we can see that Intellisense recommends autocompletion from bothint
andstr
.In the case of
func2
, the autocompletion is limited to the designed targets.