Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pikepdf/models/metadata/_docinfo.py: 42%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

31 statements  

1# SPDX-FileCopyrightText: 2022 James R. Barlow 

2# SPDX-License-Identifier: MPL-2.0 

3 

4"""DocumentInfo dictionary access with type-safe operations.""" 

5 

6from __future__ import annotations 

7 

8from collections.abc import Iterator 

9from typing import TYPE_CHECKING 

10 

11from pikepdf.models.metadata._constants import clean 

12from pikepdf.objects import Name 

13 

14if TYPE_CHECKING: # pragma: no cover 

15 from pikepdf import Pdf 

16 

17 

18class DocinfoStore: 

19 """Wrapper for PDF DocumentInfo dictionary operations. 

20 

21 Handles reading and writing values with proper encoding (ASCII/UTF-16) 

22 and character cleaning. 

23 """ 

24 

25 def __init__(self, pdf: Pdf): 

26 """Initialize with PDF reference. 

27 

28 Args: 

29 pdf: The PDF document to manage DocumentInfo for. 

30 """ 

31 self._pdf = pdf 

32 

33 def get(self, name: Name) -> str | None: 

34 """Get DocumentInfo value. 

35 

36 Args: 

37 name: The DocumentInfo key (e.g., Name.Title). 

38 

39 Returns: 

40 The value as string, or None if not present. 

41 """ 

42 if name not in self._pdf.docinfo: 

43 return None 

44 val = self._pdf.docinfo[name] 

45 return str(val) if val is not None else None 

46 

47 def set(self, name: Name, value: str) -> None: 

48 """Set DocumentInfo value with proper encoding. 

49 

50 Values that can be encoded as ASCII are stored as ASCII, 

51 otherwise stored as UTF-16 with BOM. 

52 

53 Args: 

54 name: The DocumentInfo key (e.g., Name.Title). 

55 value: The string value to set. 

56 """ 

57 # Ensure docinfo exists 

58 self._pdf.docinfo # pylint: disable=pointless-statement 

59 value = clean(value) 

60 try: 

61 # Try to save pure ASCII 

62 self._pdf.docinfo[name] = value.encode('ascii') 

63 except UnicodeEncodeError: 

64 # qpdf will serialize this as a UTF-16 with BOM string 

65 self._pdf.docinfo[name] = value 

66 

67 def delete(self, name: Name) -> bool: 

68 """Delete DocumentInfo key. 

69 

70 Args: 

71 name: The DocumentInfo key to delete. 

72 

73 Returns: 

74 True if key was present and deleted, False if not present. 

75 """ 

76 if name in self._pdf.docinfo: 

77 del self._pdf.docinfo[name] 

78 return True 

79 return False 

80 

81 def __contains__(self, name: Name) -> bool: 

82 """Check if key exists in DocumentInfo.""" 

83 return name in self._pdf.docinfo 

84 

85 def keys(self) -> Iterator[Name]: 

86 """Iterate DocumentInfo keys.""" 

87 yield from self._pdf.docinfo.keys() # type: ignore[misc]