This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author ncoghlan
Recipients barry, brett.cannon, eric.snow, ncoghlan, rhettinger
Date 2018-04-21.05:52:45
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1524289966.8.0.682650639539.issue33277@psf.upfronthosting.co.za>
In-reply-to
Content
As a concrete proposal for 3.8, how about:

1. Add the following utility functions to importlib.util (names adjusted to match PEP 451 rather than my initial suggestions above):

    def get_location(module):
        try:
            return module.__file__
        except AttributeError:
            pass
        spec = module.__spec__
        if spec.has_location:
            return spec.origin
        return None

    def get_cached_location(module):
        try:
            return module.__cached__
        except AttributeError:
            pass
        spec = module.__spec__
        if spec.has_location:
            return spec.cached
        return None

    def get_loader(module):
        try:
            return module.__loader__
        except AttributeError:
            pass
        return module.__spec__.loader

2. Explicitly make __file__/__cached__/__loader__ optional, and require 3rd party tools to use the relevant `importlib.util.get_*` APIs when they're defined rather than accessing the dunder-attributes directly.

I think those 3 are clear, but the right API for replacing direct access to __package__ is less clear, since there are two cases for querying the package name: whether you want actual packages to return their own name, or whether you want the name of their parent.

If we decide the relevant use case is "get the base package name for relative imports", then the following helper API may work:

    def get_base_package_name(module):
        """Get the package name to pass to resolve_name() for this module"""
        try:
            return module.__package__
        except AttributeError:
            pass
        modname = module.__name__
        try:
            path = module.__path__
        except AttributeError:
            pass
        else:
            return modname
        return module.__spec__.parent
History
Date User Action Args
2018-04-21 05:52:46ncoghlansetrecipients: + ncoghlan, barry, brett.cannon, rhettinger, eric.snow
2018-04-21 05:52:46ncoghlansetmessageid: <1524289966.8.0.682650639539.issue33277@psf.upfronthosting.co.za>
2018-04-21 05:52:46ncoghlanlinkissue33277 messages
2018-04-21 05:52:45ncoghlancreate