Repository navigation
Build two distributions: arcadedb (native) and arcadedb-jvm (JVM) - #66
Merged
Merged
Conversation
The JVM build is published as arcadedb-jvm (environment pypi-jvm); the name arcadedb is reserved for the native build. The import name stays arcadedb. Wheel files are arcadedb_jvm-<version>-..., so every glob, the wheel-count checks, the name guard in the publish job, the check_version.py call, after_tag_verify.sh and the pip hints for the extras follow. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ibution arcadedb.__backend__ is 'jvm' or 'native'. The import-time check that only warned when both distributions were installed now raises DistributionConflictError (an ImportError) in both builds: arcadedb-jvm refuses to import when arcadedb (native) is installed, and the other way round. The message names both packages, says how to fix it (pip uninstall arcadedb arcadedb-jvm, then install one) and links the Which package? page. Unreadable metadata still never breaks an import. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… backend, native tests The distribution `arcadedb` is the native build: the engine compiled by GraalVM Community Edition into a shared library (libarcadedb) that Python loads with ctypes. No JVM, no JPype. - native/: the Java glue (C entry points: ArcadeNative, NativeCodec, NativeExtras, BulkOps), the Maven wrapper, and scripts/build-image.sh (GraalVM CE 25.4.4.1.1, -O2, -march=compatibility, engine jars of a pinned release from Maven Central). - native/wheel/: build_wheel.py copies src/arcadedb, rewrites the JPype imports to a stub, flips the default backend to native, adds the library and the licence texts, checks THIRD_PARTY_NOTICES.md against what is compiled in (gen_notices.py), computes the platform tag from the library and builds a py3-none-<platform> wheel named arcadedb. parity_wheel.py runs the test suite against the INSTALLED wheel, file by file. - src/arcadedb/_native/: the Python native path, plus the hooks in core.py, server.py, vector.py, dataframe.py, exporter.py and exceptions.py. arcadedb.__backend__ is 'native' when it is active. The JVM wheel ships these files too (setup lists the subpackage; test_wheel_packages.py proves it); the library is only in the native wheel. - tests: test_native_*.py (collected on the native build only), conftest.py (NATIVE_NOT_APPLICABLE files are not collected on the native build; tests that need a Java object or the JVM are NOTYET / NA-JVM skips that the parity run counts apart; any other skip fails), the parity-aware child scripts in test_bridge_fixes.py and test_sigint.py. Ported from the humemai/arcadedb-embedded-python branch native-preview at 91a6ad719b0308c8ccbf569bf130412619292925 (open native-preview PRs #514 and #520-#538 are not merged there and are not in this port). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… arcadedb .github/workflows/native.yml builds the native image per platform, builds the wheel, runs the gates (glibc floor, auditwheel, twine, name and version) and the test suite against the INSTALLED wheel. scripts/select_native_matrix.py holds the legs (pinned by tests/test_select_native_matrix.py), because a native image build takes 1 to 2.5 hours per platform and the organisation shares a runner cap with upstream: - pull request: only when a native path changed (paths filter) and not for a draft; linux-x86_64, Python 3.12. - push to main (native paths only), nightly (only when something besides docs changed in the last 25 hours, a full run on Mondays) and dispatch: linux-x86_64, linux-aarch64, macos-arm64, windows-x64; Python 3.12 and 3.14. - release tag (A.B.C.devN, A.B.C, A.B.C.postN): all four platforms on Python 3.11 to 3.14. Publishing: a pre-release (A.B.C.devN) goes to the environment pypi-prerelease when linux-x86_64, linux-aarch64 and macos-arm64 passed on every Python. A final release (A.B.C, A.B.C.postN) goes to the environment pypi only when the repository variable ARCADEDB_NATIVE_READINESS_BAR_MET is true, all four platforms passed on all four Pythons, and no test is a NOTYET skip. GraalVM Community Edition only, pinned by sha256 per platform. The JVM workflows skip native/** and native.yml in their paths-ignore. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
README, the installation page, the quickstart and both PyPI descriptions (README.md for arcadedb-jvm, native/wheel/README.md for arcadedb) name both packages up front: arcadedb is the native build and the default for scripts, notebooks, tests, CLIs, serverless functions and agents; arcadedb-jvm is the JVM build for heavy, long-running loads; both import as arcadedb. The install lines are shown side by side with a one-line rule, never a bare pip install arcadedb. New permanent page docs/modules/ROOT/pages/which-package.adoc (replaces packages.adoc): the table, how to check (arcadedb.__backend__), what changes between the builds, switching and the import guard, server use (the official Docker images arcadedata/arcadedb), drivers, and a marked transition section for the old names. Transition-only callouts carry a REMOVE WHEN comment. The CI and release pages describe native.yml and the readiness bar for a final arcadedb release. tests/test_native_wheel_template.py pins the template of the native wheel (name, classifiers, sibling named in the first paragraph). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…in the parity run test_native_startup.py looked for the glue under native-spike/ and skipped when it was missing; a skip fails CI in this repository, so it now asserts the file exists at native/src/main/java. parity_wheel.py names test files on the command line, which bypasses collect_ignore, so it applies the docs-site rule of tests/conftest.py itself. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…on never replays a partly committed block Three Python-only ports from humemai/arcadedb-embedded-python native-preview (#537, #531, #527): - NativeDatabase._exec calls refuse_surplus_positionals (already shared with the JVM build, PR #52): more positional values than the SQL text can hold is a TypeError, not a silently dropped value. - The native RID class offers the Java RID surface (ordering, getBucketId, getPosition, toString, isValid, equals, compareTo) and Result.get_rid() reads a projected @Rid. - run_in_transaction: the guard that refuses to replay a block whose BATCH boundary or commit() already made part of its work durable sat inside a try whose own except swallowed the raise. The raise moves outside it. New test tests/test_run_in_transaction_partial_commit.py runs on both builds. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ver from failure text Port of humemai/arcadedb-embedded-python#535, adapted to this repository's conftest. The native build used to turn a failing test into an NA-JVM or NOTYET skip when its failure text matched a list of strings ("JVMNotRunning", "assert (None is not None)", "KeyError: 'flush'"), which is also what a real bug looks like. Now: - NATIVE_NA_JVM_TESTS is keyed <file>::[<Class>::]<test> and lists only tests that reach into the JVM on purpose, with the reason. Rows were added for the tests this repository has that the upstream table did not know (temporal writers, XML limits, to_java_rid, db._java_db patching). - pytest_runtest_makereport reports NOTYET only for NotOnNativeYet, raised by the native code. - to_java_int_array and to_java_byte_array return NumPy arrays on the native build, so the sparse vector tests no longer import jpype.types. - tests/README.md says how a test may be skipped on the native build. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ert_many into a vertex type creates vertices (P-01b) Port of humemai/arcadedb-embedded-python#538. gbCreate called GraphBatch.builder(db), which skips the engine's single-batch guard, so two concurrent batches on one database lost edges. It now calls db.batch(), as the JPype path does. insert_parallel looked at no schema and always called newDocument, which the JVM build refuses for a vertex type; it now looks the type up once per call: a vertex type gets vertices, an edge type is refused. Tests: TestInsertManyVertexType, the second-batch refusal and the two-writers-one-hub test (the last two run on both builds). Needs a rebuilt native library. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… on an engine without the where option
- create_vector_index takes rerank_oversample and fused_pq (CREATE INDEX .. METADATA
rerankOversample / fusedPQ) and get_metadata reports them.
- insert_columns: only a float32 matrix is a column of vectors (float64 and N x 0 are refused with
the one-dimensional ValueError), and the non-fast and parallel paths accept the float32 matrix.
A float64 NumPy array in a row of insert_many is the list it would have been, not a float[].
- import_documents takes disable_xml_limits. The glue lifts the three jdk.xml limits around that
one load and restores them; the XMLMessages bundle goes into the image so that an entity-limit
error names JAXP0001000x instead of "Could not load any resource bundle". New
tests/test_native_xml_limits.py (native build only).
- example 29: the where form is asserted refused ("Unknown option 'where'") on an engine that
predates 26.11.1, like has_pq_rerank does for the PQ settings.
The XML limit and bundle changes need a rebuilt native library.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…, like the final job arcadedb now has one PyPI trusted publisher (native.yml with the environment pypi) for dev, final and post releases. The environment pypi-prerelease is gone (deleted on GitHub), and the workflow header and docs/modules/ROOT/pages/development/release.adoc say so. The readiness gate (ARCADEDB_NATIVE_READINESS_BAR_MET and the full matrix for a final or post release) is unchanged. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…m, test-native, release-native) The workflow files now follow one scheme: - test-python-bindings.yml -> test-jvm.yml (the job names `Test arcadedb (<platform>, Python <v>)` do not change) - release.yml -> release-jvm.yml (publishes arcadedb-jvm through the environment pypi-jvm) - native.yml -> test-native.yml (native build and parity on pull requests that touch native paths, on main and nightly; it never publishes) - release-native.yml (new): on a version tag it validates the tag, calls test-native.yml with `release: true` (4 platforms x Python 3.11 to 3.14), applies the readiness gate ARCADEDB_NATIVE_READINESS_BAR_MET, and publishes arcadedb through the environment pypi in one job for dev, final and post - test-python-examples.yml stays The trusted publishers on PyPI are keyed on the release file names: arcadedb-jvm <- release-jvm.yml / pypi-jvm, arcadedb <- release-native.yml / pypi. select_native_matrix.py: the `tag` event is now `release` and the `publish` output is gone (publishing is decided in release-native.yml). select_matrix.py: the `bindings` workflow key is now `jvm`. Paths filters, the actionlint config, the tests that read workflow files, README badges (JVM and native), CLAUDE.md and the CI and Release docs follow. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…the nosec B608 marker applies Bandit reports B608 on the line of the f-string, and the marker sat on a later line. The statement is now one line with its marker; the interpolated value is a RID created by the test. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… working directory The native library opened ./log/arcadedb.log in the current working directory. The loader now creates the log directory (ARCADEDB_LOG_DIR, else the state directory, like the JVM build), writes logging.properties there and passes arcadedb.server.logsDirectory and java.util.logging.config.file as isolate arguments, which are in place before the engine's first log call. A user's own isolate argument wins. The log-directory logic moves from jvm.py to _logdir.py so both builds share it. Tests: the subprocess tests of test_log_dir.py run on both builds, test_native_log_dir.py covers the isolate-argument paths, and a JVM-side test compares the native copy of the engine's log settings with the engine jar. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…, and the async writer crash Python functions (register_function with replace, deterministic and inferred argument counts, unregister_function) and record events (Database.on) run on the native backend through the existing Java-to-Python upcall. The engine side is a new entry point, arcadedb_n_cb, whose checks, wording, veto and failure rules are those of the JPype bridge. A record argument or event record reaches Python as a Document, Vertex or Edge wrapper. A KeyboardInterrupt in a callback, or one that arrives as the callback is entered, aborts the statement and reaches the caller as a KeyboardInterrupt chained from the ArcadeDBError. A Java thread that runs a Python callback (an async writer) is attached to the isolate already; the thread handle for it is no longer an owned one that detaches the thread when the callback's Python thread state ends. That detach aborted the process in tests/test_async_executor.py (a callback that calls the database from a writer thread). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A callback on a Java thread (an async writer) ends its Python thread state when it returns, and the thread-local buffer that held the reply went with it: the engine read freed memory ("bad JSON value at 0" for a Python function called from an async command). The reply is now allocated by the library (arcadedb_n_alloc), and Java copies the text and frees it.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…loaded record reports only its identity save() of a new record whose before_create callback vetoed it returns the unsaved record, as on the JPype backend, instead of raising "the statement returned no record". The after_delete event of a record that was not loaded (a delete by RID) found no record to read the properties from and failed the delete; it sends the identity only now (Java change, in the next native image). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…urn value A Ctrl-C raised as Python enters the callback (before its try) left the C return value unset, and the engine took whatever the return register held: the pointer of an earlier reply that Java had freed already. Java then freed it again and the process aborted in free(). The callback is void now and writes its reply to a slot that Java zeroes before the call, so a callback that ends early leaves NULL; the failed statement becomes a KeyboardInterrupt. Python writes only library memory into the slot (the fallback to a Python-owned buffer is gone), and the unraisablehook is not used. A test runs the SIGINT loop in a fresh process and fails on a nonzero exit. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
tae898
marked this pull request as ready for review
October 25, 2026 12:22
…to the Windows child test_wheel_packages builds with setup.py build_py; the uv parity env had no setuptools, so the test failed on windows-x64 and macos-arm64 and passed on Linux only because the runner's Python ships it (humemai/arcadedb-embedded-python#539). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lls the default handler NativeDatabase.on() took the @Property line of schema with it when register_function was replaced; db.schema was a bound method again. The fresh-process SIGINT test sets the default Ctrl-C handler in the child: a parent started as a background job ignores SIGINT, and Python then installs no handler. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… (3.11, 3.13, 3.14, 3.14t) select_native_matrix.py prints a pyver list: the supported Pythons the full parity run of the event leaves out, plus the free-threaded 3.14t. The new pyver job of test-native.yml installs the already built linux-x86_64 wheel (py3-none, no rebuild) into each and runs 13 test files (14 where polars installs) through native/wheel/parity_wheel.py --files, with the same gate as the test job. The job is informational: release-native.yml reads only the native-passed-* markers and the native-wheel-* wheels, so a red pyver leg never blocks a release (a test pins that). 3.14t runs without polars, which has no free-threaded wheel, and so without test_dataframe_ingest.py. A step reports whether the GIL stays off. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nsaction runs its block; the module docstring says what is true VectorIndex.get_stats reads the schema:index:<bucket> row (the counters, not the row's own columns). get_metadata and get_quantization ask the engine through one new glue entry point (arcadedb_n_vindex, op metadata), so an index this session did not create reports the same keys as on the JVM build, defaults included. find_nearest_approximate runs the engine's PQ search through the same entry point (op approximate): no statement runs it. warm_up runs the first search that loads a persisted graph. AsyncExecutor.transaction is a new op of arcadedb_n_async: the engine begins the transaction on a writer thread, Python runs the block in the upcall, and a Python exception is thrown on the Java side so the writer reports it. The block runs in the upcall of #67, and a Python exception comes back through its out slot as {"error": ...}, which the Java side throws so the writer rolls back and reports it. Tests first, shared by both builds: tests/test_vector_index_introspection.py and tests/test_async_transaction.py (18 tests on the JVM build, 17 of 18 on native, see the PR). The two get_java_* calls stay JVM-only and are documented as such. The module docstring of _native/__init__.py listed far more as missing than is true. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…cutor has finished its work AsyncExecutor.transaction registers up to three callbacks per call (block, ok, error). They are kept in the executor's _cb_ids (declared, never used so far) and forgotten when wait_completion has returned or the executor is closed, because a retry calls the block again. The other async operations still register callbacks that are never released; that is unchanged. The reply of a failing block needs nothing new here: with #67 it is written into the out slot as library memory, which outlives the Python thread state of an async writer, so the Java side reads {"error": ...} and the writer rolls back and reaches the error callback. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…, as on the JVM build The base added these two keys to the JVM get_metadata when the engine has them (hasattr). The image links engine 26.10.2, which has not, so the native dict carries them only when the glue reports them; the shared test accepts them as optional. The glue reports them with the move to 26.11.1. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…st names the arcadedb_jvm wheel auditwheel wraps 'is consistent with the following platform tag' across lines, so the native image gate failed on a good wheel. test_build_wheel_check still wrote an arcadedb-<v> wheel after the JVM dist became arcadedb-jvm, so build.sh's check found none (3 failures on every JVM leg). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tches via db.batch(), parallel insert_many into a vertex type creates vertices) Commit 99a9dc2 was meant to port humemai/arcadedb-embedded-python#538, and its tests came across, but its NativeExtras.java change is the XML-limits helper (loadWithoutXmlLimits) and nothing else: the two hunks of #538 never reached the native glue, so the native build still failed 5 tests (test_insert_many_parallel and test_insert_columns_parallel: "Cannot create a document of type 'Vtx' because is not a document type"; test_graph_batch_close_refused_in_the_callers_transaction_can_be_retried and test_a_second_graph_batch_is_refused_while_one_is_open: DID NOT RAISE; test_two_concurrent_batches_on_one_hub_lose_no_edge: "Slot rebase not possible" on close). P-04 (data loss): arcadedb_n_gb_create built its GraphBatch with GraphBatch.builder(db), which takes no part in LocalDatabase.batchStarted. It now opens the batch with db.batch(), as the JPype path does, so build() takes the guard and close() gives it back. The Python API is unchanged. P-01b: the async insert_parallel helper called newDocument for every row. It now looks the type up once per call (the rule of humemai #519 / DocumentBatcher): a vertex type gets newVertex, a document type newDocument, an edge type is refused with a message naming it. Needs a rebuilt native library. Checked on a fresh image built from this tree (native/scripts/build-image.sh, engine 26.10.2): test_bulk_insert.py and test_graph_batch.py 87 passed, 4 skipped (all NA-JVM), test_core.py 39 passed, test_concurrency.py 5 passed. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This was referenced Oct 25, 2026
…s (no JSON text) Port of humemai/arcadedb-embedded-python#514 onto the P-04 port fix. - arcadedb_n_insert_colp: the image reads whole columns in place (int64, float64, bool, int32, float32, UTF-8 strings as Arrow offsets plus bytes, float32 vector matrices, an Arrow validity bitmap per column), no JSON text and no per-value crossing. - _native/columnar.py lays the columns out (numpy, lists of one value type with None as null, lists of float32 arrays, pyarrow arrays); _native/bulk.py sends them; insert_many chunks and the DataFrame/Arrow document load use the entry when every column maps to a supported kind, any other batch keeps the JSON path. - Only a float32 matrix (or a list of float32 arrays) is a column of vectors, as on the JPype path (tests/test_float_vector_bulk.py); #514 took any float matrix. The pack test says so. - New tests: test_native_columnar_pack.py (no native library needed, runs on both backends) and test_native_columnar_insert.py (compares the stored records of the JSON and the columnar entry points, native backend only, collect_ignore otherwise). - The two new test files use plain imports of numpy, pandas and pyarrow, not importorskip (the repo's no-skips policy). Needs a rebuilt native library (BulkOps.java, ArcadeNative.java). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Native glue: apply the P-04 and P-01b hunks that 99a9dc2 dropped
Native: Python functions in SQL and openCypher, record events, Ctrl-C, and the async writer crash
Native: get_stats, get_metadata, PQ search and AsyncExecutor.transaction work; the NotOnNativeYet docs say what is true
Native: write the engine log to the per-user log directory, never the working directory
…) into native-ci-python-versions Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…umnar-port Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…through the Python API The 31 NOTYET skips of the native parity run were calls that are JVM-only by design (get_java_database, a Java object a Schema method returns) reached by shared tests, so a final release (--max-notyet 0) would have been blocked. Raise site: needs_jvm() replaces not_yet() for those calls; the message says the call needs the JVM build (arcadedb-jvm) instead of "not yet". not_yet() stays for a real gap. Tests: the ones whose purpose is the Java object (the bridge's float-vector decision, the plain JPype path, a Java RID set, the deprecated Java newLightEdge, metadata fields only the Java index metadata carries) get NA-JVM rows. The ones that used the Java object only to read a value now read it through VectorIndex.get_metadata() (test_create_index_with_rich_metadata_sql, test_sql_metadata_gives_the_helper_defaults, the hierarchy and quantization part of test_add_hierarchy_defaults_differ_between_sql_and_python, both product quantization metadata tests), and scalar and lone-null binding get shared round-trip tests beside the NA-JVM comparisons with the plain path. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…k-format database.py The fused PQ build test still read the Java field (.fusedPQ) from the dict that _metadata() returns now, which failed on the JVM build. black re-wraps the import line that needs_jvm lengthened. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Native: columnar bulk insert by address for strings, nulls and vectors (no JSON text)
A bare isort run (no --profile black) had re-wrapped the importer import; only the needs_jvm changes remain in the file's diff. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Native CI: a cheap Python-version job (3.11, 3.13, 3.14, 3.14t) on the built wheel
Native tests: no NOTYET left (NA-JVM or read through the Python API)
GraalVM's default heap limit is 80% of the memory the isolate sees (the container limit when there is one). With the engine's off-heap memory on top, the kernel killed the process in memory-limited containers. The glue now passes -XX:MaximumHeapSizePercent=50 as an isolate argument unless ARCADEDB_NATIVE_ISOLATE_ARGS already has -Xmx, -XX:MaximumHeapSizePercent or -XX:MaxRAM (theirs wins). The isolate arguments are now always non-empty (the log directory is always set), so the dead "if iso_args:" branch is gone. Tests: the default and the override rules, and on the real image the default max_heap is about half of the memory and a user percent, -Xmx or -XX:MaxRAM replaces it. Docs: a heap-size section in the installation page. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Native: start the isolate with -XX:MaximumHeapSizePercent=50 by default
…_batch and create_vertices A pre-registered laptop A/B on the columnar native wheel (1M documents through insert_many, 200k vertices and 500k edges through GraphBatch) found 1000-row transactions faster (wall 0.822-0.831 and 0.853-0.864 of the old default) and lighter on the young GC. The native defaults become insert_many commit_every 1000 (was 10,000), graph_batch commit_every 1000 (was unset) and a create_vertices chunk equal to the batch's commit_every (was 10,000). An explicit value wins. The JVM defaults are unchanged and pinned by a source-level test. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Native build: commit every 1000 rows by default in insert_many, graph_batch and create_vertices
This was referenced Oct 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Makes the repository build two distributions that both import as
arcadedb, as decided for 26.11.1 (tracker #19):arcadedbis the native build (a GraalVM native-image shared library loaded with ctypes) andarcadedb-jvmis the JVM build this repository builds today.arcadedb-nativestays a dependency-only alias for later. Draft: nothing is merged or published by this PR.What is in it (one commit per phase)
arcadedb-jvm: pyproject name,release-jvm.yml(environmentpypi-jvm, name guard, wheel-count checks,check_version.py --pypi arcadedb-jvm),after_tag_verify.sh, wheel globs (arcadedb_jvm-*.whl), thepip install '...[extra]'hints, install lines. The import name staysarcadedb.arcadedb.__backend__('jvm'or'native') and a hard import guard: each distribution raisesDistributionConflictError(anImportError) when the other one is installed. The message names both packages, says how to fix it and links the Which package? page. This replaces the old warning. Tests intests/test_dist_conflict.py, including a fresh interpreter with a fake siblingdist-info.native/(Java glue, Maven wrapper,scripts/build-image.sh),native/wheel/(build_wheel.pybuilds thearcadedbwheel,py3-none-<platform>;gen_notices.pychecksTHIRD_PARTY_NOTICES.mdagainst what is compiled in;parity_wheel.pyruns this repository's tests against the installed wheel),src/arcadedb/_native/plus the hooks incore.py,server.py,vector.py,dataframe.py,exporter.py,exceptions.py, and the native tests with the repository's collect-ignore rule (NATIVE_NOT_APPLICABLE, native-only files not collected on the JVM build). Noarcadedb_embeddednames anywhere (scripts/check_no_embedded_name.pypasses). GraalVM Community Edition only, pinned by sha256 per platform..github/workflows/test-native.yml,.github/workflows/release-native.ymlandscripts/select_native_matrix.py(legs pinned bytests/test_select_native_matrix.py).test-native.ymlbuilds the wheels and runs the parity suite and never publishes. A pull request runs it only when a native path changed, not for a draft, on linux-x86_64 and Python 3.12. Push to main (native paths), nightly (only when something besides docs changed in 25 hours, a full run on Mondays) and dispatch run all four platforms on Python 3.12 and 3.14.release-native.ymlruns on a version tag, callstest-native.ymlwithrelease: true(all four platforms on Python 3.11 to 3.14), applies the readiness gate and publishes. The JVM workflows ignorenative/**and the two native workflow files.docs/modules/ROOT/pages/which-package.adoc, replacespackages.adoc), the CI and release pages. Transition-only callouts carry aREMOVE WHENcomment.Source of the port
Ported from
humemai/arcadedb-embedded-pythonbranchnative-previewat91a6ad719b0308c8ccbf569bf130412619292925, as it is, not from main. The open native-preview PRs #514 and #520 to #538 are not merged there and are not in this port; each has to be ported separately after it merges (#527, #535, #537 and #538 are on the readiness bar).Workflow files and release rules
One test and one release workflow per build:
test-jvm.ymlandrelease-jvm.ymlforarcadedb-jvm,test-native.ymlandrelease-native.ymlforarcadedb;test-python-examples.ymlstays. Both release workflows start on the same bare-version tag. The check namesTest arcadedb (<platform>, Python <v>)did not change.A.B.C.devNpublishesarcadedbthrough the environmentpypi(the same one as final releases) when linux-x86_64, linux-aarch64 and macos-arm64 passed on Python 3.11 to 3.14. Windows is published too when it passed, and is informational otherwise.A.B.CandA.B.C.postNpublish to the environmentpypionly when the repository variableARCADEDB_NATIVE_READINESS_BAR_METistrue, all four platforms passed on all four Pythons, and no test is a NOTYET skip. Speed parity is not part of the bar. Until then the first finalarcadedbwaits andarcadedb-jvm26.11.1 ships alone.arcadedb-jvm<-release-jvm.yml/ environmentpypi-jvmandarcadedb<-release-native.yml/ environmentpypi, and the repository variable. One environment per package:pypi-jvmandpypiboth exist already;pypi-prereleasewas dropped to keep it simple.Verified locally (linux-x86_64, Python 3.12)
-march=compatibility, image generation 2 min 33 s on 8 cores.-J-Xmx8gran out of memory in the builder; 12g (what CI uses) works.arcadedb-26.11.1.dev0-py3-none-manylinux_2_34_x86_64.whl,arcadedb_jvm-26.11.1.dev0-cp312-cp312-manylinux_2_34_x86_64.whl) and installed in fresh uv environments:__backend__isnativeandjvm. With both installed,import arcadedbraisesDistributionConflictErrorwith the full message, in either install order.native-preview, so the native path has no hook for them yet: positional-count (test_positional_count, 9), Python callbacks andregister_function(replace=)(test_python_callbacks, 31,test_python_function_interrupt, 1), RID values (test_record_id_values, 3), the new product-quantization settings (test_vector_product_quantization, 3), parallel bulk insert (test_bulk_insert, 2,test_float_vector_bulk, 3), log directory (test_log_dir, 5),test_example29_hybrid_memory(2),test_xml_limits(1), and a crash intest_async_executor. The docs-site test (7) is ignored by the parity runner now. The native CI leg will therefore be red until these are ported; this is the work between this PR and a nativearcadedbrelease.🤖 Generated with Claude Code