Install & Compatibility
Where this runs
tested against v3.0.16 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.910 runs
installs and imports cleanly · install 0.0s · import 0.157s · 22.5MB
glibcpy 3.10–3.910 runs
installs and imports cleanly · install 1.8s · import 0.144s · 24MB
21MB installed
● package 21MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
App
✓ from cement import App
This is the modern import for the main application class.
Controller
✓ from cement import Controller
Used for defining application commands and sub-commands.
ex
✓ from cement import ex
Decorator for exposing controller methods as commands.
CementApp
✓
✗ from cement.core.foundation import CementApp
This import path was common in Cement 2.x and earlier; `from cement import App` is preferred for Cement 3.x.
This quickstart demonstrates a basic Cement application with a default command and a nested 'hello' sub-command. It showcases the `App` and `Controller` classes, along with the `ex` decorator for defining commands. Running `python myapp.py` will execute the default action, while `python myapp.py hello --help` or `python myapp.py hello name --name YourName` will demonstrate the sub-command.
import sys
from cement import App, Controller, ex
class Base(Controller):
class Meta:
label = 'base'
@ex(hide=True)
def _default(self):
"""Default action if no sub-command is passed."""
print("Hello from Cement! Try 'myapp hello <name>'\n")
print("Run with --help for options.")
class HelloWorld(Controller):
class Meta:
label = 'hello'
stacked_on = 'base'
stacked_type = 'nested'
@ex(help="Say hello to a given name.")
def name(self):
"""A sample sub-command."""
name = self.app.pargs.name or "World"
print(f"Hello, {name}!")
class MyApp(App):
class Meta:
label = 'myapp'
base_controller = 'base'
handlers = [
Base,
HelloWorld,
]
if __name__ == '__main__':
try:
with MyApp() as app:
app.run()
except Exception as e:
print(f"An error occurred: {e}", file=sys.stderr)
sys.exit(1)
cement --version
Debug
Known issues
breakingCement 3.x officially dropped support for Python 2.x. It requires Python >=3.8. Applications developed with older Cement versions targeting Python 2.x will require significant migration efforts.fixUpgrade your Python environment to 3.8 or newer and update your application code to be Python 3 compatible. Refer to Python's official migration guides.
affects: <3.0.0
breakingAs of Cement 3.0.12, dependencies for the `cement` command-line development tool (specifically `PyYAML` and `Jinja2`) were moved to an optional `cement[cli]` extra. Existing automation or scripts that rely on the `cement` command without this extra installed will break.fixEnsure that `pip install cement[cli]` is executed if you use the `cement` command-line tool or its features.
affects: >=3.0.12
gotchaNative Windows development support for Cement is not 100% complete and is not a primary development target. Users developing on Windows are recommended to use Docker for a more streamlined experience, as native setups may encounter known issues.fixFor Windows development, consider using Docker. If developing natively, be aware of potential platform-specific issues and consult the documentation or issue tracker.
affects: All 3.x versions
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'cement'
This error occurs when the 'cement' library is not installed in the Python environment being used, or the Python environment is not correctly activated.
fixEnsure 'cement' is installed using pip: `pip install cement`. If using a virtual environment, activate it first. For specific versions, use `pip install cement==3.0.14`.
ImportError: cannot import name ABC
This error typically indicates that you are trying to install or run 'cement' with Python 2.x, which is not supported by recent versions of the library (Cement requires Python >= 3.8).
fixSwitch to a supported Python 3 environment (Python 3.8 or newer) and reinstall 'cement' there. Verify your Python version with `python --version` or `python3 --version`.
AttributeError: 'NoneType' object has no attribute '_meta'
This error often arises when a custom handler or controller in Cement does not properly subclass `CementBaseHandler` or `CementBaseController`, or when `super().__init__()` or `super()._setup()` are not called, leading to uninitialized internal framework attributes like `_meta`.
fixEnsure your custom handler or controller correctly inherits from the appropriate Cement base class (e.g., `CementBaseHandler`, `CementBaseController`) and calls its parent's `__init__` and `_setup` methods using `super()`, for example: `super().__init__(*args, **kw)` and `super()._setup(app_obj)`.
ArgumentError: argument -h/--help: conflicting option string(s): -h, --help
This error occurs when you attempt to define a command-line argument using '-h' or '--help' while Cement's underlying ArgParseArgumentHandler (which uses Python's `argparse` module) automatically adds these options by default.
fixTo resolve this, either choose a different short or long option for your custom argument (e.g., `-H` or `--host`), or disable the default help argument in `argparse` by initializing `ArgumentParser` with `add_help=False` if you're directly manipulating `argparse` (though this is less common when working directly with Cement's `app.args.add_argument`). For Cement applications, simply avoid redefining `-h` or `--help`.
Upgrade
Version history
3.0.16latest on PyPI · released Jul 13, 2026
Audit
Dependencies
PyYAMLoptionalRequired for `cement` command-line tool, installed via `cement[cli]`
Jinja2optionalRequired for `cement` command-line tool, installed via `cement[cli]`
colorlogoptionalOptional dependency for enhanced logging, installed via `cement[colorlog]`