Coverage for /usr/lib/python3/dist-packages/sympy/multipledispatch/core.py: 100%

20 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-14 15:55 +0200

1from __future__ import annotations 

2from typing import Any 

3 

4import inspect 

5 

6from .dispatcher import Dispatcher, MethodDispatcher, ambiguity_warn 

7 

8# XXX: This parameter to dispatch isn't documented and isn't used anywhere in 

9# sympy. Maybe it should just be removed. 

10global_namespace: dict[str, Any] = {} 

11 

12 

13def dispatch(*types, namespace=global_namespace, on_ambiguity=ambiguity_warn): 

14 """ Dispatch function on the types of the inputs 

15 

16 Supports dispatch on all non-keyword arguments. 

17 

18 Collects implementations based on the function name. Ignores namespaces. 

19 

20 If ambiguous type signatures occur a warning is raised when the function is 

21 defined suggesting the additional method to break the ambiguity. 

22 

23 Examples 

24 -------- 

25 

26 >>> from sympy.multipledispatch import dispatch 

27 >>> @dispatch(int) 

28 ... def f(x): 

29 ... return x + 1 

30 

31 >>> @dispatch(float) 

32 ... def f(x): # noqa: F811 

33 ... return x - 1 

34 

35 >>> f(3) 

36 4 

37 >>> f(3.0) 

38 2.0 

39 

40 Specify an isolated namespace with the namespace keyword argument 

41 

42 >>> my_namespace = dict() 

43 >>> @dispatch(int, namespace=my_namespace) 

44 ... def foo(x): 

45 ... return x + 1 

46 

47 Dispatch on instance methods within classes 

48 

49 >>> class MyClass(object): 

50 ... @dispatch(list) 

51 ... def __init__(self, data): 

52 ... self.data = data 

53 ... @dispatch(int) 

54 ... def __init__(self, datum): # noqa: F811 

55 ... self.data = [datum] 

56 """ 

57 types = tuple(types) 

58 

59 def _(func): 

60 name = func.__name__ 

61 

62 if ismethod(func): 

63 dispatcher = inspect.currentframe().f_back.f_locals.get( 

64 name, 

65 MethodDispatcher(name)) 

66 else: 

67 if name not in namespace: 

68 namespace[name] = Dispatcher(name) 

69 dispatcher = namespace[name] 

70 

71 dispatcher.add(types, func, on_ambiguity=on_ambiguity) 

72 return dispatcher 

73 return _ 

74 

75 

76def ismethod(func): 

77 """ Is func a method? 

78 

79 Note that this has to work as the method is defined but before the class is 

80 defined. At this stage methods look like functions. 

81 """ 

82 signature = inspect.signature(func) 

83 return signature.parameters.get('self', None) is not None