diff options
| author | jwansek <eddie.atten.ea29@gmail.com> | 2022-01-22 20:34:02 +0000 | 
|---|---|---|
| committer | jwansek <eddie.atten.ea29@gmail.com> | 2022-01-22 20:34:02 +0000 | 
| commit | 4e218b3c10fe61f5bc9a83183bd584927e37b1ec (patch) | |
| tree | 3b5ba0d7cf179e3a4d14cbfaa21ff5a31340057f | |
| parent | 4f0dde8e96bf504887cfa4cc6b3c1df85364a329 (diff) | |
| download | Smarker-4e218b3c10fe61f5bc9a83183bd584927e37b1ec.tar.gz Smarker-4e218b3c10fe61f5bc9a83183bd584927e37b1ec.zip | |
worked on handling and showing exceptions in client clode
| -rw-r--r-- | ExampleAssessments/CMP-4009B.yml | 6 | ||||
| -rw-r--r-- | ExampleAssessments/example.yml | 6 | ||||
| -rw-r--r-- | mark.py | 30 | ||||
| -rw-r--r-- | pdLine.png | bin | 0 -> 49362 bytes | |||
| -rw-r--r-- | pdResult.txt | 10 | ||||
| -rw-r--r-- | reflect.py | 25 | ||||
| -rw-r--r-- | templates/txt.jinja2 | 13 | 
7 files changed, 84 insertions, 6 deletions
| diff --git a/ExampleAssessments/CMP-4009B.yml b/ExampleAssessments/CMP-4009B.yml index c01979b..2e5c564 100644 --- a/ExampleAssessments/CMP-4009B.yml +++ b/ExampleAssessments/CMP-4009B.yml @@ -57,4 +57,8 @@ files:                      - serviceDue(2)                      - serviceAt(2)                      - powerAt(2) -                 +dependencies: +    libraries: +        - matplotlib +    files: +        - ../wsData.txt   diff --git a/ExampleAssessments/example.yml b/ExampleAssessments/example.yml index 46cab56..be1609f 100644 --- a/ExampleAssessments/example.yml +++ b/ExampleAssessments/example.yml @@ -36,4 +36,8 @@ files:                  assert nibbles.speak() == "nyaa~~"
              - |
                  milton = animals.Dog()
 -                assert milton.move() == "*moves*"
\ No newline at end of file +                assert milton.move() == "*moves*"
 +dependencies:
 +    files:
 +        - ../wsData.txt
 +        - ../IncludeDirectory
\ No newline at end of file @@ -1,3 +1,4 @@ +from dataclasses import dataclass  import jinja_helpers  import configparser  import argparse @@ -5,10 +6,36 @@ import tempfile  import zipfile  import reflect  import jinja2 +import shutil  import yaml  import json  import os +@dataclass +class FileDependencies: +    assessment_struct:dict + +    def __enter__(self): +        try: +            for file_dep in self.assessment_struct["dependencies"]["files"]: +                if os.path.isfile(file_dep): +                    shutil.copy(file_dep, os.path.split(file_dep)[-1]) +                else: +                    shutil.copytree(file_dep, os.path.split(file_dep)[-1]) +                # print("%s --> %s" % (file_dep, os.path.join(os.getcwd(), os.path.split(file_dep)[-1]))) +        except KeyError: +            pass + +    def __exit__(self, type, value, traceback): +        try: +            for file_dep in self.assessment_struct["dependencies"]["files"]: +                if os.path.isfile(os.path.split(file_dep)[-1]): +                    os.remove(os.path.split(file_dep)[-1]) +                else: +                    shutil.rmtree(os.path.split(file_dep)[-1]) +        except KeyError: +            pass +  def main(**kwargs):      student_no = os.path.splitext(os.path.split(args["submission"])[-1])[0] @@ -27,7 +54,8 @@ def main(**kwargs):          with open(kwargs["assessment"], "r") as f:              assessment_struct = yaml.safe_load(f) -        output = reflect.gen_reflection_report(submission_files, assessment_struct, student_no, kwargs) +        with FileDependencies(assessment_struct): +            output = reflect.gen_reflection_report(submission_files, assessment_struct, student_no, kwargs)          output_file = kwargs["out"]          if kwargs["format"] == "yaml": diff --git a/pdLine.png b/pdLine.pngBinary files differ new file mode 100644 index 0000000..bd88e40 --- /dev/null +++ b/pdLine.png diff --git a/pdResult.txt b/pdResult.txt new file mode 100644 index 0000000..2ad813e --- /dev/null +++ b/pdResult.txt @@ -0,0 +1,10 @@ +2021-03-19 15:10:21 50.40 7680.0 8856.0 +2012-07-03 12:12:12 60.20 9173.33 10578.0 +2005-12-08 23:30:00 100.05 11910.71 13292.36 +2025-08-29 05:33:00 45.00 6857.14 7907.14 +2031-02-15 16:53:00 20.00 666.67 857.14 +1999-04-14 04:24:00 65.00 9904.76 11421.43 +2045-07-09 20:44:00 56.00 8533.33 9840.0 +2024-11-01 09:05:00 32.00 3504.76 2811.43 +2008-02-21 13:19:00 75.45 11497.14 13257.64 +2014-06-05 14:10:00 80.09 12204.19 14072.96 @@ -4,6 +4,7 @@ from functools import reduce  from operator import getitem  import subprocess  import importlib +import traceback  import tempfile  import inspect  import pkgutil @@ -40,6 +41,9 @@ class Reflect:                      print("Missing library dependency for client module:")                      print(e)                      exit() +                # except Exception as e: +                #     print("CRITICAL ERROR IN CLIENT CODE - CANNOT CONTINUE") +                #     raise ClientCodeException(e)      def get_module_doc(self, module_name):          """Gets the documentation provided for a module. @@ -196,8 +200,11 @@ class Reflect:          with tempfile.TemporaryDirectory() as tmp:              junitxmlpath = os.path.join(tmp, "report.xml") -            cmd = ["pytest", "-v"] + [os.path.join(self.client_code_path, "test_%s" % f) for f in tests.keys()] + ["--junitxml=%s" % junitxmlpath] -            #print(" ".join(cmd)) +            test_files = [os.path.join(self.client_code_path, "test_%s" % f) for f in tests.keys()] +            cmd = ["pytest", "-v"] + test_files + ["--junitxml=%s" % junitxmlpath] +            if test_files == []: +                test_results["pytest_report"] = "*** No Tests ***" +                return test_results              proc = subprocess.Popen(cmd, stdout = subprocess.PIPE)              while True:                  line = proc.stdout.readline() @@ -236,8 +243,20 @@ def gen_reflection_report(client_code_path, assessment_struct, student_no, confi              out["files"][i][required_file]["present"] = False              continue -        reflection.import_module(module_name) +        try: +            reflection.import_module(module_name) +        except Exception as e: +            out["files"][i][required_file]["has_exception"] = True +            out["files"][i][required_file]["exception"] = {} +            out["files"][i][required_file]["exception"]["type"] = str(type(e)) +            out["files"][i][required_file]["exception"]["str"] = str(e) +            # TODO: work out how to only get the exception stack of the client code +            out["files"][i][required_file]["exception"]["traceback"] = ''.join(traceback.format_exception(None, e, e.__traceback__)) + +            continue +          required_files_features = assessment_struct["files"][i][required_file] +        out["files"][i][required_file]["has_exception"] = False          out["files"][i][required_file]["documentation"] = reflection.get_module_doc(module_name)          if "classes" in required_files_features.keys(): diff --git a/templates/txt.jinja2 b/templates/txt.jinja2 index d6a0c16..0a9cdb5 100644 --- a/templates/txt.jinja2 +++ b/templates/txt.jinja2 @@ -9,6 +9,18 @@  {% for filename, files_contents in flat_files.items() %}      = {{ filename + " =" -}}      {%- if files_contents["present"] -%} +    {%- if files_contents["has_exception"] %} +        *** File cannot be run - has compile time exception *** +        Please note that this file cannot be analysed or have tests preformed upon it +        Exception Type: +            {{ files_contents["exception"]["type"] }} +        Exception String: +            {{ files_contents["exception"]["str"] }} +        Full Traceback: +``` +{{ files_contents["exception"]["traceback"] }} +``` +    {%- else -%}      {% if "classes" in files_contents.keys() %}          Classes:          {%- set flat_classes = flatten_struct(files_contents["classes"]) -%} @@ -58,6 +70,7 @@              {%- endif %}          {%- endfor -%}      {%- endif -%} +    {%- endif -%}      {% else %}          *** File not present ***      {% endif %} | 
