[PATCH v2 1/8] dts: add params manipulation module

Juraj Linkeš juraj.linkes at pantheon.tech
Tue Jun 18 10:55:04 CEST 2024



On 17. 6. 2024 13:44, Luca Vizzarro wrote:
> On 06/06/2024 10:19, Juraj Linkeš wrote:
>> The static method in the other patch is called compose and does 
>> essentially the same thing, right? Can we use the same name (or a 
>> similar one)?
>>
>> Also, what is the difference in approaches between the two patches 
>> (or, more accurately, the reason behind the difference)? In the other 
>> patch, we're returning a dict, here we're returning a function directly.
> 
> They are essentially different. This one is as it's called quite plainly 
> a function reduction. Can be used in any context in reality.
> 
> The other one is tighter and has some specific controls (exit early if 
> None), and is directly represented as a dictionary as that's the only 
> intended way of consumption.
> 

This is a generic explanation. I had to go back to the code to find the 
reason for the difference. The dict is tailored to be used with the 
dataclass field's metadata argument and the reduce function is used with 
functions gotten from the metadata. At this point, the question is, why 
the difference when it seems we're trying to do the same thing (apply 
multiple functions through metadata), but slightly differently?

>>> +    """Reduces an iterable of :attr:`FnPtr` from end to start to a 
>>> composite function.
>>
>> We should make the order of application the same as in the method in 
>> other patch, so if we change the order in the first one, we should do 
>> the same here.
> 
> While I don't think it feels any natural coding-wise (yet again, a 
> matter of common readability to the developer vs how it's actually run), 
> I won't object as I don't have a preference.
> 
>>> +
>>> +    If the iterable is empty, the created function just returns its 
>>> fed value back.
>>> +    """
>>> +
>>> +    def composite_function(value: Any):
>>
>> The return type is missing.
> 
> I will remove types from the decorator functions as it adds too much 
> complexity and little advantage. I wasn't able to easily resolve with 
> mypy. Especially in conjunction with modify_str, where mypy complains a 
> lot about __str__ being treated as an unbound method/plain function that 
> doesn't take self.
> 

We can make this a policy - don't add return types to decorators. But 
I'm curious, what does mypy say when you use just Callable?

>>> +    _suffix = ""
>>> +    """Holder of the plain text value of Params when called 
>>> directly. A suffix for child classes."""
>>> +
>>> +    """========= BEGIN FIELD METADATA MODIFIER FUNCTIONS ========"""
>>> +
>>> +    @staticmethod
>>> +    def value_only() -> ParamsModifier:
>>
>> As far as I (or my IDE) can tell, this is not used anywhere. What's 
>> the purpose of this?
> 
> I guess this is no longer in use at the moment. It could still be used 
> for positional arguments in the future. But will remove for now.
> 
>>> +    def append_str(self, text: str) -> None:
>>> +        """Appends a string at the end of the string representation."""
>>> +        self._suffix += text
>>> +
>>> +    def __iadd__(self, text: str) -> Self:
>>> +        """Appends a string at the end of the string representation."""
>>> +        self.append_str(text)
>>> +        return self
>>> +
>>> +    @classmethod
>>> +    def from_str(cls, text: str) -> Self:
>>
>> I tried to figure out how self._suffix is used and I ended up finding 
>> out this method is not used anywhere. Is that correct? If it's not 
>> used, let's remove it.
> 
> It is used through Params.from_str. It is used transitionally in the 
> next commits.
> 

Can we remove it with the last usage of it being removed? As far as I 
understand, there's no need for the method with all commits applied.

>> What actually should be the suffix? A an arbitrary string that gets 
>> appended to the rendered command line arguments? I guess this would be 
>> here so that we can pass an already rendered string?
> 
> As we already discussed and agreed before, this is just to use Params 
> plainly with arbitrary text. It is treated as a suffix, because if 
> Params is inherited this stays, and then it can either be a prefix or a 
> suffix in that case.
> 
>>> +        """Creates a plain Params object from a string."""
>>> +        obj = cls()
>>> +        obj.append_str(text)
>>> +        return obj
>>> +
>>> +    @staticmethod
>>> +    def _make_switch(
>>> +        name: str, is_short: bool = False, is_no: bool = False, 
>>> value: str | None = None
>>> +    ) -> str:
>>> +        prefix = f"{'-' if is_short else '--'}{'no-' if is_no else ''}"
>>
>> Does is_short work with is_no (that is, if both are True)? Do we need 
>> to worry about it if not?
> 
> They should not work together, and no it is not enforced. But finally 
> that's up to the command line interface we are modelling the parameters 
> against. It is not a problem in reality.
> 


More information about the dev mailing list