collections.abc.NonStringSequence

Slight side point, but the typing alii were deprecated to avoid duplication.

I am wandering if there is some sort of “ultimate vision” for the whole typing thing?

I mean, ideally, given the direction where this is all going, the culmination will theoretically be a flexible infrastructure which can describe any python object by nitpicking features.

Type is only one part of it. Although it is one of the more complex ones (especially logical DNF simplifications of python class trees), it is roughly only 20% of the complete infrastructure for such thing.

Eventually things like this should ideally be possible.:

a : ~str & HasMethod[__getitem__] & ValueOfItem[0, OneOf[None, 0]]
b : int & HasMethod[to_bytes] | str & HasMethod[method] | OneOf[None, Ellipsis, True]
hypot = lambda x: (x[0]**2 + x[1]**2)**0.5
c : CustomFuncLess[hypot, 2]

# Simplifications
SerialProtocol & HasMethod[dumps] == HasMethod['dumps'] 
SerialProtocol | HasMethod[dumps] == SerialProtocol
print(Number | (int & list)) == Number

Maybe there is something written on this? It could provide some ground for such discussions as this.

Without deferred evaluation, you would probably need to write this:

HasMethod['__getitem__']

The goal, as I understood it, is not simply to use this in typing, but to be able to implement e.g. an isinstance runtime check for recursive algorithms.

It warrants being a type, so that it can work with isinstance. But you do have a valid question: where does this fit best? For the applications where I would use something like this, I wouldn’t necessarily be using type annotations for any static checking purpose.

Yes, which is why I suggested the second part of that statement. In fact, that function could already be added (either in collections or in string I would think), it just couldn’t be typed probably right now. I think this is a common enough usecase that such a convenience function would be beneficial (although it will probably lead to discussions if bytes should also be excluded… I vote for yes).

If this function is too small of a feature to be added, what extra usability does it gain from being a class? As far as I can tell, the only possible use for this “class” at runtime is as an argument for isinstance.

Whenever this has come up before, it’s been rejected because there aren’t enough realistic use cases apart from a flatten() function.

I would like to be able to use it for type hinting. Passing a string to a Sequence[str] or Iterable[str] is usually a bug, ducks not withstanding.

2 Likes

It occurs to me this could just be a pattern type checkers start rejecting despite being technically correct, given it IS usually a bug. No need for a new type and counter-intuitive annotations then.

Writing a mypy plugin for this should be fairly straightforward, it wouldn’t be able to cover assignments, but the more common case, i.e. function/method calls would be covered through the function/method hook. Although it may slow down things a bit if you don’t first build a cache of which callables have a parameter that needs to be checked using the corresponding signature hooks.

1 Like

Sometimes an API acepts one item or several items. Would you count the test “single or sequence?” as a use-case?

Real-world examples:

if type(problems) not in (list, tuple):
    problems = [problems]

if not isinstance(weights, (list, tuple)):
    weights = list(weights)

useful-types provides SequenceNotStr for typing, but isn’t runtime_checkable, so not up to OP’s objectives.

2 Likes