0

I have a utility package for Python projects I maintain and use. It’s a bundle of lightweight, common, junk-drawer tools (e.g. command parsing, app lifecycle management, document generation, &c &c). Currently, using this stuff is all very simple in one’s own project, but most modules written to work with it require this very irritating bit of boilerplate, like so:


from myproject.exporting import Exporter

# This is the irritating part:
exporter = Exporter(path=__file__)
export = exporter.decorator()

@export
def public_function(…):
    """ This function has been exported, and is public. """
    ...

def private_function(…):
    """ This function is private. """
    ...

# This bit does not really bother me:
__all__, __dir__ = exporter.all_and_dir()

This exporter interface lets one label classes, functions (even lambdas!) as public. These get added to generated module __all__ and __dir__(…) values, but the whole thing assists with documentation generation and other introspective things. This is besides the point, though, which is: having to do this hacky instatiation with a __file__ value is an eyesore. Linters hate __file__, so do most human Python programmers (including myself) and in general it feels like an unstable and antiquated way of doing things.

Is there a way of getting the value of __file__ in another manner? I am looking for a way to surface this datum via some other (hopefully less fragile) route.

My immediate thought is to have a module-level __getattr__(…) function, as I have had good results using these to provide instances of things on import – but, regardless of whether module __getattr__(…) is the best tool or not in this case, I am not sure about which Python introspection facilities would be warranted in their use.

Also, this answer has the basic info on the __file__ value, for those who are curious.

8
  • 1
    Why are you using __file__ in the first place? It doesn't look like you should need that info. Commented Jul 3, 2024 at 0:22
  • @user2357112 The Exporter class is a per-project subclass of something called ExporterBase and it knows the name and base path of the project in question. It uses __file__ to determine the dotted path and the relative path of the module, which help the behind-the-scenes machinery with stuff like e.g. documentation generation, dependency introspection, qualified-name lookups, and many other things. That’s why I need the __file__ datum. I’d like to get that datum some other way! Commented Jul 3, 2024 at 0:28
  • 1
    I would use an import hook at your project base - then every time you write import xyz.abc, you can do arbitrary things, including introspection, AST manipulation, etc. to the module xyz.abc before it is fully initialised. Here's the public API of types.ModuleType (module) objects. Commented Jul 3, 2024 at 0:34
  • 2
    I would keep it simple and do away the whole exporter business: if a name in your module starts with an underscore, it is assumed to be private. Otherwise, it is public. Less code means less bug. KISS. Commented Jul 3, 2024 at 2:25
  • 1
    to avoid __file__, you could call inspect.getabsfile(wrapped_func) to get the source path stackoverflow.com/questions/3718657/… Commented Jul 6, 2024 at 7:20

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.