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
« 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
18from functools import wraps
19from typing import TYPE_CHECKING
21from oc_ocdm.abstract_entity import AbstractEntity
23if TYPE_CHECKING:
24 from typing import Callable, Any
25from rdflib import URIRef
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.
34 The expected type can be expressed through a short string:
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``).
41 :param param_type: A short string representing the expected type
42 :type param_type: str
43 """
44 def accepts_only_decorator(function: Callable):
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__))
58 return accepts_only_wrapper
59 return accepts_only_decorator