Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/icalendar/cal/component_factory.py: 98%

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

40 statements  

1"""A factory to create components.""" 

2 

3from __future__ import annotations 

4 

5import re 

6from typing import TYPE_CHECKING 

7 

8from icalendar.caselessdict import CaselessDict 

9 

10if TYPE_CHECKING: 

11 from icalendar import Component 

12 

13 

14class ComponentFactory(CaselessDict): 

15 """Registered components from :rfc:`7953` and :rfc:`5545`. 

16 

17 To get a component, use this class as shown below. 

18 

19 .. code-block:: pycon 

20 

21 >>> from icalendar import ComponentFactory 

22 >>> factory = ComponentFactory() 

23 >>> event_class = factory.get_component_class('VEVENT') 

24 >>> event_class() 

25 VEVENT({}) 

26 

27 If a component class is not yet supported, it can be either created 

28 using :meth:`get_component_class` or added manually as a subclass of 

29 :class:`~icalendar.Component`. 

30 """ 

31 

32 def __init__(self, *args, **kwargs): 

33 """Set keys to upper for initial dict.""" 

34 super().__init__(*args, **kwargs) 

35 from icalendar.cal.alarm import Alarm 

36 from icalendar.cal.availability import Availability 

37 from icalendar.cal.available import Available 

38 from icalendar.cal.calendar import Calendar 

39 from icalendar.cal.event import Event 

40 from icalendar.cal.free_busy import FreeBusy 

41 from icalendar.cal.journal import Journal 

42 from icalendar.cal.timezone import Timezone, TimezoneDaylight, TimezoneStandard 

43 from icalendar.cal.todo import Todo 

44 

45 self.add_component_class(Calendar) 

46 self.add_component_class(Event) 

47 self.add_component_class(Todo) 

48 self.add_component_class(Journal) 

49 self.add_component_class(FreeBusy) 

50 self.add_component_class(Timezone) 

51 self.add_component_class(TimezoneStandard) 

52 self.add_component_class(TimezoneDaylight) 

53 self.add_component_class(Alarm) 

54 self.add_component_class(Available) 

55 self.add_component_class(Availability) 

56 

57 def add_component_class(self, cls: type[Component]) -> None: 

58 """Add a component class to the factory. 

59 

60 Args: 

61 cls: The component class to add. 

62 """ 

63 self[cls.name] = cls 

64 

65 def get_component_class(self, name: str) -> type[Component]: 

66 """Get the component class from the factory. 

67 

68 This also creates and adds the component class if it does not exist. 

69 

70 Args: 

71 name: The name of the component, for example, ``"VCALENDAR"``. 

72 

73 Returns: 

74 The registered component class. 

75 """ 

76 component_class = self.get(name) 

77 if component_class is None: 

78 from icalendar.cal.component import Component 

79 

80 component_class = type( 

81 re.sub(r"[^\w]+", "", name), (Component,), {"name": name.upper()} 

82 ) 

83 self.add_component_class(component_class) 

84 return component_class 

85 

86 

87__all__ = ["ComponentFactory"]