11"""
22Base finders
33"""
4+ import functools
45from collections import namedtuple
56from pathlib import Path
67
78from demosys .conf import settings
89from demosys .core .exceptions import ImproperlyConfigured
10+ from demosys .utils .module_loading import import_string
911
1012FinderEntry = namedtuple ('FinderEntry' , ['path' , 'abspath' , 'exists' ])
1113
@@ -17,11 +19,10 @@ class BaseFileSystemFinder:
1719 def __init__ (self ):
1820 if not hasattr (settings , self .settings_attr ):
1921 raise ImproperlyConfigured (
20- "Settings module don't define TEXTURE_DIRS ."
21- "This is required when using a FileSystemFinder."
22+ "Settings module don't define {} ."
23+ "This is required when using a FileSystemFinder." . format ( self . settings_attr )
2224 )
2325 self .paths = getattr (settings , self .settings_attr )
24- self ._cached_paths = {}
2526
2627 def find (self , path : Path ):
2728 """
@@ -31,6 +32,11 @@ def find(self, path: Path):
3132 :param path: The path to find
3233 :return: The absolute path to the file or None if not found
3334 """
35+ # Update paths from settings to make them editable runtime
36+ # This is only possible for FileSystemFinders
37+ if getattr (self , 'settings_attr' , None ):
38+ self .paths = getattr (settings , self .settings_attr )
39+
3440 path_found = None
3541
3642 for entry in self .paths :
@@ -46,9 +52,29 @@ class BaseEffectDirectoriesFinder(BaseFileSystemFinder):
4652 directory = None
4753
4854 def __init__ (self ):
49- from demosys .effects .registry import effects
50- self .paths = list (effects .get_dirs ())
55+ pass
5156
5257 def find (self , path : Path ):
5358 path = Path (self .directory ) / Path (path )
5459 return super ().find (path )
60+
61+ @property
62+ def paths (self ):
63+ from demosys .effects .registry import effects
64+ return list (effects .get_dirs ())
65+
66+
67+ @functools .lru_cache (maxsize = None )
68+ def get_finder (import_path ):
69+ """
70+ Get a finder class from an import path.
71+ Raises ``demosys.core.exceptions.ImproperlyConfigured`` if the finder is not found.
72+ This function uses an lru cache.
73+
74+ :param import_path: string representing an import path
75+ :return: An instance of the finder
76+ """
77+ Finder = import_string (import_path )
78+ if not issubclass (Finder , BaseFileSystemFinder ):
79+ raise ImproperlyConfigured ('Finder {} is not a subclass of core.finders.FileSystemFinder' .format (import_path ))
80+ return Finder ()
0 commit comments