Skip to content

Commit 31e4ced

Browse files
chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.16.5 (#625)
* chore(deps): update pre-commit hook astral-sh/ruff-pre-commit to v0.16.5 * update prek and hooks Signed-off-by: gruebel <anton.gruebel@gmail.com> --------- Signed-off-by: gruebel <anton.gruebel@gmail.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: gruebel <anton.gruebel@gmail.com>
1 parent 36ac29b commit 31e4ced

5 files changed

Lines changed: 243 additions & 214 deletions

File tree

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ permissions:
1717
contents: read
1818

1919
env:
20-
PREK_VERSION: '0.4.x'
20+
PREK_VERSION: '0.5.x'
2121
TARGET_PYTHON_VERSION: "3.14"
2222

2323
jobs:

.pre-commit-config.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
default_stages: [pre-commit]
22
repos:
33
- repo: https://github.com/astral-sh/ruff-pre-commit
4-
rev: v0.15.15
4+
rev: v0.16.5
55
hooks:
66
- id: ruff-check
77
priority: 1
@@ -22,14 +22,14 @@ repos:
2222
priority: 0
2323

2424
- repo: https://github.com/tox-dev/pyproject-fmt
25-
rev: v2.21.2
25+
rev: v2.28.2
2626
hooks:
2727
- id: pyproject-fmt
2828
priority: 0
2929
additional_dependencies: [toml-fmt-common<1.3.3] # removed after fix https://github.com/tox-dev/toml-fmt/issues/355
3030

3131
- repo: https://github.com/pre-commit/mirrors-mypy
32-
rev: v2.1.0
32+
rev: v2.3.1
3333
hooks:
3434
- id: mypy
3535
priority: 1

README.md

Lines changed: 63 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ from openfeature.provider.in_memory_provider import InMemoryFlag, InMemoryProvid
8383

8484
# flags defined in memory
8585
my_flags = {
86-
"v2_enabled": InMemoryFlag("on", {"on": True, "off": False})
86+
"v2_enabled": InMemoryFlag("on", {"on": True, "off": False}),
8787
}
8888

8989
# configure a provider
@@ -161,7 +161,7 @@ global_context = EvaluationContext(
161161
targeting_key="targeting_key1", attributes={"application": "value1"}
162162
)
163163
request_context = EvaluationContext(
164-
targeting_key="targeting_key2", attributes={"email": request.form['email']}
164+
targeting_key="targeting_key2", attributes={"email": request.form["email"]}
165165
)
166166

167167
## set global context
@@ -210,10 +210,10 @@ client = api.get_client()
210210

211211
# trigger tracking event action
212212
client.track(
213-
'visited-promo-page',
213+
"visited-promo-page",
214214
evaluation_context=EvaluationContext(),
215215
tracking_event_details=TrackingEventDetails(99.77).add("currencyCode", "USD"),
216-
)
216+
)
217217
```
218218

219219
Note that some providers may not support tracking; check the documentation for your provider for more information.
@@ -243,14 +243,13 @@ If a domain has no associated provider, the global provider is used.
243243
from openfeature import api
244244

245245
# Registering the default provider
246-
api.set_provider(MyProvider());
246+
api.set_provider(MyProvider())
247247
# Registering a provider to a domain
248-
api.set_provider(MyProvider(), "my-domain");
249-
248+
api.set_provider(MyProvider(), "my-domain")
250249
# A client bound to the default provider
251-
default_client = api.get_client();
250+
default_client = api.get_client()
252251
# A client bound to the MyProvider provider
253-
domain_scoped_client = api.get_client("my-domain");
252+
domain_scoped_client = api.get_client("my-domain")
254253
```
255254

256255
Domains can be defined on a provider during registration.
@@ -266,16 +265,20 @@ Please refer to the documentation of the provider you're using to see what event
266265
from openfeature import api
267266
from openfeature.event import EventDetails, ProviderEvent
268267

268+
269269
def on_provider_ready(event_details: EventDetails):
270270
print(f"Provider {event_details.provider_name} is ready")
271271

272+
272273
api.add_handler(ProviderEvent.PROVIDER_READY, on_provider_ready)
273274

274275
client = api.get_client()
275276

277+
276278
def on_provider_ready(event_details: EventDetails):
277279
print(f"Provider {event_details.provider_name} is ready")
278280

281+
279282
client.add_handler(ProviderEvent.PROVIDER_READY, on_provider_ready)
280283
```
281284

@@ -301,26 +304,33 @@ app = Flask(__name__)
301304
# Set the transaction context propagator
302305
api.set_transaction_context_propagator(ContextVarsTransactionContextPropagator())
303306

307+
304308
# Middleware to set the transaction context
305309
# You can call api.set_transaction_context anywhere you have information,
306310
# you want to have available in the code-paths below the current one.
307311
@app.before_request
308312
def set_request_transaction_context():
309-
ip = request.headers.get("X-Forwarded-For", request.remote_addr)
310-
user_id = request.headers.get("User-Id") # Assuming we're getting the user ID from a header
311-
evaluation_context = EvaluationContext(targeting_key=user_id, attributes={"ipAddress": ip})
312-
api.set_transaction_context(evaluation_context)
313+
ip = request.headers.get("X-Forwarded-For", request.remote_addr)
314+
user_id = request.headers.get(
315+
"User-Id"
316+
) # Assuming we're getting the user ID from a header
317+
evaluation_context = EvaluationContext(
318+
targeting_key=user_id, attributes={"ipAddress": ip}
319+
)
320+
api.set_transaction_context(evaluation_context)
321+
313322

314323
def create_response() -> str:
315-
# This method can be anywhere in our code.
316-
# The feature flag evaluation will automatically contain the transaction context merged with other context
317-
new_response = api.get_client().get_string_value("response-message", "Hello User!")
318-
return f"Message from server: {new_response}"
324+
# This method can be anywhere in our code.
325+
# The feature flag evaluation will automatically contain the transaction context merged with other context
326+
new_response = api.get_client().get_string_value("response-message", "Hello User!")
327+
return f"Message from server: {new_response}"
328+
319329

320330
# Example route where we use the transaction context
321-
@app.route('/greeting')
331+
@app.route("/greeting")
322332
def some_endpoint():
323-
return create_response()
333+
return create_response()
324334
```
325335

326336
This also works for asyncio based implementations e.g. FastApi as seen in the following example:
@@ -337,24 +347,31 @@ app = FastAPI()
337347
# Set the transaction context propagator
338348
api.set_transaction_context_propagator(ContextVarsTransactionContextPropagator())
339349

350+
340351
# Middleware to set the transaction context
341352
@app.middleware("http")
342353
async def set_request_transaction_context(request: Request, call_next):
343354
ip = request.headers.get("X-Forwarded-For", request.client.host)
344-
user_id = request.headers.get("User-Id") # Assuming we're getting the user ID from a header
345-
evaluation_context = EvaluationContext(targeting_key=user_id, attributes={"ipAddress": ip})
355+
user_id = request.headers.get(
356+
"User-Id"
357+
) # Assuming we're getting the user ID from a header
358+
evaluation_context = EvaluationContext(
359+
targeting_key=user_id, attributes={"ipAddress": ip}
360+
)
346361
api.set_transaction_context(evaluation_context)
347362
response = await call_next(request)
348363
return response
349364

365+
350366
def create_response() -> str:
351367
# This method can be located anywhere in our code.
352368
# The feature flag evaluation will automatically include the transaction context merged with other context.
353369
new_response = api.get_client().get_string_value("response-message", "Hello User!")
354370
return f"Message from server: {new_response}"
355371

372+
356373
# Example route where we use the transaction context
357-
@app.get('/greeting')
374+
@app.get("/greeting")
358375
async def some_endpoint():
359376
return create_response()
360377
```
@@ -368,10 +385,12 @@ import asyncio
368385
from openfeature import api
369386
from openfeature.provider.in_memory_provider import InMemoryFlag, InMemoryProvider
370387

371-
my_flags = { "v2_enabled": InMemoryFlag("on", {"on": True, "off": False}) }
388+
my_flags = {"v2_enabled": InMemoryFlag("on", {"on": True, "off": False})}
372389
api.set_provider(InMemoryProvider(my_flags))
373390
client = api.get_client()
374-
flag_value = await client.get_boolean_value_async("v2_enabled", False) # API calls are suffixed by _async
391+
flag_value = await client.get_boolean_value_async(
392+
"v2_enabled", False
393+
) # API calls are suffixed by _async
375394

376395
print("Value: " + str(flag_value))
377396
```
@@ -404,9 +423,9 @@ from openfeature.flag_evaluation import FlagResolutionDetails
404423
from openfeature.hook import Hook
405424
from openfeature.provider import AbstractProvider, Metadata
406425

426+
407427
class MyProvider(AbstractProvider):
408-
def get_metadata(self) -> Metadata:
409-
...
428+
def get_metadata(self) -> Metadata: ...
410429

411430
def get_provider_hooks(self) -> List[Hook]:
412431
return []
@@ -416,40 +435,35 @@ class MyProvider(AbstractProvider):
416435
flag_key: str,
417436
default_value: bool,
418437
evaluation_context: Optional[EvaluationContext] = None,
419-
) -> FlagResolutionDetails[bool]:
420-
...
438+
) -> FlagResolutionDetails[bool]: ...
421439

422440
def resolve_string_details(
423441
self,
424442
flag_key: str,
425443
default_value: str,
426444
evaluation_context: Optional[EvaluationContext] = None,
427-
) -> FlagResolutionDetails[str]:
428-
...
445+
) -> FlagResolutionDetails[str]: ...
429446

430447
def resolve_integer_details(
431448
self,
432449
flag_key: str,
433450
default_value: int,
434451
evaluation_context: Optional[EvaluationContext] = None,
435-
) -> FlagResolutionDetails[int]:
436-
...
452+
) -> FlagResolutionDetails[int]: ...
437453

438454
def resolve_float_details(
439455
self,
440456
flag_key: str,
441457
default_value: float,
442458
evaluation_context: Optional[EvaluationContext] = None,
443-
) -> FlagResolutionDetails[float]:
444-
...
459+
) -> FlagResolutionDetails[float]: ...
445460

446461
def resolve_object_details(
447462
self,
448463
flag_key: str,
449464
default_value: Union[dict, list],
450465
evaluation_context: Optional[EvaluationContext] = None,
451-
) -> FlagResolutionDetails[Union[dict, list]]:
452-
...
466+
) -> FlagResolutionDetails[Union[dict, list]]: ...
453467
```
454468

455469
Providers can also be extended to support async functionality.
@@ -461,46 +475,41 @@ To support add asynchronous calls to a provider:
461475
```python
462476
class MyProvider(AbstractProvider):
463477
...
478+
464479
async def resolve_boolean_details_async(
465480
self,
466481
flag_key: str,
467482
default_value: bool,
468483
evaluation_context: Optional[EvaluationContext] = None,
469-
) -> FlagResolutionDetails[bool]:
470-
...
484+
) -> FlagResolutionDetails[bool]: ...
471485

472486
async def resolve_string_details_async(
473487
self,
474488
flag_key: str,
475489
default_value: str,
476490
evaluation_context: Optional[EvaluationContext] = None,
477-
) -> FlagResolutionDetails[str]:
478-
...
491+
) -> FlagResolutionDetails[str]: ...
479492

480493
async def resolve_integer_details_async(
481494
self,
482495
flag_key: str,
483496
default_value: int,
484497
evaluation_context: Optional[EvaluationContext] = None,
485-
) -> FlagResolutionDetails[int]:
486-
...
498+
) -> FlagResolutionDetails[int]: ...
487499

488500
async def resolve_float_details_async(
489501
self,
490502
flag_key: str,
491503
default_value: float,
492504
evaluation_context: Optional[EvaluationContext] = None,
493-
) -> FlagResolutionDetails[float]:
494-
...
505+
) -> FlagResolutionDetails[float]: ...
495506

496507
async def resolve_object_details_async(
497508
self,
498509
flag_key: str,
499510
default_value: Union[dict, list],
500511
evaluation_context: Optional[EvaluationContext] = None,
501-
) -> FlagResolutionDetails[Union[dict, list]]:
502-
...
503-
512+
) -> FlagResolutionDetails[Union[dict, list]]: ...
504513
```
505514

506515
> Built a new provider? [Let us know](https://github.com/open-feature/openfeature.dev/issues/new?assignees=&labels=provider&projects=&template=document-provider.yaml&title=%5BProvider%5D%3A+) so we can add it to the docs!
@@ -516,10 +525,15 @@ Any of the evaluation life-cycle stages (`before`/`after`/`error`/`finally_after
516525
from openfeature.hook import Hook, HookContext, HookHints
517526
from openfeature.flag_evaluation import FlagEvaluationDetails, FlagValueType
518527

528+
519529
class MyHook(Hook):
520-
def after(self, hook_context: HookContext, details: FlagEvaluationDetails[FlagValueType], hints: HookHints):
530+
def after(
531+
self,
532+
hook_context: HookContext,
533+
details: FlagEvaluationDetails[FlagValueType],
534+
hints: HookHints,
535+
):
521536
print("This runs after the flag has been evaluated")
522-
523537
```
524538

525539
> Built a new hook? [Let us know](https://github.com/open-feature/openfeature.dev/issues/new?assignees=&labels=hook&projects=&template=document-hook.yaml&title=%5BHook%5D%3A+) so we can add it to the docs!

pyproject.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ dev = [
3434
"behave>=1.3.0,<2.0.0",
3535
"coverage[toml]>=7.10.0,<8.0.0",
3636
"poethepoet>=0.40.0,<1.0.0",
37-
"prek>=0.4.3,<0.5.0",
37+
"prek>=0.5.0,<0.6.0",
3838
"pytest>=9.0.0,<10.0.0",
3939
"pytest-asyncio>=1.3.0,<2.0.0",
4040
]
@@ -105,18 +105,18 @@ max_supported_python = "3.14"
105105

106106
[tool.mypy]
107107
files = "openfeature,tests/typechecking"
108-
python_version = "3.10" # should be identical to the minimum supported version
109108
namespace_packages = true
110109
explicit_package_bases = true
110+
python_version = "3.10" # should be identical to the minimum supported version
111+
disallow_any_generics = false
112+
strict = true
113+
pretty = true
111114
native_parser = true # Rust-based parser will become default in the future
112115
num_workers = 2
113-
pretty = true
114-
strict = true
115-
disallow_any_generics = false
116116

117117
[tool.pytest]
118-
strict = true
119118
asyncio_default_fixture_loop_scope = "function"
119+
strict = true
120120

121121
[tool.coverage]
122122
report.exclude_also = [

0 commit comments

Comments
 (0)