From 0edc98f046eebc292850fbd09621b8c9de8d9bcf Mon Sep 17 00:00:00 2001 From: manoss96 Date: Tue, 16 Aug 2022 09:13:41 +0300 Subject: [PATCH] bump to v1.5.4 - Updated docs. - Merged "ZeroArgumentsException" and "LessThanTwoArgumentsException" into "NotEnoughArgumentsException". - Merged "NegativeArgumentException", "NonPositiveArgumentException" and "MinGreaterThanMaxException" into "InvalidArgumentValueException". - Merged "NeitherStringNorPregexException", "NeitherCharNorTokenException", "NonStringArgumentException" and "NonIntegerArgumentException" into "InvalidArgumentTypeException". - Added "EmptyNegativeAssertionException" which is thrown whenever an "Empty" class instance is provided as a negative assertion pattern. - Updated parameter names of lookaround-assertion class constructors. - Modified existing tests and added some more. --- docs/requirements.txt | 2 +- docs/source/conf.py | 2 +- docs/source/docstring/modules.rst | 4 +- docs/source/docstring/pregex.rst | 41 ++++-- pyproject.toml | 2 +- src/pregex/assertions.py | 199 +++++++++++++++----------- src/pregex/classes.py | 76 +++++----- src/pregex/exceptions.py | 226 +++++++++++++----------------- src/pregex/groups.py | 52 ++++--- src/pregex/operators.py | 21 +-- src/pregex/pre.py | 65 +++++---- src/pregex/quantifiers.py | 72 ++++++---- src/pregex/tokens.py | 2 +- tests/test_assertions.py | 29 ++-- tests/test_classes.py | 34 ++--- tests/test_groups.py | 21 ++- tests/test_operators.py | 13 +- tests/test_pre.py | 18 +-- tests/test_quantifiers.py | 53 +++---- 19 files changed, 495 insertions(+), 437 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 5b3ddb3..2b1e929 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1 @@ -pregex==1.5.3 \ No newline at end of file +pregex==1.5.4 \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py index 92781ba..9358eab 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -22,7 +22,7 @@ author = 'Manos Stoumpos' # The full version, including alpha/beta/rc tags -release = '1.5.3' +release = '1.5.4' # -- General configuration --------------------------------------------------- diff --git a/docs/source/docstring/modules.rst b/docs/source/docstring/modules.rst index 60e5d8a..618380f 100644 --- a/docs/source/docstring/modules.rst +++ b/docs/source/docstring/modules.rst @@ -1,6 +1,6 @@ -+++++++ +######### pregex -+++++++ +######### In this page you can learn about each one of pregex's core modules and how to effectively use them in order to build complex RegEx patterns. diff --git a/docs/source/docstring/pregex.rst b/docs/source/docstring/pregex.rst index 8a43e27..b89ca88 100644 --- a/docs/source/docstring/pregex.rst +++ b/docs/source/docstring/pregex.rst @@ -1,53 +1,66 @@ +********************* pregex.pre ------------------ +********************* .. automodule:: pregex.pre :members: :undoc-members: ------------------ +============================ + +********************* pregex.assertions ------------------------- +********************* .. automodule:: pregex.assertions :members: :undoc-members: ------------------------- +============================ + +********************* pregex.classes ---------------------- +********************* .. automodule:: pregex.classes :members: :undoc-members: ------------------------- +============================ + +********************* pregex.groups ------------------------- +********************* .. automodule:: pregex.groups :members: :undoc-members: ------------------------- +============================ + +********************* pregex.operators ------------------------ +********************* .. automodule:: pregex.operators :members: :undoc-members: ------------------------- +============================ + +********************* pregex.quantifiers -------------------------- +********************* .. automodule:: pregex.quantifiers :members: :undoc-members: ------------------------- +============================ + +********************* pregex.tokens --------------------- +********************* .. automodule:: pregex.tokens :members: - :undoc-members: \ No newline at end of file + :undoc-members: diff --git a/pyproject.toml b/pyproject.toml index 6b641cf..49251f9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "pregex" -version = "1.5.3" +version = "1.5.4" authors = [ {email = "manosstoumpos@gmail.com"}, {name = "Manos Stoumpos"} diff --git a/src/pregex/assertions.py b/src/pregex/assertions.py index d8429b2..dd10ee3 100644 --- a/src/pregex/assertions.py +++ b/src/pregex/assertions.py @@ -14,7 +14,7 @@ quantifier. Classes & methods -=========================================== +------------------------------------------- Below are listed all classes within :py:mod:`pregex.assertions` along with any possible methods they may possess. @@ -58,22 +58,24 @@ class __PositiveLookaround(__Assertion): Constitutes the base class for classes ``FollowedBy`` and ``PrecededBy`` \ that are part of this module. - :param Pregex | str pre1: A Pregex instance or string representing the `match` pattern. - :param Pregex | str pre2: A Pregex instance or string representing the `assertion` pattern. + :param Pregex | str match: A Pregex instance or string representing the `match` pattern. + :param Pregex | str assertion: A Pregex instance or string representing the `assertion` pattern. :param (Pregex, Pregex => str) transform: A `transform` function for the provided patterns. ''' - def __init__(self, pre1: _pre.Pregex or str, pre2: _pre.Pregex or str, transform): + def __init__(self, match: _pre.Pregex or str, assertion: _pre.Pregex or str, transform): ''' Constitutes the base class for classes ``FollowedBy`` and ``PrecededBy`` \ that are part of this module. - :param Pregex | str pre1: A Pregex instance or string representing the `match` pattern. - :param Pregex | str pre2: A Pregex instance or string representing the `assertion` pattern. + :param Pregex | str match: A Pregex instance or string representing the `match` pattern. + :param Pregex | str assertion: A Pregex instance or string representing the `assertion` pattern. :param (Pregex, Pregex => str) transform: A `transform` function for the provided patterns. ''' - pre1 = __class__._to_pregex(pre1) - pre2 = __class__._to_pregex(pre2) - super().__init__(transform(pre1, pre2)) + match = __class__._to_pregex(match) + assertion = __class__._to_pregex(assertion) + result = match if assertion._get_type() == _pre._Type.Empty \ + else transform(match, assertion) + super().__init__(str(result)) class __NegativeLookaround(__Assertion): @@ -81,28 +83,37 @@ class __NegativeLookaround(__Assertion): Constitutes the base class for classes ``NotFollowedBy`` and ``NotPrecededBy`` \ that are part of this module. - :param Pregex | str pre1: A Pregex instance or string representing the `match` pattern. - :param Pregex | str *pres: One or more Pregex instances or strings representing the `assertion` patterns. + :param Pregex | str *pres: Two or more Pregex instances, the first of which always \ + represents the `match` pattern, while the rest constitute `assertion` patterns. :param (tuple[Pregex | str] => str) transform: A `transform` function for the provided patterns. - :raises LessThanTwoArgumentsException: Less than two arguments are provided. + :raises NotEnoughArgumentsException: No assertion patterns were provided. + :raises EmptyNegativeAssertionException: The empty string is provided \ + as one of the assertion patterns. ''' def __init__(self, pres: tuple[_pre.Pregex or str], transform) -> _pre.Pregex: ''' Constitutes the base class for classes ``NotFollowedBy`` and ``NotPrecededBy`` \ that are part of this module. - :param Pregex | str pre1: A Pregex instance or string representing the `match` pattern. - :param Pregex | str *pres: One or more Pregex instances or strings representing the `assertion` patterns. + :param Pregex | str *pres: Two or more Pregex instances, the first of which always \ + represents the `match` pattern, while the rest constitute `assertion` patterns. :param (tuple[Pregex | str] => str) transform: A `transform` function for the provided patterns. - :raises LessThanTwoArgumentsException: Less than two arguments are provided. + :raises NotEnoughArgumentsException: No assertion patterns were provided. + :raises EmptyNegativeAssertionException: The empty string is provided \ + as one of the assertion patterns. ''' if len(pres) < 2: - raise _ex.LessThanTwoArgumentsException() + message = "At least one assertion pattern is required." + raise _ex.NotEnoughArgumentsException(message) result = __class__._to_pregex(pres[0]) for pre in pres[1:]: - result = _pre.Pregex(transform(result, __class__._to_pregex(pre)), escape=False) + pre = __class__._to_pregex(pre) + if pre._get_type() == _pre._Type.Empty: + result = _pre.Empty() + raise _ex.EmptyNegativeAssertionException() + result = _pre.Pregex(transform(result, pre), escape=False) super().__init__(str(result)) @@ -208,106 +219,126 @@ def __init__(self): class FollowedBy(__PositiveLookaround): ''' - Matches pattern ``pre1`` only if it is followed by pattern ``pre2``, \ - without the latter being included into the match. + Matches pattern ``match`` only if it is followed by pattern \ + ``assertion``, without the latter being included into the match. - :param Pregex | str pre1: The pattern that is to be matched. - :param Pregex | str pre2: The pattern that must follow pattern ``pre1`` \ - in order for it to be considered a match. + :param Pregex | str match: A Pregex instance or string \ + representing the `match` pattern. + :param Pregex | str assertion: A Pregex instance or string \ + representing the `assertion` pattern. ''' - def __init__(self, pre1: _pre.Pregex or str, pre2: _pre.Pregex or str): + def __init__(self, match: _pre.Pregex or str, assertion: _pre.Pregex or str): ''' - Matches pattern ``pre1`` only if it is followed by pattern ``pre2``, \ - without the latter being included into the match. + Matches pattern ``match`` only if it is followed by pattern \ + ``assertion``, without the latter being included into the match. - :param Pregex | str pre1: The pattern that is to be matched. - :param Pregex | str pre2: The pattern that must follow pattern ``pre1`` \ - in order for it to be considered a match. + :param Pregex | str match: A Pregex instance or string \ + representing the `match` pattern. + :param Pregex | str assertion: A Pregex instance or string \ + representing the `assertion` pattern. ''' - super().__init__(pre1, pre2, lambda pre1, pre2: str(pre1._followed_by(pre2))) + super().__init__(match, assertion, lambda pre1, pre2: str(pre1._followed_by(pre2))) class NotFollowedBy(__NegativeLookaround): ''' - Matches pattern ``pre`` only if it is not followed by any one of \ - the rest of the provided patterns. + Matches pattern ``match` only if it is not followed by any one of \ + the `provided ``assertion`` patterns. - :param Pregex | str pre: The pattern that is to be matched. - :param Pregex | str \*pres: One or more patterns, none of which must \ - come right after ``pre`` in order for it to be considered a match. + :param Pregex | str match: The pattern that is to be matched. + :param Pregex | str \*assertions: One or more patterns, none of which must \ + come right after ``match`` in order for it to be considered a match. + + :raises NotEnoughArgumentsException: No assertion patterns were provided. + :raises EmptyNegativeAssertionException: The empty string is provided \ + as one of the assertion patterns. ''' - def __init__(self, pre: _pre.Pregex or str, *pres: _pre.Pregex or str): + def __init__(self, match: _pre.Pregex or str, *assertions: _pre.Pregex or str): ''' - Matches pattern ``pre`` only if it is not followed by any one of \ - rest of the provided patterns. + Matches pattern ``match` only if it is not followed by any one of \ + the `provided ``assertion`` patterns. - :param Pregex | str pre: The pattern that is to be matched. - :param Pregex | str \*pres: One or more patterns, none of which must \ - come right after ``pre`` in order for it to be considered a match. + :param Pregex | str match: The pattern that is to be matched. + :param Pregex | str \*assertions: One or more patterns, none of which must \ + come right after ``match`` in order for it to be considered a match. + + :raises NotEnoughArgumentsException: No assertion patterns were provided. + :raises EmptyNegativeAssertionException: The empty string is provided \ + as one of the assertion patterns. ''' - super().__init__((pre, *pres), lambda pre1, pre2: str(pre1._not_followed_by(pre2))) + super().__init__((match, *assertions), + lambda pre1, pre2: str(pre1._not_followed_by(pre2))) class PrecededBy(__PositiveLookaround): ''' - Matches pattern ``pre1`` only if it is preceded by pattern ``pre2``, \ - without the latter being included into the match. + Matches pattern ``match`` only if it is preceded by pattern \ + ``assertion``, without the latter being included into the match. - :param Pregex | str pre1: The pattern that is to be matched. - :param Pregex | str pre2: The pattern that must precede pattern ``pre1`` \ - in order for it to be considered a match. + :param Pregex | str match: A Pregex instance or string \ + representing the `match` pattern. + :param Pregex | str assertion: A Pregex instance or string \ + representing the `assertion` pattern. - :raises NonFixedWidthPatternException: A class that represents a non-fixed-width \ - pattern is provided as parameter ``pre2``. + :raises NonFixedWidthPatternException: A non-fixed-width pattern \ + is provided in place of parameter ``assertion``. ''' - def __init__(self, pre1: _pre.Pregex or str, pre2: _pre.Pregex or str): + def __init__(self, match: _pre.Pregex or str, assertion: _pre.Pregex or str): ''' - Matches pattern ``pre1`` only if it is preceded by pattern ``pre2``, \ - without the latter being included into the match. + Matches pattern ``match`` only if it is preceded by pattern \ + ``assertion``, without the latter being included into the match. - :param Pregex | str pre1: The pattern that is to be matched. - :param Pregex | str pre2: The pattern that must precede pattern ``pre1`` \ - in order for it to be considered a match. + :param Pregex | str match: A Pregex instance or string \ + representing the `match` pattern. + :param Pregex | str assertion: A Pregex instance or string \ + representing the `assertion` pattern. - :raises NonFixedWidthPatternException: A class that represents a non-fixed-width \ - pattern is provided as parameter ``pre2``. + :raises NonFixedWidthPatternException: A non-fixed-width pattern \ + is provided in place of parameter ``assertion``. ''' - if isinstance(pre2, _pre.Pregex): - if pre2._get_type() == _pre._Type.Quantifier and (not isinstance(pre2, _Exactly)): - raise _ex.NonFixedWidthPatternException(self, pre2) - super().__init__(pre1, pre2, lambda pre1, pre2: str(pre1._preceded_by(pre2))) + if isinstance(assertion, _pre.Pregex): + if assertion._get_type() == _pre._Type.Quantifier \ + and (not isinstance(assertion, _Exactly)): + raise _ex.NonFixedWidthPatternException(self, assertion) + super().__init__(match, assertion, lambda pre1, pre2: str(pre1._preceded_by(pre2))) class NotPrecededBy(__NegativeLookaround): ''' - Matches pattern ``pre`` only if it is not preceded by any one of \ - the rest of the provided patterns. - - :param Pregex | str pre: The pattern that is to be matched. - :param Pregex | str \*pres: One or more patterns, none of which must \ - come right before ``pre`` in order for it to be considered a match. - - :raises NonFixedWidthPatternException: At least one of the provided classes \ - in ``pres`` represents a non-fixed-width pattern. + Matches pattern ``match` only if it is not preceded by any one of \ + the `provided ``assertion`` patterns. + + :param Pregex | str match: The pattern that is to be matched. + :param Pregex | str \*assertions: One or more patterns, none of which must \ + come right before ``match`` in order for it to be considered a match. + + :raises NotEnoughArgumentsException: No assertion patterns were provided. + :raises EmptyNegativeAssertionException: The empty string is provided \ + as one of the assertion patterns. + :raises NonFixedWidthPatternException: At least one of the provided assertion \ + patterns is a non-fixed-width pattern. ''' - def __init__(self, pre: _pre.Pregex or str, *pres: _pre.Pregex or str): + def __init__(self, match: _pre.Pregex or str, *assertions: _pre.Pregex or str): ''' - Matches pattern ``pre`` only if it is not preceded by any one of \ - the rest of the provided patterns. - - :param Pregex | str pre: The pattern that is to be matched. - :param Pregex | str \*pres: One or more patterns, none of which must \ - come right before ``pre`` in order for it to be considered a match. - - :raises NonFixedWidthPatternException: At least one of the provided classes \ - in ``pres`` represents a non-fixed-width pattern. + Matches pattern ``match` only if it is not preceded by any one of \ + the `provided ``assertion`` patterns. + + :param Pregex | str match: The pattern that is to be matched. + :param Pregex | str \*assertions: One or more patterns, none of which must \ + come right before ``match`` in order for it to be considered a match. + + :raises NotEnoughArgumentsException: No assertion patterns were provided. + :raises EmptyNegativeAssertionException: The empty string is provided \ + as one of the assertion patterns. + :raises NonFixedWidthPatternException: At least one of the provided assertion \ + patterns is a non-fixed-width pattern. ''' - for p in pres: - if isinstance(p, _pre.Pregex): - if p._get_type() == _pre._Type.Quantifier and (not isinstance(p, _Exactly)): - raise _ex.NonFixedWidthPatternException(self, p) - super().__init__((pre, *pres), lambda pre1, pre2: str(pre1._not_preceded_by(pre2))) \ No newline at end of file + for pre in assertions: + if isinstance(pre, _pre.Pregex): + if pre._get_type() == _pre._Type.Quantifier and (not isinstance(pre, _Exactly)): + raise _ex.NonFixedWidthPatternException(self, pre) + super().__init__((match, *assertions), lambda pre1, pre2: str(pre1._not_preceded_by(pre2))) \ No newline at end of file diff --git a/src/pregex/classes.py b/src/pregex/classes.py index ddc435e..77c453e 100644 --- a/src/pregex/classes.py +++ b/src/pregex/classes.py @@ -8,7 +8,7 @@ which can be used in order to define a set or "class" of characters that can be matched. Class types -================= +------------------------------------------- A character class can be either one of the following two types: 1. **Regular class**: This type of class represents the `[...]` pattern, @@ -35,7 +35,7 @@ print(negated.get_pattern()) # This prints "[^A-Za-z]" Class unions -================= +------------------------------------------- Classes of the same type can be combined together in order to get the union of the sets of characters they represent. This can be easily done though the use of the bitwise OR operator ``|``, as depicted within the code snippet below: @@ -91,7 +91,7 @@ print(pre.get_pattern()) # This prints "[^\da\\n]" Subtracting classes -====================== +------------------------------------------- Subtraction is another operation that is exclusive to classes and it is made possible via the overloaded subtraction operator ``-``. This feature comes in handy when one wishes to construct a class that would be tiresome to create otherwise. Consider @@ -135,10 +135,10 @@ pre = AnyWhitespace() - Newline() - print(pre.get_pattern()) # This prints "[ \\x0b\\x0c\\t\\r]" + print(pre.get_pattern()) # This prints "[\\t \\x0b-\\r]" Negating classes -==================== +------------------------------------------- Finally, it is useful to know that every regular class can be negated through the use of the bitwise NOT operator ``~``: @@ -164,7 +164,7 @@ class by placing ``~`` in front of it, or use its `AnyBut*` negated class equiva The result is entirely the same and which one you'll use is just a matter of choice. Classes & methods -=========================================== +------------------------------------------- Below are listed all classes within :py:mod:`pregex.classes` along with any possible methods they may possess. @@ -947,7 +947,7 @@ class AnyBetween(__Class): :param str start: The first character of the range. :param str end: The last character of the range. - :raises NeitherCharNorTokenException: At least one of the provided characters \ + :raises InvalidArgumentTypeException: At least one of the provided characters \ is neither a `token` class instance nor a single-character string. :raises InvalidRangeException: A non-valid range is provided. @@ -963,7 +963,7 @@ def __init__(self, start: str, end: str) -> 'AnyBetween': :param str start: The first character of the range. :param str end: The last character of the range. - :raises NeitherCharNorTokenException: At least one of the provided characters \ + :raises InvalidArgumentTypeException: At least one of the provided characters \ is neither a `token` class instance nor a single-character string. :raises InvalidRangeException: A non-valid range is provided. @@ -973,10 +973,12 @@ def __init__(self, start: str, end: str) -> 'AnyBetween': ''' for c in (start, end): if isinstance(c, (str, _pre.Pregex)): - if len(str(c).replace("\\", "", 1)) > 1: - raise _ex.NeitherCharNorTokenException() + if len(str(c).replace("\\", "", 1)) > 1: + message = f"Argument \"{c}\" is neither a string nor a token." + raise _ex.InvalidArgumentTypeException(message) else: - raise _ex.NeitherCharNorTokenException() + message = f"Argument \"{c}\" is neither a string nor a token." + raise _ex.InvalidArgumentTypeException(message) start, end = str(start), str(end) if ord(start) >= ord(end): raise _ex.InvalidRangeException(start, end) @@ -992,7 +994,7 @@ class AnyButBetween(__Class): :param str start: The first character of the range. :param str end: The last character of the range. - :raises NeitherCharNorTokenException: At least one of the provided characters \ + :raises InvalidArgumentTypeException: At least one of the provided characters \ is neither a `token` class instance nor a single-character string. :raises InvalidRangeException: A non-valid range is provided. @@ -1008,7 +1010,7 @@ def __init__(self, start: str, end: str) -> 'AnyButBetween': :param str start: The first character of the range. :param str end: The last character of the range. - :raises NeitherCharNorTokenException: At least one of the provided characters \ + :raises InvalidArgumentTypeException: At least one of the provided characters \ is neither a `token` class instance nor a single-character string. :raises InvalidRangeException: A non-valid range is provided. @@ -1019,9 +1021,11 @@ def __init__(self, start: str, end: str) -> 'AnyButBetween': for c in (start, end): if isinstance(c, (str, _pre.Pregex)): if len(str(c).replace("\\", "", 1)) > 1: - raise _ex.NeitherCharNorTokenException() + message = f"Argument \"{c}\" is neither a string nor a token." + raise _ex.InvalidArgumentTypeException(message) else: - raise _ex.NeitherCharNorTokenException() + message = f"Argument \"{c}\" is neither a string nor a token." + raise _ex.InvalidArgumentTypeException(message) start, end = str(start), str(end) if ord(start) >= ord(end): raise _ex.InvalidRangeException(start, end) @@ -1037,9 +1041,9 @@ class AnyFrom(__Class): :param Pregex | str \*chars: One or more characters to match from. Each character must be \ a string of length one, provided either as is or wrapped within a `tokens` class. - :raises ZeroArgumentsExceptions: No arguments are provided. - :raises NeitherCharNorTokenException: At least one of the provided characters is \ - neither a `token` class instance nor a single-character string. + :raises NotEnoughArgumentsExceptions: No arguments are provided. + :raises InvalidArgumentTypeException: At least one of the provided arguments \ + is neither a `token` class instance nor a single-character string. ''' def __init__(self, *chars: str or _pre.Pregex) -> 'AnyFrom': @@ -1049,18 +1053,21 @@ def __init__(self, *chars: str or _pre.Pregex) -> 'AnyFrom': :param Pregex | str \*chars: One or more characters to match from. Each character must be \ a string of length one, provided either as is or wrapped within a `tokens` class. - :raises ZeroArgumentsExceptions: No arguments are provided. - :raises NeitherCharNorTokenException: At least one of the provided characters is \ - neither a `token` class instance nor a single-character string. + :raises NotEnoughArgumentsExceptions: No arguments are provided. + :raises InvalidArgumentTypeException: At least one of the provided arguments \ + is neither a `token` class instance nor a single-character string. ''' if len(chars) == 0: - raise _ex.ZeroArgumentsException(self) + message = f"No characters were provided to \"{__class__.__name__}\"." + raise _ex.NotEnoughArgumentsException(message) for c in chars: if isinstance(c, (str, _pre.Pregex)): if len(str(c).replace("\\", "", 1)) > 1: - raise _ex.NeitherCharNorTokenException() + message = f"Argument \"{c}\" is neither a string nor a token." + raise _ex.InvalidArgumentTypeException(message) else: - raise _ex.NeitherCharNorTokenException() + message = f"Argument \"{c}\" is neither a string nor a token." + raise _ex.InvalidArgumentTypeException(message) chars = tuple((f"\\{c}" if c in __class__._to_escape else c) \ if isinstance(c, str) else str(c) for c in chars) super().__init__(f"[{''.join(chars)}]", is_negated=False) @@ -1073,9 +1080,9 @@ class AnyButFrom(__Class): :param Pregex | str \*chars: One or more characters not to match from. Each character must be \ a string of length one, provided either as is or wrapped within a `tokens` class. - :raises ZeroArgumentsExceptions: No arguments are provided. - :raises NeitherCharNorTokenException: At least one of the provided characters is \ - neither a `token` class instance nor a single-character string. + :raises NotEnoughArgumentsExceptions: No arguments are provided. + :raises InvalidArgumentTypeException: At least one of the provided arguments \ + is neither a `token` class instance nor a single-character string. ''' def __init__(self, *chars: str or _pre.Pregex) -> 'AnyButFrom': @@ -1085,18 +1092,21 @@ def __init__(self, *chars: str or _pre.Pregex) -> 'AnyButFrom': :param Pregex | str \*chars: One or more characters not to match from. Each character must be \ a string of length one, provided either as is or wrapped within a `tokens` class. - :raises ZeroArgumentsExceptions: No arguments are provided. - :raises NeitherCharNorTokenException: At least one of the provided characters is \ - neither a `token` class instance nor a single-character string. + :raises NotEnoughArgumentsExceptions: No arguments are provided. + :raises InvalidArgumentTypeException: At least one of the provided arguments \ + is neither a `token` class instance nor a single-character string. ''' if len(chars) == 0: - raise _ex.ZeroArgumentsException(self) + message = f"No characters were provided to \"{__class__.__name__}\"." + raise _ex.NotEnoughArgumentsException(message) for c in chars: if isinstance(c, (str, _pre.Pregex)): if len(str(c).replace("\\", "", 1)) > 1: - raise _ex.NeitherCharNorTokenException() + message = f"Argument \"{c}\" is neither a string nor a token." + raise _ex.InvalidArgumentTypeException(message) else: - raise _ex.NeitherCharNorTokenException() + message = f"Argument \"{c}\" is neither a string nor a token." + raise _ex.InvalidArgumentTypeException(message) chars = tuple((f"\{c}" if c in __class__._to_escape else c) if isinstance(c, str) else str(c) for c in chars) super().__init__(f"[^{''.join(chars)}]", is_negated=True) diff --git a/src/pregex/exceptions.py b/src/pregex/exceptions.py index 5ab8b1c..14d7119 100644 --- a/src/pregex/exceptions.py +++ b/src/pregex/exceptions.py @@ -1,128 +1,71 @@ - - -class NeitherStringNorPregexException(Exception): - ''' - This exception is thrown whenever an argument is neither a "Pregex" \ - instance nor a string, even though it is required to be. +class InvalidArgumentValueException(Exception): ''' + This exception is thrown whenever an argument of invalid value is provided. - def __init__(self): - ''' - The class's constructor. - ''' - super().__init__("The argument that was provided is neither a string nor a subtype of \"Pregex\".") - - -class NeitherCharNorTokenException(Exception): - ''' - This exception is thrown whenever an argument is neither an instance \ - belonging in module "tokens" nor a single character string. + :param str message: The message that is to be displayed \ + along with the exception. ''' - def __init__(self): - ''' - The class's constructor. + def __init__(self, message): ''' - super().__init__("At least one of the provided arguments is neither a string nor a token.") - - -class NonStringArgumentException(Exception): - ''' - This exception is thrown whenever an argument is not a string \ - even though it is required to be. - ''' + This exception is thrown whenever an argument of invalid value is provided. - def __init__(self): - ''' - The class's constructor. + :param str message: The message that is to be displayed \ + along with the exception. ''' - super().__init__("The argument that was provided is not a string.") + super().__init__(message) -class NegativeArgumentException(Exception): +class InvalidArgumentTypeException(Exception): ''' - This exception is thrown whenever an argument is a negative number. - ''' - - def __init__(self, name: str, value: int): - ''' - The class's constructor. - - :param str name: The name of the argument that caused the exception. - :param int n: The value of the argument that caused the exception. - ''' - super().__init__(f"Argument \"{name}\" of value \"{value}\" can't be negative.") - + This exception is thrown whenever an argument of invalid type is provided. -class NonPositiveArgumentException(Exception): - ''' - This exception is thrown whenever an argument is either \ - a negative number or the number zero. + :param str message: The message that is to be displayed \ + along with the exception. ''' - def __init__(self, name: str, value: int): + def __init__(self, message): ''' - The class's constructor. + This exception is thrown whenever an argument of invalid type is provided. - :param str name: The name of the argument that caused the exception. - :param int n: The value of the argument that caused the exception. + :param str message: The message that is to be displayed \ + along with the exception. ''' - super().__init__(f"Argument \"{name}\" of value \"{value}\" can't be less than one.") + super().__init__(message) -class MinGreaterThanMaxException(Exception): - ''' - This exception is thrown whenever there were provided a tuple \ - of values "min" and "max", where "min" is greater than "max". +class NotEnoughArgumentsException(Exception): ''' + This exception is thrown whenever an insufficient amount \ + of arguments is provided. - def __init__(self, min: int, max: int): - ''' - The class's constructor. - - :param int min: The integer because of which this exception was thrown. - :param int max: The integer because of which this exception was thrown. - ''' - super().__init__(f"Minimum value \"{min}\" is greater than maximum value \"{max}\".") - - -class LessThanTwoArgumentsException(Exception): - ''' - This exception is thrown whenever one or none arguments were - provided to a method or class constructor requiring at least two. + :param str message: The message that is to be displayed \ + along with the exception. ''' - def __init__(self): - ''' - The class's constructor. + def __init__(self, message: str): ''' - super().__init__("This constructor requires at least two arguments.") - - -class ZeroArgumentsException(Exception): - ''' - This exception is thrown whenever no arguments were \ - provided to a method which requires at least two. - ''' - - def __init__(self, pre): - ''' - The class's constructor. + This exception is thrown whenever an insufficient amount \ + of arguments is provided. + :param str message: The message that is to be displayed \ + along with the exception. ''' - m = f"No arguments were provided to class constructor \"{type(pre).__name__}\"." - super().__init__(m) + super().__init__(message) class InvalidCapturingGroupNameException(Exception): ''' This exception is thrown whenever an invalid name \ for a capturing group was provided. + + :param str name: The string type argument because of which this exception was thrown. ''' def __init__(self, name: str): ''' - The class's constructor. + This exception is thrown whenever an invalid name \ + for a capturing group was provided. :param str name: The string type argument because of which this exception was thrown. ''' @@ -130,26 +73,14 @@ def __init__(self, name: str): "name must be an alphanumeric sequence that starts with a non-digit.") -class NonIntegerArgumentException(Exception): - ''' - This exception is thrown whenever the provided argument is not an integer. - ''' - - def __init__(self, arg): - ''' - The class's constructor. - - :param Any arg: The unknown type argument because of which this exception was thrown. - ''' - super().__init__(f"Argument \"{arg}\" is not an integer.") - - class CannotBeNegatedException(Exception): ''' - This exception is thrown whenever one tries to negate class "Any". + This exception is thrown whenever one tries to negate class ``Any``. ''' - def __init__(self): + ''' + This exception is thrown whenever one tries to negate class ``Any``. + ''' super().__init__(f"Class \"Any\" cannot be negated.") @@ -157,14 +88,20 @@ class CannotBeUnionedException(Exception): ''' This exception is thrown whenever one tries to union a class (or negated class) \ either with a negated class (or regular class) or an object of different type. + + :param Pregex pre: The ``Pregex`` instance because of which this exception was thrown. + :param bool are_both_classes: Indicates whether both ``Pregex`` instances are of \ + type ``__Class``. ''' def __init__(self, pre, are_both_classes: bool): ''' - The class's constructor. + This exception is thrown whenever one tries to union a class (or negated class) \ + either with a negated class (or regular class) or an object of different type. - :param Pregex pre: The "Pregex" instance because of which this exception was thrown. - :param bool are_both_classes: Indicates whether both "Pregex" instances are of type "__Class". + :param Pregex pre: The ``Pregex`` instance because of which this exception was thrown. + :param bool are_both_classes: Indicates whether both ``Pregex`` instances are of \ + type ``__Class``. ''' m = f"Classes and negated classes cannot be unioned together." if are_both_classes \ else f"Instance of type \"{type(pre).__name__}\" cannot be unioned with a class." @@ -175,14 +112,18 @@ class CannotBeSubtractedException(Exception): ''' This exception is thrown whenever one tries to subtract a class (or negated class) \ either from a negated class (or regular class) or an object of different type. + + :param Pregex pre: The ``Pregex`` instance because of which this exception was thrown. + :param bool are_both_classes: Indicates whether both ``Pregex`` instances are of type ``__Class``. ''' def __init__(self, pre, are_both_classes: bool): ''' - The class's constructor. + This exception is thrown whenever one tries to subtract a class (or negated class) \ + either from a negated class (or regular class) or an object of different type. - :param Pregex pre: The "Pregex" instance because of which this exception was thrown. - :param bool are_both_classes: Indicates whether both "Pregex" instances are of type "__Class". + :param Pregex pre: The ``Pregex`` instance because of which this exception was thrown. + :param bool are_both_classes: Indicates whether both ``Pregex`` instances are of type ``__Class``. ''' m = f"Classes and negated classes cannot be subtracted from one another." if are_both_classes \ else f"Instance of type \"{type(pre).__name__}\" cannot be subtracted from a class." @@ -192,13 +133,17 @@ def __init__(self, pre, are_both_classes: bool): class GlobalWordCharSubtractionException(Exception): ''' This exception is thrown whenever one tries to subtract from an instance of \ - either one of "AnyWordChar" or "AnyButWordChar" classes, for which parameter \ - "is_global" has been set to "true". + either one of ``AnyWordChar`` or ``AnyButWordChar`` classes, for which parameter \ + "is_global" has been set to ``True``. + + :param AnyWordChar | AnyButWordChar pre: An instance of either one of the two classes. ''' def __init__(self, pre): ''' - The class's constructor. + This exception is thrown whenever one tries to subtract from an instance of \ + either one of ``AnyWordChar`` or ``AnyButWordChar`` classes, for which parameter \ + "is_global" has been set to ``True``. :param AnyWordChar | AnyButWordChar pre: An instance of either one of the two classes. ''' @@ -211,14 +156,18 @@ class EmptyClassException(Exception): ''' This exception is thrown whenever one tries to subtract a class (or negated class) \ from a class (or negated class) which results in an empty class. + + :param Pregex pre1: The ``Pregex`` instance because of which this exception was thrown. + :param Pregex pre2: The ``Pregex`` instance because of which this exception was thrown. ''' def __init__(self, pre1, pre2): ''' - The class's constructor. + This exception is thrown whenever one tries to subtract a class (or negated class) \ + from a class (or negated class) which results in an empty class. - :param Pregex pre1: The "Pregex" instance because of which this exception was thrown. - :param Pregex pre2: The "Pregex" instance because of which this exception was thrown. + :param Pregex pre1: The ``Pregex`` instance because of which this exception was thrown. + :param Pregex pre2: The ``Pregex`` instance because of which this exception was thrown. ''' m = f"Cannot subtract class \"{pre2}\" from class \"{pre1}\"" \ " as this results into an empty class." @@ -228,12 +177,16 @@ def __init__(self, pre1, pre2): class InvalidRangeException(Exception): ''' This exception is thrown whenever there was provided a pair \ - of values "start" and "end", where "start" comes after "end". + of values ``start`` and ``end``, where ``start`` comes after ``end``. + + :param int start: The integer because of which this exception was thrown. + :param int end: The integer because of which this exception was thrown. ''' def __init__(self, start, end): ''' - The class's constructor. + This exception is thrown whenever there was provided a pair \ + of values ``start`` and ``end``, where ``start`` comes after ``end``. :param int start: The integer because of which this exception was thrown. :param int end: The integer because of which this exception was thrown. @@ -244,14 +197,17 @@ def __init__(self, start, end): class CannotBeQuantifiedException(Exception): ''' This exception is thrown whenever an instance of a class \ - that is part of the "assertions" module is being quantified. + that is part of the ``assertions`` module is being quantified. + + :param __Assertion pre: The ``__Assertion`` instance because of which this exception was thrown. ''' def __init__(self, pre): ''' - The class's constructor. + This exception is thrown whenever an instance of a class \ + that is part of the ``assertions`` module is being quantified. - :param __Assertion pre: The "__Assertion" instance because of which this exception was thrown. + :param __Assertion pre: The ``__Assertion`` instance because of which this exception was thrown. ''' m = f"Instances of class \"{type(pre).__name__}\" are not quantifiable," m += " with the sole exception to this being the \"Optional\" quantifier \"?\"." @@ -261,15 +217,19 @@ def __init__(self, pre): class NonFixedWidthPatternException(Exception): ''' This exception is thrown whenever a non-fixed-width pattern is being - provided as lookbehind-pattern to either "PrecededBy" or "NotPrecededBy". + provided as lookbehind-pattern to either ``PrecededBy`` or ``NotPrecededBy``. + + :param __Lookaround lookbehind: The ``__Lookaround`` instance because of which this exception was thrown. + :param Pregex pre: The ``Pregex`` instance because of which this exception was thrown. ''' def __init__(self, lookbehind, pre): ''' - The class's constructor. + This exception is thrown whenever a non-fixed-width pattern is being + provided as lookbehind-pattern to either ``PrecededBy`` or ``NotPrecededBy``. - :param __Lookaround lookbehind: The "__Lookaround" instance because of which this exception was thrown. - :param Pregex pre: The "Pregex" instance because of which this exception was thrown. + :param __Lookaround lookbehind: The ``__Lookaround`` instance because of which this exception was thrown. + :param Pregex pre: The ``Pregex`` instance because of which this exception was thrown. ''' m = f"Instances of class \"{type(lookbehind).__name__}\" cannot receive an instance of " m += f"class \"{type(pre).__name__}\" in place of a lookbehind-restriction-pattern as the" @@ -277,4 +237,16 @@ def __init__(self, lookbehind, pre): super().__init__(m) +class EmptyNegativeAssertionException(Exception): + ''' + This exception is thrown whenever the ``Empty`` pattern is provided + as a negative assertion. + ''' + def __init__(self): + ''' + This exception is thrown whenever the ``Empty`` pattern is provided + as a negative assertion. + ''' + message = "The empty string can't be provided as a negative lookaround assertion pattern." + super().__init__(message) \ No newline at end of file diff --git a/src/pregex/groups.py b/src/pregex/groups.py index 4bc2c90..20675c3 100644 --- a/src/pregex/groups.py +++ b/src/pregex/groups.py @@ -6,10 +6,13 @@ __doc__ = """ This module contains all necessary classes that are used to construct both capturing and non-capturing groups, as well as any other class that relates to group-related -concepts, such as backreferences and conditionals. In general, one should not have -to concern themselves with pattern-grouping, as patterns are automatically grouped -into non-capturing groups whenever this is deemed necessary. Consider for instance -the following code snippet: +concepts, such as backreferences and conditionals. + +Pattern grouping +------------------------------------------- +In general, one should not have to concern themselves with pattern grouping, +as patterns are automatically wrapped within non-capturing groups whenever this is +deemed necessary. Consider for instance the following code snippet: .. code-block:: python @@ -19,19 +22,20 @@ print(Optional("aa").get_pattern()) # This prints "(?:aa)?" In the first case, quantifier :class:`~pregex.quantifiers.Optional` is applied to the pattern -directly, whereas in the second case the pattern is wrapped within a non-capturing group +directly, whereas in the second case the pattern is placed into a non-capturing group so that "aa" is quantified as a whole. Even so, one can also explicitly construct a -non-capturing group out of any pattern if one wishes to do so: +non-capturing group out of any pattern if one wishes to do so by making use of the +:class:`Group` class: .. code-block:: python from pregex.groups import Group from pregex.quantifiers import Optional - print(Group(Optional("a")).get_pattern()) # This prints "(?:a)?" + print(Optional(Group("a")).get_pattern()) # This prints "(?:a)?" Capturing patterns -=========================================== +------------------------------------------- You'll find however that :class:`Capture` is probably the most important class of this module, as it is used to create a capturing group out of a pattern, @@ -42,12 +46,17 @@ from pregex.groups import Capture from pregex.classes import AnyLetter - pre = AnyLetter() + Capture(AnyLetter()) + AnyLetter() + pre = AnyLetter() + Capture(2 * AnyLetter()) + + text = "abc def" + print(pre.get_matches(text)) # This prints "['abc', 'def']" + print(pre.get_captures(text)) # This prints "[('bc'), ('ef')]" - print(pre.get_captures("abc def")) # This prints "[('b'), ('e')]" +As you can see, capturing is a very useful tool for whenever you are +interested in isolating some specific part of a pattern. Classes & methods -=========================================== +------------------------------------------- Below are listed all classes within :py:mod:`pregex.groups` along with any possible methods they may possess. @@ -82,7 +91,7 @@ class Capture(__Group): :param str name: The name that is assigned to the captured group for backreference purposes. \ A value of ``''`` indicates that no name is to be assigned to the group. Defaults to ``''``. - :raises NonStringArgumentException: Parameter ``name`` is not a string. + :raises InvalidArgumentTypeException: Parameter ``name`` is not a string. :raises InvalidCapturingGroupNameException: Parameter ``name`` is not a valid \ capturing-group name. Such name must contain word characters only and start \ with a non-digit character. @@ -102,7 +111,7 @@ def __init__(self, pre: _pre.Pregex or str, name: str = ''): :param str name: The name that is assigned to the captured group for backreference purposes. \ A value of ``''`` indicates that no name is to be assigned to the group. Defaults to ``''``. - :raises NonStringArgumentException: Parameter ``name`` is not a string. + :raises InvalidArgumentTypeException: Parameter ``name`` is not a string. :raises InvalidCapturingGroupNameException: Parameter ``name`` is not a valid \ capturing-group name. Such name must contain word characters only and start \ with a non-digit character. @@ -114,7 +123,8 @@ def __init__(self, pre: _pre.Pregex or str, name: str = ''): - Creating a named capturing group out of a named capturing group, changes the group's name. ''' if not isinstance(name, str): - raise _ex.NonStringArgumentException() + message = "Provided argument \"name\" is not a string." + raise _ex.InvalidArgumentTypeException(message) if name != '' and _re.fullmatch("[A-Za-z_]\w*", name) is None: raise _ex.InvalidCapturingGroupNameException(name) super().__init__(pre, lambda pre: pre._capturing_group(name)) @@ -153,7 +163,7 @@ class Backreference(__Group): :param str name: The name of the referenced capturing group. - :raises NonStringArgumentException: Parameter ``name`` is not a string. + :raises InvalidArgumentTypeException: Parameter ``name`` is not a string. :raises InvalidCapturingGroupNameException: Parameter ``name`` is not a valid \ capturing-group name. Such name must contain word characters only and start \ with a non-digit character. @@ -167,13 +177,14 @@ def __init__(self, name: str): :param str name: The name of the referenced capturing group. - :raises NonStringArgumentException: Parameter ``name`` is not a string. + :raises InvalidArgumentTypeException: Parameter ``name`` is not a string. :raises InvalidCapturingGroupNameException: Parameter ``name`` is not a valid \ capturing-group name. Such name must contain word characters only and start \ with a non-digit character. ''' if not isinstance(name, str): - raise _ex.NonStringArgumentException() + message = "Provided argument \"name\" is not a string." + raise _ex.InvalidArgumentTypeException(message) if _re.fullmatch("[A-Za-z_][A-Za-z_0-9]*", name) is None: raise _ex.InvalidCapturingGroupNameException(name) super().__init__(name, lambda s : f"(?P={s})") @@ -191,7 +202,7 @@ class Conditional(__Group): :param Pregex | str pre2: The pattern that is to be matched in case condition is false. \ Defaults to ``''``. - :raises NonStringArgumentException: Parameter ``name`` is not a string. + :raises InvalidArgumentTypeException: Parameter ``name`` is not a string. :raises InvalidCapturingGroupNameException: Parameter ``name`` is not a valid \ capturing-group name. Such name must contain word characters only and start \ with a non-digit character. @@ -209,13 +220,14 @@ def __init__(self, name: str, pre1: _pre.Pregex or str, pre2: _pre.Pregex or str :param Pregex | str pre2: The pattern that is to be matched in case condition is false. \ Defaults to ``''``. - :raises NonStringArgumentException: Parameter ``name`` is not a string. + :raises InvalidArgumentTypeException: Parameter ``name`` is not a string. :raises InvalidCapturingGroupNameException: Parameter ``name`` is not a valid \ capturing-group name. Such name must contain word characters only and start \ with a non-digit character. ''' if not isinstance(name, str): - raise _ex.NonStringArgumentException() + message = "Provided argument \"name\" is not a string." + raise _ex.InvalidArgumentTypeException(message) if _re.fullmatch("[A-Za-z_][\w]*", name) is None: raise _ex.InvalidCapturingGroupNameException(name) super().__init__(name, lambda s: f"(?({s}){pre1}{'|' + str(pre2) if pre2 != '' else ''})") \ No newline at end of file diff --git a/src/pregex/operators.py b/src/pregex/operators.py index 5393766..817fc2d 100644 --- a/src/pregex/operators.py +++ b/src/pregex/operators.py @@ -9,7 +9,7 @@ provided patterns can be matched. Classes & methods -=========================================== +------------------------------------------- Below are listed all classes within :py:mod:`pregex.operators` along with any possible methods they may possess. @@ -24,7 +24,7 @@ class __Operator(_pre.Pregex): the patterns to which the operator is to be applied. :param (tuple[Pregex | str] => str) transform: A `transform` function for the provided pattern. - :raises LessThanTwoArgumentsException: Less than two arguments are provided. + :raises NotEnoughArgumentsException: Less than two arguments are provided. ''' def __init__(self, pres: tuple[_pre.Pregex or str], transform) -> _pre.Pregex: ''' @@ -34,12 +34,13 @@ def __init__(self, pres: tuple[_pre.Pregex or str], transform) -> _pre.Pregex: the patterns to which the operator is to be applied. :param (tuple[Pregex | str] => str) transform: A `transform` function for the provided pattern. - :raises LessThanTwoArgumentsException: Less than two arguments are provided. + :raises NotEnoughArgumentsException: Less than two arguments are provided. ''' if len(pres) < 2: - raise _ex.LessThanTwoArgumentsException() - result = __class__._to_pregex(pres[0]) - for pre in pres[1:]: + message = "At least two requirements are required." + raise _ex.NotEnoughArgumentsException(message) + result =_pre.Empty() + for pre in pres: result = _pre.Pregex(transform(result, __class__._to_pregex(pre)), escape=False) super().__init__(str(result), escape=False) @@ -50,7 +51,7 @@ class Concat(__Operator): :param Pregex | str \*pres: Two or more patterns that are to be concatenated. - :raises LessThanTwoArgumentsException: Less than two arguments are provided. + :raises NotEnoughArgumentsException: Less than two arguments are provided. ''' def __init__(self, *pres: _pre.Pregex or str) -> _pre.Pregex: @@ -59,7 +60,7 @@ def __init__(self, *pres: _pre.Pregex or str) -> _pre.Pregex: :param Pregex | str \*pres: Two or more patterns that are to be concatenated. - :raises LessThanTwoArgumentsException: Less than two arguments are provided. + :raises NotEnoughArgumentsException: Less than two arguments are provided. ''' super().__init__(pres, lambda pre1, pre2: pre1._concat(pre2)) @@ -71,7 +72,7 @@ class Either(__Operator): :param Pregex | str \*pres: Two or more patterns that constitute the \ operator's alternatives. - :raises LessThanTwoArgumentsException: Less than two arguments are provided. + :raises NotEnoughArgumentsException: Less than two arguments are provided. :note: One should be aware that ``Either`` is eager, meaning that the regex engine will \ stop the moment it matches either one of the alternatives, starting from \ @@ -85,7 +86,7 @@ def __init__(self, *pres: _pre.Pregex or str): :param Pregex | str \*pres: Two or more patterns that constitute the \ operator's alternatives. - :raises LessThanTwoArgumentsException: Less than two arguments are provided. + :raises NotEnoughArgumentsException: Less than two arguments are provided. :note: One should be aware that ``Either`` is eager, meaning that the regex engine will \ stop the moment it matches either one of the alternatives, starting from \ diff --git a/src/pregex/pre.py b/src/pregex/pre.py index 07a72d3..a6b54d2 100644 --- a/src/pregex/pre.py +++ b/src/pregex/pre.py @@ -9,7 +9,7 @@ inherited by every other class as well. Converting a string into a Pregex instance -=========================================== +-------------------------------------------- In general, one can wrap any string within a Pregex instance by passing it as a parameter to the class's constructor. By doing this, any characters of the provided string that require escaping are automatically escaped. @@ -47,7 +47,7 @@ print(pre.get_pattern()) # This prints '[a-z].?' Concatenating patterns with `+` -=========================================== +------------------------------------------- Instead of using class :class:`~pregex.operators.Concat` in order to concatenate Pregex instances, one is also able to make use of the overloaded addition operator ``+`` as seen in the example below: @@ -75,7 +75,7 @@ Concatenating patterns this way is encouraged as it leads to much more easy-to-read code. Repeating patterns with `*` -=========================================== +------------------------------------------- :class:`Pregex` has one more overloaded operator, namely the multiplication operator ``*``, which essentially replaces the functionality of class :class:`~pregex.quantifiers.Exactly`. By using this operator on a Pregex instance, @@ -90,7 +90,7 @@ print(pre.get_pattern()) # This prints 'a{3}' Classes & methods -=========================================== +------------------------------------------- Below are listed all classes within :py:mod:`pregex.pre` along with any possible methods they may possess. @@ -118,7 +118,7 @@ class Pregex(): :param str pattern: The pattern that is to be wrapped within an instance of this class. :param bool escape: Determines whether to escape the provided pattern or not. Defaults to ``True``. - :raises NonStringArgumentException: Parameter ``pattern`` is not a string. + :raises InvalidArgumentTypeException: Parameter ``pattern`` is not a string. :note: This class constitutes the base class for every other class within the `pregex` package. ''' @@ -154,12 +154,13 @@ def __init__(self, pattern: str, escape: bool = True) -> 'Pregex': :param str pattern: The pattern that is to be wrapped within an instance of this class. :param bool escape: Determines whether to escape the provided pattern or not. Defaults to ``True``. - :raises NonStringArgumentException: Parameter ``pattern`` is not a string. + :raises InvalidArgumentTypeException: Parameter ``pattern`` is not a string. :note: This class constitutes the base class for every other class within the `pregex` package. ''' if not isinstance(pattern, str): - raise _ex.NonStringArgumentException() + message = "Provided argument \"pattern\" is not a string." + raise _ex.InvalidArgumentTypeException(message) if escape: self.__pattern = __class__.__escape(pattern) else: @@ -356,10 +357,11 @@ def replace(self, text: str, repl: str, count: int = 0) -> str: starting from left to right. A value of ``0`` indicates that \ all matches must be replaced. Defaults to ``0``. - :raises NegativeArgumentException: Parameter ``count`` is less than zero. + :raises InvalidArgumentValueException: Parameter ``count`` is less than zero. ''' if count < 0: - raise _ex.NegativeArgumentException("count", count) + message = "Parameter \"count\" can't be negative." + raise _ex.InvalidArgumentValueException(message) return _re.sub(str(self), repl, text, count, flags=self.__flags) @@ -446,7 +448,7 @@ def _to_pregex(pre: 'Pregex' or str) -> 'Pregex': :param Pregex | str: Either a string or a ``Pregex`` instance. - :raises NeitherStringNorPregexException: If ``pre`` is neither a string nor a \ + :raises InvalidArgumentTypeException: Argument ``pre`` is neither a string nor a \ ``Pregex`` class instance. ''' if isinstance(pre, str): @@ -454,7 +456,8 @@ def _to_pregex(pre: 'Pregex' or str) -> 'Pregex': elif issubclass(pre.__class__, __class__): return pre else: - raise _ex.NeitherStringNorPregexException() + message = "Parameter \"pre\" must either be a string or an instance of \"Pregex\"." + raise _ex.InvalidArgumentTypeException(message) ''' @@ -506,16 +509,18 @@ def __mul__(self, n: int) -> 'Pregex': :param int n: This parameter indicates the number of times that ``self`` \ is to be matched. - :raises NonIntegerArgumentException: Parameter ``n`` is not an integer. - :raises NegativeArgumentException: Parameter ``n`` is less than zero. + :raises InvalidArgumentTypeException: Parameter ``n`` is not an integer. + :raises InvalidArgumentValueException: Parameter ``n`` is less than zero. :raises CannotBeQuantifiedException: ``self`` represents an "assertion" pattern. ''' if self.__type == _Type.Assertion: raise _ex.CannotBeQuantifiedException(self) if not isinstance(n, int) or isinstance(n, bool): - raise _ex.NonIntegerArgumentException(n) + message = "Provided argument \"n\" is not an integer." + raise _ex.InvalidArgumentTypeException(message) if n < 0: - raise _ex.NegativeArgumentException("n", n) + message = "Using multiplication operator with a negative integer is not allowed." + raise _ex.InvalidArgumentValueException(message) return __class__(self._exactly(n), escape=False) @@ -526,16 +531,18 @@ def __rmul__(self, n: int) -> 'Pregex': :param int n: This parameter indicates the number of times that ``self`` \ is to be matched. - :raises NonIntegerArgumentException: Parameter ``n`` is not an integer. - :raises NegativeArgumentException: Parameter ``n`` is less than zero. + :raises InvalidArgumentTypeException: Parameter ``n`` is not an integer. + :raises InvalidArgumentValueException: Parameter ``n`` is less than zero. :raises CannotBeQuantifiedException: ``self`` represents an "assertion" pattern. ''' if self.__type == _Type.Assertion: raise _ex.CannotBeQuantifiedException(self) if not isinstance(n, int) or isinstance(n, bool): - raise _ex.NonIntegerArgumentException(n) + message = "Provided argument \"n\" is not an integer." + raise _ex.InvalidArgumentTypeException(message) if n < 0: - raise _ex.NegativeArgumentException("n", n) + message = "Using multiplication operator with a negative integer is not allowed." + raise _ex.InvalidArgumentValueException(message) return __class__(self._exactly(n), escape=False) @@ -970,13 +977,15 @@ def __mul__(self, n: int) -> 'Empty': :param int n: Does nothing. - :raises NonIntegerArgumentException: Parameter ``n`` is not an integer. - :raises NegativeArgumentException: Parameter ``n`` is less than zero. + :raises InvalidArgumentTypeException: Parameter ``n`` is not an integer. + :raises InvalidArgumentValueException: Parameter ``n`` is less than zero. ''' if not isinstance(n, int) or isinstance(n, bool): - raise _ex.NonIntegerArgumentException(n) + message = "Provided argument \"n\" is not an integer." + raise _ex.InvalidArgumentTypeException(message) if n < 0: - raise _ex.NegativeArgumentException("n", n) + message = "Using multiplication operator with a negative integer is not allowed." + raise _ex.InvalidArgumentValueException(message) return self @@ -986,13 +995,15 @@ def __rmul__(self, n: int) -> 'Empty': :param int n: Does nothing. - :raises NonIntegerArgumentException: Parameter ``n`` is not an integer. - :raises NegativeArgumentException: Parameter ``n`` is less than zero. + :raises InvalidArgumentTypeException: Parameter ``n`` is not an integer. + :raises InvalidArgumentValueException: Parameter ``n`` is less than zero. ''' if not isinstance(n, int) or isinstance(n, bool): - raise _ex.NonIntegerArgumentException(n) + message = "Provided argument \"n\" is not an integer." + raise _ex.InvalidArgumentTypeException(message) if n < 0: - raise _ex.NegativeArgumentException("n", n) + message = "Using multiplication operator with a negative integer is not allowed." + raise _ex.InvalidArgumentValueException(message) return self diff --git a/src/pregex/quantifiers.py b/src/pregex/quantifiers.py index 378cfd5..4a8898f 100644 --- a/src/pregex/quantifiers.py +++ b/src/pregex/quantifiers.py @@ -8,7 +8,7 @@ pattern-repetition rule. Classes & methods -=========================================== +------------------------------------------- Below are listed all classes within :py:mod:`pregex.quantifiers` along with any possible methods they may possess. @@ -132,8 +132,8 @@ class Exactly(__Quantifier): or wrapped within a ``Pregex`` subtype instance. :param int n: The exact number of times that the provided pattern is to be matched. - :raises NonIntegerArgumentException: Parameter ``n`` is not an integer. - :raises NegativeArgumentException: Parameter ``n`` is less than zero. + :raises InvalidArgumentTypeException: Parameter ``n`` is not an integer. + :raises InvalidArgumentValueException: Parameter ``n`` is less than zero. :raises CannotBeQuantifiedException: This class is applied to an "assertion" pattern. ''' @@ -145,14 +145,16 @@ def __init__(self, pre: _pre.Pregex or str, n: int) -> _pre.Pregex: or wrapped within a ``Pregex`` subtype instance. :param int n: The exact number of times that the provided pattern is to be matched. - :raises NonIntegerArgumentException: Parameter ``n`` is not an integer. - :raises NegativeArgumentException: Parameter ``n`` is less than zero. + :raises InvalidArgumentTypeException: Parameter ``n`` is not an integer. + :raises InvalidArgumentValueException: Parameter ``n`` is less than zero. :raises CannotBeQuantifiedException: This class is applied to an "assertion" pattern. ''' if not isinstance(n, int) or isinstance(n, bool): - raise _ex.NonIntegerArgumentException(n) + message = "Provided argument \"n\" is not an integer." + raise _ex.InvalidArgumentTypeException(message) if n < 0: - raise _ex.NegativeArgumentException("n", n) + message = "Parameter \"n\" isn't allowed to be negative." + raise _ex.InvalidArgumentValueException(message) super().__init__(pre, False, lambda pre, _: pre._exactly(n)) @@ -167,8 +169,8 @@ class AtLeast(__Quantifier): When declared as such, the regex engine will try to match \ the expression as many times as possible. Defaults to ``True``. - :raises NonIntegerArgumentException: Parameter ``n`` is not an integer. - :raises NegativeArgumentException: Parameter ``n`` is less than zero. + :raises InvalidArgumentTypeException: Parameter ``n`` is not an integer. + :raises InvalidArgumentValueException: Parameter ``n`` is less than zero. :raises CannotBeQuantifiedException: This class is applied to an "assertion" pattern. ''' @@ -183,14 +185,16 @@ def __init__(self, pre: _pre.Pregex or str, n: int, is_greedy: bool = True) -> _ When declared as such, the regex engine will try to match \ the expression as many times as possible. Defaults to ``True``. - :raises NonIntegerArgumentException: Parameter ``n`` is not an integer. - :raises NegativeArgumentException: Parameter ``n`` is less than zero. + :raises InvalidArgumentTypeException: Parameter ``n`` is not an integer. + :raises InvalidArgumentValueException: Parameter ``n`` is less than zero. :raises CannotBeQuantifiedException: This class is applied to an "assertion" pattern. ''' if not isinstance(n, int) or isinstance(n, bool): - raise _ex.NonIntegerArgumentException(n) + message = "Provided argument \"n\" is not an integer." + raise _ex.InvalidArgumentTypeException(message) if n < 0: - raise _ex.NegativeArgumentException("n", n) + message = "Parameter \"n\" isn't allowed to be negative." + raise _ex.InvalidArgumentValueException(message) super().__init__(pre, is_greedy, lambda pre, is_greedy: pre._at_least(n, is_greedy)) @@ -205,8 +209,8 @@ class AtMost(__Quantifier): When declared as such, the regex engine will try to match \ the expression as many times as possible. Defaults to ``True``. - :raises NonIntegerArgumentException: Parameter ``n`` is not an integer. - :raises NegativeArgumentException: Parameter ``n`` is less than zero. + :raises InvalidArgumentTypeException: Parameter ``n`` is not an integer. + :raises InvalidArgumentValueException: Parameter ``n`` is less than zero. :raises CannotBeQuantifiedException: This class is applied to an "assertion" pattern. :note: Setting ``n`` equal to ``None`` indicates that there is no upper limit to the number of \ @@ -224,8 +228,8 @@ def __init__(self, pre: _pre.Pregex or str, n: int, is_greedy: bool = True) -> _ When declared as such, the regex engine will try to match \ the expression as many times as possible. Defaults to ``True``. - :raises NonIntegerArgumentException: Parameter ``n`` is not an integer. - :raises NegativeArgumentException: Parameter ``n`` is less than zero. + :raises InvalidArgumentTypeException: Parameter ``n`` is not an integer. + :raises InvalidArgumentValueException: Parameter ``n`` is less than zero. :raises CannotBeQuantifiedException: This class is applied to an "assertion" pattern. :note: Setting ``n`` equal to ``None`` indicates that there is no upper limit to the number of \ @@ -233,9 +237,11 @@ def __init__(self, pre: _pre.Pregex or str, n: int, is_greedy: bool = True) -> _ ''' if not isinstance(n, int) or isinstance(n, bool): if n is not None: - raise _ex.NonIntegerArgumentException(n) + message = "Provided argument \"n\" is neither an integer nor \"None\"." + raise _ex.InvalidArgumentTypeException(message) elif n < 0: - raise _ex.NegativeArgumentException("n", n) + message = "Parameter \"n\" isn't allowed to be negative." + raise _ex.InvalidArgumentValueException(message) super().__init__(pre, is_greedy, lambda pre, is_greedy: pre._at_most(n, is_greedy)) @@ -251,9 +257,9 @@ class AtLeastAtMost(__Quantifier): When declared as such, the regex engine will try to match \ the expression as many times as possible. Defaults to ``True``. - :raises NonIntegerArgumentException: Either one of parameters ``min`` or ``max`` is not an integer. - :raises NegativeArgumentException: Either parameter ``min`` or ``max`` is less than zero. - :raises MinGreaterThanMaxException: Parameter ``min`` is greater than parameter ``max``. + :raises InvalidArgumentTypeException: Either one of parameters ``min`` or ``max`` is not an integer. + :raises InvalidArgumentValueException: Either parameter ``min`` or ``max`` is less than zero, \ + or parameter ``min`` has a greater value than parameter ``max``. :raises CannotBeQuantifiedException: This class is applied to an "assertion" pattern. :note: @@ -274,9 +280,9 @@ def __init__(self, pre: _pre.Pregex or str, min: int, max: int, is_greedy: bool When declared as such, the regex engine will try to match \ the expression as many times as possible. Defaults to ``True``. - :raises NonIntegerArgumentException: Either one of parameters ``min`` or ``max`` is not an integer. - :raises NegativeArgumentException: Either parameter ``min`` or ``max`` is less than zero. - :raises MinGreaterThanMaxException: Parameter ``min`` is greater than parameter ``max``. + :raises InvalidArgumentTypeException: Either one of parameters ``min`` or ``max`` is not an integer. + :raises InvalidArgumentValueException: Either parameter ``min`` or ``max`` is less than zero, \ + or parameter ``min`` has a greater value than parameter ``max``. :raises CannotBeQuantifiedException: This class is applied to an "assertion" pattern. :note: @@ -285,14 +291,20 @@ def __init__(self, pre: _pre.Pregex or str, min: int, max: int, is_greedy: bool times the pattern is to be repeated. ''' if not isinstance(min, int) or isinstance(min, bool): - raise _ex.NonIntegerArgumentException(min) + message = "Provided argument \"min\" is not an integer." + raise _ex.InvalidArgumentTypeException(message) elif min < 0: - raise _ex.NegativeArgumentException("min", min) + message = "Parameter \"min\" isn't allowed to be negative." + raise _ex.InvalidArgumentValueException(message) elif not isinstance(max, int) or isinstance(max, bool): if max is not None: - raise _ex.NonIntegerArgumentException(max) + message = "Provided argument \"max\" is neither an integer nor \"None\"." + raise _ex.InvalidArgumentTypeException(message) elif max < 0: - raise _ex.NegativeArgumentException("max", max) + message = "Parameter \"max\" isn't allowed to be negative." + raise _ex.InvalidArgumentValueException(message) elif max < min: - raise _ex.MinGreaterThanMaxException(min, max) + message = "The value of parameter \"max\" isn't allowed to be" + message += " less than the value of parameter \"min\"." + raise _ex.InvalidArgumentValueException(message) super().__init__(pre, is_greedy, lambda pre, is_greedy: pre._at_least_at_most(min, max, is_greedy)) \ No newline at end of file diff --git a/src/pregex/tokens.py b/src/pregex/tokens.py index 67e8416..004f381 100644 --- a/src/pregex/tokens.py +++ b/src/pregex/tokens.py @@ -8,7 +8,7 @@ on your own, as this might lead to all sorts of errors due to escaping. Classes & methods -=========================================== +------------------------------------------- Below are listed all classes within :py:mod:`pregex.tokens` along with any possible methods they may possess. diff --git a/tests/test_assertions.py b/tests/test_assertions.py index 374abd5..b5ce10e 100644 --- a/tests/test_assertions.py +++ b/tests/test_assertions.py @@ -2,7 +2,8 @@ from pregex.assertions import * from pregex.pre import Pregex, Empty, _Type from pregex.quantifiers import Exactly, Optional -from pregex.exceptions import NonFixedWidthPatternException +from pregex.exceptions import NonFixedWidthPatternException, \ + NotEnoughArgumentsException, EmptyNegativeAssertionException TEST_STR = "test" @@ -124,7 +125,7 @@ def test_followed_by(self): def test_followed_by_on_type(self): self.assertEqual(FollowedBy("a", "b")._get_type(), _Type.Assertion) - def test_followed_by_on_empty_token(self): + def test_followed_by_on_empty_token_as_assertion_pattern(self): self.assertEqual(str(FollowedBy(pre1, Empty())), f"{pre1}") @@ -139,8 +140,14 @@ def test_not_followed_by_on_multiple_patterns(self): def test_not_followed_by_on_type(self): self.assertEqual(NotFollowedBy("a", "b")._get_type(), _Type.Assertion) - def test_not_followed_by_on_empty_token(self): - self.assertEqual(str(NotFollowedBy(pre1, Empty())), f"{pre1}") + def test_not_followed_by_on_not_enough_arguments_exception(self): + self.assertRaises(NotEnoughArgumentsException, NotFollowedBy, pre1) + + def test_not_followed_by_on_empty_negative_assertion_exception(self): + self.assertRaises(EmptyNegativeAssertionException, NotFollowedBy, pre1, Empty()) + + def test_not_followed_by_on_multiple_patterns_empty_negative_assertion_exception(self): + self.assertRaises(EmptyNegativeAssertionException, NotFollowedBy, pre1, pre2, Empty()) class TestPrecededBy(unittest.TestCase): @@ -156,7 +163,7 @@ def test_preceded_by_on_quantifier(self): self.assertEqual(str(PrecededBy(pre1, exactly)), f"(?<={exactly}){pre1}") self.assertRaises(NonFixedWidthPatternException, PrecededBy, pre1, Optional(pre2)) - def test_preceded_by_on_empty_token(self): + def test_preceded_by_on_empty_token_as_assertion_pattern(self): self.assertEqual(str(PrecededBy(pre1, Empty())), f"{pre1}") @@ -175,15 +182,21 @@ def test_not_preceded_by_on_exactly_quantifier(self): exactly = Exactly(pre2, 3) self.assertEqual(str(NotPrecededBy(pre1, exactly)), f"(?{str(group)[:-1].replace('(?:', '', 1)})") - def test_named_capturing_group_on_non_string_name_exception(self): + def test_named_capturing_group_on_invalid_argument_type_exception(self): invalid_type_names = [1, 1.5, True, Pregex("z")] for name in invalid_type_names: - self.assertRaises(NonStringArgumentException, Capture, "test", name) + self.assertRaises(InvalidArgumentTypeException, Capture, "test", name) def test_named_capturing_group_on_invalid_name_exception(self): invalid_names = ["11zzz", "ald!!", "@%^Fl", "!flflf123", "dld-"] @@ -167,10 +162,10 @@ def test_backreference(self): def test_backreference_on_type(self): self.assertEqual(Backreference("a")._get_type(), _Type.Group) - def test_backreference_on_non_string_name_exception(self): + def test_backreference_on_invalid_argument_type_exception(self): invalid_type_names = [1, 1.5, True, Pregex("z")] for name in invalid_type_names: - self.assertRaises(NonStringArgumentException, Backreference, name) + self.assertRaises(InvalidArgumentTypeException, Backreference, name) def test_backreference_on_invalid_name_exception(self): invalid_names = ["11zzz", "ald!!", "@%^Fl", "!flflf123", "dld-"] @@ -202,10 +197,10 @@ def test_conditional_with_else_pre(self): self.assertEqual(str(Conditional(self.name, self.then_pre, self.else_pre)), f"(?({self.name}){self.then_pre}|{self.else_pre})") - def test_conditional_on_non_string_name_exception(self): + def test_conditional_on_invalid_argument_type_exception(self): invalid_type_names = [1, 1.5, True, Pregex("z")] for name in invalid_type_names: - self.assertRaises(NonStringArgumentException, Conditional, name, self.then_pre) + self.assertRaises(InvalidArgumentTypeException, Conditional, name, self.then_pre) def test_conditional_on_invalid_name_exception(self): invalid_names = ["11zzz", "ald!!", "@%^Fl", "!flflf123", "dld-"] diff --git a/tests/test_operators.py b/tests/test_operators.py index 637b729..25b0ccd 100644 --- a/tests/test_operators.py +++ b/tests/test_operators.py @@ -4,7 +4,7 @@ from pregex.quantifiers import Exactly from pregex.classes import AnyLowercaseLetter from pregex.assertions import FollowedBy, MatchAtStart -from pregex.exceptions import LessThanTwoArgumentsException +from pregex.exceptions import NotEnoughArgumentsException TEST_STR_1 = "test1" @@ -12,12 +12,6 @@ TEST_STR_3 = "test3" -class Test__Operator(unittest.TestCase): - - def test_operator_on_few_arguments(self): - self.assertRaises(LessThanTwoArgumentsException, Concat, TEST_STR_1) - - class TestConcat(unittest.TestCase): def test_concat_class_type(self): @@ -56,6 +50,8 @@ def test_concat_on_lookaround_assertion(self): def test_concat_on_empty_token(self): self.assertEqual(str(Concat(TEST_STR_1, Empty())), TEST_STR_1) + def test_concat_on_not_enough_arguments_exception(self): + self.assertRaises(NotEnoughArgumentsException, Concat, TEST_STR_1) class TestEither(unittest.TestCase): @@ -95,6 +91,9 @@ def test_either_on_class(self): def test_either_on_empty_token(self): self.assertEqual(str(Either(TEST_STR_1, Empty(), TEST_STR_2)), f"{TEST_STR_1}|{TEST_STR_2}") + def test_either_on_not_enough_arguments_exception(self): + self.assertRaises(NotEnoughArgumentsException, Either, TEST_STR_1) + if __name__=="__main__": unittest.main() \ No newline at end of file diff --git a/tests/test_pre.py b/tests/test_pre.py index d0beeae..2adb73c 100644 --- a/tests/test_pre.py +++ b/tests/test_pre.py @@ -2,8 +2,8 @@ import unittest from pregex.pre import Pregex, Empty, _Type from pregex.assertions import MatchAtStart, WordBoundary, NonWordBoundary -from pregex.exceptions import CannotBeQuantifiedException, NegativeArgumentException, \ - NonStringArgumentException, NonIntegerArgumentException, NonPositiveArgumentException +from pregex.exceptions import CannotBeQuantifiedException, \ + InvalidArgumentValueException, InvalidArgumentTypeException class TestPregex(unittest.TestCase): @@ -67,9 +67,9 @@ def test_pregex_on_escape(self): for c in {'\\', '^', '$', '(', ')', '[', ']', '{', '}', '?', '+', '*', '.', '|', '/'}: self.assertEqual(str(Pregex(c)), f"\{c}") - def test_pregex_on_non_string_argument(self): + def test_pregex_on_invalid_argument_type_exception(self): for val in [1, 1.3, True, Pregex("z")]: - self.assertRaises(NonStringArgumentException, Pregex, val) + self.assertRaises(InvalidArgumentTypeException, Pregex, val) def test_pregex_on_match(self): text = ":\z^l" @@ -156,7 +156,7 @@ def test_pregex_on_replace(self): self.assertEqual(self.pre1.replace(self.TEXT, repl), "bb aaa bb bb 99a bb") self.assertEqual(self.pre1.replace(self.TEXT, repl, count=1), "bb aaa _9 z9z 99a B0c") self.assertEqual(self.pre2.replace(self.TEXT, repl, count=1), "bb aaa _9 z9z 99a B0c") - self.assertRaises(NegativeArgumentException, self.pre1.replace, self.TEXT, repl, -1) + self.assertRaises(InvalidArgumentValueException, self.pre1.replace, self.TEXT, repl, -1) def test_pregex_on_split_by_match(self): self.assertEqual(self.pre1.split_by_match(self.TEXT), self.SPLIT_BY_MATCH) @@ -202,18 +202,18 @@ def test_pregex_on_multiplication(self): self.assertEqual(str(self.pre1.__mul__(1)), self.PATTERN) self.assertEqual(str(self.pre1.__mul__(2)), f"(?:{self.PATTERN}){{2}}") self.assertEqual(str(self.pre1.__mul__(0)), "") - self.assertRaises(NegativeArgumentException, self.pre1.__mul__, -1) + self.assertRaises(InvalidArgumentValueException, self.pre1.__mul__, -1) for val in ["s", 1.1, True]: - self.assertRaises(NonIntegerArgumentException, self.pre1.__mul__, val) + self.assertRaises(InvalidArgumentTypeException, self.pre1.__mul__, val) self.assertRaises(CannotBeQuantifiedException, MatchAtStart("x").__mul__, 2) def test_pregex_on_right_side_multiplication(self): self.assertEqual(str(self.pre1.__rmul__(1)), self.PATTERN) self.assertEqual(str(self.pre1.__rmul__(2)), f"(?:{self.PATTERN}){{2}}") self.assertEqual(str(self.pre1.__rmul__(0)), "") - self.assertRaises(NegativeArgumentException, self.pre1.__rmul__, -1) + self.assertRaises(InvalidArgumentValueException, self.pre1.__rmul__, -1) for val in ["s", 1.1, True]: - self.assertRaises(NonIntegerArgumentException, self.pre1.__rmul__, val) + self.assertRaises(InvalidArgumentTypeException, self.pre1.__rmul__, val) self.assertRaises(CannotBeQuantifiedException, MatchAtStart("x").__rmul__, 2) ''' diff --git a/tests/test_quantifiers.py b/tests/test_quantifiers.py index 7951c0f..fd7d43e 100644 --- a/tests/test_quantifiers.py +++ b/tests/test_quantifiers.py @@ -4,10 +4,10 @@ from pregex.operators import Concat, Either from pregex.classes import AnyLowercaseLetter from pregex.assertions import MatchAtStart -from pregex.exceptions import NeitherStringNorPregexException, NonPositiveArgumentException, \ - NegativeArgumentException, MinGreaterThanMaxException, NonIntegerArgumentException, \ +from pregex.exceptions import InvalidArgumentTypeException, InvalidArgumentValueException, \ CannotBeQuantifiedException + TEST_STR_LEN_1 = "t" TEST_STR_LEN_N = "test" TEST_LITERAL_LEN_1 = Pregex(TEST_STR_LEN_1) @@ -16,10 +16,6 @@ class Test__Quantifier(unittest.TestCase): - def test_neither_pregex_nor_str(self): - for arg in (1, 1.56, True): - self.assertRaises(NeitherStringNorPregexException, Indefinite, arg) - def test_quantifier_on_str(self): self.assertEqual(str(Optional(TEST_STR_LEN_N)), f"(?:{TEST_STR_LEN_N})?") @@ -158,13 +154,13 @@ def test_exactly_on_type(self): self.assertEqual(Exactly("abc", n=2)._get_type(), _Type.Quantifier) self.assertNotEqual(Pregex("abc{2}", escape=False)._get_type(), _Type.Quantifier) - def test_exactly_on_invalid_type_values(self): + def test_exactly_on_invalid_argument_type_exception(self): for val in ["s", 1.1, True]: - self.assertRaises(NonIntegerArgumentException, Exactly, TEST_STR_LEN_1, val) + self.assertRaises(InvalidArgumentTypeException, Exactly, TEST_STR_LEN_1, val) - def test_exactly_on_invalid_values(self): + def test_exactly_on_invalid_argument_value_exception(self): for val in [-10, -1]: - self.assertRaises(NegativeArgumentException, Exactly, TEST_STR_LEN_1, val) + self.assertRaises(InvalidArgumentValueException, Exactly, TEST_STR_LEN_1, val) class TestAtLeast(unittest.TestCase): @@ -211,13 +207,13 @@ def test_at_least_on_type(self): self.assertEqual(AtLeast("abc", n=2)._get_type(), _Type.Quantifier) self.assertNotEqual(Pregex("abc{2,}", escape=False)._get_type(), _Type.Quantifier) - def test_at_least_on_invalid_type_values(self): + def test_at_least_on_invalid_argument_type_exception(self): for val in ["s", 1.1, True]: - self.assertRaises(NonIntegerArgumentException, AtLeast, TEST_STR_LEN_1, val) + self.assertRaises(InvalidArgumentTypeException, AtLeast, TEST_STR_LEN_1, val) - def test_at_least_on_invalid_values(self): + def test_at_least_on_invalid_argument_value_exception(self): for val in [-10, -1]: - self.assertRaises(NegativeArgumentException, AtLeast, TEST_STR_LEN_1, val) + self.assertRaises(InvalidArgumentValueException, AtLeast, TEST_STR_LEN_1, val) class TestAtMost(unittest.TestCase): @@ -269,13 +265,13 @@ def test_at_most_on_type(self): self.assertEqual(AtMost("abc", n=2)._get_type(), _Type.Quantifier) self.assertNotEqual(Pregex("abc{,2}", escape=False)._get_type(), _Type.Quantifier) - def test_at_most_on_invalid_type_values(self): + def test_at_most_on_invalid_argument_type_exception(self): for val in ["s", 1.1, True]: - self.assertRaises(NonIntegerArgumentException, AtMost, TEST_STR_LEN_1, val) + self.assertRaises(InvalidArgumentTypeException, AtMost, TEST_STR_LEN_1, val) - def test_at_most_on_invalid_values(self): + def test_at_most_on_invalid_argument_value_exception(self): for val in [-10, -1]: - self.assertRaises(NegativeArgumentException, AtMost, TEST_STR_LEN_1, val) + self.assertRaises(InvalidArgumentValueException, AtMost, TEST_STR_LEN_1, val) class TestAtLeastAtMost(unittest.TestCase): @@ -366,22 +362,15 @@ def test_at_least_at_most_on_type(self): self.assertEqual(AtLeastAtMost("abc", min=1, max=2)._get_type(), _Type.Quantifier) self.assertNotEqual(Pregex("abc{1,2}", escape=False)._get_type(), _Type.Quantifier) - def test_at_least_at_most_on_invalid_type_values(self): + def test_at_least_at_most_on_invalid_argument_type_exception(self): for val in ["s", 1.1, True]: - self.assertRaises(NonIntegerArgumentException, AtLeastAtMost, TEST_STR_LEN_1, min=val, max=10) - self.assertRaises(NonIntegerArgumentException, AtLeastAtMost, TEST_STR_LEN_1, min=2, max=val) - - def test_at_least_at_most_on_negative_min_exception(self): - min, max = -1, 1 - self.assertRaises(NegativeArgumentException, AtLeastAtMost, TEST_STR_LEN_1, min, max) - - def test_at_least_at_most_on_negative_max_exception(self): - min, max = 1, -1 - self.assertRaises(NegativeArgumentException, AtLeastAtMost, TEST_STR_LEN_1, min, max) + self.assertRaises(InvalidArgumentTypeException, AtLeastAtMost, TEST_STR_LEN_1, min=val, max=10) + self.assertRaises(InvalidArgumentTypeException, AtLeastAtMost, TEST_STR_LEN_1, min=2, max=val) - def test_at_least_at_most_on_min_greater_than_max_exception(self): - min, max = 5, 3 - self.assertRaises(MinGreaterThanMaxException, AtLeastAtMost, TEST_STR_LEN_1, min, max) + def test_at_least_at_most_on_invalid_argument_value_exception(self): + self.assertRaises(InvalidArgumentValueException, AtLeastAtMost, TEST_STR_LEN_1, min=-1, max=1) + self.assertRaises(InvalidArgumentValueException, AtLeastAtMost, TEST_STR_LEN_1, min=1, max=-1) + self.assertRaises(InvalidArgumentValueException, AtLeastAtMost, TEST_STR_LEN_1, min=5, max=3) if __name__=="__main__":