codingame_tools.puzzle_manager.resolver¶
resolver
¶
Discovery of the puzzle working directory--analogous to
codingame_tools.contribution_manager.resolver, and just as simple: no upward search, no
global per-user fallback. A puzzle working directory is a local, per-task thing, not shared/
global state.
CG_PUZZLE_DIR_ENV_VAR
module-attribute
¶
CG_PUZZLE_DIR_ENV_VAR = 'CG_PUZZLE_DIR'
Environment variable that can override puzzle-dir discovery, same as an explicit
--puzzle-dir CLI flag (parsing/wiring that flag is the CLI layer's job--this module just
accepts the resolved explicit value).
DEFAULT_PUZZLE_SUBDIR_NAME
module-attribute
¶
DEFAULT_PUZZLE_SUBDIR_NAME = 'puzzle'
Name of the subdirectory of the current directory checked as a last-resort discovery step.
CgPuzzleDirNotFoundError
¶
CgPuzzleDirNotFoundError()
Bases: Exception
Raised by resolve_puzzle_dir() (unless allow_default=True) when no puzzle working
directory could be located by any discovery step. Does not indicate a bug--this is the
normal outcome before a puzzle has been imported in the current directory.
Source code in codingame_tools/puzzle_manager/resolver.py
43 44 45 46 47 48 | |
CgPuzzleDirInferenceError
¶
Bases: Exception
Raised by infer_puzzle_dir when target_file doesn't resolve into a puzzle working
directory.
find_puzzle_dir
¶
find_puzzle_dir(explicit=None, *, settings=None, start_dir=None)
Locate the puzzle working directory to use, following the documented discovery precedence:
1. `explicit` (typically the resolved value of a `--puzzle-dir` CLI flag), if given.
2. The `CG_PUZZLE_DIR` environment variable, if set.
3. `settings.current_puzzle_dir`--the *active* working directory, set by
`cg puzzle import`/`create` and `cg puzzle activate`. Outranks the configured default
below so that creating a working directory somewhere isn't silently overridden by a
standing `puzzle_dir` preference pointing elsewhere.
4. `settings.puzzle_dir` (see `CgSettings.puzzle_dir`), if given and set.
5. `start_dir` (or the current directory, if not given), if it contains a `puzzle.json`.
6. `start_dir / "puzzle"`, if it contains a `puzzle.json`.
Steps 1-4 are taken at face value--the resolved directory need not contain a puzzle.json
yet (e.g. before the first cg puzzle import). Steps 5-6 are implicit inference and are
deliberately conservative: they only match if a puzzle.json is actually already there.
Returns:
-
Path | None–The resolved puzzle directory path, or None if nothing was found at all. This function
-
Path | None–never creates anything.
Source code in codingame_tools/puzzle_manager/resolver.py
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | |
resolve_puzzle_dir
¶
resolve_puzzle_dir(explicit=None, *, settings=None, start_dir=None, allow_default=False)
Locate the puzzle working directory, following the discovery precedence documented on
find_puzzle_dir.
If allow_default is True and no directory can be found, falls back to
start_dir / "puzzle" (or ./puzzle under the current directory)--useful for cg puzzle
import, which is happy to treat "nothing found" as "start a fresh working directory
there". Deliberately not bare start_dir/cwd itself--unlike a contribution working
directory (whose own import always requires an explicit target directory, so its
resolver's allow_default fallback is never actually exercised in practice), cg puzzle
import relies on this fallback for its everyday no-argument usage, and dropping
puzzle.json/data/ directly into whatever the current directory happens to be would be
a real footgun--confirmed live (2026-07-30): an earlier version of this fell back to bare
cwd and did exactly that. submit()-style callers, where there must already be a working
directory, should leave allow_default False.
Raises:
-
CgPuzzleDirNotFoundError–if no directory could be located anywhere, and
allow_defaultis False.
Source code in codingame_tools/puzzle_manager/resolver.py
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | |
infer_puzzle_dir
¶
infer_puzzle_dir(target_file)
Infer a puzzle working directory's root from a solution file somewhere within it--e.g. VS
Code's ${file} macro, however many symlink hops away from data/solution.src it might
be (a puzzle working directory's own solution.<ext> convenience symlink, or some other
symlink elsewhere entirely that a user set up themselves--see codingame_tools.
puzzle_manager.manager's module docstring). The only two things ever promised about
target_file: a debugger's breakpoints bind to whatever path was actually open in the
editor (so this function must not need that path to be anything in particular), and
resolving every symlink in it always eventually lands on data/solution.src.
So this isn't a search: fully resolving target_file (following every symlink to its real
target) always lands on <root>/data/solution.src--DATA_SUBDIR_NAME/SOLUTION_FILE_NAME
are fixed constants, not configurable--so <root> is deterministically two path segments
up from there. Confirmed by requiring puzzle.json to actually exist at that root, so a
target_file that isn't part of any puzzle working directory at all fails clearly rather
than returning a nonsense path.
Raises:
-
CgPuzzleDirInferenceError–if
target_file, once fully resolved, isn't.../data/solution.src, orpuzzle.jsonisn't present at the inferred root.
Source code in codingame_tools/puzzle_manager/resolver.py
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | |