Skip to content

Commit

Permalink
lib.path: Created join, join_string, join_bytes & isabs. Test
Browse files Browse the repository at this point in the history
  • Loading branch information
YoSTEALTH committed Jul 28, 2024
1 parent 02d4c64 commit 3ea116e
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/shakti/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from dynamic_import import importer


__version__ = '2024.7.27'
__version__ = '2024.7.28'


importer() # helps this project manage all import needs.
7 changes: 7 additions & 0 deletions src/shakti/lib/path.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#

cpdef str join_string(str path, str other)
cpdef bytes join_bytes(bytes path, bytes other)
cpdef bint isabs(object path, bint error=?) except -1
cdef bint isabs_string(str path) noexcept
cdef bint isabs_bytes(bytes path) noexcept
128 changes: 128 additions & 0 deletions src/shakti/lib/path.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#

def join(object path not None, *other):
''' Join Multiple Paths
Type
path: str | bytes
*other: tuple[str | bytes]
return: str | bytes
Example
>>> join('/one', 'two', 'three')
'/one/two/three'
>>> join(b'/one', b'two', b'three')
b'/one/two/three'
>>> join('/one', 'two', '/three', 'four')
'/three/four'
'''
# note: benchmark tested.
cdef unsigned int i, length = len(other)

if not length:
return path

cdef bint byte = type(path) is bytes

for i in range(length):
if byte:
path = join_bytes(path, other[i])
else:
path = join_string(path, other[i])
return path


cpdef inline str join_string(str path, str other):
''' Join Two String Paths
Example
>>> join_string('/one', 'two')
'/one/two'
>>> join_string('/one', '/two')
'/two'
'''
cdef unsigned int length = len(other)

if not length:
return path

if other[0] is '/':
return other

if other[length-1] is '/':
return path + other

return path + '/' + other


cpdef inline bytes join_bytes(bytes path, bytes other):
''' Join Two Bytes Paths
Example
>>> join_bytes(b'/one', b'two')
b'/one/two'
>>> join_bytes(b'/one', b'/two')
b'/two'
'''
cdef unsigned int length = len(other)

if not length:
return path

if other[0] is 47: # b'/'
return other

if other[length-1] is 47:
return path + other

return path + b'/' + other


cpdef inline bint isabs(object path, bint error=True) except -1:
''' Absolute path
Type
path: str | bytes
return: bool
Example
>>> isabs('/dev/shm')
>>> isabs(b'/dev/shm')
True
>>> isabs('dev/shm')
>>> isabs(b'dev/shm')
False
'''
cdef unicode msg
if not path:
if error:
msg = '`isabs()` - received empty `path`'
raise ValueError(msg)
return False

cdef type t = type(path)

if t is str:
return isabs_string(path)
elif t is bytes:
return isabs_bytes(path)
elif error:
msg = '`isabs()` - takes type `str` or `bytes`'
raise TypeError(msg)
else:
return False


cdef inline bint isabs_string(str path) noexcept:
# note: assumes `path` is always true since this is cdef
return path[0] is '/'


cdef inline bint isabs_bytes(bytes path) noexcept:
# note: assumes `path` is always true since this is cdef
return path[0] is 47
39 changes: 39 additions & 0 deletions test/lib/path_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from pytest import raises
from shakti import isabs, join


def test_isabs():
# copied from cpython `Lib/test/test_posixpath.py`
with raises(ValueError):
assert isabs(None) is False
with raises(ValueError):
assert isabs('') is False
assert isabs('/') is True
assert isabs('/foo') is True
assert isabs('/foo/bar') is True
assert isabs('foo/bar') is False

with raises(ValueError):
assert isabs(b'') is False
assert isabs(b'/') is True
assert isabs(b'/foo') is True
assert isabs(b'/foo/bar') is True
assert isabs(b'foo/bar') is False

with raises(TypeError):
assert isabs(['bad type']) is False


def test_join():
assert join('/foo', '', '') == '/foo'
assert join(b'/foo', b'', b'') == b'/foo'

# copied from cpython `Lib/test/test_posixpath.py`
assert join('/foo', 'bar', '/bar', 'baz') == '/bar/baz'
assert join('/foo', 'bar', 'baz') == '/foo/bar/baz'
assert join('/foo/', 'bar/', 'baz/') == '/foo/bar/baz/'

assert join(b'/foo', b'bar', b'/bar', b'baz') == b'/bar/baz'
assert join(b'/foo', b'bar', b'baz') == b'/foo/bar/baz'
assert join(b'/foo/', b'bar/', b'baz/') == b'/foo/bar/baz/'

0 comments on commit 3ea116e

Please sign in to comment.