From 8c56d4ddca5a290e929fe6727986776de0063c26 Mon Sep 17 00:00:00 2001 From: hrdg Date: Tue, 14 May 2019 17:32:43 +0800 Subject: [PATCH 1/2] chinese --- pythonwhat/checks/check_object.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pythonwhat/checks/check_object.py b/pythonwhat/checks/check_object.py index a3890d02..086b5c7d 100644 --- a/pythonwhat/checks/check_object.py +++ b/pythonwhat/checks/check_object.py @@ -161,7 +161,7 @@ def __init__(self, n): state.assert_root("check_object", extra_msg=extra_msg) if missing_msg is None: - missing_msg = "Did you define the {{typestr}} `{{index}}` without errors?" + missing_msg = " {{typestr}} `{{index}}` ?" if expand_msg is None: expand_msg = "Did you correctly define the {{typestr}} `{{index}}`? " From 66cacbb7f9a2c8bb6501eb39b5d1fdeadd82ff0a Mon Sep 17 00:00:00 2001 From: hrdg Date: Tue, 14 May 2019 20:43:12 +0800 Subject: [PATCH 2/2] change --- pythonwhat/.coveragerc | 2 + pythonwhat/.gitignore | 79 +++++++++++++++++++ pythonwhat/.travis.yml | 19 +++++ CHANGELOG.md => pythonwhat/CHANGELOG.md | 5 -- LICENSE => pythonwhat/LICENSE | 0 MANIFEST.in => pythonwhat/MANIFEST.in | 0 Makefile => pythonwhat/Makefile | 0 README.md => pythonwhat/README.md | 0 {docs => pythonwhat/docs}/Makefile | 0 .../articles/checking_compound_statements.rst | 0 .../articles/checking_function_calls.rst | 0 .../checking_through_string_matching.rst | 0 .../docs}/articles/electives.rst | 0 .../docs}/articles/expression_tests.rst | 0 .../docs}/articles/make_your_sct_robust.rst | 0 .../docs}/articles/processes.rst | 0 .../articles/single_process_exercise.rst | 0 .../docs}/articles/test_to_check.rst | 0 .../docs}/articles/tutorial.rst | 0 {docs => pythonwhat/docs}/conf.py | 7 +- {docs => pythonwhat/docs}/data_to_doc.py | 0 {docs => pythonwhat/docs}/glossary.rst | 0 {docs => pythonwhat/docs}/index.rst | 0 .../docs}/old/test_object_accessed.md | 0 {docs => pythonwhat/docs}/reference.rst | 0 {docs => pythonwhat/docs}/tests.rst | 0 pytest.ini => pythonwhat/pytest.ini | 0 pythonwhat/pythonwhat/Feedback.py | 21 +++++ pythonwhat/{ => pythonwhat}/State.py | 39 +++++---- pythonwhat/{ => pythonwhat}/Test.py | 14 ++-- pythonwhat/{ => pythonwhat}/__init__.py | 2 +- .../{ => pythonwhat}/checks/__init__.py | 0 .../{ => pythonwhat}/checks/check_funcs.py | 37 ++++++--- .../{ => pythonwhat}/checks/check_function.py | 20 +++-- .../checks/check_has_context.py | 3 +- .../{ => pythonwhat}/checks/check_logic.py | 39 ++------- .../{ => pythonwhat}/checks/check_object.py | 41 +++++----- .../{ => pythonwhat}/checks/check_wrappers.py | 53 +++++-------- .../{ => pythonwhat}/checks/has_funcs.py | 24 +++--- pythonwhat/{ => pythonwhat}/converters.py | 0 pythonwhat/{ => pythonwhat}/local.py | 4 +- pythonwhat/{ => pythonwhat}/parsing.py | 0 pythonwhat/{ => pythonwhat}/probe.py | 13 +-- pythonwhat/{ => pythonwhat}/sct_syntax.py | 0 pythonwhat/{ => pythonwhat}/signatures.py | 0 pythonwhat/{ => pythonwhat}/tasks.py | 0 pythonwhat/{ => pythonwhat}/test_exercise.py | 4 +- .../{ => pythonwhat}/test_funcs/__init__.py | 0 .../test_funcs/test_compound_statement.py | 43 +++++----- .../test_funcs/test_function.py | 10 +-- .../test_funcs/test_object.py | 7 -- .../test_funcs/test_object_accessed.py | 6 +- .../{ => pythonwhat}/test_funcs/utils.py | 8 +- pythonwhat/{ => pythonwhat}/utils.py | 0 pythonwhat/{ => pythonwhat}/utils_ast.py | 0 pythonwhat/{ => pythonwhat}/utils_env.py | 0 pythonwhat/reporter.py | 5 -- .../requirements.txt | 4 +- setup.py => pythonwhat/setup.py | 0 {tests => pythonwhat/tests}/__init__.py | 0 {tests => pythonwhat/tests}/helper.py | 0 .../tests}/test_ast_operations.py | 0 .../tests}/test_author_warnings.py | 0 .../tests}/test_check_class_def.py | 0 .../tests}/test_check_function.py | 4 +- .../tests}/test_check_function_def.py | 0 .../tests}/test_check_if_else.py | 0 .../tests}/test_check_list_comp.py | 0 .../tests}/test_check_logic.py | 0 .../tests}/test_check_object.py | 0 .../tests}/test_check_try_except.py | 0 .../tests}/test_converters.py | 0 {tests => pythonwhat/tests}/test_debug.py | 0 {tests => pythonwhat/tests}/test_docs.py | 0 .../tests}/test_has_chosen.py | 0 {tests => pythonwhat/tests}/test_has_code.py | 0 {tests => pythonwhat/tests}/test_has_expr.py | 0 .../tests}/test_has_import.py | 0 .../tests}/test_has_no_error.py | 0 .../tests}/test_has_output.py | 0 .../tests}/test_has_printout.py | 0 .../tests}/test_highlighting.py | 0 {tests => pythonwhat/tests}/test_messaging.py | 2 +- .../tests}/test_set_context.py | 0 {tests => pythonwhat/tests}/test_set_env.py | 0 .../tests}/test_signatures.py | 0 {tests => pythonwhat/tests}/test_spec.py | 0 {tests => pythonwhat/tests}/test_state.py | 2 +- .../tests}/test_test_compound_statement.py | 0 .../tests}/test_test_exercise.py | 4 +- .../tests}/test_test_object_accessed.py | 0 {tests => pythonwhat/tests}/test_test_with.py | 0 {tests => pythonwhat/tests}/test_utils.py | 0 {tests => pythonwhat/tests}/test_v2_only.py | 0 tests/test_check_files.py | 29 ------- 95 files changed, 301 insertions(+), 249 deletions(-) create mode 100644 pythonwhat/.coveragerc create mode 100644 pythonwhat/.gitignore create mode 100644 pythonwhat/.travis.yml rename CHANGELOG.md => pythonwhat/CHANGELOG.md (99%) rename LICENSE => pythonwhat/LICENSE (100%) rename MANIFEST.in => pythonwhat/MANIFEST.in (100%) rename Makefile => pythonwhat/Makefile (100%) rename README.md => pythonwhat/README.md (100%) rename {docs => pythonwhat/docs}/Makefile (100%) rename {docs => pythonwhat/docs}/articles/checking_compound_statements.rst (100%) rename {docs => pythonwhat/docs}/articles/checking_function_calls.rst (100%) rename {docs => pythonwhat/docs}/articles/checking_through_string_matching.rst (100%) rename {docs => pythonwhat/docs}/articles/electives.rst (100%) rename {docs => pythonwhat/docs}/articles/expression_tests.rst (100%) rename {docs => pythonwhat/docs}/articles/make_your_sct_robust.rst (100%) rename {docs => pythonwhat/docs}/articles/processes.rst (100%) rename {docs => pythonwhat/docs}/articles/single_process_exercise.rst (100%) rename {docs => pythonwhat/docs}/articles/test_to_check.rst (100%) rename {docs => pythonwhat/docs}/articles/tutorial.rst (100%) rename {docs => pythonwhat/docs}/conf.py (97%) rename {docs => pythonwhat/docs}/data_to_doc.py (100%) rename {docs => pythonwhat/docs}/glossary.rst (100%) rename {docs => pythonwhat/docs}/index.rst (100%) rename {docs => pythonwhat/docs}/old/test_object_accessed.md (100%) rename {docs => pythonwhat/docs}/reference.rst (100%) rename {docs => pythonwhat/docs}/tests.rst (100%) rename pytest.ini => pythonwhat/pytest.ini (100%) create mode 100644 pythonwhat/pythonwhat/Feedback.py rename pythonwhat/{ => pythonwhat}/State.py (92%) rename pythonwhat/{ => pythonwhat}/Test.py (96%) rename pythonwhat/{ => pythonwhat}/__init__.py (70%) rename pythonwhat/{ => pythonwhat}/checks/__init__.py (100%) rename pythonwhat/{ => pythonwhat}/checks/check_funcs.py (91%) rename pythonwhat/{ => pythonwhat}/checks/check_function.py (91%) rename pythonwhat/{ => pythonwhat}/checks/check_has_context.py (97%) rename pythonwhat/{ => pythonwhat}/checks/check_logic.py (95%) rename pythonwhat/{ => pythonwhat}/checks/check_object.py (95%) rename pythonwhat/{ => pythonwhat}/checks/check_wrappers.py (95%) rename pythonwhat/{ => pythonwhat}/checks/has_funcs.py (97%) rename pythonwhat/{ => pythonwhat}/converters.py (100%) rename pythonwhat/{ => pythonwhat}/local.py (96%) rename pythonwhat/{ => pythonwhat}/parsing.py (100%) rename pythonwhat/{ => pythonwhat}/probe.py (95%) rename pythonwhat/{ => pythonwhat}/sct_syntax.py (100%) rename pythonwhat/{ => pythonwhat}/signatures.py (100%) rename pythonwhat/{ => pythonwhat}/tasks.py (100%) rename pythonwhat/{ => pythonwhat}/test_exercise.py (96%) rename pythonwhat/{ => pythonwhat}/test_funcs/__init__.py (100%) rename pythonwhat/{ => pythonwhat}/test_funcs/test_compound_statement.py (95%) rename pythonwhat/{ => pythonwhat}/test_funcs/test_function.py (94%) rename pythonwhat/{ => pythonwhat}/test_funcs/test_object.py (83%) rename pythonwhat/{ => pythonwhat}/test_funcs/test_object_accessed.py (90%) rename pythonwhat/{ => pythonwhat}/test_funcs/utils.py (94%) rename pythonwhat/{ => pythonwhat}/utils.py (100%) rename pythonwhat/{ => pythonwhat}/utils_ast.py (100%) rename pythonwhat/{ => pythonwhat}/utils_env.py (100%) delete mode 100644 pythonwhat/reporter.py rename requirements.txt => pythonwhat/requirements.txt (92%) rename setup.py => pythonwhat/setup.py (100%) rename {tests => pythonwhat/tests}/__init__.py (100%) rename {tests => pythonwhat/tests}/helper.py (100%) rename {tests => pythonwhat/tests}/test_ast_operations.py (100%) rename {tests => pythonwhat/tests}/test_author_warnings.py (100%) rename {tests => pythonwhat/tests}/test_check_class_def.py (100%) rename {tests => pythonwhat/tests}/test_check_function.py (99%) rename {tests => pythonwhat/tests}/test_check_function_def.py (100%) rename {tests => pythonwhat/tests}/test_check_if_else.py (100%) rename {tests => pythonwhat/tests}/test_check_list_comp.py (100%) rename {tests => pythonwhat/tests}/test_check_logic.py (100%) rename {tests => pythonwhat/tests}/test_check_object.py (100%) rename {tests => pythonwhat/tests}/test_check_try_except.py (100%) rename {tests => pythonwhat/tests}/test_converters.py (100%) rename {tests => pythonwhat/tests}/test_debug.py (100%) rename {tests => pythonwhat/tests}/test_docs.py (100%) rename {tests => pythonwhat/tests}/test_has_chosen.py (100%) rename {tests => pythonwhat/tests}/test_has_code.py (100%) rename {tests => pythonwhat/tests}/test_has_expr.py (100%) rename {tests => pythonwhat/tests}/test_has_import.py (100%) rename {tests => pythonwhat/tests}/test_has_no_error.py (100%) rename {tests => pythonwhat/tests}/test_has_output.py (100%) rename {tests => pythonwhat/tests}/test_has_printout.py (100%) rename {tests => pythonwhat/tests}/test_highlighting.py (100%) rename {tests => pythonwhat/tests}/test_messaging.py (99%) rename {tests => pythonwhat/tests}/test_set_context.py (100%) rename {tests => pythonwhat/tests}/test_set_env.py (100%) rename {tests => pythonwhat/tests}/test_signatures.py (100%) rename {tests => pythonwhat/tests}/test_spec.py (100%) rename {tests => pythonwhat/tests}/test_state.py (91%) rename {tests => pythonwhat/tests}/test_test_compound_statement.py (100%) rename {tests => pythonwhat/tests}/test_test_exercise.py (96%) rename {tests => pythonwhat/tests}/test_test_object_accessed.py (100%) rename {tests => pythonwhat/tests}/test_test_with.py (100%) rename {tests => pythonwhat/tests}/test_utils.py (100%) rename {tests => pythonwhat/tests}/test_v2_only.py (100%) delete mode 100644 tests/test_check_files.py diff --git a/pythonwhat/.coveragerc b/pythonwhat/.coveragerc new file mode 100644 index 00000000..c2c30563 --- /dev/null +++ b/pythonwhat/.coveragerc @@ -0,0 +1,2 @@ +[run] +source=pythonwhat \ No newline at end of file diff --git a/pythonwhat/.gitignore b/pythonwhat/.gitignore new file mode 100644 index 00000000..90e761a1 --- /dev/null +++ b/pythonwhat/.gitignore @@ -0,0 +1,79 @@ +# Vim swapfiles +.*.swp + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Ipython Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# Mac stuff +.DS_Store +tests/.DS_Store + +# pytest +.pytest_cache/ + +# datasets +*.csv diff --git a/pythonwhat/.travis.yml b/pythonwhat/.travis.yml new file mode 100644 index 00000000..a9840af6 --- /dev/null +++ b/pythonwhat/.travis.yml @@ -0,0 +1,19 @@ +sudo: false +language: python +python: +- '3.5' +before_install: +- pip install -r requirements.txt +- pip install -e . +script: pytest -m "not compiled" --cov=pythonwhat +after_success: codecov --token=$CODECOV_TOKEN +deploy: + provider: pypi + user: datacamp + password: + secure: g0lu0u/tDLNxPa0VsmPQhRfPUzA+3EavKljX9goinCbp0o6RWY7LSBEwCqmMcqIlVJ7gL2yMkBC21HsEGkIvkJhoTpWFXVWtbZEUcmyrfviu1HCrOUqsLvy9WOd+h8ZVelsPT4PEuEKtXD8K9qMjRjtiWH9xuoG+LyMPWvO2WGuIxk+z7DNIrPNm48kuC97yKKr2NWXoj9MjhfqPNAizqAiolYdLBwQX/biXQqsGNErSWp1rvojeA27PrtROLFHZO3cni7b3QjmpmaDkAYERfSbfUfom1gcAKQNeM3OfecBVxNsFc8kjhriktQyp9pWGZ44Hn9dmeYVeGfmVOEmIlCppLlQYcRm07QBtOpgN/QqOftAgZBKbd0AXftrxu64G//l9fLXGaW7i9vsqUMc7ttD4FKF5c7Du4+v3i5ouRXnnaMf2bER/FwezPn5tBrAJ2jW96CDYCnUzQzve/NRmjMUSJbNM4YAB5apXq1PyeacLUEPWphZBcurZe0/Gy3ERTDFTMpHC1fS6ciIDnzMLl69HDuCwOfT7Spvj0hjUgDPR650l66rbEG5UHDmymK2r+qsNrmSicahmKOUT8NJ478qP68G1eNemqe2iT6m8dTvMGD5vSqSgPLwrbfX/ECLk4Gx39Xn+Guj1o/TYF8MTMy/CxXIdXXx9P2Z9/4X5Xso= + on: + tags: true + distributions: sdist bdist_wheel + repo: datacamp/pythonwhat + skip_upload_docs: true diff --git a/CHANGELOG.md b/pythonwhat/CHANGELOG.md similarity index 99% rename from CHANGELOG.md rename to pythonwhat/CHANGELOG.md index f06bd833..c754f8e8 100644 --- a/CHANGELOG.md +++ b/pythonwhat/CHANGELOG.md @@ -2,11 +2,6 @@ All notable changes to the pythonwhat project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## 2.20.0 - -- Expose `_debug` function -- Update protowhat - ## 2.19.0 - `state` is now the first argument to SCT functions (instead of a keyword argument) diff --git a/LICENSE b/pythonwhat/LICENSE similarity index 100% rename from LICENSE rename to pythonwhat/LICENSE diff --git a/MANIFEST.in b/pythonwhat/MANIFEST.in similarity index 100% rename from MANIFEST.in rename to pythonwhat/MANIFEST.in diff --git a/Makefile b/pythonwhat/Makefile similarity index 100% rename from Makefile rename to pythonwhat/Makefile diff --git a/README.md b/pythonwhat/README.md similarity index 100% rename from README.md rename to pythonwhat/README.md diff --git a/docs/Makefile b/pythonwhat/docs/Makefile similarity index 100% rename from docs/Makefile rename to pythonwhat/docs/Makefile diff --git a/docs/articles/checking_compound_statements.rst b/pythonwhat/docs/articles/checking_compound_statements.rst similarity index 100% rename from docs/articles/checking_compound_statements.rst rename to pythonwhat/docs/articles/checking_compound_statements.rst diff --git a/docs/articles/checking_function_calls.rst b/pythonwhat/docs/articles/checking_function_calls.rst similarity index 100% rename from docs/articles/checking_function_calls.rst rename to pythonwhat/docs/articles/checking_function_calls.rst diff --git a/docs/articles/checking_through_string_matching.rst b/pythonwhat/docs/articles/checking_through_string_matching.rst similarity index 100% rename from docs/articles/checking_through_string_matching.rst rename to pythonwhat/docs/articles/checking_through_string_matching.rst diff --git a/docs/articles/electives.rst b/pythonwhat/docs/articles/electives.rst similarity index 100% rename from docs/articles/electives.rst rename to pythonwhat/docs/articles/electives.rst diff --git a/docs/articles/expression_tests.rst b/pythonwhat/docs/articles/expression_tests.rst similarity index 100% rename from docs/articles/expression_tests.rst rename to pythonwhat/docs/articles/expression_tests.rst diff --git a/docs/articles/make_your_sct_robust.rst b/pythonwhat/docs/articles/make_your_sct_robust.rst similarity index 100% rename from docs/articles/make_your_sct_robust.rst rename to pythonwhat/docs/articles/make_your_sct_robust.rst diff --git a/docs/articles/processes.rst b/pythonwhat/docs/articles/processes.rst similarity index 100% rename from docs/articles/processes.rst rename to pythonwhat/docs/articles/processes.rst diff --git a/docs/articles/single_process_exercise.rst b/pythonwhat/docs/articles/single_process_exercise.rst similarity index 100% rename from docs/articles/single_process_exercise.rst rename to pythonwhat/docs/articles/single_process_exercise.rst diff --git a/docs/articles/test_to_check.rst b/pythonwhat/docs/articles/test_to_check.rst similarity index 100% rename from docs/articles/test_to_check.rst rename to pythonwhat/docs/articles/test_to_check.rst diff --git a/docs/articles/tutorial.rst b/pythonwhat/docs/articles/tutorial.rst similarity index 100% rename from docs/articles/tutorial.rst rename to pythonwhat/docs/articles/tutorial.rst diff --git a/docs/conf.py b/pythonwhat/docs/conf.py similarity index 97% rename from docs/conf.py rename to pythonwhat/docs/conf.py index 46ddd4cd..3b6117ef 100644 --- a/docs/conf.py +++ b/pythonwhat/docs/conf.py @@ -49,12 +49,7 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = [ - "sphinx.ext.autodoc", - "sphinx.ext.napoleon", - "sphinxcontrib.jinja", - "sphinxprettysearchresults", -] +extensions = ["sphinx.ext.autodoc", "sphinx.ext.napoleon", "sphinxcontrib.jinja", 'sphinxprettysearchresults'] # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] diff --git a/docs/data_to_doc.py b/pythonwhat/docs/data_to_doc.py similarity index 100% rename from docs/data_to_doc.py rename to pythonwhat/docs/data_to_doc.py diff --git a/docs/glossary.rst b/pythonwhat/docs/glossary.rst similarity index 100% rename from docs/glossary.rst rename to pythonwhat/docs/glossary.rst diff --git a/docs/index.rst b/pythonwhat/docs/index.rst similarity index 100% rename from docs/index.rst rename to pythonwhat/docs/index.rst diff --git a/docs/old/test_object_accessed.md b/pythonwhat/docs/old/test_object_accessed.md similarity index 100% rename from docs/old/test_object_accessed.md rename to pythonwhat/docs/old/test_object_accessed.md diff --git a/docs/reference.rst b/pythonwhat/docs/reference.rst similarity index 100% rename from docs/reference.rst rename to pythonwhat/docs/reference.rst diff --git a/docs/tests.rst b/pythonwhat/docs/tests.rst similarity index 100% rename from docs/tests.rst rename to pythonwhat/docs/tests.rst diff --git a/pytest.ini b/pythonwhat/pytest.ini similarity index 100% rename from pytest.ini rename to pythonwhat/pytest.ini diff --git a/pythonwhat/pythonwhat/Feedback.py b/pythonwhat/pythonwhat/Feedback.py new file mode 100644 index 00000000..00fe9985 --- /dev/null +++ b/pythonwhat/pythonwhat/Feedback.py @@ -0,0 +1,21 @@ +from protowhat.Feedback import Feedback as ProtoFeedback + + +class Feedback(ProtoFeedback): + def _line_info(self): + if hasattr(self.highlight, "first_token") and hasattr( + self.highlight, "last_token" + ): + return { + "line_start": self.highlight.first_token.start[0], + "column_start": self.highlight.first_token.start[1], + "line_end": self.highlight.last_token.end[0], + "column_end": self.highlight.last_token.end[1], + } + + def get_formatted_line_info(self): + formatted_info = self.get_line_info() + for k in ["column_start"]: + if k in formatted_info: + formatted_info[k] += 1 + return formatted_info diff --git a/pythonwhat/State.py b/pythonwhat/pythonwhat/State.py similarity index 92% rename from pythonwhat/State.py rename to pythonwhat/pythonwhat/State.py index 90320efe..7e6dc830 100644 --- a/pythonwhat/State.py +++ b/pythonwhat/pythonwhat/State.py @@ -8,6 +8,7 @@ from protowhat.State import State as ProtoState from protowhat.selectors import DispatcherInterface from protowhat.Feedback import InstructorError +from pythonwhat.Feedback import Feedback from pythonwhat import signatures from pythonwhat.converters import get_manual_converters from collections.abc import Mapping @@ -62,7 +63,7 @@ def __init__( highlight=None, highlighting_disabled=None, messages=None, - creator=None, + parent_state=None, student_ast=None, solution_ast=None, student_ast_tokens=None, @@ -78,12 +79,10 @@ def __init__( self.params = list() for k, v in args.items(): - if k != "self": + if k not in ["self", "args"]: self.params.append(k) setattr(self, k, v) - self.messages = messages if messages else [] - self.ast_dispatcher = self.get_dispatcher() # parse code if didn't happen yet @@ -92,9 +91,11 @@ def __init__( if solution_ast is None: self.solution_ast = self.parse(solution_code, test=False) - if highlight is None: # todo: check parent_state? (move check to reporting?) + if highlight is None and parent_state: self.highlight = self.student_ast + self.messages = messages if messages else [] + self.converters = get_manual_converters() # accessed only from root state self.manual_sigs = None @@ -122,6 +123,7 @@ def to_child(self, append_message="", node_name="", **kwargs): append_message = {"msg": append_message, "kwargs": {}} kwargs["messages"] = [*self.messages, append_message] + kwargs["parent_state"] = self for kwarg in ["solution_context", "student_context"]: if kwarg in kwargs and not kwargs[kwarg]: @@ -202,21 +204,26 @@ def parse_external(self, code): e.filename = "script.py" # no line info for now self.report( - "Your code could not be parsed due to an error in the indentation:
`%s.`" - % str(e) + Feedback( + "Your code could not be parsed due to an error in the indentation:
`%s.`" + % str(e) + ) ) except SyntaxError as e: e.filename = "script.py" # no line info for now self.report( - "Your code can not be executed due to a syntax error:
`%s.`" % str(e) + Feedback( + "Your code can not be executed due to a syntax error:
`%s.`" + % str(e) + ) ) # Can happen, can't catch this earlier because we can't differentiate between # TypeError in parsing or TypeError within code (at runtime). except: - self.report("Something went wrong while parsing your code.") + self.report(Feedback("Something went wrong while parsing your code.")) return res @@ -257,12 +264,14 @@ def __init__(self, context_code=""): self._parser_cache = dict() context_ast = getattr(self._context_cache, context_code, None) if context_ast is None: - context_ast = self._context_cache[context_code] = self.parse(context_code)[ - 1 - ] - self.context_mappings = self._getx(FunctionParser, "mappings", context_ast) - - def find(self, name, node, *args, **kwargs): + context_ast = self._context_cache[context_code] = self.parse( + context_code + )[1] + self.context_mappings = self._getx( + FunctionParser, "mappings", context_ast + ) + + def __call__(self, name, node, *args, **kwargs): return getattr(self, name)(node) def parse(self, code): diff --git a/pythonwhat/Test.py b/pythonwhat/pythonwhat/Test.py similarity index 96% rename from pythonwhat/Test.py rename to pythonwhat/pythonwhat/Test.py index 50c20f5c..9f4596b7 100644 --- a/pythonwhat/Test.py +++ b/pythonwhat/pythonwhat/Test.py @@ -22,7 +22,7 @@ def __init__(self, name, process, feedback): self.name = name self.process = process - def test(self): + def specific_test(self): self.result = isDefinedInProcess(self.name, self.process) @@ -42,7 +42,7 @@ def __init__(self, name, collection, feedback): self.name = name self.collection = collection - def test(self): + def specific_test(self): self.result = self.name in self.collection @@ -53,7 +53,7 @@ def __init__(self, name, key, process, feedback): self.key = key self.process = process - def test(self): + def specific_test(self): self.result = isDefinedCollInProcess(self.name, self.key, self.process) @@ -67,7 +67,7 @@ def __init__(self, name, klass, process, feedback): self.klass = klass self.process = process - def test(self): + def specific_test(self): self.result = isInstanceInProcess(self.name, self.klass, self.process) @@ -92,11 +92,11 @@ def __init__(self, obj1, obj2, feedback, func=None): self.obj2 = obj2 self.func = func if func is not None else is_equal - def test(self): + def specific_test(self): """ Perform the actual test. result is set to False if the objects differ, True otherwise. """ - self.result = np.array(self.func(self.obj1, self.obj2)).all() + self.result = self.func(self.obj1, self.obj2) # Helpers for testing equality @@ -177,7 +177,7 @@ def __init__(self, string, search_string, pattern, feedback): self.search_string = search_string self.pattern = pattern - def test(self): + def specific_test(self): """ Perform the actual test. result will be True if string is found (whether or not with a pattern), False otherwise. diff --git a/pythonwhat/__init__.py b/pythonwhat/pythonwhat/__init__.py similarity index 70% rename from pythonwhat/__init__.py rename to pythonwhat/pythonwhat/__init__.py index 7a4c712d..0ea5ba40 100644 --- a/pythonwhat/__init__.py +++ b/pythonwhat/pythonwhat/__init__.py @@ -1,3 +1,3 @@ -__version__ = "2.20.0" +__version__ = "2.19.0" from .test_exercise import test_exercise, allow_errors diff --git a/pythonwhat/checks/__init__.py b/pythonwhat/pythonwhat/checks/__init__.py similarity index 100% rename from pythonwhat/checks/__init__.py rename to pythonwhat/pythonwhat/checks/__init__.py diff --git a/pythonwhat/checks/check_funcs.py b/pythonwhat/pythonwhat/checks/check_funcs.py similarity index 91% rename from pythonwhat/checks/check_funcs.py rename to pythonwhat/pythonwhat/checks/check_funcs.py index 9d5cc02e..1d6abb71 100644 --- a/pythonwhat/checks/check_funcs.py +++ b/pythonwhat/pythonwhat/checks/check_funcs.py @@ -1,6 +1,8 @@ from pythonwhat.checks.check_logic import multi from pythonwhat.checks.has_funcs import has_part +from protowhat.Test import Test from protowhat.Feedback import InstructorError +from pythonwhat.Feedback import Feedback from pythonwhat.tasks import setUpNewEnvInProcess, breakDownNewEnvInProcess from pythonwhat.utils import get_ord from pythonwhat.utils_ast import assert_ast @@ -12,6 +14,12 @@ def render(template, kwargs): return Template(template).render(**kwargs) +class StubState: + def __init__(self, highlight, highlighting_disabled): + self.highlight = highlight + self.highlighting_disabled = highlighting_disabled + + def part_to_child(stu_part, sol_part, append_message, state, node_name=None): # stu_part and sol_part will be accessible on all templates append_message["kwargs"].update({"stu_part": stu_part, "sol_part": sol_part}) @@ -115,8 +123,8 @@ def check_node( if expand_msg is None: expand_msg = "Check the {{typestr}}. " - stu_out = state.ast_dispatcher.find(name, state.student_ast) - sol_out = state.ast_dispatcher.find(name, state.solution_ast) + stu_out = state.ast_dispatcher(name, state.student_ast) + sol_out = state.ast_dispatcher(name, state.solution_ast) # check if there are enough nodes for index fmt_kwargs = { @@ -131,7 +139,7 @@ def check_node( stu_out[index] except (KeyError, IndexError): # TODO comment errors _msg = state.build_message(missing_msg, fmt_kwargs) - state.report(_msg) + state.report(Feedback(_msg, state)) # get node at index stu_part = stu_out[index] @@ -159,14 +167,20 @@ def with_context(state, *args, child=None): process=state.student_process, context=state.student_parts["with_items"] ) if isinstance(student_res, AttributeError): - child.report( - "In your `with` statement, you're not using a correct context manager." + state.report( + Feedback( + "In your `with` statement, you're not using a correct context manager.", + child.highlight, # TODO + ) ) if isinstance(student_res, (AssertionError, ValueError, TypeError)): - child.report( - "In your `with` statement, the number of values in your context manager " - "doesn't correspond to the number of variables you're trying to assign it to." + state.report( + Feedback( + "In your `with` statement, the number of values in your context manager " + "doesn't correspond to the number of variables you're trying to assign it to.", + child.highlight, + ) ) # run subtests @@ -186,8 +200,11 @@ def with_context(state, *args, child=None): close_student_context = breakDownNewEnvInProcess(process=state.student_process) if isinstance(close_student_context, Exception): state.report( - "Your `with` statement can not be closed off correctly, you're " - "not using the context manager correctly." + Feedback( + "Your `with` statement can not be closed off correctly, you're " + + "not using the context manager correctly.", + state, + ) ) return state diff --git a/pythonwhat/checks/check_function.py b/pythonwhat/pythonwhat/checks/check_function.py similarity index 91% rename from pythonwhat/checks/check_function.py rename to pythonwhat/pythonwhat/checks/check_function.py index 32ff5b8e..2ac2d99a 100644 --- a/pythonwhat/checks/check_function.py +++ b/pythonwhat/pythonwhat/checks/check_function.py @@ -1,7 +1,9 @@ -from pythonwhat.checks.check_funcs import part_to_child +from pythonwhat.checks.check_funcs import part_to_child, StubState from pythonwhat.tasks import getSignatureInProcess from pythonwhat.utils import get_ord, get_times +from protowhat.Test import Test from protowhat.Feedback import InstructorError +from pythonwhat.Feedback import Feedback from pythonwhat.parsing import IndexedDict from functools import partial @@ -47,7 +49,7 @@ def check_function( """Check whether a particular function is called. ``check_function()`` is typically followed by: - + - ``check_args()`` to check whether the arguments were specified. In turn, ``check_args()`` can be followed by ``has_equal_value()`` or ``has_equal_ast()`` to assert that the arguments were correctly specified. @@ -97,10 +99,10 @@ def check_function( if params_not_matched_msg is None: params_not_matched_msg = SIG_ISSUE_MSG - stu_out = state.ast_dispatcher.find("function_calls", state.student_ast) - sol_out = state.ast_dispatcher.find("function_calls", state.solution_ast) + stu_out = state.ast_dispatcher("function_calls", state.student_ast) + sol_out = state.ast_dispatcher("function_calls", state.solution_ast) - student_mappings = state.ast_dispatcher.find("mappings", state.student_ast) + student_mappings = state.ast_dispatcher("mappings", state.student_ast) fmt_kwargs = { "times": get_times(index + 1), @@ -129,7 +131,7 @@ def check_function( stu_parts = {**stu_out[name][index]} except (KeyError, IndexError): _msg = state.build_message(missing_msg, fmt_kwargs, append=append_missing) - state.report(_msg) + state.report(Feedback(_msg, state)) # Signatures ----- if signature: @@ -161,7 +163,11 @@ def check_function( _msg = state.build_message( params_not_matched_msg, fmt_kwargs, append=append_params_not_matched ) - state.to_child(highlight=stu_parts["node"]).report(_msg) + state.report( + Feedback( + _msg, StubState(stu_parts["node"], state.highlighting_disabled) + ) + ) # three types of parts: pos_args, keywords, args (e.g. these are bound to sig) append_message = {"msg": expand_msg, "kwargs": fmt_kwargs} diff --git a/pythonwhat/checks/check_has_context.py b/pythonwhat/pythonwhat/checks/check_has_context.py similarity index 97% rename from pythonwhat/checks/check_has_context.py rename to pythonwhat/pythonwhat/checks/check_has_context.py index 05ed3676..14bf5361 100644 --- a/pythonwhat/checks/check_has_context.py +++ b/pythonwhat/pythonwhat/checks/check_has_context.py @@ -1,5 +1,6 @@ from pythonwhat.Test import EqualTest -from protowhat.Feedback import Feedback, InstructorError +from protowhat.Feedback import InstructorError +from pythonwhat.Feedback import Feedback from pythonwhat.State import State from functools import singledispatch from pythonwhat.checks.check_funcs import check_part_index diff --git a/pythonwhat/checks/check_logic.py b/pythonwhat/pythonwhat/checks/check_logic.py similarity index 95% rename from pythonwhat/checks/check_logic.py rename to pythonwhat/pythonwhat/checks/check_logic.py index 26ada48a..587ac73e 100644 --- a/pythonwhat/checks/check_logic.py +++ b/pythonwhat/pythonwhat/checks/check_logic.py @@ -1,18 +1,9 @@ -from protowhat.checks.check_logic import ( - multi, - check_not, - check_or, - check_correct, - disable_highlighting, - fail, -) +from protowhat.checks.check_logic import multi, check_not, check_or, check_correct, disable_highlighting, fail from protowhat.Feedback import InstructorError import ast -multi.__doc__ = ( - str(multi.__doc__) - + """ +multi.__doc__ = str(multi.__doc__) + """ :Example: Suppose we want to verify the following function call: :: @@ -27,12 +18,9 @@ check_args('ndigits').has_equal_value() ) """ -) -check_not.__doc__ = ( - str(check_not.__doc__) - + """ +check_not.__doc__ = str(check_not.__doc__) + """ :Example: The SCT fails with feedback for a specific incorrect value, defined using an override: :: @@ -64,12 +52,9 @@ - This function can be considered a direct counterpart of multi. """ -) -check_or.__doc__ = ( - str(check_or.__doc__) - + """ +check_or.__doc__ = str(check_or.__doc__) + """ :Example: The SCT below tests that the student typed either 'mean' or 'median': :: @@ -83,12 +68,9 @@ the first SCT, will be presented to the student. """ -) -check_correct.__doc__ = ( - str(check_correct.__doc__) - + """ +check_correct.__doc__ = str(check_correct.__doc__) + """ :Example: The SCT below tests whether an object is correct. Only if the object is not correct, will @@ -100,15 +82,12 @@ ) """ -) # utility functions ----------------------------------------------------------- -fail.__doc__ = ( - str(fail.__doc__) - + """ +fail.__doc__ = str(fail.__doc__) + """ :Example: As a trivial SCT example, :: @@ -117,7 +96,6 @@ This can also be helpful for debugging SCTs, as it can be used to stop testing as a given point. """ -) def override(state, solution): @@ -293,9 +271,7 @@ def set_env(state, **kwargs): ) -disable_highlighting.__doc__ = ( - str(disable_highlighting.__doc__) - + """ +disable_highlighting.__doc__ = str(disable_highlighting.__doc__) + """ :Examples: SCT that will mark the 'number' portion if it is incorrect:: @@ -308,4 +284,3 @@ def set_env(state, **kwargs): Ex().check_function('round').disable_highlighting().check_args(0).has_equal_ast() Ex().check_function('round').check_args(0).disable_highlighting().has_equal_ast() """ -) diff --git a/pythonwhat/checks/check_object.py b/pythonwhat/pythonwhat/checks/check_object.py similarity index 95% rename from pythonwhat/checks/check_object.py rename to pythonwhat/pythonwhat/checks/check_object.py index 086b5c7d..bb6bfdd2 100644 --- a/pythonwhat/checks/check_object.py +++ b/pythonwhat/pythonwhat/checks/check_object.py @@ -4,7 +4,8 @@ InstanceProcessTest, DefinedCollProcessTest, ) -from protowhat.Feedback import Feedback, InstructorError +from protowhat.Feedback import InstructorError +from pythonwhat.Feedback import Feedback from pythonwhat.tasks import ( isDefinedInProcess, isInstanceInProcess, @@ -16,7 +17,9 @@ import ast -def check_object(state, index, missing_msg=None, expand_msg=None, typestr="variable"): +def check_object( + state, index, missing_msg=None, expand_msg=None, typestr="variable" +): """Check object existence (and equality) Check whether an object is defined in the student's process, and zoom in on its value in both @@ -32,7 +35,7 @@ def check_object(state, index, missing_msg=None, expand_msg=None, typestr="varia expand_msg (str): If specified, this overrides any messages that are prepended by previous SCT chains. :Example: - + Suppose you want the student to create a variable ``x``, equal to 15: :: x = 15 @@ -43,9 +46,9 @@ def check_object(state, index, missing_msg=None, expand_msg=None, typestr="varia - ``check_object()`` will check if the variable ``x`` is defined in the student process. - ``has_equal_value()`` will check whether the value of ``x`` in the solution process is the same as in the student process. - + Note that ``has_equal_value()`` only looks at **end result** of a variable in the student process. - In the example, how the object ``x`` came about in the student's submission, does not matter. + In the example, how the object ``x`` came about in the student's submission, does not matter. This means that all of the following submission will also pass the above SCT: :: x = 15 @@ -90,10 +93,10 @@ def check_object(state, index, missing_msg=None, expand_msg=None, typestr="varia ) ) ) - + - ``check_correct()`` is used to robustly check whether ``my_list`` was built correctly. - If ``my_list`` is not correct, **both** the initialization and the population code are checked. - + :Example: Because checking object correctness incorrectly is such a common misconception, we're adding another example: :: @@ -101,7 +104,7 @@ def check_object(state, index, missing_msg=None, expand_msg=None, typestr="varia import pandas as pd df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]}) df['c'] = [7, 8, 9] - + The following SCT would be **wrong**, as it does not factor in the possibility that the 'add column ``c``' step could've been wrong: :: Ex().check_correct( @@ -147,7 +150,7 @@ def __init__(self, n): # submissions that will pass this sct x = Number(1) x = Number(2 - 1) - + The basic SCT like in the previous example will notwork here. Notice how we used the ``expr_code`` argument to _override_ which value `has_equal_value()` is checking. Instead of checking whether `x` corresponds between student and solution process, it's now executing the expression ``x.n`` @@ -161,7 +164,7 @@ def __init__(self, n): state.assert_root("check_object", extra_msg=extra_msg) if missing_msg is None: - missing_msg = " {{typestr}} `{{index}}` ?" + missing_msg = "Did you define the {{typestr}} `{{index}}` without errors?" if expand_msg is None: expand_msg = "Did you correctly define the {{typestr}} `{{index}}`? " @@ -179,12 +182,8 @@ def __init__(self, n): # create child state, using either parser output, or create part from name fallback = lambda: ObjectAssignmentParser.get_part(index) - stu_part = state.ast_dispatcher.find("object_assignments", state.student_ast).get( - index, fallback() - ) - sol_part = state.ast_dispatcher.find("object_assignments", state.solution_ast).get( - index, fallback() - ) + stu_part = state.ast_dispatcher("object_assignments", state.student_ast).get(index, fallback()) + sol_part = state.ast_dispatcher("object_assignments", state.solution_ast).get(index, fallback()) # test object exists _msg = state.build_message(missing_msg, append_message["kwargs"]) @@ -244,9 +243,11 @@ def is_instance(state, inst, not_instance_msg=None): return state -def check_df(state, index, missing_msg=None, not_instance_msg=None, expand_msg=None): +def check_df( + state, index, missing_msg=None, not_instance_msg=None, expand_msg=None +): """Check whether a DataFrame was defined and it is the right type - + ``check_df()`` is a combo of ``check_object()`` and ``is_instance()`` that checks whether the specified object exists and whether the specified object is pandas DataFrame. @@ -277,9 +278,9 @@ def check_df(state, index, missing_msg=None, not_instance_msg=None, expand_msg=N - ``check_df()`` checks if ``my_df`` exists (``check_object()`` behind the scenes) and is a DataFrame (``is_instance()``) - ``check_keys("a")`` zooms in on the column ``a`` of the data frame, and ``has_equal_value()`` checks if the columns correspond between student and solution process. - ``check_keys("b")`` zooms in on hte column ``b`` of the data frame, but there's no 'equality checking' happening - + The following submissions would pass the SCT above: :: - + my_df = pd.DataFrame({"a": [1, 1 + 1, 3], "b": ["a", "l", "l"]}) my_df = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6], "c": [7, 8, 9]}) diff --git a/pythonwhat/checks/check_wrappers.py b/pythonwhat/pythonwhat/checks/check_wrappers.py similarity index 95% rename from pythonwhat/checks/check_wrappers.py rename to pythonwhat/pythonwhat/checks/check_wrappers.py index 6d4c0ca5..454f98cd 100644 --- a/pythonwhat/checks/check_wrappers.py +++ b/pythonwhat/pythonwhat/checks/check_wrappers.py @@ -1,12 +1,9 @@ -from protowhat.utils import _debug -from protowhat.checks.check_files import check_file, has_dir from pythonwhat.checks.check_funcs import check_part, check_part_index, check_node from pythonwhat.checks.has_funcs import has_equal_part from pythonwhat.checks import check_object, check_logic, check_funcs, has_funcs from pythonwhat.checks.check_function import check_function from pythonwhat.checks.check_has_context import has_context -from inspect import signature, Parameter from functools import partial, wraps from jinja2 import Template @@ -651,6 +648,25 @@ def __init__(self, i): # make has_equal_part wrappers +# todo: check @wraps implementation + +# def partial_with_state(func, *partial_args, **partial_kwargs): +# @wraps(func) +# def state_partial(state, *args, **kwargs): +# func(state, *partial_args, *args, **{**partial_kwargs, **kwargs}) +# return state_partial + + +# def right_args_partial(func, *last_args, **partial_kwargs): +# kwargs_partial = partial(func, **partial_kwargs) +# +# @wraps(func) +# def full_partial(*first_args, **kwargs): +# kwargs_partial(*first_args, *last_args, **kwargs) +# +# return full_partial + + def partial_with_offset(offset=1): def bound_partial_with_offset(func, *partial_args, **partial_kwargs): kwargs_partial = partial(func, **partial_kwargs) @@ -660,35 +676,7 @@ def full_partial(*args, **kwargs): full_args = args[:offset] + partial_args + args[offset:] return kwargs_partial(*full_args, **kwargs) - # set correct signature of returned partial - # todo: pass arguments as keywords to partial, instead of this decorator? - # (where args are always the same) - func_sig = signature(full_partial) - parameter_names = tuple(func_sig.parameters) - - partialed_positional_indices = [] - for kwarg in partial_kwargs: - param = func_sig.parameters[kwarg] - if param.default is param.empty: - partialed_positional_indices.append(parameter_names.index(kwarg)) - - partial_params = list(func_sig.parameters.values()) - for index in sorted(partialed_positional_indices, reverse=True): - # appending isn't needed for functionality, but more similar to partial - # and it shows that these arguments can still be updated as kwargs - partial_params.append( - partial_params[index].replace( - kind=Parameter.KEYWORD_ONLY, - default=partial_kwargs[partial_params[index].name], - ) - ) - del partial_params[index] - del partial_params[offset : offset + len(partial_args)] - - full_partial.__signature__ = func_sig.replace(parameters=partial_params) - return full_partial - return bound_partial_with_offset @@ -770,8 +758,5 @@ def rename_function(func, name): scts["has_context"] = has_context scts["check_function"] = check_function -scts["check_file"] = check_file -scts["has_dir"] = has_dir -scts["_debug"] = _debug locals().update(scts) diff --git a/pythonwhat/checks/has_funcs.py b/pythonwhat/pythonwhat/checks/has_funcs.py similarity index 97% rename from pythonwhat/checks/has_funcs.py rename to pythonwhat/pythonwhat/checks/has_funcs.py index 48136b87..40d41086 100644 --- a/pythonwhat/checks/has_funcs.py +++ b/pythonwhat/pythonwhat/checks/has_funcs.py @@ -10,7 +10,8 @@ ) from protowhat.Test import Test from pythonwhat.Test import EqualTest, DefinedCollTest -from protowhat.Feedback import Feedback, InstructorError +from protowhat.Feedback import InstructorError +from pythonwhat.Feedback import Feedback from pythonwhat import utils from functools import partial import re @@ -52,7 +53,7 @@ def verify(part, index): try: verify(state.student_parts[name], index) except (KeyError, IndexError): - state.report(_msg) + state.report(Feedback(_msg, state)) return state @@ -100,7 +101,7 @@ def shout(word): if d["stu_len"] != d["sol_len"]: _msg = state.build_message(unequal_msg, d) - state.report(_msg) + state.report(Feedback(_msg, state)) return state @@ -194,7 +195,7 @@ def parse_tree(tree): if exact and not code: state.do_test(EqualTest(stu_rep, sol_rep, Feedback(_msg, state))) elif not sol_rep in stu_rep: - state.report(_msg) + state.report(Feedback(_msg, state)) return state @@ -238,7 +239,7 @@ def parse_tree(tree): {0} of an object after executing the body of e.g. a ``for`` loop. copy (bool): whether to try to deep copy objects in the environment, such as lists, that could accidentally be mutated. Disable to speed up SCTs. Disabling may lead to cryptic mutation issues. - func (function): custom binary function of form f(stu_result, sol_result), for equality testing. + func: custom binary function of form f(stu_result, sol_result), for equality testing. override: If specified, this avoids the execution of the targeted code in the solution process. Instead, it will compare the {0} of the expression in the student process with the value specified in ``override``. Typically used in a ``SingleProcessExercise`` or if you want to allow for different solutions other than @@ -346,12 +347,13 @@ def has_expr( if (test == "error") ^ isinstance(eval_stu, Exception): fmt_kwargs["stu_str"] = str_stu _msg = state.build_message(error_msg, fmt_kwargs, append=append) - state.report(_msg) + feedback = Feedback(_msg, state) + state.report(feedback) # name is undefined after running expression if isinstance(eval_stu, UndefinedValue): _msg = state.build_message(undefined_msg, fmt_kwargs, append=append) - state.report(_msg) + state.report(Feedback(_msg, state)) # test equality of results _msg = state.build_message(incorrect_msg, fmt_kwargs, append=append) @@ -511,8 +513,8 @@ def has_import( import matplotlib.pyplot as pltttt """ - student_imports = state.ast_dispatcher.find("imports", state.student_ast) - solution_imports = state.ast_dispatcher.find("imports", state.solution_ast) + student_imports = state.ast_dispatcher("imports", state.student_ast) + solution_imports = state.ast_dispatcher("imports", state.solution_ast) if name not in solution_imports: raise InstructorError( @@ -660,7 +662,7 @@ def has_printout( ) try: - sol_call_ast = state.ast_dispatcher.find("function_calls", state.solution_ast)[ + sol_call_ast = state.ast_dispatcher("function_calls", state.solution_ast)[ "print" ][index]["node"] except (KeyError, IndexError): @@ -753,7 +755,7 @@ def has_no_error( _msg = state.build_message( incorrect_msg, {"error": str(state.reporter.errors[0])} ) - state.report(_msg) + state.report(Feedback(_msg, state)) return state diff --git a/pythonwhat/converters.py b/pythonwhat/pythonwhat/converters.py similarity index 100% rename from pythonwhat/converters.py rename to pythonwhat/pythonwhat/converters.py diff --git a/pythonwhat/local.py b/pythonwhat/pythonwhat/local.py similarity index 96% rename from pythonwhat/local.py rename to pythonwhat/pythonwhat/local.py index 18f5c669..de1528c8 100644 --- a/pythonwhat/local.py +++ b/pythonwhat/pythonwhat/local.py @@ -3,7 +3,7 @@ from pythonwhat.sct_syntax import Ex from pythonwhat.State import State -from pythonwhat.reporter import Reporter +from protowhat.Reporter import Reporter from contextlib import redirect_stdout @@ -38,7 +38,7 @@ def setup_state(stu_code="", sol_code="", pec="", pid=None): student_process=stu_process, solution_process=sol_process, raw_student_output=raw_stu_output, - reporter=Reporter(), + reporter=Reporter() ) State.root_state = state diff --git a/pythonwhat/parsing.py b/pythonwhat/pythonwhat/parsing.py similarity index 100% rename from pythonwhat/parsing.py rename to pythonwhat/pythonwhat/parsing.py diff --git a/pythonwhat/probe.py b/pythonwhat/pythonwhat/probe.py similarity index 95% rename from pythonwhat/probe.py rename to pythonwhat/pythonwhat/probe.py index 9a041e4d..57f33392 100644 --- a/pythonwhat/probe.py +++ b/pythonwhat/pythonwhat/probe.py @@ -61,8 +61,7 @@ def str_branch(cls, node, str_func=lambda s: str(s)): # dict(getattr(s.data.get("bound_args", {}), 'arguments', {})) f = node.data.get("func") this_node = ( - " " * node.depth - + "(" + " " * node.depth + "(" + getattr(f, "__name__", node.name) + str_func(node) + ")\n" @@ -113,9 +112,7 @@ def __call__(self, state=None): return ba.arguments["state"] def __str__(self): - return pp.pformat( - dict(getattr(self.data.get("bound_args", {}), "arguments", {})) - ) + return pp.pformat(dict(getattr(self.data.get("bound_args", {}), 'arguments', {}))) def __iter__(self): for c in self.child_list: @@ -190,7 +187,7 @@ def __call__(self, *args, **kwargs): """ if (len(args) > 0 and not isinstance(args[0], State)) or len(args) == 0: # no state placeholder if a state is passed - args = ["state_placeholder"] + list(args) + args = ['state_placeholder'] + list(args) bound_args = inspect.signature(self.f).bind(*args, **kwargs) @@ -203,9 +200,7 @@ def __call__(self, *args, **kwargs): arguments = bound_args.arguments for subtest in self.sub_tests: # TODO: auto sub test detection if subtest in arguments and arguments[subtest]: - self.build_sub_test_nodes( - arguments[subtest], self.tree, this_node, subtest - ) + self.build_sub_test_nodes(arguments[subtest], self.tree, this_node, subtest) # Second pass to build node and all its children into a subtest for node in this_node.descend(include_me=True): diff --git a/pythonwhat/sct_syntax.py b/pythonwhat/pythonwhat/sct_syntax.py similarity index 100% rename from pythonwhat/sct_syntax.py rename to pythonwhat/pythonwhat/sct_syntax.py diff --git a/pythonwhat/signatures.py b/pythonwhat/pythonwhat/signatures.py similarity index 100% rename from pythonwhat/signatures.py rename to pythonwhat/pythonwhat/signatures.py diff --git a/pythonwhat/tasks.py b/pythonwhat/pythonwhat/tasks.py similarity index 100% rename from pythonwhat/tasks.py rename to pythonwhat/pythonwhat/tasks.py diff --git a/pythonwhat/test_exercise.py b/pythonwhat/pythonwhat/test_exercise.py similarity index 96% rename from pythonwhat/test_exercise.py rename to pythonwhat/pythonwhat/test_exercise.py index 38288deb..7c103c60 100644 --- a/pythonwhat/test_exercise.py +++ b/pythonwhat/pythonwhat/test_exercise.py @@ -1,6 +1,6 @@ from pythonwhat.State import State from pythonwhat.utils import check_str, check_process -from pythonwhat.reporter import Reporter +from protowhat.Reporter import Reporter from protowhat.Test import TestFail from pythonwhat.utils import include_v1 @@ -43,7 +43,7 @@ def test_exercise( solution_process=check_process(solution_process), raw_student_output=check_str(raw_student_output), force_diagnose=force_diagnose, - reporter=Reporter(errors=[error] if error else []), + reporter=Reporter([error] if error else []) ) State.root_state = state diff --git a/pythonwhat/test_funcs/__init__.py b/pythonwhat/pythonwhat/test_funcs/__init__.py similarity index 100% rename from pythonwhat/test_funcs/__init__.py rename to pythonwhat/pythonwhat/test_funcs/__init__.py diff --git a/pythonwhat/test_funcs/test_compound_statement.py b/pythonwhat/pythonwhat/test_funcs/test_compound_statement.py similarity index 95% rename from pythonwhat/test_funcs/test_compound_statement.py rename to pythonwhat/pythonwhat/test_funcs/test_compound_statement.py index a41d8f37..b555664b 100644 --- a/pythonwhat/test_funcs/test_compound_statement.py +++ b/pythonwhat/pythonwhat/test_funcs/test_compound_statement.py @@ -1,4 +1,3 @@ -from protowhat.sct_syntax import link_to_state from pythonwhat.checks.check_funcs import ( check_node, check_part, @@ -17,12 +16,6 @@ from functools import partial from pythonwhat import utils -# this is done by the chain for v2 -# it's only needed when a new state is created and (possibly) used elsewhere -check_node = link_to_state(check_node) -check_part = link_to_state(check_part) -check_part_index = link_to_state(check_part_index) - def test_if_else(state, index=1, test=None, body=None, orelse=None): """Test parts of the if statement. @@ -282,17 +275,19 @@ def shout( word = 'help', times = 3 ): test_function_definition('shout') # fail test_function_definition('shout', arg_defaults = False) # pass test_function_definition('shout', arg_defaults = False, # fail - outputs = [('help')]) + outputs = [('help')]) test_function_definition('shout', arg_defaults = False, # pass - results = [('help', 2)]) + results = [('help', 2)]) test_function_definition('shout', args_defaults = False # pass body = test_function('print', args = []])) """ # what the function will be referred to as - child = check_node(state, "function_defs", name, "definition of `{{index}}()`") + child = check_node( + state, "function_defs", name, "definition of `{{index}}()`" + ) test_args( child, arg_names, arg_defaults, nb_args_msg, arg_names_msg, arg_defaults_msg @@ -337,7 +332,7 @@ def shout( word = 'help', times = 3 ): def test_args( - state, arg_names, arg_defaults, nb_args_msg, arg_names_msg, arg_defaults_msg + state, arg_names, arg_defaults, nb_args_msg, arg_names_msg, arg_defaults_msg ): MSG_NUM_ARGS = "You should define {{parent[typestr]}} with {{sol_len}} arguments, instead got {{stu_len}}." @@ -444,11 +439,7 @@ def test_object_after_expression( pre_code=None, **kwargs ): - state.highlight = ( - state.ast_dispatcher.find("object_assignments", state.student_ast) - .get(name, {}) - .get("highlight") - ) + state.highlight = state.ast_dispatcher("object_assignments", state.student_ast).get(name, {}).get("highlight") has_equal_value( state, incorrect_msg=incorrect_msg, @@ -498,7 +489,9 @@ def test_with( if context_vals: # test context var names ---- has_context( - child, incorrect_msg=context_vals_msg or MSG_CTXT_NAMES, exact_names=True + child, + incorrect_msg=context_vals_msg or MSG_CTXT_NAMES, + exact_names=True, ) # test num context vars ---- @@ -511,8 +504,7 @@ def test_with( for i, context_test in enumerate(context_tests or []): # partial the substate check, because the function uses two prepended messages def check_context(state): - return check_part_index( - state, + return check_part_index(state, "context", i, "%s context" % utils.get_ord(i + 1), @@ -544,8 +536,8 @@ def test_list_comp( ): """Test list comprehension.""" kwargs = locals().copy() - kwargs["typestr"] = "{{ordinal}} list comprehension" - kwargs["comptype"] = "list_comps" + kwargs['typestr'] = "{{ordinal}} list comprehension" + kwargs['comptype'] = "list_comps" test_comp(**kwargs) @@ -575,7 +567,9 @@ def test_comp( insufficient_ifs_msg = MSG_INSUFFICIENT_IFS # get comprehension - child = check_node(state, comptype, index - 1, typestr, missing_msg=not_called_msg) + child = check_node( + state, comptype, index - 1, typestr, missing_msg=not_called_msg + ) # test comprehension iter and its variable names (or number of variables) if comp_iter: @@ -600,4 +594,7 @@ def test_comp( # test that ifs are same length has_equal_part_len(child, "ifs", insufficient_ifs_msg) # test individual ifs - multi(check_part_index(child, "ifs", i, utils.get_ord(i + 1) + " if"), if_test) + multi( + check_part_index(child, "ifs", i, utils.get_ord(i + 1) + " if"), + if_test, + ) diff --git a/pythonwhat/test_funcs/test_function.py b/pythonwhat/pythonwhat/test_funcs/test_function.py similarity index 94% rename from pythonwhat/test_funcs/test_function.py rename to pythonwhat/pythonwhat/test_funcs/test_function.py index 9ce4ba2f..16adf0fe 100644 --- a/pythonwhat/test_funcs/test_function.py +++ b/pythonwhat/pythonwhat/test_funcs/test_function.py @@ -1,16 +1,10 @@ from functools import partial - -from protowhat.sct_syntax import link_to_state from pythonwhat.checks.check_function import check_function from protowhat.Feedback import InstructorError from protowhat.Test import TestFail from pythonwhat.checks.check_funcs import check_args from pythonwhat.checks.has_funcs import has_equal_value, has_equal_ast, has_printout -# this is done by the chain for v2 -# it's only needed when a new state is created and (possibly) used elsewhere -check_function = link_to_state(check_function) - def arg_test(state, name, do_eval, missing_msg, incorrect_msg): arg_state = check_args(state, name=name, missing_msg=missing_msg) @@ -135,7 +129,9 @@ def test_function_v2( eligible = do_eval[0] if isinstance(do_eval, list) and len(do_eval) > 0 else do_eval if name == "print" and state.parent_state is None and eligible: try: - return has_printout(state, index=index, not_printed_msg=incorrect_msg[0]) + return has_printout( + state, index=index, not_printed_msg=incorrect_msg[0] + ) except TestFail: # The test didn't pass; just continue with the more strict check_function test. pass diff --git a/pythonwhat/test_funcs/test_object.py b/pythonwhat/pythonwhat/test_funcs/test_object.py similarity index 83% rename from pythonwhat/test_funcs/test_object.py rename to pythonwhat/pythonwhat/test_funcs/test_object.py index c0b441d5..d19d44a7 100644 --- a/pythonwhat/test_funcs/test_object.py +++ b/pythonwhat/pythonwhat/test_funcs/test_object.py @@ -1,14 +1,7 @@ -from protowhat.sct_syntax import link_to_state from pythonwhat.tasks import getColumnsInProcess from pythonwhat.checks.check_object import check_object, check_df, check_keys from pythonwhat.checks.has_funcs import has_equal_value -# this is done by the chain for v2 -# it's only needed when a new state is created and (possibly) used elsewhere -check_object = link_to_state(check_object) -check_df = link_to_state(check_df) -check_keys = link_to_state(check_keys) - def test_object( state, diff --git a/pythonwhat/test_funcs/test_object_accessed.py b/pythonwhat/pythonwhat/test_funcs/test_object_accessed.py similarity index 90% rename from pythonwhat/test_funcs/test_object_accessed.py rename to pythonwhat/pythonwhat/test_funcs/test_object_accessed.py index a9ad7474..3e32dab9 100644 --- a/pythonwhat/test_funcs/test_object_accessed.py +++ b/pythonwhat/pythonwhat/test_funcs/test_object_accessed.py @@ -34,10 +34,8 @@ def test_object_accessed(state, name, times=1, not_accessed_msg=None): | ``test_object_accessed("arr.shape")``: pass. | ``test_object_accessed("arr.dtype")``: fail. """ - student_object_accesses = state.ast_dispatcher.find( - "object_accesses", state.student_ast - ) - student_mappings = state.ast_dispatcher.find("oa_mappings", state.student_ast) + student_object_accesses = state.ast_dispatcher("object_accesses", state.student_ast) + student_mappings = state.ast_dispatcher("oa_mappings", state.student_ast) if not not_accessed_msg: stud_name = name diff --git a/pythonwhat/test_funcs/utils.py b/pythonwhat/pythonwhat/test_funcs/utils.py similarity index 94% rename from pythonwhat/test_funcs/utils.py rename to pythonwhat/pythonwhat/test_funcs/utils.py index 5410f6e6..03fae8d9 100644 --- a/pythonwhat/test_funcs/utils.py +++ b/pythonwhat/pythonwhat/test_funcs/utils.py @@ -1,7 +1,9 @@ import ast -from protowhat.Feedback import Feedback, InstructorError +from protowhat.Feedback import InstructorError +from pythonwhat.Feedback import Feedback from pythonwhat.Test import EqualTest +from pythonwhat.checks.check_funcs import StubState from pythonwhat.checks.has_funcs import evalCalls from pythonwhat.tasks import ReprFail @@ -128,10 +130,10 @@ def call( # either error test and no error, or vice-versa stu_node = state.student_parts["node"] - stu_state = state.to_child(highlight=stu_node) + stu_state = StubState(stu_node, state.highlighting_disabled) if (test == "error") ^ isinstance(eval_stu, Exception): _msg = state.build_message(error_msg, fmt_kwargs) - stu_state.report(_msg) + state.report(Feedback(_msg, stu_state)) # incorrect result _msg = state.build_message(incorrect_msg, fmt_kwargs) diff --git a/pythonwhat/utils.py b/pythonwhat/pythonwhat/utils.py similarity index 100% rename from pythonwhat/utils.py rename to pythonwhat/pythonwhat/utils.py diff --git a/pythonwhat/utils_ast.py b/pythonwhat/pythonwhat/utils_ast.py similarity index 100% rename from pythonwhat/utils_ast.py rename to pythonwhat/pythonwhat/utils_ast.py diff --git a/pythonwhat/utils_env.py b/pythonwhat/pythonwhat/utils_env.py similarity index 100% rename from pythonwhat/utils_env.py rename to pythonwhat/pythonwhat/utils_env.py diff --git a/pythonwhat/reporter.py b/pythonwhat/reporter.py deleted file mode 100644 index df68479b..00000000 --- a/pythonwhat/reporter.py +++ /dev/null @@ -1,5 +0,0 @@ -from protowhat.Reporter import Reporter as BaseReporter - - -class Reporter(BaseReporter): - ast_highlight_offset = {"column_start": 1} diff --git a/requirements.txt b/pythonwhat/requirements.txt similarity index 92% rename from requirements.txt rename to pythonwhat/requirements.txt index e85eb809..ad2c757b 100644 --- a/requirements.txt +++ b/pythonwhat/requirements.txt @@ -1,5 +1,5 @@ # pythonwhat deps -protowhat~=1.8.0 +protowhat~=1.6.0 asttokens~=1.1.10 dill~=0.2.7.1 markdown2~=2.3.5 @@ -15,7 +15,7 @@ html5lib~=1.0.1 h5py~=2.7.1 requests~=2.20.0 seaborn~=0.8.1 -sqlalchemy~=1.3.0 +sqlalchemy~=1.2.6 xlrd~=1.1.0 # test-utils deps diff --git a/setup.py b/pythonwhat/setup.py similarity index 100% rename from setup.py rename to pythonwhat/setup.py diff --git a/tests/__init__.py b/pythonwhat/tests/__init__.py similarity index 100% rename from tests/__init__.py rename to pythonwhat/tests/__init__.py diff --git a/tests/helper.py b/pythonwhat/tests/helper.py similarity index 100% rename from tests/helper.py rename to pythonwhat/tests/helper.py diff --git a/tests/test_ast_operations.py b/pythonwhat/tests/test_ast_operations.py similarity index 100% rename from tests/test_ast_operations.py rename to pythonwhat/tests/test_ast_operations.py diff --git a/tests/test_author_warnings.py b/pythonwhat/tests/test_author_warnings.py similarity index 100% rename from tests/test_author_warnings.py rename to pythonwhat/tests/test_author_warnings.py diff --git a/tests/test_check_class_def.py b/pythonwhat/tests/test_check_class_def.py similarity index 100% rename from tests/test_check_class_def.py rename to pythonwhat/tests/test_check_class_def.py diff --git a/tests/test_check_function.py b/pythonwhat/tests/test_check_function.py similarity index 99% rename from tests/test_check_function.py rename to pythonwhat/tests/test_check_function.py index c313a07d..1063ab2e 100644 --- a/tests/test_check_function.py +++ b/pythonwhat/tests/test_check_function.py @@ -86,9 +86,7 @@ def test_bind_args(): pec = "def my_fun(a, b, *args, **kwargs): pass" s = setup_state(pec=pec, stu_code="my_fun(1, 2, 3, 4, c = 5)") - args = s._state.ast_dispatcher.find("function_calls", s._state.student_ast)[ - "my_fun" - ][0]["args"] + args = s._state.ast_dispatcher("function_calls", s._state.student_ast)["my_fun"][0]["args"] sig = signature(s._state.student_process.shell.user_ns["my_fun"]) binded_args = bind_args(sig, args) assert binded_args["a"]["node"].n == 1 diff --git a/tests/test_check_function_def.py b/pythonwhat/tests/test_check_function_def.py similarity index 100% rename from tests/test_check_function_def.py rename to pythonwhat/tests/test_check_function_def.py diff --git a/tests/test_check_if_else.py b/pythonwhat/tests/test_check_if_else.py similarity index 100% rename from tests/test_check_if_else.py rename to pythonwhat/tests/test_check_if_else.py diff --git a/tests/test_check_list_comp.py b/pythonwhat/tests/test_check_list_comp.py similarity index 100% rename from tests/test_check_list_comp.py rename to pythonwhat/tests/test_check_list_comp.py diff --git a/tests/test_check_logic.py b/pythonwhat/tests/test_check_logic.py similarity index 100% rename from tests/test_check_logic.py rename to pythonwhat/tests/test_check_logic.py diff --git a/tests/test_check_object.py b/pythonwhat/tests/test_check_object.py similarity index 100% rename from tests/test_check_object.py rename to pythonwhat/tests/test_check_object.py diff --git a/tests/test_check_try_except.py b/pythonwhat/tests/test_check_try_except.py similarity index 100% rename from tests/test_check_try_except.py rename to pythonwhat/tests/test_check_try_except.py diff --git a/tests/test_converters.py b/pythonwhat/tests/test_converters.py similarity index 100% rename from tests/test_converters.py rename to pythonwhat/tests/test_converters.py diff --git a/tests/test_debug.py b/pythonwhat/tests/test_debug.py similarity index 100% rename from tests/test_debug.py rename to pythonwhat/tests/test_debug.py diff --git a/tests/test_docs.py b/pythonwhat/tests/test_docs.py similarity index 100% rename from tests/test_docs.py rename to pythonwhat/tests/test_docs.py diff --git a/tests/test_has_chosen.py b/pythonwhat/tests/test_has_chosen.py similarity index 100% rename from tests/test_has_chosen.py rename to pythonwhat/tests/test_has_chosen.py diff --git a/tests/test_has_code.py b/pythonwhat/tests/test_has_code.py similarity index 100% rename from tests/test_has_code.py rename to pythonwhat/tests/test_has_code.py diff --git a/tests/test_has_expr.py b/pythonwhat/tests/test_has_expr.py similarity index 100% rename from tests/test_has_expr.py rename to pythonwhat/tests/test_has_expr.py diff --git a/tests/test_has_import.py b/pythonwhat/tests/test_has_import.py similarity index 100% rename from tests/test_has_import.py rename to pythonwhat/tests/test_has_import.py diff --git a/tests/test_has_no_error.py b/pythonwhat/tests/test_has_no_error.py similarity index 100% rename from tests/test_has_no_error.py rename to pythonwhat/tests/test_has_no_error.py diff --git a/tests/test_has_output.py b/pythonwhat/tests/test_has_output.py similarity index 100% rename from tests/test_has_output.py rename to pythonwhat/tests/test_has_output.py diff --git a/tests/test_has_printout.py b/pythonwhat/tests/test_has_printout.py similarity index 100% rename from tests/test_has_printout.py rename to pythonwhat/tests/test_has_printout.py diff --git a/tests/test_highlighting.py b/pythonwhat/tests/test_highlighting.py similarity index 100% rename from tests/test_highlighting.py rename to pythonwhat/tests/test_highlighting.py diff --git a/tests/test_messaging.py b/pythonwhat/tests/test_messaging.py similarity index 99% rename from tests/test_messaging.py rename to pythonwhat/tests/test_messaging.py index 86bf1222..3fff54b5 100644 --- a/tests/test_messaging.py +++ b/pythonwhat/tests/test_messaging.py @@ -1,6 +1,6 @@ import pytest import tests.helper as helper -from pythonwhat.reporter import Reporter +from protowhat.Reporter import Reporter from difflib import Differ diff --git a/tests/test_set_context.py b/pythonwhat/tests/test_set_context.py similarity index 100% rename from tests/test_set_context.py rename to pythonwhat/tests/test_set_context.py diff --git a/tests/test_set_env.py b/pythonwhat/tests/test_set_env.py similarity index 100% rename from tests/test_set_env.py rename to pythonwhat/tests/test_set_env.py diff --git a/tests/test_signatures.py b/pythonwhat/tests/test_signatures.py similarity index 100% rename from tests/test_signatures.py rename to pythonwhat/tests/test_signatures.py diff --git a/tests/test_spec.py b/pythonwhat/tests/test_spec.py similarity index 100% rename from tests/test_spec.py rename to pythonwhat/tests/test_spec.py diff --git a/tests/test_state.py b/pythonwhat/tests/test_state.py similarity index 91% rename from tests/test_state.py rename to pythonwhat/tests/test_state.py index 96dc0e8e..5f69c573 100644 --- a/tests/test_state.py +++ b/pythonwhat/tests/test_state.py @@ -12,5 +12,5 @@ def test_pec_parsing_error(): student_process=None, solution_process=None, reporter=None, - raw_student_output=None, + raw_student_output=None ) diff --git a/tests/test_test_compound_statement.py b/pythonwhat/tests/test_test_compound_statement.py similarity index 100% rename from tests/test_test_compound_statement.py rename to pythonwhat/tests/test_test_compound_statement.py diff --git a/tests/test_test_exercise.py b/pythonwhat/tests/test_test_exercise.py similarity index 96% rename from tests/test_test_exercise.py rename to pythonwhat/tests/test_test_exercise.py index 83d898dd..2a978501 100644 --- a/tests/test_test_exercise.py +++ b/pythonwhat/tests/test_test_exercise.py @@ -4,10 +4,10 @@ import tests.helper as helper -@pytest.fixture(scope="session", autouse=True) +@pytest.fixture(scope='session', autouse=True) def log_calls(): yield - print("Output test data") + print('Output test data') with open("docs/test_data.json", "w") as write_file: json.dump(helper.test_data, write_file) diff --git a/tests/test_test_object_accessed.py b/pythonwhat/tests/test_test_object_accessed.py similarity index 100% rename from tests/test_test_object_accessed.py rename to pythonwhat/tests/test_test_object_accessed.py diff --git a/tests/test_test_with.py b/pythonwhat/tests/test_test_with.py similarity index 100% rename from tests/test_test_with.py rename to pythonwhat/tests/test_test_with.py diff --git a/tests/test_utils.py b/pythonwhat/tests/test_utils.py similarity index 100% rename from tests/test_utils.py rename to pythonwhat/tests/test_utils.py diff --git a/tests/test_v2_only.py b/pythonwhat/tests/test_v2_only.py similarity index 100% rename from tests/test_v2_only.py rename to pythonwhat/tests/test_v2_only.py diff --git a/tests/test_check_files.py b/tests/test_check_files.py deleted file mode 100644 index 4e34575f..00000000 --- a/tests/test_check_files.py +++ /dev/null @@ -1,29 +0,0 @@ -from tempfile import NamedTemporaryFile - -import pytest -import tests.helper as helper -from protowhat.sct_syntax import F - -from pythonwhat.local import setup_state -from protowhat.checks import check_files as cf - - -@pytest.fixture(scope="function") -def tf(): - with NamedTemporaryFile() as tmp: - tmp.file.write(b"1 + 1") - tmp.file.flush() - yield tmp - - -def test_file_existence(tf): - s = setup_state("", "", pec="") - - child = cf.check_file(s._state, tf.name) - assert "1 + 1" in child.student_code - - file_chain = s.check_file(tf.name) - assert "1 + 1" in file_chain._state.student_code - - with helper.verify_sct(True): - s >> F(attr_scts={"check_file": cf.check_file}).check_file(tf.name)