Repository: mesonbuild/meson

Issue:
0.60 fails to build GNOME components
Using the new meson 0.60, either from upstream or Debian, GNOME components started to fail to build

Example of the eog snap build
https://launchpadlibrarian.net/565502418/buildlog_snap_ubuntu_focal_amd64_eog_BUILDING.txt.gz
```
Configuring org.gnome.eog.desktop.in using configuration

../src/data/meson.build:25:5: ERROR: Function does not take positional arguments.
```

Trying to build the current eog deb in Ubuntu with the new meson 0.60 deb from Debian unstable leads to a similar error


Discussion:
The function call that causes the error  is `i18n.merge_file` because it's called with a positional argument. You can see an example on Nautilus (which also fails): https://gitlab.gnome.org/GNOME/nautilus/-/blob/7b469dfa/data/meson.build#L23

However, according to the [docs](https://mesonbuild.com/Reference-manual_functions.html#arguments13):
> This posarg is optional since 0.60.0. It defaults to the basename of the first output.

So this should be allowed. The problem might have been introduced in commit  https://github.com/mesonbuild/meson/commit/6b1a80024c79876dc3b75f2b525be24ca8fe671a
This actually changed in 61f2866a9fa1824298bbafca8ddaaba4b169852d.

And the docs that are relevant here are https://mesonbuild.com/i18n-module.html#i18nmerge_file

> This merges translations into a text file using msgfmt. See custom_tgt for normal keywords. In addition it accepts these keywords:

It doesn't accept the positional arguments of custom_target, only the keyword arguments. However, that did not used to be type-checked, so before 0.60 if you passed a positional argument to merge_file() it would be totally ignored, but not raise an error.
Thanks for your response! 🙂 So if I understand correctly, this argument was being silently ignored on older versions of Meson and should be removed on Gnome's side?

Maybe the `merge_file` docs should be updated to mention it *only* accepts the keyword arguments from `custom_target`, at least for me with the current wording this isn't obvious.
Could the error be turned into a warning at least for a transition period to let upstreams fix their build and get new releases out?
> Maybe the `merge_file` docs should be updated to mention it _only_ accepts the keyword arguments from `custom_target`, at least for me with the current wording this isn't obvious.

We have some very nice, modern templating for the reference manual that automatically provides function signatures with typed descriptions. Sadly, it isn't wired up to the modules documentation... Even so, anywhere else that positional arguments are accepted and used, they are mentioned, and here, their intentional absence/omission is the clue.



> Could the error be turned into a warning at least for a transition period to let upstreams fix their build and get new releases out?

As I mentioned in IRC, it's very hard to know exactly which things every project out there is doing that ***violates the documentation***, and hence is directly relying on our buggy implementation. We did publish release candidates, and ask people to use them.
We should turn it into a deprecation warning for 0.60.1 and keep it removed in master. Does it break many GNOME projects? I guess it's the kind of mistake that got copy pasted everywhere?

Resolving patch:
diff --git a/mesonbuild/modules/i18n.py b/mesonbuild/modules/i18n.py
--- a/mesonbuild/modules/i18n.py
+++ b/mesonbuild/modules/i18n.py
@@ -22,7 +22,7 @@
 from .. import mlog
 from ..interpreter.type_checking import CT_BUILD_BY_DEFAULT, CT_INPUT_KW, CT_INSTALL_DIR_KW, CT_INSTALL_TAG_KW, CT_OUTPUT_KW, INSTALL_KW, NoneType, in_set_validator
 from ..interpreterbase import FeatureNew
-from ..interpreterbase.decorators import ContainerTypeInfo, KwargInfo, noPosargs, typed_kwargs, typed_pos_args
+from ..interpreterbase.decorators import ContainerTypeInfo, KwargInfo, typed_kwargs, typed_pos_args
 from ..scripts.gettext import read_linguas
 
 if T.TYPE_CHECKING:
@@ -128,7 +128,6 @@ def _get_data_dirs(state: 'ModuleState', dirs: T.Iterable[str]) -> T.List[str]:
         return [path.join(src_dir, d) for d in dirs]
 
     @FeatureNew('i18n.merge_file', '0.37.0')
-    @noPosargs
     @typed_kwargs(
         'i18n.merge_file',
         CT_BUILD_BY_DEFAULT,
@@ -143,6 +142,9 @@ def _get_data_dirs(state: 'ModuleState', dirs: T.Iterable[str]) -> T.List[str]:
         KwargInfo('type', str, default='xml', validator=in_set_validator({'xml', 'desktop'})),
     )
     def merge_file(self, state: 'ModuleState', args: T.List['TYPE_var'], kwargs: 'MergeFile') -> ModuleReturnValue:
+        if args:
+            mlog.deprecation('i18n.merge_file does not take any positional arguments. '
+                             'This will become a hard error in the next Meson release.')
         if not shutil.which('xgettext'):
             self.nogettext_warning()
             return ModuleReturnValue(None, [])


Test patch: