From cce7a1ae3a8e3c8a235cd10628a05a1f767e42ed Mon Sep 17 00:00:00 2001 From: Michael Waskom Date: Wed, 20 Nov 2024 17:35:06 -0500 Subject: [PATCH] Remove a few references to 'Stub' (#2542) * Remove a few references to 'Stub' * Remove auto-import of objects named `stub` * Update CLI tests / no longer test for `stub` imports * Fix an errant docs crosslink to Stub * Remove another test for old magical stub behavior * Simplify and fix typo --- modal/app.py | 6 +-- modal/cli/import_refs.py | 42 ++----------------- modal/functions.py | 3 +- modal/gpu.py | 2 +- test/cli_test.py | 18 -------- test/supports/app_run_tests/app_and_stub.py | 13 ------ .../app_run_tests/app_was_once_stub.py | 2 - .../app_run_tests/app_was_once_stub_2.py | 11 ----- 8 files changed, 9 insertions(+), 88 deletions(-) delete mode 100644 test/supports/app_run_tests/app_and_stub.py delete mode 100644 test/supports/app_run_tests/app_was_once_stub_2.py diff --git a/modal/app.py b/modal/app.py index 125540510..5e1aecf2f 100644 --- a/modal/app.py +++ b/modal/app.py @@ -158,8 +158,7 @@ def f(x, y): class _App: - """A Modal app (prior to April 2024 a "stub") is a group of functions and classes - deployed together. + """A Modal App is a group of functions and classes that are deployed together. The app serves at least three purposes: @@ -1083,7 +1082,8 @@ def _reset_container_app(cls): class _Stub(_App): - """This enables using an "Stub" class instead of "App". + """mdmd:hidden + This enables using a "Stub" class instead of "App". For most of Modal's history, the app class was called "Stub", so this exists for backwards compatibility, in order to facilitate moving from "Stub" to "App". diff --git a/modal/cli/import_refs.py b/modal/cli/import_refs.py index 05f92fbaf..a34cbbb76 100644 --- a/modal/cli/import_refs.py +++ b/modal/cli/import_refs.py @@ -19,7 +19,7 @@ from rich.markdown import Markdown from modal.app import App, LocalEntrypoint -from modal.exception import InvalidError, _CliUserExecutionError, deprecation_warning +from modal.exception import InvalidError, _CliUserExecutionError from modal.functions import Function @@ -79,7 +79,7 @@ def import_file_or_module(file_or_module: str): return module -def get_by_object_path(obj: Any, obj_path: Optional[str]) -> Optional[Any]: +def get_by_object_path(obj: Any, obj_path: str) -> Optional[Any]: # Try to evaluate a `.`-delimited object path in a Modal context # With the caveat that some object names can actually have `.` in their name (lifecycled methods' tags) @@ -107,35 +107,6 @@ def get_by_object_path(obj: Any, obj_path: Optional[str]) -> Optional[Any]: return obj -def get_by_object_path_try_possible_app_names(obj: Any, obj_path: Optional[str]) -> Optional[Any]: - """This just exists as a dumb workaround to support both "stub" and "app" """ - - if obj_path: - return get_by_object_path(obj, obj_path) - else: - app = get_by_object_path(obj, DEFAULT_APP_NAME) - stub = get_by_object_path(obj, "stub") - if isinstance(app, App): - return app - elif app is not None and isinstance(stub, App): - deprecation_warning( - (2024, 4, 20), - "The symbol `app` is present at the module level but it's not a Modal app." - " We will use `stub` instead, but this will not work in future Modal versions." - " Suggestion: change the name of `app` to something else.", - ) - return stub - elif isinstance(stub, App): - deprecation_warning( - (2024, 5, 1), - "The symbol `app` is not present but `stub` is. This will not work in future" - " Modal versions. Suggestion: change the name of `stub` to `app`.", - ) - return stub - else: - return None - - def _infer_function_or_help( app: App, module, accept_local_entrypoint: bool, accept_webhook: bool ) -> Union[Function, LocalEntrypoint]: @@ -210,7 +181,7 @@ def import_app(app_ref: str) -> App: import_ref = parse_import_ref(app_ref) module = import_file_or_module(import_ref.file_or_module) - app = get_by_object_path_try_possible_app_names(module, import_ref.object_path) + app = get_by_object_path(module, import_ref.object_path or DEFAULT_APP_NAME) if app is None: _show_no_auto_detectable_app(import_ref) @@ -258,7 +229,7 @@ def import_function( import_ref = parse_import_ref(func_ref) module = import_file_or_module(import_ref.file_or_module) - app_or_function = get_by_object_path_try_possible_app_names(module, import_ref.object_path) + app_or_function = get_by_object_path(module, import_ref.object_path or DEFAULT_APP_NAME) if app_or_function is None: _show_function_ref_help(import_ref, base_cmd) @@ -279,8 +250,3 @@ def import_function( return app_or_function else: raise click.UsageError(f"{app_or_function} is not a Modal entity (should be an App or Function)") - - -# For backwards compatibility - delete soon -# We use it in our internal intergration tests -import_stub = import_app diff --git a/modal/functions.py b/modal/functions.py index 36b5d7e99..4a57845d1 100644 --- a/modal/functions.py +++ b/modal/functions.py @@ -299,8 +299,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type """Functions are the basic units of serverless execution on Modal. Generally, you will not construct a `Function` directly. Instead, use the - `@app.function()` decorator on the `App` object (formerly called "Stub") - for your application. + `App.function()` decorator to register your Python functions with your App. """ # TODO: more type annotations diff --git a/modal/gpu.py b/modal/gpu.py index bda8abc31..31ebbf6fc 100644 --- a/modal/gpu.py +++ b/modal/gpu.py @@ -161,7 +161,7 @@ def __repr__(self): **GPU configuration shortcodes** The following are the valid `str` values for the `gpu` parameter of -[`@app.function`](/docs/reference/modal.Stub#function). +[`@app.function`](/docs/reference/modal.App#function). {display_string_to_config} diff --git a/test/cli_test.py b/test/cli_test.py index 3a0f632e5..bcee8f83a 100644 --- a/test/cli_test.py +++ b/test/cli_test.py @@ -140,28 +140,10 @@ def test_run(servicer, set_env_client, test_dir): def test_run_stub(servicer, set_env_client, test_dir): app_file = test_dir / "supports" / "app_run_tests" / "app_was_once_stub.py" - with pytest.warns(match="App"): - _run(["run", app_file.as_posix()]) with pytest.warns(match="App"): _run(["run", app_file.as_posix() + "::foo"]) -def test_run_stub_2(servicer, set_env_client, test_dir): - app_file = test_dir / "supports" / "app_run_tests" / "app_was_once_stub_2.py" - with pytest.warns(match="`app`"): - _run(["run", app_file.as_posix()]) - _run(["run", app_file.as_posix() + "::stub"]) - _run(["run", app_file.as_posix() + "::foo"]) - - -def test_run_stub_with_app(servicer, set_env_client, test_dir): - app_file = test_dir / "supports" / "app_run_tests" / "app_and_stub.py" - with pytest.warns(match="`app`"): - _run(["run", app_file.as_posix()]) - _run(["run", app_file.as_posix() + "::stub"]) - _run(["run", app_file.as_posix() + "::foo"]) - - def test_run_async(servicer, set_env_client, test_dir): sync_fn = test_dir / "supports" / "app_run_tests" / "local_entrypoint.py" res = _run(["run", sync_fn.as_posix()]) diff --git a/test/supports/app_run_tests/app_and_stub.py b/test/supports/app_run_tests/app_and_stub.py deleted file mode 100644 index 0accde6bc..000000000 --- a/test/supports/app_run_tests/app_and_stub.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright Modal Labs 2024 -import modal - -# If both `app` and `stub` is present, we want Modal to fall back to `stub`, -# rather than complaining about the type of `app` -app = 123 - -stub = modal.App() - - -@stub.function() -def foo(): - print("foo") diff --git a/test/supports/app_run_tests/app_was_once_stub.py b/test/supports/app_run_tests/app_was_once_stub.py index 65662d6e7..7bcf477d3 100644 --- a/test/supports/app_run_tests/app_was_once_stub.py +++ b/test/supports/app_run_tests/app_was_once_stub.py @@ -1,8 +1,6 @@ # Copyright Modal Labs 2024 import modal -# Trigger the deprecation warning for the class itself, -# but not the symbol name (see app_was_once_stub_2 for the opposite) app = modal.Stub() diff --git a/test/supports/app_run_tests/app_was_once_stub_2.py b/test/supports/app_run_tests/app_was_once_stub_2.py deleted file mode 100644 index 2501cdf5d..000000000 --- a/test/supports/app_run_tests/app_was_once_stub_2.py +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright Modal Labs 2024 -import modal - -# Don't trigger the deprecation warning for the class itself, -# but there should be a separate deprecation warning because of the symbol name -stub = modal.App() - - -@stub.function() -def foo(): - print("foo")