Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8ab4c3b

Browse files
authored
Merge pull request #1189 from lark-parser/pr1179
Minor adjustments to PR #1179
2 parents ed53bfd + c02d912 commit 8ab4c3b

File tree

2 files changed

+44
-27
lines changed

2 files changed

+44
-27
lines changed

lark/lark.py

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from abc import ABC, abstractmethod
2+
import getpass
23
import sys, os, pickle, hashlib
34
import tempfile
45
import types
@@ -308,28 +309,38 @@ def __init__(self, grammar: 'Union[Grammar, str, IO[str]]', **options) -> None:
308309
if self.options.cache is not True:
309310
raise ConfigurationError("cache argument must be bool or str")
310311

311-
cache_fn = tempfile.gettempdir() + '/.lark_cache_%s_%s_%s.tmp' % (cache_md5, *sys.version_info[:2])
312-
313-
if FS.exists(cache_fn):
314-
logger.debug('Loading grammar from cache: %s', cache_fn)
315-
# Remove options that aren't relevant for loading from cache
316-
for name in (set(options) - _LOAD_ALLOWED_OPTIONS):
317-
del options[name]
312+
try:
313+
username = getpass.getuser()
314+
except Exception:
315+
# The exception raised may be ImportError or OSError in
316+
# the future. For the cache, we don't care about the
317+
# specific reason - we just want a username.
318+
username = "unknown"
319+
320+
cache_fn = tempfile.gettempdir() + "/.lark_cache_%s_%s_%s_%s.tmp" % (username, cache_md5, *sys.version_info[:2])
321+
322+
old_options = self.options
323+
try:
318324
with FS.open(cache_fn, 'rb') as f:
319-
old_options = self.options
320-
try:
321-
file_md5 = f.readline().rstrip(b'\n')
322-
cached_used_files = pickle.load(f)
323-
if file_md5 == cache_md5.encode('utf8') and verify_used_files(cached_used_files):
324-
cached_parser_data = pickle.load(f)
325-
self._load(cached_parser_data, **options)
326-
return
327-
except Exception: # We should probably narrow done which errors we catch here.
328-
logger.exception("Failed to load Lark from cache: %r. We will try to carry on." % cache_fn)
329-
330-
# In theory, the Lark instance might have been messed up by the call to `_load`.
331-
# In practice the only relevant thing that might have been overriden should be `options`
332-
self.options = old_options
325+
logger.debug('Loading grammar from cache: %s', cache_fn)
326+
# Remove options that aren't relevant for loading from cache
327+
for name in (set(options) - _LOAD_ALLOWED_OPTIONS):
328+
del options[name]
329+
file_md5 = f.readline().rstrip(b'\n')
330+
cached_used_files = pickle.load(f)
331+
if file_md5 == cache_md5.encode('utf8') and verify_used_files(cached_used_files):
332+
cached_parser_data = pickle.load(f)
333+
self._load(cached_parser_data, **options)
334+
return
335+
except FileNotFoundError:
336+
# The cache file doesn't exist; parse and compose the grammar as normal
337+
pass
338+
except Exception: # We should probably narrow done which errors we catch here.
339+
logger.exception("Failed to load Lark from cache: %r. We will try to carry on.", cache_fn)
340+
341+
# In theory, the Lark instance might have been messed up by the call to `_load`.
342+
# In practice the only relevant thing that might have been overwritten should be `options`
343+
self.options = old_options
333344

334345

335346
# Parse the grammar file and compose the grammars
@@ -421,11 +432,14 @@ def __init__(self, grammar: 'Union[Grammar, str, IO[str]]', **options) -> None:
421432

422433
if cache_fn:
423434
logger.debug('Saving grammar to cache: %s', cache_fn)
424-
with FS.open(cache_fn, 'wb') as f:
425-
assert cache_md5 is not None
426-
f.write(cache_md5.encode('utf8') + b'\n')
427-
pickle.dump(used_files, f)
428-
self.save(f, _LOAD_ALLOWED_OPTIONS)
435+
try:
436+
with FS.open(cache_fn, 'wb') as f:
437+
assert cache_md5 is not None
438+
f.write(cache_md5.encode('utf8') + b'\n')
439+
pickle.dump(used_files, f)
440+
self.save(f, _LOAD_ALLOWED_OPTIONS)
441+
except IOError as e:
442+
logger.exception("Failed to save Lark to cache: %r.", cache_fn, e)
429443

430444
if __doc__:
431445
__doc__ += "\n\n" + LarkOptions.OPTIONS_DOC

tests/test_cache.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@ class MockFS:
2929
def __init__(self):
3030
self.files = {}
3131

32-
def open(self, name, mode=None):
32+
def open(self, name, mode="r", **kwargs):
3333
if name not in self.files:
34+
if "r" in mode:
35+
# If we are reading from a file, it should already exist
36+
raise FileNotFoundError(name)
3437
f = self.files[name] = MockFile()
3538
else:
3639
f = self.files[name]

0 commit comments

Comments
 (0)