Skip to content

Commit 81961ac

Browse files
committed
Force non-binary installation of cbor2
1 parent d0fbc02 commit 81961ac

File tree

3 files changed

+33
-17
lines changed

3 files changed

+33
-17
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ docs/build
55
dist
66
.mypy_cache
77
coverage.xml
8+
.cbor2_version
89

910
# IDE
1011
.idea

Makefile

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,24 @@ export PRINT_HELP_PYSCRIPT
2323

2424
BROWSER := poetry run python -c "$$BROWSER_PYSCRIPT"
2525

26+
ensure-pure-cbor2: ## ensures cbor2 is installed with pure Python implementation
27+
@poetry run python -c "from importlib.metadata import version; \
28+
print(version('cbor2'))" > .cbor2_version
29+
@poetry run python -c "import cbor2, inspect; \
30+
print('Checking cbor2 implementation...'); \
31+
decoder_path = inspect.getfile(cbor2.CBORDecoder); \
32+
using_c_ext = decoder_path.endswith('.so'); \
33+
print(f'Implementation path: {decoder_path}'); \
34+
print(f'Using C extension: {using_c_ext}'); \
35+
exit(1 if using_c_ext else 0)" || \
36+
(echo "Reinstalling cbor2 with pure Python implementation..." && \
37+
poetry run pip install --no-binary cbor2 "cbor2==$$(cat .cbor2_version)" --force-reinstall && \
38+
rm .cbor2_version)
39+
2640
help:
2741
@python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST)
2842

29-
cov: ## check code coverage
43+
cov: ensure-pure-cbor2 ## check code coverage
3044
poetry run pytest -n 4 --cov pycardano
3145

3246
cov-html: cov ## check code coverage and generate an html report
@@ -54,7 +68,7 @@ clean-test: ## remove test and coverage artifacts
5468
rm -fr cov_html/
5569
rm -fr .pytest_cache
5670

57-
test: ## runs tests
71+
test: ensure-pure-cbor2 ## runs tests
5872
poetry run pytest -vv -n 4
5973

6074
test-integration: ## runs integration tests
@@ -63,7 +77,7 @@ test-integration: ## runs integration tests
6377
test-single: ## runs tests with "single" markers
6478
poetry run pytest -s -vv -m single
6579

66-
qa: ## runs static analyses
80+
qa: ensure-pure-cbor2 ## runs static analyses
6781
poetry run flake8 pycardano
6882
poetry run mypy --install-types --non-interactive pycardano
6983
poetry run black --check .
@@ -78,6 +92,6 @@ docs: ## build the documentation
7892
poetry run sphinx-build docs/source docs/build/html
7993
$(BROWSER) docs/build/html/index.html
8094

81-
release: clean qa test format ## build dist version and release to pypi
95+
release: clean qa test format ensure-pure-cbor2 ## build dist version and release to pypi
8296
poetry build
8397
poetry publish

pycardano/serialization.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -200,19 +200,21 @@ def wrapper(cls, value: Primitive):
200200

201201
CBORBase = TypeVar("CBORBase", bound="CBORSerializable")
202202

203+
def decode_array(self, subtype: int) -> Sequence[Any]:
204+
# Major tag 4
205+
length = self._decode_length(subtype, allow_indefinite=True)
203206

204-
class IndefiniteDecoder(CBORDecoder):
205-
def decode_array(self, subtype: int) -> Sequence[Any]:
206-
# Major tag 4
207-
length = self._decode_length(subtype, allow_indefinite=True)
208-
209-
if length is None:
210-
return IndefiniteList(
211-
cast(Primitive, super().decode_array(subtype=subtype))
212-
)
213-
else:
214-
return super().decode_array(subtype=subtype)
207+
if length is None:
208+
return IndefiniteList(
209+
cast(Primitive, self.decode_array(subtype=subtype))
210+
)
211+
else:
212+
return self.decode_array(subtype=subtype)
215213

214+
try:
215+
cbor2._decoder.major_decoders[4] = decode_array
216+
except Exception as e:
217+
logger.warning("Failed to replace major decoder for indefinite array", e)
216218

217219
def default_encoder(
218220
encoder: CBOREncoder, value: Union[CBORSerializable, IndefiniteList]
@@ -532,8 +534,7 @@ def from_cbor(cls, payload: Union[str, bytes]) -> CBORSerializable:
532534
if type(payload) is str:
533535
payload = bytes.fromhex(payload)
534536

535-
with BytesIO(cast(bytes, payload)) as fp:
536-
value = IndefiniteDecoder(fp).decode()
537+
value = cbor2.loads(payload)
537538

538539
return cls.from_primitive(value)
539540

0 commit comments

Comments
 (0)