thombashi / pathvalidate

A Python library to sanitize/validate a string such as filenames/file-paths/etc.
https://pathvalidate.rtfd.io/
MIT License
210 stars 12 forks source link

Fails to build with Python 3.11.0 alpha 6 #22

Closed hegjon closed 1 year ago

hegjon commented 2 years ago

Full build logs and details can be found here: https://bugzilla.redhat.com/show_bug.cgi?id=2049642

The build logs are from Python 3.11 alpha 4 and pathvalidate 2.3.2, but I just tested locally and reproduced it with the same errors with pathvalidate 2.5.0 and Python 3.11 alpha 6.

hegjon commented 2 years ago

Inlining the build output from pathvalidate 2.5.0 and Python 3.11 alpha 6:

+ cd pathvalidate-2.5.0
+ CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -m64  -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection'
+ LDFLAGS='-Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -Wl,--build-id=sha1 -Wl,-dT,/builddir/build/BUILD/pathvalidate-2.5.0/.package_note-python-pathvalidate-2.5.0-3.fc37.x86_64.ld'
+ PATH=/builddir/build/BUILDROOT/python-pathvalidate-2.5.0-3.fc37.x86_64/usr/bin:/builddir/.local/bin:/builddir/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/sbin
+ PYTHONPATH=/builddir/build/BUILDROOT/python-pathvalidate-2.5.0-3.fc37.x86_64/usr/lib64/python3.11/site-packages:/builddir/build/BUILDROOT/python-pathvalidate-2.5.0-3.fc37.x86_64/usr/lib/python3.11/site-packages
+ PYTHONDONTWRITEBYTECODE=1
+ PYTEST_ADDOPTS=' --ignore=/builddir/build/BUILD/pathvalidate-2.5.0/.pyproject-builddir'
+ /usr/bin/pytest
============================= test session starts ==============================
platform linux -- Python 3.11.0a6, pytest-7.0.1, pluggy-1.0.0
rootdir: /builddir/build/BUILD/pathvalidate-2.5.0, configfile: pyproject.toml, testpaths: test
collected 3442 items

test/test_argparse.py ...........ss............ssssss                    [  0%]
test/test_click.py ................                                      [  1%]
test/test_common.py .................................................... [  2%]
........................................................................ [  4%]
........................................................................ [  7%]
.................................................................        [  8%]
test/test_filename.py .................................................. [ 10%]
........................................................................ [ 12%]
..........................................................ss............ [ 14%]
........................................................................ [ 16%]
........................................................................ [ 18%]
........................................................................ [ 20%]
........................................................................ [ 22%]
........................................................................ [ 25%]
........................................................................ [ 27%]
........................................................................ [ 29%]
........................................................................ [ 31%]
........................................................................ [ 33%]
........................................................................ [ 35%]
........................................................................ [ 37%]
....................                                                     [ 38%]
test/test_filepath.py .................................................. [ 39%]
.................................................s...................... [ 41%]
ssF..................................................................... [ 43%]
........................................................................ [ 45%]
........................................................................ [ 47%]
........................................................................ [ 50%]
........................................................................ [ 52%]
........................................................................ [ 54%]
........................................................................ [ 56%]
....FFFF................................................................ [ 58%]
........................................................................ [ 60%]
..............FF............................................F........... [ 62%]
....F..F.........F...................................................... [ 64%]
........................................................................ [ 66%]
........................................................................ [ 68%]
........................................................................ [ 71%]
....................................FFFF................................ [ 73%]
........................................................................ [ 75%]
.......................................................................F [ 77%]
FFF...........s.....                                                     [ 77%]
test/test_ltsv.py ...................................................... [ 79%]
........................................................................ [ 81%]
........................................................................ [ 83%]
........................................................................ [ 85%]
...............................                                          [ 86%]
test/test_symbol.py .................................................... [ 88%]
..........ss............................................................ [ 90%]
........................................................................ [ 92%]
........................................................................ [ 94%]
........................................................................ [ 96%]
...............................................................ss....... [ 98%]
.................................................                        [100%]

=================================== FAILURES ===================================
_ Test_validate_filepath.test_exception_invalid_char[17DOJ6bKqfdiULG0LywrS37oFh7LAmeHJJyGieLRVf4xjHkenEuiBa8P0zwknBE1\x0017DOJ6bKqfdiULG0LywrS37oFh7LAmeHJJyGieLRVf4xjHkenEuiBa8P0zwknBE1] _

self = <test.test_filepath.Test_validate_filepath object at 0x7f09a2221fd0>
value = '17DOJ6bKqfdiULG0LywrS37oFh7LAmeHJJyGieLRVf4xjHkenEuiBa8P0zwknBE1\x0017DOJ6bKqfdiULG0LywrS37oFh7LAmeHJJyGieLRVf4xjHkenEuiBa8P0zwknBE1'

    @pytest.mark.parametrize(
        ["value"],
        [["{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(ValidationError) as e:
E       Failed: DID NOT RAISE <class 'pathvalidate.error.ValidationError'>

test/test_filepath.py:331: Failed
_______ Test_sanitize_filepath.test_normal_str[universal-AA\x00B--AAB0] ________

self = <test.test_filepath.Test_sanitize_filepath object at 0x7f09a205f250>
platform = 'universal', value = 'AA\x00B', replace_text = '', expected = 'AAB'

    @pytest.mark.parametrize(
        ["platform", "value", "replace_text", "expected"],
        [
            ["universal", "AA" + c + "B", rep, "AA" + rep + "B"]
            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_TEXTS)
        ]
        + [
            ["universal", "あ" + c + "い", rep, "あ" + c + "い"]
            for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXTS)
        ]
        + [
            [pair.platform, "A" + pair.c + "B", pair.repl, "A" + pair.repl + "B"]
            for pair in AllPairs(
                OrderedDict(
                    {
                        "platform": ["posix", "linux", "macos"],
                        "c": INVALID_PATH_CHARS + unprintable_ascii_chars,
                        "repl": REPLACE_TEXTS,
                    }
                )
            )
        ]
        + [
            [pair.platform, "A" + pair.c + "B", pair.repl, "A" + pair.c + "B"]
            for pair in AllPairs(
                OrderedDict(
                    {
                        "platform": ["posix", "linux", "macos"],
                        "c": [":", "*", "?", '"', "<", ">", "|"],
                        "repl": REPLACE_TEXTS,
                    }
                )
            )
        ],
    )
    def test_normal_str(self, platform, value, replace_text, expected):
        sanitized_name = sanitize_filepath(value, platform=platform, replacement_text=replace_text)
>       assert sanitized_name == expected
E       AssertionError: assert 'AA' == 'AAB'
E         - AAB
E         ?   -
E         + AA

test/test_filepath.py:532: AssertionError
______ Test_sanitize_filepath.test_normal_str[universal-AA\x00B-_-AA_B0] _______

self = <test.test_filepath.Test_sanitize_filepath object at 0x7f09a205f4d0>
platform = 'universal', value = 'AA\x00B', replace_text = '_', expected = 'AA_B'

    @pytest.mark.parametrize(
        ["platform", "value", "replace_text", "expected"],
        [
            ["universal", "AA" + c + "B", rep, "AA" + rep + "B"]
            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_TEXTS)
        ]
        + [
            ["universal", "あ" + c + "い", rep, "あ" + c + "い"]
            for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXTS)
        ]
        + [
            [pair.platform, "A" + pair.c + "B", pair.repl, "A" + pair.repl + "B"]
            for pair in AllPairs(
                OrderedDict(
                    {
                        "platform": ["posix", "linux", "macos"],
                        "c": INVALID_PATH_CHARS + unprintable_ascii_chars,
                        "repl": REPLACE_TEXTS,
                    }
                )
            )
        ]
        + [
            [pair.platform, "A" + pair.c + "B", pair.repl, "A" + pair.c + "B"]
            for pair in AllPairs(
                OrderedDict(
                    {
                        "platform": ["posix", "linux", "macos"],
                        "c": [":", "*", "?", '"', "<", ">", "|"],
                        "repl": REPLACE_TEXTS,
                    }
                )
            )
        ],
    )
    def test_normal_str(self, platform, value, replace_text, expected):
        sanitized_name = sanitize_filepath(value, platform=platform, replacement_text=replace_text)
>       assert sanitized_name == expected
E       AssertionError: assert 'AA' == 'AA_B'
E         - AA_B
E         + AA

test/test_filepath.py:532: AssertionError
_______ Test_sanitize_filepath.test_normal_str[universal-AA\x00B--AAB1] ________

self = <test.test_filepath.Test_sanitize_filepath object at 0x7f09a205f750>
platform = 'universal', value = 'AA\x00B', replace_text = '', expected = 'AAB'

    @pytest.mark.parametrize(
        ["platform", "value", "replace_text", "expected"],
        [
            ["universal", "AA" + c + "B", rep, "AA" + rep + "B"]
            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_TEXTS)
        ]
        + [
            ["universal", "あ" + c + "い", rep, "あ" + c + "い"]
            for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXTS)
        ]
        + [
            [pair.platform, "A" + pair.c + "B", pair.repl, "A" + pair.repl + "B"]
            for pair in AllPairs(
                OrderedDict(
                    {
                        "platform": ["posix", "linux", "macos"],
                        "c": INVALID_PATH_CHARS + unprintable_ascii_chars,
                        "repl": REPLACE_TEXTS,
                    }
                )
            )
        ]
        + [
            [pair.platform, "A" + pair.c + "B", pair.repl, "A" + pair.c + "B"]
            for pair in AllPairs(
                OrderedDict(
                    {
                        "platform": ["posix", "linux", "macos"],
                        "c": [":", "*", "?", '"', "<", ">", "|"],
                        "repl": REPLACE_TEXTS,
                    }
                )
            )
        ],
    )
    def test_normal_str(self, platform, value, replace_text, expected):
        sanitized_name = sanitize_filepath(value, platform=platform, replacement_text=replace_text)
>       assert sanitized_name == expected
E       AssertionError: assert 'AA' == 'AAB'
E         - AAB
E         ?   -
E         + AA

test/test_filepath.py:532: AssertionError
______ Test_sanitize_filepath.test_normal_str[universal-AA\x00B-_-AA_B1] _______

self = <test.test_filepath.Test_sanitize_filepath object at 0x7f09a205f910>
platform = 'universal', value = 'AA\x00B', replace_text = '_', expected = 'AA_B'

    @pytest.mark.parametrize(
        ["platform", "value", "replace_text", "expected"],
        [
            ["universal", "AA" + c + "B", rep, "AA" + rep + "B"]
            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_TEXTS)
        ]
        + [
            ["universal", "あ" + c + "い", rep, "あ" + c + "い"]
            for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXTS)
        ]
        + [
            [pair.platform, "A" + pair.c + "B", pair.repl, "A" + pair.repl + "B"]
            for pair in AllPairs(
                OrderedDict(
                    {
                        "platform": ["posix", "linux", "macos"],
                        "c": INVALID_PATH_CHARS + unprintable_ascii_chars,
                        "repl": REPLACE_TEXTS,
                    }
                )
            )
        ]
        + [
            [pair.platform, "A" + pair.c + "B", pair.repl, "A" + pair.c + "B"]
            for pair in AllPairs(
                OrderedDict(
                    {
                        "platform": ["posix", "linux", "macos"],
                        "c": [":", "*", "?", '"', "<", ">", "|"],
                        "repl": REPLACE_TEXTS,
                    }
                )
            )
        ],
    )
    def test_normal_str(self, platform, value, replace_text, expected):
        sanitized_name = sanitize_filepath(value, platform=platform, replacement_text=replace_text)
>       assert sanitized_name == expected
E       AssertionError: assert 'AA' == 'AA_B'
E         - AA_B
E         + AA

test/test_filepath.py:532: AssertionError
___________ Test_sanitize_filepath.test_normal_str[posix-A\x00B--AB] ___________

self = <test.test_filepath.Test_sanitize_filepath object at 0x7f09a20dc950>
platform = 'posix', value = 'A\x00B', replace_text = '', expected = 'AB'

    @pytest.mark.parametrize(
        ["platform", "value", "replace_text", "expected"],
        [
            ["universal", "AA" + c + "B", rep, "AA" + rep + "B"]
            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_TEXTS)
        ]
        + [
            ["universal", "あ" + c + "い", rep, "あ" + c + "い"]
            for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXTS)
        ]
        + [
            [pair.platform, "A" + pair.c + "B", pair.repl, "A" + pair.repl + "B"]
            for pair in AllPairs(
                OrderedDict(
                    {
                        "platform": ["posix", "linux", "macos"],
                        "c": INVALID_PATH_CHARS + unprintable_ascii_chars,
                        "repl": REPLACE_TEXTS,
                    }
                )
            )
        ]
        + [
            [pair.platform, "A" + pair.c + "B", pair.repl, "A" + pair.c + "B"]
            for pair in AllPairs(
                OrderedDict(
                    {
                        "platform": ["posix", "linux", "macos"],
                        "c": [":", "*", "?", '"', "<", ">", "|"],
                        "repl": REPLACE_TEXTS,
                    }
                )
            )
        ],
    )
    def test_normal_str(self, platform, value, replace_text, expected):
        sanitized_name = sanitize_filepath(value, platform=platform, replacement_text=replace_text)
>       assert sanitized_name == expected
E       AssertionError: assert 'A' == 'AB'
E         - AB
E         + A

test/test_filepath.py:532: AssertionError
___________ Test_sanitize_filepath.test_normal_str[linux-A\x00B--AB] ___________

self = <test.test_filepath.Test_sanitize_filepath object at 0x7f09a20dcb50>
platform = 'linux', value = 'A\x00B', replace_text = '', expected = 'AB'

    @pytest.mark.parametrize(
        ["platform", "value", "replace_text", "expected"],
        [
            ["universal", "AA" + c + "B", rep, "AA" + rep + "B"]
            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_TEXTS)
        ]
        + [
            ["universal", "あ" + c + "い", rep, "あ" + c + "い"]
            for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXTS)
        ]
        + [
            [pair.platform, "A" + pair.c + "B", pair.repl, "A" + pair.repl + "B"]
            for pair in AllPairs(
                OrderedDict(
                    {
                        "platform": ["posix", "linux", "macos"],
                        "c": INVALID_PATH_CHARS + unprintable_ascii_chars,
                        "repl": REPLACE_TEXTS,
                    }
                )
            )
        ]
        + [
            [pair.platform, "A" + pair.c + "B", pair.repl, "A" + pair.c + "B"]
            for pair in AllPairs(
                OrderedDict(
                    {
                        "platform": ["posix", "linux", "macos"],
                        "c": [":", "*", "?", '"', "<", ">", "|"],
                        "repl": REPLACE_TEXTS,
                    }
                )
            )
        ],
    )
    def test_normal_str(self, platform, value, replace_text, expected):
        sanitized_name = sanitize_filepath(value, platform=platform, replacement_text=replace_text)
>       assert sanitized_name == expected
E       AssertionError: assert 'A' == 'AB'
E         - AB
E         + A

test/test_filepath.py:532: AssertionError
__________ Test_sanitize_filepath.test_normal_str[linux-A\x00B-_-A_B] __________

self = <test.test_filepath.Test_sanitize_filepath object at 0x7f09a20ee3d0>
platform = 'linux', value = 'A\x00B', replace_text = '_', expected = 'A_B'

    @pytest.mark.parametrize(
        ["platform", "value", "replace_text", "expected"],
        [
            ["universal", "AA" + c + "B", rep, "AA" + rep + "B"]
            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_TEXTS)
        ]
        + [
            ["universal", "あ" + c + "い", rep, "あ" + c + "い"]
            for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXTS)
        ]
        + [
            [pair.platform, "A" + pair.c + "B", pair.repl, "A" + pair.repl + "B"]
            for pair in AllPairs(
                OrderedDict(
                    {
                        "platform": ["posix", "linux", "macos"],
                        "c": INVALID_PATH_CHARS + unprintable_ascii_chars,
                        "repl": REPLACE_TEXTS,
                    }
                )
            )
        ]
        + [
            [pair.platform, "A" + pair.c + "B", pair.repl, "A" + pair.c + "B"]
            for pair in AllPairs(
                OrderedDict(
                    {
                        "platform": ["posix", "linux", "macos"],
                        "c": [":", "*", "?", '"', "<", ">", "|"],
                        "repl": REPLACE_TEXTS,
                    }
                )
            )
        ],
    )
    def test_normal_str(self, platform, value, replace_text, expected):
        sanitized_name = sanitize_filepath(value, platform=platform, replacement_text=replace_text)
>       assert sanitized_name == expected
E       AssertionError: assert 'A' == 'A_B'
E         - A_B
E         + A

test/test_filepath.py:532: AssertionError
_________ Test_sanitize_filepath.test_normal_str[macos-A\x00B-_-A_B0] __________

self = <test.test_filepath.Test_sanitize_filepath object at 0x7f09a20e5210>
platform = 'macos', value = 'A\x00B', replace_text = '_', expected = 'A_B'

    @pytest.mark.parametrize(
        ["platform", "value", "replace_text", "expected"],
        [
            ["universal", "AA" + c + "B", rep, "AA" + rep + "B"]
            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_TEXTS)
        ]
        + [
            ["universal", "あ" + c + "い", rep, "あ" + c + "い"]
            for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXTS)
        ]
        + [
            [pair.platform, "A" + pair.c + "B", pair.repl, "A" + pair.repl + "B"]
            for pair in AllPairs(
                OrderedDict(
                    {
                        "platform": ["posix", "linux", "macos"],
                        "c": INVALID_PATH_CHARS + unprintable_ascii_chars,
                        "repl": REPLACE_TEXTS,
                    }
                )
            )
        ]
        + [
            [pair.platform, "A" + pair.c + "B", pair.repl, "A" + pair.c + "B"]
            for pair in AllPairs(
                OrderedDict(
                    {
                        "platform": ["posix", "linux", "macos"],
                        "c": [":", "*", "?", '"', "<", ">", "|"],
                        "repl": REPLACE_TEXTS,
                    }
                )
            )
        ],
    )
    def test_normal_str(self, platform, value, replace_text, expected):
        sanitized_name = sanitize_filepath(value, platform=platform, replacement_text=replace_text)
>       assert sanitized_name == expected
E       AssertionError: assert 'A' == 'A_B'
E         - A_B
E         + A

test/test_filepath.py:532: AssertionError
__________ Test_sanitize_filepath.test_normal_str[posix-A\x00B-_-A_B] __________

self = <test.test_filepath.Test_sanitize_filepath object at 0x7f09a20e5bd0>
platform = 'posix', value = 'A\x00B', replace_text = '_', expected = 'A_B'

    @pytest.mark.parametrize(
        ["platform", "value", "replace_text", "expected"],
        [
            ["universal", "AA" + c + "B", rep, "AA" + rep + "B"]
            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_TEXTS)
        ]
        + [
            ["universal", "あ" + c + "い", rep, "あ" + c + "い"]
            for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXTS)
        ]
        + [
            [pair.platform, "A" + pair.c + "B", pair.repl, "A" + pair.repl + "B"]
            for pair in AllPairs(
                OrderedDict(
                    {
                        "platform": ["posix", "linux", "macos"],
                        "c": INVALID_PATH_CHARS + unprintable_ascii_chars,
                        "repl": REPLACE_TEXTS,
                    }
                )
            )
        ]
        + [
            [pair.platform, "A" + pair.c + "B", pair.repl, "A" + pair.c + "B"]
            for pair in AllPairs(
                OrderedDict(
                    {
                        "platform": ["posix", "linux", "macos"],
                        "c": [":", "*", "?", '"', "<", ">", "|"],
                        "repl": REPLACE_TEXTS,
                    }
                )
            )
        ],
    )
    def test_normal_str(self, platform, value, replace_text, expected):
        sanitized_name = sanitize_filepath(value, platform=platform, replacement_text=replace_text)
>       assert sanitized_name == expected
E       AssertionError: assert 'A' == 'A_B'
E         - A_B
E         + A

test/test_filepath.py:532: AssertionError
_________ Test_sanitize_filepath.test_normal_str[macos-A\x00B-_-A_B1] __________

self = <test.test_filepath.Test_sanitize_filepath object at 0x7f09a20e7c50>
platform = 'macos', value = 'A\x00B', replace_text = '_', expected = 'A_B'

    @pytest.mark.parametrize(
        ["platform", "value", "replace_text", "expected"],
        [
            ["universal", "AA" + c + "B", rep, "AA" + rep + "B"]
            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_TEXTS)
        ]
        + [
            ["universal", "あ" + c + "い", rep, "あ" + c + "い"]
            for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXTS)
        ]
        + [
            [pair.platform, "A" + pair.c + "B", pair.repl, "A" + pair.repl + "B"]
            for pair in AllPairs(
                OrderedDict(
                    {
                        "platform": ["posix", "linux", "macos"],
                        "c": INVALID_PATH_CHARS + unprintable_ascii_chars,
                        "repl": REPLACE_TEXTS,
                    }
                )
            )
        ]
        + [
            [pair.platform, "A" + pair.c + "B", pair.repl, "A" + pair.c + "B"]
            for pair in AllPairs(
                OrderedDict(
                    {
                        "platform": ["posix", "linux", "macos"],
                        "c": [":", "*", "?", '"', "<", ">", "|"],
                        "repl": REPLACE_TEXTS,
                    }
                )
            )
        ],
    )
    def test_normal_str(self, platform, value, replace_text, expected):
        sanitized_name = sanitize_filepath(value, platform=platform, replacement_text=replace_text)
>       assert sanitized_name == expected
E       AssertionError: assert 'A' == 'A_B'
E         - A_B
E         + A

test/test_filepath.py:532: AssertionError
_______ Test_sanitize_filepath.test_normal_pathlike[value14--expected14] _______

self = <test.test_filepath.Test_sanitize_filepath object at 0x7f09a1e24210>
value = PosixPath('AA\x00B'), replace_text = '', expected = PosixPath('AAB')

    @pytest.mark.parametrize(
        ["value", "replace_text", "expected"],
        [
            [Path("AA" + c + "B"), rep, Path("AA" + rep + "B")]
            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_TEXTS)
        ]
        + [
            [Path("あ" + c + "い"), rep, Path("あ" + c + "い")]
            for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXTS)
        ],
    )
    def test_normal_pathlike(self, value, replace_text, expected):
        sanitized_name = sanitize_filepath(value, replace_text)
>       assert sanitized_name == expected
E       AssertionError: assert PosixPath('AA') == PosixPath('AAB')

test/test_filepath.py:620: AssertionError
______ Test_sanitize_filepath.test_normal_pathlike[value15-_-expected15] _______

self = <test.test_filepath.Test_sanitize_filepath object at 0x7f09a1e24490>
value = PosixPath('AA\x00B'), replace_text = '_', expected = PosixPath('AA_B')

    @pytest.mark.parametrize(
        ["value", "replace_text", "expected"],
        [
            [Path("AA" + c + "B"), rep, Path("AA" + rep + "B")]
            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_TEXTS)
        ]
        + [
            [Path("あ" + c + "い"), rep, Path("あ" + c + "い")]
            for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXTS)
        ],
    )
    def test_normal_pathlike(self, value, replace_text, expected):
        sanitized_name = sanitize_filepath(value, replace_text)
>       assert sanitized_name == expected
E       AssertionError: assert PosixPath('AA') == PosixPath('AA_B')

test/test_filepath.py:620: AssertionError
_______ Test_sanitize_filepath.test_normal_pathlike[value16--expected16] _______

self = <test.test_filepath.Test_sanitize_filepath object at 0x7f09a1e24710>
value = PosixPath('AA\x00B'), replace_text = '', expected = PosixPath('AAB')

    @pytest.mark.parametrize(
        ["value", "replace_text", "expected"],
        [
            [Path("AA" + c + "B"), rep, Path("AA" + rep + "B")]
            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_TEXTS)
        ]
        + [
            [Path("あ" + c + "い"), rep, Path("あ" + c + "い")]
            for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXTS)
        ],
    )
    def test_normal_pathlike(self, value, replace_text, expected):
        sanitized_name = sanitize_filepath(value, replace_text)
>       assert sanitized_name == expected
E       AssertionError: assert PosixPath('AA') == PosixPath('AAB')

test/test_filepath.py:620: AssertionError
______ Test_sanitize_filepath.test_normal_pathlike[value17-_-expected17] _______

self = <test.test_filepath.Test_sanitize_filepath object at 0x7f09a1e24990>
value = PosixPath('AA\x00B'), replace_text = '_', expected = PosixPath('AA_B')

    @pytest.mark.parametrize(
        ["value", "replace_text", "expected"],
        [
            [Path("AA" + c + "B"), rep, Path("AA" + rep + "B")]
            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_TEXTS)
        ]
        + [
            [Path("あ" + c + "い"), rep, Path("あ" + c + "い")]
            for c, rep in product(NOT_SANITIZE_CHARS, REPLACE_TEXTS)
        ],
    )
    def test_normal_pathlike(self, value, replace_text, expected):
        sanitized_name = sanitize_filepath(value, replace_text)
>       assert sanitized_name == expected
E       AssertionError: assert PosixPath('AA') == PosixPath('AA_B')

test/test_filepath.py:620: AssertionError
_ Test_sanitize_filepath.test_normal_multibyte[linux-/tmp/\u3042\u3044\u3046\x00\u3048\u304a.txt--/tmp/\u3042\u3044\u3046\u3048\u304a.txt] _

self = <test.test_filepath.Test_sanitize_filepath object at 0x7f09a1c84a90>
test_platform = 'linux', value = '/tmp/あいう\x00えお.txt', replace_text = ''
expected = '/tmp/あいうえお.txt'

    @pytest.mark.parametrize(
        ["test_platform", "value", "replace_text", "expected"],
        [
            ["linux", "/tmp/あいう\0えお.txt", "", "/tmp/あいうえお.txt"],
            ["linux", "/tmp/属\0性.txt", "-", "/tmp/属-性.txt"],
            ["universal", "tmp/あいう\0えお.txt", "", "tmp/あいうえお.txt"],
            ["universal", "tmp/属\0性.txt", "-", "tmp/属-性.txt"],
        ],
    )
    def test_normal_multibyte(self, test_platform, value, replace_text, expected):
        sanitized_name = sanitize_filepath(value, replace_text, platform=test_platform)
>       assert sanitized_name == expected
E       AssertionError: assert '/tmp/あいう' == '/tmp/あいうえお.txt'
E         - /tmp/あいうえお.txt
E         + /tmp/あいう

test/test_filepath.py:689: AssertionError
_ Test_sanitize_filepath.test_normal_multibyte[linux-/tmp/\u5c5e\x00\u6027.txt---/tmp/\u5c5e-\u6027.txt] _

self = <test.test_filepath.Test_sanitize_filepath object at 0x7f09a1c84dd0>
test_platform = 'linux', value = '/tmp/属\x00性.txt', replace_text = '-'
expected = '/tmp/属-性.txt'

    @pytest.mark.parametrize(
        ["test_platform", "value", "replace_text", "expected"],
        [
            ["linux", "/tmp/あいう\0えお.txt", "", "/tmp/あいうえお.txt"],
            ["linux", "/tmp/属\0性.txt", "-", "/tmp/属-性.txt"],
            ["universal", "tmp/あいう\0えお.txt", "", "tmp/あいうえお.txt"],
            ["universal", "tmp/属\0性.txt", "-", "tmp/属-性.txt"],
        ],
    )
    def test_normal_multibyte(self, test_platform, value, replace_text, expected):
        sanitized_name = sanitize_filepath(value, replace_text, platform=test_platform)
>       assert sanitized_name == expected
E       AssertionError: assert '/tmp/属' == '/tmp/属-性.txt'
E         - /tmp/属-性.txt
E         + /tmp/属

test/test_filepath.py:689: AssertionError
_ Test_sanitize_filepath.test_normal_multibyte[universal-tmp/\u3042\u3044\u3046\x00\u3048\u304a.txt--tmp/\u3042\u3044\u3046\u3048\u304a.txt] _

self = <test.test_filepath.Test_sanitize_filepath object at 0x7f09a1c85110>
test_platform = 'universal', value = 'tmp/あいう\x00えお.txt', replace_text = ''
expected = 'tmp/あいうえお.txt'

    @pytest.mark.parametrize(
        ["test_platform", "value", "replace_text", "expected"],
        [
            ["linux", "/tmp/あいう\0えお.txt", "", "/tmp/あいうえお.txt"],
            ["linux", "/tmp/属\0性.txt", "-", "/tmp/属-性.txt"],
            ["universal", "tmp/あいう\0えお.txt", "", "tmp/あいうえお.txt"],
            ["universal", "tmp/属\0性.txt", "-", "tmp/属-性.txt"],
        ],
    )
    def test_normal_multibyte(self, test_platform, value, replace_text, expected):
        sanitized_name = sanitize_filepath(value, replace_text, platform=test_platform)
>       assert sanitized_name == expected
E       AssertionError: assert 'tmp/あいう' == 'tmp/あいうえお.txt'
E         - tmp/あいうえお.txt
E         + tmp/あいう

test/test_filepath.py:689: AssertionError
_ Test_sanitize_filepath.test_normal_multibyte[universal-tmp/\u5c5e\x00\u6027.txt---tmp/\u5c5e-\u6027.txt] _

self = <test.test_filepath.Test_sanitize_filepath object at 0x7f09a1c85450>
test_platform = 'universal', value = 'tmp/属\x00性.txt', replace_text = '-'
expected = 'tmp/属-性.txt'

    @pytest.mark.parametrize(
        ["test_platform", "value", "replace_text", "expected"],
        [
            ["linux", "/tmp/あいう\0えお.txt", "", "/tmp/あいうえお.txt"],
            ["linux", "/tmp/属\0性.txt", "-", "/tmp/属-性.txt"],
            ["universal", "tmp/あいう\0えお.txt", "", "tmp/あいうえお.txt"],
            ["universal", "tmp/属\0性.txt", "-", "tmp/属-性.txt"],
        ],
    )
    def test_normal_multibyte(self, test_platform, value, replace_text, expected):
        sanitized_name = sanitize_filepath(value, replace_text, platform=test_platform)
>       assert sanitized_name == expected
E       AssertionError: assert 'tmp/属' == 'tmp/属-性.txt'
E         - tmp/属-性.txt
E         + tmp/属

test/test_filepath.py:689: AssertionError
=============================== warnings summary ===============================
../../../../usr/lib/python3.11/site-packages/_pytest/config/__init__.py:1249
  /usr/lib/python3.11/site-packages/_pytest/config/__init__.py:1249: PytestConfigWarning: Unknown config option: discord_verbose

    self._warn_or_fail_if_strict(f"Unknown config option: {key}\n")

../../../../usr/lib/python3.11/site-packages/_pytest/config/__init__.py:1249
  /usr/lib/python3.11/site-packages/_pytest/config/__init__.py:1249: PytestConfigWarning: Unknown config option: md_report

    self._warn_or_fail_if_strict(f"Unknown config option: {key}\n")

../../../../usr/lib/python3.11/site-packages/_pytest/config/__init__.py:1249
  /usr/lib/python3.11/site-packages/_pytest/config/__init__.py:1249: PytestConfigWarning: Unknown config option: md_report_color

    self._warn_or_fail_if_strict(f"Unknown config option: {key}\n")

../../../../usr/lib/python3.11/site-packages/_pytest/config/__init__.py:1249
  /usr/lib/python3.11/site-packages/_pytest/config/__init__.py:1249: PytestConfigWarning: Unknown config option: md_report_verbose

    self._warn_or_fail_if_strict(f"Unknown config option: {key}\n")

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
FAILED test/test_filepath.py::Test_validate_filepath::test_exception_invalid_char[17DOJ6bKqfdiULG0LywrS37oFh7LAmeHJJyGieLRVf4xjHkenEuiBa8P0zwknBE1\x0017DOJ6bKqfdiULG0LywrS37oFh7LAmeHJJyGieLRVf4xjHkenEuiBa8P0zwknBE1]
FAILED test/test_filepath.py::Test_sanitize_filepath::test_normal_str[universal-AA\x00B--AAB0]
FAILED test/test_filepath.py::Test_sanitize_filepath::test_normal_str[universal-AA\x00B-_-AA_B0]
FAILED test/test_filepath.py::Test_sanitize_filepath::test_normal_str[universal-AA\x00B--AAB1]
FAILED test/test_filepath.py::Test_sanitize_filepath::test_normal_str[universal-AA\x00B-_-AA_B1]
FAILED test/test_filepath.py::Test_sanitize_filepath::test_normal_str[posix-A\x00B--AB]
FAILED test/test_filepath.py::Test_sanitize_filepath::test_normal_str[linux-A\x00B--AB]
FAILED test/test_filepath.py::Test_sanitize_filepath::test_normal_str[linux-A\x00B-_-A_B]
FAILED test/test_filepath.py::Test_sanitize_filepath::test_normal_str[macos-A\x00B-_-A_B0]
FAILED test/test_filepath.py::Test_sanitize_filepath::test_normal_str[posix-A\x00B-_-A_B]
FAILED test/test_filepath.py::Test_sanitize_filepath::test_normal_str[macos-A\x00B-_-A_B1]
FAILED test/test_filepath.py::Test_sanitize_filepath::test_normal_pathlike[value14--expected14]
FAILED test/test_filepath.py::Test_sanitize_filepath::test_normal_pathlike[value15-_-expected15]
FAILED test/test_filepath.py::Test_sanitize_filepath::test_normal_pathlike[value16--expected16]
FAILED test/test_filepath.py::Test_sanitize_filepath::test_normal_pathlike[value17-_-expected17]
FAILED test/test_filepath.py::Test_sanitize_filepath::test_normal_multibyte[linux-/tmp/\u3042\u3044\u3046\x00\u3048\u304a.txt--/tmp/\u3042\u3044\u3046\u3048\u304a.txt]
FAILED test/test_filepath.py::Test_sanitize_filepath::test_normal_multibyte[linux-/tmp/\u5c5e\x00\u6027.txt---/tmp/\u5c5e-\u6027.txt]
FAILED test/test_filepath.py::Test_sanitize_filepath::test_normal_multibyte[universal-tmp/\u3042\u3044\u3046\x00\u3048\u304a.txt--tmp/\u3042\u3044\u3046\u3048\u304a.txt]
FAILED test/test_filepath.py::Test_sanitize_filepath::test_normal_multibyte[universal-tmp/\u5c5e\x00\u6027.txt---tmp/\u5c5e-\u6027.txt]
=========== 19 failed, 3405 passed, 18 skipped, 4 warnings in 4.38s ============
thombashi commented 2 years ago

@hegjon Thank you for your report.

Does this need to be corrected in the most recent time? If not, I would like to wait for Python 3.11 RC.

hegjon commented 2 years ago

The most important is that you know that the tests and maybe the code is not working with Python 3.11. The builds have been done to report to developers as early as possible.

I would check the planed timeline here and try to plan your fixes and your releases accordingly: https://fedoraproject.org/wiki/Changes/Python3.11#Important_dates_and_plan

thombashi commented 1 year ago

@hegjon The problem has been fixed at pathvalidate 2.5.2

hegjon commented 1 year ago

Thanks, I confirm that the tests passes on Python 3.11.0rc1