Skip to content

Misc

profile(path, sortby=SortKey.CUMULATIVE)

Decorator to create a .prof file storing various metrics about execution

The .prof file can be read with snakeviz in cmd : snakeviz my_profile.dmp But it'll be loaded at the end of the script execution.

Parameters:

Name Type Description Default
path typing.Union[str, pathlib.Path]

Path of the output .prof file

required
sortby pstats.SortKey

Mode for sorting data, defaults to SortKey.CUMULATIVE See : https://docs.python.org/3/library/profile.html#module-pstats

pstats.SortKey.CUMULATIVE
Source code in pyqgis_wrapper/utils/misc.py
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
def profile(path: Union[str, Path], sortby: SortKey = SortKey.CUMULATIVE):
    """
    Decorator to create a .prof file storing various metrics about execution

    The .prof file can be read with snakeviz in cmd : snakeviz my_profile.dmp
    But it'll be loaded at the end of the script execution.

    :param path: Path of the output .prof file
    :type path: Union[str, Path]
    :param sortby: Mode for sorting data, defaults to SortKey.CUMULATIVE
        See : https://docs.python.org/3/library/profile.html#module-pstats

    :type sortby: SortKey, optional
    """
    import snakeviz.cli as cli

    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            pr = cProfile.Profile()
            pr.enable()
            try:
                return func(*args, **kwargs)
            finally:
                p = Path(path)
                if p.suffix == "":
                    p = p.with_suffix(".prof")
                pr.disable()
                s = io.StringIO()
                ps = Stats(pr, stream=s).sort_stats(sortby)
                ps.print_stats()
                p.parent.mkdir(parents=True, exist_ok=True)
                ps.dump_stats(path)
                cli.main([path])

        return wrapper

    return decorator

find_module_path(start_path, parent_name, module='processing', extension='py')

Allows the search of a module by walking in the dir. It is slower than importlib but doesn't require the module to be in sys.path

It is still recomanded to narrow the search to avoid detecting the wrong module.

For processing module the path are commonly found in - Windows : start_path = r"C:\OSGeo4Wpps\qgis-ltr\python\plugins\processing" parent_name = "core" - Ubuntu : start_path = "/usr/share/qgis/python" parent_name = "plugins"

Parameters:

Name Type Description Default
start_path typing.Union[str, pathlib.Path]

Start path when we know approximately where the module is

required
parent_name str

Name of the module parent

required
module str

Name of the module

'processing'
extension str

Extension of the module. Default to python

'py'

Returns:

Type Description
Union[str, None]

Path or None if not found

Source code in pyqgis_wrapper/utils/misc.py
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
def find_module_path(
    start_path: Union[str, Path],
    parent_name: str,
    module: str = "processing",
    extension: str = "py",
) -> Union[str, None]:
    """
    Allows the search of a module by walking in the dir.
    It is slower than importlib but doesn't
    require the module to be in sys.path

    It is still recomanded to narrow the search to avoid detecting the wrong module.

    For processing module the path are commonly found in
    - Windows :
        start_path = r"C:\OSGeo4W\apps\qgis-ltr\python\plugins\processing"
        parent_name = "core"
    - Ubuntu :
        start_path = "/usr/share/qgis/python"
        parent_name = "plugins"

    :param start_path: Start path when we know approximately where the module is
    :type start_path:Union[str, Path]
    :param parent_name: Name of the module parent
    :type parent_name: str
    :param module: Name of the module
    :type module: str
    :param extension: Extension of the module. Default to python
    :type extension: str

    :return: Path or None if not found
    :rtype: Union[str, None]
    """
    module_dir = None

    if "." not in extension:
        extension = "." + extension

    if isinstance(start_path, str):
        start_path = Path(start_path)

    for root, dirs, files in start_path.walk():
        if parent_name in dirs or parent_name + extension in files:
            module_dir = str(root.joinpath(parent_name))
            sys.path.append(module_dir)
            try:
                importlib.import_module(module)
                return module_dir
            except ImportError:
                pass
            finally:
                if module_dir in sys.path:
                    sys.path.remove(module_dir)

    return module_dir