0

I have the following dictionary:

config = {
'base_dir': Path(__file__).resolve(strict=True).parent.absolute(),
'app_dir': '<base_dir>/app'
}

I want to replace <base_dir> with the value of <base_dir> so I did this:

for key, value in config.items():
    if type(value) == str:
        vars_to_replace = re.findall(r'\<.+\>',value)
        for var in vars_to_replace:
            config[key] = value.replace(var,config[var[1:-1]])

Currently getting the error: TypeError: replace() argument 2 must be str, not WindowsPath

If I wrap my config[var[1:-1]] with str(). It gets rid of the error but I lose the WindowsPath and now app_dir becomes a string. I want to reserve the object as WindowsPath.

syrkull
  • 2,295
  • 4
  • 35
  • 68

2 Answers2

0

value is a string, so you are attempting to use the string's replace method, which takes two strings as arguments. If you want to change the value of the app_dir to be a Path object, you'll have to construct a path object and replace the current value ('/app') with that object. You can do this in several ways, here's one:

  • Convert base_dir to a string, replace the tag in app_dir with that string, and then convert the new path to a Path object

This would look like:

for key, value in config.items():
    if type(value) == str:
        vars_to_replace = re.findall(r'\<*[.+]\>',value)
        for var in vars_to_replace:
            new_path = value.replace(var, str(config[var[1:-1]]))
            config[key] = Path(new_path)

Another way would be to use something like path.join() to append to the path object:

path_addition = value.replace(var, "")
new_path_object = config[var].join(path_addition) # <-- might need to adjust this depending on the exact Path class you are using
config[key] = new_path_object

Hope these help, happy coding!

Sam
  • 1,406
  • 1
  • 8
  • 11
0

I'd say extract both base_dir and app and then construct a path with them:

for key, value in config.items():
    if isinstance(value, str):
        # parent_str will be "base_dir" and name_str will be "app"
        parent_str, name_str = re.fullmatch(r"\<(.+)?>/(\w+)", value).groups()
        parent_path = config[parent_str]
        config[key] = parent_path / Path(name_str)

I did not use for loop, assumed only one such match is possible in a value. If that's not the case, you could wrap a for loop with finditer.

Mustafa Aydın
  • 17,645
  • 4
  • 15
  • 38