python-dotenv icon indicating copy to clipboard operation
python-dotenv copied to clipboard

feat: option to change POSIX variable name regex - facilitate passthrough

Open space88man opened this issue 4 months ago • 0 comments

Background

There are certain situations where a string ${xxxxxxxx} should not be a candidate for variable substitution. This is very common in Spring Boot applications where ${a.b.c.d} is property placeholder syntax

This PR allows the user to narrow the scope of dotenv.variables._posix_variable so that some strings that resemble POSIX variable substitution can be treated literally.

Before this PR:

# I'm looking at you Spring Boot
APP_SOME_VAR=${app.some.other.var}

# after load_dotenv
# dotenv.variables._posix_variable is quite greedy
APP_SOME_VAR=

After this PR:

# somewhere in  code:
# typical Spring Boot naming convention consists of
# caps, numerals, and underscores
dotenv.set_variable_name_pattern(r"""[A-Z0-9_]+""")

# Spring Boot property placeholder syntax
APP_SOME_VAR=${app.some.other.var}

# after load_dotenv
# literal passthrough
APP_SOME_VAR=${app.some.other.var}

Real-world use case: 12-factor'ing Spring Boot applications where some properties refer to other properties ${a.b.c.d} in their values

Feature Implementation

  • opt-in package level function dotenv.set_variable_name_pattern(....) to set the regex for the naming convention. This is a substring that will be used inside the ${xxxxxx:-yyyyyy} matcher. IOW, this pattern is only used to match the variable name, not the enclosing ${...}
  • revert to default: dotenv.set_variable_name_pattern()
  • added a test for literal passthrough
  • existing tests all passed

This feature does not affect any existing code as it is purely opt-in

Thread Safety

  • this feature sets a module level variable in dotenv.variables so is not thread safe

Deferred Ideas

  • per instance _posix_variable - this would be very intrusive so not in the scope of this feature
  • thread-local _posix_variable - this is a low risk thread-safety enhancement where each thread can set its own _posix_variable

Usage

# before calling load_dotenv or dotenv_values
dotenv.set_variable_name_pattern(r'''[A-Z0-9_]+''') # Spring Boot preset
load_dotenv()
# or
load_dotenv(varname_pattern=r'''[A-Z0-9_]+''')
dotenv_values(varname_pattern=r'''[A-Z0-9_]+''')

# epilogue: reset to package default regex
dotenv.set_variable_name_pattern()

Benefits

  • allow literal passthrough of string segments that look like POSIX substitution

Workaround

Current workaround

## this is horrible
__='${'
APP_SOME_VAR=${__}app.some.other.var}

space88man avatar Aug 16 '25 05:08 space88man