Skip to content

Commit 7d984e3

Browse files
Merge branch 'main' into fix/mergebot-update-branch-issue
2 parents 588f3e5 + 2052c1b commit 7d984e3

File tree

3 files changed

+26
-14
lines changed

3 files changed

+26
-14
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ class AppSettings(BaseSettings):
142142

143143
msgspec-ext leverages msgspec's high-performance serialization with bulk JSON decoding for maximum speed.
144144

145-
**Benchmark Results** (10 runs × 1000 iterations, Python 3.12):
145+
**Benchmark Results** (Python 3.12):
146146

147147
| Library | Time per load | Relative Performance |
148148
|---------|---------------|---------------------|

src/msgspec_ext/settings.py

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -349,30 +349,42 @@ def _preprocess_env_value(cls, env_value: str, field_type: type) -> Any: # noqa
349349

350350
return env_value
351351

352-
# Handle bool
352+
# Fast path: Direct type comparison (avoid get_origin when possible)
353+
if field_type is str:
354+
return env_value
353355
if field_type is bool:
354356
return env_value.lower() in ("true", "1", "yes", "y", "t")
355-
356-
# Handle int
357357
if field_type is int:
358358
try:
359359
return int(env_value)
360360
except ValueError as e:
361361
raise ValueError(f"Cannot convert '{env_value}' to int") from e
362-
363-
# Handle float
364362
if field_type is float:
365363
try:
366364
return float(env_value)
367365
except ValueError as e:
368366
raise ValueError(f"Cannot convert '{env_value}' to float") from e
369367

370-
# Handle JSON types (list, dict, nested structs)
371-
if env_value.startswith(("{", "[")):
372-
try:
373-
return msgspec.json.decode(env_value.encode())
374-
except msgspec.DecodeError as e:
375-
raise ValueError(f"Invalid JSON in env var: {e}") from e
368+
# Only use typing introspection for complex types (Union, Optional, etc.)
369+
origin = get_origin(field_type)
370+
if origin is Union:
371+
args = get_args(field_type)
372+
non_none = [a for a in args if a is not type(None)]
373+
if non_none:
374+
# Cache the resolved type for future use
375+
resolved_type = non_none[0]
376+
cls._type_cache[field_type] = resolved_type
377+
# Recursively process with the non-None type
378+
return cls._preprocess_env_value(env_value, resolved_type)
379+
380+
return env_value
381+
382+
# Type conversion (required for JSON encoding)
383+
if field_type is bool:
384+
return env_value.lower() in ("true", "1", "yes", "y", "t")
385+
if field_type is int:
386+
return int(env_value)
387+
if field_type is float:
388+
return float(env_value)
376389

377-
# Default: return as string
378390
return env_value

src/msgspec_ext/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.1.0"
1+
__version__ = "0.2.0"

0 commit comments

Comments
 (0)