Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
with:
python-version: ${{ env.PYTHON_DEFAULT_VERSION }}
- name: Install dependencies
run: python -m pip install --upgrade nox pdm==2.26.2
run: python -m pip install --upgrade nox pdm==2.26.4
- name: Build the distribution
id: build
run: nox -vs build
Expand Down Expand Up @@ -79,7 +79,7 @@ jobs:
run: |
sudo apt-get -y update
sudo apt-get -y install patchelf scons
python -m pip install --upgrade nox pdm==2.26.2
python -m pip install --upgrade nox pdm==2.26.4
git config --global --add safe.directory '*'
- name: Bundle the distribution
id: bundle
Expand Down Expand Up @@ -114,7 +114,7 @@ jobs:
with:
python-version: ${{ env.PYTHON_DEFAULT_VERSION }}
- name: Install dependencies
run: python -m pip install --upgrade nox pdm==2.26.2
run: python -m pip install --upgrade nox pdm==2.26.4
- name: Bundle the distribution
id: bundle
shell: bash
Expand Down Expand Up @@ -159,7 +159,7 @@ jobs:
with:
python-version: ${{ env.PYTHON_DEFAULT_VERSION }}
- name: Install dependencies
run: python -m pip install --upgrade nox pdm==2.26.2
run: python -m pip install --upgrade nox pdm==2.26.4
- name: Build Dockerfile
run: nox -vs generate_dockerfile
- name: Set up QEMU
Expand Down
16 changes: 8 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
with:
python-version: ${{ env.PYTHON_DEFAULT_VERSION }}
- name: Install dependencies
run: python -m pip install --upgrade nox pdm==2.26.2
run: python -m pip install --upgrade nox pdm==2.26.4
- name: Run linters
run: nox -vs lint
- name: Validate new changelog entries
Expand All @@ -47,7 +47,7 @@ jobs:
with:
python-version: ${{ env.PYTHON_DEFAULT_VERSION }}
- name: Install dependencies
run: python -m pip install --upgrade nox pdm==2.26.2
run: python -m pip install --upgrade nox pdm==2.26.4
- name: Build the distribution
run: nox -vs build
cleanup_buckets:
Expand All @@ -70,7 +70,7 @@ jobs:
cache: "pip"
- name: Install dependencies
if: ${{ env.B2_TEST_APPLICATION_KEY != '' && env.B2_TEST_APPLICATION_KEY_ID != '' }} # TODO: skip this whole job instead
run: python -m pip install --upgrade nox pdm==2.26.2
run: python -m pip install --upgrade nox pdm==2.26.4
- name: Find and remove old buckets
if: ${{ env.B2_TEST_APPLICATION_KEY != '' && env.B2_TEST_APPLICATION_KEY_ID != '' }} # TODO: skip this whole job instead
run: nox -vs cleanup_buckets
Expand Down Expand Up @@ -111,7 +111,7 @@ jobs:
run: |
brew install fish
- name: Install dependencies
run: python -m pip install --upgrade nox pdm==2.26.2
run: python -m pip install --upgrade nox pdm==2.26.4
- name: Run unit tests
run: nox -vs unit -p ${{ matrix.python-version }}
- name: Run integration tests (without secrets)
Expand All @@ -137,7 +137,7 @@ jobs:
with:
python-version: ${{ env.PYTHON_DEFAULT_VERSION }}
- name: Install dependencies
run: python -m pip install --upgrade nox pdm==2.26.2
run: python -m pip install --upgrade nox pdm==2.26.4
- name: Generate Dockerfile
run: nox -vs generate_dockerfile
- name: Set up QEMU
Expand Down Expand Up @@ -178,7 +178,7 @@ jobs:
run: |
sudo apt-get -y update
sudo apt-get -y install patchelf scons
python -m pip install --upgrade nox pdm==2.26.2
python -m pip install --upgrade nox pdm==2.26.4
git config --global --add safe.directory '*'
- name: Bundle the distribution
id: bundle
Expand Down Expand Up @@ -217,7 +217,7 @@ jobs:
with:
python-version: ${{ env.PYTHON_DEFAULT_VERSION }}
- name: Install dependencies
run: python -m pip install --upgrade nox pdm==2.26.2
run: python -m pip install --upgrade nox pdm==2.26.4
- name: Bundle the distribution
id: bundle
shell: bash
Expand Down Expand Up @@ -256,6 +256,6 @@ jobs:
run: |
sudo apt-get update -y
sudo apt-get install -y graphviz plantuml
python -m pip install --upgrade nox pdm==2.26.2
python -m pip install --upgrade nox pdm==2.26.4
- name: Build the docs
run: nox --non-interactive -vs doc
3 changes: 2 additions & 1 deletion b2/_internal/_cli/autocomplete_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
from shlex import quote

import argcomplete
from class_registry import ClassRegistry, RegistryKeyError

from b2._internal.class_registry import ClassRegistry, RegistryKeyError

logger = logging.getLogger(__name__)

Expand Down
108 changes: 108 additions & 0 deletions b2/_internal/class_registry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
######################################################################
#
# File: b2/_internal/class_registry.py
#
# Copyright 2026 Backblaze Inc. All Rights Reserved.
#
# License https://www.backblaze.com/using_b2_code.html
#
######################################################################
from __future__ import annotations

from collections import OrderedDict
from collections.abc import Callable, Hashable, Iterable, Iterator
from typing import Any


class RegistryKeyError(KeyError):
"""Raised when a registry lookup fails."""


class ClassRegistry:
"""Registry with decorator-based class registration and instantiation."""

def __init__(self, attr_name: str | None = None, unique: bool = False) -> None:
self.attr_name = attr_name
self.unique = unique
self._registry: OrderedDict[Hashable, type] = OrderedDict()

def __contains__(self, key: Hashable) -> bool:
try:
self.get_class(key)
except RegistryKeyError:
return False
return True

def __getitem__(self, key: Hashable) -> object:
return self.get(key)

def __iter__(self) -> Iterator[Hashable]:
return self.keys()

def __len__(self) -> int:
return len(self._registry)

def __repr__(self) -> str:
return f'{type(self).__name__}(attr_name={self.attr_name!r}, unique={self.unique!r})'

def __setitem__(self, key: Hashable, class_: type) -> None:
self._register(key, class_)

def __delitem__(self, key: Hashable) -> None:
self._unregister(key)

def __missing__(self, key: Hashable) -> object:
raise RegistryKeyError(key)

@staticmethod
def create_instance(class_: type, *args: Any, **kwargs: Any) -> object:
return class_(*args, **kwargs)

def get_class(self, key: Hashable) -> type:
try:
return self._registry[key]
except KeyError:
return self.__missing__(key)

def get(self, key: Hashable, *args: Any, **kwargs: Any) -> object:
return self.create_instance(self.get_class(key), *args, **kwargs)

def items(self) -> Iterable[tuple[Hashable, type]]:
return self._registry.items()

def keys(self) -> Iterable[Hashable]:
return self._registry.keys()

def values(self) -> Iterable[type]:
return self._registry.values()

def register(self, key: Hashable | type) -> Callable[[type], type] | type:
if isinstance(key, type):
if not self.attr_name:
raise ValueError(
f'Attempting to register {key.__name__} via decorator, but attr_name is not set.'
)
attr_key = getattr(key, self.attr_name)
self._register(attr_key, key)
return key

def _decorator(cls: type) -> type:
self._register(key, cls)
return cls

return _decorator

def unregister(self, key: Hashable) -> type:
return self._unregister(key)

def _register(self, key: Hashable, class_: type) -> None:
if key in ['', None]:
raise ValueError(
f'Attempting to register class {class_.__name__} with empty registry key {key!r}.'
)
if self.unique and key in self._registry:
raise RegistryKeyError(f'{class_.__name__} with key {key!r} is already registered.')
self._registry[key] = class_

def _unregister(self, key: Hashable) -> type:
return self._registry.pop(key) if key in self._registry else self.__missing__(key)
2 changes: 1 addition & 1 deletion b2/_internal/console_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@
UnableToCreateDirectory,
)
from b2sdk.version import VERSION as b2sdk_version
from class_registry import ClassRegistry
from tabulate import tabulate

from b2._internal._cli.arg_parser_types import (
Expand Down Expand Up @@ -163,6 +162,7 @@
from b2._internal._cli.shell import detect_shell, resolve_short_call_name
from b2._internal._utils.uri import B2URI, B2FileIdURI, B2URIAdapter, B2URIBase
from b2._internal.arg_parser import B2ArgumentParser, add_normalized_argument
from b2._internal.class_registry import ClassRegistry
from b2._internal.json_encoder import B2CliJsonEncoder
from b2._internal.version import VERSION

Expand Down
1 change: 1 addition & 0 deletions changelog.d/1081.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Replace the `phx-class-registry` dependency with a simple in-house implementation.
Loading
Loading