since-dev 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- since_dev-0.1.0/LICENSE +21 -0
- since_dev-0.1.0/PKG-INFO +147 -0
- since_dev-0.1.0/README.md +126 -0
- since_dev-0.1.0/pyproject.toml +34 -0
- since_dev-0.1.0/setup.cfg +4 -0
- since_dev-0.1.0/since_dev/__init__.py +3 -0
- since_dev-0.1.0/since_dev/__main__.py +23 -0
- since_dev-0.1.0/since_dev/cli.py +631 -0
- since_dev-0.1.0/since_dev/init.py +119 -0
- since_dev-0.1.0/since_dev/local.py +75 -0
- since_dev-0.1.0/since_dev/realio.py +134 -0
- since_dev-0.1.0/since_dev/render.py +337 -0
- since_dev-0.1.0/since_dev.egg-info/PKG-INFO +147 -0
- since_dev-0.1.0/since_dev.egg-info/SOURCES.txt +15 -0
- since_dev-0.1.0/since_dev.egg-info/dependency_links.txt +1 -0
- since_dev-0.1.0/since_dev.egg-info/entry_points.txt +3 -0
- since_dev-0.1.0/since_dev.egg-info/top_level.txt +1 -0
since_dev-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Since.dev
|
|
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.
|
since_dev-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: since-dev
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Find the code in a repository that is about to stop working: retired model IDs, runtimes past end of life, breaking dependency changes. Each with its date, its line and its replacement.
|
|
5
|
+
Author-email: Nabil A <support@since.dev>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://since.dev
|
|
8
|
+
Project-URL: Documentation, https://since.dev/docs#cli
|
|
9
|
+
Project-URL: Source, https://github.com/Since-dev/cli
|
|
10
|
+
Project-URL: Issues, https://github.com/Since-dev/cli/issues
|
|
11
|
+
Keywords: deprecation,end-of-life,breaking-changes,dependencies,ai-models,mcp,cli,continuous-maintenance
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Dynamic: license-file
|
|
21
|
+
|
|
22
|
+
# since-dev
|
|
23
|
+
|
|
24
|
+
Find the code in a repository that is about to stop working: AI model IDs with a shutdown date, runtimes past end of life, dependencies with security advisories or breaking releases. Every finding comes with its file and line, its date, its replacement and its source.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx since-dev
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Run it inside any repository. A public GitHub repository needs no sign-in and no setup.
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
acme/shop main@4f2c1d9 scanned just now
|
|
34
|
+
3 with a date 1 undated 214 dependencies and 96 files read
|
|
35
|
+
Read from GitHub (main), not your working tree.
|
|
36
|
+
|
|
37
|
+
20 days claude-sonnet-4-5-20250929 on Claude API: retirement 2026-11-30
|
|
38
|
+
src/ai/client.ts:14 and 3 more use claude-sonnet-5-5
|
|
39
|
+
https://platform.claude.com/docs/en/about-claude/model-deprecations
|
|
40
|
+
|
|
41
|
+
31 days gpt-5 on OpenAI API: retirement 2026-12-11
|
|
42
|
+
src/ai/summarize.ts:8 use gpt-5.6-sol
|
|
43
|
+
https://developers.openai.com/api/docs/deprecations
|
|
44
|
+
|
|
45
|
+
passed Node.js 20: end of life 2026-04-30
|
|
46
|
+
.github/workflows/ci.yml use 24
|
|
47
|
+
https://endoflife.date/nodejs
|
|
48
|
+
|
|
49
|
+
Full report https://since.dev/scan/acme/shop?utm_source=cli
|
|
50
|
+
Next npx since-dev init your coding agent checks before it writes
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
(An example for a made-up repository. The dates are the real ones as of November 10, 2026.)
|
|
54
|
+
|
|
55
|
+
## Run it
|
|
56
|
+
|
|
57
|
+
| With | Command |
|
|
58
|
+
| --- | --- |
|
|
59
|
+
| Node 18 or newer | `npx since-dev` |
|
|
60
|
+
| uv | `uvx since-dev` |
|
|
61
|
+
| pipx | `pipx run since-dev` |
|
|
62
|
+
|
|
63
|
+
To keep it, `npm install -g since-dev` or `pip install since-dev` gives you the command `since`. The npm and PyPI packages are the same CLI: no dependencies in either, and one set of tests holds both to the same output, character for character.
|
|
64
|
+
|
|
65
|
+
## Commands
|
|
66
|
+
|
|
67
|
+
| Command | What it does |
|
|
68
|
+
| --- | --- |
|
|
69
|
+
| `since` | Checks the repository you are in. It reads the `origin` remote to know which one. |
|
|
70
|
+
| `since <owner/repo>` | Checks any public GitHub repository. A GitHub URL works too. |
|
|
71
|
+
| `since init` | Sets up your coding agent to check before it writes. See below. |
|
|
72
|
+
| `since calendar` | What ends in the next 30 days: model retirements, runtime end of life, API removals. `--within 90d`, `--provider openai`. |
|
|
73
|
+
| `since changed <package>` | Breaking changes and deprecations of a package. `--since 4.19.2` lists only what changed after that version, `--ecosystem pypi` picks the registry. Needs a key. |
|
|
74
|
+
| `since check` | The same check for CI: exit 1 when a finding fails. See below. |
|
|
75
|
+
| `since login`, `since logout` | Sign in for private repositories, and remove the stored key. |
|
|
76
|
+
|
|
77
|
+
`--all` shows every finding (10 by default), `--json` prints the answer as JSON, `--within 30d` keeps only dates within that many days.
|
|
78
|
+
|
|
79
|
+
Findings are listed with the next deadline first, then dates that have passed, then security advisories with no date, then the ones marked `review`: Since found the name in your code but could not prove the change reaches it.
|
|
80
|
+
|
|
81
|
+
## Set up your coding agent
|
|
82
|
+
|
|
83
|
+
Coding agents write the model IDs and versions that were current when they were trained. This makes yours check first:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
npx since-dev init
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
It writes four files into the repository:
|
|
90
|
+
|
|
91
|
+
| File | For |
|
|
92
|
+
| --- | --- |
|
|
93
|
+
| `.mcp.json` | Claude Code |
|
|
94
|
+
| `.cursor/mcp.json` | Cursor |
|
|
95
|
+
| `.vscode/mcp.json` | VS Code |
|
|
96
|
+
| `AGENTS.md` | A short rule, between two markers, that tells any agent when to check |
|
|
97
|
+
|
|
98
|
+
Commit them and everyone who clones the repository gets the same setup. No key goes in any file: the first tool call opens a sign-in in the browser.
|
|
99
|
+
|
|
100
|
+
It only ever adds its own `since` entry. Other servers in those files stay as they are, a second run changes nothing, and a file it cannot read as plain JSON is left alone with the lines to add by hand. `--dry-run` shows what it would write.
|
|
101
|
+
|
|
102
|
+
## What it sends
|
|
103
|
+
|
|
104
|
+
- **A public GitHub repository:** only its name. Since reads the default branch from GitHub, so uncommitted work and other branches are not in the answer. It is free: 10 scans a day per address, and a scan is kept for an hour.
|
|
105
|
+
- **A private repository, after `since login`:** if the repository is connected to your Since workspace and your plan includes it, the answer comes from there. Otherwise the CLI sends the manifests it finds in the folder (`package.json`, `requirements*.txt`, `pyproject.toml`, `go.mod`, `Cargo.toml`, `Gemfile`, `composer.json`, `pom.xml`, `build.gradle`, `*.csproj`), 10 at most unless you raise `--max-files`. Source files are never sent. Each manifest is one call to the API, which uses credits.
|
|
106
|
+
- `--local` checks the manifests in the folder even when the repository is public, for work you have not pushed.
|
|
107
|
+
|
|
108
|
+
## In CI
|
|
109
|
+
|
|
110
|
+
```yaml
|
|
111
|
+
- run: npx since-dev check --fail-on high
|
|
112
|
+
env:
|
|
113
|
+
SINCE_DEV_KEY: ${{ secrets.SINCE_DEV_KEY }}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
With a key it checks the manifests of the checkout. Without one it reads the default branch of a public repository from GitHub, and says so.
|
|
117
|
+
|
|
118
|
+
| Exit code | Meaning |
|
|
119
|
+
| --- | --- |
|
|
120
|
+
| 0 | Nothing proven at or above `--fail-on` (`low`, `medium`, `high` by default, `critical`, or `none`). |
|
|
121
|
+
| 1 | At least one finding fails. A finding marked `review` never fails a run. |
|
|
122
|
+
| 2 | Something for you to fix: a refused key, a bad option, no manifests. |
|
|
123
|
+
|
|
124
|
+
If Since cannot be reached, or the free scans for the day are used up, the run passes with a note. An outage on our side never fails your build.
|
|
125
|
+
|
|
126
|
+
On GitHub Actions, [since-dev/check](https://github.com/since-dev/check) does the same with annotations on the files and a table in the run summary.
|
|
127
|
+
|
|
128
|
+
## Sign in
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
since login
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
It asks for your email, prints a link, and waits while you approve it in the browser. The key is stored in `~/.config/since/credentials.json`, readable only by you. Setting `SINCE_DEV_KEY` works as well and wins over the stored key. `since logout` removes the stored key.
|
|
135
|
+
|
|
136
|
+
## Develop
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
node --test test.mjs
|
|
140
|
+
python3 -m unittest test_cli
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Each file in `fixtures/` is one run: the arguments, the folder, and the answers the API gives. `expected/` holds what that run prints, requests and writes. Both test suites replay every fixture and compare with the same expected file. After a change to the Node side, `UPDATE_EXPECTED=1 node --test test.mjs` rewrites the expected files: read the diff, then make the Python side match.
|
|
144
|
+
|
|
145
|
+
## License
|
|
146
|
+
|
|
147
|
+
MIT. The data comes from [Since.dev](https://since.dev): the [calendar](https://since.dev/calendar) of what ends when, and the [API](https://since.dev/docs) behind this CLI.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# since-dev
|
|
2
|
+
|
|
3
|
+
Find the code in a repository that is about to stop working: AI model IDs with a shutdown date, runtimes past end of life, dependencies with security advisories or breaking releases. Every finding comes with its file and line, its date, its replacement and its source.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npx since-dev
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Run it inside any repository. A public GitHub repository needs no sign-in and no setup.
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
acme/shop main@4f2c1d9 scanned just now
|
|
13
|
+
3 with a date 1 undated 214 dependencies and 96 files read
|
|
14
|
+
Read from GitHub (main), not your working tree.
|
|
15
|
+
|
|
16
|
+
20 days claude-sonnet-4-5-20250929 on Claude API: retirement 2026-11-30
|
|
17
|
+
src/ai/client.ts:14 and 3 more use claude-sonnet-5-5
|
|
18
|
+
https://platform.claude.com/docs/en/about-claude/model-deprecations
|
|
19
|
+
|
|
20
|
+
31 days gpt-5 on OpenAI API: retirement 2026-12-11
|
|
21
|
+
src/ai/summarize.ts:8 use gpt-5.6-sol
|
|
22
|
+
https://developers.openai.com/api/docs/deprecations
|
|
23
|
+
|
|
24
|
+
passed Node.js 20: end of life 2026-04-30
|
|
25
|
+
.github/workflows/ci.yml use 24
|
|
26
|
+
https://endoflife.date/nodejs
|
|
27
|
+
|
|
28
|
+
Full report https://since.dev/scan/acme/shop?utm_source=cli
|
|
29
|
+
Next npx since-dev init your coding agent checks before it writes
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
(An example for a made-up repository. The dates are the real ones as of November 10, 2026.)
|
|
33
|
+
|
|
34
|
+
## Run it
|
|
35
|
+
|
|
36
|
+
| With | Command |
|
|
37
|
+
| --- | --- |
|
|
38
|
+
| Node 18 or newer | `npx since-dev` |
|
|
39
|
+
| uv | `uvx since-dev` |
|
|
40
|
+
| pipx | `pipx run since-dev` |
|
|
41
|
+
|
|
42
|
+
To keep it, `npm install -g since-dev` or `pip install since-dev` gives you the command `since`. The npm and PyPI packages are the same CLI: no dependencies in either, and one set of tests holds both to the same output, character for character.
|
|
43
|
+
|
|
44
|
+
## Commands
|
|
45
|
+
|
|
46
|
+
| Command | What it does |
|
|
47
|
+
| --- | --- |
|
|
48
|
+
| `since` | Checks the repository you are in. It reads the `origin` remote to know which one. |
|
|
49
|
+
| `since <owner/repo>` | Checks any public GitHub repository. A GitHub URL works too. |
|
|
50
|
+
| `since init` | Sets up your coding agent to check before it writes. See below. |
|
|
51
|
+
| `since calendar` | What ends in the next 30 days: model retirements, runtime end of life, API removals. `--within 90d`, `--provider openai`. |
|
|
52
|
+
| `since changed <package>` | Breaking changes and deprecations of a package. `--since 4.19.2` lists only what changed after that version, `--ecosystem pypi` picks the registry. Needs a key. |
|
|
53
|
+
| `since check` | The same check for CI: exit 1 when a finding fails. See below. |
|
|
54
|
+
| `since login`, `since logout` | Sign in for private repositories, and remove the stored key. |
|
|
55
|
+
|
|
56
|
+
`--all` shows every finding (10 by default), `--json` prints the answer as JSON, `--within 30d` keeps only dates within that many days.
|
|
57
|
+
|
|
58
|
+
Findings are listed with the next deadline first, then dates that have passed, then security advisories with no date, then the ones marked `review`: Since found the name in your code but could not prove the change reaches it.
|
|
59
|
+
|
|
60
|
+
## Set up your coding agent
|
|
61
|
+
|
|
62
|
+
Coding agents write the model IDs and versions that were current when they were trained. This makes yours check first:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx since-dev init
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
It writes four files into the repository:
|
|
69
|
+
|
|
70
|
+
| File | For |
|
|
71
|
+
| --- | --- |
|
|
72
|
+
| `.mcp.json` | Claude Code |
|
|
73
|
+
| `.cursor/mcp.json` | Cursor |
|
|
74
|
+
| `.vscode/mcp.json` | VS Code |
|
|
75
|
+
| `AGENTS.md` | A short rule, between two markers, that tells any agent when to check |
|
|
76
|
+
|
|
77
|
+
Commit them and everyone who clones the repository gets the same setup. No key goes in any file: the first tool call opens a sign-in in the browser.
|
|
78
|
+
|
|
79
|
+
It only ever adds its own `since` entry. Other servers in those files stay as they are, a second run changes nothing, and a file it cannot read as plain JSON is left alone with the lines to add by hand. `--dry-run` shows what it would write.
|
|
80
|
+
|
|
81
|
+
## What it sends
|
|
82
|
+
|
|
83
|
+
- **A public GitHub repository:** only its name. Since reads the default branch from GitHub, so uncommitted work and other branches are not in the answer. It is free: 10 scans a day per address, and a scan is kept for an hour.
|
|
84
|
+
- **A private repository, after `since login`:** if the repository is connected to your Since workspace and your plan includes it, the answer comes from there. Otherwise the CLI sends the manifests it finds in the folder (`package.json`, `requirements*.txt`, `pyproject.toml`, `go.mod`, `Cargo.toml`, `Gemfile`, `composer.json`, `pom.xml`, `build.gradle`, `*.csproj`), 10 at most unless you raise `--max-files`. Source files are never sent. Each manifest is one call to the API, which uses credits.
|
|
85
|
+
- `--local` checks the manifests in the folder even when the repository is public, for work you have not pushed.
|
|
86
|
+
|
|
87
|
+
## In CI
|
|
88
|
+
|
|
89
|
+
```yaml
|
|
90
|
+
- run: npx since-dev check --fail-on high
|
|
91
|
+
env:
|
|
92
|
+
SINCE_DEV_KEY: ${{ secrets.SINCE_DEV_KEY }}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
With a key it checks the manifests of the checkout. Without one it reads the default branch of a public repository from GitHub, and says so.
|
|
96
|
+
|
|
97
|
+
| Exit code | Meaning |
|
|
98
|
+
| --- | --- |
|
|
99
|
+
| 0 | Nothing proven at or above `--fail-on` (`low`, `medium`, `high` by default, `critical`, or `none`). |
|
|
100
|
+
| 1 | At least one finding fails. A finding marked `review` never fails a run. |
|
|
101
|
+
| 2 | Something for you to fix: a refused key, a bad option, no manifests. |
|
|
102
|
+
|
|
103
|
+
If Since cannot be reached, or the free scans for the day are used up, the run passes with a note. An outage on our side never fails your build.
|
|
104
|
+
|
|
105
|
+
On GitHub Actions, [since-dev/check](https://github.com/since-dev/check) does the same with annotations on the files and a table in the run summary.
|
|
106
|
+
|
|
107
|
+
## Sign in
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
since login
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
It asks for your email, prints a link, and waits while you approve it in the browser. The key is stored in `~/.config/since/credentials.json`, readable only by you. Setting `SINCE_DEV_KEY` works as well and wins over the stored key. `since logout` removes the stored key.
|
|
114
|
+
|
|
115
|
+
## Develop
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
node --test test.mjs
|
|
119
|
+
python3 -m unittest test_cli
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Each file in `fixtures/` is one run: the arguments, the folder, and the answers the API gives. `expected/` holds what that run prints, requests and writes. Both test suites replay every fixture and compare with the same expected file. After a change to the Node side, `UPDATE_EXPECTED=1 node --test test.mjs` rewrites the expected files: read the diff, then make the Python side match.
|
|
123
|
+
|
|
124
|
+
## License
|
|
125
|
+
|
|
126
|
+
MIT. The data comes from [Since.dev](https://since.dev): the [calendar](https://since.dev/calendar) of what ends when, and the [API](https://since.dev/docs) behind this CLI.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=64"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "since-dev"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Find the code in a repository that is about to stop working: retired model IDs, runtimes past end of life, breaking dependency changes. Each with its date, its line and its replacement."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "Nabil A", email = "support@since.dev" }]
|
|
13
|
+
keywords = ["deprecation", "end-of-life", "breaking-changes", "dependencies", "ai-models", "mcp", "cli", "continuous-maintenance"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Environment :: Console",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Topic :: Software Development :: Quality Assurance",
|
|
20
|
+
]
|
|
21
|
+
dependencies = []
|
|
22
|
+
|
|
23
|
+
[project.urls]
|
|
24
|
+
Homepage = "https://since.dev"
|
|
25
|
+
Documentation = "https://since.dev/docs#cli"
|
|
26
|
+
Source = "https://github.com/Since-dev/cli"
|
|
27
|
+
Issues = "https://github.com/Since-dev/cli/issues"
|
|
28
|
+
|
|
29
|
+
[project.scripts]
|
|
30
|
+
since = "since_dev.__main__:main"
|
|
31
|
+
since-dev = "since_dev.__main__:main"
|
|
32
|
+
|
|
33
|
+
[tool.setuptools]
|
|
34
|
+
packages = ["since_dev"]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
from .cli import run
|
|
4
|
+
from .realio import RealIo
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def main():
|
|
8
|
+
for stream in (sys.stdout, sys.stderr):
|
|
9
|
+
# A Windows console in a legacy code page would fail on a title outside it; replace what it cannot show.
|
|
10
|
+
if hasattr(stream, "reconfigure"):
|
|
11
|
+
stream.reconfigure(encoding="utf-8", errors="replace")
|
|
12
|
+
try:
|
|
13
|
+
code = run(sys.argv[1:], RealIo())
|
|
14
|
+
except KeyboardInterrupt:
|
|
15
|
+
code = 130
|
|
16
|
+
except Exception as error: # noqa: BLE001 - the last line of defense: say what happened in one line
|
|
17
|
+
sys.stderr.write("since: %s\n" % error)
|
|
18
|
+
code = 1
|
|
19
|
+
sys.exit(code)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
if __name__ == "__main__":
|
|
23
|
+
main()
|