nativegate 0.1.1__tar.gz → 0.1.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.
Files changed (103) hide show
  1. {nativegate-0.1.1 → nativegate-0.1.2}/PKG-INFO +1 -1
  2. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/cli.py +17 -0
  3. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate.egg-info/PKG-INFO +1 -1
  4. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate.egg-info/SOURCES.txt +1 -0
  5. {nativegate-0.1.1 → nativegate-0.1.2}/pyproject.toml +1 -1
  6. nativegate-0.1.2/tests/test_service_name_validation.py +47 -0
  7. {nativegate-0.1.1 → nativegate-0.1.2}/README.md +0 -0
  8. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/__init__.py +0 -0
  9. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/__main__.py +0 -0
  10. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/buildinfo.py +0 -0
  11. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/config.py +0 -0
  12. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/declared_invariants.py +0 -0
  13. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/discovery.py +0 -0
  14. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/driverbuild.py +0 -0
  15. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/drivers/__init__.py +0 -0
  16. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/drivers/cpp.py +0 -0
  17. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/drivers/fortran.py +0 -0
  18. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/generators/__init__.py +0 -0
  19. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/generators/cmake_gen.py +0 -0
  20. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/generators/docker_gen.py +0 -0
  21. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/generators/error_gen.py +0 -0
  22. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/generators/f2py_gen.py +0 -0
  23. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/generators/gateway_gen.py +0 -0
  24. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/generators/golden_gen.py +0 -0
  25. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/generators/k8s_gen.py +0 -0
  26. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/generators/mcp_gen.py +0 -0
  27. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/generators/middleware_gen.py +0 -0
  28. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/generators/pybind_gen.py +0 -0
  29. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/generators/pyproject_gen.py +0 -0
  30. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/generators/python_pkg_gen.py +0 -0
  31. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/generators/test_gen.py +0 -0
  32. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/golden.py +0 -0
  33. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/invariants.py +0 -0
  34. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/ir.py +0 -0
  35. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/lattice.py +0 -0
  36. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/locking.py +0 -0
  37. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/oracle.py +0 -0
  38. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/parsers/__init__.py +0 -0
  39. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/parsers/cpp.py +0 -0
  40. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/parsers/cpp_ast.py +0 -0
  41. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/parsers/cpp_regex.py +0 -0
  42. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/parsers/fixed_form.py +0 -0
  43. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/parsers/fortran.py +0 -0
  44. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/parsers/fortran_fparser.py +0 -0
  45. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/parsers/fortran_regex.py +0 -0
  46. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/preprocess.py +0 -0
  47. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/structural_invariants.py +0 -0
  48. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/suggest.py +0 -0
  49. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/templates/__init__.py +0 -0
  50. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/templates/golden_test_template.py +0 -0
  51. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate/wire.py +0 -0
  52. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate.egg-info/dependency_links.txt +0 -0
  53. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate.egg-info/entry_points.txt +0 -0
  54. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate.egg-info/requires.txt +0 -0
  55. {nativegate-0.1.1 → nativegate-0.1.2}/nativegate.egg-info/top_level.txt +0 -0
  56. {nativegate-0.1.1 → nativegate-0.1.2}/setup.cfg +0 -0
  57. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_buildinfo.py +0 -0
  58. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_cli_serve_verify.py +0 -0
  59. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_cli_suggest.py +0 -0
  60. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_cli_verify_aggregate.py +0 -0
  61. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_cmake_gen.py +0 -0
  62. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_cpp_ast.py +0 -0
  63. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_cpp_driver.py +0 -0
  64. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_cpp_pipeline.py +0 -0
  65. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_declared_invariants.py +0 -0
  66. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_derived_types.py +0 -0
  67. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_docker_gen.py +0 -0
  68. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_driverbuild.py +0 -0
  69. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_endpoint_docstrings.py +0 -0
  70. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_fixed_form.py +0 -0
  71. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_fortran_doc_comments.py +0 -0
  72. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_fortran_driver.py +0 -0
  73. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_fortran_fparser.py +0 -0
  74. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_fortran_libraries.py +0 -0
  75. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_fortran_pipeline.py +0 -0
  76. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_gateway_gen.py +0 -0
  77. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_generated_python_is_valid.py +0 -0
  78. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_golden.py +0 -0
  79. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_invariants.py +0 -0
  80. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_ir_contract.py +0 -0
  81. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_k8s_gen.py +0 -0
  82. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_lattice.py +0 -0
  83. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_legacy_cpp.py +0 -0
  84. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_legacy_fortran.py +0 -0
  85. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_locking.py +0 -0
  86. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_mcp_gen.py +0 -0
  87. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_middleware_gen.py +0 -0
  88. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_multifile_cpp.py +0 -0
  89. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_native_oracle.py +0 -0
  90. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_native_state_contract.py +0 -0
  91. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_oracle.py +0 -0
  92. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_preprocess_and_config.py +0 -0
  93. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_preprocessed_fortran.py +0 -0
  94. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_pybind_gen.py +0 -0
  95. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_pyproject_gen.py +0 -0
  96. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_quickstart.py +0 -0
  97. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_scalar_ref.py +0 -0
  98. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_service_gen.py +0 -0
  99. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_shared_libraries.py +0 -0
  100. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_structural_invariants.py +0 -0
  101. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_suggest.py +0 -0
  102. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_verification_config.py +0 -0
  103. {nativegate-0.1.1 → nativegate-0.1.2}/tests/test_wire.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nativegate
3
- Version: 0.1.1
3
+ Version: 0.1.2
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
@@ -60,6 +60,7 @@ from .ir import (
60
60
  IRSchemaError,
61
61
  ModuleIR,
62
62
  NativeTypeError,
63
+ is_valid_python_name,
63
64
  module_from_dict,
64
65
  module_to_dict,
65
66
  validate as validate_ir,
@@ -1241,6 +1242,22 @@ def clean(name: str) -> None:
1241
1242
  def _scaffold_service(name: str, language: str, force: bool) -> Path:
1242
1243
  import shutil
1243
1244
 
1245
+ # Reject before anything is written: the name becomes a Python package
1246
+ # (services/<name>/python/<name>/), so `specfun-gamma` would fail at
1247
+ # generate time with `from ._native.specfun-gamma import ...` — invalid
1248
+ # syntax caught by the generated-file compile() gate, three commands
1249
+ # and a wasted scaffold after the user typed the name. Saying so here
1250
+ # costs nothing (DEFECTS D9, found on first contact with netlib
1251
+ # specfun, where quickstart defaults the name to the file stem and
1252
+ # `specfun-gamma` is the obvious thing to type).
1253
+ if not is_valid_python_name(name):
1254
+ raise click.ClickException(
1255
+ f"Service name '{name}' is not usable: it becomes a Python package, "
1256
+ "so it must be a valid identifier (letters, digits, underscores, "
1257
+ "not starting with a digit, not a Python keyword). "
1258
+ "Use underscores instead of dashes."
1259
+ )
1260
+
1244
1261
  service_dir = Path(SERVICES_DIR) / name
1245
1262
  if service_dir.exists():
1246
1263
  if not force:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nativegate
3
- Version: 0.1.1
3
+ Version: 0.1.2
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
@@ -93,6 +93,7 @@ tests/test_pyproject_gen.py
93
93
  tests/test_quickstart.py
94
94
  tests/test_scalar_ref.py
95
95
  tests/test_service_gen.py
96
+ tests/test_service_name_validation.py
96
97
  tests/test_shared_libraries.py
97
98
  tests/test_structural_invariants.py
98
99
  tests/test_suggest.py
@@ -13,7 +13,7 @@ build-backend = "setuptools.build_meta"
13
13
 
14
14
  [project]
15
15
  name = "nativegate"
16
- version = "0.1.1"
16
+ version = "0.1.2"
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,47 @@
1
+ """D9 regression: dash-named services are rejected at scaffold time, not
2
+ at generate time with invalid generated Python.
3
+
4
+ First contact with netlib specfun (2026-09-23): `ngate quickstart gamma.f
5
+ --name specfun-gamma` scaffolded cleanly, generated
6
+ `from ._native.specfun-gamma import ...` — invalid syntax — and only
7
+ nativegate's generated-file compile() gate refused to write it, three
8
+ commands after the moment the user should have been told.
9
+ """
10
+
11
+ import pytest
12
+ from click.testing import CliRunner
13
+
14
+ from nativegate import cli
15
+
16
+
17
+ @pytest.fixture()
18
+ def scratch(tmp_path, monkeypatch):
19
+ monkeypatch.chdir(tmp_path)
20
+ return tmp_path
21
+
22
+
23
+ @pytest.mark.parametrize("bad", ["specfun-gamma", "2lib", "class"])
24
+ def test_create_service_rejects_non_identifier_names(scratch, bad):
25
+ result = CliRunner().invoke(cli.main, ["create-service", bad, "--language", "fortran"])
26
+ assert result.exit_code != 0
27
+ assert "Python package" in result.output
28
+ # nothing may have been written
29
+ assert not (scratch / "services").exists()
30
+
31
+
32
+ def test_quickstart_rejects_dash_named_service_and_explains(tmp_path, monkeypatch):
33
+ monkeypatch.chdir(tmp_path)
34
+ source = tmp_path / "gamma.f"
35
+ source.write_text(" DOUBLE PRECISION FUNCTION DGAMMA(X)\n END\n")
36
+ result = CliRunner().invoke(
37
+ cli.main, ["quickstart", str(source), "--name", "specfun-gamma"]
38
+ )
39
+ assert result.exit_code != 0
40
+ assert "--name specfun_gamma" not in result.output
41
+
42
+
43
+ def test_valid_underscored_name_still_scaffolds(scratch):
44
+ result = CliRunner().invoke(
45
+ cli.main, ["create-service", "specfun_gamma", "--language", "fortran"]
46
+ )
47
+ assert result.exit_code == 0, result.output
File without changes
File without changes
File without changes