From 28b64b7f872beeea72ba0b71cef113fc14ea9aa8 Mon Sep 17 00:00:00 2001 From: Anai-Guo Date: Sat, 12 Sep 2026 09:14:17 -0700 Subject: [PATCH] fix(core): remove four dead duplicate definitions shadowed by a later copy Each of these names is bound twice at the same scope, so the first definition is unreachable - Python simply rebinds the name and the earlier object is discarded: * `sagemaker/core/utils/utils.py` - `snake_to_pascal` is defined twice. The first copy predates `SPECIAL_SNAKE_TO_PASCAL_MAPPINGS` and does not consult it, so it would mis-convert e.g. `volume_size_in_g_b`. It never runs: the second definition (which does consult the mapping) is the one every caller gets. * `sagemaker/core/training/configs.py` - `OutputDataConfig` is declared twice with identical fields; only the docstrings differ. The later, more accurate docstring is the one that survives. * `sagemaker/core/remote_function/job.py` - `_get_initial_job_state` is defined twice, byte for byte. * `sagemaker/serve/model_builder_utils.py` - `_ModelBuilderUtils._extract_speculative_draft_model_provider` is defined twice in the same class body, byte for byte. In every case this removes the dead copy and keeps the one that was already live, so the change is a no-op at runtime. Verified by comparing `ast.dump` of the final binding for every module-level and class-level name before and after: identical in all four files. Also confirmed no module-level code references any of these names between the two definitions (which would otherwise bind the earlier object at import time). Smoke-checked at runtime: `snake_to_pascal("volume_size_in_g_b") == "VolumeSizeInGB"` and `OutputDataConfig.model_fields == {s3_output_path, kms_key_id, compression_type}`, and `pytest sagemaker-core/tests/unit/utils` stays at 25 passed. Signed-off-by: Anai-Guo Co-Authored-By: Claude Opus 5 (1M context) --- .../src/sagemaker/core/remote_function/job.py | 7 ----- .../src/sagemaker/core/training/configs.py | 24 ---------------- .../src/sagemaker/core/utils/utils.py | 12 -------- .../sagemaker/serve/model_builder_utils.py | 28 ------------------- 4 files changed, 71 deletions(-) diff --git a/sagemaker-core/src/sagemaker/core/remote_function/job.py b/sagemaker-core/src/sagemaker/core/remote_function/job.py index d010c92903..3579a45630 100644 --- a/sagemaker-core/src/sagemaker/core/remote_function/job.py +++ b/sagemaker-core/src/sagemaker/core/remote_function/job.py @@ -2155,13 +2155,6 @@ def _rule_statuses_changed(current_statuses, last_statuses): return False -def _get_initial_job_state(description, status_key, wait): - """Placeholder docstring""" - status = description[status_key] - job_already_completed = status in ("Completed", "Failed", "Stopped") - return LogState.TAILING if wait and not job_already_completed else LogState.COMPLETE - - def _logs_init(boto_session, description, job): """Placeholder docstring""" if job == "Training": diff --git a/sagemaker-core/src/sagemaker/core/training/configs.py b/sagemaker-core/src/sagemaker/core/training/configs.py index 6ba49005a9..78fbf82a7d 100644 --- a/sagemaker-core/src/sagemaker/core/training/configs.py +++ b/sagemaker-core/src/sagemaker/core/training/configs.py @@ -125,30 +125,6 @@ class SourceCode(BaseConfig): ".ipynb_checkpoints", ] -class OutputDataConfig(shapes.OutputDataConfig): - """OutputDataConfig. - - Provides the configuration for the output data location of the training job - (will not be carried over to any model repository or deployment). - - Parameters: - s3_output_path (Optional[StrPipeVar]): - The S3 URI where the output data will be stored. This is the location where the - training job will save its output data, such as model artifacts and logs. - kms_key_id (Optional[StrPipeVar]): - The Amazon Web Services Key Management Service (Amazon Web Services KMS) key that - SageMaker uses to encrypt the model artifacts at rest using Amazon S3 server-side - encryption. - compression_type (Optional[StrPipeVar]): - The model output compression type. Select None to output an uncompressed model, - recommended for large model outputs. Defaults to gzip. - """ - - s3_output_path: Optional[StrPipeVar] = None - kms_key_id: Optional[StrPipeVar] = None - compression_type: Optional[StrPipeVar] = None - - class Compute(shapes.ResourceConfig): """Compute. diff --git a/sagemaker-core/src/sagemaker/core/utils/utils.py b/sagemaker-core/src/sagemaker/core/utils/utils.py index 9f916902f4..c8b50c244b 100644 --- a/sagemaker-core/src/sagemaker/core/utils/utils.py +++ b/sagemaker-core/src/sagemaker/core/utils/utils.py @@ -64,18 +64,6 @@ def convert_to_snake_case(entity_name): return re.sub("([a-z0-9])([A-Z])", r"\1_\2", snake_case).lower() -def snake_to_pascal(snake_str): - """ - Convert a snake_case string to PascalCase. - Args: - snake_str (str): The snake_case string to be converted. - Returns: - str: The PascalCase string. - """ - components = snake_str.split("_") - return "".join(x.title() for x in components[0:]) - - def reformat_file_with_black(filename): try: # Run black with specific options using subprocess diff --git a/sagemaker-serve/src/sagemaker/serve/model_builder_utils.py b/sagemaker-serve/src/sagemaker/serve/model_builder_utils.py index 68217dfde5..e88e5be8ee 100644 --- a/sagemaker-serve/src/sagemaker/serve/model_builder_utils.py +++ b/sagemaker-serve/src/sagemaker/serve/model_builder_utils.py @@ -3407,34 +3407,6 @@ def _detect_inference_image_from_training(self) -> None: f"Could not detect inference image for training image: {training_image}" ) - def _extract_speculative_draft_model_provider( - self, - speculative_decoding_config: Optional[Dict] = None, - ) -> Optional[str]: - """Extracts speculative draft model provider from speculative decoding config. - - Args: - speculative_decoding_config (Optional[Dict]): A speculative decoding config. - - Returns: - Optional[str]: The speculative draft model provider. - """ - if speculative_decoding_config is None: - return None - - model_provider = speculative_decoding_config.get("ModelProvider", "").lower() - - if model_provider == "jumpstart": - return "jumpstart" - - if model_provider == "custom" or speculative_decoding_config.get("ModelSource"): - return "custom" - - if model_provider == "sagemaker": - return "sagemaker" - - return "auto" - def get_huggingface_model_metadata( self, model_id: str, hf_hub_token: Optional[str] = None ) -> dict: