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

refactor: improve logging, logic, and type annotations #151

Merged
merged 16 commits into from
Dec 9, 2024

Conversation

jjjermiah
Copy link
Contributor

@jjjermiah jjjermiah commented Dec 9, 2024

Summary by CodeRabbit

  • New Features

    • Enhanced logging flexibility with new parameters for specifying logger names.
    • Improved progress reporting in the folder crawling process with descriptive progress bars.
  • Bug Fixes

    • Updated error handling for invalid file actions and DICOM tag checks for clearer user feedback.
  • Documentation

    • Improved docstring clarity and formatting across multiple functions.
  • Refactor

    • Streamlined configuration files for testing and linting processes.
    • Restructured class and function definitions for better readability and maintainability.
  • Style

    • Consistent formatting applied to function signatures and docstrings.

Copy link
Contributor

coderabbitai bot commented Dec 9, 2024

Warning

Rate limit exceeded

@jjjermiah has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 25 minutes and 10 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 046ed33 and 70b03ec.

⛔ Files ignored due to path filters (1)
  • pixi.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • .github/workflows/main.yml (3 hunks)
  • pixi.toml (3 hunks)
  • src/imgtools/io/common.py (0 hunks)

Walkthrough

The pull request includes significant updates to configuration files and source code to enhance type checking, linting, and logging functionality. The mypy.ini file specifies directories for type checking and introduces new type checking options. The pytest.ini file sets a minimum pytest version and adds command-line options for improved test reporting. The ruff.toml file updates linting rules and includes/excludes specific directories. Source code changes focus on improving logging flexibility, enhancing error handling, and refining class methods for better readability and maintainability.

Changes

File Change Summary
config/mypy.ini Updated type checking directories, excluded specific files, set Python version, and added options for stricter type checking.
config/pytest.ini Removed warning filters, set minimum pytest version, added command-line options for test execution and reporting.
config/ruff.toml Updated include/exclude sections, added ignore rules, and maintained linting rules.
pixi.toml Simplified test task command and inputs, updated dependencies, and adjusted task descriptions.
src/imgtools/cli/init.py Modified set_log_verbosity to include a logger_name parameter for enhanced logging flexibility.
src/imgtools/dicom/index/init.py Added a newline at the end of the file in the __all__ declaration.
src/imgtools/dicom/index/main.py Reformatted index function signature for readability; no functional changes.
src/imgtools/dicom/index/database/init.py Minor change to import statement; no functional impact.
src/imgtools/dicom/index/models/models.py Updated ROINames property formatting for consistency; no functional changes.
src/imgtools/dicom/sort/dicomsorter.py Changed execute method parameter to accept `FileAction
src/imgtools/dicom/sort/sort_method.py Updated handle_file function to accept `FileAction
src/imgtools/io/common.py Removed find_dicom_paths function, altering DICOM path discovery functionality.
src/imgtools/io/loaders.py Added suppress_warnings parameter to read_dicom_rtstruct function for warning control.
src/imgtools/modules/datagraph.py Updated regex handling in graph_query method for improved clarity; enhanced error handling.
src/imgtools/modules/structureset.py Added suppress_warnings parameter to from_dicom_rtstruct method for flexible warning logging.
src/imgtools/ops/functional.py Reformatted function definitions and docstrings for consistency; no functional changes.
src/imgtools/ops/ops.py Renamed BetaAutoInput to ImageAutoInput and restructured constructor for clarity.
src/imgtools/utils/crawl.py Enhanced progress reporting in crawl function by adding a description to the progress bar.

Possibly related PRs

🐰 "In the code we hop and play,
With types and tests to light the way.
From mypy checks to pytest's cheer,
Our tools are sharp, our path is clear!
With logging bright, we track our quest,
In every line, we strive for the best!" 🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ 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 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
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: 2

🧹 Outside diff range and nitpick comments (18)
src/imgtools/modules/structureset.py (1)

40-40: Add type annotation for suppress_warnings parameter

The method signature could be improved by adding a type annotation for the new parameter.

-def from_dicom_rtstruct(cls, rtstruct_path: str, suppress_warnings: bool = False) -> 'StructureSet':
+def from_dicom_rtstruct(cls, rtstruct_path: str, suppress_warnings: bool = False) -> 'StructureSet':
src/imgtools/io/loaders.py (1)

80-81: Add type hints to read_dicom_rtstruct function

The function should include type hints for consistency with other functions in the module.

-def read_dicom_rtstruct(path, suppress_warnings=False):
+def read_dicom_rtstruct(path: str, suppress_warnings: bool = False) -> StructureSet:
src/imgtools/dicom/sort/sort_method.py (1)

Line range hint 109-127: Consider enhancing error messages with examples

The error handling is comprehensive, but the error messages could be more helpful by including usage examples.

 if not source_path.exists():
-    msg = f'Source does not exist: {source_path}'
+    msg = f'Source does not exist: {source_path}. Ensure the file exists before proceeding.'
 if not overwrite and resolved_path.exists():
-    msg = f'Destination already exists: {resolved_path}'
+    msg = f'Destination already exists: {resolved_path}. Use overwrite=True to force the operation.'
src/imgtools/dicom/sort/dicomsorter.py (1)

Line range hint 99-127: Consider enhancing logging for better debugging

While the error handling is comprehensive, adding more detailed logging could help with debugging issues in production.

 if not isinstance(action, FileAction):
+    self.logger.debug(f'Converting string action "{action}" to FileAction')
     action = FileAction.validate(action)
+    self.logger.debug(f'Action validated successfully: {action}')
config/pytest.ini (2)

17-26: Consider using variables for coverage report paths

The coverage report paths could be made more maintainable by using variables. This would make it easier to update all paths at once if needed.

-    --cov-report=xml:coverage-report/coverage.xml
-    --cov-report=html:coverage-report/htmlcov
+    --cov-report=xml:${COVERAGE_DIR}/coverage.xml
+    --cov-report=html:${COVERAGE_DIR}/htmlcov

8-29: Consider adding parallel test execution configuration

For larger test suites, parallel execution can significantly reduce test runtime. Consider adding the --numprocesses auto option if using pytest-xdist.

addopts =
    --verbose
    --showlocals
+    --numprocesses auto
    --cov=imgtools
src/imgtools/cli/__init__.py (2)

8-12: Update docstring to include new parameter

The docstring is missing documentation for the logger_name parameter.

 def set_log_verbosity(
     *param_decls: str,
     logger_name: str = 'imgtools',
     quiet_decl: tuple = ('--quiet', '-q'),
     **kwargs: Any,  # noqa
 ) -> Callable[[FC], FC]:
     """
     Add a `--verbose` option to set the logging level based on verbosity count
     and a `--quiet` option to suppress all logging except errors.

     Parameters
     ----------
     *param_decls : str
         Custom names for the verbosity flag.
+    logger_name : str, optional
+        Name of the logger to configure, defaults to 'imgtools'.
     quiet_decl : tuple
         Tuple containing custom names for the quiet flag.
     **kwargs : Any
         Additional keyword arguments for the click option.

Line range hint 31-50: Simplify callback logic and improve type safety

The callback function could be simplified and made more type-safe:

  1. Use an Enum for logging levels
  2. Simplify the level comparison logic
+from enum import IntEnum
+
+class LogLevel(IntEnum):
+    ERROR = 0
+    WARNING = 1
+    INFO = 2
+    DEBUG = 3

 def callback(ctx: click.Context, param: click.Parameter, value: int) -> None:
-    levels = {0: 'ERROR', 1: 'WARNING', 2: 'INFO', 3: 'DEBUG'}
-    level = levels.get(value, 'DEBUG')  # Default to DEBUG if verbosity is high
+    level = LogLevel(min(value, LogLevel.DEBUG)).name
     logger = getLogger(logger_name)
     
     if ctx.params.get('quiet', False):
         logger.setLevel(ERROR)
         return

     levelvalue = getLevelName(level)
-    env_level = logger.level
-
-    # Override environment variable if verbosity level is passed
-    if levelvalue > env_level and value != 0:
+    if value != 0 and levelvalue > logger.level:
         logger.warning(
-            f'Environment variable {logger.name.upper()}_LOG_LEVEL is {getLevelName(env_level)} but '
+            f'Environment variable {logger.name.upper()}_LOG_LEVEL is {getLevelName(logger.level)} but '
             f'you are setting it to {getLevelName(levelvalue)}'
         )
-        logger.setLevel(levelvalue)
-    else:
-        logger.setLevel(min(levelvalue, env_level))
+    logger.setLevel(levelvalue)
src/imgtools/dicom/index/__main__.py (3)

10-11: Consider moving constants to a configuration file

The database path constants should be moved to a configuration file for better maintainability and flexibility.

Consider creating a config.py file:

from pathlib import Path

class DatabaseConfig:
    DEFAULT_DIR = Path('.imgtools')
    DEFAULT_NAME = 'imgtools.db'
    
    @classmethod
    def get_default_path(cls) -> Path:
        return cls.DEFAULT_DIR / cls.DEFAULT_NAME

Line range hint 65-73: Enhance error handling and logging structure

The warning message could be improved with structured logging and better error handling.

 if not dicom_files:
-    warningmsg = f'No DICOM files found in {directory}.'
     logger.warning(
-        warningmsg,
+        'No DICOM files found in directory',
         directory=directory,
         check_header=check_header,
         recursive=True,
         extension=extension,
+        error_code='NO_DICOM_FILES'
     )
-    return
+    raise click.UsageError('No DICOM files found. Please check the directory path and file extensions.')

88-89: Add progress tracking for long-running operations

The index building operation could benefit from progress tracking for better user experience.

-indexer.build_index_from_files(dicom_files)
+with click.progressbar(dicom_files, label='Building index') as files:
+    indexer.build_index_from_files(files)
config/mypy.ini (1)

23-37: Consider gradual adoption of strict type checking

The configuration enables multiple strict type checking options simultaneously. Consider implementing these checks gradually to make the transition smoother:

  1. Start with disallow_untyped_defs
  2. Then enable check_untyped_defs
  3. Finally add disallow_incomplete_defs and disallow_untyped_decorators

This approach would help manage the technical debt more effectively.

config/ruff.toml (2)

Line range hint 6-11: Simplify file inclusion strategy

The current approach of commenting out certain paths (src/imgtools/cli/**/*.py, src/imgtools/utils/crawl.py) makes the configuration harder to maintain. Consider either:

  1. Including them with specific rule exemptions, or
  2. Removing the commented lines to keep the configuration clean

101-108: Document rule ignores

Some ignored rules lack documentation explaining why they're ignored:

  • PLR2004: Magic numbers
  • D206: Docstring indentation
  • N813: Camelcase import

Consider adding comments explaining the rationale for ignoring these rules, similar to the existing comment for COM812.

pixi.toml (1)

116-118: Consider adding format verification step

The _ruff-format task depends on _ruff-check, but there's no verification that the formatting was successful. Consider adding a post-format check to ensure the changes were applied correctly.

 _ruff-format.cmd = ["ruff", "--config", "config/ruff.toml", "format", "src"]
 _ruff-format.inputs = ["config/ruff.toml", "src"]
 _ruff-format.depends_on = ["_ruff-check"]
+_ruff-format.outputs = ["src"]
 _ruff-format.description = "Run ruff format, run check first"
+
+_verify-format.cmd = ["ruff", "--config", "config/ruff.toml", "check", "src"]
+_verify-format.inputs = ["config/ruff.toml", "src"]
+_verify-format.depends_on = ["_ruff-format"]
+_verify-format.description = "Verify formatting was applied correctly"
src/imgtools/utils/crawl.py (1)

Line range hint 119-121: Improve error handling to align with PR objectives.

The current error handling could be enhanced to:

  1. Use the logger instead of print
  2. Catch specific exceptions instead of bare except
  3. Consider whether silently passing errors is appropriate

Consider this improvement:

-            except Exception as e:
-                print(folder, e)
-                pass
+            except Exception as e:
+                logger.error(f"Error processing DICOM in {folder}: {str(e)}")
+                # Consider whether to continue or raise based on error severity
🧰 Tools
🪛 Ruff (0.8.0)

186-186: f-string without any placeholders

Remove extraneous f prefix

(F541)

src/imgtools/ops/ops.py (2)

136-138: Remove commented-out code

The old path construction code is commented out and should be removed since it's no longer needed and the new implementation is better.

-        # self.csv_path = pathlib.Path(self.parent, ".imgtools", f"imgtools_{self.dataset_name}.csv")
-        # self.json_path =  pathlib.Path(self.parent, ".imgtools", f'imgtools_{self.dataset}.json')
-        # self.edge_path  = pathlib.Path(self.parent,".imgtools",f"imgtools_{self.dataset_name}_edges.csv")

163-167: Consider improving readability of the output streams construction

While the list comprehension is efficient, the code could be more readable with:

  1. Better variable names
  2. A brief comment explaining the purpose
  3. Breaking down the complex list comprehension
+        # Extract modality names from folder column names (e.g., "folder_CT" -> "CT")
         self.output_streams = [
-            ("_").join(cols.split("_")[1:]) 
-            for cols in self.df_combined.columns 
-            if cols.split("_")[0] == "folder"
+            "_".join(column_name.split("_")[1:])  # Join all parts after "folder_"
+            for column_name in self.df_combined.columns 
+            if column_name.startswith("folder_")
         ]
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 07a41fe and 046ed33.

⛔ Files ignored due to path filters (1)
  • pixi.lock is excluded by !**/*.lock
📒 Files selected for processing (18)
  • config/mypy.ini (1 hunks)
  • config/pytest.ini (1 hunks)
  • config/ruff.toml (2 hunks)
  • pixi.toml (2 hunks)
  • src/imgtools/cli/__init__.py (2 hunks)
  • src/imgtools/dicom/index/__init__.py (1 hunks)
  • src/imgtools/dicom/index/__main__.py (3 hunks)
  • src/imgtools/dicom/index/database/__init__.py (1 hunks)
  • src/imgtools/dicom/index/models/models.py (4 hunks)
  • src/imgtools/dicom/sort/dicomsorter.py (1 hunks)
  • src/imgtools/dicom/sort/sort_method.py (1 hunks)
  • src/imgtools/io/common.py (1 hunks)
  • src/imgtools/io/loaders.py (1 hunks)
  • src/imgtools/modules/datagraph.py (1 hunks)
  • src/imgtools/modules/structureset.py (1 hunks)
  • src/imgtools/ops/functional.py (2 hunks)
  • src/imgtools/ops/ops.py (4 hunks)
  • src/imgtools/utils/crawl.py (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • src/imgtools/dicom/index/init.py
  • src/imgtools/dicom/index/database/init.py
🧰 Additional context used
🪛 Ruff (0.8.0)
src/imgtools/io/common.py

3-3: typing.Generator imported but unused

Remove unused import: typing.Generator

(F401)

🔇 Additional comments (18)
src/imgtools/modules/structureset.py (1)

48-49: LGTM! Warning suppression implementation is clean and effective

The conditional warning implementation preserves error context and includes the file path for better debugging.

src/imgtools/io/loaders.py (1)

80-81: Verify warning suppression propagation in the codebase

Let's ensure the warning suppression parameter is properly propagated through all RTSTRUCT loading paths.

✅ Verification successful

Let me analyze the propagation of the warning suppression parameter by checking the implementation of StructureSet.from_dicom_rtstruct.


Warning suppression parameter is properly propagated

The warning suppression parameter is correctly propagated through the entire call chain:

  1. read_dicom_rtstruct(path, suppress_warnings=False) accepts the parameter and passes it directly to
  2. StructureSet.from_dicom_rtstruct(path, suppress_warnings=suppress_warnings) which uses it to control warning logging when ROI points cannot be retrieved
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for all calls to read_dicom_rtstruct and from_dicom_rtstruct
echo "Checking direct calls to read_dicom_rtstruct:"
rg "read_dicom_rtstruct\(" -A 2

echo -e "\nChecking calls through read_dicom_auto:"
rg "read_dicom_auto\(" -A 5

echo -e "\nChecking for any other RTSTRUCT loading patterns:"
rg "RTSTRUCT" -A 5

Length of output: 40571


Script:

#!/bin/bash
# Search for the implementation of from_dicom_rtstruct method
ast-grep --pattern 'def from_dicom_rtstruct($$$)'

# Also search for any other potential warning suppression handling
rg "suppress_warning" -A 3

Length of output: 1132

src/imgtools/io/common.py (1)

Line range hint 1-24: Verify the impact of removing find_dicom_paths

The removal of find_dicom_paths function could affect DICOM file discovery functionality. Let's verify if this functionality has been moved elsewhere or if it's still needed.

✅ Verification successful

Based on the search results, I can now generate the final response:

The removal of find_dicom_paths is safe as alternative DICOM discovery functionality exists

The codebase has robust DICOM file discovery functionality through:

  • find_dicoms() in src/imgtools/dicom/utils.py - A comprehensive function that handles DICOM file discovery with support for recursion, header validation, and filtering
  • crawl_one() in src/imgtools/utils/crawl.py - Provides DICOM file discovery within folder hierarchies
  • read_dicom_auto() in src/imgtools/io/loaders.py - Handles both single DICOM files and directories containing DICOM files

The removed find_dicom_paths function's functionality has been effectively replaced by these implementations, particularly the more feature-rich find_dicoms().

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining references to find_dicom_paths
rg "find_dicom_paths"

# Search for alternative DICOM path discovery implementations
ast-grep --pattern 'def $func($$$) {
  $$$
  is_dicom($$$)
  $$$
}'

Length of output: 91


Script:

#!/bin/bash
# Search for any references to find_dicom_paths in git history
git log -p | rg "find_dicom_paths"

# Search for functions that might handle DICOM file discovery
rg -A 5 "\.dcm|is_dicom|pydicom"

# Look for Python files that might contain DICOM-related functionality
fd -e py | xargs rg "dicom" -l

Length of output: 41170


Script:

#!/bin/bash
# Search for alternative DICOM file discovery implementations
rg -A 10 "def find_dicoms|def crawl_one|def read_dicom"

# Look for imports or usage of find_dicom_paths in the codebase
rg "find_dicom_paths"

# Check if there are any other functions that handle DICOM file discovery
ast-grep --pattern 'def $func($$$) {
  $$$
  glob.glob($$$dcm$$$)
  $$$
}'

Length of output: 4568

🧰 Tools
🪛 Ruff (0.8.0)

1-1: os imported but unused

Remove unused import: os

(F401)


2-2: pathlib imported but unused

Remove unused import: pathlib

(F401)


3-3: typing.Generator imported but unused

Remove unused import: typing.Generator

(F401)


5-5: pydicom.misc.is_dicom imported but unused

Remove unused import: pydicom.misc.is_dicom

(F401)

src/imgtools/dicom/sort/sort_method.py (1)

108-108: LGTM! Type annotation enhancement improves flexibility

The union type FileAction | str allows for more flexible usage while maintaining type safety through validation.

src/imgtools/dicom/sort/dicomsorter.py (2)

98-98: LGTM! Consistent type enhancement

The type annotation change aligns with the updates in sort_method.py, maintaining consistency across the codebase.


Line range hint 128-150: LGTM! Robust parallel processing implementation

The implementation of parallel processing with proper progress tracking and error handling is well done.

config/pytest.ini (1)

28-29: Verify the coverage configuration file extension

The path config/coverage.toml is unusual as coverage.py typically uses .ini, .cfg, or .coveragerc file extensions.

✅ Verification successful

Let me verify the content of the TOML file to ensure it's a valid coverage configuration file.


The .toml extension for coverage configuration is valid and correctly used

The coverage configuration file uses the TOML format which is supported by coverage.py through its integration with pyproject.toml standards. The file contains valid coverage configuration sections ([tool.coverage.run] and [tool.coverage.report]) following the expected schema. The usage of TOML format is actually a modern and recommended approach for Python tools configuration.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the coverage config file exists with the specified extension
if [ -f "config/coverage.toml" ]; then
    echo "Coverage config file exists with .toml extension"
else
    echo "Coverage config file not found with .toml extension"
    # Check for other common extensions
    for ext in ini cfg coveragerc; do
        if [ -f "config/coverage.$ext" ]; then
            echo "Found coverage config with .$ext extension"
        fi
    done
fi

Length of output: 140


Script:

#!/bin/bash
# Check the content of the coverage.toml file
if [ -f "config/coverage.toml" ]; then
    echo "Content of coverage.toml:"
    cat "config/coverage.toml"
    
    # Also check if coverage.py is listed in requirements
    echo -e "\nChecking for coverage.py in requirements:"
    rg "coverage" "*requirements*.txt" || true
fi

Length of output: 439

config/mypy.ini (1)

13-14: Verify Python version compatibility

The mypy configuration specifies Python 3.10, but the project's default Python version in pixi.toml is 3.12. Consider updating this to match the project's default Python version.

pixi.toml (1)

63-65: Verify test configuration changes

The test command has been simplified to use pytest.ini. Ensure that all necessary pytest options are properly configured in the referenced config file.

✅ Verification successful

Test configuration is properly set up and comprehensive

The pytest.ini configuration file contains all necessary settings:

  • Coverage reporting with multiple formats (terminal, XML, HTML)
  • Proper test discovery paths and patterns
  • Comprehensive test markers for categorization
  • Verbose output and debugging options
  • Coverage configuration linked correctly to coverage.toml
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if pytest.ini exists and contains necessary configurations
if [ -f config/pytest.ini ]; then
    echo "pytest.ini configurations:"
    cat config/pytest.ini
else
    echo "Warning: config/pytest.ini not found"
fi

Length of output: 1910

src/imgtools/dicom/index/models/models.py (2)

294-298: LGTM! Improved code readability.

The refactoring of nested attribute access into a more readable format with proper indentation and parentheses makes the code easier to understand while maintaining the same functionality.

Also applies to: 301-301


Line range hint 304-307: LGTM! Robust error handling implementation.

The error handling follows best practices by:

  • Logging errors with context (file path)
  • Preserving the original exception stack trace
src/imgtools/utils/crawl.py (1)

184-184: LGTM! Enhanced progress reporting.

The addition of a descriptive label and cleanup behavior to the progress bar improves user feedback during the crawling process.

src/imgtools/ops/functional.py (3)

2-7: LGTM! Enhanced type annotations and import organization.

The changes improve code quality by:

  • Adding comprehensive type hints
  • Organizing imports logically

25-65: LGTM! Improved docstring formatting and consistency.

The docstring improvements follow NumPy style guidelines and maintain consistent formatting throughout the file, enhancing code documentation.

Also applies to: 118-149, 178-212


67-71: LGTM! Enhanced error handling with proper exception chaining.

The error handling improvements:

  • Use proper exception chaining with 'raise from'
  • Provide clear error messages with available options
  • Preserve the original exception context
src/imgtools/modules/datagraph.py (1)

430-433: Improved regex pattern construction!

The changes enhance the regex pattern by:

  1. Using non-capturing groups for better performance
  2. Explicitly setting regex=True for clarity
  3. Using f-string for better readability
src/imgtools/ops/ops.py (2)

122-122: Good use of class-level configuration!

Defining imgtools_dir as a class variable follows the DRY principle and makes the configuration more maintainable.


132-134: Excellent use of pathlib.Path!

Using pathlib.Path for path handling is a better practice as it:

  1. Provides cross-platform compatibility
  2. Offers cleaner path manipulation with the / operator
  3. Makes the code more maintainable

src/imgtools/io/common.py Outdated Show resolved Hide resolved
config/mypy.ini Show resolved Hide resolved
jjjermiah and others added 2 commits December 9, 2024 10:31
…ons version 24.10.0 for improved compatibility
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link

codecov bot commented Dec 9, 2024

Codecov Report

Attention: Patch coverage is 64.63415% with 58 lines in your changes missing coverage. Please review.

Project coverage is 43.90%. Comparing base (95a2179) to head (70b03ec).
Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
src/imgtools/ops/functional.py 61.76% 52 Missing ⚠️
src/imgtools/dicom/index/__main__.py 0.00% 2 Missing ⚠️
src/imgtools/dicom/index/models/models.py 0.00% 2 Missing ⚠️
src/imgtools/dicom/index/__init__.py 0.00% 1 Missing ⚠️
src/imgtools/dicom/index/database/__init__.py 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #151      +/-   ##
==========================================
+ Coverage   43.46%   43.90%   +0.44%     
==========================================
  Files          48       48              
  Lines        3640     3603      -37     
==========================================
  Hits         1582     1582              
+ Misses       2058     2021      -37     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@jjjermiah jjjermiah merged commit ef4d0e7 into main Dec 9, 2024
17 checks passed
@jjjermiah jjjermiah deleted the jjjermiah/refactor/small-fixes branch December 9, 2024 16:42
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