mirror of
				https://github.com/searxng/searxng.git
				synced 2025-11-04 03:27:06 -05:00 
			
		
		
		
	cache_property has been added in py3.8 [1] To support cache_property in py3.7 the implementation from 3.8 has been copied to compat.py. This code can be cleanup with EOL of py3.7. [1] https://docs.python.org/3/library/functools.html#functools.cached_property Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
		
			
				
	
	
		
			71 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			71 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# SPDX-License-Identifier: AGPL-3.0-or-later
 | 
						|
# lint: pylint
 | 
						|
# pyright: basic
 | 
						|
"""Module for backward compatibility.
 | 
						|
 | 
						|
"""
 | 
						|
# pylint: disable=C,R
 | 
						|
 | 
						|
 | 
						|
try:
 | 
						|
    from functools import cached_property  # pylint: disable=unused-import
 | 
						|
 | 
						|
except ImportError:
 | 
						|
 | 
						|
    # cache_property has been added in py3.8 [1]
 | 
						|
    #
 | 
						|
    # To support cache_property in py3.7 the implementation from 3.8 has been
 | 
						|
    # copied here.  This code can be cleanup with EOL of py3.7.
 | 
						|
    #
 | 
						|
    # [1] https://docs.python.org/3/library/functools.html#functools.cached_property
 | 
						|
 | 
						|
    from threading import RLock
 | 
						|
 | 
						|
    _NOT_FOUND = object()
 | 
						|
 | 
						|
    class cached_property:
 | 
						|
        def __init__(self, func):
 | 
						|
            self.func = func
 | 
						|
            self.attrname = None
 | 
						|
            self.__doc__ = func.__doc__
 | 
						|
            self.lock = RLock()
 | 
						|
 | 
						|
        def __set_name__(self, owner, name):
 | 
						|
            if self.attrname is None:
 | 
						|
                self.attrname = name
 | 
						|
            elif name != self.attrname:
 | 
						|
                raise TypeError(
 | 
						|
                    "Cannot assign the same cached_property to two different names "
 | 
						|
                    f"({self.attrname!r} and {name!r})."
 | 
						|
                )
 | 
						|
 | 
						|
        def __get__(self, instance, owner=None):
 | 
						|
            if instance is None:
 | 
						|
                return self
 | 
						|
            if self.attrname is None:
 | 
						|
                raise TypeError("Cannot use cached_property instance without calling __set_name__ on it.")
 | 
						|
            try:
 | 
						|
                cache = instance.__dict__
 | 
						|
            except AttributeError:  # not all objects have __dict__ (e.g. class defines slots)
 | 
						|
                msg = (
 | 
						|
                    f"No '__dict__' attribute on {type(instance).__name__!r} "
 | 
						|
                    f"instance to cache {self.attrname!r} property."
 | 
						|
                )
 | 
						|
                raise TypeError(msg) from None
 | 
						|
            val = cache.get(self.attrname, _NOT_FOUND)
 | 
						|
            if val is _NOT_FOUND:
 | 
						|
                with self.lock:
 | 
						|
                    # check if another thread filled cache while we awaited lock
 | 
						|
                    val = cache.get(self.attrname, _NOT_FOUND)
 | 
						|
                    if val is _NOT_FOUND:
 | 
						|
                        val = self.func(instance)
 | 
						|
                        try:
 | 
						|
                            cache[self.attrname] = val
 | 
						|
                        except TypeError:
 | 
						|
                            msg = (
 | 
						|
                                f"The '__dict__' attribute on {type(instance).__name__!r} instance "
 | 
						|
                                f"does not support item assignment for caching {self.attrname!r} property."
 | 
						|
                            )
 | 
						|
                            raise TypeError(msg) from None
 | 
						|
            return val
 |