- I agree with your assessment here;
isinstance(value, _CONVERTIBLE_TO_STR)(where_CONVERTIBLE_TO_STR = (str, int, float)) is simpler and better than_is_convertible_to_str(value). It is also a little bit faster, which. I determined this by measuring execution times withtimeit. _contains_anylooks like it was written in a way so it can be useful in a general sense, e.g. it could be part of a utility library. But right now the only way it is used is to check if a string contains any whitespace. For simplicity and performance, I would go with something like this instead:
Based on measurements withdef contains_whitespace(text: str) -> bool: return any(character in _WHITESPACE for character in text)timeitand randomly-generated strings, I found that this was also generally faster than_contains_any(text, _WHITESPACE).- You can get a small performance boost by using string interpolation with f-strings (
f"{quote_str}{string1}{quote_str}") instead of string concatenation via the+operator (quote_str + string1 + quote_str). Nothing huge, and the good thing is the f-string versionbut improving performance without having to sacrifice readability is just as understandable and clearpretty nice. - For
flist_to_str, I would make some naming changes.- If I pretended that I didn't know the context of the larger problem statement, seeing the names
flist_to_strandflist: list[str]and the documentation "flat list of strings", I would probably wonder, "Why call it a flat list of strings? How is that any different from a list of strings?" And if we look at the type hints there really isn't a difference, so I would change the followingnaming to make that more clear:flist_to_str->list_to_strflist: list[str]->items: list[str]- "flat list of strings" -> "list of strings" (in the documentation)
quote_str: str->quote_mark: str- I think this is a little more precise.
string1: str->text: str- I totally understand choosing the name
string1to avoid shadowing thestringmodule and, buttextis probably a better name here. - To be fair, coming up with a good generic name for a string in Python is hard because the built-intwo best candidates (
strandstring) are already taken by a built-in function and a standard library module, butrespectively. I always end up using something likesortextis probablyas a better choice hereresult.
- I totally understand choosing the name
- If I pretended that I didn't know the context of the larger problem statement, seeing the names
In summary, there were some small nits pointed out here and there but overall I found the code and the public API it exposes very well-documented and easy to read. The docstrings were useful and had illuminating examples; I didn't think they were excessive at all.