*: Correctly handle annotation-only imports

This allows removing several dependencies on the checkout module.

Change-Id: I5544829efa92b323d96b2fa1f607129403c128bf
Reviewed-on: https://pigweed-review.googlesource.com/c/infra/recipes/+/209041
Reviewed-by: Ted Pudlik <tpudlik@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed-service-accounts.iam.gserviceaccount.com>
Pigweed-Auto-Submit: Rob Mohr <mohrr@google.com>
Lint: Lint 🤖 <android-build-ayeaye@system.gserviceaccount.com>
Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/recipe_modules/bazel/__init__.py b/recipe_modules/bazel/__init__.py
index 43fcde2..5e8b3d3 100644
--- a/recipe_modules/bazel/__init__.py
+++ b/recipe_modules/bazel/__init__.py
@@ -15,7 +15,6 @@
 # pylint: disable=missing-docstring
 
 DEPS = [
-    'pigweed/checkout',
     'recipe_engine/cipd',
     'recipe_engine/context',
     'recipe_engine/file',
diff --git a/recipe_modules/bazel/api.py b/recipe_modules/bazel/api.py
index 597d1c5..a036edd 100644
--- a/recipe_modules/bazel/api.py
+++ b/recipe_modules/bazel/api.py
@@ -20,9 +20,10 @@
 from typing import Any, Sequence, TypeVar, TYPE_CHECKING
 
 from PB.recipe_modules.pigweed.bazel.options import Options
-from recipe_engine import config_types, recipe_api
+from recipe_engine import recipe_api
 
 if TYPE_CHECKING:  # pragma: no cover
+    from recipe_engine import config_types
     from RECIPE_MODULES.pigweed.checkout import api as checkout_api
 
 
diff --git a/recipe_modules/bazel/tests/full.py b/recipe_modules/bazel/tests/full.py
index 59225dc..858ba3a 100644
--- a/recipe_modules/bazel/tests/full.py
+++ b/recipe_modules/bazel/tests/full.py
@@ -13,12 +13,16 @@
 # the License.
 """Full test of environment module."""
 
-from typing import Generator
+from __future__ import annotations
 
 import dataclasses
-from typing import Optional
+from typing import Generator, TYPE_CHECKING
+
 from PB.recipe_modules.pigweed.bazel.tests.full import InputProperties
-from recipe_engine import config_types, post_process, recipe_test_api
+from recipe_engine import post_process
+
+if TYPE_CHECKING:  # pragma: no cover
+    from recipe_engine import config_types, recipe_test_api
 
 DEPS = [
     'pigweed/bazel',
diff --git a/recipe_modules/bazel/tests/update_commit_hash.py b/recipe_modules/bazel/tests/update_commit_hash.py
index 92a2df6..7bdcd03 100644
--- a/recipe_modules/bazel/tests/update_commit_hash.py
+++ b/recipe_modules/bazel/tests/update_commit_hash.py
@@ -13,17 +13,21 @@
 # the License.
 """Full test of bazel module's update_commit_hash() method."""
 
-from typing import Generator
+from __future__ import annotations
 
 import dataclasses
-from typing import Optional
+from typing import Generator, TYPE_CHECKING
+
 from PB.recipe_modules.pigweed.bazel.tests.update_commit_hash import (
     UpdateCommitHashProperties,
 )
 from PB.recipe_modules.pigweed.checkout.options import (
     Options as CheckoutOptions,
 )
-from recipe_engine import config_types, post_process, recipe_test_api
+from recipe_engine import post_process
+
+if TYPE_CHECKING:  # pragma: no cover
+    from recipe_engine import config_types, recipe_test_api
 
 DEPS = [
     'pigweed/bazel',
diff --git a/recipe_modules/build/api.py b/recipe_modules/build/api.py
index 8c1b4f6..6f02624 100644
--- a/recipe_modules/build/api.py
+++ b/recipe_modules/build/api.py
@@ -13,10 +13,16 @@
 # the License.
 """Calls to build code."""
 
+from __future__ import annotations
+
 import dataclasses
+from typing import TYPE_CHECKING
 
 from PB.recipe_modules.pigweed.build import options as options_pb2
-from recipe_engine import config_types, recipe_api, step_data
+from recipe_engine import config_types, recipe_api
+
+if TYPE_CHECKING:  # pragma: no cover
+    from recipe_engine import step_data
 
 
 @dataclasses.dataclass
diff --git a/recipe_modules/checkout/api.py b/recipe_modules/checkout/api.py
index 0c8adf6..5c6e7bd 100644
--- a/recipe_modules/checkout/api.py
+++ b/recipe_modules/checkout/api.py
@@ -17,10 +17,12 @@
 api.checkout(remote='https://pigweed.googlesource.com/pigweed/pigweed')
 """
 
+from __future__ import annotations
+
 import collections
 import contextlib
 import re
-from typing import Any, Sequence
+from typing import Any, Sequence, TYPE_CHECKING
 import urllib
 import xml.etree.ElementTree
 
@@ -33,7 +35,10 @@
     triggers as triggers_pb2,
 )
 from PB.recipe_modules.pigweed.checkout.options import Options
-from recipe_engine import config_types, recipe_api
+from recipe_engine import recipe_api
+
+if TYPE_CHECKING:  # pragma: no cover
+    from recipe_engine import config_types
 
 PIGWEED_REMOTE = 'https://pigweed.googlesource.com/pigweed/pigweed'
 
diff --git a/recipe_modules/cipd_upload/__init__.py b/recipe_modules/cipd_upload/__init__.py
index 664d371..bb8a1b2 100644
--- a/recipe_modules/cipd_upload/__init__.py
+++ b/recipe_modules/cipd_upload/__init__.py
@@ -16,7 +16,6 @@
 
 DEPS = [
     'fuchsia/cipd_util',
-    'pigweed/checkout',
     'recipe_engine/cipd',
     'recipe_engine/file',
     'recipe_engine/platform',
diff --git a/recipe_modules/cipd_upload/api.py b/recipe_modules/cipd_upload/api.py
index 53ce735..f82fd9f 100644
--- a/recipe_modules/cipd_upload/api.py
+++ b/recipe_modules/cipd_upload/api.py
@@ -13,13 +13,19 @@
 # the License.
 """Utility functions for uploading a cipd package."""
 
-from typing import Sequence
+from __future__ import annotations
+
+from typing import Sequence, TYPE_CHECKING
 
 from PB.recipe_modules.fuchsia.cipd_util.upload_manifest import (
     CIPDUploadManifest,
 )
-from recipe_engine import config_types, recipe_api, step_data
-from RECIPE_MODULES.pigweed.checkout import api as checkout_api
+
+from recipe_engine import recipe_api
+
+if TYPE_CHECKING:  # pragma: no cover
+    from recipe_engine import config_types
+    from RECIPE_MODULES.pigweed.checkout import api as checkout_api
 
 
 class CipdUploadApi(recipe_api.RecipeApi):
diff --git a/recipe_modules/default_timeout/api.py b/recipe_modules/default_timeout/api.py
index a7eb548..70cb612 100644
--- a/recipe_modules/default_timeout/api.py
+++ b/recipe_modules/default_timeout/api.py
@@ -13,9 +13,11 @@
 # the License.
 """Ensure the given call completes before swarming kills the build."""
 
+from __future__ import annotations
+
 import contextlib
 import dataclasses
-from typing import Generator
+from typing import Generator, TYPE_CHECKING
 
 from recipe_engine import recipe_api
 from RECIPE_MODULES.fuchsia.utils import nice_duration
diff --git a/recipe_modules/environment/__init__.py b/recipe_modules/environment/__init__.py
index c327303..e0e7a77 100644
--- a/recipe_modules/environment/__init__.py
+++ b/recipe_modules/environment/__init__.py
@@ -16,7 +16,6 @@
 
 DEPS = [
     'fuchsia/macos_sdk',
-    'pigweed/checkout',
     'pigweed/default_timeout',
     'pigweed/save_logs',
     'recipe_engine/buildbucket',
diff --git a/recipe_modules/environment/api.py b/recipe_modules/environment/api.py
index 01a0c41..ebb7f87 100644
--- a/recipe_modules/environment/api.py
+++ b/recipe_modules/environment/api.py
@@ -19,14 +19,19 @@
   ...
 """
 
+from __future__ import annotations
+
 import contextlib
 import dataclasses
 import pprint
+from typing import TYPE_CHECKING
 
 from PB.recipe_modules.pigweed.environment.options import Options
-from RECIPE_MODULES.pigweed.checkout import api as checkout_api
+from recipe_engine import recipe_api
 
-from recipe_engine import config_types, engine_types, recipe_api
+if TYPE_CHECKING:  # pragma: no cover
+    from recipe_engine import config_types, engine_types
+    from RECIPE_MODULES.pigweed.checkout import api as checkout_api
 
 
 @dataclasses.dataclass
diff --git a/recipe_modules/environment/tests/full.py b/recipe_modules/environment/tests/full.py
index b65ab09..865fecb 100644
--- a/recipe_modules/environment/tests/full.py
+++ b/recipe_modules/environment/tests/full.py
@@ -13,11 +13,15 @@
 # the License.
 """Full test of environment module."""
 
+from __future__ import annotations
+
 import dataclasses
-from typing import Generator, Optional
+from typing import Generator, Optional, TYPE_CHECKING
 
 from PB.recipe_modules.pigweed.environment.tests.full import InputProperties
-from recipe_engine import config_types, recipe_test_api
+
+if TYPE_CHECKING:  # pragma: no cover
+    from recipe_engine import config_types, recipe_test_api
 
 DEPS = [
     'pigweed/environment',
diff --git a/recipe_modules/gerrit_comment/__init__.py b/recipe_modules/gerrit_comment/__init__.py
index 0ec9b0f..a405409 100644
--- a/recipe_modules/gerrit_comment/__init__.py
+++ b/recipe_modules/gerrit_comment/__init__.py
@@ -17,6 +17,5 @@
 DEPS = [
     'fuchsia/gerrit',
     'recipe_engine/buildbucket',
-    'recipe_engine/defer',
     'recipe_engine/step',
 ]
diff --git a/recipe_modules/gerrit_comment/api.py b/recipe_modules/gerrit_comment/api.py
index f1e4c5a..6518940 100644
--- a/recipe_modules/gerrit_comment/api.py
+++ b/recipe_modules/gerrit_comment/api.py
@@ -12,13 +12,19 @@
 # License for the specific language governing permissions and limitations under
 # the License.
 
+from __future__ import annotations
+
+from typing import TYPE_CHECKING
+
 from recipe_engine import recipe_api
 
 from PB.recipe_modules.pigweed.gerrit_comment.options import (
     CommentBehavior,
     Options,
 )
-from RECIPE_MODULES.recipe_engine.defer import api as defer_api
+
+if TYPE_CHECKING:  # pragma: no cover
+    from RECIPE_MODULES.recipe_engine.defer import api as defer_api
 
 
 class GerritCommentApi(recipe_api.RecipeApi):
diff --git a/recipe_modules/pw_presubmit/__init__.py b/recipe_modules/pw_presubmit/__init__.py
index 2c47636..9058380 100644
--- a/recipe_modules/pw_presubmit/__init__.py
+++ b/recipe_modules/pw_presubmit/__init__.py
@@ -16,7 +16,6 @@
 
 DEPS = [
     'fuchsia/buildbucket_util',
-    'pigweed/checkout',
     'pigweed/cipd_upload',
     'pigweed/default_timeout',
     'pigweed/gerrit_comment',
diff --git a/recipe_modules/pw_presubmit/api.py b/recipe_modules/pw_presubmit/api.py
index e5bf828..92d5829 100644
--- a/recipe_modules/pw_presubmit/api.py
+++ b/recipe_modules/pw_presubmit/api.py
@@ -13,14 +13,19 @@
 # the License.
 """Wrapper for 'pw presubmit' in the project source tree."""
 
+from __future__ import annotations
+
 import collections
 import dataclasses
 import shlex
-from typing import Sequence
+from typing import Sequence, TYPE_CHECKING
 
-from RECIPE_MODULES.pigweed.checkout import api as checkout_api
 from PB.recipe_modules.pigweed.pw_presubmit import options as options_pb2
-from recipe_engine import config_types, recipe_api, step_data
+from recipe_engine import recipe_api
+
+if TYPE_CHECKING:  # pragma: no cover
+    from RECIPE_MODULES.pigweed.checkout import api as checkout_api
+    from recipe_engine import config_types, step_data
 
 METADATA = {
     'binary_sizes': (('target', 12345), ('target.budget', 12346)),
@@ -395,7 +400,7 @@
     def build_id(self, ctx: PresubmitContext) -> str | None:
         command: List[str] = ctx.options.command_name.split()
         command.extend(['--directory', ctx.checkout.root, 'build-id'])
-        step_data: step_data.StepData = self.m.step(
+        stepdata: step_data.StepData = self.m.step(
             'get build id',
             command,
             stdout=self.m.raw_io.output_text(),
@@ -406,8 +411,8 @@
         )
 
         namespace: str | None = None
-        if step_data.exc_result.retcode == 0:
-            namespace: str = step_data.stdout.strip()
+        if stepdata.exc_result.retcode == 0:
+            namespace: str = stepdata.stdout.strip()
             if namespace == '0':
                 namespace = None
 
diff --git a/recipe_modules/roll_util/api.py b/recipe_modules/roll_util/api.py
index f1556c2..36afd87 100644
--- a/recipe_modules/roll_util/api.py
+++ b/recipe_modules/roll_util/api.py
@@ -13,17 +13,23 @@
 # the License.
 """Utility functions for rollers."""
 
+from __future__ import annotations
+
 import collections
+import enum
 import re
-from typing import Any, Optional, Sequence
+from typing import Any, Optional, Sequence, TYPE_CHECKING
 import urllib
 
 import attrs
-import enum
-from recipe_engine import config_types, recipe_api
+
 from PB.recipe_modules.fuchsia.auto_roller.options import (
     Options as AutoRollerOptions,
 )
+from recipe_engine import recipe_api
+
+if TYPE_CHECKING:  # pragma: no cover
+    from recipe_engine import config_types
 
 # If we're embedding the original commit message, prepend 'Original-' to lines
 # which begin with these tags.
diff --git a/recipe_modules/save_logs/api.py b/recipe_modules/save_logs/api.py
index fb28031..28954af 100644
--- a/recipe_modules/save_logs/api.py
+++ b/recipe_modules/save_logs/api.py
@@ -13,7 +13,14 @@
 # the License.
 """Utilities for saving logs."""
 
-from recipe_engine import config_types, engine_types, recipe_api
+from __future__ import annotations
+
+from typing import TYPE_CHECKING
+
+from recipe_engine import recipe_api
+
+if TYPE_CHECKING:  # pragma: no cover
+    from recipe_engine import config_types, engine_types
 
 
 class PresubmitError(recipe_api.StepFailure):
diff --git a/recipes/envtest.py b/recipes/envtest.py
index d211580..10bceca 100644
--- a/recipes/envtest.py
+++ b/recipes/envtest.py
@@ -13,11 +13,15 @@
 # the License.
 """Recipe for testing Pigweed using developer env setup scripts."""
 
+from __future__ import annotations
+
 import re
-from typing import Generator
+from typing import Generator, TYPE_CHECKING
 
 from PB.recipes.pigweed.envtest import InputProperties
-from recipe_engine import config_types, recipe_api, recipe_test_api
+
+if TYPE_CHECKING:  # pragma: no cover
+    from recipe_engine import config_types, recipe_api, recipe_test_api
 
 DEPS = [
     'fuchsia/macos_sdk',
diff --git a/recipes/run_script.py b/recipes/run_script.py
index 21cd44e..21626a2 100644
--- a/recipes/run_script.py
+++ b/recipes/run_script.py
@@ -13,11 +13,16 @@
 # the License.
 """Recipe for running a specified script from."""
 
-from typing import Callable, Generator
+from __future__ import annotations
+
 import re
+from typing import Callable, Generator, TYPE_CHECKING
 
 from PB.recipes.pigweed.run_script import InputProperties
-from recipe_engine import config_types, recipe_api, recipe_test_api
+from recipe_engine import config_types
+
+if TYPE_CHECKING:  # pragma: no cover
+    from recipe_engine import recipe_api, recipe_test_api
 
 DEPS = [
     'pigweed/checkout',
diff --git a/recipes/static_checks.py b/recipes/static_checks.py
index f87e36d..5b9bab4 100644
--- a/recipes/static_checks.py
+++ b/recipes/static_checks.py
@@ -13,13 +13,18 @@
 # the License.
 """Assorted checks that do not require checking out code."""
 
+from __future__ import annotations
+
 import functools
 import re
-from typing import Any, Generator, Sequence
+from typing import Any, Generator, Sequence, TYPE_CHECKING
 
 from PB.recipes.pigweed.static_checks import InputProperties
-from recipe_engine import post_process, recipe_api, recipe_test_api
-from RECIPE_MODULES.pigweed.util import api as util_api
+from recipe_engine import post_process
+
+if TYPE_CHECKING:  # pragma: no cover
+    from recipe_engine import recipe_api, recipe_test_api
+    from RECIPE_MODULES.pigweed.util import api as util_api
 
 DEPS = [
     'fuchsia/gerrit',
diff --git a/recipes/submodule_roller.py b/recipes/submodule_roller.py
index 0d32a21..cd1c4b6 100644
--- a/recipes/submodule_roller.py
+++ b/recipes/submodule_roller.py
@@ -13,15 +13,19 @@
 # the License.
 """Roll submodules of a git repository."""
 
+from __future__ import annotations
+
 import configparser
 import dataclasses
 import io
 import re
-from typing import Generator
+from typing import Generator, TYPE_CHECKING
 
 import attrs
 from PB.recipes.pigweed.submodule_roller import InputProperties, Submodule
-from recipe_engine import config_types, post_process, recipe_test_api
+
+if TYPE_CHECKING:  # pragma: no cover
+    from recipe_engine import config_types, post_process, recipe_test_api
 
 DEPS = [
     'fuchsia/auto_roller',
diff --git a/recipes/xrefs.py b/recipes/xrefs.py
index 9b9a24c..5e4c861 100644
--- a/recipes/xrefs.py
+++ b/recipes/xrefs.py
@@ -13,11 +13,15 @@
 # the License.
 """Generate crossrefs using Kythe and upload to GCS."""
 
-from typing import Generator
+from __future__ import annotations
+
+from typing import Generator, TYPE_CHECKING
 import urllib
 
 from PB.recipes.pigweed.xrefs import InputProperties
-from recipe_engine import config_types, recipe_api, recipe_test_api
+
+if TYPE_CHECKING:  # pragma: no cover
+    from recipe_engine import config_types, recipe_api, recipe_test_api
 
 DEPS = [
     'fuchsia/buildbucket_util',