thombashi / pathvalidate Goto Github PK
View Code? Open in Web Editor NEWA Python library to sanitize/validate a string such as filenames/file-paths/etc.
Home Page: https://pathvalidate.rtfd.io/
License: MIT License
A Python library to sanitize/validate a string such as filenames/file-paths/etc.
Home Page: https://pathvalidate.rtfd.io/
License: MIT License
pathvalidate 2.5.0
In Visual Studio Code, no suggestions are given for functions of pathvalidate, e.g. for sanitize_filename
:
I thought that this is a problem of VSC's pylance therefore I opened this issue. It was closed with the comment that this is a problem how pathvalidate does the import. To fix it, it should be done as described in PEP561 resp. library interface.
On: https://github.com/thombashi/pathvalidate/blob/master/README.rst#L110
The output should be in the format:
[PV1100] invalid characters found: ...
and
[PV1002] found a reserved name ...
long_part = 'a'*261
invalid_path = pathlib.Path.home() / long_part / 'another_part'
# windows limit suppressed but still there is 259 limit of the every middle part of path
invalid_path = '\\\\?\\' + str(pathlib.Path.home() / long_part / 'file.exe')
pathvalidate.validate_filepath(str(invalid_path), max_len=1024) # no error
pathlib.Path(invalid_path).mkdir(parents=True) # OSError: [WinError 123]
In [14]: try:
...: pathvalidate.validate_filepath('asdf\rsdf')
...: except Exception as e:
...: print(e)
...:
...:
sdf', reason=INVALID_CHARACTERars=(\
Per https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words and various other results on Google, "CLOCK$" is a problematic filename in some versions of Windows. Apparently it is possible to create such a file through some methods, but then not to delete it. Testing on various Windows platforms may reveal more details of the behavior. If it remains problematic, it may warrant inclusion in this library?
Here's another example that doesn't do what I would expect (although perhaps I'm expecting the wrong thing?).
In pathvalidate 2.4.1:
>>> pathvalidate.validate_filename("")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/iac2/st/lib/python3.8/site-packages/pathvalidate/_filename.py", line 260, in validate_filename
FileNameValidator(
File "/home/iac2/st/lib/python3.8/site-packages/pathvalidate/_filename.py", line 134, in validate
validate_pathtype(
File "/home/iac2/st/lib/python3.8/site-packages/pathvalidate/_common.py", line 49, in validate_pathtype
raise ValidationError(
pathvalidate.error.ValidationError: reason=NULL_NAME, description=the value must be a not empty
That's what I would expect.
>>> pathvalidate.sanitize_filename("")
''
>>> pathvalidate.sanitize_filename("/")
''
>>> pathvalidate.sanitize_filename("//")
''
>>> pathvalidate.sanitize_filename("?")
''
That's consistent with the character removal, but the end result is not a valid filename, so I would have expected sanitize_filename()
to raise an error here?
I can call validate_filename()
after sanitize_filename()
to take care of this. Is that what I should be doing, or should I be able to expect that sanitize_filename()
either returns a usable filename or raises an error?
Cheers.
In pathvalidate 2.4.1:
>>> pathvalidate.validate_filename(".")
>>> pathvalidate.validate_filename("..")
>>> pathvalidate.sanitize_filename(".")
'.'
>>> pathvalidate.sanitize_filename("..")
'..'
I know that .
and ..
can be valid in a path, but surely not as filenames on any of the supported platforms?
Thanks.
Edited to add:
My expectation would be that validate_filename()
would perhaps raise a ValidationError with a reason of RESERVED_NAME
in the two cases above?
Also, if these are considered reserved filenames, shouldn't _
be appended to each, as with, for example: sanitize_filename("con")
returns con_
?
I tried to install it via apt:
su -l
add-apt-repository ppa:thombashi/ppa
apt update
apt install python3-pathvalidate
Trying add-apt-repository ppa:thombashi/ppa
leads to the following error message:
kRyzen7:~# add-apt-repository ppa:thombashi/ppa
deb packages of my repositories (https://github.com/thombashi).
PPA packaging sources can be found at https://github.com/thombashi/PPA
More info: https://launchpad.net/~thombashi/+archive/ubuntu/ppa
Press [ENTER] to continue or ctrl-c to cancel adding it
gpg: Die "Keybox" /tmp/tmprksegdde/pubring.gpg' wurde erstellt
gpg: /tmp/tmprksegdde/trustdb.gpg: trust-db erzeugt
gpg: Schlüssel CF9859CE95D9F1E2: Öffentlicher Schlüssel "Launchpad PPA for Tsuyoshi Hombashi" importiert
gpg: Anzahl insgesamt bearbeiteter Schlüssel: 1
gpg: importiert: 1
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
gpg: Keine gültigen OpenPGP-Daten gefunden.
My interpretation is that an old method (apt-key) is used in thombashi's script. Maybe this method is no longer support by the apt version used in Debian 11.
After this failed I tried to install pathvalidate via pip:
(as superuser) apt install python3-pip
and as normal user : pip install pathvalidate
. This seems to have been successfull:
Collecting pathvalidate
Downloading pathvalidate-2.5.0-py3-none-any.whl (19 kB)
Installing collected packages: pathvalidate
Successfully installed pathvalidate-2.5.0
But still the python script that tries to import sanit from pathvalidate fails.
Whereas sanitize_filepath
works perfectly for a relative path, it has an unexpected behaviour on absolute paths. It either rises an exception or, when platform
is specified as 'auto' or 'Linux', it lefts the string unchanged.
The execution (see sanitize-filepath-bug.pdf) has been run with Python 3.8.5 under Linux (Ubuntu 20.04.2 LTS). I've just installed for the first time pathvalidate
today via pip.
I'm a Fedora Linux packager that would like to include pathvalidate in our official RPM repository.
All files in the pathvalidate-2.3.2.tar.gz sdist have file permission 755. This causes the packaging the apply patches, it is preferred to be as close as possible to upstream.
See https://bugzilla.redhat.com/show_bug.cgi?id=1936059 for details.
Content of pathvalidate-2.3.2.tar.gz:
jonny@jonny-thinkpad ~/rpmbuild/SOURCES $ tar tzfv pathvalidate-2.3.2.tar.gz
drwxrwxrwx toor/toor 0 2021-01-03 10:34 pathvalidate-2.3.2/
-rwxrwxrwx toor/toor 1084 2019-10-09 09:45 pathvalidate-2.3.2/LICENSE
-rwxrwxrwx toor/toor 242 2020-10-10 10:10 pathvalidate-2.3.2/MANIFEST.in
-rwxrwxrwx toor/toor 12934 2021-01-03 10:34 pathvalidate-2.3.2/PKG-INFO
-rwxrwxrwx toor/toor 8864 2020-12-13 09:14 pathvalidate-2.3.2/README.rst
drwxrwxrwx toor/toor 0 2021-01-03 10:34 pathvalidate-2.3.2/docs/
drwxrwxrwx toor/toor 0 2021-01-03 10:34 pathvalidate-2.3.2/docs/pages/
drwxrwxrwx toor/toor 0 2021-01-03 10:34 pathvalidate-2.3.2/docs/pages/introduction/
-rwxrwxrwx toor/toor 97 2019-10-09 09:45 pathvalidate-2.3.2/docs/pages/introduction/summary.txt
drwxrwxrwx toor/toor 0 2021-01-03 10:34 pathvalidate-2.3.2/pathvalidate/
-rwxrwxrwx toor/toor 936 2020-10-10 10:10 pathvalidate-2.3.2/pathvalidate/__init__.py
-rwxrwxrwx toor/toor 209 2021-01-03 10:23 pathvalidate-2.3.2/pathvalidate/__version__.py
-rwxrwxrwx toor/toor 3967 2020-10-10 10:10 pathvalidate-2.3.2/pathvalidate/_base.py
-rwxrwxrwx toor/toor 3314 2020-12-13 08:16 pathvalidate-2.3.2/pathvalidate/_common.py
-rwxrwxrwx toor/toor 266 2020-10-10 10:10 pathvalidate-2.3.2/pathvalidate/_const.py
-rwxrwxrwx toor/toor 11052 2021-01-03 05:22 pathvalidate-2.3.2/pathvalidate/_filename.py
-rwxrwxrwx toor/toor 13870 2021-01-03 05:15 pathvalidate-2.3.2/pathvalidate/_filepath.py
-rwxrwxrwx toor/toor 1301 2020-12-13 08:08 pathvalidate-2.3.2/pathvalidate/_ltsv.py
-rwxrwxrwx toor/toor 2203 2020-10-10 10:10 pathvalidate-2.3.2/pathvalidate/_symbol.py
-rwxrwxrwx toor/toor 1468 2020-10-10 10:10 pathvalidate-2.3.2/pathvalidate/argparse.py
-rwxrwxrwx toor/toor 1518 2020-10-10 10:10 pathvalidate-2.3.2/pathvalidate/click.py
-rwxrwxrwx toor/toor 4207 2020-10-10 10:10 pathvalidate-2.3.2/pathvalidate/error.py
-rwxrwxrwx toor/toor 0 2020-10-10 10:10 pathvalidate-2.3.2/pathvalidate/py.typed
drwxrwxrwx toor/toor 0 2021-01-03 10:34 pathvalidate-2.3.2/pathvalidate.egg-info/
-rwxrwxrwx toor/toor 12934 2021-01-03 10:34 pathvalidate-2.3.2/pathvalidate.egg-info/PKG-INFO
-rwxrwxrwx toor/toor 864 2021-01-03 10:34 pathvalidate-2.3.2/pathvalidate.egg-info/SOURCES.txt
-rwxrwxrwx toor/toor 1 2021-01-03 10:34 pathvalidate-2.3.2/pathvalidate.egg-info/dependency_links.txt
-rwxrwxrwx toor/toor 124 2021-01-03 10:34 pathvalidate-2.3.2/pathvalidate.egg-info/requires.txt
-rwxrwxrwx toor/toor 13 2021-01-03 10:34 pathvalidate-2.3.2/pathvalidate.egg-info/top_level.txt
-rwxrwxrwx toor/toor 952 2020-10-10 10:10 pathvalidate-2.3.2/pyproject.toml
drwxrwxrwx toor/toor 0 2021-01-03 10:34 pathvalidate-2.3.2/requirements/
-rwxrwxrwx toor/toor 29 2020-10-10 10:10 pathvalidate-2.3.2/requirements/docs_requirements.txt
-rwxrwxrwx toor/toor 1 2020-10-10 10:10 pathvalidate-2.3.2/requirements/requirements.txt
-rwxrwxrwx toor/toor 106 2020-12-13 08:57 pathvalidate-2.3.2/requirements/test_requirements.txt
-rwxrwxrwx toor/toor 38 2021-01-03 10:34 pathvalidate-2.3.2/setup.cfg
-rwxrwxrwx toor/toor 2791 2020-12-13 08:27 pathvalidate-2.3.2/setup.py
drwxrwxrwx toor/toor 0 2021-01-03 10:34 pathvalidate-2.3.2/test/
-rwxrwxrwx toor/toor 0 2019-10-09 09:45 pathvalidate-2.3.2/test/__init__.py
-rwxrwxrwx toor/toor 1895 2020-10-10 10:10 pathvalidate-2.3.2/test/_common.py
-rwxrwxrwx toor/toor 3944 2020-10-10 10:10 pathvalidate-2.3.2/test/test_argparse.py
-rwxrwxrwx toor/toor 2025 2020-10-10 10:10 pathvalidate-2.3.2/test/test_click.py
-rwxrwxrwx toor/toor 1193 2020-10-10 10:10 pathvalidate-2.3.2/test/test_common.py
-rwxrwxrwx toor/toor 18388 2020-12-16 10:20 pathvalidate-2.3.2/test/test_filename.py
-rwxrwxrwx toor/toor 27717 2020-12-17 05:22 pathvalidate-2.3.2/test/test_filepath.py
-rwxrwxrwx toor/toor 2441 2020-10-10 10:10 pathvalidate-2.3.2/test/test_ltsv.py
-rwxrwxrwx toor/toor 4642 2020-10-10 10:10 pathvalidate-2.3.2/test/test_symbol.py
-rwxrwxrwx toor/toor 1580 2020-12-13 05:48 pathvalidate-2.3.2/tox.ini
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.
If you pass ./whatever/path to sanitize_filepath, "./" is changed to "._/"
Since "./" != "._/" on any platform this will cause code using pathvalidate to throw an exception down the line.
As far as I can tell under the Windows platform, the following issues exist:
These are for sanitize_filepath:
from pathvalidate import sanitize_filepath
sanitize_filepath(r"users\benjamin\test\test1.zip")
'users/benjamin/test/test1.zip'
sanitize_filepath(r"\users\benjamin\test\test1.zip")
Traceback (most recent call last):
File "", line 1, in
File "C:\Users\bschollnick.URMC-SH\python3\av1\lib\site-packages\pathvalidate_filepath.py", line 376, in sanitize_filepath
).sanitize(file_path, replacement_text)
File "C:\Users\bschollnick.URMC-SH\python3\av1\lib\site-packages\pathvalidate_filepath.py", line 74, in sanitize
self.__fpath_validator.validate_abspath(value)
File "C:\Users\bschollnick.URMC-SH\python3\av1\lib\site-packages\pathvalidate_filepath.py", line 206, in validate_abspath
raise err_object
pathvalidate.error.ValidationError: reason=MALFORMED_ABS_PATH, target-platform=universal, description=an invalid absolute file path (\users\benjamin\test\test1.zip) for the platform (universal). to avoid the error, specify an appropriate platform correspond with the path format, or 'auto'.
import os
print(os.sep)
'\'sanitize_filepath(r"users\benjamin\test\test1.zip")
'users/benjamin/test/test1.zip'
Please note, the string I passed in was using os.sep. What was returned, did not use os.sep.
Typing of pathvalidate is incorrect. It uses Union for input/output arguments instead of using generics.
This throws mypy off - it cannot infer exact type of output variable, even if it's easily inferable from code structure.
repro.py
import pathlib
import typing
import pathvalidate
print(pathvalidate.__version__)
s = pathvalidate.sanitize_filename("lorem_ipsum")
print(type(s))
if typing.TYPE_CHECKING:
reveal_type(s)
p = pathvalidate.sanitize_filename(pathlib.Path("lorem_ipsum"))
print(type(p))
if typing.TYPE_CHECKING:
reveal_type(p)
Outputs:
$ python3 repro.py
2.5.0
<class 'str'>
<class 'pathlib.PosixPath'>
$ mypy repro.py
repro.py:11: note: Revealed type is "Union[builtins.str, pathlib.Path]"
repro.py:16: note: Revealed type is "Union[builtins.str, pathlib.Path]"
Success: no issues found in 1 source file
Expected output:
str
type inferred for first reveal_type
, pathlib.Path
inferred for second reveal_type
Thanks for your nice package. I would like to use and integrate it into another project.
It would be nice if the package was a standalone package. There are two uncommon dependencies while only small parts of it are used. A package like typepy
can be replaced easily. six
is common, but you are using only one function of it. So why not include the following function from six.py (including the license):
def add_metaclass(metaclass):
"""Class decorator for creating a class with a metaclass."""
def wrapper(cls):
orig_vars = cls.__dict__.copy()
slots = orig_vars.get('__slots__')
if slots is not None:
if isinstance(slots, str):
slots = [slots]
for slots_var in slots:
orig_vars.pop(slots_var)
orig_vars.pop('__dict__', None)
orig_vars.pop('__weakref__', None)
return metaclass(cls.__name__, cls.__bases__, orig_vars)
return wrapper
File names that consist of whitespace characters only are valid on my system. I'm on Linux 5.9.6
, I don't know if such file names are also valid for MacOS or not.
>>> validate_filename(" ", platform="linux")
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "/home/joe/.venv/lib/python3.8/site-packages/pathvalidate/_filename.py", line 249, in validate_filename
FileNameValidator(
File "/home/joe/.venv/lib/python3.8/site-packages/pathvalidate/_filename.py", line 134, in validate
validate_pathtype(value)
File "/home/joe/.venv/lib/python3.8/site-packages/pathvalidate/_common.py", line 41, in validate_pathtype
raise ValidationError(
pathvalidate.error.ValidationError: reason=NULL_NAME, description=the value must be a not empty
When running the following:
sanitized = sanitize_filename(txt, platform="Windows")
If the variable txt contains a unicode dash an invalid sanitized filename is returned. The unicode dash is not replaced. An error occurs when a filename is opened using the sanitized filename.
The following change works:
sanitized = sanitize_filename(re.sub(u"\u2013", "-", txt), platform="Windows")
I think the function should remove the unicode en dash and replace it with an ascii dash.
The root of the problem seems to be that even on a non-windows platform the backslash is treated as a path separator character, leading to false absolute path detections. The following script demonstrates the problem with a few examples:
>>> from pathvalidate import validate_filename, ValidationError
>>> for name in ["\\", "\\\\", "\\ ", "C:\\", "c:\\", "\\xyz", "\\xyz "]:
... try:
... validate_filename(name, platform="linux")
... except ValidationError as e:
... print(e.reason, "for", repr(name))
... else:
... raise Exception("did not raise for %r" % (name,))
...
ErrorReason.FOUND_ABS_PATH for '\\'
ErrorReason.FOUND_ABS_PATH for '\\\\'
ErrorReason.FOUND_ABS_PATH for '\\ '
ErrorReason.FOUND_ABS_PATH for 'C:\\'
ErrorReason.FOUND_ABS_PATH for 'c:\\'
ErrorReason.FOUND_ABS_PATH for '\\xyz'
ErrorReason.FOUND_ABS_PATH for '\\xyz '
I'm on Linux 5.11.10
, I don't know if such file names are also valid for MacOS or not.
Method sanitize() in class FileNameSanitizer uses __RE_INVALID_WIN_FILENAME constant independently from inbound platform name. Shouldn't it check platform and use __RE_INVALID_FILENAME in case of non-windows OS?
See code at line:
pathvalidate/pathvalidate/_file.py
Line 122 in 718e62a
Similar situation is in sanitize() method in FilePathSanitizer class:
pathvalidate/pathvalidate/_file.py
Line 212 in 718e62a
The maximum length for filenames/pathnames - e.g. 255/4096 for linux - is really a byte length constraint. Thus, given a typical scenario, where sys.getfilesystemencoding()
returns utf-8
, a path can pass validation that cannot be actually created in the system.
>>> import sys, pathvalidate as pv
>>> sys.getfilesystemencoding()
'utf-8'
>>> good = '\u2013' * 85
>>> long = '\u2013' * 86
>>> len(good), len(long)
(85, 86)
>>> pv.validate_filename(good)
>>> pv.validate_filename(long)
>>> pv.validate_filename('a' * 256)
Traceback (most recent call last):
...
pathvalidate.error.InvalidLengthError: filename is too long: expected<=255, actual=256, reason=INVALID_LENGTH
>>> with open(good, 'w') as handle:
... handle.write('good')
...
4
>>> with open(long, 'w') as handle:
... handle.write('long')
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 36] File name too long: '––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––'
pathvalidate.sanitize_filename() is clipping to 255 on Windows 11.
My Windows 11 installation has long filename enabled by default in the registry.
It would be good to either check that setting, or at least be able to override the 255 limit when calling the method.
I would like to trim heading and trailing Space 0x20
&& trailing Period 0x2E
with sanitize_filename
if given platform is Windows
.
File and Folder names that begin or end with the ASCII Space (0x20) will be saved without these characters. File and Folder names that end with the ASCII Period (0x2E) character will also be saved without this character. All other trailing or leading whitespace characters are retained.
Thank you for this package!
It seems that the value for target-platform below should be not just Windows, but also Linux, or universal. The code is running on linux, producing this justified validation error, only the target-platform field is confusing:
validate_filename(name)
File "lib/python3.10/site-packages/pathvalidate/_filename.py", line 318, in validate_filename
).validate(filename)
File "/lib/python3.10/site-packages/pathvalidate/_filename.py", line 191, in validate
self.__validate_win_filename(unicode_filename)
File "python3.10/site-packages/pathvalidate/_filename.py", line 221, in __validate_win_filename
raise InvalidCharError(
pathvalidate.error.InvalidCharError: [PV1100] invalid characters found: invalids=('/'), value='foo / 𝜋', target-platform=Windows
Or is it necessary to specify the target platforms before calling this api?
(I would humbly like to reject for all three popular platforms in my case)
For more details: https://bugzilla.redhat.com/show_bug.cgi?id=2259547
The bugzilla issue was with pathvalidate 2.5.2. Here is the locally reproduced output with pathvalidate 3.2.0:
+ cd pathvalidate-3.2.0
+ CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -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 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer '
+ LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld-errors -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -specs=/usr/lib/rpm/redhat/redhat-package-notes '
+ PATH=/builddir/build/BUILDROOT/python-pathvalidate-3.2.0-1.fc40.x86_64/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/sbin
+ PYTHONPATH=/builddir/build/BUILDROOT/python-pathvalidate-3.2.0-1.fc40.x86_64/usr/lib64/python3.13/site-packages:/builddir/build/BUILDROOT/python-pathvalidate-3.2.0-1.fc40.x86_64/usr/lib/python3.13/site-packages
+ PYTHONDONTWRITEBYTECODE=1
+ PYTEST_ADDOPTS=' --ignore=/builddir/build/BUILD/pathvalidate-3.2.0/.pyproject-builddir'
+ PYTEST_XDIST_AUTO_NUM_WORKERS=4
+ /usr/bin/pytest
============================= test session starts ==============================
platform linux -- Python 3.13.0a3, pytest-7.4.3, pluggy-1.3.0
rootdir: /builddir/build/BUILD/pathvalidate-3.2.0
configfile: pyproject.toml
testpaths: test
collected 3727 items
test/test_argparse.py ...........ss............ssssss [ 0%]
test/test_click.py ................ [ 1%]
test/test_common.py .................................................... [ 2%]
........................................................................ [ 4%]
........................................................................ [ 6%]
................................................................. [ 8%]
test/test_error.py ... [ 8%]
test/test_filename.py .................................................. [ 9%]
........................................................................ [ 11%]
................................................................ss...... [ 13%]
........................................................................ [ 15%]
........................................................................ [ 17%]
........................................................................ [ 19%]
..................F.F..FFF.F..FF........................................ [ 21%]
........................................................................ [ 23%]
........................................................................ [ 25%]
........................................................................ [ 27%]
........................................................................ [ 29%]
........................................................................ [ 30%]
........................................................................ [ 32%]
........................................................................ [ 34%]
........................................................................ [ 36%]
........................................................................ [ 38%]
.................. [ 39%]
test/test_filepath.py .................................................. [ 40%]
...................................................F...s................ [ 42%]
......ss................................................................ [ 44%]
........................................................................ [ 46%]
........................................................................ [ 48%]
........................................................................ [ 50%]
........................................................................ [ 52%]
........................................................................ [ 54%]
........................................................................ [ 55%]
........................................................................ [ 57%]
........................................................................ [ 59%]
........................................................................ [ 61%]
........................................................................ [ 63%]
........................................................................ [ 65%]
........................................................................ [ 67%]
........................................................................ [ 69%]
........................................................................ [ 71%]
........................................................................ [ 73%]
........................................................................ [ 75%]
........................................................................ [ 77%]
...............................................................s...... [ 79%]
test/test_handler.py .................. [ 79%]
test/test_ltsv.py ...................................................... [ 81%]
........................................................................ [ 82%]
........................................................................ [ 84%]
........................................................................ [ 86%]
............................... [ 87%]
test/test_symbol.py .................................................... [ 89%]
..........ss............................................................ [ 90%]
........................................................................ [ 92%]
........................................................................ [ 94%]
........................................................................ [ 96%]
...............................................................ss....... [ 98%]
................................................. [100%]
=================================== FAILURES ===================================
_____ Test_validate_filename.test_win_abs_path[windows-\\-ValidationError] _____
self = <test.test_filename.Test_validate_filename object at 0x7f1ce9125e50>
platform = 'windows', value = '\\'
expected = <class 'pathvalidate.error.ValidationError'>
@pytest.mark.parametrize(
["platform", "value", "expected"],
[
[win_abspath, platform, None]
for win_abspath, platform in product(
["linux", "macos", "posix"],
["\\", "\\\\", "\\ ", "C:\\", "c:\\", "\\xyz", "\\xyz "],
)
]
+ [
[win_abspath, platform, ValidationError]
for win_abspath, platform in product(
["windows", "universal"], ["\\", "\\\\", "\\ ", "C:\\", "c:\\", "\\xyz", "\\xyz "]
)
],
)
def test_win_abs_path(self, platform, value, expected):
if expected is None:
validate_filename(value, platform=platform)
else:
with pytest.raises(expected) as e:
validate_filename(value, platform=platform)
> assert e.value.reason == ErrorReason.FOUND_ABS_PATH
E AssertionError: assert <ErrorReason.INVALID_CHARACTER: ('PV1100', 'INVALID_CHARACTER', 'invalid characters found')> == <ErrorReason.FOUND_ABS_PATH: ('PV1200', 'FOUND_ABS_PATH', 'found an absolute path where must be a relative path')>
E + where <ErrorReason.INVALID_CHARACTER: ('PV1100', 'INVALID_CHARACTER', 'invalid characters found')> = [PV1100] invalid characters found: invalids=('\\'), value='\\', platform=Windows.reason
E + where [PV1100] invalid characters found: invalids=('\\'), value='\\', platform=Windows = <ExceptionInfo [PV1100] invalid characters found: invalids=('\\'), value='\\', platform=Windows tblen=4>.value
E + and <ErrorReason.FOUND_ABS_PATH: ('PV1200', 'FOUND_ABS_PATH', 'found an absolute path where must be a relative path')> = ErrorReason.FOUND_ABS_PATH
test/test_filename.py:416: AssertionError
____ Test_validate_filename.test_win_abs_path[windows-\\ -ValidationError] _____
self = <test.test_filename.Test_validate_filename object at 0x7f1ce9125f70>
platform = 'windows', value = '\\ '
expected = <class 'pathvalidate.error.ValidationError'>
@pytest.mark.parametrize(
["platform", "value", "expected"],
[
[win_abspath, platform, None]
for win_abspath, platform in product(
["linux", "macos", "posix"],
["\\", "\\\\", "\\ ", "C:\\", "c:\\", "\\xyz", "\\xyz "],
)
]
+ [
[win_abspath, platform, ValidationError]
for win_abspath, platform in product(
["windows", "universal"], ["\\", "\\\\", "\\ ", "C:\\", "c:\\", "\\xyz", "\\xyz "]
)
],
)
def test_win_abs_path(self, platform, value, expected):
if expected is None:
validate_filename(value, platform=platform)
else:
with pytest.raises(expected) as e:
validate_filename(value, platform=platform)
> assert e.value.reason == ErrorReason.FOUND_ABS_PATH
E AssertionError: assert <ErrorReason.INVALID_CHARACTER: ('PV1100', 'INVALID_CHARACTER', 'invalid characters found')> == <ErrorReason.FOUND_ABS_PATH: ('PV1200', 'FOUND_ABS_PATH', 'found an absolute path where must be a relative path')>
E + where <ErrorReason.INVALID_CHARACTER: ('PV1100', 'INVALID_CHARACTER', 'invalid characters found')> = [PV1100] invalid characters found: invalids=('\\'), value='\\ ', platform=Windows.reason
E + where [PV1100] invalid characters found: invalids=('\\'), value='\\ ', platform=Windows = <ExceptionInfo [PV1100] invalid characters found: invalids=('\\'), value='\\ ', platform=Windows tblen=4>.value
E + and <ErrorReason.FOUND_ABS_PATH: ('PV1200', 'FOUND_ABS_PATH', 'found an absolute path where must be a relative path')> = ErrorReason.FOUND_ABS_PATH
test/test_filename.py:416: AssertionError
___ Test_validate_filename.test_win_abs_path[windows-\\xyz-ValidationError] ____
self = <test.test_filename.Test_validate_filename object at 0x7f1ce9126120>
platform = 'windows', value = '\\xyz'
expected = <class 'pathvalidate.error.ValidationError'>
@pytest.mark.parametrize(
["platform", "value", "expected"],
[
[win_abspath, platform, None]
for win_abspath, platform in product(
["linux", "macos", "posix"],
["\\", "\\\\", "\\ ", "C:\\", "c:\\", "\\xyz", "\\xyz "],
)
]
+ [
[win_abspath, platform, ValidationError]
for win_abspath, platform in product(
["windows", "universal"], ["\\", "\\\\", "\\ ", "C:\\", "c:\\", "\\xyz", "\\xyz "]
)
],
)
def test_win_abs_path(self, platform, value, expected):
if expected is None:
validate_filename(value, platform=platform)
else:
with pytest.raises(expected) as e:
validate_filename(value, platform=platform)
> assert e.value.reason == ErrorReason.FOUND_ABS_PATH
E AssertionError: assert <ErrorReason.INVALID_CHARACTER: ('PV1100', 'INVALID_CHARACTER', 'invalid characters found')> == <ErrorReason.FOUND_ABS_PATH: ('PV1200', 'FOUND_ABS_PATH', 'found an absolute path where must be a relative path')>
E + where <ErrorReason.INVALID_CHARACTER: ('PV1100', 'INVALID_CHARACTER', 'invalid characters found')> = [PV1100] invalid characters found: invalids=('\\'), value='\\xyz', platform=Windows.reason
E + where [PV1100] invalid characters found: invalids=('\\'), value='\\xyz', platform=Windows = <ExceptionInfo [PV1100] invalid characters found: invalids=('\\'), value='\\xyz', platform=Windows tblen=4>.value
E + and <ErrorReason.FOUND_ABS_PATH: ('PV1200', 'FOUND_ABS_PATH', 'found an absolute path where must be a relative path')> = ErrorReason.FOUND_ABS_PATH
test/test_filename.py:416: AssertionError
___ Test_validate_filename.test_win_abs_path[windows-\\xyz -ValidationError] ___
self = <test.test_filename.Test_validate_filename object at 0x7f1ce91261b0>
platform = 'windows', value = '\\xyz '
expected = <class 'pathvalidate.error.ValidationError'>
@pytest.mark.parametrize(
["platform", "value", "expected"],
[
[win_abspath, platform, None]
for win_abspath, platform in product(
["linux", "macos", "posix"],
["\\", "\\\\", "\\ ", "C:\\", "c:\\", "\\xyz", "\\xyz "],
)
]
+ [
[win_abspath, platform, ValidationError]
for win_abspath, platform in product(
["windows", "universal"], ["\\", "\\\\", "\\ ", "C:\\", "c:\\", "\\xyz", "\\xyz "]
)
],
)
def test_win_abs_path(self, platform, value, expected):
if expected is None:
validate_filename(value, platform=platform)
else:
with pytest.raises(expected) as e:
validate_filename(value, platform=platform)
> assert e.value.reason == ErrorReason.FOUND_ABS_PATH
E AssertionError: assert <ErrorReason.INVALID_CHARACTER: ('PV1100', 'INVALID_CHARACTER', 'invalid characters found')> == <ErrorReason.FOUND_ABS_PATH: ('PV1200', 'FOUND_ABS_PATH', 'found an absolute path where must be a relative path')>
E + where <ErrorReason.INVALID_CHARACTER: ('PV1100', 'INVALID_CHARACTER', 'invalid characters found')> = [PV1100] invalid characters found: invalids=('\\'), value='\\xyz ', platform=Windows.reason
E + where [PV1100] invalid characters found: invalids=('\\'), value='\\xyz ', platform=Windows = <ExceptionInfo [PV1100] invalid characters found: invalids=('\\'), value='\\xyz ', platform=Windows tblen=4>.value
E + and <ErrorReason.FOUND_ABS_PATH: ('PV1200', 'FOUND_ABS_PATH', 'found an absolute path where must be a relative path')> = ErrorReason.FOUND_ABS_PATH
test/test_filename.py:416: AssertionError
____ Test_validate_filename.test_win_abs_path[universal-\\-ValidationError] ____
self = <test.test_filename.Test_validate_filename object at 0x7f1ce9126240>
platform = 'universal', value = '\\'
expected = <class 'pathvalidate.error.ValidationError'>
@pytest.mark.parametrize(
["platform", "value", "expected"],
[
[win_abspath, platform, None]
for win_abspath, platform in product(
["linux", "macos", "posix"],
["\\", "\\\\", "\\ ", "C:\\", "c:\\", "\\xyz", "\\xyz "],
)
]
+ [
[win_abspath, platform, ValidationError]
for win_abspath, platform in product(
["windows", "universal"], ["\\", "\\\\", "\\ ", "C:\\", "c:\\", "\\xyz", "\\xyz "]
)
],
)
def test_win_abs_path(self, platform, value, expected):
if expected is None:
validate_filename(value, platform=platform)
else:
with pytest.raises(expected) as e:
validate_filename(value, platform=platform)
> assert e.value.reason == ErrorReason.FOUND_ABS_PATH
E AssertionError: assert <ErrorReason.INVALID_CHARACTER: ('PV1100', 'INVALID_CHARACTER', 'invalid characters found')> == <ErrorReason.FOUND_ABS_PATH: ('PV1200', 'FOUND_ABS_PATH', 'found an absolute path where must be a relative path')>
E + where <ErrorReason.INVALID_CHARACTER: ('PV1100', 'INVALID_CHARACTER', 'invalid characters found')> = [PV1100] invalid characters found: invalids=('\\'), value='\\', platform=Windows.reason
E + where [PV1100] invalid characters found: invalids=('\\'), value='\\', platform=Windows = <ExceptionInfo [PV1100] invalid characters found: invalids=('\\'), value='\\', platform=Windows tblen=4>.value
E + and <ErrorReason.FOUND_ABS_PATH: ('PV1200', 'FOUND_ABS_PATH', 'found an absolute path where must be a relative path')> = ErrorReason.FOUND_ABS_PATH
test/test_filename.py:416: AssertionError
___ Test_validate_filename.test_win_abs_path[universal-\\ -ValidationError] ____
self = <test.test_filename.Test_validate_filename object at 0x7f1ce9126360>
platform = 'universal', value = '\\ '
expected = <class 'pathvalidate.error.ValidationError'>
@pytest.mark.parametrize(
["platform", "value", "expected"],
[
[win_abspath, platform, None]
for win_abspath, platform in product(
["linux", "macos", "posix"],
["\\", "\\\\", "\\ ", "C:\\", "c:\\", "\\xyz", "\\xyz "],
)
]
+ [
[win_abspath, platform, ValidationError]
for win_abspath, platform in product(
["windows", "universal"], ["\\", "\\\\", "\\ ", "C:\\", "c:\\", "\\xyz", "\\xyz "]
)
],
)
def test_win_abs_path(self, platform, value, expected):
if expected is None:
validate_filename(value, platform=platform)
else:
with pytest.raises(expected) as e:
validate_filename(value, platform=platform)
> assert e.value.reason == ErrorReason.FOUND_ABS_PATH
E AssertionError: assert <ErrorReason.INVALID_CHARACTER: ('PV1100', 'INVALID_CHARACTER', 'invalid characters found')> == <ErrorReason.FOUND_ABS_PATH: ('PV1200', 'FOUND_ABS_PATH', 'found an absolute path where must be a relative path')>
E + where <ErrorReason.INVALID_CHARACTER: ('PV1100', 'INVALID_CHARACTER', 'invalid characters found')> = [PV1100] invalid characters found: invalids=('\\'), value='\\ ', platform=Windows.reason
E + where [PV1100] invalid characters found: invalids=('\\'), value='\\ ', platform=Windows = <ExceptionInfo [PV1100] invalid characters found: invalids=('\\'), value='\\ ', platform=Windows tblen=4>.value
E + and <ErrorReason.FOUND_ABS_PATH: ('PV1200', 'FOUND_ABS_PATH', 'found an absolute path where must be a relative path')> = ErrorReason.FOUND_ABS_PATH
test/test_filename.py:416: AssertionError
__ Test_validate_filename.test_win_abs_path[universal-\\xyz-ValidationError] ___
self = <test.test_filename.Test_validate_filename object at 0x7f1ce9126510>
platform = 'universal', value = '\\xyz'
expected = <class 'pathvalidate.error.ValidationError'>
@pytest.mark.parametrize(
["platform", "value", "expected"],
[
[win_abspath, platform, None]
for win_abspath, platform in product(
["linux", "macos", "posix"],
["\\", "\\\\", "\\ ", "C:\\", "c:\\", "\\xyz", "\\xyz "],
)
]
+ [
[win_abspath, platform, ValidationError]
for win_abspath, platform in product(
["windows", "universal"], ["\\", "\\\\", "\\ ", "C:\\", "c:\\", "\\xyz", "\\xyz "]
)
],
)
def test_win_abs_path(self, platform, value, expected):
if expected is None:
validate_filename(value, platform=platform)
else:
with pytest.raises(expected) as e:
validate_filename(value, platform=platform)
> assert e.value.reason == ErrorReason.FOUND_ABS_PATH
E AssertionError: assert <ErrorReason.INVALID_CHARACTER: ('PV1100', 'INVALID_CHARACTER', 'invalid characters found')> == <ErrorReason.FOUND_ABS_PATH: ('PV1200', 'FOUND_ABS_PATH', 'found an absolute path where must be a relative path')>
E + where <ErrorReason.INVALID_CHARACTER: ('PV1100', 'INVALID_CHARACTER', 'invalid characters found')> = [PV1100] invalid characters found: invalids=('\\'), value='\\xyz', platform=Windows.reason
E + where [PV1100] invalid characters found: invalids=('\\'), value='\\xyz', platform=Windows = <ExceptionInfo [PV1100] invalid characters found: invalids=('\\'), value='\\xyz', platform=Windows tblen=4>.value
E + and <ErrorReason.FOUND_ABS_PATH: ('PV1200', 'FOUND_ABS_PATH', 'found an absolute path where must be a relative path')> = ErrorReason.FOUND_ABS_PATH
test/test_filename.py:416: AssertionError
__ Test_validate_filename.test_win_abs_path[universal-\\xyz -ValidationError] __
self = <test.test_filename.Test_validate_filename object at 0x7f1ce91265a0>
platform = 'universal', value = '\\xyz '
expected = <class 'pathvalidate.error.ValidationError'>
@pytest.mark.parametrize(
["platform", "value", "expected"],
[
[win_abspath, platform, None]
for win_abspath, platform in product(
["linux", "macos", "posix"],
["\\", "\\\\", "\\ ", "C:\\", "c:\\", "\\xyz", "\\xyz "],
)
]
+ [
[win_abspath, platform, ValidationError]
for win_abspath, platform in product(
["windows", "universal"], ["\\", "\\\\", "\\ ", "C:\\", "c:\\", "\\xyz", "\\xyz "]
)
],
)
def test_win_abs_path(self, platform, value, expected):
if expected is None:
validate_filename(value, platform=platform)
else:
with pytest.raises(expected) as e:
validate_filename(value, platform=platform)
> assert e.value.reason == ErrorReason.FOUND_ABS_PATH
E AssertionError: assert <ErrorReason.INVALID_CHARACTER: ('PV1100', 'INVALID_CHARACTER', 'invalid characters found')> == <ErrorReason.FOUND_ABS_PATH: ('PV1200', 'FOUND_ABS_PATH', 'found an absolute path where must be a relative path')>
E + where <ErrorReason.INVALID_CHARACTER: ('PV1100', 'INVALID_CHARACTER', 'invalid characters found')> = [PV1100] invalid characters found: invalids=('\\'), value='\\xyz ', platform=Windows.reason
E + where [PV1100] invalid characters found: invalids=('\\'), value='\\xyz ', platform=Windows = <ExceptionInfo [PV1100] invalid characters found: invalids=('\\'), value='\\xyz ', platform=Windows tblen=4>.value
E + and <ErrorReason.FOUND_ABS_PATH: ('PV1200', 'FOUND_ABS_PATH', 'found an absolute path where must be a relative path')> = ErrorReason.FOUND_ABS_PATH
test/test_filename.py:416: AssertionError
________ Test_validate_filepath.test_abs_path[windows-/a/b/c.txt-None] _________
self = <test.test_filepath.Test_validate_filepath object at 0x7f1ce8ed6f90>
test_platform = 'windows', value = '/a/b/c.txt', expected = None
@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", None],
["windows", "C:\\a\\b\\c.txt", None],
["universal", "/a/b/c.txt", ValidationError],
["universal", "C:\\a\\b\\c.txt", ValidationError],
],
)
def test_abs_path(self, test_platform, value, expected):
if expected is None:
> validate_filepath(value, platform=test_platform)
test/test_filepath.py:292:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
pathvalidate/_filepath.py:371: in validate_filepath
).validate(file_path)
pathvalidate/_filepath.py:195: in validate
self.validate_abspath(value)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <pathvalidate._filepath.FilePathValidator object at 0x7f1ce8665310>
value = '/a/b/c.txt'
def validate_abspath(self, value: PathType) -> None:
is_posix_abs = posixpath.isabs(value)
is_nt_abs = ntpath.isabs(value)
err_object = ValidationError(
description=(
"an invalid absolute file path ({}) for the platform ({}).".format(
value, self.platform.value
)
+ " to avoid the error, specify an appropriate platform corresponding to"
+ " the path format or 'auto'."
),
platform=self.platform,
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]):
ValidationError(
description=(
("POSIX style" if is_posix_abs else "NT style")
+ " absolute file path found. expected a platform-independent file path."
),
platform=self.platform,
reason=ErrorReason.MALFORMED_ABS_PATH,
)
if self._is_windows(include_universal=True) and is_posix_abs:
> raise err_object
E pathvalidate.error.ValidationError: [PV1201] found a malformed absolute path: platform=Windows, description=an invalid absolute file path (/a/b/c.txt) for the platform (Windows). to avoid the error, specify an appropriate platform corresponding to the path format or 'auto'.
pathvalidate/_filepath.py:269: ValidationError
=============================== warnings summary ===============================
../../../../usr/lib/python3.13/site-packages/_pytest/config/__init__.py:1373
/usr/lib/python3.13/site-packages/_pytest/config/__init__.py:1373: PytestConfigWarning: Unknown config option: discord_verbose
self._warn_or_fail_if_strict(f"Unknown config option: {key}\n")
../../../../usr/lib/python3.13/site-packages/_pytest/config/__init__.py:1373
/usr/lib/python3.13/site-packages/_pytest/config/__init__.py:1373: PytestConfigWarning: Unknown config option: md_report
self._warn_or_fail_if_strict(f"Unknown config option: {key}\n")
../../../../usr/lib/python3.13/site-packages/_pytest/config/__init__.py:1373
/usr/lib/python3.13/site-packages/_pytest/config/__init__.py:1373: PytestConfigWarning: Unknown config option: md_report_color
self._warn_or_fail_if_strict(f"Unknown config option: {key}\n")
../../../../usr/lib/python3.13/site-packages/_pytest/config/__init__.py:1373
/usr/lib/python3.13/site-packages/_pytest/config/__init__.py:1373: PytestConfigWarning: Unknown config option: md_report_verbose
self._warn_or_fail_if_strict(f"Unknown config option: {key}\n")
test/test_filename.py::Test_sanitize_filename::test_normal_check_reserved[CON-True-CON_]
test/test_filename.py::Test_sanitize_filename::test_normal_check_reserved[CON-True-CON_]
test/test_filename.py::Test_sanitize_filename::test_normal_check_reserved[CON-False-CON]
test/test_filename.py::Test_sanitize_filename::test_normal_check_reserved[CON-False-CON]
/builddir/build/BUILD/pathvalidate-3.2.0/pathvalidate/_filename.py:450: DeprecationWarning: 'check_reserved' is deprecated. Use 'reserved_name_handler' instead.
warnings.warn(
test/test_filepath.py::Test_sanitize_filepath::test_normal_check_reserved[CON-True-CON_]
test/test_filepath.py::Test_sanitize_filepath::test_normal_check_reserved[CON-False-CON]
/builddir/build/BUILD/pathvalidate-3.2.0/pathvalidate/_filepath.py:499: DeprecationWarning: 'check_reserved' is deprecated. Use 'reserved_name_handler' instead.
warnings.warn(
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
FAILED test/test_filename.py::Test_validate_filename::test_win_abs_path[windows-\\-ValidationError]
FAILED test/test_filename.py::Test_validate_filename::test_win_abs_path[windows-\\ -ValidationError]
FAILED test/test_filename.py::Test_validate_filename::test_win_abs_path[windows-\\xyz-ValidationError]
FAILED test/test_filename.py::Test_validate_filename::test_win_abs_path[windows-\\xyz -ValidationError]
FAILED test/test_filename.py::Test_validate_filename::test_win_abs_path[universal-\\-ValidationError]
FAILED test/test_filename.py::Test_validate_filename::test_win_abs_path[universal-\\ -ValidationError]
FAILED test/test_filename.py::Test_validate_filename::test_win_abs_path[universal-\\xyz-ValidationError]
FAILED test/test_filename.py::Test_validate_filename::test_win_abs_path[universal-\\xyz -ValidationError]
FAILED test/test_filepath.py::Test_validate_filepath::test_abs_path[windows-/a/b/c.txt-None]
=========== 9 failed, 3700 passed, 18 skipped, 10 warnings in 5.57s ============
On macOS 12.6.6. Basically, it's marking anything with a leading '/' as invalid.
$ ipython
Python 3.11.3 (main, Apr 7 2023, 19:29:16) [Clang 14.0.0 (clang-1400.0.29.202)]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.13.2 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import pathvalidate as pv
In [2]: pv.is_valid_filepath('/Users/ken/duptemp/foo')
Out[2]: False
In [3]: pv.is_valid_filepath('~/duptemp/foo')
Out[3]: True
In [4]: pv.is_valid_filepath('bar/zot')
Out[4]: True
In [5]: pv.is_valid_filepath('/bar/zot')
Out[5]: False
For now, sanitizing functions will trim the trailing string when the byte length exceeds the max_len
.
This behavior may not be preferable in some cases.
Make it possible to choose the behavior of sanitizing when a byte length of the value exceeds max_len
and change the default behavior.
Choices of behavior:
KEEP
: do nothingTRIM
: trim the trailing string (current default)TRIM_NAME
: trim the trailing string except for the file extensionERROR
: raise an exception (new default)Using Python 3.6.9 with pathvalidate 2.1.0:
import argparse
from pathvalidate.argparse import validate_filename_arg, validate_filepath_arg
parser = argparse.ArgumentParser()
parser.add_argument('--s3-bucket', type=str, help='check authentication repo for bucket names')
parser.add_argument('--input-path', type=validate_filepath_arg)
parser.add_argument('--output-path', type=validate_filepath_arg)
args = parser.parse_args(['download', '--s3-bucket', 'default', '--input-path', '/path/to/somewhere.txt', '--output-path', '/path/to/somewhere.txt'])
python3 example_bug.py
usage: example_bug.py [-h] [--s3-bucket S3_BUCKET] [--input-path INPUT_PATH]
[--output-path OUTPUT_PATH]
example_bug.py: error: argument --input-path: reason=MALFORMED_ABS_PATH, target-platform=universal, description=an invalid absolute file path (/path/to/somewhere.txt) for the platform (universal). specify an appropriate platform or 'auto'.
The error is raised in:
def validate_abspath(self, value: PathType) -> None:
...
if self._is_universal() and any([is_posix_abs, is_nt_abs]):
raise err_object
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.