Skip to content

Commit

Permalink
tests
Browse files Browse the repository at this point in the history
  • Loading branch information
amyasnikov committed Sep 23, 2024
1 parent 916237a commit 5f294da
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 11 deletions.
16 changes: 15 additions & 1 deletion validity/tests/test_utils/test_misc.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import operator
from contextlib import nullcontext
from dataclasses import dataclass

import pytest

from validity.utils.misc import reraise
from validity.utils.misc import partialcls, reraise
from validity.utils.version import NetboxVersion


Expand Down Expand Up @@ -64,3 +65,16 @@ def test_netbox_version(obj1, obj2, compare_results):
operators = [operator.lt, operator.le, operator.eq, operator.ge, operator.gt]
for op, expected_result in zip(operators, compare_results):
assert op(obj1, obj2) is expected_result


def test_partialcls():
@dataclass
class A:
a: int
b: int

A2 = partialcls(A, b=10)
assert A2(5) == A(5, 10)
assert A2(1, 2) == A(1, 2)
assert A2(a=3, b=4) == A(3, 4)
assert type(A2(1, 2)) is A
21 changes: 11 additions & 10 deletions validity/utils/misc.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import inspect
from concurrent.futures import ThreadPoolExecutor
from contextlib import contextmanager, suppress
from functools import partialmethod
from itertools import islice
from typing import TYPE_CHECKING, Any, Callable, Iterable, TypeVar
from typing import TYPE_CHECKING, Any, Callable, Iterable

from core.exceptions import SyncError
from django.db.models import Q
Expand Down Expand Up @@ -87,13 +86,15 @@ def batched(iterable: Iterable, n: int, container: type = list):
yield batch


_T = TypeVar("_T", bound=type)


def partialcls(cls: _T, *args, class_name: str | None = None, **kwargs) -> _T:
def partialcls(cls, *args, **kwargs):
"""
Creates subclass of a given class with partially filled __init__ params
Returns partial class with args and kwargs applied to __init__.
All original class attributes are preserved. When called, returns original class instance
"""
class_name = class_name or cls.__name__
class_attributes = {"__init__": partialmethod(cls.__init__, *args, **kwargs)}
return type(cls.__name__, (cls,), class_attributes)

def __new__(_, *new_args, **new_kwargs):
new_args = args + new_args
new_kwargs = kwargs | new_kwargs
return cls(*new_args, **new_kwargs)

return type(cls.__name__, (cls,), {"__new__": __new__})

0 comments on commit 5f294da

Please sign in to comment.