Decorator turning a function into a generic function
(func)
| 336 | (len(dispatch_args), len(arguments), msg)) |
| 337 | |
| 338 | def gen_func_dec(func): |
| 339 | """Decorator turning a function into a generic function""" |
| 340 | |
| 341 | # first check the dispatch arguments |
| 342 | argset = set(getfullargspec(func).args) |
| 343 | if not set(dispatch_args) <= argset: |
| 344 | raise NameError('Unknown dispatch arguments %s' % dispatch_str) |
| 345 | |
| 346 | typemap = {} |
| 347 | |
| 348 | def vancestors(*types): |
| 349 | """ |
| 350 | Get a list of sets of virtual ancestors for the given types |
| 351 | """ |
| 352 | check(types) |
| 353 | ras = [[] for _ in range(len(dispatch_args))] |
| 354 | for types_ in typemap: |
| 355 | for t, type_, ra in zip(types, types_, ras): |
| 356 | if issubclass(t, type_) and type_ not in t.__mro__: |
| 357 | append(type_, ra) |
| 358 | return [set(ra) for ra in ras] |
| 359 | |
| 360 | def ancestors(*types): |
| 361 | """ |
| 362 | Get a list of virtual MROs, one for each type |
| 363 | """ |
| 364 | check(types) |
| 365 | lists = [] |
| 366 | for t, vas in zip(types, vancestors(*types)): |
| 367 | n_vas = len(vas) |
| 368 | if n_vas > 1: |
| 369 | raise RuntimeError( |
| 370 | 'Ambiguous dispatch for %s: %s' % (t, vas)) |
| 371 | elif n_vas == 1: |
| 372 | va, = vas |
| 373 | mro = type('t', (t, va), {}).__mro__[1:] |
| 374 | else: |
| 375 | mro = t.__mro__ |
| 376 | lists.append(mro[:-1]) # discard t and object |
| 377 | return lists |
| 378 | |
| 379 | def register(*types): |
| 380 | """ |
| 381 | Decorator to register an implementation for the given types |
| 382 | """ |
| 383 | check(types) |
| 384 | |
| 385 | def dec(f): |
| 386 | check(getfullargspec(f).args, operator.lt, ' in ' + f.__name__) |
| 387 | typemap[types] = f |
| 388 | return f |
| 389 | |
| 390 | return dec |
| 391 | |
| 392 | def dispatch_info(*types): |
| 393 | """ |
| 394 | An utility to introspect the dispatch algorithm |
| 395 | """ |
nothing calls this directly
no test coverage detected