pyobjict 2.0.0__tar.gz → 2.0.2__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.
@@ -0,0 +1,139 @@
1
+ Metadata-Version: 2.3
2
+ Name: pyobjict
3
+ Version: 2.0.2
4
+ Summary: A Python dict that supports attribute-style access as well as hierarchical keys, JSON serialization, ZIP compression, and more.
5
+ License: MIT
6
+ Author: Ian Starnes
7
+ Author-email: ians@311labs.com
8
+ Requires-Python: >=3.7,<4.0
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.7
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Description-Content-Type: text/markdown
19
+
20
+ ![](https://github.com/311labs/objict/workflows/tests/badge.svg)
21
+
22
+ # objict
23
+
24
+ `objict` is a Python library that extends the standard dictionary to allow attribute-style access, hierarchical keys, and additional functionalities like JSON/XML serialization, delta comparison, and more. It's inspired by the [uberdict](https://github.com/eukaryote/uberdict) library.
25
+
26
+ ## Installation
27
+
28
+ To install `objict`, use the following pip command:
29
+
30
+ ```bash
31
+ pip install pyobjict
32
+ ```
33
+
34
+ ## Features
35
+
36
+ - **Attribute Access**: Access dictionary values using dot notation (e.g., `d.key`).
37
+ - **Hierarchical Keys**: Seamlessly handle nested dictionary structures with keys like `a.b.c`.
38
+ - **Serialization**: Convert to/from JSON, XML, and ZIP formats.
39
+ - **File Operations**: Read from and write to files conveniently.
40
+ - **Delta Comparison**: Compute differences between two `objicts`.
41
+ - **Resilient Missing Keys**: Returns `None` instead of raising an error for missing attributes.
42
+ - **Type Safety and Conversion**: Supports type-safe fetching of values.
43
+
44
+ ## Basic Usage
45
+
46
+ ```python
47
+ from objict import objict
48
+
49
+ # Creating an objict
50
+ d1 = objict(name="John", age=24)
51
+ print(d1.name) # Output: John
52
+ print(d1["age"]) # Output: 24
53
+
54
+ # Adding new attributes
55
+ d1.gender = "male"
56
+ print(d1.gender) # Output: male
57
+
58
+ # Nested objict
59
+ d2 = objict(user=d1)
60
+ print(d2.user.name) # Output: John
61
+ ```
62
+
63
+ ## Advanced Usage
64
+
65
+ ### Hierarchical Keys
66
+
67
+ ```python
68
+ d3 = objict()
69
+ d3.set("address.street", "123 Elm St")
70
+ print(d3.address.street) # Output: 123 Elm St
71
+ ```
72
+
73
+ ### Serialization
74
+
75
+ #### JSON
76
+
77
+ ```python
78
+ json_data = d1.to_json(as_string=True, pretty=True)
79
+ print(json_data)
80
+ ```
81
+
82
+ #### XML
83
+
84
+ ```python
85
+ xml_data = d1.to_xml()
86
+ print(xml_data)
87
+ ```
88
+
89
+ #### ZIP Compression
90
+
91
+ ```python
92
+ zip_data = d1.to_zip(as_string=True)
93
+ ```
94
+
95
+ ### File Operations
96
+
97
+ ```python
98
+ d1.save("data.json")
99
+ d3 = objict.from_file("data.json")
100
+ print(d3) # Reconstructed objict from file
101
+ ```
102
+
103
+ ### Delta Comparison
104
+
105
+ ```python
106
+ d4 = objict(name="John", age=25)
107
+ changes = d1.changes(d4)
108
+ print(changes) # Output: {'age': 25}
109
+ ```
110
+
111
+ ### Type Safety and Conversion
112
+
113
+ ```python
114
+ dob = d1.get_typed("dob", typed=datetime.datetime)
115
+ ```
116
+
117
+ ### Handling Missing Keys and Defaults
118
+
119
+ ```python
120
+ print(d1.unknown_key) # Output: None
121
+
122
+ d1.setdefault("country", "USA")
123
+ print(d1.country) # Output: USA
124
+ ```
125
+
126
+ ## Utility Methods
127
+
128
+ - **to_json()**: Convert `objict` to JSON.
129
+ - **to_xml()**: Convert `objict` to XML.
130
+ - **to_zip()**: Compress `objict`.
131
+ - **from_json(json_string)**: Create `objict` from JSON.
132
+ - **from_file(path)**: Load `objict` from a file.
133
+ - **copy(shallow=True)**: Create a copy of the `objict`.
134
+ - **extend(\*args, \*\*kwargs)**: Merge another dictionary into this `objict`.
135
+
136
+ ## Conclusion
137
+
138
+ `objict` is a versatile tool for developers who want more flexible dictionary operations in Python. Whether you're dealing with nested data, performing file I/O, or converting data formats, `objict` simplifies these tasks with a clean and Pythonic interface.
139
+
@@ -0,0 +1,119 @@
1
+ ![](https://github.com/311labs/objict/workflows/tests/badge.svg)
2
+
3
+ # objict
4
+
5
+ `objict` is a Python library that extends the standard dictionary to allow attribute-style access, hierarchical keys, and additional functionalities like JSON/XML serialization, delta comparison, and more. It's inspired by the [uberdict](https://github.com/eukaryote/uberdict) library.
6
+
7
+ ## Installation
8
+
9
+ To install `objict`, use the following pip command:
10
+
11
+ ```bash
12
+ pip install pyobjict
13
+ ```
14
+
15
+ ## Features
16
+
17
+ - **Attribute Access**: Access dictionary values using dot notation (e.g., `d.key`).
18
+ - **Hierarchical Keys**: Seamlessly handle nested dictionary structures with keys like `a.b.c`.
19
+ - **Serialization**: Convert to/from JSON, XML, and ZIP formats.
20
+ - **File Operations**: Read from and write to files conveniently.
21
+ - **Delta Comparison**: Compute differences between two `objicts`.
22
+ - **Resilient Missing Keys**: Returns `None` instead of raising an error for missing attributes.
23
+ - **Type Safety and Conversion**: Supports type-safe fetching of values.
24
+
25
+ ## Basic Usage
26
+
27
+ ```python
28
+ from objict import objict
29
+
30
+ # Creating an objict
31
+ d1 = objict(name="John", age=24)
32
+ print(d1.name) # Output: John
33
+ print(d1["age"]) # Output: 24
34
+
35
+ # Adding new attributes
36
+ d1.gender = "male"
37
+ print(d1.gender) # Output: male
38
+
39
+ # Nested objict
40
+ d2 = objict(user=d1)
41
+ print(d2.user.name) # Output: John
42
+ ```
43
+
44
+ ## Advanced Usage
45
+
46
+ ### Hierarchical Keys
47
+
48
+ ```python
49
+ d3 = objict()
50
+ d3.set("address.street", "123 Elm St")
51
+ print(d3.address.street) # Output: 123 Elm St
52
+ ```
53
+
54
+ ### Serialization
55
+
56
+ #### JSON
57
+
58
+ ```python
59
+ json_data = d1.to_json(as_string=True, pretty=True)
60
+ print(json_data)
61
+ ```
62
+
63
+ #### XML
64
+
65
+ ```python
66
+ xml_data = d1.to_xml()
67
+ print(xml_data)
68
+ ```
69
+
70
+ #### ZIP Compression
71
+
72
+ ```python
73
+ zip_data = d1.to_zip(as_string=True)
74
+ ```
75
+
76
+ ### File Operations
77
+
78
+ ```python
79
+ d1.save("data.json")
80
+ d3 = objict.from_file("data.json")
81
+ print(d3) # Reconstructed objict from file
82
+ ```
83
+
84
+ ### Delta Comparison
85
+
86
+ ```python
87
+ d4 = objict(name="John", age=25)
88
+ changes = d1.changes(d4)
89
+ print(changes) # Output: {'age': 25}
90
+ ```
91
+
92
+ ### Type Safety and Conversion
93
+
94
+ ```python
95
+ dob = d1.get_typed("dob", typed=datetime.datetime)
96
+ ```
97
+
98
+ ### Handling Missing Keys and Defaults
99
+
100
+ ```python
101
+ print(d1.unknown_key) # Output: None
102
+
103
+ d1.setdefault("country", "USA")
104
+ print(d1.country) # Output: USA
105
+ ```
106
+
107
+ ## Utility Methods
108
+
109
+ - **to_json()**: Convert `objict` to JSON.
110
+ - **to_xml()**: Convert `objict` to XML.
111
+ - **to_zip()**: Compress `objict`.
112
+ - **from_json(json_string)**: Create `objict` from JSON.
113
+ - **from_file(path)**: Load `objict` from a file.
114
+ - **copy(shallow=True)**: Create a copy of the `objict`.
115
+ - **extend(\*args, \*\*kwargs)**: Merge another dictionary into this `objict`.
116
+
117
+ ## Conclusion
118
+
119
+ `objict` is a versatile tool for developers who want more flexible dictionary operations in Python. Whether you're dealing with nested data, performing file I/O, or converting data formats, `objict` simplifies these tasks with a clean and Pythonic interface.
@@ -1,4 +1,4 @@
1
- __version_info__ = (2, 0, 0)
1
+ __version_info__ = (2, 0, 2)
2
2
  __version__ = ".".join(map(str, __version_info__))
3
3
  ALL = ["objict"]
4
4
  import sys
@@ -9,6 +9,12 @@ try:
9
9
  except ImportError:
10
10
  xmltodict = None
11
11
 
12
+ try:
13
+ import ujson
14
+ except ImportError:
15
+ ujson = None
16
+ # support for ujson can be turned off by objict.ujson = None
17
+
12
18
  import datetime
13
19
  import time
14
20
  import os
@@ -147,6 +153,18 @@ class objict(dict):
147
153
  if typed is None:
148
154
  return val
149
155
  try:
156
+ type_map = {
157
+ "int": int,
158
+ "str": str,
159
+ "float": float,
160
+ "bool": bool,
161
+ "list": list,
162
+ "dict": dict,
163
+ "datetime": datetime.datetime,
164
+ "date": datetime.date
165
+ }
166
+ if isinstance(typed, str):
167
+ typed = type_map.get(typed, None)
150
168
  conversion_map = {
151
169
  int: lambda v: int(v) if v != '' else 0,
152
170
  str: str,
@@ -312,10 +330,11 @@ class objict(dict):
312
330
  d[k] = v.id
313
331
  else:
314
332
  d[k] = str(v)
333
+ serializer = json if ujson is None else ujson
315
334
  if as_string:
316
335
  if pretty:
317
- return json.dumps(d, indent=4)
318
- return json.dumps(d)
336
+ return serializer.dumps(d, indent=4)
337
+ return serializer.dumps(d)
319
338
  return d
320
339
 
321
340
  def toXML(self):
@@ -483,14 +502,15 @@ class objict(dict):
483
502
  """
484
503
  creates a dictionary json string
485
504
  """
505
+ serializer = json if ujson is None else ujson
486
506
  if ignore_errors:
487
507
  try:
488
- jmsg = json.loads(json_string)
508
+ jmsg = serializer.loads(json_string)
489
509
  return cls.from_dict(jmsg)
490
510
  except:
491
511
  return cls()
492
512
 
493
- jmsg = json.loads(json_string)
513
+ jmsg = serializer.loads(json_string)
494
514
  return cls.from_dict(jmsg)
495
515
 
496
516
  # deprecated
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pyobjict"
3
- version = "2.0.0"
3
+ version = "2.0.2"
4
4
  description = "A Python dict that supports attribute-style access as well as hierarchical keys, JSON serialization, ZIP compression, and more."
5
5
  authors = ["Ian Starnes <ians@311labs.com>"]
6
6
  license = "MIT"
pyobjict-2.0.0/PKG-INFO DELETED
@@ -1,112 +0,0 @@
1
- Metadata-Version: 2.3
2
- Name: pyobjict
3
- Version: 2.0.0
4
- Summary: A Python dict that supports attribute-style access as well as hierarchical keys, JSON serialization, ZIP compression, and more.
5
- License: MIT
6
- Author: Ian Starnes
7
- Author-email: ians@311labs.com
8
- Requires-Python: >=3.7,<4.0
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Programming Language :: Python :: 3
11
- Classifier: Programming Language :: Python :: 3.7
12
- Classifier: Programming Language :: Python :: 3.8
13
- Classifier: Programming Language :: Python :: 3.9
14
- Classifier: Programming Language :: Python :: 3.10
15
- Classifier: Programming Language :: Python :: 3.11
16
- Classifier: Programming Language :: Python :: 3.12
17
- Classifier: Programming Language :: Python :: 3.13
18
- Description-Content-Type: text/markdown
19
-
20
- ![](https://github.com/311labs/objict/workflows/tests/badge.svg)
21
-
22
- ## Turn a dict into an Object or objict!
23
-
24
- Based on uberdict(https://github.com/eukaryote/uberdict)
25
-
26
- ## Installation
27
-
28
- ```
29
- pip install pyobjict
30
- ```
31
-
32
-
33
- ### Some Differences:
34
-
35
- * Support for to/from JSON
36
- * Support for to/from XML
37
- * Support for to/from ZIP compression (base64)
38
- * Support to/from file
39
- * When an attribute is not found it returns None instead of raising an Error
40
- * Support for .get("a.b.c")
41
- * Support for delta between to objicts (obj.changes())
42
- * Will automatically handle key conversion from "a.b.c" to "a -> b -> c" creation
43
-
44
-
45
- ## Simple to use!
46
-
47
- ```python
48
- >>> from objict import objict
49
- >>> d1 = objict(name="John", age=24)
50
- >>> d1
51
- {'name': 'John', 'age': 24}
52
- >>> d1.name
53
- 'John'
54
- >>> d1.age
55
- 24
56
- >>> d1.gender = "male"
57
- >>> d1
58
- {'name': 'John', 'age': 24, 'gender': 'male'}
59
- >>> d1.gender
60
- 'male'
61
- >>> import datetime
62
- >>> d1.dob = datetime.datetime(1985, 5, 2)
63
- >>> d1.dob
64
- datetime.datetime(1985, 5, 2, 0, 0)
65
- >>> d1.toJSON()
66
- {'name': 'John', 'age': 24, 'gender': 'male', 'dob': 483865200.0}
67
- >>> d1.save("test1.json")
68
- >>> d2 = objict.fromFile("test1.json")
69
- >>> d2
70
- {'name': 'John', 'age': 24, 'gender': 'male', 'dob': 483865200.0}
71
- >>> d2.toXML()
72
- '<name>John</name><age>24</age><gender>male</gender><dob>483865200.0</dob>'
73
- >>> d3 = objict(user1=d2)
74
- >>> d3.user2 = objict(name="Jenny", age=27)
75
- >>> d3
76
- {'user1': {'name': 'John', 'age': 24, 'gender': 'male', 'dob': 483865200.0}, 'user2': {'name': 'Jenny', 'age': 27}}
77
- >>> d3.toXML()
78
- '<user1><name>John</name><age>24</age><gender>male</gender><dob>483865200.0</dob></user1><user2><name>Jenny</name><age>27</age></user2>'
79
- >>> d3.toJSON(True)
80
- '{\n "user1": {\n "name": "John",\n "age": 24,\n "gender": "male",\n "dob": 483865200.0\n },\n "user2": {\n "name": "Jenny",\n "age": 27\n }\n}'
81
- >>> print(d3.toJSON(True))
82
- {
83
- "user1": {
84
- "name": "John",
85
- "age": 24,
86
- "gender": "male",
87
- "dob": 483865200.0
88
- },
89
- "user2": {
90
- "name": "Jenny",
91
- "age": 27
92
- }
93
- }
94
- >>> d3.toZIP()
95
- b'x\x9c\xab\xe6R\x00\x02\xa5\xd2\xe2\xd4"C%+\x85j0\x17,\x94\x97\x98\x9b\n\x14Q\xf2\xca\xcf\xc8S\xd2A\x88\'\xa6\x83\x84\x8dL\x90\x84\xd2S\xf3RR\x8b@\x8as\x13sR\x91\x15\xa7\xe4\'\x01\x85M,\x8c-\xccL\x8d\x0c\x0c\xf4\x0c\xc0R\xb5:\x08[\x8dp\xd8\x9a\x9a\x97W\x89\xc5Zs\x88\x01\\\xb5\x00^\x1c\'I'
96
- >>> dz = d3.toZIP()
97
- >>> d4 = objict.fromZIP(dz)
98
- >>> d4
99
- {'user1': {'name': 'John', 'age': 24, 'gender': 'male', 'dob': 483865200.0}, 'user2': {'name': 'Jenny', 'age': 27}}
100
- >>> d5 = d4.copy()
101
- >>> d5.user1.name
102
- 'John'
103
- >>> d5.user1.name = "Jim"
104
- >>> d5
105
- {'user1': {'name': 'Jim', 'age': 24, 'gender': 'male', 'dob': 483865200.0}, 'user2': {'name': 'Jenny', 'age': 27}}
106
- >>> d5.changes(d4)
107
- {'user1': {'name': 'John'}}
108
-
109
- ```
110
-
111
-
112
-
pyobjict-2.0.0/README.md DELETED
@@ -1,92 +0,0 @@
1
- ![](https://github.com/311labs/objict/workflows/tests/badge.svg)
2
-
3
- ## Turn a dict into an Object or objict!
4
-
5
- Based on uberdict(https://github.com/eukaryote/uberdict)
6
-
7
- ## Installation
8
-
9
- ```
10
- pip install pyobjict
11
- ```
12
-
13
-
14
- ### Some Differences:
15
-
16
- * Support for to/from JSON
17
- * Support for to/from XML
18
- * Support for to/from ZIP compression (base64)
19
- * Support to/from file
20
- * When an attribute is not found it returns None instead of raising an Error
21
- * Support for .get("a.b.c")
22
- * Support for delta between to objicts (obj.changes())
23
- * Will automatically handle key conversion from "a.b.c" to "a -> b -> c" creation
24
-
25
-
26
- ## Simple to use!
27
-
28
- ```python
29
- >>> from objict import objict
30
- >>> d1 = objict(name="John", age=24)
31
- >>> d1
32
- {'name': 'John', 'age': 24}
33
- >>> d1.name
34
- 'John'
35
- >>> d1.age
36
- 24
37
- >>> d1.gender = "male"
38
- >>> d1
39
- {'name': 'John', 'age': 24, 'gender': 'male'}
40
- >>> d1.gender
41
- 'male'
42
- >>> import datetime
43
- >>> d1.dob = datetime.datetime(1985, 5, 2)
44
- >>> d1.dob
45
- datetime.datetime(1985, 5, 2, 0, 0)
46
- >>> d1.toJSON()
47
- {'name': 'John', 'age': 24, 'gender': 'male', 'dob': 483865200.0}
48
- >>> d1.save("test1.json")
49
- >>> d2 = objict.fromFile("test1.json")
50
- >>> d2
51
- {'name': 'John', 'age': 24, 'gender': 'male', 'dob': 483865200.0}
52
- >>> d2.toXML()
53
- '<name>John</name><age>24</age><gender>male</gender><dob>483865200.0</dob>'
54
- >>> d3 = objict(user1=d2)
55
- >>> d3.user2 = objict(name="Jenny", age=27)
56
- >>> d3
57
- {'user1': {'name': 'John', 'age': 24, 'gender': 'male', 'dob': 483865200.0}, 'user2': {'name': 'Jenny', 'age': 27}}
58
- >>> d3.toXML()
59
- '<user1><name>John</name><age>24</age><gender>male</gender><dob>483865200.0</dob></user1><user2><name>Jenny</name><age>27</age></user2>'
60
- >>> d3.toJSON(True)
61
- '{\n "user1": {\n "name": "John",\n "age": 24,\n "gender": "male",\n "dob": 483865200.0\n },\n "user2": {\n "name": "Jenny",\n "age": 27\n }\n}'
62
- >>> print(d3.toJSON(True))
63
- {
64
- "user1": {
65
- "name": "John",
66
- "age": 24,
67
- "gender": "male",
68
- "dob": 483865200.0
69
- },
70
- "user2": {
71
- "name": "Jenny",
72
- "age": 27
73
- }
74
- }
75
- >>> d3.toZIP()
76
- b'x\x9c\xab\xe6R\x00\x02\xa5\xd2\xe2\xd4"C%+\x85j0\x17,\x94\x97\x98\x9b\n\x14Q\xf2\xca\xcf\xc8S\xd2A\x88\'\xa6\x83\x84\x8dL\x90\x84\xd2S\xf3RR\x8b@\x8as\x13sR\x91\x15\xa7\xe4\'\x01\x85M,\x8c-\xccL\x8d\x0c\x0c\xf4\x0c\xc0R\xb5:\x08[\x8dp\xd8\x9a\x9a\x97W\x89\xc5Zs\x88\x01\\\xb5\x00^\x1c\'I'
77
- >>> dz = d3.toZIP()
78
- >>> d4 = objict.fromZIP(dz)
79
- >>> d4
80
- {'user1': {'name': 'John', 'age': 24, 'gender': 'male', 'dob': 483865200.0}, 'user2': {'name': 'Jenny', 'age': 27}}
81
- >>> d5 = d4.copy()
82
- >>> d5.user1.name
83
- 'John'
84
- >>> d5.user1.name = "Jim"
85
- >>> d5
86
- {'user1': {'name': 'Jim', 'age': 24, 'gender': 'male', 'dob': 483865200.0}, 'user2': {'name': 'Jenny', 'age': 27}}
87
- >>> d5.changes(d4)
88
- {'user1': {'name': 'John'}}
89
-
90
- ```
91
-
92
-
File without changes