Coverage for oc_ocdm/decorators.py: 88%

17 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2025-05-30 22:05 +0000

1#!/usr/bin/python 

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

3# Copyright (c) 2016, Silvio Peroni <essepuntato@gmail.com> 

4# 

5# Permission to use, copy, modify, and/or distribute this software for any purpose 

6# with or without fee is hereby granted, provided that the above copyright notice 

7# and this permission notice appear in all copies. 

8# 

9# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 

10# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 

11# FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, 

12# OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 

13# DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 

14# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 

15# SOFTWARE. 

16from __future__ import annotations 

17 

18from functools import wraps 

19from typing import TYPE_CHECKING 

20 

21from oc_ocdm.abstract_entity import AbstractEntity 

22 

23if TYPE_CHECKING: 

24 from typing import Callable, Any 

25from rdflib import URIRef 

26 

27 

28def accepts_only(param_type: str): 

29 """ 

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

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

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

33 

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

35 

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

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

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

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

40 

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

42 :type param_type: str 

43 """ 

44 def accepts_only_decorator(function: Callable): 

45 

46 @wraps(function) 

47 def accepts_only_wrapper(self, param: Any = None, **kwargs): 

48 lowercase_type = param_type.lower() 

49 if param is None or \ 

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

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

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

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

54 else: 

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

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

57 

58 return accepts_only_wrapper 

59 return accepts_only_decorator