Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
pyfs
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
pyfs
Commits
0bd14855
Commit
0bd14855
authored
Dec 20, 2010
by
willmcgugan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fs.path optimizations since these functions are called so frequently
parent
53e8bd02
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
80 additions
and
40 deletions
+80
-40
fs/base.py
+0
-0
fs/memoryfs.py
+22
-13
fs/path.py
+27
-27
fs/tests/test_path.py
+31
-0
No files found.
fs/base.py
View file @
0bd14855
fs/memoryfs.py
View file @
0bd14855
...
@@ -32,13 +32,13 @@ class MemoryFile(object):
...
@@ -32,13 +32,13 @@ class MemoryFile(object):
def
seek_and_lock
(
f
):
def
seek_and_lock
(
f
):
def
deco
(
self
,
*
args
,
**
kwargs
):
def
deco
(
self
,
*
args
,
**
kwargs
):
try
:
try
:
self
.
lock
.
acquire
()
self
.
_
lock
.
acquire
()
self
.
mem_file
.
seek
(
self
.
pos
)
self
.
mem_file
.
seek
(
self
.
pos
)
ret
=
f
(
self
,
*
args
,
**
kwargs
)
ret
=
f
(
self
,
*
args
,
**
kwargs
)
self
.
pos
=
self
.
mem_file
.
tell
()
self
.
pos
=
self
.
mem_file
.
tell
()
return
ret
return
ret
finally
:
finally
:
self
.
lock
.
release
()
self
.
_
lock
.
release
()
return
deco
return
deco
def
__init__
(
self
,
path
,
memory_fs
,
mem_file
,
mode
,
lock
):
def
__init__
(
self
,
path
,
memory_fs
,
mem_file
,
mode
,
lock
):
...
@@ -47,7 +47,7 @@ class MemoryFile(object):
...
@@ -47,7 +47,7 @@ class MemoryFile(object):
self
.
memory_fs
=
memory_fs
self
.
memory_fs
=
memory_fs
self
.
mem_file
=
mem_file
self
.
mem_file
=
mem_file
self
.
mode
=
mode
self
.
mode
=
mode
self
.
lock
=
lock
self
.
_
lock
=
lock
self
.
pos
=
0
self
.
pos
=
0
...
@@ -59,7 +59,7 @@ class MemoryFile(object):
...
@@ -59,7 +59,7 @@ class MemoryFile(object):
finally
:
finally
:
lock
.
release
()
lock
.
release
()
if
_check_mode
(
mode
,
'w'
):
el
if
_check_mode
(
mode
,
'w'
):
lock
.
acquire
()
lock
.
acquire
()
try
:
try
:
self
.
mem_file
.
seek
(
0
)
self
.
mem_file
.
seek
(
0
)
...
@@ -96,12 +96,17 @@ class MemoryFile(object):
...
@@ -96,12 +96,17 @@ class MemoryFile(object):
def
readline
(
self
,
*
args
,
**
kwargs
):
def
readline
(
self
,
*
args
,
**
kwargs
):
return
self
.
mem_file
.
readline
(
*
args
,
**
kwargs
)
return
self
.
mem_file
.
readline
(
*
args
,
**
kwargs
)
#@seek_and_lock
def
close
(
self
):
def
close
(
self
):
if
not
self
.
closed
and
self
.
mem_file
is
not
None
:
do_close
=
False
self
.
memory_fs
.
_on_close_memory_file
(
self
,
self
.
path
)
self
.
_lock
.
acquire
()
try
:
do_close
=
not
self
.
closed
and
self
.
mem_file
is
not
None
if
do_close
:
self
.
closed
=
True
self
.
closed
=
True
finally
:
self
.
_lock
.
release
()
if
do_close
:
self
.
memory_fs
.
_on_close_memory_file
(
self
,
self
.
path
)
@seek_and_lock
@seek_and_lock
def
read
(
self
,
size
=
None
):
def
read
(
self
,
size
=
None
):
...
@@ -124,13 +129,13 @@ class MemoryFile(object):
...
@@ -124,13 +129,13 @@ class MemoryFile(object):
#@seek_and_lock
#@seek_and_lock
def
write
(
self
,
data
):
def
write
(
self
,
data
):
self
.
memory_fs
.
_on_modify_memory_file
(
self
.
path
)
self
.
memory_fs
.
_on_modify_memory_file
(
self
.
path
)
self
.
lock
.
acquire
()
self
.
_
lock
.
acquire
()
try
:
try
:
self
.
mem_file
.
seek
(
self
.
pos
)
self
.
mem_file
.
seek
(
self
.
pos
)
self
.
mem_file
.
write
(
data
)
self
.
mem_file
.
write
(
data
)
self
.
pos
=
self
.
mem_file
.
tell
()
self
.
pos
=
self
.
mem_file
.
tell
()
finally
:
finally
:
self
.
lock
.
release
()
self
.
_
lock
.
release
()
@seek_and_lock
@seek_and_lock
def
writelines
(
self
,
*
args
,
**
kwargs
):
def
writelines
(
self
,
*
args
,
**
kwargs
):
...
@@ -385,6 +390,7 @@ class MemoryFS(FS):
...
@@ -385,6 +390,7 @@ class MemoryFS(FS):
@synchronize
@synchronize
def
open
(
self
,
path
,
mode
=
"r"
,
**
kwargs
):
def
open
(
self
,
path
,
mode
=
"r"
,
**
kwargs
):
path
=
normpath
(
path
)
filepath
,
filename
=
pathsplit
(
path
)
filepath
,
filename
=
pathsplit
(
path
)
parent_dir_entry
=
self
.
_get_dir_entry
(
filepath
)
parent_dir_entry
=
self
.
_get_dir_entry
(
filepath
)
...
@@ -432,13 +438,12 @@ class MemoryFS(FS):
...
@@ -432,13 +438,12 @@ class MemoryFS(FS):
raise
ResourceInvalidError
(
path
,
msg
=
"That's a directory, not a file:
%(path)
s"
)
raise
ResourceInvalidError
(
path
,
msg
=
"That's a directory, not a file:
%(path)
s"
)
pathname
,
dirname
=
pathsplit
(
path
)
pathname
,
dirname
=
pathsplit
(
path
)
parent_dir
=
self
.
_get_dir_entry
(
pathname
)
parent_dir
=
self
.
_get_dir_entry
(
pathname
)
del
parent_dir
.
contents
[
dirname
]
del
parent_dir
.
contents
[
dirname
]
@synchronize
@synchronize
def
removedir
(
self
,
path
,
recursive
=
False
,
force
=
False
):
def
removedir
(
self
,
path
,
recursive
=
False
,
force
=
False
):
path
=
normpath
(
path
)
dir_entry
=
self
.
_get_dir_entry
(
path
)
dir_entry
=
self
.
_get_dir_entry
(
path
)
if
dir_entry
is
None
:
if
dir_entry
is
None
:
...
@@ -462,7 +467,9 @@ class MemoryFS(FS):
...
@@ -462,7 +467,9 @@ class MemoryFS(FS):
@synchronize
@synchronize
def
rename
(
self
,
src
,
dst
):
def
rename
(
self
,
src
,
dst
):
src_dir
,
src_name
=
pathsplit
(
src
)
src
=
normpath
(
src
)
dst
=
normpath
(
dst
)
src_dir
,
src_name
=
pathsplit
(
src
)
src_entry
=
self
.
_get_dir_entry
(
src
)
src_entry
=
self
.
_get_dir_entry
(
src
)
if
src_entry
is
None
:
if
src_entry
is
None
:
raise
ResourceNotFoundError
(
src
)
raise
ResourceNotFoundError
(
src
)
...
@@ -504,12 +511,14 @@ class MemoryFS(FS):
...
@@ -504,12 +511,14 @@ class MemoryFS(FS):
@synchronize
@synchronize
def
_on_close_memory_file
(
self
,
open_file
,
path
):
def
_on_close_memory_file
(
self
,
open_file
,
path
):
dir_entry
=
self
.
_get_dir_entry
(
path
)
dir_entry
=
self
.
_get_dir_entry
(
path
)
if
dir_entry
is
not
None
:
dir_entry
.
open_files
.
remove
(
open_file
)
dir_entry
.
open_files
.
remove
(
open_file
)
@synchronize
@synchronize
def
_on_modify_memory_file
(
self
,
path
):
def
_on_modify_memory_file
(
self
,
path
):
dir_entry
=
self
.
_get_dir_entry
(
path
)
dir_entry
=
self
.
_get_dir_entry
(
path
)
if
dir_entry
is
not
None
:
dir_entry
.
modified_time
=
datetime
.
datetime
.
now
()
dir_entry
.
modified_time
=
datetime
.
datetime
.
now
()
@synchronize
@synchronize
...
...
fs/path.py
View file @
0bd14855
...
@@ -37,25 +37,21 @@ def normpath(path):
...
@@ -37,25 +37,21 @@ def normpath(path):
if
not
path
:
if
not
path
:
return
path
return
path
components
=
[]
components
=
[]
for
comp
in
path
.
replace
(
'
\\
'
,
'/'
)
.
split
(
"/"
):
append
=
components
.
append
if
not
comp
or
comp
==
"."
:
for
comp
in
[
c
for
c
in
path
.
replace
(
'
\\
'
,
'/'
)
.
split
(
"/"
)
if
c
not
in
(
''
,
'.'
)]:
pass
if
comp
==
".."
:
elif
comp
==
".."
:
try
:
try
:
components
.
pop
()
components
.
pop
()
except
IndexError
:
except
IndexError
:
err
=
"too many backrefs in path '
%
s'"
%
(
path
,)
err
=
"too many backrefs in path '
%
s'"
%
(
path
,)
raise
ValueError
(
err
)
raise
ValueError
(
err
)
else
:
else
:
components
.
append
(
comp
)
append
(
comp
)
if
path
[
0
]
in
"
\\
/"
:
if
path
[
0
]
in
'
\\
/'
:
if
not
components
:
if
not
components
:
components
=
[
""
]
append
(
""
)
components
.
insert
(
0
,
""
)
components
.
insert
(
0
,
""
)
if
isinstance
(
path
,
unicode
):
return
"/"
.
join
(
components
)
return
u"/"
.
join
(
components
)
else
:
return
'/'
.
join
(
components
)
def
iteratepath
(
path
,
numsplits
=
None
):
def
iteratepath
(
path
,
numsplits
=
None
):
...
@@ -69,9 +65,9 @@ def iteratepath(path, numsplits=None):
...
@@ -69,9 +65,9 @@ def iteratepath(path, numsplits=None):
if
not
path
:
if
not
path
:
return
[]
return
[]
if
numsplits
==
None
:
if
numsplits
==
None
:
return
map
(
None
,
path
.
split
(
'/'
)
)
return
path
.
split
(
'/'
)
else
:
else
:
return
map
(
None
,
path
.
split
(
'/'
,
numsplits
)
)
return
path
.
split
(
'/'
,
numsplits
)
def
recursepath
(
path
,
reverse
=
False
):
def
recursepath
(
path
,
reverse
=
False
):
"""Returns intermediate paths from the root to the given path
"""Returns intermediate paths from the root to the given path
...
@@ -84,11 +80,13 @@ def recursepath(path, reverse=False):
...
@@ -84,11 +80,13 @@ def recursepath(path, reverse=False):
"""
"""
if
reverse
:
if
reverse
:
paths
=
[]
paths
=
[]
append
=
paths
.
append
path
=
abspath
(
normpath
(
path
))
.
rstrip
(
"/"
)
path
=
abspath
(
normpath
(
path
))
.
rstrip
(
"/"
)
while
path
:
while
path
:
paths
.
append
(
path
)
append
(
path
)
path
=
dirname
(
path
)
.
rstrip
(
"/"
)
path
=
dirname
(
path
)
.
rstrip
(
"/"
)
return
paths
+
[
u"/"
]
paths
.
append
(
u"/"
)
return
paths
else
:
else
:
paths
=
[
u""
]
+
list
(
iteratepath
(
path
))
paths
=
[
u""
]
+
list
(
iteratepath
(
path
))
return
[
u"/"
]
+
[
u'/'
.
join
(
paths
[:
i
+
1
])
for
i
in
xrange
(
1
,
len
(
paths
))]
return
[
u"/"
]
+
[
u'/'
.
join
(
paths
[:
i
+
1
])
for
i
in
xrange
(
1
,
len
(
paths
))]
...
@@ -100,8 +98,6 @@ def abspath(path):
...
@@ -100,8 +98,6 @@ def abspath(path):
adds a leading '/' character if the path doesn't already have one.
adds a leading '/' character if the path doesn't already have one.
"""
"""
if
not
path
:
return
u'/'
if
not
path
.
startswith
(
'/'
):
if
not
path
.
startswith
(
'/'
):
return
u'/'
+
path
return
u'/'
+
path
return
path
return
path
...
@@ -173,10 +169,10 @@ def pathsplit(path):
...
@@ -173,10 +169,10 @@ def pathsplit(path):
('/foo/bar', 'baz')
('/foo/bar', 'baz')
"""
"""
split
=
normpath
(
path
)
.
rsplit
(
'/'
,
1
)
if
'/'
not
in
path
:
if
len
(
split
)
==
1
:
return
(
''
,
path
)
return
(
u''
,
split
[
0
]
)
split
=
path
.
rsplit
(
'/'
,
1
)
return
split
[
0
]
or
'/'
,
split
[
1
]
return
(
split
[
0
]
or
'/'
,
split
[
1
])
# Allow pathsplit() to be used as fs.path.split()
# Allow pathsplit() to be used as fs.path.split()
split
=
pathsplit
split
=
pathsplit
...
@@ -211,14 +207,14 @@ def isdotfile(path):
...
@@ -211,14 +207,14 @@ def isdotfile(path):
>>> isdotfile('.baz')
>>> isdotfile('.baz')
True
True
>>> isdotfile('foo/bar/
.
baz')
>>> isdotfile('foo/bar/baz')
True
True
>>> isdotfile('foo/bar.baz')
>>> isdotfile('foo/bar.baz')
.
False
False
"""
"""
return
pathsplit
(
path
)[
-
1
]
.
startswith
(
'.'
)
return
basename
(
path
)
.
startswith
(
'.'
)
def
dirname
(
path
):
def
dirname
(
path
):
"""Returns the parent directory of a path.
"""Returns the parent directory of a path.
...
@@ -232,7 +228,9 @@ def dirname(path):
...
@@ -232,7 +228,9 @@ def dirname(path):
'foo/bar'
'foo/bar'
"""
"""
return
pathsplit
(
path
)[
0
]
if
'/'
not
in
path
:
return
''
return
path
.
rsplit
(
'/'
,
1
)[
0
]
def
basename
(
path
):
def
basename
(
path
):
...
@@ -247,7 +245,9 @@ def basename(path):
...
@@ -247,7 +245,9 @@ def basename(path):
'baz'
'baz'
"""
"""
return
pathsplit
(
path
)[
1
]
if
'/'
not
in
path
:
return
path
return
path
.
rsplit
(
'/'
,
1
)[
-
1
]
def
issamedir
(
path1
,
path2
):
def
issamedir
(
path1
,
path2
):
...
@@ -262,7 +262,7 @@ def issamedir(path1, path2):
...
@@ -262,7 +262,7 @@ def issamedir(path1, path2):
False
False
"""
"""
return
pathsplit
(
normpath
(
path1
))[
0
]
==
pathsplit
(
normpath
(
path2
))[
0
]
return
dirname
(
normpath
(
path1
))
==
dirname
(
normpath
(
path2
))
def
isbase
(
path1
,
path2
):
def
isbase
(
path1
,
path2
):
p1
=
forcedir
(
abspath
(
path1
))
p1
=
forcedir
(
abspath
(
path1
))
...
...
fs/tests/test_path.py
View file @
0bd14855
...
@@ -103,6 +103,37 @@ class TestPathFunctions(unittest.TestCase):
...
@@ -103,6 +103,37 @@ class TestPathFunctions(unittest.TestCase):
self
.
assertEquals
(
recursepath
(
"hello"
,
reverse
=
True
),[
"/hello"
,
"/"
])
self
.
assertEquals
(
recursepath
(
"hello"
,
reverse
=
True
),[
"/hello"
,
"/"
])
self
.
assertEquals
(
recursepath
(
""
,
reverse
=
True
),[
"/"
])
self
.
assertEquals
(
recursepath
(
""
,
reverse
=
True
),[
"/"
])
def
test_isdotfile
(
self
):
for
path
in
[
'.foo'
,
'.svn'
,
'foo/.svn'
,
'foo/bar/.svn'
,
'/foo/.bar'
]:
self
.
assert_
(
isdotfile
(
path
))
for
path
in
[
'asfoo'
,
'df.svn'
,
'foo/er.svn'
,
'foo/bar/test.txt'
,
'/foo/bar'
]:
self
.
assertFalse
(
isdotfile
(
path
))
def
test_dirname
(
self
):
tests
=
[(
'foo'
,
''
),
(
'foo/bar'
,
'foo'
),
(
'foo/bar/baz'
,
'foo/bar'
),
(
'/'
,
''
)]
for
path
,
test_dirname
in
tests
:
self
.
assertEqual
(
dirname
(
path
),
test_dirname
)
def
test_basename
(
self
):
tests
=
[(
'foo'
,
'foo'
),
(
'foo/bar'
,
'bar'
),
(
'foo/bar/baz'
,
'baz'
),
(
'/'
,
''
)]
for
path
,
test_basename
in
tests
:
self
.
assertEqual
(
basename
(
path
),
test_basename
)
class
Test_PathMap
(
unittest
.
TestCase
):
class
Test_PathMap
(
unittest
.
TestCase
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment