-
Notifications
You must be signed in to change notification settings - Fork 8
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
Implement default submission template #338
Conversation
Warning Rate limit exceeded@jan-janssen has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 9 minutes and 15 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the 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. WalkthroughThe changes introduce a new Changes
Possibly related PRs
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? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 27
🧹 Outside diff range and nitpick comments (8)
pysqa/utils/basic.py (1)
514-523
: LGTM! Consider adding type hints for improved code clarity.The refactoring to use
render_submission_template
improves modularity and separates concerns. This change enhances maintainability and potentially allows for easier customization of submission templates for different queue systems.Consider adding type hints to the
render_submission_template
method call for improved code clarity and maintainability. For example:return self._commands.render_submission_template( command: str = command, submission_template: Template = active_queue["template"], working_directory: str = working_directory, job_name: str = job_name, cores: Optional[int] = cores, memory_max: Optional[int] = memory_max, run_time_max: Optional[int] = run_time_max, dependency_list: Optional[List[int]] = dependency_list, **kwargs )pysqa/wrapper/moab.py (1)
24-35
: Include working directory change in the submission scriptThe
working_directory
parameter is accepted but not used in the submission script. To ensure the job executes in the correct working directory, include a command to change to that directory before executing the main command.Consider adding the following line before
{{command}}
:{%- endif %} +cd {{ working_directory }} {{command}}
This ensures the job runs in the intended directory.
pysqa/wrapper/flux.py (1)
101-101
: Update docstring type forsubmission_template
parameterThe
submission_template
parameter is typed asUnion[str, Template]
in the function signature but is documented as(str)
in the docstring. For consistency and clarity, update the docstring to reflect the correct type.Correct the docstring as follows:
- submission_template (str): Submission script template pysqa.wrapper.flux.template + submission_template (Union[str, Template], optional): Submission script template. Defaults to `template`.pysqa/wrapper/lsf.py (1)
100-101
: Document the usage of**kwargs
in the methodThe method accepts
**kwargs
, which are passed to the template rendering. However, there is no explanation in the docstring about what additional keyword arguments can be provided. To enhance clarity, consider updating the docstring to inform users about the possibility of passing extra parameters to the template.Suggested addition to the docstring:
**kwargs, ) -> str: """ Generate the job submission template. Args: ... + **kwargs: Additional keyword arguments to be passed to the template rendering.
pysqa/wrapper/sge.py (3)
31-38
: Validation formemory_max
andrun_time_max
unitsThe template uses
{{memory_max}}
and{{run_time_max}}
directly, but it's unclear what units are expected (e.g., bytes, kilobytes, megabytes, seconds, minutes). This might lead to incorrect resource requests.Consider adding unit validation or documentation to clarify the expected units for
memory_max
andrun_time_max
.
105-105
: Defaultworking_directory
might not be intuitiveThe default value for
working_directory
isos.path.abspath(".")
, which resolves to the current working directory when the script is run. This may not be the intended directory for job execution.Consider requiring the user to specify
working_directory
, or clarify in the documentation that it defaults to the directory from which the script is executed.
114-127
: Improve docstring formatting and consistencyThe docstring has some inconsistencies and could be formatted more clearly for better readability.
- Ensure all parameter descriptions are aligned and consistently formatted.
- Correct any typos or mismatches in parameter names and descriptions.
Suggested changes:
""" Generate the job submission template. Args: command (str): The command to be executed. job_name (str, optional): The job name. Defaults to "pysqa". working_directory (str, optional): The working directory. Defaults to the current directory. cores (int, optional): The number of cores. Defaults to 1. memory_max (int, optional): The maximum memory in megabytes. Defaults to None. run_time_max (int, optional): The maximum run time in seconds. Defaults to None. dependency_list (list[int], optional): The list of dependency job IDs. Defaults to None. - submission_template (str): Submission script template. + submission_template (Union[str, Template], optional): The submission script template. Defaults to the class-defined template. **kwargs: Additional template variables. Returns: str: The rendered job submission script. """pysqa/wrapper/torque.py (1)
25-41
: Add usage ofworking_directory
in the template or remove the parameterThe
working_directory
parameter is currently not used within the submission template.If the working directory needs to be set, consider adding it to the template:
+#PBS -d {{ working_directory }}
Alternatively, if setting the working directory is handled elsewhere, you might consider removing the
working_directory
parameter from the method signature to avoid confusion.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (8)
- pysqa/utils/basic.py (1 hunks)
- pysqa/wrapper/flux.py (2 hunks)
- pysqa/wrapper/generic.py (3 hunks)
- pysqa/wrapper/lsf.py (3 hunks)
- pysqa/wrapper/moab.py (3 hunks)
- pysqa/wrapper/sge.py (3 hunks)
- pysqa/wrapper/slurm.py (3 hunks)
- pysqa/wrapper/torque.py (3 hunks)
🔇 Additional comments (9)
pysqa/utils/basic.py (2)
514-523
: Summary: Improved modularity in job submission template rendering.The changes in this file are minimal but impactful. By introducing the
render_submission_template
method, the code now has better separation of concerns and improved modularity. This refactoring allows for easier customization of submission templates for different queue systems without affecting the overall functionality of theBasisQueueAdapter
class.Key points:
- The public API of the class remains unchanged.
- The change is localized to the
_job_submission_template
method.- The new implementation delegates template rendering to a separate method, likely implemented in subclasses of
SchedulerCommands
.These changes align well with best practices for maintainable and extensible code.
514-523
: Verify the implementation ofrender_submission_template
in the SchedulerCommands subclass.The refactoring introduces a new method
render_submission_template
which is called onself._commands
. Ensure that this method is properly implemented in the appropriate subclass ofSchedulerCommands
for each supported queue system.Run the following script to verify the implementation of
render_submission_template
:pysqa/wrapper/generic.py (2)
6-6
: Imports added for new functionalityThe addition of
List
,Optional
, andUnion
from thetyping
module andTemplate
fromjinja2
is appropriate and necessary for the new methods introduced.Also applies to: 8-8
57-65
: Changedget_queue_status_command
from property to methodThe
get_queue_status_command
was previously defined as a property with@property
and@abstractmethod
decorators. It has now been changed to an abstract method by removing the@property
decorator. This alteration changes how subclasses implement this method and may impact any code that accesses it as a property.Run the following script to identify subclasses that may need updates:
Ensure that all subclasses and code accessing
get_queue_status_command
are updated to reflect this change.✅ Verification successful
Verification Successful: No subclasses or instances are using
get_queue_status_command
as a property.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Find subclasses of SchedulerCommands with get_queue_status_command defined as a property. # Test: Search for subclasses using @property for get_queue_status_command. ast-grep --lang python --pattern $'class $_(SchedulerCommands):\n $$$\n @property\n def get_queue_status_command($_):\n $$$\n $$$'Length of output: 145
Script:
#!/bin/bash # Description: Find all instances where get_queue_status_command is defined as a property in Python files. ast-grep --lang python --pattern $'@property\n def get_queue_status_command($_):\n $$$'Length of output: 96
pysqa/wrapper/flux.py (2)
84-84
: Unused parametermemory_max
The parameter
memory_max
is accepted by the function but is not used in the submission template. Ifmemory_max
is not needed, consider removing it from the function parameters. If it is required, include it in the template to set the maximum memory for the job.Please verify whether
memory_max
should be included in the submission template. If Flux supports specifying memory limits, incorporatememory_max
into the template accordingly.Also applies to: 114-114
19-19
: Verify time unit conversion forrun_time_max
In the template,
run_time_max
is converted to minutes using integer division by 60:{{ [1, run_time_max // 60]|max }}
. Please verify thatrun_time_max
is provided in seconds and that the-t
option expects time in minutes.pysqa/wrapper/lsf.py (1)
34-34
: Verify thatrun_time_max
andmemory_max
are in the correct unitsIn the template directives
#BSUB -W {{run_time_max}}
and#BSUB -M {{memory_max}}
, ensure that the values provided forrun_time_max
andmemory_max
are in the units expected by LSF. Typically:
-W
expects the run time in minutes.-M
expects the memory limit in kilobytes.Adjust the parameter units or include unit conversions if necessary to prevent scheduling issues.
Also applies to: 37-37
pysqa/wrapper/torque.py (1)
30-31
: Validate units for thememory_max
parameterEnsure that the
memory_max
parameter is provided in gigabytes as an integer. If users provide memory in other units or as a string, it could result in scheduling errors.Consider adding validation in the
render_submission_template
method to confirm thememory_max
is an integer representing gigabytes.pysqa/wrapper/slurm.py (1)
33-33
: Verify the calculation ofrun_time_max
for SLURM's--time
directiveThe calculation
{{ [1, run_time_max // 60]|max }}
may not correctly reflect SLURM's expected time format. SLURM expects the--time
parameter in the formatminutes
,hours:minutes:seconds
, ordays-hours
. Ensure thatrun_time_max
is converted appropriately.Run the following script to verify the correct handling of
run_time_max
:
pysqa/wrapper/moab.py
Outdated
memory_max (int, optional): The maximum memory. Defaults to None. | ||
run_time_max (int, optional): The maximum run time. Defaults to None. | ||
dependency_list (list[int], optional): The list of dependency job IDs. Defaults to None. | ||
submission_template (str): Submission script template pysqa.wrapper.torque.template |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update the docstring to reference the correct template
The docstring for the submission_template
parameter refers to pysqa.wrapper.torque.template
, which is incorrect for the Moab scheduler. It should reference the Moab template to avoid confusion.
Please correct the docstring as follows:
- submission_template (str): Submission script template pysqa.wrapper.torque.template
+ submission_template (str): Submission script template for Moab scheduler
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
submission_template (str): Submission script template pysqa.wrapper.torque.template | |
submission_template (str): Submission script template for Moab scheduler |
#MSUB -l pmem={{ memory_max| int }}gb | ||
{%- endif %} | ||
{%- if run_time_max %} | ||
#$ -l walltime={{run_time_max}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct the resource directive prefix for consistency
The resource directive on line 31 uses #$
, which is inconsistent with the other Moab directives that use #MSUB
. This inconsistency may lead to the scheduler ignoring the line or causing unexpected behavior.
Please update the line to use the correct Moab directive prefix:
-#$ -l walltime={{run_time_max}}
+#MSUB -l walltime={{ run_time_max }}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
#$ -l walltime={{run_time_max}} | |
#MSUB -l walltime={{ run_time_max }} |
template = """\ | ||
#!/bin/bash | ||
#MSUB -N {{job_name}} | ||
{%- if memory_max %} | ||
#MSUB -l pmem={{ memory_max| int }}gb | ||
{%- endif %} | ||
{%- if run_time_max %} | ||
#$ -l walltime={{run_time_max}} | ||
{%- endif %} | ||
|
||
{{command}} | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Include the number of cores in the submission template
The cores
parameter is accepted by the render_submission_template
method but is not utilized in the submission script. To ensure the scheduler allocates the correct number of cores, include the appropriate resource directive in the submission template.
Add the following to the template to request the specified number of cores:
{%- if run_time_max %}
#MSUB -l walltime={{ run_time_max }}
{%- endif %}
+{%- if cores %}
+#MSUB -l nodes=1:ppn={{ cores }}
+{%- endif %}
{{command}}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
template = """\ | |
#!/bin/bash | |
#MSUB -N {{job_name}} | |
{%- if memory_max %} | |
#MSUB -l pmem={{ memory_max| int }}gb | |
{%- endif %} | |
{%- if run_time_max %} | |
#$ -l walltime={{run_time_max}} | |
{%- endif %} | |
{{command}} | |
""" | |
template = """\ | |
#!/bin/bash | |
#MSUB -N {{job_name}} | |
{%- if memory_max %} | |
#MSUB -l pmem={{ memory_max| int }}gb | |
{%- endif %} | |
{%- if run_time_max %} | |
#MSUB -l walltime={{run_time_max}} | |
{%- endif %} | |
{%- if cores %} | |
#MSUB -l nodes=1:ppn={{ cores }} | |
{%- endif %} | |
{{command}} | |
""" |
Handle job dependencies in the submission template
The dependency_list
parameter is accepted but not utilized in the submission script. To properly manage job dependencies, include directives that specify the job IDs this job depends on.
Add the following lines to handle job dependencies:
{%- if run_time_max %}
#MSUB -l walltime={{ run_time_max }}
{%- endif %}
+{%- if dependency_list %}
+#MSUB -l depend={{ dependency_list | join(':') }}
+{%- endif %}
{{command}}
This inclusion will ensure that the job submission respects any specified dependencies.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
template = """\ | |
#!/bin/bash | |
#MSUB -N {{job_name}} | |
{%- if memory_max %} | |
#MSUB -l pmem={{ memory_max| int }}gb | |
{%- endif %} | |
{%- if run_time_max %} | |
#$ -l walltime={{run_time_max}} | |
{%- endif %} | |
{{command}} | |
""" | |
template = """\ | |
#!/bin/bash | |
#MSUB -N {{job_name}} | |
{%- if memory_max %} | |
#MSUB -l pmem={{ memory_max| int }}gb | |
{%- endif %} | |
{%- if run_time_max %} | |
#MSUB -l walltime={{run_time_max}} | |
{%- endif %} | |
{%- if dependency_list %} | |
#MSUB -l depend={{ dependency_list | join(':') }} | |
{%- endif %} | |
{{command}} | |
""" |
@property | ||
def enable_reservation_command(self) -> list[str]: | ||
""" | ||
Returns the command to enable job reservation on the scheduler. | ||
|
||
Returns: | ||
list[str]: The command to enable job reservation. | ||
""" | ||
raise NotImplementedError() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing @abstractmethod
decorator on enable_reservation_command
The enable_reservation_command
property lacks the @abstractmethod
decorator. Other abstract properties in the class, such as submit_job_command
and delete_job_command
, include both @property
and @abstractmethod
decorators. Adding the @abstractmethod
decorator ensures consistency and enforces implementation in subclasses.
Apply this diff to add the decorator:
@property
+@abstractmethod
def enable_reservation_command(self) -> list[str]:
"""
Returns the command to enable job reservation on the scheduler.
Returns:
list[str]: The command to enable job reservation.
"""
- raise NotImplementedError()
+ pass
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
@property | |
def enable_reservation_command(self) -> list[str]: | |
""" | |
Returns the command to enable job reservation on the scheduler. | |
Returns: | |
list[str]: The command to enable job reservation. | |
""" | |
raise NotImplementedError() | |
@property | |
@abstractmethod | |
def enable_reservation_command(self) -> list[str]: | |
""" | |
Returns the command to enable job reservation on the scheduler. | |
Returns: | |
list[str]: The command to enable job reservation. | |
""" | |
pass |
pysqa/wrapper/generic.py
Outdated
def render_submission_template( | ||
command: str, | ||
submission_template: Union[str, Template], | ||
working_directory: str, | ||
job_name: str = "pysqa", | ||
cores: int = 1, | ||
memory_max: Optional[int] = None, | ||
run_time_max: Optional[int] = None, | ||
dependency_list: Optional[List[int]] = None, | ||
**kwargs, | ||
) -> str: | ||
""" | ||
Returns the command to get the status of the job queue. | ||
Generate the job submission template. | ||
|
||
Args: | ||
command (str, optional): The command to be executed. | ||
job_name (str, optional): The job name. Defaults to "pysqa". | ||
working_directory (str, optional): The working directory. Defaults to ".". | ||
cores (int, optional): The number of cores. Defaults to 1. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistencies between function signature and docstring in render_submission_template
There are discrepancies between the function signature and the docstring:
- Parameter Order: The order of parameters in the docstring does not match the function signature.
- Optional Parameters:
command
: In the signature, it's required (command: str
), but the docstring marks it as optional.working_directory
: Required in the signature but marked as optional in the docstring with a default value that isn't reflected in the signature.
- Type Annotations:
submission_template
: In the signature, it'sUnion[str, Template]
, but the docstring lists it asstr
.
- Missing Parameters:
**kwargs
is not documented in the docstring.
Apply this diff to correct the docstring:
"""
Generate the job submission template.
Args:
- command (str, optional): The command to be executed.
+ command (str): The command to be executed.
+ submission_template (Union[str, Template]): The submission script template.
working_directory (str): The working directory.
- job_name (str, optional): The job name. Defaults to "pysqa".
- working_directory (str, optional): The working directory. Defaults to ".".
+ job_name (str, optional): The job name. Defaults to "pysqa".
cores (int, optional): The number of cores. Defaults to 1.
memory_max (int, optional): The maximum memory. Defaults to None.
run_time_max (int, optional): The maximum run time. Defaults to None.
dependency_list (list[int], optional): The list of dependency job IDs. Defaults to None.
+ **kwargs: Additional keyword arguments.
- submission_template (str): Submission script template pysqa.wrapper.torque.template
Returns:
str: The rendered job submission template.
"""
Ensure that the function signature and docstring parameters are consistent, accurately reflect default values, and document all parameters.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def render_submission_template( | |
command: str, | |
submission_template: Union[str, Template], | |
working_directory: str, | |
job_name: str = "pysqa", | |
cores: int = 1, | |
memory_max: Optional[int] = None, | |
run_time_max: Optional[int] = None, | |
dependency_list: Optional[List[int]] = None, | |
**kwargs, | |
) -> str: | |
""" | |
Returns the command to get the status of the job queue. | |
Generate the job submission template. | |
Args: | |
command (str, optional): The command to be executed. | |
job_name (str, optional): The job name. Defaults to "pysqa". | |
working_directory (str, optional): The working directory. Defaults to ".". | |
cores (int, optional): The number of cores. Defaults to 1. | |
def render_submission_template( | |
command: str, | |
submission_template: Union[str, Template], | |
working_directory: str, | |
job_name: str = "pysqa", | |
cores: int = 1, | |
memory_max: Optional[int] = None, | |
run_time_max: Optional[int] = None, | |
dependency_list: Optional[List[int]] = None, | |
**kwargs, | |
) -> str: | |
""" | |
Generate the job submission template. | |
Args: | |
command (str): The command to be executed. | |
submission_template (Union[str, Template]): The submission script template. | |
working_directory (str): The working directory. | |
job_name (str, optional): The job name. Defaults to "pysqa". | |
cores (int, optional): The number of cores. Defaults to 1. | |
memory_max (int, optional): The maximum memory. Defaults to None. | |
run_time_max (int, optional): The maximum run time. Defaults to None. | |
dependency_list (list[int], optional): The list of dependency job IDs. Defaults to None. | |
**kwargs: Additional keyword arguments. | |
Returns: | |
str: The rendered job submission template. | |
""" |
{%- if dependency %} | ||
#PBS -W depend=afterok:{{ dependency | join(':') }} | ||
{%- endif %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix variable name inconsistency between dependency_list
and dependency
In the submission template, the variable dependency
is used, but in the render_submission_template
method, the parameter is named dependency_list
. This inconsistency may cause a KeyError
during template rendering.
Apply this diff to fix the inconsistency:
# In the template (lines 36-38):
-{%- if dependency %}
-#PBS -W depend=afterok:{{ dependency | join(':') }}
+{%- if dependency_list %}
+#PBS -W depend=afterok:{{ dependency_list | join(':') }}
{%- endif %}
# In the `render_submission_template` method (line 165):
- dependency_list=dependency_list,
+ dependency=dependency_list,
Also applies to: 165-165
pysqa/wrapper/slurm.py
Outdated
memory_max (int, optional): The maximum memory. Defaults to None. | ||
run_time_max (int, optional): The maximum run time. Defaults to None. | ||
dependency_list (list[int], optional): The list of dependency job IDs. Defaults to None. | ||
submission_template (str): Submission script template pysqa.wrapper.torque.template |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update the docstring for submission_template
parameter
The docstring for submission_template
mentions pysqa.wrapper.torque.template
, which is incorrect for the SLURM scheduler. Please update it to reflect the correct template.
Apply this diff to fix the docstring:
submission_template (str): Submission script template
- pysqa.wrapper.torque.template
+ Default SLURM submission script template.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
submission_template (str): Submission script template pysqa.wrapper.torque.template | |
submission_template (str): Submission script template | |
Default SLURM submission script template. |
{%- if dependency %} | ||
#SBATCH --dependency=afterok:{{ dependency | join(',') }} | ||
{%- endif %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent variable name dependency
vs dependency_list
In the template, the variable dependency
is used, but in the render_submission_template
method, the parameter is named dependency_list
. This inconsistency will lead to a KeyError
when rendering the template. Please ensure that the variable names match between the template and the method.
Apply this diff to fix the issue:
-{%- if dependency %}
-#SBATCH --dependency=afterok:{{ dependency | join(',') }}
+{%- if dependency_list %}
+#SBATCH --dependency=afterok:{{ dependency_list | join(',') }}
{%- endif %}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
{%- if dependency %} | |
#SBATCH --dependency=afterok:{{ dependency | join(',') }} | |
{%- endif %} | |
{%- if dependency_list %} | |
#SBATCH --dependency=afterok:{{ dependency_list | join(',') }} | |
{%- endif %} |
template = """\ | ||
#!/bin/bash | ||
#SBATCH --output=time.out | ||
#SBATCH --job-name={{job_name}} | ||
#SBATCH --chdir={{working_directory}} | ||
#SBATCH --get-user-env=L | ||
#SBATCH --partition={{partition}} | ||
{%- if run_time_max %} | ||
#SBATCH --time={{ [1, run_time_max // 60]|max }} | ||
{%- endif %} | ||
{%- if dependency %} | ||
#SBATCH --dependency=afterok:{{ dependency | join(',') }} | ||
{%- endif %} | ||
{%- if memory_max %} | ||
#SBATCH --mem={{memory_max}}G | ||
{%- endif %} | ||
#SBATCH --cpus-per-task={{cores}} | ||
|
||
{{command}} | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Undefined variable partition
in the template
The partition
variable is used in the submission template but is not provided to the render_submission_template
method or passed during template rendering. This will cause a KeyError
when rendering the template. Consider adding a partition
parameter to the method and passing it to the template.
Apply this diff to fix the issue:
def render_submission_template(
command: str,
job_name: str = "pysqa",
working_directory: str = os.path.abspath("."),
cores: int = 1,
memory_max: Optional[int] = None,
run_time_max: Optional[int] = None,
+ partition: str = "default",
dependency_list: Optional[List[int]] = None,
submission_template: Union[str, Template] = template,
**kwargs,
) -> str:
...
return submission_template.render(
command=command,
job_name=job_name,
working_directory=working_directory,
cores=cores,
memory_max=memory_max,
run_time_max=run_time_max,
+ partition=partition,
dependency_list=dependency_list,
**kwargs,
)
Committable suggestion was skipped due to low confidence.
🛠️ Refactor suggestion
Enhance the submission template with optional email notifications
Consider adding optional parameters for email notifications to inform users about job start, completion, or failure events. This can improve user experience for long-running jobs.
Modify the template to include email options:
{%- if email %}
#SBATCH --mail-user={{ email }}
{%- endif %}
{%- if email_events %}
#SBATCH --mail-type={{ email_events | join(',') }}
{%- endif %}
Update the method parameters and rendering context:
def render_submission_template(
command: str,
job_name: str = "pysqa",
working_directory: Optional[str] = None,
cores: int = 1,
memory_max: Optional[int] = None,
run_time_max: Optional[int] = None,
dependency_list: Optional[List[int]] = None,
+ email: Optional[str] = None,
+ email_events: Optional[List[str]] = None,
submission_template: Union[str, Template] = template,
**kwargs,
) -> str:
+ if working_directory is None:
+ working_directory = os.path.abspath(".")
...
return submission_template.render(
command=command,
job_name=job_name,
working_directory=working_directory,
cores=cores,
memory_max=memory_max,
run_time_max=run_time_max,
dependency_list=dependency_list,
+ email=email,
+ email_events=email_events,
**kwargs,
)
Committable suggestion was skipped due to low confidence.
🛠️ Refactor suggestion
Consider simplifying the runtime calculation in the template
The expression {{ [1, run_time_max // 60]|max }}
may be unnecessarily complex. If run_time_max
is already provided in minutes or the appropriate SLURM time format, you can use it directly.
Modify the template line:
-#SBATCH --time={{ [1, run_time_max // 60]|max }}
+#SBATCH --time={{ run_time_max }}
Ensure that run_time_max
is provided in the correct format expected by SLURM (e.g., minutes
, hours:minutes:seconds
, or days-hours
).
Committable suggestion was skipped due to low confidence.
def render_submission_template( | ||
command: str, | ||
job_name: str = "pysqa", | ||
working_directory: str = os.path.abspath("."), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid using function calls in default parameter values
The default value os.path.abspath(".")
is evaluated at function definition time, which may not reflect the current working directory when the function is called. It's better to set the default to None
and compute it inside the function.
Apply this diff to fix the issue:
def render_submission_template(
command: str,
job_name: str = "pysqa",
- working_directory: str = os.path.abspath("."),
+ working_directory: Optional[str] = None,
cores: int = 1,
memory_max: Optional[int] = None,
run_time_max: Optional[int] = None,
dependency_list: Optional[List[int]] = None,
submission_template: Union[str, Template] = template,
**kwargs,
) -> str:
+ if working_directory is None:
+ working_directory = os.path.abspath(".")
...
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
working_directory: str = os.path.abspath("."), | |
def render_submission_template( | |
command: str, | |
job_name: str = "pysqa", | |
working_directory: Optional[str] = None, | |
cores: int = 1, | |
memory_max: Optional[int] = None, | |
run_time_max: Optional[int] = None, | |
dependency_list: Optional[List[int]] = None, | |
submission_template: Union[str, Template] = template, | |
**kwargs, | |
) -> str: | |
if working_directory is None: | |
working_directory = os.path.abspath(".") | |
... |
There was a problem hiding this 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 (2)
tests/test_scheduler_commands.py (1)
Line range hint
6-58
: Consider expanding test coverage for SchedulerCommands.While the existing tests cover basic functionality and error cases, the move to an abstract base class might introduce new methods or behaviors that require testing.
Consider the following improvements:
- Review the abstract
SchedulerCommands
class for any new methods or behaviors that aren't currently tested.- Add tests for any new functionality introduced in the abstract class.
- Ensure that the
TmpSchedularCommands
class correctly implements all required methods from the abstract base class.To help identify any new methods that might need testing, you can run:
#!/bin/bash # Description: List methods in the SchedulerCommands class # Test: Extract method names from the SchedulerCommands class ast-grep --lang python --pattern 'class SchedulerCommands($_): $$$ def $METHOD($_) { $$$ } $$$ ' pysqa/wrapper/abstract.py | grep -oP '(?<=def )\w+'Compare the output with the existing tests and add coverage for any missing methods.
pysqa/wrapper/abstract.py (1)
68-107
: LGTM with a minor suggestion: Consider improvingsubmission_template
parameter.The
render_submission_template
method is well-implemented and documented. It enhances the class's functionality by allowing dynamic job submission template generation. The use of type hints and comprehensive docstring is commendable.However, there's a minor inconsistency in the
submission_template
parameter:Consider updating the type hint and docstring for the
submission_template
parameter to reflect that it can be either a string or aTemplate
object. Here's a suggested change:- submission_template: Union[str, Template], + submission_template: Union[str, Template], job_name: str = "pysqa", working_directory: str = os.path.abspath("."), cores: int = 1, memory_max: Optional[int] = None, run_time_max: Optional[int] = None, dependency_list: Optional[List[int]] = None, **kwargs, ) -> str: """ Generate the job submission template. Args: command (str, optional): The command to be executed. job_name (str, optional): The job name. Defaults to "pysqa". working_directory (str, optional): The working directory. Defaults to ".". cores (int, optional): The number of cores. Defaults to 1. memory_max (int, optional): The maximum memory. Defaults to None. run_time_max (int, optional): The maximum run time. Defaults to None. dependency_list (list[int], optional): The list of dependency job IDs. Defaults to None. - submission_template (str): Submission script template pysqa.wrapper.torque.template + submission_template (Union[str, Template]): Submission script template as a string or Template object.This change would make the method signature and docstring more consistent with the actual implementation.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (9)
- pysqa/utils/basic.py (2 hunks)
- pysqa/wrapper/abstract.py (3 hunks)
- pysqa/wrapper/flux.py (2 hunks)
- pysqa/wrapper/lsf.py (3 hunks)
- pysqa/wrapper/moab.py (3 hunks)
- pysqa/wrapper/sge.py (3 hunks)
- pysqa/wrapper/slurm.py (3 hunks)
- pysqa/wrapper/torque.py (3 hunks)
- tests/test_scheduler_commands.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
- pysqa/utils/basic.py
- pysqa/wrapper/flux.py
- pysqa/wrapper/lsf.py
- pysqa/wrapper/moab.py
- pysqa/wrapper/sge.py
- pysqa/wrapper/slurm.py
🔇 Additional comments (8)
pysqa/wrapper/abstract.py (3)
25-33
: LGTM: Well-defined abstract property method.The
enable_reservation_command
property method is correctly implemented as an abstract method. It follows the established pattern in the class, has appropriate type hints, and includes a clear docstring.
5-10
: LGTM: Appropriate imports and consistent file structure.The addition of the Jinja2 Template import is necessary for the new
render_submission_template
method. The overall file structure remains consistent with the abstract base class pattern, maintaining good coding practices.
Line range hint
1-108
: Summary: Well-implemented enhancements to the SchedulerCommands class.The changes to this file enhance the
SchedulerCommands
abstract base class by adding two new methods:
enable_reservation_command
: A new abstract property method for enabling job reservation.render_submission_template
: A static method for generating job submission templates using Jinja2.These additions improve the flexibility and functionality of the job scheduling system. The implementation maintains consistent coding style, proper use of type hints, and comprehensive documentation.
pysqa/wrapper/torque.py (5)
5-7
: LGTM: Import statements are appropriateThe added import statements for
os
,re
, andUnion
from typing are necessary for the new functionality and follow good practices.
9-10
: LGTM: Additional imports are appropriateThe added import statements for
pandas
andTemplate
from jinja2 are necessary for the new template rendering functionality and follow good practices.
128-166
: LGTM: render_submission_template method is well-structuredThe
render_submission_template
method is well-structured and properly usessuper()
to call the parent class's method. The method signature and docstring are appropriate for the job submission requirements.However, please ensure that the previously mentioned issues are addressed:
- The inconsistency between
dependency_list
anddependency
.- The formatting of
run_time_max
toHH:MM:SS
.
Line range hint
1-166
: Summary: Good implementation with minor issues to addressThe implementation of the default submission template for the Torque job scheduler is generally well-done. The new
render_submission_template
method and the template string enhance the functionality of theTorqueCommands
class.However, there are two main issues that need to be addressed:
- The inconsistency between
dependency_list
anddependency
in the template and method signature.- The potential incorrect formatting of
run_time_max
for Torque'swalltime
parameter.Once these issues are resolved, the implementation will be robust and consistent with the requirements of the Torque job scheduler.
36-38
:⚠️ Potential issueFix variable name inconsistency between
dependency_list
anddependency
In the submission template, the variable
dependency
is used, but in therender_submission_template
method, the parameter is nameddependency_list
. This inconsistency may cause aKeyError
during template rendering.Apply this diff to fix the inconsistency:
{%- if dependency %} #PBS -W depend=afterok:{{ dependency | join(':') }} {%- endif %}
to:
{%- if dependency_list %} #PBS -W depend=afterok:{{ dependency_list | join(':') }} {%- endif %}
Also, update the
render_submission_template
method accordingly:- dependency_list=dependency_list, + dependency=dependency_list,Likely invalid or redundant comment.
@@ -1,5 +1,5 @@ | |||
import unittest | |||
from pysqa.wrapper.generic import SchedulerCommands | |||
from pysqa.wrapper.abstract import SchedulerCommands |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Update tests to use concrete SchedulerCommands subclasses.
The SchedulerCommands
class has been refactored to an abstract base class in pysqa/wrapper/abstract.py
, and several concrete subclasses (e.g., TorqueCommands
, SlurmCommands
) now inherit from it. Ensure that tests/test_scheduler_commands.py
imports and utilizes these concrete implementations instead of the abstract class to maintain valid and comprehensive test coverage.
🔗 Analysis chain
Verify test coverage after import change.
The import statement has been updated to import SchedulerCommands
from pysqa.wrapper.abstract
instead of pysqa.wrapper.generic
. This change might indicate a significant refactoring or relocation of the SchedulerCommands
class.
Please ensure that:
- The existing tests are still valid and cover all necessary aspects of the refactored
SchedulerCommands
class. - Any new methods or behaviors introduced in the abstract version are adequately tested.
- The
TmpSchedularCommands
class still correctly inherits from and implements the abstractSchedulerCommands
.
To verify the changes in the SchedulerCommands
class, you can run the following script:
This will help identify any changes in the class definition that might require updates to the tests.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Compare the old and new SchedulerCommands classes
# Test: Check the differences between the old and new SchedulerCommands classes
rg --type python -A 20 'class SchedulerCommands' pysqa/wrapper/
Length of output: 96
Script:
#!/bin/bash
# Description: Compare the old and new SchedulerCommands classes
# Test: Check the differences between the old and new SchedulerCommands classes
rg --type py -A 20 'class SchedulerCommands' pysqa/wrapper/
Length of output: 1169
Script:
#!/bin/bash
# Description: Find concrete implementations of SchedulerCommands
# Search for classes that inherit from SchedulerCommands and are not abstract
rg --type py 'class\s+\w+\(SchedulerCommands\):' pysqa/wrapper/
Length of output: 443
#PBS -l walltime={{run_time_max}} | ||
{%- endif %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure run_time_max
is formatted as HH:MM:SS
for Torque's walltime
Torque's walltime
parameter expects time in HH:MM:SS
format. Currently, run_time_max
might be provided as an integer (e.g., total seconds), which could lead to incorrect scheduling.
Consider converting run_time_max
to the appropriate format before rendering the template. Here's how you can adjust the code:
# In the `render_submission_template` method before rendering:
if run_time_max is not None:
run_time_max = "{:02d}:{:02d}:{:02d}".format(
run_time_max // 3600,
(run_time_max % 3600) // 60,
run_time_max % 60
)
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (2)
- pysqa/utils/basic.py (4 hunks)
- pysqa/utils/core.py (1 hunks)
🧰 Additional context used
🪛 Ruff
pysqa/utils/core.py
61-61: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
84-87: Do not call
getattr
with a constant attribute value. It is not any safer than normal property access.Replace
getattr
with attribute access(B009)
🔇 Additional comments (1)
pysqa/utils/basic.py (1)
190-190
:⚠️ Potential issueEnsure compatibility of
submission_template
parameter with superclass methodAdding the
submission_template
parameter to_job_submission_template
may cause issues if the superclass method does not accept this parameter. This could lead to aTypeError
when callingsuper()._job_submission_template()
.Run the following script to verify if the superclass method accepts
submission_template
:
super().__init__( | ||
queue_type=config["queue_type"], execute_command=execute_command | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure 'queue_type' key exists in config
to avoid KeyError
The call to super().__init__
uses config["queue_type"]
. If 'queue_type'
is not present in the config
dictionary, this will raise a KeyError
. Consider adding error handling or providing a default value to prevent this issue.
Apply this diff to handle missing 'queue_type'
key:
def __init__(
self,
config: dict,
directory: str = "~/.queues",
execute_command: callable = execute_command,
):
+ queue_type = config.get("queue_type")
+ if queue_type is None:
+ raise ValueError("The 'queue_type' key is missing in the config dictionary.")
super().__init__(
- queue_type=config["queue_type"], execute_command=execute_command
+ queue_type=queue_type, execute_command=execute_command
)
Alternatively, you can set a default queue_type
if appropriate.
Committable suggestion was skipped due to low confidence.
return super()._job_submission_template( | ||
queue=None, | ||
submission_template=active_queue["template"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure 'template' key exists in active_queue
to avoid KeyError
The code accesses active_queue["template"]
. If the 'template'
key is missing in active_queue
, this will raise a KeyError
. Please ensure that all active queues have a 'template'
defined or add error handling to manage missing templates.
Apply this diff to handle missing 'template'
key:
if queue not in self.queue_list:
raise ValueError(
"The queue "
+ queue
+ " was not found in the list of queues: "
+ str(self.queue_list)
)
active_queue = self._config["queues"][queue]
+if "template" not in active_queue:
+ raise ValueError("The active queue does not have a 'template' defined.")
cores, run_time_max, memory_max = self.check_queue_parameters(
queue=None,
cores=cores,
run_time_max=run_time_max,
memory_max=memory_max,
active_queue=active_queue,
)
return super()._job_submission_template(
queue=None,
submission_template=active_queue["template"],
job_name=job_name,
Alternatively, provide a default template or handle this scenario gracefully.
Committable suggestion was skipped due to low confidence.
df_selected = df[df["jobid"] == process_id]["status"] | ||
if len(df_selected) != 0: | ||
results_lst.append(df_selected.values[0]) | ||
else: | ||
results_lst.append("finished") | ||
return results_lst |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid assuming job status is 'finished' when not found
Setting the job status to "finished"
when the job ID is not found may be inaccurate, as the job could be pending, failed, or cancelled. Consider setting the status to "unknown"
or implementing additional checks.
Apply this diff:
if len(df_selected) != 0:
results_lst.append(df_selected.values[0])
else:
- results_lst.append("finished")
+ results_lst.append("unknown")
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
df_selected = df[df["jobid"] == process_id]["status"] | |
if len(df_selected) != 0: | |
results_lst.append(df_selected.values[0]) | |
else: | |
results_lst.append("finished") | |
return results_lst | |
df_selected = df[df["jobid"] == process_id]["status"] | |
if len(df_selected) != 0: | |
results_lst.append(df_selected.values[0]) | |
else: | |
results_lst.append("unknown") | |
return results_lst |
os.makedirs(working_directory) | ||
queue_script_path = os.path.join(working_directory, "run_queue.sh") | ||
with open(queue_script_path, "w") as f: | ||
f.writelines(queue_script) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use write()
instead of writelines()
when writing a string
The writelines()
method expects an iterable of strings, but queue_script
is a single string. Use write()
to correctly write the content.
Apply this diff:
with open(queue_script_path, "w") as f:
- f.writelines(queue_script)
+ f.write(queue_script)
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
f.writelines(queue_script) | |
with open(queue_script_path, "w") as f: | |
f.write(queue_script) |
pysqa/utils/core.py
Outdated
self._submission_template = getattr( | ||
importlib.import_module(queue_type_dict[queue_type]["module_name"]), | ||
"template", | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Avoid unnecessary use of getattr
with a constant attribute
Since 'template'
is a constant attribute name, you can access it directly for better readability.
Apply this diff:
- self._submission_template = getattr(
- importlib.import_module(queue_type_dict[queue_type]["module_name"]),
- "template",
- )
+ module = importlib.import_module(queue_type_dict[queue_type]["module_name"])
+ self._submission_template = module.template
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
self._submission_template = getattr( | |
importlib.import_module(queue_type_dict[queue_type]["module_name"]), | |
"template", | |
) | |
module = importlib.import_module(queue_type_dict[queue_type]["module_name"]) | |
self._submission_template = module.template |
🧰 Tools
🪛 Ruff
84-87: Do not call
getattr
with a constant attribute value. It is not any safer than normal property access.Replace
getattr
with attribute access(B009)
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
🧹 Outside diff range and nitpick comments (2)
pysqa/wrapper/gent.py (2)
21-22
: Consider renaming the module-level template variable.The assignment of
template_slurm
to a new variable namedtemplate
is correct and likely part of a standardization effort. However, this creates a potential naming confusion sincetemplate
is now both a module-level variable and an imported name.To improve clarity, consider renaming the module-level variable to something more specific, such as
gent_template
ordefault_template
.Here's a suggested change:
- template = template_slurm + gent_template = template_slurmThis change would make the code more explicit and reduce the potential for confusion.
Line range hint
26-95
: Consider updating GentCommands to use the new template.The introduction of the
template
object from theslurm
module suggests a move towards standardization of job submission templates. However, theGentCommands
class doesn't currently use this new template.To fully implement this change:
- Consider adding a
render_submission_template
method toGentCommands
that uses the new template.- Update existing methods in
GentCommands
to use the new template where appropriate.This would ensure consistency with the apparent goal of standardizing template usage across different queue adapters.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (3)
- pysqa/queueadapter.py (2 hunks)
- pysqa/utils/core.py (1 hunks)
- pysqa/wrapper/gent.py (2 hunks)
🧰 Additional context used
🪛 Ruff
pysqa/utils/core.py
61-61: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
85-88: Do not call
getattr
with a constant attribute value. It is not any safer than normal property access.Replace
getattr
with attribute access(B009)
🔇 Additional comments (5)
pysqa/wrapper/gent.py (1)
8-8
: LGTM: Import statement for template looks good.The import statement correctly brings in the
template
object from theslurm
module and aliases it astemplate_slurm
. This prepares for its usage later in the file.pysqa/queueadapter.py (2)
5-5
: LGTM: Import statement updated correctly.The import statement has been appropriately updated to include
Tuple
andUnion
from thetyping
module. This change is necessary to support the new type annotation in thecheck_queue_parameters
method and follows best practices for type hinting in Python.
Line range hint
1-391
: Overall assessment: Improvements in type safety with minor documentation update needed.The changes in this file enhance type safety and specificity, particularly in the
check_queue_parameters
method. The updated import statement and method signature are well-implemented. The only remaining task is to update the method's docstring to reflect the new return type accurately.These changes contribute to better code quality and maintainability. Great job on improving the type annotations!
pysqa/utils/core.py (2)
343-343
:⚠️ Potential issueUse
write()
instead ofwritelines()
for writing a single stringThe
writelines()
method expects an iterable of strings, butqueue_script
is a single string.Use
write()
to correctly write the content. Apply this diff:with open(queue_script_path, "w") as f: - f.writelines(queue_script) + f.write(queue_script)Likely invalid or redundant comment.
246-251
:⚠️ Potential issueReconsider default status for jobs not found in queue
Setting the job status to
"finished"
when the job ID is not found may be inaccurate. The job could be in various states like pending, failed, or cancelled.Consider setting the status to
"unknown"
or implementing additional checks to determine the actual status. Apply this diff as a starting point:if len(df_selected) != 0: results_lst.append(df_selected.values[0]) else: - results_lst.append("finished") + results_lst.append("unknown")Likely invalid or redundant comment.
) -> Tuple[ | ||
Union[float, int, None], Union[float, int, None], Union[float, int, None] | ||
]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approve signature change and update docstring.
The method signature update improves type safety and code readability by providing a more specific return type annotation. This change is beneficial for maintainability and helps catch potential type-related errors early.
However, the method's docstring still mentions returning a List, which is now inconsistent with the new Tuple return type.
Please update the docstring to reflect the new return type. For example:
"""
...
Returns:
Tuple[Union[float, int, None], Union[float, int, None], Union[float, int, None]]: A tuple containing the checked parameters (cores, run_time_max, memory_max).
"""
Also, ensure that the method implementation returns a tuple that matches this new type annotation.
Returns: | ||
SchedulerCommands: queuing system commands class instance | ||
""" | ||
if queue_type in queue_type_dict.keys(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Simplify dictionary membership check
The current check if queue_type in queue_type_dict.keys():
can be simplified to improve readability and performance slightly.
Apply this diff to simplify the dictionary membership check:
-if queue_type in queue_type_dict.keys():
+if queue_type in queue_type_dict:
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if queue_type in queue_type_dict.keys(): | |
if queue_type in queue_type_dict: |
🧰 Tools
🪛 Ruff
61-61: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
process_id (int): The process ID. | ||
|
||
Returns: | ||
str: The status of the job.results_lst.append(df_selected.values[0]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct the docstring return description in get_status_of_job
The return description includes an unintended code snippet, which may confuse users.
Apply this diff to fix the docstring:
- str: The status of the job.results_lst.append(df_selected.values[0])
+ str: The status of the job.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
str: The status of the job.results_lst.append(df_selected.values[0]) | |
str: The status of the job. |
if queue_type_dict[queue_type]["module_name"] is not None: | ||
self._submission_template = getattr( | ||
importlib.import_module(queue_type_dict[queue_type]["module_name"]), | ||
"template", | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Simplify attribute access for template
The use of getattr
with a constant attribute name can be simplified for better readability.
Apply this diff to simplify the attribute access:
- self._submission_template = getattr(
- importlib.import_module(queue_type_dict[queue_type]["module_name"]),
- "template",
- )
+ module = importlib.import_module(queue_type_dict[queue_type]["module_name"])
+ self._submission_template = module.template
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if queue_type_dict[queue_type]["module_name"] is not None: | |
self._submission_template = getattr( | |
importlib.import_module(queue_type_dict[queue_type]["module_name"]), | |
"template", | |
) | |
if queue_type_dict[queue_type]["module_name"] is not None: | |
module = importlib.import_module(queue_type_dict[queue_type]["module_name"]) | |
self._submission_template = module.template |
🧰 Tools
🪛 Ruff
85-88: Do not call
getattr
with a constant attribute value. It is not any safer than normal property access.Replace
getattr
with attribute access(B009)
if queue is not None: | ||
raise ValueError() | ||
if submission_template is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Improve error handling when queue
is specified
Raising a ValueError
without a message when queue
is not None
can be unclear to users.
Consider providing a clear error message or removing the queue
parameter if it's not supported. Here's an example of adding an informative error message:
if queue is not None:
- raise ValueError()
+ raise ValueError("Specifying 'queue' is not supported in this context.")
Alternatively, if the queue
parameter is not used at all, consider removing it from the method signature and any references within the method.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if queue is not None: | |
raise ValueError() | |
if submission_template is None: | |
if queue is not None: | |
raise ValueError("Specifying 'queue' is not supported in this context.") | |
if submission_template is None: |
if isinstance(command, list): | ||
command = "".join(command) | ||
if working_directory is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use appropriate separator when joining commands
Using "".join(command)
concatenates the commands without any separators, which may result in invalid command strings.
Consider joining with a newline or space, depending on your specific use case. Apply this diff to join commands with newlines:
if isinstance(command, list):
- command = "".join(command)
+ command = "\n".join(command)
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if isinstance(command, list): | |
command = "".join(command) | |
if working_directory is None: | |
if isinstance(command, list): | |
command = "\n".join(command) | |
if working_directory is None: |
# Conflicts: # pysqa/utils/basic.py # pysqa/wrapper/abstract.py # pysqa/wrapper/flux.py # pysqa/wrapper/gent.py # pysqa/wrapper/lsf.py # pysqa/wrapper/moab.py # pysqa/wrapper/sge.py # pysqa/wrapper/slurm.py # pysqa/wrapper/torque.py
Summary by CodeRabbit
Release Notes
New Features
render_submission_template
method across multiple job scheduler classes (Flux, LSF, Moab, SGE, SLURM, Torque) for generating dynamic job submission scripts.enable_reservation_command
property toSchedulerCommands
class to support job reservation functionality.CoreQueueAdapter
class to streamline job submission and management across various queuing systems.Refactor
SchedulerCommands
class to improve abstraction and enforce implementation in subclasses.BasisQueueAdapter
class by removing redundant methods and leveraging functionality from the superclass.Bug Fixes
check_queue_parameters
function for better clarity on expected output.