assignment-codeval 0.0.27__tar.gz → 0.0.28__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/PKG-INFO +1 -1
  2. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/pyproject.toml +1 -1
  3. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval/check_grading.py +1 -1
  4. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval/convertMD2Html.py +49 -15
  5. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval.egg-info/PKG-INFO +1 -1
  6. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/README.md +0 -0
  7. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/setup.cfg +0 -0
  8. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval/__init__.py +0 -0
  9. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval/ai_benchmark.py +0 -0
  10. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval/canvas_utils.py +0 -0
  11. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval/cli.py +0 -0
  12. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval/commons.py +0 -0
  13. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval/create_assignment.py +0 -0
  14. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval/evaluate.py +0 -0
  15. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval/export_tests.py +0 -0
  16. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval/file_utils.py +0 -0
  17. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval/github_connect.py +0 -0
  18. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval/install_assignment.py +0 -0
  19. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval/recent_comments.py +0 -0
  20. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval/submissions.py +0 -0
  21. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval/test_template.html +0 -0
  22. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval.egg-info/SOURCES.txt +0 -0
  23. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval.egg-info/dependency_links.txt +0 -0
  24. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval.egg-info/entry_points.txt +0 -0
  25. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval.egg-info/requires.txt +0 -0
  26. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/src/assignment_codeval.egg-info/top_level.txt +0 -0
  27. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/tests/test_check_grading.py +0 -0
  28. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/tests/test_codeval.py +0 -0
  29. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/tests/test_create_assignment.py +0 -0
  30. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/tests/test_evaluate_submissions.py +0 -0
  31. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/tests/test_export_tests.py +0 -0
  32. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/tests/test_function_detection.py +0 -0
  33. {assignment_codeval-0.0.27 → assignment_codeval-0.0.28}/tests/test_install_assignment.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: assignment-codeval
3
- Version: 0.0.27
3
+ Version: 0.0.28
4
4
  Summary: CodEval for evaluating programming assignments
5
5
  Requires-Python: >=3.12
6
6
  Description-Content-Type: text/markdown
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "assignment-codeval"
7
- version = "0.0.27"
7
+ version = "0.0.28"
8
8
  description = "CodEval for evaluating programming assignments"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -62,7 +62,7 @@ def _has_codeval_comment_after_submission(submission_node, codeval_prefix):
62
62
  comments = submission_node.get("commentsConnection", {}).get("nodes", [])
63
63
  for comment in comments:
64
64
  text = comment.get("comment", "")
65
- if not text.startswith(codeval_prefix):
65
+ if not text.startswith(codeval_prefix.rstrip()):
66
66
  continue
67
67
  created_at = comment.get("createdAt")
68
68
  if created_at and created_at > submitted_at:
@@ -1,5 +1,6 @@
1
1
  import os
2
2
  import re
3
+ import zipfile
3
4
 
4
5
  import markdown
5
6
 
@@ -41,19 +42,28 @@ def ansi_to_html(text):
41
42
  return ''.join(result)
42
43
 
43
44
 
44
- def _read_file_content(filename, spec_dir):
45
- """Read the content of a file referenced by an OF or IF tag."""
46
- if not spec_dir:
47
- return None
48
- filepath = os.path.join(spec_dir, filename)
49
- try:
50
- with open(filepath, 'r') as f:
51
- return f.read()
52
- except (FileNotFoundError, OSError):
53
- return None
45
+ def _read_file_content(filename, spec_dir, zip_archives=None):
46
+ """Read the content of a file referenced by an IF/OF/EF tag.
54
47
 
48
+ Searches local spec_dir first, then zip archives. Returns content as string.
49
+ """
50
+ if spec_dir:
51
+ filepath = os.path.join(spec_dir, filename)
52
+ try:
53
+ with open(filepath, 'r') as f:
54
+ return f.read()
55
+ except (FileNotFoundError, OSError):
56
+ pass
57
+ if zip_archives:
58
+ for zf in zip_archives:
59
+ try:
60
+ return zf.read(filename).decode('utf-8')
61
+ except KeyError:
62
+ continue
63
+ return None
55
64
 
56
- def sampleTestCases(listOfTC, numOfTC, spec_dir=None):
65
+
66
+ def sampleTestCases(listOfTC, numOfTC, spec_dir=None, zip_archives=None):
57
67
  counter = 0
58
68
  samples = "<pre><code>"
59
69
  for line in listOfTC:
@@ -64,7 +74,7 @@ def sampleTestCases(listOfTC, numOfTC, spec_dir=None):
64
74
  samples = samples + "\n" + "Command to RUN: " + line[2:]
65
75
  elif line.startswith('IF '):
66
76
  filename = line[3:].strip()
67
- content = _read_file_content(filename, spec_dir)
77
+ content = _read_file_content(filename, spec_dir, zip_archives)
68
78
  if content is not None:
69
79
  samples = samples + "<span style=\"color:green\">" + ansi_to_html(content) + "</span>"
70
80
  else:
@@ -75,7 +85,7 @@ def sampleTestCases(listOfTC, numOfTC, spec_dir=None):
75
85
  samples = samples + "<span style=\"color:green\">" + line[2:] + "</span>"
76
86
  elif line.startswith('OF '):
77
87
  filename = line[3:].strip()
78
- content = _read_file_content(filename, spec_dir)
88
+ content = _read_file_content(filename, spec_dir, zip_archives)
79
89
  if content is not None:
80
90
  samples = samples + "<span style=\"color:blue\">" + ansi_to_html(content) + "</span>"
81
91
  else:
@@ -86,6 +96,13 @@ def sampleTestCases(listOfTC, numOfTC, spec_dir=None):
86
96
  samples = samples + "<span style=\"color:blue\">" + line[2:] + "</span>"
87
97
  elif line.startswith('X '):
88
98
  samples = samples + "Expected Exit Code: " + line[2:]
99
+ elif line.startswith('EF '):
100
+ filename = line[3:].strip()
101
+ content = _read_file_content(filename, spec_dir, zip_archives)
102
+ if content is not None:
103
+ samples = samples + "<span style=\"color:Tomato\">" + ansi_to_html(content) + "</span>"
104
+ else:
105
+ samples = samples + "<span style=\"color:Tomato\">Expected error from file: " + filename + "\n</span>"
89
106
  elif line.startswith('EB '):
90
107
  samples = samples + "<span style=\"color:Tomato\">" + line[3:] + "</span>"
91
108
  elif line.startswith('E '):
@@ -104,24 +121,41 @@ def mdToHtml(file_name, files_resolver=None):
104
121
  compile_command = ""
105
122
  past_crt_hw = False
106
123
  numOfSampleTC = 1
124
+ zip_paths = []
107
125
  for line in f:
108
126
  if 'CRT_HW START' in line:
109
127
  assignment_name = line[13:].strip()
110
128
  elif 'CRT_HW END' in line:
111
129
  assignment = text
112
130
  past_crt_hw = True
113
- elif line.startswith(('T ', 'I ', 'IB ', 'IF ', 'O ', 'OB ', 'OF ', 'X ', 'E ', 'EB ')):
131
+ elif line.startswith(('T ', 'I ', 'IB ', 'IF ', 'O ', 'OB ', 'OF ',
132
+ 'EF ', 'X ', 'E ', 'EB ')):
114
133
  examples.append(line)
115
134
  elif line.startswith('HT '):
116
135
  break
117
136
  else:
118
137
  if past_crt_hw and line.startswith('C '):
119
138
  compile_command = line[2:].strip()
139
+ if past_crt_hw and line.startswith('Z '):
140
+ zip_paths.append(line[2:].strip())
120
141
  if 'EXMPLS ' in line:
121
142
  numOfSampleTC = int(line[7:])
122
143
  text = text + line
123
144
  spec_dir = os.path.dirname(os.path.abspath(file_name))
124
- samples = sampleTestCases(examples, numOfSampleTC, spec_dir)
145
+
146
+ # Open zip archives for IF/OF/EF file resolution
147
+ zip_archives = []
148
+ try:
149
+ for zp in zip_paths:
150
+ full_path = os.path.join(spec_dir, zp)
151
+ if os.path.exists(full_path):
152
+ zip_archives.append(zipfile.ZipFile(full_path, 'r'))
153
+ samples = sampleTestCases(examples, numOfSampleTC, spec_dir,
154
+ zip_archives)
155
+ finally:
156
+ for zf in zip_archives:
157
+ zf.close()
158
+
125
159
  assignment = re.sub('EXMPLS [0-9]+', samples, assignment)
126
160
  if compile_command:
127
161
  assignment = assignment.replace('COMPILE', compile_command)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: assignment-codeval
3
- Version: 0.0.27
3
+ Version: 0.0.28
4
4
  Summary: CodEval for evaluating programming assignments
5
5
  Requires-Python: >=3.12
6
6
  Description-Content-Type: text/markdown