# importloc
<!-- docsub: begin -->
<!-- docsub: include docs/desc.md -->
> *Import Python objects from arbitrary locations specified by string.*
<!-- docsub: end -->
<!-- docsub: begin -->
<!-- docsub: include docs/badges.md -->
[](https://github.com/makukha/importloc/blob/main/LICENSE)
[](https://pypi.python.org/pypi/importloc)
[](https://pypi.org/project/importloc)
[](https://github.com/makukha/importloc)
[](https://github.com/makukha/importloc)
[](https://github.com/makukha/multipython)
[](https://github.com/makukha/docsub)
[](http://mypy.readthedocs.io)
[](https://github.com/astral-sh/ruff)
[](https://github.com/astral-sh/ruff)
<!-- docsub: end -->
<!-- docsub: begin -->
<!-- docsub: include docs/features.md -->
# Features
* Minimalistic fully typed package
* Import from files or named modules
* Import deeply nested objects
* Import all instances or all subclasses
* Configurable module name conflict resolution
* Atomicity: on import error, new module is removed, and previous, if any, is restored
<!-- docsub: end -->
# Installation
```shell
$ pip install importloc
```
# Usage
<!-- docsub: begin #readme -->
<!-- docsub: include docs/usage.md -->
* Various locations
<!-- docsub: begin -->
<!-- docsub: x usage toc tests/test_usage.py 'L[0-9]' -->
* [Import from file](#import-from-file)
* [Import from module](#import-from-module)
* [Distinguish file and module locations](#distinguish-file-and-module-locations)
<!-- docsub: end -->
* Various targets
<!-- docsub: begin -->
<!-- docsub: x usage toc tests/test_usage.py 'T[0-9]' -->
* [Import nested class](#import-nested-class)
* [Import module as a whole](#import-module-as-a-whole)
* [Use `Path` object when loading module](#use-path-object-when-loading-module)
* [Import all instances of some type](#import-all-instances-of-some-type)
* [Import all subclasses](#import-all-subclasses)
<!-- docsub: end -->
* Custom module name
<!-- docsub: begin -->
<!-- docsub: x usage toc tests/test_usage.py 'N[0-9]' -->
* [Use different module name](#use-different-module-name)
* [Generate module name at run time](#generate-module-name-at-run-time)
<!-- docsub: end -->
* What if module is already imported?
<!-- docsub: begin -->
<!-- docsub: x usage toc tests/test_usage.py 'R[0-9]' -->
* [Module name conflict raises error by default](#module-name-conflict-raises-error-by-default)
* [Reuse module that is already imported](#reuse-module-that-is-already-imported)
* [Reload module that is already imported](#reload-module-that-is-already-imported)
* [Replace old module with imported one](#replace-old-module-with-imported-one)
* [Load module under different generated name](#load-module-under-different-generated-name)
* [Combine override and rename](#combine-override-and-rename)
<!-- docsub: end -->
* What if object does not exist?
<!-- docsub: begin -->
<!-- docsub: x usage toc tests/test_usage.py 'O[0-9]' -->
* [Missing object causes `AttributeError`](#missing-object-causes-attribute-error)
<!-- docsub: end -->
## Quick start
The main and most used entity is `Location`.
```python
from importloc import Location
```
## Various locations
<!-- docsub: begin -->
<!-- docsub: x usage section tests/test_usage.py 'L[0-9]' -->
### Import from file
```python
Location('app/config.py:conf').load()
```
_Example_
```pycon
>>> loc = Location('app/config.py:conf')
>>> loc
<PathLocation 'app/config.py' obj='conf'>
>>> loc.load()
<config.Config object at 0x...>
```
### Import from module
```python
Location('app.__main__:cli').load()
```
_Example_
```pycon
>>> loc = Location('app.__main__:cli')
>>> loc
<ModuleLocation 'app.__main__' obj='cli'>
>>> loc.load()
<function cli at 0x...>
```
### Distinguish file and module locations
```python
Location('./config.py:conf').load()
```
_Example_
```pycon
>>> loc = Location('config.py:conf')
>>> loc
<ModuleLocation 'config.py' obj='conf'>
>>> loc.load()
Traceback (most recent call last):
...
ModuleNotFoundError: No module named 'config.py'...
```
Use relative path (similar to Docker bind mount). Path separator will result in
`PathLocation` instead of `ModuleLocation`.
```pycon
>>> loc = Location('./config.py:conf')
>>> loc
<PathLocation 'config.py' obj='conf'>
>>> loc.load()
<config.Config object at 0x...>
```
<!-- docsub: end -->
## Various targets
<!-- docsub: begin -->
<!-- docsub: x usage section tests/test_usage.py 'T[0-9]' -->
### Import nested class
```python
Location('app/config.py:Config.Nested').load()
```
_Example_
```pycon
>>> loc = Location('app/config.py:Config.Nested')
>>> loc
<PathLocation 'app/config.py' obj='Config.Nested'>
>>> loc.load()
<class 'config.Config.Nested'>
```
### Import module as a whole
```python
Location('app/config.py').load()
```
_Example_
```pycon
>>> loc = Location('app/config.py')
>>> loc
<PathLocation 'app/config.py'>
>>> loc.load()
<module 'config' from '...'>
```
### Use `Path` object when loading module
```python
Location(Path('config.py')).load()
```
_Example_
```pycon
>>> from pathlib import Path
>>> loc = Location(Path('config.py'))
>>> loc
<PathLocation 'config.py'>
>>> loc.load()
<module 'config' from '...'>
```
### Import all instances of some type
```python
get_instances(Location('app.__main__').load(), Callable)
```
_Example_
```pycon
>>> from collections.abc import Callable
>>> from importloc import get_instances
>>> loc = Location('app.__main__')
>>> loc
<ModuleLocation 'app.__main__'>
>>> get_instances(loc.load(), Callable)
[<function cli at 0x...>]
```
### Import all subclasses
```python
get_subclasses(Location('app.errors').load(), Exception)
```
_Example_
```pycon
>>> from importloc import get_subclasses
>>> loc = Location('app.errors')
>>> loc
<ModuleLocation 'app.errors'>
>>> get_subclasses(loc.load(), Exception)
[<class 'app.errors.Error1'>, <class 'app.errors.Error2'>]
```
<!-- docsub: end -->
## Custom module name
<!-- docsub: begin -->
<!-- docsub: x usage section tests/test_usage.py 'N[0-9]' -->
### Use different module name
```python
Location('...').load(modname='app_main')
```
_Example_
```pycon
>>> Location('app/config.py:Config').load(modname='app_main')
<class 'app_main.Config'>
```
### Generate module name at run time
```python
Location('...').load(modname=random_name)
```
_Example_
```pycon
>>> from importloc import random_name
>>> Location('app/config.py:Config').load(modname=random_name)
<class 'u....Config'>
```
<!-- docsub: end -->
## What if module is already imported?
The module name conflict can be resolved with one the methods:
* ``reuse`` existing module imported before
* ``reload`` existing module
* ``replace`` existing module
* ``rename`` new module (try to import under new name)
* ``raise`` exception (default)
For details, see documentation on [ConflictResolution](https://importloc.readthedocs.io/en/latest/api.html#ConflictResolution).
<!-- docsub: begin -->
<!-- docsub: x usage section tests/test_usage.py 'R[0-9]' -->
### Module name conflict raises error by default
```python
Location('...').load()
```
_Example_
```pycon
>>> Location('app/config.py:Config').load()
<class 'config.Config'>
>>> Location('app/config.py:Config').load()
Traceback (most recent call last):
...
importloc.exc.ModuleNameConflict: Module "config" is already imported
```
### Reuse module that is already imported
```python
Location('...').load(on_conflict='reuse')
```
_Example_
```pycon
>>> C = Location('app/config.py:Config').load()
>>> C
<class 'config.Config'>
>>> old_id = id(C)
>>> C = Location('app/config.py:Config').load(on_conflict='reuse')
>>> C
<class 'config.Config'>
>>> # C is the same object:
>>> id(C) == old_id
True
```
### Reload module that is already imported
```python
Location('...').load(on_conflict='reload')
```
_Example_
```pycon
>>> import sys
>>> C = Location('app/config.py:Config').load()
>>> C
<class 'config.Config'>
>>> old_id = id(C)
>>> mod_id = id(sys.modules['config'])
>>> C = Location('app/config.py:Config').load(on_conflict='reload')
>>> C
<class 'config.Config'>
>>> # module object remains the same after reloading:
>>> id(sys.modules['config']) == mod_id
True
>>> # C is the new object from reloaded module:
>>> id(C) == old_id
False
```
### Replace old module with imported one
```python
Location('...').load(on_conflict='replace')
```
_Example_
```pycon
>>> import sys
>>> C = Location('app/config.py:Config').load()
>>> C
<class 'config.Config'>
>>> mod_id = id(sys.modules['config'])
>>> C = Location('app/config.py:Config').load(on_conflict='replace')
>>> C
<class 'config.Config'>
>>> # module object is the new one:
>>> id(sys.modules['config']) == mod_id
False
```
### Load module under different generated name
```python
Location('...').load(on_conflict='rename', rename=random_name)
```
_Example_
```pycon
>>> from importloc import random_name
>>> Location('app/config.py').load()
<module 'config' from ...>
>>> Location('app/config.py').load(on_conflict='rename', rename=random_name)
<module 'u...'>
```
### Combine override and rename
```python
Location('...').load(modname='...', on_conflict='rename', rename=random_name)
```
_Example_
```pycon
>>> from importloc import random_name
>>> Location('app/config.py').load(modname='app_config')
<module 'app_config' from ...>
>>> Location('app/config.py').load(
... modname='app_config', on_conflict='rename', rename=random_name
... )
<module 'u...' from ...>
```
<!-- docsub: end -->
## What if object does not exist?
<!-- docsub: begin -->
<!-- docsub: x usage section tests/test_usage.py 'O[0-9]' -->
### Missing object causes `AttributeError`
When module was imported but requested object does not exist, `AttributeError`
is raised.
_Example_
```pycon
>>> Location('app/config.py:unknown').load()
Traceback (most recent call last):
...
AttributeError: object has no attribute 'unknown'
>>> # due to import atomicity, module 'config' was removed
>>> import sys
>>> 'config' in sys.modules
False
```
<!-- docsub: end -->
<!-- docsub: end #readme -->
# See also
* [Similar implementations](https://importloc.readthedocs.io/en/latest/alternatives.html)
* [Project changelog](https://github.com/makukha/importloc/tree/main/CHANGELOG.md)
Raw data
{
"_id": null,
"home_page": null,
"name": "importloc",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "import, import-module, import-object, import-string, python",
"author": null,
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/98/b4/435ce77fb255e5d341de926bf81ccd2b8defe3a0c604b4f8e82660c6eb8f/importloc-0.3.1.tar.gz",
"platform": null,
"description": "# importloc\n<!-- docsub: begin -->\n<!-- docsub: include docs/desc.md -->\n> *Import Python objects from arbitrary locations specified by string.*\n<!-- docsub: end -->\n\n<!-- docsub: begin -->\n<!-- docsub: include docs/badges.md -->\n[](https://github.com/makukha/importloc/blob/main/LICENSE)\n[](https://pypi.python.org/pypi/importloc)\n[](https://pypi.org/project/importloc)\n[](https://github.com/makukha/importloc)\n[](https://github.com/makukha/importloc)\n[](https://github.com/makukha/multipython)\n[](https://github.com/makukha/docsub)\n[](http://mypy.readthedocs.io)\n[](https://github.com/astral-sh/ruff)\n[](https://github.com/astral-sh/ruff)\n<!-- docsub: end -->\n\n\n<!-- docsub: begin -->\n<!-- docsub: include docs/features.md -->\n# Features\n\n* Minimalistic fully typed package\n* Import from files or named modules\n* Import deeply nested objects\n* Import all instances or all subclasses\n* Configurable module name conflict resolution\n* Atomicity: on import error, new module is removed, and previous, if any, is restored\n<!-- docsub: end -->\n\n\n# Installation\n\n```shell\n$ pip install importloc\n```\n\n\n# Usage\n\n<!-- docsub: begin #readme -->\n<!-- docsub: include docs/usage.md -->\n* Various locations\n <!-- docsub: begin -->\n <!-- docsub: x usage toc tests/test_usage.py 'L[0-9]' -->\n * [Import from file](#import-from-file)\n * [Import from module](#import-from-module)\n * [Distinguish file and module locations](#distinguish-file-and-module-locations)\n <!-- docsub: end -->\n* Various targets\n <!-- docsub: begin -->\n <!-- docsub: x usage toc tests/test_usage.py 'T[0-9]' -->\n * [Import nested class](#import-nested-class)\n * [Import module as a whole](#import-module-as-a-whole)\n * [Use `Path` object when loading module](#use-path-object-when-loading-module)\n * [Import all instances of some type](#import-all-instances-of-some-type)\n * [Import all subclasses](#import-all-subclasses)\n <!-- docsub: end -->\n* Custom module name\n <!-- docsub: begin -->\n <!-- docsub: x usage toc tests/test_usage.py 'N[0-9]' -->\n * [Use different module name](#use-different-module-name)\n * [Generate module name at run time](#generate-module-name-at-run-time)\n <!-- docsub: end -->\n* What if module is already imported?\n <!-- docsub: begin -->\n <!-- docsub: x usage toc tests/test_usage.py 'R[0-9]' -->\n * [Module name conflict raises error by default](#module-name-conflict-raises-error-by-default)\n * [Reuse module that is already imported](#reuse-module-that-is-already-imported)\n * [Reload module that is already imported](#reload-module-that-is-already-imported)\n * [Replace old module with imported one](#replace-old-module-with-imported-one)\n * [Load module under different generated name](#load-module-under-different-generated-name)\n * [Combine override and rename](#combine-override-and-rename)\n <!-- docsub: end -->\n* What if object does not exist?\n <!-- docsub: begin -->\n <!-- docsub: x usage toc tests/test_usage.py 'O[0-9]' -->\n * [Missing object causes `AttributeError`](#missing-object-causes-attribute-error)\n <!-- docsub: end -->\n\n\n## Quick start\n\nThe main and most used entity is `Location`.\n\n```python\nfrom importloc import Location\n```\n\n\n## Various locations\n\n<!-- docsub: begin -->\n<!-- docsub: x usage section tests/test_usage.py 'L[0-9]' -->\n### Import from file\n\n```python\nLocation('app/config.py:conf').load()\n```\n\n_Example_\n```pycon\n>>> loc = Location('app/config.py:conf')\n>>> loc\n<PathLocation 'app/config.py' obj='conf'>\n>>> loc.load()\n<config.Config object at 0x...>\n```\n\n### Import from module\n\n```python\nLocation('app.__main__:cli').load()\n```\n\n_Example_\n```pycon\n>>> loc = Location('app.__main__:cli')\n>>> loc\n<ModuleLocation 'app.__main__' obj='cli'>\n>>> loc.load()\n<function cli at 0x...>\n```\n\n### Distinguish file and module locations\n\n```python\nLocation('./config.py:conf').load()\n```\n\n_Example_\n```pycon\n>>> loc = Location('config.py:conf')\n>>> loc\n<ModuleLocation 'config.py' obj='conf'>\n>>> loc.load()\nTraceback (most recent call last):\n ...\nModuleNotFoundError: No module named 'config.py'...\n```\n\nUse relative path (similar to Docker bind mount). Path separator will result in\n`PathLocation` instead of `ModuleLocation`.\n\n```pycon\n>>> loc = Location('./config.py:conf')\n>>> loc\n<PathLocation 'config.py' obj='conf'>\n>>> loc.load()\n<config.Config object at 0x...>\n```\n\n<!-- docsub: end -->\n\n\n## Various targets\n\n<!-- docsub: begin -->\n<!-- docsub: x usage section tests/test_usage.py 'T[0-9]' -->\n### Import nested class\n\n```python\nLocation('app/config.py:Config.Nested').load()\n```\n\n_Example_\n```pycon\n>>> loc = Location('app/config.py:Config.Nested')\n>>> loc\n<PathLocation 'app/config.py' obj='Config.Nested'>\n>>> loc.load()\n<class 'config.Config.Nested'>\n```\n\n### Import module as a whole\n\n```python\nLocation('app/config.py').load()\n```\n\n_Example_\n```pycon\n>>> loc = Location('app/config.py')\n>>> loc\n<PathLocation 'app/config.py'>\n>>> loc.load()\n<module 'config' from '...'>\n```\n\n### Use `Path` object when loading module\n\n```python\nLocation(Path('config.py')).load()\n```\n\n_Example_\n```pycon\n>>> from pathlib import Path\n>>> loc = Location(Path('config.py'))\n>>> loc\n<PathLocation 'config.py'>\n>>> loc.load()\n<module 'config' from '...'>\n```\n\n### Import all instances of some type\n\n```python\nget_instances(Location('app.__main__').load(), Callable)\n```\n\n_Example_\n```pycon\n>>> from collections.abc import Callable\n>>> from importloc import get_instances\n>>> loc = Location('app.__main__')\n>>> loc\n<ModuleLocation 'app.__main__'>\n>>> get_instances(loc.load(), Callable)\n[<function cli at 0x...>]\n```\n\n### Import all subclasses\n\n```python\nget_subclasses(Location('app.errors').load(), Exception)\n```\n\n_Example_\n```pycon\n>>> from importloc import get_subclasses\n>>> loc = Location('app.errors')\n>>> loc\n<ModuleLocation 'app.errors'>\n>>> get_subclasses(loc.load(), Exception)\n[<class 'app.errors.Error1'>, <class 'app.errors.Error2'>]\n```\n\n<!-- docsub: end -->\n\n\n## Custom module name\n\n<!-- docsub: begin -->\n<!-- docsub: x usage section tests/test_usage.py 'N[0-9]' -->\n### Use different module name\n\n```python\nLocation('...').load(modname='app_main')\n```\n\n_Example_\n```pycon\n>>> Location('app/config.py:Config').load(modname='app_main')\n<class 'app_main.Config'>\n```\n\n### Generate module name at run time\n\n```python\nLocation('...').load(modname=random_name)\n```\n\n_Example_\n```pycon\n>>> from importloc import random_name\n>>> Location('app/config.py:Config').load(modname=random_name)\n<class 'u....Config'>\n```\n\n<!-- docsub: end -->\n\n\n## What if module is already imported?\n\nThe module name conflict can be resolved with one the methods:\n\n* ``reuse`` existing module imported before\n* ``reload`` existing module\n* ``replace`` existing module\n* ``rename`` new module (try to import under new name)\n* ``raise`` exception (default)\n\nFor details, see documentation on [ConflictResolution](https://importloc.readthedocs.io/en/latest/api.html#ConflictResolution).\n\n<!-- docsub: begin -->\n<!-- docsub: x usage section tests/test_usage.py 'R[0-9]' -->\n### Module name conflict raises error by default\n\n```python\nLocation('...').load()\n```\n\n_Example_\n```pycon\n>>> Location('app/config.py:Config').load()\n<class 'config.Config'>\n>>> Location('app/config.py:Config').load()\nTraceback (most recent call last):\n ...\nimportloc.exc.ModuleNameConflict: Module \"config\" is already imported\n```\n\n### Reuse module that is already imported\n\n```python\nLocation('...').load(on_conflict='reuse')\n```\n\n_Example_\n```pycon\n>>> C = Location('app/config.py:Config').load()\n>>> C\n<class 'config.Config'>\n>>> old_id = id(C)\n>>> C = Location('app/config.py:Config').load(on_conflict='reuse')\n>>> C\n<class 'config.Config'>\n>>> # C is the same object:\n>>> id(C) == old_id\nTrue\n```\n\n### Reload module that is already imported\n\n```python\nLocation('...').load(on_conflict='reload')\n```\n\n_Example_\n```pycon\n>>> import sys\n>>> C = Location('app/config.py:Config').load()\n>>> C\n<class 'config.Config'>\n>>> old_id = id(C)\n>>> mod_id = id(sys.modules['config'])\n>>> C = Location('app/config.py:Config').load(on_conflict='reload')\n>>> C\n<class 'config.Config'>\n>>> # module object remains the same after reloading:\n>>> id(sys.modules['config']) == mod_id\nTrue\n>>> # C is the new object from reloaded module:\n>>> id(C) == old_id\nFalse\n```\n\n### Replace old module with imported one\n\n```python\nLocation('...').load(on_conflict='replace')\n```\n\n_Example_\n```pycon\n>>> import sys\n>>> C = Location('app/config.py:Config').load()\n>>> C\n<class 'config.Config'>\n>>> mod_id = id(sys.modules['config'])\n>>> C = Location('app/config.py:Config').load(on_conflict='replace')\n>>> C\n<class 'config.Config'>\n>>> # module object is the new one:\n>>> id(sys.modules['config']) == mod_id\nFalse\n```\n\n### Load module under different generated name\n\n```python\nLocation('...').load(on_conflict='rename', rename=random_name)\n```\n\n_Example_\n```pycon\n>>> from importloc import random_name\n>>> Location('app/config.py').load()\n<module 'config' from ...>\n>>> Location('app/config.py').load(on_conflict='rename', rename=random_name)\n<module 'u...'>\n```\n\n### Combine override and rename\n\n```python\nLocation('...').load(modname='...', on_conflict='rename', rename=random_name)\n```\n\n_Example_\n```pycon\n>>> from importloc import random_name\n>>> Location('app/config.py').load(modname='app_config')\n<module 'app_config' from ...>\n>>> Location('app/config.py').load(\n... modname='app_config', on_conflict='rename', rename=random_name\n... )\n<module 'u...' from ...>\n```\n\n<!-- docsub: end -->\n\n\n## What if object does not exist?\n\n<!-- docsub: begin -->\n<!-- docsub: x usage section tests/test_usage.py 'O[0-9]' -->\n### Missing object causes `AttributeError`\n\nWhen module was imported but requested object does not exist, `AttributeError`\nis raised.\n\n_Example_\n```pycon\n>>> Location('app/config.py:unknown').load()\nTraceback (most recent call last):\n ...\nAttributeError: object has no attribute 'unknown'\n>>> # due to import atomicity, module 'config' was removed\n>>> import sys\n>>> 'config' in sys.modules\nFalse\n```\n\n<!-- docsub: end -->\n\n<!-- docsub: end #readme -->\n\n# See also\n\n* [Similar implementations](https://importloc.readthedocs.io/en/latest/alternatives.html)\n* [Project changelog](https://github.com/makukha/importloc/tree/main/CHANGELOG.md)\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Import Python objects from arbitrary locations specified by string",
"version": "0.3.1",
"project_urls": {
"Changelog": "https://github.com/makukha/importloc/releases",
"Documentation": "https://importloc.readthedocs.io",
"Homepage": "https://github.com/makukha/importloc",
"Issues": "https://github.com/makukha/importloc/issues",
"Repository": "https://github.com/makukha/importloc"
},
"split_keywords": [
"import",
" import-module",
" import-object",
" import-string",
" python"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "5e02867c521489bf0da6189cac33fd28349e697e353fcd52db0e8c75af19c9a7",
"md5": "ed43e3051681fcf3e9c802b02ae9a01e",
"sha256": "84f5baaf7f02a488125e722a7e1d15cd5150dfd1287a77085e5aa0e55fdd4d03"
},
"downloads": -1,
"filename": "importloc-0.3.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "ed43e3051681fcf3e9c802b02ae9a01e",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 11858,
"upload_time": "2025-02-06T19:19:43",
"upload_time_iso_8601": "2025-02-06T19:19:43.009861Z",
"url": "https://files.pythonhosted.org/packages/5e/02/867c521489bf0da6189cac33fd28349e697e353fcd52db0e8c75af19c9a7/importloc-0.3.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "98b4435ce77fb255e5d341de926bf81ccd2b8defe3a0c604b4f8e82660c6eb8f",
"md5": "0449e32dc425668dbe57047f3f2f97d0",
"sha256": "2c4fb82bbeb41c176f2a0bb52cc36b1c94fa01fa0a5e6ca2567254cb12648a0d"
},
"downloads": -1,
"filename": "importloc-0.3.1.tar.gz",
"has_sig": false,
"md5_digest": "0449e32dc425668dbe57047f3f2f97d0",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 92831,
"upload_time": "2025-02-06T19:19:44",
"upload_time_iso_8601": "2025-02-06T19:19:44.350595Z",
"url": "https://files.pythonhosted.org/packages/98/b4/435ce77fb255e5d341de926bf81ccd2b8defe3a0c604b4f8e82660c6eb8f/importloc-0.3.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-06 19:19:44",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "makukha",
"github_project": "importloc",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"tox": true,
"lcname": "importloc"
}