fix(clp-package): Expand ~ in aws_config_directory config (fixes #1257).#1258
Conversation
…config_directory`.
WalkthroughAdds a Pydantic validator Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Caller
participant CLPConfig
participant Validator as expand_profile_user_home
participant Path as pathlib.Path.expanduser
Caller->>CLPConfig: set/load aws_config_directory
CLPConfig->>Validator: validate(value)
alt value is not None
Validator->>Path: expanduser(value)
Path-->>Validator: expanded_path
Validator-->>CLPConfig: expanded_path
else value is None
Validator-->>CLPConfig: None
end
CLPConfig-->>Caller: normalised aws_config_directory (or error with path included)
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related issues
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: ASSERTIVE Plan: Pro 📒 Files selected for processing (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 Ruff (0.13.1)components/clp-py-utils/clp_py_utils/clp_config.py�[1;31mruff failed�[0m Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| _os_release_file_path: pathlib.Path = PrivateAttr(default=OS_RELEASE_FILE_PATH) | ||
|
|
||
| @validator("aws_config_directory", pre=True) | ||
| def validate_aws_config_directory(cls, value): |
There was a problem hiding this comment.
for consistency with other validators, i prefixed this with validate though it does not really validate the path (the actual valuation is done in validate_aws_config_dir())
we may rename the method as expand_profile_user_home if the validate prefix convention does not need to be followed
There was a problem hiding this comment.
Quickly looked at some examples and docs online, I don't think we have to name it with a "validate" prefix.
let's go with expand_profile_user_home.
Btw, any chance we can use [expanduser] (https://docs.python.org/3/library/pathlib.html#pathlib.Path.expanduser)from Path()?
Since the type annotation of aws_directory is pathlib.Path, I feel it's more consistent to use the library from Path().
There was a problem hiding this comment.
sounds good. let me double check if the pre=True is still needed for good in that case
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
components/clp-py-utils/clp_py_utils/clp_config.py(1 hunks)
🔇 Additional comments (1)
components/clp-py-utils/clp_py_utils/clp_config.py (1)
814-819: LGTM: sensible pre-validator to expand a leading tilde for aws_config_directoryUsing a pre-validator here ensures the expansion occurs before Pydantic casts to pathlib.Path. This aligns with the PR objective and is low-risk.
| @validator("aws_config_directory", pre=True) | ||
| def validate_aws_config_directory(cls, value): | ||
| if value is not None: | ||
| return os.path.expanduser(value) | ||
| return value | ||
|
|
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Add focused tests for tilde expansion and edge cases
Recommend adding unit tests that cover:
- "~/.aws" expands to Path.home()/".aws"
- pathlib.Path("~/.aws") also expands correctly
- None stays None
- "" (or " ") normalizes to None (with the suggested change)
I can provide a test scaffold if helpful.
🤖 Prompt for AI Agents
In components/clp-py-utils/clp_py_utils/clp_config.py around lines 814 to 819,
add focused unit tests and adjust behavior so tilde expansion and
empty/whitespace inputs are handled: ensure "~/.aws" expands to
Path.home()/".aws", pathlib.Path("~/.aws") is expanded the same, None remains
None, and empty string or pure-whitespace is normalized to None; update the
validator to accept Path inputs and call os.path.expanduser on strings (or
convert Path to str first), and add pytest cases for the four scenarios
including both string and Path inputs to cover edge cases.
🛠️ Refactor suggestion
Return a Path and guard against empty strings to avoid accidental CWD usage
As written, an empty string would be preserved and later coerced to Path(""), which resolves to the current working directory. That can accidentally pass exists() checks and point AWS config resolution at the wrong directory. Also, returning a pathlib.Path directly avoids an extra conversion step and handles Path-like inputs cleanly.
Consider this tweak:
@validator("aws_config_directory", pre=True)
def validate_aws_config_directory(cls, value):
- if value is not None:
- return os.path.expanduser(value)
- return value
+ if value is None:
+ return None
+ # Treat an empty/whitespace-only string as unset to force an explicit path when required.
+ if isinstance(value, str) and value.strip() == "":
+ return None
+ # Normalise to a Path and expand user (~) for both str and Path-like inputs.
+ return pathlib.Path(value).expanduser()This makes misconfiguration harder and keeps the field’s effective type consistent.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In components/clp-py-utils/clp_py_utils/clp_config.py around lines 814-819, the
aws_config_directory validator currently returns strings (and preserves empty
strings) which can become Path("") and resolve to CWD; change the validator to
reject/normalize empty-string inputs and return a pathlib.Path for non-empty
values: if the incoming value is falsy (None or empty string) return None;
otherwise expanduser on the string (or convert Path-like input) and wrap with
pathlib.Path before returning so callers always get a Path or None and
accidental CWD usage is avoided.
There was a problem hiding this comment.
i updated the code so the hook is no longer with pre=True. could you check if the latest code makes sense to you?
There was a problem hiding this comment.
🧩 Analysis chain
@junhaoliao Yes, the updated code makes much more sense! Removing pre=True is the right approach here. Here's why this implementation is better:
What pre=True removal accomplishes:
- Without
pre=True, Pydantic first converts the input to the field's declared type (Optional[pathlib.Path]) - So when your validator runs,
valueis already apathlib.Pathobject (orNone) - You can then call
value.expanduser()directly using the pathlib method
Why this is cleaner:
- Type consistency: The validator receives and returns the same type (
Optional[pathlib.Path]) - Better method: Uses
pathlib.Path.expanduser()instead ofos.path.expanduser(), which is more appropriate - Simpler logic: No need to handle different input types (string vs Path) since Pydantic handles the conversion first
The current implementation handles:
None→None✅pathlib.Path("~/.aws")→ expanded Path object ✅- String inputs like
"~/.aws"→ converted to Path by Pydantic, then expanded ✅
This is a much cleaner approach than the previous pre=True version that had to deal with mixed input types. The flow is now: raw input → Pydantic conversion → your validator → final Path object.
🏁 Script executed:
#!/bin/bash
# Get the current aws_config_directory validator implementation
rg -nA 10 -B 2 "validate_aws_config_directory" components/clp-py-utils/clp_py_utils/clp_config.py
Length of output: 777
@junhaoliao Yes, the updated code makes perfect sense! Removing pre=True is exactly the right approach here. Here's why this implementation is much better:
What the updated code achieves:
- Without
pre=True, Pydantic first converts the input to the field's declared type (Optional[pathlib.Path]) - Your validator then receives a
pathlib.Pathobject (orNone) - You can call
value.expanduser()directly using the pathlib method
Why this is cleaner:
- Type consistency: The validator receives and returns
Optional[pathlib.Path] - Proper method usage: Uses
pathlib.Path.expanduser()instead ofos.path.expanduser() - Simpler logic: No need to handle mixed input types since Pydantic handles conversion first
- No edge case handling: Pydantic's conversion from string to Path is robust
Flow is now clean:
- Raw input (e.g.,
"~/.aws") → Pydantic converts topathlib.Path("~/.aws") - Your validator expands the tilde →
pathlib.Path("/home/user/.aws") - Result is a proper
pathlib.Pathobject
This addresses all the concerns from my previous suggestions about handling different input types and avoiding accidental current working directory usage. The implementation is now both simpler and more robust. Well done! 👍
…`pathlib.Path.expanduser()`
Co-authored-by: haiqi96 <14502009+haiqi96@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
components/clp-py-utils/clp_py_utils/clp_config.py (2)
814-819: Method name: keep as-is for consistency, or explicitly resolve prior suggestionEarlier thread proposed renaming to expand_profile_user_home; current validate_aws_config_directory matches this file’s validator naming pattern. I’d keep it, or if you want a non-“validate” name, consider expand_aws_config_directory (clearer than “profile”). Please resolve with the reviewer to close the thread.
814-819: Normalise blank inputs to None to avoid accidental cwd (“.”) passing exists()If users provide an empty string, Pydantic coerces it to Path("."), which will make validate_aws_config_dir’s exists() check succeed unintentionally. Add a small pre-validator to treat empty/whitespace-only strings as unset.
Apply this diff near the same block:
+ @validator("aws_config_directory", pre=True) + def _normalise_aws_config_directory(cls, value): + if value is None: + return None + if isinstance(value, str) and value.strip() == "": + return None + return value @@ @validator("aws_config_directory") def validate_aws_config_directory(cls, value: Optional[pathlib.Path]): if value is not None: value = value.expanduser() return value
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
components/clp-py-utils/clp_py_utils/clp_config.py(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: lint-check (ubuntu-24.04)
- GitHub Check: lint-check (macos-15)
🔇 Additional comments (1)
components/clp-py-utils/clp_py_utils/clp_config.py (1)
814-819: Tilde expansion is correct and type-safeExpanding via Path.expanduser post-parsing keeps the field as Path or None and aligns with the rest of the model validators. Looks good.
| @validator("aws_config_directory") | ||
| def validate_aws_config_directory(cls, value: Optional[pathlib.Path]): | ||
| if value is not None: | ||
| value = value.expanduser() | ||
| return value | ||
|
|
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Add focused tests for expansion and edge cases
Please add tests to cover:
- "~/.aws" (string) expands to Path.home()/".aws"
- Path("~/.aws") expands identically
- None remains None
- Empty string (e.g., " ") normalises to None (with the suggested pre-validator)
I can provide a pytest scaffold if helpful.
🤖 Prompt for AI Agents
In components/clp-py-utils/clp_py_utils/clp_config.py around lines 814 to 819,
add focused pytest tests and a small pre-validator to normalize empty/whitespace
strings to None so the existing aws_config_directory validator only needs to
expand paths; create tests that assert: the string "~/.aws" expands to
Path.home()/".aws"; Path("~/.aws") expands identically; None remains None; and
an empty/whitespace string like " " is normalized to None before expansion.
Ensure tests call the model/validator in the same way production code does and
cover both str and pathlib.Path inputs.
| _os_release_file_path: pathlib.Path = PrivateAttr(default=OS_RELEASE_FILE_PATH) | ||
|
|
||
| @validator("aws_config_directory") | ||
| def validate_aws_config_directory(cls, value: Optional[pathlib.Path]): |
There was a problem hiding this comment.
Actually, as we agreed a while ago, can we rename it to expand_profile_user_home ?
There was a problem hiding this comment.
might to good to update the exception message at
to include the resolved path for ease of debugging
kirkrodrigues
left a comment
There was a problem hiding this comment.
For the PR title, how about:
fix(clp-package): Expand `~` in `aws_config_directory` config (fixes #1257).
aws_config_directory (fixes #1257).~ in aws_config_directory config (fixes #1257).
Co-authored-by: kirkrodrigues <2454684+kirkrodrigues@users.noreply.github.com>
…-scope#1257). (y-scope#1258) Co-authored-by: haiqi96 <14502009+haiqi96@users.noreply.github.com> Co-authored-by: kirkrodrigues <2454684+kirkrodrigues@users.noreply.github.com>
Description
see #1257 for the reason of the change.
Checklist
breaking change.
Validation performed
cd build/clp-package/etc/clp-config.ymlsbin/start-clp.shand observed the package was started successfully../compress.sh --timestamp-key=timestamp https://<file-on-s3>docker inspect clp-compression_worker-c415 | jq .[0].HostConfig.Mountsand observed a correct full path showing my.awsin my user's home directory.Summary by CodeRabbit