object-filtering 0.1.11__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,165 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py,cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # poetry
98
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
102
+ #poetry.lock
103
+
104
+ # pdm
105
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
106
+ #pdm.lock
107
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
108
+ # in version control.
109
+ # https://pdm.fming.dev/latest/usage/project/#working-with-version-control
110
+ .pdm.toml
111
+ .pdm-python
112
+ .pdm-build/
113
+
114
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
115
+ __pypackages__/
116
+
117
+ # Celery stuff
118
+ celerybeat-schedule
119
+ celerybeat.pid
120
+
121
+ # SageMath parsed files
122
+ *.sage.py
123
+
124
+ # Environments
125
+ .env
126
+ .venv
127
+ env/
128
+ venv/
129
+ ENV/
130
+ env.bak/
131
+ venv.bak/
132
+
133
+ # Spyder project settings
134
+ .spyderproject
135
+ .spyproject
136
+
137
+ # Rope project settings
138
+ .ropeproject
139
+
140
+ # mkdocs documentation
141
+ /site
142
+
143
+ # mypy
144
+ .mypy_cache/
145
+ .dmypy.json
146
+ dmypy.json
147
+
148
+ # Pyre type checker
149
+ .pyre/
150
+
151
+ # pytype static type analyzer
152
+ .pytype/
153
+
154
+ # Cython debug symbols
155
+ cython_debug/
156
+
157
+ # PyCharm
158
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
159
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
160
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
161
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
162
+ #.idea/
163
+ /docs/object_filtering.ebnf
164
+ /dist_old
165
+ /.vscode
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Scott Ratchford
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,44 @@
1
+ Metadata-Version: 2.3
2
+ Name: object_filtering
3
+ Version: 0.1.11
4
+ Summary: A module for determining whether arbitrary Python objects meet a set of defined criteria.
5
+ Project-URL: Homepage, https://github.com/KyberCritter/Object-Filtering
6
+ Project-URL: Issues, https://github.com/KyberCritter/Object-Filtering/issues
7
+ Author-email: Scott Ratchford <object_filtering@scottratchford.com>
8
+ License-File: LICENSE.txt
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Natural Language :: English
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Topic :: File Formats :: JSON
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
+ Classifier: Topic :: Utilities
17
+ Requires-Python: >=3.12
18
+ Description-Content-Type: text/markdown
19
+
20
+ # Object Filtering
21
+
22
+ A Python module that functions for determining whether arbitrary Python objects meet a set of defined criteria. Filters use JSON to represent a set of criteria that objects must meet. Filters can be arbitrarily nested and can contain conditional logic.
23
+
24
+ See `/docs/filter_specifications.md` for details on filter implementation.
25
+
26
+ ## Installation Options
27
+
28
+ 1. Download the latest version of `object_filtering` from PyPi by running the command `pip install object_filtering`.
29
+ 2. Download the latest version of `object_filtering` from the Releases tab on GitHub and install the wheel (`.whl`).
30
+
31
+ ## Making Modifications
32
+
33
+ 1. Clone this repository.
34
+ 2. Make modifications to the source code.
35
+ 3. (Optional) Change the module version in `pyproject.toml`.
36
+ 4. Run `pytest` from the root of the repository to run unit tests. Only continue if all tests pass.
37
+ 5. Build the module by running `py -m build` from the root of the repository.
38
+ 6. Install the newly built wheel file.
39
+
40
+ ## License
41
+
42
+ (c) 2024 Scott Ratchford.
43
+
44
+ `object_filtering` is licensed under the MIT License. See `LICENSE.txt` for details.
@@ -0,0 +1,11 @@
1
+ [[source]]
2
+ url = "https://pypi.org/simple"
3
+ verify_ssl = true
4
+ name = "pypi"
5
+
6
+ [packages]
7
+
8
+ [dev-packages]
9
+
10
+ [requires]
11
+ python_version = "3.12"
@@ -0,0 +1,25 @@
1
+ # Object Filtering
2
+
3
+ A Python module that functions for determining whether arbitrary Python objects meet a set of defined criteria. Filters use JSON to represent a set of criteria that objects must meet. Filters can be arbitrarily nested and can contain conditional logic.
4
+
5
+ See `/docs/filter_specifications.md` for details on filter implementation.
6
+
7
+ ## Installation Options
8
+
9
+ 1. Download the latest version of `object_filtering` from PyPi by running the command `pip install object_filtering`.
10
+ 2. Download the latest version of `object_filtering` from the Releases tab on GitHub and install the wheel (`.whl`).
11
+
12
+ ## Making Modifications
13
+
14
+ 1. Clone this repository.
15
+ 2. Make modifications to the source code.
16
+ 3. (Optional) Change the module version in `pyproject.toml`.
17
+ 4. Run `pytest` from the root of the repository to run unit tests. Only continue if all tests pass.
18
+ 5. Build the module by running `py -m build` from the root of the repository.
19
+ 6. Install the newly built wheel file.
20
+
21
+ ## License
22
+
23
+ (c) 2024 Scott Ratchford.
24
+
25
+ `object_filtering` is licensed under the MIT License. See `LICENSE.txt` for details.
@@ -0,0 +1,175 @@
1
+ # Filter Specifications
2
+
3
+ (c) 2024 Scott Ratchford
4
+
5
+ This file is licensed under the MIT License. See LICENSE.txt for details.
6
+
7
+ Filters are JSON objects containing conditional checks and comparisons to perform on the instance variables, properties, and methods of any Python object. To use a method in a filter, the method definition must be decorated with the `@filter_criterion'. Instance variables and properties can be used without the decorator.
8
+
9
+ ## Extended Backus-Naur Form of Filter Specifications
10
+
11
+ This format defines the representation of a filter in JSON. When parsing filters, whitespace between components is ignored.
12
+
13
+ ```EBNF
14
+ # filter, the highest level. Always defines at least 1 logical_component.
15
+ filter ::= "{\"name\":" string ", \"description\":" string ",\"priority\":" nonnegative_integer ",\"object_types\": [" object_types "], \"logical_component\":" logical_component "}"
16
+
17
+ # Non-logic information for filter
18
+ object_types ::= string | string "," object_types
19
+
20
+ # logical_components, the second level. All logical_components are interchangeable in any circumstance.
21
+ logical_components ::= logical_component | logical_component logical_components
22
+ logical_component ::= filter | rule | conditional_statement | group_expression
23
+ rule ::= "\"criterion:\"" string ", \"operator\":" operator ", \"comparison_value:\"" comparison_value ", \"parameters:\"" parameter_list ", \"multi_object_behavior:\"" multi_object_behavior
24
+ conditional_statement ::= "{\"if\":" logical_components ", \"then\":" logical_components ", \"else\":" logical_components "}"
25
+ group_expression ::= "{ \"condition\":" condition ", \"logical_components\":" logical_components "}"
26
+
27
+ # Portions of logical_components. Cannot be used on their own.
28
+ operator ::= "\"<\"" | "\"<=\"" | "\"==\"" | "\"!=\"" | "\">=\"" | "\">\""
29
+ comparison_value ::= integer | float | string | boolean
30
+ condition ::= "and" | "or"
31
+ parameter_list ::= "[]" | "[" parameters "]"
32
+ parameters ::= comparison_value | comparison_value "," parameters
33
+ multi_object_behavior ::= "\"none\"" | "\"add\"" | "\"each_meets_criterion\"" | "\"each_equal_in_object\""
34
+
35
+ # Basic data types. Equivalent to their JSON EBNF. (nonnegative_integer is not a data type in JSON.)
36
+ integer ::= "-" digits | nonnegative_integer
37
+ digits ::= digit | digit digits
38
+ digit ::= "0" | nonzero_digit
39
+ nonzero_digit ::= "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
40
+ nonnegative_integer ::= "0" | nonzero_digit digits | digits
41
+
42
+ float ::= integer "." nonnegative_integer | integer "." nonnegative_integer exponent | integer exponent
43
+ exponent ::= exponent_letter "+" nonnegative_integer | exponent_letter integer
44
+ exponent_letter ::= "e" | "E"
45
+
46
+ string ::= "\"\"" | "\"" chars "\""
47
+ chars ::= char | char chars
48
+ char ::= " " | "!" | "\"" | "#" | "$" | "%" | "&" | "'" | "(" | ")" | "*" | "+" | "," | "-" | "." | "/" | "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | ":" | ";" | "<" | "=" | ">" | "?" | "@" | "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" | "[" | "\\" | "]" | "^" | "_" | "`" | "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" | "{" | "|" | "}" | "~"
49
+
50
+ boolean ::= "true" | "false"
51
+ ```
52
+
53
+ ## Terms
54
+
55
+ - **Logical Expression**: A single boolean value, rule, group expression, conditional expression, or filter.
56
+ - **Boolean Value**: The literal value True or False.
57
+ - **Rule**: The lowest-level logical expression, which cannot contain any other logical expressions. Evaluates to True or False based on the criterion within.
58
+ - **Group Expression**: A group of logical expressions, joined with a logical operator.
59
+ - **Conditional Expression**: Logical expressions that evaluate based on the criteria of the other logical expressions within.
60
+ - **Operator**: Comparison symbols. <, <=, ==, !=, >=, >.
61
+ - **Logical Operator**: Terms that define how many logical expressions within must evaluate to True for the whole group to be True. "and" or "or".
62
+
63
+ ## Detailed Filter Structure
64
+
65
+ ### Filter
66
+
67
+ A filter is an object that includes several key elements:
68
+
69
+ - **name**: The name of the filter.
70
+ - **description**: A brief explanation of what the filter does.
71
+ - **priority**: A number indicating how important the filter is (lower numbers indicate higher priority, must be >= 0).
72
+ - **object_types**: A list of types of objects the filter applies to.
73
+ - **logical_expression**: A single logical expression, as defined above.
74
+
75
+ ### Rule
76
+
77
+ A rule specifies a single condition to check and includes:
78
+
79
+ - **Criterion**: The property to check (e.g., width, height).
80
+ - **Operator**: The operator used to compare the criterion with the comparison value. Defined above.
81
+ - **Comparison Value**: The value to compare the property against.
82
+ - **Parameters**: Additional values to use in the comparison, if the criterion is a method.
83
+ - **Multi Value Behavior**: How a list of values returned by evaluating the criterion should be evaluated. For advanced usage only. "none", "add", "each_meets_criterion", or "each_equal_in_object".
84
+
85
+ ### Operators
86
+
87
+ Operators define how to compare values:
88
+
89
+ | Operator | Meaning |
90
+ |----------|-------------------|
91
+ | < | Less than |
92
+ | <= | Less than or equal|
93
+ | == | Equal to |
94
+ | != | Not equal to |
95
+ | >= | Greater than or equal |
96
+ | > | Greater than |
97
+
98
+ ### Group Expressions
99
+
100
+ Group expressions define the conditions and rules that the filter uses. They use a logical operator (defined above) to determine how many of the logical expressions must evaluate to **True** for the whole group expression to evaluate to **True**.
101
+
102
+ - **logical_operator**: The logical operator to use. "and" indicates that all logical expressions evaluate to **True** for the group expression to be **True**. "or" indicates that 1 or more logical expressions must evaluate to **True** for the group expression to be **True**.
103
+ - **logical_expressions**: One or more logical expressions of any kind. Surrounded by `[ ]`.
104
+
105
+ ### Conditional Expression
106
+
107
+ A conditional expression includes three parts:
108
+
109
+ - **if**: The first logical expression to evaluate. If the logical expression evaluates to **True**, the *then* conditional expression will be evaluated. If the *if* portion evaluates to **False**, the *else* portion will be evaluated.
110
+ - **then**: A logical expression, only evaluated if *if* is **True**. If *if* is **True** and *then* is **True**, then the conditional expression is **True**. If *if* is **True** and *then* is **False**, then the conditional expression is **False**.
111
+ - **else**: A logical expression, only evaluated if *if* is **False**. If *if* is **False** and *else* is **True**, then the conditional expression is **True**. If *if* is **False** and *else* is **False**, then the conditional expression is **False**.
112
+
113
+ To evaluate to **True**, either the *if* and *then* conditions must evaluate to **True**, or the *if* conditions must evaluate to **False** and the *else* conditions must evaluate to **True**.
114
+
115
+ ```JSON
116
+ {
117
+ "name": "Fits in Box",
118
+ "description": "A sample filter demonstrating potential conditions for an animal to fit in a cardboard box.",
119
+ "priority": 2,
120
+ "object_types": ["Animal"],
121
+ "logical_expression": [
122
+ {
123
+ "logical_operator": "or",
124
+ "logical_expressions": [
125
+ {
126
+ "if": {
127
+ "logical_operator": "and",
128
+ "logical_expressions": [
129
+ {"criterion": "species", "operator": "==", "comparison_value": "cat", "parameters": [], "multi_value_behavior": "none"},
130
+ {"criterion": "weight", "operator": "<", "comparison_value": 8.9, "parameters": [], "multi_value_behavior": "none"},
131
+ ]
132
+ },
133
+ "then": {
134
+ "logical_operator": "or",
135
+ "logical_expressions": [
136
+ {"criterion": "height", "operator": "<=", "comparison_value": 1.5, "parameters": [], "multi_value_behavior": "none"},
137
+ {"criterion": "length", "operator": "<=", "comparison_value": 2, "parameters": [], "multi_value_behavior": "none"}
138
+ ]
139
+ },
140
+ "else": {
141
+ "logical_operator": "and",
142
+ "logical_expressions": [
143
+ {"criterion": "species", "operator": "==", "comparison_value": "cat", "parameters": [], "multi_value_behavior": "none"}
144
+ ]
145
+ }
146
+ },
147
+ {
148
+ "if": {
149
+ "condition": "and",
150
+ "rules": [
151
+ {"criterion": "species", "operator": "==", "comparison_value": "dog", "parameters": [], "multi_value_behavior": "none"},
152
+ {"criterion": "weight", "operator": "<", "comparison_value": 8.9, "parameters": [], "multi_value_behavior": "none"},
153
+ ]
154
+ },
155
+ "then": {
156
+ "condition": "or",
157
+ "rules": [
158
+ {"criterion": "height", "operator": "<=", "comparison_value": 1.5, "parameters": [], "multi_value_behavior": "none"},
159
+ {"criterion": "length", "operator": "<=", "comparison_value": 2.5, "parameters": [], "multi_value_behavior": "none"}
160
+ ]
161
+ },
162
+ "else": false,
163
+ }
164
+ ]
165
+ },
166
+ {
167
+ "logical_operator": "and",
168
+ "logical_expressions": [
169
+ {"criterion": "width", "operator": "<=", "comparison_value": 20, "parameters": [], "multi_value_behavior": "none"},
170
+ {"criterion": "rounded_length", "operator": "<=", "comparison_value": 62, "parameters": [], "multi_value_behavior": "none"}
171
+ ]
172
+ }
173
+ ]
174
+ }
175
+ ```
@@ -0,0 +1,35 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [tool.setuptools]
6
+ packages = ["object_filtering"]
7
+
8
+ [project]
9
+ name = "object_filtering"
10
+ version = "0.1.11"
11
+ authors = [
12
+ { name="Scott Ratchford", email="object_filtering@scottratchford.com" },
13
+ ]
14
+ description = "A module for determining whether arbitrary Python objects meet a set of defined criteria."
15
+ readme = "README.md"
16
+ requires-python = ">=3.12"
17
+ classifiers = [
18
+ "License :: OSI Approved :: MIT License",
19
+ "Programming Language :: Python :: 3.12",
20
+ "Development Status :: 4 - Beta",
21
+ "Intended Audience :: Developers",
22
+ "Natural Language :: English",
23
+ "Topic :: File Formats :: JSON",
24
+ "Topic :: Software Development :: Libraries :: Python Modules",
25
+ "Topic :: Utilities",
26
+ ]
27
+
28
+ [project.urls]
29
+ Homepage = "https://github.com/KyberCritter/Object-Filtering"
30
+ Issues = "https://github.com/KyberCritter/Object-Filtering/issues"
31
+
32
+ [tool.pytest.ini_options]
33
+ pythonpath = [
34
+ "."
35
+ ]
Binary file
@@ -0,0 +1,4 @@
1
+ # (c) 2024 Scott Ratchford
2
+ # This file is licensed under the MIT License. See LICENSE.txt for details.
3
+
4
+ from .object_filtering import *