I have a project that needs updating from python2 to python3. It currently uses pkg_resources
, which has significant overhead (PyCon 2018 - Get Your Resources Faster with importlib.resources, by Barry Warsaw). It will be packaged into a zip file. The relevant portions of the package structure are:
+-- project/
|__+ __init__.py
|__+ main.py
|__resources/
| |__+ images/
| | |__ # program images
| |__+ logging/
| |__+ custom_logger.py
|__log/
|__+ project_log.log
Intent for Original Question
The intent for the original question was to ask "how does one get the absolute path to a subpackage from within another subpackage", but I did a poor job wording this. I thought since current working directory
meant "path to where the cwd
command is run from" that this could be used, but I later learned my understanding was incomplete. current working directory
means (in layman's terms) "path to where the cwd
command is run from on the commandline"). This is why I was having trouble. If I run my program from within the top-level package
C:\Users\usr\Destop\program>py main.py
and use pathlib.Path.cwd()
in a .py
file in any other subpackage (resources
, logging
, log
), I will get the same answer:
C:\Users\usr\Destop\program
I learned this is proper behavior, but it means I cannot use relative paths to get from one subpackage to another (I need to use relative paths since I don't know where the end user will install this program on his/her machine).
Relevant 2nd Part to Question that was Not Well-Clarified
Since part of my need is to update to python3, both pkgutil
and importlib.resources
were investigated. Each of these require resources to be treated as packages, so to update to use either of them, I have to add __init__.py
to the folders resources
, logging
, and log
. Not a big deal thankfully as this isn't a large program.
Note, for backwards compatibility with minimal code reediting, a namespace renaming has been recommended and used by others (e.g. see (How to use importlib.resources.path(package, resource)?).:
try:
import importlib.resources as pkg_resources
except ImportError:
# Try backported to PY<37 `importlib_resources`.
import importlib_resources as pkg_resources
Neither pgkutil
nor importlib.resources
has a method that directly returns "this subpackage" (in the way that pathlib.Path.cwd()
"directly returns" the cwd
without any extra code), but I think importlib.resources
has a method I can use that will require the least amount of code and still be understandable to readers. Please note the ask is to get the absolute path to "this subpackage" and nothing else. I do not want to have to use a different approach.
The methods I would use is
try:
import importlib.resources as pkg_resources
except ImportError:
# Try backported to PY<37 `importlib_resources`.
import importlib_resources as pkg_resources
with pkg_resources.path("logging", "__init__.py") as fl:
path = fl.parent.resolve()
Conclusion
Beyond this, I have no questions, because it will probably be judged as an "opinion" question. Please note the __file__
method is unacceptable as this does not work with zip packages (see PyCon 2018 - Get Your Resources Faster with importlib.resources, by Barry Warsaw). If there is anything incorrect in this approach or if it can be improved, I would like to know.