Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-python-box for openSUSE:Factory checked in at 2022-11-12 17:40:55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-python-box (Old) and /work/SRC/openSUSE:Factory/.python-python-box.new.1597 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-python-box" Sat Nov 12 17:40:55 2022 rev:8 rq:1035242 version:6.1.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-python-box/python-python-box.changes 2022-06-18 22:06:28.271680092 +0200 +++ /work/SRC/openSUSE:Factory/.python-python-box.new.1597/python-python-box.changes 2022-11-12 17:41:12.346181070 +0100 @@ -1,0 +2,11 @@ +Wed Nov 9 18:38:35 UTC 2022 - Yogalakshmi Arunachalam <yarunacha...@suse.com> + +- Update to 6.1.0 + * Adding Python 3.11 support + * Adding #195 box_from_string function (thanks to Marcelo Huerta) + * Changing the deprecated toml package with modern tomllib, tomli and tomli-w usage (thanks to MichaŠGórny) + * Fixing mypy __ior__ type (thanks to Jacob Hayes) + * Fixing line endings with a pre-commit update + * Fixing BoxList was using old style of super in internal code usage + +------------------------------------------------------------------- Old: ---- 6.0.2.tar.gz New: ---- 6.1.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-python-box.spec ++++++ --- /var/tmp/diff_new_pack.sFY9ly/_old 2022-11-12 17:41:12.882184261 +0100 +++ /var/tmp/diff_new_pack.sFY9ly/_new 2022-11-12 17:41:12.886184285 +0100 @@ -20,7 +20,7 @@ # python_requires='>=3.6' %define skip_python2 1 Name: python-python-box -Version: 6.0.2 +Version: 6.1.0 Release: 0 Summary: Advanced Python dictionaries with dot notation access License: MIT ++++++ 6.0.2.tar.gz -> 6.1.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/.github/workflows/pythonpublish.yml new/Box-6.1.0/.github/workflows/pythonpublish.yml --- old/Box-6.0.2/.github/workflows/pythonpublish.yml 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/.github/workflows/pythonpublish.yml 2022-10-30 00:23:35.000000000 +0200 @@ -13,11 +13,11 @@ runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Python - uses: actions/setup-python@v1 + uses: actions/setup-python@v4 with: - python-version: '3.9' + python-version: '3.10' - name: Install dependencies run: | python -m pip install --upgrade pip @@ -34,13 +34,13 @@ strategy: matrix: os: [macos-latest, windows-latest] - python-version: ["3.7", "3.8", "3.9", "3.10"] + python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: Install dependencies @@ -58,15 +58,15 @@ deploy-cython-manylinux: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Python 3.10 - uses: actions/setup-python@v1 + uses: actions/setup-python@v4 with: python-version: "3.10" - uses: RalfG/python-wheels-manylinux-build@v0.4.2-manylinux2014_x86_64 with: - python-versions: 'cp37-cp37m cp38-cp38 cp39-cp39 cp310-cp310' + python-versions: 'cp37-cp37m cp38-cp38 cp39-cp39 cp310-cp310 cp311-cp311' build-requirements: 'cython' - name: Install dependencies diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/.github/workflows/tests.yml new/Box-6.1.0/.github/workflows/tests.yml --- old/Box-6.0.2/.github/workflows/tests.yml 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/.github/workflows/tests.yml 2022-10-30 00:23:35.000000000 +0200 @@ -13,13 +13,13 @@ package-checks: strategy: matrix: - python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "pypy-3.8"] + python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "pypy-3.8"] os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - uses: actions/cache@v2 @@ -66,9 +66,9 @@ package-manylinux-checks: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Python 3.10 - uses: actions/setup-python@v1 + uses: actions/setup-python@v4 with: python-version: "3.10" @@ -85,7 +85,7 @@ - uses: RalfG/python-wheels-manylinux-build@v0.4.2-manylinux2014_x86_64 with: - python-versions: 'cp37-cp37m cp38-cp38 cp39-cp39 cp310-cp310' + python-versions: 'cp37-cp37m cp38-cp38 cp39-cp39 cp310-cp310 cp311-cp311' build-requirements: 'cython' - name: Test packaged wheel on linux @@ -103,13 +103,13 @@ test: strategy: matrix: - python-version: ["3.7", "3.8", "3.9", "3.10"] + python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - uses: actions/cache@v2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/.pre-commit-config.yaml new/Box-6.1.0/.pre-commit-config.yaml --- old/Box-6.0.2/.pre-commit-config.yaml 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/.pre-commit-config.yaml 2022-10-30 00:23:35.000000000 +0200 @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 + rev: v4.3.0 hooks: # Identify invalid files - id: check-ast @@ -29,7 +29,7 @@ exclude: ^test/data/.+ - repo: https://github.com/ambv/black - rev: 22.1.0 + rev: 22.10.0 hooks: - id: black args: [--config=.black.toml] @@ -51,8 +51,8 @@ always_run: true - repo: https://github.com/pre-commit/mirrors-mypy - rev: 'v0.931' + rev: 'v0.982' hooks: - id: mypy types: [python] - additional_dependencies: [ruamel.yaml,toml,msgpack,types-PyYAML,types-toml] + additional_dependencies: [ruamel.yaml,toml,types-toml,tomli,tomli-w,msgpack,types-PyYAML] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/AUTHORS.rst new/Box-6.1.0/AUTHORS.rst --- old/Box-6.0.2/AUTHORS.rst 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/AUTHORS.rst 2022-10-30 00:23:35.000000000 +0200 @@ -27,6 +27,7 @@ - Jacob Hayes (JacobHayes) - Dominic (Yobmod) - Ivan Pepelnjak (ipspace) +- MichaŠGórny (mgorny) Suggestions and bug reporting: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/CHANGES.rst new/Box-6.1.0/CHANGES.rst --- old/Box-6.0.2/CHANGES.rst 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/CHANGES.rst 2022-10-30 00:23:35.000000000 +0200 @@ -1,6 +1,16 @@ Changelog ========= +Version 6.1.0 +------------- + +* Adding Python 3.11 support +* Adding #195 box_from_string function (thanks to Marcelo Huerta) +* Changing the deprecated ``toml`` package with modern ``tomllib``, ``tomli`` and ``tomli-w`` usage (thanks to MichaŠGórny) +* Fixing mypy __ior__ type (thanks to Jacob Hayes) +* Fixing line endings with a pre-commit update +* Fixing BoxList was using old style of `super` in internal code usage + Version 6.0.2 ------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/README.rst new/Box-6.1.0/README.rst --- old/Box-6.0.2/README.rst 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/README.rst 2022-10-30 00:23:35.000000000 +0200 @@ -59,7 +59,7 @@ Check out `more details <https://github.com/cdgriffith/Box/wiki/Installation>`_ on installation details. -Box 6 is tested on python 3.6+, if you are upgrading from previous versions, please look through +Box 6 is tested on python 3.7+, if you are upgrading from previous versions, please look through `any breaking changes and new features <https://github.com/cdgriffith/Box/wiki/Major-Version-Breaking-Changes>`_. Optimized Version diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/box/__init__.py new/Box-6.1.0/box/__init__.py --- old/Box-6.0.2/box/__init__.py 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/box/__init__.py 2022-10-30 00:23:35.000000000 +0200 @@ -2,13 +2,13 @@ # -*- coding: utf-8 -*- __author__ = "Chris Griffith" -__version__ = "6.0.2" +__version__ = "6.1.0" from box.box import Box from box.box_list import BoxList from box.config_box import ConfigBox from box.exceptions import BoxError, BoxKeyError -from box.from_file import box_from_file +from box.from_file import box_from_file, box_from_string from box.shorthand_box import SBox import box.converters diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/box/box.py new/Box-6.1.0/box/box.py --- old/Box-6.0.2/box/box.py 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/box/box.py 2022-10-30 00:23:35.000000000 +0200 @@ -29,7 +29,8 @@ _to_toml, _to_yaml, msgpack_available, - toml_available, + toml_read_library, + toml_write_library, yaml_available, ) from box.exceptions import BoxError, BoxKeyError, BoxTypeError, BoxValueError, BoxWarning @@ -301,7 +302,7 @@ new_box.update(other) return new_box - def __ior__(self, other: Mapping[Any, Any]): + def __ior__(self, other: Mapping[Any, Any]): # type: ignore[override] if not isinstance(other, dict): raise BoxTypeError("Box can only merge two boxes or a box and a dictionary.") self.update(other) @@ -954,7 +955,7 @@ ) -> "Box": raise BoxError('yaml is unavailable on this system, please install the "ruamel.yaml" or "PyYAML" package') - if toml_available: + if toml_write_library is not None: def to_toml(self, filename: Union[str, PathLike] = None, encoding: str = "utf-8", errors: str = "strict"): """ @@ -967,6 +968,13 @@ """ return _to_toml(self.to_dict(), filename=filename, encoding=encoding, errors=errors) + else: + + def to_toml(self, filename: Union[str, PathLike] = None, encoding: str = "utf-8", errors: str = "strict"): + raise BoxError('toml is unavailable on this system, please install the "tomli-w" package') + + if toml_read_library is not None: + @classmethod def from_toml( cls, @@ -996,9 +1004,6 @@ else: - def to_toml(self, filename: Union[str, PathLike] = None, encoding: str = "utf-8", errors: str = "strict"): - raise BoxError('toml is unavailable on this system, please install the "toml" package') - @classmethod def from_toml( cls, @@ -1008,7 +1013,7 @@ errors: str = "strict", **kwargs, ) -> "Box": - raise BoxError('toml is unavailable on this system, please install the "toml" package') + raise BoxError('toml is unavailable on this system, please install the "tomli" package') if msgpack_available: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/box/box.pyi new/Box-6.1.0/box/box.pyi --- old/Box-6.0.2/box/box.pyi 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/box/box.pyi 2022-10-30 00:23:35.000000000 +0200 @@ -46,7 +46,7 @@ def __iadd__(self, other: Mapping[Any, Any]) -> Any: ... def __or__(self, other: Mapping[Any, Any]) -> Any: ... def __ror__(self, other: Mapping[Any, Any]) -> Any: ... - def __ior__(self, other: Mapping[Any, Any]) -> Any: ... + def __ior__(self, other: Mapping[Any, Any]) -> Any: ... # type: ignore[override] def __sub__(self, other: Mapping[Any, Any]) -> Any: ... def __hash__(self) -> Any: ... # type: ignore[override] def __dir__(self): ... diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/box/box_list.py new/Box-6.1.0/box/box_list.py --- old/Box-6.0.2/box/box_list.py 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/box/box_list.py 2022-10-30 00:23:35.000000000 +0200 @@ -21,7 +21,8 @@ _to_toml, _to_yaml, msgpack_available, - toml_available, + toml_read_library, + toml_write_library, yaml_available, ) from box.exceptions import BoxError, BoxTypeError @@ -61,11 +62,11 @@ def __getitem__(self, item): if self.box_options.get("box_dots") and isinstance(item, str) and item.startswith("["): list_pos = _list_pos_re.search(item) - value = super(BoxList, self).__getitem__(int(list_pos.groups()[0])) + value = super().__getitem__(int(list_pos.groups()[0])) if len(list_pos.group()) == len(item): return value return value.__getitem__(item[len(list_pos.group()) :].lstrip(".")) - return super(BoxList, self).__getitem__(item) + return super().__getitem__(item) def __delitem__(self, key): if self.box_options.get("frozen_box"): @@ -74,10 +75,10 @@ list_pos = _list_pos_re.search(key) pos = int(list_pos.groups()[0]) if len(list_pos.group()) == len(key): - return super(BoxList, self).__delitem__(pos) + return super().__delitem__(pos) if hasattr(self[pos], "__delitem__"): return self[pos].__delitem__(key[len(list_pos.group()) :].lstrip(".")) # type: ignore - super(BoxList, self).__delitem__(key) + super().__delitem__(key) def __setitem__(self, key, value): if self.box_options.get("frozen_box"): @@ -86,9 +87,9 @@ list_pos = _list_pos_re.search(key) pos = int(list_pos.groups()[0]) if len(list_pos.group()) == len(key): - return super(BoxList, self).__setitem__(pos, value) - return super(BoxList, self).__getitem__(pos).__setitem__(key[len(list_pos.group()) :].lstrip("."), value) - super(BoxList, self).__setitem__(key, value) + return super().__setitem__(pos, value) + return super().__getitem__(pos).__setitem__(key[len(list_pos.group()) :].lstrip("."), value) + super().__setitem__(key, value) def _is_intact_type(self, obj): if self.box_options.get("box_intact_types") and isinstance(obj, self.box_options["box_intact_types"]): @@ -107,14 +108,14 @@ return p_object def append(self, p_object): - super(BoxList, self).append(self._convert(p_object)) + super().append(self._convert(p_object)) def extend(self, iterable): for item in iterable: self.append(item) def insert(self, index, p_object): - super(BoxList, self).insert(index, self._convert(p_object)) + super().insert(index, self._convert(p_object)) def _dotted_helper(self): keys = [] @@ -312,7 +313,7 @@ ): raise BoxError('yaml is unavailable on this system, please install the "ruamel.yaml" or "PyYAML" package') - if toml_available: + if toml_read_library is not None: def to_toml( self, @@ -333,6 +334,19 @@ """ return _to_toml({key_name: self.to_list()}, filename=filename, encoding=encoding, errors=errors) + else: + + def to_toml( + self, + filename: Union[str, PathLike] = None, + key_name: str = "toml", + encoding: str = "utf-8", + errors: str = "strict", + ): + raise BoxError('toml is unavailable on this system, please install the "tomli-w" package') + + if toml_read_library is not None: + @classmethod def from_toml( cls, @@ -367,15 +381,6 @@ else: - def to_toml( - self, - filename: Union[str, PathLike] = None, - key_name: str = "toml", - encoding: str = "utf-8", - errors: str = "strict", - ): - raise BoxError('toml is unavailable on this system, please install the "toml" package') - @classmethod def from_toml( cls, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/box/box_list.pyi new/Box-6.1.0/box/box_list.pyi --- old/Box-6.0.2/box/box_list.pyi 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/box/box_list.pyi 2022-10-30 00:23:35.000000000 +0200 @@ -1,9 +1,10 @@ import box from box.converters import ( - BOX_PARAMETERS as BOX_PARAMETERS, - msgpack_available as msgpack_available, - toml_available as toml_available, - yaml_available as yaml_available, + BOX_PARAMETERS, + msgpack_available, + yaml_available, + toml_read_library, + toml_write_library, ) from box.exceptions import BoxError as BoxError, BoxTypeError as BoxTypeError from os import PathLike as PathLike diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/box/converters.py new/Box-6.1.0/box/converters.py --- old/Box-6.0.2/box/converters.py 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/box/converters.py 2022-10-30 00:23:35.000000000 +0200 @@ -5,16 +5,16 @@ import csv import json +import sys from io import StringIO from os import PathLike from pathlib import Path -from typing import Union, Optional, Dict +from typing import Union, Optional, Dict, Any, Callable from box.exceptions import BoxError pyyaml_available = True ruamel_available = True -toml_available = True msgpack_available = True try: @@ -30,11 +30,59 @@ except ImportError: pyyaml_available = False +toml_read_library: Optional[Any] = None +toml_write_library: Optional[Any] = None +toml_decode_error: Optional[Callable] = None + + +class BoxTomlDecodeError(BoxError): + """Toml Decode Error""" + + try: import toml except ImportError: - toml = None # type: ignore - toml_available = False + pass +else: + toml_read_library = toml + toml_write_library = toml + toml_decode_error = toml.TomlDecodeError + + class BoxTomlDecodeError(BoxError, toml.TomlDecodeError): # type: ignore + """Toml Decode Error""" + + +try: + import tomllib +except ImportError: + pass +else: + toml_read_library = tomllib + toml_decode_error = tomllib.TOMLDecodeError + + class BoxTomlDecodeError(BoxError, tomllib.TOMLDecodeError): # type: ignore + """Toml Decode Error""" + + +try: + import tomli +except ImportError: + pass +else: + toml_read_library = tomli + toml_decode_error = tomli.TOMLDecodeError + + class BoxTomlDecodeError(BoxError, tomli.TOMLDecodeError): # type: ignore + """Toml Decode Error""" + + +try: + import tomli_w +except ImportError: + pass +else: + toml_write_library = tomli_w + try: import msgpack # type: ignore @@ -198,21 +246,41 @@ def _to_toml(obj, filename: Union[str, PathLike] = None, encoding: str = "utf-8", errors: str = "strict"): if filename: _exists(filename, create=True) - with open(filename, "w", encoding=encoding, errors=errors) as f: - toml.dump(obj, f) + if toml_write_library.__name__ == "toml": # type: ignore + with open(filename, "w", encoding=encoding, errors=errors) as f: + try: + toml_write_library.dump(obj, f) # type: ignore + except toml_decode_error as err: # type: ignore + raise BoxTomlDecodeError(err) from err + else: + with open(filename, "wb") as f: + try: + toml_write_library.dump(obj, f) # type: ignore + except toml_decode_error as err: # type: ignore + raise BoxTomlDecodeError(err) from err else: - return toml.dumps(obj) + try: + return toml_write_library.dumps(obj) # type: ignore + except toml_decode_error as err: # type: ignore + raise BoxTomlDecodeError(err) from err def _from_toml( - toml_string: str = None, filename: Union[str, PathLike] = None, encoding: str = "utf-8", errors: str = "strict" + toml_string: str = None, + filename: Union[str, PathLike] = None, + encoding: str = "utf-8", + errors: str = "strict", ): if filename: _exists(filename) - with open(filename, "r", encoding=encoding, errors=errors) as f: - data = toml.load(f) + if toml_read_library.__name__ == "toml": # type: ignore + with open(filename, "r", encoding=encoding, errors=errors) as f: + data = toml_read_library.load(f) # type: ignore + else: + with open(filename, "rb") as f: + data = toml_read_library.load(f) # type: ignore elif toml_string: - data = toml.loads(toml_string) + data = toml_read_library.loads(toml_string) # type: ignore else: raise BoxError("from_toml requires a string or filename") return data diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/box/converters.pyi new/Box-6.1.0/box/converters.pyi --- old/Box-6.0.2/box/converters.pyi 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/box/converters.pyi 2022-10-30 00:23:35.000000000 +0200 @@ -1,11 +1,14 @@ from box.exceptions import BoxError as BoxError from os import PathLike as PathLike -from typing import Any, Union, Optional, Dict +from typing import Any, Union, Optional, Dict, Callable yaml_available: bool toml_available: bool msgpack_available: bool BOX_PARAMETERS: Any +toml_read_library: Optional[Any] +toml_write_library: Optional[Any] +toml_decode_error: Optional[Callable] def _exists(filename: Union[str, PathLike], create: bool = False) -> Any: ... def _to_json( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/box/from_file.py new/Box-6.1.0/box/from_file.py --- old/Box-6.0.2/box/from_file.py 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/box/from_file.py 2022-10-30 00:23:35.000000000 +0200 @@ -4,10 +4,11 @@ from os import PathLike from pathlib import Path from typing import Callable, Dict, Union +import sys from box.box import Box from box.box_list import BoxList -from box.converters import msgpack_available, toml_available, yaml_available +from box.converters import msgpack_available, toml_read_library, yaml_available, toml_decode_error from box.exceptions import BoxError try: @@ -19,17 +20,12 @@ YAMLError = False # type: ignore try: - from toml import TomlDecodeError # type: ignore -except ImportError: - TomlDecodeError = False # type: ignore - -try: from msgpack import UnpackException # type: ignore except ImportError: UnpackException = False # type: ignore -__all__ = ["box_from_file"] +__all__ = ["box_from_file", "box_from_string"] def _to_json(file, encoding, errors, **kwargs): @@ -59,11 +55,11 @@ def _to_toml(file, encoding, errors, **kwargs): - if not toml_available: - raise BoxError(f'File "{file}" is toml but no package is available to open it. Please install "toml"') + if not toml_read_library: + raise BoxError(f'File "{file}" is toml but no package is available to open it. Please install "tomli"') try: return Box.from_toml(filename=file, encoding=encoding, errors=errors, **kwargs) - except TomlDecodeError: + except toml_decode_error: raise BoxError("File is not TOML as expected") @@ -113,3 +109,37 @@ if file_type.lower() in converters: return converters[file_type.lower()](file, encoding, errors, **kwargs) # type: ignore raise BoxError(f'"{file_type}" is an unknown type. Please use either csv, toml, msgpack, yaml or json') + + +def box_from_string(content: str, string_type: str = "json") -> Union[Box, BoxList]: + """ + Parse the provided string into a Box or BoxList object as appropriate. + + :param content: String to parse + :param string_type: manually specify file type: json, toml or yaml + :return: Box or BoxList + """ + + if string_type == "json": + try: + return Box.from_json(json_string=content) + except JSONDecodeError: + raise BoxError("File is not JSON as expected") + except BoxError: + return BoxList.from_json(json_string=content) + elif string_type == "toml": + try: + return Box.from_toml(toml_string=content) + except toml_decode_error: # type: ignore + raise BoxError("File is not TOML as expected") + except BoxError: + return BoxList.from_toml(toml_string=content) + elif string_type == "yaml": + try: + return Box.from_yaml(yaml_string=content) + except YAMLError: + raise BoxError("File is not YAML as expected") + except BoxError: + return BoxList.from_yaml(yaml_string=content) + else: + raise BoxError(f"Unsupported string_string of {string_type}") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/box/from_file.pyi new/Box-6.1.0/box/from_file.pyi --- old/Box-6.0.2/box/from_file.pyi 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/box/from_file.pyi 2022-10-30 00:23:35.000000000 +0200 @@ -6,3 +6,4 @@ def box_from_file( file: Union[str, PathLike], file_type: str = ..., encoding: str = ..., errors: str = ..., **kwargs: Any ) -> Union[Box, BoxList]: ... +def box_from_string(content: str, string_type: str = ...) -> Union[Box, BoxList]: ... diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/requirements-dev.txt new/Box-6.1.0/requirements-dev.txt --- old/Box-6.0.2/requirements-dev.txt 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/requirements-dev.txt 2022-10-30 00:23:35.000000000 +0200 @@ -1,5 +1,5 @@ # Files needed for pre-commit hooks -black>=21.7b0 +black>=22.10.0 Cython>=0.29 -mypy>=0.910 -pre-commit>=2.15 +mypy>=0.982 +pre-commit>=2.20 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/requirements-test.txt new/Box-6.1.0/requirements-test.txt --- old/Box-6.0.2/requirements-test.txt 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/requirements-test.txt 2022-10-30 00:23:35.000000000 +0200 @@ -1,9 +1,9 @@ coverage>=5.0.4 msgpack>=1.0 -pytest>=5.4.1 +pytest>=7.1.3 pytest-cov>=2.8.1 ruamel.yaml>=0.17 -toml>=0.10.2 +tomli>=1.2.3; python_version < '3.11' +tomli-w>=1.0.0 types-PyYAML>=6.0.3 -types-toml>=0.1.3 wheel>=0.34.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/requirements.txt new/Box-6.1.0/requirements.txt --- old/Box-6.0.2/requirements.txt 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/requirements.txt 2022-10-30 00:23:35.000000000 +0200 @@ -1,3 +1,4 @@ msgpack>=1.0.0 ruamel.yaml>=0.17 -toml>=0.10.2 +tomli>=1.2.3; python_version < '3.11' +tomli-w diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/setup.py new/Box-6.1.0/setup.py --- old/Box-6.0.2/setup.py 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/setup.py 2022-10-30 00:23:35.000000000 +0200 @@ -44,7 +44,7 @@ py_modules=["box"], packages=["box"], ext_modules=extra, - python_requires=">=3.6", + python_requires=">=3.7", include_package_data=True, platforms="any", classifiers=[ @@ -55,6 +55,7 @@ "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Programming Language :: Python :: Implementation :: CPython", "Development Status :: 5 - Production/Stable", "Natural Language :: English", @@ -70,6 +71,7 @@ "yaml": ["ruamel.yaml>=0.17"], "ruamel.yaml": ["ruamel.yaml>=0.17"], "PyYAML": ["PyYAML"], + "tomli": ["tomli; python_version < '3.11'", "tomli-w"], "toml": ["toml"], "msgpack": ["msgpack"], }, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/test/data/bad_file.txt new/Box-6.1.0/test/data/bad_file.txt --- old/Box-6.0.2/test/data/bad_file.txt 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/test/data/bad_file.txt 2022-10-30 00:23:35.000000000 +0200 @@ -1,3 +1,3 @@ Nothing good in here # bad data -test/ \ No newline at end of file +test/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/test/data/json_list.json new/Box-6.1.0/test/data/json_list.json --- old/Box-6.0.2/test/data/json_list.json 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/test/data/json_list.json 2022-10-30 00:23:35.000000000 +0200 @@ -1,4 +1,4 @@ [ "test", "data" -] \ No newline at end of file +] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/test/test_box_list.py new/Box-6.1.0/test/test_box_list.py --- old/Box-6.0.2/test/test_box_list.py 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/test/test_box_list.py 2022-10-30 00:23:35.000000000 +0200 @@ -11,9 +11,9 @@ import pytest from ruamel.yaml import YAML -import toml from box import Box, BoxError, BoxList +from box.converters import toml_read_library, toml_write_library class TestBoxList: @@ -101,19 +101,19 @@ def test_box_list_to_toml(self): bl = BoxList([{"item": 1, "CamelBad": 2}]) - assert toml.loads(bl.to_toml(key_name="test"))["test"][0]["item"] == 1 + assert toml_read_library.loads(bl.to_toml(key_name="test"))["test"][0]["item"] == 1 with pytest.raises(BoxError): BoxList.from_toml("[[test]]\nitem = 1\nCamelBad = 2\n\n", key_name="does not exist") def test_box_list_from_tml(self): alist = [{"item": 1}, {"CamelBad": 2}] - toml_list = toml.dumps({"key": alist}) + toml_list = toml_write_library.dumps({"key": alist}) bl = BoxList.from_toml(toml_string=toml_list, key_name="key", camel_killer_box=True) assert bl[0].item == 1 assert bl[1].camel_bad == 2 with pytest.raises(BoxError): - BoxList.from_toml(toml.dumps({"a": 2}), "a") + BoxList.from_toml(toml_write_library.dumps({"a": 2}), "a") with pytest.raises(BoxError): BoxList.from_toml(toml_list, "bad_key") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/test/test_from_file.py new/Box-6.1.0/test/test_from_file.py --- old/Box-6.0.2/test/test_from_file.py 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/test/test_from_file.py 2022-10-30 00:23:35.000000000 +0200 @@ -5,7 +5,7 @@ import pytest -from box import Box, BoxError, BoxList, box_from_file +from box import Box, BoxError, BoxList, box_from_file, box_from_string class TestFromFile: @@ -37,3 +37,13 @@ box_from_file(Path(test_root, "data", "bad_file.txt")) with pytest.raises(BoxError): box_from_file("does not exist") + + def test_from_string_all(self): + with open(Path(test_root, "data", "json_file.json"), "r") as f: + box_from_string(f.read()) + + with open(Path(test_root, "data", "toml_file.tml"), "r") as f: + box_from_string(f.read(), string_type="toml") + + with open(Path(test_root, "data", "yaml_file.yaml"), "r") as f: + box_from_string(f.read(), string_type="yaml") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Box-6.0.2/test/test_sbox.py new/Box-6.1.0/test/test_sbox.py --- old/Box-6.0.2/test/test_sbox.py 2022-04-02 04:24:21.000000000 +0200 +++ new/Box-6.1.0/test/test_sbox.py 2022-10-30 00:23:35.000000000 +0200 @@ -3,6 +3,8 @@ import json from test.common import test_dict +import pytest + from ruamel.yaml import YAML from box import Box, SBox