Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_leak(self):
with open("leak.c", "w") as f:
src = '#include \n'\
'void leak() {malloc(sizeof(int));}\n'\
'int main() {\n'\
' leak();\n'\
'}'
f.write(src)
check50.c.compile("leak.c")
with self.assertRaises(check50.Failure):
with check50.internal.register:
check50.c.valgrind("./leak").exit()
def test_after_check(self):
check50.internal.check_running = True
l = []
check50.internal.register.after_check(lambda : l.append("foo"))
with check50.internal.register:
self.assertEqual(l, [])
self.assertEqual(l, ["foo"])
with check50.internal.register:
self.assertEqual(l, ["foo"])
self.assertEqual(l, ["foo"])
check50.internal.check_running = False
def __call__(self):
mod = importlib.util.module_from_spec(self.spec)
self.spec.loader.exec_module(mod)
internal.check_running = True
try:
return getattr(mod, self.check_name)(self.checks_root, self.state)
finally:
internal.check_running = False
# Ensure that we don't get duplicate error messages.
reported = set()
for error in xml.iterfind("error"):
# Type of error valgrind encountered
kind = error.find("kind").text
# Valgrind's error message
what = error.find("xwhat/text" if kind.startswith("Leak_") else "what").text
# Error message that we will report
msg = ["\t", what]
# Find first stack frame within student's code.
for frame in error.iterfind("stack/frame"):
obj = frame.find("obj")
if obj is not None and internal.run_dir in Path(obj.text).parents:
file, line = frame.find("file"), frame.find("line")
if file is not None and line is not None:
msg.append(f": ({_('file')}: {file.text}, {_('line')}: {line.text})")
break
msg = "".join(msg)
if msg not in reported:
log(msg)
reported.add(msg)
# Only raise exception if we encountered errors.
if reported:
raise Failure(_("valgrind tests failed; rerun with --log for more information."))
if not internal.check_dir.is_dir():
raise internal.Error(_("{} is not a directory").format(internal.check_dir))
else:
# Otherwise have lib50 create a local copy of slug
try:
internal.check_dir = lib50.local(SLUG, offline=args.offline)
except lib50.ConnectionError:
raise internal.Error(_("check50 could not retrieve checks from GitHub. Try running check50 again with --offline.").format(SLUG))
except lib50.InvalidSlugError:
raise_invalid_slug(SLUG, offline=args.offline)
# Load config
config = internal.load_config(internal.check_dir)
# Compile local checks if necessary
if isinstance(config["checks"], dict):
config["checks"] = internal.compile_checks(config["checks"], prompt=args.dev)
install_translations(config["translations"])
if not args.offline:
install_dependencies(config["dependencies"], verbose=args.verbose)
checks_file = (internal.check_dir / config["checks"]).resolve()
# Have lib50 decide which files to include
included = lib50.files(config.get("files"))[0]
# Only open devnull conditionally
ctxmanager = open(os.devnull, "w") if not args.verbose else nullcontext()
with ctxmanager as devnull:
if args.verbose:
stdout = sys.stdout
# Show lib50 commands being run in verbose mode
logging.basicConfig(level=os.environ.get("CHECK50_LOGLEVEL", "INFO"))
lib50.ProgressBar.DISABLED = True
args.log = True
# Filter out any duplicates from args.output
seen_output = set()
args.output = [output for output in args.output if not (output in seen_output or seen_output.add(output))]
# Set excepthook
excepthook.verbose = args.verbose
excepthook.outputs = args.output
excepthook.output_file = args.output_file
if not args.local:
commit_hash = lib50.push("check50", SLUG, internal.CONFIG_LOADER, data={"check50": True})[1]
with lib50.ProgressBar("Waiting for results") if "ansi" in args.output else nullcontext():
tag_hash, results = await_results(commit_hash, SLUG)
else:
with lib50.ProgressBar("Checking") if not args.verbose and "ansi" in args.output else nullcontext():
# If developing, assume slug is a path to check_dir
if args.dev:
internal.check_dir = Path(SLUG).expanduser().resolve()
if not internal.check_dir.is_dir():
raise internal.Error(_("{} is not a directory").format(internal.check_dir))
else:
# Otherwise have lib50 create a local copy of slug
try:
internal.check_dir = lib50.local(SLUG, offline=args.offline)
except lib50.ConnectionError:
raise internal.Error(_("check50 could not retrieve checks from GitHub. Try running check50 again with --offline.").format(SLUG))
except lib50.InvalidSlugError:
:raises yaml.YAMLError: if ``path / .check50.yaml`` is not a valid YAML file
This function is particularly useful when a set of checks logically extends
another, as is often the case in CS50's own problems that have a "less comfy"
and "more comfy" version. The "more comfy" version can include all of the
"less comfy" checks like so::
less = check50.import_checks("../less")
from less import *
.. note::
the ``__name__`` of the imported module is given by the basename
of the specified path (``less`` in the above example).
"""
dir = internal.check_dir / path
file = internal.load_config(dir)["checks"]
mod = internal.import_file(dir.name, (dir / file).resolve())
sys.modules[dir.name] = mod
return mod