-
Notifications
You must be signed in to change notification settings - Fork 107
Major Version Breaking Changes
Due to https://github.com/cdgriffith/Box/issues/251
That means if you provide my_box['a.b.c'] = 3
to a new default box, it will split it down into sub boxes!
my_box = Box(box_dots=True, default_box=True)
my_box['a.b.c']
# Box({'a': {'b': {'c': {}}}})
However this now means trying to set it without default_box
also true will result in an error:
my_box = Box(box_dots=True)
my_box['a.b.c'] = 3
# box.exceptions.BoxKeyError: ''Box' object has no attribute a'
pip install python-box[all]
is now equivlenet to pip install python-box["ruamel.yaml>=0.17", "tomli; python_version < '3.11'", "tomli-w", "msgpack"]
Now:
my_box = Box(a=1, b=2)
{'a': 5} | my_box == Box(a=1, b=2)
Previously:
my_box = Box(a=1, b=2)
{'a': 5} | my_box == Box(a=5, b=2)
If you were using the key box_namespace
before it must be changed as it will no longer work
Doing Box().getdoc()
or Box()?
in iPython will return the Box docstring
Box 6 comes with extended UTF-8 support for anything that is valid python. Which means in previous cases where characters outside the ascii latin alphabet were removed. Now they will be there.
my_box = Box({"σeq": 1})
# 6.0 behavior
my_box.σeq
#5.x and lower - will remove the σ
my_box.eq
Box 6 removed support for older ruamel.yaml
versions, and requires 0.17 at minimum. It also uses the Round Trip loader for ruamel.yaml by default.
This means if you get the error ruamel.yaml.representer.RepresenterError: cannot represent an object
you need to either fix your code (as you should probably not be dumping python objects) or use .to_yaml(ruamel_typ='unsafe')
in your code.
Box 6 is also now using Cython for speed ups on supported platforms. If you have any weird errors and need an easier to debug version, grab the *-any.whl
file and manually install https://pypi.org/project/python-box/#files
Box 5.0 no longer installs all possible converter libraries, nor requires them for use (unless you are trying to run that missing transform.) To install them when box is installed, you can include them as extra requirements via pip install -r requirements.txt
.
pip install --upgrade python-box[ruamel.yaml,toml,msgpack]
You can install all, none, or just the one(s) you need. The options are:
ruamel.yaml
-
PyYAML
(ifruamel.yaml
is also detected, Box will useruamel.yaml
first) toml
msgpack
Box 4.0 has brought a lot of great new features, but also some breaking changes. They are documented here to help you upgrade.
To install the latest 4.x you will need at least Python 3.6 (or current supported python 3.x version)
pip install --upgrade python-box>=4
If your application is no longer working, and need a quick fix:
pip install --upgrade python-box<4
Enabled with box_dots=True
.
from box import Box
my_box = Box(a={'b': {'c': {'d': 'my_value'}}}, box_dots=True)
print(my_box['a.b.c.d'])
# 'my_value
my_box['a.b.c.d'] = 'test'
# <Box: {'a': {'b': {'c': {'d': 'test'}}}}>
del my_box['a.b.c.d']
# <Box: {'a': {'b': {'c': {}}}}>
This only works with keys that are string to begin with, as we don't do any automatic conversion behind the scene.
4.1 Update: This now also supports list traversal, like my_box['my_key[0][0]']
from box import Box
Box(a=4) + Box(a='overwritten', b=5)
# <Box: {'a': 'overwritten', 'b': 5}>
- Added toml conversion support
- Added CSV conversion support
- Added box_from_file helper function
Traditional update is destructive to nested dictionaries.
from box import Box
box_one = Box(inside_dict={'data': 5})
box_two = Box(inside_dict={'folly': True})
box_one.update(box_two)
repr(box_one)
# <Box: {'inside_dict': {'folly': True}}>
Merge update takes existing sub dictionaries into consideration
from box import Box
box_one = Box(inside_dict={'data': 5})
box_two = Box(inside_dict={'folly': True})
box_one.merge_update(box_two)
repr(box_one)
"<Box: {'inside_dict': {'data': 5, 'folly': True}}>"
There was a bug in the 4.0 code that meant camel killer was not working at all under normal conditions due to the change of how the box is instantiated.
from box import Box
my_box = Box({'CamelCase': 'Item'}, camel_killer_box=True)
assert my_box.camel_case == 'Item'
print(my_box.to_dict())
# {'camel_case': 'Item'}
Keys with safety underscores used to be treated internally as if the underscores didn't always exist, i.e.
from box import Box
b = Box(_out = 'preserved')
b.update({'out': 'updated'})
# expected:
# {'_out': 'preserved', 'out': 'updated'}
# observed:
# {'_out': 'updated'}
Those issues have been (hopefully) overcome and now will have the expected <Box: {'_out': 'preserved', 'out': 'updated'}>
ruamel.yaml is now an install requirement and new default instead of PyYAML. By design ruamel.yaml uses the newer YAML v1.2 (which PyYAML does not yet support as of Jan 2020).
To use the older version of 1.1, make sure to specify the version while using the from_yaml methods.
from box import Box
Box.from_yaml("fire_ze_missiles: no")
<Box: {'fire_ze_missiles': 'no'}>
Box.from_yaml("fire_ze_missiles: no", version='1.1')
<Box: {'fire_ze_missiles': False}>
You can read more about the differences here <https://yaml.readthedocs.io/en/latest/pyyaml.html#differences-with-pyyaml>
_
To use PyYAML instead of ruamel.yaml you must install box without dependencies (such as --no-deps
with pip
)
If you do chose to stick with PyYaML, you can suppress the warning on just box's import:
import warnings
with warnings.catch_warnings():
warnings.simplefilter("ignore")
from box import Box
- Default Box will also work on
None
placeholders
Python 2 is soon officially EOL and Box 4 won't support it in anyway. Box 3 will not be updated, other than will consider PRs for bugs or security issues.
As dictionaries are ordered by default in Python 3.6+ there is no point to continue writing and testing code outside of that.
As BoxObject was not cross platform compatible and had some issues <https://github.com/GrahamDumpleton/wrapt/issues/132>
_ it has been removed.
Everything is converted on creation again, as the speed was seldom worth the extra headaches associated with such a design.
These documents are for Box 5.0+