python-bunch 0.1.5__tar.gz → 0.1.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,18 +1,18 @@
1
- This applies only to the contents of this package and does not affect the licensing of any projects that depend on it.
2
-
3
- This is free and unencumbered software released into the public domain.
4
-
5
- Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
6
- software, either in source code form or as a compiled binary, for any purpose,
7
- commercial or non-commercial, and by any means.
8
-
9
- In jurisdictions that recognize copyright laws, the author has dedicated any
10
- copyright interest in the software to the public domain. This software is
11
- provided "as is", without warranty of any kind, express or implied, including
12
- but not limited to the warranties of merchantability, fitness for a particular
13
- purpose and noninfringement. In no event shall the authors be liable for any
14
- claim, damages or other liability, whether in an action of contract, tort or
15
- otherwise, arising from, out of or in connection with the software or the use
16
- or other dealings in the software.
17
-
18
- For more information, please refer to <https://unlicense.org>
1
+ This applies only to the contents of this package and does not affect the licensing of any projects that depend on it.
2
+
3
+ This is free and unencumbered software released into the public domain.
4
+
5
+ Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
6
+ software, either in source code form or as a compiled binary, for any purpose,
7
+ commercial or non-commercial, and by any means.
8
+
9
+ In jurisdictions that recognize copyright laws, the author has dedicated any
10
+ copyright interest in the software to the public domain. This software is
11
+ provided "as is", without warranty of any kind, express or implied, including
12
+ but not limited to the warranties of merchantability, fitness for a particular
13
+ purpose and noninfringement. In no event shall the authors be liable for any
14
+ claim, damages or other liability, whether in an action of contract, tort or
15
+ otherwise, arising from, out of or in connection with the software or the use
16
+ or other dealings in the software.
17
+
18
+ For more information, please refer to <https://unlicense.org>
@@ -1,52 +1,53 @@
1
- Metadata-Version: 2.4
2
- Name: python-bunch
3
- Version: 0.1.5
4
- Summary: A lightweight Python class that behaves like a dict but supports attribute-style access.
5
- Author-email: Omer Menashe <unspecified@mail.com>
6
- License: MIT
7
- Keywords: python-bunch,bunch,dict,attribute-access,json,utility
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Operating System :: OS Independent
11
- Requires-Python: >=3.7
12
- Description-Content-Type: text/markdown
13
- License-File: LICENSE
14
- Dynamic: license-file
15
-
16
- ## Bunch
17
-
18
- A simple Python class that allows dictionary-style and attribute-style access to data interchangeably. Think of it as a lightweight object wrapper for dictionaries — great for config objects, JSON responses, or anything else you'd normally throw in a dict.
19
-
20
- ### <ins> Features </ins>
21
-
22
- - Access keys as attributes or like a dictionary
23
- - Convert from regular dictionaries
24
- - Pretty-printed JSON representation
25
- - Check if a value exists
26
- - Fully compatible with `in`, `.keys()`, `.items()`, etc.
27
-
28
- ### <ins> Installation </ins>
29
-
30
- You can install this package via PIP: _pip install python-bunch_
31
-
32
- ### <ins> Usage </ins>
33
-
34
- ```python
35
- # - Mutable Bunch -
36
- from bunch.bunch import Bunch
37
-
38
- my_bunch = Bunch({'name': 'Jane', 'age': 30})
39
-
40
- print(my_bunch.name) # Output: Jane
41
- print(my_bunch['age']) # Output: 30
42
-
43
- # - Immutable Bunch -v
44
- from bunch.immutable_bunch import ImmutableBunch
45
-
46
- my_immutable_bunch = ImmutableBunch({'name': 'John', 'age': 25})
47
- print(my_immutable_bunch.name) # Output: John
48
- print(my_immutable_bunch['age']) # Output: 35
49
-
50
- # Attempting to modify an ImmutableBunch will raise an Exception
51
- my_immutable_bunch.name = 'Alice' # Raises ImmutableBunchException
52
- ```
1
+ Metadata-Version: 2.4
2
+ Name: python-bunch
3
+ Version: 0.1.6
4
+ Summary: A lightweight Python class that behaves like a dict but supports attribute-style access.
5
+ Author-email: Omer Menashe <unspecified@mail.com>
6
+ License: MIT
7
+ Project-URL: Source, https://github.com/iamomerm/python-bunch
8
+ Keywords: python-bunch,bunch,dict,attribute-access,json,utility
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.7
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Dynamic: license-file
16
+
17
+ ## Bunch
18
+
19
+ A simple Python class that allows dictionary-style and attribute-style access to data interchangeably. Think of it as a lightweight object wrapper for dictionaries — great for config objects, JSON responses, or anything else you'd normally throw in a dict.
20
+
21
+ ### <ins> Features </ins>
22
+
23
+ - Access keys as attributes or like a dictionary
24
+ - Convert from regular dictionaries
25
+ - Pretty-printed JSON representation
26
+ - Check if a value exists
27
+ - Fully compatible with `in`, `.keys()`, `.items()`, etc.
28
+
29
+ ### <ins> Installation </ins>
30
+
31
+ You can install this package via PIP: _pip install python-bunch_
32
+
33
+ ### <ins> Usage </ins>
34
+
35
+ ```python
36
+ # - Mutable Bunch -
37
+ from bunch.bunch import Bunch
38
+
39
+ my_bunch = Bunch({'name': 'Jane', 'age': 30})
40
+
41
+ print(my_bunch.name) # Output: Jane
42
+ print(my_bunch['age']) # Output: 30
43
+
44
+ # - Immutable Bunch -v
45
+ from bunch.immutable_bunch import ImmutableBunch
46
+
47
+ my_immutable_bunch = ImmutableBunch({'name': 'John', 'age': 25})
48
+ print(my_immutable_bunch.name) # Output: John
49
+ print(my_immutable_bunch['age']) # Output: 35
50
+
51
+ # Attempting to modify an ImmutableBunch will raise an Exception
52
+ my_immutable_bunch.name = 'Alice' # Raises ImmutableBunchException
53
+ ```
@@ -1,37 +1,37 @@
1
- ## Bunch
2
-
3
- A simple Python class that allows dictionary-style and attribute-style access to data interchangeably. Think of it as a lightweight object wrapper for dictionaries — great for config objects, JSON responses, or anything else you'd normally throw in a dict.
4
-
5
- ### <ins> Features </ins>
6
-
7
- - Access keys as attributes or like a dictionary
8
- - Convert from regular dictionaries
9
- - Pretty-printed JSON representation
10
- - Check if a value exists
11
- - Fully compatible with `in`, `.keys()`, `.items()`, etc.
12
-
13
- ### <ins> Installation </ins>
14
-
15
- You can install this package via PIP: _pip install python-bunch_
16
-
17
- ### <ins> Usage </ins>
18
-
19
- ```python
20
- # - Mutable Bunch -
21
- from bunch.bunch import Bunch
22
-
23
- my_bunch = Bunch({'name': 'Jane', 'age': 30})
24
-
25
- print(my_bunch.name) # Output: Jane
26
- print(my_bunch['age']) # Output: 30
27
-
28
- # - Immutable Bunch -v
29
- from bunch.immutable_bunch import ImmutableBunch
30
-
31
- my_immutable_bunch = ImmutableBunch({'name': 'John', 'age': 25})
32
- print(my_immutable_bunch.name) # Output: John
33
- print(my_immutable_bunch['age']) # Output: 35
34
-
35
- # Attempting to modify an ImmutableBunch will raise an Exception
36
- my_immutable_bunch.name = 'Alice' # Raises ImmutableBunchException
37
- ```
1
+ ## Bunch
2
+
3
+ A simple Python class that allows dictionary-style and attribute-style access to data interchangeably. Think of it as a lightweight object wrapper for dictionaries — great for config objects, JSON responses, or anything else you'd normally throw in a dict.
4
+
5
+ ### <ins> Features </ins>
6
+
7
+ - Access keys as attributes or like a dictionary
8
+ - Convert from regular dictionaries
9
+ - Pretty-printed JSON representation
10
+ - Check if a value exists
11
+ - Fully compatible with `in`, `.keys()`, `.items()`, etc.
12
+
13
+ ### <ins> Installation </ins>
14
+
15
+ You can install this package via PIP: _pip install python-bunch_
16
+
17
+ ### <ins> Usage </ins>
18
+
19
+ ```python
20
+ # - Mutable Bunch -
21
+ from bunch.bunch import Bunch
22
+
23
+ my_bunch = Bunch({'name': 'Jane', 'age': 30})
24
+
25
+ print(my_bunch.name) # Output: Jane
26
+ print(my_bunch['age']) # Output: 30
27
+
28
+ # - Immutable Bunch -v
29
+ from bunch.immutable_bunch import ImmutableBunch
30
+
31
+ my_immutable_bunch = ImmutableBunch({'name': 'John', 'age': 25})
32
+ print(my_immutable_bunch.name) # Output: John
33
+ print(my_immutable_bunch['age']) # Output: 35
34
+
35
+ # Attempting to modify an ImmutableBunch will raise an Exception
36
+ my_immutable_bunch.name = 'Alice' # Raises ImmutableBunchException
37
+ ```
@@ -1,70 +1,70 @@
1
- import json
2
- from typing import Any
3
-
4
-
5
- class Bunch:
6
- def __init__(self, *args, **kwargs):
7
- for arg in args:
8
- if not isinstance(arg, dict):
9
- kwargs[arg] = None
10
- self.__dict__.update(kwargs)
11
-
12
- def __getitem__(self, key: Any) -> Any or None:
13
- return self.__dict__.get(key, None)
14
-
15
- def __setitem__(self, key: Any, value: Any) -> None:
16
- self.__dict__[key] = value
17
-
18
- def __delitem__(self, key: Any) -> None:
19
- del self.__dict__[key]
20
-
21
- def __contains__(self, key: Any) -> bool:
22
- return key in self.__dict__
23
-
24
- def __str__(self) -> str:
25
- return json.dumps(self.__dict__, sort_keys=False)
26
-
27
- def __repr__(self) -> str:
28
- return self.__str__()
29
-
30
- def __getattr__(self, key: Any) -> Any or None:
31
- if key in self.__dict__:
32
- return self.__dict__[key]
33
- return None
34
-
35
- def __setattr__(self, name: str, value: Any) -> None:
36
- self.__dict__[name] = value
37
-
38
- def __delattr__(self, name) -> None:
39
- del self.__dict__[name]
40
-
41
- def contains_value(self, value: Any) -> bool:
42
- return value in self.__dict__.values()
43
-
44
- def clear(self) -> None:
45
- self.__dict__.clear()
46
-
47
- def pop(self, key: Any, default: Any = None) -> Any or None:
48
- return self.__dict__.pop(key, default)
49
-
50
- def popitem(self) -> Any or None:
51
- return self.__dict__.popitem()
52
-
53
- def update(self, other: dict) -> None:
54
- self.__dict__.update(other)
55
-
56
- def setdefault(self, key: Any, default: Any = None) -> Any or None:
57
- return self.__dict__.setdefault(key, default)
58
-
59
- def keys(self):
60
- return self.__dict__.keys()
61
-
62
- def values(self):
63
- return self.__dict__.values()
64
-
65
- def items(self):
66
- return self.__dict__.items()
67
-
68
- @staticmethod
69
- def from_dict(dictionary: dict) -> Any:
70
- return Bunch(**dictionary)
1
+ import json
2
+ from typing import Any
3
+
4
+
5
+ class Bunch:
6
+ def __init__(self, *args, **kwargs):
7
+ for arg in args:
8
+ if not isinstance(arg, dict):
9
+ kwargs[arg] = None
10
+ self.__dict__.update(kwargs)
11
+
12
+ def __getitem__(self, key: Any) -> Any or None:
13
+ return self.__dict__.get(key, None)
14
+
15
+ def __setitem__(self, key: Any, value: Any) -> None:
16
+ self.__dict__[key] = value
17
+
18
+ def __delitem__(self, key: Any) -> None:
19
+ del self.__dict__[key]
20
+
21
+ def __contains__(self, key: Any) -> bool:
22
+ return key in self.__dict__
23
+
24
+ def __str__(self) -> str:
25
+ return json.dumps(self.__dict__, sort_keys=False)
26
+
27
+ def __repr__(self) -> str:
28
+ return self.__str__()
29
+
30
+ def __getattr__(self, key: Any) -> Any or None:
31
+ if key in self.__dict__:
32
+ return self.__dict__[key]
33
+ return None
34
+
35
+ def __setattr__(self, name: str, value: Any) -> None:
36
+ self.__dict__[name] = value
37
+
38
+ def __delattr__(self, name) -> None:
39
+ del self.__dict__[name]
40
+
41
+ def contains_value(self, value: Any) -> bool:
42
+ return value in self.__dict__.values()
43
+
44
+ def clear(self) -> None:
45
+ self.__dict__.clear()
46
+
47
+ def pop(self, key: Any, default: Any = None) -> Any or None:
48
+ return self.__dict__.pop(key, default)
49
+
50
+ def popitem(self) -> Any or None:
51
+ return self.__dict__.popitem()
52
+
53
+ def update(self, other: dict) -> None:
54
+ self.__dict__.update(other)
55
+
56
+ def setdefault(self, key: Any, default: Any = None) -> Any or None:
57
+ return self.__dict__.setdefault(key, default)
58
+
59
+ def keys(self):
60
+ return self.__dict__.keys()
61
+
62
+ def values(self):
63
+ return self.__dict__.values()
64
+
65
+ def items(self):
66
+ return self.__dict__.items()
67
+
68
+ @staticmethod
69
+ def from_dict(dictionary: dict) -> Any:
70
+ return Bunch(**dictionary)
@@ -1,75 +1,75 @@
1
- import json
2
- from typing import Any
3
-
4
-
5
- class ImmutableBunchException(Exception):
6
- def __init__(self, message: str) -> None:
7
- super().__init__(message)
8
-
9
-
10
- class ImmutableBunch:
11
- def __init__(self, *args, **kwargs):
12
- for arg in args:
13
- if not isinstance(arg, dict):
14
- kwargs[arg] = None
15
- self.__dict__.update(kwargs)
16
-
17
- def __getitem__(self, key: Any) -> Any or None:
18
- return self.__dict__.get(key, None)
19
-
20
- def __setitem__(self, key: Any, value: Any) -> None:
21
- raise ImmutableBunchException('ImmutableBunch does not support item assignment')
22
-
23
- def __delitem__(self, key: Any) -> None:
24
- raise ImmutableBunchException('ImmutableBunch does not support item deletion')
25
-
26
- def __contains__(self, key: Any) -> bool:
27
- return key in self.__dict__
28
-
29
- def __str__(self) -> str:
30
- return json.dumps(self.__dict__, sort_keys=False)
31
-
32
- def __repr__(self) -> str:
33
- return self.__str__()
34
-
35
- def __getattr__(self, key: Any) -> Any or None:
36
- if key in self.__dict__:
37
- return self.__dict__[key]
38
- return None
39
-
40
- def __setattr__(self, name: str, value: Any) -> None:
41
- raise ImmutableBunchException('ImmutableBunch does not support attribute assignment')
42
-
43
- def __delattr__(self, name) -> None:
44
- raise ImmutableBunchException('ImmutableBunch does not support attribute deletion')
45
-
46
- def contains_value(self, value: Any) -> bool:
47
- return value in self.__dict__.values()
48
-
49
- def clear(self) -> None:
50
- raise ImmutableBunchException('ImmutableBunch does not support clearing')
51
-
52
- def pop(self, key: Any, default: Any = None) -> Any or None:
53
- raise ImmutableBunchException('ImmutableBunch does not support popping')
54
-
55
- def popitem(self) -> Any or None:
56
- raise ImmutableBunchException('ImmutableBunch does not support popitem')
57
-
58
- def update(self, other: dict) -> None:
59
- raise ImmutableBunchException('ImmutableBunch does not support update')
60
-
61
- def setdefault(self, key: Any, default: Any = None) -> Any or None:
62
- raise ImmutableBunchException('ImmutableBunch does not support setdefault')
63
-
64
- def keys(self):
65
- return self.__dict__.keys()
66
-
67
- def values(self):
68
- return self.__dict__.values()
69
-
70
- def items(self):
71
- return self.__dict__.items()
72
-
73
- @staticmethod
74
- def from_dict(dictionary: dict) -> Any:
75
- return ImmutableBunch(**dictionary)
1
+ import json
2
+ from typing import Any
3
+
4
+
5
+ class ImmutableBunchException(Exception):
6
+ def __init__(self, message: str) -> None:
7
+ super().__init__(message)
8
+
9
+
10
+ class ImmutableBunch:
11
+ def __init__(self, *args, **kwargs):
12
+ for arg in args:
13
+ if not isinstance(arg, dict):
14
+ kwargs[arg] = None
15
+ self.__dict__.update(kwargs)
16
+
17
+ def __getitem__(self, key: Any) -> Any or None:
18
+ return self.__dict__.get(key, None)
19
+
20
+ def __setitem__(self, key: Any, value: Any) -> None:
21
+ raise ImmutableBunchException('ImmutableBunch does not support item assignment')
22
+
23
+ def __delitem__(self, key: Any) -> None:
24
+ raise ImmutableBunchException('ImmutableBunch does not support item deletion')
25
+
26
+ def __contains__(self, key: Any) -> bool:
27
+ return key in self.__dict__
28
+
29
+ def __str__(self) -> str:
30
+ return json.dumps(self.__dict__, sort_keys=False)
31
+
32
+ def __repr__(self) -> str:
33
+ return self.__str__()
34
+
35
+ def __getattr__(self, key: Any) -> Any or None:
36
+ if key in self.__dict__:
37
+ return self.__dict__[key]
38
+ return None
39
+
40
+ def __setattr__(self, name: str, value: Any) -> None:
41
+ raise ImmutableBunchException('ImmutableBunch does not support attribute assignment')
42
+
43
+ def __delattr__(self, name) -> None:
44
+ raise ImmutableBunchException('ImmutableBunch does not support attribute deletion')
45
+
46
+ def contains_value(self, value: Any) -> bool:
47
+ return value in self.__dict__.values()
48
+
49
+ def clear(self) -> None:
50
+ raise ImmutableBunchException('ImmutableBunch does not support clearing')
51
+
52
+ def pop(self, key: Any, default: Any = None) -> Any or None:
53
+ raise ImmutableBunchException('ImmutableBunch does not support popping')
54
+
55
+ def popitem(self) -> Any or None:
56
+ raise ImmutableBunchException('ImmutableBunch does not support popitem')
57
+
58
+ def update(self, other: dict) -> None:
59
+ raise ImmutableBunchException('ImmutableBunch does not support update')
60
+
61
+ def setdefault(self, key: Any, default: Any = None) -> Any or None:
62
+ raise ImmutableBunchException('ImmutableBunch does not support setdefault')
63
+
64
+ def keys(self):
65
+ return self.__dict__.keys()
66
+
67
+ def values(self):
68
+ return self.__dict__.values()
69
+
70
+ def items(self):
71
+ return self.__dict__.items()
72
+
73
+ @staticmethod
74
+ def from_dict(dictionary: dict) -> Any:
75
+ return ImmutableBunch(**dictionary)
@@ -1,20 +1,23 @@
1
- [build-system]
2
- requires = ["setuptools>=61.0"]
3
- build-backend = "setuptools.build_meta"
4
-
5
- [project]
6
- name = "python-bunch"
7
- version = "0.1.5"
8
- description = "A lightweight Python class that behaves like a dict but supports attribute-style access."
9
- readme = "README.md"
10
- requires-python = ">=3.7"
11
- license = {text = "MIT"}
12
- authors = [
13
- { name="Omer Menashe", email="unspecified@mail.com" }
14
- ]
15
- keywords = ["python-bunch", "bunch", "dict", "attribute-access", "json", "utility"]
16
- classifiers = [
17
- "Programming Language :: Python :: 3",
18
- "License :: OSI Approved :: MIT License",
19
- "Operating System :: OS Independent"
20
- ]
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "python-bunch"
7
+ version = "0.1.6"
8
+ description = "A lightweight Python class that behaves like a dict but supports attribute-style access."
9
+ readme = "README.md"
10
+ requires-python = ">=3.7"
11
+ license = {text = "MIT"}
12
+ authors = [
13
+ { name="Omer Menashe", email="unspecified@mail.com" }
14
+ ]
15
+ keywords = ["python-bunch", "bunch", "dict", "attribute-access", "json", "utility"]
16
+ classifiers = [
17
+ "Programming Language :: Python :: 3",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Operating System :: OS Independent"
20
+ ]
21
+
22
+ [project.urls]
23
+ "Source" = "https://github.com/iamomerm/python-bunch"
@@ -1,52 +1,53 @@
1
- Metadata-Version: 2.4
2
- Name: python-bunch
3
- Version: 0.1.5
4
- Summary: A lightweight Python class that behaves like a dict but supports attribute-style access.
5
- Author-email: Omer Menashe <unspecified@mail.com>
6
- License: MIT
7
- Keywords: python-bunch,bunch,dict,attribute-access,json,utility
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Operating System :: OS Independent
11
- Requires-Python: >=3.7
12
- Description-Content-Type: text/markdown
13
- License-File: LICENSE
14
- Dynamic: license-file
15
-
16
- ## Bunch
17
-
18
- A simple Python class that allows dictionary-style and attribute-style access to data interchangeably. Think of it as a lightweight object wrapper for dictionaries — great for config objects, JSON responses, or anything else you'd normally throw in a dict.
19
-
20
- ### <ins> Features </ins>
21
-
22
- - Access keys as attributes or like a dictionary
23
- - Convert from regular dictionaries
24
- - Pretty-printed JSON representation
25
- - Check if a value exists
26
- - Fully compatible with `in`, `.keys()`, `.items()`, etc.
27
-
28
- ### <ins> Installation </ins>
29
-
30
- You can install this package via PIP: _pip install python-bunch_
31
-
32
- ### <ins> Usage </ins>
33
-
34
- ```python
35
- # - Mutable Bunch -
36
- from bunch.bunch import Bunch
37
-
38
- my_bunch = Bunch({'name': 'Jane', 'age': 30})
39
-
40
- print(my_bunch.name) # Output: Jane
41
- print(my_bunch['age']) # Output: 30
42
-
43
- # - Immutable Bunch -v
44
- from bunch.immutable_bunch import ImmutableBunch
45
-
46
- my_immutable_bunch = ImmutableBunch({'name': 'John', 'age': 25})
47
- print(my_immutable_bunch.name) # Output: John
48
- print(my_immutable_bunch['age']) # Output: 35
49
-
50
- # Attempting to modify an ImmutableBunch will raise an Exception
51
- my_immutable_bunch.name = 'Alice' # Raises ImmutableBunchException
52
- ```
1
+ Metadata-Version: 2.4
2
+ Name: python-bunch
3
+ Version: 0.1.6
4
+ Summary: A lightweight Python class that behaves like a dict but supports attribute-style access.
5
+ Author-email: Omer Menashe <unspecified@mail.com>
6
+ License: MIT
7
+ Project-URL: Source, https://github.com/iamomerm/python-bunch
8
+ Keywords: python-bunch,bunch,dict,attribute-access,json,utility
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.7
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Dynamic: license-file
16
+
17
+ ## Bunch
18
+
19
+ A simple Python class that allows dictionary-style and attribute-style access to data interchangeably. Think of it as a lightweight object wrapper for dictionaries — great for config objects, JSON responses, or anything else you'd normally throw in a dict.
20
+
21
+ ### <ins> Features </ins>
22
+
23
+ - Access keys as attributes or like a dictionary
24
+ - Convert from regular dictionaries
25
+ - Pretty-printed JSON representation
26
+ - Check if a value exists
27
+ - Fully compatible with `in`, `.keys()`, `.items()`, etc.
28
+
29
+ ### <ins> Installation </ins>
30
+
31
+ You can install this package via PIP: _pip install python-bunch_
32
+
33
+ ### <ins> Usage </ins>
34
+
35
+ ```python
36
+ # - Mutable Bunch -
37
+ from bunch.bunch import Bunch
38
+
39
+ my_bunch = Bunch({'name': 'Jane', 'age': 30})
40
+
41
+ print(my_bunch.name) # Output: Jane
42
+ print(my_bunch['age']) # Output: 30
43
+
44
+ # - Immutable Bunch -v
45
+ from bunch.immutable_bunch import ImmutableBunch
46
+
47
+ my_immutable_bunch = ImmutableBunch({'name': 'John', 'age': 25})
48
+ print(my_immutable_bunch.name) # Output: John
49
+ print(my_immutable_bunch['age']) # Output: 35
50
+
51
+ # Attempting to modify an ImmutableBunch will raise an Exception
52
+ my_immutable_bunch.name = 'Alice' # Raises ImmutableBunchException
53
+ ```
@@ -1,4 +1,4 @@
1
- [egg_info]
2
- tag_build =
3
- tag_date = 0
4
-
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -1,108 +1,108 @@
1
- import json
2
- import unittest
3
- from collections import Counter
4
-
5
- from bunch.bunch import Bunch
6
-
7
-
8
- class TestBunch(unittest.TestCase):
9
- def test_getitem(self):
10
- b = Bunch(name='Alice', age=30)
11
- self.assertEqual(b['name'], 'Alice')
12
-
13
- def test_setitem(self):
14
- b = Bunch(name='Alice')
15
- b['age'] = 30
16
- self.assertEqual(b.age, 30)
17
-
18
- def test_delitem(self):
19
- b = Bunch(name='Alice', age=30)
20
- del b['name']
21
- self.assertEqual(b.name, None)
22
-
23
- def test_contains(self):
24
- b = Bunch(name='Alice', age=30)
25
- self.assertTrue('name' in b)
26
- self.assertFalse('location' in b)
27
-
28
- def test_str(self):
29
- b = Bunch(name='Alice', age=30)
30
- expected_str = json.dumps({'name': 'Alice', 'age': 30})
31
- self.assertEqual(b.__str__(), expected_str)
32
-
33
- def test_repr(self):
34
- b = Bunch(name='Alice', age=30)
35
- expected_repr = json.dumps({'name': 'Alice', 'age': 30})
36
- self.assertEqual(b.__repr__(), expected_repr)
37
-
38
- def test_getattr(self):
39
- b = Bunch(name='Alice', age=30)
40
- self.assertEqual(b.age, 30)
41
-
42
- def test_setattr(self):
43
- b = Bunch(name='Alice', age=30)
44
- b.age = 40
45
- b.location = 'New York'
46
- self.assertEqual(b.age, 40)
47
- self.assertEqual(b.location, 'New York')
48
-
49
- def test_delattr(self):
50
- b = Bunch(name='Alice', age=30)
51
- del b.age
52
- self.assertEqual(b.age, None)
53
-
54
- def test_contains_value(self):
55
- b = Bunch(name='Alice', age=30)
56
- self.assertTrue(b.contains_value('Alice'))
57
- self.assertFalse(b.contains_value('Bob'))
58
-
59
- def test_clear(self):
60
- b = Bunch(name='Alice', age=30)
61
- b.clear()
62
- self.assertEqual(len(b.keys()), 0)
63
-
64
- def test_pop(self):
65
- b = Bunch(name='Alice', age=30)
66
- popped_value = b.pop('name')
67
- self.assertEqual(popped_value, 'Alice')
68
- self.assertEqual(b.name, None)
69
-
70
- def test_popitem(self):
71
- b = Bunch(name='Alice', age=30)
72
- popped_value = b.popitem()
73
- self.assertEqual(popped_value, ('age', 30))
74
- self.assertEqual(b.age, None)
75
-
76
- def test_update(self):
77
- b = Bunch(name='Alice', age=30)
78
- d = {'name': 'Bob', 'age': 35}
79
- b.update(d)
80
- self.assertEqual(d['name'], 'Bob')
81
- self.assertEqual(d['age'], 35)
82
-
83
- def test_setdefault(self):
84
- b = Bunch(name='Alice', age=30)
85
- b.setdefault('location')
86
- self.assertEqual(b.location, None)
87
-
88
- def test_keys(self):
89
- b = Bunch(name='Alice', age=30)
90
- self.assertEqual(Counter(b.keys()), Counter(['name', 'age']))
91
-
92
- def test_values(self):
93
- b = Bunch(name='Alice', age=30)
94
- self.assertEqual(Counter(b.values()), Counter(['Alice', 30]))
95
-
96
- def test_items(self):
97
- b = Bunch(name='Alice', age=30)
98
- self.assertEqual(Counter(b.items()), Counter([('name', 'Alice'), ('age', 30)]))
99
-
100
- def test_from_dict(self):
101
- data = {'fruit': 'apple', 'color': 'red'}
102
- b = Bunch.from_dict(data)
103
- self.assertEqual(b.fruit, 'apple')
104
- self.assertEqual(b.color, 'red')
105
-
106
-
107
- if __name__ == '__main__':
108
- unittest.main()
1
+ import json
2
+ import unittest
3
+ from collections import Counter
4
+
5
+ from bunch.bunch import Bunch
6
+
7
+
8
+ class TestBunch(unittest.TestCase):
9
+ def test_getitem(self):
10
+ b = Bunch(name='Alice', age=30)
11
+ self.assertEqual(b['name'], 'Alice')
12
+
13
+ def test_setitem(self):
14
+ b = Bunch(name='Alice')
15
+ b['age'] = 30
16
+ self.assertEqual(b.age, 30)
17
+
18
+ def test_delitem(self):
19
+ b = Bunch(name='Alice', age=30)
20
+ del b['name']
21
+ self.assertEqual(b.name, None)
22
+
23
+ def test_contains(self):
24
+ b = Bunch(name='Alice', age=30)
25
+ self.assertTrue('name' in b)
26
+ self.assertFalse('location' in b)
27
+
28
+ def test_str(self):
29
+ b = Bunch(name='Alice', age=30)
30
+ expected_str = json.dumps({'name': 'Alice', 'age': 30})
31
+ self.assertEqual(b.__str__(), expected_str)
32
+
33
+ def test_repr(self):
34
+ b = Bunch(name='Alice', age=30)
35
+ expected_repr = json.dumps({'name': 'Alice', 'age': 30})
36
+ self.assertEqual(b.__repr__(), expected_repr)
37
+
38
+ def test_getattr(self):
39
+ b = Bunch(name='Alice', age=30)
40
+ self.assertEqual(b.age, 30)
41
+
42
+ def test_setattr(self):
43
+ b = Bunch(name='Alice', age=30)
44
+ b.age = 40
45
+ b.location = 'New York'
46
+ self.assertEqual(b.age, 40)
47
+ self.assertEqual(b.location, 'New York')
48
+
49
+ def test_delattr(self):
50
+ b = Bunch(name='Alice', age=30)
51
+ del b.age
52
+ self.assertEqual(b.age, None)
53
+
54
+ def test_contains_value(self):
55
+ b = Bunch(name='Alice', age=30)
56
+ self.assertTrue(b.contains_value('Alice'))
57
+ self.assertFalse(b.contains_value('Bob'))
58
+
59
+ def test_clear(self):
60
+ b = Bunch(name='Alice', age=30)
61
+ b.clear()
62
+ self.assertEqual(len(b.keys()), 0)
63
+
64
+ def test_pop(self):
65
+ b = Bunch(name='Alice', age=30)
66
+ popped_value = b.pop('name')
67
+ self.assertEqual(popped_value, 'Alice')
68
+ self.assertEqual(b.name, None)
69
+
70
+ def test_popitem(self):
71
+ b = Bunch(name='Alice', age=30)
72
+ popped_value = b.popitem()
73
+ self.assertEqual(popped_value, ('age', 30))
74
+ self.assertEqual(b.age, None)
75
+
76
+ def test_update(self):
77
+ b = Bunch(name='Alice', age=30)
78
+ d = {'name': 'Bob', 'age': 35}
79
+ b.update(d)
80
+ self.assertEqual(d['name'], 'Bob')
81
+ self.assertEqual(d['age'], 35)
82
+
83
+ def test_setdefault(self):
84
+ b = Bunch(name='Alice', age=30)
85
+ b.setdefault('location')
86
+ self.assertEqual(b.location, None)
87
+
88
+ def test_keys(self):
89
+ b = Bunch(name='Alice', age=30)
90
+ self.assertEqual(Counter(b.keys()), Counter(['name', 'age']))
91
+
92
+ def test_values(self):
93
+ b = Bunch(name='Alice', age=30)
94
+ self.assertEqual(Counter(b.values()), Counter(['Alice', 30]))
95
+
96
+ def test_items(self):
97
+ b = Bunch(name='Alice', age=30)
98
+ self.assertEqual(Counter(b.items()), Counter([('name', 'Alice'), ('age', 30)]))
99
+
100
+ def test_from_dict(self):
101
+ data = {'fruit': 'apple', 'color': 'red'}
102
+ b = Bunch.from_dict(data)
103
+ self.assertEqual(b.fruit, 'apple')
104
+ self.assertEqual(b.color, 'red')
105
+
106
+
107
+ if __name__ == '__main__':
108
+ unittest.main()
@@ -1,114 +1,114 @@
1
- import json
2
- import unittest
3
- from collections import Counter
4
- from contextlib import contextmanager
5
-
6
- from bunch.immutable_bunch import ImmutableBunch, ImmutableBunchException
7
-
8
-
9
- @contextmanager
10
- def raise_immutable_exception():
11
- try:
12
- yield
13
- except ImmutableBunchException:
14
- pass
15
- else:
16
- raise Exception('ImmutableBunchException not raised as expected')
17
-
18
-
19
- class TestBunch(unittest.TestCase):
20
- def test_getitem(self):
21
- ib = ImmutableBunch(name='Alice', age=30)
22
- self.assertEqual(ib['name'], 'Alice')
23
-
24
- def test_setitem(self):
25
- ib = ImmutableBunch(name='Alice')
26
- with raise_immutable_exception():
27
- ib['age'] = 30
28
-
29
- def test_delitem(self):
30
- ib = ImmutableBunch(name='Alice', age=30)
31
- with raise_immutable_exception():
32
- del ib['name']
33
-
34
- def test_contains(self):
35
- ib = ImmutableBunch(name='Alice', age=30)
36
- self.assertTrue('name' in ib)
37
- self.assertFalse('location' in ib)
38
-
39
- def test_str(self):
40
- ib = ImmutableBunch(name='Alice', age=30)
41
- expected_str = json.dumps({'name': 'Alice', 'age': 30})
42
- self.assertEqual(ib.__str__(), expected_str)
43
-
44
- def test_repr(self):
45
- ib = ImmutableBunch(name='Alice', age=30)
46
- expected_repr = json.dumps({'name': 'Alice', 'age': 30})
47
- self.assertEqual(ib.__repr__(), expected_repr)
48
-
49
- def test_getattr(self):
50
- ib = ImmutableBunch(name='Alice', age=30)
51
- self.assertEqual(ib.age, 30)
52
-
53
- def test_setattr(self):
54
- ib = ImmutableBunch(name='Alice', age=30)
55
- with raise_immutable_exception():
56
- ib.age = 40
57
-
58
- def test_delattr(self):
59
- ib = ImmutableBunch(name='Alice', age=30)
60
- with raise_immutable_exception():
61
- del ib.age
62
-
63
- def test_contains_value(self):
64
- ib = ImmutableBunch(name='Alice', age=30)
65
- self.assertTrue(ib.contains_value('Alice'))
66
- self.assertFalse(ib.contains_value('Bob'))
67
-
68
- def test_clear(self):
69
- ib = ImmutableBunch(name='Alice', age=30)
70
- with raise_immutable_exception():
71
- ib.clear()
72
-
73
- def test_pop(self):
74
- ib = ImmutableBunch(name='Alice', age=30)
75
- with raise_immutable_exception():
76
- ib.pop('name')
77
-
78
- def test_popitem(self):
79
- ib = ImmutableBunch(name='Alice', age=30)
80
- with raise_immutable_exception():
81
- ib.popitem()
82
-
83
- def test_update(self):
84
- ib = ImmutableBunch(name='Alice', age=30)
85
- d = {'name': 'Bob', 'age': 35}
86
- with raise_immutable_exception():
87
- ib.update(d)
88
-
89
- def test_setdefault(self):
90
- ib = ImmutableBunch(name='Alice', age=30)
91
- with raise_immutable_exception():
92
- ib.setdefault('location')
93
-
94
- def test_keys(self):
95
- ib = ImmutableBunch(name='Alice', age=30)
96
- self.assertEqual(Counter(ib.keys()), Counter(['name', 'age']))
97
-
98
- def test_values(self):
99
- ib = ImmutableBunch(name='Alice', age=30)
100
- self.assertEqual(Counter(ib.values()), Counter(['Alice', 30]))
101
-
102
- def test_items(self):
103
- ib = ImmutableBunch(name='Alice', age=30)
104
- self.assertEqual(Counter(ib.items()), Counter([('name', 'Alice'), ('age', 30)]))
105
-
106
- def test_from_dict(self):
107
- data = {'fruit': 'apple', 'color': 'red'}
108
- ib = ImmutableBunch.from_dict(data)
109
- self.assertEqual(ib.fruit, 'apple')
110
- self.assertEqual(ib.color, 'red')
111
-
112
-
113
- if __name__ == '__main__':
114
- unittest.main()
1
+ import json
2
+ import unittest
3
+ from collections import Counter
4
+ from contextlib import contextmanager
5
+
6
+ from bunch.immutable_bunch import ImmutableBunch, ImmutableBunchException
7
+
8
+
9
+ @contextmanager
10
+ def raise_immutable_exception():
11
+ try:
12
+ yield
13
+ except ImmutableBunchException:
14
+ pass
15
+ else:
16
+ raise Exception('ImmutableBunchException not raised as expected')
17
+
18
+
19
+ class TestBunch(unittest.TestCase):
20
+ def test_getitem(self):
21
+ ib = ImmutableBunch(name='Alice', age=30)
22
+ self.assertEqual(ib['name'], 'Alice')
23
+
24
+ def test_setitem(self):
25
+ ib = ImmutableBunch(name='Alice')
26
+ with raise_immutable_exception():
27
+ ib['age'] = 30
28
+
29
+ def test_delitem(self):
30
+ ib = ImmutableBunch(name='Alice', age=30)
31
+ with raise_immutable_exception():
32
+ del ib['name']
33
+
34
+ def test_contains(self):
35
+ ib = ImmutableBunch(name='Alice', age=30)
36
+ self.assertTrue('name' in ib)
37
+ self.assertFalse('location' in ib)
38
+
39
+ def test_str(self):
40
+ ib = ImmutableBunch(name='Alice', age=30)
41
+ expected_str = json.dumps({'name': 'Alice', 'age': 30})
42
+ self.assertEqual(ib.__str__(), expected_str)
43
+
44
+ def test_repr(self):
45
+ ib = ImmutableBunch(name='Alice', age=30)
46
+ expected_repr = json.dumps({'name': 'Alice', 'age': 30})
47
+ self.assertEqual(ib.__repr__(), expected_repr)
48
+
49
+ def test_getattr(self):
50
+ ib = ImmutableBunch(name='Alice', age=30)
51
+ self.assertEqual(ib.age, 30)
52
+
53
+ def test_setattr(self):
54
+ ib = ImmutableBunch(name='Alice', age=30)
55
+ with raise_immutable_exception():
56
+ ib.age = 40
57
+
58
+ def test_delattr(self):
59
+ ib = ImmutableBunch(name='Alice', age=30)
60
+ with raise_immutable_exception():
61
+ del ib.age
62
+
63
+ def test_contains_value(self):
64
+ ib = ImmutableBunch(name='Alice', age=30)
65
+ self.assertTrue(ib.contains_value('Alice'))
66
+ self.assertFalse(ib.contains_value('Bob'))
67
+
68
+ def test_clear(self):
69
+ ib = ImmutableBunch(name='Alice', age=30)
70
+ with raise_immutable_exception():
71
+ ib.clear()
72
+
73
+ def test_pop(self):
74
+ ib = ImmutableBunch(name='Alice', age=30)
75
+ with raise_immutable_exception():
76
+ ib.pop('name')
77
+
78
+ def test_popitem(self):
79
+ ib = ImmutableBunch(name='Alice', age=30)
80
+ with raise_immutable_exception():
81
+ ib.popitem()
82
+
83
+ def test_update(self):
84
+ ib = ImmutableBunch(name='Alice', age=30)
85
+ d = {'name': 'Bob', 'age': 35}
86
+ with raise_immutable_exception():
87
+ ib.update(d)
88
+
89
+ def test_setdefault(self):
90
+ ib = ImmutableBunch(name='Alice', age=30)
91
+ with raise_immutable_exception():
92
+ ib.setdefault('location')
93
+
94
+ def test_keys(self):
95
+ ib = ImmutableBunch(name='Alice', age=30)
96
+ self.assertEqual(Counter(ib.keys()), Counter(['name', 'age']))
97
+
98
+ def test_values(self):
99
+ ib = ImmutableBunch(name='Alice', age=30)
100
+ self.assertEqual(Counter(ib.values()), Counter(['Alice', 30]))
101
+
102
+ def test_items(self):
103
+ ib = ImmutableBunch(name='Alice', age=30)
104
+ self.assertEqual(Counter(ib.items()), Counter([('name', 'Alice'), ('age', 30)]))
105
+
106
+ def test_from_dict(self):
107
+ data = {'fruit': 'apple', 'color': 'red'}
108
+ ib = ImmutableBunch.from_dict(data)
109
+ self.assertEqual(ib.fruit, 'apple')
110
+ self.assertEqual(ib.color, 'red')
111
+
112
+
113
+ if __name__ == '__main__':
114
+ unittest.main()