diff --git a/devel/moth.py b/devel/moth.py index 1875bd7..de6456b 100644 --- a/devel/moth.py +++ b/devel/moth.py @@ -2,6 +2,7 @@ import argparse import contextlib +import copy import glob import hashlib import html @@ -11,6 +12,7 @@ import mistune import os import random import string +import sys import tempfile import shlex import yaml @@ -27,9 +29,25 @@ def djb2hash(str): def pushd(newdir): curdir = os.getcwd() os.chdir(newdir) + + # Force a copy of the old path, instead of just a reference + old_path = list(sys.path) + old_modules = copy.copy(sys.modules) + sys.path.append(newdir) + try: yield finally: + # Restore the old path + to_remove = [] + for module in sys.modules: + if module not in old_modules: + to_remove.append(module) + + for module in to_remove: + del(sys.modules[module]) + + sys.path = old_path os.chdir(curdir) @@ -363,7 +381,7 @@ class Puzzle: files = [fn for fn,f in self.files.items() if f.visible] return { - 'authors': self.authors, + 'authors': self.get_authors(), 'hashes': self.hashes(), 'files': files, 'scripts': self.scripts, @@ -411,7 +429,8 @@ class Category: with pushd(self.path): self.catmod.make(points, puzzle) else: - puzzle.read_directory(path) + with pushd(self.path): + puzzle.read_directory(path) return puzzle def __iter__(self): diff --git a/example-puzzles/example/200/puzzle.py b/example-puzzles/example/200/puzzle.py new file mode 100755 index 0000000..cfb9614 --- /dev/null +++ b/example-puzzles/example/200/puzzle.py @@ -0,0 +1,19 @@ +import io +import categorylib # Category-level libraries can be imported here + +def make(puzzle): + import puzzlelib # puzzle-level libraries can only be imported inside of the make function + puzzle.authors = ['donaldson'] + puzzle.summary = 'more crazy stuff you can do with puzzle generation using Python libraries' + + puzzle.body.write("## Crazy Things You Can Do With Puzzle Generation (part II)\n") + puzzle.body.write("\n") + puzzle.body.write("The source to this puzzle has some more advanced examples of stuff you can do in Python.\n") + puzzle.body.write("\n") + puzzle.body.write("1 == %s\n\n" % puzzlelib.getone(),) + puzzle.body.write("2 == %s\n\n" % categorylib.gettwo(),) + + puzzle.answers.append('tea') + answer = puzzle.make_answer() # Generates a random answer, appending it to puzzle.answers too + puzzle.log("Answers: {}".format(puzzle.answers)) + diff --git a/example-puzzles/example/200/puzzlelib.py b/example-puzzles/example/200/puzzlelib.py new file mode 100644 index 0000000..566be76 --- /dev/null +++ b/example-puzzles/example/200/puzzlelib.py @@ -0,0 +1,7 @@ +"""This is an example of a puzzle-level library. + +This library can be imported by sibling puzzles using `import puzzlelib` +""" + +def getone(): + return 1 diff --git a/example-puzzles/example/categorylib.py b/example-puzzles/example/categorylib.py new file mode 100644 index 0000000..fb5a230 --- /dev/null +++ b/example-puzzles/example/categorylib.py @@ -0,0 +1,7 @@ +"""This is an example of a category-level library. + +This library can be imported by child puzzles using `import categorylib` +""" + +def gettwo(): + return 2