🕷️ Crawler Inspector

URL Lookup

Direct Parameter Lookup

Raw Queries and Responses

1. Shard Calculation

Query:
Response:
Calculated Shard: 80 (from laksa080)

2. Crawled Status Check

Query:
Response:

3. Robots.txt Check

Query:
Response:

4. Spam/Ban Check

Query:
Response:

5. Seen Status Check

ℹ️ Skipped - page is already crawled

📄
INDEXABLE
CRAWLED
9 days ago
🤖
ROBOTS ALLOWED

Page Info Filters

FilterStatusConditionDetails
HTTP statusPASSdownload_http_code = 200HTTP 200
Age cutoffPASSdownload_stamp > now() - 6 MONTH0.3 months ago
History dropPASSisNull(history_drop_reason)No drop reason
Spam/banPASSfh_dont_index != 1 AND ml_spam_score = 0ml_spam_score=0
CanonicalPASSmeta_canonical IS NULL OR = '' OR = src_unparsedNot set

Page Details

PropertyValue
URLhttps://joshcannon.me/2025/07/19/relative-imports.html
Last Crawled2026-04-02 16:18:52 (9 days ago)
First Indexed2025-07-22 14:31:47 (8 months ago)
HTTP Status Code200
Meta TitlePython: Relative vs Absolute Imports
Meta Description9 out of 10 Pythonistas agree...
Meta Canonicalnull
Boilerpipe Text
In the PyTexas Discord my fellow PyTexas organizer and friend, Mason Egger, asked: Do you prefer absolute or relative imports for inter-module imports within applications? Go ahead and call me a Sith because I deal in absolutes. And here’s why. Ways of running Python files # Python has more than a few ways of running a “Python file”: python path/to/file.py : Run the file at this path python -m path.to.file : Run the module found with this dotted name python path/to : Run the __main__.py file under this directory path python -m path/to : Run the module found with this dotted name, which this time would be the directory’s __init__.py python path/to/zipapp.zip : Run this zipapp pytest or any other installed script name: Run the script found at <Python environment directory>/bin/<name> , e.g. .venv/bin/pytest Ways of importing your fellow module # from . import sibling : Imports sibling from under the same/parent directory this module is in This first would try to import attribute sibling from __init__.py then try to import the module named sibling (either sibling/__init__.py or sibling.py ) from .sibling import boogers : Same idea, but this time we need to load module sibling and attribute/submodule boogers from .. import uncle : Imports uncle from under the grandparent directory (using similar rules) from ..uncle import tickles : (you get the jist) from ... import great_aunt : … These are all examples of relative imports. What they import is relative to the module importing them. (By the way, in case you needed one, here’s an example of an absolute import: from pkgname.child import fun ) Ways of running Python files which import their fellow modules # Given this flat layout project: . ├── macaroni/ │ ├── __init__.py │ ├── salad.py │ └── and_/ │ ├── __init__.py │ └── cheese.py Contents / Invocation python -m macaroni.and_.cheese python macaroni/and_/cheese.py from ..salad import dressing 🎉 💥 ImportError: attempted relative import with no known parent package from macaroni.salad import dressing 🎉 🎉 Why is that? # Buried in the Python docs’ tutorials, in Chapter 6 “Modules”, Section 4 “Packages”, Subsection 2 “Intra-package References” ( 6.4.2. here ), there is this paragraph 1 : Note that relative imports are based on the name of the current module’s package. Since the main module does not have a package, modules intended for use as the main module of a Python application must always use absolute imports. When Python encounters a relative import, it is relative to the current package , which for the “main module” (the module being invoked), doesn’t exist. The bottom line : Absolute imports work consistently irrespective of how your Python file is executed. Relative imports don’t give you that luxury. The paragraph used to read differently, but it was also slightly incorrect so I suggested a change in PR 136846 .  ↩
Markdown
[A Blog](https://joshcannon.me/) - [Now](https://joshcannon.me/now) # Python: Relative vs Absolute Imports ## 9 out of 10 Pythonistas agree... Posted on July 19, 2025 In the PyTexas Discord my fellow PyTexas organizer and friend, Mason Egger, asked: > Do you prefer absolute or relative imports for inter-module imports within applications? Go ahead and [call me a Sith](https://youtu.be/wgpytjlW5wU?si=qoLqiNyuv0EJPpqD) because I deal in absolutes. And here’s why. # Ways of running Python files [\#](https://joshcannon.me/2025/07/19/relative-imports.html#ways-of-running-python-files) Python has more than a few ways of running a “Python file”: - `python path/to/file.py`: Run the file at this path - `python -m path.to.file`: Run the module found with this dotted name - `python path/to`: Run the `__main__.py` file under this directory path - `python -m path/to`: Run the module found with this dotted name, which this time would be the directory’s `__init__.py` - `python path/to/zipapp.zip`: Run this [zipapp](https://docs.python.org/3/library/zipapp.html) - `pytest` or any other installed script name: Run the script found at `<Python environment directory>/bin/<name>`, e.g. `.venv/bin/pytest` # Ways of importing your fellow module [\#](https://joshcannon.me/2025/07/19/relative-imports.html#ways-of-importing-your-fellow-module) - `from . import sibling`: Imports `sibling` from under the same/parent directory this module is in - This first would try to import attribute `sibling` from `__init__.py` - then try to import the module named `sibling` (either `sibling/__init__.py` or `sibling.py`) - `from .sibling import boogers`: Same idea, but this time we need to load module `sibling` and attribute/submodule `boogers` - `from .. import uncle`: Imports `uncle` from under the grandparent directory (using similar rules) - `from ..uncle import tickles`: (you get the jist) - `from ... import great_aunt`: … These are all examples of *relative* imports. What they import is *relative* to the module importing them. (By the way, in case you needed one, here’s an example of an *absolute* import: `from pkgname.child import fun`) # Ways of running Python files which import their fellow modules [\#](https://joshcannon.me/2025/07/19/relative-imports.html#ways-of-running-python-files-which-import-their-fellow-modules) Given this [flat layout](https://packaging.python.org/en/latest/discussions/src-layout-vs-flat-layout/) project: ``` . ├── macaroni/ │ ├── __init__.py │ ├── salad.py │ └── and_/ │ ├── __init__.py │ └── cheese.py ``` | Contents / Invocation | `python -m macaroni.and_.cheese` | `python macaroni/and_/cheese.py` | |---|---|---| | `from ..salad import dressing` | 🎉 | 💥 `ImportError: attempted relative import with no known parent package` | | `from macaroni.salad import dressing` | 🎉 | 🎉 | # Why is that? [\#](https://joshcannon.me/2025/07/19/relative-imports.html#why-is-that) Buried in the Python docs’ tutorials, in Chapter 6 “Modules”, Section 4 “Packages”, Subsection 2 “Intra-package References” ([6\.4.2. here](https://docs.python.org/3/tutorial/modules.html#intra-package-references)), there is this paragraph [1](https://joshcannon.me/2025/07/19/relative-imports.html#fn:1): > Note that relative imports are based on the name of the current module’s package. Since the main module does not have a package, modules intended for use as the main module of a Python application must always use absolute imports. When Python encounters a relative import, [it is relative to the current package](https://docs.python.org/3/reference/import.html#package-relative-imports), which for the “main module” (the module being invoked), doesn’t exist. **The bottom line**: Absolute imports work consistently irrespective of how your Python file is executed. Relative imports don’t give you that luxury. *** 1. The paragraph used to read differently, but it was also slightly incorrect so I suggested a change in [PR 136846](https://github.com/python/cpython/pull/136846). [↩](https://joshcannon.me/2025/07/19/relative-imports.html#fnref:1) - [← Previous Post](https://joshcannon.me/2025/07/05/cogpinned-scripts.html "Using `cog` for pinned Single-File Python scripts") - [Next Post →](https://joshcannon.me/2025/08/16/py-namespace-packages.html "Python Namespace Packages are a pain") - [RSS](https://joshcannon.me/feed.xml "RSS") - [Email me](mailto:joshdcannon@gmail.com "Email me") - [GitHub](https://github.com/thejcannon "GitHub") - [Mastodon](https://fosstodon.org/@thejcannon "Mastodon") Josh Cannon • 2026 Powered by [Beautiful Jekyll](https://beautifuljekyll.com/)
Readable Markdown
In the PyTexas Discord my fellow PyTexas organizer and friend, Mason Egger, asked: > Do you prefer absolute or relative imports for inter-module imports within applications? Go ahead and [call me a Sith](https://youtu.be/wgpytjlW5wU?si=qoLqiNyuv0EJPpqD) because I deal in absolutes. And here’s why. ## Ways of running Python files [\#](https://joshcannon.me/2025/07/19/relative-imports.html#ways-of-running-python-files) Python has more than a few ways of running a “Python file”: - `python path/to/file.py`: Run the file at this path - `python -m path.to.file`: Run the module found with this dotted name - `python path/to`: Run the `__main__.py` file under this directory path - `python -m path/to`: Run the module found with this dotted name, which this time would be the directory’s `__init__.py` - `python path/to/zipapp.zip`: Run this [zipapp](https://docs.python.org/3/library/zipapp.html) - `pytest` or any other installed script name: Run the script found at `<Python environment directory>/bin/<name>`, e.g. `.venv/bin/pytest` ## Ways of importing your fellow module [\#](https://joshcannon.me/2025/07/19/relative-imports.html#ways-of-importing-your-fellow-module) - `from . import sibling`: Imports `sibling` from under the same/parent directory this module is in - This first would try to import attribute `sibling` from `__init__.py` - then try to import the module named `sibling` (either `sibling/__init__.py` or `sibling.py`) - `from .sibling import boogers`: Same idea, but this time we need to load module `sibling` and attribute/submodule `boogers` - `from .. import uncle`: Imports `uncle` from under the grandparent directory (using similar rules) - `from ..uncle import tickles`: (you get the jist) - `from ... import great_aunt`: … These are all examples of *relative* imports. What they import is *relative* to the module importing them. (By the way, in case you needed one, here’s an example of an *absolute* import: `from pkgname.child import fun`) ## Ways of running Python files which import their fellow modules [\#](https://joshcannon.me/2025/07/19/relative-imports.html#ways-of-running-python-files-which-import-their-fellow-modules) Given this [flat layout](https://packaging.python.org/en/latest/discussions/src-layout-vs-flat-layout/) project: ``` . ├── macaroni/ │ ├── __init__.py │ ├── salad.py │ └── and_/ │ ├── __init__.py │ └── cheese.py ``` | Contents / Invocation | `python -m macaroni.and_.cheese` | `python macaroni/and_/cheese.py` | |---|---|---| | `from ..salad import dressing` | 🎉 | 💥 `ImportError: attempted relative import with no known parent package` | | `from macaroni.salad import dressing` | 🎉 | 🎉 | ## Why is that? [\#](https://joshcannon.me/2025/07/19/relative-imports.html#why-is-that) Buried in the Python docs’ tutorials, in Chapter 6 “Modules”, Section 4 “Packages”, Subsection 2 “Intra-package References” ([6\.4.2. here](https://docs.python.org/3/tutorial/modules.html#intra-package-references)), there is this paragraph [1](https://joshcannon.me/2025/07/19/relative-imports.html#fn:1): > Note that relative imports are based on the name of the current module’s package. Since the main module does not have a package, modules intended for use as the main module of a Python application must always use absolute imports. When Python encounters a relative import, [it is relative to the current package](https://docs.python.org/3/reference/import.html#package-relative-imports), which for the “main module” (the module being invoked), doesn’t exist. **The bottom line**: Absolute imports work consistently irrespective of how your Python file is executed. Relative imports don’t give you that luxury. *** 1. The paragraph used to read differently, but it was also slightly incorrect so I suggested a change in [PR 136846](https://github.com/python/cpython/pull/136846). [↩](https://joshcannon.me/2025/07/19/relative-imports.html#fnref:1)
Shard80 (laksa)
Root Hash10028807919680690880
Unparsed URLme,joshcannon!/2025/07/19/relative-imports.html s443