icalendar
repository·main·Indexed 22 days ago
https://github.com/collective/icalendarA Python package providing an RFC 5545 compatible parser and generator of iCalendar files, used to create, inspect, and modify calendaring information.
What's inside icalendar
- icalendar is a Python package designed for handling Internet Calendaring and Scheduling (iCalendar) data. It serves as an RFC 5545 compatible parser and generator, allowing developers to create, inspect, and modify calendaring information within Python applications.
How to contribute to icalendar
mainThere are many ways to contribute to the
icalendarproject beyond code:- Issue Management: Report security issues via the Security Policy, report other issues in the tracker, comment on issues, and triage open issues or pull requests.
- Code & Docs: Submit pull requests from your fork, review existing PRs, and extend the documentation.
- Community: Participate in GitHub Discussions, write blog posts, or share announcements on social media.
- Support: Sponsor development through Open Collective.
Explore the icalendar.prop package structure
mainThe
icalendar.proppackage provides specialized property modules for handling various iCalendar data types. It is organized into subpackages for complex logic and submodules for specific data types.Subpackages
icalendar.prop.dt: Likely handles Date/Time related properties.icalendar.prop.recur: Handles recurrence rules and logic.
Data Type Submodules
The package includes dedicated modules for specific iCalendar property types, such as:
- Scalars:
boolean,float,integer,text. - Identifiers & References:
uid,uri,xml_reference,adr(Address). - Complex Types:
geo(Geospatial),categories,conference,cal_address,org(Organization). - Media & Content:
binary,image,inline. - Specialized:
factory(for property creation),broken(for handling invalid properties), andunknown.
Understand the icalendar maintenance structure
mainThe
icalendarproject uses a tiered maintenance structure consisting of Maintainers, Collaborators, and Code Owners to manage code quality, releases, and security.Maintainers
Maintainers hold full administrative permissions across the project's ecosystem, including:
- GitHub:
Adminaccess to the repository. - PyPI:
MaintainerorOwneraccess (requires 2FA). - Read the Docs:
Maintaineraccess. - GitHub Workflows:
Environments/Configure PyPIaccess to allow releases from tags. - Code of Conduct:
OwnerorManageraccess to theicalendar-coc@googlegroups.comGoogle Group. - OSS Fuzz:
Registeredaccess to the issue tracker. - Metadata: Must be listed in the
maintainerssection ofpyproject.toml.
Collaborators
Collaborators have write access to the repository. Their responsibilities include:
- Merging pull requests (note: you cannot merge your own PRs).
- Initiating new releases.
- Becoming a Code Owner.
Code Owners
A Code Owner is a collaborator or maintainer responsible for specific parts of the codebase. When a pull request modifies code in their domain, they are automatically requested for review. Ownership is defined in the
.github/CODEOWNERSfile.- GitHub:
Overview of icalendar capabilities and timezone support
mainThe
icalendarpackage provides tools to create, inspect, and modify iCalendar data compliant with RFC 5545.A key feature is its support for multiple timezone implementations, allowing you to work with various Python timezone libraries. Supported implementations include:
zoneinfodateutil.tzpytz
Note that
python-dateutilandtzdataare required dependencies.Understand icalendar versioning and branches
mainThe
icalendarproject follows Semantic Versioning (SemVer).- Major version: Incremented for breaking changes.
- Minor version: Incremented for new features.
- Patch version: Incremented for minor changes and bug fixes.
- Stable releases: Formatted as
X.Y.Z(e.g.,7.0.0). - Unstable releases: Denoted by
a,b, orrc(e.g.,7.0.0a1).
Development is organized into specific branches based on major versions, which determines Python compatibility and the type of updates received.
Identify and inspect broken properties using vBroken
mainProperties that fail to parse are converted into
vBrokeninstances. This allows you to preserve the raw value for inspection or round-trip serialization. You can identify a broken property usingisinstance(property, vBroken).vBrokeninstances provide the following metadata:property_name: The name of the property (e.g.,'DTSTART').expected_type: The type the parser expected.parse_error: The originalExceptionthat occurred during parsing.
>>> from icalendar import Calendar >>> from icalendar.prop import vBroken >>> ical_str = b"""BEGIN:VCALENDAR\n... VERSION:2.0\n... PRODID:test\n... BEGIN:VEVENT\n... UID:test-123\n... DTSTART:INVALID-DATE\n... SUMMARY:Meeting\n... END:VEVENT\n... END:VCALENDAR""" >>> cal = Calendar.from_ical(ical_str) >>> event = cal.walk("VEVENT")[0] >>> dtstart = event["DTSTART"] >>> isinstance(dtstart, vBroken) True >>> str(dtstart) 'INVALID-DATE' >>> dtstart.property_name 'DTSTART' >>> dtstart.expected_type 'vDDDTypes' >>> isinstance(dtstart.parse_error, Exception) TrueRound-trip preservation of custom components
mainThe
icalendarlibrary is designed to be round-trip safe for custom components. All X-Components and IANA-components not defined in RFC 5545 are preserved. When you parse a calendar containing unknown components and then call.to_ical(), all custom components, their properties, and their subcomponents are maintained in the output.from icalendar import Calendar original = b"""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//Test//EN BEGIN:X-VENDOR-COMPONENT X-VENDOR-PROP:proprietary UID:vendor-123 END:X-VENDOR-COMPONENT END:VCALENDAR """ cal = Calendar.from_ical(original) regenerated = cal.to_ical() # Verification assert b"X-VENDOR-COMPONENT" in regenerated assert b"X-VENDOR-PROP" in regeneratedReplace pytz with zoneinfo (Deprecated in 6.0.0)
mainStarting in version 6.0.0,pytzsupport is deprecated. It is highly recommended to migrate to the standard libraryzoneinfomodule (available in Python 3.9+). Whilepytzstill works,zoneinfois the preferred way to handle timezones inicalendar.Structure docstrings using Google Python Style Guide conventions
mainicalendar follows PEP 257 and adopts conventions from the Google Python Style Guide. A docstring should consist of a one-line summary, followed by an optional description, and then specific sections (usually ordered by inputs then outputs).
Key Rules:
- Summary: Must be a one-line summary of the object, terminated with a period.
- Description: If the summary is insufficient, provide an overall description (avoid implementation details) separated from the summary by a blank line.
- Sections: Use a section header followed by a colon (
:) and an indented block of text. All items in a section should terminate with a period. - Class Docstrings: Do not write docstrings for
__init__or__new__methods. Instead, write the docstring for the class itself. Sphinx will automatically append__init__docstrings to the class docstring. - Escaping: To avoid double-escaping, use the raw
rindicator before the leading docstring delimiter (e.g.,r""").
"""Summary. Longer description. """Serialize partially valid data with round-trip support
mainThe
icalendarparser is error-tolerant. A single broken property does not prevent you from accessing other valid properties in the same component. Furthermore, broken properties preserve their raw values, ensuring that when you callComponent.to_ical(), the invalid data is serialized back into the output exactly as it appeared in the input.>>> from icalendar import Calendar >>> ical_str = b"""BEGIN:VCALENDAR\n... VERSION:2.0\n... PRODID:test\n... BEGIN:VEVENT\n... UID:test-123\n... DTSTART:INVALID-DATE\n... DTEND:20250102T120000Z\n... SUMMARY:Meeting\n... END:VEVENT\n... END:VCALENDAR""" >>> cal = Calendar.from_ical(ical_str) >>> event = cal.walk("VEVENT")[0] >>> # Accessing valid properties works >>> event["DTEND"].dt.year 2025 >>> str(event["SUMMARY"]) 'Meeting' >>> # Round-trip serialization preserves the error >>> output = cal.to_ical() >>> b"DTSTART:INVALID-DATE" in output TrueUse the Parameters section for function arguments
mainUse the
Parameters:section (do not useArgsorArguments) to document function inputs.Formatting Rules:
- Ordering:
- Group parameters into Required and Optional.
- Within each group, sort them alphabetically.
- Required parameters must always appear before optional parameters.
- Note: The order in the docstring must respect the order in the Python signature to avoid breaking changes, but the alphabetical sorting applies within the required/optional groups.
- Content: Each parameter should include its name and a brief description.
- Required Flag: For required attributes, include the term "Required." in the description, preferably immediately after the name.
- Types: Use Python type hints in the function signature whenever possible; Sphinx will render them automatically. If type hints are missing, you must specify the type manually in the docstring.
def some_function(creq, breq, areq, bopt=2, aopt=1, copt=3) -> type_hints: """Summary. Longer description. Parameters: areq: Required. A string. breq: Required. A string. creq: Required. A string. aopt: An integer. bopt: An integer. copt: An integer. """ pass- Ordering: