Expand shell variables of form $var and ${var}. Unknown variables are left unchanged.
(path)
| 291 | _varprogb = None |
| 292 | |
| 293 | def expandvars(path): |
| 294 | """Expand shell variables of form $var and ${var}. Unknown variables |
| 295 | are left unchanged.""" |
| 296 | path = os.fspath(path) |
| 297 | global _varprog, _varprogb |
| 298 | if isinstance(path, bytes): |
| 299 | if b'$' not in path: |
| 300 | return path |
| 301 | if not _varprogb: |
| 302 | import re |
| 303 | _varprogb = re.compile(br'\$(\w+|\{[^}]*\})', re.ASCII) |
| 304 | search = _varprogb.search |
| 305 | start = b'{' |
| 306 | end = b'}' |
| 307 | environ = getattr(os, 'environb', None) |
| 308 | else: |
| 309 | if '$' not in path: |
| 310 | return path |
| 311 | if not _varprog: |
| 312 | import re |
| 313 | _varprog = re.compile(r'\$(\w+|\{[^}]*\})', re.ASCII) |
| 314 | search = _varprog.search |
| 315 | start = '{' |
| 316 | end = '}' |
| 317 | environ = os.environ |
| 318 | i = 0 |
| 319 | while True: |
| 320 | m = search(path, i) |
| 321 | if not m: |
| 322 | break |
| 323 | i, j = m.span(0) |
| 324 | name = m.group(1) |
| 325 | if name.startswith(start) and name.endswith(end): |
| 326 | name = name[1:-1] |
| 327 | try: |
| 328 | if environ is None: |
| 329 | value = os.fsencode(os.environ[os.fsdecode(name)]) |
| 330 | else: |
| 331 | value = environ[name] |
| 332 | except KeyError: |
| 333 | i = j |
| 334 | else: |
| 335 | tail = path[j:] |
| 336 | path = path[:i] + value |
| 337 | i = len(path) |
| 338 | path += tail |
| 339 | return path |
| 340 | |
| 341 | |
| 342 | # Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B. |