Skip to content

Bitmath2#111

Merged
timlnx merged 92 commits intomasterfrom
bitmath2
Apr 18, 2026
Merged

Bitmath2#111
timlnx merged 92 commits intomasterfrom
bitmath2

Conversation

@timlnx
Copy link
Copy Markdown
Owner

@timlnx timlnx commented Apr 17, 2026

wherein we moderize this project

closes #54
closes #85
closes #99

@github-advanced-security
Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

teto and others added 29 commits April 16, 2026 23:36
Adds numbers.Integer as a valid parent.
Previously there was a conditional that mapped the old Python 2.x
long() and unicode() types to int() and str() types. That is no longer
required now that we are Python 3.x only.

In addition to the extra conditional, several type checks were able to
be removed.

Also this commit removes the click and progressbar integrations for
now. They will return later as examples in the
documentation/source. Full credit will be given to the original
authors.
timlnx added 28 commits April 17, 2026 13:05
… units

- Add ZiB (2^70), YiB (2^80) as Byte subclasses with Zio/Yio aliases
- Add Zib (2^70), Yib (2^80) as Bit subclasses
- Add Zi/Yi to NIST_PREFIXES and NIST_STEPS
- Add to_ZiB, to_YiB, to_Zib, to_Yib conversion methods and properties
  to the Bitmath base class alongside their SI counterparts
- Add ZiB/YiB/Zib/Yib to __all__ and ALL_UNIT_TYPES
- Fix _norm: always use float(value) * _unit_value so that int and
  float inputs produce the same _byte_value. Without this, ZB(654)
  stored an exact Python int while ZB(654.0) stored a float, causing
  Python 3's exact int/float comparison to return False even for
  logically equal instances (the root cause in issue #54).
- Add parse tests for Zio/Yio/Zo/Yo aliases
- Add instantiation, equality, conversion, and property tests for all
  four new units in their respective existing test files

Closes #54
…tring_unsafe

- parse_string() signature updated to show strict and system params
- Add parse-string-loose section documenting strict=False behaviour,
  replacing the old parse_string_unsafe description and examples
- parse_string_unsafe() section marked deprecated as of 2.0.0;
  shows migration instructions and how to suppress the warning
- Default system updated to NIST throughout (was SI in old docs)
…n override

Replace vague bullet list with a three-tier precedence model that
accurately describes when system is and is not consulted:
1. No unit → always Byte, system irrelevant
2. Self-describing unit (i-marker present) → always NIST, system irrelevant
3. Ambiguous single-letter unit → system decides (NIST default)

Lead with an .. important:: block scoped to strict=False so readers
understand the constraint before seeing the examples.
Fixes:
- KiB(1)/3 result was 0.3330078125 (Python 2 integer division); replaced
  with KiB(6)/4 = KiB(1.5) which is exact and correct under Python 3
- reverse=True sort output showed raw KiB values for human_sizes instead
  of the MiB results that best_prefix() produces; corrected to match the
  forward-sorted output above it
- Rich Comparison link updated from Python 2.7 to Python 3 docs

New sections:
- Parsing Strings: parse_string strict and non-strict mode with examples
  covering exact units, octet aliases, ambiguous single-letter units,
  plain numbers, and the i-marker override of system
- Summing an Iterable: bitmath.sum() vs built-in sum()
- Rounding: math.floor/ceil/round on bitmath instances, with warning
  about lossy intermediate rounding
Built-in sum() now works with bitmath objects via the __radd__ identity
(0 + bm = bm), preserving the type of the first element. Document this
alongside bitmath.sum() so users know when to reach for each: built-in
for type-preserving accumulation, bitmath.sum() for normalised-to-Byte
(or custom start) output regardless of input types.

Update the bitmath.sum() docstring to match, replacing the stale claim
that built-in sum() returns a plain float.
Documents the bitmath.sum() function added in 2.0.0 in the module API
reference, positioned after bitmath.listdir(). Includes parameter table,
note contrasting it with built-in sum(), and a seealso cross-reference
to the Getting Started page. Also adds the simple_examples_summing anchor
needed by that cross-reference.
SI_STEPS was missing Z and Y entries; NIST_STEPS was missing Zi and Yi
(added with the ZiB/YiB/Zib/Yib units in 2.0.0); ALL_UNIT_TYPES used
the old 'b'/'B' spellings instead of 'Bit'/'Byte' and was missing the
Zb/ZB/Yb/YB/Zib/ZiB/Yib/YiB entries added this release.
…tprefix

The format() context manager mutated module-level globals (format_string,
format_plural) without a try/finally, causing two bugs:
  1. In concurrent code, threads clobbered each other's saved/restored
     values — the race condition reported in issue #83.
  2. An exception raised inside the with block left the globals permanently
     mutated for the remainder of the process.

Fix by switching to threading.local storage. Each thread entering a
context manager writes to its own _thread_local namespace; __str__ and
the unit property read from that namespace (falling back to the module
globals when not inside a context). Module globals are never written by
the context manager, so threads not inside any context are unaffected.
Nested contexts within a thread correctly save and restore the enclosing
context's thread-local values via a sentinel-based save/restore pattern.

Also implements the bestprefix parameter that was previously accepted but
silently ignored: when bestprefix=True, __str__ calls self.best_prefix()
before formatting, so the rendered string uses the best human-readable
prefix unit automatically.

Additional changes:
- Fixed test_print_GiB_plural_fmt_in_mgr which was a copy-paste of the
  Byte test; it now tests GiB(3.0) as its name and docstring imply.
- Added bestprefix, exception-safety, and nesting tests to
  test_context_manager.py.
- Added tests/test_context_manager_thread_safe.py with six thread-safety
  tests including a direct reproduction of the issue #83 race condition.

closes #83
Rewrote contributing.rst to reflect the current 2.0.0 toolchain:
GitHub Actions CI, pytest, pycodestyle/flake8 checks, and accurate
make targets. Added Windows (MINGW/Cygwin/MSYS) branch to viewdocs.
Adds __format__ to Bitmath so instances work with Python's standard
string formatting protocol (PEP 3101). An empty spec returns str(self);
any numeric format spec (e.g. ':.2f', '>10.1f') is applied to
self.value only, letting the caller control the surrounding string.

    size = bitmath.MiB(2.847598437)
    f'{size:.1f} {size.unit}'  # -> '2.8 MiB'
    f'{size}'                  # -> '2.847598437 MiB'

Note: uses self.value.__format__(fmt_spec) rather than the built-in
format() to avoid the name collision with the module-level
bitmath.format() context manager.

Eight tests added to test_representation.py. Documentation added to
instances.rst with credit to the original author.

closes #76
Add ZiB/YiB/Zib/Yib, non-strict parse_string, bitmath.sum(), built-in
sum() support, f-string/__format__, and rounding to the feature list.
Fix 'OS X' -> 'macOS' and 'almost 200' -> 'nearly 300' unit tests.
…apter

The integrations subpackage (bmargparse, bmclick, bmprogressbar) required
users to install optional dependencies that were not declared in the package
metadata, and the bundled implementations became stale. Per issue #85, the
approach of shipping copy-paste examples in documentation is simpler and
easier to maintain.

Changes:
- Remove bitmath/integrations/ package and tests/test_argparse_type.py
- Remove full_demo.py (broken legacy demo script)
- Add docsite/source/integration_examples.rst with standalone argparse,
  click, and progressbar2 examples
- Replace 3rd Party Module Integrations section in module.rst with a
  pointer to the new chapter
- Update index.rst / index.rst.in toctree to include the new chapter
- Update real_life_examples.rst progress bar section with chapter pointer
- Update README.rst argparse example to use inline BitmathType function
- Drop bitmath.integrations from pyproject.toml packages list
…ets, install docs

- Replace MANIFEST.in with hatchling sdist include/exclude in pyproject.toml
- Add build/pypi/pypitest Makefile targets using python -m build + twine
- Update sdist/install Makefile targets to drop setup.py references
- Fix 'Source' install instructions in README and docsite to use pip install .
- Remove NOTE: UPDATE THIS placeholder from index.rst / index.rst.in
@timlnx timlnx merged commit 6a71b85 into master Apr 18, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Project isn't dead! bitmath 2.0.0 coming soon! RFE: Use progressbar2 Comparison issues with LARGE units

3 participants