Skip to content

Commit 5cfd654

Browse files
committed
Initial attempt at lazy loading
1 parent ce05903 commit 5cfd654

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+393
-223
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,5 +112,5 @@ tbb = ">=2019.5"
112112
tests = "./test.sh"
113113
coverage = "./test.sh coverage"
114114
docs = "cd docs && ./setup.sh"
115-
black = 'black --exclude=".*\.ipynb" --extend-exclude=".venv|.pixi" --diff ./'
115+
black = 'black --exclude=".*\.ipynb" --extend-exclude=".venv|.pixi" ./'
116116
isort = 'isort --profile black --skip .venv --skip .pixi ./'

stumpy/__init__.py

Lines changed: 96 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,63 @@
11
import ast
2+
import importlib
23
import os.path
34
import pathlib
5+
import types
46
from importlib.metadata import distribution
57
from site import getsitepackages
68

79
from numba import cuda
810

911
from . import cache, config
10-
from .aamp import aamp # noqa: F401
11-
from .aamp_mmotifs import aamp_mmotifs # noqa: F401
12-
from .aamp_motifs import aamp_match, aamp_motifs # noqa: F401
13-
from .aamp_ostinato import aamp_ostinato, aamp_ostinatoed # noqa: F401
14-
from .aamp_stimp import aamp_stimp, aamp_stimped # noqa: F401
15-
from .aampdist import aampdist, aampdisted # noqa: F401
16-
from .aampdist_snippets import aampdist_snippets # noqa: F401
17-
from .aamped import aamped # noqa: F401
18-
from .aampi import aampi # noqa: F401
19-
from .chains import allc, atsc # noqa: F401
20-
from .core import mass # noqa: F401
21-
from .floss import floss, fluss # noqa: F401
22-
from .maamp import maamp, maamp_mdl, maamp_subspace # noqa: F401
23-
from .maamped import maamped # noqa: F401
24-
from .mmotifs import mmotifs # noqa: F401
25-
from .motifs import match, motifs # noqa: F401
26-
from .mpdist import mpdist, mpdisted # noqa: F401
27-
from .mstump import mdl, mstump, subspace # noqa: F401
28-
from .mstumped import mstumped # noqa: F401
29-
from .ostinato import ostinato, ostinatoed # noqa: F401
30-
from .scraamp import prescraamp, scraamp # noqa: F401
31-
from .scrump import prescrump, scrump # noqa: F401
32-
from .snippets import snippets # noqa: F401
33-
from .stimp import stimp, stimped # noqa: F401
34-
from .stump import stump # noqa: F401
35-
from .stumped import stumped # noqa: F401
36-
from .stumpi import stumpi # noqa: F401
12+
13+
# Define which functions belong to which submodules
14+
# Key: function name to expose at top level
15+
# Value: name of the submodule
16+
_lazy_imports = {
17+
"aamp": "aamp",
18+
"aamp_mmotifs": "aamp_mmotifs",
19+
"aamp_match": "aamp_motifs",
20+
"aamp_motifs": "aamp_motifs",
21+
"aamp_ostinato": "aamp_ostinato",
22+
"aamp_ostinatoed": "aamp_ostinato",
23+
"aamp_stimp": "aamp_stimp",
24+
"aamp_stimped": "aamp_stimp",
25+
"aampdist": "aampdist",
26+
"aampdisted": "aampdist",
27+
"aampdist_snippets": "aampdist_snippets",
28+
"aamped": "aamped",
29+
"aampi": "aampi",
30+
"allc": "chains",
31+
"atsc": "chains",
32+
"mass": "core",
33+
"floss": "floss",
34+
"fluss": "floss",
35+
"maamp": "maamp",
36+
"maamp_mdl": "maamp",
37+
"maamp_subspace": "maamp",
38+
"maamped": "maamped",
39+
"mmotifs": "mmotifs",
40+
"match": "motifs",
41+
"motifs": "motifs",
42+
"mpdist": "mpdist",
43+
"mpdisted": "mpdist",
44+
"mdl": "mstump",
45+
"mstump": "mstump",
46+
"subspace": "mstump",
47+
"mstumped": "mstumped",
48+
"ostinato": "ostinato",
49+
"ostinatoed": "ostinato",
50+
"prescraamp": "scraamp",
51+
"scraamp": "scraamp",
52+
"prescrump": "scrump",
53+
"scrump": "scrump",
54+
"snippets": "snippets",
55+
"stimp": "stimp",
56+
"stimped": "stimp",
57+
"stump": "stump",
58+
"stumped": "stumped",
59+
"stumpi": "stumpi",
60+
}
3761

3862
# Get the default fastmath flags for all njit functions
3963
# and update the _STUMPY_DEFAULTS dictionary
@@ -61,14 +85,18 @@ def _get_fastmath_value(module_name, func_name): # pragma: no cover
6185
config._STUMPY_DEFAULTS[key] = _get_fastmath_value(module_name, func_name)
6286

6387
if cuda.is_available():
64-
from .gpu_aamp import gpu_aamp # noqa: F401
65-
from .gpu_aamp_ostinato import gpu_aamp_ostinato # noqa: F401
66-
from .gpu_aamp_stimp import gpu_aamp_stimp # noqa: F401
67-
from .gpu_aampdist import gpu_aampdist # noqa: F401
68-
from .gpu_mpdist import gpu_mpdist # noqa: F401
69-
from .gpu_ostinato import gpu_ostinato # noqa: F401
70-
from .gpu_stimp import gpu_stimp # noqa: F401
71-
from .gpu_stump import gpu_stump # noqa: F401
88+
_lazy_imports.update(
89+
{
90+
"gpu_aamp": "gpu_aamp",
91+
"gpu_aamp_ostinato": "gpu_aamp_ostinato",
92+
"gpu_aamp_stimp": "gpu_aamp_stimp",
93+
"gpu_aampdist": "gpu_aampdist",
94+
"gpu_mpdist": "gpu_mpdist",
95+
"gpu_ostinato": "gpu_ostinato",
96+
"gpu_stimp": "gpu_stimp",
97+
"gpu_stump": "gpu_stump",
98+
}
99+
)
72100
else: # pragma: no cover
73101
from . import core
74102
from .core import _gpu_aamp_driver_not_found as gpu_aamp # noqa: F401
@@ -220,3 +248,36 @@ def _get_fastmath_value(module_name, func_name): # pragma: no cover
220248
__version__ = "Please install this project with setup.py"
221249
else: # pragma: no cover
222250
__version__ = _dist.version
251+
252+
253+
# PEP 562: module-level __getattr__ for lazy imports
254+
def __getattr__(name): # pragma: no cover
255+
if name in _lazy_imports:
256+
submodule_name = _lazy_imports[name]
257+
full_module_path = f"{__package__}.{submodule_name}"
258+
module = importlib.import_module(full_module_path)
259+
# Retrieve the attribute from the loaded submodule and cache it
260+
attr = getattr(module, name)
261+
globals()[name] = attr
262+
return attr
263+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
264+
265+
266+
# Ensure that if a submodule was imported during package import
267+
# (causing the package attribute to point to the submodule object), we
268+
# replace that entry with the actual attribute (e.g., function) so that
269+
# users get the expected callable at `stumpy.aamp` rather than the module.
270+
for _name, _sub in _lazy_imports.items(): # pragma: no cover
271+
val = globals().get(_name)
272+
if isinstance(val, types.ModuleType):
273+
try:
274+
replacement = getattr(val, _name)
275+
except AttributeError:
276+
# Nothing to do if the submodule doesn't define the attribute
277+
continue
278+
globals()[_name] = replacement
279+
280+
281+
def __dir__(): # pragma: no cover
282+
# Expose lazy names in dir() for discoverability
283+
return sorted(list(globals().keys()) + list(_lazy_imports.keys()))

stumpy/gpu_aamp_ostinato.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
# Copyright 2019 TD Ameritrade. Released under the terms of the 3-Clause BSD license.
33
# STUMPY is a trademark of TD Ameritrade IP Company, Inc. All rights reserved.
44

5-
from . import core, gpu_aamp
5+
from . import core
66
from .aamp_ostinato import _aamp_ostinato, _get_aamp_central_motif
7+
from .gpu_aamp import gpu_aamp
78

89

910
def gpu_aamp_ostinato(Ts, m, device_id=0, p=2.0):

stumpy/gpu_aamp_stimp.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
# Copyright 2019 TD Ameritrade. Released under the terms of the 3-Clause BSD license.
33
# STUMPY is a trademark of TD Ameritrade IP Company, Inc. All rights reserved.
44

5-
from . import gpu_aamp
65
from .aamp_stimp import _aamp_stimp
6+
from .gpu_aamp import gpu_aamp
77

88

99
class gpu_aamp_stimp(_aamp_stimp):

stumpy/gpu_aampdist.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
import functools
66

7-
from . import gpu_aamp
87
from .core import _mpdist
8+
from .gpu_aamp import gpu_aamp
99

1010

1111
def gpu_aampdist(T_A, T_B, m, percentage=0.05, k=None, device_id=0, p=2.0):

stumpy/stimp.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44

55
import numpy as np
66

7-
from . import core, scrump
7+
from . import core
88
from .aamp_stimp import aamp_stimp, aamp_stimped
9+
from .scrump import scrump
910
from .stump import stump
1011
from .stumped import stumped
1112

stumpy/stomp.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
import numpy as np
88

9-
from . import config, core, stamp
9+
from . import config, core
10+
from .stamp import _mass_PI
1011

1112

1213
def _stomp(T_A, m, T_B=None, ignore_trivial=True):
@@ -105,7 +106,7 @@ def _stomp(T_A, m, T_B=None, ignore_trivial=True):
105106
IR = -1
106107
else:
107108
if ignore_trivial:
108-
P, I = stamp._mass_PI(
109+
P, I = _mass_PI(
109110
T_A[:m],
110111
T_B,
111112
M_T,
@@ -115,7 +116,7 @@ def _stomp(T_A, m, T_B=None, ignore_trivial=True):
115116
T_subseq_isconstant=T_subseq_isconstant,
116117
Q_subseq_isconstant=Q_subseq_isconstant[[0]],
117118
)
118-
PR, IR = stamp._mass_PI(
119+
PR, IR = _mass_PI(
119120
T_A[:m],
120121
T_B,
121122
M_T,
@@ -127,7 +128,7 @@ def _stomp(T_A, m, T_B=None, ignore_trivial=True):
127128
Q_subseq_isconstant=Q_subseq_isconstant[[0]],
128129
)
129130
else:
130-
P, I = stamp._mass_PI(
131+
P, I = _mass_PI(
131132
T_A[:m],
132133
T_B,
133134
M_T,

stumpy/stumpi.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44

55
import numpy as np
66

7-
from . import config, core, stump
7+
from . import config, core
88
from .aampi import aampi
9+
from .stump import stump
910

1011

1112
@core.non_normalized(

tests/test_aamp.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
import pandas as pd
55
import pytest
66

7-
from stumpy import aamp, config
7+
from stumpy import config
8+
from stumpy.aamp import aamp
89

910
test_data = [
1011
(

tests/test_aamp_mmotifs.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
import numpy.testing as npt
44
import pytest
55

6-
from stumpy import aamp_mmotifs, config
6+
from stumpy import config
7+
from stumpy.aamp_mmotifs import aamp_mmotifs
78

89
test_data = [
910
np.array(

0 commit comments

Comments
 (0)