oopsh

oopsh corrects errors in previous console commands: type oops after a
failed command and it suggests (and runs) the fixed one.
oopsh is a maintained fork of thefuck by Vladimir Iakovlev, which is no longer maintained and doesn't run on Python 3.12+. It is not an official thefuck release. All of thefuck's rules work in oopsh, and the project keeps thefuck's full history and MIT license. See the roadmap for what's planned.
Switching from thefuck? Install oopsh and change one line in your shell config:
your settings, custom rules and THEFUCK_* variables keep working.
More details.
Is oopsh too slow? Try the experimental instant mode!
Examples:
➜ apt-get install vim
E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?
➜ oops
sudo apt-get install vim [enter/↑/↓/ctrl+c]
[sudo] password for nvbn:
Reading package lists... Done
...
➜ git push
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin master
➜ oops
git push --set-upstream origin master [enter/↑/↓/ctrl+c]
Counting objects: 9, done.
...
➜ puthon
No command 'puthon' found, did you mean:
Command 'python' from package 'python-minimal' (main)
Command 'python' from package 'python3' (main)
zsh: command not found: puthon
➜ oops
python [enter/↑/↓/ctrl+c]
Python 3.4.2 (default, Oct 8 2014, 13:08:17)
...
➜ git brnch
git: 'brnch' is not a git command. See 'git --help'.
Did you mean this?
branch
➜ oops
git branch [enter/↑/↓/ctrl+c]
* master
➜ lein rpl
'rpl' is not a task. See 'lein help'.
Did you mean this?
repl
➜ oops
lein repl [enter/↑/↓/ctrl+c]
nREPL server started on port 54848 on host 127.0.0.1 - nrepl://127.0.0.1:54848
REPL-y 0.3.1
...
If you're not afraid of blindly running corrected commands, the
require_confirmation settings option can be disabled:
➜ apt-get install vim
E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?
➜ oops
sudo apt-get install vim
[sudo] password for nvbn:
Reading package lists... Done
...
Contents
- Requirements
- Installation
- Coming from thefuck
- Updating
- How it works
- Creating your own rules
- Settings
- Third party packages with rules
- Experimental instant mode
- Developing
- License
Requirements
- Python 3.10+
- Linux, macOS or Windows; Bash, Zsh, Fish, PowerShell or tcsh
Back to Contents
Installation
Install oopsh with pipx or uv,
which keep it in its own environment (recent Linux distributions don't let
pip install into the system Python):
pipx install oopsh
# or
uv tool install oopsh
On macOS and Linux you can also use Homebrew:
brew install geomago/tap/oopsh
#
Then add this line to your .bashrc, .zshrc or other startup script:
eval "$(oopsh --alias)"
# You can use whatever you want as an alias:
eval "$(oopsh --alias argh)"
For other shells:
| Shell | Config file | Line to add |
|---|---|---|
| Fish | ~/.config/fish/config.fish |
oopsh --alias | source |
| PowerShell | $PROFILE |
iex "$(oopsh --alias)" |
| tcsh | ~/.tcshrc |
eval `oopsh --alias` |
Changes are only available in a new shell session. To make changes immediately
available, run source ~/.bashrc (or your shell config file like .zshrc).
If you just type oops before configuring anything, oopsh tells you which line
to add, and adds it for you if you run oops a second time.
The alias defines two shell functions: oops and oopsh, which do the same
thing. oopsh also stays the name of the program, so oopsh --version,
oopsh --help and oopsh --alias keep working. (In tcsh only oops is defined.)
To run fixed commands without confirmation, use the --yeah option (or just -y for short, or --hard if you're especially frustrated):
oops --yeah
To fix commands recursively until succeeding, use the -r option:
oops -r
Back to Contents
Coming from thefuck
oopsh is a drop-in replacement for thefuck:
- Until you have an oopsh config dir, oopsh uses your thefuck one
(
~/.config/thefuck/or~/.thefuck/) as it is, settings and custom rules included. - Custom rules and
thefuck_contrib_*packages that import from thefuck (from thefuck.utils import for_app) keep working unchanged. THEFUCK_*environment variables keep working; theOOPSH_*ones win if both are set.
To switch:
- In your shell config, replace
eval $(thefuck --alias)witheval "$(oopsh --alias)". You now typeoopsinstead offuck; to keep the old word, useeval "$(oopsh --alias fuck)". - Optionally, run
oopsh --migrate: it copies your thefuck config to~/.config/oopsh/(it never overwrites files) and tells you what else you may want to change. - Uninstall thefuck:
pip uninstall thefuck.
Back to Contents
Updating
pipx upgrade oopsh
# or
uv tool upgrade oopsh
# or
brew upgrade oopsh
Uninstall
To remove oopsh, reverse the installation process:
- erase or comment the
oopsh --aliasline from your Bash, Zsh, Fish, PowerShell, tcsh, ... shell config - uninstall the package:
pipx uninstall oopsh(oruv tool uninstall oopsh, orbrew uninstall oopsh)
How it works
oopsh attempts to match the previous command with a rule. If a match is found, a new command is created using the matched rule and executed. The following rules are enabled by default:
adb_unknown_command– fixes misspelled commands likeadb logcta;ag_literal– adds-Qtoagwhen suggested;aws_cli– fixes misspelled commands likeaws dynamdb scan;az_cli– fixes misspelled commands likeaz providers;cargo– runscargo buildinstead ofcargo;cargo_no_command– fixes wrong commands likecargo buid;cat_dir– replacescatwithlswhen you try tocata directory;cd_correction– spellchecks and corrects failed cd commands;cd_cs– changescstocd;cd_mkdir– creates directories before cd'ing into them;cd_parent– changescd..tocd ..;cd_quotes– quotes directories with spaces, likecd My Documents;chmod_x– adds execution bit;choco_install– appends common suffixes for chocolatey packages;composer_not_command– fixes composer command name;composer_not_package– fixes misspelled package names forcomposer require, using composer's suggestions;conda_mistype– fixes conda commands;cp_create_destination– creates a new directory when you attempt tocpormvto a non-existent onecp_omitting_directory– adds-awhen youcpdirectory;cpp11– adds missing-std=c++11tog++orclang++;dirty_untar– fixestar xcommand that untarred in the current directory;dirty_unzip– fixesunzipcommand that unzipped in the current directory;django_south_ghost– adds--delete-ghost-migrationsto failed because ghosts django south migration;django_south_merge– adds--mergeto inconsistent django south migration;docker_login– executes adocker loginand repeats the previous command;docker_not_command– fixes wrong docker commands likedocker tags;docker_image_being_used_by_container‐ removes the container that is using the image before removing the image;dry– fixes repetitions likegit git push;edit_filename– adds the missing extension when an editor is given a file that does not exist, likevim moduletovim module.py;fab_command_not_found– fixes misspelled fabric commands;fix_alt_space– replaces Alt+Space with Space character;fix_file– opens a file with an error in your$EDITOR;gcloud_cli– fixes misspelled commands likegcloud compute instance list;gem_unknown_command– fixes wronggemcommands;git_add– fixes "pathspec 'foo' did not match any file(s) known to git.";git_add_force– adds--forcetogit add <pathspec>...when paths are .gitignore'd;git_bisect_usage– fixesgit bisect strt,git bisect goood,git bisect rset, etc. when bisecting;git_branch_delete– changesgit branch -dtogit branch -D;git_branch_delete_checked_out– changesgit branch -dtogit checkout master && git branch -Dwhen trying to delete a checked out branch;git_branch_exists– offersgit branch -d foo,git branch -D fooorgit checkout foowhen creating a branch that already exists;git_branch_list– catchesgit branch listin place ofgit branchand removes created branch;git_branch_0flag– fixes commands such asgit branch 0vandgit branch 0rremoving the created branch;git_checkout– fixes branch name or creates new branch;git_clone_git_clone– replacesgit clone git clone ...withgit clone ...git_clone_missing– addsgit cloneto URLs that appear to link to a git repository.git_commit_add– offersgit commit -a ...orgit commit -p ...after previous commit if it failed because nothing was staged;git_commit_amend– offersgit commit --amendafter previous commit;git_commit_reset– offersgit reset HEAD~after previous commit;git_diff_no_index– adds--no-indexto previousgit diffon untracked files;git_diff_staged– adds--stagedto previousgit diffwith unexpected output;git_fix_stash– fixesgit stashcommands (misspelled subcommand and missingsave);git_flag_after_filename– fixesfatal: bad flag '...' after filenamegit_help_aliased– fixesgit help <alias>commands replacing with the aliased command;git_hook_bypass– adds--no-verifyflag previous togit am,git commit, orgit pushcommand;git_lfs_mistype– fixes mistypedgit lfs <command>commands;git_main_master– fixes incorrect branch name betweenmainandmastergit_merge– adds remote to branch names;git_merge_unrelated– adds--allow-unrelated-historieswhen requiredgit_not_command– fixes wrong git commands likegit brnch;git_pull– sets upstream before executing previousgit pull;git_pull_clone– clones instead of pulling when the repo does not exist;git_pull_uncommitted_changes– stashes changes before pulling and pops them afterwards;git_push– adds--set-upstream origin $branchto previous failedgit push;git_push_different_branch_names– fixes pushes when local branch name does not match remote branch name;git_push_pull– runsgit pullwhenpushwas rejected;git_push_without_commits– creates an initial commit if you forget and onlygit add ., when setting up a new project;git_rebase_no_changes– runsgit rebase --skipinstead ofgit rebase --continuewhen there are no changes;git_remote_delete– replacesgit remote delete remote_namewithgit remote remove remote_name;git_rm_local_modifications– adds-for--cachedwhen you try torma locally modified file;git_rm_recursive– adds-rwhen you try torma directory;git_rm_staged– adds-for--cachedwhen you try torma file with staged changesgit_rebase_merge_dir– offersgit rebase (--continue | --abort | --skip)or removing the.git/rebase-mergedir when a rebase is in progress;git_remote_seturl_add– runsgit remote addwhengit remote set_urlon nonexistent remote;git_safe_directory– trusts a repository owned by another user with thegit config --global --add safe.directorycommand git suggests;git_stash– stashes your local modifications before rebasing or switching branch;git_stash_pop– adds your local modifications before popping stash, then resets;git_tag_force– adds--forcetogit tag <tagname>when the tag already exists;git_two_dashes– adds a missing dash to commands likegit commit -amendorgit rebase -continue;go_run– appends.goextension when compiling/running Go programs;go_unknown_command– fixes wronggocommands, for examplego bulid;gradle_no_task– fixes not found or ambiguousgradletask;gradle_wrapper– replacesgradlewith./gradlew;grep_arguments_order– fixesgreparguments order for situations likegrep -lir . test;grep_recursive– adds-rwhen you try togrepdirectory;grunt_task_not_found– fixes misspelledgruntcommands;gulp_not_task– fixes misspelledgulptasks;has_exists_script– prepends./when script/binary exists;heroku_multiple_apps– adds--app <app>toherokucommands likeheroku pg;heroku_not_command– fixes wrongherokucommands likeheroku log;history– tries to replace command with the most similar command from history;hostscli– tries to fixhostscliusage;ifconfig_device_not_found– fixes wrong device names likewlan0towlp2s0;java– removes.javaextension when running Java programs;javac– appends missing.javawhen compiling Java files;kedro_no_such_command– fixes wrongkedrocommands likekedro ne;lein_not_task– fixes wrongleintasks likelein rpl;long_form_help– changes-hto--helpwhen the short form version is not supportedln_no_hard_link– catches hard link creation on directories, suggest symbolic link;ln_s_order– fixesln -sarguments order;ls_all– adds-Atolswhen output is empty;ls_lah– adds-lahtols;makefile– fixes wrongmakecommands;man– changes manual section;man_no_space– fixes man commands without spaces, for examplemandiff;mercurial– fixes wronghgcommands;missing_space_before_subcommand– fixes command with missing space likenpminstall;mkdir_p– adds-pwhen you try to create a directory without a parent;mvn_no_command– addsclean packagetomvn;mvn_unknown_lifecycle_phase– fixes misspelled life cycle phases withmvn;ninja– fixes wrong targets passed to theninjabuild tool;npm_missing_script– fixesnpmcustom script name innpm run-script <script>;npm_run_script– adds missingrun-scriptfor customnpmscripts;npm_wrong_command– fixes wrong npm commands likenpm urgrade;no_command– fixes wrong console commands, for examplevom/vim;no_such_file– creates missing directories withmvandcpcommands;omnienv_no_such_command– fixes wrong commands forgoenv,nodenv,pyenvandrbenv(eg.:pyenv isntallorgoenv list);open– either prependshttp://to address passed toopenor creates a new file or directory and passes it toopen;ping– removeshttp(s)://and paths when you ping a URL copied from the browser;pip_install– fixes permission issues withpip installcommands by adding--useror prependingsudoif necessary;pip_unknown_command– fixes wrongpipcommands, for examplepip instatl/pip install;php_s– replaces-sby-Swhen trying to run a local php server;port_already_in_use– kills process that bound port;prove_recursively– adds-rwhen called with directory;python_command– prependspythonwhen you try to run non-executable/without./python script;python_execute– appends missing.pywhen executing Python files;python_module_error– fixes ModuleNotFoundError by trying topip installthat module;quotation_marks– fixes uneven usage of'and"when containing args';path_from_history– replaces not found path with a similar absolute path from history;rails_migrations_pending– runs pending migrations;rbenv_install– fixes ruby-build definition not found by updating ruby-build;react_native_command_unrecognized– fixes unrecognizedreact-nativecommands;remove_shell_prompt_literal– removes leading shell prompt symbol$, common when copying commands from documentations;remove_trailing_cedilla– removes trailing cedillasç, a common typo for European keyboard layouts;restic_typo– fixes misspelledresticcommands, likerestic snapshot;rm_dir– adds-rfwhen you try to remove a directory;scm_correction– corrects wrong scm likehg logtogit log;sed_unterminated_s– adds missing '/' tosed'sscommands;sl_ls– changessltols;ssh_known_hosts– removes host fromknown_hostson warning;su– runs the command withsu -cwhensudois not installed;sudo– prependssudoto the previous command if it failed because of permissions;sudo_command_from_user_path– runs commands from users$PATHwithsudo;switch_lang– switches command from your local layout to en;systemctl– correctly orders parameters of confusingsystemctl;terraform_init.py– runsterraform initbefore plan or apply;terraform_init_upgrade– runsterraform init -upgradewhen the dependency lock file is out of date, then the command again;terraform_no_command.py– fixes unrecognizedterraformcommands;test.py– runspytestinstead oftest.py;touch– creates missing directories before "touching";tsuru_login– runstsuru loginif not authenticated or session expired;tsuru_not_command– fixes wrongtsurucommands liketsuru shell;tmux– fixestmuxcommands;unknown_command– fixes hadoop hdfs-style "unknown command", for example adds missing '-' to the command onhdfs dfs ls;unsudo– removessudofrom previous command if a process refuses to run on superuser privilege.upper_to_lower_case– replaces the uppercase letters with lowercase, so the command is correct;vagrant_up– starts up the vagrant instance;whois– fixeswhoiscommand;workon_doesnt_exists– fixesvirtualenvwrapperenv name os suggests to create new.wrong_hyphen_before_subcommand– removes an improperly placed hyphen (apt-install->apt install,git-log->git log, etc.)yarn_alias– fixes aliasedyarncommands likeyarn ls;yarn_command_not_found– fixes misspelledyarncommands;yarn_command_replaced– fixes replacedyarncommands;yarn_help– makes it easier to openyarndocumentation;
Back to Contents
The following rules are enabled by default on specific platforms only:
apt_get– installs app from apt if it not installed (requirespython-commandnotfound/python3-commandnotfound);apt_get_search– changes trying to search usingapt-getwith searching usingapt-cache;apt_invalid_operation– fixes invalidaptandapt-getcalls, likeapt-get isntall vim;apt_list_upgradable– helps you runapt list --upgradableafterapt update;apt_unable_to_locate– suggests packages with a similar name whenaptorapt-getcannot find a package;apt_upgrade– helps you runapt upgradeafterapt list --upgradable;brew_cask_dependency– installs cask dependencies;brew_install– fixes formula name forbrew install;brew_reinstall– turnsbrew install <formula>intobrew reinstall <formula>;brew_link– adds--overwrite --dry-runif linking fails;brew_uninstall– adds--forcetobrew uninstallif multiple versions were installed;brew_unknown_command– fixes wrong brew commands, for examplebrew docto/brew doctor;brew_update_formula– turnsbrew update <formula>intobrew upgrade <formula>;dnf_no_such_command– fixes mistyped DNF commands;docker_daemon_not_running– starts the Docker daemon withsystemctland runs the command again;nix_shell– runs a missing command in anix-shellwith the package that provides it;nixos_cmd_not_found– installs apps on NixOS;pacman– installs app withpacmanif it is not installed (usesyay,pikaur,yaourtorparuif available);pacman_invalid_option– replaces lowercasepacmanoptions with uppercase.pacman_not_found– fixes package name withpacman,yay,pikaur,yaourtorparu.xcode_license– accepts the Xcode license withsudo xcodebuild -licenseand runs the command again;yum_invalid_operation– fixes invalidyumcalls, likeyum isntall vim;
The following commands are bundled with oopsh, but are not enabled by default:
git_push_force– adds--force-with-leaseto agit push(may conflict withgit_push_pull);rm_root– adds--no-preserve-roottorm -rf /command.
Back to Contents
Creating your own rules
To add your own rule, create a file named your-rule-name.py
in ~/.config/oopsh/rules. The rule file must contain two functions:
match(command: Command) -> bool
get_new_command(command: Command) -> str | list[str]
Additionally, rules can contain optional functions:
side_effect(old_command: Command, fixed_command: str) -> None
Rules can also contain the optional variables enabled_by_default, requires_output and priority.
Command has three attributes: script, output and script_parts.
Your rule should not change Command.
Rules api changed in 3.0: To access a rule's settings, import it with
from oopsh.conf import settings
settings is a special object assembled from ~/.config/oopsh/settings.py,
and values from env (see more below).
A simple example rule for running a script with sudo:
def match(command):
return ('permission denied' in command.output.lower()
or 'EACCES' in command.output)
def get_new_command(command):
return 'sudo {}'.format(command.script)
# Optional:
enabled_by_default = True
def side_effect(command, fixed_command):
subprocess.call('chmod 777 .', shell=True)
priority = 1000 # Lower first, default is 1000
requires_output = True
More examples of rules, utility functions for rules, app/os-specific helpers.
Back to Contents
Settings
Several oopsh parameters can be changed in the file $XDG_CONFIG_HOME/oopsh/settings.py
($XDG_CONFIG_HOME defaults to ~/.config):
rules– list of enabled rules, by defaultoopsh.const.DEFAULT_RULES;exclude_rules– list of disabled rules, by default[];require_confirmation– requires confirmation before running new command, by defaultTrue;wait_command– the max amount of time in seconds for getting previous command output;no_colors– disable colored output;priority– dict with rules priorities, rule with lowerprioritywill be matched first;debug– enables debug output, by defaultFalse;history_limit– the numeric value of how many history commands will be scanned, like2000;alter_history– push fixed command to history, by defaultTrue;wait_slow_command– max amount of time in seconds for getting previous command output if it inslow_commandslist;slow_commands– list of slow commands;num_close_matches– the maximum number of close matches to suggest, by default3.excluded_search_path_prefixes– path prefixes to ignore when searching for commands, by default[]. On Windows Subsystem for Linux (WSL), adding['/mnt/']or['/mnt/c/']avoids searching Windows paths, which can make oopsh much slower.
An example of settings.py:
rules = ['sudo', 'no_command']
exclude_rules = ['git_push']
require_confirmation = True
wait_command = 10
no_colors = False
priority = {'sudo': 100, 'no_command': 9999}
debug = False
history_limit = 9999
wait_slow_command = 20
slow_commands = ['react-native', 'gradle']
num_close_matches = 5
Or via environment variables:
OOPSH_RULES– list of enabled rules, likeDEFAULT_RULES:rm_rootorsudo:no_command;OOPSH_EXCLUDE_RULES– list of disabled rules, likegit_pull:git_push;OOPSH_REQUIRE_CONFIRMATION– require confirmation before running new command,true/false;OOPSH_WAIT_COMMAND– the max amount of time in seconds for getting previous command output;OOPSH_NO_COLORS– disable colored output,true/false;OOPSH_PRIORITY– priority of the rules, likeno_command=9999:apt_get=100, rule with lowerprioritywill be matched first;OOPSH_DEBUG– enables debug output,true/false;OOPSH_HISTORY_LIMIT– how many history commands will be scanned, like2000;OOPSH_ALTER_HISTORY– push fixed command to historytrue/false;OOPSH_WAIT_SLOW_COMMAND– the max amount of time in seconds for getting previous command output if it inslow_commandslist;OOPSH_SLOW_COMMANDS– list of slow commands, likelein:gradle;OOPSH_NUM_CLOSE_MATCHES– the maximum number of close matches to suggest, like5.OOPSH_EXCLUDED_SEARCH_PATH_PREFIXES– path prefixes to ignore when searching for commands, by default[].
For example:
export OOPSH_RULES='sudo:no_command'
export OOPSH_EXCLUDE_RULES='git_pull:git_push'
export OOPSH_REQUIRE_CONFIRMATION='true'
export OOPSH_WAIT_COMMAND=10
export OOPSH_NO_COLORS='false'
export OOPSH_PRIORITY='no_command=9999:apt_get=100'
export OOPSH_HISTORY_LIMIT='2000'
export OOPSH_NUM_CLOSE_MATCHES='5'
Back to Contents
Third-party packages with rules
If you'd like to make a specific set of non-public rules, but would still like
to share them with others, create a package named oopsh_contrib_* with
the following structure (packages named thefuck_contrib_* work too):
oopsh_contrib_foo
oopsh_contrib_foo
rules
__init__.py
*third-party rules*
__init__.py
*third-party-utils*
pyproject.toml
oopsh will find rules located in the rules module.
Back to Contents
Experimental instant mode
The default behavior of oopsh requires time to re-run previous commands. When in instant mode, oopsh saves time by logging output with script, then reading the log.
Currently, instant mode only supports bash or zsh. zsh's autocorrect function also needs to be disabled in order for oopsh to work properly.
To enable instant mode, add --enable-experimental-instant-mode
to the alias initialization in .bashrc, .bash_profile or .zshrc.
For example:
eval "$(oopsh --alias --enable-experimental-instant-mode)"
Back to Contents
Developing
See CONTRIBUTING.md
License MIT
Project License can be found here.
oopsh is based on thefuck by Vladimir Iakovlev and its many contributors, originally inspired by a @liamosaur tweet.
Back to Contents
Metadata
Release files for oopsh 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| oopsh-1.0.1.tar.gz | 189.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| oopsh-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 338.3 kB
Release files / oopsh-1.0.1.tar.gz
| Download URL | oopsh-1.0.1.tar.gz |
|---|---|
| Size | 189.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b17e19725d1b57544e3faa0649e25b2220c11fa2eb50a1def422f8222ac668b0
|
|
BLAKE2b-256 checksum How to use checksums |
8e2c05b8cc3cc9d633ca55808d98444361b83d6cef1349fb725d06546bfbfe7f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.
Transparency logRelease files / oopsh-1.0.1-py3-none-any.whl
| Download URL | oopsh-1.0.1-py3-none-any.whl |
|---|---|
| Size | 149.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7f0a8f461d3fcb3e9b428aaa86e90dd1c6763e609da1f474998d25301b38227c
|
|
BLAKE2b-256 checksum How to use checksums |
8224ae5339ad819fff39a031d8a264b315b8a4f1d806dded857e816b98b154ff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.
Transparency log