44
55import hashlib
66from datetime import datetime
7- from typing import Optional , Tuple , Union
7+ from typing import TYPE_CHECKING , Any , Optional , Sequence , Union
88
99from .actions import Action
1010from .enums import (
1414 FileAttachmentAnnotationName ,
1515)
1616from .syntax import (
17- build_obj_dict ,
1817 Destination ,
1918 Name ,
2019 PDFContentStream ,
2120 PDFDate ,
2221 PDFObject ,
2322 PDFString ,
23+ build_obj_dict ,
24+ create_dictionary_string as pdf_dict ,
25+ create_list_string as pdf_list ,
26+ iobj_ref as pdf_ref ,
2427)
25- from .syntax import create_dictionary_string as pdf_dict
26- from .syntax import create_list_string as pdf_list
27- from .syntax import iobj_ref as pdf_ref
2828
29+ if TYPE_CHECKING :
30+ from .encryption import StandardSecurityHandler
2931
3032# cf. https://docs.verapdf.org/validation/pdfa-part1/#rule-653-2
3133DEFAULT_ANNOT_FLAGS = (AnnotationFlag .PRINT ,)
@@ -35,26 +37,26 @@ class AnnotationMixin:
3537 def __init__ (
3638 self ,
3739 subtype : str ,
38- x : int ,
39- y : int ,
40- width : int ,
41- height : int ,
42- flags : Union [ Tuple [ AnnotationFlag ], Tuple [ str ] ] = DEFAULT_ANNOT_FLAGS ,
43- contents : str = None ,
44- dest : Destination = None ,
45- action : Action = None ,
46- color : tuple = None ,
47- modification_time : datetime = None ,
48- title : str = None ,
49- quad_points : tuple = None ,
50- border_width : int = 0 , # PDF readers support: displayed by Acrobat but not Sumatra
51- name : Union [AnnotationName , FileAttachmentAnnotationName ] = None ,
52- ink_list : Tuple [ int ] = () , # for ink annotations
53- file_spec : str = None ,
54- field_type : str = None ,
55- value = None ,
56- default_appearance : str = None , # for free text annotations
57- ):
40+ x : float ,
41+ y : float ,
42+ width : float ,
43+ height : float ,
44+ flags : tuple [ AnnotationFlag | str , ... ] = DEFAULT_ANNOT_FLAGS ,
45+ contents : Optional [ str ] = None ,
46+ dest : Optional [ Destination | PDFString ] = None ,
47+ action : Optional [ Action ] = None ,
48+ color : Optional [ tuple [ float , float , float ]] = None ,
49+ modification_time : Optional [ datetime ] = None ,
50+ title : Optional [ str ] = None ,
51+ quad_points : Optional [ Sequence [ float ]] = None ,
52+ border_width : float = 0 , # PDF readers support: displayed by Acrobat but not Sumatra
53+ name : Union [AnnotationName , FileAttachmentAnnotationName , None ] = None ,
54+ ink_list : Optional [ tuple [ float , ...]] = None , # for ink annotations
55+ file_spec : Optional [ Union [ "FileSpec" , str ]] = None ,
56+ field_type : Optional [ str ] = None ,
57+ value : Optional [ str ] = None ,
58+ default_appearance : Optional [ str ] = None , # for free text annotations
59+ ) -> None :
5860 self .type = Name ("Annot" )
5961 self .subtype = Name (subtype )
6062 self .rect = f"[{ x :.2f} { y - height :.2f} { x + width :.2f} { y :.2f} ]"
@@ -69,14 +71,14 @@ def __init__(
6971 self .t = PDFString (title , encrypt = True ) if title else None
7072 self .m = PDFDate (modification_time , encrypt = True ) if modification_time else None
7173 self .quad_points = (
72- pdf_list (f"{ quad_point :.2f} " for quad_point in quad_points )
74+ pdf_list ([ f"{ quad_point :.2f} " for quad_point in quad_points ] )
7375 if quad_points
7476 else None
7577 )
7678 self .p = None # must always be set before calling .serialize()
7779 self .name = name
7880 self .ink_list = (
79- ("[" + pdf_list (f"{ coord :.2f} " for coord in ink_list ) + "]" )
81+ ("[" + pdf_list ([ f"{ coord :.2f} " for coord in ink_list ] ) + "]" )
8082 if ink_list
8183 else None
8284 )
@@ -87,7 +89,7 @@ def __init__(
8789class PDFAnnotation (AnnotationMixin , PDFObject ):
8890 "A PDF annotation that get serialized as an obj<</>>endobj block"
8991
90- def __init__ (self , * args , ** kwargs ) :
92+ def __init__ (self , * args : Any , ** kwargs : Any ) -> None :
9193 super ().__init__ (* args , ** kwargs )
9294
9395
@@ -115,15 +117,19 @@ class AnnotationDict(AnnotationMixin):
115117 "d_a" ,
116118 )
117119
118- def serialize (self , _security_handler = None , _obj_id = None ):
120+ def serialize (
121+ self ,
122+ _security_handler : Optional ["StandardSecurityHandler" ] = None ,
123+ _obj_id : Optional [int ] = None ,
124+ ) -> str :
119125 obj_dict = build_obj_dict (
120126 {key : getattr (self , key ) for key in dir (self )},
121127 _security_handler = _security_handler ,
122128 _obj_id = _obj_id ,
123129 )
124130 return pdf_dict (obj_dict )
125131
126- def __repr__ (self ):
132+ def __repr__ (self ) -> str :
127133 keys = [key for key in dir (self ) if not key .startswith ("__" )]
128134 d = {key : getattr (self , key ) for key in keys }
129135 d = {key : value for key , value in d .items () if not callable (value )}
@@ -145,7 +151,7 @@ def __init__(
145151 ):
146152 super ().__init__ (contents = contents , compress = compress )
147153 self .type = Name ("EmbeddedFile" )
148- params = {"/Size" : len (contents )}
154+ params : dict [ str , object ] = {"/Size" : len (contents )}
149155 if creation_date :
150156 params ["/CreationDate" ] = PDFDate (creation_date , with_tz = True ).serialize ()
151157 if modification_date :
@@ -158,22 +164,22 @@ def __init__(
158164 if mime_type :
159165 self .subtype = Name (mime_type )
160166 self .params = pdf_dict (params )
161- self ._basename = basename # private so that it does not get serialized
162- self ._desc = desc # private so that it does not get serialized
163- self ._globally_enclosed = True
164- self ._af_relationship = af_relationship
165- self ._file_spec = None
167+ self ._basename : str = basename # private so that it does not get serialized
168+ self ._desc : str = desc # private so that it does not get serialized
169+ self ._globally_enclosed : bool = True
170+ self ._af_relationship : Optional [ AssociatedFileRelationship ] = af_relationship
171+ self ._file_spec : Optional [ FileSpec ] = None
166172
167- def globally_enclosed (self ):
173+ def globally_enclosed (self ) -> bool :
168174 return self ._globally_enclosed
169175
170- def set_globally_enclosed (self , value ) :
176+ def set_globally_enclosed (self , value : bool ) -> None :
171177 self ._globally_enclosed = value
172178
173- def basename (self ):
179+ def basename (self ) -> str :
174180 return self ._basename
175181
176- def file_spec (self ):
182+ def file_spec (self ) -> "FileSpec" :
177183 if not self ._file_spec :
178184 self ._file_spec = FileSpec (
179185 self , self ._basename , self ._desc , self ._af_relationship
@@ -201,5 +207,5 @@ def __init__(
201207 self ._embedded_file = embedded_file
202208
203209 @property
204- def e_f (self ):
210+ def e_f (self ) -> str :
205211 return pdf_dict ({"/F" : pdf_ref (self ._embedded_file .id )})
0 commit comments