Skip to content

Commit c23cfca

Browse files
rkhwajawillmcgugan
authored andcommitted
Allow custom subfs (#314)
* Implementation - don't know if it works * Add test * More documentation * Change documentation for opendir * Make a test for my original problem * Run black * Back out .gitignore changes
1 parent ef8682b commit c23cfca

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed

fs/base.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ class FS(object):
101101
# most FS will use default walking algorithms
102102
walker_class = Walker
103103

104+
# default to SubFS, used by opendir and should be returned by makedir(s)
105+
subfs_class = None
106+
104107
def __init__(self):
105108
# type: (...) -> None
106109
"""Create a filesystem. See help(type(self)) for accurate signature.
@@ -1180,7 +1183,7 @@ def opendir(
11801183
factory (callable, optional): A callable that when invoked
11811184
with an FS instance and ``path`` will return a new FS object
11821185
representing the sub-directory contents. If no ``factory``
1183-
is supplied then `~fs.subfs.SubFS` will be used.
1186+
is supplied then `~fs.subfs_class` will be used.
11841187
11851188
Returns:
11861189
~fs.subfs.SubFS: A filesystem representing a sub-directory.
@@ -1192,7 +1195,7 @@ def opendir(
11921195
"""
11931196
from .subfs import SubFS
11941197

1195-
_factory = factory or SubFS
1198+
_factory = factory or self.subfs_class or SubFS
11961199

11971200
if not self.getbasic(path).is_dir:
11981201
raise errors.DirectoryExpected(path=path)

tests/test_subfs.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
import os
44
import shutil
55
import tempfile
6+
import unittest
67

78
from fs import osfs
9+
from fs.subfs import SubFS
10+
from fs.memoryfs import MemoryFS
811
from fs.path import relpath
912
from .test_osfs import TestOSFS
1013

@@ -26,3 +29,44 @@ def tearDown(self):
2629
def _get_real_path(self, path):
2730
_path = os.path.join(self.temp_dir, "__subdir__", relpath(path))
2831
return _path
32+
33+
34+
class CustomSubFS(SubFS):
35+
"""Just a custom class to change the type"""
36+
37+
def custom_function(self, custom_path):
38+
fs, delegate_path = self.delegate_path(custom_path)
39+
fs.custom_function(delegate_path)
40+
41+
42+
class CustomSubFS2(SubFS):
43+
"""Just a custom class to change the type"""
44+
45+
46+
class CustomFS(MemoryFS):
47+
subfs_class = CustomSubFS
48+
49+
def __init__(self):
50+
super(CustomFS, self).__init__()
51+
self.custom_path = None
52+
53+
def custom_function(self, custom_path):
54+
self.custom_path = custom_path
55+
56+
57+
class TestCustomSubFS(unittest.TestCase):
58+
"""Test customization of the SubFS returned from opendir etc"""
59+
60+
def test_opendir(self):
61+
fs = CustomFS()
62+
fs.makedir("__subdir__")
63+
subfs = fs.opendir("__subdir__")
64+
# By default, you get the fs's defined custom SubFS
65+
assert isinstance(subfs, CustomSubFS)
66+
67+
subfs.custom_function("filename")
68+
assert fs.custom_path == "/__subdir__/filename"
69+
70+
# Providing the factory explicitly still works
71+
subfs = fs.opendir("__subdir__", factory=CustomSubFS2)
72+
assert isinstance(subfs, CustomSubFS2)

0 commit comments

Comments
 (0)