Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move interval object and tests into separate files #115

Merged
merged 3 commits into from
Mar 5, 2025

Conversation

rlskoeser
Copy link
Member

@rlskoeser rlskoeser commented Mar 5, 2025

Pulled the file reorganization out of #114 in hopes it would make it easier to review the new functionality

Summary by CodeRabbit

  • Documentation

    • Revised documentation with updated section titles and clearer presentation of date and interval features.
  • New Features

    • Introduced a Calendar component to enhance public date handling.
    • Added a new date interval functionality for representing and validating uncertain date ranges.
  • Refactor

    • Streamlined module imports and restructured API references for improved code organization.
  • Tests

    • Added a comprehensive test suite for the new date interval functionality.
    • Removed tests related to the previous UndateInterval class, reducing test coverage.

Copy link
Contributor

coderabbitai bot commented Mar 5, 2025

Note

Reviews paused

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Walkthrough

The pull request reorganizes the documentation and updates module imports across the project. The docs now rename a section and replace the UndateInterval reference with a new Calendar reference, while also moving the original UndateInterval reference to a different namespace. The public API in __init__.py is updated to include Calendar. Import statements in several converters and transformers have been simplified by referencing undate directly. Furthermore, the UndateInterval class is moved to its own file, with its definition removed from undate.py, and the associated tests are updated accordingly.

Changes

File(s) Change Summary
docs/undate/core.rst Renamed section from "undates and undate intervals" to "dates, intervals, and calendar"; replaced the UndateInterval reference with a new Calendar reference and moved the original to a different namespace.
src/undate/__init__.py Updated import statements to include Calendar and modified the __all__ declaration to add Calendar alongside existing entities.
src/undate/converters/calendars/{hebrew,hijri}/* Changed import paths in both converters and transformers from undate.undate to undate for Undate, UndateInterval, and Calendar.
src/undate/converters/{edtf,iso8601}/*.py Simplified import statements by moving imports for Undate and UndateInterval from undate.undate to undate.
src/undate/{interval.py, undate.py} Introduced a new UndateInterval class in interval.py and removed its definition from undate.py, updating the parse method to reflect the change.
tests/{test_converters, test_interval.py, test_undate.py} Updated test import paths to the new module structure; added comprehensive tests for UndateInterval in a new file and removed the legacy TestUndateInterval class.

Possibly related PRs

  • EDTF demo/validation notebook #98: The changes in the main PR focus on reorganizing and renaming documentation related to the UndateInterval and Calendar classes, while the retrieved PR introduces a notebook that demonstrates the use of the UndateInterval class, indicating a direct relationship in terms of the classes being referenced.

Suggested reviewers

  • ColeDCrawford
  • robcast

Poem

I'm a little coder bunny, hopping through each line,
Changing docs and imports, making everything align.
New intervals and calendars now dance in the light,
With tidy tests and modules, the code feels just right.
My whiskers twitch with joy as I nibble on this code delight!
🐇💻✨


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/undate/interval.py (1)

66-75: Formatting logic.
Leveraging BaseDateConverter for recognized formats and raising a ValueError when unsupported keeps the class flexible. The debugging print statement (print(f"converter_cls == {converter_cls}")) might be removed or converted to a proper log statement for production.

-        print(f"converter_cls == {converter_cls}")
+        # Consider removing or using logger.debug(...) to avoid unexpected console output
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ea45598 and 0fefcec.

📒 Files selected for processing (16)
  • docs/undate/core.rst (1 hunks)
  • src/undate/__init__.py (1 hunks)
  • src/undate/converters/calendars/hebrew/converter.py (1 hunks)
  • src/undate/converters/calendars/hebrew/transformer.py (1 hunks)
  • src/undate/converters/calendars/hijri/converter.py (1 hunks)
  • src/undate/converters/calendars/hijri/transformer.py (1 hunks)
  • src/undate/converters/edtf/converter.py (1 hunks)
  • src/undate/converters/edtf/transformer.py (1 hunks)
  • src/undate/converters/iso8601.py (1 hunks)
  • src/undate/interval.py (1 hunks)
  • src/undate/undate.py (3 hunks)
  • tests/test_converters/edtf/test_edtf_transformer.py (1 hunks)
  • tests/test_converters/test_edtf.py (1 hunks)
  • tests/test_converters/test_iso8601.py (1 hunks)
  • tests/test_interval.py (1 hunks)
  • tests/test_undate.py (1 hunks)
✅ Files skipped from review due to trivial changes (9)
  • src/undate/converters/edtf/transformer.py
  • src/undate/converters/calendars/hijri/transformer.py
  • src/undate/converters/calendars/hebrew/transformer.py
  • tests/test_converters/test_edtf.py
  • src/undate/converters/calendars/hijri/converter.py
  • src/undate/converters/edtf/converter.py
  • src/undate/converters/iso8601.py
  • src/undate/converters/calendars/hebrew/converter.py
  • tests/test_converters/test_iso8601.py
⏰ Context from checks skipped due to timeout of 90000ms (10)
  • GitHub Check: python-unit (3.13)
  • GitHub Check: python-unit (3.12)
  • GitHub Check: python-unit (3.11)
  • GitHub Check: python-unit (3.10)
  • GitHub Check: python-unit (3.9)
  • GitHub Check: python-unit (3.13)
  • GitHub Check: python-unit (3.12)
  • GitHub Check: python-unit (3.11)
  • GitHub Check: python-unit (3.10)
  • GitHub Check: python-unit (3.9)
🔇 Additional comments (36)
src/undate/__init__.py (2)

4-5: Good code organization with explicit imports.

The imports are now properly structured with Calendar imported from undate.undate and UndateInterval imported from its new location in undate.interval. This clearly reflects the reorganization mentioned in the PR objectives.


7-7: Appropriate __all__ list update.

The __all__ list is correctly updated to include Calendar and maintain UndateInterval, ensuring both are part of the public API while reflecting the reorganization of the codebase.

tests/test_converters/edtf/test_edtf_transformer.py (1)

2-3: Import statement properly simplified.

The import has been correctly updated to use the public API directly from undate rather than from the specific undate.undate module. This is a good practice as it follows the principle of importing from the public API and shields the tests from internal implementation details.

docs/undate/core.rst (2)

4-5: Section title appropriately updated.

The section title has been updated from "undates and undate intervals" to "dates, intervals, and calendar", which accurately reflects the reorganized structure of the code and includes the new Calendar class.


10-14: Documentation references correctly updated.

The documentation has been properly updated to:

  1. Reference the new Calendar class from undate.undate
  2. Update the reference to UndateInterval to point to its new location in undate.interval

This ensures the documentation accurately reflects the new code organization.

tests/test_undate.py (3)

5-5: Import statement appropriately updated.

The import has been correctly updated to import Undate, UndateInterval, and Calendar directly from undate rather than from undate.undate. This follows best practices of importing from the public API.


417-419: Test for parse method retains backwards compatibility.

The test for the parse method correctly maintains compatibility with the UndateInterval class even after its relocation. This ensures that the public API functionality remains consistent despite the internal code reorganization.


454-461: Test for Calendar.get_converter is appropriately maintained.

The test for retrieving calendar converters has been properly maintained, ensuring that the Calendar functionality works as expected after the code reorganization.

src/undate/undate.py (5)

1-1: Good use of postponed evaluation of type hints.
Using from __future__ import annotations is recommended when aiming for forward references, and allows for cleaner type annotation without string literals in Python versions prior to 3.11.


3-3: Imports used for date calculations and regex.
These imports (datetime, re, and TYPE_CHECKING) look correct based on usage throughout the file. No immediate issues.

Also applies to: 5-5, 6-6


8-9: Forward reference for UndateInterval.
Conditionally importing UndateInterval under TYPE_CHECKING prevents runtime overhead. This approach is consistent with recommended Python best practices for forward references.


21-21: Additional date-related imports.
Importing ONE_DAY, ONE_MONTH_MAX, Date, DatePrecision, and Timedelta from the same module keeps related date/time utilities grouped together and improves clarity.


225-225: Clarify the parse return type docstring vs. usage.
The method signature now correctly supports returning an UndateInterval, but the docstring warns that “some parsers may return intervals.” Ensure that any parser truly capable of producing an interval is properly documented and tested. Otherwise, you may consider limiting the default use.

tests/test_interval.py (11)

1-9: Imports and fixtures.
All imports here (calendar, datetime, pytest, Undate, UndateInterval, Timedelta) appear relevant to the test suite. This is a clean setup.


10-28: Check for robust typing in test_init_types.
These tests ensure correct construction of UndateInterval from datetime.date and other unsupported types. They comprehensively cover edge cases (e.g., integers or strings). Great approach to guaranteeing correct behavior.


29-32: Interval validation.
The test correctly checks for invalid intervals where the latest is before the earliest. This strongly validates core constructor logic.


33-43: String representation.
The test confirms interval string formatting (e.g. "2022/2023", "2022/2023-05", etc.), matching the expected range representation. The coverage is straightforward and beneficial.


44-57: Format method coverage.
These checks confirm that both “EDTF” and “ISO8601” formats produce the correct string output, including open-ended intervals (../2000, 2000/..). This helps ensure consistent user-facing representations.


58-66: __repr__ details.
Validation of labeled vs. unlabeled interval representations is comprehensive. Good job verifying that labels show up appropriately.


68-75: Open range string tests.
Ensures coverage of partially known intervals and open-ended combos (e.g. "0900/", "../1900-12") to confirm consistent text output.


76-84: Equality checks.
These tests verify that intervals with matching earliest and latest are considered equal. Straightforward and thorough.


85-96: Inequality checks.
Covering distinct earliest and latest boundaries ensures correct inequality checks. All relevant differences are tested.


97-99: Minimum allowable year constraints.
Verifying Undate.MIN_ALLOWABLE_YEAR is not a leap year ensures consistent logic across boundary conditions.


100-146: Duration tests for known, unknown, and edge cases.
Thoroughly tests inclusive day calculations, unknown-year intervals, edge leaps (e.g. February spanning). Ensures correct returns (NotImplemented or exceptions) for open-ended or partially open intervals. This coverage is excellent.

src/undate/interval.py (12)

1-5: Imports for datetime and typing.
Straightforward usage aligning with the class logic. No issues noted.


7-10: Undate and date tools.
These imports from undate modules are well organized. Ensure ONE_YEAR is used accurately for year computations.


12-12: New UndateInterval class.
Introducing this class clarifies date-range logic separate from Undate. The additional docstring helps maintain readability.


31-36: Constructor signature.
Optional earliest/latest Undate objects and an optional label are intuitive. Nicely typed for clarity in the docstring.


37-47: Earliest date type handling.
Conversion from datetime.date to Undate is a good convenience. The ValueError for unsupported types is explicit and user-friendly.


48-52: Latest date type handling.
Symmetrically done, matching earliest date logic. This consistency is beneficial to prevent silent conversion mismatches.


54-56: Interval validity check.
Raising a ValueError if latest <= earliest ensures data integrity for legitimate intervals. Good early check.


58-60: Assigning constructor parameters.
Straightforward assignment of earliest, latest, label. Clear and maintainable.


62-65: __str__ method returning EDTF-like open intervals.
The .. prefix usage for open start is creative and consistent with extended interval formats.


76-80: __repr__ includes optional label.
Display of label in single quotes is consistent with how Undate does it, ensuring a uniform debugging experience.


81-84: Equality check.
Comparing earliest and latest suffices for interval equality. Straightforward implementation.


85-126: Comprehensive duration logic.

  1. Correctly returns NotImplemented for open-ended intervals.
  2. Inclusive day count for fully known intervals.
  3. Intelligent handling of unknown-year intervals using one-year offsets.
  4. Raises NotImplementedError when only one year is known.

Overall, well-structured. This behavior is fully covered in tests/test_interval.py.

@rlskoeser
Copy link
Member Author

@coderabbitai ignore

Copy link
Contributor

coderabbitai bot commented Mar 5, 2025

✅ Actions performed

Reviews paused.

@rlskoeser rlskoeser merged commit 6eaa0be into develop Mar 5, 2025
7 checks passed
@rlskoeser rlskoeser deleted the feature/reorg-interval branch March 5, 2025 23:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant