Skip to content

Commit

Permalink
chore!: drop Python 3.8 support (#441)
Browse files Browse the repository at this point in the history
* drop Python 3.8 support

Signed-off-by: gruebel <anton.gruebel@gmail.com>

* pin mypy python version to 3.9

Signed-off-by: gruebel <anton.gruebel@gmail.com>

---------

Signed-off-by: gruebel <anton.gruebel@gmail.com>
Co-authored-by: Michael Beemer <beeme1mr@users.noreply.github.com>
  • Loading branch information
gruebel and beeme1mr authored Feb 11, 2025
1 parent d4f53b4 commit bcd1a38
Show file tree
Hide file tree
Showing 16 changed files with 57 additions and 52 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]

steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
Expand All @@ -44,7 +44,7 @@ jobs:
- name: Run E2E tests with behave
run: hatch run e2e

- if: matrix.python-version == '3.11'
- if: matrix.python-version == '3.13'
name: Upload coverage to Codecov
uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1
with:
Expand All @@ -61,7 +61,7 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5
with:
python-version: "3.11"
python-version: "3.13"
cache: "pip"

- name: Run pre-commit
Expand All @@ -77,7 +77,7 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5
with:
python-version: "3.11"
python-version: "3.13"

- name: Initialize CodeQL
uses: github/codeql-action/init@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
default_stages: [commit]
default_stages: [pre-commit]
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.6
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

### System Requirements

Python 3.8 and above are required.
Python 3.9 and above are required.

### Target version(s)

Python 3.8 and above are supported by the SDK.
Python 3.9 and above are supported by the SDK.

### Installation and Dependencies

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
</a>

<a href="https://www.python.org/downloads/">
<img alt="Min python version" src="https://img.shields.io/badge/python->=3.8-blue.svg" />
<img alt="Min python version" src="https://img.shields.io/badge/python->=3.9-blue.svg" />
</a>

<a href="https://www.repostatus.org/#wip">
Expand All @@ -51,7 +51,7 @@

### Requirements

- Python 3.8+
- Python 3.9+

### Install

Expand Down
6 changes: 3 additions & 3 deletions openfeature/_event_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import threading
from collections import defaultdict
from typing import TYPE_CHECKING, Dict, List
from typing import TYPE_CHECKING

from openfeature.event import (
EventDetails,
Expand All @@ -17,10 +17,10 @@


_global_lock = threading.RLock()
_global_handlers: Dict[ProviderEvent, List[EventHandler]] = defaultdict(list)
_global_handlers: dict[ProviderEvent, list[EventHandler]] = defaultdict(list)

_client_lock = threading.RLock()
_client_handlers: Dict[OpenFeatureClient, Dict[ProviderEvent, List[EventHandler]]] = (
_client_handlers: dict[OpenFeatureClient, dict[ProviderEvent, list[EventHandler]]] = (
defaultdict(lambda: defaultdict(list))
)

Expand Down
6 changes: 3 additions & 3 deletions openfeature/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
NoOpTransactionContextPropagator()
)

_hooks: typing.List[Hook] = []
_hooks: list[Hook] = []


def get_client(
Expand Down Expand Up @@ -96,7 +96,7 @@ def set_transaction_context(evaluation_context: EvaluationContext) -> None:
)


def add_hooks(hooks: typing.List[Hook]) -> None:
def add_hooks(hooks: list[Hook]) -> None:
global _hooks
_hooks = _hooks + hooks

Expand All @@ -106,7 +106,7 @@ def clear_hooks() -> None:
_hooks = []


def get_hooks() -> typing.List[Hook]:
def get_hooks() -> list[Hook]:
return _hooks


Expand Down
24 changes: 12 additions & 12 deletions openfeature/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,14 @@
typing.Awaitable[FlagResolutionDetails[typing.Union[dict, list]]],
],
]
TypeMap = typing.Dict[
TypeMap = dict[
FlagType,
typing.Union[
typing.Type[bool],
typing.Type[int],
typing.Type[float],
typing.Type[str],
typing.Tuple[typing.Type[dict], typing.Type[list]],
type[bool],
type[int],
type[float],
type[str],
tuple[type[dict], type[list]],
],
]

Expand All @@ -101,7 +101,7 @@ def __init__(
domain: typing.Optional[str],
version: typing.Optional[str],
context: typing.Optional[EvaluationContext] = None,
hooks: typing.Optional[typing.List[Hook]] = None,
hooks: typing.Optional[list[Hook]] = None,
) -> None:
self.domain = domain
self.version = version
Expand All @@ -118,7 +118,7 @@ def get_provider_status(self) -> ProviderStatus:
def get_metadata(self) -> ClientMetadata:
return ClientMetadata(domain=self.domain)

def add_hooks(self, hooks: typing.List[Hook]) -> None:
def add_hooks(self, hooks: list[Hook]) -> None:
self.hooks = self.hooks + hooks

def get_boolean_value(
Expand Down Expand Up @@ -423,12 +423,12 @@ def _establish_hooks_and_provider(
default_value: typing.Any,
evaluation_context: typing.Optional[EvaluationContext],
flag_evaluation_options: typing.Optional[FlagEvaluationOptions],
) -> typing.Tuple[
) -> tuple[
FeatureProvider,
HookContext,
HookHints,
typing.List[Hook],
typing.List[Hook],
list[Hook],
list[Hook],
]:
if evaluation_context is None:
evaluation_context = EvaluationContext()
Expand Down Expand Up @@ -477,7 +477,7 @@ def _before_hooks_and_merge_context(
self,
flag_type: FlagType,
hook_context: HookContext,
merged_hooks: typing.List[Hook],
merged_hooks: list[Hook],
hook_hints: HookHints,
evaluation_context: typing.Optional[EvaluationContext],
) -> EvaluationContext:
Expand Down
10 changes: 5 additions & 5 deletions openfeature/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from dataclasses import dataclass, field
from enum import Enum
from typing import Callable, Dict, List, Optional, Union
from typing import Callable, Optional, Union

from openfeature.exception import ErrorCode

Expand All @@ -18,19 +18,19 @@ class ProviderEvent(Enum):

@dataclass
class ProviderEventDetails:
flags_changed: Optional[List[str]] = None
flags_changed: Optional[list[str]] = None
message: Optional[str] = None
error_code: Optional[ErrorCode] = None
metadata: Dict[str, Union[bool, str, int, float]] = field(default_factory=dict)
metadata: dict[str, Union[bool, str, int, float]] = field(default_factory=dict)


@dataclass
class EventDetails(ProviderEventDetails):
provider_name: str = ""
flags_changed: Optional[List[str]] = None
flags_changed: Optional[list[str]] = None
message: Optional[str] = None
error_code: Optional[ErrorCode] = None
metadata: Dict[str, Union[bool, str, int, float]] = field(default_factory=dict)
metadata: dict[str, Union[bool, str, int, float]] = field(default_factory=dict)

@classmethod
def from_provider_event_details(
Expand Down
2 changes: 1 addition & 1 deletion openfeature/flag_evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class FlagEvaluationDetails(typing.Generic[T_co]):

@dataclass
class FlagEvaluationOptions:
hooks: typing.List[Hook] = field(default_factory=list)
hooks: list[Hook] = field(default_factory=list)
hook_hints: HookHints = field(default_factory=dict)


Expand Down
4 changes: 2 additions & 2 deletions openfeature/hook/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ def __setattr__(self, key: str, value: typing.Any) -> None:
float,
str,
datetime,
typing.List[typing.Any],
typing.Dict[str, typing.Any],
list[typing.Any],
dict[str, typing.Any],
],
]

Expand Down
14 changes: 7 additions & 7 deletions openfeature/hook/_hook_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def error_hooks(
flag_type: FlagType,
hook_context: HookContext,
exception: Exception,
hooks: typing.List[Hook],
hooks: list[Hook],
hints: typing.Optional[HookHints] = None,
) -> None:
kwargs = {"hook_context": hook_context, "exception": exception, "hints": hints}
Expand All @@ -26,7 +26,7 @@ def after_all_hooks(
flag_type: FlagType,
hook_context: HookContext,
details: FlagEvaluationDetails[typing.Any],
hooks: typing.List[Hook],
hooks: list[Hook],
hints: typing.Optional[HookHints] = None,
) -> None:
kwargs = {"hook_context": hook_context, "details": details, "hints": hints}
Expand All @@ -39,7 +39,7 @@ def after_hooks(
flag_type: FlagType,
hook_context: HookContext,
details: FlagEvaluationDetails[typing.Any],
hooks: typing.List[Hook],
hooks: list[Hook],
hints: typing.Optional[HookHints] = None,
) -> None:
kwargs = {"hook_context": hook_context, "details": details, "hints": hints}
Expand All @@ -51,7 +51,7 @@ def after_hooks(
def before_hooks(
flag_type: FlagType,
hook_context: HookContext,
hooks: typing.List[Hook],
hooks: list[Hook],
hints: typing.Optional[HookHints] = None,
) -> EvaluationContext:
kwargs = {"hook_context": hook_context, "hints": hints}
Expand All @@ -68,7 +68,7 @@ def before_hooks(

def _execute_hooks(
flag_type: FlagType,
hooks: typing.List[Hook],
hooks: list[Hook],
hook_method: HookType,
**kwargs: typing.Any,
) -> list:
Expand All @@ -91,10 +91,10 @@ def _execute_hooks(

def _execute_hooks_unchecked(
flag_type: FlagType,
hooks: typing.List[Hook],
hooks: list[Hook],
hook_method: HookType,
**kwargs: typing.Any,
) -> typing.List[typing.Optional[EvaluationContext]]:
) -> list[typing.Optional[EvaluationContext]]:
"""
Execute a single hook without checking whether an exception is thrown. This is
used in the before and after hooks since any exception will be caught in the
Expand Down
4 changes: 2 additions & 2 deletions openfeature/provider/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def shutdown(self) -> None: ...

def get_metadata(self) -> Metadata: ...

def get_provider_hooks(self) -> typing.List[Hook]: ...
def get_provider_hooks(self) -> list[Hook]: ...

def resolve_boolean_details(
self,
Expand Down Expand Up @@ -134,7 +134,7 @@ def shutdown(self) -> None:
def get_metadata(self) -> Metadata:
pass

def get_provider_hooks(self) -> typing.List[Hook]:
def get_provider_hooks(self) -> list[Hook]:
return []

@abstractmethod
Expand Down
4 changes: 2 additions & 2 deletions openfeature/provider/_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@

class ProviderRegistry:
_default_provider: FeatureProvider
_providers: typing.Dict[str, FeatureProvider]
_provider_status: typing.Dict[FeatureProvider, ProviderStatus]
_providers: dict[str, FeatureProvider]
_provider_status: dict[FeatureProvider, ProviderStatus]

def __init__(self) -> None:
self._default_provider = NoOpProvider()
Expand Down
6 changes: 3 additions & 3 deletions openfeature/provider/in_memory_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class State(StrEnum):
DISABLED = "DISABLED"

default_variant: str
variants: typing.Dict[str, T_co]
variants: dict[str, T_co]
flag_metadata: FlagMetadata = field(default_factory=dict)
state: State = State.ENABLED
context_evaluator: typing.Optional[
Expand All @@ -51,7 +51,7 @@ def resolve(
)


FlagStorage = typing.Dict[str, InMemoryFlag[typing.Any]]
FlagStorage = dict[str, InMemoryFlag[typing.Any]]

V = typing.TypeVar("V")

Expand All @@ -65,7 +65,7 @@ def __init__(self, flags: FlagStorage) -> None:
def get_metadata(self) -> Metadata:
return InMemoryMetadata()

def get_provider_hooks(self) -> typing.List[Hook]:
def get_provider_hooks(self) -> list[Hook]:
return []

def resolve_boolean_details(
Expand Down
2 changes: 1 addition & 1 deletion openfeature/provider/no_op_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class NoOpProvider(AbstractProvider):
def get_metadata(self) -> Metadata:
return NoOpMetadata()

def get_provider_hooks(self) -> typing.List[Hook]:
def get_provider_hooks(self) -> list[Hook]:
return []

def resolve_boolean_details(
Expand Down
9 changes: 7 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ keywords = [
"toggles",
]
dependencies = []
requires-python = ">=3.8"
requires-python = ">=3.9"

[project.urls]
Homepage = "https://github.com/open-feature/python-sdk"
Expand Down Expand Up @@ -66,21 +66,26 @@ packages = ["openfeature"]

[tool.mypy]
files = "openfeature"

python_version = "3.9" # should be identical to the minimum supported version
namespace_packages = true
explicit_package_bases = true
local_partial_types = true # will become the new default from version 2
pretty = true
strict = true
disallow_any_generics = false

[tool.pytest.ini_options]
asyncio_default_fixture_loop_scope = "function"

[tool.ruff]
exclude = [
".git",
".venv",
"__pycache__",
"venv",
]
target-version = "py38"
target-version = "py39"

[tool.ruff.lint]
select = [
Expand Down

0 comments on commit bcd1a38

Please sign in to comment.