Where is the "easygopigo3" library?

Greetings!

I hope this finds you safe, healthy and well.

Question:
I have been looking at the easygopigo3.py file(s) and I noticed that there are three of them. I found them located at:

/home/pi/Desktop/GoPiGo3/Software/Python/build/lib/easygopigo3.py

/home/pi/Desktop/GoPiGo3/Software/Python/build/lib.linux-armv7l-2.7/easygopigo3.py

/home/pi/Desktop/GoPiGo3/Software/Python/easygopigo3.py

Since I could not figure out which one was THE one, I renamed them, all of them, to “easy-gopigo3.py”. Now, I would assume that an import looking for “easygopigo3” would fail if the include file is named “easy-gopigp3”, right?

Nope!

I can run either the control panel “example” or the Remote Camera Robot project, and there are no include errors thrown - and all the functionality that depends on the easygopigo classes still works.

I am puzzled. I looked (using “file find”), for any other occurrences of “easygopigo3”, and found none.

I edited the python files to invalidate them and force a rebuild. I rebooted my 'bot. Nothing seems to affect this.

This leads me to only three possible conclusions:

  1. There’s another include file hidden somewhere.
  2. These python files exist as pre-compiled binaries someplace with the includes wrapped up in them.
  3. I’m going out of my mind.

If I comment out the include:

from easygopigo3 import EasyGoPiGo3

It throws an error and fails. (As I would expect.)

Would someone please explain to me what is happening here? I cannot imagine where the python scripts are satisfying their includes from.

Thanks!

SHORT ANSWER:
type:

python3 -m site
or
python -m site

in them “Easter” eggs

pi@Carl:~/Carl $ unzip -v /usr/local/lib/python3.5/dist-packages/gopigo3-1.2.0-py3.5.egg
Archive: /usr/local/lib/python3.5/dist-packages/gopigo3-1.2.0-py3.5.egg
Length Method Size Cmpr Date Time CRC-32 Name


56914 Defl:N 10458 82% 2019-06-22 12:00 3efc8972 easygopigo3.py
64711 Defl:N 11831 82% 2019-06-22 12:00 3272acf7 easysensors.py
34027 Defl:N 6750 80% 2019-06-22 12:00 d614f4d4 gopigo3.py
1346 Defl:N 627 53% 2019-06-22 12:00 06fd394b EGG-INFO/PKG-INFO

2 Likes

I’m a bit confused by the answer.

When I execute “python3 -m site” in a terminal window, I get a listing that is, essentially, like sys.path in the python shell.

Viz.:

pi@Charlie:~ $ python3 -m site
sys.path = [
    '/home/pi',
    '/usr/lib/python37.zip',
    '/usr/lib/python3.7',
    '/usr/lib/python3.7/lib-dynload',
    '/usr/local/lib/python3.7/dist-packages',
    '/usr/local/lib/python3.7/dist-packages/wiringpi-2.46.0-py3.7-linux-armv7l.egg',
    '/usr/local/lib/python3.7/dist-packages/smbus_cffi-0.5.1-py3.7-linux-armv7l.egg',
    '/usr/local/lib/python3.7/dist-packages/python_periphery-2.0.0-py3.7.egg',
    '/usr/local/lib/python3.7/dist-packages/cffi-1.13.2-py3.7-linux-armv7l.egg',
    '/usr/local/lib/python3.7/dist-packages/pycparser-2.19-py3.7.egg',
    '/usr/local/lib/python3.7/dist-packages/DI_Sensors-1.0.0-py3.7.egg',
    '/usr/local/lib/python3.7/dist-packages/Line_Follower-1.0.0-py3.7.egg',
    '/usr/local/lib/python3.7/dist-packages/Dexter_AutoDetection_and_I2C_Mutex-0.0.0-py3.7.egg',
    '/usr/local/lib/python3.7/dist-packages/gopigo3-1.2.0-py3.7.egg',
    '/usr/local/lib/python3.7/dist-packages/brickpi3-0.0.0-py3.7.egg',
    '/usr/local/lib/python3.7/dist-packages/grovepi-1.0.4-py3.7.egg',
    '/usr/local/lib/python3.7/dist-packages/pivotpi-0.0.0-py3.7.egg',
    '/usr/lib/python3/dist-packages',
]
USER_BASE: '/home/pi/.local' (exists)
USER_SITE: '/home/pi/.local/lib/python3.7/site-packages' (doesn't exist)
ENABLE_USER_SITE: True
pi@Charlie:~ $ 

So, my understanding is that, somewhere  in this pile of paths, is the particular include file I’m looking for?  And I have to go searching through everything  in my quest to find it?

So, there isn’t a way to ask exactly where  a particular include file is coming from?

This appears to tell me that there is a copy of that include file in the gopigo3-1.2.0-py3.5.egg file.  That returns us to the Musical Question - how do I know that this  is the one being used, instead of a file at /lib/user/foo/bar/python/more_stuff/cleverly_hidden/?

So far, there are now four possible locations, if I don’t include the dozen or so other paths.

The closest I have been able to find is the “__file__” and “os.path.abspath()” python functions.  Since I want a complete, absolute path, I tried os.path.abspath() in a python shell.  It returned:

>>> import os
>>> import easygopigo3
>>> os.path.abspath("easygopigo3")
'/home/pi/Dexter/GoPiGo3/Projects/RemoteCameraRobot/easygopigo3'
>>> 

os.path.abspath, without the “import easygopigo3” returns the same thing after closing and restarting Thonny.

>>> import os
>>> os.path.abspath("easygopigo3")
'/home/pi/Dexter/GoPiGo3/Projects/RemoteCameraRobot/easygopigo3'
>>> 

. . . saying that the include path is the directory that the Remote Camera Pi executable would run from - yet, it’s not there either.

Sigh. . .

1 Like

I think you are going to have to understand deeply the import process and the dynamic nature of sys.modules - when do things get listed in sys.modules, and when to they get delisted.

I don’t.

The fact that easygopigo3.__file__ shows a non-existent file might indicate that the import process found an easygopigo3.pyc which was originally built from the file when it existed by searching the sys.modules dictionary.

I saw some notes about things getting removed from sys.modules when an import fails, but you are so deep in the weeds from what I have explored, I really can’t help you.

2 Likes

Perhaps a bit of explanation is in order here:
Why am I getting so “wacked out” over the location of an object that (should be) well defined and work?

Though I can’t claim the “chops” you folks have, while testing  software, I’ve been “bitten” a few times by this.

  1. I’ve been in situations while testing where a developer had two versions of a library kicking around, wrote the software using one library, and thought  that he was using the second. Ergo, the software fails miserably in testing, yet the developer cannot reproduce it.

  2. Ever since the introduction of Windows Vista, all versions of Windows have inherited what I call “The ‘Virtual Store’ bug”.  In an effort to help “protect the user/programmer from themselves”, (<== Red Alert! Red Alert!), if an unprivileged process attempts to access a privileged location, (i.e. “Program Files”, etc.), a copy  is created in the user’s “%APPDATA%\Local\Virtual Store” directory, and execution proceeds from there.  Where this becomes a problem is when the actual software in the “Program Files” directory is updated or upgraded - the copy in the Virtual Store is never refreshed.  And, since the copy in the Virtual Store has priority - the updates don’t get executed unless the Virtual Store is cleared.

  3. Since this is my first foray into the Wild and Woolly world of robotics and hardware/software of this kind, I want to have a clearer understanding of how things are done.  When I say “do this”, what specifically causes  the wheels to turn or move in the way they do?  How, (in the programmatic sense), does the GoPiGo actually do  the things it does?  (i.e.  How does the GoPiGo actually know  when it has traveled 2 meters and/or 6 feet?)

Etc.

I am sorry if I have frustrated or annoyed you folks, but since there are several copies of the “easygopigo3” library floating around, I don’t know which of these - if any - are current and accurate.  These may simply be artifacts from earlier versions of the GoPiGo that have been left around collecting dust.

2 Likes

This is not on the python path. Consider it “DI Private” - used to build the DI libraries

Another not on the python path “DI Private” file that may exist as an artifact when python3 and python2.7 were diverging, but appears to be the source for the python2.7 egg file that will be built

I am pretty sure this is a convenience copy for users to see what is in the easygopigo3 object. It is not on the Python path.

I don’t know how your thonny IDE is confused about where easygopigo3 is imported from; When you execute outside of thonny does it report the same non-existent location?

Are you running in a virtual environment by any chance?

I am pretty sure my environment is getting the import from the egg listed in the site list (because that is what it lists for

import easygopigo3
import inspect


print("inspect.getfile()",inspect.getfile(easygopigo3))
print("__file__",easygopigo3.__file__)
print("__cached__",easygopigo3.__cached__)

pi@Carl:~/Carl/Examples/FindImport $ python3 findimport.py 
inspect.getfile() /usr/local/lib/python3.5/dist-packages/gopigo3-1.2.0-py3.5.egg/easygopigo3.py
__file__ /usr/local/lib/python3.5/dist-packages/gopigo3-1.2.0-py3.5.egg/easygopigo3.py
__cached__ None

The inspect package is the “officially supported” way of looking inside Python thing-ies. You can get the method specification, parameters, documentation, types, source code even I think.

2 Likes