Skip to content

Commit

Permalink
Fix reading integers from empy bitarray raises Exception (#10)
Browse files Browse the repository at this point in the history
* Defaulting reading integers to zero if we end up out of the range of bits available for that.
* Fixing problems found through linters and adding support for prettier.
* Adding testing workflow. Updated python versions tested for this library.
  • Loading branch information
gguridi authored Nov 30, 2021
1 parent e4ae417 commit b5d5372
Show file tree
Hide file tree
Showing 18 changed files with 55,580 additions and 141 deletions.
56 changes: 28 additions & 28 deletions .github/workflows/development.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,43 @@ name: Development Version
on:
push:
branches:
- master
- master

jobs:
tests:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.6, 3.7, 3.8]
python-version: [3.6, 3.7, 3.8, 3.9, "3.10"]
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: pip install -r requirements-test.txt
- name: Test with pytest
run: pytest -v .
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: pip install -r requirements-test.txt
- name: Test with pytest
run: pytest -v .

deploy:
runs-on: ubuntu-latest
needs: tests
steps:
- uses: actions/checkout@v2
with:
fetch-depth: '0'
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.x
- name: Install dependencies
run: pip install setuptools wheel twine
- name: Build and publish
env:
TWINE_REPOSITORY_URL: https://test.pypi.org/legacy/
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.TESTPYPI_TOKEN }}
run: |
python setup.py clean sdist bdist_wheel
twine upload --skip-existing dist/*
- uses: actions/checkout@v2
with:
fetch-depth: "0"
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.x
- name: Install dependencies
run: pip install setuptools wheel twine
- name: Build and publish
env:
TWINE_REPOSITORY_URL: https://test.pypi.org/legacy/
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.TESTPYPI_TOKEN }}
run: |
python setup.py clean sdist bdist_wheel
twine upload --skip-existing dist/*
58 changes: 29 additions & 29 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,38 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.6, 3.7, 3.8]
python-version: [3.6, 3.7, 3.8, 3.9, "3.10"]
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: pip install -r requirements-test.txt
- name: Test with pytest
run: pytest -v .
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: pip install -r requirements-test.txt
- name: Test with pytest
run: pytest -v .

deploy:
runs-on: ubuntu-latest
needs: tests
steps:
- uses: actions/checkout@v2
with:
fetch-depth: '0'
- name: Set release version
run: echo ::set-env name=RELEASE_VERSION::$(echo ${GITHUB_REF:10})
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: 3.x
- name: Install dependencies
run: pip install setuptools wheel twine
- name: Build and publish
env:
TWINE_REPOSITORY_URL: https://upload.pypi.org/legacy/
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
run: |
python setup.py clean sdist bdist_wheel
twine upload dist/*
- uses: actions/checkout@v2
with:
fetch-depth: "0"
- name: Set release version
run: echo ::set-env name=RELEASE_VERSION::$(echo ${GITHUB_REF:10})
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: 3.x
- name: Install dependencies
run: pip install setuptools wheel twine
- name: Build and publish
env:
TWINE_REPOSITORY_URL: https://upload.pypi.org/legacy/
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
run: |
python setup.py clean sdist bdist_wheel
twine upload dist/*
20 changes: 20 additions & 0 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Testing

on: push

jobs:
tests:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.6, 3.7, 3.8, 3.9, "3.10"]
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: pip install -r requirements-test.txt
- name: Test with pytest
run: pytest -v .
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"printWidth": 120,
"tabWidth": 2,
"singleQuote": false,
"trailingComma": "all"
}
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,24 @@

[![Build Status](https://travis-ci.org/gguridi/iab-tcf.svg?branch=master)](https://travis-ci.org/gguridi/iab-tcf)
[![codecov](https://codecov.io/gh/gguridi/iab-tcf/branch/master/graph/badge.svg)](https://codecov.io/gh/gguridi/iab-tcf)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/6e6a8a02a6b14c5998b29bbe06327c87)](https://www.codacy.com/gh/gguridi/iab-tcf/dashboard)
![Releasing](https://github.com/gguridi/iab-tcf/workflows/Releasing/badge.svg)
[![Documentation Status](https://readthedocs.org/projects/iab-tcf/badge/?version=latest)](https://iab-tcf.readthedocs.io/en/latest/?badge=latest)


A Python implementation of the IAB consent strings (v1.1 and v2)

# Installing
## Installing

Install and update using pip:

```bash
pip install -U iab-tcf
```

# Documentation

[Documentation](https://iab-tcf.readthedocs.io/en/stable/) of this package can be found at:
## Documentation

* https://iab-tcf.readthedocs.io/en/stable/
[Documentation](https://iab-tcf.readthedocs.io/en/stable/) of this package can be
found at [readthedocs.io](https://iab-tcf.readthedocs.io/en/stable/).

To generate the documentation locally:

Expand All @@ -31,7 +30,7 @@ sphinx-apidoc -f -o . ../iab_tcf/
make html
```

# A Simple Example
## A Simple Example

In order to decode a v1.1 or v2 consent string automatically we can do:

Expand All @@ -43,8 +42,8 @@ consent = decode("CO5VTlWO5VTlWH1AAAENAwCwAIAAAAAAAIAAAAoAAAAA.YAAAAAAAAAA")
print(consent.version) # prints 2
```

If we want to improve performance and we already know it's going to be a v2 consent
string we can do:
If we want to improve performance and we already know it's going to
be a v2 consent string we can do:

```python
from iab_tcf import decode_v2
Expand All @@ -54,7 +53,7 @@ consent = decode_v2("CO5VTlWO5VTlWH1AAAENAwCwAIAAAAAAAIAAAAoAAAAA.YAAAAAAAAAA")
print(consent.version) # prints 2
```

# Tests
## Tests

In order to run the tests locally we can do:

Expand All @@ -63,6 +62,7 @@ pip install -r requirements-test.txt
pytest -v .
```

# Thanks
## Thanks

Many thanks to [LiveRamp/iabconsent](https://github.com/LiveRamp/iabconsent) which greatly inspired this project, and forms the basis and internal logic.
Many thanks to [LiveRamp/iabconsent](https://github.com/LiveRamp/iabconsent)
which greatly inspired this project, and forms the basis and internal logic.
1 change: 1 addition & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#
import os
import sys

import sphinx_rtd_theme

sys.path.insert(0, os.path.abspath(".."))
Expand Down
10 changes: 6 additions & 4 deletions iab_tcf/bits.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from typing import List, Dict, Tuple
from datetime import datetime
from typing import Dict, List, Tuple

from bitarray import bitarray
from bitarray.util import ba2int
from datetime import datetime


class Reader:
Expand Down Expand Up @@ -37,7 +38,8 @@ def read_int(self, n: int) -> int:
:param n: Number of bits to retrieve and transform into int.
"""
return ba2int(self.read_bits(n))
bits = self.read_bits(n)
return ba2int(bits) if bits else 0

def read_time(self) -> datetime:
"""Reads 36 bits (the length TCF uses for timestamps) and transforms
Expand Down Expand Up @@ -83,7 +85,7 @@ def read_range(self, n: int) -> List[Tuple[int, int]]:
:param n: Number of ranges we are going to process.
"""
ranges = []
for i in range(n):
for _ in range(n):
is_range = self.read_bool()
start = self.read_int(16)
end = start if not is_range else self.read_int(16)
Expand Down
3 changes: 2 additions & 1 deletion iab_tcf/iab_tcf.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import List
import base64
from typing import List

from .bits import Reader


Expand Down
3 changes: 1 addition & 2 deletions iab_tcf/iab_tcf_v1.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from typing import List
from .iab_tcf import base64_decode
from .bits import Reader
from .iab_tcf import base64_decode


class ConsentV1:
Expand Down
6 changes: 3 additions & 3 deletions iab_tcf/iab_tcf_v2.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import json
from typing import List, Tuple
from typing import List

from .bits import Reader
from .iab_tcf import base64_decode, segments
from .v2.publisher_restriction import PubRestrictionEntry
from .v2.non_core_segments import NonCoreSegment
from .v2.publisher_restriction import PubRestrictionEntry


class ConsentV2:
Expand Down
5 changes: 3 additions & 2 deletions iab_tcf/v2/non_core_segments.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import List, Dict, Tuple
from .publisher_tc import PubTCEntry
from typing import Dict

from ..bits import Reader
from .publisher_tc import PubTCEntry


class NonCoreSegment:
Expand Down
1 change: 1 addition & 0 deletions requirements-test.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
-r requirements.txt
pytest>=6.0.1
pytest-cov>=2.10.1
black
7 changes: 4 additions & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os
import json
import os
from pathlib import Path
from typing import List, Dict
from typing import Dict, List


def load_seed(file):
Expand All @@ -23,4 +23,5 @@ def _value(key: int):

def mapbit_from_dict(length: int, trues: Dict) -> Dict[int, bool]:
trues = [int(i) for i, _ in trues.items()]
return mapbit(length or len(trues), trues=trues)
falses = [i + 1 for i in range(length)]
return mapbit(length or len(trues), trues=trues, falses=falses)
Loading

0 comments on commit b5d5372

Please sign in to comment.