icalendar

repository·main·Indexed 22 days ago

https://github.com/collective/icalendar

A Python package providing an RFC 5545 compatible parser and generator of iCalendar files, used to create, inspect, and modify calendaring information.

Tokens
30.7K
Snippets
109
Records
143
Agent score
77%

What's inside icalendar

  1. Overview of icalendar

    main
    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.
  2. How to contribute to icalendar

    main

    There are many ways to contribute to the icalendar project 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.
  3. Explore the icalendar.prop package structure

    main

    The icalendar.prop package 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), and unknown.
  4. Understand the icalendar maintenance structure

    main

    The icalendar project 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: Admin access to the repository.
    • PyPI: Maintainer or Owner access (requires 2FA).
    • Read the Docs: Maintainer access.
    • GitHub Workflows: Environments/Configure PyPI access to allow releases from tags.
    • Code of Conduct: Owner or Manager access to the icalendar-coc@googlegroups.com Google Group.
    • OSS Fuzz: Registered access to the issue tracker.
    • Metadata: Must be listed in the maintainers section of pyproject.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/CODEOWNERS file.

  5. Overview of icalendar capabilities and timezone support

    main

    The icalendar package 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:

    • zoneinfo
    • dateutil.tz
    • pytz

    Note that python-dateutil and tzdata are required dependencies.

  6. Understand icalendar versioning and branches

    main

    The icalendar project 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, or rc (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.

  7. Identify and inspect broken properties using vBroken

    main

    Properties that fail to parse are converted into vBroken instances. This allows you to preserve the raw value for inspection or round-trip serialization. You can identify a broken property using isinstance(property, vBroken).

    vBroken instances provide the following metadata:

    • property_name: The name of the property (e.g., 'DTSTART').
    • expected_type: The type the parser expected.
    • parse_error: The original Exception that 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)
    True
  8. Round-trip preservation of custom components

    main

    The icalendar library 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 regenerated
  9. Replace pytz with zoneinfo (Deprecated in 6.0.0)

    main
    Starting in version 6.0.0, pytz support is deprecated. It is highly recommended to migrate to the standard library zoneinfo module (available in Python 3.9+). While pytz still works, zoneinfo is the preferred way to handle timezones in icalendar.
  10. Structure docstrings using Google Python Style Guide conventions

    main

    icalendar 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 r indicator before the leading docstring delimiter (e.g., r""").
    """Summary.
    
    Longer description.
    """
  11. Serialize partially valid data with round-trip support

    main

    The icalendar parser 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 call Component.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
    True
  12. Use the Parameters section for function arguments

    main

    Use the Parameters: section (do not use Args or Arguments) to document function inputs.

    Formatting Rules:

    1. 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.
    2. Content: Each parameter should include its name and a brief description.
    3. Required Flag: For required attributes, include the term "Required." in the description, preferably immediately after the name.
    4. 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