fixed over-usage of assert

This commit is contained in:
Peter Boin 2017-07-09 11:32:37 +10:00
parent 0ae4e08b81
commit 988ee9db94
5 changed files with 65 additions and 27 deletions

View File

@ -2,6 +2,17 @@
# ===================== Parsing Exceptions =====================
class GCodeBlockFormatError(Exception):
"""Raised when errors encountered while parsing block text"""
pass
# ===================== Parsing Exceptions =====================
class GCodeParameterError(Exception):
"""Raised for conflicting / invalid / badly formed parameters"""
class GCodeWordStrError(Exception):
"""Raised when issues found while parsing a word string"""
# ===================== Machine Exceptions =====================
class MachineInvalidAxis(Exception):
"""Raised if an axis is invalid"""
# For example: for axes X/Y/Z, set the value of "Q"; wtf?
class MachineInvalidState(Exception):
"""Raised if a machine state is set incorrectly, or in conflict"""

View File

@ -3,6 +3,8 @@ from copy import copy
from .words import Word
from .exceptions import GCodeParameterError
# Terminology of a "G-Code"
# For the purposes of this library, so-called "G" codes do not necessarily
# use the letter "G" in their word; other letters include M, F, S, and T
@ -196,8 +198,11 @@ class GCode(object):
:param word: Word instance
"""
assert isinstance(word, Word), "invalid parameter class: %r" % word
assert word.letter in self.param_letters, "invalid parameter for %s: %s" % (self.__class__.__name__, str(word))
assert word.letter not in self.params, "parameter defined twice: %s -> %s" % (self.params[word.letter], word)
if word.letter not in self.param_letters:
raise GCodeParameterError("invalid parameter for %s: %s" % (self.__class__.__name__, str(word)))
if word.letter in self.params:
raise GCodeParameterError("parameter defined twice: %s -> %s" % (self.params[word.letter], word))
self.params[word.letter] = word
def __getattr__(self, key):
@ -243,7 +248,7 @@ class GCode(object):
:param machine: Machine instance, to change state
:return: GCodeEffect instance; effect the gcode just had on machine
"""
from .machine import Machine # importing high-level state
from .machine import Machine # importing up (done live to avoid dependency loop)
assert isinstance(machine, Machine), "invalid parameter"
# Set mode

View File

@ -11,6 +11,7 @@ from .block import Block
from .line import Line
from .words import Word
from .exceptions import MachineInvalidAxis, MachineInvalidState
UNIT_IMPERIAL = GCodeUseInches.unit_id # G20
UNIT_METRIC = GCodeUseMillimeters.unit_id # G21
@ -37,7 +38,8 @@ class Position(object):
axes = self.__class__.default_axes
else:
invalid_axes = set(axes) - self.POSSIBLE_AXES
assert not invalid_axes, "invalid axes proposed %s" % invalid_axes
if invalid_axes:
raise MachineInvalidAxis("invalid axes proposed %s" % invalid_axes)
self.__dict__['axes'] = set(axes) & self.POSSIBLE_AXES
# Unit
@ -61,7 +63,7 @@ class Position(object):
if key in self.axes:
self._value[key] = value
elif key in self.POSSIBLE_AXES:
raise AssertionError("'%s' axis is not defined to be set" % key)
raise MachineInvalidAxis("'%s' axis is not defined to be set" % key)
else:
self.__dict__[key] = value
@ -86,14 +88,16 @@ class Position(object):
# Arithmetic
def __add__(self, other):
assert not (self.axes ^ other.axes), "axes: %r != %r" % (self.axes, other.axes)
if self.axes ^ other.axes:
raise MachineInvalidAxis("axes: %r != %r" % (self.axes, other.axes))
new_obj = copy(self)
for k in new_obj._value:
new_obj._value[k] += other._value[k]
return new_obj
def __sub__(self, other):
assert not (other.axes - self.axes), "for a - b: axes in b, that are not in a: %r" % (other.axes - self.axes)
if other.axes - self.axes:
raise MachineInvalidAxis("for a - b: axes in b, that are not in a: %r" % (other.axes - self.axes))
new_obj = copy(self)
for k in other._value:
new_obj._value[k] -= other._value[k]
@ -277,11 +281,12 @@ class Mode(object):
# clear mode group
self.modal_groups[MODAL_GROUP_MAP[key]] = None
else:
# set mode group explicitly
# set mode group explicitly, not advisable
# (recommended to use self.set_mode(value) instead)
assert isinstance(value, GCode), "invalid value type: %r" % value
assert value.modal_group == MODAL_GROUP_MAP[key], \
"cannot set '%s' mode as %r, wrong group" % (key, value)
if not isinstance(value, GCode):
raise MachineInvalidState("invalid mode value: %r" % value)
if value.modal_group != MODAL_GROUP_MAP[key]:
raise MachineInvalidState("cannot set '%s' mode as %r, wrong group" % (key, value))
self.modal_groups[MODAL_GROUP_MAP[key]] = value.modal_copy()
else:
self.__dict__[key] = value
@ -329,6 +334,21 @@ class Machine(object):
if coord_sys_mode:
self.state.cur_coord_sys = coord_sys_mode.coord_system_id
def modal_gcode(self, modal_params):
if not modal_params:
return None
if self.mode.motion is None:
raise MachineInvalidState("unable to assign modal parameters when no motion mode is set")
(modal_gcodes, unasigned_words) = words2gcodes([self.mode.motion.word] + modal_params)
if unasigned_words:
raise MachineInvalidState("modal parameters '%s' cannot be assigned when in mode: %r" % (
' '.join(str(x) for x in unasigned_words), self.mode
))
if modal_gcodes:
assert len(modal_gcodes) == 1, "more than 1 modal code found"
return modal_gcodes[0]
return None
def process(self, *gcode_list, **kwargs):
"""
Process gcodes
@ -338,12 +358,9 @@ class Machine(object):
# Add modal gcode to list of given gcodes
modal_params = kwargs.get('modal_params', [])
if modal_params:
assert self.mode.motion is not None, "unable to assign modal parameters when no motion mode is set"
(modal_gcodes, unasigned_words) = words2gcodes([self.mode.motion.word] + modal_params)
assert unasigned_words == [], "modal parameters '%s' unknown when in mode: %r" % (
' '.join(str(x) for x in unasigned_words), self.mode
)
gcode_list += modal_gcodes
modal_gcode = self.modal_gcode(modal_params)
if modal_gcode:
gcode_list.append(modal_gcode)
for gcode in sorted(gcode_list):
gcode.process(self) # shifts ownership of what happens now to GCode class

View File

@ -2,7 +2,7 @@ import re
import itertools
import six
from .exceptions import GCodeBlockFormatError
from .exceptions import GCodeBlockFormatError, GCodeWordStrError
REGEX_FLOAT = re.compile(r'^-?(\d+\.?\d*|\.\d+)') # testcase: ..tests.test_words.WordValueMatchTests.test_float
REGEX_INT = re.compile(r'^-?\d+')
@ -201,10 +201,13 @@ WORD_MAP = {
class Word(object):
def __init__(self, *args):
assert len(args) in [1, 2], "input arguments either: (letter, value) or (word_str)"
if len(args) not in (1, 2):
raise AssertionError("input arguments either: (letter, value) or (word_str)")
if len(args) == 2:
# Word('G', 90)
(letter, value) = args
else:
# Word('G90')
word_str = args[0]
letter = word_str[0] # first letter
value = word_str[1:] # rest of string
@ -300,7 +303,7 @@ def text2words(block_text):
value_regex = WORD_MAP[letter]['value_regex']
value_match = value_regex.search(block_text[index:])
if value_match is None:
raise GCodeBlockFormatError("word '%s' value invalid" % letter)
raise GCodeWordStrError("word '%s' value invalid" % letter)
value = value_match.group() # matched text
yield Word(letter, value)
@ -311,13 +314,14 @@ def text2words(block_text):
remainder = block_text[index:]
if remainder and re.search(r'\S', remainder):
raise GCodeBlockFormatError("block code remaining '%s'" % remainder)
raise GCodeWordStrError("block code remaining '%s'" % remainder)
def str2word(word_str):
words = list(text2words(word_str))
if words:
assert len(words) <= 1, "more than one word given"
if len(words) > 1:
raise GCodeWordStrError("more than one word given")
return words[0]
return None

View File

@ -7,6 +7,7 @@ add_pygcode_to_path()
# Units under test
from pygcode.machine import Position, Machine
from pygcode.line import Line
from pygcode.exceptions import MachineInvalidAxis
class PositionTests(unittest.TestCase):
@ -56,9 +57,9 @@ class PositionTests(unittest.TestCase):
self.assertEqual(p1 + p2, Position(axes='XYZ', X=1, Y=12, Z=-20))
p3 = Position(axes='XYZA')
with self.assertRaises(AssertionError):
with self.assertRaises(MachineInvalidAxis):
p1 + p3 # mismatched axes
with self.assertRaises(AssertionError):
with self.assertRaises(MachineInvalidAxis):
p3 + p1 # mismatched axes
def test_arithmetic_sub(self):
@ -68,7 +69,7 @@ class PositionTests(unittest.TestCase):
p3 = Position(axes='XYZA')
p3 - p1 # fine
with self.assertRaises(AssertionError):
with self.assertRaises(MachineInvalidAxis):
p1 - p3 # mismatched axes
def test_arithmetic_multiply(self):