nativegate 0.1.4__tar.gz → 0.1.6__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.
Files changed (107) hide show
  1. {nativegate-0.1.4 → nativegate-0.1.6}/PKG-INFO +1 -1
  2. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/generators/f2py_gen.py +18 -0
  3. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/parsers/dialect.py +9 -1
  4. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate.egg-info/PKG-INFO +1 -1
  5. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate.egg-info/SOURCES.txt +1 -0
  6. {nativegate-0.1.4 → nativegate-0.1.6}/pyproject.toml +1 -1
  7. nativegate-0.1.6/tests/test_cmake_missing_input.py +67 -0
  8. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_dialect.py +32 -0
  9. {nativegate-0.1.4 → nativegate-0.1.6}/README.md +0 -0
  10. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/__init__.py +0 -0
  11. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/__main__.py +0 -0
  12. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/buildinfo.py +0 -0
  13. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/cli.py +0 -0
  14. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/config.py +0 -0
  15. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/declared_invariants.py +0 -0
  16. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/discovery.py +0 -0
  17. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/driverbuild.py +0 -0
  18. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/drivers/__init__.py +0 -0
  19. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/drivers/cpp.py +0 -0
  20. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/drivers/fortran.py +0 -0
  21. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/generators/__init__.py +0 -0
  22. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/generators/cmake_gen.py +0 -0
  23. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/generators/docker_gen.py +0 -0
  24. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/generators/error_gen.py +0 -0
  25. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/generators/gateway_gen.py +0 -0
  26. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/generators/golden_gen.py +0 -0
  27. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/generators/k8s_gen.py +0 -0
  28. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/generators/mcp_gen.py +0 -0
  29. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/generators/middleware_gen.py +0 -0
  30. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/generators/pybind_gen.py +0 -0
  31. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/generators/pyproject_gen.py +0 -0
  32. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/generators/python_pkg_gen.py +0 -0
  33. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/generators/test_gen.py +0 -0
  34. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/golden.py +0 -0
  35. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/invariants.py +0 -0
  36. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/ir.py +0 -0
  37. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/lattice.py +0 -0
  38. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/locking.py +0 -0
  39. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/oracle.py +0 -0
  40. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/parsers/__init__.py +0 -0
  41. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/parsers/cpp.py +0 -0
  42. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/parsers/cpp_ast.py +0 -0
  43. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/parsers/cpp_regex.py +0 -0
  44. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/parsers/fixed_form.py +0 -0
  45. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/parsers/fortran.py +0 -0
  46. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/parsers/fortran_fparser.py +0 -0
  47. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/parsers/fortran_regex.py +0 -0
  48. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/preprocess.py +0 -0
  49. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/structural_invariants.py +0 -0
  50. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/suggest.py +0 -0
  51. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/templates/__init__.py +0 -0
  52. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/templates/golden_test_template.py +0 -0
  53. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate/wire.py +0 -0
  54. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate.egg-info/dependency_links.txt +0 -0
  55. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate.egg-info/entry_points.txt +0 -0
  56. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate.egg-info/requires.txt +0 -0
  57. {nativegate-0.1.4 → nativegate-0.1.6}/nativegate.egg-info/top_level.txt +0 -0
  58. {nativegate-0.1.4 → nativegate-0.1.6}/setup.cfg +0 -0
  59. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_buildinfo.py +0 -0
  60. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_cli_serve_verify.py +0 -0
  61. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_cli_suggest.py +0 -0
  62. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_cli_verify_aggregate.py +0 -0
  63. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_cmake_gen.py +0 -0
  64. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_config_unknown_keys.py +0 -0
  65. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_cpp_ast.py +0 -0
  66. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_cpp_driver.py +0 -0
  67. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_cpp_pipeline.py +0 -0
  68. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_declared_invariants.py +0 -0
  69. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_derived_types.py +0 -0
  70. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_docker_gen.py +0 -0
  71. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_driverbuild.py +0 -0
  72. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_endpoint_docstrings.py +0 -0
  73. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_fixed_form.py +0 -0
  74. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_fortran_doc_comments.py +0 -0
  75. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_fortran_driver.py +0 -0
  76. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_fortran_fparser.py +0 -0
  77. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_fortran_libraries.py +0 -0
  78. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_fortran_pipeline.py +0 -0
  79. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_gateway_gen.py +0 -0
  80. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_generated_python_is_valid.py +0 -0
  81. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_golden.py +0 -0
  82. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_invariants.py +0 -0
  83. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_ir_contract.py +0 -0
  84. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_k8s_gen.py +0 -0
  85. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_lattice.py +0 -0
  86. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_legacy_cpp.py +0 -0
  87. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_legacy_fortran.py +0 -0
  88. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_locking.py +0 -0
  89. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_mcp_gen.py +0 -0
  90. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_middleware_gen.py +0 -0
  91. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_multifile_cpp.py +0 -0
  92. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_native_oracle.py +0 -0
  93. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_native_state_contract.py +0 -0
  94. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_oracle.py +0 -0
  95. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_preprocess_and_config.py +0 -0
  96. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_preprocessed_fortran.py +0 -0
  97. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_pybind_gen.py +0 -0
  98. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_pyproject_gen.py +0 -0
  99. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_quickstart.py +0 -0
  100. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_scalar_ref.py +0 -0
  101. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_service_gen.py +0 -0
  102. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_service_name_validation.py +0 -0
  103. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_shared_libraries.py +0 -0
  104. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_structural_invariants.py +0 -0
  105. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_suggest.py +0 -0
  106. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_verification_config.py +0 -0
  107. {nativegate-0.1.4 → nativegate-0.1.6}/tests/test_wire.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nativegate
3
- Version: 0.1.4
3
+ Version: 0.1.6
4
4
  Summary: Make legacy C++/C/Fortran AI-ready and microservice-ready: expose native code as an MCP server, REST API and container
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -67,6 +67,24 @@ set(F2PY_SOURCES
67
67
  {sources}
68
68
  )
69
69
 
70
+ # Say the fix, not the symptom: when this tree is consumed without
71
+ # `ngate generate` having run (a packaging commit that ships the service
72
+ # tree without native/_expanded), ninja would otherwise die mid-configure
73
+ # with "no known rule to make it", which hides the remedy one exception
74
+ # down a build log. Confirmed in the wild as DEFECTS D11, via
75
+ # ravikings/specfun-py's first CI run.
76
+ foreach(f2py_source IN LISTS F2PY_SOURCES)
77
+ if(NOT EXISTS "${{f2py_source}}")
78
+ message(FATAL_ERROR
79
+ "Missing build input: ${{f2py_source}}\n"
80
+ "nativegate generates this file when it resolves INCLUDE decks, "
81
+ "dialect marking and intent directives. Run:\n"
82
+ " ngate generate {service_name}\n"
83
+ "from this service directory (or the repo root), then build again."
84
+ )
85
+ endif()
86
+ endforeach()
87
+
70
88
  set(F2PY_OUTPUT "${{CMAKE_CURRENT_BINARY_DIR}}/{module.name}${{PY_EXT_SUFFIX}}")
71
89
 
72
90
  # f2py's meson backend picks tempfile.mkdtemp() for its build directory
@@ -41,7 +41,15 @@ import re
41
41
 
42
42
  DIALECT_CHOICES = ("cs", "cd")
43
43
 
44
- _PREFIX_RE = re.compile(r"^(CS|CD)(?=[ \t])", re.IGNORECASE | re.MULTILINE)
44
+ # Statement labels are dialect-marked too ("CD900 DGAMMA = RES"), so no
45
+ # space lookahead: any line starting with CS/CD is prefix-marked, with a
46
+ # following space, tab, digit or line end allowed out to avoid tripping
47
+ # on prose comments like "CSIMPLER". A live statement never starts with
48
+ # literal letters in column 1 — the statement field begins in column 7 —
49
+ # so there is no legitimate Fortran that begins "CS"/"CD" here. A comment
50
+ # that merely starts with those letters is, at worst, re-marked; the
51
+ # only real hazard would be more labels lost to a stricter pattern.
52
+ _PREFIX_RE = re.compile(r"^(CS|CD)(?=[ \t\n]|\d|$)", re.IGNORECASE | re.MULTILINE)
45
53
 
46
54
 
47
55
  def resolve_dialect(raw: str | None) -> str:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nativegate
3
- Version: 0.1.4
3
+ Version: 0.1.6
4
4
  Summary: Make legacy C++/C/Fortran AI-ready and microservice-ready: expose native code as an MCP server, REST API and container
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -57,6 +57,7 @@ tests/test_cli_serve_verify.py
57
57
  tests/test_cli_suggest.py
58
58
  tests/test_cli_verify_aggregate.py
59
59
  tests/test_cmake_gen.py
60
+ tests/test_cmake_missing_input.py
60
61
  tests/test_config_unknown_keys.py
61
62
  tests/test_cpp_ast.py
62
63
  tests/test_cpp_driver.py
@@ -13,7 +13,7 @@ build-backend = "setuptools.build_meta"
13
13
 
14
14
  [project]
15
15
  name = "nativegate"
16
- version = "0.1.4"
16
+ version = "0.1.6"
17
17
  description = "Make legacy C++/C/Fortran AI-ready and microservice-ready: expose native code as an MCP server, REST API and container"
18
18
  readme = "README.md"
19
19
  requires-python = ">=3.10"
@@ -0,0 +1,67 @@
1
+ """D11: a service tree consumed without `generate` must say so at configure
2
+ time.
3
+
4
+ The generated CMake references native/_expanded/ sources that `ngate
5
+ generate` writes. A packaging commit that ships the service tree without
6
+ them (the exact failure of specfun-py's first CI run) surfaced as ninja's
7
+ "no known rule to make it" mid-build, with the remedy buried one exception
8
+ down a log. The generated CMake now fatals at configure time with the
9
+ remedy written out.
10
+ """
11
+
12
+ import shutil
13
+ import textwrap
14
+ from pathlib import Path
15
+
16
+ import pytest
17
+
18
+ from nativegate.generators import f2py_gen
19
+
20
+
21
+ def test_generated_cmake_carries_the_missing_input_guard():
22
+ cmake = f2py_gen.generate_cmake(
23
+ type("M", (), {"name": "specfun"})(),
24
+ "specfun",
25
+ ["native/_expanded/gamma.f"],
26
+ )
27
+ assert "foreach(f2py_source IN LISTS F2PY_SOURCES)" in cmake
28
+ assert "NOT EXISTS" in cmake
29
+ assert "ngate generate" in cmake
30
+
31
+
32
+ @pytest.mark.skipif(shutil.which("cmake") is None, reason="cmake not on PATH")
33
+ @pytest.mark.skipif(
34
+ shutil.which("gfortran") is None, reason="Fortran language check needs a compiler"
35
+ )
36
+ def test_guard_fires_when_the_input_file_is_absent(tmp_path):
37
+ cmake = f2py_gen.generate_cmake(
38
+ type("M", (), {"name": "specfun"})(),
39
+ "specfun",
40
+ ["native/_expanded/gamma.f"],
41
+ )
42
+ (tmp_path / "CMakeLists.txt").write_text(cmake)
43
+ (tmp_path / "native" / "_expanded").mkdir(parents=True)
44
+ (tmp_path / "native" / "_expanded" / "gamma.f").write_text(
45
+ textwrap.dedent("""\
46
+ MISSING
47
+ """)
48
+ )
49
+ (tmp_path / "native" / "_expanded" / "gamma.f").unlink()
50
+
51
+ result = _configure(tmp_path)
52
+ combined = result.stdout + result.stderr
53
+ assert "Missing build input" in combined
54
+ assert "ngate generate specfun" in combined
55
+ # and NOT the misleading ninja symptom
56
+ assert "no known rule to make it" not in combined
57
+
58
+
59
+ def _configure(tmp_path):
60
+ import subprocess
61
+ import sys
62
+ env_path = sys.executable
63
+ return subprocess.run(
64
+ ["cmake", "-S", str(tmp_path), "-B", str(tmp_path / "build"),
65
+ f"-DPython_EXECUTABLE={env_path}"],
66
+ capture_output=True, text=True,
67
+ )
@@ -45,10 +45,42 @@ CD DOUBLE PRECISION
45
45
  1 C,CONV,EPS
46
46
  DGAMMA = 24.0D0
47
47
  RETURN
48
+ C the labelled assignment is dialect-marked as well: label in cols 1-5,
49
+ C prefix occupying cols 1-2, so the 9 lands in column 3 — still inside
50
+ C the label field (columns 1-5) after two blanks are substituted.
51
+ 900 DGAMMA = 24.0D0
52
+ RETURN
53
+ END
54
+ """)
55
+
56
+ DUAL_WITH_MARKED_LABEL = textwrap.dedent("""\
57
+ CD DOUBLE PRECISION FUNCTION DGAMMA(X)
58
+ CS REAL FUNCTION GAMMA(X)
59
+ GO TO 900
60
+ CD900 DGAMMA = 24.0D0
61
+ CS900 GAMMA = 24.0E0
62
+ RETURN
63
+ 900 CONTINUE
64
+ RETURN
48
65
  END
49
66
  """)
50
67
 
51
68
 
69
+ def test_apply_dialect_marks_statement_labels_too():
70
+ """`CD900 DGAMMA = ...` is the line that exposed the strict space-lookahead
71
+ regex: labels start at column 1 and the prefix replaces its first two
72
+ characters, so the following character is a digit, not a space. A
73
+ space-lookahead regex would leave the label line inert and the resolved
74
+ file compiles with "label 900 referenced but never defined"."""
75
+ out = apply_dialect(DUAL_WITH_MARKED_LABEL, "cd")
76
+ lines = out.splitlines()
77
+ # label survives in the label field (digits starting column 3 is legal)
78
+ assert " 900 DGAMMA = 24.0D0" in lines
79
+ # the CS half is commented, label included
80
+ assert "C 900 GAMMA = 24.0E0" in lines
81
+ assert "C REAL FUNCTION GAMMA(X)" in lines
82
+
83
+
52
84
  def test_apply_dialect_selects_cd():
53
85
  out = apply_dialect(DUAL_DIALECT, "cd")
54
86
  lines = out.splitlines()
File without changes
File without changes
File without changes
File without changes