-
Notifications
You must be signed in to change notification settings - Fork 549
chore(types): Type-clean colang/ (111 errors) #1381
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
base: develop
Are you sure you want to change the base?
Conversation
Tagging @cparisien, @Pouyanpi , @trebedea for review |
Documentation preview |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
f5e281f
to
489b2a3
Compare
b4a4f85
to
f507ea0
Compare
Converting to draft while I rebase on the latest changes to |
… branch" This reverts commit 71d00f0.
f507ea0
to
76caade
Compare
Refreshed this PR based on the latest |
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.
is this an unexpected indent?
if hasattr(self, "_run_output_rails_in_parallel_streaming"): | ||
self.action_dispatcher.register_action( | ||
self._run_output_rails_in_parallel_streaming, | ||
getattr(self, "_run_output_rails_in_parallel_streaming"), |
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.
getattr(self, "_run_output_rails_in_parallel_streaming"), | |
self._run_output_rails_in_parallel_streaming, # type: ignore |
using getattr() after hasattr() check is redundant and less type-safe and also not LSP friendly.
side note (not related to this PR): having these methods registered in a base class is BAD.
if hasattr(self, "_run_flows_in_parallel"): | ||
self.action_dispatcher.register_action( | ||
self._run_flows_in_parallel, name="run_flows_in_parallel" | ||
getattr(self, "_run_flows_in_parallel"), name="run_flows_in_parallel" |
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.
getattr(self, "_run_flows_in_parallel"), name="run_flows_in_parallel" | |
self._run_flows_in_parallel, name="run_flows_in_parallel" # type: ignore |
if hasattr(self, "_run_input_rails_in_parallel"): | ||
self.action_dispatcher.register_action( | ||
self._run_input_rails_in_parallel, name="run_input_rails_in_parallel" | ||
getattr(self, "_run_input_rails_in_parallel"), |
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.
getattr(self, "_run_input_rails_in_parallel"), | |
self._run_input_rails_in_parallel, # type: ignore |
if hasattr(self, "_run_output_rails_in_parallel"): | ||
self.action_dispatcher.register_action( | ||
self._run_output_rails_in_parallel, name="run_output_rails_in_parallel" | ||
getattr(self, "_run_output_rails_in_parallel"), |
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.
getattr(self, "_run_output_rails_in_parallel"), | |
self._run_output_rails_in_parallel, # type: ignore |
@tgasser-nv I created a dummy commit and can see around 63 pyright errors when pre-commits are run. Would you please have a look? |
Description
Summary
This report details the type-safety enhancements and bug fixes introduced in the pull request. The changes primarily focus on preventing runtime
TypeError
,AttributeError
, andKeyError
exceptions by handling potentiallyNone
values and ensuring variables conform to their expected types.Medium Risk
Changes in this category add new logical branches (e.g.,
if obj is not None
) or make assumptions about default behavior. While they significantly improve robustness, they alter execution flow and warrant careful review.1. Guarding Against
None
Values Before AccessThis is the most common fix, adding checks to ensure an object is not
None
before its attributes or keys are accessed. This preventsAttributeError
andTypeError
.Files:
nemoguardrails/colang/v1_0/lang/colang_parser.py
, Line 340nemoguardrails/colang/v1_0/lang/colang_parser.py
, Line 962nemoguardrails/colang/v1_0/lang/colang_parser.py
, Line 1014nemoguardrails/colang/v1_0/lang/colang_parser.py
, Line 1370nemoguardrails/colang/v1_0/lang/comd_parser.py
, Line 365nemoguardrails/colang/v2_x/runtime/runtime.py
, Line 390Original Error: Potential
TypeError: 'NoneType' object is not subscriptable
orAttributeError: 'NoneType' object has no attribute '...'
.Example Fix (
colang_parser.py
, Line 962):Explanation:
self.current_element
andyaml_value
are notNone
before attempting to iterate over keys and perform assignments.None
, the operation should be silently skipped.ValueError
ifself.current_element
isNone
, enforcing that it must be initialized before this function is called. However, skipping is a more defensive and robust approach in a complex parser.2. Providing Default Values for Optional Variables
This pattern handles cases where a variable might be
None
by substituting a sensible default (e.g., an empty list, empty string, or0
).Files:
nemoguardrails/colang/runtime.py
, Line 37nemoguardrails/colang/v1_0/lang/colang_parser.py
, Line 315nemoguardrails/colang/v1_0/lang/coyml_parser.py
, Line 424nemoguardrails/colang/v1_0/runtime/flows.py
, Line 471Original Error: Potential
TypeError
when a function expects an iterable or number but receivesNone
.Example Fix (
coyml_parser.py
, Line 424):Explanation:
[]
as a default if the"then"
or"else"
keys are missing fromif_element
or are not lists. This ensures_extract_elements
always receives an iterable.3. Explicit Type Casting and Result Wrapping
This involves explicitly converting a variable to a required type (e.g.,
str()
,int()
) or wrapping a return value to conform to an expected structure (e.g., wrapping a value in a dictionary).Files:
nemoguardrails/colang/v1_0/runtime/flows.py
, Line 263nemoguardrails/colang/v1_0/runtime/runtime.py
, Line 798nemoguardrails/colang/v1_0/lang/coyml_parser.py
, Line 434Original Error: Potential
TypeError
if a function receives an object of an unexpected type.Example Fix (
runtime.py
, Line 798):Explanation:
_get_action_resp
is expected to return a dictionary. This fix wraps any non-dictionary return value into adict
with a"value"
key.Low Risk
These changes involve adding or correcting type hints and performing minor refactors that do not alter the program's logic. They improve code clarity and static analysis without any risk of functional regression.
1. Addition of Standard Type Hints
This involves adding explicit type annotations to variables and function signatures, which helps static analysis tools catch errors.
Files:
nemoguardrails/colang/v1_0/lang/colang_parser.py
, Line 129nemoguardrails/colang/v1_0/runtime/flows.py
, Line 95nemoguardrails/logging/processing_log.py
, Line 25Original Error: Lack of type information, making static analysis less effective.
Example Fix (
colang_parser.py
, Line 129):Explanation:
self.current_element
is now explicitly typed as being either a dictionary orNone
. This allows the type checker (mypy
) to validate its usage throughout the class.2. Assertions to Guide the Type Checker
This pattern uses
assert
statements to inform the type checker that a variable is notNone
within a specific code block, narrowing its type.File:
nemoguardrails/colang/v1_0/lang/colang_parser.py
, Line 1836Original Error: The type checker would incorrectly flag usage of
snippet
as a potentialTypeError
because it was initialized toNone
.Example Fix (
colang_parser.py
, Line 1836):Explanation:
assert snippet is not None
statement guarantees to the static analyzer that from this point forward,snippet
cannot beNone
, thus making the accesssnippet["lines"]
type-safe.snippet
has been assigned a dictionary by the time this line is reached.if snippet is not None:
block could be used, but since the logic implies it can't beNone
here, an assertion is more appropriate to catch logic errors during development.Test Plan
Type-checking
Unit-tests
Local CLI check
Checklist