files structure: move src_paths as a dynamic property, add remove

Plugins wishing to manipulate the Files structure have an append
method but can't dynamically work on src_paths since it's computed
once on Files instanciation

This commits allows plugins to manipulate Files trough append and
remove of file objects while not having to care about the src_paths
since it's now a dynamically computed property
This commit is contained in:
Ultrabug
2021-02-16 21:16:22 +01:00
committed by GitHub
parent e65c7660ad
commit b1f5dae055
3 changed files with 34 additions and 2 deletions

View File

@@ -100,6 +100,9 @@ up horizontal space for better rendering of content like tables (#2193).
filtering for sections (#2203).
* Official support for Python 3.9 has been added and support for Python 3.5
has been dropped.
* Structure Files object now has a `remove` method to help plugin developers
manipulate the Files tree. The corresponding `src_paths` has become a
property to accomodate this possible dynamic behavior. See #2305.
## Version 1.1.2 (2020-05-14)

View File

@@ -15,7 +15,6 @@ class Files:
""" A collection of File objects. """
def __init__(self, files):
self._files = files
self.src_paths = {file.src_path: file for file in files}
def __iter__(self):
return iter(self._files)
@@ -26,6 +25,10 @@ class Files:
def __contains__(self, path):
return path in self.src_paths
@property
def src_paths(self):
return {file.src_path: file for file in self._files}
def get_file_from_path(self, path):
""" Return a File instance with File.src_path equal to path. """
return self.src_paths.get(os.path.normpath(path))
@@ -33,7 +36,10 @@ class Files:
def append(self, file):
""" Append file to Files collection. """
self._files.append(file)
self.src_paths[file.src_path] = file
def remove(self, file):
""" Remove file from Files collection. """
self._files.remove(file)
def copy_static_files(self, dirty=False):
""" Copy static files from source to destination. """

View File

@@ -674,3 +674,26 @@ class TestFiles(PathAssertionMixin, unittest.TestCase):
self.assertPathIsFile(dest_path)
with open(dest_path, 'r', encoding='utf-8') as f:
self.assertEqual(f.read(), 'destination content')
def test_files_append_remove_src_paths(self):
fs = [
File('index.md', '/path/to/docs', '/path/to/site', use_directory_urls=True),
File('foo/bar.md', '/path/to/docs', '/path/to/site', use_directory_urls=True),
File('foo/bar.html', '/path/to/docs', '/path/to/site', use_directory_urls=True),
File('foo/bar.jpg', '/path/to/docs', '/path/to/site', use_directory_urls=True),
File('foo/bar.js', '/path/to/docs', '/path/to/site', use_directory_urls=True),
File('foo/bar.css', '/path/to/docs', '/path/to/site', use_directory_urls=True)
]
files = Files(fs)
self.assertEqual(len(files), 6)
self.assertEqual(len(files.src_paths), 6)
extra_file = File('extra.md', '/path/to/docs', '/path/to/site', use_directory_urls=True)
self.assertFalse(extra_file.src_path in files)
files.append(extra_file)
self.assertEqual(len(files), 7)
self.assertEqual(len(files.src_paths), 7)
self.assertTrue(extra_file.src_path in files)
files.remove(extra_file)
self.assertEqual(len(files), 6)
self.assertEqual(len(files.src_paths), 6)
self.assertFalse(extra_file.src_path in files)