Skip to content

Commit be8198f

Browse files
committed
Created is-legacy-terminal pkg
1 parent 08f9242 commit be8198f

141 files changed

Lines changed: 2807 additions & 5 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/dependabot.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ updates:
1313
- /data-languages
1414
- /find-project-root
1515
- /get-min-py
16+
- /is-legacy-terminal
1617
- /is-unicode-supported
1718
- /latin-locales
1819
- /markup-languages

docs/README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# 🐍 adamlui / python-utils
44

5-
<a href="https://pypacktrends.com/?packages=computer-languages&packages=data-languages&packages=find-project-root&packages=get-min-py&packages=is-unicode-supported&packages=latin-locales&packages=markup-languages&packages=non-latin-locales&packages=programming-languages&packages=project-markers&packages=prose-languages&packages=remove-json-keys&packages=translate-messages&time_range=allTimeCumulative&scheme=dark">
5+
<a href="https://pypacktrends.com/?packages=computer-languages&packages=data-languages&packages=find-project-root&packages=get-min-py&packages=is-legacy-terminal&packages=is-unicode-supported&packages=latin-locales&packages=markup-languages&packages=non-latin-locales&packages=programming-languages&packages=project-markers&packages=prose-languages&packages=remove-json-keys&packages=translate-messages&time_range=allTimeCumulative&scheme=dark">
66
<img height=31 src="https://img.shields.io/badge/Downloads-15.9k-af68ff.svg?logo=weightsandbiases&logoColor=white&labelColor=464646&style=for-the-badge"></a>
77
<a href="./LICENSE.md">
88
<img height=31 src="https://img.shields.io/badge/License-MIT-f99b27.svg?logo=internetarchive&logoColor=white&labelColor=464646&style=for-the-badge"></a>
@@ -67,7 +67,16 @@
6767
Discuss</a>
6868
</blockquote>
6969

70-
### <a href="https://github.com/adamlui/python-utils/tree/main/is-unicode-supported/#readme">📟 is-unicode-supported</a>
70+
### <a href="https://github.com/adamlui/python-utils/tree/main/is-legacy-terminal/#readme">📟 is-legacy-terminal</a>
71+
72+
> Detect whether the terminal is legacy.
73+
<br>[Install](https://github.com/adamlui/python-utils/tree/main/is-legacy-terminal/#-installation) /
74+
[Readme](https://github.com/adamlui/python-utils/tree/main/is-legacy-terminal/#readme) /
75+
[API usage](https://github.com/adamlui/python-utils/tree/main/is-legacy-terminal/#-api-usage) /
76+
[CLI usage](https://github.com/adamlui/python-utils/tree/main/is-legacy-terminal/#-command-line-usage) /
77+
[Discuss](https://github.com/adamlui/python-utils/discussions)
78+
79+
### <a href="https://github.com/adamlui/python-utils/tree/main/is-unicode-supported/#readme">🈶 is-unicode-supported</a>
7180

7281
> Detect whether the terminal supports advanced Unicode.
7382
<br>[Install](https://github.com/adamlui/python-utils/tree/main/is-unicode-supported/#-installation) /

is-legacy-terminal/docs/LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# 🏛️ MIT License
2+
3+
**Copyright © 2026 [Adam Lui](https://github.com/adamlui)**
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

is-legacy-terminal/docs/README.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<a id="top"></a>
2+
3+
# > 📟 is-legacy-terminal
4+
5+
<a href="https://github.com/adamlui/python-utils/releases/tag/is-legacy-terminal-1.0.0">
6+
<img height=31 src="https://img.shields.io/badge/Latest_Build-1.0.0-32fcee.svg?logo=icinga&logoColor=white&labelColor=464646&style=for-the-badge"></a>
7+
<a href="https://github.com/adamlui/python-utils/blob/main/is-legacy-terminal/docs/LICENSE.md">
8+
<img height=31 src="https://img.shields.io/badge/License-MIT-f99b27.svg?logo=internetarchive&logoColor=white&labelColor=464646&style=for-the-badge"></a>
9+
<a href="https://www.codefactor.io/repository/github/adamlui/python-utils">
10+
<img height=31 src="https://img.shields.io/codefactor/grade/github/adamlui/python-utils?label=Code+Quality&logo=codefactor&logoColor=white&labelColor=464646&color=a0fc55&style=for-the-badge"></a>
11+
<a href="https://sonarcloud.io/component_measures?metric=new_vulnerabilities&id=adamlui_python-utils">
12+
<img height=31 src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fsonarcloud.io%2Fapi%2Fmeasures%2Fcomponent%3Fcomponent%3Dadamlui_python-utils%26metricKeys%3Dvulnerabilities&query=%24.component.measures.0.value&style=for-the-badge&logo=sonar&logoColor=white&labelColor=464646&label=Vulnerabilities&color=fafc74"></a>
13+
14+
> ### _Detect whether the terminal is legacy._
15+
16+
Checks if terminal is legacy (flicker-prone, limited rendering, etc.). On Windows, returns `True` if CMD or PowerShell ISE not hosted in modern shell. On *nix systems, returns `True` if `env.TERM` is `dumb` or `unknown` (indicating a very basic terminal).
17+
18+
19+
## ⚡ Installation
20+
21+
```bash
22+
pip install is-legacy-terminal
23+
```
24+
25+
## 💻 Command line usage
26+
27+
```bash
28+
is-legacy-terminal # or islegacyterm
29+
# e.g. => True
30+
```
31+
32+
CLI options:
33+
34+
| Option | Description
35+
| ----------------- | -----------------
36+
| `-h`, `--help` | Show help screen
37+
| `-v`, `--version` | Show version
38+
| `--docs` | Open docs URL
39+
40+
## 🔌 API usage
41+
42+
```py
43+
import is_legacy_terminal
44+
45+
if is_legacy_terminal():
46+
print('Is legacy terminal!')
47+
else:
48+
print('Is not legacy terminal!')
49+
```
50+
51+
_Note: Most type checkers will falsely warn_ `is_legacy_terminal` _is not a callable module because they are incapable of analyzing runtime behavior (where the module is replaced w/ a function for cleaner, direct access). You can safely suppress such warnings using_ `# type: ignore`.
52+
53+
## MIT License
54+
55+
Copyright © 2026 [Adam Lui](https://github.com/adamlui).
56+
57+
## Related
58+
59+
🈶 [is-unicode-supported](https://github.com/adamlui/python-utils/tree/main/is-unicode-supported/#readme) - Detect whether the terminal supports advanced Unicode.
60+
61+
#
62+
63+
<picture><source media="(prefers-color-scheme: dark)" srcset="https://cdn.jsdelivr.net/gh/adamlui/python-utils@760599e/assets/images/icons/home/white/icon32x27.png"><img height=13 src="https://cdn.jsdelivr.net/gh/adamlui/python-utils@760599e/assets/images/icons/home/dark-gray/icon32x27.png"></picture> <a href=https://github.com/adamlui/python-utils/#readme>**More Python utilities**</a> /
64+
<a href="#top">Back to top ↑</a>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# 🛡️ Security Policy
2+
3+
If you find a vulnerability, please e-mail security@tidelift.com and a fix will be coordinated within 2 business days.

is-legacy-terminal/noxfile.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
from pathlib import Path
2+
from types import SimpleNamespace as sn
3+
4+
import nox
5+
6+
pkg = sn(dir=Path(__file__).parent.name)
7+
pkg.name = pkg.dir.replace('-', '_')
8+
paths = sn(utils=sn(bump='utils/bump.py', clean='utils/clean.py', publish='utils/publish.sh'))
9+
10+
def session(func) : return nox.session(venv_backend='none', name=func.__name__.replace('_', '-'))(func)
11+
12+
# SESSIONS
13+
14+
@session
15+
def dev(session) : session.run('pip', 'install', '-e', '.') ; session.run(pkg.dir, '--help', *session.posargs)
16+
@session
17+
def debug(session) : session.run('py', '-m', pkg.name, '--debug', *session.posargs, env={ 'PYTHONPATH': 'src' })
18+
19+
@session
20+
def lint(session): # staged project files
21+
files = session.run('git', 'diff', '--cached', '--name-only', '--relative', silent=True, log=False).splitlines()
22+
if files : session.run('pre-commit', 'run', '--files', *files, *session.posargs)
23+
@session
24+
def lint_all(session): # all project files
25+
files = session.run('git', 'ls-files', '.', silent=True, log=False).splitlines()
26+
session.run('pre-commit', 'run', '--files', *files, *session.posargs)
27+
28+
@session
29+
def bump_patch(session, no_push=True):
30+
cmd = ['py', paths.utils.bump, '--patch']
31+
if no_push : cmd.append('--no-push')
32+
session.run(*cmd, *session.posargs)
33+
@session
34+
def bump_minor(session, no_push=True):
35+
cmd = ['py', paths.utils.bump, '--minor']
36+
if no_push : cmd.append('--no-push')
37+
session.run(*cmd, *session.posargs)
38+
@session
39+
def bump_feat(session, no_push=True):
40+
bump_minor(session, no_push)
41+
@session
42+
def bump_major(session, no_push=True):
43+
cmd = ['py', paths.utils.bump, '--major']
44+
if no_push : cmd.append('--no-push')
45+
session.run(*cmd, *session.posargs)
46+
47+
@session
48+
def build(session) : clean(session) ; session.run('py', '-m', 'build') ; print('Build complete!')
49+
@session
50+
def publish(session) : session.run('bash', paths.utils.publish, *session.posargs)
51+
52+
@session
53+
def deploy_patch(session) : bump_patch(session, no_push=False) ; build(session) ; publish(session)
54+
@session
55+
def deploy_minor(session) : bump_minor(session, no_push=False) ; build(session) ; publish(session)
56+
@session
57+
def deploy_feat(session) : deploy_minor(session)
58+
@session
59+
def deploy_major(session) : bump_major(session, no_push=False) ; build(session) ; publish(session)
60+
61+
@session
62+
def clean(session, *args) : session.run('py', paths.utils.clean, *args)

is-legacy-terminal/pyproject.toml

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
[build-system]
2+
requires = [
3+
"setuptools~=82.0.0",
4+
"wheel",
5+
]
6+
build-backend = "setuptools.build_meta"
7+
8+
[project]
9+
name = "is-legacy-terminal"
10+
version = "1.0.0"
11+
description = "Detect whether the terminal is legacy."
12+
authors = [
13+
{ name = "Adam Lui", email = "adam@kudoai.com" },
14+
]
15+
readme = "docs/README.md"
16+
license = "MIT"
17+
license-files = [
18+
"docs/LICENSE.md",
19+
]
20+
dependencies = [
21+
"colorama~=0.4.6 ; platform_system == 'Windows'",
22+
"json5~=0.13.0",
23+
]
24+
requires-python = ">=3.8,<4"
25+
keywords = [
26+
"ansi",
27+
"api",
28+
"cli",
29+
"cmd",
30+
"compatibility",
31+
"conhost",
32+
"console",
33+
"detect",
34+
"detection",
35+
"dev-tool",
36+
"flicker",
37+
"legacy",
38+
"powershell",
39+
"shell",
40+
"support",
41+
"supported",
42+
"supports",
43+
"terminal",
44+
"vt100",
45+
"windows-console",
46+
]
47+
classifiers = [
48+
"Development Status :: 5 - Production/Stable",
49+
"Environment :: Console",
50+
"Intended Audience :: Developers",
51+
"Intended Audience :: End Users/Desktop",
52+
"Intended Audience :: Information Technology",
53+
"Intended Audience :: System Administrators",
54+
"Natural Language :: English",
55+
"Operating System :: OS Independent",
56+
"Programming Language :: Python",
57+
"Programming Language :: Python :: 3",
58+
"Programming Language :: Python :: 3 :: Only",
59+
"Programming Language :: Python :: 3.8",
60+
"Programming Language :: Python :: 3.9",
61+
"Programming Language :: Python :: 3.10",
62+
"Programming Language :: Python :: 3.11",
63+
"Programming Language :: Python :: 3.12",
64+
"Programming Language :: Python :: 3.13",
65+
"Programming Language :: Python :: 3.14",
66+
"Programming Language :: Python :: 3.15",
67+
"Topic :: Software Development",
68+
"Topic :: Software Development :: Libraries",
69+
"Topic :: Software Development :: Libraries :: Python Modules",
70+
"Topic :: System",
71+
"Topic :: System :: Shells",
72+
"Topic :: System :: Systems Administration",
73+
"Topic :: Terminals",
74+
"Topic :: Utilities",
75+
"Typing :: Typed",
76+
]
77+
78+
[project.urls]
79+
Changelog = "https://github.com/adamlui/python-utils/releases/tag/is-legacy-terminal-1.0.0"
80+
Documentation = "https://github.com/adamlui/python-utils/tree/main/is-legacy-terminal/docs"
81+
Funding = "https://github.com/sponsors/adamlui"
82+
Homepage = "https://github.com/adamlui/python-utils/tree/main/is-legacy-terminal/#readme"
83+
Issues = "https://github.com/adamlui/python-utils/issues"
84+
"PyPI Stats" = "https://pepy.tech/projects/is-legacy-terminal"
85+
Releases = "https://github.com/adamlui/python-utils/releases"
86+
Repository = "https://github.com/adamlui/python-utils"
87+
88+
[project.scripts]
89+
is-legacy-terminal = "is_legacy_terminal.cli.__main__:main"
90+
is-legacy-term = "is_legacy_terminal.cli.__main__:main"
91+
is-legacy-console = "is_legacy_terminal.cli.__main__:main"
92+
is-terminal-legacy = "is_legacy_terminal.cli.__main__:main"
93+
is-term-legacy = "is_legacy_terminal.cli.__main__:main"
94+
is-console-legacy = "is_legacy_terminal.cli.__main__:main"
95+
islegacyterminal = "is_legacy_terminal.cli.__main__:main"
96+
islegacyterm = "is_legacy_terminal.cli.__main__:main"
97+
islegacyconsole = "is_legacy_terminal.cli.__main__:main"
98+
isterminallegacy = "is_legacy_terminal.cli.__main__:main"
99+
istermlegacy = "is_legacy_terminal.cli.__main__:main"
100+
isconsolelegacy = "is_legacy_terminal.cli.__main__:main"
101+
102+
[project.optional-dependencies]
103+
dev = [
104+
"nox>=2026.2.9",
105+
"remove-json-keys~=1.9.1",
106+
"tomli~=2.4.0",
107+
"tomli-w~=1.2.0",
108+
"translate-messages~=1.9.0",
109+
]
110+
111+
[tool.setuptools.packages.find]
112+
where = [
113+
"src",
114+
]
115+
116+
[tool.setuptools.package-data]
117+
is_legacy_terminal = [
118+
"data/*.json",
119+
"data/_locales/en/messages.json",
120+
]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import sys
2+
3+
from .api import is_legacy_terminal
4+
from . import cli
5+
6+
sys.modules[__name__].cli = cli # type: ignore
7+
sys.modules[__name__] = is_legacy_terminal # type: ignore
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import os, sys
2+
3+
def is_legacy_terminal() -> bool:
4+
if sys.platform == 'win32':
5+
modern = any(os.environ.get(env_var) for env_var in ('WT_SESSION', 'ConEmuPID', 'VSCODE_TERM', 'TERM_PROGRAM'))
6+
legacy = os.environ.get('COMSPEC', '').lower().endswith('cmd.exe') or bool(os.environ.get('PSISE'))
7+
return legacy and not modern # since host shell can override
8+
else:
9+
return os.environ.get('TERM', '') in ('dumb', 'unknown')

is-legacy-terminal/src/is_legacy_terminal/cli/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)