Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'release/scripts/modules/bpy/path.py')
-rw-r--r--release/scripts/modules/bpy/path.py104
1 files changed, 69 insertions, 35 deletions
diff --git a/release/scripts/modules/bpy/path.py b/release/scripts/modules/bpy/path.py
index 874efc2e131..d7c6101115d 100644
--- a/release/scripts/modules/bpy/path.py
+++ b/release/scripts/modules/bpy/path.py
@@ -43,10 +43,11 @@ __all__ = (
import bpy as _bpy
import os as _os
-from _bpy_path import (extensions_audio,
- extensions_movie,
- extensions_image,
- )
+from _bpy_path import (
+ extensions_audio,
+ extensions_movie,
+ extensions_image,
+ )
def _getattr_bytes(var, attr):
@@ -60,7 +61,7 @@ def abspath(path, start=None, library=None):
:arg start: Relative to this path,
when not set the current filename is used.
- :type start: string
+ :type start: string or bytes
:arg library: The library this path is from. This is only included for
convenience, when the library is not None its path replaces *start*.
:type library: :class:`bpy.types.Library`
@@ -89,9 +90,11 @@ def relpath(path, start=None):
"""
Returns the path relative to the current blend file using the "//" prefix.
+ :arg path: An absolute path.
+ :type path: string or bytes
:arg start: Relative to this path,
when not set the current filename is used.
- :type start: string
+ :type start: string or bytes
"""
if isinstance(path, bytes):
if not path.startswith(b"//"):
@@ -111,11 +114,18 @@ def is_subdir(path, directory):
"""
Returns true if *path* in a subdirectory of *directory*.
Both paths must be absolute.
+
+ :arg path: An absolute path.
+ :type path: string or bytes
"""
from os.path import normpath, normcase
path = normpath(normcase(path))
directory = normpath(normcase(directory))
- return path.startswith(directory)
+ if len(path) > len(directory):
+ if path.startswith(directory):
+ sep = ord(_os.sep) if isinstance(directory, bytes) else _os.sep
+ return (path[len(directory)] == sep)
+ return False
def clean_name(name, replace="_"):
@@ -124,26 +134,50 @@ def clean_name(name, replace="_"):
may cause problems under various circumstances,
such as writing to a file.
All characters besides A-Z/a-z, 0-9 are replaced with "_"
- or the replace argument if defined.
+ or the *replace* argument if defined.
"""
- bad_chars = ("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e"
- "\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d"
- "\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c"
- "\x2e\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x40\x5b\x5c\x5d\x5e\x60\x7b"
- "\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a"
- "\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99"
- "\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
- "\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
- "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6"
- "\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5"
- "\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4"
- "\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3"
- "\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe")
-
- for ch in bad_chars:
- name = name.replace(ch, replace)
- return name
+ if replace != "_":
+ if len(replace) != 1 or ord(replace) > 255:
+ raise ValueError("Value must be a single ascii character")
+
+ def maketrans_init():
+ trans_cache = clean_name._trans_cache
+ trans = trans_cache.get(replace)
+ if trans is None:
+ bad_chars = (
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2e, 0x2f, 0x3a,
+ 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x5b, 0x5c,
+ 0x5d, 0x5e, 0x60, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe,
+ )
+ trans = str.maketrans({char: replace for char in bad_chars})
+ trans_cache[replace] = trans
+ return trans
+
+ trans = maketrans_init()
+ return name.translate(trans)
+clean_name._trans_cache = {}
def _clean_utf8(name):
@@ -221,7 +255,8 @@ def resolve_ncase(path):
if _os.path.isdir(dirpath):
try:
files = _os.listdir(dirpath)
- except PermissionError: # We might not have the permission to list dirpath...
+ except PermissionError:
+ # We might not have the permission to list dirpath...
return path, False
else:
return path, False
@@ -248,22 +283,21 @@ def ensure_ext(filepath, ext, case_sensitive=False):
"""
Return the path with the extension added if it is not already set.
- :arg ext: The extension to check for.
+ :arg ext: The extension to check for, can be a compound extension. Should
+ start with a dot, such as '.blend' or '.tar.gz'.
:type ext: string
:arg case_sensitive: Check for matching case when comparing extensions.
:type case_sensitive: bool
"""
- fn_base, fn_ext = _os.path.splitext(filepath)
- if fn_base and fn_ext:
- if ((case_sensitive and ext == fn_ext) or
- (ext.lower() == fn_ext.lower())):
+ if case_sensitive:
+ if filepath.endswith(ext):
return filepath
- else:
- return fn_base + ext
-
else:
- return filepath + ext
+ if filepath[-len(ext):].lower().endswith(ext.lower()):
+ return filepath
+
+ return filepath + ext
def module_names(path, recursive=False):