Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: datacamp/protowhat
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.7.0
Choose a base ref
...
head repository: datacamp/protowhat
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref

Commits on May 10, 2019

  1. Remove numpy dependency

    hermansje committed May 10, 2019
    Copy the full SHA
    18b0258 View commit details
  2. Improve debug functionality

    hermansje committed May 10, 2019
    Copy the full SHA
    40c2cb7 View commit details
  3. Add debug on failure option

    hermansje committed May 10, 2019
    Copy the full SHA
    a9e42fc View commit details
  4. Simplify using state.report

    hermansje committed May 10, 2019
    Copy the full SHA
    78746cf View commit details
  5. Copy the full SHA
    1264828 View commit details
  6. Format code

    hermansje committed May 10, 2019
    Copy the full SHA
    2640546 View commit details
  7. Copy the full SHA
    20efef3 View commit details

Commits on May 22, 2019

  1. Copy the full SHA
    cafbc97 View commit details
  2. Bump version

    hermansje committed May 22, 2019
    Copy the full SHA
    8995168 View commit details

Commits on May 27, 2019

  1. Update markdown dependency

    hermansje committed May 27, 2019
    Copy the full SHA
    2f314df View commit details

Commits on Jun 5, 2019

  1. Copy the full SHA
    6719213 View commit details
  2. Copy the full SHA
    2fff899 View commit details

Commits on Jun 7, 2019

  1. Add small test

    hermansje committed Jun 7, 2019
    Copy the full SHA
    6756d23 View commit details

Commits on Jun 20, 2019

  1. Copy the full SHA
    cf24cfd View commit details

Commits on Jun 21, 2019

  1. Add allow_errors

    This can be reused in other xwhats
    It should replace the pythonwhat standalone function allow_errors and the sqlwhat SCT function allow_error
    hermansje committed Jun 21, 2019
    Copy the full SHA
    f3182e4 View commit details
  2. Merge pull request #37 from datacamp/jh/papercuts

    Add shared allow_errors and improve repr
    hermansje authored Jun 21, 2019
    Copy the full SHA
    e804055 View commit details

Commits on Jun 24, 2019

  1. Copy the full SHA
    b0d3c21 View commit details

Commits on Jun 25, 2019

  1. Update pypi credentials

    hermansje committed Jun 25, 2019
    Copy the full SHA
    a884b65 View commit details
  2. Fix exception type

    hermansje committed Jun 25, 2019
    Copy the full SHA
    70f70d9 View commit details
  3. Store checked path

    hermansje committed Jun 25, 2019
    Copy the full SHA
    d20c0e2 View commit details

Commits on Jun 27, 2019

  1. Merge pull request #38 from datacamp/jh/store-path

    Store checked path
    hermansje authored Jun 27, 2019
    Copy the full SHA
    49ed00c View commit details
  2. Clean up import

    hermansje committed Jun 27, 2019
    Copy the full SHA
    270423a View commit details

Commits on Jun 28, 2019

  1. Copy the full SHA
    3d5fe2f View commit details

Commits on Jul 25, 2019

  1. Add simple helper to verify if State is root

    This can be used in protowhat SCTs and instead of pythonwhat assert_root.
    hermansje committed Jul 25, 2019
    Copy the full SHA
    bba7034 View commit details
  2. Merge pull request #40 from datacamp/feat/state-root-helper

    Add simple helper to verify if State is root
    hermansje authored Jul 25, 2019
    Copy the full SHA
    256adee View commit details
  3. Add bash history helpers

    hermansje committed Jul 25, 2019
    Copy the full SHA
    c8aa76f View commit details
  4. Copy the full SHA
    f0b6fb0 View commit details
  5. Improve documentation

    hermansje committed Jul 25, 2019
    Copy the full SHA
    7bc68b1 View commit details
  6. Add tests

    + fix for Python initialising default arguments only once
    hermansje committed Jul 25, 2019
    Copy the full SHA
    1f2d1ab View commit details

Commits on Jul 26, 2019

  1. Copy the full SHA
    2ac1b89 View commit details

Commits on Jul 29, 2019

  1. Copy the full SHA
    0065e7e View commit details
  2. Copy the full SHA
    af8c676 View commit details
  3. Merge pull request #39 from datacamp/jh/bash-history

    [CX-370] bash history SCT support
    hermansje authored Jul 29, 2019
    Copy the full SHA
    07739f3 View commit details

Commits on Jul 30, 2019

  1. Copy the full SHA
    70e2b20 View commit details
  2. Merge pull request #41 from datacamp/feat/highlight-file

    [CX-354] Send file to highlight
    hermansje authored Jul 30, 2019
    Copy the full SHA
    405edf7 View commit details
  3. Copy the full SHA
    cf9a5a0 View commit details

Commits on Aug 11, 2019

  1. Copy the full SHA
    39cff17 View commit details

Commits on Aug 21, 2019

  1. Merge pull request #44 from datacamp/fix/no-position

    Handle highlight position absence
    hermansje authored Aug 21, 2019
    Copy the full SHA
    453858c View commit details
  2. Copy the full SHA
    1a72eff View commit details

Commits on Aug 22, 2019

  1. Copy the full SHA
    1ee814f View commit details

Commits on Sep 3, 2019

  1. Merge pull request #45 from datacamp/fix/get_text

    Fix has_code get_text None handling
    TimSangster authored Sep 3, 2019
    Copy the full SHA
    85d0085 View commit details
  2. Copy the full SHA
    0c846a1 View commit details

Commits on Sep 5, 2019

  1. Update CHANGELOG.md

    hermansje authored Sep 5, 2019
    Copy the full SHA
    4511e4c View commit details

Commits on Sep 8, 2019

  1. Add counting helpers

    hermansje committed Sep 8, 2019
    Copy the full SHA
    e58f16e View commit details

Commits on Sep 9, 2019

  1. Merge pull request #46 from datacamp/feat/add-messaging-utils

    Add counting helpers
    hermansje authored Sep 9, 2019
    Copy the full SHA
    4ad0320 View commit details
  2. Copy the full SHA
    aeb3d54 View commit details

Commits on Sep 25, 2019

  1. Copy the full SHA
    f6515f6 View commit details
  2. Bump version. changelog

    TimSangster committed Sep 25, 2019
    Copy the full SHA
    2e76bf3 View commit details
  3. Merge pull request #47 from datacamp/feat/skip_head

    [LE-1152] Add passable skip_head flag
    TimSangster authored Sep 25, 2019
    Copy the full SHA
    84cdb9a View commit details

Commits on Nov 21, 2019

  1. Copy the full SHA
    1fc2770 View commit details
51 changes: 51 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
version: 2.1

orbs:
python: circleci/python@1.2

jobs:
build-and-test:
docker:
- image: cimg/python:3.9
steps:
- checkout
- run:
name: Install packages
command: make install-test
- run:
name: Run tests
command: python -m pytest --cov=protowhat
publish:
docker:
- image: cimg/python:3.9
steps:
- checkout
- run:
command: |
python setup.py sdist bdist_wheel
pip install pipenv
pipenv install twine
pipenv run twine upload --verbose --repository pypi dist/*
workflows:
pr:
jobs:
- build-and-test:
filters:
branches:
ignore: master
publish:
jobs:
- build-and-test:
filters:
tags:
only: /^v\d+\.\d+\.\d+$/
branches:
ignore: /.*/
- publish:
requires:
- build-and-test
filters:
tags:
only: /^v\d+\.\d+\.\d+$/
branches:
ignore: /.*/
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -77,3 +77,6 @@ target/

# Mac stuff -------------------------------------------------------------------
.DS_Store

# IDE
.idea
15 changes: 0 additions & 15 deletions .travis.yml

This file was deleted.

70 changes: 70 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -2,6 +2,76 @@

All notable changes to the protowhat project will be documented in this file.

## 2.1.0

- Support Python version 3.9
- Update dependencies to up-to-date versions

## 2.0.1

- Expose `prepare_validation` from `protowhat.checks`

## 2.0.0

- Refactor SCT syntax to be an execution graph and enable derived features
- Split SCT syntax and SCT context code
- Refactor exceptions to share an interface to simplify logic
- Refactor feedback to be centralized and built from formalized components
- Add support for embedding xwhats
- Add `prepare_validation` helper for checking bash history
- Add autodebug (`_debug` will be invoked automatically for instructor errors)

## 1.14.1

- Fix final feedback message after append_messsage(s) from having duplicate information

## 1.14.0

- Add (default off) append_message functionality to check_node, check_edge and has_eqaul_ast

## 1.13.0

- Add include_head option to Selector

## 1.12.0

- Add messaging helpers

## 1.11.2

- Proper handling of `ast.get_text` returning `None` in `has_code`

## 1.11.1

- Handle highlight position absence (in combination with `antlr-ast` v0.7.0)

## 1.11.0

- Add bash history SCTs
- Add `State.is_root` property
- Return file path in feedback if set

## 1.10.0

- Pass file path to SCT chain after `check_file`

## 1.9.0

- Add `allow_errors`

## 1.8.2

- Support unicode when checking files
- Fix disabling parsing file content

## 1.8.0

- `Feedback` doesn't need to be subclassed in depending SCT libraries.
- `_debug` now has an `on_error` argument which can be set to `True` to show debugging info
on the next failure or before finishing.
- No NumPy dependency
- Simplified `State.report`

## 1.7.0

This release improves the base functionality for all depending SCT libraries.
9 changes: 6 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -7,13 +7,16 @@ commands :
@grep -h -E '^##' Makefile | sed -e 's/## //g'

install:
pip install -e .
pip install -r requirements.txt
pip3.9 install -e .
pip3.9 install -r requirements.txt

install-test:
pip3.9 install -e .
pip3.9 install -r requirements-test.txt

## test : run tests.
test :
pytest --cov=protowhat
codecov

## clean : clean up junk files.
clean :
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# protowhat

[![Build Status](https://travis-ci.org/datacamp/protowhat.svg?branch=master)](https://travis-ci.org/datacamp/protowhat)
[![codecov](https://codecov.io/gh/datacamp/protowhat/branch/master/graph/badge.svg)](https://codecov.io/gh/datacamp/protowhat)
[![PyPI version](https://badge.fury.io/py/protowhat.svg)](https://badge.fury.io/py/protowhat)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fdatacamp%2Fprotowhat.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fdatacamp%2Fprotowhat?ref=badge_shield)

@@ -14,14 +12,15 @@
## Installation

```
pip install protowhat # install from pypi
pyenv local 3.9.0
pip3.9 install protowhat # install from pypi
make install # install from source
```

## Testing

```
pip install -e .
pip3.9 install -e .
pytest
```

11 changes: 6 additions & 5 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -3,8 +3,9 @@ protowhat

protowhat is a utility package required by

- `sqlwhat <https://sqlwhat.readthedocs.io>`_ to write SCTs for SQL exercises, and
- `protowhat <https://shellwhat.readthedocs.io>`_ to write SCTs for Shell exercises.
- `pythonwhat <https://pythonwhat.readthedocs.io>`_ to write SCTs for Python exercises
- `sqlwhat <https://sqlwhat.readthedocs.io>`_ to write SCTs for SQL exercises
- `shellwhat <https://shellwhat.readthedocs.io>`_ to write SCTs for Shell exercises

protowhat contains functionality that is shared between these packages, including:

@@ -13,11 +14,11 @@ protowhat contains functionality that is shared between these packages, includin
- AST element selection, dispatching and message generation,
- Basic SCT functions such as ``success_msg()`` and ``has_chosen()``.

All relevent documentation to write SCTs for SQL and Shell exercises,
including functions that reside in ``protowhat``, can be found in the `sqlwhat <https://sqlwhat.readthedocs.io>`_ and `protowhat <https://shellwhat.readthedocs.io>`_ documentation.
All relevent documentation to write SCTs for Python, SQL and Shell exercises,
including functions that reside in ``protowhat``, can be found in the `pythonwhat <https://pythonwhat.readthedocs.io>`_, `sqlwhat <https://sqlwhat.readthedocs.io>`_ and `shellwhat <https://shellwhat.readthedocs.io>`_ documentation.

.. toctree::
:maxdepth: 2
:caption: Reference

reference
reference
18 changes: 15 additions & 3 deletions docs/reference.rst
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ Ex()

.. automethod:: protowhat.sct_syntax.Ex.__call__

AST Checks
AST checks
----------

.. automodule:: protowhat.checks.check_funcs
@@ -15,8 +15,20 @@ Logic
.. automodule:: protowhat.checks.check_logic
:members:

Simple tests
------------
Simple checks
-------------

.. automodule:: protowhat.checks.check_simple
:members:

File checks
-----------

.. automodule:: protowhat.checks.check_files
:members:

Bash history checks
-------------------

.. automodule:: protowhat.checks.check_bash_history
:members:
113 changes: 94 additions & 19 deletions protowhat/Feedback.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,100 @@
class Feedback:
def __init__(self, message, state=None):
from typing import Dict, Union, List
from collections import Counter
from jinja2 import Template


class FeedbackComponent:
def __init__(self, message: str, kwargs: dict = None, append=True):
self.message = message
self.highlight = None
self.highlighting_disabled = False
if state is not None:
self.highlight = getattr(state, "highlight", None)
self.highlighting_disabled = state.highlighting_disabled
self.kwargs = kwargs or {}
self.append = append

def __repr__(self):
return "<{} {}>".format(self.__class__.__name__, repr(vars(self)))


class Feedback:
# This is the offset for ANTLR
ast_highlight_offset = {"column_start": 1, "column_end": 1}

def __init__(
self,
conclusion: FeedbackComponent,
context_components: List[FeedbackComponent] = None,
highlight=None,
path=None,
highlighting_disabled=False,
highlight_offset=None,
full_code_position=None,
):
self.conclusion = conclusion
self.context_components = context_components or []
self.highlight = highlight
self.path = path
self.highlighting_disabled = highlighting_disabled
self.highlight_offset = highlight_offset or {}
self.full_code_position = full_code_position

@classmethod
def get_highlight_position(cls, highlight) -> Dict[str, int]:
"""Get the position of the highlight object
This method can be customized in subclasses and
use class properties to do so if needed
"""
if hasattr(highlight, "get_position"):
return highlight.get_position()

def get_highlight(self) -> Dict[str, int]:
highlight = Counter()

if not self.highlighting_disabled:
position = self.get_highlight_position(self.highlight)

# TODO: handle highlighting everything
# if position != self.full_code_position:

if position:
highlight.update(self.highlight_offset)
if "line_start" in highlight and "line_end" not in highlight:
highlight["line_end"] = highlight["line_start"]

highlight.update(position)
highlight.update(self.ast_highlight_offset)

if self.path:
highlight["path"] = str(self.path)

return highlight or {}

def _highlight_data(self):
return self.highlight.get_position()
def get_message(self):
out_list = []
msgs = [*filter(lambda x: x is not None, self.context_components), self.conclusion]

def get_highlight_data(self):
result = None
try:
if self.highlight is not None and not self.highlighting_disabled:
result = self._highlight_data()
except:
pass
if not self.conclusion.append:
msgs = msgs[-1:]
elif getattr(self, "highlight", None) and not self.highlighting_disabled:
# if highlighting info is available, don't use all context messages
msgs = msgs[-3:]

return result or {}
# format messages in list, by iterating over previous, current, and next message
for prev_msg, msg, next_msg in zip([None, *msgs[:-1]], msgs, [*msgs[1:], None]):
tmp_kwargs = {
"parent": getattr(prev_msg, "kwargs", None),
"child": getattr(next_msg, "kwargs", None),
"this": getattr(msg, "kwargs"),
**getattr(msg, "kwargs"),
}
# don't bother appending if there is no message
if not getattr(msg, "message"):
continue
else:
# This is slow (but it should only happen once for a submission)
out = Template(msg.message.replace("__JINJA__:", "")).render(tmp_kwargs)
out_list.append(out)

stripped_messages = [s.strip() for s in out_list]
return " ".join(stripped_messages)

class InstructorError(Exception):
pass
def __repr__(self):
return "<{} {}>".format(self.__class__.__name__, repr(vars(self)))
Loading