obj-tag-group 0.1.0__py3-none-any.whl
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 @@
|
|
|
1
|
+
from .reg import Tag_Group
|
obj_tag_group/reg.py
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import pickle
|
|
2
|
+
import re
|
|
3
|
+
import hashlib
|
|
4
|
+
from collections import defaultdict
|
|
5
|
+
|
|
6
|
+
class Tag_Group:
|
|
7
|
+
def __init__(self):
|
|
8
|
+
self.tags = defaultdict(set)
|
|
9
|
+
self.hashes = defaultdict(set)
|
|
10
|
+
self.unhash = {}
|
|
11
|
+
|
|
12
|
+
def hash_item(self, obj):
|
|
13
|
+
"""Uses pickle to create a key for an item"""
|
|
14
|
+
try:
|
|
15
|
+
pickled_data = pickle.dumps(obj, protocol=pickle.HIGHEST_PROTOCOL)
|
|
16
|
+
item_hash = hashlib.sha256(pickled_data).hexdigest()
|
|
17
|
+
return item_hash, pickled_data
|
|
18
|
+
except (pickle.PicklingError, AttributeError, TypeError):
|
|
19
|
+
raise TypeError(f"""Object of type {type(obj).__name__} cannot be serialized with pickle.
|
|
20
|
+
Ensure it doesn't contain unpicklable elements like open files or lambdas.""")
|
|
21
|
+
|
|
22
|
+
def tag_object(self, obj, tags):
|
|
23
|
+
"""
|
|
24
|
+
Associates one or more tags with an arbitrary object.
|
|
25
|
+
'tags' can be a single string or an iterable of strings.
|
|
26
|
+
"""
|
|
27
|
+
key, pickled_data = self.hash_item(obj)
|
|
28
|
+
self.unhash[key] = pickled_data
|
|
29
|
+
|
|
30
|
+
if isinstance(tags, str):
|
|
31
|
+
tags = (tags,)
|
|
32
|
+
|
|
33
|
+
for tag in tags:
|
|
34
|
+
self.tags[key].add(tag)
|
|
35
|
+
self.hashes[tag].add(key)
|
|
36
|
+
|
|
37
|
+
def untag_object(self, obj, tags = None):
|
|
38
|
+
"""
|
|
39
|
+
Removes tags from an object.
|
|
40
|
+
|
|
41
|
+
If 'tags' is provided (string or iterable of strings), only those tags will be removed.
|
|
42
|
+
If no tags are provided, completely removes an object and all its associated tags from tracking.
|
|
43
|
+
"""
|
|
44
|
+
key, _ = self.hash_item(obj)
|
|
45
|
+
if key not in self.unhash:
|
|
46
|
+
return
|
|
47
|
+
|
|
48
|
+
if tags is not None:
|
|
49
|
+
if isinstance(tags, str):
|
|
50
|
+
tags = (tags,)
|
|
51
|
+
|
|
52
|
+
for tag in tags:
|
|
53
|
+
if tag in self.tags[key]:
|
|
54
|
+
self.tags[key].discard(tag)
|
|
55
|
+
if tag in self.hashes and key in self.hashes[tag]:
|
|
56
|
+
self.hashes[tag].discard(key)
|
|
57
|
+
if not self.hashes[tag]:
|
|
58
|
+
del self.hashes[tag]
|
|
59
|
+
|
|
60
|
+
if not self.tags[key]:
|
|
61
|
+
del self.tags[key]
|
|
62
|
+
del self.unhash[key]
|
|
63
|
+
|
|
64
|
+
else:
|
|
65
|
+
item_tags = self.tags.pop(key, set())
|
|
66
|
+
for tag in item_tags:
|
|
67
|
+
if key in self.hashes[tag]:
|
|
68
|
+
self.hashes[tag].discard(key)
|
|
69
|
+
if not self.hashes[tag]:
|
|
70
|
+
del self.hashes[tag]
|
|
71
|
+
del self.unhash[key]
|
|
72
|
+
|
|
73
|
+
def get_tags(self, obj):
|
|
74
|
+
"""Returns the set of tags associated with a specific object."""
|
|
75
|
+
obj_key, _ = self.hash_item(obj)
|
|
76
|
+
return self.tags.get(obj_key, set())
|
|
77
|
+
|
|
78
|
+
def filter_tags(self, pattern, flags=0):
|
|
79
|
+
"""
|
|
80
|
+
Filters and returns a list of objects where at least one
|
|
81
|
+
associated tag matches the provided regular expression.
|
|
82
|
+
"""
|
|
83
|
+
compiled_search = re.compile(pattern, flags).search
|
|
84
|
+
matches = set()
|
|
85
|
+
|
|
86
|
+
for tag, hashset in self.hashes.items():
|
|
87
|
+
if compiled_search(tag):
|
|
88
|
+
matches.update(hashset)
|
|
89
|
+
|
|
90
|
+
return [pickle.loads(self.unhash[hashed_item]) for hashed_item in matches]
|
|
91
|
+
|
|
92
|
+
def save_to_file(self, filename):
|
|
93
|
+
"""Serializes the entire Tag_Group registry state to a file."""
|
|
94
|
+
with open(filename, 'wb') as f:
|
|
95
|
+
pickle.dump(self, f, protocol=pickle.HIGHEST_PROTOCOL)
|
|
96
|
+
|
|
97
|
+
@classmethod
|
|
98
|
+
def load_from_file(cls, filename):
|
|
99
|
+
"""
|
|
100
|
+
Loads and returns a saved Tag_Group instance from a file.
|
|
101
|
+
If the file doesn't exist, returns a fresh, empty Tag_Group instance.
|
|
102
|
+
"""
|
|
103
|
+
try:
|
|
104
|
+
with open(filename, 'rb') as f:
|
|
105
|
+
return pickle.load(f)
|
|
106
|
+
except FileNotFoundError:
|
|
107
|
+
print(f"File '{filename}' not found. Initializing a new registry.")
|
|
108
|
+
return cls()
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: obj_tag_group
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A flexible, searchable registry that allows you to attach text tags to almost any arbitrary Python object.
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: Operating System :: OS Independent
|
|
8
|
+
Requires-Python: >=3.8
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Dynamic: license-file
|
|
12
|
+
|
|
13
|
+
# obj_tag_group
|
|
14
|
+
|
|
15
|
+
A flexible, searchable registry that allows you to attach text tags to almost any arbitrary Python object.
|
|
16
|
+
|
|
17
|
+
Objects are indexed by their serialized content, allowing for quick filtering of items using regular expression searches on their associated tags.
|
|
18
|
+
- For this reason, this package will fail to work on objects that cannot be serialized (such as lambda functions).
|
|
19
|
+
- The tags work by creating a full copy of the object in memory, and will not reflect any future changes made to the object/s.
|
|
20
|
+
|
|
21
|
+
Note: This code is very rough, unoptimized, and prone to errors. Use at your own risk.
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## Features
|
|
25
|
+
|
|
26
|
+
- Add / remove tags to most Python objects, even unhashable ones such as dictionaries and lists, as well as custom classes
|
|
27
|
+
- Filter and retrieve objects using regular expression queries
|
|
28
|
+
- Save the entire tagged registry to disk and load it back later.
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install obj_tag_group
|
|
35
|
+
```
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
obj_tag_group/__init__.py,sha256=S7KzcNqs_MYxjnn-5nJu2Lxz2FHrimkN2-aulL3gZiQ,26
|
|
2
|
+
obj_tag_group/reg.py,sha256=Qy3WRDa8bGwtBldLDK0qMJwrGL1dQvj55VlzdVHiysA,3994
|
|
3
|
+
obj_tag_group-0.1.0.dist-info/licenses/LICENSE,sha256=fPY9lMPnwAP_ElNq_F_guiFBP5N41F2xRlX_SplAouc,1075
|
|
4
|
+
obj_tag_group-0.1.0.dist-info/METADATA,sha256=QoX7CaDzP9I8F_VFYQZCR0pi9Elltz5Ikv9CdLFY4lA,1361
|
|
5
|
+
obj_tag_group-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
6
|
+
obj_tag_group-0.1.0.dist-info/top_level.txt,sha256=384YK_sE_drIaO9_c77pgh_yydDiw2sDAfz2m5Nlv-8,14
|
|
7
|
+
obj_tag_group-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
obj_tag_group
|