Coverage for oc_ocdm / decorators.py: 94%

16 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-03-28 18:52 +0000

1#!/usr/bin/python 

2 

3# SPDX-FileCopyrightText: 2020-2022 Simone Persiani <iosonopersia@gmail.com> 

4# SPDX-FileCopyrightText: 2024-2026 Arcangelo Massari <arcangelo.massari@unibo.it> 

5# 

6# SPDX-License-Identifier: ISC 

7 

8# -*- coding: utf-8 -*- 

9from __future__ import annotations 

10 

11from functools import wraps 

12from typing import TYPE_CHECKING, TypeVar, cast 

13 

14from oc_ocdm.abstract_entity import AbstractEntity 

15 

16if TYPE_CHECKING: 

17 from typing import Callable 

18from rdflib import URIRef 

19 

20F = TypeVar('F', bound='Callable[..., object]') 

21 

22 

23def accepts_only(param_type: str) -> Callable[[F], F]: 

24 """ 

25 A decorator that can be applied to the entity methods such as setters and removers 

26 when they accept a parameter. It enforces the right parameter type by raising a 

27 ``TypeError`` when the parameter is not None but its type is not the expected one. 

28 

29 The expected type can be expressed through a short string: 

30 

31 * 'literal' for the ``str`` type; 

32 * 'thing' for the ``URIRef`` type (from ``rdflib``); 

33 * '_dataset_' for the ``Dataset`` entities; 

34 * the OCDM short name in case of any other entity (e.g. 'br' for ``BibliographicResource``). 

35 

36 :param param_type: A short string representing the expected type 

37 :type param_type: str 

38 """ 

39 def accepts_only_decorator(function: F) -> F: 

40 

41 @wraps(function) 

42 def accepts_only_wrapper(self: object, param: object = None, **kwargs: object) -> object: 

43 lowercase_type = param_type.lower() 

44 if param is None or \ 

45 (lowercase_type == 'literal' and isinstance(param, str)) or \ 

46 (lowercase_type == 'thing' and isinstance(param, URIRef)) or \ 

47 (isinstance(param, AbstractEntity) and param.short_name == lowercase_type): 

48 return function(self, param, **kwargs) 

49 else: 

50 raise TypeError('[%s.%s] Expected argument type: %s. Provided argument type: %s.' % 

51 (self.__class__.__name__, function.__name__, lowercase_type, type(param).__name__)) 

52 

53 return cast(F, accepts_only_wrapper) 

54 return accepts_only_decorator