Traits¶
All aspects of a system are represented as traits.
There are six types of traits:
Architectures: CPU architectures, like x86_64 or ARM64
Platforms: Operating systems, like Windows, macOS or Ubuntu
Shells: Command-line interpreters, like Bash, Zsh or Fish
Terminals: Terminal emulators, like Kitty, Alacritty or iTerm2
CI systems: Continuous Integration environments, like GitHub Actions or Travis CI
Agents: AI coding agent environments, like Claude Code, Cursor or Cline
Trait usage¶
Current traits¶
You can get all currently detected traits via the current_traits() function.
>>> from extra_platforms import current_traits
>>> current_traits()
{
Architecture(id='aarch64', name='ARM64 (AArch64)'),
Platform(id='macos', name='macOS'),
CI(id='github_ci', name='GitHub Actions runner'),
}
This function returns the set of all predefined traits that match the current system. It may include multiple traits of the same type when several are independently detectable (for instance, both BASH and POWERSHELL on GitHub Ubuntu runners where PSModulePath leaks from Azure infrastructure).
To get the single primary trait for a given type, use the dedicated current_*() functions, which apply disambiguation:
>>> from extra_platforms import current_architecture, current_platform, current_shell
>>> current_architecture()
Architecture(id='aarch64', name='ARM64 (AArch64)')
>>> current_platform()
Platform(id='macos', name='macOS')
>>> current_shell()
Shell(id='zsh', name='Zsh')
Predefined traits¶
All traits are available at the root of the extra_platforms package, as an uppercase symbol:
>>> from extra_platforms import X86_64 # import an architecture
>>> X86_64
Architecture(id='x86_64', name='x86-64 (AMD64)')
>>> from extra_platforms import DEBIAN # import a platform
>>> DEBIAN
Platform(id='debian', name='Debian')
>>> from extra_platforms import GITHUB_CI # import a CI system
>>> GITHUB_CI
CI(id='github_ci', name='GitHub Actions runner')
They all inherit from the Trait base class, and share a common interface.
Current property¶
Each trait has a current property that calls the corresponding detection function:
>>> X86_64.current
True
>>> DEBIAN.current
False
>>> GITHUB_CI.current
False
Detection functions¶
Each trait is associated with a detection function, which returns True if the current system matches that trait.
These functions are also exposed at the root of the extra_platforms package:
>>> from extra_platforms import is_x86_64, is_debian, is_github_ci
>>> is_x86_64()
True
>>> is_debian()
False
>>> is_github_ci()
False
Groups¶
Traits are combined into groups for easier detection of related traits.
You can get all groups a trait belongs to via the groups property:
>>> X86_64.groups
frozenset({
Group(id='x86', name='x86 family'),
Group(id='all_architectures', name='All architectures'),
Group(id='arch_64_bit', name='64-bit architectures'),
Group(id='little_endian', name='Little-endian architectures'),
Group(id='all_traits', name='All architectures, platforms, shells, terminals, CI systems, and agents')})
Additional information¶
Each trait provides an info() method that returns a dictionary containing all available metadata about that trait:
>>> from extra_platforms import AARCH64, MACOS
>>> AARCH64.info()
{'id': 'aarch64', 'name': 'ARM64 (AArch64)', 'icon': '📱', 'url': 'https://en.wikipedia.org/wiki/AArch64', 'current': True, 'machine': 'arm64', 'processor': None}
>>> MACOS.info()
{'id': 'macos', 'name': 'macOS', 'icon': '🍎', 'url': 'https://apple.com/macos/', 'current': True, 'distro_id': None, 'release': None, 'version': '26.2', 'version_parts': {'major': '26', 'minor': '2', 'build_number': None}, 'like': None, 'codename': 'Tahoe'}
The exact structure depends on the trait type.
All traits¶
All recognized traits and their properties:
Icon |
Symbol |
Name |
Detection function |
Type |
|---|---|---|---|---|
📱 |
ARM64 (AArch64) |
Architecture |
||
➿ |
IBM AIX |
Platform |
||
🔳 |
Alacritty |
Terminal |
||
|
AlmaLinux |
Platform |
||
🏔️ |
Alpine Linux |
Platform |
||
Δ |
ALT Linux |
Platform |
||
⤻ |
Amazon Linux |
Platform |
||
🤖 |
Android |
Platform |
||
🍏 |
Apple Terminal |
Terminal |
||
🎗️ |
Arch Linux |
Platform |
||
📱 |
ARM (32-bit) |
Architecture |
||
📱 |
ARMv5TE (little-endian) |
Architecture |
||
📱 |
ARMv6 (little-endian) |
Architecture |
||
📱 |
ARMv7 (little-endian) |
Architecture |
||
📱 |
ARMv8 (32-bit, little-endian) |
Architecture |
||
⟁ |
Artix Linux |
Platform |
||
🪶 |
Almquist Shell |
Shell |
||
═ |
Azure Pipelines |
CI |
||
⟲ |
Bamboo |
CI |
||
# |
Bash |
Shell |
||
🪁 |
Buildkite |
CI |
||
⛑️ |
Buildroot |
Platform |
||
⌬ |
CachyOS |
Platform |
||
💠 |
CentOS |
Platform |
||
🧿 |
ChromeOS |
Platform |
||
⪾ |
Circle CI |
CI |
||
≋ |
Cirrus CI |
CI |
||
✴️ |
Claude Code |
Agent |
||
✳️ |
Clear Linux OS |
Platform |
||
👾 |
Cline |
Agent |
||
꩜ |
CloudLinux OS |
Platform |
||
▶ |
Command Prompt |
Shell |
||
ᚙ |
CodeBuild |
CI |
||
📕 |
OpenAI Codex |
Agent |
||
◰ |
Contour |
Terminal |
||
✈️ |
GitHub Copilot CLI |
Agent |
||
💘 |
Crush |
Agent |
||
✜ |
CRUX |
Platform |
||
𝐂 |
C shell |
Shell |
||
➤ |
Cursor |
Agent |
||
Ͼ |
Cygwin |
Platform |
||
💨 |
Dash |
Shell |
||
🌀 |
Debian |
Platform |
||
🪰 |
DragonFly BSD |
Platform |
||
🚀 |
EndeavourOS |
Platform |
||
🐽 |
Exherbo Linux |
Platform |
||
🎩 |
Fedora |
Platform |
||
🐟 |
Fish |
Shell |
||
🦶 |
foot |
Terminal |
||
😈 |
FreeBSD |
Platform |
||
♊ |
Gemini CLI |
Agent |
||
🥚 |
Generic Linux |
Platform |
||
🗜️ |
Gentoo Linux |
Platform |
||
👻 |
Ghostty |
Terminal |
||
🐙 |
GitHub Actions runner |
CI |
||
🦊 |
GitLab CI |
CI |
||
𝐆 |
GNOME Terminal |
Terminal |
||
📺 |
GNU Screen |
Terminal |
||
🐃 |
Guix System |
Platform |
||
🍂 |
Haiku |
Platform |
||
🥫 |
Hermetic Build |
CI |
||
⥁ |
Heroku CI |
CI |
||
🦬 |
GNU/Hurd |
Platform |
||
⬡ |
Hyper |
Terminal |
||
𝗶 |
Intel 80386 (i386) |
Architecture |
||
𝗶 |
Intel Pentium (i586) |
Architecture |
||
𝗶 |
Intel Pentium Pro (i686) |
Architecture |
||
🤹 |
IBM PowerKVM |
Platform |
||
🔥 |
illumos |
Platform |
||
⬛ |
iTerm2 |
Terminal |
||
🔱 |
Kali Linux |
Platform |
||
🐱 |
Kitty |
Terminal |
||
💎 |
Konsole |
Terminal |
||
𝐊 |
Korn shell |
Shell |
||
🤹 |
KVM for IBM z Systems |
Platform |
||
🌿 |
Linux Mint |
Platform |
||
🐉 |
LoongArch (64-bit) |
Architecture |
||
🍎 |
macOS |
Platform |
||
⍥ |
Mageia |
Platform |
||
💫 |
Mandriva Linux |
Platform |
||
▲ |
Manjaro Linux |
Platform |
||
🌘 |
MidnightBSD |
Platform |
||
🔲 |
MIPS (32-bit, big-endian) |
Architecture |
||
🔲 |
MIPS64 (big-endian) |
Architecture |
||
🔲 |
MIPS64 (little-endian) |
Architecture |
||
🔲 |
MIPS (32-bit, little-endian) |
Architecture |
||
🚩 |
NetBSD |
Platform |
||
❄️ |
NixOS |
Platform |
||
|
Nobara |
Platform |
||
𝜈 |
Nushell |
Shell |
||
🃏 |
NuTyX |
Platform |
||
🐡 |
OpenBSD |
Platform |
||
🦎 |
openSUSE |
Platform |
||
📶 |
OpenWrt |
Platform |
||
🦴 |
Oracle Linux |
Platform |
||
🟦 |
IBM i |
Platform |
||
∥ |
Parallels |
Platform |
||
π |
Pi |
Agent |
||
🍓 |
Pidora |
Platform |
||
🐹 |
PikaOS |
Platform |
||
🔷 |
PowerShell |
Shell |
||
⚡ |
PowerPC (32-bit) |
Architecture |
||
⚡ |
PowerPC 64-bit (big-endian) |
Architecture |
||
⚡ |
PowerPC 64-bit (little-endian) |
Architecture |
||
🍓 |
Raspbian |
Platform |
||
🎩 |
RedHat Enterprise Linux |
Platform |
||
🏞️ |
Rio |
Terminal |
||
Ⅴ |
RISC-V (32-bit) |
Architecture |
||
Ⅴ |
RISC-V (64-bit) |
Architecture |
||
⛰️ |
Rocky Linux |
Platform |
||
🏢 |
IBM z/Architecture (s390x) |
Architecture |
||
⚛️ |
Scientific Linux |
Platform |
||
𝐒 |
Bourne Shell |
Shell |
||
🚬 |
Slackware |
Platform |
||
🦎 |
SUSE Linux Enterprise Server |
Platform |
||
🕷️ |
SliTaz GNU/Linux |
Platform |
||
🌞 |
Solaris |
Platform |
||
|
Solus |
Platform |
||
🧙 |
Source Mage GNU/Linux |
Platform |
||
☀️ |
SPARC (32-bit) |
Architecture |
||
☀️ |
SPARC (64-bit) |
Architecture |
||
🌅 |
SunOS |
Platform |
||
🐈 |
Tabby |
Terminal |
||
𝐓 |
tcsh |
Shell |
||
🏙️ |
TeamCity |
CI |
||
🔀 |
Tilix |
Terminal |
||
📟 |
tmux |
Terminal |
||
👷 |
Travis CI |
CI |
||
🤵 |
Tuxedo OS |
Platform |
||
🎯 |
Ubuntu |
Platform |
||
🌊 |
Ultramarine |
Platform |
||
❓ |
Unknown agent |
Agent |
||
❓ |
Unknown architecture |
Architecture |
||
❓ |
Unknown CI |
CI |
||
❓ |
Unknown platform |
Platform |
||
❓ |
Unknown shell |
Shell |
||
❓ |
Unknown terminal |
Terminal |
||
∅ |
Void Linux |
Platform |
||
🔵 |
VS Code Terminal |
Terminal |
||
🌐 |
WebAssembly (32-bit) |
Architecture |
||
🌐 |
WebAssembly (64-bit) |
Architecture |
||
🔡 |
WezTerm |
Terminal |
||
🪟 |
Windows |
Platform |
||
⊡ |
Windows Terminal |
Terminal |
||
⊞ |
Windows Subsystem for Linux v1 |
Platform |
||
⊞ |
Windows Subsystem for Linux v2 |
Platform |
||
🖥️ |
x86-64 (AMD64) |
Architecture |
||
Ⓧ |
XenServer |
Platform |
||
🐍 |
Xonsh |
Shell |
||
𝐗 |
xterm |
Terminal |
||
🪵 |
Zellij |
Terminal |
||
ℤ |
Zsh |
Shell |
Trait implementation¶
classDiagram
Trait <|-- Agent
Trait <|-- Architecture
Trait <|-- CI
Trait <|-- Platform
Trait <|-- Shell
Trait <|-- Terminal
_ClassMetadata <|-- _Identifiable
_Identifiable <|-- Trait
- class extra_platforms.Trait(id, name, icon='❓', url='', aliases=())[source]¶
Bases:
_IdentifiableBase class for system traits like platforms and architectures.
A trait is a distinguishing characteristic of the runtime environment that can be detected and identified.
In addition to the common fields inherited from
_Identifiable, each trait provides:url: A link to official documentation or website for the trait.aliases: Alternative IDs resolving to the trait.current: A boolean indicating if the current environment matches this trait.info(): A method returning a dictionary of gathered attributes about the trait.groups: A set ofGroupobjects that include this trait as a member.
- aliases: tuple[str, ...] = ()¶
Alternative IDs for this trait.
Aliases are alternative identifiers that resolve to the same trait. When an alias is used, a warning is emitted to encourage using the canonical ID.
Note
Aliases do not generate their own symbols, detection functions, or pytest decorators. Only the canonical
idproduces these artifacts.
- property current: bool¶
Returns whether the current environment matches this trait.
Calls the detection function named by
detection_func_id, which caches its own result. That function is looked up in the registry of thedetectionmodule, where tests replace it to simulate another environment.Raises
NotImplementedErrorif a detection function cannot be found.Hint
This is a property to avoid calling all detection heuristics on
Traitobject creation, which happens at module import time.
- info()[source]¶
Returns all trait attributes that can be gathered.
This default implementation returns the identity metadata common to all traits. Subclasses extend it with category-specific fields by merging
super().info()into their own result.
- _reference_lines()¶
The metadata lines linking the detection function and Pytest decorators.
- all_group = 'ALL_TRAITS'¶
The symbol name for the group containing all instances of this type.
- data_module_id = 'trait_data'¶
The module name where instances of this type are defined.
- property detection_func_id: str¶
ID of the detection function for this object.
The detection function is expected to be named
is_<id>()and available at the root of theextra_platformsmodule.
- doc_page = 'traits.md'¶
The documentation page filename.
- generate_docstring()¶
Generate the docstring of this predefined object.
Combines the attribute docstring written under the object in its data module with the metadata lines of the object.
- Return type:
- property skip_decorator_id: str¶
ID of the Pytest skip decorator for this object.
The decorator is expected to be named
@skip_<id>and available from theextra_platforms.pytestmodule.
- property symbol_id: str¶
Symbolic identifier.
This is the variable name under which the instance can be accessed at the root of the
extra_platformsmodule.Mainly useful for documentation generation.
- type_id = 'trait'¶
Machine-readable type identifier used to derive module and symbol names.
- type_name = 'trait'¶
Human-readable type name for documentation, like
"CI system".
- unknown_symbol = 'UNKNOWN_TRAIT'¶
The symbol name for the unknown instance of this type.
- class extra_platforms.Platform(id, name, icon='❓', url='', aliases=())[source]¶
Bases:
TraitA platform identifies one or more operating systems.
Distributions or systems that share the same characteristics share a platform.
See the
platform_datamodule for the granularity policy deciding when a distribution gets a dedicated platform, and when it is folded into an existing one.Todo
Detect the init system (systemd, upstart, sysvinit, openrc, runit, …), another dimension of platform characterization. See python-distro/distro#142 for prior discussion on init system detection.
- all_group = 'ALL_PLATFORMS'¶
The symbol name for the group containing all instances of this type.
- data_module_id = 'platform_data'¶
The module name where instances of this type are defined.
- doc_page = 'platforms.md'¶
The documentation page filename.
- type_id = 'platform'¶
Machine-readable type identifier used to derive module and symbol names.
- type_name = 'platform'¶
Human-readable type name for documentation, like
"CI system".
- unknown_symbol = 'UNKNOWN_PLATFORM'¶
The symbol name for the unknown instance of this type.
- class extra_platforms.Architecture(id, name, icon='❓', url='', aliases=())[source]¶
Bases:
TraitA CPU architecture identifies a processor instruction set.
Todo
Extend our architecture metadata beyond basic ISA detection with archspec, which provides a rich database of CPU microarchitectures (feature flags, compiler compatibility, family trees).
- all_group = 'ALL_ARCHITECTURES'¶
The symbol name for the group containing all instances of this type.
- data_module_id = 'architecture_data'¶
The module name where instances of this type are defined.
- doc_page = 'architectures.md'¶
The documentation page filename.
- type_id = 'architecture'¶
Machine-readable type identifier used to derive module and symbol names.
- type_name = 'architecture'¶
Human-readable type name for documentation, like
"CI system".
- unknown_symbol = 'UNKNOWN_ARCHITECTURE'¶
The symbol name for the unknown instance of this type.
- class extra_platforms.Shell(id, name, icon='❓', url='', aliases=(), version_env_var=None, interpreter=None, executables=())[source]¶
Bases:
TraitA shell identifies a command-line interpreter.
See also
Inspired by UV’s cross-platform shell detection.
- all_group = 'ALL_SHELLS'¶
The symbol name for the group containing all instances of this type.
- data_module_id = 'shell_data'¶
The module name where instances of this type are defined.
- doc_page = 'shells.md'¶
The documentation page filename.
- type_id = 'shell'¶
Machine-readable type identifier used to derive module and symbol names.
- type_name = 'shell'¶
Human-readable type name for documentation, like
"CI system".
- unknown_symbol = 'UNKNOWN_SHELL'¶
The symbol name for the unknown instance of this type.
- version_env_var: str | None = None¶
Environment variable set by the shell at startup (like
BASH_VERSION).A reliable signal that the shell is currently running, not just configured as the login shell in
SHELL.Nonefor shells that do not set a dedicated startup variable (like Dash or Almquist Shell).
- interpreter: str | None = None¶
Base name of the host interpreter for shells run as an interpreted script.
Set for shells that are not standalone executables but launcher scripts run by an interpreter (like
XONSH, run bypython). The value is the interpreter’s base name ("python"); detection tolerates a trailing version (python3,python3.11). When set, the parent process tree is also scanned for an interpreter process whose arguments include a launcher file named after this shell’sid, so the shell is detected even without its startup environment variable.Nonefor standalone shells.
- executables: tuple[str, ...] = ()¶
File names the shell’s binary goes by, when they differ from its ID.
Most shells answer to their
idalone, so the field stays empty.POWERSHELLships aspwshon every platform since6.0and aspowershell_iseon Windows,NUSHELLasnu, andKSHasksh93on Fedora and illumos, wherekshlinks to it. Detection matches the resolvedSHELLpath and the parent process tree againstexecutable_names, and so doesshell_from_path().
- class extra_platforms.Terminal(id, name, icon='❓', url='', aliases=())[source]¶
Bases:
TraitA terminal identifies the application rendering the shell’s output.
Note
Shell and Terminal are orthogonal: any shell can run inside any terminal. Unlike shells, multiple terminals can be active simultaneously (like tmux inside Kitty).
See also
Other tools that detect terminals for adaptation:
Starship adapts prompt rendering based on terminal
crossterm (Rust) negotiates terminal features
python-prompt-toolkit adapts to terminal capabilities
rich probes terminal features for rendering
termenv (Go) maintains terminal capability database
- all_group = 'ALL_TERMINALS'¶
The symbol name for the group containing all instances of this type.
- data_module_id = 'terminal_data'¶
The module name where instances of this type are defined.
- doc_page = 'terminals.md'¶
The documentation page filename.
- type_id = 'terminal'¶
Machine-readable type identifier used to derive module and symbol names.
- type_name = 'terminal'¶
Human-readable type name for documentation, like
"CI system".
- unknown_symbol = 'UNKNOWN_TERMINAL'¶
The symbol name for the unknown instance of this type.
- class extra_platforms.CI(id, name, icon='❓', url='', aliases=())[source]¶
Bases:
TraitA CI/CD environment identifies a continuous integration platform.
Its metadata spells the type name out, and keeps the more natural
ALL_CIandci.mdinstead of the derivedALL_CISandcis.md.- all_group = 'ALL_CI'¶
The symbol name for the group containing all instances of this type.
- data_module_id = 'ci_data'¶
The module name where instances of this type are defined.
- doc_page = 'ci.md'¶
The documentation page filename.
- type_id = 'ci'¶
Machine-readable type identifier used to derive module and symbol names.
- type_name = 'CI system'¶
Human-readable type name for documentation, like
"CI system".
- unknown_symbol = 'UNKNOWN_CI'¶
The symbol name for the unknown instance of this type.
- class extra_platforms.Agent(id, name, icon='❓', url='', aliases=())[source]¶
Bases:
TraitAn agent identifies an AI coding agent environment.
- all_group = 'ALL_AGENTS'¶
The symbol name for the group containing all instances of this type.
- data_module_id = 'agent_data'¶
The module name where instances of this type are defined.
- doc_page = 'agents.md'¶
The documentation page filename.
- type_id = 'agent'¶
Machine-readable type identifier used to derive module and symbol names.
- type_name = 'agent'¶
Human-readable type name for documentation, like
"CI system".
- unknown_symbol = 'UNKNOWN_AGENT'¶
The symbol name for the unknown instance of this type.