Skip to content
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Rearranged the update_tests.sh to be easier to read + fixed minor bug…
…s/formatting issues
  • Loading branch information
terryluan12 committed Jan 12, 2026
commit db005d465c44ca18b37fd0223bd6fa6d38ec0202
155 changes: 86 additions & 69 deletions scripts/update_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Options:
-h/--help Show this help message and exit

Example Usage:
$0 -c ~/cpython -r - . -t 300 # Updates all non-updated tests with a timeout value of 300 seconds
$0 -c ~/cpython -r . -t 300 # Updates all non-updated tests with a timeout value of 300 seconds
$0 -c ~/cpython -r . -u -j 5 # Updates all non-updated tests + copies files not in cpython into rpython, with maximum 5 processes active at a time
$0 -c ~/cpython -r . -a # Updates all non-updated tests + annotates with @unittest.expectedFailure/@unittest.skip
$0 -r . -s # For all current tests, check if @unittest.skip can be downgraded to @unittest.expectedFailure
Expand Down Expand Up @@ -56,11 +56,11 @@ ignored_libraries=("multiprocessing" "concurrent")
while [[ $# -gt 0 ]]; do
case "$1" in
-c|--cpython-path)
cpython_path="$2"
cpython_path="$2/Lib/test"
shift 2
;;
-r|--rpython-path)
rpython_path="$2"
rpython_path="$2/Lib/test"
shift 2
;;
-u|--copy-untracked)
Expand Down Expand Up @@ -93,10 +93,13 @@ while [[ $# -gt 0 ]]; do
;;
esac
done
Comment on lines +56 to +95
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Missing validation for required arguments and option values.

Several issues with argument parsing:

  1. Options like -t, -j, -c, -r don't validate that $2 exists before shift 2, which can silently consume the next flag.
  2. No validation that cpython_path is provided when not using --update-skipped.
  3. No validation that paths exist or that timeout/num_jobs are valid integers.
Suggested validation pattern
         -t|--timeout)
+            if [[ -z "$2" || "$2" == -* ]]; then
+                echo "Error: -t requires a numeric value" >&2
+                exit 1
+            fi
             timeout="$2"
             shift 2
             ;;

Add post-parsing validation:

# After the while loop
if ! $check_skip_flag && [[ -z "$cpython_path" ]]; then
    echo "Error: --cpython-path is required for update mode" >&2
    exit 1
fi

if [[ -z "$rpython_path" ]]; then
    echo "Error: --rpython-path is required" >&2
    exit 1
fi

if [[ ! -d "$cpython_path" ]] && ! $check_skip_flag; then
    echo "Error: CPython path does not exist: $cpython_path" >&2
    exit 1
fi
🤖 Prompt for AI Agents
In @scripts/update_tests.sh around lines 56 - 95, Argument parsing lacks
validation: ensure each option that does "shift 2" (flags -c/--cpython-path,
-r/--rpython-path, -t/--timeout, -j/--jobs) first checks that a following value
($2) exists and is not another flag before shifting; after the while loop
validate required variables (if check_skip_flag is false require cpython_path,
always require rpython_path), verify that cpython_path and rpython_path point to
existing directories, and validate timeout and num_jobs are positive integers;
update the case branches for cpython_path/rpython_path/timeout/num_jobs to error
and exit when $2 missing, and add post-parsing checks for existence and integer
format for timeout/num_jobs before proceeding.

# -------------------------------------- Constants ------------------------------------- #
RUSTPYTHON_POSSIBLE_SKIP_RE="@unittest.skip.*\([\"']TODO:\s*RUSTPYTHON.*[\"']\)"
RUSTPYTHON_CANONICAL_SKIP_RE="@unittest.skip\('TODO: RUSTPYTHON; .*'\)"
RUSTPYTHON_CANONICAL_EX_FAILURE="@unittest.expectedFailure # TODO: RUSTPYTHON"
RUSTPYTHON_CANONICAL_EX_FAILURE_RE="\s@unittest\.expectedFailure # TODO: RUSTPYTHON.*"

cpython_path="$cpython_path/Lib/test"
rpython_path="$rpython_path/Lib/test"

# --------------------------------- Updating functions --------------------------------- #

update_tests() {
local libraries=("$@")
Expand Down Expand Up @@ -135,11 +138,13 @@ update_test() {
fi
Comment on lines +132 to +138
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Missing error handling and variable quoting.

  1. No error handling if lib_updater.py fails - the script continues silently.
  2. Variables passed to annotate_lib should be quoted to handle paths with spaces.
  3. The boolean check $annotate works but [[ $annotate == true ]] is clearer.
Suggested improvements
     else
         echo "Using lib_updater to update $lib"
-        ./scripts/lib_updater.py --from $clib_path --to $rlib_path -o $rlib_path
+        if ! ./scripts/lib_updater.py --from "$clib_path" --to "$rlib_path" -o "$rlib_path"; then
+            echo "Warning: lib_updater.py failed for $lib" >&2
+        fi
     fi


-    if [[ $annotate && -f "$rlib_path" && $(basename -- "$rlib_path") == test_*.py ]]; then
-        annotate_lib $lib $rlib_path
+    if [[ $annotate == true && -f "$rlib_path" && $(basename -- "$rlib_path") == test_*.py ]]; then
+        annotate_lib "$lib" "$rlib_path"
     fi
📝 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.

Suggested change
./scripts/lib_updater.py --from $clib_path --to $rlib_path -o $rlib_path
fi
if [[ $annotate && -f "$rlib_path" && $(basename -- "$rlib_path") == test_*.py ]]; then
annotate_lib $lib $rlib_path
fi
if ! ./scripts/lib_updater.py --from "$clib_path" --to "$rlib_path" -o "$rlib_path"; then
echo "Warning: lib_updater.py failed for $lib" >&2
fi
fi
if [[ $annotate == true && -f "$rlib_path" && $(basename -- "$rlib_path") == test_*.py ]]; then
annotate_lib "$lib" "$rlib_path"
fi
🤖 Prompt for AI Agents
In @scripts/update_tests.sh around lines 132 - 138, The block calling
lib_updater.py should check its exit status and fail fast: after running
./scripts/lib_updater.py --from $clib_path --to $rlib_path -o $rlib_path, test
the command's return code and log/exit (e.g., non-zero -> echo error and exit 1)
instead of continuing silently; also change the annotate conditional to
explicitly test [[ $annotate == true ]] and quote variables when calling
annotate_lib (use annotate_lib "$lib" "$rlib_path") so paths with spaces are
handled safely.

}

# --------------------------------- Downgrade Skips functions --------------------------------- #

check_skips() {
local libraries=("$@")
for lib in "${libraries[@]}"
do
if grep -qiE "@unittest.skip.*\('TODO:\s*RUSTPYTHON.*'\)" "$rpython_path/$lib"; then
if grep -qiE "$RUSTPYTHON_POSSIBLE_SKIP_RE" "$rpython_path/$lib"; then
sem
check_skip "$lib" &
else
Expand All @@ -158,6 +163,41 @@ check_skip() {
annotate_lib $lib $rlib_path
}

apply_skip() {
local rlib_path=$1
local test_name=$2
local hanging=$3
message="unknown"

# Check if the test has a backup skip
if [[ -n "${SKIP_BACKUP[$test_name]}" ]]; then
message="${SKIP_BACKUP[$test_name]//\'/\"}"
elif $hanging; then
message="hanging"
fi

add_above_test "$rlib_path" "$test_name" "@unittest.skip('TODO: RUSTPYTHON; $message')"
}

backup_skips() {
local rlib_path=$1
declare -gA SKIP_BACKUP=() # global associative array
readarray -t skips < <(grep -E -n "^[[:space:]]*@unittest\.skip.*TODO\s?:\s?RUSTPYTHON" "$rlib_path" | sort -u)

for line in "${skips[@]}"; do
line_num="${line%%:*}"
line_text=$(echo "$line" | grep -oPi "(?<=RUSTPYTHON)\s*[;:]\s*\K(.*)?(?=[\"'])")
next_line=$(sed -n "$((line_num + 1))p" "$rlib_path")

if [[ "$next_line" =~ def[[:space:]]+([a-zA-Z0-9_]+)\( ]]; then
test_name="${BASH_REMATCH[1]}"
SKIP_BACKUP[$test_name]="$line_text"
fi
done
}

# --------------------------------- General functions --------------------------------- #

annotate_lib() {
local lib=${1//\//.}
local rlib_path=$2
Expand All @@ -182,7 +222,7 @@ annotate_lib() {
if already_failed $rlib_path $test; then
replace_expected_with_skip $rlib_path $test
else
add_above_test $rlib_path $test "@unittest.expectedFailure # TODO: RUSTPYTHON"
add_above_test $rlib_path $test "$RUSTPYTHON_CANONICAL_EX_FAILURE"
fi
done

Expand All @@ -199,7 +239,7 @@ annotate_lib() {

output=$(rustpython $lib 2>&1)

if [[ attempts -gt 10 ]]; then
if [[ $attempts -gt 15 ]]; then
echo "Issue annotating $lib" >&2
return;
fi
Expand All @@ -209,38 +249,41 @@ annotate_lib() {
unset SKIP_BACKUP
}
Comment on lines +201 to +250
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Declare and assign separately to avoid masking return values.

The combined declaration and assignment on line 204 masks the exit status of rustpython. If rustpython fails catastrophically, you won't detect it.

Also, the 15-attempt limit is reasonable but the logic could still get stuck if tests alternate between different failure modes.

Suggested fix for SC2155
 annotate_lib() {
     local lib=${1//\//.}
     local rlib_path=$2
-    local output=$(rustpython $lib 2>&1)
+    local output
+    output=$(rustpython "$lib" 2>&1)
📝 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.

Suggested change
annotate_lib() {
local lib=${1//\//.}
local rlib_path=$2
local output=$(rustpython $lib 2>&1)
if grep -q "NO TESTS RAN" <<< "$output"; then
echo "No tests ran in $lib. skipping annotation"
return
fi
echo "Annotating $lib"
local attempts=0
while ! grep -q "Tests result: SUCCESS" <<< "$output"; do
((attempts++))
# echo "$lib failing, annotating..."
readarray -t failed_tests <<< "$(echo "$output" | awk '/^(FAIL:|ERROR:)/ {print $2}' | sort -u)"
# If the test fails/errors, then expectedFailure it
for test in "${failed_tests[@]}"
do
if already_failed $rlib_path $test; then
replace_expected_with_skip $rlib_path $test
else
add_above_test $rlib_path $test "$RUSTPYTHON_CANONICAL_EX_FAILURE"
fi
done
# If the test crashes/hangs, then skip it
if grep -q "\.\.\.$" <<< "$output"; then
crashing_test=$(echo "$output" | grep '\.\.\.$' | head -n 1 | awk '{print $1}')
if grep -q "Timeout" <<< "$output"; then
hanging=true
else
hanging=false
fi
apply_skip "$rlib_path" "$crashing_test" $hanging
fi
output=$(rustpython $lib 2>&1)
if [[ $attempts -gt 15 ]]; then
echo "Issue annotating $lib" >&2
return;
fi
done
echo "Successfully updated $lib"
unset SKIP_BACKUP
}
annotate_lib() {
local lib=${1//\//.}
local rlib_path=$2
local output
output=$(rustpython "$lib" 2>&1)
if grep -q "NO TESTS RAN" <<< "$output"; then
echo "No tests ran in $lib. skipping annotation"
return
fi
echo "Annotating $lib"
local attempts=0
while ! grep -q "Tests result: SUCCESS" <<< "$output"; do
((attempts++))
# echo "$lib failing, annotating..."
readarray -t failed_tests <<< "$(echo "$output" | awk '/^(FAIL:|ERROR:)/ {print $2}' | sort -u)"
# If the test fails/errors, then expectedFailure it
for test in "${failed_tests[@]}"
do
if already_failed $rlib_path $test; then
replace_expected_with_skip $rlib_path $test
else
add_above_test $rlib_path $test "$RUSTPYTHON_CANONICAL_EX_FAILURE"
fi
done
# If the test crashes/hangs, then skip it
if grep -q "\.\.\.$" <<< "$output"; then
crashing_test=$(echo "$output" | grep '\.\.\.$' | head -n 1 | awk '{print $1}')
if grep -q "Timeout" <<< "$output"; then
hanging=true
else
hanging=false
fi
apply_skip "$rlib_path" "$crashing_test" $hanging
fi
output=$(rustpython $lib 2>&1)
if [[ $attempts -gt 15 ]]; then
echo "Issue annotating $lib" >&2
return;
fi
done
echo "Successfully updated $lib"
unset SKIP_BACKUP
}
🧰 Tools
🪛 Shellcheck (0.11.0)

[warning] 204-204: Declare and assign separately to avoid masking return values.

(SC2155)

🤖 Prompt for AI Agents
In @scripts/update_tests.sh around lines 201 - 250, In annotate_lib, avoid
combining declaration and assignment for output (currently local
output=$(rustpython ...)) so the rustpython exit code isn’t masked; instead
declare local output first, run output=$(rustpython $lib 2>&1) and capture its
exit status ($?) immediately, logging and returning on a non-zero catastrophic
failure; also harden the retry loop around attempts by detecting unchanged or
oscillating output (e.g., keep previous_output and if output == previous_output
or it alternates between two states for multiple iterations then abort with an
error) so the while loop can’t hang indefinitely even within the 15-attempt cap.


sem() {
while (( $(jobs -rp | wc -l) >= $num_jobs )); do
sleep 0.1 # brief pause before checking again
done
}

add_above_test() {
local file=$1
local test=$2
local line=$3
sed -i "s/^\([[:space:]]*\)def $test(/\1$line\n\1def $test(/" "$file"
}

# --------------------------------- Utility functions --------------------------------- #

rustpython() {
cargo run --release --features encodings,sqlite -- -m test -j 1 -u all --fail-env-changed --timeout "$timeout" -v "$@"
}

replace_expected_with_skip() {
file=$1
test_name=$2
sed -E "/^\s*@unittest\.expectedFailure\s+# TODO: RUSTPYTHON/ { N; /\n\s*def $test_name/ { s/^(\s*)@unittest\.expectedFailure\s+# TODO: RUSTPYTHON/\1@unittest.skip\('TODO: RUSTPYTHON'\)/ } }" -i $file
sed -E "/$RUSTPYTHON_CANONICAL_EX_FAILURE_RE/ { N; /\n\s*def $test_name/ { s/^(\s*)@unittest\.expectedFailure\s+# TODO: RUSTPYTHON/\1@unittest.skip\('TODO: RUSTPYTHON'\)/ } }" -i $file
}
Comment on lines +271 to +275
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Missing variable quoting and lost skip reason.

  1. $file should be quoted to handle paths with spaces.
  2. The replacement loses any specific skip reason, converting to a generic message. Consider preserving the reason if one exists.
Suggested fix
 replace_expected_with_skip() {
-    file=$1
-    test_name=$2
-    sed -E "/$RUSTPYTHON_CANONICAL_EX_FAILURE_RE/ { N; /\n\s*def $test_name/ { s/^(\s*)@unittest\.expectedFailure\s+# TODO: RUSTPYTHON/\1@unittest.skip\('TODO: RUSTPYTHON'\)/ } }" -i $file
+    local file=$1
+    local test_name=$2
+    sed -E "/$RUSTPYTHON_CANONICAL_EX_FAILURE_RE/ { N; /\n\s*def $test_name/ { s/^(\s*)@unittest\.expectedFailure\s+# TODO: RUSTPYTHON/\1@unittest.skip('TODO: RUSTPYTHON')/ } }" -i "$file"
 }
📝 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.

Suggested change
replace_expected_with_skip() {
file=$1
test_name=$2
sed -E "/$RUSTPYTHON_CANONICAL_EX_FAILURE_RE/ { N; /\n\s*def $test_name/ { s/^(\s*)@unittest\.expectedFailure\s+# TODO: RUSTPYTHON/\1@unittest.skip\('TODO: RUSTPYTHON'\)/ } }" -i $file
}
replace_expected_with_skip() {
local file=$1
local test_name=$2
sed -E "/$RUSTPYTHON_CANONICAL_EX_FAILURE_RE/ { N; /\n\s*def $test_name/ { s/^(\s*)@unittest\.expectedFailure\s+# TODO: RUSTPYTHON/\1@unittest.skip('TODO: RUSTPYTHON')/ } }" -i "$file"
}
🤖 Prompt for AI Agents
In @scripts/update_tests.sh around lines 271 - 275, The helper function
replace_expected_with_skip should quote the $file argument and preserve any
existing skip reason instead of injecting a generic one; update
replace_expected_with_skip to call sed on "$file" (quoted) and change the
substitution to capture the original inline comment/reason (e.g., the text after
the # marker or after "TODO: RUSTPYTHON") and reuse that captured reason inside
the @unittest.skip(...) replacement so the original reason is preserved while
converting @unittest.expectedFailure to @unittest.skip.


already_failed() {
file=$1
test_name=$2
grep -qPz "\s*@unittest\.expectedFailure # TODO: RUSTPYTHON\n\s*def\s+${test_name}\(" $file
grep -qPz "$RUSTPYTHON_CANONICAL_EX_FAILURE_RE\n\s*def\s+${test_name}\(" $file
}

files_equal() {
cmp --silent "$1" "$2"
}

rustpython() {
cargo run --release --features encodings,sqlite -- -m test -j 1 -u all --fail-env-changed --timeout "$timeout" -v "$@"
}

sem() {
while (( $(jobs -rp | wc -l) >= $num_jobs )); do
sleep 0.1 # brief pause before checking again
done
}

add_above_test() {
local file=$1
local test=$2
local line=$3
sed -i "s/^\([[:space:]]*\)def $test(/\1$line\n\1def $test(/" "$file"
}

remove_skips() {
local rlib_path=$1
Expand All @@ -252,51 +295,25 @@ remove_skips() {
sed -i -E '/^[[:space:]]*@unittest\.skip.*\(["'\'']TODO\s?:\s?RUSTPYTHON.*["'\'']\)/Id' $rlib_path
}

apply_skip() {
local rlib_path=$1
local test_name=$2
local hanging=$3
message="unknown"

# Check if the test has a backup skip
if [[ -n "${SKIP_BACKUP[$test_name]}" ]]; then
message="${SKIP_BACKUP[$test_name]//\'/\"}"
elif $hanging; then
message="hanging"
fi

add_above_test "$rlib_path" "$test_name" "@unittest.skip('TODO: RUSTPYTHON; $message')"
}

backup_skips() {
local rlib_path=$1
declare -gA SKIP_BACKUP=() # global associative array
readarray -t skips < <(grep -E -n "^[[:space:]]*@unittest\.skip.*TODO\s?:\s?RUSTPYTHON" "$rlib_path" | sort -u)
main() {
if ! $check_skip_flag; then
echo "Updating Tests"

for line in "${skips[@]}"; do
line_num="${line%%:*}"
line_text=$(echo "$line" | grep -oPi "(?<=RUSTPYTHON)\s*[;:]\s*\K(.*)?(?=[\"'])")
next_line=$(sed -n "$((line_num + 1))p" "$rlib_path")
# If libraries are not specified, then update all tests
if [[ "${#libraries[@]}" -eq 0 ]]; then
readarray -t libraries <<< $(find ${cpython_path} -type f -printf "%P\n" | grep -vE "$(IFS=\|; echo "${ignored_libraries[*]}")")
fi
update_tests "${libraries[@]}"
else
echo "Checking Skips"

if [[ "$next_line" =~ def[[:space:]]+([a-zA-Z0-9_]+)\( ]]; then
test_name="${BASH_REMATCH[1]}"
SKIP_BACKUP[$test_name]="$line_text"
# If libraries are not specified, then check all tests
if [[ ${#libraries[@]} -eq 0 ]]; then
readarray -t libraries <<< $(find ${rpython_path} -iname "test_*.py" -type f -printf "%P\n" | grep -vE "$(IFS=\|; echo "${ignored_libraries[*]}")")
fi
done
check_skips "${libraries[@]}"
Comment on lines +303 to +314
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Word splitting issues and empty result handling (SC2046).

The find command output should be properly handled to avoid word splitting issues. Additionally, if find returns no results, the array will contain one empty element rather than being empty.

Suggested fix using process substitution
         # If libraries are not specified, then update all tests
         if [[ "${#libraries[@]}" -eq 0 ]]; then
-            readarray -t libraries <<< $(find ${cpython_path} -type f -printf "%P\n" | grep -vE "$(IFS=\|; echo "${ignored_libraries[*]}")")
+            readarray -t libraries < <(find "${cpython_path}" -type f -printf "%P\n" | grep -vE "$(IFS=\|; echo "${ignored_libraries[*]}")")
+            # Remove empty elements
+            libraries=("${libraries[@]}")
         fi

Same pattern for line 312:

         if [[ ${#libraries[@]} -eq 0 ]]; then
-            readarray -t libraries <<< $(find ${rpython_path} -iname "test_*.py" -type f -printf "%P\n" | grep -vE "$(IFS=\|; echo "${ignored_libraries[*]}")")
+            readarray -t libraries < <(find "${rpython_path}" -iname "test_*.py" -type f -printf "%P\n" | grep -vE "$(IFS=\|; echo "${ignored_libraries[*]}")")
         fi
📝 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.

Suggested change
if [[ "${#libraries[@]}" -eq 0 ]]; then
readarray -t libraries <<< $(find ${cpython_path} -type f -printf "%P\n" | grep -vE "$(IFS=\|; echo "${ignored_libraries[*]}")")
fi
update_tests "${libraries[@]}"
else
echo "Checking Skips"
# If libraries are not specified, then check all tests
if [[ ${#libraries[@]} -eq 0 ]]; then
readarray -t libraries <<< $(find ${rpython_path} -iname "test_*.py" -type f -printf "%P\n" | grep -vE "$(IFS=\|; echo "${ignored_libraries[*]}")")
fi
check_skips "${libraries[@]}"
if [[ "${#libraries[@]}" -eq 0 ]]; then
readarray -t libraries < <(find "${cpython_path}" -type f -printf "%P\n" | grep -vE "$(IFS=\|; echo "${ignored_libraries[*]}")")
fi
update_tests "${libraries[@]}"
else
echo "Checking Skips"
# If libraries are not specified, then check all tests
if [[ ${#libraries[@]} -eq 0 ]]; then
readarray -t libraries < <(find "${rpython_path}" -iname "test_*.py" -type f -printf "%P\n" | grep -vE "$(IFS=\|; echo "${ignored_libraries[*]}")")
fi
check_skips "${libraries[@]}"
🧰 Tools
🪛 Shellcheck (0.11.0)

[warning] 304-304: Quote this to prevent word splitting.

(SC2046)


[warning] 312-312: Quote this to prevent word splitting.

(SC2046)

fi
}

if ! $check_skip_flag; then
echo "Updating Tests"

if [[ ${#libraries[@]} -eq 0 ]]; then
readarray -t libraries <<< $(find ${cpython_path} -type f -printf "%P\n" | grep -vE "$(IFS=\|; echo "${ignored_libraries[*]}")")
fi
update_tests "${libraries[@]}"
else
echo "Checking Skips"

if [[ ${#libraries[@]} -eq 0 ]]; then
readarray -t libraries <<< $(find ${rpython_path} -iname "test_*.py" -type f -printf "%P\n" | grep -vE "$(IFS=\|; echo "${ignored_libraries[*]}")")
fi
check_skips "${libraries[@]}"
fi
main