Add Code
This commit is contained in:
2
code/.venv/.gitignore
vendored
Normal file
2
code/.venv/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# created by virtualenv automatically
|
||||
*
|
||||
BIN
code/.venv/bin/__pycache__/bin2hex.cpython-312.pyc
Normal file
BIN
code/.venv/bin/__pycache__/bin2hex.cpython-312.pyc
Normal file
Binary file not shown.
BIN
code/.venv/bin/__pycache__/esp_rfc2217_server.cpython-312.pyc
Normal file
BIN
code/.venv/bin/__pycache__/esp_rfc2217_server.cpython-312.pyc
Normal file
Binary file not shown.
BIN
code/.venv/bin/__pycache__/espefuse.cpython-312.pyc
Normal file
BIN
code/.venv/bin/__pycache__/espefuse.cpython-312.pyc
Normal file
Binary file not shown.
BIN
code/.venv/bin/__pycache__/espsecure.cpython-312.pyc
Normal file
BIN
code/.venv/bin/__pycache__/espsecure.cpython-312.pyc
Normal file
Binary file not shown.
BIN
code/.venv/bin/__pycache__/esptool.cpython-312.pyc
Normal file
BIN
code/.venv/bin/__pycache__/esptool.cpython-312.pyc
Normal file
Binary file not shown.
BIN
code/.venv/bin/__pycache__/hex2bin.cpython-312.pyc
Normal file
BIN
code/.venv/bin/__pycache__/hex2bin.cpython-312.pyc
Normal file
Binary file not shown.
BIN
code/.venv/bin/__pycache__/hex2dump.cpython-312.pyc
Normal file
BIN
code/.venv/bin/__pycache__/hex2dump.cpython-312.pyc
Normal file
Binary file not shown.
BIN
code/.venv/bin/__pycache__/hexdiff.cpython-312.pyc
Normal file
BIN
code/.venv/bin/__pycache__/hexdiff.cpython-312.pyc
Normal file
Binary file not shown.
BIN
code/.venv/bin/__pycache__/hexinfo.cpython-312.pyc
Normal file
BIN
code/.venv/bin/__pycache__/hexinfo.cpython-312.pyc
Normal file
Binary file not shown.
BIN
code/.venv/bin/__pycache__/hexmerge.cpython-312.pyc
Normal file
BIN
code/.venv/bin/__pycache__/hexmerge.cpython-312.pyc
Normal file
Binary file not shown.
87
code/.venv/bin/activate
Normal file
87
code/.venv/bin/activate
Normal file
@@ -0,0 +1,87 @@
|
||||
# This file must be used with "source bin/activate" *from bash*
|
||||
# you cannot run it directly
|
||||
|
||||
|
||||
if [ "${BASH_SOURCE-}" = "$0" ]; then
|
||||
echo "You must source this script: \$ source $0" >&2
|
||||
exit 33
|
||||
fi
|
||||
|
||||
deactivate () {
|
||||
unset -f pydoc >/dev/null 2>&1 || true
|
||||
|
||||
# reset old environment variables
|
||||
# ! [ -z ${VAR+_} ] returns true if VAR is declared at all
|
||||
if ! [ -z "${_OLD_VIRTUAL_PATH:+_}" ] ; then
|
||||
PATH="$_OLD_VIRTUAL_PATH"
|
||||
export PATH
|
||||
unset _OLD_VIRTUAL_PATH
|
||||
fi
|
||||
if ! [ -z "${_OLD_VIRTUAL_PYTHONHOME+_}" ] ; then
|
||||
PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME"
|
||||
export PYTHONHOME
|
||||
unset _OLD_VIRTUAL_PYTHONHOME
|
||||
fi
|
||||
|
||||
# The hash command must be called to get it to forget past
|
||||
# commands. Without forgetting past commands the $PATH changes
|
||||
# we made may not be respected
|
||||
hash -r 2>/dev/null
|
||||
|
||||
if ! [ -z "${_OLD_VIRTUAL_PS1+_}" ] ; then
|
||||
PS1="$_OLD_VIRTUAL_PS1"
|
||||
export PS1
|
||||
unset _OLD_VIRTUAL_PS1
|
||||
fi
|
||||
|
||||
unset VIRTUAL_ENV
|
||||
unset VIRTUAL_ENV_PROMPT
|
||||
if [ ! "${1-}" = "nondestructive" ] ; then
|
||||
# Self destruct!
|
||||
unset -f deactivate
|
||||
fi
|
||||
}
|
||||
|
||||
# unset irrelevant variables
|
||||
deactivate nondestructive
|
||||
|
||||
VIRTUAL_ENV='/home/rhetenor/Projects/esp/python/.venv'
|
||||
if ([ "$OSTYPE" = "cygwin" ] || [ "$OSTYPE" = "msys" ]) && $(command -v cygpath &> /dev/null) ; then
|
||||
VIRTUAL_ENV=$(cygpath -u "$VIRTUAL_ENV")
|
||||
fi
|
||||
export VIRTUAL_ENV
|
||||
|
||||
_OLD_VIRTUAL_PATH="$PATH"
|
||||
PATH="$VIRTUAL_ENV/bin:$PATH"
|
||||
export PATH
|
||||
|
||||
if [ "x" != x ] ; then
|
||||
VIRTUAL_ENV_PROMPT=""
|
||||
else
|
||||
VIRTUAL_ENV_PROMPT=$(basename "$VIRTUAL_ENV")
|
||||
fi
|
||||
export VIRTUAL_ENV_PROMPT
|
||||
|
||||
# unset PYTHONHOME if set
|
||||
if ! [ -z "${PYTHONHOME+_}" ] ; then
|
||||
_OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME"
|
||||
unset PYTHONHOME
|
||||
fi
|
||||
|
||||
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT-}" ] ; then
|
||||
_OLD_VIRTUAL_PS1="${PS1-}"
|
||||
PS1="(${VIRTUAL_ENV_PROMPT}) ${PS1-}"
|
||||
export PS1
|
||||
fi
|
||||
|
||||
# Make sure to unalias pydoc if it's already there
|
||||
alias pydoc 2>/dev/null >/dev/null && unalias pydoc || true
|
||||
|
||||
pydoc () {
|
||||
python -m pydoc "$@"
|
||||
}
|
||||
|
||||
# The hash command must be called to get it to forget past
|
||||
# commands. Without forgetting past commands the $PATH changes
|
||||
# we made may not be respected
|
||||
hash -r 2>/dev/null || true
|
||||
55
code/.venv/bin/activate.csh
Normal file
55
code/.venv/bin/activate.csh
Normal file
@@ -0,0 +1,55 @@
|
||||
# This file must be used with "source bin/activate.csh" *from csh*.
|
||||
# You cannot run it directly.
|
||||
# Created by Davide Di Blasi <davidedb@gmail.com>.
|
||||
|
||||
set newline='\
|
||||
'
|
||||
|
||||
alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH:q" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT:q" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate && unalias pydoc'
|
||||
|
||||
# Unset irrelevant variables.
|
||||
deactivate nondestructive
|
||||
|
||||
setenv VIRTUAL_ENV '/home/rhetenor/Projects/esp/python/.venv'
|
||||
|
||||
set _OLD_VIRTUAL_PATH="$PATH:q"
|
||||
setenv PATH "$VIRTUAL_ENV:q/bin:$PATH:q"
|
||||
|
||||
|
||||
|
||||
if ('' != "") then
|
||||
setenv VIRTUAL_ENV_PROMPT ''
|
||||
else
|
||||
setenv VIRTUAL_ENV_PROMPT "$VIRTUAL_ENV:t:q"
|
||||
endif
|
||||
|
||||
if ( $?VIRTUAL_ENV_DISABLE_PROMPT ) then
|
||||
if ( $VIRTUAL_ENV_DISABLE_PROMPT == "" ) then
|
||||
set do_prompt = "1"
|
||||
else
|
||||
set do_prompt = "0"
|
||||
endif
|
||||
else
|
||||
set do_prompt = "1"
|
||||
endif
|
||||
|
||||
if ( $do_prompt == "1" ) then
|
||||
# Could be in a non-interactive environment,
|
||||
# in which case, $prompt is undefined and we wouldn't
|
||||
# care about the prompt anyway.
|
||||
if ( $?prompt ) then
|
||||
set _OLD_VIRTUAL_PROMPT="$prompt:q"
|
||||
if ( "$prompt:q" =~ *"$newline:q"* ) then
|
||||
:
|
||||
else
|
||||
set prompt = '('"$VIRTUAL_ENV_PROMPT:q"') '"$prompt:q"
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
unset env_name
|
||||
unset do_prompt
|
||||
|
||||
alias pydoc python -m pydoc
|
||||
|
||||
rehash
|
||||
103
code/.venv/bin/activate.fish
Normal file
103
code/.venv/bin/activate.fish
Normal file
@@ -0,0 +1,103 @@
|
||||
# This file must be used using `source bin/activate.fish` *within a running fish ( http://fishshell.com ) session*.
|
||||
# Do not run it directly.
|
||||
|
||||
function _bashify_path -d "Converts a fish path to something bash can recognize"
|
||||
set fishy_path $argv
|
||||
set bashy_path $fishy_path[1]
|
||||
for path_part in $fishy_path[2..-1]
|
||||
set bashy_path "$bashy_path:$path_part"
|
||||
end
|
||||
echo $bashy_path
|
||||
end
|
||||
|
||||
function _fishify_path -d "Converts a bash path to something fish can recognize"
|
||||
echo $argv | tr ':' '\n'
|
||||
end
|
||||
|
||||
function deactivate -d 'Exit virtualenv mode and return to the normal environment.'
|
||||
# reset old environment variables
|
||||
if test -n "$_OLD_VIRTUAL_PATH"
|
||||
# https://github.com/fish-shell/fish-shell/issues/436 altered PATH handling
|
||||
if test (echo $FISH_VERSION | head -c 1) -lt 3
|
||||
set -gx PATH (_fishify_path "$_OLD_VIRTUAL_PATH")
|
||||
else
|
||||
set -gx PATH $_OLD_VIRTUAL_PATH
|
||||
end
|
||||
set -e _OLD_VIRTUAL_PATH
|
||||
end
|
||||
|
||||
if test -n "$_OLD_VIRTUAL_PYTHONHOME"
|
||||
set -gx PYTHONHOME "$_OLD_VIRTUAL_PYTHONHOME"
|
||||
set -e _OLD_VIRTUAL_PYTHONHOME
|
||||
end
|
||||
|
||||
if test -n "$_OLD_FISH_PROMPT_OVERRIDE"
|
||||
and functions -q _old_fish_prompt
|
||||
# Set an empty local `$fish_function_path` to allow the removal of `fish_prompt` using `functions -e`.
|
||||
set -l fish_function_path
|
||||
|
||||
# Erase virtualenv's `fish_prompt` and restore the original.
|
||||
functions -e fish_prompt
|
||||
functions -c _old_fish_prompt fish_prompt
|
||||
functions -e _old_fish_prompt
|
||||
set -e _OLD_FISH_PROMPT_OVERRIDE
|
||||
end
|
||||
|
||||
set -e VIRTUAL_ENV
|
||||
set -e VIRTUAL_ENV_PROMPT
|
||||
|
||||
if test "$argv[1]" != 'nondestructive'
|
||||
# Self-destruct!
|
||||
functions -e pydoc
|
||||
functions -e deactivate
|
||||
functions -e _bashify_path
|
||||
functions -e _fishify_path
|
||||
end
|
||||
end
|
||||
|
||||
# Unset irrelevant variables.
|
||||
deactivate nondestructive
|
||||
|
||||
set -gx VIRTUAL_ENV '/home/rhetenor/Projects/esp/python/.venv'
|
||||
|
||||
# https://github.com/fish-shell/fish-shell/issues/436 altered PATH handling
|
||||
if test (echo $FISH_VERSION | head -c 1) -lt 3
|
||||
set -gx _OLD_VIRTUAL_PATH (_bashify_path $PATH)
|
||||
else
|
||||
set -gx _OLD_VIRTUAL_PATH $PATH
|
||||
end
|
||||
set -gx PATH "$VIRTUAL_ENV"'/bin' $PATH
|
||||
|
||||
# Prompt override provided?
|
||||
# If not, just use the environment name.
|
||||
if test -n ''
|
||||
set -gx VIRTUAL_ENV_PROMPT ''
|
||||
else
|
||||
set -gx VIRTUAL_ENV_PROMPT (basename "$VIRTUAL_ENV")
|
||||
end
|
||||
|
||||
# Unset `$PYTHONHOME` if set.
|
||||
if set -q PYTHONHOME
|
||||
set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME
|
||||
set -e PYTHONHOME
|
||||
end
|
||||
|
||||
function pydoc
|
||||
python -m pydoc $argv
|
||||
end
|
||||
|
||||
if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
|
||||
# Copy the current `fish_prompt` function as `_old_fish_prompt`.
|
||||
functions -c fish_prompt _old_fish_prompt
|
||||
|
||||
function fish_prompt
|
||||
# Run the user's prompt first; it might depend on (pipe)status.
|
||||
set -l prompt (_old_fish_prompt)
|
||||
|
||||
printf '(%s) ' $VIRTUAL_ENV_PROMPT
|
||||
|
||||
string join -- \n $prompt # handle multi-line prompts
|
||||
end
|
||||
|
||||
set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV"
|
||||
end
|
||||
96
code/.venv/bin/activate.nu
Normal file
96
code/.venv/bin/activate.nu
Normal file
@@ -0,0 +1,96 @@
|
||||
# virtualenv activation module
|
||||
# Activate with `overlay use activate.nu`
|
||||
# Deactivate with `deactivate`, as usual
|
||||
#
|
||||
# To customize the overlay name, you can call `overlay use activate.nu as foo`,
|
||||
# but then simply `deactivate` won't work because it is just an alias to hide
|
||||
# the "activate" overlay. You'd need to call `overlay hide foo` manually.
|
||||
|
||||
export-env {
|
||||
def is-string [x] {
|
||||
($x | describe) == 'string'
|
||||
}
|
||||
|
||||
def has-env [...names] {
|
||||
$names | each {|n|
|
||||
$n in $env
|
||||
} | all {|i| $i == true}
|
||||
}
|
||||
|
||||
# Emulates a `test -z`, but btter as it handles e.g 'false'
|
||||
def is-env-true [name: string] {
|
||||
if (has-env $name) {
|
||||
# Try to parse 'true', '0', '1', and fail if not convertible
|
||||
let parsed = (do -i { $env | get $name | into bool })
|
||||
if ($parsed | describe) == 'bool' {
|
||||
$parsed
|
||||
} else {
|
||||
not ($env | get -i $name | is-empty)
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
let virtual_env = '/home/rhetenor/Projects/esp/python/.venv'
|
||||
let bin = 'bin'
|
||||
|
||||
let is_windows = ($nu.os-info.family) == 'windows'
|
||||
let path_name = (if (has-env 'Path') {
|
||||
'Path'
|
||||
} else {
|
||||
'PATH'
|
||||
}
|
||||
)
|
||||
|
||||
let venv_path = ([$virtual_env $bin] | path join)
|
||||
let new_path = ($env | get $path_name | prepend $venv_path)
|
||||
|
||||
# If there is no default prompt, then use the env name instead
|
||||
let virtual_env_prompt = (if ('' | is-empty) {
|
||||
($virtual_env | path basename)
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let new_env = {
|
||||
$path_name : $new_path
|
||||
VIRTUAL_ENV : $virtual_env
|
||||
VIRTUAL_ENV_PROMPT : $virtual_env_prompt
|
||||
}
|
||||
|
||||
let new_env = (if (is-env-true 'VIRTUAL_ENV_DISABLE_PROMPT') {
|
||||
$new_env
|
||||
} else {
|
||||
# Creating the new prompt for the session
|
||||
let virtual_prefix = $'(char lparen)($virtual_env_prompt)(char rparen) '
|
||||
|
||||
# Back up the old prompt builder
|
||||
let old_prompt_command = (if (has-env 'PROMPT_COMMAND') {
|
||||
$env.PROMPT_COMMAND
|
||||
} else {
|
||||
''
|
||||
})
|
||||
|
||||
let new_prompt = (if (has-env 'PROMPT_COMMAND') {
|
||||
if 'closure' in ($old_prompt_command | describe) {
|
||||
{|| $'($virtual_prefix)(do $old_prompt_command)' }
|
||||
} else {
|
||||
{|| $'($virtual_prefix)($old_prompt_command)' }
|
||||
}
|
||||
} else {
|
||||
{|| $'($virtual_prefix)' }
|
||||
})
|
||||
|
||||
$new_env | merge {
|
||||
PROMPT_COMMAND : $new_prompt
|
||||
VIRTUAL_PREFIX : $virtual_prefix
|
||||
}
|
||||
})
|
||||
|
||||
# Environment variables that will be loaded as the virtual env
|
||||
load-env $new_env
|
||||
}
|
||||
|
||||
export alias pydoc = python -m pydoc
|
||||
export alias deactivate = overlay hide activate
|
||||
61
code/.venv/bin/activate.ps1
Normal file
61
code/.venv/bin/activate.ps1
Normal file
@@ -0,0 +1,61 @@
|
||||
$script:THIS_PATH = $myinvocation.mycommand.path
|
||||
$script:BASE_DIR = Split-Path (Resolve-Path "$THIS_PATH/..") -Parent
|
||||
|
||||
function global:deactivate([switch] $NonDestructive) {
|
||||
if (Test-Path variable:_OLD_VIRTUAL_PATH) {
|
||||
$env:PATH = $variable:_OLD_VIRTUAL_PATH
|
||||
Remove-Variable "_OLD_VIRTUAL_PATH" -Scope global
|
||||
}
|
||||
|
||||
if (Test-Path function:_old_virtual_prompt) {
|
||||
$function:prompt = $function:_old_virtual_prompt
|
||||
Remove-Item function:\_old_virtual_prompt
|
||||
}
|
||||
|
||||
if ($env:VIRTUAL_ENV) {
|
||||
Remove-Item env:VIRTUAL_ENV -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
if ($env:VIRTUAL_ENV_PROMPT) {
|
||||
Remove-Item env:VIRTUAL_ENV_PROMPT -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
if (!$NonDestructive) {
|
||||
# Self destruct!
|
||||
Remove-Item function:deactivate
|
||||
Remove-Item function:pydoc
|
||||
}
|
||||
}
|
||||
|
||||
function global:pydoc {
|
||||
python -m pydoc $args
|
||||
}
|
||||
|
||||
# unset irrelevant variables
|
||||
deactivate -nondestructive
|
||||
|
||||
$VIRTUAL_ENV = $BASE_DIR
|
||||
$env:VIRTUAL_ENV = $VIRTUAL_ENV
|
||||
|
||||
if ("" -ne "") {
|
||||
$env:VIRTUAL_ENV_PROMPT = ""
|
||||
}
|
||||
else {
|
||||
$env:VIRTUAL_ENV_PROMPT = $( Split-Path $env:VIRTUAL_ENV -Leaf )
|
||||
}
|
||||
|
||||
New-Variable -Scope global -Name _OLD_VIRTUAL_PATH -Value $env:PATH
|
||||
|
||||
$env:PATH = "$env:VIRTUAL_ENV/bin:" + $env:PATH
|
||||
if (!$env:VIRTUAL_ENV_DISABLE_PROMPT) {
|
||||
function global:_old_virtual_prompt {
|
||||
""
|
||||
}
|
||||
$function:_old_virtual_prompt = $function:prompt
|
||||
|
||||
function global:prompt {
|
||||
# Add the custom prefix to the existing prompt
|
||||
$previous_prompt_value = & $function:_old_virtual_prompt
|
||||
("(" + $env:VIRTUAL_ENV_PROMPT + ") " + $previous_prompt_value)
|
||||
}
|
||||
}
|
||||
38
code/.venv/bin/activate_this.py
Normal file
38
code/.venv/bin/activate_this.py
Normal file
@@ -0,0 +1,38 @@
|
||||
"""
|
||||
Activate virtualenv for current interpreter:
|
||||
|
||||
import runpy
|
||||
runpy.run_path(this_file)
|
||||
|
||||
This can be used when you must use an existing Python interpreter, not the virtualenv bin/python.
|
||||
""" # noqa: D415
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import site
|
||||
import sys
|
||||
|
||||
try:
|
||||
abs_file = os.path.abspath(__file__)
|
||||
except NameError as exc:
|
||||
msg = "You must use import runpy; runpy.run_path(this_file)"
|
||||
raise AssertionError(msg) from exc
|
||||
|
||||
bin_dir = os.path.dirname(abs_file)
|
||||
base = bin_dir[: -len("bin") - 1] # strip away the bin part from the __file__, plus the path separator
|
||||
|
||||
# prepend bin to PATH (this file is inside the bin directory)
|
||||
os.environ["PATH"] = os.pathsep.join([bin_dir, *os.environ.get("PATH", "").split(os.pathsep)])
|
||||
os.environ["VIRTUAL_ENV"] = base # virtual env is right above bin directory
|
||||
os.environ["VIRTUAL_ENV_PROMPT"] = "" or os.path.basename(base) # noqa: SIM222
|
||||
|
||||
# add the virtual environments libraries to the host python import mechanism
|
||||
prev_length = len(sys.path)
|
||||
for lib in "../lib/python3.12/site-packages".split(os.pathsep):
|
||||
path = os.path.realpath(os.path.join(bin_dir, lib))
|
||||
site.addsitedir(path.decode("utf-8") if "" else path)
|
||||
sys.path[:] = sys.path[prev_length:] + sys.path[0:prev_length]
|
||||
|
||||
sys.real_prefix = sys.prefix
|
||||
sys.prefix = base
|
||||
115
code/.venv/bin/bin2hex.py
Executable file
115
code/.venv/bin/bin2hex.py
Executable file
@@ -0,0 +1,115 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
|
||||
# Copyright (c) 2008-2018 Alexander Belchenko
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author nor the names
|
||||
# of its contributors may be used to endorse
|
||||
# or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''Intel HEX file format bin2hex convertor utility.'''
|
||||
|
||||
VERSION = '2.3.0'
|
||||
|
||||
if __name__ == '__main__':
|
||||
import getopt
|
||||
import os
|
||||
import sys
|
||||
|
||||
usage = '''Bin2Hex convertor utility.
|
||||
Usage:
|
||||
python bin2hex.py [options] INFILE [OUTFILE]
|
||||
|
||||
Arguments:
|
||||
INFILE name of bin file for processing.
|
||||
Use '-' for reading from stdin.
|
||||
|
||||
OUTFILE name of output file. If omitted then output
|
||||
will be writing to stdout.
|
||||
|
||||
Options:
|
||||
-h, --help this help message.
|
||||
-v, --version version info.
|
||||
--offset=N offset for loading bin file (default: 0).
|
||||
'''
|
||||
|
||||
offset = 0
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "hv",
|
||||
["help", "version", "offset="])
|
||||
|
||||
for o, a in opts:
|
||||
if o in ("-h", "--help"):
|
||||
print(usage)
|
||||
sys.exit(0)
|
||||
elif o in ("-v", "--version"):
|
||||
print(VERSION)
|
||||
sys.exit(0)
|
||||
elif o in ("--offset"):
|
||||
base = 10
|
||||
if a[:2].lower() == '0x':
|
||||
base = 16
|
||||
try:
|
||||
offset = int(a, base)
|
||||
except:
|
||||
raise getopt.GetoptError('Bad offset value')
|
||||
|
||||
if not args:
|
||||
raise getopt.GetoptError('Input file is not specified')
|
||||
|
||||
if len(args) > 2:
|
||||
raise getopt.GetoptError('Too many arguments')
|
||||
|
||||
except getopt.GetoptError:
|
||||
msg = sys.exc_info()[1] # current exception
|
||||
txt = 'ERROR: '+str(msg) # that's required to get not-so-dumb result from 2to3 tool
|
||||
print(txt)
|
||||
print(usage)
|
||||
sys.exit(2)
|
||||
|
||||
from intelhex import compat
|
||||
|
||||
fin = args[0]
|
||||
if fin == '-':
|
||||
# read from stdin
|
||||
fin = compat.get_binary_stdin()
|
||||
elif not os.path.isfile(fin):
|
||||
txt = "ERROR: File not found: %s" % fin # that's required to get not-so-dumb result from 2to3 tool
|
||||
print(txt)
|
||||
sys.exit(1)
|
||||
|
||||
if len(args) == 2:
|
||||
fout = args[1]
|
||||
else:
|
||||
# write to stdout
|
||||
fout = sys.stdout # compat.get_binary_stdout()
|
||||
|
||||
from intelhex import bin2hex
|
||||
sys.exit(bin2hex(fin, fout, offset))
|
||||
311
code/.venv/bin/esp_rfc2217_server.py
Executable file
311
code/.venv/bin/esp_rfc2217_server.py
Executable file
@@ -0,0 +1,311 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
|
||||
# SPDX-FileCopyrightText: 2009-2015 Chris Liechti
|
||||
# SPDX-FileContributor: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
# Redirect data from a TCP/IP connection to a serial port and vice versa using RFC 2217.
|
||||
#
|
||||
# This is a modified version of rfc2217_server.py provided by the pyserial package
|
||||
# (pythonhosted.org/pyserial/examples.html#single-port-tcp-ip-serial-bridge-rfc-2217).
|
||||
# It uses a custom PortManager to properly apply the RTS & DTR signals
|
||||
# for reseting ESP chips.
|
||||
#
|
||||
# Run the following command on the server side to make
|
||||
# connection between /dev/ttyUSB1 and TCP port 4000:
|
||||
#
|
||||
# python esp_rfc2217_server.py -p 4000 /dev/ttyUSB1
|
||||
#
|
||||
# Esptool can connect to the ESP device through that server as it is
|
||||
# demonstrated in the following example:
|
||||
#
|
||||
# esptool.py --port rfc2217://localhost:4000?ign_set_control flash_id
|
||||
#
|
||||
###################################################################################
|
||||
# redirect data from a TCP/IP connection to a serial port and vice versa
|
||||
# using RFC 2217
|
||||
#
|
||||
# (C) 2009-2015 Chris Liechti <cliechti@gmx.net>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
import logging
|
||||
import os
|
||||
import socket
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
|
||||
from esptool.config import load_config_file
|
||||
from esptool.reset import (
|
||||
ClassicReset,
|
||||
CustomReset,
|
||||
DEFAULT_RESET_DELAY,
|
||||
HardReset,
|
||||
UnixTightReset,
|
||||
)
|
||||
|
||||
import serial
|
||||
import serial.rfc2217
|
||||
from serial.rfc2217 import (
|
||||
COM_PORT_OPTION,
|
||||
SET_CONTROL,
|
||||
SET_CONTROL_DTR_OFF,
|
||||
SET_CONTROL_DTR_ON,
|
||||
SET_CONTROL_RTS_OFF,
|
||||
SET_CONTROL_RTS_ON,
|
||||
)
|
||||
|
||||
cfg, _ = load_config_file(verbose=True)
|
||||
cfg = cfg["esptool"]
|
||||
|
||||
|
||||
class EspPortManager(serial.rfc2217.PortManager):
|
||||
"""
|
||||
The beginning of the reset sequence is detected and the proper reset sequence
|
||||
is applied in a thread. The rest of the reset sequence received is just ignored
|
||||
and not sent to the serial port.
|
||||
"""
|
||||
|
||||
def __init__(self, serial_port, connection, esp32r0_delay, logger=None):
|
||||
self.esp32r0_delay = esp32r0_delay
|
||||
self.is_download_mode = False
|
||||
super(EspPortManager, self).__init__(serial_port, connection, logger)
|
||||
|
||||
def _telnet_process_subnegotiation(self, suboption):
|
||||
if suboption[0:1] == COM_PORT_OPTION and suboption[1:2] == SET_CONTROL:
|
||||
if suboption[2:3] == SET_CONTROL_DTR_OFF:
|
||||
self.is_download_mode = False
|
||||
self.serial.dtr = False
|
||||
return
|
||||
elif suboption[2:3] == SET_CONTROL_RTS_OFF and not self.is_download_mode:
|
||||
reset_thread = threading.Thread(target=self._hard_reset_thread)
|
||||
reset_thread.daemon = True
|
||||
reset_thread.name = "hard_reset_thread"
|
||||
reset_thread.start()
|
||||
return
|
||||
elif suboption[2:3] == SET_CONTROL_DTR_ON and not self.is_download_mode:
|
||||
self.is_download_mode = True
|
||||
reset_thread = threading.Thread(target=self._reset_thread)
|
||||
reset_thread.daemon = True
|
||||
reset_thread.name = "reset_thread"
|
||||
reset_thread.start()
|
||||
return
|
||||
elif suboption[2:3] in [
|
||||
SET_CONTROL_DTR_ON,
|
||||
SET_CONTROL_RTS_ON,
|
||||
SET_CONTROL_RTS_OFF,
|
||||
]:
|
||||
return
|
||||
# only in cases not handled above do the original implementation in PortManager
|
||||
super(EspPortManager, self)._telnet_process_subnegotiation(suboption)
|
||||
|
||||
def _hard_reset_thread(self):
|
||||
"""
|
||||
The reset logic used for hard resetting the chip.
|
||||
"""
|
||||
if self.logger:
|
||||
self.logger.info("Activating hard reset in thread")
|
||||
HardReset(self.serial)()
|
||||
|
||||
def _reset_thread(self):
|
||||
"""
|
||||
The reset logic is used from esptool.py because the RTS and DTR signals
|
||||
cannot be retransmitted through RFC 2217 with proper timing.
|
||||
"""
|
||||
if self.logger:
|
||||
self.logger.info("Activating reset in thread")
|
||||
|
||||
delay = DEFAULT_RESET_DELAY
|
||||
if self.esp32r0_delay:
|
||||
delay += 0.5
|
||||
|
||||
cfg_custom_reset_sequence = cfg.get("custom_reset_sequence")
|
||||
if cfg_custom_reset_sequence is not None:
|
||||
CustomReset(self.serial, cfg_custom_reset_sequence)()
|
||||
elif os.name != "nt":
|
||||
UnixTightReset(self.serial, delay)()
|
||||
else:
|
||||
ClassicReset(self.serial, delay)()
|
||||
|
||||
|
||||
class Redirector(object):
|
||||
def __init__(self, serial_instance, socket, debug=False, esp32r0delay=False):
|
||||
self.serial = serial_instance
|
||||
self.socket = socket
|
||||
self._write_lock = threading.Lock()
|
||||
self.rfc2217 = EspPortManager(
|
||||
self.serial,
|
||||
self,
|
||||
esp32r0delay,
|
||||
logger=logging.getLogger("rfc2217.server") if debug else None,
|
||||
)
|
||||
self.log = logging.getLogger("redirector")
|
||||
|
||||
def statusline_poller(self):
|
||||
self.log.debug("status line poll thread started")
|
||||
while self.alive:
|
||||
time.sleep(1)
|
||||
self.rfc2217.check_modem_lines()
|
||||
self.log.debug("status line poll thread terminated")
|
||||
|
||||
def shortcircuit(self):
|
||||
"""connect the serial port to the TCP port by copying everything
|
||||
from one side to the other"""
|
||||
self.alive = True
|
||||
self.thread_read = threading.Thread(target=self.reader)
|
||||
self.thread_read.daemon = True
|
||||
self.thread_read.name = "serial->socket"
|
||||
self.thread_read.start()
|
||||
self.thread_poll = threading.Thread(target=self.statusline_poller)
|
||||
self.thread_poll.daemon = True
|
||||
self.thread_poll.name = "status line poll"
|
||||
self.thread_poll.start()
|
||||
self.writer()
|
||||
|
||||
def reader(self):
|
||||
"""loop forever and copy serial->socket"""
|
||||
self.log.debug("reader thread started")
|
||||
while self.alive:
|
||||
try:
|
||||
data = self.serial.read(self.serial.in_waiting or 1)
|
||||
if data:
|
||||
# escape outgoing data when needed (Telnet IAC (0xff) character)
|
||||
self.write(b"".join(self.rfc2217.escape(data)))
|
||||
except socket.error as msg:
|
||||
self.log.error("{}".format(msg))
|
||||
# probably got disconnected
|
||||
break
|
||||
self.alive = False
|
||||
self.log.debug("reader thread terminated")
|
||||
|
||||
def write(self, data):
|
||||
"""thread safe socket write with no data escaping. used to send telnet stuff"""
|
||||
with self._write_lock:
|
||||
self.socket.sendall(data)
|
||||
|
||||
def writer(self):
|
||||
"""loop forever and copy socket->serial"""
|
||||
while self.alive:
|
||||
try:
|
||||
data = self.socket.recv(1024)
|
||||
if not data:
|
||||
break
|
||||
self.serial.write(b"".join(self.rfc2217.filter(data)))
|
||||
except socket.error as msg:
|
||||
self.log.error("{}".format(msg))
|
||||
# probably got disconnected
|
||||
break
|
||||
self.stop()
|
||||
|
||||
def stop(self):
|
||||
"""Stop copying"""
|
||||
self.log.debug("stopping")
|
||||
if self.alive:
|
||||
self.alive = False
|
||||
self.thread_read.join()
|
||||
self.thread_poll.join()
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="RFC 2217 Serial to Network (TCP/IP) redirector.",
|
||||
epilog="NOTE: no security measures are implemented. "
|
||||
"Anyone can remotely connect to this service over the network.\n"
|
||||
"Only one connection at once is supported. "
|
||||
"When the connection is terminated it waits for the next connect.",
|
||||
)
|
||||
|
||||
parser.add_argument("SERIALPORT")
|
||||
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
"--localport",
|
||||
type=int,
|
||||
help="local TCP port, default: %(default)s",
|
||||
metavar="TCPPORT",
|
||||
default=2217,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-v",
|
||||
"--verbose",
|
||||
dest="verbosity",
|
||||
action="count",
|
||||
help="print more diagnostic messages (option can be given multiple times)",
|
||||
default=0,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--r0",
|
||||
help="Use delays necessary for ESP32 revision 0 chips",
|
||||
action="store_true",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.verbosity > 3:
|
||||
args.verbosity = 3
|
||||
level = (logging.WARNING, logging.INFO, logging.DEBUG, logging.NOTSET)[
|
||||
args.verbosity
|
||||
]
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
# logging.getLogger('root').setLevel(logging.INFO)
|
||||
logging.getLogger("rfc2217").setLevel(level)
|
||||
|
||||
# connect to serial port
|
||||
ser = serial.serial_for_url(args.SERIALPORT, do_not_open=True)
|
||||
ser.timeout = 3 # required so that the reader thread can exit
|
||||
# reset control line as no _remote_ "terminal" has been connected yet
|
||||
ser.dtr = False
|
||||
ser.rts = False
|
||||
|
||||
logging.info("RFC 2217 TCP/IP to Serial redirector - type Ctrl-C / BREAK to quit")
|
||||
|
||||
try:
|
||||
ser.open()
|
||||
except serial.SerialException as e:
|
||||
logging.error("Could not open serial port {}: {}".format(ser.name, e))
|
||||
sys.exit(1)
|
||||
|
||||
logging.info("Serving serial port: {}".format(ser.name))
|
||||
settings = ser.get_settings()
|
||||
|
||||
srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
srv.bind(("", args.localport))
|
||||
srv.listen(1)
|
||||
logging.info("TCP/IP port: {}".format(args.localport))
|
||||
while True:
|
||||
try:
|
||||
client_socket, addr = srv.accept()
|
||||
logging.info("Connected by {}:{}".format(addr[0], addr[1]))
|
||||
client_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
||||
ser.rts = True
|
||||
ser.dtr = True
|
||||
# enter network <-> serial loop
|
||||
r = Redirector(ser, client_socket, args.verbosity > 0, args.r0)
|
||||
try:
|
||||
r.shortcircuit()
|
||||
finally:
|
||||
logging.info("Disconnected")
|
||||
r.stop()
|
||||
client_socket.close()
|
||||
ser.dtr = False
|
||||
ser.rts = False
|
||||
# Restore port settings (may have been changed by RFC 2217
|
||||
# capable client)
|
||||
ser.apply_settings(settings)
|
||||
except KeyboardInterrupt:
|
||||
sys.stdout.write("\n")
|
||||
break
|
||||
except socket.error as msg:
|
||||
logging.error(str(msg))
|
||||
|
||||
logging.info("--- exit ---")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
37
code/.venv/bin/espefuse.py
Executable file
37
code/.venv/bin/espefuse.py
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2014-2022 Fredrik Ahlberg, Angus Gratton,
|
||||
# Espressif Systems (Shanghai) CO LTD, other contributors as noted.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# This executable script is a thin wrapper around the main functionality
|
||||
# in the espefuse Python package
|
||||
|
||||
# When updating this script, please also update esptool.py and espsecure.py
|
||||
|
||||
import contextlib
|
||||
import os
|
||||
import sys
|
||||
|
||||
if os.name != "nt":
|
||||
# Linux/macOS: remove current script directory to avoid importing this file
|
||||
# as a module; we want to import the installed espefuse module instead
|
||||
with contextlib.suppress(ValueError):
|
||||
executable_dir = os.path.dirname(sys.executable)
|
||||
sys.path = [
|
||||
path
|
||||
for path in sys.path
|
||||
if not path.endswith(("/bin", "/sbin")) and path != executable_dir
|
||||
]
|
||||
|
||||
# Linux/macOS: delete imported module entry to force Python to load
|
||||
# the module from scratch; this enables importing espefuse module in
|
||||
# other Python scripts
|
||||
with contextlib.suppress(KeyError):
|
||||
del sys.modules["espefuse"]
|
||||
|
||||
import espefuse
|
||||
|
||||
if __name__ == "__main__":
|
||||
espefuse._main()
|
||||
37
code/.venv/bin/espsecure.py
Executable file
37
code/.venv/bin/espsecure.py
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2014-2022 Fredrik Ahlberg, Angus Gratton,
|
||||
# Espressif Systems (Shanghai) CO LTD, other contributors as noted.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# This executable script is a thin wrapper around the main functionality
|
||||
# in the espsecure Python package
|
||||
|
||||
# When updating this script, please also update esptool.py and espefuse.py
|
||||
|
||||
import contextlib
|
||||
import os
|
||||
import sys
|
||||
|
||||
if os.name != "nt":
|
||||
# Linux/macOS: remove current script directory to avoid importing this file
|
||||
# as a module; we want to import the installed espsecure module instead
|
||||
with contextlib.suppress(ValueError):
|
||||
executable_dir = os.path.dirname(sys.executable)
|
||||
sys.path = [
|
||||
path
|
||||
for path in sys.path
|
||||
if not path.endswith(("/bin", "/sbin")) and path != executable_dir
|
||||
]
|
||||
|
||||
# Linux/macOS: delete imported module entry to force Python to load
|
||||
# the module from scratch; this enables importing espsecure module in
|
||||
# other Python scripts
|
||||
with contextlib.suppress(KeyError):
|
||||
del sys.modules["espsecure"]
|
||||
|
||||
import espsecure
|
||||
|
||||
if __name__ == "__main__":
|
||||
espsecure._main()
|
||||
37
code/.venv/bin/esptool.py
Executable file
37
code/.venv/bin/esptool.py
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2014-2022 Fredrik Ahlberg, Angus Gratton,
|
||||
# Espressif Systems (Shanghai) CO LTD, other contributors as noted.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# This executable script is a thin wrapper around the main functionality
|
||||
# in the esptool Python package
|
||||
|
||||
# When updating this script, please also update espefuse.py and espsecure.py
|
||||
|
||||
import contextlib
|
||||
import os
|
||||
import sys
|
||||
|
||||
if os.name != "nt":
|
||||
# Linux/macOS: remove current script directory to avoid importing this file
|
||||
# as a module; we want to import the installed esptool module instead
|
||||
with contextlib.suppress(ValueError):
|
||||
executable_dir = os.path.dirname(sys.executable)
|
||||
sys.path = [
|
||||
path
|
||||
for path in sys.path
|
||||
if not path.endswith(("/bin", "/sbin")) and path != executable_dir
|
||||
]
|
||||
|
||||
# Linux/macOS: delete imported module entry to force Python to load
|
||||
# the module from scratch; this enables importing esptool module in
|
||||
# other Python scripts
|
||||
with contextlib.suppress(KeyError):
|
||||
del sys.modules["esptool"]
|
||||
|
||||
import esptool
|
||||
|
||||
if __name__ == "__main__":
|
||||
esptool._main()
|
||||
132
code/.venv/bin/hex2bin.py
Executable file
132
code/.venv/bin/hex2bin.py
Executable file
@@ -0,0 +1,132 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
|
||||
# Copyright (c) 2005-2018 Alexander Belchenko
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author nor the names
|
||||
# of its contributors may be used to endorse
|
||||
# or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''Intel HEX file format hex2bin convertor utility.'''
|
||||
|
||||
VERSION = '2.3.0'
|
||||
|
||||
if __name__ == '__main__':
|
||||
import getopt
|
||||
import os
|
||||
import sys
|
||||
|
||||
usage = '''Hex2Bin convertor utility.
|
||||
Usage:
|
||||
python hex2bin.py [options] INFILE [OUTFILE]
|
||||
|
||||
Arguments:
|
||||
INFILE name of hex file for processing.
|
||||
OUTFILE name of output file. If omitted then output
|
||||
will be writing to stdout.
|
||||
|
||||
Options:
|
||||
-h, --help this help message.
|
||||
-v, --version version info.
|
||||
-p, --pad=FF pad byte for empty spaces (ascii hex value).
|
||||
-r, --range=START:END specify address range for writing output
|
||||
(ascii hex value).
|
||||
Range can be in form 'START:' or ':END'.
|
||||
-l, --length=NNNN,
|
||||
-s, --size=NNNN size of output (decimal value).
|
||||
'''
|
||||
|
||||
pad = None
|
||||
start = None
|
||||
end = None
|
||||
size = None
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "hvp:r:l:s:",
|
||||
["help", "version", "pad=", "range=",
|
||||
"length=", "size="])
|
||||
|
||||
for o, a in opts:
|
||||
if o in ("-h", "--help"):
|
||||
print(usage)
|
||||
sys.exit(0)
|
||||
elif o in ("-v", "--version"):
|
||||
print(VERSION)
|
||||
sys.exit(0)
|
||||
elif o in ("-p", "--pad"):
|
||||
try:
|
||||
pad = int(a, 16) & 0x0FF
|
||||
except:
|
||||
raise getopt.GetoptError('Bad pad value')
|
||||
elif o in ("-r", "--range"):
|
||||
try:
|
||||
l = a.split(":")
|
||||
if l[0] != '':
|
||||
start = int(l[0], 16)
|
||||
if l[1] != '':
|
||||
end = int(l[1], 16)
|
||||
except:
|
||||
raise getopt.GetoptError('Bad range value(s)')
|
||||
elif o in ("-l", "--lenght", "-s", "--size"):
|
||||
try:
|
||||
size = int(a, 10)
|
||||
except:
|
||||
raise getopt.GetoptError('Bad size value')
|
||||
|
||||
if start != None and end != None and size != None:
|
||||
raise getopt.GetoptError('Cannot specify START:END and SIZE simultaneously')
|
||||
|
||||
if not args:
|
||||
raise getopt.GetoptError('Hex file is not specified')
|
||||
|
||||
if len(args) > 2:
|
||||
raise getopt.GetoptError('Too many arguments')
|
||||
|
||||
except getopt.GetoptError:
|
||||
msg = sys.exc_info()[1] # current exception
|
||||
txt = 'ERROR: '+str(msg) # that's required to get not-so-dumb result from 2to3 tool
|
||||
print(txt)
|
||||
print(usage)
|
||||
sys.exit(2)
|
||||
|
||||
fin = args[0]
|
||||
if not os.path.isfile(fin):
|
||||
txt = "ERROR: File not found: %s" % fin # that's required to get not-so-dumb result from 2to3 tool
|
||||
print(txt)
|
||||
sys.exit(1)
|
||||
|
||||
if len(args) == 2:
|
||||
fout = args[1]
|
||||
else:
|
||||
# write to stdout
|
||||
from intelhex import compat
|
||||
fout = compat.get_binary_stdout()
|
||||
|
||||
from intelhex import hex2bin
|
||||
sys.exit(hex2bin(fin, fout, start, end, size, pad))
|
||||
135
code/.venv/bin/hex2dump.py
Executable file
135
code/.venv/bin/hex2dump.py
Executable file
@@ -0,0 +1,135 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
|
||||
# Copyright (c) 2008-2018 Alexander Belchenko
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author nor the names
|
||||
# of its contributors may be used to endorse
|
||||
# or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""Show content of hex file as hexdump."""
|
||||
|
||||
VERSION = '2.3.0'
|
||||
|
||||
USAGE = '''hex2dump: show content of hex file as hexdump.
|
||||
Usage:
|
||||
python hex2dump.py [options] HEXFILE
|
||||
|
||||
Options:
|
||||
-h, --help this help message.
|
||||
-v, --version version info.
|
||||
-r, --range=START:END specify address range for dumping
|
||||
(ascii hex value).
|
||||
Range can be in form 'START:' or ':END'.
|
||||
--width=N dump N data bytes per line (default: 16).
|
||||
|
||||
Arguments:
|
||||
HEXFILE name of hex file for processing (use '-' to read
|
||||
from stdin)
|
||||
'''
|
||||
|
||||
import sys
|
||||
|
||||
DEFAULT_WIDTH = 16
|
||||
|
||||
def hex2dump(hexfile, start=None, end=None, width=DEFAULT_WIDTH):
|
||||
import intelhex
|
||||
if hexfile == '-':
|
||||
hexfile = sys.stdin
|
||||
try:
|
||||
ih = intelhex.IntelHex(hexfile)
|
||||
except (IOError, intelhex.IntelHexError):
|
||||
e = sys.exc_info()[1] # current exception
|
||||
sys.stderr.write('Error reading file: %s\n' % e)
|
||||
return 1
|
||||
if not (start is None and end is None):
|
||||
ih = ih[slice(start,end)]
|
||||
ih.dump(tofile=sys.stdout, width=width)
|
||||
return 0
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
import getopt
|
||||
|
||||
if argv is None:
|
||||
argv = sys.argv[1:]
|
||||
|
||||
start = None
|
||||
end = None
|
||||
width = DEFAULT_WIDTH
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "hvp:r:",
|
||||
["help", "version", "range=", "width="])
|
||||
for o, a in opts:
|
||||
if o in ("-h", "--help"):
|
||||
print(USAGE)
|
||||
return 0
|
||||
elif o in ("-v", "--version"):
|
||||
print(VERSION)
|
||||
return 0
|
||||
elif o in ("-r", "--range"):
|
||||
try:
|
||||
l = a.split(":")
|
||||
if l[0] != '':
|
||||
start = int(l[0], 16)
|
||||
if l[1] != '':
|
||||
end = int(l[1], 16)
|
||||
except:
|
||||
raise getopt.GetoptError('Bad range value(s)')
|
||||
elif o == "--width":
|
||||
try:
|
||||
width = int(a)
|
||||
if width < 1:
|
||||
raise ValueError
|
||||
except:
|
||||
raise getopt.GetoptError('Bad width value (%s)' % a)
|
||||
if not args:
|
||||
raise getopt.GetoptError('Hex file is not specified')
|
||||
if len(args) > 1:
|
||||
raise getopt.GetoptError('Too many arguments')
|
||||
except getopt.GetoptError:
|
||||
msg = sys.exc_info()[1] # current exception
|
||||
txt = 'ERROR: '+str(msg) # that's required to get not-so-dumb result from 2to3 tool
|
||||
print(txt)
|
||||
print(USAGE)
|
||||
return 2
|
||||
|
||||
try:
|
||||
return hex2dump(args[0], start, end, width)
|
||||
except IOError:
|
||||
e = sys.exc_info()[1] # current exception
|
||||
import errno
|
||||
if e.errno not in (0, errno.EPIPE):
|
||||
raise
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.exit(main())
|
||||
90
code/.venv/bin/hexdiff.py
Executable file
90
code/.venv/bin/hexdiff.py
Executable file
@@ -0,0 +1,90 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
|
||||
# Copyright (c) 2011-2018 Alexander Belchenko
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author nor the names
|
||||
# of its contributors may be used to endorse
|
||||
# or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""Produce diff for 2 hex files using hex dump as string representation
|
||||
of compared data.
|
||||
"""
|
||||
|
||||
VERSION = '2.3.0'
|
||||
|
||||
USAGE = '''hexdiff: diff dumps of 2 hex files.
|
||||
Usage:
|
||||
python hexdiff.py [options] FILE1 FILE2
|
||||
|
||||
Options:
|
||||
-h, --help this help message.
|
||||
-v, --version version info.
|
||||
'''
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
import getopt
|
||||
|
||||
if argv is None:
|
||||
argv = sys.argv[1:]
|
||||
try:
|
||||
opts, args = getopt.gnu_getopt(argv, 'hv', ['help', 'version'])
|
||||
|
||||
for o,a in opts:
|
||||
if o in ('-h', '--help'):
|
||||
print(USAGE)
|
||||
return 0
|
||||
elif o in ('-v', '--version'):
|
||||
print(VERSION)
|
||||
return 0
|
||||
|
||||
except getopt.GetoptError:
|
||||
e = sys.exc_info()[1] # current exception
|
||||
sys.stderr.write(str(e)+"\n")
|
||||
sys.stderr.write(USAGE+"\n")
|
||||
return 1
|
||||
|
||||
if len(args) != 2:
|
||||
sys.stderr.write("ERROR: You should specify 2 files to diff.\n")
|
||||
sys.stderr.write(USAGE+"\n")
|
||||
return 1
|
||||
|
||||
fname1, fname2 = args
|
||||
|
||||
from intelhex import IntelHex, diff_dumps
|
||||
ih1 = IntelHex(fname1)
|
||||
ih2 = IntelHex(fname2)
|
||||
diff_dumps(ih1, ih2, name1=fname1, name2=fname2)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
108
code/.venv/bin/hexinfo.py
Executable file
108
code/.venv/bin/hexinfo.py
Executable file
@@ -0,0 +1,108 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
|
||||
# Copyright (c) 2015 Andrew Fernandes <andrew@fernandes.org>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author nor the names
|
||||
# of its contributors may be used to endorse
|
||||
# or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""Summarize the information in a hex file by printing the execution
|
||||
start address (if any), and the address ranges covered by the
|
||||
data (if any), in YAML format.
|
||||
"""
|
||||
|
||||
VERSION = '2.3.0'
|
||||
|
||||
USAGE = '''hexinfo: summarize a hex file's contents.
|
||||
Usage:
|
||||
python hexinfo.py [options] FILE [ FILE ... ]
|
||||
|
||||
Options:
|
||||
-h, --help this help message.
|
||||
-v, --version version info.
|
||||
'''
|
||||
|
||||
import sys
|
||||
|
||||
INDENT = ' '
|
||||
INLIST = '- '
|
||||
|
||||
def summarize_yaml(fname):
|
||||
print("{:s}file: '{:s}'".format(INLIST, fname))
|
||||
from intelhex import IntelHex
|
||||
ih = IntelHex(fname)
|
||||
if ih.start_addr:
|
||||
keys = sorted(ih.start_addr.keys())
|
||||
if keys == ['CS','IP']:
|
||||
entry = ih.start_addr['CS'] * 65536 + ih.start_addr['IP']
|
||||
elif keys == ['EIP']:
|
||||
entry = ih.start_addr['EIP']
|
||||
else:
|
||||
raise RuntimeError("unknown 'IntelHex.start_addr' found")
|
||||
print("{:s}entry: 0x{:08X}".format(INDENT, entry))
|
||||
segments = ih.segments()
|
||||
if segments:
|
||||
print("{:s}data:".format(INDENT))
|
||||
for s in segments:
|
||||
print("{:s}{:s}{{ first: 0x{:08X}, last: 0x{:08X}, length: 0x{:08X} }}".format(INDENT, INLIST, s[0], s[1]-1, s[1]-s[0]))
|
||||
print("")
|
||||
|
||||
def main(argv=None):
|
||||
import getopt
|
||||
|
||||
if argv is None:
|
||||
argv = sys.argv[1:]
|
||||
try:
|
||||
opts, args = getopt.gnu_getopt(argv, 'hv', ['help', 'version'])
|
||||
|
||||
for o,a in opts:
|
||||
if o in ('-h', '--help'):
|
||||
print(USAGE)
|
||||
return 0
|
||||
elif o in ('-v', '--version'):
|
||||
print(VERSION)
|
||||
return 0
|
||||
|
||||
except getopt.GetoptError:
|
||||
e = sys.exc_info()[1] # current exception
|
||||
sys.stderr.write(str(e)+"\n")
|
||||
sys.stderr.write(USAGE+"\n")
|
||||
return 1
|
||||
|
||||
if len(args) < 1:
|
||||
sys.stderr.write("ERROR: You should specify one or more files to summarize.\n")
|
||||
sys.stderr.write(USAGE+"\n")
|
||||
return 1
|
||||
|
||||
for fname in args:
|
||||
summarize_yaml(fname)
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
178
code/.venv/bin/hexmerge.py
Executable file
178
code/.venv/bin/hexmerge.py
Executable file
@@ -0,0 +1,178 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
|
||||
# Copyright (c) 2008-2018 Alexander Belchenko
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author nor the names
|
||||
# of its contributors may be used to endorse
|
||||
# or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""Merge content of several hex files into one file."""
|
||||
|
||||
VERSION = '2.3.0'
|
||||
|
||||
USAGE = '''hexmerge: merge content of hex files.
|
||||
Usage:
|
||||
python hexmerge.py [options] FILES...
|
||||
|
||||
Options:
|
||||
-h, --help this help message.
|
||||
-v, --version version info.
|
||||
-o, --output=FILENAME output file name (emit output to stdout
|
||||
if option is not specified)
|
||||
-r, --range=START:END specify address range for output
|
||||
(ascii hex value). Both values are inclusive.
|
||||
Range can be in form 'START:' or ':END'.
|
||||
--no-start-addr Don't write start addr to output file.
|
||||
--overlap=METHOD What to do when data in files overlapped.
|
||||
Supported variants:
|
||||
* error -- stop and show error message (default)
|
||||
* ignore -- keep data from first file that
|
||||
contains data at overlapped address
|
||||
* replace -- use data from last file that
|
||||
contains data at overlapped address
|
||||
|
||||
Arguments:
|
||||
FILES list of hex files for merging
|
||||
(use '-' to read content from stdin)
|
||||
|
||||
You can specify address range for each file in the form:
|
||||
|
||||
filename:START:END
|
||||
|
||||
See description of range option above.
|
||||
|
||||
You can omit START or END, so supported variants are:
|
||||
|
||||
filename:START: read filename and use data starting from START addr
|
||||
filename::END read filename and use data till END addr
|
||||
|
||||
Use entire file content:
|
||||
|
||||
filename
|
||||
or
|
||||
filename::
|
||||
'''
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
def main(args=None):
|
||||
import getopt
|
||||
|
||||
output = None
|
||||
start = None
|
||||
end = None
|
||||
write_start_addr = True
|
||||
overlap = 'error'
|
||||
|
||||
if args is None:
|
||||
args = sys.argv[1:]
|
||||
try:
|
||||
opts, args = getopt.gnu_getopt(args, 'hvo:r:',
|
||||
['help', 'version',
|
||||
'output=', 'range=',
|
||||
'no-start-addr', 'overlap=',
|
||||
])
|
||||
|
||||
for o,a in opts:
|
||||
if o in ('-h', '--help'):
|
||||
print(USAGE)
|
||||
return 0
|
||||
elif o in ('-v', '--version'):
|
||||
print(VERSION)
|
||||
return 0
|
||||
elif o in ('-o', '--output'):
|
||||
output = a
|
||||
elif o in ("-r", "--range"):
|
||||
try:
|
||||
l = a.split(":")
|
||||
if l[0] != '':
|
||||
start = int(l[0], 16)
|
||||
if l[1] != '':
|
||||
end = int(l[1], 16)
|
||||
except (ValueError, IndexError):
|
||||
raise getopt.GetoptError('Bad range value(s)')
|
||||
elif o == '--no-start-addr':
|
||||
write_start_addr = False
|
||||
elif o == '--overlap':
|
||||
if a in ('error', 'ignore', 'replace'):
|
||||
overlap = a
|
||||
else:
|
||||
raise getopt.GetoptError('Bad overlap value')
|
||||
|
||||
if len(args) == 0:
|
||||
raise getopt.GetoptError('You should specify file list')
|
||||
|
||||
except getopt.GetoptError:
|
||||
e = sys.exc_info()[1] # current exception
|
||||
sys.stderr.write(str(e)+"\n")
|
||||
sys.stderr.write(USAGE+"\n")
|
||||
return 1
|
||||
|
||||
import intelhex
|
||||
# TODO: move actual merge code into intelhex package as helper function
|
||||
# and write couple of tests for it.
|
||||
res = intelhex.IntelHex()
|
||||
|
||||
def end_addr_inclusive(addr):
|
||||
if addr is not None:
|
||||
return addr + 1
|
||||
return addr
|
||||
|
||||
for f in args:
|
||||
try:
|
||||
fname, fstart, fend = intelhex._get_file_and_addr_range(f)
|
||||
except intelhex._BadFileNotation:
|
||||
sys.stderr.write('Bad argument: "%s"\n' % f)
|
||||
sys.stderr.write(USAGE+"\n")
|
||||
return 1
|
||||
if fname == '-':
|
||||
fname = sys.stdin
|
||||
ih = intelhex.IntelHex(fname)
|
||||
if (fstart, fend) != (None, None):
|
||||
ih = ih[fstart:end_addr_inclusive(fend)]
|
||||
try:
|
||||
res.merge(ih, overlap)
|
||||
except intelhex.AddressOverlapError:
|
||||
e = sys.exc_info()[1] # current exception
|
||||
sys.stderr.write('Merging: '+fname+"\n")
|
||||
sys.stderr.write(str(e)+"\n")
|
||||
return 1
|
||||
|
||||
if (start, end) != (None, None):
|
||||
res = res[start:end_addr_inclusive(end)]
|
||||
if output is None:
|
||||
output = sys.stdout
|
||||
res.write_hex_file(output, write_start_addr)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
8
code/.venv/bin/list_serial_ports
Executable file
8
code/.venv/bin/list_serial_ports
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from utilities.list_serial_ports import lsp
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(lsp())
|
||||
8
code/.venv/bin/pip
Executable file
8
code/.venv/bin/pip
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from pip._internal.cli.main import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
8
code/.venv/bin/pip-3.12
Executable file
8
code/.venv/bin/pip-3.12
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from pip._internal.cli.main import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
8
code/.venv/bin/pip3
Executable file
8
code/.venv/bin/pip3
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from pip._internal.cli.main import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
8
code/.venv/bin/pip3.12
Executable file
8
code/.venv/bin/pip3.12
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from pip._internal.cli.main import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
8
code/.venv/bin/pyserial-miniterm
Executable file
8
code/.venv/bin/pyserial-miniterm
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from serial.tools.miniterm import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
8
code/.venv/bin/pyserial-ports
Executable file
8
code/.venv/bin/pyserial-ports
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from serial.tools.list_ports import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
1
code/.venv/bin/python
Symbolic link
1
code/.venv/bin/python
Symbolic link
@@ -0,0 +1 @@
|
||||
/usr/bin/python3.12
|
||||
1
code/.venv/bin/python3
Symbolic link
1
code/.venv/bin/python3
Symbolic link
@@ -0,0 +1 @@
|
||||
python
|
||||
1
code/.venv/bin/python3.12
Symbolic link
1
code/.venv/bin/python3.12
Symbolic link
@@ -0,0 +1 @@
|
||||
python
|
||||
162
code/.venv/bin/webreplcmd
Executable file
162
code/.venv/bin/webreplcmd
Executable file
@@ -0,0 +1,162 @@
|
||||
#!/home/rhetenor/Projects/esp/python/.venv/bin/python
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
import webrepl
|
||||
|
||||
examples="""webreplcmd --host 192.168.4.1 --password ulx3s ls
|
||||
webreplcmd --host 192.168.4.1 --password ulx3s get src-remote-file.txt dest-local-file.txt
|
||||
webreplcmd --host 192.168.4.1 --password ulx3s put src-local-file.txt dest-remote-file.txt
|
||||
webreplcmd --host 192.168.4.1 --password ulx3s cat main.py
|
||||
webreplcmd --host 192.168.4.1 --password ulx3s cmd 'import os; os.listdir()'
|
||||
"""
|
||||
|
||||
parser = argparse.ArgumentParser(description='webrepl - connect to websocket webrepl',
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog=examples)
|
||||
parser.add_argument('--host', '-i', default=os.environ.get('WEBREPL_HOST', None), help="Host to connect to")
|
||||
parser.add_argument('--port', '-P', type=int, default=os.environ.get('WEBREPL_PORT', 8266), help="Port to connect to")
|
||||
parser.add_argument('--verbose', '-v', action='store_true', help="Verbose information")
|
||||
parser.add_argument('--debug', '-d', action='store_true', help="Enable debugging messages")
|
||||
parser.add_argument('--password', '-p', default=os.environ.get('WEBREPL_PASSWORD', None), help="Use following password to connect")
|
||||
parser.add_argument('--before', '-B', action='append', default=os.environ.get('WEBREPL_BEFORE', None), help="command to execute before")
|
||||
parser.add_argument('--cmd', '-c', action='append', default=os.environ.get('WEBREPL_CMD', None), help="command to execute")
|
||||
parser.add_argument('--after', '-A', action='append', default=os.environ.get('WEBREPL_AFTER', None), help="command to execute after")
|
||||
parser.add_argument('commands', metavar='CMD', type=str, nargs='+',
|
||||
help='commands for repl')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.host:
|
||||
print("You need to specify host")
|
||||
parser.print_usage()
|
||||
sys.exit()
|
||||
|
||||
password=''
|
||||
if not args.password:
|
||||
print("You need to specify password")
|
||||
try:
|
||||
import getpass
|
||||
password = getpass.getpass()
|
||||
except:
|
||||
parser.print_usage()
|
||||
sys.exit()
|
||||
else:
|
||||
password = args.password
|
||||
|
||||
if not args.commands or len(args.commands)<1:
|
||||
print("Command is not recognized/given")
|
||||
parser.print_usage()
|
||||
sys.exit()
|
||||
|
||||
repl=webrepl.Webrepl(**{})
|
||||
|
||||
if args.debug:
|
||||
repl.debug = True
|
||||
|
||||
if args.verbose:
|
||||
repl.verbose = True
|
||||
|
||||
try:
|
||||
repl.connect(args.host, args.port)
|
||||
repl.login(password)
|
||||
except Exception as e:
|
||||
print("Error connecting to host",args.host,"at port",args.port,":",e)
|
||||
sys.exit()
|
||||
|
||||
if not repl.connected:
|
||||
print("Not connected. Check your password!")
|
||||
sys.exit()
|
||||
|
||||
if args.before:
|
||||
for cmd in args.before:
|
||||
print("[i] Issuing command: "+cmd)
|
||||
try:
|
||||
r=repl.send_cmd(cmd)
|
||||
print(r.decode())
|
||||
except Exception as e:
|
||||
print("[e] Error running command:",cmd,":",e)
|
||||
|
||||
cmd = args.commands[0].lower()
|
||||
|
||||
if cmd == "ver" or cmd == "version":
|
||||
if args.verbose:
|
||||
print("[i] Getting version")
|
||||
ver=repl.get_ver()
|
||||
print("[i] Version ",ver[0], ver[1], ver[2])
|
||||
elif cmd == "list" or cmd == "ls":
|
||||
print("[i] Listing")
|
||||
r=repl.sendcmd("import os; os.listdir()")
|
||||
print(r.decode())
|
||||
elif cmd == "get" or cmd == "download":
|
||||
if len(args.commands)<3:
|
||||
sys.stderr.write("Not enough arguments for "+cmd+"\n")
|
||||
sys.exit()
|
||||
source=args.commands[1]
|
||||
dest=args.commands[2]
|
||||
if args.verbose:
|
||||
print("[i] Downloading "+source+" to "+dest)
|
||||
repl.get_file(source, dest)
|
||||
elif cmd == "put" or cmd == "upload":
|
||||
if len(args.commands)<3:
|
||||
sys.stderr.write("Not enough arguments for "+cmd+"\n")
|
||||
sys.exit()
|
||||
source=args.commands[1]
|
||||
dest=args.commands[2]
|
||||
if args.verbose:
|
||||
print("[i] Uploading "+source+" to "+dest)
|
||||
repl.put_file(source, dest)
|
||||
elif cmd == "del" or cmd == "rm" or cmd == "dele":
|
||||
if len(args.commands)<2:
|
||||
sys.stderr.write("Not enough arguments for "+cmd+"\n")
|
||||
sys.exit()
|
||||
filename=args.commands[1]
|
||||
if args.verbose:
|
||||
print("[i] Deleting "+filename)
|
||||
r=repl.sendcmd("import os; os.remove('"+filename+"')")
|
||||
print(r.decode())
|
||||
elif cmd == "print" or cmd == "cat" or cmd == "type":
|
||||
if len(args.commands)<2:
|
||||
sys.stderr.write("Not enough arguments for "+cmd+"\n")
|
||||
sys.exit()
|
||||
source=args.commands[1]
|
||||
if args.verbose:
|
||||
print("[i] Content of file",source)
|
||||
r=repl.get_file_content(source)
|
||||
print(r.decode())
|
||||
elif cmd == "command" or cmd == "cmd":
|
||||
if len(args.commands)<2:
|
||||
sys.stderr.write("Not enough arguments for "+cmd+"\n")
|
||||
sys.exit()
|
||||
cmd=args.commands[1]
|
||||
if args.verbose:
|
||||
print("[i] Executing "+cmd)
|
||||
r=repl.sendcmd(cmd)
|
||||
print(r.decode())
|
||||
else:
|
||||
sys.stderr.write("Command not recognized\n")
|
||||
|
||||
if args.cmd:
|
||||
for cmd in args.cmd:
|
||||
print("[i] Issuing command: "+cmd)
|
||||
try:
|
||||
r=repl.send_cmd(cmd)
|
||||
print(r.decode())
|
||||
except Exception as e:
|
||||
print("[e] Error running command:",cmd,":",e)
|
||||
|
||||
if args.after:
|
||||
for cmd in args.after:
|
||||
print("[i] Issuing command: "+cmd)
|
||||
try:
|
||||
r=repl.send_cmd(cmd)
|
||||
print(r.decode())
|
||||
except Exception as e:
|
||||
print("[e] Error running command:",cmd,":",e)
|
||||
|
||||
if args.verbose:
|
||||
print("[i] closing REPL/WS")
|
||||
repl.disconnect()
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
pip
|
||||
@@ -0,0 +1,36 @@
|
||||
Metadata-Version: 2.1
|
||||
Name: PyBoard
|
||||
Version: 1.1.4
|
||||
Summary: A Python package for programming with Arduino.
|
||||
Home-page: https://github.com/kaiyu-liu/PyBoard
|
||||
Author: Kevin Liu
|
||||
Author-email: winaes@126.com
|
||||
License: GPL v3
|
||||
Classifier: Environment :: Other Environment
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: Intended Audience :: Education
|
||||
Classifier: Natural Language :: English
|
||||
Classifier: Operating System :: MacOS
|
||||
Classifier: Operating System :: Microsoft
|
||||
Classifier: Operating System :: POSIX
|
||||
Classifier: Operating System :: Unix
|
||||
Classifier: Topic :: Scientific/Engineering
|
||||
Classifier: Topic :: Education
|
||||
Classifier: Programming Language :: Python :: 3.5
|
||||
Requires-Dist: pymata-aio >=2.25
|
||||
|
||||
# PyBoard
|
||||
A project that helps to use Python in STEM projects easily. The project is based on PyMata and makes the APIs as close to the functions in Arduino as possible.
|
||||
|
||||
== Installation
|
||||
|
||||
pip install PyBoard
|
||||
|
||||
== Usage
|
||||
|
||||
Please look at the examples folder to see how it works.
|
||||
|
||||
== License
|
||||
|
||||
GPL v3
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
PyBoard-1.1.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
PyBoard-1.1.4.dist-info/METADATA,sha256=75bL6KHfusE99zg6qBm4C-zKf-yJK7-5ocJC3fLKetQ,1003
|
||||
PyBoard-1.1.4.dist-info/RECORD,,
|
||||
PyBoard-1.1.4.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
PyBoard-1.1.4.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
|
||||
PyBoard-1.1.4.dist-info/top_level.txt,sha256=Lxn4VWX3v2-acNb1pnoNCabY7LslscnlLsGkKCd67sI,8
|
||||
pyboard/__init__.py,sha256=MAiDuBlNc7SGg1NuQvafd1_MRIUO5zn1CryL_akIiCk,768
|
||||
pyboard/__pycache__/__init__.cpython-312.pyc,,
|
||||
pyboard/__pycache__/board.cpython-312.pyc,,
|
||||
pyboard/__pycache__/main.cpython-312.pyc,,
|
||||
pyboard/__pycache__/pyboard_constants.cpython-312.pyc,,
|
||||
pyboard/__pycache__/pyboard_core.cpython-312.pyc,,
|
||||
pyboard/__pycache__/pyboard_iot.cpython-312.pyc,,
|
||||
pyboard/board.py,sha256=xni359QZD1eM_r5LEeaLJG4dC13n-e-pDVFBHP_zCl4,31731
|
||||
pyboard/main.py,sha256=6vwDSMG7w9RQb66JONgyGwKjp3EHBzUkZbRVLjdoAwc,901
|
||||
pyboard/pyboard_constants.py,sha256=vXr56UFRGTbuvABYiKbxUVsDzSl0sEXh3SI81ro2dDU,1131
|
||||
pyboard/pyboard_core.py,sha256=K20f2JxM--809EBmToOUsH8WpbQpvrunNbfEJQDlaFs,7227
|
||||
pyboard/pyboard_iot.py,sha256=D3MhMPKpGadnEFzSKydmqe6_UGxAj0Wulmn-qByS5XY,30600
|
||||
@@ -0,0 +1,5 @@
|
||||
Wheel-Version: 1.0
|
||||
Generator: setuptools (72.2.0)
|
||||
Root-Is-Purelib: true
|
||||
Tag: py3-none-any
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
pyboard
|
||||
@@ -0,0 +1 @@
|
||||
pip
|
||||
@@ -0,0 +1,20 @@
|
||||
Copyright (c) 2017-2021 Ingy döt Net
|
||||
Copyright (c) 2006-2016 Kirill Simonov
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,46 @@
|
||||
Metadata-Version: 2.1
|
||||
Name: PyYAML
|
||||
Version: 6.0.2
|
||||
Summary: YAML parser and emitter for Python
|
||||
Home-page: https://pyyaml.org/
|
||||
Download-URL: https://pypi.org/project/PyYAML/
|
||||
Author: Kirill Simonov
|
||||
Author-email: xi@resolvent.net
|
||||
License: MIT
|
||||
Project-URL: Bug Tracker, https://github.com/yaml/pyyaml/issues
|
||||
Project-URL: CI, https://github.com/yaml/pyyaml/actions
|
||||
Project-URL: Documentation, https://pyyaml.org/wiki/PyYAMLDocumentation
|
||||
Project-URL: Mailing lists, http://lists.sourceforge.net/lists/listinfo/yaml-core
|
||||
Project-URL: Source Code, https://github.com/yaml/pyyaml
|
||||
Platform: Any
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: MIT License
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Programming Language :: Cython
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.8
|
||||
Classifier: Programming Language :: Python :: 3.9
|
||||
Classifier: Programming Language :: Python :: 3.10
|
||||
Classifier: Programming Language :: Python :: 3.11
|
||||
Classifier: Programming Language :: Python :: 3.12
|
||||
Classifier: Programming Language :: Python :: 3.13
|
||||
Classifier: Programming Language :: Python :: Implementation :: CPython
|
||||
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||
Classifier: Topic :: Text Processing :: Markup
|
||||
Requires-Python: >=3.8
|
||||
License-File: LICENSE
|
||||
|
||||
YAML is a data serialization format designed for human readability
|
||||
and interaction with scripting languages. PyYAML is a YAML parser
|
||||
and emitter for Python.
|
||||
|
||||
PyYAML features a complete YAML 1.1 parser, Unicode support, pickle
|
||||
support, capable extension API, and sensible error messages. PyYAML
|
||||
supports standard YAML tags and provides Python-specific tags that
|
||||
allow to represent an arbitrary Python object.
|
||||
|
||||
PyYAML is applicable for a broad range of tasks from complex
|
||||
configuration files to object serialization and persistence.
|
||||
@@ -0,0 +1,43 @@
|
||||
PyYAML-6.0.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
PyYAML-6.0.2.dist-info/LICENSE,sha256=jTko-dxEkP1jVwfLiOsmvXZBAqcoKVQwfT5RZ6V36KQ,1101
|
||||
PyYAML-6.0.2.dist-info/METADATA,sha256=9-odFB5seu4pGPcEv7E8iyxNF51_uKnaNGjLAhz2lto,2060
|
||||
PyYAML-6.0.2.dist-info/RECORD,,
|
||||
PyYAML-6.0.2.dist-info/WHEEL,sha256=1pP4yhrbipRtdbm4Rbg3aoTjzc7pDhpHKO0CEY24CNM,152
|
||||
PyYAML-6.0.2.dist-info/top_level.txt,sha256=rpj0IVMTisAjh_1vG3Ccf9v5jpCQwAz6cD1IVU5ZdhQ,11
|
||||
_yaml/__init__.py,sha256=04Ae_5osxahpJHa3XBZUAf4wi6XX32gR8D6X6p64GEA,1402
|
||||
_yaml/__pycache__/__init__.cpython-312.pyc,,
|
||||
yaml/__init__.py,sha256=N35S01HMesFTe0aRRMWkPj0Pa8IEbHpE9FK7cr5Bdtw,12311
|
||||
yaml/__pycache__/__init__.cpython-312.pyc,,
|
||||
yaml/__pycache__/composer.cpython-312.pyc,,
|
||||
yaml/__pycache__/constructor.cpython-312.pyc,,
|
||||
yaml/__pycache__/cyaml.cpython-312.pyc,,
|
||||
yaml/__pycache__/dumper.cpython-312.pyc,,
|
||||
yaml/__pycache__/emitter.cpython-312.pyc,,
|
||||
yaml/__pycache__/error.cpython-312.pyc,,
|
||||
yaml/__pycache__/events.cpython-312.pyc,,
|
||||
yaml/__pycache__/loader.cpython-312.pyc,,
|
||||
yaml/__pycache__/nodes.cpython-312.pyc,,
|
||||
yaml/__pycache__/parser.cpython-312.pyc,,
|
||||
yaml/__pycache__/reader.cpython-312.pyc,,
|
||||
yaml/__pycache__/representer.cpython-312.pyc,,
|
||||
yaml/__pycache__/resolver.cpython-312.pyc,,
|
||||
yaml/__pycache__/scanner.cpython-312.pyc,,
|
||||
yaml/__pycache__/serializer.cpython-312.pyc,,
|
||||
yaml/__pycache__/tokens.cpython-312.pyc,,
|
||||
yaml/_yaml.cpython-312-x86_64-linux-gnu.so,sha256=PJFgxnc0f5Dyde6WKmBm6fZWapawmWl7aBRruXjRA80,2481784
|
||||
yaml/composer.py,sha256=_Ko30Wr6eDWUeUpauUGT3Lcg9QPBnOPVlTnIMRGJ9FM,4883
|
||||
yaml/constructor.py,sha256=kNgkfaeLUkwQYY_Q6Ff1Tz2XVw_pG1xVE9Ak7z-viLA,28639
|
||||
yaml/cyaml.py,sha256=6ZrAG9fAYvdVe2FK_w0hmXoG7ZYsoYUwapG8CiC72H0,3851
|
||||
yaml/dumper.py,sha256=PLctZlYwZLp7XmeUdwRuv4nYOZ2UBnDIUy8-lKfLF-o,2837
|
||||
yaml/emitter.py,sha256=jghtaU7eFwg31bG0B7RZea_29Adi9CKmXq_QjgQpCkQ,43006
|
||||
yaml/error.py,sha256=Ah9z-toHJUbE9j-M8YpxgSRM5CgLCcwVzJgLLRF2Fxo,2533
|
||||
yaml/events.py,sha256=50_TksgQiE4up-lKo_V-nBy-tAIxkIPQxY5qDhKCeHw,2445
|
||||
yaml/loader.py,sha256=UVa-zIqmkFSCIYq_PgSGm4NSJttHY2Rf_zQ4_b1fHN0,2061
|
||||
yaml/nodes.py,sha256=gPKNj8pKCdh2d4gr3gIYINnPOaOxGhJAUiYhGRnPE84,1440
|
||||
yaml/parser.py,sha256=ilWp5vvgoHFGzvOZDItFoGjD6D42nhlZrZyjAwa0oJo,25495
|
||||
yaml/reader.py,sha256=0dmzirOiDG4Xo41RnuQS7K9rkY3xjHiVasfDMNTqCNw,6794
|
||||
yaml/representer.py,sha256=IuWP-cAW9sHKEnS0gCqSa894k1Bg4cgTxaDwIcbRQ-Y,14190
|
||||
yaml/resolver.py,sha256=9L-VYfm4mWHxUD1Vg4X7rjDRK_7VZd6b92wzq7Y2IKY,9004
|
||||
yaml/scanner.py,sha256=YEM3iLZSaQwXcQRg2l2R4MdT0zGP2F9eHkKGKnHyWQY,51279
|
||||
yaml/serializer.py,sha256=ChuFgmhU01hj4xgI8GaKv6vfM2Bujwa9i7d2FAHj7cA,4165
|
||||
yaml/tokens.py,sha256=lTQIzSVw8Mg9wv459-TjiOQe6wVziqaRlqX2_89rp54,2573
|
||||
@@ -0,0 +1,6 @@
|
||||
Wheel-Version: 1.0
|
||||
Generator: bdist_wheel (0.44.0)
|
||||
Root-Is-Purelib: false
|
||||
Tag: cp312-cp312-manylinux_2_17_x86_64
|
||||
Tag: cp312-cp312-manylinux2014_x86_64
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
_yaml
|
||||
yaml
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1
code/.venv/lib/python3.12/site-packages/_virtualenv.pth
Normal file
1
code/.venv/lib/python3.12/site-packages/_virtualenv.pth
Normal file
@@ -0,0 +1 @@
|
||||
import _virtualenv
|
||||
103
code/.venv/lib/python3.12/site-packages/_virtualenv.py
Normal file
103
code/.venv/lib/python3.12/site-packages/_virtualenv.py
Normal file
@@ -0,0 +1,103 @@
|
||||
"""Patches that are applied at runtime to the virtual environment."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
VIRTUALENV_PATCH_FILE = os.path.join(__file__)
|
||||
|
||||
|
||||
def patch_dist(dist):
|
||||
"""
|
||||
Distutils allows user to configure some arguments via a configuration file:
|
||||
https://docs.python.org/3/install/index.html#distutils-configuration-files.
|
||||
|
||||
Some of this arguments though don't make sense in context of the virtual environment files, let's fix them up.
|
||||
""" # noqa: D205
|
||||
# we cannot allow some install config as that would get packages installed outside of the virtual environment
|
||||
old_parse_config_files = dist.Distribution.parse_config_files
|
||||
|
||||
def parse_config_files(self, *args, **kwargs):
|
||||
result = old_parse_config_files(self, *args, **kwargs)
|
||||
install = self.get_option_dict("install")
|
||||
|
||||
if "prefix" in install: # the prefix governs where to install the libraries
|
||||
install["prefix"] = VIRTUALENV_PATCH_FILE, os.path.abspath(sys.prefix)
|
||||
for base in ("purelib", "platlib", "headers", "scripts", "data"):
|
||||
key = f"install_{base}"
|
||||
if key in install: # do not allow global configs to hijack venv paths
|
||||
install.pop(key, None)
|
||||
return result
|
||||
|
||||
dist.Distribution.parse_config_files = parse_config_files
|
||||
|
||||
|
||||
# Import hook that patches some modules to ignore configuration values that break package installation in case
|
||||
# of virtual environments.
|
||||
_DISTUTILS_PATCH = "distutils.dist", "setuptools.dist"
|
||||
# https://docs.python.org/3/library/importlib.html#setting-up-an-importer
|
||||
|
||||
|
||||
class _Finder:
|
||||
"""A meta path finder that allows patching the imported distutils modules."""
|
||||
|
||||
fullname = None
|
||||
|
||||
# lock[0] is threading.Lock(), but initialized lazily to avoid importing threading very early at startup,
|
||||
# because there are gevent-based applications that need to be first to import threading by themselves.
|
||||
# See https://github.com/pypa/virtualenv/issues/1895 for details.
|
||||
lock = [] # noqa: RUF012
|
||||
|
||||
def find_spec(self, fullname, path, target=None): # noqa: ARG002
|
||||
if fullname in _DISTUTILS_PATCH and self.fullname is None: # noqa: PLR1702
|
||||
# initialize lock[0] lazily
|
||||
if len(self.lock) == 0:
|
||||
import threading # noqa: PLC0415
|
||||
|
||||
lock = threading.Lock()
|
||||
# there is possibility that two threads T1 and T2 are simultaneously running into find_spec,
|
||||
# observing .lock as empty, and further going into hereby initialization. However due to the GIL,
|
||||
# list.append() operation is atomic and this way only one of the threads will "win" to put the lock
|
||||
# - that every thread will use - into .lock[0].
|
||||
# https://docs.python.org/3/faq/library.html#what-kinds-of-global-value-mutation-are-thread-safe
|
||||
self.lock.append(lock)
|
||||
|
||||
from functools import partial # noqa: PLC0415
|
||||
from importlib.util import find_spec # noqa: PLC0415
|
||||
|
||||
with self.lock[0]:
|
||||
self.fullname = fullname
|
||||
try:
|
||||
spec = find_spec(fullname, path)
|
||||
if spec is not None:
|
||||
# https://www.python.org/dev/peps/pep-0451/#how-loading-will-work
|
||||
is_new_api = hasattr(spec.loader, "exec_module")
|
||||
func_name = "exec_module" if is_new_api else "load_module"
|
||||
old = getattr(spec.loader, func_name)
|
||||
func = self.exec_module if is_new_api else self.load_module
|
||||
if old is not func:
|
||||
try: # noqa: SIM105
|
||||
setattr(spec.loader, func_name, partial(func, old))
|
||||
except AttributeError:
|
||||
pass # C-Extension loaders are r/o such as zipimporter with <3.7
|
||||
return spec
|
||||
finally:
|
||||
self.fullname = None
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def exec_module(old, module):
|
||||
old(module)
|
||||
if module.__name__ in _DISTUTILS_PATCH:
|
||||
patch_dist(module)
|
||||
|
||||
@staticmethod
|
||||
def load_module(old, name):
|
||||
module = old(name)
|
||||
if module.__name__ in _DISTUTILS_PATCH:
|
||||
patch_dist(module)
|
||||
return module
|
||||
|
||||
|
||||
sys.meta_path.insert(0, _Finder())
|
||||
33
code/.venv/lib/python3.12/site-packages/_yaml/__init__.py
Normal file
33
code/.venv/lib/python3.12/site-packages/_yaml/__init__.py
Normal file
@@ -0,0 +1,33 @@
|
||||
# This is a stub package designed to roughly emulate the _yaml
|
||||
# extension module, which previously existed as a standalone module
|
||||
# and has been moved into the `yaml` package namespace.
|
||||
# It does not perfectly mimic its old counterpart, but should get
|
||||
# close enough for anyone who's relying on it even when they shouldn't.
|
||||
import yaml
|
||||
|
||||
# in some circumstances, the yaml module we imoprted may be from a different version, so we need
|
||||
# to tread carefully when poking at it here (it may not have the attributes we expect)
|
||||
if not getattr(yaml, '__with_libyaml__', False):
|
||||
from sys import version_info
|
||||
|
||||
exc = ModuleNotFoundError if version_info >= (3, 6) else ImportError
|
||||
raise exc("No module named '_yaml'")
|
||||
else:
|
||||
from yaml._yaml import *
|
||||
import warnings
|
||||
warnings.warn(
|
||||
'The _yaml extension module is now located at yaml._yaml'
|
||||
' and its location is subject to change. To use the'
|
||||
' LibYAML-based parser and emitter, import from `yaml`:'
|
||||
' `from yaml import CLoader as Loader, CDumper as Dumper`.',
|
||||
DeprecationWarning
|
||||
)
|
||||
del warnings
|
||||
# Don't `del yaml` here because yaml is actually an existing
|
||||
# namespace member of _yaml.
|
||||
|
||||
__name__ = '_yaml'
|
||||
# If the module is top-level (i.e. not a part of any specific package)
|
||||
# then the attribute should be set to ''.
|
||||
# https://docs.python.org/3.8/library/types.html
|
||||
__package__ = ''
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
pip
|
||||
@@ -0,0 +1,46 @@
|
||||
PYTHON SOFTWARE FOUNDATION LICENSE
|
||||
----------------------------------
|
||||
|
||||
1. This LICENSE AGREEMENT is between Ilan Schnell, and the Individual or
|
||||
Organization ("Licensee") accessing and otherwise using this software
|
||||
("bitarray") in source or binary form and its associated documentation.
|
||||
|
||||
2. Subject to the terms and conditions of this License Agreement, Ilan Schnell
|
||||
hereby grants Licensee a nonexclusive, royalty-free, world-wide
|
||||
license to reproduce, analyze, test, perform and/or display publicly,
|
||||
prepare derivative works, distribute, and otherwise use bitarray
|
||||
alone or in any derivative version, provided, however, that Ilan Schnell's
|
||||
License Agreement and Ilan Schnell's notice of copyright, i.e., "Copyright (c)
|
||||
2008 - 2024 Ilan Schnell; All Rights Reserved" are retained in bitarray
|
||||
alone or in any derivative version prepared by Licensee.
|
||||
|
||||
3. In the event Licensee prepares a derivative work that is based on
|
||||
or incorporates bitarray or any part thereof, and wants to make
|
||||
the derivative work available to others as provided herein, then
|
||||
Licensee hereby agrees to include in any such work a brief summary of
|
||||
the changes made to bitarray.
|
||||
|
||||
4. Ilan Schnell is making bitarray available to Licensee on an "AS IS"
|
||||
basis. ILAN SCHNELL MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
||||
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, ILAN SCHNELL MAKES NO AND
|
||||
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
||||
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF BITARRAY WILL NOT
|
||||
INFRINGE ANY THIRD PARTY RIGHTS.
|
||||
|
||||
5. ILAN SCHNELL SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF BITARRAY
|
||||
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
|
||||
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING BITARRAY,
|
||||
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
||||
|
||||
6. This License Agreement will automatically terminate upon a material
|
||||
breach of its terms and conditions.
|
||||
|
||||
7. Nothing in this License Agreement shall be deemed to create any
|
||||
relationship of agency, partnership, or joint venture between Ilan Schnell
|
||||
and Licensee. This License Agreement does not grant permission to use Ilan
|
||||
Schnell trademarks or trade name in a trademark sense to endorse or promote
|
||||
products or services of Licensee, or any third party.
|
||||
|
||||
8. By copying, installing or otherwise using bitarray, Licensee
|
||||
agrees to be bound by the terms and conditions of this License
|
||||
Agreement.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
bitarray-2.9.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
bitarray-2.9.2.dist-info/LICENSE,sha256=a14E9uBGLhuXvoM_nWXmbNXs6zKD9Kb1MiYQh9CrEjM,2412
|
||||
bitarray-2.9.2.dist-info/METADATA,sha256=AcCMyOnbnpLfWGRf8pb8AQwTtuIXrJ1tPV04U3RorNM,34424
|
||||
bitarray-2.9.2.dist-info/RECORD,,
|
||||
bitarray-2.9.2.dist-info/WHEEL,sha256=4ZiCdXIWMxJyEClivrQv1QAHZpQh8kVYU92_ZAVwaok,152
|
||||
bitarray-2.9.2.dist-info/top_level.txt,sha256=cLdoeIHotTwh4eHSe8qy8umF7zzyxUM90I8zFb2_xhg,9
|
||||
bitarray/__init__.py,sha256=LzhfIzq4GYmC7-nRwx4veFnPO4Cy5XA5b6qdjVhQYl0,2511
|
||||
bitarray/__init__.pyi,sha256=aELtBsMYq66ob-8icr3COdYa0CrFJmsd88sdPE2sbto,5256
|
||||
bitarray/__pycache__/__init__.cpython-312.pyc,,
|
||||
bitarray/__pycache__/test_bitarray.cpython-312.pyc,,
|
||||
bitarray/__pycache__/test_util.cpython-312.pyc,,
|
||||
bitarray/__pycache__/util.cpython-312.pyc,,
|
||||
bitarray/_bitarray.cpython-312-x86_64-linux-gnu.so,sha256=14HHa1TjQ1pmIePCLwjb3r_D7SkzcigQfQU6F0dK2_w,494720
|
||||
bitarray/_util.cpython-312-x86_64-linux-gnu.so,sha256=ADHJVpvewtOhuK5bgeOiJn34VDTsPSm7y_HVusnv7wY,196136
|
||||
bitarray/bitarray.h,sha256=f5CXTBVDfR9XF_YZMXqOB52zg9u_6dwaQYCEqsX_AIM,10447
|
||||
bitarray/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
bitarray/pythoncapi_compat.h,sha256=9ywdY-5gQSwyy61cQ-pEH2Wn4GyowXe93m3bGSlDN1E,16187
|
||||
bitarray/test_150.pickle,sha256=v5oAS4jJwWDVDh8s0mPn4iCvwN3-Y5sZWpVGkpwyCqw,356
|
||||
bitarray/test_281.pickle,sha256=GaA8vsZmcyZZmIzGDP6ppfaRlsthUxgJ9tMsyjpynoc,442
|
||||
bitarray/test_bitarray.py,sha256=-o4hN4T1Dan34YIOTBqq0BXpiLIAGV8QtTSfjRW5ZhE,182731
|
||||
bitarray/test_util.py,sha256=4zURWe3wT5ZOnaRZ_u8K4AfTDxCQmYspBOclZiMF2rc,88028
|
||||
bitarray/util.py,sha256=8KY_zK5hWhAKAfe94LmYsojkLt8ienaDfZgcd1EBVIg,14015
|
||||
bitarray/util.pyi,sha256=6Ol-9EQ3Ad6RzN8b-nmYp9ZGtRjz1knMSK-gL_8urmo,2532
|
||||
@@ -0,0 +1,6 @@
|
||||
Wheel-Version: 1.0
|
||||
Generator: bdist_wheel (0.41.2)
|
||||
Root-Is-Purelib: false
|
||||
Tag: cp312-cp312-manylinux_2_17_x86_64
|
||||
Tag: cp312-cp312-manylinux2014_x86_64
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
bitarray
|
||||
76
code/.venv/lib/python3.12/site-packages/bitarray/__init__.py
Normal file
76
code/.venv/lib/python3.12/site-packages/bitarray/__init__.py
Normal file
@@ -0,0 +1,76 @@
|
||||
# Copyright (c) 2008 - 2024, Ilan Schnell; All Rights Reserved
|
||||
"""
|
||||
This package defines an object type which can efficiently represent
|
||||
a bitarray. Bitarrays are sequence types and behave very much like lists.
|
||||
|
||||
Please find a description of this package at:
|
||||
|
||||
https://github.com/ilanschnell/bitarray
|
||||
|
||||
Author: Ilan Schnell
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
from bitarray._bitarray import (bitarray, decodetree, _sysinfo,
|
||||
_bitarray_reconstructor,
|
||||
get_default_endian, _set_default_endian,
|
||||
__version__)
|
||||
|
||||
|
||||
__all__ = ['bitarray', 'frozenbitarray', 'decodetree', 'bits2bytes']
|
||||
|
||||
|
||||
class frozenbitarray(bitarray):
|
||||
"""frozenbitarray(initializer=0, /, endian='big', buffer=None) -> \
|
||||
frozenbitarray
|
||||
|
||||
Return a `frozenbitarray` object. Initialized the same way a `bitarray`
|
||||
object is initialized. A `frozenbitarray` is immutable and hashable,
|
||||
and may therefore be used as a dictionary key.
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._freeze()
|
||||
|
||||
def __repr__(self):
|
||||
return 'frozen' + bitarray.__repr__(self)
|
||||
|
||||
def __hash__(self):
|
||||
"Return hash(self)."
|
||||
# ensure hash is independent of endianness
|
||||
a = bitarray(self, 'big')
|
||||
return hash((len(a), a.tobytes()))
|
||||
|
||||
# Technically the code below is not necessary, as all these methods will
|
||||
# raise a TypeError on read-only memory. However, with a different error
|
||||
# message.
|
||||
def __delitem__(self, *args, **kwargs):
|
||||
"" # no docstring
|
||||
raise TypeError("frozenbitarray is immutable")
|
||||
|
||||
append = bytereverse = clear = extend = encode = fill = __delitem__
|
||||
frombytes = fromfile = insert = invert = pack = pop = __delitem__
|
||||
remove = reverse = setall = sort = __setitem__ = __delitem__
|
||||
__iadd__ = __iand__ = __imul__ = __ior__ = __ixor__ = __delitem__
|
||||
__ilshift__ = __irshift__ = __delitem__
|
||||
|
||||
|
||||
def bits2bytes(__n):
|
||||
"""bits2bytes(n, /) -> int
|
||||
|
||||
Return the number of bytes necessary to store n bits.
|
||||
"""
|
||||
import sys
|
||||
if not isinstance(__n, (int, long) if sys.version_info[0] == 2 else int):
|
||||
raise TypeError("integer expected")
|
||||
if __n < 0:
|
||||
raise ValueError("non-negative integer expected")
|
||||
return (__n + 7) // 8
|
||||
|
||||
|
||||
def test(verbosity=1):
|
||||
"""test(verbosity=1) -> TextTestResult
|
||||
|
||||
Run self-test, and return unittest.runner.TextTestResult object.
|
||||
"""
|
||||
from bitarray import test_bitarray
|
||||
return test_bitarray.run(verbosity=verbosity)
|
||||
149
code/.venv/lib/python3.12/site-packages/bitarray/__init__.pyi
Normal file
149
code/.venv/lib/python3.12/site-packages/bitarray/__init__.pyi
Normal file
@@ -0,0 +1,149 @@
|
||||
# Copyright (c) 2021 - 2024, Ilan Schnell; All Rights Reserved
|
||||
#
|
||||
# This stub, as well as util.pyi, are tested with Python 3.9 and mypy 0.950
|
||||
|
||||
from collections.abc import Iterable, Iterator, Sequence
|
||||
from unittest.runner import TextTestResult
|
||||
|
||||
from typing import Any, BinaryIO, Dict, Union, overload
|
||||
|
||||
|
||||
CodeDict = Dict[Any, bitarray]
|
||||
BytesLike = Union[bytes, Iterable[int]]
|
||||
|
||||
|
||||
class decodetree:
|
||||
def __init__(self, code: CodeDict) -> None: ...
|
||||
def complete(self) -> bool: ...
|
||||
def nodes(self) -> int: ...
|
||||
def todict(self) -> CodeDict: ...
|
||||
|
||||
|
||||
class bitarray:
|
||||
def __init__(self,
|
||||
initializer: Union[int, str, Iterable[int], None] = ...,
|
||||
endian: Union[str, None] = ...,
|
||||
buffer: Any = ...) -> None: ...
|
||||
|
||||
def all(self) -> bool: ...
|
||||
def any(self) -> bool: ...
|
||||
def append(self, value: int) -> None: ...
|
||||
def buffer_info(self) -> tuple: ...
|
||||
def bytereverse(self,
|
||||
start: int = ...,
|
||||
stop: int = ...) -> None: ...
|
||||
|
||||
def clear(self) -> None: ...
|
||||
def copy(self) -> bitarray: ...
|
||||
def count(self,
|
||||
sub_bitarray: Union[bitarray, int] = ...,
|
||||
start: int = ...,
|
||||
stop: int = ...,
|
||||
step: int = ...) -> int: ...
|
||||
|
||||
def decode(self, code: Union[CodeDict, decodetree]) -> list: ...
|
||||
def encode(self, code: CodeDict, x: Iterable) -> None: ...
|
||||
def endian(self) -> str: ...
|
||||
def extend(self, x: Union[str, Iterable[int]]) -> None: ...
|
||||
def fill(self) -> int: ...
|
||||
def find(self,
|
||||
sub_bitarray: Union[bitarray, int],
|
||||
start: int = ...,
|
||||
stop: int = ...,
|
||||
right: int = ...) -> int: ...
|
||||
|
||||
def frombytes(self, a: BytesLike) -> None: ...
|
||||
def fromfile(self, f: BinaryIO, n: int = ...) -> None: ...
|
||||
def index(self,
|
||||
sub_bitarray: Union[bitarray, int],
|
||||
start: int = ...,
|
||||
stop: int = ...,
|
||||
right: int = ...) -> int: ...
|
||||
|
||||
def insert(self, i: int, value: int) -> None: ...
|
||||
def invert(self, i: int = ...) -> None: ...
|
||||
def iterdecode(self,
|
||||
code: Union[CodeDict, decodetree]) -> Iterator: ...
|
||||
|
||||
def itersearch(self,
|
||||
sub_bitarray: Union[bitarray, int],
|
||||
start: int = ...,
|
||||
stop: int = ...,
|
||||
right: int = ...) -> Iterator[int]: ...
|
||||
|
||||
def pack(self, b: BytesLike) -> None: ...
|
||||
def pop(self, i: int = ...) -> int: ...
|
||||
def remove(self, value: int) -> None: ...
|
||||
def reverse(self) -> None: ...
|
||||
def search(self, sub_bitarray: Union[bitarray, int],
|
||||
limit: int = ...) -> list[int]: ...
|
||||
|
||||
def setall(self, value: int) -> None: ...
|
||||
def sort(self, reverse: int) -> None: ...
|
||||
def to01(self) -> str: ...
|
||||
def tobytes(self) -> bytes: ...
|
||||
def tofile(self, f: BinaryIO) -> None: ...
|
||||
def tolist(self) -> list[int]: ...
|
||||
def unpack(self,
|
||||
zero: bytes = ...,
|
||||
one: bytes = ...) -> bytes: ...
|
||||
|
||||
def __len__(self) -> int: ...
|
||||
def __iter__(self) -> Iterator[int]: ...
|
||||
@overload
|
||||
def __getitem__(self, i: int) -> int: ...
|
||||
@overload
|
||||
def __getitem__(self, s: Union[slice, Sequence]) -> bitarray: ...
|
||||
@overload
|
||||
def __setitem__(self, i: Union[int, slice, Sequence], o: int) -> None: ...
|
||||
@overload
|
||||
def __setitem__(self, s: Union[slice, Sequence] , o: bitarray) -> None: ...
|
||||
def __delitem__(self, i: Union[int, slice, Sequence]) -> None: ...
|
||||
|
||||
def __add__(self, other: bitarray) -> bitarray: ...
|
||||
def __iadd__(self, other: bitarray) -> bitarray: ...
|
||||
def __mul__(self, n: int) -> bitarray: ...
|
||||
def __imul__(self, n: int) -> bitarray: ...
|
||||
def __rmul__(self, n: int) -> bitarray: ...
|
||||
|
||||
def __ge__(self, other: bitarray) -> bool: ...
|
||||
def __gt__(self, other: bitarray) -> bool: ...
|
||||
def __le__(self, other: bitarray) -> bool: ...
|
||||
def __lt__(self, other: bitarray) -> bool: ...
|
||||
|
||||
def __and__(self, other: bitarray) -> bitarray: ...
|
||||
def __or__(self, other: bitarray) -> bitarray: ...
|
||||
def __xor__(self, other: bitarray) -> bitarray: ...
|
||||
def __iand__(self, other: bitarray) -> bitarray: ...
|
||||
def __ior__(self, other: bitarray) -> bitarray: ...
|
||||
def __ixor__(self, other: bitarray) -> bitarray: ...
|
||||
def __invert__(self) -> bitarray: ...
|
||||
def __lshift__(self, n: int) -> bitarray: ...
|
||||
def __rshift__(self, n: int) -> bitarray: ...
|
||||
def __ilshift__(self, n: int) -> bitarray: ...
|
||||
def __irshift__(self, n: int) -> bitarray: ...
|
||||
|
||||
# data descriptors
|
||||
@property
|
||||
def nbytes(self) -> int: ...
|
||||
@property
|
||||
def padbits(self) -> int: ...
|
||||
@property
|
||||
def readonly(self) -> bool: ...
|
||||
|
||||
|
||||
class frozenbitarray(bitarray):
|
||||
def __hash__(self) -> int: ...
|
||||
|
||||
|
||||
__version__: str
|
||||
def bits2bytes(n: int) -> int: ...
|
||||
def get_default_endian() -> str: ...
|
||||
def test(verbosity: int = ...) -> TextTestResult: ...
|
||||
def _set_default_endian(endian: str) -> None: ...
|
||||
def _sysinfo() -> tuple: ...
|
||||
def _bitarray_reconstructor(cls: type,
|
||||
buffer: bytes,
|
||||
endian: str,
|
||||
padbits: int,
|
||||
readonly: int) -> bitarray: ...
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
336
code/.venv/lib/python3.12/site-packages/bitarray/bitarray.h
Normal file
336
code/.venv/lib/python3.12/site-packages/bitarray/bitarray.h
Normal file
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
Copyright (c) 2008 - 2024, Ilan Schnell; All Rights Reserved
|
||||
bitarray is published under the PSF license.
|
||||
|
||||
Author: Ilan Schnell
|
||||
*/
|
||||
#define BITARRAY_VERSION "2.9.2"
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
# include <stddef.h>
|
||||
#else
|
||||
# ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h> /* For size_t */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Compatibility with Visual Studio 2013 and older which don't support
|
||||
the inline keyword in C (only in C++): use __inline instead.
|
||||
(copied from pythoncapi_compat.h) */
|
||||
#if (defined(_MSC_VER) && _MSC_VER < 1900 \
|
||||
&& !defined(__cplusplus) && !defined(inline))
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <intrin.h> /* For _byteswap_uint64() */
|
||||
#endif
|
||||
|
||||
/* --- definitions specific to Python --- */
|
||||
|
||||
/* Py_UNREACHABLE was introduced in Python 3.7 */
|
||||
#ifndef Py_UNREACHABLE
|
||||
#define Py_UNREACHABLE() abort()
|
||||
#endif
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
#define IS_PY3K 1
|
||||
#define BYTES_SIZE_FMT "y#"
|
||||
#else
|
||||
#define IS_PY3K 0
|
||||
/* the Py_MIN and Py_MAX macros were introduced in Python 3.3 */
|
||||
#define Py_MIN(x, y) (((x) > (y)) ? (y) : (x))
|
||||
#define Py_MAX(x, y) (((x) > (y)) ? (x) : (y))
|
||||
#define PySlice_GetIndicesEx(slice, len, start, stop, step, slicelength) \
|
||||
PySlice_GetIndicesEx(((PySliceObject *) slice), \
|
||||
(len), (start), (stop), (step), (slicelength))
|
||||
#define PyLong_FromLong PyInt_FromLong
|
||||
#define BYTES_SIZE_FMT "s#"
|
||||
#endif
|
||||
|
||||
/* --- bitarrayobject --- */
|
||||
|
||||
/* .ob_size is buffer size (in bytes), not the number of elements.
|
||||
The number of elements (bits) is .nbits. */
|
||||
typedef struct {
|
||||
PyObject_VAR_HEAD
|
||||
char *ob_item; /* buffer */
|
||||
Py_ssize_t allocated; /* allocated buffer size (in bytes) */
|
||||
Py_ssize_t nbits; /* length of bitarray, i.e. elements */
|
||||
int endian; /* bit-endianness of bitarray */
|
||||
int ob_exports; /* how many buffer exports */
|
||||
PyObject *weakreflist; /* list of weak references */
|
||||
Py_buffer *buffer; /* used when importing a buffer */
|
||||
int readonly; /* buffer is readonly */
|
||||
} bitarrayobject;
|
||||
|
||||
/* --- bit-endianness --- */
|
||||
#define ENDIAN_LITTLE 0
|
||||
#define ENDIAN_BIG 1
|
||||
|
||||
#define IS_LE(self) ((self)->endian == ENDIAN_LITTLE)
|
||||
#define IS_BE(self) ((self)->endian == ENDIAN_BIG)
|
||||
|
||||
/* endianness as string */
|
||||
#define ENDIAN_STR(endian) ((endian) == ENDIAN_LITTLE ? "little" : "big")
|
||||
|
||||
/* number of pad bits */
|
||||
#define PADBITS(self) (8 * Py_SIZE(self) - (self)->nbits)
|
||||
|
||||
/* number of bytes necessary to store given bits */
|
||||
#define BYTES(bits) (((bits) + 7) >> 3)
|
||||
|
||||
/* we're not using bitmask_table here, as it is actually slower */
|
||||
#define BITMASK(self, i) (((char) 1) << ((self)->endian == ENDIAN_LITTLE ? \
|
||||
((i) % 8) : (7 - (i) % 8)))
|
||||
|
||||
/* buffer as uint64 array */
|
||||
#define WBUFF(self) ((uint64_t *) (self)->ob_item)
|
||||
|
||||
/* assert that .nbits is in agreement with .ob_size */
|
||||
#define assert_nbits(self) assert(BYTES((self)->nbits) == Py_SIZE(self))
|
||||
|
||||
/* assert byte index is in range */
|
||||
#define assert_byte_in_range(self, j) \
|
||||
assert(self->ob_item && 0 <= (j) && (j) < Py_SIZE(self))
|
||||
|
||||
/* ------------ low level access to bits in bitarrayobject ------------- */
|
||||
|
||||
static inline int
|
||||
getbit(bitarrayobject *self, Py_ssize_t i)
|
||||
{
|
||||
assert_nbits(self);
|
||||
assert(0 <= i && i < self->nbits);
|
||||
return self->ob_item[i >> 3] & BITMASK(self, i) ? 1 : 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
setbit(bitarrayobject *self, Py_ssize_t i, int vi)
|
||||
{
|
||||
char *cp, mask;
|
||||
|
||||
assert_nbits(self);
|
||||
assert(0 <= i && i < self->nbits);
|
||||
assert(self->readonly == 0);
|
||||
|
||||
mask = BITMASK(self, i);
|
||||
cp = self->ob_item + (i >> 3);
|
||||
if (vi)
|
||||
*cp |= mask;
|
||||
else
|
||||
*cp &= ~mask;
|
||||
}
|
||||
|
||||
static const char bitmask_table[2][8] = {
|
||||
{0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}, /* little endian */
|
||||
{0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}, /* big endian */
|
||||
};
|
||||
|
||||
/* character with n leading ones is: ones_table[endian][n] */
|
||||
static const char ones_table[2][8] = {
|
||||
{0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f}, /* little endian */
|
||||
{0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe}, /* big endian */
|
||||
};
|
||||
|
||||
/* Return last byte in buffer with pad bits zeroed out.
|
||||
If the length of the bitarray is a multiple of 8 (which includes an empty
|
||||
bitarray), 0 is returned. */
|
||||
static inline char
|
||||
zlc(bitarrayobject *self) /* zlc = zeroed last char */
|
||||
{
|
||||
const int r = self->nbits % 8; /* index into mask table */
|
||||
|
||||
if (r == 0)
|
||||
return 0;
|
||||
return self->ob_item[Py_SIZE(self) - 1] & ones_table[IS_BE(self)][r];
|
||||
}
|
||||
|
||||
/* Return a uint64_t word representing the last (up to 63) remaining bits
|
||||
of the buffer. All missing bytes (to complete the word) and padbits are
|
||||
treated as zeros.
|
||||
If the length of the bitarray is a multiple of 64 (which includes an empty
|
||||
bitarray), 0 is returned. */
|
||||
static inline uint64_t
|
||||
zlw(bitarrayobject *self) /* zlw = zeroed last word */
|
||||
{
|
||||
const Py_ssize_t nbits = self->nbits;
|
||||
const Py_ssize_t nw = 8 * (nbits / 64); /* bytes in complete words */
|
||||
const int nr = (nbits % 64) / 8; /* complete remaining bytes */
|
||||
uint64_t res = 0;
|
||||
|
||||
assert(nw + nr == nbits / 8 && nw + nr <= Py_SIZE(self));
|
||||
memcpy((char *) &res, self->ob_item + nw, (size_t) nr);
|
||||
if (nbits % 8)
|
||||
*(((char *) &res) + nr) = zlc(self);
|
||||
|
||||
assert(nbits % 64 || res == 0);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* unless buffer is readonly, zero out pad bits - self->nbits is unchanged */
|
||||
static inline void
|
||||
set_padbits(bitarrayobject *self)
|
||||
{
|
||||
const int r = self->nbits % 8; /* index into mask table */
|
||||
|
||||
if (self->readonly == 0 && r)
|
||||
self->ob_item[Py_SIZE(self) - 1] &= ones_table[IS_BE(self)][r];
|
||||
}
|
||||
|
||||
/* population count - number of 1's in uint64 */
|
||||
static inline int
|
||||
popcnt_64(uint64_t x)
|
||||
{
|
||||
#if (defined(__clang__) || defined(__GNUC__))
|
||||
return __builtin_popcountll(x);
|
||||
#else
|
||||
/* https://en.wikipedia.org/wiki/Hamming_weight popcount64c */
|
||||
const uint64_t m1 = 0x5555555555555555;
|
||||
const uint64_t m2 = 0x3333333333333333;
|
||||
const uint64_t m4 = 0x0f0f0f0f0f0f0f0f;
|
||||
const uint64_t h01 = 0x0101010101010101;
|
||||
|
||||
x -= (x >> 1) & m1;
|
||||
x = (x & m2) + ((x >> 2) & m2);
|
||||
x = (x + (x >> 4)) & m4;
|
||||
return (x * h01) >> 56;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
builtin_bswap64(uint64_t word)
|
||||
{
|
||||
#if (defined(__clang__) || \
|
||||
(defined(__GNUC__) \
|
||||
&& ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))))
|
||||
/* __builtin_bswap64() is available since GCC 4.3. */
|
||||
# define HAVE_BUILTIN_BSWAP64 1
|
||||
return __builtin_bswap64(word);
|
||||
#elif defined(_MSC_VER)
|
||||
# define HAVE_BUILTIN_BSWAP64 1
|
||||
return _byteswap_uint64(word);
|
||||
#else
|
||||
# define HAVE_BUILTIN_BSWAP64 0
|
||||
Py_UNREACHABLE();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return distance [0..3] to next aligned pointer.
|
||||
While on modern compilers uint64_t pointers may be misaligned, it may
|
||||
cause problems on older ones. Moreover, it may lead to slowdown (even
|
||||
on modern compilers). */
|
||||
static inline int
|
||||
to_aligned(void *p)
|
||||
{
|
||||
int r = ((uintptr_t) p) % 4;
|
||||
return r ? 4 - r : 0;
|
||||
}
|
||||
|
||||
/* population count of n words starting from at uint64_t pointer w */
|
||||
static inline Py_ssize_t
|
||||
popcnt_words(uint64_t *w, Py_ssize_t n)
|
||||
{
|
||||
Py_ssize_t cnt = 0;
|
||||
|
||||
assert(n >= 0 && to_aligned((void *) w) == 0);
|
||||
while (n--)
|
||||
cnt += popcnt_64(*w++);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/* adjust index a manner consistent with the handling of normal slices */
|
||||
static inline void
|
||||
adjust_index(Py_ssize_t length, Py_ssize_t *i, Py_ssize_t step)
|
||||
{
|
||||
if (*i < 0) {
|
||||
*i += length;
|
||||
if (*i < 0)
|
||||
*i = (step < 0) ? -1 : 0;
|
||||
}
|
||||
else if (*i >= length) {
|
||||
*i = (step < 0) ? length - 1 : length;
|
||||
}
|
||||
}
|
||||
|
||||
/* same as PySlice_AdjustIndices() which was introduced in Python 3.6.1 */
|
||||
static inline Py_ssize_t
|
||||
adjust_indices(Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop,
|
||||
Py_ssize_t step)
|
||||
{
|
||||
#if PY_VERSION_HEX > 0x03060100
|
||||
return PySlice_AdjustIndices(length, start, stop, step);
|
||||
#else
|
||||
assert(step != 0);
|
||||
adjust_index(length, start, step);
|
||||
adjust_index(length, stop, step);
|
||||
/*
|
||||
a / b does integer division. If either a or b is negative, the result
|
||||
depends on the compiler (rounding can go toward 0 or negative infinity).
|
||||
Therefore, we are careful that both a and b are always positive.
|
||||
*/
|
||||
if (step < 0) {
|
||||
if (*stop < *start)
|
||||
return (*start - *stop - 1) / (-step) + 1;
|
||||
}
|
||||
else {
|
||||
if (*start < *stop)
|
||||
return (*stop - *start - 1) / step + 1;
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* adjust slice parameters such that step is always positive; produces
|
||||
simpler loops over elements when their order is irrelevant */
|
||||
static inline void
|
||||
adjust_step_positive(Py_ssize_t slicelength,
|
||||
Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step)
|
||||
{
|
||||
if (*step < 0) {
|
||||
*stop = *start + 1;
|
||||
*start = *stop + *step * (slicelength - 1) - 1;
|
||||
*step = -(*step);
|
||||
}
|
||||
assert(*start >= 0 && *stop >= 0 && *step > 0 && slicelength >= 0);
|
||||
/* slicelength == 0 implies stop <= start */
|
||||
assert(slicelength != 0 || *stop <= *start);
|
||||
/* step == 1 and slicelength != 0 implies stop - start == slicelength */
|
||||
assert(*step != 1 || slicelength == 0 || *stop - *start == slicelength);
|
||||
}
|
||||
|
||||
/* convert Python object to C int and set value at address -
|
||||
return 1 on success, 0 on failure (and set exception) */
|
||||
static inline int
|
||||
conv_pybit(PyObject *value, int *vi)
|
||||
{
|
||||
Py_ssize_t n;
|
||||
|
||||
n = PyNumber_AsSsize_t(value, NULL);
|
||||
if (n == -1 && PyErr_Occurred())
|
||||
return 0;
|
||||
|
||||
if (n < 0 || n > 1) {
|
||||
PyErr_Format(PyExc_ValueError, "bit must be 0 or 1, got %zd", n);
|
||||
return 0;
|
||||
}
|
||||
*vi = (int) n;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return 0 if bitarrays have equal length and bit-endianness.
|
||||
Otherwise, set exception and return -1. */
|
||||
static inline int
|
||||
ensure_eq_size_endian(bitarrayobject *a, bitarrayobject *b)
|
||||
{
|
||||
if (a->nbits != b->nbits) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"bitarrays of equal length expected");
|
||||
return -1;
|
||||
}
|
||||
if (a->endian != b->endian) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"bitarrays of equal bit-endianness expected");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,577 @@
|
||||
// Header file providing new C API functions to old Python versions.
|
||||
//
|
||||
// File distributed under the Zero Clause BSD (0BSD) license.
|
||||
// Copyright Contributors to the pythoncapi_compat project.
|
||||
//
|
||||
// Homepage:
|
||||
// https://github.com/python/pythoncapi_compat
|
||||
//
|
||||
// Latest version:
|
||||
// https://raw.githubusercontent.com/python/pythoncapi_compat/master/pythoncapi_compat.h
|
||||
//
|
||||
// SPDX-License-Identifier: 0BSD
|
||||
|
||||
#ifndef PYTHONCAPI_COMPAT
|
||||
#define PYTHONCAPI_COMPAT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <Python.h>
|
||||
#include "frameobject.h" // PyFrameObject, PyFrame_GetBack()
|
||||
|
||||
|
||||
// Compatibility with Visual Studio 2013 and older which don't support
|
||||
// the inline keyword in C (only in C++): use __inline instead.
|
||||
#if (defined(_MSC_VER) && _MSC_VER < 1900 \
|
||||
&& !defined(__cplusplus) && !defined(inline))
|
||||
# define PYCAPI_COMPAT_STATIC_INLINE(TYPE) static __inline TYPE
|
||||
#else
|
||||
# define PYCAPI_COMPAT_STATIC_INLINE(TYPE) static inline TYPE
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef _Py_CAST
|
||||
# define _Py_CAST(type, expr) ((type)(expr))
|
||||
#endif
|
||||
|
||||
// On C++11 and newer, _Py_NULL is defined as nullptr on C++11,
|
||||
// otherwise it is defined as NULL.
|
||||
#ifndef _Py_NULL
|
||||
# if defined(__cplusplus) && __cplusplus >= 201103
|
||||
# define _Py_NULL nullptr
|
||||
# else
|
||||
# define _Py_NULL NULL
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Cast argument to PyObject* type.
|
||||
#ifndef _PyObject_CAST
|
||||
# define _PyObject_CAST(op) _Py_CAST(PyObject*, op)
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-42262 added Py_NewRef() to Python 3.10.0a3
|
||||
#if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_NewRef)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
|
||||
_Py_NewRef(PyObject *obj)
|
||||
{
|
||||
Py_INCREF(obj);
|
||||
return obj;
|
||||
}
|
||||
#define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-42262 added Py_XNewRef() to Python 3.10.0a3
|
||||
#if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_XNewRef)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
|
||||
_Py_XNewRef(PyObject *obj)
|
||||
{
|
||||
Py_XINCREF(obj);
|
||||
return obj;
|
||||
}
|
||||
#define Py_XNewRef(obj) _Py_XNewRef(_PyObject_CAST(obj))
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-39573 added Py_SET_REFCNT() to Python 3.9.0a4
|
||||
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_REFCNT)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(void)
|
||||
_Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt)
|
||||
{
|
||||
ob->ob_refcnt = refcnt;
|
||||
}
|
||||
#define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT(_PyObject_CAST(ob), refcnt)
|
||||
#endif
|
||||
|
||||
|
||||
// Py_SETREF() and Py_XSETREF() were added to Python 3.5.2.
|
||||
// It is excluded from the limited C API.
|
||||
#if (PY_VERSION_HEX < 0x03050200 && !defined(Py_SETREF)) && !defined(Py_LIMITED_API)
|
||||
#define Py_SETREF(dst, src) \
|
||||
do { \
|
||||
PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \
|
||||
PyObject *_tmp_dst = (*_tmp_dst_ptr); \
|
||||
*_tmp_dst_ptr = _PyObject_CAST(src); \
|
||||
Py_DECREF(_tmp_dst); \
|
||||
} while (0)
|
||||
|
||||
#define Py_XSETREF(dst, src) \
|
||||
do { \
|
||||
PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \
|
||||
PyObject *_tmp_dst = (*_tmp_dst_ptr); \
|
||||
*_tmp_dst_ptr = _PyObject_CAST(src); \
|
||||
Py_XDECREF(_tmp_dst); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-43753 added Py_Is(), Py_IsNone(), Py_IsTrue() and Py_IsFalse()
|
||||
// to Python 3.10.0b1.
|
||||
#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_Is)
|
||||
# define Py_Is(x, y) ((x) == (y))
|
||||
#endif
|
||||
#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsNone)
|
||||
# define Py_IsNone(x) Py_Is(x, Py_None)
|
||||
#endif
|
||||
#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsTrue)
|
||||
# define Py_IsTrue(x) Py_Is(x, Py_True)
|
||||
#endif
|
||||
#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsFalse)
|
||||
# define Py_IsFalse(x) Py_Is(x, Py_False)
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-39573 added Py_SET_TYPE() to Python 3.9.0a4
|
||||
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(void)
|
||||
_Py_SET_TYPE(PyObject *ob, PyTypeObject *type)
|
||||
{
|
||||
ob->ob_type = type;
|
||||
}
|
||||
#define Py_SET_TYPE(ob, type) _Py_SET_TYPE(_PyObject_CAST(ob), type)
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-39573 added Py_SET_SIZE() to Python 3.9.0a4
|
||||
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(void)
|
||||
_Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size)
|
||||
{
|
||||
ob->ob_size = size;
|
||||
}
|
||||
#define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size)
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
|
||||
#if PY_VERSION_HEX < 0x030900B1 || defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(PyCodeObject*)
|
||||
PyFrame_GetCode(PyFrameObject *frame)
|
||||
{
|
||||
assert(frame != _Py_NULL);
|
||||
assert(frame->f_code != _Py_NULL);
|
||||
return _Py_CAST(PyCodeObject*, Py_NewRef(frame->f_code));
|
||||
}
|
||||
#endif
|
||||
|
||||
PYCAPI_COMPAT_STATIC_INLINE(PyCodeObject*)
|
||||
_PyFrame_GetCodeBorrow(PyFrameObject *frame)
|
||||
{
|
||||
PyCodeObject *code = PyFrame_GetCode(frame);
|
||||
Py_DECREF(code);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
// bpo-40421 added PyFrame_GetBack() to Python 3.9.0b1
|
||||
#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*)
|
||||
PyFrame_GetBack(PyFrameObject *frame)
|
||||
{
|
||||
assert(frame != _Py_NULL);
|
||||
return _Py_CAST(PyFrameObject*, Py_XNewRef(frame->f_back));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*)
|
||||
_PyFrame_GetBackBorrow(PyFrameObject *frame)
|
||||
{
|
||||
PyFrameObject *back = PyFrame_GetBack(frame);
|
||||
Py_XDECREF(back);
|
||||
return back;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-40421 added PyFrame_GetLocals() to Python 3.11.0a7
|
||||
#if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
|
||||
PyFrame_GetLocals(PyFrameObject *frame)
|
||||
{
|
||||
#if PY_VERSION_HEX >= 0x030400B1
|
||||
if (PyFrame_FastToLocalsWithError(frame) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
PyFrame_FastToLocals(frame);
|
||||
#endif
|
||||
return Py_NewRef(frame->f_locals);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-40421 added PyFrame_GetGlobals() to Python 3.11.0a7
|
||||
#if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
|
||||
PyFrame_GetGlobals(PyFrameObject *frame)
|
||||
{
|
||||
return Py_NewRef(frame->f_globals);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-40421 added PyFrame_GetBuiltins() to Python 3.11.0a7
|
||||
#if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
|
||||
PyFrame_GetBuiltins(PyFrameObject *frame)
|
||||
{
|
||||
return Py_NewRef(frame->f_builtins);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-40421 added PyFrame_GetLasti() to Python 3.11.0b1
|
||||
#if PY_VERSION_HEX < 0x030B00B1 && !defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(int)
|
||||
PyFrame_GetLasti(PyFrameObject *frame)
|
||||
{
|
||||
#if PY_VERSION_HEX >= 0x030A00A7
|
||||
// bpo-27129: Since Python 3.10.0a7, f_lasti is an instruction offset,
|
||||
// not a bytes offset anymore. Python uses 16-bit "wordcode" (2 bytes)
|
||||
// instructions.
|
||||
if (frame->f_lasti < 0) {
|
||||
return -1;
|
||||
}
|
||||
return frame->f_lasti * 2;
|
||||
#else
|
||||
return frame->f_lasti;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// gh-91248 added PyFrame_GetVar() to Python 3.12.0a2
|
||||
#if PY_VERSION_HEX < 0x030C00A2 && !defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
|
||||
PyFrame_GetVar(PyFrameObject *frame, PyObject *name)
|
||||
{
|
||||
PyObject *locals, *value;
|
||||
|
||||
locals = PyFrame_GetLocals(frame);
|
||||
if (locals == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
value = PyDict_GetItemWithError(locals, name);
|
||||
#else
|
||||
value = PyDict_GetItem(locals, name);
|
||||
#endif
|
||||
Py_DECREF(locals);
|
||||
|
||||
if (value == NULL) {
|
||||
if (PyErr_Occurred()) {
|
||||
return NULL;
|
||||
}
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
PyErr_Format(PyExc_NameError, "variable %R does not exist", name);
|
||||
#else
|
||||
PyErr_SetString(PyExc_NameError, "variable does not exist");
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
return Py_NewRef(value);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// gh-91248 added PyFrame_GetVarString() to Python 3.12.0a2
|
||||
#if PY_VERSION_HEX < 0x030C00A2 && !defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
|
||||
PyFrame_GetVarString(PyFrameObject *frame, const char *name)
|
||||
{
|
||||
PyObject *name_obj, *value;
|
||||
name_obj = PyUnicode_FromString(name);
|
||||
if (name_obj == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
value = PyFrame_GetVar(frame, name_obj);
|
||||
Py_DECREF(name_obj);
|
||||
return value;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-39947 added PyThreadState_GetInterpreter() to Python 3.9.0a5
|
||||
#if PY_VERSION_HEX < 0x030900A5 || defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(PyInterpreterState *)
|
||||
PyThreadState_GetInterpreter(PyThreadState *tstate)
|
||||
{
|
||||
assert(tstate != _Py_NULL);
|
||||
return tstate->interp;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-40429 added PyThreadState_GetFrame() to Python 3.9.0b1
|
||||
#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*)
|
||||
PyThreadState_GetFrame(PyThreadState *tstate)
|
||||
{
|
||||
assert(tstate != _Py_NULL);
|
||||
return _Py_CAST(PyFrameObject *, Py_XNewRef(tstate->frame));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*)
|
||||
_PyThreadState_GetFrameBorrow(PyThreadState *tstate)
|
||||
{
|
||||
PyFrameObject *frame = PyThreadState_GetFrame(tstate);
|
||||
Py_XDECREF(frame);
|
||||
return frame;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a5
|
||||
#if PY_VERSION_HEX < 0x030900A5 || defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(PyInterpreterState*)
|
||||
PyInterpreterState_Get(void)
|
||||
{
|
||||
PyThreadState *tstate;
|
||||
PyInterpreterState *interp;
|
||||
|
||||
tstate = PyThreadState_GET();
|
||||
if (tstate == _Py_NULL) {
|
||||
Py_FatalError("GIL released (tstate is NULL)");
|
||||
}
|
||||
interp = tstate->interp;
|
||||
if (interp == _Py_NULL) {
|
||||
Py_FatalError("no current interpreter");
|
||||
}
|
||||
return interp;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a6
|
||||
#if 0x030700A1 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(uint64_t)
|
||||
PyThreadState_GetID(PyThreadState *tstate)
|
||||
{
|
||||
assert(tstate != _Py_NULL);
|
||||
return tstate->id;
|
||||
}
|
||||
#endif
|
||||
|
||||
// bpo-43760 added PyThreadState_EnterTracing() to Python 3.11.0a2
|
||||
#if PY_VERSION_HEX < 0x030B00A2 && !defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(void)
|
||||
PyThreadState_EnterTracing(PyThreadState *tstate)
|
||||
{
|
||||
tstate->tracing++;
|
||||
#if PY_VERSION_HEX >= 0x030A00A1
|
||||
tstate->cframe->use_tracing = 0;
|
||||
#else
|
||||
tstate->use_tracing = 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// bpo-43760 added PyThreadState_LeaveTracing() to Python 3.11.0a2
|
||||
#if PY_VERSION_HEX < 0x030B00A2 && !defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(void)
|
||||
PyThreadState_LeaveTracing(PyThreadState *tstate)
|
||||
{
|
||||
int use_tracing = (tstate->c_tracefunc != _Py_NULL
|
||||
|| tstate->c_profilefunc != _Py_NULL);
|
||||
tstate->tracing--;
|
||||
#if PY_VERSION_HEX >= 0x030A00A1
|
||||
tstate->cframe->use_tracing = use_tracing;
|
||||
#else
|
||||
tstate->use_tracing = use_tracing;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-37194 added PyObject_CallNoArgs() to Python 3.9.0a1
|
||||
// PyObject_CallNoArgs() added to PyPy 3.9.16-v7.3.11
|
||||
#if !defined(PyObject_CallNoArgs) && PY_VERSION_HEX < 0x030900A1
|
||||
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
|
||||
PyObject_CallNoArgs(PyObject *func)
|
||||
{
|
||||
return PyObject_CallFunctionObjArgs(func, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-39245 made PyObject_CallOneArg() public (previously called
|
||||
// _PyObject_CallOneArg) in Python 3.9.0a4
|
||||
// PyObject_CallOneArg() added to PyPy 3.9.16-v7.3.11
|
||||
#if !defined(PyObject_CallOneArg) && PY_VERSION_HEX < 0x030900A4
|
||||
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
|
||||
PyObject_CallOneArg(PyObject *func, PyObject *arg)
|
||||
{
|
||||
return PyObject_CallFunctionObjArgs(func, arg, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-1635741 added PyModule_AddObjectRef() to Python 3.10.0a3
|
||||
#if PY_VERSION_HEX < 0x030A00A3
|
||||
PYCAPI_COMPAT_STATIC_INLINE(int)
|
||||
PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value)
|
||||
{
|
||||
int res;
|
||||
Py_XINCREF(value);
|
||||
res = PyModule_AddObject(module, name, value);
|
||||
if (res < 0) {
|
||||
Py_XDECREF(value);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-40024 added PyModule_AddType() to Python 3.9.0a5
|
||||
#if PY_VERSION_HEX < 0x030900A5
|
||||
PYCAPI_COMPAT_STATIC_INLINE(int)
|
||||
PyModule_AddType(PyObject *module, PyTypeObject *type)
|
||||
{
|
||||
const char *name, *dot;
|
||||
|
||||
if (PyType_Ready(type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// inline _PyType_Name()
|
||||
name = type->tp_name;
|
||||
assert(name != _Py_NULL);
|
||||
dot = strrchr(name, '.');
|
||||
if (dot != _Py_NULL) {
|
||||
name = dot + 1;
|
||||
}
|
||||
|
||||
return PyModule_AddObjectRef(module, name, _PyObject_CAST(type));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-40241 added PyObject_GC_IsTracked() to Python 3.9.0a6.
|
||||
// bpo-4688 added _PyObject_GC_IS_TRACKED() to Python 2.7.0a2.
|
||||
#if PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(int)
|
||||
PyObject_GC_IsTracked(PyObject* obj)
|
||||
{
|
||||
return (PyObject_IS_GC(obj) && _PyObject_GC_IS_TRACKED(obj));
|
||||
}
|
||||
#endif
|
||||
|
||||
// bpo-40241 added PyObject_GC_IsFinalized() to Python 3.9.0a6.
|
||||
// bpo-18112 added _PyGCHead_FINALIZED() to Python 3.4.0 final.
|
||||
#if PY_VERSION_HEX < 0x030900A6 && PY_VERSION_HEX >= 0x030400F0 && !defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(int)
|
||||
PyObject_GC_IsFinalized(PyObject *obj)
|
||||
{
|
||||
PyGC_Head *gc = _Py_CAST(PyGC_Head*, obj) - 1;
|
||||
return (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED(gc));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-39573 added Py_IS_TYPE() to Python 3.9.0a4
|
||||
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_IS_TYPE)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(int)
|
||||
_Py_IS_TYPE(PyObject *ob, PyTypeObject *type) {
|
||||
return Py_TYPE(ob) == type;
|
||||
}
|
||||
#define Py_IS_TYPE(ob, type) _Py_IS_TYPE(_PyObject_CAST(ob), type)
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-46906 added PyFloat_Pack2() and PyFloat_Unpack2() to Python 3.11a7.
|
||||
// bpo-11734 added _PyFloat_Pack2() and _PyFloat_Unpack2() to Python 3.6.0b1.
|
||||
// Python 3.11a2 moved _PyFloat_Pack2() and _PyFloat_Unpack2() to the internal
|
||||
// C API: Python 3.11a2-3.11a6 versions are not supported.
|
||||
#if 0x030600B1 <= PY_VERSION_HEX && PY_VERSION_HEX <= 0x030B00A1 && !defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(int)
|
||||
PyFloat_Pack2(double x, char *p, int le)
|
||||
{ return _PyFloat_Pack2(x, (unsigned char*)p, le); }
|
||||
|
||||
PYCAPI_COMPAT_STATIC_INLINE(double)
|
||||
PyFloat_Unpack2(const char *p, int le)
|
||||
{ return _PyFloat_Unpack2((const unsigned char *)p, le); }
|
||||
#endif
|
||||
|
||||
|
||||
// bpo-46906 added PyFloat_Pack4(), PyFloat_Pack8(), PyFloat_Unpack4() and
|
||||
// PyFloat_Unpack8() to Python 3.11a7.
|
||||
// Python 3.11a2 moved _PyFloat_Pack4(), _PyFloat_Pack8(), _PyFloat_Unpack4()
|
||||
// and _PyFloat_Unpack8() to the internal C API: Python 3.11a2-3.11a6 versions
|
||||
// are not supported.
|
||||
#if PY_VERSION_HEX <= 0x030B00A1 && !defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(int)
|
||||
PyFloat_Pack4(double x, char *p, int le)
|
||||
{ return _PyFloat_Pack4(x, (unsigned char*)p, le); }
|
||||
|
||||
PYCAPI_COMPAT_STATIC_INLINE(int)
|
||||
PyFloat_Pack8(double x, char *p, int le)
|
||||
{ return _PyFloat_Pack8(x, (unsigned char*)p, le); }
|
||||
|
||||
PYCAPI_COMPAT_STATIC_INLINE(double)
|
||||
PyFloat_Unpack4(const char *p, int le)
|
||||
{ return _PyFloat_Unpack4((const unsigned char *)p, le); }
|
||||
|
||||
PYCAPI_COMPAT_STATIC_INLINE(double)
|
||||
PyFloat_Unpack8(const char *p, int le)
|
||||
{ return _PyFloat_Unpack8((const unsigned char *)p, le); }
|
||||
#endif
|
||||
|
||||
|
||||
// gh-92154 added PyCode_GetCode() to Python 3.11.0b1
|
||||
#if PY_VERSION_HEX < 0x030B00B1 && !defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
|
||||
PyCode_GetCode(PyCodeObject *code)
|
||||
{
|
||||
return Py_NewRef(code->co_code);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// gh-95008 added PyCode_GetVarnames() to Python 3.11.0rc1
|
||||
#if PY_VERSION_HEX < 0x030B00C1 && !defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
|
||||
PyCode_GetVarnames(PyCodeObject *code)
|
||||
{
|
||||
return Py_NewRef(code->co_varnames);
|
||||
}
|
||||
#endif
|
||||
|
||||
// gh-95008 added PyCode_GetFreevars() to Python 3.11.0rc1
|
||||
#if PY_VERSION_HEX < 0x030B00C1 && !defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
|
||||
PyCode_GetFreevars(PyCodeObject *code)
|
||||
{
|
||||
return Py_NewRef(code->co_freevars);
|
||||
}
|
||||
#endif
|
||||
|
||||
// gh-95008 added PyCode_GetCellvars() to Python 3.11.0rc1
|
||||
#if PY_VERSION_HEX < 0x030B00C1 && !defined(PYPY_VERSION)
|
||||
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
|
||||
PyCode_GetCellvars(PyCodeObject *code)
|
||||
{
|
||||
return Py_NewRef(code->co_cellvars);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Py_UNUSED() was added to Python 3.4.0b2.
|
||||
#if PY_VERSION_HEX < 0x030400B2 && !defined(Py_UNUSED)
|
||||
# if defined(__GNUC__) || defined(__clang__)
|
||||
# define Py_UNUSED(name) _unused_ ## name __attribute__((unused))
|
||||
# else
|
||||
# define Py_UNUSED(name) _unused_ ## name
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // PYTHONCAPI_COMPAT
|
||||
BIN
code/.venv/lib/python3.12/site-packages/bitarray/test_150.pickle
Normal file
BIN
code/.venv/lib/python3.12/site-packages/bitarray/test_150.pickle
Normal file
Binary file not shown.
BIN
code/.venv/lib/python3.12/site-packages/bitarray/test_281.pickle
Normal file
BIN
code/.venv/lib/python3.12/site-packages/bitarray/test_281.pickle
Normal file
Binary file not shown.
5157
code/.venv/lib/python3.12/site-packages/bitarray/test_bitarray.py
Normal file
5157
code/.venv/lib/python3.12/site-packages/bitarray/test_bitarray.py
Normal file
File diff suppressed because it is too large
Load Diff
2339
code/.venv/lib/python3.12/site-packages/bitarray/test_util.py
Normal file
2339
code/.venv/lib/python3.12/site-packages/bitarray/test_util.py
Normal file
File diff suppressed because it is too large
Load Diff
423
code/.venv/lib/python3.12/site-packages/bitarray/util.py
Normal file
423
code/.venv/lib/python3.12/site-packages/bitarray/util.py
Normal file
@@ -0,0 +1,423 @@
|
||||
# Copyright (c) 2019 - 2024, Ilan Schnell; All Rights Reserved
|
||||
# bitarray is published under the PSF license.
|
||||
#
|
||||
# Author: Ilan Schnell
|
||||
"""
|
||||
Useful utilities for working with bitarrays.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from bitarray import bitarray, bits2bytes
|
||||
|
||||
from bitarray._util import (
|
||||
zeros, ones, count_n, parity,
|
||||
count_and, count_or, count_xor, any_and, subset,
|
||||
_correspond_all,
|
||||
serialize, deserialize,
|
||||
ba2hex, hex2ba,
|
||||
ba2base, base2ba,
|
||||
sc_encode, sc_decode,
|
||||
vl_encode, vl_decode,
|
||||
canonical_decode,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
'zeros', 'ones', 'urandom',
|
||||
'pprint', 'make_endian', 'rindex', 'strip', 'count_n',
|
||||
'parity', 'count_and', 'count_or', 'count_xor', 'any_and', 'subset',
|
||||
'intervals',
|
||||
'ba2hex', 'hex2ba',
|
||||
'ba2base', 'base2ba',
|
||||
'ba2int', 'int2ba',
|
||||
'serialize', 'deserialize',
|
||||
'sc_encode', 'sc_decode',
|
||||
'vl_encode', 'vl_decode',
|
||||
'huffman_code', 'canonical_huffman', 'canonical_decode',
|
||||
]
|
||||
|
||||
|
||||
_is_py2 = bool(sys.version_info[0] == 2)
|
||||
|
||||
|
||||
def urandom(__length, endian=None):
|
||||
"""urandom(length, /, endian=None) -> bitarray
|
||||
|
||||
Return a bitarray of `length` random bits (uses `os.urandom`).
|
||||
"""
|
||||
a = bitarray(0, endian)
|
||||
a.frombytes(os.urandom(bits2bytes(__length)))
|
||||
del a[__length:]
|
||||
return a
|
||||
|
||||
|
||||
def rindex(__a, __sub_bitarray=1, __start=0, __stop=sys.maxsize):
|
||||
"""rindex(bitarray, sub_bitarray=1, start=0, stop=<end>, /) -> int
|
||||
|
||||
Return rightmost (highest) index where sub_bitarray (or item - defaults
|
||||
to 1) is found in bitarray (`a`), such that sub_bitarray is contained
|
||||
within `a[start:stop]`.
|
||||
Raises `ValueError` when the sub_bitarray is not present.
|
||||
"""
|
||||
from warnings import warn
|
||||
|
||||
warn("rindex() is deprecated and will be removed in bitarray 3.0 - "
|
||||
"use .index(..., right=True) method instead.",
|
||||
DeprecationWarning, stacklevel=1)
|
||||
|
||||
if not isinstance(__a, bitarray):
|
||||
raise TypeError("bitarray expected, got '%s'" % type(__a).__name__)
|
||||
|
||||
return __a.index(__sub_bitarray, __start, __stop, right=True)
|
||||
|
||||
|
||||
def pprint(__a, stream=None, group=8, indent=4, width=80):
|
||||
"""pprint(bitarray, /, stream=None, group=8, indent=4, width=80)
|
||||
|
||||
Prints the formatted representation of object on `stream` (which defaults
|
||||
to `sys.stdout`). By default, elements are grouped in bytes (8 elements),
|
||||
and 8 bytes (64 elements) per line.
|
||||
Non-bitarray objects are printed by the standard library
|
||||
function `pprint.pprint()`.
|
||||
"""
|
||||
if stream is None:
|
||||
stream = sys.stdout
|
||||
|
||||
if not isinstance(__a, bitarray):
|
||||
import pprint as _pprint
|
||||
_pprint.pprint(__a, stream=stream, indent=indent, width=width)
|
||||
return
|
||||
|
||||
group = int(group)
|
||||
if group < 1:
|
||||
raise ValueError('group must be >= 1')
|
||||
indent = int(indent)
|
||||
if indent < 0:
|
||||
raise ValueError('indent must be >= 0')
|
||||
width = int(width)
|
||||
if width <= indent:
|
||||
raise ValueError('width must be > %d (indent)' % indent)
|
||||
|
||||
gpl = (width - indent) // (group + 1) # groups per line
|
||||
epl = group * gpl # elements per line
|
||||
if epl == 0:
|
||||
epl = width - indent - 2
|
||||
type_name = type(__a).__name__
|
||||
# here 4 is len("'()'")
|
||||
multiline = len(type_name) + 4 + len(__a) + len(__a) // group >= width
|
||||
if multiline:
|
||||
quotes = "'''"
|
||||
elif __a:
|
||||
quotes = "'"
|
||||
else:
|
||||
quotes = ""
|
||||
|
||||
stream.write("%s(%s" % (type_name, quotes))
|
||||
for i, b in enumerate(__a):
|
||||
if multiline and i % epl == 0:
|
||||
stream.write('\n%s' % (indent * ' '))
|
||||
if i % group == 0 and i % epl != 0:
|
||||
stream.write(' ')
|
||||
stream.write(str(b))
|
||||
|
||||
if multiline:
|
||||
stream.write('\n')
|
||||
|
||||
stream.write("%s)\n" % quotes)
|
||||
stream.flush()
|
||||
|
||||
|
||||
def make_endian(__a, endian):
|
||||
"""make_endian(bitarray, /, endian) -> bitarray
|
||||
|
||||
When the endianness of the given bitarray is different from `endian`,
|
||||
return a new bitarray, with endianness `endian` and the same elements
|
||||
as the original bitarray.
|
||||
Otherwise (endianness is already `endian`) the original bitarray is returned
|
||||
unchanged.
|
||||
"""
|
||||
from warnings import warn
|
||||
|
||||
warn("make_endian() is deprecated and will be removed in bitarray 3.0 - "
|
||||
"use bitarray(..., endian=...) instead",
|
||||
DeprecationWarning, stacklevel=1)
|
||||
|
||||
if not isinstance(__a, bitarray):
|
||||
raise TypeError("bitarray expected, got '%s'" % type(__a).__name__)
|
||||
|
||||
if __a.endian() == endian:
|
||||
return __a
|
||||
|
||||
return bitarray(__a, endian)
|
||||
|
||||
|
||||
def strip(__a, mode='right'):
|
||||
"""strip(bitarray, /, mode='right') -> bitarray
|
||||
|
||||
Return a new bitarray with zeros stripped from left, right or both ends.
|
||||
Allowed values for mode are the strings: `left`, `right`, `both`
|
||||
"""
|
||||
if not isinstance(mode, str):
|
||||
raise TypeError("str expected for mode, got '%s'" % type(__a).__name__)
|
||||
if mode not in ('left', 'right', 'both'):
|
||||
raise ValueError("mode must be 'left', 'right' or 'both', got %r" %
|
||||
mode)
|
||||
|
||||
start = None if mode == 'right' else __a.find(1)
|
||||
if start == -1:
|
||||
return __a[:0]
|
||||
stop = None if mode == 'left' else __a.find(1, right=1) + 1
|
||||
return __a[start:stop]
|
||||
|
||||
|
||||
def intervals(__a):
|
||||
"""intervals(bitarray, /) -> iterator
|
||||
|
||||
Compute all uninterrupted intervals of 1s and 0s, and return an
|
||||
iterator over tuples `(value, start, stop)`. The intervals are guaranteed
|
||||
to be in order, and their size is always non-zero (`stop - start > 0`).
|
||||
"""
|
||||
try:
|
||||
value = __a[0] # value of current interval
|
||||
except IndexError:
|
||||
return
|
||||
n = len(__a)
|
||||
stop = 0 # "previous" stop - becomes next start
|
||||
|
||||
while stop < n:
|
||||
start = stop
|
||||
# assert __a[start] == value
|
||||
try: # find next occurrence of opposite value
|
||||
stop = __a.index(not value, start)
|
||||
except ValueError:
|
||||
stop = n
|
||||
yield int(value), start, stop
|
||||
value = not value # next interval has opposite value
|
||||
|
||||
|
||||
def ba2int(__a, signed=False):
|
||||
"""ba2int(bitarray, /, signed=False) -> int
|
||||
|
||||
Convert the given bitarray to an integer.
|
||||
The bit-endianness of the bitarray is respected.
|
||||
`signed` indicates whether two's complement is used to represent the integer.
|
||||
"""
|
||||
if not isinstance(__a, bitarray):
|
||||
raise TypeError("bitarray expected, got '%s'" % type(__a).__name__)
|
||||
length = len(__a)
|
||||
if length == 0:
|
||||
raise ValueError("non-empty bitarray expected")
|
||||
|
||||
le = bool(__a.endian() == 'little')
|
||||
if __a.padbits:
|
||||
pad = zeros(__a.padbits, __a.endian())
|
||||
__a = __a + pad if le else pad + __a
|
||||
|
||||
if _is_py2:
|
||||
a = bitarray(__a, 'big')
|
||||
if le:
|
||||
a.reverse()
|
||||
res = int(ba2hex(a), 16)
|
||||
else: # py3
|
||||
res = int.from_bytes(__a.tobytes(), byteorder=__a.endian())
|
||||
|
||||
if signed and res >= 1 << (length - 1):
|
||||
res -= 1 << length
|
||||
return res
|
||||
|
||||
|
||||
def int2ba(__i, length=None, endian=None, signed=False):
|
||||
"""int2ba(int, /, length=None, endian=None, signed=False) -> bitarray
|
||||
|
||||
Convert the given integer to a bitarray (with given endianness,
|
||||
and no leading (big-endian) / trailing (little-endian) zeros), unless
|
||||
the `length` of the bitarray is provided. An `OverflowError` is raised
|
||||
if the integer is not representable with the given number of bits.
|
||||
`signed` determines whether two's complement is used to represent the integer,
|
||||
and requires `length` to be provided.
|
||||
"""
|
||||
if not isinstance(__i, (int, long) if _is_py2 else int):
|
||||
raise TypeError("int expected, got '%s'" % type(__i).__name__)
|
||||
if length is not None:
|
||||
if not isinstance(length, int):
|
||||
raise TypeError("int expected for length")
|
||||
if length <= 0:
|
||||
raise ValueError("length must be > 0")
|
||||
if signed and length is None:
|
||||
raise TypeError("signed requires length")
|
||||
|
||||
if __i == 0:
|
||||
# there are special cases for 0 which we'd rather not deal with below
|
||||
return zeros(length or 1, endian)
|
||||
|
||||
if signed:
|
||||
m = 1 << (length - 1)
|
||||
if not (-m <= __i < m):
|
||||
raise OverflowError("signed integer not in range(%d, %d), "
|
||||
"got %d" % (-m, m, __i))
|
||||
if __i < 0:
|
||||
__i += 1 << length
|
||||
else: # unsigned
|
||||
if __i < 0:
|
||||
raise OverflowError("unsigned integer not positive, got %d" % __i)
|
||||
if length and __i >= (1 << length):
|
||||
raise OverflowError("unsigned integer not in range(0, %d), "
|
||||
"got %d" % (1 << length, __i))
|
||||
|
||||
a = bitarray(0, endian)
|
||||
le = bool(a.endian() == 'little')
|
||||
if _is_py2:
|
||||
s = hex(__i)[2:].rstrip('L')
|
||||
a.extend(hex2ba(s, 'big'))
|
||||
if le:
|
||||
a.reverse()
|
||||
else: # py3
|
||||
b = __i.to_bytes(bits2bytes(__i.bit_length()), byteorder=a.endian())
|
||||
a.frombytes(b)
|
||||
|
||||
if length is None:
|
||||
return strip(a, 'right' if le else 'left')
|
||||
|
||||
la = len(a)
|
||||
if la > length:
|
||||
a = a[:length] if le else a[-length:]
|
||||
if la < length:
|
||||
pad = zeros(length - la, a.endian())
|
||||
a = a + pad if le else pad + a
|
||||
assert len(a) == length
|
||||
return a
|
||||
|
||||
# ------------------------------ Huffman coding -----------------------------
|
||||
|
||||
def _huffman_tree(__freq_map):
|
||||
"""_huffman_tree(dict, /) -> Node
|
||||
|
||||
Given a dict mapping symbols to their frequency, construct a Huffman tree
|
||||
and return its root node.
|
||||
"""
|
||||
from heapq import heappush, heappop
|
||||
|
||||
class Node(object):
|
||||
"""
|
||||
A Node instance will either have a 'symbol' (leaf node) or
|
||||
a 'child' (a tuple with both children) attribute.
|
||||
The 'freq' attribute will always be present.
|
||||
"""
|
||||
def __lt__(self, other):
|
||||
# heapq needs to be able to compare the nodes
|
||||
return self.freq < other.freq
|
||||
|
||||
minheap = []
|
||||
# create all leaf nodes and push them onto the queue
|
||||
for sym, f in __freq_map.items():
|
||||
leaf = Node()
|
||||
leaf.symbol = sym
|
||||
leaf.freq = f
|
||||
heappush(minheap, leaf)
|
||||
|
||||
# repeat the process until only one node remains
|
||||
while len(minheap) > 1:
|
||||
# take the two nodes with lowest frequencies from the queue
|
||||
# to construct a new node and push it onto the queue
|
||||
parent = Node()
|
||||
parent.child = heappop(minheap), heappop(minheap)
|
||||
parent.freq = parent.child[0].freq + parent.child[1].freq
|
||||
heappush(minheap, parent)
|
||||
|
||||
# the single remaining node is the root of the Huffman tree
|
||||
return minheap[0]
|
||||
|
||||
|
||||
def huffman_code(__freq_map, endian=None):
|
||||
"""huffman_code(dict, /, endian=None) -> dict
|
||||
|
||||
Given a frequency map, a dictionary mapping symbols to their frequency,
|
||||
calculate the Huffman code, i.e. a dict mapping those symbols to
|
||||
bitarrays (with given endianness). Note that the symbols are not limited
|
||||
to being strings. Symbols may may be any hashable object (such as `None`).
|
||||
"""
|
||||
if not isinstance(__freq_map, dict):
|
||||
raise TypeError("dict expected, got '%s'" % type(__freq_map).__name__)
|
||||
|
||||
b0 = bitarray('0', endian)
|
||||
b1 = bitarray('1', endian)
|
||||
|
||||
if len(__freq_map) < 2:
|
||||
if len(__freq_map) == 0:
|
||||
raise ValueError("cannot create Huffman code with no symbols")
|
||||
# Only one symbol: Normally if only one symbol is given, the code
|
||||
# could be represented with zero bits. However here, the code should
|
||||
# be at least one bit for the .encode() and .decode() methods to work.
|
||||
# So we represent the symbol by a single code of length one, in
|
||||
# particular one 0 bit. This is an incomplete code, since if a 1 bit
|
||||
# is received, it has no meaning and will result in an error.
|
||||
return {list(__freq_map)[0]: b0}
|
||||
|
||||
result = {}
|
||||
|
||||
def traverse(nd, prefix=bitarray(0, endian)):
|
||||
try: # leaf
|
||||
result[nd.symbol] = prefix
|
||||
except AttributeError: # parent, so traverse each of the children
|
||||
traverse(nd.child[0], prefix + b0)
|
||||
traverse(nd.child[1], prefix + b1)
|
||||
|
||||
traverse(_huffman_tree(__freq_map))
|
||||
return result
|
||||
|
||||
|
||||
def canonical_huffman(__freq_map):
|
||||
"""canonical_huffman(dict, /) -> tuple
|
||||
|
||||
Given a frequency map, a dictionary mapping symbols to their frequency,
|
||||
calculate the canonical Huffman code. Returns a tuple containing:
|
||||
|
||||
0. the canonical Huffman code as a dict mapping symbols to bitarrays
|
||||
1. a list containing the number of symbols of each code length
|
||||
2. a list of symbols in canonical order
|
||||
|
||||
Note: the two lists may be used as input for `canonical_decode()`.
|
||||
"""
|
||||
if not isinstance(__freq_map, dict):
|
||||
raise TypeError("dict expected, got '%s'" % type(__freq_map).__name__)
|
||||
|
||||
if len(__freq_map) < 2:
|
||||
if len(__freq_map) == 0:
|
||||
raise ValueError("cannot create Huffman code with no symbols")
|
||||
# Only one symbol: see note above in huffman_code()
|
||||
sym = list(__freq_map)[0]
|
||||
return {sym: bitarray('0', 'big')}, [0, 1], [sym]
|
||||
|
||||
code_length = {} # map symbols to their code length
|
||||
|
||||
def traverse(nd, length=0):
|
||||
# traverse the Huffman tree, but (unlike in huffman_code() above) we
|
||||
# now just simply record the length for reaching each symbol
|
||||
try: # leaf
|
||||
code_length[nd.symbol] = length
|
||||
except AttributeError: # parent, so traverse each of the children
|
||||
traverse(nd.child[0], length + 1)
|
||||
traverse(nd.child[1], length + 1)
|
||||
|
||||
traverse(_huffman_tree(__freq_map))
|
||||
|
||||
# we now have a mapping of symbols to their code length,
|
||||
# which is all we need
|
||||
|
||||
table = sorted(code_length.items(), key=lambda item: (item[1], item[0]))
|
||||
|
||||
maxbits = max(item[1] for item in table)
|
||||
codedict = {}
|
||||
count = (maxbits + 1) * [0]
|
||||
|
||||
code = 0
|
||||
for i, (sym, length) in enumerate(table):
|
||||
codedict[sym] = int2ba(code, length, 'big')
|
||||
count[length] += 1
|
||||
if i + 1 < len(table):
|
||||
code += 1
|
||||
code <<= table[i + 1][1] - length
|
||||
|
||||
return codedict, count, [item[0] for item in table]
|
||||
71
code/.venv/lib/python3.12/site-packages/bitarray/util.pyi
Normal file
71
code/.venv/lib/python3.12/site-packages/bitarray/util.pyi
Normal file
@@ -0,0 +1,71 @@
|
||||
# Copyright (c) 2021 - 2024, Ilan Schnell; All Rights Reserved
|
||||
|
||||
from collections import Counter
|
||||
from collections.abc import Iterable, Iterator, Sequence
|
||||
from typing import Any, AnyStr, BinaryIO, Optional, Union
|
||||
|
||||
from bitarray import bitarray, BytesLike, CodeDict
|
||||
|
||||
|
||||
FreqMap = Union[Counter[int], dict[Any, Union[int, float]]]
|
||||
|
||||
|
||||
def zeros(length: int, endian: Optional[str] = ...) -> bitarray: ...
|
||||
def ones(length: int, endian: Optional[str] = ...) -> bitarray: ...
|
||||
|
||||
def urandom(length: int, endian: Optional[str] = ...) -> bitarray: ...
|
||||
def pprint(a: Any, stream: BinaryIO = ...,
|
||||
group: int = ...,
|
||||
indent: int = ...,
|
||||
width: int = ...) -> None: ...
|
||||
|
||||
def make_endian(a: bitarray, endian: str) -> bitarray: ...
|
||||
def rindex(a: bitarray,
|
||||
sub_bitarray: Union[bitarray, int] = ...,
|
||||
start: int = ...,
|
||||
stop: int = ...) -> int: ...
|
||||
|
||||
def strip(a: bitarray, mode: str = ...) -> bitarray: ...
|
||||
|
||||
def count_n(a: bitarray,
|
||||
n: int,
|
||||
value: int = ...) -> int: ...
|
||||
|
||||
def parity(a: bitarray) -> int: ...
|
||||
def count_and(a: bitarray, b: bitarray) -> int: ...
|
||||
def count_or(a: bitarray, b: bitarray) -> int: ...
|
||||
def count_xor(a: bitarray, b: bitarray) -> int: ...
|
||||
def any_and(a: bitarray, b: bitarray) -> bool: ...
|
||||
def subset(a: bitarray, b: bitarray) -> bool: ...
|
||||
def _correspond_all(a: bitarray, b: bitarray) -> tuple: ...
|
||||
|
||||
def intervals(a: bitarray) -> Iterator: ...
|
||||
|
||||
def ba2hex(a: bitarray) -> str: ...
|
||||
def hex2ba(s: AnyStr, endian: Optional[str] = ...) -> bitarray: ...
|
||||
def ba2base(n: int, a: bitarray) -> str: ...
|
||||
def base2ba(n: int,
|
||||
s: AnyStr,
|
||||
endian: Optional[str] = ...) -> bitarray: ...
|
||||
|
||||
def ba2int(a: bitarray, signed: int = ...) -> int: ...
|
||||
def int2ba(i: int,
|
||||
length: int = ...,
|
||||
endian: str = ...,
|
||||
signed: int = ...) -> bitarray: ...
|
||||
|
||||
def serialize(a: bitarray) -> bytes: ...
|
||||
def deserialize(b: BytesLike) -> bitarray: ...
|
||||
def sc_encode(a: bitarray) -> bytes: ...
|
||||
def sc_decode(stream: BytesLike) -> bitarray: ...
|
||||
def vl_encode(a: bitarray) -> bytes: ...
|
||||
def vl_decode(stream: BytesLike,
|
||||
endian: Optional[str] = ...) -> bitarray: ...
|
||||
|
||||
def _huffman_tree(freq_map: FreqMap) -> Any: ...
|
||||
def huffman_code(freq_map: FreqMap,
|
||||
endian: Optional[str] = ...) -> CodeDict: ...
|
||||
def canonical_huffman(Freq_Map) -> tuple[CodeDict, list, list]: ...
|
||||
def canonical_decode(a: bitarray,
|
||||
count: Sequence[int],
|
||||
symbol: Iterable[Any]) -> Iterator: ...
|
||||
@@ -0,0 +1 @@
|
||||
pip
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2006 Scott Griffiths (dr.scottgriffiths@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -0,0 +1,133 @@
|
||||
Metadata-Version: 2.1
|
||||
Name: bitstring
|
||||
Version: 4.2.3
|
||||
Summary: Simple construction, analysis and modification of binary data.
|
||||
Author-email: Scott Griffiths <dr.scottgriffiths@gmail.com>
|
||||
Project-URL: homepage, https://github.com/scott-griffiths/bitstring
|
||||
Project-URL: documentation, https://bitstring.readthedocs.io/
|
||||
Keywords: binary,bitarray,bitvector,bitfield
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.8
|
||||
Classifier: Programming Language :: Python :: 3.9
|
||||
Classifier: Programming Language :: Python :: 3.10
|
||||
Classifier: Programming Language :: Python :: 3.11
|
||||
Classifier: Programming Language :: Python :: 3.12
|
||||
Classifier: License :: OSI Approved :: MIT License
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||
Requires-Python: >=3.8
|
||||
Description-Content-Type: text/markdown
|
||||
License-File: LICENSE
|
||||
Requires-Dist: bitarray <3.0.0,>=2.9.0
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
**bitstring** is a Python module to help make the creation and analysis of all types of bit-level binary data as simple and efficient as possible.
|
||||
|
||||
It has been actively maintained since 2006.
|
||||
|
||||
|
||||
|
||||
[](https://github.com/scott-griffiths/bitstring/actions/workflows/ci.yml)
|
||||
[](https://bitstring.readthedocs.io/en/latest/)
|
||||
[](https://app.codacy.com/gh/scott-griffiths/bitstring/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
|
||||
[](https://libraries.io/pypi/bitstring)
|
||||
|
||||
[](https://www.pepy.tech/projects/bitstring)
|
||||
[](https://pypistats.org/packages/bitstring)
|
||||
|
||||
----
|
||||
|
||||
> [!NOTE]
|
||||
> To see what been added, improved or fixed, and also to see what's coming in the next version, see the [release notes](https://github.com/scott-griffiths/bitstring/blob/main/release_notes.md).
|
||||
|
||||
|
||||
# Overview
|
||||
|
||||
* Efficiently store and manipulate binary data in idiomatic Python.
|
||||
* Create bitstrings from hex, octal, binary, files, formatted strings, bytes, integers and floats of different endiannesses.
|
||||
* Powerful binary packing and unpacking functions.
|
||||
* Bit-level slicing, joining, searching, replacing and more.
|
||||
* Create and manipulate arrays of fixed-length bitstrings.
|
||||
* Read from and interpret bitstrings as streams of binary data.
|
||||
* Rich API - chances are that whatever you want to do there's a simple and elegant way of doing it.
|
||||
* Open source software, released under the MIT licence.
|
||||
|
||||
# Documentation
|
||||
|
||||
Extensive documentation for the bitstring module is available.
|
||||
Some starting points are given below:
|
||||
|
||||
* [Overview](https://bitstring.readthedocs.io/en/stable/index.html)
|
||||
* [Quick Reference](https://bitstring.readthedocs.io/en/stable/quick_reference.html)
|
||||
* [Full Reference](https://bitstring.readthedocs.io/en/stable/reference.html)
|
||||
|
||||
There is also an introductory walkthrough notebook on [binder](https://mybinder.org/v2/gh/scott-griffiths/bitstring/main?labpath=doc%2Fwalkthrough.ipynb).
|
||||
|
||||
# Examples
|
||||
|
||||
### Installation
|
||||
```
|
||||
$ pip install bitstring
|
||||
```
|
||||
|
||||
### Creation
|
||||
```pycon
|
||||
>>> from bitstring import Bits, BitArray, BitStream, pack
|
||||
>>> a = BitArray(bin='00101')
|
||||
>>> b = Bits(a_file_object)
|
||||
>>> c = BitArray('0xff, 0b101, 0o65, uint6=22')
|
||||
>>> d = pack('intle16, hex=a, 0b1', 100, a='0x34f')
|
||||
>>> e = pack('<16h', *range(16))
|
||||
```
|
||||
|
||||
### Different interpretations, slicing and concatenation
|
||||
```pycon
|
||||
>>> a = BitArray('0x3348')
|
||||
>>> a.hex, a.bin, a.uint, a.float, a.bytes
|
||||
('3348', '0011001101001000', 13128, 0.2275390625, b'3H')
|
||||
>>> a[10:3:-1].bin
|
||||
'0101100'
|
||||
>>> '0b100' + 3*a
|
||||
BitArray('0x866906690669, 0b000')
|
||||
```
|
||||
|
||||
### Reading data sequentially
|
||||
```pycon
|
||||
>>> b = BitStream('0x160120f')
|
||||
>>> b.read(12).hex
|
||||
'160'
|
||||
>>> b.pos = 0
|
||||
>>> b.read('uint12')
|
||||
352
|
||||
>>> b.readlist('uint12, bin3')
|
||||
[288, '111']
|
||||
```
|
||||
|
||||
### Searching, inserting and deleting
|
||||
```pycon
|
||||
>>> c = BitArray('0b00010010010010001111') # c.hex == '0x1248f'
|
||||
>>> c.find('0x48')
|
||||
(8,)
|
||||
>>> c.replace('0b001', '0xabc')
|
||||
>>> c.insert('0b0000', pos=3)
|
||||
>>> del c[12:16]
|
||||
```
|
||||
|
||||
### Arrays of fixed-length formats
|
||||
```pycon
|
||||
>>> from bitstring import Array
|
||||
>>> a = Array('uint7', [9, 100, 3, 1])
|
||||
>>> a.data
|
||||
BitArray('0x1390181')
|
||||
>>> a[::2] *= 5
|
||||
>>> a
|
||||
Array('uint7', [45, 100, 15, 1])
|
||||
```
|
||||
|
||||
|
||||
<sub>Copyright (c) 2006 - 2024 Scott Griffiths</sub>
|
||||
@@ -0,0 +1,39 @@
|
||||
bitstring-4.2.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
bitstring-4.2.3.dist-info/LICENSE,sha256=NwXu1akj812b-sofEOkTbMhNbldlcK7GYb2mmZHxKeo,1106
|
||||
bitstring-4.2.3.dist-info/METADATA,sha256=aUUR8ljmKXchDLSPxTGzHot_7Wi659yUYUWS5Zi-3Ek,5017
|
||||
bitstring-4.2.3.dist-info/RECORD,,
|
||||
bitstring-4.2.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
||||
bitstring-4.2.3.dist-info/top_level.txt,sha256=9Xh4qfKH0fMhwxzzkSBk3uzTRGiYPPM1FuYFAgCB-ks,10
|
||||
bitstring/__init__.py,sha256=GjT0V01IeR3DBanzVa5utd4csONZx-PUSr6H0fuXnNU,13899
|
||||
bitstring/__main__.py,sha256=Lg6ARiAqKssp_uj1msYpiTGDybhJRshQmeftQ-yTpc0,1658
|
||||
bitstring/__pycache__/__init__.cpython-312.pyc,,
|
||||
bitstring/__pycache__/__main__.cpython-312.pyc,,
|
||||
bitstring/__pycache__/array_.cpython-312.pyc,,
|
||||
bitstring/__pycache__/bitarray_.cpython-312.pyc,,
|
||||
bitstring/__pycache__/bits.cpython-312.pyc,,
|
||||
bitstring/__pycache__/bitstore.cpython-312.pyc,,
|
||||
bitstring/__pycache__/bitstore_helpers.cpython-312.pyc,,
|
||||
bitstring/__pycache__/bitstream.cpython-312.pyc,,
|
||||
bitstring/__pycache__/bitstring_options.cpython-312.pyc,,
|
||||
bitstring/__pycache__/dtypes.cpython-312.pyc,,
|
||||
bitstring/__pycache__/exceptions.cpython-312.pyc,,
|
||||
bitstring/__pycache__/fp8.cpython-312.pyc,,
|
||||
bitstring/__pycache__/luts.cpython-312.pyc,,
|
||||
bitstring/__pycache__/methods.cpython-312.pyc,,
|
||||
bitstring/__pycache__/mxfp.cpython-312.pyc,,
|
||||
bitstring/__pycache__/utils.cpython-312.pyc,,
|
||||
bitstring/array_.py,sha256=d4vuZAc0ecJC95RD5_WPApehyH-ZGms4pcxl2I0R90I,36201
|
||||
bitstring/bitarray_.py,sha256=kZTVYBo32vQuhQ4TZQldQkqRE5OMPVoKCoxEfKOTg8U,22319
|
||||
bitstring/bits.py,sha256=N2bszuYM_WrTfqx-5-m56Vu_XgPZLeTta4xysBqCSYs,76754
|
||||
bitstring/bitstore.py,sha256=jHk1cwBPqCJoYq2TEgIE37u_7K8HZq5K0L__X8edMgc,10337
|
||||
bitstring/bitstore_helpers.py,sha256=6UHBomeOZlfQmY_Wa17U1zi7FBo73n2D9GPPmPztIrk,9107
|
||||
bitstring/bitstream.py,sha256=Hu1ZpcCeP6lfpJiKAwKoJI22A-vsKATN1F2RvnS3rFY,29017
|
||||
bitstring/bitstring_options.py,sha256=54Io4xLDylwXdRQpb12eNkSpSXQhRTW9Aidx7G42h7w,3560
|
||||
bitstring/dtypes.py,sha256=oBrcavnz15vaBZ_GOVm0tOaW6Ml0oXoz8RyZSyqG6Zo,16897
|
||||
bitstring/exceptions.py,sha256=7O3oVJJgvUOadqIzg6U-8fUGyOTu_lmjbMtX3yPc18o,553
|
||||
bitstring/fp8.py,sha256=8CIiGlijn9OmBwdpJOl-1oVPUY6qVL2jGl1N8u8LjAg,3768
|
||||
bitstring/luts.py,sha256=KPuXC9MvTOQSOlb0bFBKbnuxXuVBYlhaFEdIgSrwtzs,27072
|
||||
bitstring/methods.py,sha256=3JM4jo8B6r3xQYY2nvbibmf7byQYTHTZye0F8D2lF10,4351
|
||||
bitstring/mxfp.py,sha256=IxXK0SZy5RTD883YwATg6tlqVfl1uCFQplp5BVBwx9Q,9058
|
||||
bitstring/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
bitstring/utils.py,sha256=tuWHppQUcCVLbtrZoO7eUkpNk6pJLtsOZT7QdWADW78,9221
|
||||
@@ -0,0 +1,5 @@
|
||||
Wheel-Version: 1.0
|
||||
Generator: bdist_wheel (0.43.0)
|
||||
Root-Is-Purelib: true
|
||||
Tag: py3-none-any
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
bitstring
|
||||
337
code/.venv/lib/python3.12/site-packages/bitstring/__init__.py
Normal file
337
code/.venv/lib/python3.12/site-packages/bitstring/__init__.py
Normal file
@@ -0,0 +1,337 @@
|
||||
#!/usr/bin/env python
|
||||
r"""
|
||||
This package defines classes that simplify bit-wise creation, manipulation and
|
||||
interpretation of data.
|
||||
|
||||
Classes:
|
||||
|
||||
Bits -- An immutable container for binary data.
|
||||
BitArray -- A mutable container for binary data.
|
||||
ConstBitStream -- An immutable container with streaming methods.
|
||||
BitStream -- A mutable container with streaming methods.
|
||||
Array -- An efficient list-like container where each item has a fixed-length binary format.
|
||||
Dtype -- Encapsulate the data types used in the other classes.
|
||||
|
||||
Functions:
|
||||
|
||||
pack -- Create a BitStream from a format string.
|
||||
|
||||
Data:
|
||||
|
||||
options -- Module-wide options.
|
||||
|
||||
Exceptions:
|
||||
|
||||
Error -- Module exception base class.
|
||||
CreationError -- Error during creation.
|
||||
InterpretError -- Inappropriate interpretation of binary data.
|
||||
ByteAlignError -- Whole byte position or length needed.
|
||||
ReadError -- Reading or peeking past the end of a bitstring.
|
||||
|
||||
https://github.com/scott-griffiths/bitstring
|
||||
"""
|
||||
|
||||
__licence__ = """
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2006 Scott Griffiths (dr.scottgriffiths@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
|
||||
__version__ = "4.2.3"
|
||||
|
||||
__author__ = "Scott Griffiths"
|
||||
|
||||
import sys
|
||||
|
||||
from .bits import Bits
|
||||
from .bitstring_options import Options
|
||||
from .bitarray_ import BitArray
|
||||
from .bitstream import ConstBitStream, BitStream
|
||||
from .methods import pack
|
||||
from .array_ import Array
|
||||
from .exceptions import Error, ReadError, InterpretError, ByteAlignError, CreationError
|
||||
from .dtypes import DtypeDefinition, dtype_register, Dtype
|
||||
import types
|
||||
from typing import List, Tuple, Literal
|
||||
from .mxfp import decompress_luts as mxfp_decompress_luts
|
||||
from .fp8 import decompress_luts as binary8_decompress_luts
|
||||
|
||||
# Decompress the LUTs for the exotic floating point formats
|
||||
mxfp_decompress_luts()
|
||||
binary8_decompress_luts()
|
||||
|
||||
# The Options class returns a singleton.
|
||||
options = Options()
|
||||
|
||||
# These get defined properly by the module magic below. This just stops mypy complaining about them.
|
||||
bytealigned = lsb0 = None
|
||||
|
||||
|
||||
# An opaque way of adding module level properties. Taken from https://peps.python.org/pep-0549/
|
||||
# This is now deprecated. Use the options object directly instead.
|
||||
class _MyModuleType(types.ModuleType):
|
||||
@property
|
||||
def bytealigned(self) -> bool:
|
||||
"""Determines whether a number of methods default to working only on byte boundaries."""
|
||||
return options.bytealigned
|
||||
|
||||
@bytealigned.setter
|
||||
def bytealigned(self, value: bool) -> None:
|
||||
"""Determines whether a number of methods default to working only on byte boundaries."""
|
||||
options.bytealigned = value
|
||||
|
||||
@property
|
||||
def lsb0(self) -> bool:
|
||||
"""If True, the least significant bit (the final bit) is indexed as bit zero."""
|
||||
return options.lsb0
|
||||
|
||||
@lsb0.setter
|
||||
def lsb0(self, value: bool) -> None:
|
||||
"""If True, the least significant bit (the final bit) is indexed as bit zero."""
|
||||
options.lsb0 = value
|
||||
|
||||
|
||||
sys.modules[__name__].__class__ = _MyModuleType
|
||||
|
||||
|
||||
# These methods convert a bit length to the number of characters needed to print it for different interpretations.
|
||||
def hex_bits2chars(bitlength: int):
|
||||
# One character for every 4 bits
|
||||
return bitlength // 4
|
||||
|
||||
|
||||
def oct_bits2chars(bitlength: int):
|
||||
# One character for every 3 bits
|
||||
return bitlength // 3
|
||||
|
||||
|
||||
def bin_bits2chars(bitlength: int):
|
||||
# One character for each bit
|
||||
return bitlength
|
||||
|
||||
|
||||
def bytes_bits2chars(bitlength: int):
|
||||
# One character for every 8 bits
|
||||
return bitlength // 8
|
||||
|
||||
|
||||
def uint_bits2chars(bitlength: int):
|
||||
# How many characters is largest possible int of this length?
|
||||
return len(str((1 << bitlength) - 1))
|
||||
|
||||
|
||||
def int_bits2chars(bitlength: int):
|
||||
# How many characters is largest negative int of this length? (To include minus sign).
|
||||
return len(str((-1 << (bitlength - 1))))
|
||||
|
||||
|
||||
def float_bits2chars(bitlength: Literal[16, 32, 64]):
|
||||
# These bit lengths were found by looking at lots of possible values
|
||||
if bitlength in [16, 32]:
|
||||
return 23 # Empirical value
|
||||
else:
|
||||
return 24 # Empirical value
|
||||
|
||||
|
||||
def p3binary_bits2chars(_: Literal[8]):
|
||||
return 19 # Empirical value
|
||||
|
||||
|
||||
def p4binary_bits2chars(_: Literal[8]):
|
||||
# Found by looking at all the possible values
|
||||
return 13 # Empirical value
|
||||
|
||||
|
||||
def e4m3mxfp_bits2chars(_: Literal[8]):
|
||||
return 13
|
||||
|
||||
|
||||
def e5m2mxfp_bits2chars(_: Literal[8]):
|
||||
return 19
|
||||
|
||||
|
||||
def e3m2mxfp_bits2chars(_: Literal[6]):
|
||||
# Not sure what the best value is here. It's 7 without considering the scale that could be applied.
|
||||
return 7
|
||||
|
||||
|
||||
def e2m3mxfp_bits2chars(_: Literal[6]):
|
||||
# Not sure what the best value is here.
|
||||
return 7
|
||||
|
||||
|
||||
def e2m1mxfp_bits2chars(_: Literal[4]):
|
||||
# Not sure what the best value is here.
|
||||
return 7
|
||||
|
||||
|
||||
def e8m0mxfp_bits2chars(_: Literal[8]):
|
||||
# Has same range as float32
|
||||
return 23
|
||||
|
||||
|
||||
def mxint_bits2chars(_: Literal[8]):
|
||||
# Not sure what the best value is here.
|
||||
return 10
|
||||
|
||||
|
||||
def bfloat_bits2chars(_: Literal[16]):
|
||||
# Found by looking at all the possible values
|
||||
return 23 # Empirical value
|
||||
|
||||
|
||||
def bits_bits2chars(bitlength: int):
|
||||
# For bits type we can see how long it needs to be printed by trying any value
|
||||
temp = Bits(bitlength)
|
||||
return len(str(temp))
|
||||
|
||||
|
||||
def bool_bits2chars(_: Literal[1]):
|
||||
# Bools are printed as 1 or 0, not True or False, so are one character each
|
||||
return 1
|
||||
|
||||
|
||||
dtype_definitions = [
|
||||
# Integer types
|
||||
DtypeDefinition('uint', Bits._setuint, Bits._getuint, int, False, uint_bits2chars,
|
||||
description="a two's complement unsigned int"),
|
||||
DtypeDefinition('uintle', Bits._setuintle, Bits._getuintle, int, False, uint_bits2chars,
|
||||
allowed_lengths=(8, 16, 24, ...), description="a two's complement little-endian unsigned int"),
|
||||
DtypeDefinition('uintbe', Bits._setuintbe, Bits._getuintbe, int, False, uint_bits2chars,
|
||||
allowed_lengths=(8, 16, 24, ...), description="a two's complement big-endian unsigned int"),
|
||||
DtypeDefinition('int', Bits._setint, Bits._getint, int, True, int_bits2chars,
|
||||
description="a two's complement signed int"),
|
||||
DtypeDefinition('intle', Bits._setintle, Bits._getintle, int, True, int_bits2chars,
|
||||
allowed_lengths=(8, 16, 24, ...), description="a two's complement little-endian signed int"),
|
||||
DtypeDefinition('intbe', Bits._setintbe, Bits._getintbe, int, True, int_bits2chars,
|
||||
allowed_lengths=(8, 16, 24, ...), description="a two's complement big-endian signed int"),
|
||||
# String types
|
||||
DtypeDefinition('hex', Bits._sethex, Bits._gethex, str, False, hex_bits2chars,
|
||||
allowed_lengths=(0, 4, 8, ...), description="a hexadecimal string"),
|
||||
DtypeDefinition('bin', Bits._setbin_safe, Bits._getbin, str, False, bin_bits2chars,
|
||||
description="a binary string"),
|
||||
DtypeDefinition('oct', Bits._setoct, Bits._getoct, str, False, oct_bits2chars,
|
||||
allowed_lengths=(0, 3, 6, ...), description="an octal string"),
|
||||
# Float types
|
||||
DtypeDefinition('float', Bits._setfloatbe, Bits._getfloatbe, float, True, float_bits2chars,
|
||||
allowed_lengths=(16, 32, 64), description="a big-endian floating point number"),
|
||||
DtypeDefinition('floatle', Bits._setfloatle, Bits._getfloatle, float, True, float_bits2chars,
|
||||
allowed_lengths=(16, 32, 64), description="a little-endian floating point number"),
|
||||
DtypeDefinition('bfloat', Bits._setbfloatbe, Bits._getbfloatbe, float, True, bfloat_bits2chars,
|
||||
allowed_lengths=(16,), description="a 16 bit big-endian bfloat floating point number"),
|
||||
DtypeDefinition('bfloatle', Bits._setbfloatle, Bits._getbfloatle, float, True, bfloat_bits2chars,
|
||||
allowed_lengths=(16,), description="a 16 bit little-endian bfloat floating point number"),
|
||||
# Other known length types
|
||||
DtypeDefinition('bits', Bits._setbits, Bits._getbits, Bits, False, bits_bits2chars,
|
||||
description="a bitstring object"),
|
||||
DtypeDefinition('bool', Bits._setbool, Bits._getbool, bool, False, bool_bits2chars,
|
||||
allowed_lengths=(1,), description="a bool (True or False)"),
|
||||
DtypeDefinition('bytes', Bits._setbytes, Bits._getbytes, bytes, False, bytes_bits2chars,
|
||||
multiplier=8, description="a bytes object"),
|
||||
# Unknown length types
|
||||
DtypeDefinition('se', Bits._setse, Bits._getse, int, True, None,
|
||||
variable_length=True, description="a signed exponential-Golomb code"),
|
||||
DtypeDefinition('ue', Bits._setue, Bits._getue, int, False, None,
|
||||
variable_length=True, description="an unsigned exponential-Golomb code"),
|
||||
DtypeDefinition('sie', Bits._setsie, Bits._getsie, int, True, None,
|
||||
variable_length=True, description="a signed interleaved exponential-Golomb code"),
|
||||
DtypeDefinition('uie', Bits._setuie, Bits._getuie, int, False, None,
|
||||
variable_length=True, description="an unsigned interleaved exponential-Golomb code"),
|
||||
# Special case pad type
|
||||
DtypeDefinition('pad', Bits._setpad, Bits._getpad, None, False, None,
|
||||
description="a skipped section of padding"),
|
||||
|
||||
# MXFP and IEEE 8-bit float types
|
||||
DtypeDefinition('p3binary', Bits._setp3binary, Bits._getp3binary, float, True, p3binary_bits2chars,
|
||||
allowed_lengths=(8,), description="an 8 bit float with binary8p3 format"),
|
||||
DtypeDefinition('p4binary', Bits._setp4binary, Bits._getp4binary, float, True, p4binary_bits2chars,
|
||||
allowed_lengths=(8,), description="an 8 bit float with binary8p4 format"),
|
||||
DtypeDefinition('e4m3mxfp', Bits._sete4m3mxfp, Bits._gete4m3mxfp, float, True, e4m3mxfp_bits2chars,
|
||||
allowed_lengths=(8,), description="an 8 bit float with MXFP E4M3 format"),
|
||||
DtypeDefinition('e5m2mxfp', Bits._sete5m2mxfp, Bits._gete5m2mxfp, float, True, e5m2mxfp_bits2chars,
|
||||
allowed_lengths=(8,), description="an 8 bit float with MXFP E5M2 format"),
|
||||
DtypeDefinition('e3m2mxfp', Bits._sete3m2mxfp, Bits._gete3m2mxfp, float, True, e3m2mxfp_bits2chars,
|
||||
allowed_lengths=(6,), description="a 6 bit float with MXFP E3M2 format"),
|
||||
DtypeDefinition('e2m3mxfp', Bits._sete2m3mxfp, Bits._gete2m3mxfp, float, True, e2m3mxfp_bits2chars,
|
||||
allowed_lengths=(6,), description="a 6 bit float with MXFP E2M3 format"),
|
||||
DtypeDefinition('e2m1mxfp', Bits._sete2m1mxfp, Bits._gete2m1mxfp, float, True, e2m1mxfp_bits2chars,
|
||||
allowed_lengths=(4,), description="a 4 bit float with MXFP E2M1 format"),
|
||||
DtypeDefinition('e8m0mxfp', Bits._sete8m0mxfp, Bits._gete8m0mxfp, float, False, e8m0mxfp_bits2chars,
|
||||
allowed_lengths=(8,), description="an 8 bit float with MXFP E8M0 format"),
|
||||
DtypeDefinition('mxint', Bits._setmxint, Bits._getmxint, float, True, mxint_bits2chars,
|
||||
allowed_lengths=(8,), description="an 8 bit float with MXFP INT8 format"),
|
||||
]
|
||||
|
||||
|
||||
aliases: List[Tuple[str, str]] = [
|
||||
# Floats default to big endian
|
||||
('float', 'floatbe'),
|
||||
('bfloat', 'bfloatbe'),
|
||||
|
||||
# Some single letter aliases for popular types
|
||||
('int', 'i'),
|
||||
('uint', 'u'),
|
||||
('hex', 'h'),
|
||||
('oct', 'o'),
|
||||
('bin', 'b'),
|
||||
('float', 'f'),
|
||||
]
|
||||
|
||||
# Create native-endian aliases depending on the byteorder of the system
|
||||
byteorder: str = sys.byteorder
|
||||
if byteorder == 'little':
|
||||
aliases.extend([
|
||||
('uintle', 'uintne'),
|
||||
('intle', 'intne'),
|
||||
('floatle', 'floatne'),
|
||||
('bfloatle', 'bfloatne'),
|
||||
])
|
||||
else:
|
||||
aliases.extend([
|
||||
('uintbe', 'uintne'),
|
||||
('intbe', 'intne'),
|
||||
('floatbe', 'floatne'),
|
||||
('bfloatbe', 'bfloatne'),
|
||||
])
|
||||
|
||||
|
||||
for dt in dtype_definitions:
|
||||
dtype_register.add_dtype(dt)
|
||||
for alias in aliases:
|
||||
dtype_register.add_dtype_alias(alias[0], alias[1])
|
||||
|
||||
property_docstrings = [f'{name} -- Interpret as {dtype_register[name].description}.' for name in dtype_register.names]
|
||||
property_docstring = '\n '.join(property_docstrings)
|
||||
|
||||
# We can't be sure the docstrings are present, as it might be compiled without docstrings.
|
||||
if Bits.__doc__ is not None:
|
||||
Bits.__doc__ = Bits.__doc__.replace('[GENERATED_PROPERTY_DESCRIPTIONS]', property_docstring)
|
||||
if BitArray.__doc__ is not None:
|
||||
BitArray.__doc__ = BitArray.__doc__.replace('[GENERATED_PROPERTY_DESCRIPTIONS]', property_docstring)
|
||||
if ConstBitStream.__doc__ is not None:
|
||||
ConstBitStream.__doc__ = ConstBitStream.__doc__.replace('[GENERATED_PROPERTY_DESCRIPTIONS]', property_docstring)
|
||||
if BitStream.__doc__ is not None:
|
||||
BitStream.__doc__ = BitStream.__doc__.replace('[GENERATED_PROPERTY_DESCRIPTIONS]', property_docstring)
|
||||
|
||||
|
||||
__all__ = ['ConstBitStream', 'BitStream', 'BitArray', 'Array',
|
||||
'Bits', 'pack', 'Error', 'ReadError', 'InterpretError',
|
||||
'ByteAlignError', 'CreationError', 'bytealigned', 'lsb0', 'Dtype', 'options']
|
||||
@@ -0,0 +1,50 @@
|
||||
import sys
|
||||
from bitstring.bits import Bits
|
||||
from bitstring.dtypes import Register
|
||||
|
||||
dtype_register = Register()
|
||||
|
||||
|
||||
def main() -> None:
|
||||
# check if final parameter is an interpretation string
|
||||
fp = sys.argv[-1]
|
||||
if fp in ['-h', '--help'] or len(sys.argv) == 1:
|
||||
print("""Create and interpret a bitstring from command-line parameters.
|
||||
|
||||
Command-line parameters are concatenated and a bitstring created
|
||||
from them. If the final parameter is either an interpretation string
|
||||
or ends with a '.' followed by an interpretation string then that
|
||||
interpretation of the bitstring will be used when printing it.
|
||||
|
||||
Typical usage might be invoking the Python module from a console
|
||||
as a one-off calculation:
|
||||
|
||||
$ python -m bitstring int:16=-400
|
||||
0xfe70
|
||||
$ python -m bitstring float:32=0.2 bin
|
||||
00111110010011001100110011001101
|
||||
$ python -m bitstring 0xff 3*0b01,0b11 uint
|
||||
65367
|
||||
$ python -m bitstring hex=01, uint:12=352.hex
|
||||
01160
|
||||
""")
|
||||
return
|
||||
if fp in dtype_register.names:
|
||||
# concatenate all other parameters and interpret using the final one
|
||||
b1 = Bits(','.join(sys.argv[1: -1]))
|
||||
print(b1._readtoken(fp, 0, b1.__len__())[0])
|
||||
else:
|
||||
# does final parameter end with a dot then an interpretation string?
|
||||
interp = fp[fp.rfind('.') + 1:]
|
||||
if interp in dtype_register.names:
|
||||
sys.argv[-1] = fp[:fp.rfind('.')]
|
||||
b1 = Bits(','.join(sys.argv[1:]))
|
||||
print(b1._readtoken(interp, 0, b1.__len__())[0])
|
||||
else:
|
||||
# No interpretation - just use default print
|
||||
b1 = Bits(','.join(sys.argv[1:]))
|
||||
print(b1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user