{"id":25439286,"url":"https://github.com/joaduo/rel_imp","last_synced_at":"2025-11-01T09:30:21.012Z","repository":{"id":20444776,"uuid":"23721711","full_name":"joaduo/rel_imp","owner":"joaduo","description":"Relative import tool for running subpackages or submodules as main scripts (enabling explicit relative imports)","archived":false,"fork":false,"pushed_at":"2022-03-15T17:31:51.000Z","size":50,"stargazers_count":1,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-04T04:53:23.033Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/joaduo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-09-05T23:41:32.000Z","updated_at":"2020-12-22T09:50:27.000Z","dependencies_parsed_at":"2022-07-31T20:08:03.283Z","dependency_job_id":null,"html_url":"https://github.com/joaduo/rel_imp","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joaduo%2Frel_imp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joaduo%2Frel_imp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joaduo%2Frel_imp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joaduo%2Frel_imp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/joaduo","download_url":"https://codeload.github.com/joaduo/rel_imp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239269779,"owners_count":19610871,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-02-17T10:18:59.992Z","updated_at":"2025-11-01T09:30:20.923Z","avatar_url":"https://github.com/joaduo.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# The rel_imp utility\n\n[ ![Codeship Status for joaduo/rel_imp](https://codeship.com/projects/6634b790-b2f6-0132-44e8-3a4b0bbda320/status?branch=master)](https://codeship.com/projects/70108)\n\nEnabling explicit relative imports in main modules the easy way.\n\nFor enabling relative import in `__main__` module PEP 366 presents a workaround like:\n\n```python\nif __name__ == \"__main__\" and __package__ is None:\n    __package__ = \"my_pkg\"\n\nfrom .foo import bar\n```\n\nWith `rel_imp` you can rewrite it as:\n\n```python\nimport rel_imp; rel_imp.init()\nfrom .foo import bar\n```\n\nCleaner, faster and less coupled. (you don't need to specify the package manually)\n\n**Note:** In order to use `rel_imp` the module you are coding must be inside a package or a sub-package. \n\n## Why using explicit relative imports? \n\nPython 2 still supports implicit relative import and will be deprecated in Python 3, so you will want to migrate those scripts using implicit relative import to explicit relative import. Check more on the [PEP 404](http://legacy.python.org/dev/peps/pep-0404/#id18).\n\nExplicit relative imports makes your code less coupled. As [PEP 328](http://legacy.python.org/dev/peps/pep-0328/#rationale-for-relative-imports) says:\n\n\u003e Several use cases were presented, the most important of which is being able to rearrange the structure of large packages without having to edit sub-packages. In addition, a module inside a package can't easily import itself without relative imports. \n\nOn the other hand PEP 8 says:\n\n\u003e Absolute imports are recommended, as they are usually more readable and tend to be better behaved (or at least give better error messages) if the import system is incorrectly configured.\n\nIf you find a point to use explicit relative imports, then you can use rel_imp to allow running packages as main.\n\n## Why running sub-modules as main?\n\nSome reasons:\n\n1. A submodule can become a command line tool if called as main.\n2. You can have unit test or smoke test within the module.\n3. You simply want to run it without any explicit test to see if at least it imports everything it needs.  \n\n## Installation and Uninstallation\n\n### Install via pip\n\n```\npip install rel_imp\n```\nRemove it with:\n\n```\npip uninstall rel_imp\n```\n\n### Install downloading the file\nDownload the `rel_imp.py` in one your Python's search path.\n\n```\nwget https://raw.githubusercontent.com/joaduo/rel_imp/master/rel_imp.py\n```\n\n## Example\n\nImagine you have 2 modules inside a package called \"my_pkg\".\n\nThat would be:\n\n* `my_pkg/__init__.py`\n* `my_pkg/math_lib.py`\n* `my_pkg/test.py`\n\nSo in test.py we could have\n\n```python\nfrom .math_lib import factorize\n\ndef factorize_and_print(number):\n    num = factorize(number)\n    print num\n\nif __name__ == '__main__':\n    #Small smoke test\n    factorize_and_print(10)\n    factorize_and_print(0)\n    factorize_and_print(-10)\n```\n\nIf you do `python my_pkg/test.py` it will throw an exception because of the relative import at the first line.\n\nSo you can use `rel_imp` to make your code look nicer. Simply do:\n\n```python\nimport rel_imp; rel_imp.init()\nfrom .math_lib import factorize\n```\n\nIt is equivalent as the prior solution but you don't have to worry about keeping in sync `__package__`'s value.\n\nYou can also use a shorter solution with implicit `init()` using the `relative_import` module:\n\n```python\nimport relative_import\nfrom .math_lib import factorize\n```\n\n## How does it work?\n\nIt uses the same technique in PEP 366 but `__package__`'s value is set through dynamic inspection of the stack. To solve the value of `__package__` it compares the current `__main__`'s file with search paths in sys.path - or, optionally, a list of paths given in the settings -.\n\nFor example, for a file in `/home/user/projects/python/math/my_pkg/test.py` given the following paths in sys.path:\n```python\n[\n'/home/user/projects/python/',\n'/home/user/projects/python/math/',\n'/home/user/projects/python/math/my_pkg/',\n]\n```\nIt will pick the closest path to the `__main__`'s file that is not the `__main__`'s file's directory.\n\nThen the base path use to solve `__package__` variable will be `/home/user/projects/python/math/`\n\nThis process is only done once and for the `__main__`. Succesive calls to `rel_imp.init()` does nothing.\n\n## Disabling `rel_imp` initialization\n\nYou can simply define a environment variable `PYTHON_DISABLE_REL_IMP` with any value.\n\n## Feedback or bugs reporting\n\nFile an issue through github's [issue tracking system](https://github.com/joaduo/rel_imp/issues).\n\nYou can optionally contact me at joaduo gmail com.\n\n## Related PEPs\n\n* http://legacy.python.org/dev/peps/pep-0328/\n* http://legacy.python.org/dev/peps/pep-0366/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoaduo%2Frel_imp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoaduo%2Frel_imp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoaduo%2Frel_imp/lists"}