mirror of
https://git.mirrors.martin98.com/https://github.com/petaflot/pygcode
synced 2025-07-26 16:21:59 +08:00
fixed over-usage of assert
This commit is contained in:
parent
0ae4e08b81
commit
988ee9db94
@ -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"""
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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):
|
||||
|
Loading…
x
Reference in New Issue
Block a user