Skip to content
PL1

Passing a WindowsPath as value of TourConfig's kernels_dir causes a bad escape error

running the following code on windows:

import planetary_coverage as pc
from pathlib import Path

tc = pc.TourConfig( mk="plan",  
                   kernels_dir=Path("C:/Users/luca_/AppData/Local/JANUS/jana/Cache/kernels/juice"), 
                   download_kernels=True,
                    load_kernels=True         )

produces the following error:

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
File C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\lib\sre_parse.py:1051, in parse_template(source, state)
   1050 try:
-> 1051     this = chr(ESCAPES[this][1])
   1052 except KeyError:

KeyError: '\\U'

During handling of the above exception, another exception occurred:

error                                     Traceback (most recent call last)
Cell In[44], line 4
      1 import planetary_coverage as pc
      2 from pathlib import Path
----> 4 tc = pc.TourConfig( mk="plan",  kernels_dir=Path("C:/Users/luca_/AppData/Local/JANUS/jana/Cache/kernels/juice"), 
      5                    download_kernels=True,
      6                     load_kernels=True         )

File c:\Users\luca_\code\.venv\lib\site-packages\planetary_coverage\trajectory\config.py:147, in TourConfig.__init__(self, mk, kernels, spacecraft, instrument, target, version, kernels_dir, download_kernels, remote_kernels, load_kernels, default_time_step, abcorr, exclude)
    144 self._add(kernels)
    146 if load_kernels:
--> 147     self.load_kernels()
    149 # Trajectory/Flyby default parameters
    150 self.default_time_step = default_time_step

File c:\Users\luca_\code\.venv\lib\site-packages\planetary_coverage\spice\pool.py:358, in check_kernels.<locals>.wrapper(_self, *args, **kwargs)
    355 if SpicePool != hash(_self):
    356     log_spice_pool.info(
    357         'The content of the pool changed -> the kernels will be reloaded.')
--> 358     SpicePool.add(_self.kernels, purge=True)
    360 return func(_self, *args, **kwargs)

File c:\Users\luca_\code\.venv\lib\site-packages\planetary_coverage\spice\pool.py:110, in MetaSpicePool.add(cls, kernel, purge)
    108 if isinstance(kernel, (tuple, list)):
    109     for _kernel in kernel:
--> 110         cls.add(_kernel, purge=False)
    112 elif kernel in cls:
    113     raise ValueError(f'Kernel `{kernel}` is already in the pool.')

File c:\Users\luca_\code\.venv\lib\site-packages\planetary_coverage\spice\pool.py:119, in MetaSpicePool.add(cls, kernel, purge)
    116 log_spice_pool.debug('Add `%s` in the SPICE pool', kernel)
    118 if isinstance(kernel, MetaKernel):
--> 119     with kernel as mk:
    120         # `mk` is the name of a `NamedTemporaryFile` (see `MetaKernel`)
    121         sp.furnsh(mk)
    123         log_spice_pool.debug('Cache metakernel original hash.')

File c:\Users\luca_\code\.venv\lib\site-packages\planetary_coverage\spice\metakernel.py:109, in MetaKernel.__enter__(self)
    102 if self._tmp_mk is None:
    103     self._tmp_mk = NamedTemporaryFile(
    104         'w',
    105         prefix=self.fname.stem + '-',
    106         suffix='.tm',
    107         delete=False,
    108     )
--> 109     self._tmp_mk.write(self.content)
    110     self._tmp_mk.seek(0)
    112 return self._tmp_mk.name

File c:\Users\luca_\code\.venv\lib\site-packages\planetary_coverage\spice\metakernel.py:207, in MetaKernel.content(self)
    204 if 'PATH_VALUES' not in self.data:
    205     return self.__content
--> 207 return re.sub(
    208     r' *PATH_VALUES\s*=\s*\(\s*[\w\'\_\-\.]+\s*\)',
    209     format_data(path_values=self.data['PATH_VALUES']),
    210     self.__content)

File C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\lib\re.py:209, in sub(pattern, repl, string, count, flags)
    202 def sub(pattern, repl, string, count=0, flags=0):
    203     """Return the string obtained by replacing the leftmost
    204     non-overlapping occurrences of the pattern in string by the
    205     replacement repl.  repl can be either a string or a callable;
    206     if a string, backslash escapes in it are processed.  If it is
    207     a callable, it's passed the Match object and must return
    208     a replacement string to be used."""
--> 209     return _compile(pattern, flags).sub(repl, string, count)

File C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\lib\re.py:326, in _subx(pattern, template)
    324 def _subx(pattern, template):
    325     # internal: Pattern.sub/subn implementation helper
--> 326     template = _compile_repl(template, pattern)
    327     if not template[0] and len(template[1]) == 1:
    328         # literal replacement
    329         return template[1][0]

File C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\lib\re.py:317, in _compile_repl(repl, pattern)
    314 @functools.lru_cache(_MAXCACHE)
    315 def _compile_repl(repl, pattern):
    316     # internal: compile replacement pattern
--> 317     return sre_parse.parse_template(repl, pattern)

File C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\lib\sre_parse.py:1054, in parse_template(source, state)
   1052         except KeyError:
   1053             if c in ASCIILETTERS:
-> 1054                 raise s.error('bad escape %s' % this, len(this))
   1055         lappend(this)
   1056 else:

error: bad escape \U at position 23

suspect the key is at planetary_coverage\spice\metakernel.py:207 where

re.sub(
    208     r' *PATH_VALUES\s*=\s*\(\s*[\w\'\_\-\.]+\s*\)',
    209     format_data(path_values=self.data['PATH_VALUES']),
    210     self.__content)

might require additional escaping for python on windows, but it would require more investigation