curry.cache module

Implements a cache for Curry-to-ICurry and JSON-to-Python conversions.

This cache supplements the filesystem caching in .curry files so that interactive statements can also be cached. This exists because the conversions can be extremely slow depending on the Curry system used and its configuration.

The Curry-to-ICurry cache is keyed by content, not by file name: an entry is found again from any directory and, for an anonymous module, under any module name. An entry holds the ICurry text of the module and the texts of the two interface files the front end wrote for it, which travel with the ICurry (see INTERFACE_SUFFIXES). An error the front end reports about the program is cached as well. See Curry2ICurryCache and icurry_cache_key.

Environment Variables:

SPRITE_CACHE_FILE

Specifies the cache file. A file name turns the Curry-to-ICurry cache on. The empty string disables caching. When the variable is not set, the settings of the installation apply (see Make.config).

SPRITE_CACHE_UPDATE

Specifies a glob or regex pattern. Matching files are considered out-of-date by the cache, so are updated. The pattern is considered a regex if it begins and ends with slashes. For the Curry-to-ICurry cache the pattern is compared with the name of the Curry source file.

class curry.cache.Curry2ICurryCache[source]

Bases: object

Coordinates caching for the Curry -> ICurry conversion.

The table curry2icurry_<format> of the cache file stores one row per key (see icurry_cache_key): the module name the front end wrote, the text of the ICurry file, and the texts of the two interface files beside it (the columns fint and icurry; see INTERFACE_SUFFIXES), or, for a program the front end rejected, the module name and the error text. An interface the front end did not write is NULL. Counts of the hits and the misses of this process are kept in stats; a replayed error counts as a hit.

class Slot(file_in, file_out, currypath=(), options=(), tool=None)[source]

Bases: object

Clients create an instance with a pair of file names indicating the input and output files. The output file should be created or updated from the input. If the conversion is cached, it will be written to the second file, the interface files will be written beside it (see interface_filename; an empty file for a NULL column), and this object will evaluate to True. If a program error is cached, the object evaluates to False and error holds the error text. Otherwise, the contents of the second file and of the interface files beside it should be generated by other means, and, afterwards, update should be called to tell the cache to read those files and update its entry, or update_error with the exception of the front end.

update()[source]

Reads the output file and the interface files beside it, and stores them under the key. An interface file that is missing or empty is stored as NULL.

update_error(err)[source]

Stores the failure of the front end, when err (the CompileError of _system.pexec) reports an error of the program. Another failure is not stored.

TABLE = 'curry2icurry_3'
stats = {'hit': 0, 'miss': 0}
class curry.cache.ParsedJsonCache[source]

Bases: object

class Slot(jsonfile)[source]

Bases: object

Caches the parsing of ICurry-JSON into Python. The pickled Python representation is stored.

update(icur)[source]
static select(like=None)[source]
curry.cache.enabled()[source]

Whether a cache file is in use.

curry.cache.filename()[source]

Returns the name of the cache file or None.

curry.cache.icurry_cache_enabled()[source]

Whether the Curry-to-ICurry cache is on. A file named by SPRITE_CACHE_FILE turns it on. The empty string turns it off. Otherwise the installation decides (ENABLE_ICURRY_CACHE in Make.config).

curry.cache.icurry_cache_key(curryfile, currypath=(), options=(), tool=None)[source]

The key under which the ICurry of curryfile is cached.

The key is a digest of the source text of the module, the source texts of the modules it imports (see import_closure), the front-end options, the route from Curry to ICurry with its program and flags (see frontend_digest) and the version of its steps (see route_version), and the intermediate subdirectory, which names the version of the Curry library. The directory of the file is not part of the key. The module name is part of the key for a named module, because the front end writes it into the ICurry. For an anonymous module (see config.is_anonymous_modname) the name is left out, and the cached text is renamed on a hit.

Parameters:
  • curryfile – The Curry source file.

  • currypath – The Curry search path used for the conversion.

  • options – The front-end options that change its output.

  • tool – The route from Curry to ICurry, frontend or icurry. The configured route by default.

Returns:

A hex digest.

curry.cache.import_closure(curryfile, currypath=())[source]

Finds the modules that curryfile imports, transitively, as Curry source files in the Curry path. The Prelude is implicit. A module without a source file in the path (a library of the Curry system) is left out. The directory of curryfile is searched first.

Returns:

A dict from module name to SourceInfo.

curry.cache.interface_filename(icyfile, suffix)[source]

The interface file with suffix beside the ICurry file icyfile.

curry.cache.is_program_error(stderr)[source]

Tells whether the standard error of the front end reports an error of the program: an error at a source position, other than a missing import.

curry.cache.rename_in_message(text, old, new)[source]

Renames a module in a message of the front end, word by word.

curry.cache.rename_module(text, old, new)[source]

Renames the module of an ICurry text, a FlatCurry interface (.fint), or a Curry interface (.icurry) from old to new.

In an ICurry text and in a FlatCurry interface the front end writes the module name into the header (IProg, Prog), into qualified names ("module","name",n), into the module part of a generated name such as _inst#Prelude.Show#module.T, and into the name of an external function "module.f". In every case the name follows a double quote or a hash sign, and a double quote or a dot follows it. A string literal of the program cannot match: ICurry spells it as a list of characters, and an interface holds no literal. A Curry interface names its own module once, in the header interface module where; the names it declares are unqualified, and the names of other modules are qualified by those modules.

The caller must make sure that no other module named in the text has old plus a dot as a prefix. Anonymous modules satisfy this.

curry.cache.reset()[source]

Forgets the cache file, the update pattern, the database connection, and the digests of the routes. The next use reads the environment again.

curry.cache.route_version()[source]

The version of the steps between the front end and the translation (ROUTE_VERSION of curry.toolchain._frontend), part of the key of the ICurry cache. The digest of the route sees the programs, the flags and the sources of the translation and of the binding optimization, not the step that applies the pass to the FlatCurry file: a step that joins the route or changes what it writes changes the key through this number (issue #101). The product cache does without it: its key digests the ICurry text itself.

curry.cache.write_file(filename, content)[source]

Writes content, a text or bytes, to filename through a temporary file in the same directory, so a reader never sees a partial file. The directory is created. The file gets the mode a plain open would give it, not the private mode of the temporary file.