Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit decbbe4

Browse files
committedJul 5, 2017
Add type annotations to plugin categories
Signed-off-by: Chris Warrick <kwpolska@gmail.com>
1 parent e5fd904 commit decbbe4

File tree

1 file changed

+58
-50
lines changed

1 file changed

+58
-50
lines changed
 

‎nikola/plugin_categories.py

+58-50
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@
3535

3636
from .utils import LOGGER, first_line, req_missing
3737

38+
try:
39+
from typing import *
40+
if TYPE_CHECKING:
41+
import nikola # NOQA
42+
import nikola.post # NOQA
43+
except ImportError:
44+
pass
45+
3846
__all__ = (
3947
'Command',
4048
'LateTask',
@@ -90,11 +98,11 @@ def get_deps(self, filename):
9098
class PostScanner(BasePlugin):
9199
"""The scan method of these plugins is called by Nikola.scan_posts."""
92100

93-
def scan(self):
101+
def scan(self) -> 'List[nikola.post.Post]':
94102
"""Create a list of posts from some source. Returns a list of Post objects."""
95103
raise NotImplementedError()
96104

97-
def supported_extensions(self):
105+
def supported_extensions(self) -> 'Optional[List]':
98106
"""Return a list of supported file extensions, or None if such a list isn't known beforehand."""
99107
return None
100108

@@ -122,7 +130,7 @@ def __call__(self, config=None, **kwargs):
122130
DoitCommand.__init__(self, config, **kwargs)
123131
return self
124132

125-
def execute(self, options=None, args=None):
133+
def execute(self, options=None, args=None) -> int:
126134
"""Check if the command can run in the current environment, fail if needed, or call _execute."""
127135
options = options or {}
128136
args = args or []
@@ -132,7 +140,7 @@ def execute(self, options=None, args=None):
132140
return False
133141
return self._execute(options, args)
134142

135-
def _execute(self, options, args):
143+
def _execute(self, options, args) -> int:
136144
"""Do whatever this command does.
137145
138146
@param options (dict) with values from cmd_options
@@ -171,11 +179,11 @@ class BaseTask(BasePlugin):
171179
# the others have to be specifie in the command line.
172180
is_default = True
173181

174-
def gen_tasks(self):
182+
def gen_tasks(self) -> 'List[dict]':
175183
"""Generate tasks."""
176184
raise NotImplementedError()
177185

178-
def group_task(self):
186+
def group_task(self) -> dict:
179187
"""Return dict for group task."""
180188
return {
181189
'basename': self.name,
@@ -201,39 +209,39 @@ class TemplateSystem(BasePlugin):
201209

202210
name = "dummy_templates"
203211

204-
def set_directories(self, directories, cache_folder):
212+
def set_directories(self, directories: 'List[str]', cache_folder: str):
205213
"""Set the list of folders where templates are located and cache."""
206214
raise NotImplementedError()
207215

208-
def template_deps(self, template_name):
216+
def template_deps(self, template_name: str):
209217
"""Return filenames which are dependencies for a template."""
210218
raise NotImplementedError()
211219

212-
def get_deps(self, filename):
220+
def get_deps(self, filename: str):
213221
"""Return paths to dependencies for the template loaded from filename."""
214222
raise NotImplementedError()
215223

216-
def get_string_deps(self, text):
224+
def get_string_deps(self, text: str):
217225
"""Find dependencies for a template string."""
218226
raise NotImplementedError()
219227

220-
def render_template(self, template_name, output_name, context):
228+
def render_template(self, template_name: str, output_name: str, context: 'Dict[str, str]'):
221229
"""Render template to a file using context.
222230
223231
This must save the data to output_name *and* return it
224232
so that the caller may do additional processing.
225233
"""
226234
raise NotImplementedError()
227235

228-
def render_template_to_string(self, template, context):
236+
def render_template_to_string(self, template: str, context: 'Dict[str, str]') -> str:
229237
"""Render template to a string using context."""
230238
raise NotImplementedError()
231239

232-
def inject_directory(self, directory):
240+
def inject_directory(self, directory: str):
233241
"""Inject the directory with the lowest priority in the template search mechanism."""
234242
raise NotImplementedError()
235243

236-
def get_template_path(self, template_name):
244+
def get_template_path(self, template_name: str) -> str:
237245
"""Get the path to a template or return None."""
238246
raise NotImplementedError()
239247

@@ -243,7 +251,7 @@ class TaskMultiplier(BasePlugin):
243251

244252
name = "dummy multiplier"
245253

246-
def process(self, task):
254+
def process(self, task) -> list:
247255
"""Examine task and create more tasks. Returns extra tasks only."""
248256
return []
249257

@@ -270,11 +278,11 @@ class PageCompiler(BasePlugin):
270278
}
271279
config_dependencies = []
272280

273-
def get_dep_filename(self, post, lang):
281+
def get_dep_filename(self, post: 'nikola.post.Post', lang: str) -> str:
274282
"""Return the .dep file's name for the given post and language."""
275283
return post.translated_base_path(lang) + '.dep'
276284

277-
def _read_extra_deps(self, post, lang):
285+
def _read_extra_deps(self, post: 'nikola.post.Post', lang: str) -> 'List[str]':
278286
"""Read contents of .dep file and return them as a list."""
279287
dep_path = self.get_dep_filename(post, lang)
280288
if os.path.isfile(dep_path):
@@ -283,9 +291,9 @@ def _read_extra_deps(self, post, lang):
283291
return deps
284292
return []
285293

286-
def register_extra_dependencies(self, post):
294+
def register_extra_dependencies(self, post: 'nikola.post.Post'):
287295
"""Add dependency to post object to check .dep file."""
288-
def create_lambda(lang):
296+
def create_lambda(lang: str) -> 'Callable':
289297
# We create a lambda like this so we can pass `lang` to it, because if we didn’t
290298
# add that function, `lang` would always be the last language in TRANSLATIONS.
291299
# (See http://docs.python-guide.org/en/latest/writing/gotchas/#late-binding-closures)
@@ -294,38 +302,38 @@ def create_lambda(lang):
294302
for lang in self.site.config['TRANSLATIONS']:
295303
post.add_dependency(create_lambda(lang), 'fragment', lang=lang)
296304

297-
def get_extra_targets(self, post, lang, dest):
305+
def get_extra_targets(self, post: 'nikola.post.Post', lang: str, dest: str) -> 'List[str]':
298306
"""Return a list of extra targets for the render_posts task when compiling the post for the specified language."""
299307
if self.use_dep_file:
300308
return [self.get_dep_filename(post, lang)]
301309
else:
302310
return []
303311

304-
def compile(self, source, dest, is_two_file=True, post=None, lang=None):
312+
def compile(self, source: str, dest: str, is_two_file=True, post=None, lang=None):
305313
"""Compile the source file into HTML and save as dest."""
306314
raise NotImplementedError()
307315

308-
def compile_string(self, data, source_path=None, is_two_file=True, post=None, lang=None):
316+
def compile_string(self, data: str, source_path=None, is_two_file=True, post=None, lang=None) -> str:
309317
"""Compile the source file into HTML strings (with shortcode support).
310318
311319
Returns a tuple of at least two elements: HTML string [0] and shortcode dependencies [last].
312320
"""
313321
# This function used to have some different APIs in different places.
314322
raise NotImplementedError()
315323

316-
def create_post(self, path, content=None, onefile=False, is_page=False, **kw):
324+
def create_post(self, path: str, content=None, onefile=False, is_page=False, **kw):
317325
"""Create post file with optional metadata."""
318326
raise NotImplementedError()
319327

320-
def extension(self):
328+
def extension(self) -> str:
321329
"""Return the preferred extension for the output of this compiler."""
322330
return ".html"
323331

324-
def read_metadata(self, post, lang=None):
332+
def read_metadata(self, post: 'nikola.post.Post', lang=None) -> 'Dict[str, str]':
325333
"""Read the metadata from a post, and return a metadata dict."""
326334
return {}
327335

328-
def split_metadata(self, data, post=None, lang=None):
336+
def split_metadata(self, data: str, post=None, lang=None) -> (str, str):
329337
"""Split data from metadata in the raw post content."""
330338
if lang and post:
331339
extractor = post.used_extractor[lang]
@@ -338,7 +346,7 @@ def split_metadata(self, data, post=None, lang=None):
338346
else:
339347
return data, data
340348

341-
def get_compiler_extensions(self):
349+
def get_compiler_extensions(self) -> list:
342350
"""Activate all the compiler extension plugins for a given compiler and return them."""
343351
plugins = []
344352
for plugin_info in self.site.compiler_extensions:
@@ -399,7 +407,7 @@ class MetadataExtractor(BasePlugin):
399407
# Whether or not the extractor supports writing metadata.
400408
supports_write = False
401409

402-
def _extract_metadata_from_text(self, source_text: str) -> dict:
410+
def _extract_metadata_from_text(self, source_text: str) -> 'Dict[str, str]':
403411
"""Extract metadata from text."""
404412
raise NotImplementedError()
405413

@@ -415,17 +423,17 @@ def split_metadata_from_text(self, source_text: str) -> (str, str):
415423
# Necessary?
416424
return split_result[0], split_result[-1]
417425

418-
def extract_text(self, source_text: str) -> dict:
426+
def extract_text(self, source_text: str) -> 'Dict[str, str]':
419427
"""Split file, return metadata and the content."""
420428
split = self.split_metadata_from_text(source_text)
421429
meta = self._extract_metadata_from_text(split[0])
422430
return meta
423431

424-
def extract_filename(self, filename: str, lang: str) -> dict:
432+
def extract_filename(self, filename: str, lang: str) -> 'Dict[str, str]':
425433
"""Extract metadata from filename."""
426434
return {}
427435

428-
def write_metadata(self, metadata: dict, comment_wrap=False) -> str:
436+
def write_metadata(self, metadata: 'Dict[str, str]', comment_wrap=False) -> str:
429437
"""Write metadata in this extractor’s format.
430438
431439
``comment_wrap`` is either True, False, or a 2-tuple of comments to use for wrapping, if necessary.
@@ -499,7 +507,7 @@ def _execute(self, options={}, args=[]):
499507
"""Import the data into Nikola."""
500508
raise NotImplementedError()
501509

502-
def generate_base_site(self, path):
510+
def generate_base_site(self, path: str):
503511
"""Create the base site."""
504512
raise NotImplementedError()
505513

@@ -700,7 +708,7 @@ class Taxonomy(BasePlugin):
700708
'taxonomy_rss': '',
701709
}
702710

703-
def is_enabled(self, lang=None):
711+
def is_enabled(self, lang=None) -> bool:
704712
"""Return True if this taxonomy is enabled, or False otherwise.
705713
706714
If lang is None, this determins whether the classification is
@@ -710,18 +718,18 @@ def is_enabled(self, lang=None):
710718
"""
711719
return True
712720

713-
def get_implicit_classifications(self, lang):
721+
def get_implicit_classifications(self, lang: str) -> 'List[str]':
714722
"""Return a list of classification strings which should always appear in posts_per_classification."""
715723
return []
716724

717-
def classify(self, post, lang):
725+
def classify(self, post: 'nikola.post.Post', lang: str) -> 'Iterable[str]':
718726
"""Classify the given post for the given language.
719727
720728
Must return a list or tuple of strings.
721729
"""
722730
raise NotImplementedError()
723731

724-
def sort_posts(self, posts, classification, lang):
732+
def sort_posts(self, posts: 'List[nikola.post.Post]', classification: str, lang: str):
725733
"""Sort the given list of posts.
726734
727735
Allows the plugin to order the posts per classification as it wants.
@@ -730,7 +738,7 @@ def sort_posts(self, posts, classification, lang):
730738
"""
731739
pass
732740

733-
def sort_classifications(self, classifications, lang, level=None):
741+
def sort_classifications(self, classifications: 'List[str]', lang: str, level=None):
734742
"""Sort the given list of classification strings.
735743
736744
Allows the plugin to order the classifications as it wants. The
@@ -743,7 +751,7 @@ def sort_classifications(self, classifications, lang, level=None):
743751
"""
744752
pass
745753

746-
def get_classification_friendly_name(self, classification, lang, only_last_component=False):
754+
def get_classification_friendly_name(self, classification: str, lang: str, only_last_component=False) -> str:
747755
"""Extract a friendly name from the classification.
748756
749757
The result of this function is usually displayed to the user, instead
@@ -755,7 +763,7 @@ def get_classification_friendly_name(self, classification, lang, only_last_compo
755763
"""
756764
raise NotImplementedError()
757765

758-
def get_overview_path(self, lang, dest_type='page'):
766+
def get_overview_path(self, lang: str, dest_type='page') -> str:
759767
"""Return path for classification overview.
760768
761769
This path handler for the classification overview must return one or
@@ -776,7 +784,7 @@ def get_overview_path(self, lang, dest_type='page'):
776784
"""
777785
raise NotImplementedError()
778786

779-
def get_path(self, classification, lang, dest_type='page'):
787+
def get_path(self, classification: str, lang: str, dest_type='page') -> str:
780788
"""Return path to the classification page.
781789
782790
This path handler for the given classification must return one to
@@ -804,23 +812,23 @@ def get_path(self, classification, lang, dest_type='page'):
804812
"""
805813
raise NotImplementedError()
806814

807-
def extract_hierarchy(self, classification):
815+
def extract_hierarchy(self, classification: str) -> 'List[str]':
808816
"""Given a classification, return a list of parts in the hierarchy.
809817
810818
For non-hierarchical taxonomies, it usually suffices to return
811819
`[classification]`.
812820
"""
813821
return [classification]
814822

815-
def recombine_classification_from_hierarchy(self, hierarchy):
823+
def recombine_classification_from_hierarchy(self, hierarchy: 'List[str]') -> str:
816824
"""Given a list of parts in the hierarchy, return the classification string.
817825
818826
For non-hierarchical taxonomies, it usually suffices to return hierarchy[0].
819827
"""
820828
return hierarchy[0]
821829

822-
def provide_overview_context_and_uptodate(self, lang):
823-
"""Provide data for the context and the uptodate list for the classifiation overview.
830+
def provide_overview_context_and_uptodate(self, lang: str) -> str:
831+
"""Provide data for the context and the uptodate list for the classification overview.
824832
825833
Must return a tuple of two dicts. The first is merged into the page's context,
826834
the second will be put into the uptodate list of all generated tasks.
@@ -829,8 +837,8 @@ def provide_overview_context_and_uptodate(self, lang):
829837
"""
830838
raise NotImplementedError()
831839

832-
def provide_context_and_uptodate(self, classification, lang, node=None):
833-
"""Provide data for the context and the uptodate list for the list of the given classifiation.
840+
def provide_context_and_uptodate(self, classification: str, lang: str, node=None) -> 'Tuple[Dict]':
841+
"""Provide data for the context and the uptodate list for the list of the given classification.
834842
835843
Must return a tuple of two dicts. The first is merged into the page's context,
836844
the second will be put into the uptodate list of all generated tasks.
@@ -842,15 +850,15 @@ def provide_context_and_uptodate(self, classification, lang, node=None):
842850
"""
843851
raise NotImplementedError()
844852

845-
def should_generate_classification_page(self, classification, post_list, lang):
853+
def should_generate_classification_page(self, classification: str, post_list: 'List[nikola.post.Post]', lang: str) -> bool:
846854
"""Only generates list of posts for classification if this function returns True."""
847855
return True
848856

849-
def should_generate_rss_for_classification_page(self, classification, post_list, lang):
857+
def should_generate_rss_for_classification_page(self, classification: str, post_list: 'List[nikola.post.Post]', lang: str) -> bool:
850858
"""Only generates RSS feed for list of posts for classification if this function returns True."""
851859
return self.should_generate_classification_page(classification, post_list, lang)
852860

853-
def postprocess_posts_per_classification(self, posts_per_classification_per_language, flat_hierarchy_per_lang=None, hierarchy_lookup_per_lang=None):
861+
def postprocess_posts_per_classification(self, posts_per_classification_per_language: 'List[nikola.post.Post]', flat_hierarchy_per_lang=None, hierarchy_lookup_per_lang=None) -> 'List[nikola.post.Post]':
854862
"""Rearrange, modify or otherwise use the list of posts per classification and per language.
855863
856864
For compatibility reasons, the list could be stored somewhere else as well.
@@ -862,7 +870,7 @@ def postprocess_posts_per_classification(self, posts_per_classification_per_lang
862870
"""
863871
pass
864872

865-
def get_other_language_variants(self, classification, lang, classifications_per_language):
873+
def get_other_language_variants(self, classification: str, lang: str, classifications_per_language: 'List[str]') -> 'List[str]':
866874
"""Return a list of variants of the same classification in other languages.
867875
868876
Given a `classification` in a language `lang`, return a list of pairs

0 commit comments

Comments
 (0)
Please sign in to comment.