forked from stanfordnlp/dspy
-
Notifications
You must be signed in to change notification settings - Fork 0
feat: make numpy an optional dependency #34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
isaacbmiller
wants to merge
17
commits into
main
Choose a base branch
from
isaac/numpy-opt
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 12 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
c6fb042
feat: make numpy an optional dependency
isaacbmiller 40d5c92
Update dspy/teleprompt/utils.py
isaacbmiller 1c8a95b
fix(ci): add numpy to dev and test_extras
isaacbmiller 787a37c
refactor: move _numpy helper under dspy/utils/
isaacbmiller 1b10976
refactor: generalize numpy helper into require_optional
isaacbmiller e3e7183
refactor: replace gratuitous numpy with stdlib math in mipro/infer_rules
isaacbmiller 0224c48
fix(_optional): only suggest dspy[extra] when caller asserts it exists
isaacbmiller 23e0b7a
refactor(_optional): centralize dspy-extras registry, drop per-call e…
isaacbmiller b078a23
refactor: replace _optional with lazy_import, stdlib math in teleprom…
isaacbmiller 39a8f84
refactor: replace np.log2 with math.log2 in gepa auto_budget
isaacbmiller 5bd8647
fix: skip tomllib test on Python < 3.11
isaacbmiller b7fc979
refactor: replace numpy.std with statistics.pstdev in copro_optimizer
isaacbmiller 1b3224c
refactor: vendor lazy_loader pattern into require() with _MissingModu…
isaacbmiller ccee0e3
docs: add numpy install notes to API pages and tutorials
isaacbmiller 330361d
refactor: detect dspy/dspy-ai dist for install hints, move math impor…
isaacbmiller efecfc9
test(lazy_import): tighten brittle lazy_import tests
isaacbmiller ddc1ac3
docs(lazy_import): switch RST double backticks to mkdocs single backt…
isaacbmiller File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| """Lazy-import helpers for optional dependencies. | ||
|
|
||
| Dspy ships in two flavors with different hard-dependency sets (`dspy` and | ||
| `dspy-runtime`). Optional deps must be importable lazily so that `import dspy` | ||
| succeeds even when they are absent, and call sites must raise a clear, | ||
| actionable ImportError when the dep really is needed. | ||
| """ | ||
|
|
||
| import functools | ||
| import importlib | ||
| import importlib.util | ||
| from typing import Any | ||
|
|
||
| _INSTALL_HINTS: dict[str, str] = { | ||
| "optuna": "optuna", | ||
| "mcp": "mcp", | ||
| "langchain_core": "langchain", | ||
| "weaviate": "weaviate", | ||
| "anthropic": "anthropic", | ||
| "numpy": "numpy", | ||
| } | ||
|
|
||
|
|
||
| @functools.cache | ||
| def is_available(module: str) -> bool: | ||
| """Return True if ``module`` can be imported, without importing it. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. single back-tick is preferred in our settings of mkdocs. |
||
|
|
||
| Uses ``importlib.util.find_spec`` so calling this does not execute the | ||
| module's top-level code. Safe for cheap branching ("if the optional dep | ||
| is installed, register the hook; otherwise skip"). | ||
| """ | ||
| try: | ||
| return importlib.util.find_spec(module) is not None | ||
| except (ImportError, ValueError): | ||
| return False | ||
|
|
||
|
|
||
| def require(module: str, *, extra: str | None = None, feature: str | None = None) -> Any: | ||
| """Import a module by dotted path; raise a friendly ImportError if missing. | ||
|
isaacbmiller marked this conversation as resolved.
Outdated
|
||
|
|
||
| Use at call sites where an optional dependency is needed to perform an action. | ||
|
|
||
| Args: | ||
| module: Dotted module path (e.g. ``"litellm"`` or ``"gepa.core.adapter"``). | ||
| The top-level segment is shown to the user. | ||
| extra: Name of the dspy extra that pulls in this dep. Defaults to the | ||
| entry in ``_INSTALL_HINTS`` for the top-level module, falling back | ||
| to the top-level module name. | ||
| feature: Short feature label included in the error (e.g. ``"dspy.LM"``). | ||
| Defaults to ``"this feature"``. | ||
|
|
||
| Returns: | ||
| The imported module. | ||
| """ | ||
| try: | ||
| return importlib.import_module(module) | ||
| except ImportError as e: | ||
| top = module.split(".", 1)[0] | ||
| feat = feature or "this feature" | ||
| ext = extra or _INSTALL_HINTS.get(top, top) | ||
| raise ImportError( | ||
| f"{top} is required to use {feat}. " | ||
| f"Install with `pip install dspy[{ext}]` or `pip install {top}`." | ||
|
isaacbmiller marked this conversation as resolved.
Outdated
|
||
| ) from e | ||
|
|
||
|
|
||
| def optional(module: str, attr: str | None = None, default: Any = None) -> Any: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. optional is not used, can we wait that it's needed before making this util? |
||
| """Try to import a module (and optionally one attribute). Return ``default`` if missing. | ||
|
|
||
| Use at module load time when a class needs to inherit from a base provided by | ||
| an optional dep: returning a sentinel (typically ``object``) lets the class be | ||
| defined even when the dep is absent. Gate actual use behind ``require()``. | ||
| """ | ||
| try: | ||
| mod = importlib.import_module(module) | ||
| except ImportError: | ||
| return default | ||
| if attr is None: | ||
| return mod | ||
| return getattr(mod, attr, default) | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.