Skip to main content

deal with object reference notations

Project description

objectref

objectref is a library to parse object references and find referenced objects.

Notations

Object references are notations to locate modules or objects from the top level of a module.

package.module
package.module:object.attr

The first form simply refers a module, while the second form an object in module. It is also described in here.

This library also supports relative object references (prefixed with dots).

Usage

  • find(ref: str, package: str | None = None) -> Any

    The find function takes an object reference or parse() result, and returns the object pointed by the reference.

    The package argument must be set when the reference is relative.

    If qualified name is unspecified (the first form), the result is a module (types.ModuleType instance).

    ModuleNotFoundError is raised if the module cannot be found nor imported; LookupError if the object is not accessible from the top level of the module.

  • parse(ref: str) -> tuple[str, str | None]

    The parse function takes an object reference, and results in a tuple of module name and qualified name. The qualified name would be None in first form.

    ValueError is raised if the reference is invalid.

Example

import os.path

import objectref

print(objectref.find("os.path") == os.path)  # True
print(objectref.find("os.path:join") == os.path.join)  # True
print(objectref.parse("os.path"))  # ("os.path", None)
print(objectref.parse("os.path:join"))  # ("os.path", "join")

Entrypoint example

There are two main ways to execute a Python program.

  • Run python -m myapp.main in shells, which executes the module as __main__ under the hood. This relates to the first form of notation.

  • Run myapp installed by pip. It is generated according to entrypoint defined in the project metadata (e.g. myapp = myapp.main:main). This requires the second form notation with callable objects.

Here is a code snippet to unify these two ways and start a program by its object reference.

import objectref


def run(ref: str, package: str | None = None):
    modname, qualname = objectref.parse(ref)

    if qualname is None:
        # Use runpy to run a module with __name__ = "__main__"
        if modname.startswith("."):
            # runpy does not support relative module name.
            from importlib.util import resolve_name
            modname = resolve_name(modname, package)
        import runpy
        return runpy.run_module(modname, run_name="__main__")

    fn = objectref.find((modname, qualname), package)
    return fn()


if __name__ == "__main__":
    run("this")  # run the "this" module dynamically.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

objectref-2023.10.31.tar.gz (7.3 kB view hashes)

Uploaded Source

Built Distribution

objectref-2023.10.31-py3-none-any.whl (4.4 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page