Skip to content

Commit

Permalink
feat: Use oneof for metadata field
Browse files Browse the repository at this point in the history
Hide the enum behind static methods on the python type
  • Loading branch information
tobni committed May 20, 2023
1 parent a06cbf0 commit 732d1ab
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 27 deletions.
13 changes: 7 additions & 6 deletions src/python/pants/engine/internals/native_engine.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -448,9 +448,12 @@ class PyStubCAS:
# Dependency inference
# ------------------------------------------------------------------------------

class JavascriptInferenceMetadata:
def __init__(self, package_root: str, import_patterns: dict[str, list[str]]) -> None: ...
def __eq__(self, other: JavascriptInferenceMetadata | Any) -> bool: ...
class InferenceMetadata:
@staticmethod
def javascript(
package_root: str, import_patterns: dict[str, list[str]]
) -> InferenceMetadata: ...
def __eq__(self, other: InferenceMetadata | Any) -> bool: ...
def __hash__(self) -> int: ...
def __repr__(self) -> str: ...

Expand All @@ -467,9 +470,7 @@ class NativeDependenciesRequest:
result = await Get(NativeParsedPythonDependencies, NativeDependenciesRequest(input_digest, None)
"""

def __init__(
self, digest: Digest, metadata: JavascriptInferenceMetadata | None = None
) -> None: ...
def __init__(self, digest: Digest, metadata: InferenceMetadata | None = None) -> None: ...
def __eq__(self, other: NativeDependenciesRequest | Any) -> bool: ...
def __hash__(self) -> int: ...
def __repr__(self) -> str: ...
Expand Down
20 changes: 20 additions & 0 deletions src/python/pants/engine/internals/native_engine_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2023 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).
from pants.engine.internals.native_engine import (
EMPTY_DIGEST,
InferenceMetadata,
NativeDependenciesRequest,
)


def test_can_construct_javascript_metadata() -> None:
InferenceMetadata.javascript(
package_root="some/dir", import_patterns={"a-pattern-*": ["replaces-me-*"]}
)


def test_can_construct_native_dependencies_request() -> None:
NativeDependenciesRequest(EMPTY_DIGEST, None)
NativeDependenciesRequest(
EMPTY_DIGEST, InferenceMetadata.javascript(package_root="some/dir", import_patterns={})
)
4 changes: 3 additions & 1 deletion src/rust/engine/protos/protos/pants/cache.proto
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ message CacheKey {

message DependencyInferenceRequest {
build.bazel.remote.execution.v2.Digest input_file_digest = 1;
optional JavascriptInferenceMetadata metadata = 2;
oneof metadata {
JavascriptInferenceMetadata js = 2;
}
}


Expand Down
9 changes: 9 additions & 0 deletions src/rust/engine/protos/src/hashing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0 (see LICENSE).
use std::hash::{Hash, Hasher};

use crate::gen::pants::cache::dependency_inference_request::Metadata;
use crate::gen::pants::cache::JavascriptInferenceMetadata;

impl Hash for JavascriptInferenceMetadata {
Expand All @@ -13,3 +14,11 @@ impl Hash for JavascriptInferenceMetadata {
}
}
}

impl Hash for Metadata {
fn hash<H: Hasher>(&self, state: &mut H) {
match self {
Metadata::Js(m) => m.hash(state),
}
}
}
50 changes: 30 additions & 20 deletions src/rust/engine/src/externs/dep_inference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,27 @@ use pyo3::types::PyDict;
use pyo3::{IntoPy, PyObject, Python};

use fs::DirectoryDigest;
use protos::gen::pants::cache::{javascript_inference_metadata, JavascriptInferenceMetadata};
use protos::gen::pants::cache::{
dependency_inference_request, javascript_inference_metadata, JavascriptInferenceMetadata,
};

use crate::externs::fs::PyDigest;

pub(crate) fn register(m: &PyModule) -> PyResult<()> {
m.add_class::<PyNativeDependenciesRequest>()?;
m.add_class::<PyJavascriptInferenceMetadata>()
m.add_class::<PyInferenceMetadata>()
}

#[pyclass(name = "JavascriptInferenceMetadata")]
#[pyclass(name = "InferenceMetadata")]
#[derive(Clone, Debug, PartialEq)]
pub struct PyJavascriptInferenceMetadata(pub JavascriptInferenceMetadata);
pub struct PyInferenceMetadata(pub dependency_inference_request::Metadata);

#[pymethods]
impl PyJavascriptInferenceMetadata {
#[new]
fn __new__(package_root: String, patterns: &PyDict) -> PyResult<Self> {
impl PyInferenceMetadata {
#[staticmethod]
fn javascript(package_root: String, import_patterns: &PyDict) -> PyResult<Self> {
use javascript_inference_metadata::ImportPattern;
let import_patterns: PyResult<Vec<ImportPattern>> = patterns
let import_patterns: PyResult<Vec<ImportPattern>> = import_patterns
.iter()
.map(|(key, value)| {
Ok(ImportPattern {
Expand All @@ -36,10 +38,24 @@ impl PyJavascriptInferenceMetadata {
})
})
.collect();
Ok(Self(JavascriptInferenceMetadata {
package_root,
import_patterns: import_patterns?,
}))
Ok(Self(dependency_inference_request::Metadata::Js(
JavascriptInferenceMetadata {
package_root,
import_patterns: import_patterns?,
},
)))
}

fn __richcmp__(&self, other: &Self, op: CompareOp, py: Python) -> PyObject {
match op {
CompareOp::Eq => (self == other).into_py(py),
CompareOp::Ne => (self != other).into_py(py),
_ => py.NotImplemented(),
}
}

fn __repr__(&self) -> String {
format!("InferenceMetadata({:?})", self.0)
}

fn __hash__(&self) -> u64 {
Expand All @@ -49,23 +65,17 @@ impl PyJavascriptInferenceMetadata {
}
}

impl From<JavascriptInferenceMetadata> for PyJavascriptInferenceMetadata {
fn from(value: JavascriptInferenceMetadata) -> Self {
PyJavascriptInferenceMetadata(value)
}
}

#[pyclass(name = "NativeDependenciesRequest")]
#[derive(Clone, Debug, PartialEq)]
pub struct PyNativeDependenciesRequest {
pub directory_digest: DirectoryDigest,
pub metadata: Option<JavascriptInferenceMetadata>,
pub metadata: Option<dependency_inference_request::Metadata>,
}

#[pymethods]
impl PyNativeDependenciesRequest {
#[new]
fn __new__(digest: PyDigest, metadata: Option<PyJavascriptInferenceMetadata>) -> Self {
fn __new__(digest: PyDigest, metadata: Option<PyInferenceMetadata>) -> Self {
Self {
directory_digest: digest.0,
metadata: metadata.map(|inner| inner.0),
Expand Down

0 comments on commit 732d1ab

Please sign in to comment.