py-fastplus 0.2.0__tar.gz → 0.2.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.
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/.github/workflows/Publish.yml +6 -0
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/Cargo.lock +1 -1
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/Cargo.toml +1 -1
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/PKG-INFO +1 -1
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/src/field.rs +3 -0
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/src/operator.rs +65 -11
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/.githooks/pre-commit +0 -0
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/.github/workflows/Commit.yml +0 -0
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/.gitignore +0 -0
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/LICENSE +0 -0
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/README.md +0 -0
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/examples/parse_demo.rs +0 -0
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/pyproject.toml +0 -0
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/python/fastplus/__about__.py +0 -0
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/python/fastplus/__init__.py +0 -0
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/python/fastplus/core.pyi +0 -0
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/python/fastplus/parser.py +0 -0
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/python/tests/test_all.py +0 -0
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/src/ast.rs +0 -0
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/src/fastplus.pest +0 -0
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/src/lib.rs +0 -0
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/src/parser.rs +0 -0
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/src/python.rs +0 -0
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/src/python_macro.rs +0 -0
- {py_fastplus-0.2.0 → py_fastplus-0.2.2}/uv.lock +0 -0
|
@@ -187,6 +187,12 @@ jobs:
|
|
|
187
187
|
uses: actions/attest@v4
|
|
188
188
|
with:
|
|
189
189
|
subject-path: 'wheels-*/*'
|
|
190
|
+
- name: Recreate latest release
|
|
191
|
+
if: ${{ steps.release-tag.outputs.tag == 'dev-latest' || steps.release-tag.outputs.tag == 'main-latest' }}
|
|
192
|
+
env:
|
|
193
|
+
GH_TOKEN: ${{ github.token }}
|
|
194
|
+
RELEASE_TAG: ${{ steps.release-tag.outputs.tag }}
|
|
195
|
+
run: gh release delete "$RELEASE_TAG" --yes || true
|
|
190
196
|
- name: Create or update GitHub Release
|
|
191
197
|
uses: softprops/action-gh-release@v3
|
|
192
198
|
with:
|
|
@@ -218,6 +218,7 @@ impl Constant {
|
|
|
218
218
|
| (Constant::Driver(_), Constant::Driver(_))
|
|
219
219
|
| (Constant::Range(_), Constant::Range(_))
|
|
220
220
|
| (Constant::Array(_), Constant::Array(_))
|
|
221
|
+
| (Constant::Array(_), Constant::Range(_))
|
|
221
222
|
| (Constant::Set(_), Constant::Set(_))
|
|
222
223
|
| (Constant::String(_), Constant::String(_)) => true,
|
|
223
224
|
_ => false,
|
|
@@ -495,6 +496,8 @@ mod tests {
|
|
|
495
496
|
assert!(Constant::Ratio(0.0).fit(&Constant::Zero));
|
|
496
497
|
assert!(Constant::Ratio(0.0).fit(&Constant::One));
|
|
497
498
|
assert!(!Constant::Ratio(0.0).fit(&Constant::PositiveInteger(2)));
|
|
499
|
+
assert!(Constant::Array(Vec::new()).fit(&Constant::Range(0.1)));
|
|
500
|
+
assert!(!Constant::Range(0.1).fit(&Constant::Array(Vec::new())));
|
|
498
501
|
|
|
499
502
|
let expected = HashSet::from([1, 2, 3]);
|
|
500
503
|
let actual = Constant::EnumInteger {
|
|
@@ -85,10 +85,7 @@ impl Operator {
|
|
|
85
85
|
};
|
|
86
86
|
|
|
87
87
|
let actual = Field::Constant(value.clone());
|
|
88
|
-
|
|
89
|
-
&& matches!(name.as_str(), "range" | "buckets")
|
|
90
|
-
&& is_nan_constant(value);
|
|
91
|
-
if !spec.param_type.fit(&actual) && !bucket_nan {
|
|
88
|
+
if !spec.param_type.fit(&actual) {
|
|
92
89
|
return Err(OperatorCheckError::InvalidKeywordType {
|
|
93
90
|
name: name.clone(),
|
|
94
91
|
expected: Box::new(spec.param_type.clone()),
|
|
@@ -142,8 +139,34 @@ impl Operator {
|
|
|
142
139
|
}
|
|
143
140
|
}
|
|
144
141
|
"bucket" => {
|
|
145
|
-
|
|
142
|
+
let range = kw_args.get("range").or_else(|| {
|
|
143
|
+
self.kw_args
|
|
144
|
+
.get("range")
|
|
145
|
+
.and_then(|spec| spec.default_value.as_ref())
|
|
146
|
+
});
|
|
147
|
+
let buckets = kw_args.get("buckets").or_else(|| {
|
|
148
|
+
self.kw_args
|
|
149
|
+
.get("buckets")
|
|
150
|
+
.and_then(|spec| spec.default_value.as_ref())
|
|
151
|
+
});
|
|
152
|
+
if let Some(buckets) = buckets
|
|
153
|
+
&& !is_nan_constant(buckets)
|
|
154
|
+
&& matches!(buckets, Constant::Range(_))
|
|
155
|
+
{
|
|
156
|
+
return Err(OperatorCheckError::InvalidExpression(
|
|
157
|
+
"bucket requires buckets to be an Array, not a Range, consider use the range param".to_string(),
|
|
158
|
+
));
|
|
159
|
+
}
|
|
160
|
+
if let Some(Constant::Array(values)) = buckets
|
|
161
|
+
&& !values
|
|
162
|
+
.windows(2)
|
|
163
|
+
.all(|pair| pair[0].is_finite() && pair[1].is_finite() && pair[1] > pair[0])
|
|
146
164
|
{
|
|
165
|
+
return Err(OperatorCheckError::InvalidExpression(
|
|
166
|
+
"bucket requires buckets to be strictly increasing".to_string(),
|
|
167
|
+
));
|
|
168
|
+
}
|
|
169
|
+
if let (Some(range), Some(buckets)) = (range, buckets) {
|
|
147
170
|
let range_is_nan = is_nan_constant(range);
|
|
148
171
|
let buckets_is_nan = is_nan_constant(buckets);
|
|
149
172
|
if range_is_nan == buckets_is_nan {
|
|
@@ -1181,8 +1204,8 @@ define_operator_registry! {
|
|
|
1181
1204
|
"bucket",
|
|
1182
1205
|
[Matrix],
|
|
1183
1206
|
{
|
|
1184
|
-
"range" => (Range,
|
|
1185
|
-
"buckets" => (Array,
|
|
1207
|
+
"range" => (Range, Some(Constant::NaN)),
|
|
1208
|
+
"buckets" => (Array, Some(Constant::NaN)),
|
|
1186
1209
|
"skipBoth" => (Boolean, Some(Constant::Boolean(false))),
|
|
1187
1210
|
"NaNGroup" => (Boolean, Some(Constant::Boolean(false))),
|
|
1188
1211
|
},
|
|
@@ -1197,7 +1220,7 @@ define_operator_registry! {
|
|
|
1197
1220
|
{
|
|
1198
1221
|
"lower" => (Number, None),
|
|
1199
1222
|
"upper" => (Number, None),
|
|
1200
|
-
"inverse" => (Boolean,
|
|
1223
|
+
"inverse" => (Boolean, Some(Constant::Boolean(false))),
|
|
1201
1224
|
"mask" => (Mask, Some(Constant::NaN)),
|
|
1202
1225
|
},
|
|
1203
1226
|
1,
|
|
@@ -1474,6 +1497,12 @@ mod tests {
|
|
|
1474
1497
|
));
|
|
1475
1498
|
|
|
1476
1499
|
let bucket = get_operator("bucket").unwrap();
|
|
1500
|
+
assert!(matches!(
|
|
1501
|
+
bucket.apply(&[Field::Matrix], &HashMap::new()),
|
|
1502
|
+
Err(OperatorCheckError::InvalidExpression(message))
|
|
1503
|
+
if message.contains("exactly one")
|
|
1504
|
+
));
|
|
1505
|
+
|
|
1477
1506
|
let mut bucket_kwargs = HashMap::new();
|
|
1478
1507
|
bucket_kwargs.insert("range".to_string(), Constant::Range(0.1));
|
|
1479
1508
|
bucket_kwargs.insert("buckets".to_string(), Constant::Array(vec![0.0, 1.0]));
|
|
@@ -1483,17 +1512,42 @@ mod tests {
|
|
|
1483
1512
|
if message.contains("exactly one")
|
|
1484
1513
|
));
|
|
1485
1514
|
|
|
1515
|
+
bucket_kwargs.insert("range".to_string(), Constant::Range(0.1));
|
|
1516
|
+
bucket_kwargs.insert("buckets".to_string(), Constant::Range(0.1));
|
|
1517
|
+
assert!(matches!(
|
|
1518
|
+
bucket.apply(&[Field::Matrix], &bucket_kwargs),
|
|
1519
|
+
Err(OperatorCheckError::InvalidExpression(message))
|
|
1520
|
+
if message.contains("Array, not a Range")
|
|
1521
|
+
));
|
|
1522
|
+
|
|
1523
|
+
bucket_kwargs.insert("range".to_string(), Constant::Range(0.1));
|
|
1524
|
+
bucket_kwargs.insert("buckets".to_string(), Constant::Array(vec![0.0, 0.0, 1.0]));
|
|
1525
|
+
assert!(matches!(
|
|
1526
|
+
bucket.apply(&[Field::Matrix], &bucket_kwargs),
|
|
1527
|
+
Err(OperatorCheckError::InvalidExpression(message))
|
|
1528
|
+
if message.contains("strictly increasing")
|
|
1529
|
+
));
|
|
1530
|
+
|
|
1531
|
+
bucket_kwargs.insert("buckets".to_string(), Constant::Array(vec![1.0, 0.0]));
|
|
1532
|
+
assert!(matches!(
|
|
1533
|
+
bucket.apply(&[Field::Matrix], &bucket_kwargs),
|
|
1534
|
+
Err(OperatorCheckError::InvalidExpression(message))
|
|
1535
|
+
if message.contains("strictly increasing")
|
|
1536
|
+
));
|
|
1537
|
+
|
|
1486
1538
|
bucket_kwargs.insert("range".to_string(), Constant::NaN);
|
|
1487
1539
|
assert!(matches!(
|
|
1488
1540
|
bucket.apply(&[Field::Matrix], &bucket_kwargs),
|
|
1489
|
-
|
|
1541
|
+
Err(OperatorCheckError::InvalidKeywordType { name, .. })
|
|
1542
|
+
if name == "range"
|
|
1490
1543
|
));
|
|
1491
1544
|
|
|
1545
|
+
bucket_kwargs.insert("range".to_string(), Constant::Range(0.1));
|
|
1492
1546
|
bucket_kwargs.insert("buckets".to_string(), Constant::NaN);
|
|
1493
1547
|
assert!(matches!(
|
|
1494
1548
|
bucket.apply(&[Field::Matrix], &bucket_kwargs),
|
|
1495
|
-
Err(OperatorCheckError::
|
|
1496
|
-
if
|
|
1549
|
+
Err(OperatorCheckError::InvalidKeywordType { name, .. })
|
|
1550
|
+
if name == "buckets"
|
|
1497
1551
|
));
|
|
1498
1552
|
|
|
1499
1553
|
let clamp = get_operator("clamp").unwrap();
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|