22"""
33Python Frontmatter: Parse and manage posts with YAML frontmatter
44"""
5+ from __future__ import annotations
56
67import codecs
7- import re
8-
8+ import io
9+ from typing import TYPE_CHECKING , Iterable
910
1011from .util import u
1112from .default_handlers import YAMLHandler , JSONHandler , TOMLHandler
1213
1314
15+ if TYPE_CHECKING :
16+ from .default_handlers import BaseHandler
17+
18+
1419__all__ = ["parse" , "load" , "loads" , "dump" , "dumps" ]
1520
1621
2227]
2328
2429
25- def detect_format (text , handlers ) :
30+ def detect_format (text : str , handlers : Iterable [ BaseHandler ]) -> BaseHandler | None :
2631 """
2732 Figure out which handler to use, based on metadata.
2833 Returns a handler instance or None.
@@ -40,7 +45,12 @@ def detect_format(text, handlers):
4045 return None
4146
4247
43- def parse (text , encoding = "utf-8" , handler = None , ** defaults ):
48+ def parse (
49+ text : str ,
50+ encoding : str = "utf-8" ,
51+ handler : BaseHandler | None = None ,
52+ ** defaults : object ,
53+ ) -> tuple [dict [str , object ], str ]:
4454 """
4555 Parse text with frontmatter, return metadata and content.
4656 Pass in optional metadata defaults as keyword args.
@@ -79,14 +89,14 @@ def parse(text, encoding="utf-8", handler=None, **defaults):
7989 return metadata , text
8090
8191 # parse, now that we have frontmatter
82- fm = handler .load (fm )
83- if isinstance (fm , dict ):
84- metadata .update (fm )
92+ fm_data = handler .load (fm )
93+ if isinstance (fm_data , dict ):
94+ metadata .update (fm_data )
8595
8696 return metadata , content .strip ()
8797
8898
89- def check (fd , encoding = "utf-8" ):
99+ def check (fd : str | io . IOBase , encoding : str = "utf-8" ) -> bool :
90100 """
91101 Check if a file-like object or filename has a frontmatter,
92102 return True if exists, False otherwise.
@@ -109,7 +119,7 @@ def check(fd, encoding="utf-8"):
109119 return checks (text , encoding )
110120
111121
112- def checks (text , encoding = "utf-8" ):
122+ def checks (text : str , encoding : str = "utf-8" ) -> bool :
113123 """
114124 Check if a text (binary or unicode) has a frontmatter,
115125 return True if exists, False otherwise.
@@ -127,7 +137,12 @@ def checks(text, encoding="utf-8"):
127137 return detect_format (text , handlers ) != None
128138
129139
130- def load (fd , encoding = "utf-8" , handler = None , ** defaults ):
140+ def load (
141+ fd : str | io .IOBase ,
142+ encoding : str = "utf-8" ,
143+ handler : BaseHandler | None = None ,
144+ ** defaults : object ,
145+ ) -> Post :
131146 """
132147 Load and parse a file-like object or filename,
133148 return a :py:class:`post <frontmatter.Post>`.
@@ -150,7 +165,12 @@ def load(fd, encoding="utf-8", handler=None, **defaults):
150165 return loads (text , encoding , handler , ** defaults )
151166
152167
153- def loads (text , encoding = "utf-8" , handler = None , ** defaults ):
168+ def loads (
169+ text : str ,
170+ encoding : str = "utf-8" ,
171+ handler : BaseHandler | None = None ,
172+ ** defaults : object ,
173+ ) -> Post :
154174 """
155175 Parse text (binary or unicode) and return a :py:class:`post <frontmatter.Post>`.
156176
@@ -166,7 +186,13 @@ def loads(text, encoding="utf-8", handler=None, **defaults):
166186 return Post (content , handler , ** metadata )
167187
168188
169- def dump (post , fd , encoding = "utf-8" , handler = None , ** kwargs ):
189+ def dump (
190+ post : Post ,
191+ fd : str | io .IOBase ,
192+ encoding : str = "utf-8" ,
193+ handler : BaseHandler | None = None ,
194+ ** kwargs : object ,
195+ ) -> None :
170196 """
171197 Serialize :py:class:`post <frontmatter.Post>` to a string and write to a file-like object.
172198 Text will be encoded on the way out (utf-8 by default).
@@ -213,7 +239,7 @@ def dump(post, fd, encoding="utf-8", handler=None, **kwargs):
213239 f .write (content )
214240
215241
216- def dumps (post , handler = None , ** kwargs ) :
242+ def dumps (post : Post , handler : BaseHandler | None = None , ** kwargs : object ) -> str :
217243 """
218244 Serialize a :py:class:`post <frontmatter.Post>` to a string and return text.
219245 This always returns unicode text, which can then be encoded.
@@ -265,46 +291,48 @@ class Post(object):
265291 For convenience, metadata values are available as proxied item lookups.
266292 """
267293
268- def __init__ (self , content , handler = None , ** metadata ):
294+ def __init__ (
295+ self , content : str , handler : BaseHandler | None = None , ** metadata : object
296+ ) -> None :
269297 self .content = str (content )
270298 self .metadata = metadata
271299 self .handler = handler
272300
273- def __getitem__ (self , name ) :
301+ def __getitem__ (self , name : str ) -> object :
274302 "Get metadata key"
275303 return self .metadata [name ]
276304
277- def __contains__ (self , item ) :
305+ def __contains__ (self , item : object ) -> bool :
278306 "Check metadata contains key"
279307 return item in self .metadata
280308
281- def __setitem__ (self , name , value ) :
309+ def __setitem__ (self , name : str , value : object ) -> None :
282310 "Set a metadata key"
283311 self .metadata [name ] = value
284312
285- def __delitem__ (self , name ) :
313+ def __delitem__ (self , name : str ) -> None :
286314 "Delete a metadata key"
287315 del self .metadata [name ]
288316
289- def __bytes__ (self ):
317+ def __bytes__ (self ) -> bytes :
290318 return self .content .encode ("utf-8" )
291319
292- def __str__ (self ):
320+ def __str__ (self ) -> str :
293321 return self .content
294322
295- def get (self , key , default = None ):
323+ def get (self , key : str , default : object = None ) -> object :
296324 "Get a key, fallback to default"
297325 return self .metadata .get (key , default )
298326
299- def keys (self ):
327+ def keys (self ) -> Iterable [ str ] :
300328 "Return metadata keys"
301329 return self .metadata .keys ()
302330
303- def values (self ):
331+ def values (self ) -> Iterable [ object ] :
304332 "Return metadata values"
305333 return self .metadata .values ()
306334
307- def to_dict (self ):
335+ def to_dict (self ) -> dict [ str , object ] :
308336 "Post as a dict, for serializing"
309337 d = self .metadata .copy ()
310338 d ["content" ] = self .content
0 commit comments