├── LICENSE.txt ├── README.md ├── disallow_import_star ├── __about__.py └── __init__.py ├── pyproject.toml └── tests ├── __init__.py └── test_disallow_import_star.py /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023-present Trey Hunner 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Stop your users from doing whatever they want 2 | 3 | [![PyPI - Version](https://img.shields.io/pypi/v/disallow-import-star.svg)](https://pypi.org/project/disallow-import-star) 4 | [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/disallow-import-star.svg)](https://pypi.org/project/disallow-import-star) 5 | 6 | Are you a meanie? 7 | Do you feel your users shouldn't be allowed to to use `from your_module import *` whenever they want? 8 | 9 | This is the package for you! 10 | 11 | Just `pip install disallow-import-star` and add this magical lines to your module: 12 | 13 | ```python 14 | from disallow_import_star import __all__ 15 | ``` 16 | 17 | ## Would you like to impose your will on *other* packages? 18 | 19 | If you really want your users to stop using `import *` in *other* their packages, you can monkey patch your user's favorite packages, like this: 20 | 21 | ```python 22 | from disallow_import_star import __all__ 23 | import math 24 | import numpy 25 | import tkinter 26 | 27 | 28 | # Why should our users be able to use import * ANYWHERE? 29 | math.__all__ == __all__ 30 | numpy.__all__ == __all__ 31 | tkinter.__all__ == __all__ 32 | ``` 33 | 34 | ## Want to control *all* the packages? 35 | 36 | To really upset your `import *`-using users, run this: 37 | 38 | ```python 39 | from disallow_import_star 40 | 41 | disallow_import_star.disallow_import_star_EVERYWHERE() 42 | ``` 43 | -------------------------------------------------------------------------------- /disallow_import_star/__about__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023-present Trey Hunner 2 | # 3 | # SPDX-License-Identifier: MIT 4 | __version__ = '0.4.1' 5 | -------------------------------------------------------------------------------- /disallow_import_star/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023-present Trey Hunner 2 | # 3 | # SPDX-License-Identifier: MIT 4 | import builtins 5 | from textwrap import dedent 6 | 7 | 8 | star_exception = ImportError(dedent(""" 9 | import * explicitly disallowed 10 | 11 | April Fools! 12 | 13 | Learn Python tips that are actually practical from https://pym.how 14 | """).strip()) 15 | 16 | 17 | class NoStar: 18 | def __getitem__(self, index): 19 | raise star_exception 20 | 21 | 22 | __all__ = NoStar() 23 | 24 | 25 | _original_import = builtins.__import__ 26 | 27 | 28 | def __import__(name, globals=None, locals=None, fromlist=(), level=0): 29 | if fromlist and fromlist[0] == "*": 30 | raise star_exception 31 | return _original_import(name, globals, locals, fromlist, level) 32 | 33 | 34 | def disallow_import_star_EVERYWHERE(): 35 | builtins.__import__ = __import__ 36 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["hatchling"] 3 | build-backend = "hatchling.build" 4 | 5 | [project] 6 | name = "disallow-import-star" 7 | description = 'Impose your will on your users' 8 | readme = "README.md" 9 | requires-python = ">=3.7" 10 | license = "MIT" 11 | keywords = [] 12 | authors = [ 13 | { name = "Trey Hunner", email = "trey@treyhunner.com" }, 14 | ] 15 | classifiers = [ 16 | "Development Status :: 4 - Beta", 17 | "Programming Language :: Python", 18 | "Programming Language :: Python :: 3.7", 19 | "Programming Language :: Python :: 3.8", 20 | "Programming Language :: Python :: 3.9", 21 | "Programming Language :: Python :: 3.10", 22 | "Programming Language :: Python :: 3.11", 23 | "Programming Language :: Python :: Implementation :: CPython", 24 | "Programming Language :: Python :: Implementation :: PyPy", 25 | ] 26 | dependencies = [] 27 | dynamic = ["version"] 28 | 29 | [project.urls] 30 | Documentation = "https://github.com/treyhunner/disallow-import-star#readme" 31 | Issues = "https://github.com/treyhunner/disallow-import-star/issues" 32 | Source = "https://github.com/treyhunner/disallow-import-star" 33 | 34 | [tool.hatch.version] 35 | path = "disallow_import_star/__about__.py" 36 | 37 | [tool.hatch.envs.default] 38 | dependencies = [ 39 | "pytest", 40 | "pytest-cov", 41 | ] 42 | [tool.hatch.envs.default.scripts] 43 | cov = "pytest --cov-report=term-missing --cov-config=pyproject.toml --cov=disallow_import_star --cov=tests {args}" 44 | no-cov = "cov --no-cov {args}" 45 | 46 | [[tool.hatch.envs.test.matrix]] 47 | python = ["37", "38", "39", "310", "311"] 48 | 49 | [tool.coverage.run] 50 | branch = true 51 | parallel = true 52 | omit = [ 53 | "disallow_import_star/__about__.py", 54 | ] 55 | 56 | [tool.coverage.report] 57 | exclude_lines = [ 58 | "no cov", 59 | "if __name__ == .__main__.:", 60 | "if TYPE_CHECKING:", 61 | ] 62 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023-present Trey Hunner 2 | # 3 | # SPDX-License-Identifier: MIT 4 | -------------------------------------------------------------------------------- /tests/test_disallow_import_star.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023-present Trey Hunner 2 | # 3 | # SPDX-License-Identifier: MIT 4 | from disallow_import_star import __all__ 5 | import pytest 6 | 7 | 8 | def test_looping_over_all_fails(): 9 | with pytest.raises(ImportError): 10 | list(__all__) 11 | 12 | 13 | def test_no_star_import_allowed(): 14 | with pytest.raises(ImportError): 15 | exec("from disallow_import_star import *") 16 | --------------------------------------------------------------------------------