bug-gnulib@gnu.org mirror (unofficial)
 help / color / mirror / Atom feed
From: Bruno Haible <bruno@clisp.org>
To: bug-gnulib@gnu.org
Subject: gnulib-tool.py: Stop using codecs.open
Date: Sat, 13 Apr 2024 13:08:44 +0200	[thread overview]
Message-ID: <8622726.dhtptGC4xO@nimes> (raw)

It seems that codecs.open is frowned upon, nowadays [1],
and that the Python 3 way of opening a file is a built-in function 'open' [2].

Let's use this consistently. With newline='\n' in order to match what
gnulib-tool.sh does.

Specifying encoding='utf-8' is what makes the most sense today. If a package
still has a configure.ac or Makefile.am in ISO-8859-1 encoding, this will
probably fail. Let's see if people report a problem with this; it should be
very rare.

[1] https://stackoverflow.com/questions/5250744/difference-between-open-and-codecs-open-in-python
[2] https://docs.python.org/3/library/functions.html#open


2024-04-13  Bruno Haible  <bruno@clisp.org>

	gnulib-tool.py: Stop using codecs.open.
	* pygnulib/*.py: To open a file, consistently use
	open(..., mode='[rwa]', newline='\n', encoding='utf-8').

diff --git a/gnulib-tool.py.TODO b/gnulib-tool.py.TODO
index 1eada15429..160f7b7465 100644
--- a/gnulib-tool.py.TODO
+++ b/gnulib-tool.py.TODO
@@ -10,9 +10,5 @@ Optimize:
 
 Various other refactorings, as deemed useful:
   - Use an enum for 'all', 'old', 'new', 'added', 'removed' in GLImport.py.
-  - go through all the open() and codecs.open() calls and turn them into
-        with open(file_name, 'r', newline='\n', encoding='utf-8') as file:
-    or
-        with open(file_name, 'w', newline='\n', encoding='utf-8') as file:
 
 ================================================================================
diff --git a/pygnulib/GLEmiter.py b/pygnulib/GLEmiter.py
index ad164515dc..6edad6619e 100644
--- a/pygnulib/GLEmiter.py
+++ b/pygnulib/GLEmiter.py
@@ -20,7 +20,6 @@ from __future__ import annotations
 #===============================================================================
 import os
 import re
-import codecs
 import subprocess as sp
 from collections.abc import Callable
 from . import constants
@@ -895,7 +894,7 @@ AC_DEFUN([%V1%_LIBSOURCES], [
             if makefile_name:
                 path = joinpath(sourcebase, 'Makefile.am')
                 if isfile(path):
-                    with codecs.open(path, 'rb', 'UTF-8') as file:
+                    with open(path, mode='r', newline='\n', encoding='utf-8') as file:
                         data = file.read()
                     if pattern.findall(data):
                         lib_gets_installed = True
diff --git a/pygnulib/GLFileSystem.py b/pygnulib/GLFileSystem.py
index 6c40586574..ee78181d82 100644
--- a/pygnulib/GLFileSystem.py
+++ b/pygnulib/GLFileSystem.py
@@ -354,10 +354,10 @@ class GLFileAssistant:
                     transformer = sed_transform_testsrelated_lib_file
             if transformer != None:
                 # Read the file that we looked up.
-                with open(lookedup, 'r', newline='\n', encoding='utf-8') as file:
+                with open(lookedup, mode='r', newline='\n', encoding='utf-8') as file:
                     src_data = file.read()
                 # Write the transformed data to the temporary file.
-                with open(tmpfile, 'w', newline='\n', encoding='utf-8') as file:
+                with open(tmpfile, mode='w', newline='\n', encoding='utf-8') as file:
                     file.write(re.sub(transformer[0], transformer[1], src_data))
         path = joinpath(self.config['destdir'], rewritten)
         if isfile(path):
diff --git a/pygnulib/GLImport.py b/pygnulib/GLImport.py
index 3d694a7919..02a49f8512 100644
--- a/pygnulib/GLImport.py
+++ b/pygnulib/GLImport.py
@@ -20,7 +20,6 @@ from __future__ import annotations
 #===============================================================================
 import os
 import re
-import codecs
 import subprocess as sp
 from . import constants
 from .GLError import GLError
@@ -97,7 +96,7 @@ class GLImport:
         os.rmdir(self.cache['tempdir'])
 
         # Read configure.{ac,in}.
-        with codecs.open(self.config.getAutoconfFile(), 'rb', 'UTF-8') as file:
+        with open(self.config.getAutoconfFile(), mode='r', newline='\n', encoding='utf-8') as file:
             data = file.read()
 
         # Get cached auxdir and libtool from configure.{ac,in}.
@@ -127,7 +126,7 @@ class GLImport:
         # Get other cached variables.
         path = joinpath(self.config['m4base'], 'gnulib-cache.m4')
         if isfile(path):
-            with codecs.open(path, 'rb', 'UTF-8') as file:
+            with open(path, mode='r', newline='\n', encoding='utf-8') as file:
                 data = file.read()
 
             # gl_LGPL is special, because it can occur with or without
@@ -221,7 +220,7 @@ class GLImport:
             destdir, m4base = self.config.getDestDir(), self.config.getM4Base()
             path = joinpath(destdir, m4base, 'gnulib-comp.m4')
             if isfile(path):
-                with codecs.open(path, 'rb', 'UTF-8') as file:
+                with open(path, mode='r', newline='\n', encoding='utf-8') as file:
                     data = file.read()
                 regex = r'AC_DEFUN\(\[%s_FILE_LIST\], \[(.*?)\]\)' % self.cache['macro_prefix']
                 pattern = re.compile(regex, re.S | re.M)
@@ -274,7 +273,7 @@ class GLImport:
         if self.config['automake_subdir'] or self.config['automake_subdir_tests']:
             found_subdir_objects = False
             if self.config['destdir']:
-                with open(self.config['configure_ac'], encoding='utf-8') as file:
+                with open(self.config['configure_ac'], mode='r', newline='\n', encoding='utf-8') as file:
                     data = file.read()
                 pattern = re.compile(r'^.*AM_INIT_AUTOMAKE\([\[ ]*([^])]*).*$', re.MULTILINE)
                 configure_ac_automake_options = pattern.findall(data)
@@ -289,7 +288,7 @@ class GLImport:
                 else:
                     base = '.'
                 if isfile(joinpath(base, 'Makefile.am')):
-                    with open(joinpath(base, 'Makefile.am'), encoding='utf-8') as file:
+                    with open(joinpath(base, 'Makefile.am'), mode='r', newline='\n', encoding='utf-8') as file:
                         data = file.read()
                     pattern = re.compile(r'^AUTOMAKE_OPTIONS[\t ]*=(.*)$', re.MULTILINE)
                     automake_options = pattern.findall(data)
@@ -772,7 +771,7 @@ AC_DEFUN([%s_FILE_LIST], [\n''' % macro_prefix
         backupname = '%s~' % srcpath
         if isfile(joinpath(destdir, srcpath)):
             if files_added or files_removed:
-                with codecs.open(joinpath(destdir, srcpath), 'rb', 'UTF-8') as file:
+                with open(joinpath(destdir, srcpath), mode='r', newline='\n', encoding='utf-8') as file:
                     original_lines = file.readlines()
                 # Clean the newlines but not trailing whitespace.
                 original_lines = [ line.rstrip('\n')
@@ -796,7 +795,7 @@ AC_DEFUN([%s_FILE_LIST], [\n''' % macro_prefix
                         new_lines = [ line
                                       for line in new_lines
                                       if line not in lines_to_remove ]
-                        with codecs.open(joinpath(destdir, srcpath), 'wb', 'UTF-8') as file:
+                        with open(joinpath(destdir, srcpath), mode='w', newline='\n', encoding='utf-8') as file:
                             file.write(lines_to_multiline(new_lines))
                     else:  # if self.config['dryrun']
                         print('Update %s (backup in %s)' % (srcpath, backupname))
@@ -810,7 +809,7 @@ AC_DEFUN([%s_FILE_LIST], [\n''' % macro_prefix
                     if ignore == '.cvsignore':
                         # Automake generates Makefile rules that create .dirstamp files.
                         files_added = ['.deps', '.dirstamp'] + files_added
-                    with codecs.open(joinpath(destdir, srcpath), 'wb', 'UTF-8') as file:
+                    with open(joinpath(destdir, srcpath), mode='w', newline='\n', encoding='utf-8') as file:
                         file.write(lines_to_multiline(files_added))
                 else:  # if self.config['dryrun']
                     print('Create %s' % srcpath)
@@ -1160,7 +1159,7 @@ AC_DEFUN([%s_FILE_LIST], [\n''' % macro_prefix
             basename = joinpath(pobase, 'Makevars')
             tmpfile = self.assistant.tmpfilename(basename)
             emit = self.emitter.po_Makevars()
-            with codecs.open(tmpfile, 'wb', 'UTF-8') as file:
+            with open(tmpfile, mode='w', newline='\n', encoding='utf-8') as file:
                 file.write(emit)
             filename, backup, flag = self.assistant.super_update(basename, tmpfile)
             if flag == 1:
@@ -1180,7 +1179,7 @@ AC_DEFUN([%s_FILE_LIST], [\n''' % macro_prefix
             # Create po makefile parameterization, part 2.
             basename = joinpath(pobase, 'POTFILES.in')
             tmpfile = self.assistant.tmpfilename(basename)
-            with codecs.open(tmpfile, 'wb', 'UTF-8') as file:
+            with open(tmpfile, mode='w', newline='\n', encoding='utf-8') as file:
                 file.write(self.emitter.po_POTFILES_in(filetable['all']))
             basename = joinpath(pobase, 'POTFILES.in')
             filename, backup, flag = self.assistant.super_update(basename, tmpfile)
@@ -1219,7 +1218,7 @@ AC_DEFUN([%s_FILE_LIST], [\n''' % macro_prefix
                                  for file in os.listdir(joinpath(destdir, pobase))
                                  if file.endswith('.po') ])
                 data += lines_to_multiline(files)
-                with codecs.open(tmpfile, 'wb', 'UTF-8') as file:
+                with open(tmpfile, mode='w', newline='\n', encoding='utf-8') as file:
                     file.write(data)
                 filename, backup, flag = self.assistant.super_update(basename, tmpfile)
                 if flag == 1:
@@ -1240,7 +1239,7 @@ AC_DEFUN([%s_FILE_LIST], [\n''' % macro_prefix
         basename = joinpath(m4base, 'gnulib-cache.m4')
         tmpfile = self.assistant.tmpfilename(basename)
         emit = self.gnulib_cache()
-        with codecs.open(tmpfile, 'wb', 'UTF-8') as file:
+        with open(tmpfile, mode='w', newline='\n', encoding='utf-8') as file:
             file.write(emit)
         filename, backup, flag = self.assistant.super_update(basename, tmpfile)
         if flag == 1:
@@ -1265,7 +1264,7 @@ AC_DEFUN([%s_FILE_LIST], [\n''' % macro_prefix
         basename = joinpath(m4base, 'gnulib-comp.m4')
         tmpfile = self.assistant.tmpfilename(basename)
         emit = self.gnulib_comp(filetable, gentests)
-        with codecs.open(tmpfile, 'wb', 'UTF-8') as file:
+        with open(tmpfile, mode='w', newline='\n', encoding='utf-8') as file:
             file.write(emit)
         filename, backup, flag = self.assistant.super_update(basename, tmpfile)
         if flag == 1:
@@ -1298,7 +1297,7 @@ AC_DEFUN([%s_FILE_LIST], [\n''' % macro_prefix
             emit = sp.run([joinpath(DIRS['root'], 'build-aux/prefix-gnulib-mk'), '--from-gnulib-tool',
                            f'--lib-name={libname}', f'--prefix={sourcebase}/'],
                           input=emit, text=True, capture_output=True).stdout
-        with codecs.open(tmpfile, 'wb', 'UTF-8') as file:
+        with open(tmpfile, mode='w', newline='\n', encoding='utf-8') as file:
             file.write(emit)
         filename, backup, flag = self.assistant.super_update(basename, tmpfile)
         if flag == 1:
@@ -1322,7 +1321,7 @@ AC_DEFUN([%s_FILE_LIST], [\n''' % macro_prefix
             emit = self.emitter.tests_Makefile_am(basename, self.moduletable.getTestsModules(),
                                                   self.moduletable, self.makefiletable,
                                                   '%stests_WITNESS' % macro_prefix, for_test)
-            with codecs.open(tmpfile, 'wb', 'UTF-8') as file:
+            with open(tmpfile, mode='w', newline='\n', encoding='utf-8') as file:
                 file.write(emit)
             filename, backup, flag = self.assistant.super_update(basename, tmpfile)
             if flag == 1:
@@ -1450,7 +1449,7 @@ in <library>_a_LDFLAGS or <library>_la_LDFLAGS when linking a library.''')
                           % (dictionary['val'], dictionary['var'], joinpath(dictionary['dir'], 'Makefile.am')))
 
         # Detect position_early_after.
-        with codecs.open(configure_ac, 'rb', 'UTF-8') as file:
+        with open(configure_ac, mode='r', newline='\n', encoding='utf-8') as file:
             data = file.read()
         match_result1 = \
             bool(re.compile(r'^ *AC_PROG_CC_STDC', re.M).findall(data))
diff --git a/pygnulib/GLInfo.py b/pygnulib/GLInfo.py
index 845ca6d733..716d1ddf0d 100644
--- a/pygnulib/GLInfo.py
+++ b/pygnulib/GLInfo.py
@@ -20,7 +20,6 @@ from __future__ import annotations
 #===============================================================================
 import os
 import re
-import codecs
 import subprocess as sp
 from . import constants
 
@@ -120,7 +119,7 @@ class GLInfo:
                     result = result.rstrip(os.linesep)
                     return result
         # gnulib copy without versioning information.
-        with codecs.open(os.path.join(DIRS['root'], 'ChangeLog'), 'rb', 'UTF-8') as file:
+        with open(os.path.join(DIRS['root'], 'ChangeLog'), mode='r', newline='\n', encoding='utf-8') as file:
             line = file.readline()
             first_changelog_line = line.rstrip()
         result = re.compile(r' .*').sub(r'', first_changelog_line)
diff --git a/pygnulib/GLModuleSystem.py b/pygnulib/GLModuleSystem.py
index 0399a708d0..6639c9a6e8 100644
--- a/pygnulib/GLModuleSystem.py
+++ b/pygnulib/GLModuleSystem.py
@@ -21,7 +21,6 @@ from __future__ import annotations
 import os
 import re
 import sys
-import codecs
 import hashlib
 import subprocess as sp
 from . import constants
@@ -208,7 +207,7 @@ class GLModule:
         self.filesystem = GLFileSystem(self.config)
         self.modulesystem = GLModuleSystem(self.config)
         # Read the module description file into memory.
-        with codecs.open(path, 'rb', 'UTF-8') as file:
+        with open(path, mode='r', newline='\n', encoding='utf-8') as file:
             self.content = file.read().replace('\r\n', '\n')
         # Dissect it into sections.
         self.sections = dict()
diff --git a/pygnulib/GLTestDir.py b/pygnulib/GLTestDir.py
index be61d58b52..dc70e8d304 100644
--- a/pygnulib/GLTestDir.py
+++ b/pygnulib/GLTestDir.py
@@ -21,7 +21,6 @@ from __future__ import annotations
 import os
 import re
 import sys
-import codecs
 import subprocess as sp
 from pathlib import Path
 from . import constants
@@ -391,7 +390,7 @@ class GLTestDir:
         else:  # if not single_configure
             emit = self.emitter.lib_Makefile_am(destfile, modules,
                                                 moduletable, self.makefiletable, '', for_test)
-        with codecs.open(destfile, 'wb', 'UTF-8') as file:
+        with open(destfile, mode='w', newline='\n', encoding='utf-8') as file:
             file.write(emit)
 
         # Create $m4base/Makefile.am.
@@ -406,7 +405,7 @@ class GLTestDir:
                 file = constants.substart('m4/', '', file)
                 emit += 'EXTRA_DIST += %s\n' % file
         emit = constants.nlconvert(emit)
-        with codecs.open(destfile, 'wb', 'UTF-8') as file:
+        with open(destfile, mode='w', newline='\n', encoding='utf-8') as file:
             file.write(emit)
 
         subdirs = [sourcebase, m4base]
@@ -423,7 +422,7 @@ class GLTestDir:
                 witness_macro = '%stests_WITNESS' % macro_prefix
                 emit = self.emitter.tests_Makefile_am(destfile, tests_modules, moduletable,
                                                       self.makefiletable, witness_macro, for_test)
-                with codecs.open(destfile, 'wb', 'UTF-8') as file:
+                with open(destfile, mode='w', newline='\n', encoding='utf-8') as file:
                     file.write(emit)
             else:  # if not single_configure
                 # Create $testsbase/Makefile.am.
@@ -432,7 +431,7 @@ class GLTestDir:
                 self.config.setLibtests(False)
                 emit = self.emitter.tests_Makefile_am(destfile, modules, moduletable,
                                                       self.makefiletable, '', for_test)
-                with codecs.open(destfile, 'wb', 'UTF-8') as file:
+                with open(destfile, mode='w', newline='\n', encoding='utf-8') as file:
                     file.write(emit)
                 # Viewed from the $testsbase subdirectory, $auxdir is different.
                 emit = ''
@@ -525,7 +524,7 @@ class GLTestDir:
                 emit += 'AC_OUTPUT\n'
                 emit = constants.nlconvert(emit)
                 path = joinpath(self.testdir, testsbase, 'configure.ac')
-                with codecs.open(path, 'wb', 'UTF-8') as file:
+                with open(path, mode='w', newline='\n', encoding='utf-8') as file:
                     file.write(emit)
 
                 # Restore changed variables.
@@ -542,7 +541,7 @@ class GLTestDir:
         emit += 'ACLOCAL_AMFLAGS = -I %s\n' % m4base
         emit = constants.nlconvert(emit)
         path = joinpath(self.testdir, 'Makefile.am')
-        with codecs.open(path, 'wb', 'UTF-8') as file:
+        with open(path, mode='w', newline='\n', encoding='utf-8') as file:
             file.write(emit)
 
         # Create configure.ac
@@ -667,7 +666,7 @@ class GLTestDir:
         emit += 'AC_CONFIG_FILES([%s])\n' % ' '.join(makefiles)
         emit += 'AC_OUTPUT\n'
         path = joinpath(self.testdir, 'configure.ac')
-        with codecs.open(path, 'wb', 'UTF-8') as file:
+        with open(path, mode='w', newline='\n', encoding='utf-8') as file:
             file.write(emit)
 
         # Create autogenerated files.
@@ -749,7 +748,7 @@ class GLTestDir:
         # Need to run configure and make once, to create built files that are to be
         # distributed (such as parse-datetime.c).
         path = joinpath(self.testdir, sourcebase, 'Makefile.am')
-        with codecs.open(path, 'rb', 'UTF-8') as file:
+        with open(path, mode='r', newline='\n', encoding='utf-8') as file:
             snippet = file.read()
         snippet = combine_lines(snippet)
 
@@ -794,7 +793,7 @@ class GLTestDir:
         if inctests:
             # Likewise for built files in the $testsbase directory.
             path = joinpath(self.testdir, testsbase, 'Makefile.am')
-            with codecs.open(path, 'rb', 'UTF-8') as file:
+            with open(path, mode='r', newline='\n', encoding='utf-8') as file:
                 snippet = file.read()
             snippet = combine_lines(snippet)
 
@@ -841,7 +840,7 @@ class GLTestDir:
             sp.call('./configure')
             if distributed_built_sources:
                 os.chdir(sourcebase)
-                with codecs.open('Makefile', 'ab', 'UTF-8') as file:
+                with open('Makefile', mode='a', newline='\n', encoding='utf-8') as file:
                     file.write('built_sources: $(BUILT_SOURCES)\n')
                 args = [UTILS['make'],
                         'AUTOCONF=%s' % UTILS['autoconf'],
@@ -854,7 +853,7 @@ class GLTestDir:
                 os.chdir('..')
             if tests_distributed_built_sources:
                 os.chdir(testsbase)
-                with codecs.open('Makefile', 'ab', 'UTF-8') as file:
+                with open('Makefile', mode='a', newline='\n', encoding='utf-8') as file:
                     file.write('built_sources: $(BUILT_SOURCES)\n')
                 args = [UTILS['make'],
                         'AUTOCONF=%s' % UTILS['autoconf'],
@@ -992,7 +991,7 @@ class GLMegaTestDir:
         emit += 'done\n'
         emit = constants.nlconvert(emit)
         path = joinpath(self.megatestdir, 'do-autobuild')
-        with codecs.open(path, 'wb', 'UTF-8') as file:
+        with open(path, mode='w', newline='\n', encoding='utf-8') as file:
             file.write(emit)
 
         # Create Makefile.am.
@@ -1002,7 +1001,7 @@ class GLMegaTestDir:
         emit += 'EXTRA_DIST = do-autobuild\n'
         emit = constants.nlconvert(emit)
         path = joinpath(self.megatestdir, 'Makefile.am')
-        with codecs.open(path, 'wb', 'UTF-8') as file:
+        with open(path, mode='w', newline='\n', encoding='utf-8') as file:
             file.write(emit)
 
         emit = '# Process this file with autoconf '
@@ -1017,7 +1016,7 @@ class GLMegaTestDir:
         emit += 'AC_OUTPUT\n'
         emit = constants.nlconvert(emit)
         path = joinpath(self.megatestdir, 'configure.ac')
-        with codecs.open(path, 'wb', 'UTF-8') as file:
+        with open(path, mode='w', newline='\n', encoding='utf-8') as file:
             file.write(emit)
 
         # Create autogenerated files.
diff --git a/pygnulib/constants.py b/pygnulib/constants.py
index f307ffa6b1..70381164be 100644
--- a/pygnulib/constants.py
+++ b/pygnulib/constants.py
@@ -28,7 +28,6 @@ import stat
 import platform
 import shutil
 import tempfile
-import codecs
 import subprocess as sp
 import __main__ as interpreter
 
@@ -238,7 +237,7 @@ def execute(args: list[str], verbose: int) -> None:
             os.remove(temp)
         else:
             print('executing %s' % ' '.join(args))
-            with codecs.open(temp, 'rb') as file:
+            with open(temp, mode='r', newline='\n', encoding='utf-8') as file:
                 cmdout = file.read()
             print(cmdout)
             os.remove(temp)
diff --git a/pygnulib/main.py b/pygnulib/main.py
index 471f4b9fb9..5875618941 100644
--- a/pygnulib/main.py
+++ b/pygnulib/main.py
@@ -77,7 +77,6 @@ from __future__ import annotations
 import os
 import re
 import sys
-import codecs
 import random
 import argparse
 import subprocess as sp
@@ -923,7 +922,7 @@ def main() -> None:
         config.setAutoconfFile(configure_ac)
 
         # Analyze configure.ac.
-        with open(configure_ac, 'r', encoding='utf-8') as file:
+        with open(configure_ac, mode='r', newline='\n', encoding='utf-8') as file:
             configure_ac_data = file.read()
 
         guessed_m4dirs = []
@@ -989,7 +988,7 @@ def main() -> None:
                 dirisnext = False
                 filepath = joinpath(destdir, 'Makefile.am')
                 if isfile(filepath):
-                    with codecs.open(filepath, 'rb', 'UTF-8') as file:
+                    with open(filepath, mode='r', newline='\n', encoding='utf-8') as file:
                         data = file.read()
                         data = data.split('ACLOCAL_AMFLAGS')[1]
                         data = data[data.find('=') + 1:data.find('\n')]
@@ -1016,7 +1015,7 @@ def main() -> None:
                     filepath = joinpath(destdir, 'aclocal.m4')
                     if isfile(filepath):
                         pattern = re.compile(r'm4_include\(\[(.*?)]\)')
-                        with codecs.open(filepath, 'rb', 'UTF-8') as file:
+                        with open(filepath, mode='r', newline='\n', encoding='utf-8') as file:
                             m4dirs = pattern.findall(file.read())
                         m4dirs = [ os.path.dirname(m4dir)
                                    for m4dir in m4dirs ]
@@ -1421,7 +1420,7 @@ def main_with_exception_handling() -> None:
                     incompatibilities += ' %s' % pair[1]
                     incompatibilities += constants.NL
                 tempname = mktemp()
-                with codecs.open(tempname, 'wb', 'UTF-8') as file:
+                with open(tempname, mode='w', newline='\n', encoding='utf-8') as file:
                     file.write(incompatibilities)
                 sed_table = 's,^\\([^ ]*\\) ,\\1' + ' ' * 51 + ',\n'
                 sed_table += 's,^\\(' + '.' * 49 + '[^ ]*\\) *,' + ' ' * 17 + '\\1 ,'





             reply	other threads:[~2024-04-13 11:09 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-13 11:08 Bruno Haible [this message]
2024-04-14 17:53 ` gnulib-tool.py: Stop using codecs.open Collin Funk
2024-04-14 22:16   ` Bruno Haible
2024-04-14 23:18     ` Collin Funk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://lists.gnu.org/mailman/listinfo/bug-gnulib

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8622726.dhtptGC4xO@nimes \
    --to=bruno@clisp.org \
    --cc=bug-gnulib@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).