fix(dagster-aws): handle s3_prefix=None in PickledObjectS3IOManager#33600
fix(dagster-aws): handle s3_prefix=None in PickledObjectS3IOManager#33600Vamsi-klu wants to merge 1 commit into
Conversation
Greptile SummaryFixes a
Confidence Score: 5/5This PR is safe to merge — it makes a minimal, targeted fix to a well-understood bug with no behavioral changes for callers who already pass a valid non-empty prefix. The change is a single-line normalization in the constructor that only affects the None/empty-string code path, which was previously broken entirely. The fix is correct: No files require special attention.
|
| Filename | Overview |
|---|---|
| python_modules/libraries/dagster-aws/dagster_aws/s3/io_manager.py | Adds s3_prefix = s3_prefix or "" normalization before the boto3 call so that None is converted to an empty string, fixing a ParamValidationError when no prefix is configured. |
| python_modules/libraries/dagster-aws/dagster_aws_tests/s3_tests/test_io_manager.py | Adds two new tests: a parametrized regression test for None/"" prefix and a sanity-check test for a valid prefix. The boto3 client is imported inline rather than using the existing construct_s3_client helper, but this is a minor style nit. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["PickledObjectS3IOManager.__init__(s3_prefix)"] --> B["check.opt_str_param(s3_prefix)"]
B --> C{"s3_prefix or ''"}
C -- "None → ''" --> D["s3_prefix = ''"]
C -- "'' → ''" --> D
C -- "'my-prefix' → 'my-prefix'" --> E["s3_prefix = 'my-prefix'"]
D --> F["s3.list_objects(Prefix='')"]
E --> G["s3.list_objects(Prefix='my-prefix')"]
F --> H{"s3_prefix truthy?"}
G --> H
H -- "No (empty string)" --> I["base_path = None"]
H -- "Yes" --> J["base_path = UPath(s3_prefix)"]
I --> K["super().__init__(base_path=None)"]
J --> K
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A["PickledObjectS3IOManager.__init__(s3_prefix)"] --> B["check.opt_str_param(s3_prefix)"]
B --> C{"s3_prefix or ''"}
C -- "None → ''" --> D["s3_prefix = ''"]
C -- "'' → ''" --> D
C -- "'my-prefix' → 'my-prefix'" --> E["s3_prefix = 'my-prefix'"]
D --> F["s3.list_objects(Prefix='')"]
E --> G["s3.list_objects(Prefix='my-prefix')"]
F --> H{"s3_prefix truthy?"}
G --> H
H -- "No (empty string)" --> I["base_path = None"]
H -- "Yes" --> J["base_path = UPath(s3_prefix)"]
I --> K["super().__init__(base_path=None)"]
J --> K
Reviews (2): Last reviewed commit: "fix(dagster-aws): handle s3_prefix=None ..." | Re-trigger Greptile
boto3's list_objects rejects Prefix=None with a ParamValidationError. Normalize None to empty string before passing to boto3. Fixes: dagster-io#33490 Co-Authored-By: codingrealitylabs <codingrealitylabs@users.noreply.github.com> Co-Authored-By: girlcoder-gaming <girlcoder-gaming@users.noreply.github.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
a11a597 to
9a7c6b3
Compare
Merge activity
|
|
@smackesey are there any actions on my end to help this PR merged? |
|
whoops, forgot to hit the button. Merged! |
|
@smackesey thanks for approving this one! It's approved but the merge looks gated on CI not having run for the fork PR. Could you trigger CI / merge when you get a chance, or let me know if anything else is needed? Appreciate it. |
9a7c6b3 to
321d040
Compare
|
@smackesey following up because this PR is still open and still approved on the same head ( The Graphite stack-merge attempts on Mar 16 failed with "Fast-forward merges are not supported for forked repositories", so the "Merged!" comment did not actually merge the PR. Could you merge it via the GitHub UI, or otherwise from a target-repo branch, when you get a chance? I have not rebased or changed the branch so the approved head stays intact. Thanks. |
Summary & Motivation
Fixes #33490
PickledObjectS3IOManageracceptss3_prefix=Nonein its constructor signature (s3_prefix: str | None = None), but it was passed directly to boto3'slist_objects(Prefix=None), which raisesbotocore.exceptions.ParamValidationErrorbecause boto3 strictly requires thePrefixparameter to be a string type.This affects users who:
s3_pickle_io_managerresource factory (wheres3_prefixdefaults toNoneif not configured)s3_prefix=NonetoPickledObjectS3IOManagerRoot Cause
In
PickledObjectS3IOManager.__init__, line 35 directly passes the uncheckeds3_prefixvalue to boto3:When
s3_prefix=None, boto3 raises:Fix
Added
s3_prefix = s3_prefix or ""normalization after thecheck.opt_str_paramcall and before the boto3 call. An empty string is the correct boto3 equivalent of "no prefix" and is also falsy, so the existingbase_path = UPath(s3_prefix) if s3_prefix else Nonelogic continues to work correctly.Test Plan
test_pickled_object_s3_io_manager_none_and_empty_prefix(parametrized:None,"")test_pickled_object_s3_io_manager_with_valid_prefixtest_io_manager.pysuite (7 tests)make ruffTest Results
Changelog
PickledObjectS3IOManagerno longer raisesParamValidationErrorwhens3_prefix=None.🤖 Generated with Claude Code