[Git][debian-gis-team/bpack][master] 5 commits: New upstream version 1.3.0
Antonio Valentino (@antonio.valentino)
gitlab at salsa.debian.org
Thu Jan 9 06:31:12 GMT 2025
Antonio Valentino pushed to branch master at Debian GIS Project / bpack
Commits:
14062567 by Antonio Valentino at 2025-01-09T06:23:49+00:00
New upstream version 1.3.0
- - - - -
39790a21 by Antonio Valentino at 2025-01-09T06:23:50+00:00
Update upstream source from tag 'upstream/1.3.0'
Update to upstream version '1.3.0'
with Debian dir 47aa67356eb1dd22b8f857e047740a2917c96840
- - - - -
206ca39a by Antonio Valentino at 2025-01-09T06:24:49+00:00
New upstream release
- - - - -
8f9d68d5 by Antonio Valentino at 2025-01-09T06:25:52+00:00
Update dates in d/copyright
- - - - -
4c0cfb44 by Antonio Valentino at 2025-01-09T06:26:47+00:00
Set distribution to unstable
- - - - -
12 changed files:
- .flake8
- .pre-commit-config.yaml
- Makefile
- README.rst
- bpack/__init__.py
- bpack/descriptors.py
- bpack/tests/test_field_descriptor.py
- + bpack/tests/test_future_annotations.py
- debian/changelog
- debian/copyright
- docs/release_notes.rst
- tox.ini
Changes:
=====================================
.flake8
=====================================
@@ -8,17 +8,17 @@ extend-ignore = E203,E501,E701,W503,SC,CNL
# extend-ignore = SC # flake8-spellcheck: too aggressive
# extend-ignore = CNL # flake8-class-newline: incompatible with black
# extend-ignore = A003,A005 # Python builtin is shadowed by class attribute / module
-extend-select = W504,B950
# https://docs.astral.sh/ruff/rules/#pydocstyle-d
-# D105: undocumented-magic-method
-# D107: undocumented-public-init
-# extend-ignore = E203,W503,D105,D107 # D* are in pyproject.toml
+# extend-ignore = D105 # undocumented-magic-method
+# extend-ignore = D107 # undocumented-public-init
+extend-select = W504,B950
per-file-ignores =
*/tests/test_*.py: D,T003
*/tests/data/*.py: D,T003,F821
bpack/utils.py: D103
bpack/codecs.py: A005
bpack/typing.py: A005
+ bpack/tests/test_future_annotations.py: D,T003,NQA102
statistics = True
count = True
extend-exclude = examples/*
=====================================
.pre-commit-config.yaml
=====================================
@@ -22,7 +22,7 @@ repos:
# - id: ruff-format
- repo: https://github.com/asottile/pyupgrade
- rev: v3.19.0
+ rev: v3.19.1
hooks:
- id: pyupgrade
args: [--py39-plus]
@@ -30,7 +30,8 @@ repos:
(?x)^(
bpack/tests/test_field_descriptor.py|
bpack/tests/test_record_descriptor.py|
- bpack/tests/test_utils.py
+ bpack/tests/test_utils.py|
+ bpack/tests/test_future_annotations.py
)
- repo: https://github.com/pycqa/flake8
@@ -51,7 +52,7 @@ repos:
name: isort (python)
- repo: https://github.com/psf/black-pre-commit-mirror
- rev: 24.8.0
+ rev: 24.10.0
hooks:
- id: black
language_version: python3.9
=====================================
Makefile
=====================================
@@ -4,7 +4,8 @@ PYTHON=python3
SPHINX_APIDOC=sphinx-apidoc
TARGET=bpack
-.PHONY: default help dist check fullcheck coverage lint api docs clean cleaner distclean
+.PHONY: default help dist check fullcheck coverage clean cleaner distclean \
+ lint docs api
default: help
@@ -16,12 +17,12 @@ help:
@echo " check - run a full test (using pytest)"
@echo " fullcheck - run a full test (using tox)"
@echo " coverage - run tests and generate the coverage report"
- @echo " lint - perform check with code linter (flake8, black)"
- @echo " api - update the API source files in the documentation"
- @echo " docs - generate the sphinx documentation"
@echo " clean - clean build artifacts"
@echo " cleaner - clean cache files and working directories of al tools"
@echo " distclean - clean all the generated files"
+ @echo " lint - perform check with code linter (flake8, black)"
+ @echo " docs - generate the sphinx documentation"
+ @echo " api - update the API source files in the documentation"
dist:
$(PYTHON) -m build
@@ -36,24 +37,6 @@ fullcheck:
coverage:
$(PYTHON) -m pytest --doctest-modules --cov=$(TARGET) --cov-report=html --cov-report=term
-lint:
- $(PYTHON) -m flake8 --count --statistics $(TARGET)
- $(PYTHON) -m pydocstyle --count $(TARGET)
- $(PYTHON) -m isort --check $(TARGET)
- $(PYTHON) -m black --check $(TARGET)
- # $(PYTHON) -m mypy --check-untyped-defs --ignore-missing-imports $(TARGET)
- # ruff check $(TARGET)
-
-api:
- $(RM) -r docs/api
- $(SPHINX_APIDOC) --module-first --separate --no-toc -o docs/api \
- --doc-project "$(TARGET) API" --templatedir docs/_templates/apidoc \
- $(TARGET) $(TARGET)/tests
-
-docs:
- mkdir -p docs/_static
- $(MAKE) -C docs html
-
clean:
$(RM) -r *.*-info build
find . -name __pycache__ -type d -exec $(RM) -r {} +
@@ -70,3 +53,21 @@ cleaner: clean
distclean: cleaner
$(RM) -r dist
+
+lint:
+ $(PYTHON) -m flake8 --count --statistics $(TARGET)
+ $(PYTHON) -m pydocstyle --count $(TARGET)
+ $(PYTHON) -m isort --check $(TARGET)
+ $(PYTHON) -m black --check $(TARGET)
+ # $(PYTHON) -m mypy --check-untyped-defs --ignore-missing-imports $(TARGET)
+ # ruff check $(TARGET)
+
+docs:
+ mkdir -p docs/_static
+ $(MAKE) -C docs html
+
+api:
+ $(RM) -r docs/api
+ $(SPHINX_APIDOC) --module-first --separate --no-toc -o docs/api \
+ --doc-project "$(TARGET) API" --templatedir docs/_templates/apidoc \
+ $(TARGET) $(TARGET)/tests
=====================================
README.rst
=====================================
@@ -4,7 +4,7 @@ Binary data structures (un-)Packing library
.. badges
-|PyPI Status| |GHA Status| |Documentation Status|
+|PyPI Status| |GHA Status| |Documentation Status| |Python Versions| |License|
.. |PyPI Status| image:: https://img.shields.io/pypi/v/bpack.svg
:target: https://pypi.org/project/bpack
@@ -15,6 +15,12 @@ Binary data structures (un-)Packing library
.. |Documentation Status| image:: https://readthedocs.org/projects/bpack/badge/?version=latest
:target: https://bpack.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
+.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/bpack
+ :target: https://pypi.org/project/bpack
+ :alt: Supported Python versions
+.. |License| image:: https://img.shields.io/pypi/l/${packagename}
+ :target: https://pypi.org/project/${packagename}
+ :alt: License
.. description
@@ -52,7 +58,7 @@ Encoders/decoders (*backends*) rely on well known Python packages like:
License
-------
-:Copyright: 2020-2024, Antonio Valentino <antonio.valentino at tiscali.it>
+:Copyright: 2020-2025, Antonio Valentino <antonio.valentino at tiscali.it>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
=====================================
bpack/__init__.py
=====================================
@@ -20,4 +20,4 @@ from .descriptors import ( # noqa: F401
calcsize,
)
-__version__ = "1.2.0"
+__version__ = "1.3.0"
=====================================
bpack/descriptors.py
=====================================
@@ -7,7 +7,7 @@ import types
import builtins
import warnings
import dataclasses
-from typing import Optional, Union
+from typing import Optional, Union, get_type_hints
from collections.abc import Iterator, Sequence
import bpack.utils
@@ -62,6 +62,11 @@ def _resolve_type(type_):
Replace :class:`typing.Annotated` types with the corresponding
not-annotated ones.
"""
+ if isinstance(type_, str):
+ raise TypeError(
+ f"the 'type_' parameter cannot be a string (type_: {type_!r})"
+ )
+
if bpack.utils.is_sequence_type(type_):
etype = bpack.utils.effective_type(type_)
try:
@@ -97,6 +102,10 @@ class BinFieldDescriptor:
def _validate_type(self):
if self.type is None:
raise TypeError(f"invalid type '{self.type!r}'")
+ elif isinstance(self.type, str):
+ raise TypeError(
+ f"'{self.__class__.__name__}.type' cannot be a string"
+ )
def _validate_size(self):
msg = f"invalid size: {self.size!r} (must be a positive integer)"
@@ -133,6 +142,12 @@ class BinFieldDescriptor:
def __post_init__(self):
"""Finalize BinFieldDescriptor instance initialization."""
+ if isinstance(self.type, str):
+ raise TypeError(
+ f"the 'type' parameter cannot be a string "
+ f"(type_: {self.type!r})"
+ )
+
if self.offset is not None:
self._validate_offset()
@@ -201,6 +216,11 @@ class BinFieldDescriptor:
"""Update the field descriptor according to the specified type."""
if self.type is not None:
raise TypeError("the type attribute is already set")
+ if isinstance(type_, str):
+ raise TypeError(
+ f"the 'type_' parameter cannot be a string (type_: {type_!r})"
+ )
+
if bpack.typing.is_annotated(type_):
_, params = bpack.typing.get_args(type_)
valid = True
@@ -221,7 +241,11 @@ class BinFieldDescriptor:
self.size = params.size
elif bpack.utils.is_sequence_type(type_):
etype = bpack.utils.effective_type(type_, keep_annotations=True)
+
+ # this is needed to set "signed" and "size"
self.update_from_type(etype)
+
+ # restore the proper sequence type
self.type = _resolve_type(type_)
else:
self.type = type_
@@ -284,6 +308,12 @@ def is_field(obj) -> bool:
def _update_field_metadata(field_, **kwargs):
+ type_ = kwargs.get("type")
+ if isinstance(type_, str):
+ raise TypeError(
+ f"the 'type' parameter cannot be a string (type_: {type_!r})"
+ )
+
metadata = field_.metadata.copy() if field_.metadata is not None else {}
metadata.update(**kwargs)
field_.metadata = types.MappingProxyType(metadata)
@@ -444,6 +474,9 @@ def descriptor( # noqa: CCR001
else:
cls = dataclasses.dataclass(cls, **kwargs)
+ # import inspect
+ # types_ = inspect.get_annotations(cls)
+ types_ = get_type_hints(cls, include_extras=True)
fields_ = dataclasses.fields(cls)
# Initialize to a dummy value with initial offset + size = 0
@@ -457,6 +490,10 @@ def descriptor( # noqa: CCR001
# NOTE: this is ensured by dataclasses but not by attr
assert field_.type is not None
+ # resolve all types
+ if isinstance(field_.type, str):
+ field_.type = types_[field_.name]
+
if bpack.typing.is_annotated(field_.type):
# check byteorder
_, params = bpack.typing.get_args(field_.type)
@@ -476,6 +513,7 @@ def descriptor( # noqa: CCR001
except NotFieldDescriptorError:
field_descr = BinFieldDescriptor()
if isinstance(field_, Field):
+ # set "type", "size" and "signed"
field_descr.update_from_type(field_.type)
if field_descr.size is None:
=====================================
bpack/tests/test_field_descriptor.py
=====================================
@@ -156,7 +156,7 @@ class TestRecordFields:
@staticmethod
def test_invalid_field_type():
- with pytest.raises(TypeError):
+ with pytest.raises((TypeError, NameError)):
@bpack.descriptor
class Record:
=====================================
bpack/tests/test_future_annotations.py
=====================================
@@ -0,0 +1,81 @@
+"""Tests bpack with "from __future__ import annotations"."""
+
+from __future__ import annotations
+
+import enum
+
+import pytest
+
+import bpack
+from bpack import T
+
+
+class EEnumType(enum.IntEnum):
+ A = 1
+ B = 2
+ C = 3
+
+
+ at bpack.descriptor
+class Record:
+ field_1: int = bpack.field(size=4, default=11)
+ field_2: float = bpack.field(size=4, default=22.22)
+ field_3: EEnumType = bpack.field(size=1, default=EEnumType.A)
+
+
+ at bpack.descriptor
+class NestedRecord:
+ field_1: str = bpack.field(size=10, default="0123456789")
+ field_2: Record = bpack.field(
+ size=bpack.calcsize(Record), default_factory=Record
+ )
+ field_3: int = bpack.field(size=4, default=3)
+ field_4: T["f8"] = 0.1 # noqa: F821
+
+
+def test_nested_records():
+ record = Record()
+ nested_record = NestedRecord()
+
+ assert nested_record.field_1 == "0123456789"
+ assert nested_record.field_2 == record
+ assert nested_record.field_2.field_1 == record.field_1
+ assert nested_record.field_2.field_2 == record.field_2
+ assert nested_record.field_2.field_3 is EEnumType.A
+ assert nested_record.field_3 == 3
+ assert nested_record.field_4 == 0.1
+
+
+def test_nested_records_consistency_error():
+ with pytest.raises(bpack.descriptors.DescriptorConsistencyError):
+
+ @bpack.descriptor
+ class NestedRecord:
+ field_1: str = bpack.field(size=10, default="0123456789")
+ field_2: Record = bpack.field(
+ size=bpack.calcsize(Record) + 1, default_factory=Record
+ )
+ field_3: int = bpack.field(size=4, default=3)
+
+
+def test_nested_records_autosize():
+ assert bpack.calcsize(NestedRecord) == 31
+
+
+def test_unexisting_field_type():
+ with pytest.raises((TypeError, NameError)):
+
+ @bpack.descriptor
+ class Record:
+ field_1: "unexisting" = bpack.field(size=4) # noqa: F821
+
+
+invalid = True
+
+
+def test_invalid_field_type():
+ with pytest.raises((TypeError, NameError)):
+
+ @bpack.descriptor
+ class Record:
+ field_1: "invalid" = bpack.field(size=4) # noqa: F821
=====================================
debian/changelog
=====================================
@@ -1,3 +1,10 @@
+bpack (1.3.0-1) unstable; urgency=medium
+
+ * New upstream version.
+ * Update dates in d/copyright.
+
+ -- Antonio Valentino <antonio.valentino at tiscali.it> Thu, 09 Jan 2025 06:26:26 +0000
+
bpack (1.2.0-1) unstable; urgency=medium
[ Bas Couwenberg ]
=====================================
debian/copyright
=====================================
@@ -4,11 +4,11 @@ Upstream-Contact: Antonio Valentino <antonio.valentino at tiscali.it>
Source: https://github.com/avalentino/bpack
Files: *
-Copyright: 2023-2024, Antonio Valentino <antonio.valentino at tiscali.it>
+Copyright: 2023-2025, Antonio Valentino <antonio.valentino at tiscali.it>
License: Apache-2.0
Files: debian/*
-Copyright: 2023-2024, Antonio Valentino <antonio.valentino at tiscali.it>
+Copyright: 2023-2025, Antonio Valentino <antonio.valentino at tiscali.it>
License: Apache-2.0
License: Apache-2.0
=====================================
docs/release_notes.rst
=====================================
@@ -1,6 +1,24 @@
Release Notes
=============
+bpack v1.3.0 (06/01/2025)
+-------------------------
+
+* Support for annotations saved in string form (see also `PEP-563`_).
+ Is some circumstances Python typing annotations are stored
+ as strings. E.g. this happens when people uses::
+
+ from __future__ import annotations
+
+ Starting from v1.3.0, `bpack` is compatible with this way of storing
+ annotations.
+ Please note, anyway, that `bpack` still need to evaluate the annotations
+ at compile time so the "Postponed Evaluation of Annotations" described in
+ `PEP-563`_ is not really supported.
+
+.. _`PEP-563`: https://peps.python.org/pep-0563
+
+
bpack v1.2.0 (26/11/2024)
-------------------------
=====================================
tox.ini
=====================================
@@ -6,7 +6,6 @@ env_list =
py311
py312
py313
- pypy3
strict
coverage
codestyle
@@ -22,14 +21,6 @@ extras = test
commands =
python3 -m pytest {tty:--color=yes} --doctest-modules {posargs}
-[testenv:pypy3]
-deps =
- pytest>=6
- typing-extensions
-extras = bs,np
-commands =
- python3 -m pytest {tty:--color=yes} {posargs}
-
[testenv:strict]
commands =
python3 -m pytest {tty:--color=yes} -W error {posargs}
@@ -54,7 +45,7 @@ deps =
changedir = {toxinidir}
commands =
python3 -m flake8 --version
- python3 -m flake8 --count --statistics --count bpack
+ python3 -m flake8 --count --statistics bpack
python3 -m pydocstyle --count bpack
python3 -m isort --check bpack
python3 -m black --check bpack
View it on GitLab: https://salsa.debian.org/debian-gis-team/bpack/-/compare/51dffb0109aa4911db8ee4a5cb679c3954a604fe...4c0cfb44062d848615aec22a2bede9e589184c21
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/bpack/-/compare/51dffb0109aa4911db8ee4a5cb679c3954a604fe...4c0cfb44062d848615aec22a2bede9e589184c21
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20250109/92c61517/attachment-0001.htm>
More information about the Pkg-grass-devel
mailing list