Hello community, here is the log from the commit of package python-pathvalidate for openSUSE:Leap:15.2 checked in at 2020-03-31 07:23:15 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Leap:15.2/python-pathvalidate (Old) and /work/SRC/openSUSE:Leap:15.2/.python-pathvalidate.new.3160 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pathvalidate" Tue Mar 31 07:23:15 2020 rev:2 rq:789499 version:2.2.2 Changes: -------- --- /work/SRC/openSUSE:Leap:15.2/python-pathvalidate/python-pathvalidate.changes 2020-03-27 16:48:19.919940651 +0100 +++ /work/SRC/openSUSE:Leap:15.2/.python-pathvalidate.new.3160/python-pathvalidate.changes 2020-03-31 07:23:17.242421922 +0200 @@ -1,0 +2,11 @@ +Sat Mar 28 12:35:30 UTC 2020 - Martin Hauke <mar...@gmx.de> + +- Update to version 2.2.2 + * Fix __str__ method + * Fix to avoid raise an exception when an absolute path + includes "."/".." + * Modify an error message + * Modify raising exception from NullNameError to ValidationError + of validate_pathtype + +------------------------------------------------------------------- Old: ---- pathvalidate-2.2.1.tar.gz New: ---- pathvalidate-2.2.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pathvalidate.spec ++++++ --- /var/tmp/diff_new_pack.p0S74D/_old 2020-03-31 07:23:17.610422082 +0200 +++ /var/tmp/diff_new_pack.p0S74D/_new 2020-03-31 07:23:17.610422082 +0200 @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define skip_python2 1 Name: python-pathvalidate -Version: 2.2.1 +Version: 2.2.2 Release: 0 Summary: Python library to sanitize/validate a string such as filenames License: MIT ++++++ pathvalidate-2.2.1.tar.gz -> pathvalidate-2.2.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathvalidate-2.2.1/PKG-INFO new/pathvalidate-2.2.2/PKG-INFO --- old/pathvalidate-2.2.1/PKG-INFO 2020-03-20 12:12:26.292878600 +0100 +++ new/pathvalidate-2.2.2/PKG-INFO 2020-03-28 13:31:57.910138000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pathvalidate -Version: 2.2.1 +Version: 2.2.2 Summary: pathvalidate is a Python library to sanitize/validate a string such as filenames/file-paths/etc. Home-page: https://github.com/thombashi/pathvalidate Author: Tsuyoshi Hombashi @@ -54,7 +54,9 @@ - Sanitize/Validate a string as a: - file name - file path - - filename/filepath validator/sanitizer for ``argparse``/``click`` + - file name/path argument validator/sanitizer for ``argparse`` and ``click`` + - Multi platform support: + - sanitize/validate file names/paths for a specific platform (``Linux``/``Windows``/``macOS``/``Posix``) or ``universal`` (platform independent) - Multibyte character support Examples @@ -79,6 +81,9 @@ _a*b:c<d>e%f/(g)h+i_0.txt -> _abcde%f(g)h+i_0.txt + The default target ``platform`` is ``universal``. + i.e. the sanitized file name is valid for any platform. + Sanitize a filepath --------------------- :Sample Code: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathvalidate-2.2.1/README.rst new/pathvalidate-2.2.2/README.rst --- old/pathvalidate-2.2.1/README.rst 2020-03-20 12:04:58.000000000 +0100 +++ new/pathvalidate-2.2.2/README.rst 2020-03-28 13:14:15.000000000 +0100 @@ -43,7 +43,9 @@ - Sanitize/Validate a string as a: - file name - file path -- filename/filepath validator/sanitizer for ``argparse``/``click`` +- file name/path argument validator/sanitizer for ``argparse`` and ``click`` +- Multi platform support: + - sanitize/validate file names/paths for a specific platform (``Linux``/``Windows``/``macOS``/``Posix``) or ``universal`` (platform independent) - Multibyte character support Examples @@ -68,6 +70,9 @@ _a*b:c<d>e%f/(g)h+i_0.txt -> _abcde%f(g)h+i_0.txt +The default target ``platform`` is ``universal``. +i.e. the sanitized file name is valid for any platform. + Sanitize a filepath --------------------- :Sample Code: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathvalidate-2.2.1/pathvalidate/__version__.py new/pathvalidate-2.2.2/pathvalidate/__version__.py --- old/pathvalidate-2.2.1/pathvalidate/__version__.py 2020-03-20 12:06:04.000000000 +0100 +++ new/pathvalidate-2.2.2/pathvalidate/__version__.py 2020-03-28 13:17:03.000000000 +0100 @@ -1,6 +1,6 @@ __author__ = "Tsuyoshi Hombashi" __copyright__ = "Copyright 2016, {}".format(__author__) __license__ = "MIT License" -__version__ = "2.2.1" +__version__ = "2.2.2" __maintainer__ = __author__ __email__ = "tsuyoshi.homba...@gmail.com" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathvalidate-2.2.1/pathvalidate/_common.py new/pathvalidate-2.2.2/pathvalidate/_common.py --- old/pathvalidate-2.2.1/pathvalidate/_common.py 2020-03-20 12:10:34.000000000 +0100 +++ new/pathvalidate-2.2.2/pathvalidate/_common.py 2020-03-28 08:20:03.000000000 +0100 @@ -29,7 +29,7 @@ def validate_pathtype(text: PathType, error_msg: Optional[str] = None) -> None: - from .error import NullNameError + from .error import ValidationError, ErrorReason if _is_not_null_string(text) or is_pathlike_obj(text): return @@ -38,7 +38,9 @@ if not error_msg: error_msg = "the value must be a not empty" - raise NullNameError(error_msg) + raise ValidationError( + description=error_msg, reason=ErrorReason.NULL_NAME, + ) raise TypeError("text must be a string: actual={}".format(type(text))) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathvalidate-2.2.1/pathvalidate/_filename.py new/pathvalidate-2.2.2/pathvalidate/_filename.py --- old/pathvalidate-2.2.1/pathvalidate/_filename.py 2020-02-12 06:42:00.000000000 +0100 +++ new/pathvalidate-2.2.2/pathvalidate/_filename.py 2020-03-28 07:34:36.000000000 +0100 @@ -19,13 +19,7 @@ preprocess, validate_pathtype, ) -from .error import ( - ErrorReason, - InvalidCharError, - InvalidLengthError, - ReservedNameError, - ValidationError, -) +from .error import ErrorReason, InvalidCharError, InvalidLengthError, ValidationError _DEFAULT_MAX_FILENAME_LEN = 255 @@ -74,14 +68,14 @@ try: self.__validator.validate(sanitized_filename) - except ReservedNameError as e: - if e.reusable_name is False: + except ValidationError as e: + if e.reason == ErrorReason.RESERVED_NAME and e.reusable_name is False: sanitized_filename = re.sub( re.escape(e.reserved_name), "{}_".format(e.reserved_name), sanitized_filename ) - except InvalidCharError: - if self.platform in [Platform.UNIVERSAL, Platform.WINDOWS]: - sanitized_filename = sanitized_filename.rstrip(" .") + elif e.reason == ErrorReason.INVALID_CHARACTER: + if self.platform in [Platform.UNIVERSAL, Platform.WINDOWS]: + sanitized_filename = sanitized_filename.rstrip(" .") if is_pathlike_obj(value): return Path(sanitized_filename) @@ -229,14 +223,14 @@ If |True|, check reserved names of the ``platform``. Raises: - InvalidLengthError: + ValidationError (ErrorReason.INVALID_LENGTH): If the ``filename`` is longer than ``max_len`` characters. - InvalidCharError: + ValidationError (ErrorReason.INVALID_CHARACTER): If the ``filename`` includes invalid character(s) for a filename: |invalid_filename_chars|. The following characters are also invalid for Windows platform: |invalid_win_filename_chars|. - ReservedNameError: + ValidationError (ErrorReason.RESERVED_NAME): If the ``filename`` equals reserved name by OS. Windows reserved name is as follows: ``"CON"``, ``"PRN"``, ``"AUX"``, ``"NUL"``, ``"COM[1-9]"``, ``"LPT[1-9]"``. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathvalidate-2.2.1/pathvalidate/_filepath.py new/pathvalidate-2.2.2/pathvalidate/_filepath.py --- old/pathvalidate-2.2.1/pathvalidate/_filepath.py 2020-02-12 09:12:46.000000000 +0100 +++ new/pathvalidate-2.2.2/pathvalidate/_filepath.py 2020-03-28 09:11:53.000000000 +0100 @@ -176,7 +176,7 @@ self._validate_reserved_keywords(unicode_file_path) unicode_file_path = unicode_file_path.replace("\\", "/") for entry in unicode_file_path.split("/"): - if not entry: + if not entry or entry in (".", ".."): continue self.__fname_validator._validate_reserved_keywords(entry) @@ -202,14 +202,27 @@ reason=ErrorReason.MALFORMED_ABS_PATH, ) + if any([self._is_windows() and is_nt_abs, self._is_linux() and is_posix_abs]): + return + if self._is_universal() and any([is_posix_abs, is_nt_abs]): - raise err_object + ValidationError( + description=( + "{}. expected a platform independent file path".format( + "POSIX absolute file path found" + if is_posix_abs + else "NT absolute file path found" + ) + ), + platform=self.platform, + reason=ErrorReason.MALFORMED_ABS_PATH, + ) - if any([self._is_windows(), self._is_universal()]) and posixpath.isabs(value): + if any([self._is_windows(), self._is_universal()]) and is_posix_abs: raise err_object drive, _tail = ntpath.splitdrive(value) - if not self._is_windows() and drive and ntpath.isabs(value): + if not self._is_windows() and drive and is_nt_abs: raise err_object def __validate_unix_file_path(self, unicode_file_path: str) -> None: @@ -275,12 +288,12 @@ If |True|, check reserved names of the ``platform``. Raises: - InvalidCharError: + ValidationError (ErrorReason.INVALID_CHARACTER): If the ``file_path`` includes invalid char(s): |invalid_file_path_chars|. The following characters are also invalid for Windows platform: |invalid_win_file_path_chars| - InvalidLengthError: + ValidationError (ErrorReason.INVALID_LENGTH): If the ``file_path`` is longer than ``max_len`` characters. ValidationError: If ``file_path`` include invalid values. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathvalidate-2.2.1/pathvalidate/_ltsv.py new/pathvalidate-2.2.2/pathvalidate/_ltsv.py --- old/pathvalidate-2.2.1/pathvalidate/_ltsv.py 2020-02-01 05:55:55.000000000 +0100 +++ new/pathvalidate-2.2.2/pathvalidate/_ltsv.py 2020-03-28 07:18:25.000000000 +0100 @@ -17,7 +17,7 @@ `Labeled Tab-separated Values (LTSV) <http://ltsv.org/>`__ label or not. :param label: Label to validate. - :raises pathvalidate.InvalidCharError: + :raises pathvalidate.ValidationError: If invalid character(s) found in the ``label`` for a LTSV format label. """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathvalidate-2.2.1/pathvalidate/_symbol.py new/pathvalidate-2.2.2/pathvalidate/_symbol.py --- old/pathvalidate-2.2.1/pathvalidate/_symbol.py 2020-01-11 06:04:34.000000000 +0100 +++ new/pathvalidate-2.2.2/pathvalidate/_symbol.py 2020-03-28 07:29:05.000000000 +0100 @@ -33,9 +33,13 @@ """ Verifying whether symbol(s) included in the ``text`` or not. - :param text: Input text. - :raises pathvalidate.InvalidCharError: - If symbol(s) included in the ``text``. + Args: + text: + Input text to validate. + + Raises: + ValidationError (ErrorReason.INVALID_CHARACTER): + If symbol(s) included in the ``text``. """ match_list = __RE_SYMBOL.findall(preprocess(text)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathvalidate-2.2.1/pathvalidate/error.py new/pathvalidate-2.2.2/pathvalidate/error.py --- old/pathvalidate-2.2.1/pathvalidate/error.py 2020-02-05 22:45:13.000000000 +0100 +++ new/pathvalidate-2.2.2/pathvalidate/error.py 2020-03-28 13:09:19.000000000 +0100 @@ -10,17 +10,28 @@ @enum.unique class ErrorReason(enum.Enum): - FOUND_ABS_PATH = "FOUND_ABS_PATH" - NULL_NAME = "NULL_NAME" - INVALID_CHARACTER = "INVALID_CHARACTER" - INVALID_LENGTH = "INVALID_LENGTH" - MALFORMED_ABS_PATH = "MALFORMED_ABS_PATH" - RESERVED_NAME = "RESERVED_NAME" + """ + Validation error reasons. + """ + + FOUND_ABS_PATH = "FOUND_ABS_PATH" #: found an absolute path when expecting a file name + NULL_NAME = "NULL_NAME" #: empty value + INVALID_CHARACTER = "INVALID_CHARACTER" #: found invalid characters(s) in a value + INVALID_LENGTH = "INVALID_LENGTH" #: found invalid string length + MALFORMED_ABS_PATH = "MALFORMED_ABS_PATH" #: found invalid absolute path format + RESERVED_NAME = "RESERVED_NAME" #: found a reserved name by a platform class ValidationError(ValueError): """ - Base exception class that indicates invalid name errors. + Exception class of validation errors. + + .. py:attribute:: reason + + The cause of the error. + + Returns: + :py:class:`~pathvalidate.error.ErrorReason`: """ @property @@ -36,6 +47,10 @@ return self.__description @property + def reserved_name(self) -> str: + return self.__reserved_name + + @property def reusable_name(self) -> bool: return self.__reusable_name @@ -43,6 +58,7 @@ self.__platform = kwargs.pop("platform", None) self.__reason = kwargs.pop("reason", None) self.__description = kwargs.pop("description", None) + self.__reserved_name = kwargs.pop("reserved_name", None) self.__reusable_name = kwargs.pop("reusable_name", None) try: @@ -62,7 +78,7 @@ item_list.append("target-platform={}".format(self.platform.value)) if self.description: item_list.append("description={}".format(self.description)) - if self.reusable_name: + if self.__reusable_name is not None: item_list.append("reusable_name={}".format(self.reusable_name)) return ", ".join(item_list).strip() @@ -109,13 +125,7 @@ Exception raised when a string matched a reserved name. """ - @property - def reserved_name(self) -> str: - return self.__reserved_name - def __init__(self, *args, **kwargs) -> None: - self.__reserved_name = kwargs.pop("reserved_name", None) - kwargs["reason"] = ErrorReason.RESERVED_NAME super().__init__(args, **kwargs) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathvalidate-2.2.1/pathvalidate.egg-info/PKG-INFO new/pathvalidate-2.2.2/pathvalidate.egg-info/PKG-INFO --- old/pathvalidate-2.2.1/pathvalidate.egg-info/PKG-INFO 2020-03-20 12:12:26.000000000 +0100 +++ new/pathvalidate-2.2.2/pathvalidate.egg-info/PKG-INFO 2020-03-28 13:31:57.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pathvalidate -Version: 2.2.1 +Version: 2.2.2 Summary: pathvalidate is a Python library to sanitize/validate a string such as filenames/file-paths/etc. Home-page: https://github.com/thombashi/pathvalidate Author: Tsuyoshi Hombashi @@ -54,7 +54,9 @@ - Sanitize/Validate a string as a: - file name - file path - - filename/filepath validator/sanitizer for ``argparse``/``click`` + - file name/path argument validator/sanitizer for ``argparse`` and ``click`` + - Multi platform support: + - sanitize/validate file names/paths for a specific platform (``Linux``/``Windows``/``macOS``/``Posix``) or ``universal`` (platform independent) - Multibyte character support Examples @@ -79,6 +81,9 @@ _a*b:c<d>e%f/(g)h+i_0.txt -> _abcde%f(g)h+i_0.txt + The default target ``platform`` is ``universal``. + i.e. the sanitized file name is valid for any platform. + Sanitize a filepath --------------------- :Sample Code: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathvalidate-2.2.1/test/test_filename.py new/pathvalidate-2.2.2/test/test_filename.py --- old/pathvalidate-2.2.1/test/test_filename.py 2020-02-22 17:24:14.000000000 +0100 +++ new/pathvalidate-2.2.2/test/test_filename.py 2020-03-28 13:13:02.000000000 +0100 @@ -13,10 +13,7 @@ from pathvalidate import ( ErrorReason, - InvalidCharError, - InvalidLengthError, Platform, - ReservedNameError, ValidationError, is_valid_filename, sanitize_filename, @@ -151,7 +148,7 @@ [ ["lower than one", -1, None], ["valid", 5, None], - ["invalid_length", 200, InvalidLengthError], + ["invalid_length", 200, ErrorReason.INVALID_LENGTH], ], ) def test_min_len(self, value, min_len, expected): @@ -159,27 +156,36 @@ validate_filename(value, min_len=min_len) assert is_valid_filename(value, min_len=min_len) else: - with pytest.raises(expected): + with pytest.raises(ValidationError) as e: validate_filename(value, min_len=min_len) + assert e.value.reason == expected @pytest.mark.parametrize( ["value", "platform", "max_len", "expected"], [ ["a" * 255, None, None, None], - ["a" * 5000, None, 10000, InvalidLengthError], - ["invalid_max_len", None, 0, ValueError], + ["a" * 5000, None, 10000, ErrorReason.INVALID_LENGTH], ["valid_length", "universal", 255, None], ["valid_length", Platform.UNIVERSAL, 255, None], - ["invalid_length", None, 2, InvalidLengthError], + ["invalid_length", None, 2, ErrorReason.INVALID_LENGTH], ], ) def test_max_len(self, value, platform, max_len, expected): if expected is None: validate_filename(value, platform=platform, max_len=max_len) assert is_valid_filename(value, platform=platform, max_len=max_len) - else: - with pytest.raises(expected): - validate_filename(value, platform=platform, max_len=max_len) + return + + with pytest.raises(ValidationError) as e: + validate_filename(value, platform=platform, max_len=max_len) + assert e.value.reason == expected + + @pytest.mark.parametrize( + ["value", "platform", "max_len", "expected"], [["invalid_max_len", None, 0, ValueError],], + ) + def test_abnormal_max_len(self, value, platform, max_len, expected): + with pytest.raises(expected): + validate_filename(value, platform=platform, max_len=max_len) @pytest.mark.parametrize( ["value", "min_len", "max_len", "expected"], @@ -224,8 +230,9 @@ ), ) def test_exception_invalid_char(self, value, platform): - with pytest.raises(InvalidCharError): + with pytest.raises(ValidationError) as e: validate_filename(value, platform) + assert e.value.reason == ErrorReason.INVALID_CHARACTER assert not is_valid_filename(value, platform=platform) @pytest.mark.parametrize( @@ -241,34 +248,36 @@ ], ) def test_exception_win_invalid_char(self, value, platform): - with pytest.raises(InvalidCharError): + with pytest.raises(ValidationError) as e: validate_filename(value, platform=platform) + assert e.value.reason == ErrorReason.INVALID_CHARACTER assert not is_valid_filename(value, platform=platform) @pytest.mark.parametrize( ["value", "platform", "expected"], [ - [reserved_keyword, platform, ReservedNameError] + [reserved_keyword, platform, ValidationError] for reserved_keyword, platform in product( WIN_RESERVED_FILE_NAMES, ["windows", "universal"] ) ] + [ - ["{}.txt".format(reserved_keyword), platform, ReservedNameError] + ["{}.txt".format(reserved_keyword), platform, ValidationError] for reserved_keyword, platform in product( WIN_RESERVED_FILE_NAMES, ["windows", "universal"] ) if reserved_keyword not in [".", ".."] ] + [ - [reserved_keyword, platform, ReservedNameError] + [reserved_keyword, platform, ValidationError] for reserved_keyword, platform in product([".", ".."], ["posix", "linux", "macos"]) ] - + [[":", "posix", ReservedNameError], [":", "macos", ReservedNameError],], + + [[":", "posix", ValidationError], [":", "macos", ValidationError],], ) def test_exception_reserved_name(self, value, platform, expected): with pytest.raises(expected) as e: validate_filename(value, platform=platform) + assert e.value.reason == ErrorReason.RESERVED_NAME assert e.value.reserved_name assert e.value.reusable_name is False @@ -292,15 +301,16 @@ @pytest.mark.parametrize( ["value", "platform", "expected"], [ - [value, platform, InvalidCharError] + [value, platform, ErrorReason.INVALID_CHARACTER] for value, platform in product(["asdf\rsdf"], ["windows", "universal"]) ], ) def test_exception_escape_err_msg(self, value, platform, expected): - with pytest.raises(expected) as e: + with pytest.raises(ValidationError) as e: print(platform, repr(value)) validate_filename(value, platform=platform) + assert e.value.reason == ErrorReason.INVALID_CHARACTER assert str(e.value) == ( r"invalid char found: invalids=('\r'), value='asdf\rsdf', " "reason=INVALID_CHARACTER, target-platform=Windows" @@ -311,7 +321,7 @@ [ [None, ValueError], ["", ValidationError], - ["a" * 256, InvalidLengthError], + ["a" * 256, ValidationError], [1, TypeError], [True, TypeError], [nan, TypeError], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathvalidate-2.2.1/test/test_filepath.py new/pathvalidate-2.2.2/test/test_filepath.py --- old/pathvalidate-2.2.1/test/test_filepath.py 2020-02-12 07:32:04.000000000 +0100 +++ new/pathvalidate-2.2.2/test/test_filepath.py 2020-03-28 13:24:54.000000000 +0100 @@ -13,10 +13,7 @@ from pathvalidate import ( ErrorReason, - InvalidCharError, - InvalidLengthError, Platform, - ReservedNameError, ValidationError, is_valid_filepath, sanitize_filepath, @@ -76,11 +73,11 @@ class Test_validate_filepath: VALID_CHARS = VALID_PATH_CHARS - VALID_MULTIBYTE_PATH_LIST = [ + VALID_MULTIBYTE_PATHS = [ "c:\\Users\\新しいフォルダー\\あいうえお.txt", "D:\\新しいフォルダー\\ユーザ属性.txt", ] - WIN_VALID_PATH_LIST = [ + WIN_VALID_PATHS = [ "D:\\Users\\\\est\\AppData\\Local\\Temp\\pytest-of-test\\pytest-0\\\\hoge.csv", "D:/Users/test/AppData/Local/Temp/pytest-of-test/pytest-0/test_exception__hoge_csv_heade1/hoge.csv", # noqa "C:\\Users\\est\\AppData/Local\\Temp/pytest-of-test\\pytest-0/\\hoge.csv", @@ -112,7 +109,7 @@ chain.from_iterable( [ [args for args in product([valid_path], ["windows"])] - for valid_path in VALID_MULTIBYTE_PATH_LIST + for valid_path in VALID_MULTIBYTE_PATHS ] ), ) @@ -120,7 +117,7 @@ validate_filepath(value, platform) assert is_valid_filepath(value, platform=platform) - @pytest.mark.parametrize(["value"], [[valid_path] for valid_path in WIN_VALID_PATH_LIST]) + @pytest.mark.parametrize(["value"], [[valid_path] for valid_path in WIN_VALID_PATHS]) def test_normal_win(self, value): platform = "windows" validate_filepath(value, platform=platform) @@ -131,35 +128,37 @@ [ ["lower than one", -1, None], ["valid", 5, None], - ["invalid_length", 200, InvalidLengthError], + ["invalid_length", 200, ErrorReason.INVALID_LENGTH], ], ) def test_normal_min_len(self, value, min_len, expected): if expected is None: validate_filepath(value, min_len=min_len) assert is_valid_filepath(value, min_len=min_len) - else: - with pytest.raises(expected): - validate_filepath(value, min_len=min_len) + return + + with pytest.raises(ValidationError) as e: + validate_filepath(value, min_len=min_len) + assert e.value.reason == expected @pytest.mark.parametrize( ["value", "platform", "max_len", "expected"], [ ["a" * 4096, "linux", None, None], - ["a" * 4097, "linux", None, InvalidLengthError], + ["a" * 4097, "linux", None, ErrorReason.INVALID_LENGTH], ["a" * 1024, "posix", None, None], - ["a" * 1025, "posix", None, InvalidLengthError], - ["a" * 4097, Platform.LINUX, None, InvalidLengthError], - ["a" * 255, "linux", 100, InvalidLengthError], - ["a" * 5000, "windows", 10000, ValidationError], + ["a" * 1025, "posix", None, ErrorReason.INVALID_LENGTH], + ["a" * 4097, Platform.LINUX, None, ErrorReason.INVALID_LENGTH], + ["a" * 255, "linux", 100, ErrorReason.INVALID_LENGTH], + ["a" * 5000, "windows", 10000, ErrorReason.INVALID_LENGTH], ["a" * 260, "windows", None, None], - ["a" * 300, "windows", 1024, ValidationError], - ["a" * 261, Platform.WINDOWS, None, InvalidLengthError], - ["a" * 261, "windows", None, InvalidLengthError], + ["a" * 300, "windows", 1024, ErrorReason.INVALID_LENGTH], + ["a" * 261, Platform.WINDOWS, None, ErrorReason.INVALID_LENGTH], + ["a" * 261, "windows", None, ErrorReason.INVALID_LENGTH], ["a" * 260, "universal", None, None], - ["a" * 261, "universal", None, InvalidLengthError], - ["a" * 300, "universal", 1024, ValidationError], - ["a" * 261, Platform.UNIVERSAL, None, InvalidLengthError], + ["a" * 261, "universal", None, ErrorReason.INVALID_LENGTH], + ["a" * 300, "universal", 1024, ErrorReason.INVALID_LENGTH], + ["a" * 261, Platform.UNIVERSAL, None, ErrorReason.INVALID_LENGTH], ], ) def test_normal_max_len(self, value, platform, max_len, expected): @@ -168,8 +167,9 @@ assert is_valid_filepath(value, platform=platform, max_len=max_len) return - with pytest.raises(expected): + with pytest.raises(ValidationError) as e: validate_filepath(value, platform=platform, max_len=max_len) + assert e.value.reason == ErrorReason.INVALID_LENGTH @pytest.mark.parametrize( ["value", "min_len", "max_len", "expected"], @@ -186,16 +186,17 @@ if expected is None: validate_filepath(value, min_len=min_len, max_len=max_len) assert is_valid_filepath(value, min_len=min_len, max_len=max_len) - else: - with pytest.raises(expected): - validate_filepath(value, min_len=min_len, max_len=max_len) + return + + with pytest.raises(expected): + validate_filepath(value, min_len=min_len, max_len=max_len) @pytest.mark.parametrize( ["test_platform", "value", "expected"], [ ["linux", "/a/b/c.txt", None], ["linux", "C:\\a\\b\\c.txt", ValidationError], - ["windows", "/a/b/c.txt", ValidationError], + ["windows", "/a/b/c.txt", None], ["windows", "C:\\a\\b\\c.txt", None], ["universal", "/a/b/c.txt", ValidationError], ["universal", "C:\\a\\b\\c.txt", ValidationError], @@ -205,21 +206,23 @@ if expected is None: validate_filepath(value, platform=test_platform) assert is_valid_filepath(value, platform=test_platform) - else: - with pytest.raises(expected): - validate_filepath(value, platform=test_platform) + return + + with pytest.raises(expected): + validate_filepath(value, platform=test_platform) @pytest.mark.skipif(m_platform.system() != "Windows", reason="platform dependent tests") @pytest.mark.parametrize( - ["value", "expected"], [["/a/b/c.txt", ValidationError], ["C:\\a\\b\\c.txt", None],], + ["value", "expected"], [["C:\\a\\b\\c.txt", None],], ) def test_normal_auto_platform_win(self, value, expected): if expected is None: validate_filepath(value, platform="auto") assert is_valid_filepath(value, platform="auto") - else: - with pytest.raises(expected): - validate_filepath(value, platform="auto") + return + + with pytest.raises(expected): + validate_filepath(value, platform="auto") @pytest.mark.skipif(m_platform.system() != "Linux", reason="platform dependent tests") @pytest.mark.parametrize( @@ -229,18 +232,23 @@ if expected is None: validate_filepath(value, platform="auto") assert is_valid_filepath(value, platform="auto") - else: - with pytest.raises(expected): - validate_filepath(value, platform="auto") + return + + with pytest.raises(expected): + validate_filepath(value, platform="auto") @pytest.mark.parametrize( ["test_platform", "value", "expected"], [ ["linux", "a/b/c.txt", None], ["linux", "a/b?/c.txt", None], + ["linux", "../a/./../b/c.txt", None], ["windows", "a/b/c.txt", None], ["windows", "a/b?/c.txt", ValidationError], + ["windows", "../a/./../b/c.txt", None], ["universal", "a/b/c.txt", None], + ["universal", "./a/b/c.txt", None], + ["universal", "../a/./../b/c.txt", None], ["universal", "a/b?/c.txt", ValidationError], ], ) @@ -288,8 +296,9 @@ [["{0}{1}{0}".format(randstr(64), invalid_c)] for invalid_c in INVALID_PATH_CHARS], ) def test_exception_invalid_char(self, value): - with pytest.raises(InvalidCharError): + with pytest.raises(ValidationError) as e: validate_filepath(value) + assert e.value.reason == ErrorReason.INVALID_CHARACTER assert not is_valid_filepath(value) @pytest.mark.parametrize( @@ -305,8 +314,9 @@ ], ) def test_exception_invalid_win_char(self, value, platform): - with pytest.raises(InvalidCharError): + with pytest.raises(ValidationError) as e: validate_filepath(value, platform=platform) + assert e.value.reason == ErrorReason.INVALID_CHARACTER assert not is_valid_filepath(value, platform=platform) @pytest.mark.parametrize( @@ -336,26 +346,26 @@ @pytest.mark.parametrize( ["value", "platform", "expected"], [ - ["abc\\{}\\xyz".format(reserved_keyword), platform, ReservedNameError] + ["abc\\{}\\xyz".format(reserved_keyword), platform, ValidationError] for reserved_keyword, platform in product( WIN_RESERVED_FILE_NAMES, ["windows", "universal"] ) if reserved_keyword not in [".", ".."] ] + [ - ["foo/abc/{}.txt".format(reserved_keyword), platform, ReservedNameError] + ["foo/abc/{}.txt".format(reserved_keyword), platform, ValidationError] for reserved_keyword, platform in product(WIN_RESERVED_FILE_NAMES, ["universal"]) if reserved_keyword not in [".", ".."] ] + [ - ["{}".format(reserved_keyword), platform, ReservedNameError] + ["{}".format(reserved_keyword), platform, ValidationError] for reserved_keyword, platform in product( WIN_RESERVED_FILE_NAMES, ["windows", "universal"] ) if reserved_keyword not in [".", ".."] ] + [ - ["{}\\{}".format(drive, filename), platform, ReservedNameError] + ["{}\\{}".format(drive, filename), platform, ValidationError] for drive, platform, filename in product( ["C:", "D:"], ["windows"], NTFS_RESERVED_FILE_NAMES ) @@ -365,6 +375,7 @@ with pytest.raises(expected) as e: print(platform, value) validate_filepath(value, platform=platform) + assert e.value.reason == ErrorReason.RESERVED_NAME assert e.value.reusable_name is False assert e.value.reserved_name @@ -373,15 +384,16 @@ @pytest.mark.parametrize( ["value", "platform", "expected"], [ - [value, platform, InvalidCharError] + [value, platform, ErrorReason.INVALID_CHARACTER] for value, platform in product(["asdf\rsdf"], ["windows", "universal"]) ], ) def test_exception_escape_err_msg(self, value, platform, expected): - with pytest.raises(expected) as e: + with pytest.raises(ValidationError) as e: print(platform, repr(value)) validate_filepath(value, platform=platform) + assert e.value.reason == expected assert str(e.value) == ( r"invalid char found: invalids=('\r'), value='asdf\rsdf', " "reason=INVALID_CHARACTER, target-platform=Windows" @@ -411,6 +423,7 @@ ["C:\\Users/est\\AppData/Local\\Temp/pytest-of-test\\pytest-0/hoge.csv"], ["C:\\Users"], ["C:\\"], + ["\\Users"], ], ) def test_normal(self, value): @@ -418,34 +431,39 @@ assert is_valid_filepath(value, platform="windows") @pytest.mark.parametrize( - ["value", "expected"], - [["C:\\Users\\" + "a" * 1024, InvalidCharError], ["\\Users", InvalidCharError]], + ["value", "platform", "expected"], + [ + [r"C:\Users\a", "universal", ErrorReason.MALFORMED_ABS_PATH], + [r"C:\Users:a", "universal", ErrorReason.MALFORMED_ABS_PATH], + ["C:\\Users\\" + "a" * 1024, "windows", ErrorReason.INVALID_LENGTH], + [r"C:\Users:a", "windows", ErrorReason.INVALID_CHARACTER], + ], ) - def test_exception(self, value, expected): + def test_exception(self, value, platform, expected): with pytest.raises(ValidationError) as e: - validate_filepath(value) - assert e.value.reason == ErrorReason.MALFORMED_ABS_PATH - assert not is_valid_filepath(value) + validate_filepath(value, platform=platform) + assert e.value.reason == expected + assert not is_valid_filepath(value, platform=platform) class Test_sanitize_filepath: SANITIZE_CHARS = INVALID_WIN_PATH_CHARS + unprintable_ascii_chars NOT_SANITIZE_CHARS = VALID_PATH_CHARS - REPLACE_TEXT_LIST = ["", "_"] + REPLACE_TEXTS = ["", "_"] @pytest.mark.parametrize( ["platform", "value", "replace_text", "expected"], [ ["universal", "AA" + c + "B", rep, "AA" + rep + "B"] - for c, rep in product(SANITIZE_CHARS, REPLACE_TEXT_LIST) + for c, rep in product(SANITIZE_CHARS, REPLACE_TEXTS) ] + [ ["universal", "A" + c + "B", rep, "A" + c + "B"] - for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXT_LIST) + for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXTS) ] + [ ["universal", "あ" + c + "い", rep, "あ" + c + "い"] - for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXT_LIST) + for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXTS) ] + [ [pair.platform, "A" + pair.c + "B", pair.repl, "A" + pair.repl + "B"] @@ -454,7 +472,7 @@ { "platform": ["posix", "linux", "macos"], "c": INVALID_PATH_CHARS + unprintable_ascii_chars, - "repl": REPLACE_TEXT_LIST, + "repl": REPLACE_TEXTS, } ) ) @@ -466,7 +484,7 @@ { "platform": ["posix", "linux", "macos"], "c": [":", "*", "?", '"', "<", ">", "|"], - "repl": REPLACE_TEXT_LIST, + "repl": REPLACE_TEXTS, } ) ) @@ -550,15 +568,15 @@ ["value", "replace_text", "expected"], [ [Path("AA" + c + "B"), rep, Path("AA" + rep + "B")] - for c, rep in product(SANITIZE_CHARS, REPLACE_TEXT_LIST) + for c, rep in product(SANITIZE_CHARS, REPLACE_TEXTS) ] + [ [Path("A" + c + "B"), rep, Path("A" + c + "B")] - for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXT_LIST) + for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXTS) ] + [ [Path("あ" + c + "い"), rep, Path("あ" + c + "い")] - for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXT_LIST) + for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXTS) ], ) def test_normal_pathlike(self, value, replace_text, expected): @@ -590,10 +608,30 @@ validate_filepath(sanitized_name, platform=test_platform) assert is_valid_filepath(sanitized_name, platform=test_platform) + @pytest.mark.parametrize( + ["platform", "value", "expected"], + [ + ["windows", "a/b", "a\\b"], + ["windows", "a\\b", "a\\b"], + ["windows", "a\\\\b", "a\\b"], + ["linux", "a/b", "a/b"], + ["linux", "a//b", "a/b"], + ["linux", "a\\b", "a/b"], + ["linux", "a\\\\b", "a/b"], + ["universal", "a/b", "a/b"], + ["universal", "a//b", "a/b"], + ["universal", "a\\b", "a/b"], + ["universal", "a\\\\b", "a/b"], + ], + ) + def test_normal_path_separator(self, platform, value, expected): + sanitized = sanitize_filepath(value, platform=platform) + assert sanitized == expected + assert is_valid_filepath(sanitized, platform=platform) + @pytest.mark.skipif(m_platform.system() != "Windows", reason="platform dependent tests") @pytest.mark.parametrize( - ["value", "expected"], - [["/a/b/c.txt", ValidationError], ["C:\\a\\b|c.txt", "C:\\a\\bc.txt"],], + ["value", "expected"], [["C:\\a\\b|c.txt", "C:\\a\\bc.txt"],], ) def test_normal_auto_platform_win(self, value, expected): if isinstance(expected, str): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathvalidate-2.2.1/test/test_ltsv.py new/pathvalidate-2.2.2/test/test_ltsv.py --- old/pathvalidate-2.2.1/test/test_ltsv.py 2020-02-01 05:56:47.000000000 +0100 +++ new/pathvalidate-2.2.2/test/test_ltsv.py 2020-03-28 11:43:25.000000000 +0100 @@ -6,7 +6,8 @@ import pytest -from pathvalidate import InvalidCharError, ValidationError, sanitize_ltsv_label, validate_ltsv_label +from pathvalidate import sanitize_ltsv_label, validate_ltsv_label +from pathvalidate.error import ErrorReason, ValidationError from ._common import INVALID_WIN_FILENAME_CHARS, alphanum_chars @@ -58,8 +59,9 @@ + [["あいうえお"], ["ラベル"]], ) def test_exception_invalid_char(self, value): - with pytest.raises(InvalidCharError): + with pytest.raises(ValidationError) as e: validate_ltsv_label(value) + assert e.value.reason == ErrorReason.INVALID_CHARACTER class Test_sanitize_ltsv_label: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathvalidate-2.2.1/test/test_symbol.py new/pathvalidate-2.2.2/test/test_symbol.py --- old/pathvalidate-2.2.1/test/test_symbol.py 2020-01-11 10:35:48.000000000 +0100 +++ new/pathvalidate-2.2.2/test/test_symbol.py 2020-03-28 11:59:31.000000000 +0100 @@ -6,14 +6,9 @@ import pytest -from pathvalidate import ( - InvalidCharError, - ascii_symbols, - replace_symbol, - unprintable_ascii_chars, - validate_symbol, -) +from pathvalidate import ascii_symbols, replace_symbol, unprintable_ascii_chars, validate_symbol from pathvalidate._symbol import replace_unprintable, validate_unprintable +from pathvalidate.error import ErrorReason, ValidationError from ._common import alphanum_chars @@ -42,8 +37,9 @@ ], ) def test_exception_invalid_char(self, value): - with pytest.raises(InvalidCharError): + with pytest.raises(ValidationError) as e: validate_symbol(value) + assert e.value.reason == ErrorReason.INVALID_CHARACTER class Test_replace_symbol: @@ -114,8 +110,9 @@ ], ) def test_exception_invalid_char(self, value): - with pytest.raises(InvalidCharError): + with pytest.raises(ValidationError) as e: validate_unprintable(value) + assert e.value.reason == ErrorReason.INVALID_CHARACTER class Test_replace_unprintable: