Code Maintenance In Python: Find All Files That Import A Module

One of the complexities of managing code for a robot, is knowing which programs use a common module that is changing.

For example, I created a module called carlDataJson(.py) to create, retrieve, update, and delete (CRUD) “Carl Data”. A year later, I realize that it should have been called just “carlData(.py)”, so that in the future, I can replace the underlying JSON file database with a real database (sql-lite), and not have lots of code “remembering” the JSON days:

import carlDataJson

carlDataJson.saveCarlData("key","value")  

should really be:

import carlData

carlData.saveCarlData("key","value")  

I discovered there is a way to find every Carl program that imports the carlDataJson module:

$ grep -r --include "*.py" "import carlDataJson" .
./Examples/Vosk/vcommand.py:import carlDataJson
./Examples/pycam/MotionDetect/carl_motion_hibye.py:    import carlDataJson as cdj
./Projects/WheelLog/wheellog.py:    import carlDataJson
./Projects/IMU/imulog.py:    import carlDataJson
./Projects/carlDataJson/add_to_carlData.py:import carlDataJson
./Projects/carlDataJson/print_carlDataJson.py:import carlDataJson
./Projects/Juicer/juicer.py:import carlDataJson as cd
./plib/imulog.py:    import carlDataJson
./plib/status.py:import carlDataJson as carlData
./plib/getLastDismount.py:import carlDataJson
./plib/juicer.py:import carlDataJson as cd
./plib/getChargingStateStr.py:import carlDataJson
./plib/getDockCycle.py:import carlDataJson
./plib/wheellog.py:    import carlDataJson
./plib/vcommand.py:import carlDataJson
./plib/getLastDocking.py:import carlDataJson

So if I want to change the name now before even more programs become dependent on this poorly named module, I can know every file that must be updated (and retested…).

To make that easier to remember the next time, I created utility:

what_uses.sh:

#!/bin/bash

# FILE:  what_uses.sh
# USAGE:  ./what_uses.sh "pattern"

if [ "$#" -ne 1 ] ;
        then echo "Usage:  ./what_uses.sh \"import xyz\" "
        exit
fi
echo "Searching to find what Python files use \"$1\" "
grep -r --include "*.py" "$1" .

Example using “what_uses.sh” to find which programs are using a "do not initialize the EasyGoPiGo3() class speed variable:

$ ./what_uses.sh "noinit=True"
Searching to find what Python files use "noinit=True" 
./Examples/nyumaya/carl_hotword_eyes.py:	egpg = noinit_easygopigo3.EasyGoPiGo3(use_mutex=True, noinit=True)
./Examples/Vosk/test_vcommand_egpg.py:	egpg = easygopigo3.EasyGoPiGo3(use_mutex=True, noinit=True)
./Projects/VoiceCommander/voicecmdr.py:	egpg = easygopigo3.EasyGoPiGo3(use_mutex=True, noinit=True)
./systests/tiltpan/plib_tiltpan_test.py:        egpg = easygopigo3.EasyGoPiGo3(use_mutex=True,noinit=True)
./systests/noinit/test_noinit_easygopigo3.py:# PURPOSE:  Test the noinit=True option of the noinit_easygopigo3.EasyGoPiGo3() class
./systests/noinit/test_noinit_easygopigo3.py:#           by instantiating an EasyGoPiGo3(noinit=True) ojbect to access battery voltage
./systests/noinit/test_noinit_easygopigo3.py:    print("Initializing an EasyGoPiGo3(noinit=True) object")
./systests/noinit/test_noinit_easygopigo3.py:    noinit_egpg = noinit_easygopigo3.EasyGoPiGo3(use_mutex=True, noinit=True)
./systests/easygopigo3_plib/test_plib_easygopigo3.py:egpg = easygopigo3.EasyGoPiGo3(use_mutex=True, noinit=True)
./systests/easygopigo3_plib/test_new_easygopigo3.py:    egpg = easygopigo3.EasyGoPiGo3(use_mutex=True, noinit=True)
./systests/easygopigo3_plib/test_new_easygopigo3.py:    print("Exception while instantiating EasyGoPiGo3(noinit=True)")
./plib/vBatt.py:egpg = noinit_easygopigo3.EasyGoPiGo3(use_mutex=True, noinit=True)
./plib/eyes.py:	egpg = noinit_easygopigo3.EasyGoPiGo3(use_mutex=True, noinit=True)
1 Like

great idea for the shell program. I don’t use grep often enough to remember all of the parameters.
/K

2 Likes