memorymanagement 1.0.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.
- memorymanagement/__init__.py +20 -0
- memorymanagement/cleaning/__init__.py +2 -0
- memorymanagement/cleaning/cleaning.py +131 -0
- memorymanagement/pointers/__init__.py +3 -0
- memorymanagement/pointers/core.py +127 -0
- memorymanagement/pointers/decorators.py +77 -0
- memorymanagement-1.0.0.dist-info/METADATA +162 -0
- memorymanagement-1.0.0.dist-info/RECORD +11 -0
- memorymanagement-1.0.0.dist-info/WHEEL +5 -0
- memorymanagement-1.0.0.dist-info/licenses/LICENSE +21 -0
- memorymanagement-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Provides memory management support.
|
|
3
|
+
|
|
4
|
+
---
|
|
5
|
+
## Module `cleaning`
|
|
6
|
+
The class `Cleaner` flags the global references to erase them when commanded. References can be chosen to be excluded or included again in the process.
|
|
7
|
+
## Module `pointers`
|
|
8
|
+
A safe implementation of pointers for Python. Written in pure Python, this module includes two things:
|
|
9
|
+
### 1. Class `Pointer`
|
|
10
|
+
Creates a `Pointer` instance. These pointers point to a reference, not to an object in memory.
|
|
11
|
+
If value for the reference is changed, so is the pointer value and *viceversa*.
|
|
12
|
+
### 2. Decorator `pointerize`
|
|
13
|
+
Allows a function to receive pointers instead of the normally expected values.
|
|
14
|
+
"""
|
|
15
|
+
# Imports
|
|
16
|
+
from .cleaning import Cleaner
|
|
17
|
+
from .pointers import Pointer,pointerize
|
|
18
|
+
|
|
19
|
+
# Declare "__all__"
|
|
20
|
+
__all__=["Cleaner","Pointer","pointerize"]
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Imports
|
|
2
|
+
from sys import modules
|
|
3
|
+
|
|
4
|
+
# Define the class "Cleaner"
|
|
5
|
+
class Cleaner:
|
|
6
|
+
"""
|
|
7
|
+
Class for references management. It keeps track of the names of the global variables to be deleted and deletes them when ordered.
|
|
8
|
+
|
|
9
|
+
The cleaning process only deletes the flagged references to objects, but doesn't directly force the garbage collector to destroy the objects they are pointing to.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
## WARNING
|
|
13
|
+
THERE CAN ONLY BE **ONE** CLEANER OBJECT.\n
|
|
14
|
+
Initializing a new one will delete all global references to the previous one.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
Attributes:
|
|
18
|
+
_not_delete (`list[str]`, Hidden): List of variables to never delete from memory. These cannot be included in the process even if ordered so.\n
|
|
19
|
+
These mainly are variables needed for the system to work and imports.
|
|
20
|
+
_excluded (`list[str]`, Hidden): List of variables excluded from the memory cleaning that can be included again if desired.
|
|
21
|
+
_flagged (`list[str]`, Hidden): List of variables to erase from memory. Variables can be put in and/or taken out through methods.
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Methods
|
|
25
|
+
:update: *`MethodType`*
|
|
26
|
+
Updates the list of variables to erase from memory including all the new variables global variables not manually excluded.\n
|
|
27
|
+
It also allows to incorporate previously excluded variables.
|
|
28
|
+
:exclude: *`MethodType`*
|
|
29
|
+
Allows you to exclude variables from the cleaning process without need to use the `instance.update()` method.
|
|
30
|
+
:include: *`MethodType`*
|
|
31
|
+
Allows you to include variables in the cleaning process without need to use the `instance.update()` method.
|
|
32
|
+
:clean: *`MethodType`*
|
|
33
|
+
Erases all the flagged references from memory.
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Properties
|
|
37
|
+
:not_delete: *`MethodType`*, *Getter*
|
|
38
|
+
Returns the list of variables that shouldn't be deleted and can't be included in the cleaning process.
|
|
39
|
+
:excluded: *`MethodType`*, *Getter*
|
|
40
|
+
Returns the list of variables excluded from the cleaning process but can be included again if ordered.
|
|
41
|
+
:flagged: *`MethodType`*, *Getter*
|
|
42
|
+
Returns the list of variables to be erased from memory.
|
|
43
|
+
None of this properties has setter or deleter. Those lists can only be manipulated through the class methods.
|
|
44
|
+
"""
|
|
45
|
+
def __init__(self,not_delete:list[str]=list(vars(modules["__main__"])),excluded:list[str]=[],flagged:list[str]=[]):
|
|
46
|
+
"""
|
|
47
|
+
Initializes the class instance.\n
|
|
48
|
+
It is recommended to initialize the instance right after all global imports at the beggining of the program so no argument is needed.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
Arguments:
|
|
52
|
+
not_delete (`list[str]`, Optional): List of variables to never be deleted. It takes the list of global variables of the main module by default.
|
|
53
|
+
excluded (`list[str]`, Optional): List of variables to be excluded from the memory cleaning process. Empty list by default.
|
|
54
|
+
flagged (`list[str]`, Optional): List of variables to be erased from memory. Empty list by default.
|
|
55
|
+
"""
|
|
56
|
+
for key,value in vars(modules["__main__"]).copy().items():
|
|
57
|
+
if isinstance(value,Cleaner) and key in vars(modules["__main__"]).keys():
|
|
58
|
+
del vars(modules["__main__"])[key]
|
|
59
|
+
self._not_delete=not_delete.copy()
|
|
60
|
+
self._excluded=excluded.copy()
|
|
61
|
+
self._flagged=flagged.copy()
|
|
62
|
+
return
|
|
63
|
+
def update(self,exclude:str|list[str]|tuple[str]|None=None,include:str|list[str]|tuple[str]|None=None):
|
|
64
|
+
"""
|
|
65
|
+
Flags all the new global variables' references that were not manually excluded here or before. You can also include previously excluded references.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
Arguments:
|
|
69
|
+
exclude (`str`|`list[str]`|`tuple[str]`|`None`, Optional): Allows you to exclude a single (`str`) or multiple (`list` or `tuple`) variables.
|
|
70
|
+
`None` by default.
|
|
71
|
+
include (`str`|`list[str]`|`tuple[str]`|`None`, Optional): Allows you to include a single (`str`) or multiple (`list` or `tuple`) variables.
|
|
72
|
+
`None` by default.
|
|
73
|
+
"""
|
|
74
|
+
if exclude:
|
|
75
|
+
if isinstance(exclude,str):
|
|
76
|
+
exclude=[exclude]
|
|
77
|
+
self._excluded.extend([var for var in exclude if var not in self._excluded])
|
|
78
|
+
if include:
|
|
79
|
+
if isinstance(include,str):
|
|
80
|
+
include=[include]
|
|
81
|
+
for var in include:
|
|
82
|
+
while var in self._excluded:
|
|
83
|
+
self._excluded.remove(var)
|
|
84
|
+
self._flagged=[var for var in list(vars(modules["__main__"])) if var not in self._not_delete and var not in self._excluded]
|
|
85
|
+
return
|
|
86
|
+
@property
|
|
87
|
+
def not_delete(self):
|
|
88
|
+
return self._not_delete
|
|
89
|
+
@property
|
|
90
|
+
def excluded(self):
|
|
91
|
+
return self._excluded
|
|
92
|
+
@property
|
|
93
|
+
def flagged(self):
|
|
94
|
+
return self._flagged
|
|
95
|
+
def exclude(self,*exclude:str):
|
|
96
|
+
"""
|
|
97
|
+
Allows to exclude the desired references from the cleaning process.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
Arguments:
|
|
101
|
+
*exclude (`str`): Stream of references to be excluded.
|
|
102
|
+
"""
|
|
103
|
+
for var in exclude:
|
|
104
|
+
while var in self._flagged:
|
|
105
|
+
self._flagged.remove(var)
|
|
106
|
+
if var not in self._excluded:
|
|
107
|
+
self._excluded.append(var)
|
|
108
|
+
return
|
|
109
|
+
def include(self,*include:str):
|
|
110
|
+
"""
|
|
111
|
+
Allows to include the desired references (previously excluded) in the cleaning process.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
Arguments:
|
|
115
|
+
*include (`str`): Stream of references to be included.
|
|
116
|
+
"""
|
|
117
|
+
for var in include:
|
|
118
|
+
if var not in self._flagged:
|
|
119
|
+
self._flagged.append(var)
|
|
120
|
+
while var in self._excluded:
|
|
121
|
+
self._excluded.remove(var)
|
|
122
|
+
return
|
|
123
|
+
def clean(self):
|
|
124
|
+
"""
|
|
125
|
+
Culminates the cleaning process. Erases all the flagged references.
|
|
126
|
+
"""
|
|
127
|
+
for var in self._flagged:
|
|
128
|
+
if var in list(vars(modules["__main__"])):
|
|
129
|
+
del vars(modules["__main__"])[var]
|
|
130
|
+
self._flagged.clear()
|
|
131
|
+
return
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Import "TypeVar" and "Generic"
|
|
2
|
+
from typing import TypeVar,Generic
|
|
3
|
+
# Import "modules" from "sys" package
|
|
4
|
+
from sys import modules
|
|
5
|
+
# Import "currentframe" from "inspect" package
|
|
6
|
+
from inspect import currentframe
|
|
7
|
+
|
|
8
|
+
# Create new generic type
|
|
9
|
+
object_type=TypeVar("object_type")
|
|
10
|
+
# Define the class "Pointer"
|
|
11
|
+
class Pointer(Generic[object_type]):
|
|
12
|
+
"""
|
|
13
|
+
Implements pointers in Python for both mutable (though unneded) and non-mutable objects.
|
|
14
|
+
These pointers are completely safe and do not work internally as C's pointers, they are just an imitation of their behaviour.
|
|
15
|
+
|
|
16
|
+
When a Pointer instance is created, though it stores a value, it "points" to an specific reference, not the value in a memory adress.
|
|
17
|
+
This way, all references pointing to the same non-mutable object don't change when the pointer is updated, avoiding a potential mess.
|
|
18
|
+
|
|
19
|
+
Non-mutable objects still change their memory adresses when re-referenced but the reference and the value stored in the pointer are forced to share memory adress.
|
|
20
|
+
|
|
21
|
+
Value and memory adress updates are not made in real-time, but the methods update the non-coincident values:
|
|
22
|
+
* **Getter**: it updates its own value to the variable's one (if variable was given instead of literal).
|
|
23
|
+
* **Setter**: it updates the value of the variable to its own (if variable was given instead of literal).
|
|
24
|
+
* **Deleter**: it also deletes the original variable (if variable was given instead of literal).
|
|
25
|
+
---
|
|
26
|
+
Attributes:
|
|
27
|
+
value (`Any`, Hidden): Object to point to.
|
|
28
|
+
attr (`str`|`None`, Hidden): Attribute of class instance. Only if `value` is a class instance.
|
|
29
|
+
name (`str`, Hidden): Name of the global variable to which the pointer is pointing.
|
|
30
|
+
Could require an input from the user to introduce the name of the variable if more than one is found.
|
|
31
|
+
vars_dict (`dict[str,Any]`, Hidden): Dictionary of variables.
|
|
32
|
+
`vars(modules["__main__"])` if pointing to a global variable and `inspect.currentframe().f_back.f_locals` if pointing to a local variable.
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Methods
|
|
36
|
+
1. **Getter**: Gets the value.
|
|
37
|
+
2. **Setter**: Sets a new value.
|
|
38
|
+
3. **Deleter**: Deletes the value.
|
|
39
|
+
All three methods are part of the same property.
|
|
40
|
+
---
|
|
41
|
+
## Properties
|
|
42
|
+
:value: *`MethodType`*
|
|
43
|
+
Points to `value` (or `value.attr`). Called through `<instance>.value`. All three possible objects (getter, setter and deleter) have been declared.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Currently supported
|
|
48
|
+
Both global and local variables can be pointed at.
|
|
49
|
+
|
|
50
|
+
Literals are **not** supported because of it being useless. If you create a `Pointer` instance for a literal and works,
|
|
51
|
+
keep in mind that it is merely by accident and it is **not** the intended use it was designed for.
|
|
52
|
+
Currently, the only use for inserting a literal instead of a referenced value could be for the class code to display all the references pointing to that literal
|
|
53
|
+
and bind the instance to the desired reference.
|
|
54
|
+
"""
|
|
55
|
+
def __init__(self,value=None,attr:str|None=None,*,local:bool=False):
|
|
56
|
+
"""
|
|
57
|
+
Arguments:
|
|
58
|
+
value (`Any`,Optional): Object to point to. If want to point to a class instance atribute, introduce the class instance without the atribute.
|
|
59
|
+
attr (`str`|`None`, Optional): Atribute of the class instance to which you want to point. Leave empty if `value` is not a class instance.
|
|
60
|
+
local (`bool`, Optional): Indicates if the value to point to is a local variable (`True` for yes and `False` for no). `False` by default.
|
|
61
|
+
"""
|
|
62
|
+
if local:
|
|
63
|
+
vars_dict=currentframe().f_back.f_locals
|
|
64
|
+
else:
|
|
65
|
+
vars_dict=vars(modules["__main__"])
|
|
66
|
+
self._value=value
|
|
67
|
+
self._vars_dict=vars_dict
|
|
68
|
+
self._attr=attr
|
|
69
|
+
name=None
|
|
70
|
+
name=[]
|
|
71
|
+
for key,v in vars_dict.items():
|
|
72
|
+
try:
|
|
73
|
+
if v is value:
|
|
74
|
+
name.append(key)
|
|
75
|
+
except ValueError:
|
|
76
|
+
pass
|
|
77
|
+
if len(name)>1:
|
|
78
|
+
print(f"{name}\nMultiple variable names found for the 'value' parameter, introduce the correct one:")
|
|
79
|
+
while True:
|
|
80
|
+
name_aux=input()
|
|
81
|
+
if name_aux in name:
|
|
82
|
+
break
|
|
83
|
+
else:
|
|
84
|
+
print("Error, introduce the correct variable name for the 'value' parameter:")
|
|
85
|
+
name=name_aux
|
|
86
|
+
del name_aux
|
|
87
|
+
elif len(name)==1:
|
|
88
|
+
name=name[0]
|
|
89
|
+
elif len(name)==0:
|
|
90
|
+
name=None
|
|
91
|
+
self._name=name
|
|
92
|
+
return
|
|
93
|
+
@property
|
|
94
|
+
def value(self):
|
|
95
|
+
if self._attr:
|
|
96
|
+
if self._name and self._name not in list(self._vars_dict):
|
|
97
|
+
del self._value,self._attr
|
|
98
|
+
raise KeyError("The class instance has already been deleted, so the pointer no longer has access to it.")
|
|
99
|
+
elif self._attr not in dir(self._value):
|
|
100
|
+
raise AttributeError(f"The atribute '{self._attr}' has already been deleted, so the pointer no longer has access to it.")
|
|
101
|
+
return getattr(self._value,self._attr)
|
|
102
|
+
else:
|
|
103
|
+
if self._name:
|
|
104
|
+
if self._name not in list(self._vars_dict):
|
|
105
|
+
del self._value
|
|
106
|
+
raise KeyError("The variable has already been deleted, so the pointer no longer has access to it.")
|
|
107
|
+
if self._value is not self._vars_dict[self._name]:
|
|
108
|
+
self._value=self._vars_dict[self._name]
|
|
109
|
+
return self._value
|
|
110
|
+
@value.setter
|
|
111
|
+
def value(self,value):
|
|
112
|
+
if self._attr:
|
|
113
|
+
setattr(self._value,self._attr,value)
|
|
114
|
+
else:
|
|
115
|
+
self._value=value
|
|
116
|
+
if self._name and value is not self._vars_dict[self._name]:
|
|
117
|
+
self._vars_dict[self._name]=value
|
|
118
|
+
return
|
|
119
|
+
@value.deleter
|
|
120
|
+
def value(self):
|
|
121
|
+
if self._attr:
|
|
122
|
+
delattr(self._value,self._attr)
|
|
123
|
+
else:
|
|
124
|
+
del self._value
|
|
125
|
+
if self._name:
|
|
126
|
+
del self._vars_dict[self._name]
|
|
127
|
+
return
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Imports
|
|
2
|
+
from sys import settrace
|
|
3
|
+
from inspect import signature
|
|
4
|
+
from functools import wraps
|
|
5
|
+
from .core import Pointer
|
|
6
|
+
|
|
7
|
+
# Define the decorator
|
|
8
|
+
def pointerize(func):
|
|
9
|
+
"""
|
|
10
|
+
Allows the decorated function to receive pointers instead of the normally expected values.
|
|
11
|
+
|
|
12
|
+
The decorated function is still able to receive its normally expected parameters.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
Arguments:
|
|
16
|
+
func (`FunctionType`): Decorated function.
|
|
17
|
+
"""
|
|
18
|
+
# Makes the decorating function to keep its identity
|
|
19
|
+
@wraps(func)
|
|
20
|
+
# Define the wrapper
|
|
21
|
+
def wrapper(*args,**kwargs):
|
|
22
|
+
# Obtain the signature (parameters and defaults) of the decorated function
|
|
23
|
+
sig=signature(func)
|
|
24
|
+
# Bind call arguments to the signature
|
|
25
|
+
bound=sig.bind(*args,**kwargs)
|
|
26
|
+
# Defaults all the arguments which haven't been passed
|
|
27
|
+
bound.apply_defaults()
|
|
28
|
+
|
|
29
|
+
# Dictionary containing all the parameters
|
|
30
|
+
param_map=bound.arguments
|
|
31
|
+
|
|
32
|
+
# Dictionary containing only the parameters that are pointers
|
|
33
|
+
pointer_map={
|
|
34
|
+
name:val for name,val in param_map.items()
|
|
35
|
+
if isinstance(val,Pointer)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# List containing all the positional arguments to be passed to the decorated function
|
|
39
|
+
exec_args=[
|
|
40
|
+
val.value if isinstance(val,Pointer) else val
|
|
41
|
+
for val in bound.args
|
|
42
|
+
]
|
|
43
|
+
# Dictionary containing all the keyword arguments to be passed to the decorated function
|
|
44
|
+
exec_kwargs={
|
|
45
|
+
k:v.value if isinstance(v,Pointer) else v
|
|
46
|
+
for k,v in bound.kwargs.items()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# Empty dict, future source to update pointers' values
|
|
50
|
+
frame_data={}
|
|
51
|
+
|
|
52
|
+
# Tracer function compatible with the sys.settrace API
|
|
53
|
+
def tracer(frame,event,arg):
|
|
54
|
+
if event=="return" and frame.f_code is func.__code__:
|
|
55
|
+
frame_data.update(frame.f_locals)
|
|
56
|
+
return tracer
|
|
57
|
+
# Activate tracing
|
|
58
|
+
settrace(tracer)
|
|
59
|
+
# We try to execute the function
|
|
60
|
+
try:
|
|
61
|
+
result=func(*exec_args,**exec_kwargs)
|
|
62
|
+
# Even if the program meets an error
|
|
63
|
+
finally:
|
|
64
|
+
# It deactivates tracing
|
|
65
|
+
settrace(None)
|
|
66
|
+
# If no exception or error is raised, the program continues from here
|
|
67
|
+
|
|
68
|
+
# Iterates through the pointers
|
|
69
|
+
for name,ptr in pointer_map.items():
|
|
70
|
+
# Checks if the parameter name is in the traced frame (of local variables of the decorated function)
|
|
71
|
+
if name in frame_data:
|
|
72
|
+
# In which case, the pointer's value is updated
|
|
73
|
+
ptr.value=frame_data[name]
|
|
74
|
+
# Return the result of the decorated function
|
|
75
|
+
return result
|
|
76
|
+
# Return the wrapper
|
|
77
|
+
return wrapper
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: memorymanagement
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Adds support for memory management
|
|
5
|
+
Home-page: https://github.com/Ricardo-Werner-Rivas/python-memory-management/tree/main
|
|
6
|
+
Author: Ricardo Werner Rivas
|
|
7
|
+
Author-email: ricardowernerrivas@gmail.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Issues Page, https://github.com/Ricardo-Werner-Rivas/python-memory-management/issues
|
|
10
|
+
Project-URL: Repository, https://github.com/Ricardo-Werner-Rivas/python-memory-management
|
|
11
|
+
Classifier: Programming Language :: Python
|
|
12
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Dynamic: license-file
|
|
16
|
+
|
|
17
|
+
# `memorymanagement`
|
|
18
|
+
Provides memory management support.
|
|
19
|
+
## Modules
|
|
20
|
+
### `cleaning`
|
|
21
|
+
Provides the class `Cleaner`, which allows you to flag references stored in memory to eventually erase them.
|
|
22
|
+
It is also possible to modify the list of flagged references through its methods.
|
|
23
|
+
### `pointers`
|
|
24
|
+
Provides a safe implementation of pointers for Python.
|
|
25
|
+
#### Class `Pointer`
|
|
26
|
+
The pointer itself. Imitates the behaviour of C pointers. This pointer points to a reference, not to an object stored in memory.
|
|
27
|
+
#### Decorator `pointerize`
|
|
28
|
+
Allows functions to receive pointers instead of values.
|
|
29
|
+
## Installation
|
|
30
|
+
You can install the `memorymanager` package from PyPI as follows:
|
|
31
|
+
```bash
|
|
32
|
+
pip install memorymanagement
|
|
33
|
+
```
|
|
34
|
+
You can also install the `memorymanager` package (Test PyPI versión of `memorymanager`) from TestPyPI as follows:
|
|
35
|
+
```bash
|
|
36
|
+
pip install --index-url https://test.pypi.org/simple/ memorymanager
|
|
37
|
+
```
|
|
38
|
+
For TestPyPI versión, `--no-deps` option is not needed because it has no dependencies.
|
|
39
|
+
## How to use
|
|
40
|
+
### Class `Cleaner`
|
|
41
|
+
```py
|
|
42
|
+
# Imports
|
|
43
|
+
# Make your imports here
|
|
44
|
+
from memorymanagement import Cleaner # Importing class Cleaner
|
|
45
|
+
```
|
|
46
|
+
Right after imports are done, I recommend to initialize an instance of class `Cleaner`, so no arguments are needed. This is the optimal use this class was designed for.
|
|
47
|
+
```py
|
|
48
|
+
# Initialize cleaner object
|
|
49
|
+
cleaner=Cleaner()
|
|
50
|
+
```
|
|
51
|
+
Create, for example, these global variables:
|
|
52
|
+
```py
|
|
53
|
+
value_1=10
|
|
54
|
+
value_2=50
|
|
55
|
+
value_3=100
|
|
56
|
+
```
|
|
57
|
+
Update the list of flagged references like one of the following:
|
|
58
|
+
* Including all new global variables:
|
|
59
|
+
```py
|
|
60
|
+
cleaner.update()
|
|
61
|
+
print(cleaner.flagged)
|
|
62
|
+
```
|
|
63
|
+
Output:
|
|
64
|
+
```sh
|
|
65
|
+
["value_1","value_2","value_3"]
|
|
66
|
+
```
|
|
67
|
+
* Excluding some variables:
|
|
68
|
+
```py
|
|
69
|
+
cleaner.update(exclude="value_2")
|
|
70
|
+
print(cleaner.flagged)
|
|
71
|
+
```
|
|
72
|
+
Output:
|
|
73
|
+
```sh
|
|
74
|
+
["value_1","value_3"]
|
|
75
|
+
```
|
|
76
|
+
---
|
|
77
|
+
```py
|
|
78
|
+
cleaner.update(exclude=["value_2","value_3"])
|
|
79
|
+
print(cleaner.flagged)
|
|
80
|
+
```
|
|
81
|
+
Output:
|
|
82
|
+
```sh
|
|
83
|
+
["value_1"]
|
|
84
|
+
```
|
|
85
|
+
* Include again some variables:
|
|
86
|
+
|
|
87
|
+
After having excluded some variables
|
|
88
|
+
```py
|
|
89
|
+
cleaner.update(exclude=["value_2","value_3"])
|
|
90
|
+
```
|
|
91
|
+
You can reintroduce them
|
|
92
|
+
```py
|
|
93
|
+
# Create a new variable and update
|
|
94
|
+
value_4=150
|
|
95
|
+
cleaner.update(exclude="value_4",include="value_2") # "include" can also be a list of strings
|
|
96
|
+
print(cleaner.flagged)
|
|
97
|
+
```
|
|
98
|
+
Output:
|
|
99
|
+
```sh
|
|
100
|
+
["value_1","value_2"]
|
|
101
|
+
```
|
|
102
|
+
You can also directly include or exclude references like so:
|
|
103
|
+
```py
|
|
104
|
+
cleaner.exclude(<name_var_1>,<name_var_2>,...)
|
|
105
|
+
```
|
|
106
|
+
```py
|
|
107
|
+
cleaner.include(<name_var_1>,<name_var_2>,...)
|
|
108
|
+
```
|
|
109
|
+
### Class `Pointer`
|
|
110
|
+
Example:
|
|
111
|
+
```py
|
|
112
|
+
from memorymanagement import Pointer
|
|
113
|
+
a=10
|
|
114
|
+
x=Pointer(a)
|
|
115
|
+
print(f"a:\n{a}\n\nPointer:\n{x.value}\n\n")
|
|
116
|
+
a=20
|
|
117
|
+
print(f"a:\n{a}\n\nPointer:\n{x.value}\n\n")
|
|
118
|
+
a=10
|
|
119
|
+
x.value=20
|
|
120
|
+
print(f"a:\n{a}\n\nPointer:\n{x.value}")
|
|
121
|
+
```
|
|
122
|
+
Output:
|
|
123
|
+
```sh
|
|
124
|
+
a:
|
|
125
|
+
10
|
|
126
|
+
|
|
127
|
+
Pointer:
|
|
128
|
+
10
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
a:
|
|
132
|
+
20
|
|
133
|
+
|
|
134
|
+
Pointer:
|
|
135
|
+
20
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
a:
|
|
139
|
+
20
|
|
140
|
+
|
|
141
|
+
Pointer:
|
|
142
|
+
20
|
|
143
|
+
```
|
|
144
|
+
### Decorator `pointerize`
|
|
145
|
+
Example:
|
|
146
|
+
```py
|
|
147
|
+
from memorymanagement import pointerize
|
|
148
|
+
@pointerize
|
|
149
|
+
def myFunction(value:int):
|
|
150
|
+
value=20
|
|
151
|
+
return
|
|
152
|
+
a=10
|
|
153
|
+
print(f"Value: {a}")
|
|
154
|
+
myFunction(Pointer(a))
|
|
155
|
+
print(f"Value: {a}")
|
|
156
|
+
```
|
|
157
|
+
Output:
|
|
158
|
+
```sh
|
|
159
|
+
Value: 10
|
|
160
|
+
Value: 20
|
|
161
|
+
|
|
162
|
+
```
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
memorymanagement/__init__.py,sha256=Clyt9uUH0DZW36BdmWCMYNg4R2uLYYsSdsn1UgeLSJs,816
|
|
2
|
+
memorymanagement/cleaning/__init__.py,sha256=YnrtCkREJ01-FOGURPYQmlpWGT9TtreG40z5X0-WYJY,40
|
|
3
|
+
memorymanagement/cleaning/cleaning.py,sha256=FjwfFw5nv-zGt2UdRTUE9NNaHs8ZXsIaMsXwEm4hye8,6237
|
|
4
|
+
memorymanagement/pointers/__init__.py,sha256=mSC1rCofRafPigcndKzYncHT2KYV5NNjtOj0ixlLfjw,127
|
|
5
|
+
memorymanagement/pointers/core.py,sha256=f9FBOCUX-_lCI-zgt2J7tUJb3JdkkECcYwpdXRHAFz0,6233
|
|
6
|
+
memorymanagement/pointers/decorators.py,sha256=NDMlexU6s123jPU0Tqny8HkMdtPsfwrzVAgjCAYpy4A,2869
|
|
7
|
+
memorymanagement-1.0.0.dist-info/licenses/LICENSE,sha256=YbbIWfIjYfz9q2bm60jGAfdvdIqD96jDLvz16YsFOOk,1077
|
|
8
|
+
memorymanagement-1.0.0.dist-info/METADATA,sha256=HdZOYIds5L5rqrhEJ0sGTixBKunUWS4jrirbM74S0sA,3980
|
|
9
|
+
memorymanagement-1.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
10
|
+
memorymanagement-1.0.0.dist-info/top_level.txt,sha256=7SwrpC3BY9Cm6sqwu082DJE5SteRBira0LGqziTO7eQ,17
|
|
11
|
+
memorymanagement-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Ricardo Werner Rivas
|
|
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
|
+
memorymanagement
|