1
1
from __future__ import annotations
2
2
3
3
import typing
4
- from dataclasses import dataclass
4
+ from datetime import datetime
5
5
from enum import Enum
6
6
from typing import TYPE_CHECKING
7
7
@@ -20,24 +20,53 @@ class HookType(Enum):
20
20
ERROR = "error"
21
21
22
22
23
- @dataclass
24
23
class HookContext :
25
- flag_key : str
26
- flag_type : FlagType
27
- default_value : typing .Any
28
- evaluation_context : EvaluationContext
29
- client_metadata : typing .Optional [ClientMetadata ] = None
30
- provider_metadata : typing .Optional [Metadata ] = None
24
+ def __init__ ( # noqa: PLR0913
25
+ self ,
26
+ flag_key : str ,
27
+ flag_type : FlagType ,
28
+ default_value : typing .Any ,
29
+ evaluation_context : EvaluationContext ,
30
+ client_metadata : typing .Optional [ClientMetadata ] = None ,
31
+ provider_metadata : typing .Optional [Metadata ] = None ,
32
+ ):
33
+ self .flag_key = flag_key
34
+ self .flag_type = flag_type
35
+ self .default_value = default_value
36
+ self .evaluation_context = evaluation_context
37
+ self .client_metadata = client_metadata
38
+ self .provider_metadata = provider_metadata
31
39
32
40
def __setattr__ (self , key : str , value : typing .Any ) -> None :
33
- if hasattr (self , key ) and key in ("flag_key" , "flag_type" , "default_value" ):
41
+ if hasattr (self , key ) and key in (
42
+ "flag_key" ,
43
+ "flag_type" ,
44
+ "default_value" ,
45
+ "client_metadata" ,
46
+ "provider_metadata" ,
47
+ ):
34
48
raise AttributeError (f"Attribute { key !r} is immutable" )
35
49
super ().__setattr__ (key , value )
36
50
37
51
52
+ # https://openfeature.dev/specification/sections/hooks/#requirement-421
53
+ HookHints = typing .Mapping [
54
+ str ,
55
+ typing .Union [
56
+ bool ,
57
+ int ,
58
+ float ,
59
+ str ,
60
+ datetime ,
61
+ typing .List [typing .Any ],
62
+ typing .Dict [str , typing .Any ],
63
+ ],
64
+ ]
65
+
66
+
38
67
class Hook :
39
68
def before (
40
- self , hook_context : HookContext , hints : dict
69
+ self , hook_context : HookContext , hints : HookHints
41
70
) -> typing .Optional [EvaluationContext ]:
42
71
"""
43
72
Runs before flag is resolved.
@@ -54,7 +83,7 @@ def after(
54
83
self ,
55
84
hook_context : HookContext ,
56
85
details : FlagEvaluationDetails [typing .Any ],
57
- hints : dict ,
86
+ hints : HookHints ,
58
87
) -> None :
59
88
"""
60
89
Runs after a flag is resolved.
@@ -67,7 +96,7 @@ def after(
67
96
pass
68
97
69
98
def error (
70
- self , hook_context : HookContext , exception : Exception , hints : dict
99
+ self , hook_context : HookContext , exception : Exception , hints : HookHints
71
100
) -> None :
72
101
"""
73
102
Run when evaluation encounters an error. Errors thrown will be swallowed.
@@ -78,7 +107,7 @@ def error(
78
107
"""
79
108
pass
80
109
81
- def finally_after (self , hook_context : HookContext , hints : dict ) -> None :
110
+ def finally_after (self , hook_context : HookContext , hints : HookHints ) -> None :
82
111
"""
83
112
Run after flag evaluation, including any error processing.
84
113
This will always run. Errors will be swallowed.
0 commit comments