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
ea0d2e43
Commit
ea0d2e43
authored
Dec 27, 2011
by
willmcgugan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Python3 changes
parent
3b900b1c
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
87 additions
and
66 deletions
+87
-66
ChangeLog
+2
-0
fs/expose/fuse/__init__.py
+26
-14
fs/filelike.py
+4
-4
fs/ftpfs.py
+5
-5
fs/s3fs.py
+2
-0
fs/sftpfs.py
+2
-0
fs/tests/__init__.py
+38
-39
fs/tests/test_zipfs.py
+6
-3
tox.ini
+2
-1
No files found.
ChangeLog
View file @
ea0d2e43
...
@@ -81,3 +81,5 @@
...
@@ -81,3 +81,5 @@
* Added `appdirfs` module to abstract per-user application directories
* Added `appdirfs` module to abstract per-user application directories
0.5:
0.5:
* Ported to Python 3.X
fs/expose/fuse/__init__.py
View file @
ea0d2e43
...
@@ -67,12 +67,14 @@ from fs.path import *
...
@@ -67,12 +67,14 @@ from fs.path import *
from
fs.local_functools
import
wraps
from
fs.local_functools
import
wraps
from
six
import
PY3
from
six
import
PY3
from
six
import
b
try
:
try
:
if
PY3
:
#if PY3:
import
fuse3
as
fuse
# import fuse3 as fuse
else
:
#else:
import
fuse
# import fuse
import
fuse_ctypes
as
fuse
except
NotImplementedError
:
except
NotImplementedError
:
raise
ImportError
(
"FUSE found but not usable"
)
raise
ImportError
(
"FUSE found but not usable"
)
try
:
try
:
...
@@ -530,8 +532,12 @@ class MountProcess(subprocess.Popen):
...
@@ -530,8 +532,12 @@ class MountProcess(subprocess.Popen):
def
__init__
(
self
,
fs
,
path
,
fuse_opts
=
{},
nowait
=
False
,
**
kwds
):
def
__init__
(
self
,
fs
,
path
,
fuse_opts
=
{},
nowait
=
False
,
**
kwds
):
self
.
path
=
path
self
.
path
=
path
if
nowait
or
kwds
.
get
(
"close_fds"
,
False
):
if
nowait
or
kwds
.
get
(
"close_fds"
,
False
):
cmd
=
'import cPickle; '
if
PY3
:
cmd
=
cmd
+
'data = cPickle.loads(
%
s); '
cmd
=
"from pickle import loads;"
else
:
cmd
=
"from cPickle import loads;"
#cmd = 'import cPickle; '
cmd
=
cmd
+
'data = loads(
%
s); '
cmd
=
cmd
+
'from fs.expose.fuse import MountProcess; '
cmd
=
cmd
+
'from fs.expose.fuse import MountProcess; '
cmd
=
cmd
+
'MountProcess._do_mount_nowait(data)'
cmd
=
cmd
+
'MountProcess._do_mount_nowait(data)'
cmd
=
cmd
%
(
repr
(
cPickle
.
dumps
((
fs
,
path
,
fuse_opts
),
-
1
)),)
cmd
=
cmd
%
(
repr
(
cPickle
.
dumps
((
fs
,
path
,
fuse_opts
),
-
1
)),)
...
@@ -539,15 +545,21 @@ class MountProcess(subprocess.Popen):
...
@@ -539,15 +545,21 @@ class MountProcess(subprocess.Popen):
super
(
MountProcess
,
self
)
.
__init__
(
cmd
,
**
kwds
)
super
(
MountProcess
,
self
)
.
__init__
(
cmd
,
**
kwds
)
else
:
else
:
(
r
,
w
)
=
os
.
pipe
()
(
r
,
w
)
=
os
.
pipe
()
cmd
=
'import cPickle; '
if
PY3
:
cmd
=
cmd
+
'data = cPickle.loads(
%
s); '
cmd
=
"from pickle import loads;"
else
:
cmd
=
"from cPickle import loads;"
#cmd = 'import cPickle; '
cmd
=
cmd
+
'data = loads(
%
s); '
cmd
=
cmd
+
'from fs.expose.fuse import MountProcess; '
cmd
=
cmd
+
'from fs.expose.fuse import MountProcess; '
cmd
=
cmd
+
'MountProcess._do_mount_wait(data)'
cmd
=
cmd
+
'MountProcess._do_mount_wait(data)'
cmd
=
cmd
%
(
repr
(
cPickle
.
dumps
((
fs
,
path
,
fuse_opts
,
r
,
w
),
-
1
)),)
cmd
=
cmd
%
(
repr
(
cPickle
.
dumps
((
fs
,
path
,
fuse_opts
,
r
,
w
),
-
1
)),)
cmd
=
[
sys
.
executable
,
"-c"
,
cmd
]
cmd
=
[
sys
.
executable
,
"-c"
,
cmd
]
super
(
MountProcess
,
self
)
.
__init__
(
cmd
,
**
kwds
)
super
(
MountProcess
,
self
)
.
__init__
(
cmd
,
**
kwds
)
os
.
close
(
w
)
os
.
close
(
w
)
if
os
.
read
(
r
,
1
)
!=
"S"
:
byte
=
os
.
read
(
r
,
1
)
if
byte
!=
b
(
"S"
):
self
.
terminate
()
self
.
terminate
()
raise
RuntimeError
(
"FUSE error: "
+
os
.
read
(
r
,
20
)
.
decode
(
NATIVE_ENCODING
))
raise
RuntimeError
(
"FUSE error: "
+
os
.
read
(
r
,
20
)
.
decode
(
NATIVE_ENCODING
))
...
@@ -595,7 +607,7 @@ class MountProcess(subprocess.Popen):
...
@@ -595,7 +607,7 @@ class MountProcess(subprocess.Popen):
successful
=
[]
successful
=
[]
def
ready_callback
():
def
ready_callback
():
successful
.
append
(
True
)
successful
.
append
(
True
)
os
.
write
(
w
,
"S"
)
os
.
write
(
w
,
b
(
"S"
)
)
os
.
close
(
w
)
os
.
close
(
w
)
opts
[
"ready_callback"
]
=
ready_callback
opts
[
"ready_callback"
]
=
ready_callback
def
unmount_callback
():
def
unmount_callback
():
...
@@ -603,12 +615,12 @@ class MountProcess(subprocess.Popen):
...
@@ -603,12 +615,12 @@ class MountProcess(subprocess.Popen):
opts
[
"unmount_callback"
]
=
unmount_callback
opts
[
"unmount_callback"
]
=
unmount_callback
try
:
try
:
mount
(
fs
,
path
,
**
opts
)
mount
(
fs
,
path
,
**
opts
)
except
Exception
,
e
:
except
Exception
,
e
:
os
.
write
(
w
,
"E"
+
str
(
e
))
os
.
write
(
w
,
b
(
"E"
)
+
b
(
e
))
os
.
close
(
w
)
os
.
close
(
w
)
else
:
else
:
if
not
successful
:
if
not
successful
:
os
.
write
(
w
,
"E"
)
os
.
write
(
w
,
b
(
"E"
)
)
os
.
close
(
w
)
os
.
close
(
w
)
...
...
fs/filelike.py
View file @
ea0d2e43
...
@@ -49,7 +49,7 @@ import six
...
@@ -49,7 +49,7 @@ import six
from
six
import
PY3
,
b
from
six
import
PY3
,
b
if
PY3
:
if
PY3
:
_StringIO
=
six
.
Bytes
IO
from
six
import
BytesIO
as
_String
IO
else
:
else
:
try
:
try
:
from
cStringIO
import
StringIO
as
_StringIO
from
cStringIO
import
StringIO
as
_StringIO
...
@@ -669,7 +669,7 @@ class FileWrapper(FileLikeBase):
...
@@ -669,7 +669,7 @@ class FileWrapper(FileLikeBase):
return
self
.
wrapped_file
.
tell
()
return
self
.
wrapped_file
.
tell
()
def
_truncate
(
self
,
size
):
def
_truncate
(
self
,
size
):
return
self
.
wrapped_file
.
truncate
(
size
)
return
self
.
wrapped_file
.
truncate
(
size
)
class
StringIO
(
FileWrapper
):
class
StringIO
(
FileWrapper
):
...
@@ -721,8 +721,8 @@ class SpooledTemporaryFile(FileWrapper):
...
@@ -721,8 +721,8 @@ class SpooledTemporaryFile(FileWrapper):
try
:
try
:
stf_args
=
(
max_size
,
mode
,
bufsize
)
+
args
stf_args
=
(
max_size
,
mode
,
bufsize
)
+
args
wrapped_file
=
_tempfile
.
SpooledTemporaryFile
(
*
stf_args
,
**
kwds
)
wrapped_file
=
_tempfile
.
SpooledTemporaryFile
(
*
stf_args
,
**
kwds
)
#
wrapped_file._file = StringIO()
wrapped_file
.
_file
=
StringIO
()
wrapped_file
.
_file
=
six
.
BytesIO
()
#
wrapped_file._file = six.BytesIO()
self
.
__is_spooled
=
True
self
.
__is_spooled
=
True
except
AttributeError
:
except
AttributeError
:
ntf_args
=
(
mode
,
bufsize
)
+
args
ntf_args
=
(
mode
,
bufsize
)
+
args
...
...
fs/ftpfs.py
View file @
ea0d2e43
...
@@ -30,7 +30,7 @@ from socket import error as socket_error
...
@@ -30,7 +30,7 @@ from socket import error as socket_error
from
fs.local_functools
import
wraps
from
fs.local_functools
import
wraps
import
six
import
six
from
six
import
PY3
from
six
import
PY3
,
b
if
PY3
:
if
PY3
:
from
six
import
BytesIO
as
StringIO
from
six
import
BytesIO
as
StringIO
...
@@ -654,7 +654,7 @@ class _FTPFile(object):
...
@@ -654,7 +654,7 @@ class _FTPFile(object):
@fileftperrors
@fileftperrors
def
read
(
self
,
size
=
None
):
def
read
(
self
,
size
=
None
):
if
self
.
conn
is
None
:
if
self
.
conn
is
None
:
return
''
return
b
(
''
)
chunks
=
[]
chunks
=
[]
if
size
is
None
or
size
<
0
:
if
size
is
None
or
size
<
0
:
...
@@ -682,7 +682,7 @@ class _FTPFile(object):
...
@@ -682,7 +682,7 @@ class _FTPFile(object):
self
.
read_pos
+=
len
(
data
)
self
.
read_pos
+=
len
(
data
)
remaining_bytes
-=
len
(
data
)
remaining_bytes
-=
len
(
data
)
return
''
.
join
(
chunks
)
return
b
(
''
)
.
join
(
chunks
)
@fileftperrors
@fileftperrors
def
write
(
self
,
data
):
def
write
(
self
,
data
):
...
@@ -812,11 +812,11 @@ class _FTPFile(object):
...
@@ -812,11 +812,11 @@ class _FTPFile(object):
This isn't terribly efficient. It would probably be better to do
This isn't terribly efficient. It would probably be better to do
a read followed by splitlines.
a read followed by splitlines.
"""
"""
endings
=
'
\r\n
'
endings
=
b
(
'
\r\n
'
)
chars
=
[]
chars
=
[]
append
=
chars
.
append
append
=
chars
.
append
read
=
self
.
read
read
=
self
.
read
join
=
''
.
join
join
=
b
(
''
)
.
join
while
True
:
while
True
:
char
=
read
(
1
)
char
=
read
(
1
)
if
not
char
:
if
not
char
:
...
...
fs/s3fs.py
View file @
ea0d2e43
...
@@ -2,6 +2,8 @@
...
@@ -2,6 +2,8 @@
fs.s3fs
fs.s3fs
=======
=======
**Currently only avaiable on Python2 due to boto not being available for Python3**
FS subclass accessing files in Amazon S3
FS subclass accessing files in Amazon S3
This module provides the class 'S3FS', which implements the FS filesystem
This module provides the class 'S3FS', which implements the FS filesystem
...
...
fs/sftpfs.py
View file @
ea0d2e43
...
@@ -2,6 +2,8 @@
...
@@ -2,6 +2,8 @@
fs.sftpfs
fs.sftpfs
=========
=========
**Currently only avaiable on Python2 due to paramiko not being available for Python3**
Filesystem accessing an SFTP server (via paramiko)
Filesystem accessing an SFTP server (via paramiko)
"""
"""
...
...
fs/tests/__init__.py
View file @
ea0d2e43
...
@@ -721,19 +721,18 @@ class FSTestCases(object):
...
@@ -721,19 +721,18 @@ class FSTestCases(object):
checkcontents
(
"hello"
,
b
(
"hi"
))
checkcontents
(
"hello"
,
b
(
"hi"
))
self
.
fs
.
setcontents
(
"hello"
,
b
(
"1234567890"
))
self
.
fs
.
setcontents
(
"hello"
,
b
(
"1234567890"
))
checkcontents
(
"hello"
,
b
(
"1234567890"
))
checkcontents
(
"hello"
,
b
(
"1234567890"
))
with
self
.
fs
.
open
(
"hello"
,
"r+"
)
as
f
:
with
self
.
fs
.
open
(
"hello"
,
"r
b
+"
)
as
f
:
f
.
truncate
(
7
)
f
.
truncate
(
7
)
checkcontents
(
"hello"
,
b
(
"1234567"
))
checkcontents
(
"hello"
,
b
(
"1234567"
))
with
self
.
fs
.
open
(
"hello"
,
"r+"
)
as
f
:
with
self
.
fs
.
open
(
"hello"
,
"r
b
+"
)
as
f
:
f
.
seek
(
5
)
f
.
seek
(
5
)
f
.
truncate
()
f
.
truncate
()
checkcontents
(
"hello"
,
b
(
"12345"
))
checkcontents
(
"hello"
,
b
(
"12345"
))
def
test_truncate_to_larger_size
(
self
):
def
test_truncate_to_larger_size
(
self
):
print
repr
(
self
.
fs
)
with
self
.
fs
.
open
(
"hello"
,
"wb"
)
as
f
:
print
self
.
fs
.
__class__
with
self
.
fs
.
open
(
"hello"
,
"wb"
)
as
f
:
f
.
truncate
(
30
)
f
.
truncate
(
30
)
self
.
assertEquals
(
self
.
fs
.
getsize
(
"hello"
),
30
)
self
.
assertEquals
(
self
.
fs
.
getsize
(
"hello"
),
30
)
# Some file systems (FTPFS) don't support both reading and writing
# Some file systems (FTPFS) don't support both reading and writing
...
@@ -792,34 +791,34 @@ class FSTestCases(object):
...
@@ -792,34 +791,34 @@ class FSTestCases(object):
def
test_big_file
(
self
):
def
test_big_file
(
self
):
"""Test handling of a big file (1MB)"""
"""Test handling of a big file (1MB)"""
chunk_size
=
1024
*
256
chunk_size
=
1024
*
256
num_chunks
=
4
num_chunks
=
4
def
chunk_stream
():
def
chunk_stream
():
"""Generate predictable-but-randomy binary content."""
"""Generate predictable-but-randomy binary content."""
r
=
random
.
Random
(
0
)
r
=
random
.
Random
(
0
)
randint
=
r
.
randint
randint
=
r
.
randint
int2byte
=
six
.
int2byte
int2byte
=
six
.
int2byte
for
_i
in
xrange
(
num_chunks
):
for
_i
in
xrange
(
num_chunks
):
c
=
b
(
""
)
.
join
(
int2byte
(
randint
(
0
,
255
))
for
_j
in
xrange
(
chunk_size
//
8
))
c
=
b
(
""
)
.
join
(
int2byte
(
randint
(
0
,
255
))
for
_j
in
xrange
(
chunk_size
//
8
))
yield
c
*
8
yield
c
*
8
f
=
self
.
fs
.
open
(
"bigfile"
,
"wb"
)
f
=
self
.
fs
.
open
(
"bigfile"
,
"wb"
)
try
:
try
:
for
chunk
in
chunk_stream
():
for
chunk
in
chunk_stream
():
f
.
write
(
chunk
)
f
.
write
(
chunk
)
finally
:
finally
:
f
.
close
()
f
.
close
()
chunks
=
chunk_stream
()
chunks
=
chunk_stream
()
f
=
self
.
fs
.
open
(
"bigfile"
,
"rb"
)
f
=
self
.
fs
.
open
(
"bigfile"
,
"rb"
)
try
:
try
:
try
:
try
:
while
True
:
while
True
:
if
chunks
.
next
()
!=
f
.
read
(
chunk_size
):
if
chunks
.
next
()
!=
f
.
read
(
chunk_size
):
assert
False
,
"bigfile was corrupted"
assert
False
,
"bigfile was corrupted"
except
StopIteration
:
except
StopIteration
:
if
f
.
read
()
!=
b
(
""
):
if
f
.
read
()
!=
b
(
""
):
assert
False
,
"bigfile was corrupted"
assert
False
,
"bigfile was corrupted"
finally
:
finally
:
f
.
close
()
f
.
close
()
def
test_settimes
(
self
):
def
test_settimes
(
self
):
def
cmp_datetimes
(
d1
,
d2
):
def
cmp_datetimes
(
d1
,
d2
):
...
@@ -842,7 +841,7 @@ def chunk_stream():
...
@@ -842,7 +841,7 @@ def chunk_stream():
self
.
assertTrue
(
cmp_datetimes
(
d2
,
info
[
'modified_time'
]))
self
.
assertTrue
(
cmp_datetimes
(
d2
,
info
[
'modified_time'
]))
#
Disabled - see below
#
May be disabled - see end of file
class
ThreadingTestCases
(
object
):
class
ThreadingTestCases
(
object
):
"""Testcases for thread-safety of FS implementations."""
"""Testcases for thread-safety of FS implementations."""
...
@@ -911,7 +910,7 @@ class ThreadingTestCases(object):
...
@@ -911,7 +910,7 @@ class ThreadingTestCases(object):
def
test_setcontents_threaded_samefile
(
self
):
def
test_setcontents_threaded_samefile
(
self
):
def
setcontents
(
name
,
contents
):
def
setcontents
(
name
,
contents
):
f
=
self
.
fs
.
open
(
name
,
"w"
)
f
=
self
.
fs
.
open
(
name
,
"w
b
"
)
self
.
_yield
()
self
.
_yield
()
try
:
try
:
f
.
write
(
contents
)
f
.
write
(
contents
)
...
@@ -1057,6 +1056,6 @@ class ThreadingTestCases(object):
...
@@ -1057,6 +1056,6 @@ class ThreadingTestCases(object):
self
.
assertEquals
(
self
.
fs
.
getcontents
(
"thread2.txt"
,
'rb'
),
c
)
self
.
assertEquals
(
self
.
fs
.
getcontents
(
"thread2.txt"
,
'rb'
),
c
)
self
.
_runThreads
(
thread1
,
thread2
)
self
.
_runThreads
(
thread1
,
thread2
)
# Uncomment to temporarily disable threading tests
class
ThreadingTestCases
(
object
):
#
class ThreadingTestCases(object):
_dont_retest
=
()
#
_dont_retest = ()
fs/tests/test_zipfs.py
View file @
ea0d2e43
...
@@ -15,7 +15,7 @@ import fs.tests
...
@@ -15,7 +15,7 @@ import fs.tests
from
fs.path
import
*
from
fs.path
import
*
from
fs
import
zipfs
from
fs
import
zipfs
from
six
import
b
from
six
import
PY3
,
b
class
TestReadZipFS
(
unittest
.
TestCase
):
class
TestReadZipFS
(
unittest
.
TestCase
):
...
@@ -122,9 +122,12 @@ class TestWriteZipFS(unittest.TestCase):
...
@@ -122,9 +122,12 @@ class TestWriteZipFS(unittest.TestCase):
def
test_creation
(
self
):
def
test_creation
(
self
):
zf
=
zipfile
.
ZipFile
(
self
.
temp_filename
,
"r"
)
zf
=
zipfile
.
ZipFile
(
self
.
temp_filename
,
"r"
)
def
check_contents
(
filename
,
contents
):
def
check_contents
(
filename
,
contents
):
zcontents
=
zf
.
read
(
filename
.
encode
(
"CP437"
))
if
PY3
:
zcontents
=
zf
.
read
(
filename
)
else
:
zcontents
=
zf
.
read
(
filename
.
encode
(
"CP437"
))
self
.
assertEqual
(
contents
,
zcontents
)
self
.
assertEqual
(
contents
,
zcontents
)
check_contents
(
"a.txt"
,
b
(
)
"Hello, World!"
)
check_contents
(
"a.txt"
,
b
(
"Hello, World!"
)
)
check_contents
(
"b.txt"
,
b
(
"b"
))
check_contents
(
"b.txt"
,
b
(
"b"
))
check_contents
(
"foo/bar/baz.txt"
,
b
(
"baz"
))
check_contents
(
"foo/bar/baz.txt"
,
b
(
"baz"
))
check_contents
(
"foo/second.txt"
,
b
(
"hai"
))
check_contents
(
"foo/second.txt"
,
b
(
"hai"
))
...
...
tox.ini
View file @
ea0d2e43
...
@@ -30,5 +30,6 @@ commands = nosetests fs.tests -v \
...
@@ -30,5 +30,6 @@ commands = nosetests fs.tests -v \
deps
=
distribute
deps
=
distribute
six
six
dexml
dexml
nose
nose
winpdb
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