Skip to content

Commit

Permalink
Version 7.2.0 (#271)
Browse files Browse the repository at this point in the history
* Adding #266 support for accessing nested items in BoxList using numpy-style tuple indexing (thanks to Bit0r)
* Adding tests and Cython releases for Python 3.12
* Fixing #251 support for circular references in lists (thanks to Muspi Merol)
* Fixing #261 altering all `__repr__` methods so that subclassing will output the correct class name (thanks to Gabriel Tkacz)
* Fixing #267 Fix type 'int' not iterable (thanks to YISH)

---------

Co-authored-by: Bit0r <nie_wang@outlook.com>
Co-authored-by: Muspi Merol <me@promplate.dev>
Co-authored-by: Gabriel Tkacz <55806524+gtkacz@users.noreply.github.com>
Co-authored-by: Gabriel Tkacz <gabriel.tkacz@gscap.com.br>
Co-authored-by: YISH <mokeyish@hotmail.com>
  • Loading branch information
6 people committed Jun 12, 2024
1 parent cc26a46 commit a23451d
Show file tree
Hide file tree
Showing 11 changed files with 75 additions and 48 deletions.
23 changes: 11 additions & 12 deletions .github/workflows/pythonpublish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.11'
python-version: '3.12'

- name: Install Dependencies
run: |
Expand All @@ -39,13 +39,13 @@ jobs:
strategy:
matrix:
os: [macos-11, windows-latest]
python-version: ["3.8", "3.9", "3.10", "3.11"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
Expand All @@ -63,19 +63,19 @@ jobs:
deploy-cython-manylinux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.11
uses: actions/setup-python@v4
- uses: actions/checkout@v4
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.11"
python-version: "3.12"

- name: Build wheels
run: |
python -m pip install --upgrade pip
pip install cibuildwheel setuptools wheel
python -m cibuildwheel --output-dir dist
env:
CIBW_BUILD: cp38-manylinux_x86_64 cp39-manylinux_x86_64 cp310-manylinux_x86_64 cp311-manylinux_x86_64 cp311-macosx_x86_64
CIBW_BUILD: cp38-manylinux_x86_64 cp39-manylinux_x86_64 cp310-manylinux_x86_64 cp311-manylinux_x86_64 cp312-manylinux_x86_64
CIBW_BEFORE_BUILD: pip install Cython==3.0.0
CIBW_BEFORE_TEST: pip install -r requirements.txt -r requirements-test.txt setuptools wheel twine
CIBW_TEST_COMMAND: pytest {package}/test -vv
Expand All @@ -87,4 +87,3 @@ jobs:
run: |
pip install twine
twine upload dist/*-manylinux*.whl
twine upload dist/*-macosx*.whl
30 changes: 15 additions & 15 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ jobs:
package-checks:
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12-dev", "pypy-3.8"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "pypy-3.8"]
os: [ubuntu-latest, macos-11, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- uses: actions/cache@v3
Expand Down Expand Up @@ -58,19 +58,19 @@ jobs:
Remove-item box -recurse -force
python -m pytest -vv
- name: Upload wheel artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: python_box
name: python_box_${{matrix.os}}_${{ matrix.python-version }}
path: dist/*.whl

package-manylinux-checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.11
uses: actions/setup-python@v4
- uses: actions/checkout@v4
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.11"
python-version: "3.12"

- uses: actions/cache@v3
with:
Expand All @@ -83,27 +83,27 @@ jobs:
pip install cibuildwheel
python -m cibuildwheel --output-dir dist
env:
CIBW_BUILD: cp38-manylinux_x86_64 cp39-manylinux_x86_64 cp310-manylinux_x86_64 cp311-manylinux_x86_64 cp311-macosx_x86_64
CIBW_BUILD: cp38-manylinux_x86_64 cp39-manylinux_x86_64 cp310-manylinux_x86_64 cp311-manylinux_x86_64 cp312-manylinux_x86_64
CIBW_BEFORE_BUILD: pip install Cython==3.0.0
CIBW_BEFORE_TEST: pip install -r requirements.txt -r requirements-test.txt setuptools wheel twine
CIBW_TEST_COMMAND: pytest {package}/test -vv

- name: Upload wheel artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: python_box
name: python_box_manylinux
path: dist/*-manylinux*.whl

test:
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
os: [ubuntu-latest, macos-11, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- uses: actions/cache@v3
Expand Down
10 changes: 5 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.6.0
hooks:
# Identify invalid files
- id: check-ast
Expand All @@ -20,16 +20,16 @@ repos:
- id: fix-encoding-pragma
- id: fix-byte-order-marker
# General quality checks
- id: mixed-line-ending
args: [--fix=lf]
# - id: mixed-line-ending
# args: [--fix=lf]
- id: trailing-whitespace
args: [--markdown-linebreak-ext=md]
- id: check-executables-have-shebangs
- id: end-of-file-fixer
exclude: ^test/data/.+

- repo: https://github.com/ambv/black
rev: 23.7.0
rev: 24.4.2
hooks:
- id: black
args: [--config=.black.toml]
Expand All @@ -51,7 +51,7 @@ repos:
always_run: true

- repo: https://github.com/pre-commit/mirrors-mypy
rev: 'v1.4.1'
rev: 'v1.10.0'
hooks:
- id: mypy
types: [python]
Expand Down
5 changes: 4 additions & 1 deletion AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ Code contributions:
- Michał Górny (mgorny)
- Serge Lu (Serge45)
- Eric Prestat (ericpre)

- Gabriel Mitelman Tkacz (gtkacz)
- Muspi Merol (CNSeniorious000)
- YISH (mokeyish)
- Bit0r


Suggestions and bug reporting:
Expand Down
9 changes: 9 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
Changelog
=========

Version 7.2.0
-------------

* Adding #266 support for accessing nested items in BoxList using numpy-style tuple indexing (thanks to Bit0r)
* Adding tests and Cython releases for Python 3.12
* Fixing #251 support for circular references in lists (thanks to Muspi Merol)
* Fixing #261 altering all `__repr__` methods so that subclassing will output the correct class name (thanks to Gabriel Tkacz)
* Fixing #267 Fix type 'int' not iterable (thanks to YISH)

Version 7.1.1
-------------

Expand Down
2 changes: 1 addition & 1 deletion box/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-

__author__ = "Chris Griffith"
__version__ = "7.1.1"
__version__ = "7.2.0"

from box.box import Box
from box.box_list import BoxList
Expand Down
5 changes: 3 additions & 2 deletions box/box.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,8 @@ def __contains__(self, item):
except BoxError:
return False
else:
return children in self[first_item]
it = self[first_item]
return isinstance(it, Iterable) and children in it

def keys(self, dotted: Union[bool] = False):
if not dotted:
Expand Down Expand Up @@ -777,7 +778,7 @@ def popitem(self):
return key, self.pop(key)

def __repr__(self) -> str:
return f"Box({self})"
return f"{self.__class__.__name__}({self})"

def __str__(self) -> str:
return str(self.to_dict())
Expand Down
21 changes: 17 additions & 4 deletions box/box_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,17 @@ def __new__(cls, *args, **kwargs):
# This is required for pickling to work correctly
obj.box_options = {"box_class": box.Box}
obj.box_options.update(kwargs)
obj.box_org_ref = 0
obj.box_org_ref = None
return obj

def __init__(self, iterable: Optional[Iterable] = None, box_class: Type[box.Box] = box.Box, **box_options):
self.box_options = box_options
self.box_options["box_class"] = box_class
self.box_org_ref = id(iterable) if iterable else 0
self.box_org_ref = iterable
if iterable:
for x in iterable:
self.append(x)
self.box_org_ref = None
if box_options.get("frozen_box"):

def frozen(*args, **kwargs):
Expand All @@ -65,6 +66,14 @@ def __getitem__(self, item):
if len(list_pos.group()) == len(item):
return value
return value.__getitem__(item[len(list_pos.group()) :].lstrip("."))
if isinstance(item, tuple):
result = self
for idx in item:
if isinstance(result, list):
result = result[idx]
else:
raise BoxTypeError(f"Cannot numpy-style indexing on {type(result).__name__}.")
return result
return super().__getitem__(item)

def __delitem__(self, key):
Expand Down Expand Up @@ -101,7 +110,11 @@ def _convert(self, p_object):
elif isinstance(p_object, box.Box):
p_object._box_config.update(self.box_options)
if isinstance(p_object, list) and not self._is_intact_type(p_object):
p_object = self.__class__(p_object, **self.box_options)
p_object = (
self
if p_object is self or p_object is self.box_org_ref
else self.__class__(p_object, **self.box_options)
)
elif isinstance(p_object, BoxList):
p_object.box_options.update(self.box_options)
return p_object
Expand Down Expand Up @@ -133,7 +146,7 @@ def _dotted_helper(self) -> List[str]:
return keys

def __repr__(self):
return f"BoxList({self.to_list()})"
return f"{self.__class__.__name__}({self.to_list()})"

def __str__(self):
return str(self.to_list())
Expand Down
2 changes: 1 addition & 1 deletion box/config_box.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def getfloat(self, item, default=None):
return self.float(item, default)

def __repr__(self):
return "ConfigBox({0})".format(str(self.to_dict()))
return f"{self.__class__.__name__}({str(self.to_dict())})"

def copy(self):
return ConfigBox(super().copy())
Expand Down
4 changes: 2 additions & 2 deletions box/shorthand_box.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def toml(self) -> str:
return self.to_toml()

def __repr__(self):
return f"SBox({self})"
return f"{self.__class__.__name__}({self})"

def copy(self) -> "SBox":
return SBox(super(SBox, self).copy())
Expand All @@ -66,4 +66,4 @@ def __new__(cls, *args, **kwargs):
return obj

def __repr__(self) -> str:
return f"DDBox({self})"
return f"{self.__class__.__name__}({self})"
12 changes: 7 additions & 5 deletions test/test_box_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ def test_box_list(self):
assert new_list[-1].item == 22
new_list.append([{"bad_item": 33}])
assert new_list[-1][0].bad_item == 33
new_list[-1].append([{"bad_item": 33}])
assert new_list[-1, -1, 0].bad_item == 33
bx = Box({0: {1: {2: {3: 3}}}, (0, 1, 2, 3): 4})
assert bx[0, 1, 2, 3] == 4
assert repr(new_list).startswith("BoxList(")
for x in new_list.to_list():
assert not isinstance(x, (BoxList, Box))
Expand Down Expand Up @@ -228,10 +232,8 @@ def test_no_recursion_errors(self):
a.list_of_dicts.append([{"example2": 2}])
assert a["list_of_dicts"][1] == [{"example2": 2}]

def test_no_circular_references(self):
if sys.version_info >= (3, 12) and sys.platform == "win32":
pytest.skip("Windows fatal exception: stack overflow on github actions")
def test_circular_references(self):
circular_list = []
circular_list.append(circular_list)
with pytest.raises(RecursionError):
BoxList(circular_list)
circular_box = BoxList(circular_list)
assert circular_box[0] == circular_box

0 comments on commit a23451d

Please sign in to comment.