-
-
Notifications
You must be signed in to change notification settings - Fork 115
Add non-Path files support (for example Traversable) and open files using Path.open method #724
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Since you're already using |
|
|
I've added tests for Traversable type to show the usecase. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR improves file handling in pydantic-settings by switching from the built-in open() function to using the .open() method on path-like objects. This change aims to add support for non-filesystem path types like Traversable from importlib.resources, enabling configuration files to be loaded from packages and archives.
Key Changes:
- Modified file opening in JSON, YAML, and TOML config sources to use
path.open()instead ofopen(path) - Updated
_read_files()logic inConfigFileSourceMixinto handle path-like objects more flexibly - Added test for Traversable support using
importlib.resources
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pydantic_settings/sources/providers/json.py | Changed to use file_path.open() for opening JSON files |
| pydantic_settings/sources/providers/yaml.py | Changed to use file_path.open() for opening YAML files |
| pydantic_settings/sources/providers/toml.py | Changed to use file_path.open() for opening TOML files |
| pydantic_settings/sources/base.py | Modified _read_files() to handle non-Path objects by conditionally converting strings and applying expanduser() only to Path objects |
| tests/test_source_json.py | Added test_traversable_support() to verify Traversable objects can be used as configuration file sources |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if isinstance(file, str): | ||
| file_path = Path(file) | ||
| else: | ||
| file_path = file |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic has a bug when handling Traversable objects. The check at line 199 isinstance(files, (str, os.PathLike)) doesn't catch Traversable objects (they don't implement os.PathLike). This means a single Traversable object won't be converted to a list, and the iteration at line 202 will fail or behave incorrectly.
Consider changing the logic to check if files is not a sequence (or more specifically, check if it has the file-like interface you need) before wrapping it in a list. For example:
if not isinstance(files, Sequence) or isinstance(files, (str, os.PathLike)):
files = [files]There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Sube-py would be great if you could handle this
| file_path = Path(file) | ||
| else: | ||
| file_path = file | ||
| if isinstance(file_path, Path): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this if here? As we convert str to Path above?
Open files (JSON, TOML, YAML) using
file_path.open()instead ofopen(file_path).Not only this is more suitable way, this change also adds support for passing types other than
pathlib.Pathandstr, for exampleTraversableand some others, that don't have real path to file, but allow to be opened using the.open()method.