Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package tree-sitter for openSUSE:Factory 
checked in at 2026-08-21 16:50:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/tree-sitter (Old)
 and      /work/SRC/openSUSE:Factory/.tree-sitter.new.1258 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "tree-sitter"

Fri Aug 21 16:50:19 2026 rev:28 rq:1372547 version:0.26.8

Changes:
--------
--- /work/SRC/openSUSE:Factory/tree-sitter/tree-sitter.changes  2026-05-17 
18:56:31.111553224 +0200
+++ /work/SRC/openSUSE:Factory/.tree-sitter.new.1258/tree-sitter.changes        
2026-08-21 16:51:07.638284082 +0200
@@ -1,0 +2,50 @@
+Thu Aug 20 13:53:41 UTC 2026 - Martin Pluskal <[email protected]>
+
+- Do not emit treesitter_grammar_src() rpm symbols for relative
+  require() paths (., .., ./, ../). Local relative requires are
+  still followed to find nested external grammar deps. Fixes
+  installcheck on grammars that share a sibling common/
+  directory (nothing provides treesitter_grammar_src(../common)
+  for tree-sitter-php-devel).
+
+-------------------------------------------------------------------
+Thu Aug 20 08:46:22 UTC 2026 - Martin Pluskal <[email protected]>
+
+- Add an opt-in Python binding macro to the grammar framework.
+  Review follow-up: generate a Python loader instead of compiling
+  the upstream C binding, so the parser is not built a second time:
+  * %treesitter_python_install installs upstream's pure-Python
+    bindings/python package files as-is and replaces the compiled
+    _binding extension with a generated _binding.py that loads the
+    grammar library from %{_libdir}/tree-sitter via ctypes and
+    hands its TSLanguage pointer to python-tree-sitter as the
+    "tree_sitter.Language" PyCapsule the Language() constructor
+    expects - no duplicate parser, no compiler, no wheel
+  * New source tree-sitter-python-shim.py.in: the template the
+    generated _binding.py comes from, shipped in %{_rpmconfigdir}
+    so it is versioned and testable instead of inlined in a macro
+  * %treesitter_python_build is a deprecated no-op; consumers no
+    longer need the python devel/pip/wheel/setuptools/installer
+    BuildRequires
+  * The python subpackage pins the grammar package exactly
+    (Requires: %{name} = %{version}-%{release}); library and
+    binding come from the same source package and move in lockstep
+  * %treesitter_python_install also takes an explicit multi-language
+    form, MODNAME GRAMMAR..., for upstream modules that expose
+    several grammars from one python package: each grammar yields a
+    language_<grammar>() function loading its own library, matching
+    the upstream binding of tree-sitter-typescript
+    (language_typescript and language_tsx, no plain language)
+  * Consuming specs still carry the (now much smaller) singlespec
+    template literally: the python-rpm-macros generator re-reads
+    the raw spec text for the %package template, so an %include
+    fragment cannot provide it (the BuildRequires alone could move
+    to a fragment - the OBS scheduler does resolve %include - but
+    splitting one small block across two files is not worth it)
+  * Documented python subpackage dep is Suggests:
+    python-tree-sitter >= 0.22, not Requires -- python-tree-sitter
+    is not in Rings:1-MinimalX, so a hard Requires fails Staging
+    installcheck for ring1 grammars (matching tree-sitter-bash)
+  * No change for grammar packages that do not opt in
+
+-------------------------------------------------------------------

New:
----
  tree-sitter-python-shim.py.in

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ tree-sitter.spec ++++++
--- /var/tmp/diff_new_pack.7s3l1c/_old  2026-08-21 16:51:10.296379544 +0200
+++ /var/tmp/diff_new_pack.7s3l1c/_new  2026-08-21 16:51:10.299379652 +0200
@@ -36,6 +36,7 @@
 Source24:       compile-macros.sh
 Source25:       treesitter_grammar.attr
 Source26:       treesitter_grammar.req
+Source27:       tree-sitter-python-shim.py.in
 BuildRequires:  cargo-packaging
 BuildRequires:  clang
 BuildRequires:  fdupes
@@ -110,6 +111,7 @@
 
 install -Dm644 %{SOURCE25} %{buildroot}%{_fileattrsdir}/$(basename %{SOURCE25})
 install -Dm755 %{SOURCE26} %{buildroot}%{_rpmconfigdir}/$(basename %{SOURCE26})
+install -Dm644 %{SOURCE27} %{buildroot}%{_rpmconfigdir}/$(basename %{SOURCE27})
 
 #remove .a/.la files
 find %{buildroot} -type f \( -name "*.la" -o -name "*.a" \) -delete -print
@@ -147,6 +149,7 @@
 %{_rpmconfigdir}/%{name}-target.py
 %{_rpmmacrodir}/macros.treesitter
 %{_rpmconfigdir}/treesitter_grammar.req
+%{_rpmconfigdir}/tree-sitter-python-shim.py.in
 %{_fileattrsdir}/treesitter_grammar.attr
 %dir %{_emacs_sitelispdir}
 %dir %{_emacs_sitestartdir}

++++++ _scmsync.obsinfo ++++++
--- /var/tmp/diff_new_pack.7s3l1c/_old  2026-08-21 16:51:10.417383890 +0200
+++ /var/tmp/diff_new_pack.7s3l1c/_new  2026-08-21 16:51:10.424384141 +0200
@@ -1,6 +1,6 @@
-mtime: 1778866530
-commit: eb3df7e9d39c71d2c3d1614445eb1122df9567e6663bc2d64646f4566de80bb0
+mtime: 1787235978
+commit: 7b58a6ff7fe22f73f8388cd38d57f1aca71ab17a57f15f00a18d0e8f7add5a8d
 url: https://src.opensuse.org/tree-sitter/tree-sitter
-revision: eb3df7e9d39c71d2c3d1614445eb1122df9567e6663bc2d64646f4566de80bb0
+revision: 7b58a6ff7fe22f73f8388cd38d57f1aca71ab17a57f15f00a18d0e8f7add5a8d
 projectscmsync: https://src.opensuse.org/tree-sitter/_ObsPrj
 

++++++ build.specials.obscpio ++++++

++++++ build.specials.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.gitignore new/.gitignore
--- old/.gitignore      1970-01-01 01:00:00.000000000 +0100
+++ new/.gitignore      2026-08-20 16:26:18.000000000 +0200
@@ -0,0 +1,5 @@
+*.obscpio
+*.osc
+_build.*
+.pbuild
+tree-sitter-*-build/

++++++ macros.in ++++++
--- /var/tmp/diff_new_pack.7s3l1c/_old  2026-08-21 16:51:10.915401776 +0200
+++ /var/tmp/diff_new_pack.7s3l1c/_new  2026-08-21 16:51:10.918401883 +0200
@@ -19,6 +19,123 @@
 %files -n %{__treesitter_devel_package_name} \
 %{treesitter_devel_files}
 
+
+# --[[
+#    Optional Python binding subpackage for grammars whose upstream ships
+#    bindings/python (the tree-sitter org grammars do). Ships the
+#    tree_sitter_<grammar> module for every python flavor (singlespec), for
+#    consumers like graphify that use the grammar from Python via
+#    python3-tree-sitter.
+#
+#    No second copy of the parser is compiled: upstream's pure-Python
+#    package files (__init__.py, __init__.pyi, py.typed, queries) are
+#    installed as-is and the compiled _binding C extension is replaced by a
+#    generated _binding.py (from %%{_treesitter_python_shim_template}) that
+#    ctypes-loads the grammar library this same source package installs
+#    into %%{_treesitter_grammardir} and hands its TSLanguage pointer to
+#    python-tree-sitter as the "tree_sitter.Language" PyCapsule that the
+#    Language() constructor expects. No compiler, no wheel, no abi concerns.
+#
+#    Usage -- the spec MUST carry the BuildRequires AND the singlespec
+#    subpackage template literally. Neither can come from a macro in this
+#    file: the OBS scheduler extracts BuildRequires without
+#    macros.treesitter installed, and the python-rpm-macros generator
+#    re-reads the raw spec text for the %%package template to clone per
+#    flavor.
+#
+#    %%define python_subpackage_only 1
+#    BuildRequires:  fdupes
+#    BuildRequires:  python-rpm-macros
+#    BuildRequires:  %%{python_module base}
+#    # only for the functional test in %%check:
+#    BuildRequires:  %%{python_module tree-sitter}
+#
+#    %%treesitter_grammars %%{_name}
+#    %%python_subpackages
+#
+#    %%package -n python-%%{name}
+#    Summary: Python binding for the %%{name} grammar
+#    Requires: %%{name} = %%{version}-%%{release}
+#    Suggests: python-tree-sitter >= 0.22
+#    %%description -n python-%%{name}
+#    ...
+#
+#    %%files %%{python_files %%{name}}
+#    %%license LICENSE
+#    %%{python_sitearch}/tree_sitter_*
+#
+#    %%install
+#    %%treesitter_install
+#    %%treesitter_python_install
+#
+#    The Requires on the grammar package is exact on purpose: the grammar
+#    library is unversioned and both halves come from the same source
+#    package, so library and binding always move in lockstep.
+#
+#    python-tree-sitter is Suggests, not Requires: it is a separate
+#    package not in Rings:1-MinimalX, and several grammars live in
+#    ring1. A hard Requires fails Staging installcheck (nothing
+#    provides python*-tree-sitter). tree-sitter-bash already uses
+#    Suggests for the same reason.
+# --]]
+
+# Template the generated _binding.py comes from; shipped by tree-sitter
+# next to the other rpm helpers so it is versioned and testable on its own
+# instead of being inlined (and %%-escaped) in a macro body.
+%_treesitter_python_shim_template 
%{_rpmconfigdir}/tree-sitter-python-shim.py.in
+
+# Deprecated no-op: nothing is compiled for the python binding any more.
+# Kept so in-flight grammar branches that still call it in %%build keep
+# building; remove once those branches are refreshed.
+%treesitter_python_build %{nil}
+
+# %%treesitter_python_install [grammarname]
+# %%treesitter_python_install MODNAME GRAMMAR1 GRAMMAR2 ...
+# Installs upstream's bindings/python/tree_sitter_<name> package for every
+# python flavor, dropping binding.c and generating _binding.py from
+# %%{_treesitter_python_shim_template}.
+#
+# Bare or single-argument form: the module tree_sitter_<grammarname>
+# (default: the single grammar declared via %%treesitter_grammars) gets a
+# plain language() function, matching upstream's single-language bindings.
+#
+# Multi-language form, for upstream modules that expose several grammars
+# from one python package (no plain language()): pass the module name and
+# then every grammar; each grammar Gi yields a language_<Gi>() function
+# loading libtree-sitter-<Gi>.so. tree-sitter-typescript is the known case:
+#     %%treesitter_python_install typescript typescript tsx
+# generates language_typescript() and language_tsx() in
+# tree_sitter_typescript, matching its upstream binding exactly.
+# CAUTION: in the multi form the module name does NOT count as a grammar --
+# when the module also exposes its namesake grammar, repeat it (as above).
+# "%%treesitter_python_install typescript tsx" would generate ONLY
+# language_tsx() and the module's own __init__ import would fail.
+%treesitter_python_install() \
+tspy_args="%{?*}" \
+if test -z "${tspy_args}"; then \
+  tspy_args="%{treesitter_grammar_names}" \
+  if test $(echo ${tspy_args} | wc -w) -ne 1; then echo "error: package 
declares multiple grammars (${tspy_args}); call %%treesitter_python_install 
MODNAME GRAMMAR... explicitly (see macros.treesitter)" >&2; exit 1; fi \
+fi \
+set -- ${tspy_args} \
+tspy_grammar="$1" \
+tspy_mod="tree_sitter_$(echo "$1" | tr '-' '_')" \
+if ! test -d "bindings/python/${tspy_mod}"; then echo "error: 
bindings/python/${tspy_mod} not found -- upstream ships no python binding for 
$1" >&2; exit 1; fi \
+sed -e "s|@GRAMMAR@|${tspy_grammar}|g" %{_treesitter_python_shim_template} > 
_tspy_binding.py \
+# NB: no backslash-escaped quotes below -- rpm macro expansion strips the \
+# backslashes and collapses the shell quoting. Python string literals are \
+# single-quoted and docstrings triple-single-quoted so none are needed. \
+if test "$#" -eq 1; then \
+  tspy_und=$(echo "${tspy_grammar}" | tr '-' '_') \
+  { echo '' ; echo '' ; echo 'def language():' ; echo "    '''Return the 
language capsule for tree_sitter.Language().'''" ; echo "    return 
_language('%{_treesitter_grammardir}/%{_treesitter_grammar_base_libname}-${tspy_grammar}.so',
 'tree_sitter_${tspy_und}')" ; } >> _tspy_binding.py \
+else \
+  shift \
+  for tspy_g in "$@"; do \
+    tspy_g_und=$(echo "${tspy_g}" | tr '-' '_') \
+    { echo '' ; echo '' ; echo "def language_${tspy_g_und}():" ; echo "    
'''Return the ${tspy_g} language capsule for tree_sitter.Language().'''" ; echo 
"    return 
_language('%{_treesitter_grammardir}/%{_treesitter_grammar_base_libname}-${tspy_g}.so',
 'tree_sitter_${tspy_g_und}')" ; } >> _tspy_binding.py \
+  done \
+fi \
+%{python_expand install -d %{buildroot}%{$python_sitearch}/${tspy_mod} ; cp 
-pr bindings/python/${tspy_mod}/. %{buildroot}%{$python_sitearch}/${tspy_mod}/ 
; rm -f %{buildroot}%{$python_sitearch}/${tspy_mod}/binding.c ; if test -d 
queries && ! test -d %{buildroot}%{$python_sitearch}/${tspy_mod}/queries; then 
install -d %{buildroot}%{$python_sitearch}/${tspy_mod}/queries ; install -m 
0644 queries/*.scm %{buildroot}%{$python_sitearch}/${tspy_mod}/queries/ ; fi ; 
install -m 0644 _tspy_binding.py 
%{buildroot}%{$python_sitearch}/${tspy_mod}/_binding.py ; %fdupes 
%{buildroot}%{$python_sitearch}}
+
 ### LUA-MACROS ###
 
 

++++++ tree-sitter-python-shim.py.in ++++++
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2026 SUSE LLC
#
# Header template for the pure-Python tree-sitter grammar binding generated
# by %treesitter_python_install (see macros.treesitter). The grammar name
# token in the docstring is substituted at package build time; the
# per-language "def language...()" lines are appended below this header by
# the macro, one per grammar library the module exposes.
#
# This file is generated into MIT-licensed grammar subpackages, so it is
# MIT itself.
#
# Instead of compiling upstream's binding.c (which would link a second copy
# of the parser), load the grammar library packaged by this same source
# package and hand its TSLanguage pointer to python-tree-sitter as the
# PyCapsule named "tree_sitter.Language" that Language() expects.
"""Binding for the @GRAMMAR@ tree-sitter grammar (openSUSE, ctypes-based)."""

import ctypes

# Module-level cache: the TSLanguage pointers handed out below point into
# these mappings. The module stays referenced in sys.modules for the life
# of the interpreter, so no library is ever dlclose()d while capsules
# pointing into it exist.
_libs = {}

# ctypes defaults restype to c_int, which truncates pointers on 64-bit.
# The explicit restypes below are load-bearing; do not remove them.
_PyCapsule_New = ctypes.pythonapi.PyCapsule_New
_PyCapsule_New.restype = ctypes.py_object
_PyCapsule_New.argtypes = (ctypes.c_void_p, ctypes.c_char_p, ctypes.c_void_p)

_CAPSULE_NAME = b"tree_sitter.Language"


def _language(path, symbol):
    lib = _libs.get(path)
    if lib is None:
        lib = _libs[path] = ctypes.CDLL(path)
    fn = getattr(lib, symbol)
    fn.restype = ctypes.c_void_p
    fn.argtypes = ()
    return _PyCapsule_New(fn(), _CAPSULE_NAME, None)

++++++ treesitter_grammar.req ++++++
--- /var/tmp/diff_new_pack.7s3l1c/_old  2026-08-21 16:51:11.030405906 +0200
+++ /var/tmp/diff_new_pack.7s3l1c/_new  2026-08-21 16:51:11.039406229 +0200
@@ -79,9 +79,8 @@
                                 
requiredLvl2.group(1).removeprefix("'").removesuffix("'")
                             requiredLvl2_grp_cleaned = \
                                 
requiredLvl2_grp_cleaned.removeprefix("\"").removesuffix("\"")
-                        if not requiredLvl2_grp_cleaned.split('/')[0] == "..":
-                            # Don't emit dependencies which are local
-                            pass
+                        # Follow local relative requires to find nested
+                        # external deps; emission is filtered below.
                         dummyRequire(requiredLvl2_grp_cleaned, maxDepth - 1)
         except FileNotFoundError:
             pass
@@ -89,8 +88,14 @@
         if maxDepth == 5:
             # In case we immediately fail to open the first grammar source file
             return
-        # We only want to resolve dependencies outside of the package
-        
print(f"{treeSitterGrammarSymbolToken}({Path(requiredFile_fd).parent})")
+        # We only want to resolve dependencies outside of the package.
+        # Never emit a relative-path rpm symbol (., .., ./..., ../...):
+        # those are local fragments, not grammar names. A token such as
+        # ../common produced treesitter_grammar_src(../common).
+        token = str(Path(requiredFile_fd).parent)
+        if token in (".", "..") or token.startswith("../") or 
token.startswith("./"):
+            return
+        print(f"{treeSitterGrammarSymbolToken}({token})")
 
 for line in fileinput.input():
     line = line.rstrip('\n')

Reply via email to