typing: fix some broken Sequence annotations

T.Sequence is a questionable concept. The idea is to hammer out generic,
maximally forgiving APIs that operate on protocols, which is a fancy way
of saying "I don't care if you use tuples or lists". This is rarely
needed, actually, and in exchange for this fancy behavior you get free
bugs.

Specifically, `somestr` is of type `T.Sequence[str]`, and also
`somestr[0]` is another string of type you guessed it. It's ~~turtles~~
strings all the way down.

It's worth noting that trying to code for "protocols" is a broken
concept if the contents have semantic meaning, e.g. it operates on
"the install tags of this object" rather than "an iterable that supports
efficient element access".

The other way to use T.Sequence is "I don't like that T.List is
invariant, but also I don't like that T.Tuple makes you specify exact
ordering". This sort of works. In fact it probably does work as long as
you don't allow str in your sequences, which of course everyone allows
anyway.

Use of Sequence has cute side effects, such as actually passing lists
around, knowing that you are going to get a list and knowing that you
need to pass it on as a list, and then having to re-allocate as
`list(mylist)` "because the type annotations says it could be a str or
tuple".

Except it cannot be a str, because if it is then the application is
fatally flawed and logic errors occur to disastrous end user effects,
and the type annotations:
- do not enforce their promises of annotating types
- fail to live up to "minimal runtime penalties" due to all the `list()`

Shun this broken concept, by hardening the type annotations. As it turns
out, we do not actually need any of this covariance or protocol-ism for
a list of strings! The whole attempt was a slow, buggy waste of time.
pull/11159/head
Eli Schwartz 2 years ago
parent cbf4496434
commit e5a9272034
No known key found for this signature in database
GPG Key ID: CEB167EFB5722BD6
  1. 4
      mesonbuild/dependencies/mpi.py
  2. 2
      mesonbuild/interpreter/interpreter.py
  3. 2
      mesonbuild/modules/gnome.py
  4. 2
      mesonbuild/mparser.py
  5. 2
      mesonbuild/utils/universal.py

@ -102,7 +102,7 @@ def mpi_factory(env: 'Environment',
class _MPIConfigToolDependency(ConfigToolDependency):
def _filter_compile_args(self, args: T.Sequence[str]) -> T.List[str]:
def _filter_compile_args(self, args: T.List[str]) -> T.List[str]:
"""
MPI wrappers return a bunch of garbage args.
Drop -O2 and everything that is not needed.
@ -126,7 +126,7 @@ class _MPIConfigToolDependency(ConfigToolDependency):
result.append(f)
return result
def _filter_link_args(self, args: T.Sequence[str]) -> T.List[str]:
def _filter_link_args(self, args: T.List[str]) -> T.List[str]:
"""
MPI wrappers return a bunch of garbage args.
Drop -O2 and everything that is not needed.

@ -1377,7 +1377,7 @@ class Interpreter(InterpreterBase, HoldableObject):
def func_exception(self, node, args, kwargs):
raise Exception()
def add_languages(self, args: T.Sequence[str], required: bool, for_machine: MachineChoice) -> bool:
def add_languages(self, args: T.List[str], required: bool, for_machine: MachineChoice) -> bool:
success = self.add_languages_for(args, required, for_machine)
if not self.coredata.is_cross_build():
self.coredata.copy_build_options_from_regular_ones()

@ -1066,7 +1066,7 @@ class GnomeModule(ExtensionModule):
return typelib_includes, new_depends
@staticmethod
def _get_external_args_for_langs(state: 'ModuleState', langs: T.Sequence[str]) -> T.List[str]:
def _get_external_args_for_langs(state: 'ModuleState', langs: T.List[str]) -> T.List[str]:
ret: T.List[str] = []
for lang in langs:
ret += mesonlib.listify(state.environment.coredata.get_external_args(MachineChoice.HOST, lang))

@ -525,7 +525,7 @@ class Parser:
return True
return False
def accept_any(self, tids: T.Sequence[str]) -> str:
def accept_any(self, tids: T.Tuple[str, ...]) -> str:
tid = self.current.tid
if tid in tids:
self.getsym()

@ -1906,7 +1906,7 @@ class RealPathAction(argparse.Action):
setattr(namespace, self.dest, os.path.abspath(os.path.realpath(values)))
def get_wine_shortpath(winecmd: T.List[str], wine_paths: T.Sequence[str],
def get_wine_shortpath(winecmd: T.List[str], wine_paths: T.List[str],
workdir: T.Optional[str] = None) -> str:
'''
WINEPATH size is limited to 1024 bytes which can easily be exceeded when

Loading…
Cancel
Save