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
838d94c3
Commit
838d94c3
authored
Nov 20, 2010
by
willmcgugan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed getmeta/hasmeta, added documentation and tests
parent
e4fe27c2
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
139 additions
and
29 deletions
+139
-29
fs/base.py
+48
-12
fs/contrib/bigfs/__init__.py
+1
-0
fs/contrib/davfs/__init__.py
+1
-0
fs/contrib/tahoefs/__init__.py
+1
-1
fs/ftpfs.py
+5
-2
fs/memoryfs.py
+6
-2
fs/mountfs.py
+1
-1
fs/osfs/__init__.py
+26
-1
fs/rpcfs.py
+11
-4
fs/s3fs.py
+4
-1
fs/sftpfs.py
+4
-1
fs/tempfs.py
+4
-0
fs/tests/__init__.py
+20
-0
fs/wrapfs/__init__.py
+2
-2
fs/wrapfs/readonlyfs.py
+2
-1
fs/zipfs.py
+3
-1
No files found.
fs/base.py
View file @
838d94c3
...
@@ -15,7 +15,8 @@ __all__ = ['DummyLock',
...
@@ -15,7 +15,8 @@ __all__ = ['DummyLock',
'NullFile'
,
'NullFile'
,
'synchronize'
,
'synchronize'
,
'FS'
,
'FS'
,
'flags_to_mode'
]
'flags_to_mode'
,
'NoDefaultMeta'
]
import
os
,
os
.
path
import
os
,
os
.
path
import
sys
import
sys
...
@@ -33,9 +34,6 @@ from fs.path import *
...
@@ -33,9 +34,6 @@ from fs.path import *
from
fs.errors
import
*
from
fs.errors
import
*
from
fs.local_functools
import
wraps
from
fs.local_functools
import
wraps
SubFS
=
None
# this is lazily imported from fs.wrapfs.subfs
class
DummyLock
(
object
):
class
DummyLock
(
object
):
"""A dummy lock object that doesn't do anything.
"""A dummy lock object that doesn't do anything.
...
@@ -68,6 +66,11 @@ def silence_fserrors(f, *args, **kwargs):
...
@@ -68,6 +66,11 @@ def silence_fserrors(f, *args, **kwargs):
return
None
return
None
class
NoDefaultMeta
(
object
):
"""A singleton used to signify that there is no default for getmeta"""
pass
class
NullFile
(
object
):
class
NullFile
(
object
):
"""A NullFile is a file object that has no functionality.
"""A NullFile is a file object that has no functionality.
...
@@ -188,8 +191,33 @@ class FS(object):
...
@@ -188,8 +191,33 @@ class FS(object):
else
:
else
:
self
.
_lock
=
DummyLock
()
self
.
_lock
=
DummyLock
()
def
getmeta
(
self
,
meta_name
,
default
=
Ellipsis
):
def
getmeta
(
self
,
meta_name
,
default
=
NoDefaultMeta
):
"""Retrieve a meta value associated with the FS object
"""Retrieve a meta value associated with an FS object. Meta values are
a way of an FS implementation to report potentially useful information
associated with the file system.
A meta key is a lower case string with no spaces. Meta keys may also
be grouped in namespaces in a dotted notation, e.g. 'atomic.namespaces'.
FS implementations aren't obliged to return any meta values, but the
following are common:
* *read_only* True if the file system can not be modified
* *network* True if the file system requires network access
* *unicode_paths* True if the file system can use unicode paths
* *case_insensitive_paths* True if the file system ignores the case of paths
* *atomic.makedir* True if making a directory is an atomic operation
* *atomic.rename" True if rename is an atomic operation, (and not implemented as a copy followed by a delete)
* *atomic.setcontents" True if the implementation supports setting the contents of a file as an atomic operation (without opening a file)
The following are less common:
* *free_space* The free space (in bytes) available on the file system
FS implementations may expose non-generic meta data through a self-named namespace. e.g. 'somefs.some_meta'
Since no meta value is guaranteed to exist, it is advisable to always supply a
default value to `getmeta`.
:param meta_name: The name of the meta value to retrieve
:param meta_name: The name of the meta value to retrieve
:param default: An option default to return, if the meta value isn't present
:param default: An option default to return, if the meta value isn't present
...
@@ -197,7 +225,7 @@ class FS(object):
...
@@ -197,7 +225,7 @@ class FS(object):
"""
"""
if
meta_name
not
in
self
.
_meta
:
if
meta_name
not
in
self
.
_meta
:
if
default
is
not
Ellipsis
:
if
default
is
not
NoDefaultMeta
:
return
default
return
default
raise
NoMetaError
(
meta_name
=
meta_name
)
raise
NoMetaError
(
meta_name
=
meta_name
)
return
self
.
_meta
[
meta_name
]
return
self
.
_meta
[
meta_name
]
...
@@ -210,7 +238,7 @@ class FS(object):
...
@@ -210,7 +238,7 @@ class FS(object):
"""
"""
try
:
try
:
self
.
getmeta
(
'meta_name'
)
self
.
getmeta
(
meta_name
)
except
NoMetaError
:
except
NoMetaError
:
return
False
return
False
return
True
return
True
...
@@ -512,7 +540,16 @@ class FS(object):
...
@@ -512,7 +540,16 @@ class FS(object):
def
getinfo
(
self
,
path
):
def
getinfo
(
self
,
path
):
"""Returns information for a path as a dictionary. The exact content of
"""Returns information for a path as a dictionary. The exact content of
this dictionary will vary depending on the implementation, but will
this dictionary will vary depending on the implementation, but will
likely include a few common values.
likely include a few common values. The following values will be found
in info dictionaries for most implementations:
* "size" - Number of bytes used to store the file or directory
* "created_time" - A datetime object containing the time the resource
was created
* "accessed_time" - A datetime object containing the time the resource
was last accessed
* "modified_time" - A datetime object containing the time the resource
was modified
:param path: a path to retrieve information for
:param path: a path to retrieve information for
:rtype: dict
:rtype: dict
...
@@ -521,7 +558,7 @@ class FS(object):
...
@@ -521,7 +558,7 @@ class FS(object):
def
desc
(
self
,
path
):
def
desc
(
self
,
path
):
"""Returns short descriptive text regarding a path. Intended mainly as
"""Returns short descriptive text regarding a path. Intended mainly as
a debugging aid
a debugging aid
.
:param path: A path to describe
:param path: A path to describe
:rtype: str
:rtype: str
...
@@ -583,8 +620,7 @@ class FS(object):
...
@@ -583,8 +620,7 @@ class FS(object):
:param path: path to directory to open
:param path: path to directory to open
:rtype: An FS object
:rtype: An FS object
"""
"""
global
SubFS
if
SubFS
is
None
:
from
fs.wrapfs.subfs
import
SubFS
from
fs.wrapfs.subfs
import
SubFS
if
not
self
.
exists
(
path
):
if
not
self
.
exists
(
path
):
raise
ResourceNotFoundError
(
path
)
raise
ResourceNotFoundError
(
path
)
...
...
fs/contrib/bigfs/__init__.py
View file @
838d94c3
...
@@ -161,6 +161,7 @@ class BigFS(FS):
...
@@ -161,6 +161,7 @@ class BigFS(FS):
'read_only'
:
True
,
'read_only'
:
True
,
'unicode_paths'
:
True
,
'unicode_paths'
:
True
,
'case_insensitive_paths'
:
False
,
'case_insensitive_paths'
:
False
,
'network'
:
False
,
}
}
def
__init__
(
self
,
filename
,
mode
=
"r"
,
thread_synchronize
=
True
):
def
__init__
(
self
,
filename
,
mode
=
"r"
,
thread_synchronize
=
True
):
...
...
fs/contrib/davfs/__init__.py
View file @
838d94c3
...
@@ -77,6 +77,7 @@ class DAVFS(FS):
...
@@ -77,6 +77,7 @@ class DAVFS(FS):
'read_only'
:
False
,
'read_only'
:
False
,
'unicode_paths'
:
True
,
'unicode_paths'
:
True
,
'case_insensitive_paths'
:
False
,
'case_insensitive_paths'
:
False
,
'network'
:
True
}
}
def
__init__
(
self
,
url
,
credentials
=
None
,
get_credentials
=
None
,
thread_synchronize
=
True
,
connection_classes
=
None
,
timeout
=
None
):
def
__init__
(
self
,
url
,
credentials
=
None
,
get_credentials
=
None
,
thread_synchronize
=
True
,
connection_classes
=
None
,
timeout
=
None
):
...
...
fs/contrib/tahoefs/__init__.py
View file @
838d94c3
...
@@ -80,7 +80,7 @@ class TahoeFS(CacheFS):
...
@@ -80,7 +80,7 @@ class TahoeFS(CacheFS):
'read_only'
:
False
,
'read_only'
:
False
,
'unicode_paths'
:
True
,
'unicode_paths'
:
True
,
'case_insensitive_paths'
:
False
,
'case_insensitive_paths'
:
False
,
'
may_bloc
k'
:
True
'
networ
k'
:
True
}
}
def
__init__
(
self
,
dircap
,
timeout
=
60
,
autorun
=
True
,
largefilesize
=
10
*
1024
*
1024
,
webapi
=
'http://127.0.0.1:3456'
):
def
__init__
(
self
,
dircap
,
timeout
=
60
,
autorun
=
True
,
largefilesize
=
10
*
1024
*
1024
,
webapi
=
'http://127.0.0.1:3456'
):
...
...
fs/ftpfs.py
View file @
838d94c3
...
@@ -737,11 +737,14 @@ class FTPFS(FS):
...
@@ -737,11 +737,14 @@ class FTPFS(FS):
_locals
=
threading
.
local
()
_locals
=
threading
.
local
()
_meta
=
{
'virtual'
:
False
,
_meta
=
{
'network'
:
True
,
'virtual'
:
False
,
'read_only'
:
False
,
'read_only'
:
False
,
'unicode_paths'
:
True
,
'unicode_paths'
:
True
,
'case_insensitive_paths'
:
False
,
'case_insensitive_paths'
:
False
,
'may_block'
:
True
'atomic.makedir'
:
True
,
'atomic.rename'
:
True
,
'atomic.setcontents'
:
False
,
}
}
def
__init__
(
self
,
host
=
''
,
user
=
''
,
passwd
=
''
,
acct
=
''
,
timeout
=
_GLOBAL_DEFAULT_TIMEOUT
,
def
__init__
(
self
,
host
=
''
,
user
=
''
,
passwd
=
''
,
acct
=
''
,
timeout
=
_GLOBAL_DEFAULT_TIMEOUT
,
...
...
fs/memoryfs.py
View file @
838d94c3
...
@@ -184,10 +184,14 @@ class MemoryFS(FS):
...
@@ -184,10 +184,14 @@ class MemoryFS(FS):
"""
"""
_meta
=
{
'virtual'
:
False
,
_meta
=
{
'network'
:
False
,
'virtual'
:
False
,
'read_only'
:
False
,
'read_only'
:
False
,
'unicode_paths'
:
True
,
'unicode_paths'
:
True
,
'case_insensitive_paths'
:
False
'case_insensitive_paths'
:
False
,
'atomic.makedir'
:
True
,
'atomic.rename'
:
True
,
'atomic.setcontents'
:
False
,
}
}
def
_make_dir_entry
(
self
,
*
args
,
**
kwargs
):
def
_make_dir_entry
(
self
,
*
args
,
**
kwargs
):
...
...
fs/mountfs.py
View file @
838d94c3
...
@@ -72,7 +72,7 @@ class MountFS(FS):
...
@@ -72,7 +72,7 @@ class MountFS(FS):
_meta
=
{
'virtual'
:
True
,
_meta
=
{
'virtual'
:
True
,
'read_only'
:
False
,
'read_only'
:
False
,
'unicode_paths'
:
True
,
'unicode_paths'
:
True
,
'case_insensitive_paths'
:
False
'case_insensitive_paths'
:
False
,
}
}
DirMount
=
DirMount
DirMount
=
DirMount
...
...
fs/osfs/__init__.py
View file @
838d94c3
...
@@ -18,6 +18,7 @@ import os.path
...
@@ -18,6 +18,7 @@ import os.path
import
sys
import
sys
import
errno
import
errno
import
datetime
import
datetime
import
platform
from
fs.base
import
*
from
fs.base
import
*
from
fs.errors
import
*
from
fs.errors
import
*
...
@@ -73,10 +74,14 @@ class OSFS(OSFSXAttrMixin, OSFSWatchMixin, FS):
...
@@ -73,10 +74,14 @@ class OSFS(OSFSXAttrMixin, OSFSWatchMixin, FS):
methods in the os and os.path modules.
methods in the os and os.path modules.
"""
"""
_meta
=
{
'virtual'
:
False
,
_meta
=
{
'network'
:
False
,
'virtual'
:
False
,
'read_only'
:
False
,
'read_only'
:
False
,
'unicode_paths'
:
os
.
path
.
supports_unicode_filenames
,
'unicode_paths'
:
os
.
path
.
supports_unicode_filenames
,
'case_insensitive_paths'
:
os
.
path
.
normcase
(
'Aa'
)
==
'aa'
,
'case_insensitive_paths'
:
os
.
path
.
normcase
(
'Aa'
)
==
'aa'
,
'atomic.makedir'
:
True
,
'atomic.rename'
:
True
,
'atomic.setcontents'
:
False
,
}
}
def
__init__
(
self
,
root_path
,
thread_synchronize
=
_thread_synchronize_default
,
encoding
=
None
,
create
=
False
,
dir_mode
=
0700
):
def
__init__
(
self
,
root_path
,
thread_synchronize
=
_thread_synchronize_default
,
encoding
=
None
,
create
=
False
,
dir_mode
=
0700
):
...
@@ -155,6 +160,26 @@ class OSFS(OSFSXAttrMixin, OSFSWatchMixin, FS):
...
@@ -155,6 +160,26 @@ class OSFS(OSFSXAttrMixin, OSFSWatchMixin, FS):
raise
ValueError
(
"path not within this FS:
%
s (
%
s)"
%
(
os
.
path
.
normcase
(
path
),
prefix
))
raise
ValueError
(
"path not within this FS:
%
s (
%
s)"
%
(
os
.
path
.
normcase
(
path
),
prefix
))
return
path
[
len
(
self
.
root_path
):]
return
path
[
len
(
self
.
root_path
):]
def
getmeta
(
self
,
meta_name
,
default
=
NoDefaultMeta
):
if
meta_name
==
'free_space'
:
if
platform
.
system
()
==
'Windows'
:
try
:
import
ctypes
free_bytes
=
ctypes
.
ulonglong
(
0
)
ctypes
.
windll
.
kernel32
.
GetDiskFreeSpaceExW
(
ctypes
.
c_wchar_p
(
self
.
root_path
),
None
,
None
,
ctypes
.
pointer
(
free_bytes
))
return
free_bytes
.
value
except
ImportError
:
# Fall through to call the base class
pass
else
:
stat
=
os
.
statvfs
(
self
.
root_path
)
return
stat
.
f_bfree
*
stat
.
f_bsize
return
super
(
OSFS
,
self
)
.
getmeta
(
meta_name
,
default
)
@convert_os_errors
@convert_os_errors
def
open
(
self
,
path
,
mode
=
"r"
,
**
kwargs
):
def
open
(
self
,
path
,
mode
=
"r"
,
**
kwargs
):
mode
=
filter
(
lambda
c
:
c
in
"rwabt+"
,
mode
)
mode
=
filter
(
lambda
c
:
c
in
"rwabt+"
,
mode
)
...
...
fs/rpcfs.py
View file @
838d94c3
...
@@ -89,10 +89,7 @@ class RPCFS(FS):
...
@@ -89,10 +89,7 @@ class RPCFS(FS):
"""
"""
_meta
=
{
'virtual'
:
False
,
_meta
=
{
'virtual'
:
False
,
'read_only'
:
False
,
'network'
:
True
,
'unicode_paths'
:
True
,
'case_insensitive_paths'
:
False
,
'may_block'
:
True
,
}
}
def
__init__
(
self
,
uri
,
transport
=
None
):
def
__init__
(
self
,
uri
,
transport
=
None
):
...
@@ -147,6 +144,16 @@ class RPCFS(FS):
...
@@ -147,6 +144,16 @@ class RPCFS(FS):
"""Decode paths arriving over the wire."""
"""Decode paths arriving over the wire."""
return
path
.
decode
(
"base64"
)
.
decode
(
"utf8"
)
return
path
.
decode
(
"base64"
)
.
decode
(
"utf8"
)
def
getmeta
(
self
,
meta_name
,
default
=
NoDefaultMeta
):
if
meta_name
in
self
.
_meta
:
return
self
.
_meta
[
meta_name
]
return
self
.
proxy
.
getmeta
(
meta_name
,
default
)
def
hasmeta
(
self
,
meta_name
):
if
meta_name
in
self
.
_meta
:
return
True
return
self
.
proxy
.
hasmeta
(
meta_name
)
def
open
(
self
,
path
,
mode
=
"r"
):
def
open
(
self
,
path
,
mode
=
"r"
):
# TODO: chunked transport of large files
# TODO: chunked transport of large files
path
=
self
.
encode_path
(
path
)
path
=
self
.
encode_path
(
path
)
...
...
fs/s3fs.py
View file @
838d94c3
...
@@ -60,7 +60,10 @@ class S3FS(FS):
...
@@ -60,7 +60,10 @@ class S3FS(FS):
'read_only'
:
False
,
'read_only'
:
False
,
'unicode_paths'
:
True
,
'unicode_paths'
:
True
,
'case_insensitive_paths'
:
False
,
'case_insensitive_paths'
:
False
,
'may_block'
:
True
,
'network'
:
True
,
'atomic.makedir'
:
True
,
'atomic.rename'
:
False
,
'atomic.setconetns'
:
True
}
}
class
meta
:
class
meta
:
...
...
fs/sftpfs.py
View file @
838d94c3
...
@@ -50,7 +50,10 @@ class SFTPFS(FS):
...
@@ -50,7 +50,10 @@ class SFTPFS(FS):
'read_only'
:
False
,
'read_only'
:
False
,
'unicode_paths'
:
True
,
'unicode_paths'
:
True
,
'case_insensitive_paths'
:
False
,
'case_insensitive_paths'
:
False
,
'may_block'
:
True
,
'network'
:
True
,
'atomic.makedir'
:
True
,
'atomic.rename'
:
True
,
'atomic.setcontents'
:
False
}
}
def
__init__
(
self
,
connection
,
root_path
=
"/"
,
encoding
=
None
,
**
credentials
):
def
__init__
(
self
,
connection
,
root_path
=
"/"
,
encoding
=
None
,
**
credentials
):
...
...
fs/tempfs.py
View file @
838d94c3
...
@@ -24,6 +24,10 @@ class TempFS(OSFS):
...
@@ -24,6 +24,10 @@ class TempFS(OSFS):
'read_only'
:
False
,
'read_only'
:
False
,
'unicode_paths'
:
os
.
path
.
supports_unicode_filenames
,
'unicode_paths'
:
os
.
path
.
supports_unicode_filenames
,
'case_insensitive_paths'
:
os
.
path
.
normcase
(
'Aa'
)
==
'aa'
,
'case_insensitive_paths'
:
os
.
path
.
normcase
(
'Aa'
)
==
'aa'
,
'network'
:
False
,
'atomic.makedir'
:
True
,
'atomic.rename'
:
True
,
'atomic.setcontents'
:
False
}
}
def
__init__
(
self
,
identifier
=
None
,
temp_dir
=
None
,
dir_mode
=
0700
,
thread_synchronize
=
_thread_synchronize_default
):
def
__init__
(
self
,
identifier
=
None
,
temp_dir
=
None
,
dir_mode
=
0700
,
thread_synchronize
=
_thread_synchronize_default
):
...
...
fs/tests/__init__.py
View file @
838d94c3
...
@@ -48,6 +48,26 @@ class FSTestCases(object):
...
@@ -48,6 +48,26 @@ class FSTestCases(object):
"""Check that a file exists within self.fs"""
"""Check that a file exists within self.fs"""
return
self
.
fs
.
exists
(
p
)
return
self
.
fs
.
exists
(
p
)
def
test_meta
(
self
):
"""Checks getmeta / hasmeta are functioning"""
# getmeta / hasmeta are hard to test, since there is no way to validate
# the implementations response
meta_names
=
[
"read_only"
,
"network"
,
"unicode_paths"
]
stupid_meta
=
'thismetashouldnotexist!"r$$
%
^&&*()_+'
self
.
assertRaises
(
NoMetaError
,
self
.
fs
.
getmeta
,
stupid_meta
)
self
.
assertFalse
(
self
.
fs
.
hasmeta
(
stupid_meta
))
self
.
assertEquals
(
None
,
self
.
fs
.
getmeta
(
stupid_meta
,
None
))
self
.
assertEquals
(
3.14
,
self
.
fs
.
getmeta
(
stupid_meta
,
3.14
))
for
meta_name
in
meta_names
:
try
:
meta
=
self
.
fs
.
getmeta
(
meta_name
)
self
.
assertTrue
(
self
.
fs
.
hasmeta
(
meta_name
))
except
NoMetaError
:
self
.
assertFalse
(
self
.
fs
.
hasmeta
(
meta_name
))
def
test_root_dir
(
self
):
def
test_root_dir
(
self
):
self
.
assertTrue
(
self
.
fs
.
isdir
(
""
))
self
.
assertTrue
(
self
.
fs
.
isdir
(
""
))
self
.
assertTrue
(
self
.
fs
.
isdir
(
"/"
))
self
.
assertTrue
(
self
.
fs
.
isdir
(
"/"
))
...
...
fs/wrapfs/__init__.py
View file @
838d94c3
...
@@ -19,7 +19,7 @@ import re
...
@@ -19,7 +19,7 @@ import re
import
sys
import
sys
import
fnmatch
import
fnmatch
from
fs.base
import
FS
,
threading
,
synchronize
from
fs.base
import
FS
,
threading
,
synchronize
,
NoDefaultMeta
from
fs.errors
import
*
from
fs.errors
import
*
from
fs.path
import
*
from
fs.path
import
*
from
fs.local_functools
import
wraps
from
fs.local_functools
import
wraps
...
@@ -118,7 +118,7 @@ class WrapFS(FS):
...
@@ -118,7 +118,7 @@ class WrapFS(FS):
return
(
mode
,
mode
)
return
(
mode
,
mode
)
@rewrite_errors
@rewrite_errors
def
getmeta
(
self
,
meta_name
,
default
=
Ellipsis
):
def
getmeta
(
self
,
meta_name
,
default
=
NoDefaultMeta
):
return
self
.
wrapped_fs
.
getmeta
(
meta_name
,
default
)
return
self
.
wrapped_fs
.
getmeta
(
meta_name
,
default
)
@rewrite_errors
@rewrite_errors
...
...
fs/wrapfs/readonlyfs.py
View file @
838d94c3
...
@@ -6,6 +6,7 @@ An FS wrapper class for blocking operations that would modify the FS.
...
@@ -6,6 +6,7 @@ An FS wrapper class for blocking operations that would modify the FS.
"""
"""
from
fs.base
import
NoDefaultMeta
from
fs.wrapfs
import
WrapFS
from
fs.wrapfs
import
WrapFS
from
fs.errors
import
UnsupportedError
,
NoSysPathError
from
fs.errors
import
UnsupportedError
,
NoSysPathError
...
@@ -20,7 +21,7 @@ class ReadOnlyFS(WrapFS):
...
@@ -20,7 +21,7 @@ class ReadOnlyFS(WrapFS):
"""
"""
def
getmeta
(
self
,
meta_name
,
default
=
Ellipsis
):
def
getmeta
(
self
,
meta_name
,
default
=
NoDefaultMeta
):
if
meta_name
==
'read_only'
:
if
meta_name
==
'read_only'
:
return
True
return
True
return
self
.
wrapped_fs
(
meta_name
,
default
)
return
self
.
wrapped_fs
(
meta_name
,
default
)
...
...
fs/zipfs.py
View file @
838d94c3
...
@@ -76,6 +76,8 @@ class ZipFS(FS):
...
@@ -76,6 +76,8 @@ class ZipFS(FS):
'read_only'
:
False
,
'read_only'
:
False
,
'unicode_paths'
:
True
,
'unicode_paths'
:
True
,
'case_insensitive_paths'
:
False
,
'case_insensitive_paths'
:
False
,
'network'
:
False
,
'atomic.setcontents'
:
False
}
}
def
__init__
(
self
,
zip_file
,
mode
=
"r"
,
compression
=
"deflated"
,
allow_zip_64
=
False
,
encoding
=
"CP437"
,
thread_synchronize
=
True
):
def
__init__
(
self
,
zip_file
,
mode
=
"r"
,
compression
=
"deflated"
,
allow_zip_64
=
False
,
encoding
=
"CP437"
,
thread_synchronize
=
True
):
...
@@ -149,7 +151,7 @@ class ZipFS(FS):
...
@@ -149,7 +151,7 @@ class ZipFS(FS):
f
=
self
.
_path_fs
.
open
(
path
,
'w'
)
f
=
self
.
_path_fs
.
open
(
path
,
'w'
)
f
.
close
()
f
.
close
()
def
getmeta
(
self
,
meta_name
,
default
=
Ellipsis
):
def
getmeta
(
self
,
meta_name
,
default
=
NoDefaultMeta
):
if
meta_name
==
'read_only'
:
if
meta_name
==
'read_only'
:
return
self
.
read_only
return
self
.
read_only
return
super
(
ZipFS
,
self
)
.
getmeta
(
meta_name
,
default
)
return
super
(
ZipFS
,
self
)
.
getmeta
(
meta_name
,
default
)
...
...
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