Imported Upstream version 1.7.8 upstream/1.7.8
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 18 Jan 2022 02:15:06 +0000 (11:15 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 18 Jan 2022 02:15:06 +0000 (11:15 +0900)
235 files changed:
NEWS
configure
configure.ac
ltmain.sh
m4/libtool.m4
src/bin/fstarcsort-main.cc
src/bin/fstarcsort.cc
src/bin/fstcompose.cc
src/bin/fstdeterminize-main.cc
src/bin/fstdifference.cc
src/bin/fstdraw-main.cc
src/bin/fstdraw.cc
src/bin/fstequivalent-main.cc
src/bin/fstequivalent.cc
src/bin/fstinfo-main.cc
src/bin/fstinfo.cc
src/bin/fstintersect-main.cc
src/bin/fstintersect.cc
src/bin/fstmap.cc
src/bin/fstprint-main.cc
src/bin/fstproject-main.cc
src/bin/fstproject.cc
src/bin/fstpush-main.cc
src/bin/fstrandgen-main.cc
src/bin/fstrandgen.cc
src/bin/fstrelabel-main.cc
src/bin/fstrelabel.cc
src/bin/fstreplace-main.cc
src/bin/fstreplace.cc
src/bin/fstrmepsilon-main.cc
src/bin/fstrmepsilon.cc
src/bin/fstshortestdistance-main.cc
src/bin/fstshortestdistance.cc
src/bin/fstshortestpath-main.cc
src/bin/fstsymbols-main.cc
src/extensions/compact/Makefile.am
src/extensions/compact/Makefile.in
src/extensions/compact/compact16_unweighted-fst.cc
src/extensions/compact/compact16_unweighted_acceptor-fst.cc
src/extensions/compact/compact16_weighted_string-fst.cc
src/extensions/compact/compact64_unweighted_acceptor-fst.cc
src/extensions/compact/compact64_weighted_string-fst.cc
src/extensions/compact/compact8_unweighted_acceptor-fst.cc
src/extensions/compact/compact8_weighted_string-fst.cc
src/extensions/compress/Makefile.am
src/extensions/compress/Makefile.in
src/extensions/const/Makefile.am
src/extensions/const/Makefile.in
src/extensions/far/Makefile.am
src/extensions/far/Makefile.in
src/extensions/far/far-class.cc
src/extensions/far/farcompilestrings-main.cc
src/extensions/far/farcompilestrings.cc
src/extensions/far/farcreate-main.cc
src/extensions/far/farcreate.cc
src/extensions/far/farequal.cc
src/extensions/far/farextract.cc
src/extensions/far/farinfo.cc
src/extensions/far/farisomorphic-main.cc
src/extensions/far/farisomorphic.cc
src/extensions/far/farprintstrings-main.cc
src/extensions/far/farprintstrings.cc
src/extensions/far/farscript.cc
src/extensions/far/getters.cc
src/extensions/far/strings.cc
src/extensions/linear/Makefile.am
src/extensions/linear/Makefile.in
src/extensions/linear/linear-classifier-fst.cc
src/extensions/linear/linear-tagger-fst.cc
src/extensions/lookahead/Makefile.am
src/extensions/lookahead/Makefile.in
src/extensions/mpdt/Makefile.am
src/extensions/mpdt/Makefile.in
src/extensions/mpdt/mpdtexpand-main.cc
src/extensions/mpdt/mpdtinfo-main.cc
src/extensions/mpdt/mpdtscript.cc
src/extensions/ngram/Makefile.am
src/extensions/ngram/Makefile.in
src/extensions/ngram/bitmap-index.cc
src/extensions/ngram/ngram-fst.cc
src/extensions/ngram/nthbit.cc
src/extensions/pdt/Makefile.am
src/extensions/pdt/Makefile.in
src/extensions/pdt/pdtcompose-main.cc
src/extensions/pdt/pdtexpand-main.cc
src/extensions/pdt/pdtreplace-main.cc
src/extensions/pdt/pdtreplace.cc
src/extensions/pdt/pdtshortestpath-main.cc
src/extensions/python/cintegral_types.pxd
src/extensions/python/cios.pxd
src/extensions/python/cpywrapfst.pxd
src/extensions/python/cutility.pxd
src/extensions/python/pywrapfst.cpp
src/extensions/python/pywrapfst.pxd
src/extensions/python/pywrapfst.pyx
src/extensions/special/Makefile.am
src/extensions/special/Makefile.in
src/extensions/special/phi-fst.cc
src/include/Makefile.am
src/include/Makefile.in
src/include/fst/accumulator.h
src/include/fst/arc-arena.h
src/include/fst/arc-map.h
src/include/fst/bi-table.h
src/include/fst/cache.h
src/include/fst/compact-fst.h
src/include/fst/compat.h
src/include/fst/complement.h
src/include/fst/compose-filter.h
src/include/fst/compose.h
src/include/fst/determinize.h
src/include/fst/dfs-visit.h
src/include/fst/disambiguate.h
src/include/fst/edit-fst.h
src/include/fst/encode.h
src/include/fst/equal.h
src/include/fst/expander-cache.h
src/include/fst/expectation-weight.h
src/include/fst/extensions/far/compile-strings.h
src/include/fst/extensions/far/far-class.h
src/include/fst/extensions/far/far.h
src/include/fst/extensions/far/farscript.h
src/include/fst/extensions/far/getters.h
src/include/fst/extensions/far/print-strings.h
src/include/fst/extensions/far/sttable.h
src/include/fst/extensions/linear/linear-fst-data-builder.h
src/include/fst/extensions/linear/linear-fst.h
src/include/fst/extensions/linear/loglinear-apply.h
src/include/fst/extensions/linear/trie.h
src/include/fst/extensions/mpdt/compose.h
src/include/fst/extensions/mpdt/expand.h
src/include/fst/extensions/mpdt/info.h
src/include/fst/extensions/mpdt/mpdt.h
src/include/fst/extensions/ngram/bitmap-index.h
src/include/fst/extensions/ngram/ngram-fst.h
src/include/fst/extensions/ngram/nthbit.h
src/include/fst/extensions/pdt/compose.h
src/include/fst/extensions/pdt/expand.h
src/include/fst/extensions/pdt/info.h
src/include/fst/extensions/pdt/paren.h
src/include/fst/extensions/pdt/replace.h
src/include/fst/extensions/pdt/reverse.h
src/include/fst/extensions/pdt/shortest-path.h
src/include/fst/extensions/special/phi-fst.h
src/include/fst/extensions/special/rho-fst.h
src/include/fst/extensions/special/sigma-fst.h
src/include/fst/float-weight.h
src/include/fst/fst-decl.h
src/include/fst/fst.h
src/include/fst/heap.h
src/include/fst/invert.h
src/include/fst/isomorphic.h
src/include/fst/label-reachable.h
src/include/fst/lexicographic-weight.h
src/include/fst/lookahead-filter.h
src/include/fst/lookahead-matcher.h
src/include/fst/mapped-file.h
src/include/fst/matcher.h
src/include/fst/memory.h
src/include/fst/pair-weight.h
src/include/fst/power-weight-mappers.h
src/include/fst/power-weight.h
src/include/fst/product-weight.h
src/include/fst/project.h
src/include/fst/properties.h
src/include/fst/prune.h
src/include/fst/push.h
src/include/fst/queue.h
src/include/fst/randequivalent.h
src/include/fst/randgen.h
src/include/fst/register.h
src/include/fst/relabel.h
src/include/fst/replace-util.h
src/include/fst/replace.h
src/include/fst/reverse.h
src/include/fst/rmepsilon.h
src/include/fst/script/arc-class.h
src/include/fst/script/arciterator-class.h
src/include/fst/script/arcsort.h
src/include/fst/script/compile-impl.h
src/include/fst/script/determinize.h
src/include/fst/script/disambiguate.h
src/include/fst/script/draw-impl.h
src/include/fst/script/draw.h
src/include/fst/script/epsnormalize.h
src/include/fst/script/equivalent.h
src/include/fst/script/fstscript-decl.h
src/include/fst/script/fstscript.h
src/include/fst/script/getters.h
src/include/fst/script/isomorphic.h
src/include/fst/script/minimize.h
src/include/fst/script/print-impl.h
src/include/fst/script/prune.h
src/include/fst/script/push.h
src/include/fst/script/replace.h
src/include/fst/script/script-impl.h
src/include/fst/script/shortest-distance.h
src/include/fst/script/shortest-path.h
src/include/fst/script/weight-class.h
src/include/fst/set-weight.h
src/include/fst/shortest-distance.h
src/include/fst/shortest-path.h
src/include/fst/signed-log-weight.h
src/include/fst/sparse-power-weight.h
src/include/fst/state-map.h
src/include/fst/string-weight.h
src/include/fst/string.h
src/include/fst/symbol-table.h
src/include/fst/synchronize.h
src/include/fst/test/algo_test.h
src/include/fst/test/rand-fst.h
src/include/fst/tuple-weight.h
src/include/fst/union-weight.h
src/include/fst/util.h
src/include/fst/vector-fst.h
src/include/fst/visit.h
src/include/fst/weight.h
src/include/fst/windows_defs.inc [new file with mode: 0644]
src/lib/Makefile.am
src/lib/Makefile.in
src/lib/fst.cc
src/lib/mapped-file.cc
src/lib/properties.cc
src/lib/symbol-table.cc
src/script/Makefile.am
src/script/Makefile.in
src/script/arciterator-class.cc
src/script/getters.cc
src/script/project.cc
src/script/prune.cc
src/script/relabel.cc
src/script/shortest-distance.cc
src/script/text-io.cc
src/test/algo_test.cc
src/test/weight_test.cc

diff --git a/NEWS b/NEWS
index 305aa35..6f0ec4a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,8 @@
 OpenFst: Release 1.7
+   * TokenType is now a scoped enum (1.7.8)
+   * pywrapfst is now Python 3-only (1.7.8)
+   * fstproject now has --project_type flag (1.7.8)
+   * BitmapIndex is now 2x faster for Select0/Select1 (1.7.8)
    * Property testing is now thread-safe (1.7.7)
    * Modernizes random generation (1.7.7)
    * Adds MakeArcMapFst (1.7.6)
index 5df6f05..5984619 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for OpenFst 1.7.7.
+# Generated by GNU Autoconf 2.69 for OpenFst 1.7.8.
 #
 # Report bugs to <help@www.openfst.org>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='OpenFst'
 PACKAGE_TARNAME='openfst'
-PACKAGE_VERSION='1.7.7'
-PACKAGE_STRING='OpenFst 1.7.7'
+PACKAGE_VERSION='1.7.8'
+PACKAGE_STRING='OpenFst 1.7.8'
 PACKAGE_BUGREPORT='help@www.openfst.org'
 PACKAGE_URL=''
 
@@ -1398,7 +1398,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures OpenFst 1.7.7 to adapt to many kinds of systems.
+\`configure' configures OpenFst 1.7.8 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1469,7 +1469,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of OpenFst 1.7.7:";;
+     short | recursive ) echo "Configuration of OpenFst 1.7.8:";;
    esac
   cat <<\_ACEOF
 
@@ -1602,7 +1602,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-OpenFst configure 1.7.7
+OpenFst configure 1.7.8
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2043,7 +2043,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by OpenFst $as_me 1.7.7, which was
+It was created by OpenFst $as_me 1.7.8, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2906,7 +2906,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='openfst'
- VERSION='1.7.7'
+ VERSION='1.7.8'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -5940,7 +5940,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-netbsd*)
+netbsd* | netbsdelf*-gnu)
   if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
     lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
   else
@@ -6302,7 +6302,7 @@ esac
 fi
 
 : ${AR=ar}
-: ${AR_FLAGS=cru}
+: ${AR_FLAGS=cr}
 
 
 
@@ -6803,11 +6803,8 @@ _LT_EOF
   test $ac_status = 0; }; then
     # Now try to grab the symbols.
     nlist=conftest.nm
-    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
-  (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && test -s "$nlist"; then
+    $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5
+    if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then
       # Try sorting and uniquifying the output.
       if sort "$nlist" | uniq > "$nlist"T; then
        mv -f "$nlist"T "$nlist"
@@ -8026,8 +8023,8 @@ int forced_loaded() { return 2;}
 _LT_EOF
       echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
       $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
-      echo "$AR cru libconftest.a conftest.o" >&5
-      $AR cru libconftest.a conftest.o 2>&5
+      echo "$AR cr libconftest.a conftest.o" >&5
+      $AR cr libconftest.a conftest.o 2>&5
       echo "$RANLIB libconftest.a" >&5
       $RANLIB libconftest.a 2>&5
       cat > conftest.c << _LT_EOF
@@ -9137,6 +9134,12 @@ lt_prog_compiler_static=
        lt_prog_compiler_pic='-KPIC'
        lt_prog_compiler_static='-static'
         ;;
+      # flang / f18. f95 an alias for gfortran or flang on Debian
+      flang* | f18* | f95*)
+       lt_prog_compiler_wl='-Wl,'
+       lt_prog_compiler_pic='-fPIC'
+       lt_prog_compiler_static='-static'
+        ;;
       # icc used to be incompatible with GCC.
       # ICC 10 doesn't accept -KPIC any more.
       icc* | ifort*)
@@ -9613,6 +9616,9 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
   openbsd* | bitrig*)
     with_gnu_ld=no
     ;;
+  linux* | k*bsd*-gnu | gnu*)
+    link_all_deplibs=no
+    ;;
   esac
 
   ld_shlibs=yes
@@ -9867,7 +9873,7 @@ _LT_EOF
       fi
       ;;
 
-    netbsd*)
+    netbsd* | netbsdelf*-gnu)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
        archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
        wlarc=
@@ -10537,6 +10543,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
        if test yes = "$lt_cv_irix_exported_symbol"; then
           archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
        fi
+       link_all_deplibs=no
       else
        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
        archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
@@ -10558,7 +10565,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
       esac
       ;;
 
-    netbsd*)
+    netbsd* | netbsdelf*-gnu)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
        archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
       else
   dynamic_linker='GNU/Linux ld.so'
   ;;
 
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
 netbsd*)
   version_type=sunos
   need_lib_prefix=no
@@ -13063,7 +13082,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
       # Commands to make compiler produce verbose output that lists
       # what "hidden" libraries, object files and flags are used when
       # linking a shared library.
-      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
 
     else
       GXX=no
@@ -13555,7 +13574,7 @@ fi
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
           *)
             if test yes = "$GXX"; then
@@ -13620,7 +13639,7 @@ fi
            # explicitly linking system object files so we need to strip them
            # from the output so that they don't get included in the library
            # dependencies.
-           output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+           output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
            ;;
           *)
            if test yes = "$GXX"; then
@@ -13959,7 +13978,7 @@ fi
              # Commands to make compiler produce verbose output that lists
              # what "hidden" libraries, object files and flags are used when
              # linking a shared library.
-             output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+             output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
 
            else
              # FIXME: insert proper C++ library support
@@ -14043,7 +14062,7 @@ fi
                # Commands to make compiler produce verbose output that lists
                # what "hidden" libraries, object files and flags are used when
                # linking a shared library.
-               output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+               output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
              else
                # g++ 2.7 appears to require '-G' NOT '-shared' on this
                # platform.
@@ -14054,7 +14073,7 @@ fi
                # Commands to make compiler produce verbose output that lists
                # what "hidden" libraries, object files and flags are used when
                # linking a shared library.
-               output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+               output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
              fi
 
              hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir'
@@ -14567,7 +14586,7 @@ lt_prog_compiler_static_CXX=
            ;;
        esac
        ;;
-      netbsd*)
+      netbsd* | netbsdelf*-gnu)
        ;;
       *qnx* | *nto*)
         # QNX uses GNU C++, but need to define -shared option too, otherwise
@@ -14942,6 +14961,9 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
       ;;
     esac
     ;;
+  linux* | k*bsd*-gnu | gnu*)
+    link_all_deplibs_CXX=no
+    ;;
   *)
     export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
     ;;
   dynamic_linker='GNU/Linux ld.so'
   ;;
 
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
 netbsd*)
   version_type=sunos
   need_lib_prefix=no
@@ -17550,7 +17584,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by OpenFst $as_me 1.7.7, which was
+This file was extended by OpenFst $as_me 1.7.8, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -17616,7 +17650,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-OpenFst config.status 1.7.7
+OpenFst config.status 1.7.8
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -18853,7 +18887,6 @@ See \`config.log' for more details" "$LINENO" 5; }
     cat <<_LT_EOF >> "$cfgfile"
 #! $SHELL
 # Generated automatically by $as_me ($PACKAGE) $VERSION
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
 # NOTE: Changes made to this file will be lost: look at ltmain.sh.
 
 # Provide generalized library-building support services.
index d52ed02..8e544b7 100644 (file)
@@ -1,4 +1,4 @@
-AC_INIT([OpenFst], [1.7.7], [help@www.openfst.org])
+AC_INIT([OpenFst], [1.7.8], [help@www.openfst.org])
 AM_INIT_AUTOMAKE([foreign nostdinc -Wall -Werror subdir-objects])
 AM_PROG_AR
 
index b6f1800..0cb7f90 100644 (file)
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -31,7 +31,7 @@
 
 PROGRAM=libtool
 PACKAGE=libtool
-VERSION=2.4.6
+VERSION="2.4.6 Debian-2.4.6-14"
 package_revision=2.4.6
 
 
@@ -387,7 +387,7 @@ EXIT_SKIP=77          # $? = 77 is used to indicate a skipped test to automake.
 # putting '$debug_cmd' at the start of all your functions, you can get
 # bash to show function call trace with:
 #
-#    debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
+#    debug_cmd='echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
 debug_cmd=${debug_cmd-":"}
 exit_cmd=:
 
@@ -1370,7 +1370,7 @@ func_lt_ver ()
 #! /bin/sh
 
 # Set a version string for this script.
-scriptversion=2014-01-07.03; # UTC
+scriptversion=2015-10-07.11; # UTC
 
 # A portable, pluggable option parser for Bourne shell.
 # Written by Gary V. Vaughan, 2010
@@ -1530,6 +1530,8 @@ func_run_hooks ()
 {
     $debug_cmd
 
+    _G_rc_run_hooks=false
+
     case " $hookable_fns " in
       *" $1 "*) ;;
       *) func_fatal_error "'$1' does not support hook funcions.n" ;;
@@ -1538,16 +1540,16 @@ func_run_hooks ()
     eval _G_hook_fns=\$$1_hooks; shift
 
     for _G_hook in $_G_hook_fns; do
-      eval $_G_hook '"$@"'
-
-      # store returned options list back into positional
-      # parameters for next 'cmd' execution.
-      eval _G_hook_result=\$${_G_hook}_result
-      eval set dummy "$_G_hook_result"; shift
+      if eval $_G_hook '"$@"'; then
+        # store returned options list back into positional
+        # parameters for next 'cmd' execution.
+        eval _G_hook_result=\$${_G_hook}_result
+        eval set dummy "$_G_hook_result"; shift
+        _G_rc_run_hooks=:
+      fi
     done
 
-    func_quote_for_eval ${1+"$@"}
-    func_run_hooks_result=$func_quote_for_eval_result
+    $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result
 }
 
 
@@ -1557,10 +1559,16 @@ func_run_hooks ()
 ## --------------- ##
 
 # In order to add your own option parsing hooks, you must accept the
-# full positional parameter list in your hook function, remove any
-# options that you action, and then pass back the remaining unprocessed
+# full positional parameter list in your hook function, you may remove/edit
+# any options that you action, and then pass back the remaining unprocessed
 # options in '<hooked_function_name>_result', escaped suitably for
-# 'eval'.  Like this:
+# 'eval'.  In this case you also must return $EXIT_SUCCESS to let the
+# hook's caller know that it should pay attention to
+# '<hooked_function_name>_result'.  Returning $EXIT_FAILURE signalizes that
+# arguments are left untouched by the hook and therefore caller will ignore the
+# result variable.
+#
+# Like this:
 #
 #    my_options_prep ()
 #    {
@@ -1570,9 +1578,11 @@ func_run_hooks ()
 #        usage_message=$usage_message'
 #      -s, --silent       don'\''t print informational messages
 #    '
-#
-#        func_quote_for_eval ${1+"$@"}
-#        my_options_prep_result=$func_quote_for_eval_result
+#        # No change in '$@' (ignored completely by this hook).  There is
+#        # no need to do the equivalent (but slower) action:
+#        # func_quote_for_eval ${1+"$@"}
+#        # my_options_prep_result=$func_quote_for_eval_result
+#        false
 #    }
 #    func_add_hook func_options_prep my_options_prep
 #
@@ -1581,25 +1591,37 @@ func_run_hooks ()
 #    {
 #        $debug_cmd
 #
+#        args_changed=false
+#
 #        # Note that for efficiency, we parse as many options as we can
 #        # recognise in a loop before passing the remainder back to the
 #        # caller on the first unrecognised argument we encounter.
 #        while test $# -gt 0; do
 #          opt=$1; shift
 #          case $opt in
-#            --silent|-s) opt_silent=: ;;
+#            --silent|-s) opt_silent=:
+#                         args_changed=:
+#                         ;;
 #            # Separate non-argument short options:
 #            -s*)         func_split_short_opt "$_G_opt"
 #                         set dummy "$func_split_short_opt_name" \
 #                             "-$func_split_short_opt_arg" ${1+"$@"}
 #                         shift
+#                         args_changed=:
 #                         ;;
-#            *)            set dummy "$_G_opt" "$*"; shift; break ;;
+#            *)           # Make sure the first unrecognised option "$_G_opt"
+#                         # is added back to "$@", we could need that later
+#                         # if $args_changed is true.
+#                         set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
 #          esac
 #        done
 #
-#        func_quote_for_eval ${1+"$@"}
-#        my_silent_option_result=$func_quote_for_eval_result
+#        if $args_changed; then
+#          func_quote_for_eval ${1+"$@"}
+#          my_silent_option_result=$func_quote_for_eval_result
+#        fi
+#
+#        $args_changed
 #    }
 #    func_add_hook func_parse_options my_silent_option
 #
@@ -1611,16 +1633,32 @@ func_run_hooks ()
 #        $opt_silent && $opt_verbose && func_fatal_help "\
 #    '--silent' and '--verbose' options are mutually exclusive."
 #
-#        func_quote_for_eval ${1+"$@"}
-#        my_option_validation_result=$func_quote_for_eval_result
+#        false
 #    }
 #    func_add_hook func_validate_options my_option_validation
 #
-# You'll alse need to manually amend $usage_message to reflect the extra
+# You'll also need to manually amend $usage_message to reflect the extra
 # options you parse.  It's preferable to append if you can, so that
 # multiple option parsing hooks can be added safely.
 
 
+# func_options_finish [ARG]...
+# ----------------------------
+# Finishing the option parse loop (call 'func_options' hooks ATM).
+func_options_finish ()
+{
+    $debug_cmd
+
+    _G_func_options_finish_exit=false
+    if func_run_hooks func_options ${1+"$@"}; then
+      func_options_finish_result=$func_run_hooks_result
+      _G_func_options_finish_exit=:
+    fi
+
+    $_G_func_options_finish_exit
+}
+
+
 # func_options [ARG]...
 # ---------------------
 # All the functions called inside func_options are hookable. See the
@@ -1630,17 +1668,28 @@ func_options ()
 {
     $debug_cmd
 
-    func_options_prep ${1+"$@"}
-    eval func_parse_options \
-        ${func_options_prep_result+"$func_options_prep_result"}
-    eval func_validate_options \
-        ${func_parse_options_result+"$func_parse_options_result"}
+    _G_rc_options=false
 
-    eval func_run_hooks func_options \
-        ${func_validate_options_result+"$func_validate_options_result"}
+    for my_func in options_prep parse_options validate_options options_finish
+    do
+      if eval func_$my_func '${1+"$@"}'; then
+        eval _G_res_var='$'"func_${my_func}_result"
+        eval set dummy "$_G_res_var" ; shift
+        _G_rc_options=:
+      fi
+    done
+
+    # Save modified positional parameters for caller.  As a top-level
+    # options-parser function we always need to set the 'func_options_result'
+    # variable (regardless the $_G_rc_options value).
+    if $_G_rc_options; then
+      func_options_result=$_G_res_var
+    else
+      func_quote_for_eval ${1+"$@"}
+      func_options_result=$func_quote_for_eval_result
+    fi
 
-    # save modified positional parameters for caller
-    func_options_result=$func_run_hooks_result
+    $_G_rc_options
 }
 
 
@@ -1649,9 +1698,9 @@ func_options ()
 # All initialisations required before starting the option parse loop.
 # Note that when calling hook functions, we pass through the list of
 # positional parameters.  If a hook function modifies that list, and
-# needs to propogate that back to rest of this script, then the complete
+# needs to propagate that back to rest of this script, then the complete
 # modified list must be put in 'func_run_hooks_result' before
-# returning.
+# returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned).
 func_hookable func_options_prep
 func_options_prep ()
 {
@@ -1661,10 +1710,14 @@ func_options_prep ()
     opt_verbose=false
     opt_warning_types=
 
-    func_run_hooks func_options_prep ${1+"$@"}
+    _G_rc_options_prep=false
+    if func_run_hooks func_options_prep ${1+"$@"}; then
+      _G_rc_options_prep=:
+      # save modified positional parameters for caller
+      func_options_prep_result=$func_run_hooks_result
+    fi
 
-    # save modified positional parameters for caller
-    func_options_prep_result=$func_run_hooks_result
+    $_G_rc_options_prep
 }
 
 
@@ -1678,18 +1731,20 @@ func_parse_options ()
 
     func_parse_options_result=
 
+    _G_rc_parse_options=false
     # this just eases exit handling
     while test $# -gt 0; do
       # Defer to hook functions for initial option parsing, so they
       # get priority in the event of reusing an option name.
-      func_run_hooks func_parse_options ${1+"$@"}
-
-      # Adjust func_parse_options positional parameters to match
-      eval set dummy "$func_run_hooks_result"; shift
+      if func_run_hooks func_parse_options ${1+"$@"}; then
+        eval set dummy "$func_run_hooks_result"; shift
+        _G_rc_parse_options=:
+      fi
 
       # Break out of the loop if we already parsed every option.
       test $# -gt 0 || break
 
+      _G_match_parse_options=:
       _G_opt=$1
       shift
       case $_G_opt in
@@ -1704,7 +1759,10 @@ func_parse_options ()
                      ;;
 
         --warnings|--warning|-W)
-                      test $# = 0 && func_missing_arg $_G_opt && break
+                      if test $# = 0 && func_missing_arg $_G_opt; then
+                        _G_rc_parse_options=:
+                        break
+                      fi
                       case " $warning_categories $1" in
                         *" $1 "*)
                           # trailing space prevents matching last $1 above
@@ -1757,15 +1815,25 @@ func_parse_options ()
                       shift
                       ;;
 
-        --)           break ;;
+        --)           _G_rc_parse_options=: ; break ;;
         -*)           func_fatal_help "unrecognised option: '$_G_opt'" ;;
-        *)            set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+        *)            set dummy "$_G_opt" ${1+"$@"}; shift
+                      _G_match_parse_options=false
+                      break
+                      ;;
       esac
+
+      $_G_match_parse_options && _G_rc_parse_options=:
     done
 
-    # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    func_parse_options_result=$func_quote_for_eval_result
+
+    if $_G_rc_parse_options; then
+      # save modified positional parameters for caller
+      func_quote_for_eval ${1+"$@"}
+      func_parse_options_result=$func_quote_for_eval_result
+    fi
+
+    $_G_rc_parse_options
 }
 
 
@@ -1778,16 +1846,21 @@ func_validate_options ()
 {
     $debug_cmd
 
+    _G_rc_validate_options=false
+
     # Display all warnings if -W was not given.
     test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
 
-    func_run_hooks func_validate_options ${1+"$@"}
+    if func_run_hooks func_validate_options ${1+"$@"}; then
+      # save modified positional parameters for caller
+      func_validate_options_result=$func_run_hooks_result
+      _G_rc_validate_options=:
+    fi
 
     # Bail if the options were screwed!
     $exit_cmd $EXIT_FAILURE
 
-    # save modified positional parameters for caller
-    func_validate_options_result=$func_run_hooks_result
+    $_G_rc_validate_options
 }
 
 
@@ -2068,12 +2141,12 @@ include the following information:
        compiler:       $LTCC
        compiler flags: $LTCFLAGS
        linker:         $LD (gnu? $with_gnu_ld)
-       version:        $progname (GNU libtool) 2.4.6
+       version:        $progname $scriptversion Debian-2.4.6-14
        automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
        autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
 
 Report bugs to <bug-libtool@gnu.org>.
-GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+GNU libtool home page: <http://www.gnu.org/s/libtool/>.
 General help using GNU software: <http://www.gnu.org/gethelp/>."
     exit 0
 }
@@ -2270,6 +2343,8 @@ libtool_options_prep ()
     nonopt=
     preserve_args=
 
+    _G_rc_lt_options_prep=:
+
     # Shorthand for --mode=foo, only valid as the first argument
     case $1 in
     clean|clea|cle|cl)
@@ -2293,11 +2368,18 @@ libtool_options_prep ()
     uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
       shift; set dummy --mode uninstall ${1+"$@"}; shift
       ;;
+    *)
+      _G_rc_lt_options_prep=false
+      ;;
     esac
 
-    # Pass back the list of options.
-    func_quote_for_eval ${1+"$@"}
-    libtool_options_prep_result=$func_quote_for_eval_result
+    if $_G_rc_lt_options_prep; then
+      # Pass back the list of options.
+      func_quote_for_eval ${1+"$@"}
+      libtool_options_prep_result=$func_quote_for_eval_result
+    fi
+
+    $_G_rc_lt_options_prep
 }
 func_add_hook func_options_prep libtool_options_prep
 
@@ -2309,9 +2391,12 @@ libtool_parse_options ()
 {
     $debug_cmd
 
+    _G_rc_lt_parse_options=false
+
     # Perform our own loop to consume as many options as possible in
     # each iteration.
     while test $# -gt 0; do
+      _G_match_lt_parse_options=:
       _G_opt=$1
       shift
       case $_G_opt in
@@ -2386,15 +2471,22 @@ libtool_parse_options ()
                         func_append preserve_args " $_G_opt"
                         ;;
 
-       # An option not handled by this hook function:
-        *)             set dummy "$_G_opt" ${1+"$@"};  shift; break  ;;
+        # An option not handled by this hook function:
+        *)              set dummy "$_G_opt" ${1+"$@"} ; shift
+                        _G_match_lt_parse_options=false
+                        break
+                        ;;
       esac
+      $_G_match_lt_parse_options && _G_rc_lt_parse_options=:
     done
 
+    if $_G_rc_lt_parse_options; then
+      # save modified positional parameters for caller
+      func_quote_for_eval ${1+"$@"}
+      libtool_parse_options_result=$func_quote_for_eval_result
+    fi
 
-    # save modified positional parameters for caller
-    func_quote_for_eval ${1+"$@"}
-    libtool_parse_options_result=$func_quote_for_eval_result
+    $_G_rc_lt_parse_options
 }
 func_add_hook func_parse_options libtool_parse_options
 
@@ -7220,11 +7312,6 @@ func_mode_link ()
        arg=$func_stripname_result
        ;;
 
-      -Wl,--as-needed)
-       deplibs="$deplibs $arg"
-       continue
-       ;;
-
       -Wl,*)
        func_stripname '-Wl,' '' "$arg"
        args=$func_stripname_result
@@ -7277,10 +7364,16 @@ func_mode_link ()
       # -tp=*                Portland pgcc target processor selection
       # --sysroot=*          for sysroot support
       # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+      # -specs=*             GCC specs files
       # -stdlib=*            select c++ std lib with clang
+      # -fsanitize=*         Clang/GCC memory and address sanitizer
+      # -fuse-ld=*           Linker select flags for GCC
+      # -static-*            direct GCC to link specific libraries statically
+      # -fcilkplus           Cilk Plus language extension features for C/C++
       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
       -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
-      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*)
+      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
+      -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus)
         func_quote_for_eval "$arg"
        arg=$func_quote_for_eval_result
         func_append compile_command " $arg"
@@ -7529,7 +7622,6 @@ func_mode_link ()
 
     case $linkmode in
     lib)
-       as_needed_flag=
        passes="conv dlpreopen link"
        for file in $dlfiles $dlprefiles; do
          case $file in
@@ -7541,7 +7633,6 @@ func_mode_link ()
        done
        ;;
     prog)
-       as_needed_flag=
        compile_deplibs=
        finalize_deplibs=
        alldeplibs=false
@@ -7575,7 +7666,10 @@ func_mode_link ()
        case $pass in
        dlopen) libs=$dlfiles ;;
        dlpreopen) libs=$dlprefiles ;;
-       link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+       link)
+         libs="$deplibs %DEPLIBS%"
+         test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
+         ;;
        esac
       fi
       if test lib,dlpreopen = "$linkmode,$pass"; then
@@ -7611,15 +7705,6 @@ func_mode_link ()
        lib=
        found=false
        case $deplib in
-       -Wl,--as-needed)
-         if test prog,link = "$linkmode,$pass" ||
-            test lib,link = "$linkmode,$pass"; then
-           as_needed_flag="$deplib "
-         else
-           deplibs="$deplib $deplibs"
-         fi
-         continue
-         ;;
        -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
         |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
          if test prog,link = "$linkmode,$pass"; then
@@ -7903,19 +7988,19 @@ func_mode_link ()
            # It is a libtool convenience library, so add in its objects.
            func_append convenience " $ladir/$objdir/$old_library"
            func_append old_convenience " $ladir/$objdir/$old_library"
+           tmp_libs=
+           for deplib in $dependency_libs; do
+             deplibs="$deplib $deplibs"
+             if $opt_preserve_dup_deps; then
+               case "$tmp_libs " in
+               *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+               esac
+             fi
+             func_append tmp_libs " $deplib"
+           done
          elif test prog != "$linkmode" && test lib != "$linkmode"; then
            func_fatal_error "'$lib' is not a convenience library"
          fi
-         tmp_libs=
-         for deplib in $dependency_libs; do
-           deplibs="$deplib $deplibs"
-           if $opt_preserve_dup_deps; then
-             case "$tmp_libs " in
-             *" $deplib "*) func_append specialdeplibs " $deplib" ;;
-             esac
-           fi
-           func_append tmp_libs " $deplib"
-         done
          continue
        fi # $pass = conv
 
@@ -8839,6 +8924,9 @@ func_mode_link ()
            revision=$number_minor
            lt_irix_increment=no
            ;;
+         *)
+           func_fatal_configuration "$modename: unknown library version type '$version_type'"
+           ;;
          esac
          ;;
        no)
@@ -10037,13 +10125,6 @@ EOF
          test "X$libobjs" = "X " && libobjs=
        fi
 
-       # A bit hacky. I had wanted to add \$as_needed_flag to archive_cmds instead, but that
-       # comes from libtool.m4 which is part of the project being built. This should put it
-       # in the right place though.
-       if test lib,link = "$linkmode,$pass" && test -n "$as_needed_flag"; then
-         libobjs=$as_needed_flag$libobjs
-       fi
-
        save_ifs=$IFS; IFS='~'
        for cmd in $cmds; do
          IFS=$sp$nl
@@ -10276,8 +10357,8 @@ EOF
       compile_deplibs=$new_libs
 
 
-      func_append compile_command " $as_needed_flag $compile_deplibs"
-      func_append finalize_command " $as_needed_flag $finalize_deplibs"
+      func_append compile_command " $compile_deplibs"
+      func_append finalize_command " $finalize_deplibs"
 
       if test -n "$rpath$xrpath"; then
        # If the user specified any rpath flags, then add them.
index a3bc337..a6d21ae 100644 (file)
@@ -728,7 +728,6 @@ _LT_CONFIG_SAVE_COMMANDS([
     cat <<_LT_EOF >> "$cfgfile"
 #! $SHELL
 # Generated automatically by $as_me ($PACKAGE) $VERSION
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
 # NOTE: Changes made to this file will be lost: look at ltmain.sh.
 
 # Provide generalized library-building support services.
@@ -1042,8 +1041,8 @@ int forced_loaded() { return 2;}
 _LT_EOF
       echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
       $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
-      echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
-      $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+      echo "$AR cr libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+      $AR cr libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
       echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
       $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
       cat > conftest.c << _LT_EOF
@@ -1493,7 +1492,7 @@ need_locks=$enable_libtool_lock
 m4_defun([_LT_PROG_AR],
 [AC_CHECK_TOOLS(AR, [ar], false)
 : ${AR=ar}
-: ${AR_FLAGS=cru}
+: ${AR_FLAGS=cr}
 _LT_DECL([], [AR], [1], [The archiver])
 _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
 
@@ -2887,6 +2886,18 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   dynamic_linker='GNU/Linux ld.so'
   ;;
 
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
 netbsd*)
   version_type=sunos
   need_lib_prefix=no
@@ -3546,7 +3557,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-netbsd*)
+netbsd* | netbsdelf*-gnu)
   if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
     lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
   else
@@ -4052,7 +4063,8 @@ _LT_EOF
   if AC_TRY_EVAL(ac_compile); then
     # Now try to grab the symbols.
     nlist=conftest.nm
-    if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+    $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD
+    if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then
       # Try sorting and uniquifying the output.
       if sort "$nlist" | uniq > "$nlist"T; then
        mv -f "$nlist"T "$nlist"
@@ -4424,7 +4436,7 @@ m4_if([$1], [CXX], [
            ;;
        esac
        ;;
-      netbsd*)
+      netbsd* | netbsdelf*-gnu)
        ;;
       *qnx* | *nto*)
         # QNX uses GNU C++, but need to define -shared option too, otherwise
@@ -4692,6 +4704,12 @@ m4_if([$1], [CXX], [
        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
        _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
         ;;
+      # flang / f18. f95 an alias for gfortran or flang on Debian
+      flang* | f18* | f95*)
+       _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+       _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+       _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
       # icc used to be incompatible with GCC.
       # ICC 10 doesn't accept -KPIC any more.
       icc* | ifort*)
@@ -4936,6 +4954,9 @@ m4_if([$1], [CXX], [
       ;;
     esac
     ;;
+  linux* | k*bsd*-gnu | gnu*)
+    _LT_TAGVAR(link_all_deplibs, $1)=no
+    ;;
   *)
     _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
     ;;
@@ -4998,6 +5019,9 @@ dnl Note also adjust exclude_expsyms for C++ above.
   openbsd* | bitrig*)
     with_gnu_ld=no
     ;;
+  linux* | k*bsd*-gnu | gnu*)
+    _LT_TAGVAR(link_all_deplibs, $1)=no
+    ;;
   esac
 
   _LT_TAGVAR(ld_shlibs, $1)=yes
@@ -5252,7 +5276,7 @@ _LT_EOF
       fi
       ;;
 
-    netbsd*)
+    netbsd* | netbsdelf*-gnu)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
        _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
        wlarc=
@@ -5773,6 +5797,7 @@ _LT_EOF
        if test yes = "$lt_cv_irix_exported_symbol"; then
           _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
        fi
+       _LT_TAGVAR(link_all_deplibs, $1)=no
       else
        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
@@ -5794,7 +5819,7 @@ _LT_EOF
       esac
       ;;
 
-    netbsd*)
+    netbsd* | netbsdelf*-gnu)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
        _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
       else
@@ -6420,7 +6445,7 @@ if test yes != "$_lt_caught_CXX_error"; then
       # Commands to make compiler produce verbose output that lists
       # what "hidden" libraries, object files and flags are used when
       # linking a shared library.
-      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
 
     else
       GXX=no
@@ -6795,7 +6820,7 @@ if test yes != "$_lt_caught_CXX_error"; then
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
           *)
             if test yes = "$GXX"; then
@@ -6860,7 +6885,7 @@ if test yes != "$_lt_caught_CXX_error"; then
            # explicitly linking system object files so we need to strip them
            # from the output so that they don't get included in the library
            # dependencies.
-           output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+           output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
            ;;
           *)
            if test yes = "$GXX"; then
@@ -7199,7 +7224,7 @@ if test yes != "$_lt_caught_CXX_error"; then
              # Commands to make compiler produce verbose output that lists
              # what "hidden" libraries, object files and flags are used when
              # linking a shared library.
-             output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+             output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
 
            else
              # FIXME: insert proper C++ library support
@@ -7283,7 +7308,7 @@ if test yes != "$_lt_caught_CXX_error"; then
                # Commands to make compiler produce verbose output that lists
                # what "hidden" libraries, object files and flags are used when
                # linking a shared library.
-               output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+               output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
              else
                # g++ 2.7 appears to require '-G' NOT '-shared' on this
                # platform.
@@ -7294,7 +7319,7 @@ if test yes != "$_lt_caught_CXX_error"; then
                # Commands to make compiler produce verbose output that lists
                # what "hidden" libraries, object files and flags are used when
                # linking a shared library.
-               output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+               output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
              fi
 
              _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
index e5fc71a..9cf8484 100644 (file)
@@ -40,8 +40,8 @@ int fstarcsort_main(int argc, char **argv) {
 
   s::ArcSortType sort_type;
   if (!s::GetArcSortType(FLAGS_sort_type, &sort_type)) {
-    LOG(ERROR) << argv[0] << ": Unknown or unsupported sort type: "
-               << FLAGS_sort_type;
+    LOG(ERROR) << argv[0]
+               << ": Unknown or unsupported sort type: " << FLAGS_sort_type;
     return 1;
   }
 
index 9d7cf2e..9476be1 100644 (file)
@@ -5,7 +5,7 @@
 #include <fst/flags.h>
 
 DEFINE_string(sort_type, "ilabel",
-              "Comparison method, one of: \"ilabel\", \"olabel\"");
+              "Comparison method: one of \"ilabel\", \"olabel\"");
 
 int fstarcsort_main(int argc, char **argv);
 
index 297a6e1..e7aa378 100644 (file)
@@ -4,7 +4,7 @@
 #include <fst/flags.h>
 
 DEFINE_string(compose_filter, "auto",
-              "Composition filter, one of: \"alt_sequence\", \"auto\", "
+              "Composition filter: one of \"alt_sequence\", \"auto\", "
               "\"match\", \"no_match\", \"null\", \"sequence\", \"trivial\"");
 DEFINE_bool(connect, true, "Trim output");
 
index efade36..7902de6 100644 (file)
@@ -39,7 +39,7 @@ int fstdeterminize_main(int argc, char **argv) {
   DeterminizeType det_type;
   if (!s::GetDeterminizeType(FLAGS_det_type, &det_type)) {
     LOG(ERROR) << argv[0] << ": Unknown or unsupported determinization type: "
-                          << FLAGS_det_type;
+               << FLAGS_det_type;
     return 1;
   }
 
index 2086bbf..6f28c87 100644 (file)
@@ -4,7 +4,7 @@
 #include <fst/flags.h>
 
 DEFINE_string(compose_filter, "auto",
-              "Composition filter, one of: \"alt_sequence\", \"auto\", "
+              "Composition filter: one of \"alt_sequence\", \"auto\", "
               "\"match\", \"null\", \"sequence\", \"trivial\"");
 DEFINE_bool(connect, true, "Trim output");
 
index 7cc3097..b6b163f 100644 (file)
@@ -33,9 +33,9 @@ DECLARE_bool(allow_negative_labels);
 
 int fstdraw_main(int argc, char **argv) {
   namespace s = fst::script;
-  using fst::script::FstClass;
   using fst::SymbolTable;
   using fst::SymbolTableTextOptions;
+  using fst::script::FstClass;
 
   std::string usage = "Prints out binary FSTs in dot text format.\n\n  Usage: ";
   usage += argv[0];
index 69f6fb8..fb34c8a 100644 (file)
@@ -10,7 +10,7 @@ DEFINE_string(ssymbols, "", "State label symbol table");
 DEFINE_bool(numeric, false, "Print numeric labels");
 DEFINE_int32(precision, 5, "Set precision (number of char/float)");
 DEFINE_string(float_format, "g",
-              "Floating-point format, one of: \"e\", \"f\", or \"g\"");
+              "Floating-point format: one of \"e\", \"f\", or \"g\"");
 DEFINE_bool(show_weight_one, false,
             "Print/draw arc weights and final weights equal to Weight::One()");
 DEFINE_string(title, "", "Set figure title");
index cb66f64..4a0bec6 100644 (file)
@@ -60,7 +60,7 @@ int fstequivalent_main(int argc, char **argv) {
     s::RandArcSelection ras;
     if (!s::GetRandArcSelection(FLAGS_select, &ras)) {
       LOG(ERROR) << argv[0] << ": Unknown or unsupported select type "
-                            << FLAGS_select;
+                 << FLAGS_select;
       return 1;
     }
     const RandGenOptions<s::RandArcSelection> opts(ras, FLAGS_max_length);
index 996ce7d..b2d442a 100644 (file)
@@ -12,7 +12,7 @@ DEFINE_int32(max_length, std::numeric_limits<int32>::max(),
 DEFINE_int32(npath, 1, "Number of paths to generate");
 DEFINE_uint64(seed, std::random_device()(), "Random seed");
 DEFINE_string(select, "uniform",
-              "Selection type: one of: "
+              "Selection type: one of "
               " \"uniform\", \"log_prob\" (when appropriate),"
               " \"fast_log_prob\" (when appropriate)");
 
index 5aab254..5d21708 100644 (file)
@@ -40,5 +40,5 @@ int fstinfo_main(int argc, char **argv) {
   s::Info(*ifst, FLAGS_test_properties, FLAGS_arc_filter, FLAGS_info_type,
           FLAGS_fst_verify);
 
-      return 0;
+  return 0;
 }
index a085a57..fa2b4c4 100644 (file)
@@ -4,12 +4,12 @@
 #include <fst/flags.h>
 
 DEFINE_string(arc_filter, "any",
-              "Arc filter: one of:"
+              "Arc filter: one of"
               " \"any\", \"epsilon\", \"iepsilon\", \"oepsilon\"; "
               "this only affects the counts of (co)accessible states, "
               "connected states, and (strongly) connected components");
 DEFINE_string(info_type, "auto",
-              "Info format: one of: \"auto\", \"long\", \"short\"");
+              "Info format: one of \"auto\", \"long\", \"short\"");
 DEFINE_bool(test_properties, true,
             "Compute property values (if unknown to FST)");
 DEFINE_bool(fst_verify, true, "Verify FST sanity");
index 6008c4d..aa722ef 100644 (file)
@@ -18,6 +18,7 @@ DECLARE_bool(connect);
 int fstintersect_main(int argc, char **argv) {
   namespace s = fst::script;
   using fst::ComposeFilter;
+  using fst::IntersectOptions;
   using fst::script::FstClass;
   using fst::script::VectorFstClass;
 
@@ -57,7 +58,7 @@ int fstintersect_main(int argc, char **argv) {
     return 1;
   }
 
-  const fst::IntersectOptions opts(FLAGS_connect, compose_filter);
+  const IntersectOptions opts(FLAGS_connect, compose_filter);
 
   s::Intersect(*ifst1, *ifst2, &ofst, opts);
 
index 802cc1c..48b000a 100644 (file)
@@ -4,7 +4,7 @@
 #include <fst/flags.h>
 
 DEFINE_string(compose_filter, "auto",
-             "Composition filter, one of: \"alt_sequence\", \"auto\", "
+              "Composition filter: one of \"alt_sequence\", \"auto\", "
               "\"match\", \"null\", \"sequence\", \"trivial\"");
 DEFINE_bool(connect, true, "Trim output");
 
index cf8ddca..4f1af30 100644 (file)
@@ -5,13 +5,13 @@
 #include <fst/weight.h>
 
 DEFINE_double(delta, fst::kDelta, "Comparison/quantization delta");
-DEFINE_string(map_type, "identity",
-              "Map operation, one of: \"arc_sum\", \"arc_unique\", "
-              "\"float_power\" (--power)\", \"identity\", \"input_epsilon\", "
-              "\"invert\", \"output_epsilon\", \"plus (--weight)\", "
-              "\"quantize (--delta)\", \"rmweight\", \"superfinal\", "
-              "\"power (--power)\", \"times (--weight)\", \"to_log\", "
-              "\"to_log64\", \"to_std\"");
+DEFINE_string(
+    map_type, "identity",
+    "Map operation: one of \"arc_sum\", \"arc_unique\", "
+    "\"identity\", \"input_epsilon\", \"invert\", \"output_epsilon\", "
+    "\"plus (--weight)\", \"power (--power)\", \"quantize (--delta)\", "
+    "\"rmweight\", \"superfinal\", \"times (--weight)\", "
+    "\"to_log\", \"to_log64\", \"to_std\"");
 DEFINE_double(power, 1.0, "Power parameter");
 DEFINE_string(weight, "", "Weight parameter");
 
index 4d5599c..c5f905d 100644 (file)
@@ -26,9 +26,9 @@ DECLARE_string(missing_symbol);
 
 int fstprint_main(int argc, char **argv) {
   namespace s = fst::script;
-  using fst::script::FstClass;
   using fst::SymbolTable;
   using fst::SymbolTableTextOptions;
+  using fst::script::FstClass;
 
   std::string usage =
       "Prints out binary FSTs in simple text format.\n\n  Usage: ";
index ab700fe..25a3a71 100644 (file)
 #include <fst/script/getters.h>
 #include <fst/script/project.h>
 
-DECLARE_bool(project_output);
+DECLARE_string(project_type);
 
 int fstproject_main(int argc, char **argv) {
   namespace s = fst::script;
+  using fst::ProjectType;
   using fst::script::MutableFstClass;
 
   std::string usage =
@@ -38,7 +39,14 @@ int fstproject_main(int argc, char **argv) {
   std::unique_ptr<MutableFstClass> fst(MutableFstClass::Read(in_name, true));
   if (!fst) return 1;
 
-  s::Project(fst.get(), s::GetProjectType(FLAGS_project_output));
+  ProjectType project_type;
+  if (!s::GetProjectType(FLAGS_project_type, &project_type)) {
+    LOG(ERROR) << argv[0] << ": Unknown or unsupported project type: "
+               << FLAGS_project_type;
+    return 1;
+  }
+
+  s::Project(fst.get(), project_type);
 
   return !fst->Write(out_name);
 }
index 1cfb913..8daf57c 100644 (file)
@@ -3,7 +3,8 @@
 
 #include <fst/flags.h>
 
-DEFINE_bool(project_output, false, "Project on output (vs. input)");
+DEFINE_string(project_type, "input",
+              "Side to project from, one of: \"input\", \"output\"");
 
 int fstproject_main(int argc, char **argv);
 
index 0e747da..3ac240e 100644 (file)
@@ -50,8 +50,7 @@ int fstpush_main(int argc, char **argv) {
 
   VectorFstClass ofst(ifst->ArcType());
 
-  s::Push(*ifst, &ofst, flags, s::GetReweightType(FLAGS_to_final),
-          FLAGS_delta);
+  s::Push(*ifst, &ofst, flags, s::GetReweightType(FLAGS_to_final), FLAGS_delta);
 
   return !ofst.Write(out_name);
 }
index ab08551..95bb786 100644 (file)
@@ -21,6 +21,7 @@ DECLARE_bool(remove_total_weight);
 
 int fstrandgen_main(int argc, char **argv) {
   namespace s = fst::script;
+  using fst::RandGenOptions;
   using fst::script::FstClass;
   using fst::script::VectorFstClass;
 
@@ -55,9 +56,9 @@ int fstrandgen_main(int argc, char **argv) {
   }
 
   s::RandGen(*ifst, &ofst,
-             fst::RandGenOptions<s::RandArcSelection>(
-                 ras, FLAGS_max_length, FLAGS_npath, FLAGS_weighted,
-                 FLAGS_remove_total_weight),
+             RandGenOptions<s::RandArcSelection>(ras, FLAGS_max_length,
+                                                 FLAGS_npath, FLAGS_weighted,
+                                                 FLAGS_remove_total_weight),
              FLAGS_seed);
 
   return !ofst.Write(out_name);
index fb54267..501fbaa 100644 (file)
@@ -8,7 +8,7 @@ DEFINE_int32(max_length, std::numeric_limits<int32>::max(),
 DEFINE_int32(npath, 1, "Number of paths to generate");
 DEFINE_uint64(seed, std::random_device()(), "Random seed");
 DEFINE_string(select, "uniform",
-              "Selection type: one of: "
+              "Selection type: one of "
               " \"uniform\", \"log_prob\" (when appropriate),"
               " \"fast_log_prob\" (when appropriate)");
 DEFINE_bool(weighted, false,
index 5505575..83552af 100644 (file)
@@ -27,9 +27,10 @@ DECLARE_bool(allow_negative_labels);
 
 int fstrelabel_main(int argc, char **argv) {
   namespace s = fst::script;
-  using fst::script::MutableFstClass;
+  using fst::ReadLabelPairs;
   using fst::SymbolTable;
   using fst::SymbolTableTextOptions;
+  using fst::script::MutableFstClass;
 
   std::string usage =
       "Relabels the input and/or the output labels of the FST.\n\n"
@@ -78,25 +79,23 @@ int fstrelabel_main(int argc, char **argv) {
         FLAGS_relabel_osymbols.empty()
             ? nullptr
             : SymbolTable::ReadText(FLAGS_relabel_osymbols, opts));
-    s::Relabel(fst.get(),
-               old_isymbols ? old_isymbols.get() : fst->InputSymbols(),
-               relabel_isymbols.get(), FLAGS_unknown_isymbol,
-               attach_new_isymbols,
-               old_osymbols ? old_osymbols.get() : fst->OutputSymbols(),
-               relabel_osymbols.get(), FLAGS_unknown_osymbol,
-               attach_new_osymbols);
+    s::Relabel(
+        fst.get(), old_isymbols ? old_isymbols.get() : fst->InputSymbols(),
+        relabel_isymbols.get(), FLAGS_unknown_isymbol, attach_new_isymbols,
+        old_osymbols ? old_osymbols.get() : fst->OutputSymbols(),
+        relabel_osymbols.get(), FLAGS_unknown_osymbol, attach_new_osymbols);
   } else {
     // Reads in relabeling pairs.
     std::vector<std::pair<int64, int64>> ipairs;
     if (!FLAGS_relabel_ipairs.empty()) {
-      if (!fst::ReadLabelPairs(FLAGS_relabel_ipairs, &ipairs,
-                                   FLAGS_allow_negative_labels))
+      if (!ReadLabelPairs(FLAGS_relabel_ipairs, &ipairs,
+                          FLAGS_allow_negative_labels))
         return 1;
     }
     std::vector<std::pair<int64, int64>> opairs;
     if (!FLAGS_relabel_opairs.empty()) {
-      if (!fst::ReadLabelPairs(FLAGS_relabel_opairs, &opairs,
-                                   FLAGS_allow_negative_labels))
+      if (!ReadLabelPairs(FLAGS_relabel_opairs, &opairs,
+                          FLAGS_allow_negative_labels))
         return 1;
     }
     s::Relabel(fst.get(), ipairs, opairs);
index 29f24ef..fed7a39 100644 (file)
@@ -10,11 +10,12 @@ DEFINE_string(relabel_osymbols, "", "Output symbol set to relabel to");
 DEFINE_string(relabel_ipairs, "", "Input relabel pairs (numeric)");
 DEFINE_string(relabel_opairs, "", "Output relabel pairs (numeric)");
 DEFINE_string(unknown_isymbol, "",
-    "Input symbol to use to relabel OOVs (default: OOVs are errors)");
-DEFINE_string(unknown_osymbol, "",
+              "Input symbol to use to relabel OOVs (default: OOVs are errors)");
+DEFINE_string(
+    unknown_osymbol, "",
     "Output symbol to use to relabel OOVs (default: OOVs are errors)");
 DEFINE_bool(allow_negative_labels, false,
-    "Allow negative labels (not recommended; may cause conflicts)");
+            "Allow negative labels (not recommended; may cause conflicts)");
 
 int fstrelabel_main(int argc, char **argv);
 
index 932f6aa..59d0960 100644 (file)
@@ -34,9 +34,9 @@ void Cleanup(std::vector<std::pair<int64, const FstClass *>> *pairs) {
 
 int fstreplace_main(int argc, char **argv) {
   namespace s = fst::script;
+  using fst::ReplaceLabelType;
   using fst::script::FstClass;
   using fst::script::VectorFstClass;
-  using fst::ReplaceLabelType;
 
   std::string usage =
       "Recursively replaces FST arcs with other FST(s).\n\n"
index 0cab330..7c36046 100644 (file)
@@ -4,11 +4,11 @@
 #include <fst/flags.h>
 
 DEFINE_string(call_arc_labeling, "input",
-              "Which labels to make non-epsilon on the call arc. "
-              "One of: \"input\" (default), \"output\", \"both\", \"neither\"");
+              "Which labels to make non-epsilon on the call arc: "
+              "one of: \"input\" (default), \"output\", \"both\", \"neither\"");
 DEFINE_string(return_arc_labeling, "neither",
-              "Which labels to make non-epsilon on the return arc. "
-              "One of: \"input\", \"output\", \"both\", \"neither\" (default)");
+              "Which labels to make non-epsilon on the return arc: "
+              "one of: \"input\", \"output\", \"both\", \"neither\" (default)");
 DEFINE_int64(return_label, 0, "Label to put on return arc");
 DEFINE_bool(epsilon_on_replace, false, "Call/return arcs are epsilon arcs?");
 
index 24a108e..92aba7a 100644 (file)
@@ -20,6 +20,7 @@ DECLARE_string(weight);
 
 int fstrmepsilon_main(int argc, char **argv) {
   namespace s = fst::script;
+  using fst::QueueType;
   using fst::script::MutableFstClass;
   using fst::script::WeightClass;
 
@@ -46,7 +47,7 @@ int fstrmepsilon_main(int argc, char **argv) {
       FLAGS_weight.empty() ? WeightClass::Zero(fst->WeightType())
                            : WeightClass(fst->WeightType(), FLAGS_weight);
 
-  fst::QueueType queue_type;
+  QueueType queue_type;
   if (!s::GetQueueType(FLAGS_queue_type, &queue_type)) {
     LOG(ERROR) << argv[0]
                << ": Unknown or unsupported queue type: " << FLAGS_queue_type;
index c249c52..192f5c9 100644 (file)
@@ -10,7 +10,7 @@ DEFINE_bool(connect, true, "Trim output");
 DEFINE_double(delta, fst::kShortestDelta, "Comparison/quantization delta");
 DEFINE_int64(nstate, fst::kNoStateId, "State number threshold");
 DEFINE_string(queue_type, "auto",
-              "Queue type: one of: \"auto\", "
+              "Queue type: one of \"auto\", "
               "\"fifo\", \"lifo\", \"shortest\", \"state\", \"top\"");
 DEFINE_string(weight, "", "Weight threshold");
 
index 4bff8e9..945ab87 100644 (file)
@@ -21,10 +21,10 @@ DECLARE_string(queue_type);
 
 int fstshortestdistance_main(int argc, char **argv) {
   namespace s = fst::script;
+  using fst::AUTO_QUEUE;
+  using fst::QueueType;
   using fst::script::FstClass;
   using fst::script::WeightClass;
-  using fst::QueueType;
-  using fst::AUTO_QUEUE;
 
   std::string usage = "Finds shortest distance(s) in an FST.\n\n  Usage: ";
   usage += argv[0];
index 63e6537..f87e9ad 100644 (file)
@@ -10,7 +10,7 @@ DEFINE_bool(reverse, false, "Perform in the reverse direction");
 DEFINE_double(delta, fst::kShortestDelta, "Comparison/quantization delta");
 DEFINE_int64(nstate, fst::kNoStateId, "State number threshold");
 DEFINE_string(queue_type, "auto",
-              "Queue type: one of: \"auto\", "
+              "Queue type: one of \"auto\", "
               "\"fifo\", \"lifo\", \"shortest\", \"state\", \"top\"");
 
 int fstshortestdistance_main(int argc, char **argv);
index e63f939..fe06ac0 100644 (file)
@@ -22,9 +22,10 @@ DECLARE_string(weight);
 
 int fstshortestpath_main(int argc, char **argv) {
   namespace s = fst::script;
+  using fst::QueueType;
   using fst::script::FstClass;
-  using fst::script::WeightClass;
   using fst::script::VectorFstClass;
+  using fst::script::WeightClass;
 
   std::string usage = "Finds shortest path(s) in an FST.\n\n  Usage: ";
   usage += argv[0];
@@ -51,15 +52,15 @@ int fstshortestpath_main(int argc, char **argv) {
 
   VectorFstClass ofst(ifst->ArcType());
 
-  fst::QueueType queue_type;
+  QueueType queue_type;
   if (!s::GetQueueType(FLAGS_queue_type, &queue_type)) {
     LOG(ERROR) << "Unknown or unsupported queue type: " << FLAGS_queue_type;
     return 1;
   }
 
-  const s::ShortestPathOptions opts(queue_type, FLAGS_nshortest,
-                                    FLAGS_unique, FLAGS_delta,
-                                    weight_threshold, FLAGS_nstate);
+  const s::ShortestPathOptions opts(queue_type, FLAGS_nshortest, FLAGS_unique,
+                                    FLAGS_delta, weight_threshold,
+                                    FLAGS_nstate);
 
   s::ShortestPath(*ifst, &ofst, opts);
 
index 9064d67..31bd309 100644 (file)
@@ -28,10 +28,10 @@ DECLARE_bool(verify);
 
 int fstsymbols_main(int argc, char **argv) {
   namespace s = fst::script;
-  using fst::script::MutableFstClass;
   using fst::ReadLabelPairs;
   using fst::SymbolTable;
   using fst::SymbolTableTextOptions;
+  using fst::script::MutableFstClass;
 
   std::string usage =
       "Performs operations (set, clear, relabel) on the symbol"
index 37098cb..454eadf 100644 (file)
@@ -7,7 +7,7 @@ libfst_LTLIBRARIES = compact8_acceptor-fst.la compact8_string-fst.la compact8_un
 lib_LTLIBRARIES = libfstcompact.la
 
 libfstcompact_la_SOURCES = compact8_acceptor-fst.cc compact8_string-fst.cc compact8_unweighted-fst.cc compact8_unweighted_acceptor-fst.cc compact8_weighted_string-fst.cc compact16_acceptor-fst.cc compact16_string-fst.cc compact16_unweighted-fst.cc compact16_unweighted_acceptor-fst.cc compact16_weighted_string-fst.cc compact64_acceptor-fst.cc compact64_string-fst.cc compact64_unweighted-fst.cc compact64_unweighted_acceptor-fst.cc compact64_weighted_string-fst.cc
-libfstcompact_la_LDFLAGS = -version-info 20:0:0
+libfstcompact_la_LDFLAGS = -version-info 21:0:0
 
 compact8_acceptor_fst_la_SOURCES = compact8_acceptor-fst.cc
 compact8_acceptor_fst_la_LDFLAGS = -avoid-version -module
index 09fd333..9313db8 100644 (file)
@@ -527,7 +527,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 libfst_LTLIBRARIES = compact8_acceptor-fst.la compact8_string-fst.la compact8_unweighted-fst.la compact8_unweighted_acceptor-fst.la compact8_weighted_string-fst.la compact16_acceptor-fst.la compact16_string-fst.la compact16_unweighted-fst.la compact16_unweighted_acceptor-fst.la compact16_weighted_string-fst.la compact64_acceptor-fst.la compact64_string-fst.la compact64_unweighted-fst.la compact64_unweighted_acceptor-fst.la compact64_weighted_string-fst.la
 lib_LTLIBRARIES = libfstcompact.la
 libfstcompact_la_SOURCES = compact8_acceptor-fst.cc compact8_string-fst.cc compact8_unweighted-fst.cc compact8_unweighted_acceptor-fst.cc compact8_weighted_string-fst.cc compact16_acceptor-fst.cc compact16_string-fst.cc compact16_unweighted-fst.cc compact16_unweighted_acceptor-fst.cc compact16_weighted_string-fst.cc compact64_acceptor-fst.cc compact64_string-fst.cc compact64_unweighted-fst.cc compact64_unweighted_acceptor-fst.cc compact64_weighted_string-fst.cc
-libfstcompact_la_LDFLAGS = -version-info 20:0:0
+libfstcompact_la_LDFLAGS = -version-info 21:0:0
 compact8_acceptor_fst_la_SOURCES = compact8_acceptor-fst.cc
 compact8_acceptor_fst_la_LDFLAGS = -avoid-version -module
 compact8_string_fst_la_SOURCES = compact8_string-fst.cc
index 99b5209..105f8c8 100644 (file)
@@ -15,5 +15,4 @@ static FstRegisterer<CompactUnweightedFst<LogArc, uint16>>
 static FstRegisterer<CompactUnweightedFst<Log64Arc, uint16>>
     CompactUnweightedFst_Log64Arc_uint16_registerer;
 
-
 }  // namespace fst
index c6c6f33..436ddc2 100644 (file)
@@ -6,16 +6,13 @@
 
 namespace fst {
 
-static FstRegisterer<
-    CompactUnweightedAcceptorFst<StdArc, uint16>>
+static FstRegisterer<CompactUnweightedAcceptorFst<StdArc, uint16>>
     CompactUnweightedAcceptorFst_StdArc_uint16_registerer;
 
-static FstRegisterer<
-    CompactUnweightedAcceptorFst<LogArc, uint16>>
+static FstRegisterer<CompactUnweightedAcceptorFst<LogArc, uint16>>
     CompactUnweightedAcceptorFst_LogArc_uint16_registerer;
 
-static FstRegisterer<
-    CompactUnweightedAcceptorFst<Log64Arc, uint16>>
+static FstRegisterer<CompactUnweightedAcceptorFst<Log64Arc, uint16>>
     CompactUnweightedAcceptorFst_Log64Arc_uint16_registerer;
 
 }  // namespace fst
index e84700c..46214f5 100644 (file)
@@ -6,16 +6,13 @@
 
 namespace fst {
 
-static FstRegisterer<
-    CompactWeightedStringFst<StdArc, uint16>>
+static FstRegisterer<CompactWeightedStringFst<StdArc, uint16>>
     CompactWeightedStringFst_StdArc_uint16_registerer;
 
-static FstRegisterer<
-    CompactWeightedStringFst<LogArc, uint16>>
+static FstRegisterer<CompactWeightedStringFst<LogArc, uint16>>
     CompactWeightedStringFst_LogArc_uint16_registerer;
 
-static FstRegisterer<
-    CompactWeightedStringFst<Log64Arc, uint16>>
+static FstRegisterer<CompactWeightedStringFst<Log64Arc, uint16>>
     CompactWeightedStringFst_Log64Arc_uint16_registerer;
 
 }  // namespace fst
index 50c4219..6afe73e 100644 (file)
@@ -6,16 +6,13 @@
 
 namespace fst {
 
-static FstRegisterer<
-    CompactUnweightedAcceptorFst<StdArc, uint64>>
+static FstRegisterer<CompactUnweightedAcceptorFst<StdArc, uint64>>
     CompactUnweightedAcceptorFst_StdArc_uint64_registerer;
 
-static FstRegisterer<
-    CompactUnweightedAcceptorFst<LogArc, uint64>>
+static FstRegisterer<CompactUnweightedAcceptorFst<LogArc, uint64>>
     CompactUnweightedAcceptorFst_LogArc_uint64_registerer;
 
-static FstRegisterer<
-    CompactUnweightedAcceptorFst<Log64Arc, uint64>>
+static FstRegisterer<CompactUnweightedAcceptorFst<Log64Arc, uint64>>
     CompactUnweightedAcceptorFst_Log64Arc_uint64_registerer;
 
 }  // namespace fst
index 46fde32..65c8570 100644 (file)
@@ -6,16 +6,13 @@
 
 namespace fst {
 
-static FstRegisterer<
-    CompactWeightedStringFst<StdArc, uint64>>
+static FstRegisterer<CompactWeightedStringFst<StdArc, uint64>>
     CompactWeightedStringFst_StdArc_uint64_registerer;
 
-static FstRegisterer<
-    CompactWeightedStringFst<LogArc, uint64>>
+static FstRegisterer<CompactWeightedStringFst<LogArc, uint64>>
     CompactWeightedStringFst_LogArc_uint64_registerer;
 
-static FstRegisterer<
-    CompactWeightedStringFst<Log64Arc, uint64>>
+static FstRegisterer<CompactWeightedStringFst<Log64Arc, uint64>>
     CompactWeightedStringFst_Log64Arc_uint64_registerer;
 
 }  // namespace fst
index 91f5658..de6dbf2 100644 (file)
@@ -6,16 +6,13 @@
 
 namespace fst {
 
-static FstRegisterer<
-    CompactUnweightedAcceptorFst<StdArc, uint8>>
+static FstRegisterer<CompactUnweightedAcceptorFst<StdArc, uint8>>
     CompactUnweightedAcceptorFst_StdArc_uint8_registerer;
 
-static FstRegisterer<
-    CompactUnweightedAcceptorFst<LogArc, uint8>>
+static FstRegisterer<CompactUnweightedAcceptorFst<LogArc, uint8>>
     CompactUnweightedAcceptorFst_LogArc_uint8_registerer;
 
-static FstRegisterer<
-    CompactUnweightedAcceptorFst<Log64Arc, uint8>>
+static FstRegisterer<CompactUnweightedAcceptorFst<Log64Arc, uint8>>
     CompactUnweightedAcceptorFst_Log64Arc_uint8_registerer;
 
 }  // namespace fst
index 7dba90e..889daf2 100644 (file)
@@ -6,16 +6,13 @@
 
 namespace fst {
 
-static FstRegisterer<
-    CompactWeightedStringFst<StdArc, uint8>>
+static FstRegisterer<CompactWeightedStringFst<StdArc, uint8>>
     CompactWeightedStringFst_StdArc_uint8_registerer;
 
-static FstRegisterer<
-    CompactWeightedStringFst<LogArc, uint8>>
+static FstRegisterer<CompactWeightedStringFst<LogArc, uint8>>
     CompactWeightedStringFst_LogArc_uint8_registerer;
 
-static FstRegisterer<
-    CompactWeightedStringFst<Log64Arc, uint8>>
+static FstRegisterer<CompactWeightedStringFst<Log64Arc, uint8>>
     CompactWeightedStringFst_Log64Arc_uint8_registerer;
 
 }  // namespace fst
index 9123656..5df4d92 100644 (file)
@@ -13,7 +13,7 @@ endif
 
 if HAVE_SCRIPT
 libfstcompressscript_la_SOURCES = compressscript.cc
-libfstcompressscript_la_LDFLAGS = -version-info 20:0:0
+libfstcompressscript_la_LDFLAGS = -version-info 21:0:0
 libfstcompressscript_la_LIBADD = ../../script/libfstscript.la \
                                  ../../lib/libfst.la \
                                  -lm $(DL_LIBS)
index 5d7d93c..3f34421 100644 (file)
@@ -370,7 +370,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 
 @HAVE_BIN_TRUE@fstcompress_SOURCES = fstcompress.cc fstcompress-main.cc
 @HAVE_SCRIPT_TRUE@libfstcompressscript_la_SOURCES = compressscript.cc
-@HAVE_SCRIPT_TRUE@libfstcompressscript_la_LDFLAGS = -version-info 20:0:0
+@HAVE_SCRIPT_TRUE@libfstcompressscript_la_LDFLAGS = -version-info 21:0:0
 @HAVE_SCRIPT_TRUE@libfstcompressscript_la_LIBADD = ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@                                 ../../lib/libfst.la \
 @HAVE_SCRIPT_TRUE@                                 -lm $(DL_LIBS)
index 08d401b..2cb1294 100644 (file)
@@ -7,7 +7,7 @@ libfst_LTLIBRARIES = const8-fst.la const16-fst.la const64-fst.la
 lib_LTLIBRARIES = libfstconst.la
 
 libfstconst_la_SOURCES = const8-fst.cc const16-fst.cc const64-fst.cc
-libfstconst_la_LDFLAGS = -version-info 20:0:0
+libfstconst_la_LDFLAGS = -version-info 21:0:0
 
 const8_fst_la_SOURCES = const8-fst.cc
 const8_fst_la_LDFLAGS = -avoid-version -module
index 0d70559..b16e675 100644 (file)
@@ -371,7 +371,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 libfst_LTLIBRARIES = const8-fst.la const16-fst.la const64-fst.la
 lib_LTLIBRARIES = libfstconst.la
 libfstconst_la_SOURCES = const8-fst.cc const16-fst.cc const64-fst.cc
-libfstconst_la_LDFLAGS = -version-info 20:0:0
+libfstconst_la_LDFLAGS = -version-info 21:0:0
 const8_fst_la_SOURCES = const8-fst.cc
 const8_fst_la_LDFLAGS = -avoid-version -module
 const16_fst_la_SOURCES = const16-fst.cc
index 0088c56..c115846 100644 (file)
@@ -7,13 +7,13 @@ lib_LTLIBRARIES = libfstfar.la
 endif
 
 libfstfar_la_SOURCES = sttable.cc stlist.cc
-libfstfar_la_LDFLAGS = -version-info 20:0:0
+libfstfar_la_LDFLAGS = -version-info 21:0:0
 libfstfar_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 
 if HAVE_SCRIPT
 libfstfarscript_la_SOURCES = far-class.cc farscript.cc getters.cc script-impl.cc \
                              strings.cc sttable.cc stlist.cc
-libfstfarscript_la_LDFLAGS = -version-info 20:0:0
+libfstfarscript_la_LDFLAGS = -version-info 21:0:0
 libfstfarscript_la_LIBADD = \
     libfstfar.la ../../script/libfstscript.la \
         ../../lib/libfst.la -lm $(DL_LIBS)
index 5a486ca..e4ab9f2 100644 (file)
@@ -449,12 +449,12 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @HAVE_SCRIPT_FALSE@lib_LTLIBRARIES = libfstfar.la
 @HAVE_SCRIPT_TRUE@lib_LTLIBRARIES = libfstfar.la libfstfarscript.la
 libfstfar_la_SOURCES = sttable.cc stlist.cc
-libfstfar_la_LDFLAGS = -version-info 20:0:0
+libfstfar_la_LDFLAGS = -version-info 21:0:0
 libfstfar_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 @HAVE_SCRIPT_TRUE@libfstfarscript_la_SOURCES = far-class.cc farscript.cc getters.cc script-impl.cc \
 @HAVE_SCRIPT_TRUE@                             strings.cc sttable.cc stlist.cc
 
-@HAVE_SCRIPT_TRUE@libfstfarscript_la_LDFLAGS = -version-info 20:0:0
+@HAVE_SCRIPT_TRUE@libfstfarscript_la_LDFLAGS = -version-info 21:0:0
 @HAVE_SCRIPT_TRUE@libfstfarscript_la_LIBADD = \
 @HAVE_SCRIPT_TRUE@    libfstfar.la ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@        ../../lib/libfst.la -lm $(DL_LIBS)
index dd45058..8fd8bd7 100644 (file)
@@ -9,7 +9,6 @@
 namespace fst {
 namespace script {
 
-
 // FarReaderClass.
 
 FarReaderClass *FarReaderClass::Open(const std::string &source) {
@@ -27,7 +26,7 @@ FarReaderClass *FarReaderClass::Open(const std::vector<std::string> &sources) {
   OpenFarReaderClassArgs args(sources);
   args.retval = nullptr;
   Apply<Operation<OpenFarReaderClassArgs>>("OpenFarReaderClass", arc_type,
-                                            &args);
+                                           &args);
   return args.retval;
 }
 
index e9dc14f..8f752c5 100644 (file)
@@ -8,8 +8,8 @@
 
 #include <fst/flags.h>
 #include <fst/extensions/far/farscript.h>
-#include <fst/extensions/far/getters.h>
 #include <fstream>
+#include <fst/script/getters.h>
 
 DECLARE_string(key_prefix);
 DECLARE_string(key_suffix);
@@ -43,7 +43,7 @@ int farcompilestrings_main(int argc, char **argv) {
     for (int i = 1; i < argc - 1; ++i) {
       std::ifstream istrm(argv[i]);
       std::string str;
-      while (getline(istrm, str)) in_sources.push_back(str);
+      while (std::getline(istrm, str)) in_sources.push_back(str);
     }
   } else {
     for (int i = 1; i < argc - 1; ++i)
@@ -67,13 +67,17 @@ int farcompilestrings_main(int argc, char **argv) {
     return 1;
   }
 
-  fst::FarTokenType token_type;
-  if (!s::GetFarTokenType(FLAGS_token_type, &token_type)) {
-    LOG(ERROR) << "Unkonwn or unsupported FAR token type: " << FLAGS_token_type;
+  fst::TokenType token_type;
+  if (!s::GetTokenType(FLAGS_token_type, &token_type)) {
+    LOG(ERROR) << "Unknown or unsupported FAR token type: " << FLAGS_token_type;
     return 1;
   }
 
-  const auto far_type = s::GetFarType(FLAGS_far_type);
+  fst::FarType far_type;
+  if (!s::GetFarType(FLAGS_far_type, &far_type)) {
+    LOG(ERROR) << "Unknown or unsupported FAR type: " << FLAGS_far_type;
+    return 1;
+  }
 
   s::FarCompileStrings(in_sources, out_source, FLAGS_arc_type, FLAGS_fst_type,
                        far_type, FLAGS_generate_keys, entry_type, token_type,
index 9d05e54..79aebf7 100644 (file)
@@ -29,6 +29,4 @@ DEFINE_bool(initial_symbols, true,
 
 int farcompilestrings_main(int argc, char **argv);
 
-int main(int argc, char **argv) {
-  return farcompilestrings_main(argc, argv);
-}
+int main(int argc, char **argv) { return farcompilestrings_main(argc, argv); }
index 9b399cf..60d50d7 100644 (file)
@@ -34,7 +34,7 @@ int farcreate_main(int argc, char **argv) {
     for (int i = 1; i < argc - 1; ++i) {
       std::ifstream istrm(argv[i]);
       std::string str;
-      while (getline(istrm, str)) in_sources.push_back(str);
+      while (std::getline(istrm, str)) in_sources.push_back(str);
     }
   } else {
     for (int i = 1; i < argc - 1; ++i)
@@ -55,7 +55,11 @@ int farcreate_main(int argc, char **argv) {
   const auto arc_type = s::LoadArcTypeFromFst(in_sources[0]);
   if (arc_type.empty()) return 1;
 
-  const auto far_type = s::GetFarType(FLAGS_far_type);
+  fst::FarType far_type;
+  if (!s::GetFarType(FLAGS_far_type, &far_type)) {
+    LOG(ERROR) << "Unknown or unsupported FAR type: " << FLAGS_far_type;
+    return 1;
+  }
 
   s::FarCreate(in_sources, out_source, arc_type, FLAGS_generate_keys, far_type,
                FLAGS_key_prefix, FLAGS_key_suffix);
index c20cebd..284e5d5 100644 (file)
@@ -12,6 +12,4 @@ DEFINE_bool(file_list_input, false,
 
 int farcreate_main(int argc, char **argv);
 
-int main(int argc, char **argv) {
-  return farcreate_main(argc, argv);
-}
+int main(int argc, char **argv) { return farcreate_main(argc, argv); }
index 69d5853..39e1cfb 100644 (file)
@@ -8,6 +8,4 @@ DEFINE_double(delta, fst::kDelta, "Comparison/quantization delta");
 
 int farequal_main(int argc, char **argv);
 
-int main(int argc, char **argv) {
-  return farequal_main(argc, argv);
-}
+int main(int argc, char **argv) { return farequal_main(argc, argv); }
index 839f623..eb9dd3e 100644 (file)
@@ -12,6 +12,4 @@ DEFINE_string(range_delimiter, "-", "Delimiter for ranges of keys");
 
 int farextract_main(int argc, char **argv);
 
-int main(int argc, char **argv) {
-  return farextract_main(argc, argv);
-}
+int main(int argc, char **argv) { return farextract_main(argc, argv); }
index ab67cf7..ae9ee29 100644 (file)
@@ -9,6 +9,4 @@ DEFINE_bool(list_fsts, false, "Display FST information for each key");
 
 int farinfo_main(int argc, char **argv);
 
-int main(int argc, char **argv) {
-  return farinfo_main(argc, argv);
-}
+int main(int argc, char **argv) { return farinfo_main(argc, argv); }
index cb0a6bf..614a94a 100644 (file)
@@ -34,8 +34,8 @@ int farisomorphic_main(int argc, char **argv) {
   const auto arc_type = s::LoadArcTypeFromFar(argv[1]);
   if (arc_type.empty()) return 1;
 
-  bool result = s::FarIsomorphic(argv[1], argv[2], arc_type,
-                                 FLAGS_delta, FLAGS_begin_key, FLAGS_end_key);
+  bool result = s::FarIsomorphic(argv[1], argv[2], arc_type, FLAGS_delta,
+                                 FLAGS_begin_key, FLAGS_end_key);
 
   if (!result) VLOG(1) << "FARs are not isomorphic.";
 
index 5ea4118..1ed29ec 100644 (file)
@@ -8,6 +8,4 @@ DEFINE_double(delta, fst::kDelta, "Comparison/quantization delta");
 
 int farisomorphic_main(int argc, char **argv);
 
-int main(int argc, char **argv) {
-  return farisomorphic_main(argc, argv);
-}
+int main(int argc, char **argv) { return farisomorphic_main(argc, argv); }
index 37feb6c..dabfec8 100644 (file)
@@ -8,7 +8,7 @@
 
 #include <fst/flags.h>
 #include <fst/extensions/far/farscript.h>
-#include <fst/extensions/far/getters.h>
+#include <fst/script/getters.h>
 
 DECLARE_string(filename_prefix);
 DECLARE_string(filename_suffix);
@@ -47,8 +47,8 @@ int farprintstrings_main(int argc, char **argv) {
     return 1;
   }
 
-  fst::FarTokenType token_type;
-  if (!s::GetFarTokenType(FLAGS_token_type, &token_type)) {
+  fst::TokenType token_type;
+  if (!s::GetTokenType(FLAGS_token_type, &token_type)) {
     LOG(ERROR) << "Unknown or unsupported FAR token type: " << FLAGS_token_type;
     return 1;
   }
index 27db6d4..137ad4a 100644 (file)
@@ -22,6 +22,4 @@ DEFINE_bool(initial_symbols, true,
 
 int farprintstrings_main(int argc, char **argv);
 
-int main(int argc, char **argv) {
-  return farprintstrings_main(argc, argv);
-}
+int main(int argc, char **argv) { return farprintstrings_main(argc, argv); }
index 9e23cb7..be7216c 100644 (file)
@@ -16,7 +16,7 @@ void FarCompileStrings(const std::vector<std::string> &in_sources,
                        const std::string &out_source,
                        const std::string &arc_type, const std::string &fst_type,
                        const FarType &far_type, int32 generate_keys,
-                       FarEntryType fet, FarTokenType tt,
+                       FarEntryType fet, TokenType tt,
                        const std::string &symbols_source,
                        const std::string &unknown_symbol, bool keep_symbols,
                        bool initial_symbols, bool allow_negative_labels,
@@ -98,11 +98,10 @@ REGISTER_FST_OPERATION_3ARCS(FarIsomorphic, FarIsomorphicArgs);
 
 void FarPrintStrings(const std::vector<std::string> &isources,
                      const std::string &arc_type, const FarEntryType entry_type,
-                     const FarTokenType token_type,
-                     const std::string &begin_key, const std::string &end_key,
-                     bool print_key, bool print_weight,
-                     const std::string &symbols_source, bool initial_symbols,
-                     const int32 generate_sources,
+                     const TokenType token_type, const std::string &begin_key,
+                     const std::string &end_key, bool print_key,
+                     bool print_weight, const std::string &symbols_source,
+                     bool initial_symbols, const int32 generate_sources,
                      const std::string &source_prefix,
                      const std::string &source_suffix) {
   FarPrintStringsArgs args(isources, entry_type, token_type, begin_key, end_key,
index c49f1bb..46b9392 100644 (file)
@@ -16,36 +16,26 @@ namespace fst {
 
 namespace script {
 
-FarType GetFarType(const std::string &str) {
+bool GetFarType(const std::string &str, FarType *far_type) {
   if (str == "fst") {
-    return FAR_FST;
+    *far_type = FarType::FST;
   } else if (str == "stlist") {
-    return FAR_STLIST;
+    *far_type = FarType::STLIST;
   } else if (str == "sttable") {
-    return FAR_STTABLE;
+    *far_type = FarType::STTABLE;
+  } else if (str == "default") {
+    *far_type = FarType::DEFAULT;
   } else {
-    return FAR_DEFAULT;
+    return false;
   }
+  return true;
 }
 
 bool GetFarEntryType(const std::string &str, FarEntryType *entry_type) {
   if (str == "line") {
-    *entry_type = FET_LINE;
+    *entry_type = FarEntryType::LINE;
   } else if (str == "file") {
-    *entry_type = FET_FILE;
-  } else {
-    return false;
-  }
-  return true;
-}
-
-bool GetFarTokenType(const std::string &str, FarTokenType *token_type) {
-  if (str == "symbol") {
-    *token_type = FTT_SYMBOL;
-  } else if (str == "byte") {
-    *token_type = FTT_BYTE;
-  } else if (str == "utf8") {
-    *token_type = FTT_UTF8;
+    *entry_type = FarEntryType::FILE;
   } else {
     return false;
   }
@@ -57,15 +47,15 @@ void ExpandArgs(int argc, char **argv, int *argcp, char ***argvp) {
 
 }  // namespace script
 
-std::string GetFarTypeString(FarType type) {
-  switch (type) {
-    case FAR_FST:
+std::string GetFarTypeString(FarType far_type) {
+  switch (far_type) {
+    case FarType::FST:
       return "fst";
-    case FAR_STLIST:
+    case FarType::STLIST:
       return "stlist";
-    case FAR_STTABLE:
+    case FarType::STTABLE:
       return "sttable";
-    case FAR_DEFAULT:
+    case FarType::DEFAULT:
       return "default";
     default:
       return "<unknown>";
index ac4740b..c1ae0c7 100644 (file)
@@ -31,7 +31,7 @@ int KeySize(const char *source) {
   }
   std::string s;
   int nline = 0;
-  while (getline(istrm, s)) ++nline;
+  while (std::getline(istrm, s)) ++nline;
   return nline ? ceil(log10(nline + 1)) : 1;
 }
 
index 4eebe06..0cca4e2 100644 (file)
@@ -15,7 +15,7 @@ if HAVE_SCRIPT
 lib_LTLIBRARIES = libfstlinearscript.la
 
 libfstlinearscript_la_SOURCES = linearscript.cc
-libfstlinearscript_la_LDFLAGS = -version-info 20:0:0
+libfstlinearscript_la_LDFLAGS = -version-info 21:0:0
 libfstlinearscript_la_LIBADD = ../../script/libfstscript.la
 endif
 
index 6ae1d35..1ba2d35 100644 (file)
@@ -396,7 +396,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @HAVE_BIN_TRUE@fstloglinearapply_LDADD = libfstlinearscript.la ../../script/libfstscript.la
 @HAVE_SCRIPT_TRUE@lib_LTLIBRARIES = libfstlinearscript.la
 @HAVE_SCRIPT_TRUE@libfstlinearscript_la_SOURCES = linearscript.cc
-@HAVE_SCRIPT_TRUE@libfstlinearscript_la_LDFLAGS = -version-info 20:0:0
+@HAVE_SCRIPT_TRUE@libfstlinearscript_la_LDFLAGS = -version-info 21:0:0
 @HAVE_SCRIPT_TRUE@libfstlinearscript_la_LIBADD = ../../script/libfstscript.la
 libfst_LTLIBRARIES = linear_tagger-fst.la linear_classifier-fst.la
 linear_tagger_fst_la_SOURCES = linear-tagger-fst.cc
index d2e248e..075a875 100644 (file)
@@ -5,8 +5,8 @@
 #include <fst/register.h>
 
 using fst::LinearClassifierFst;
-using fst::StdArc;
 using fst::LogArc;
+using fst::StdArc;
 
 REGISTER_FST(LinearClassifierFst, StdArc);
 REGISTER_FST(LinearClassifierFst, LogArc);
index 0110fa7..3c72bbd 100644 (file)
@@ -5,8 +5,8 @@
 #include <fst/register.h>
 
 using fst::LinearTaggerFst;
-using fst::StdArc;
 using fst::LogArc;
+using fst::StdArc;
 
 REGISTER_FST(LinearTaggerFst, StdArc);
 REGISTER_FST(LinearTaggerFst, LogArc);
index 1a4da1e..7e58889 100644 (file)
@@ -9,7 +9,7 @@ lib_LTLIBRARIES = libfstlookahead.la
 
 libfstlookahead_la_SOURCES = arc_lookahead-fst.cc ilabel_lookahead-fst.cc \
                              olabel_lookahead-fst.cc
-libfstlookahead_la_LDFLAGS = -version-info 20:0:0
+libfstlookahead_la_LDFLAGS = -version-info 21:0:0
 
 arc_lookahead_fst_la_SOURCES = arc_lookahead-fst.cc
 arc_lookahead_fst_la_LDFLAGS = -avoid-version -module
index d278949..72e4e93 100644 (file)
@@ -382,7 +382,7 @@ lib_LTLIBRARIES = libfstlookahead.la
 libfstlookahead_la_SOURCES = arc_lookahead-fst.cc ilabel_lookahead-fst.cc \
                              olabel_lookahead-fst.cc
 
-libfstlookahead_la_LDFLAGS = -version-info 20:0:0
+libfstlookahead_la_LDFLAGS = -version-info 21:0:0
 arc_lookahead_fst_la_SOURCES = arc_lookahead-fst.cc
 arc_lookahead_fst_la_LDFLAGS = -avoid-version -module
 ilabel_lookahead_fst_la_SOURCES = ilabel_lookahead-fst.cc
index 1aaeefe..b76961a 100644 (file)
@@ -20,7 +20,7 @@ endif
 if HAVE_SCRIPT
 lib_LTLIBRARIES = libfstmpdtscript.la
 libfstmpdtscript_la_SOURCES = mpdtscript.cc
-libfstmpdtscript_la_LDFLAGS = -version-info 20:0:0
+libfstmpdtscript_la_LDFLAGS = -version-info 21:0:0
 libfstmpdtscript_la_LIBADD = ../../script/libfstscript.la \
                              ../../lib/libfst.la -lm $(DL_LIBS)
 endif
index 113c736..d6dab78 100644 (file)
@@ -407,7 +407,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @HAVE_BIN_TRUE@mpdtreverse_SOURCES = mpdtreverse.cc mpdtreverse-main.cc
 @HAVE_SCRIPT_TRUE@lib_LTLIBRARIES = libfstmpdtscript.la
 @HAVE_SCRIPT_TRUE@libfstmpdtscript_la_SOURCES = mpdtscript.cc
-@HAVE_SCRIPT_TRUE@libfstmpdtscript_la_LDFLAGS = -version-info 20:0:0
+@HAVE_SCRIPT_TRUE@libfstmpdtscript_la_LDFLAGS = -version-info 21:0:0
 @HAVE_SCRIPT_TRUE@libfstmpdtscript_la_LIBADD = ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@                             ../../lib/libfst.la -lm $(DL_LIBS)
 
index f4b5810..3d96d9d 100644 (file)
@@ -22,10 +22,10 @@ DECLARE_bool(keep_parentheses);
 
 int mpdtexpand_main(int argc, char **argv) {
   namespace s = fst::script;
+  using fst::MPdtExpandOptions;
+  using fst::ReadLabelTriples;
   using fst::script::FstClass;
   using fst::script::VectorFstClass;
-  using fst::ReadLabelTriples;
-  using fst::MPdtExpandOptions;
 
   std::string usage = "Expand a (bounded-stack) MPDT as an FST.\n\n  Usage: ";
   usage += argv[0];
index 231055e..a7d830c 100644 (file)
@@ -21,8 +21,8 @@ DECLARE_string(mpdt_parentheses);
 
 int mpdtinfo_main(int argc, char **argv) {
   namespace s = fst::script;
-  using fst::script::FstClass;
   using fst::ReadLabelTriples;
+  using fst::script::FstClass;
 
   std::string usage = "Prints out information about an MPDT.\n\n  Usage: ";
   usage += argv[0];
index a33d449..4d7b090 100644 (file)
@@ -27,7 +27,8 @@ void MPdtCompose(const FstClass &ifst1, const FstClass &ifst2,
                  const std::vector<int64> &assignments, MutableFstClass *ofst,
                  const MPdtComposeOptions &copts, bool left_pdt) {
   if (!internal::ArcTypesMatch(ifst1, ifst2, "MPdtCompose") ||
-      !internal::ArcTypesMatch(ifst1, *ofst, "MPdtCompose")) return;
+      !internal::ArcTypesMatch(ifst1, *ofst, "MPdtCompose"))
+    return;
   MPdtComposeArgs args(ifst1, ifst2, parens, assignments, ofst, copts,
                        left_pdt);
   Apply<Operation<MPdtComposeArgs>>("MPdtCompose", ifst1.ArcType(), &args);
index ebabe88..97d55f1 100644 (file)
@@ -10,4 +10,4 @@ ngram_fst_la_SOURCES = bitmap-index.cc ngram-fst.cc nthbit.cc
 ngram_fst_la_LDFLAGS = -avoid-version -module
 
 libfstngram_la_SOURCES = bitmap-index.cc ngram-fst.cc nthbit.cc
-libfstngram_la_LDFLAGS = -version-info 20:0:0
+libfstngram_la_LDFLAGS = -version-info 21:0:0
index 104093b..0668c74 100644 (file)
@@ -355,7 +355,7 @@ lib_LTLIBRARIES = libfstngram.la
 ngram_fst_la_SOURCES = bitmap-index.cc ngram-fst.cc nthbit.cc
 ngram_fst_la_LDFLAGS = -avoid-version -module
 libfstngram_la_SOURCES = bitmap-index.cc ngram-fst.cc nthbit.cc
-libfstngram_la_LDFLAGS = -version-info 20:0:0
+libfstngram_la_LDFLAGS = -version-info 21:0:0
 all: all-am
 
 .SUFFIXES:
index b44a7c6..909d6d0 100644 (file)
 #include <algorithm>
 #include <iterator>
 
+#include <fst/types.h>
 #include <fst/log.h>
 #include <fst/extensions/ngram/nthbit.h>
 
 namespace fst {
-namespace {
-const size_t kPrimaryBlockBits =
-    BitmapIndex::kStorageBitSize * BitmapIndex::kSecondaryBlockSize;
 
 static_assert(sizeof(long long) >= sizeof(uint64),  // NOLINT
               "__builtin_...ll is used on uint64 values.");
 
-// If [begin, begin+size) is a monotonically increasing running sum of
-// popcounts for a bitmap, this will return the index of the word that contains
-// the value'th zero.  If value is larger then the number of zeros in the
-// bitmap, size will be returned.  The idea is that the number of zerocounts
-// (i.e. the popcount of logical NOT of values) is offset * kStorageBitSize
-// minus the value for each element of the running sum.
-template <size_t BlockSize, typename Container>
-size_t InvertedSearch(const Container& c,
-                      size_t first_idx,
-                      size_t last_idx,
-                      size_t value) {
-  const size_t begin_idx = first_idx;
-  while (first_idx != last_idx) {
-    // Invariant: [first_idx, last_idx) is the search range.
-    size_t mid_idx = first_idx + ((last_idx - first_idx) / 2);
-    size_t mid_value = BlockSize * (1 + (mid_idx - begin_idx)) - c[mid_idx];
-    if (mid_value < value) {
-      first_idx = mid_idx + 1;
-    } else {
-      last_idx = mid_idx;
-    }
-  }
-  return first_idx;
-}
-}  // namespace
-
 size_t BitmapIndex::Rank1(size_t end) const {
+  DCHECK_LE(end, Bits());
+  // TODO(jrosenstock): Remove nullptr support and this special case.
   if (end == 0) return 0;
-  const uint32 end_word = (end - 1) >> BitmapIndex::kStorageLogBitSize;
-  const uint32 sum = get_index_ones_count(end_word);
-  const size_t masked = end & kStorageBlockMask;
-  if (masked == 0) {
-    return sum + __builtin_popcountll(bits_[end_word]);
-  } else {
-    const uint64 zero = 0;
-    return sum + __builtin_popcountll(bits_[end_word] &
-                                      (~zero >> (kStorageBitSize - masked)));
-  }
+  // Without this special case, we'd go past the end.  It's questionable
+  // whether we should support end == Bits().
+  if (end >= num_bits_) return GetOnesCount();
+  const uint32 end_word = end / kStorageBitSize;
+  const uint32 sum = GetIndexOnesCount(end_word);
+  const int bit_index = end % kStorageBitSize;
+  // TODO(jrosenstock): better with or without special case, and does
+  // this depend on whether there's a popcnt instruction?
+  if (bit_index == 0) return sum;  // Entire answer is in the index.
+  const uint64 mask = (uint64{1} << bit_index) - 1;
+  return sum + __builtin_popcountll(bits_[end_word] & mask);
 }
 
 size_t BitmapIndex::Select1(size_t bit_index) const {
   if (bit_index >= GetOnesCount()) return Bits();
-  // search primary index for the relevant block
-  uint32 rembits = bit_index + 1;
-  const uint32 block = find_primary_block(bit_index + 1);
-  uint32 offset = 0;
-  if (block > 0) {
-    rembits -= primary_index_[block - 1];
-    offset += block * kSecondaryBlockSize;
-  }
-  // search the secondary index
-  uint32 word = find_secondary_block(offset, rembits);
-  if (word > 0) {
-    rembits -= secondary_index_[offset + word - 1];
-    offset += word;
-  }
-  int nth = nth_bit(bits_[offset], rembits);
-  return (offset << BitmapIndex::kStorageLogBitSize) + nth;
+  const RankIndexEntry& entry = FindRankIndexEntry(bit_index);
+  const uint32 block_index = &entry - rank_index_.data();
+  // TODO(jrosenstock): Look at whether word or bit indices are faster.
+  static_assert(kUnitsPerRankIndexEntry == 8);
+  uint32 word_index = block_index * kUnitsPerRankIndexEntry;
+
+  // Find position within this block.
+  uint32 rembits = bit_index - entry.absolute_ones_count();
+  if (rembits < entry.relative_ones_count_4()) {
+    if (rembits < entry.relative_ones_count_2()) {
+      if (rembits < entry.relative_ones_count_1()) {
+        // First word, nothing to do.
+      } else {
+        word_index += 1;
+        rembits -= entry.relative_ones_count_1();
+      }
+    } else if (rembits < entry.relative_ones_count_3()) {
+      word_index += 2;
+      rembits -= entry.relative_ones_count_2();
+    } else {
+      word_index += 3;
+      rembits -= entry.relative_ones_count_3();
+    }
+  } else if (rembits < entry.relative_ones_count_6()) {
+    if (rembits < entry.relative_ones_count_5()) {
+      word_index += 4;
+      rembits -= entry.relative_ones_count_4();
+    } else {
+      word_index += 5;
+      rembits -= entry.relative_ones_count_5();
+    }
+  } else if (rembits < entry.relative_ones_count_7()) {
+    word_index += 6;
+    rembits -= entry.relative_ones_count_6();
+  } else {
+    word_index += 7;
+    rembits -= entry.relative_ones_count_7();
+  }
+
+  const int nth = nth_bit(bits_[word_index], rembits);
+  return kStorageBitSize * word_index + nth;
 }
 
 size_t BitmapIndex::Select0(size_t bit_index) const {
-  if (bit_index >= Bits() - GetOnesCount()) return Bits();
-  // search inverted primary index for relevant block
-  uint32 remzeros = bit_index + 1;
-  uint32 offset = 0;
-  const uint32 block = find_inverted_primary_block(bit_index + 1);
-  if (block > 0) {
-    remzeros -= kPrimaryBlockBits * block - primary_index_[block - 1];
-    offset += block * kSecondaryBlockSize;
-  }
-  // search the inverted secondary index
-  uint32 word = find_inverted_secondary_block(offset, remzeros);
-  if (word > 0) {
-    remzeros -= BitmapIndex::kStorageBitSize * word -
-                secondary_index_[offset + word - 1];
-    offset += word;
-  }
-  int nth = nth_bit(~bits_[offset], remzeros);
-  return (offset << BitmapIndex::kStorageLogBitSize) + nth;
+  const uint32 zeros_count = Bits() - GetOnesCount();
+  if (bit_index >= zeros_count) return Bits();
+  const RankIndexEntry& entry = FindInvertedRankIndexEntry(bit_index);
+  const uint32 block_index = &entry - rank_index_.data();
+  static_assert(kUnitsPerRankIndexEntry == 8);
+  uint32 word_index = block_index * kUnitsPerRankIndexEntry;
+
+  // Find position within this block.
+  uint32 entry_zeros_count =
+      kStorageBitSize * word_index - entry.absolute_ones_count();
+  uint32 remzeros = bit_index - entry_zeros_count;
+  if (remzeros < 4 * kStorageBitSize - entry.relative_ones_count_4()) {
+    if (remzeros < 2 * kStorageBitSize - entry.relative_ones_count_2()) {
+      if (remzeros < kStorageBitSize - entry.relative_ones_count_1()) {
+        // Nothing to do.
+      } else {
+        word_index += 1;
+        remzeros -= kStorageBitSize - entry.relative_ones_count_1();
+      }
+    } else if (remzeros < 3 * kStorageBitSize - entry.relative_ones_count_3()) {
+      word_index += 2;
+      remzeros -= 2 * kStorageBitSize - entry.relative_ones_count_2();
+    } else {
+      word_index += 3;
+      remzeros -= 3 * kStorageBitSize - entry.relative_ones_count_3();
+    }
+  } else if (remzeros < 6 * kStorageBitSize - entry.relative_ones_count_6()) {
+    if (remzeros < 5 * kStorageBitSize - entry.relative_ones_count_5()) {
+      word_index += 4;
+      remzeros -= 4 * kStorageBitSize - entry.relative_ones_count_4();
+    } else {
+      word_index += 5;
+      remzeros -= 5 * kStorageBitSize - entry.relative_ones_count_5();
+    }
+  } else if (remzeros < 7 * kStorageBitSize - entry.relative_ones_count_7()) {
+    word_index += 6;
+    remzeros -= 6 * kStorageBitSize - entry.relative_ones_count_6();
+  } else {
+    word_index += 7;
+    remzeros -= 7 * kStorageBitSize - entry.relative_ones_count_7();
+  }
+
+  const int nth = nth_bit(~bits_[word_index], remzeros);
+  return kStorageBitSize * word_index + nth;
 }
 
 std::pair<size_t, size_t> BitmapIndex::Select0s(size_t bit_index) const {
-  const uint64 zero = 0;
-  const uint64 ones = ~zero;
-  size_t zeros_count = Bits() - GetOnesCount();
-  if (bit_index >= zeros_count) return std::make_pair(Bits(), Bits());
-  if (bit_index + 1 >= zeros_count) {
-    return std::make_pair(Select0(bit_index), Bits());
-  }
-  // search inverted primary index for relevant block
-  uint32 remzeros = bit_index + 1;
-  uint32 offset = 0;
-  const uint32 block = find_inverted_primary_block(bit_index + 1);
-  size_t num_zeros_in_block =
-      kPrimaryBlockBits * (1 + block) - primary_index_[block];
-  if (block > 0) {
-    size_t num_zeros_next =
-        kPrimaryBlockBits * block - primary_index_[block - 1];
-    num_zeros_in_block -= num_zeros_next;
-    remzeros -= num_zeros_next;
-    offset += block * kSecondaryBlockSize;
-  }
-  // search the inverted secondary index
-  uint32 word = find_inverted_secondary_block(offset, remzeros);
-  uint32 sum_zeros_next_word = BitmapIndex::kStorageBitSize * (1 + word) -
-                               secondary_index_[offset + word];
-  uint32 sum_zeros_this_word = 0;
-  if (word > 0) {
-    sum_zeros_this_word = BitmapIndex::kStorageBitSize * word -
-                          secondary_index_[offset + word - 1];
-    remzeros -= sum_zeros_this_word;
-    offset += word;
-  }
-  int nth = nth_bit(~bits_[offset], remzeros);
-  size_t current_zero = (offset << BitmapIndex::kStorageLogBitSize) + nth;
-
-  size_t next_zero;
-  // Does the current block contain the next zero?
-  if (num_zeros_in_block > remzeros + 1) {
-    if (sum_zeros_next_word - sum_zeros_this_word >= remzeros + 1) {
-      // the next zero is in this word
-      next_zero = (offset << BitmapIndex::kStorageLogBitSize) +
-                  nth_bit(~bits_[offset], remzeros + 1);
-    } else {
-      // Find the first field that is not all ones by linear scan.
-      // In the worst case, this may scan 8Kbytes.  The alternative is
-      // to inspect secondary_index_ looking for a place to jump to, but
-      // that would probably use more cache.
-      while (bits_[++offset] == ones) {
+  const uint32 zeros_count = Bits() - GetOnesCount();
+  if (bit_index >= zeros_count) return {Bits(), Bits()};
+  if (bit_index + 1 >= zeros_count) return {Select0(bit_index), Bits()};
+
+  const RankIndexEntry& entry = FindInvertedRankIndexEntry(bit_index);
+  const uint32 block_index = &entry - rank_index_.data();
+  uint32 word_index = block_index * kUnitsPerRankIndexEntry;
+
+  // Find position within this block.
+  uint32 entry_zeros_count =
+      kStorageBitSize * word_index - entry.absolute_ones_count();
+  uint32 remzeros = bit_index - entry_zeros_count;
+  if (remzeros < 4 * kStorageBitSize - entry.relative_ones_count_4()) {
+    if (remzeros < 2 * kStorageBitSize - entry.relative_ones_count_2()) {
+      if (remzeros < kStorageBitSize - entry.relative_ones_count_1()) {
+        // Nothing to do.
+      } else {
+        word_index += 1;
+        remzeros -= kStorageBitSize - entry.relative_ones_count_1();
       }
-      next_zero = (offset << BitmapIndex::kStorageLogBitSize) +
-                  __builtin_ctzll(~bits_[offset]);
+    } else if (remzeros < 3 * kStorageBitSize - entry.relative_ones_count_3()) {
+      word_index += 2;
+      remzeros -= 2 * kStorageBitSize - entry.relative_ones_count_2();
+    } else {
+      word_index += 3;
+      remzeros -= 3 * kStorageBitSize - entry.relative_ones_count_3();
+    }
+  } else if (remzeros < 6 * kStorageBitSize - entry.relative_ones_count_6()) {
+    if (remzeros < 5 * kStorageBitSize - entry.relative_ones_count_5()) {
+      word_index += 4;
+      remzeros -= 4 * kStorageBitSize - entry.relative_ones_count_4();
+    } else {
+      word_index += 5;
+      remzeros -= 5 * kStorageBitSize - entry.relative_ones_count_5();
     }
+  } else if (remzeros < 7 * kStorageBitSize - entry.relative_ones_count_7()) {
+    word_index += 6;
+    remzeros -= 6 * kStorageBitSize - entry.relative_ones_count_6();
   } else {
-    // the next zero is in a different block, a full search is required.
-    next_zero = Select0(bit_index + 1);
+    word_index += 7;
+    remzeros -= 7 * kStorageBitSize - entry.relative_ones_count_7();
+  }
+
+  // Find the position of the bit_index-th zero.
+  const uint64 inv_word = ~bits_[word_index];
+  const int nth = nth_bit(inv_word, remzeros);
+
+  // Then, we want to "1-out" everything below that position, and count trailing
+  // ones on the result.  This gives us the position of the next zero.
+  // There is no count trailing ones builtin, so we invert and use count
+  // trailing zeros.
+
+  // This mask has 1s in the nth+1 low order bits; it is equivalent to
+  // (1 << (nth + 1)) - 1, but doesn't need a special case when nth == 63.
+  // We want ~0 in this case anyway.  We want nth+1 because if the bit_index-th
+  // zero is in position nth, we need to skip nth+1 positions.
+  const uint64 mask = -(uint64{0x2} << nth);  // == ~((2 << nth) - 1)
+  const uint64 masked_inv_word = inv_word & mask;
+
+  // If this is 0, then the next zero is not in the same word.
+  if (masked_inv_word != 0) {
+    // We can't ctz on 0, but we already checked that.
+    const int next_nth = __builtin_ctzll(masked_inv_word);
+    return {kStorageBitSize * word_index + nth,
+            kStorageBitSize * word_index + next_nth};
+  } else {
+    // TODO(jrosenstock): Try other words in the block.
+    // This should not be massively important.  With a bit density of 1/2,
+    // 31/32 zeros in a word have the next zero in the same word.
+    return {kStorageBitSize * word_index + nth, Select0(bit_index + 1)};
   }
-  return std::make_pair(current_zero, next_zero);
 }
 
-size_t BitmapIndex::get_index_ones_count(size_t array_index) const {
-  uint32 sum = 0;
-  if (array_index > 0) {
-    sum += secondary_index_[array_index - 1];
-    uint32 end_block = (array_index - 1) / kSecondaryBlockSize;
-    if (end_block > 0) sum += primary_index_[end_block - 1];
+uint32 BitmapIndex::GetIndexOnesCount(size_t array_index) const {
+  const auto& rank_index_entry =
+      rank_index_[array_index / kUnitsPerRankIndexEntry];
+  uint32 ones_count = rank_index_entry.absolute_ones_count();
+  static_assert(kUnitsPerRankIndexEntry == 8);
+  switch (array_index % kUnitsPerRankIndexEntry) {
+    case 1:
+      ones_count += rank_index_entry.relative_ones_count_1();
+      break;
+    case 2:
+      ones_count += rank_index_entry.relative_ones_count_2();
+      break;
+    case 3:
+      ones_count += rank_index_entry.relative_ones_count_3();
+      break;
+    case 4:
+      ones_count += rank_index_entry.relative_ones_count_4();
+      break;
+    case 5:
+      ones_count += rank_index_entry.relative_ones_count_5();
+      break;
+    case 6:
+      ones_count += rank_index_entry.relative_ones_count_6();
+      break;
+    case 7:
+      ones_count += rank_index_entry.relative_ones_count_7();
+      break;
   }
-  return sum;
+  return ones_count;
 }
 
-void BitmapIndex::BuildIndex(const uint64 *bits, size_t num_bits) {
-  // Primary counts are uint32s, so this is the most *set* bits we support
+void BitmapIndex::BuildIndex(const uint64* bits, size_t num_bits,
+                             bool enable_select_0_index,
+                             bool enable_select_1_index) {
+  // Absolute counts are uint32s, so this is the most *set* bits we support
   // for now.  Just check the number of *input* bits is less than this
   // to keep things simple.
   DCHECK_LT(num_bits, uint64{1} << 32);
   bits_ = bits;
   num_bits_ = num_bits;
-  primary_index_.resize(primary_index_size());
-  secondary_index_.resize(ArraySize());
-  const uint64 zero = 0;
-  const uint64 ones = ~zero;
-  uint32 popcount = 0;
-  // We keep the primary index zero for empty bitmaps.
-  if (ArraySize() == 0) primary_index_.at(0) = 0;
-  for (uint32 block = 0; block * kSecondaryBlockSize < ArraySize(); block++) {
-    uint32 block_popcount = 0;
-    uint32 block_begin = block * kSecondaryBlockSize;
-    uint32 block_end = block_begin + kSecondaryBlockSize;
-    if (block_end > ArraySize()) block_end = ArraySize();
-    for (uint32 j = block_begin; j < block_end; ++j) {
-      uint64 mask = ones;
-      if (j == ArraySize() - 1) {
-        mask = ones >> (-num_bits_ & BitmapIndex::kStorageBlockMask);
+  rank_index_.resize(rank_index_size());
+
+  select_0_index_.clear();
+  if (enable_select_0_index) {
+    // Reserve approximately enough for density = 1/2.
+    select_0_index_.reserve(num_bits / (2 * kBitsPerSelect0Block) + 1);
+  }
+
+  select_1_index_.clear();
+  if (enable_select_1_index) {
+    select_1_index_.reserve(num_bits / (2 * kBitsPerSelect1Block) + 1);
+  }
+
+  uint32 ones_count = 0;
+  uint32 zeros_count = 0;  // Only updated if enable_select_0_index.
+  for (uint32 word_index = 0; word_index < ArraySize(); ++word_index) {
+    auto& rank_index_entry = rank_index_[word_index / kUnitsPerRankIndexEntry];
+    static_assert(kUnitsPerRankIndexEntry == 8);
+    switch (word_index % kUnitsPerRankIndexEntry) {
+      case 0:
+        rank_index_entry.set_absolute_ones_count(ones_count);
+        break;
+      case 1:
+        rank_index_entry.set_relative_ones_count_1(
+            ones_count - rank_index_entry.absolute_ones_count());
+        break;
+      case 2:
+        rank_index_entry.set_relative_ones_count_2(
+            ones_count - rank_index_entry.absolute_ones_count());
+        break;
+      case 3:
+        rank_index_entry.set_relative_ones_count_3(
+            ones_count - rank_index_entry.absolute_ones_count());
+        break;
+      case 4:
+        rank_index_entry.set_relative_ones_count_4(
+            ones_count - rank_index_entry.absolute_ones_count());
+        break;
+      case 5:
+        rank_index_entry.set_relative_ones_count_5(
+            ones_count - rank_index_entry.absolute_ones_count());
+        break;
+      case 6:
+        rank_index_entry.set_relative_ones_count_6(
+            ones_count - rank_index_entry.absolute_ones_count());
+        break;
+      case 7:
+        rank_index_entry.set_relative_ones_count_7(
+            ones_count - rank_index_entry.absolute_ones_count());
+        break;
+    }
+
+    // We can assume that the last word has zeros in the high bits.
+    const uint64 word = bits[word_index];
+    const int word_ones_count = __builtin_popcountll(word);
+    const uint32 bit_offset = kStorageBitSize * word_index;
+
+    if (enable_select_0_index) {
+      // Zeros count is somewhat move involved to compute, so only do it
+      // if we need it.  The last word has zeros in the high bits, so
+      // that needs to be accounted for when computing the zeros count
+      // from the ones count.
+      const uint32 bits_remaining = num_bits - bit_offset;
+      const int word_zeros_count =
+          std::min(bits_remaining, kStorageBitSize) - word_ones_count;
+
+      // We record a 0 every kBitsPerSelect0Block bits.  So, if zeros_count
+      // is 0 mod kBitsPerSelect0Block, we record the next zero.  If
+      // zeros_count is 1 mod kBitsPerSelect0Block, we need to skip
+      // kBitsPerSelect0Block - 1 zeros, then record a zero.  And so on.
+      // What function is this?  It's -zeros_count % kBitsPerSelect0Block.
+      const uint32 zeros_to_skip = -zeros_count % kBitsPerSelect0Block;
+      if (word_zeros_count > zeros_to_skip) {
+        const int nth = nth_bit(~word, zeros_to_skip);
+        select_0_index_.push_back(bit_offset + nth);
       }
-      block_popcount += __builtin_popcountll(bits_[j] & mask);
-      secondary_index_[j] = block_popcount;
+
+      zeros_count += word_zeros_count;
     }
-    popcount += block_popcount;
-    primary_index_[block] = popcount;
+
+    if (enable_select_1_index) {
+      const uint32 ones_to_skip = -ones_count % kBitsPerSelect1Block;
+      if (word_ones_count > ones_to_skip) {
+        const int nth = nth_bit(word, ones_to_skip);
+        select_1_index_.push_back(bit_offset + nth);
+      }
+    }
+
+    ones_count += word_ones_count;
   }
-}
 
-size_t BitmapIndex::find_secondary_block(size_t block_begin,
-                                         size_t rem_bit_index) const {
-  size_t block_end = block_begin + kSecondaryBlockSize;
-  if (block_end > ArraySize()) block_end = ArraySize();
-  return std::distance(
-      secondary_index_.begin() + block_begin,
-      std::lower_bound(secondary_index_.begin() + block_begin,
-                       secondary_index_.begin() + block_end, rem_bit_index));
-}
+  // Do we have any extra bits that need to be recorded?
+  // We already recorded all the lower relative positions,
+  // so we need to do the higher ones.
+  // This is only necessary if num_bits % kBitsPerRankIndexEntry != 0,
+  // but if it is 0, we end up in case 7 and do nothing.  This also
+  // holds for num_bits == 0.  If we do have an if statement guarding
+  // this, mutants complains that it can be changed to if (true).
+  // Therefore, we complicate the understanding of the code to please the
+  // tools.
+  auto& rank_index_entry = rank_index_[(num_bits - 1) / kBitsPerRankIndexEntry];
+  switch (((num_bits - 1) / kStorageBitSize) % kUnitsPerRankIndexEntry) {
+    case 0:
+      rank_index_entry.set_relative_ones_count_1(
+          ones_count - rank_index_entry.absolute_ones_count());
+    case 1:
+      rank_index_entry.set_relative_ones_count_2(
+          ones_count - rank_index_entry.absolute_ones_count());
+    case 2:
+      rank_index_entry.set_relative_ones_count_3(
+          ones_count - rank_index_entry.absolute_ones_count());
+    case 3:
+      rank_index_entry.set_relative_ones_count_4(
+          ones_count - rank_index_entry.absolute_ones_count());
+    case 4:
+      rank_index_entry.set_relative_ones_count_5(
+          ones_count - rank_index_entry.absolute_ones_count());
+    case 5:
+      rank_index_entry.set_relative_ones_count_6(
+          ones_count - rank_index_entry.absolute_ones_count());
+    case 6:
+      rank_index_entry.set_relative_ones_count_7(
+          ones_count - rank_index_entry.absolute_ones_count());
+    case 7:
+      // Nothing to do, this count will be included in the final
+      // absolute count.
+      break;
+  }
+
+  // Add the extra entry with the total number of bits.
+  rank_index_.back().set_absolute_ones_count(ones_count);
+
+  if (enable_select_0_index) {
+    // Add extra entry with num_bits_.
+    select_0_index_.push_back(num_bits_);
+    select_0_index_.shrink_to_fit();
+  }
 
-size_t BitmapIndex::find_inverted_secondary_block(size_t block_begin,
-                                                  size_t rem_bit_index) const {
-  size_t block_end = block_begin + kSecondaryBlockSize;
-  if (block_end > ArraySize()) block_end = ArraySize();
-  return InvertedSearch<BitmapIndex::kStorageBitSize>(secondary_index_,
-                                                      block_begin, block_end,
-                                                      rem_bit_index)
-      - block_begin;
+  if (enable_select_1_index) {
+    select_1_index_.push_back(num_bits_);
+    select_1_index_.shrink_to_fit();
+  }
 }
 
-inline size_t BitmapIndex::find_primary_block(size_t bit_index) const {
-  return std::distance(
-      primary_index_.begin(),
-      std::lower_bound(primary_index_.begin(), primary_index_.end(),
-                       bit_index));
+const BitmapIndex::RankIndexEntry& BitmapIndex::FindRankIndexEntry(
+    size_t bit_index) const {
+  DCHECK_GE(bit_index, 0);
+  DCHECK_LT(bit_index, rank_index_.back().absolute_ones_count());
+
+  const RankIndexEntry* begin = nullptr;
+  const RankIndexEntry* end = nullptr;
+  if (select_1_index_.empty()) {
+    begin = &rank_index_[0];
+    end = begin + rank_index_.size();
+  } else {
+    const uint32 select_index = bit_index / kBitsPerSelect1Block;
+    DCHECK_LT(select_index + 1, select_1_index_.size());
+
+    // TODO(jrosenstock): It would be nice to handle the exact hit
+    // bit_index % kBitsPerSelect1Block == 0 case so we could
+    // return the value, but that requiries some refactoring:
+    // either inlining this into Select1, or returning a pair
+    // or out param, etc.
+
+    // The bit is between these indices.
+    const uint32 lo_bit_index = select_1_index_[select_index];
+    const uint32 hi_bit_index = select_1_index_[select_index + 1];
+
+    begin = &rank_index_[lo_bit_index / kBitsPerSelect1Block];
+    end = &rank_index_[(hi_bit_index + kBitsPerSelect1Block - 1) /
+                       kBitsPerSelect1Block];
+  }
+
+  // Linear search if the range is small.
+  const RankIndexEntry* entry = nullptr;
+  if (end - begin <= kMaxLinearSearchBlocks) {
+    for (entry = begin; entry != end; ++entry) {
+      if (entry->absolute_ones_count() > bit_index) break;
+    }
+  } else {
+    RankIndexEntry search_entry;
+    search_entry.set_absolute_ones_count(bit_index);
+    // TODO(jrosenstock): benchmark upper vs custom bsearch.
+    entry = &*std::upper_bound(
+        begin, end, search_entry,
+        [](const RankIndexEntry& e1, const RankIndexEntry& e2) {
+          return e1.absolute_ones_count() < e2.absolute_ones_count();
+        });
+  }
+
+  const auto& e = *(entry - 1);
+  DCHECK_LE(e.absolute_ones_count(), bit_index);
+  DCHECK_GT(entry->absolute_ones_count(), bit_index);
+  return e;
 }
 
-size_t BitmapIndex::find_inverted_primary_block(size_t bit_index) const {
-  return InvertedSearch<kPrimaryBlockBits>(
-      primary_index_, 0, primary_index_.size(), bit_index);
+const BitmapIndex::RankIndexEntry& BitmapIndex::FindInvertedRankIndexEntry(
+    size_t bit_index) const {
+  DCHECK_GE(bit_index, 0);
+  DCHECK_LT(bit_index, num_bits_ - rank_index_.back().absolute_ones_count());
+
+  uint32 lo = 0, hi = 0;
+  if (select_0_index_.empty()) {
+    lo = 0;
+    hi = (num_bits_ + kBitsPerRankIndexEntry - 1) / kBitsPerRankIndexEntry;
+  } else {
+    const uint32 select_index = bit_index / kBitsPerSelect0Block;
+    DCHECK_LT(select_index + 1, select_0_index_.size());
+
+    // TODO(jrosenstock): Same special case for exact hit.
+
+    lo = select_0_index_[select_index] / kBitsPerSelect0Block;
+    hi = (select_0_index_[select_index + 1] + kBitsPerSelect0Block - 1) /
+         kBitsPerSelect0Block;
+  }
+
+  DCHECK_LT(hi, rank_index_.size());
+  // Linear search never showed an advantage when benchmarking.  This may be
+  // because the linear search is more complex with the zeros_count computation,
+  // or because the ranges are larger, so linear search is triggered less often,
+  // and the difference is harder to measure.
+  while (lo + 1 < hi) {
+    const uint32 mid = lo + (hi - lo) / 2;
+    if (bit_index <
+        kBitsPerRankIndexEntry * mid - rank_index_[mid].absolute_ones_count()) {
+      hi = mid;
+    } else {
+      lo = mid;
+    }
+  }
+
+  DCHECK_LE(lo * kBitsPerRankIndexEntry - rank_index_[lo].absolute_ones_count(),
+            bit_index);
+  if ((lo + 1) * kBitsPerRankIndexEntry <= num_bits_) {
+    DCHECK_GT((lo + 1) * kBitsPerRankIndexEntry -
+                  rank_index_[lo + 1].absolute_ones_count(),
+              bit_index);
+  } else {
+    DCHECK_GT(num_bits_ - rank_index_[lo + 1].absolute_ones_count(), bit_index);
+  }
+  return rank_index_[lo];
 }
+
 }  // end namespace fst
index 15940eb..f21b161 100644 (file)
@@ -8,9 +8,9 @@
 #include <fst/arc.h>
 #include <fst/register.h>
 
+using fst::LogArc;
 using fst::NGramFst;
 using fst::StdArc;
-using fst::LogArc;
 
 REGISTER_FST(NGramFst, StdArc);
 REGISTER_FST(NGramFst, LogArc);
index aec0749..2b5159f 100644 (file)
@@ -218,8 +218,10 @@ static const uint8 nth_bit_bit_pos[8][256] = {
     }};
 
 uint32 nth_bit(const uint64 v, uint32 r) {
-  // nth_bit uses 1-origin for r, but code below is more natural with 0-origin.
-  r--;
+  DCHECK_NE(v, 0);
+  DCHECK_LE(0, r);
+  DCHECK_LT(r, __builtin_popcountll(v));
+
   uint32 next_byte = v & 255;
   uint32 byte_popcount = nth_bit_bit_count[next_byte];
   if (r < byte_popcount) return nth_bit_bit_pos[r][next_byte];
@@ -258,9 +260,9 @@ uint32 nth_bit(const uint64 v, uint32 r) {
 // These tables are generated using:
 //
 //  constexpr uint64 kOnesStep8 = 0x0101010101010101;
-//  printf("const uint64 kPrefixSumOverflow[65] = {\n");
-//  for (int k = 0; k <= 64; ++k) {
-//    printf("  0x%" FST_LL_FORMAT "x,\n",  (0x80 - k) * kOnesStep8);
+//  printf("const uint64 kPrefixSumOverflow[64] = {\n");
+//  for (int k = 0; k < 64; ++k) {
+//    printf("  0x%" FST_LL_FORMAT "x,\n",  (0x7F - k) * kOnesStep8);
 //  }
 //  printf("};\n");
 //
@@ -279,8 +281,7 @@ uint32 nth_bit(const uint64 v, uint32 r) {
 namespace internal {
 
 // clang-format off
-const uint64 kPrefixSumOverflow[65] = {
-  0x8080808080808080,
+const uint64 kPrefixSumOverflow[64] = {
   0x7f7f7f7f7f7f7f7f,
   0x7e7e7e7e7e7e7e7e,
   0x7d7d7d7d7d7d7d7d,
@@ -487,7 +488,7 @@ const uint8 kSelectInByte[8 * 256] = {
 // clang-format on
 
 }  // namespace internal
-#endif  // 64-bit, non-BMI2
-#endif  // !defined(__BMI2__)
+#endif                        // 64-bit, non-BMI2
+#endif                        // !defined(__BMI2__)
 
 }  // namespace fst
index a152890..304cbca 100644 (file)
@@ -24,7 +24,7 @@ endif
 if HAVE_SCRIPT
 lib_LTLIBRARIES = libfstpdtscript.la
 libfstpdtscript_la_SOURCES = getters.cc pdtscript.cc
-libfstpdtscript_la_LDFLAGS = -version-info 20:0:0
+libfstpdtscript_la_LDFLAGS = -version-info 21:0:0
 libfstpdtscript_la_LIBADD = ../../script/libfstscript.la \
                             ../../lib/libfst.la -lm $(DL_LIBS)
 endif
index 01a3b0f..846f3db 100644 (file)
@@ -428,7 +428,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @HAVE_BIN_TRUE@pdtshortestpath_SOURCES = pdtshortestpath.cc pdtshortestpath-main.cc
 @HAVE_SCRIPT_TRUE@lib_LTLIBRARIES = libfstpdtscript.la
 @HAVE_SCRIPT_TRUE@libfstpdtscript_la_SOURCES = getters.cc pdtscript.cc
-@HAVE_SCRIPT_TRUE@libfstpdtscript_la_LDFLAGS = -version-info 20:0:0
+@HAVE_SCRIPT_TRUE@libfstpdtscript_la_LDFLAGS = -version-info 21:0:0
 @HAVE_SCRIPT_TRUE@libfstpdtscript_la_LIBADD = ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@                            ../../lib/libfst.la -lm $(DL_LIBS)
 
index 39f4afb..b8def6a 100644 (file)
@@ -23,9 +23,9 @@ DECLARE_string(compose_filter);
 
 int pdtcompose_main(int argc, char **argv) {
   namespace s = fst::script;
-  using fst::ReadLabelPairs;
   using fst::PdtComposeFilter;
   using fst::PdtComposeOptions;
+  using fst::ReadLabelPairs;
   using fst::script::FstClass;
   using fst::script::VectorFstClass;
 
index 8ba6937..36e9f0a 100644 (file)
@@ -22,10 +22,10 @@ DECLARE_string(weight);
 
 int pdtexpand_main(int argc, char **argv) {
   namespace s = fst::script;
+  using fst::ReadLabelPairs;
   using fst::script::FstClass;
   using fst::script::VectorFstClass;
   using fst::script::WeightClass;
-  using fst::ReadLabelPairs;
 
   std::string usage = "Expand a (bounded-stack) PDT as an FST.\n\n  Usage: ";
   usage += argv[0];
index c983210..6a2d087 100644 (file)
@@ -36,10 +36,10 @@ void Cleanup(std::vector<std::pair<int64, const FstClass *>> *pairs) {
 
 int pdtreplace_main(int argc, char **argv) {
   namespace s = fst::script;
-  using fst::script::FstClass;
-  using fst::script::VectorFstClass;
   using fst::PdtParserType;
   using fst::WriteLabelPairs;
+  using fst::script::FstClass;
+  using fst::script::VectorFstClass;
 
   std::string usage = "Converts an RTN represented by FSTs";
   usage += " and non-terminal labels into PDT.\n\n  Usage: ";
@@ -61,8 +61,8 @@ int pdtreplace_main(int argc, char **argv) {
 
   PdtParserType parser_type;
   if (!s::GetPdtParserType(FLAGS_pdt_parser_type, &parser_type)) {
-    LOG(ERROR) << argv[0] << ": Unknown PDT parser type: "
-               << FLAGS_pdt_parser_type;
+    LOG(ERROR) << argv[0]
+               << ": Unknown PDT parser type: " << FLAGS_pdt_parser_type;
     delete ifst;
     return 1;
   }
index 1237c64..a2c4a85 100644 (file)
@@ -13,9 +13,11 @@ DEFINE_int64(start_paren_labels, fst::kNoLabel,
              "Index to use for the first inserted parentheses; if not "
              "specified, the next available label beyond the highest output "
              "label is used");
-DEFINE_string(left_paren_prefix, "(_", "Prefix to attach to SymbolTable "
+DEFINE_string(left_paren_prefix, "(_",
+              "Prefix to attach to SymbolTable "
               "labels for inserted left parentheses");
-DEFINE_string(right_paren_prefix, ")_", "Prefix to attach to SymbolTable "
+DEFINE_string(right_paren_prefix, ")_",
+              "Prefix to attach to SymbolTable "
               "labels for inserted right parentheses");
 
 int pdtreplace_main(int argc, char **argv);
index 7978dbb..ce0779a 100644 (file)
@@ -22,10 +22,10 @@ DECLARE_string(pdt_parentheses);
 
 int pdtshortestpath_main(int argc, char **argv) {
   namespace s = fst::script;
-  using fst::script::FstClass;
-  using fst::script::VectorFstClass;
   using fst::QueueType;
   using fst::ReadLabelPairs;
+  using fst::script::FstClass;
+  using fst::script::VectorFstClass;
 
   std::string usage = "Shortest path in a (bounded-stack) PDT.\n\n  Usage: ";
   usage += argv[0];
index c3f8d86..01480d0 100644 (file)
@@ -1,3 +1,4 @@
+#cython: language_level=3
 # See www.openfst.org for extensive documentation on this weighted
 # finite-state transducer library.
 
index e1b16b0..02dda61 100644 (file)
@@ -1,8 +1,10 @@
+#cython: language_level=3
 # See www.openfst.org for extensive documentation on this weighted
 # finite-state transducer library.
 
 
 from libcpp.string cimport string
+
 from cintegral_types cimport int8
 from cintegral_types cimport int16
 from cintegral_types cimport int32
index bb5b90c..681ebdb 100644 (file)
@@ -1,6 +1,8 @@
+#cython: language_level=3
 # See www.openfst.org for extensive documentation on this weighted
 # finite-state transducer library.
 
+
 from libcpp cimport bool
 from libcpp.string cimport string
 from libcpp.vector cimport vector
@@ -127,9 +129,11 @@ cdef extern from "<fst/fstlib.h>" namespace "fst" nogil:
     EPS_NORM_INPUT
     EPS_NORM_OUTPUT
 
-  enum ProjectType:
-    PROJECT_INPUT
-    PROJECT_OUTPUT
+  # TODO(wolfsonkin): Don't do this hack if Cython gets proper enum class
+  # support: https://github.com/cython/cython/issues/1603
+  ctypedef enum ProjectType:
+    PROJECT_INPUT "fst::ProjectType::INPUT"
+    PROJECT_OUTPUT "fst::ProjectType::OUTPUT"
 
   enum QueueType:
     TRIVIAL_QUEUE
@@ -257,6 +261,13 @@ cdef extern from "<fst/fstlib.h>" namespace "fst" nogil:
 
   SymbolTable *FstReadSymbols(const string &, bool)
 
+  # TODO(wolfsonkin): Don't do this hack if Cython gets proper enum class
+  # support: https://github.com/cython/cython/issues/1603.
+  ctypedef enum TokenType:
+    SYMBOL "fst::TokenType::SYMBOL"
+    BYTE "fst::TokenType::BYTE"
+    UTF8 "fst::TokenType::UTF8"
+
 
 cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
@@ -613,7 +624,7 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
 
   cdef void Minimize(MutableFstClass *, MutableFstClass *, float, bool)
 
-  cdef ProjectType GetProjectType(bool)
+  cdef bool GetProjectType(const string &, ProjectType *)
 
   cdef void Project(MutableFstClass *, ProjectType)
 
@@ -747,15 +758,19 @@ cdef extern from "<fst/script/getters.h>" namespace "fst::script" nogil:
 
   cdef ReweightType GetReweightType(bool)
 
+  cdef bool GetTokenType(const string &, TokenType *)
+
 
 cdef extern from "<fst/extensions/far/far.h>" namespace "fst" nogil:
 
-  enum FarType:
-    FAR_DEFAULT
-    FAR_STTABLE
-    FAR_STLIST
-    FAR_FST
-    FAR_SSTABLE
+  # TODO(wolfsonkin): Don't do this hack if Cython gets proper enum class
+  # support: https://github.com/cython/cython/issues/1603
+  ctypedef enum FarType:
+    FAR_DEFAULT "fst::FarType::DEFAULT"
+    FAR_STTABLE "fst::FarType::STTABLE"
+    FAR_STLIST "fst::FarType::STLIST"
+    FAR_FST "fst::FarType::FST"
+    FAR_SSTABLE "fst::FarType::SSTABLE"
 
 cdef extern from "<fst/extensions/far/getters.h>" \
     namespace "fst" nogil:
@@ -766,7 +781,7 @@ cdef extern from "<fst/extensions/far/getters.h>" \
 cdef extern from "<fst/extensions/far/getters.h>" \
     namespace "fst::script" nogil:
 
-  FarType GetFarType(const string &)
+  bool GetFarType(const string &, FarType *)
 
 
 cdef extern from "<fst/extensions/far/far-class.h>" \
index c9db544..9844e49 100644 (file)
@@ -1,3 +1,4 @@
+#cython: language_level=3
 # See www.openfst.org for extensive documentation on this weighted
 # finite-state transducer library.
 
@@ -5,8 +6,6 @@
 #TODO(kbg): When/if PR https://github.com/cython/cython/pull/3358 is merged
 # and we update third-party Cython up to or beyond a version that includes
 # this, delete this file and instead use libcpp.utility.move.
-
-
 cdef extern from * namespace "fst":
     """
     #include <type_traits>
index 9f08b01..416f242 100644 (file)
@@ -1,33 +1,4 @@
-/* Generated by Cython 0.29.15 */
-
-/* BEGIN: Cython Metadata
-{
-    "distutils": {
-        "depends": [],
-        "extra_compile_args": [
-            "-std=c++17",
-            "-Wno-register",
-            "-Wno-unused-function",
-            "-Wno-unused-local-typedefs",
-            "-funsigned-char"
-        ],
-        "language": "c++",
-        "libraries": [
-            "fstfarscript",
-            "fstfar",
-            "fstscript",
-            "fst",
-            "m",
-            "dl"
-        ],
-        "name": "pywrapfst",
-        "sources": [
-            "src/pywrapfst.pyx"
-        ]
-    },
-    "module_name": "pywrapfst"
-}
-END: Cython Metadata */
+/* Generated by Cython 0.29.20 */
 
 #define PY_SSIZE_T_CLEAN
 #include "Python.h"
@@ -36,8 +7,8 @@ END: Cython Metadata */
 #elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000)
     #error Cython requires Python 2.6+ or Python 3.3+.
 #else
-#define CYTHON_ABI "0_29_15"
-#define CYTHON_HEX_VERSION 0x001D0FF0
+#define CYTHON_ABI "0_29_20"
+#define CYTHON_HEX_VERSION 0x001D14F0
 #define CYTHON_FUTURE_DIVISION 1
 #include <stddef.h>
 #ifndef offsetof
@@ -527,8 +498,10 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) {
   #define PyString_Type                PyUnicode_Type
   #define PyString_Check               PyUnicode_Check
   #define PyString_CheckExact          PyUnicode_CheckExact
+#ifndef PyObject_Unicode
   #define PyObject_Unicode             PyObject_Str
 #endif
+#endif
 #if PY_MAJOR_VERSION >= 3
   #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
   #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)
@@ -539,6 +512,13 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) {
 #ifndef PySet_CheckExact
   #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
 #endif
+#if PY_VERSION_HEX >= 0x030900A4
+  #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt)
+  #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size)
+#else
+  #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt)
+  #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size)
+#endif
 #if CYTHON_ASSUME_SAFE_MACROS
   #define __Pyx_PySequence_SIZE(seq)  Py_SIZE(seq)
 #else
@@ -619,11 +599,10 @@ static CYTHON_INLINE float __PYX_NAN() {
 #define __Pyx_truncl truncl
 #endif
 
-
+#define __PYX_MARK_ERR_POS(f_index, lineno) \
+    { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; }
 #define __PYX_ERR(f_index, lineno, Ln_error) \
-{ \
-  __pyx_filename = __pyx_f[f_index]; __pyx_lineno = lineno; __pyx_clineno = __LINE__; goto Ln_error; \
-}
+    { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; }
 
 #ifndef __PYX_EXTERN_C
   #ifdef __cplusplus
@@ -636,8 +615,6 @@ static CYTHON_INLINE float __PYX_NAN() {
 #define __PYX_HAVE__pywrapfst
 #define __PYX_HAVE_API__pywrapfst
 /* Early includes */
-#include <stddef.h>
-#include <time.h>
 #include "ios"
 #include "new"
 #include "stdexcept"
@@ -646,6 +623,17 @@ static CYTHON_INLINE float __PYX_NAN() {
 #include <string.h>
 #include <string>
 #include <utility>
+
+    #if __cplusplus > 199711L
+    #include <type_traits>
+
+    namespace cython_std {
+    template <typename T> typename std::remove_reference<T>::type&& move(T& t) noexcept { return std::move(t); }
+    template <typename T> typename std::remove_reference<T>::type&& move(T&& t) noexcept { return std::move(t); }
+    }
+
+    #endif
+    
 #include <vector>
 #include <stdint.h>
 #include <fst/types.h>
@@ -659,8 +647,8 @@ static CYTHON_INLINE float __PYX_NAN() {
 #include <fst/extensions/far/far.h>
 #include <fst/extensions/far/getters.h>
 #include <fst/extensions/far/far-class.h>
-#include <sys/types.h>
-#include <unistd.h>
+#include <stddef.h>
+#include <time.h>
 #include <fst/compat.h>
 
     #include <type_traits>
@@ -888,13 +876,13 @@ static const char *__pyx_filename;
 
 
 static const char *__pyx_f[] = {
-  "src/pywrapfst.pyx",
+  "pywrapfst.pyx",
   "stringsource",
 };
 
 /*--- Type declarations ---*/
 struct __pyx_obj_9pywrapfst_Weight;
-struct __pyx_obj_9pywrapfst__SymbolTable;
+struct __pyx_obj_9pywrapfst_SymbolTableView;
 struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView;
 struct __pyx_obj_9pywrapfst__FstSymbolTableView;
 struct __pyx_obj_9pywrapfst__MutableSymbolTable;
@@ -914,7 +902,7 @@ struct __pyx_obj_9pywrapfst_FarReader;
 struct __pyx_obj_9pywrapfst_FarWriter;
 struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__;
 
-/* "cpywrapfst.pxd":500
+/* "cpywrapfst.pxd":507
  * 
  * 
  * ctypedef pair[int64, const FstClass *] LabelFstClassPair             # <<<<<<<<<<<<<<
@@ -923,7 +911,7 @@ struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__;
  */
 typedef std::pair<int64,fst::script::FstClass const *>  __pyx_t_10cpywrapfst_LabelFstClassPair;
 
-/* "cpywrapfst.pxd":502
+/* "cpywrapfst.pxd":509
  * ctypedef pair[int64, const FstClass *] LabelFstClassPair
  * 
  * ctypedef pair[int64, int64] LabelPair             # <<<<<<<<<<<<<<
@@ -934,13 +922,11 @@ typedef std::pair<int64,int64>  __pyx_t_10cpywrapfst_LabelPair;
 struct __pyx_opt_args_9pywrapfst_19_MutableSymbolTable_add_symbol;
 struct __pyx_opt_args_9pywrapfst_3Fst_draw;
 struct __pyx_opt_args_9pywrapfst_3Fst_print;
-struct __pyx_opt_args_9pywrapfst_3Fst_text;
 struct __pyx_opt_args_9pywrapfst_10MutableFst__arcsort;
 struct __pyx_opt_args_9pywrapfst_10MutableFst__closure;
 struct __pyx_opt_args_9pywrapfst_10MutableFst__delete_arcs;
 struct __pyx_opt_args_9pywrapfst_10MutableFst__delete_states;
 struct __pyx_opt_args_9pywrapfst_10MutableFst__minimize;
-struct __pyx_opt_args_9pywrapfst_10MutableFst__project;
 struct __pyx_opt_args_9pywrapfst_10MutableFst__prune;
 struct __pyx_opt_args_9pywrapfst_10MutableFst__push;
 struct __pyx_opt_args_9pywrapfst_10MutableFst__relabel_pairs;
@@ -992,7 +978,7 @@ typedef fst::SymbolTable const *__pyx_t_9pywrapfst_const_SymbolTable_ptr;
  * 
  *   cpdef int64 add_symbol(self, symbol, int64 key=?) except *             # <<<<<<<<<<<<<<
  * 
- *   cpdef void add_table(self, _SymbolTable syms) except *
+ *   cpdef void add_table(self, SymbolTableView syms) except *
  */
 struct __pyx_opt_args_9pywrapfst_19_MutableSymbolTable_add_symbol {
   int __pyx_n;
@@ -1049,13 +1035,13 @@ typedef fst::script::VectorFstClass *__pyx_t_9pywrapfst_VectorFstClass_ptr;
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
  *                   source,
- *                   _SymbolTable isymbols=?,
+ *                   SymbolTableView isymbols=?,
  */
 struct __pyx_opt_args_9pywrapfst_3Fst_draw {
   int __pyx_n;
-  struct __pyx_obj_9pywrapfst__SymbolTable *isymbols;
-  struct __pyx_obj_9pywrapfst__SymbolTable *osymbols;
-  struct __pyx_obj_9pywrapfst__SymbolTable *ssymbols;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *isymbols;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *osymbols;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *ssymbols;
   bool acceptor;
   PyObject *title;
   double width;
@@ -1074,37 +1060,20 @@ struct __pyx_opt_args_9pywrapfst_3Fst_draw {
  *   cpdef _FstSymbolTableView output_symbols(self)
  * 
  *   cpdef string print(self,             # <<<<<<<<<<<<<<
- *                     _SymbolTable isymbols=?,
- *                     _SymbolTable osymbols=?,
+ *                     SymbolTableView isymbols=?,
+ *                     SymbolTableView osymbols=?,
  */
 struct __pyx_opt_args_9pywrapfst_3Fst_print {
   int __pyx_n;
-  struct __pyx_obj_9pywrapfst__SymbolTable *isymbols;
-  struct __pyx_obj_9pywrapfst__SymbolTable *osymbols;
-  struct __pyx_obj_9pywrapfst__SymbolTable *ssymbols;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *isymbols;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *osymbols;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *ssymbols;
   bool acceptor;
   bool show_weight_one;
   PyObject *missing_sym;
 };
 
-/* "pywrapfst.pxd":308
- *   cpdef StateIterator states(self)
- * 
- *   cpdef string text(self,             # <<<<<<<<<<<<<<
- *                     _SymbolTable isymbols=?,
- *                     _SymbolTable osymbols=?,
- */
-struct __pyx_opt_args_9pywrapfst_3Fst_text {
-  int __pyx_n;
-  struct __pyx_obj_9pywrapfst__SymbolTable *isymbols;
-  struct __pyx_obj_9pywrapfst__SymbolTable *osymbols;
-  struct __pyx_obj_9pywrapfst__SymbolTable *ssymbols;
-  bool acceptor;
-  bool show_weight_one;
-  PyObject *missing_sym;
-};
-
-/* "pywrapfst.pxd":337
+/* "pywrapfst.pxd":329
  *   cpdef void add_states(self, size_t)
  * 
  *   cdef void _arcsort(self, sort_type=?) except *             # <<<<<<<<<<<<<<
@@ -1116,7 +1085,7 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__arcsort {
   PyObject *sort_type;
 };
 
-/* "pywrapfst.pxd":339
+/* "pywrapfst.pxd":331
  *   cdef void _arcsort(self, sort_type=?) except *
  * 
  *   cdef void _closure(self, bool closure_plus=?)             # <<<<<<<<<<<<<<
@@ -1128,7 +1097,7 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__closure {
   bool closure_plus;
 };
 
-/* "pywrapfst.pxd":347
+/* "pywrapfst.pxd":339
  *   cdef void _decode(self, EncodeMapper) except *
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=?) except *             # <<<<<<<<<<<<<<
@@ -1140,7 +1109,7 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__delete_arcs {
   size_t n;
 };
 
-/* "pywrapfst.pxd":349
+/* "pywrapfst.pxd":341
  *   cdef void _delete_arcs(self, int64 state, size_t n=?) except *
  * 
  *   cdef void _delete_states(self, states=?) except *             # <<<<<<<<<<<<<<
@@ -1152,7 +1121,7 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__delete_states {
   PyObject *states;
 };
 
-/* "pywrapfst.pxd":355
+/* "pywrapfst.pxd":347
  *   cdef void _invert(self)
  * 
  *   cdef void _minimize(self, float delta=?, bool allow_nondet=?) except *             # <<<<<<<<<<<<<<
@@ -1165,20 +1134,8 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__minimize {
   bool allow_nondet;
 };
 
-/* "pywrapfst.pxd":361
- *   cpdef int64 num_states(self)
- * 
- *   cdef void _project(self, bool project_output=?) except *             # <<<<<<<<<<<<<<
- * 
- *   cdef void _prune(self, float delta=?, int64 nstate=?, weight=?) except *
- */
-struct __pyx_opt_args_9pywrapfst_10MutableFst__project {
-  int __pyx_n;
-  bool project_output;
-};
-
-/* "pywrapfst.pxd":363
- *   cdef void _project(self, bool project_output=?) except *
+/* "pywrapfst.pxd":355
+ *   cdef void _project(self, project_type) except *
  * 
  *   cdef void _prune(self, float delta=?, int64 nstate=?, weight=?) except *             # <<<<<<<<<<<<<<
  * 
@@ -1191,7 +1148,7 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__prune {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":365
+/* "pywrapfst.pxd":357
  *   cdef void _prune(self, float delta=?, int64 nstate=?, weight=?) except *
  * 
  *   cdef void _push(self,             # <<<<<<<<<<<<<<
@@ -1205,7 +1162,7 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__push {
   bool to_final;
 };
 
-/* "pywrapfst.pxd":370
+/* "pywrapfst.pxd":362
  *                   bool to_final=?)
  * 
  *   cdef void _relabel_pairs(self, ipairs=?, opairs=?) except *             # <<<<<<<<<<<<<<
@@ -1218,26 +1175,26 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__relabel_pairs {
   PyObject *opairs;
 };
 
-/* "pywrapfst.pxd":372
+/* "pywrapfst.pxd":364
  *   cdef void _relabel_pairs(self, ipairs=?, opairs=?) except *
  * 
  *   cdef void _relabel_tables(self,             # <<<<<<<<<<<<<<
- *                             _SymbolTable old_isymbols=?,
- *                             _SymbolTable new_isymbols=?,
+ *                             SymbolTableView old_isymbols=?,
+ *                             SymbolTableView new_isymbols=?,
  */
 struct __pyx_opt_args_9pywrapfst_10MutableFst__relabel_tables {
   int __pyx_n;
-  struct __pyx_obj_9pywrapfst__SymbolTable *old_isymbols;
-  struct __pyx_obj_9pywrapfst__SymbolTable *new_isymbols;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *old_isymbols;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *new_isymbols;
   PyObject *unknown_isymbol;
   bool attach_new_isymbols;
-  struct __pyx_obj_9pywrapfst__SymbolTable *old_osymbols;
-  struct __pyx_obj_9pywrapfst__SymbolTable *new_osymbols;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *old_osymbols;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *new_osymbols;
   PyObject *unknown_osymbol;
   bool attach_new_osymbols;
 };
 
-/* "pywrapfst.pxd":386
+/* "pywrapfst.pxd":378
  *   cdef void _reserve_states(self, int64 n)
  * 
  *   cdef void _reweight(self, potentials, bool to_final=?) except *             # <<<<<<<<<<<<<<
@@ -1249,7 +1206,7 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__reweight {
   bool to_final;
 };
 
-/* "pywrapfst.pxd":388
+/* "pywrapfst.pxd":380
  *   cdef void _reweight(self, potentials, bool to_final=?) except *
  * 
  *   cdef void _rmepsilon(self,             # <<<<<<<<<<<<<<
@@ -1265,7 +1222,7 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__rmepsilon {
   float delta;
 };
 
-/* "pywrapfst.pxd":395
+/* "pywrapfst.pxd":387
  *                        float delta=?) except *
  * 
  *   cdef void _set_final(self, int64 state, weight=?) except *             # <<<<<<<<<<<<<<
@@ -1277,7 +1234,7 @@ struct __pyx_opt_args_9pywrapfst_10MutableFst__set_final {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":503
+/* "pywrapfst.pxd":495
  * 
  * 
  * cdef Fst _map(Fst ifst, float delta=?, map_type=?, double power=?, weight=?)             # <<<<<<<<<<<<<<
@@ -1292,7 +1249,7 @@ struct __pyx_opt_args_9pywrapfst__map {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":505
+/* "pywrapfst.pxd":497
  * cdef Fst _map(Fst ifst, float delta=?, map_type=?, double power=?, weight=?)
  * 
  * cpdef Fst arcmap(Fst ifst, float delta=?, map_type=?, double power=?, weight=?)             # <<<<<<<<<<<<<<
@@ -1307,7 +1264,7 @@ struct __pyx_opt_args_9pywrapfst_arcmap {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":507
+/* "pywrapfst.pxd":499
  * cpdef Fst arcmap(Fst ifst, float delta=?, map_type=?, double power=?, weight=?)
  * 
  * cpdef MutableFst compose(Fst ifst1,             # <<<<<<<<<<<<<<
@@ -1320,7 +1277,7 @@ struct __pyx_opt_args_9pywrapfst_compose {
   bool connect;
 };
 
-/* "pywrapfst.pxd":512
+/* "pywrapfst.pxd":504
  *                          bool connect=?)
  * 
  * cpdef Fst convert(Fst ifst, fst_type=?)             # <<<<<<<<<<<<<<
@@ -1332,7 +1289,7 @@ struct __pyx_opt_args_9pywrapfst_convert {
   PyObject *fst_type;
 };
 
-/* "pywrapfst.pxd":514
+/* "pywrapfst.pxd":506
  * cpdef Fst convert(Fst ifst, fst_type=?)
  * 
  * cpdef MutableFst determinize(Fst ifst,             # <<<<<<<<<<<<<<
@@ -1349,7 +1306,7 @@ struct __pyx_opt_args_9pywrapfst_determinize {
   bool increment_subsequential_label;
 };
 
-/* "pywrapfst.pxd":522
+/* "pywrapfst.pxd":514
  *                              bool increment_subsequential_label=?)
  * 
  * cpdef MutableFst difference(Fst ifst1,             # <<<<<<<<<<<<<<
@@ -1362,7 +1319,7 @@ struct __pyx_opt_args_9pywrapfst_difference {
   bool connect;
 };
 
-/* "pywrapfst.pxd":527
+/* "pywrapfst.pxd":519
  *                             bool connect=?)
  * 
  * cpdef MutableFst disambiguate(Fst ifst,             # <<<<<<<<<<<<<<
@@ -1377,7 +1334,7 @@ struct __pyx_opt_args_9pywrapfst_disambiguate {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":533
+/* "pywrapfst.pxd":525
  *                               weight=?)
  * 
  * cpdef MutableFst epsnormalize(Fst ifst, bool eps_norm_output=?)             # <<<<<<<<<<<<<<
@@ -1389,7 +1346,7 @@ struct __pyx_opt_args_9pywrapfst_epsnormalize {
   bool eps_norm_output;
 };
 
-/* "pywrapfst.pxd":535
+/* "pywrapfst.pxd":527
  * cpdef MutableFst epsnormalize(Fst ifst, bool eps_norm_output=?)
  * 
  * cpdef bool equal(Fst ifst1, Fst ifst2, float delta=?)             # <<<<<<<<<<<<<<
@@ -1401,7 +1358,7 @@ struct __pyx_opt_args_9pywrapfst_equal {
   float delta;
 };
 
-/* "pywrapfst.pxd":537
+/* "pywrapfst.pxd":529
  * cpdef bool equal(Fst ifst1, Fst ifst2, float delta=?)
  * 
  * cpdef bool equivalent(Fst ifst1, Fst ifst2, float delta=?) except *             # <<<<<<<<<<<<<<
@@ -1413,7 +1370,7 @@ struct __pyx_opt_args_9pywrapfst_equivalent {
   float delta;
 };
 
-/* "pywrapfst.pxd":539
+/* "pywrapfst.pxd":531
  * cpdef bool equivalent(Fst ifst1, Fst ifst2, float delta=?) except *
  * 
  * cpdef MutableFst intersect(Fst ifst1,             # <<<<<<<<<<<<<<
@@ -1426,7 +1383,7 @@ struct __pyx_opt_args_9pywrapfst_intersect {
   bool connect;
 };
 
-/* "pywrapfst.pxd":544
+/* "pywrapfst.pxd":536
  *                            bool connect=?)
  * 
  * cpdef bool isomorphic(Fst ifst1, Fst ifst2, float delta=?)             # <<<<<<<<<<<<<<
@@ -1438,7 +1395,7 @@ struct __pyx_opt_args_9pywrapfst_isomorphic {
   float delta;
 };
 
-/* "pywrapfst.pxd":546
+/* "pywrapfst.pxd":538
  * cpdef bool isomorphic(Fst ifst1, Fst ifst2, float delta=?)
  * 
  * cpdef MutableFst prune(Fst ifst,             # <<<<<<<<<<<<<<
@@ -1452,7 +1409,7 @@ struct __pyx_opt_args_9pywrapfst_prune {
   PyObject *weight;
 };
 
-/* "pywrapfst.pxd":551
+/* "pywrapfst.pxd":543
  *                        weight=?)
  * 
  * cpdef MutableFst push(Fst ifst,             # <<<<<<<<<<<<<<
@@ -1469,7 +1426,7 @@ struct __pyx_opt_args_9pywrapfst_push {
   bool to_final;
 };
 
-/* "pywrapfst.pxd":559
+/* "pywrapfst.pxd":551
  *                       bool to_final=?)
  * 
  * cpdef bool randequivalent(Fst ifst1,             # <<<<<<<<<<<<<<
@@ -1480,30 +1437,30 @@ struct __pyx_opt_args_9pywrapfst_randequivalent {
   int __pyx_n;
   int32 npath;
   float delta;
-  time_t seed;
   PyObject *select;
   int32 max_length;
+  uint64 seed;
 };
 
-/* "pywrapfst.pxd":567
- *                           int32 max_length=?) except *
+/* "pywrapfst.pxd":559
+ *                           uint64 seed=?) except *
  * 
  * cpdef MutableFst randgen(Fst ifst,             # <<<<<<<<<<<<<<
  *                          int32 npath=?,
- *                          time_t seed=?,
+ *                          select=?,
  */
 struct __pyx_opt_args_9pywrapfst_randgen {
   int __pyx_n;
   int32 npath;
-  time_t seed;
   PyObject *select;
   int32 max_length;
   bool remove_total_weight;
   bool weighted;
+  uint64 seed;
 };
 
-/* "pywrapfst.pxd":575
- *                          bool weighted=?)
+/* "pywrapfst.pxd":567
+ *                          uint64 seed=?)
  * 
  * cpdef MutableFst replace(pairs,             # <<<<<<<<<<<<<<
  *                          call_arc_labeling=?,
@@ -1517,24 +1474,24 @@ struct __pyx_opt_args_9pywrapfst_replace {
   int64 return_label;
 };
 
-/* "pywrapfst.pxd":581
+/* "pywrapfst.pxd":573
  *                          int64 return_label=?)
  * 
  * cpdef MutableFst reverse(Fst ifst, bool require_superinitial=?)             # <<<<<<<<<<<<<<
  * 
- * cdef vector[fst.WeightClass] *_shortestdistance(Fst ifst,
+ * cdef void _shortestdistance(Fst ifst,
  */
 struct __pyx_opt_args_9pywrapfst_reverse {
   int __pyx_n;
   bool require_superinitial;
 };
 
-/* "pywrapfst.pxd":583
+/* "pywrapfst.pxd":575
  * cpdef MutableFst reverse(Fst ifst, bool require_superinitial=?)
  * 
- * cdef vector[fst.WeightClass] *_shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
- *                                                 float delta=?,
- *                                                 int64 nstate=?,
+ * cdef void _shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
+ *                             vector[fst.WeightClass] *,
+ *                             float delta=?,
  */
 struct __pyx_opt_args_9pywrapfst__shortestdistance {
   int __pyx_n;
@@ -1544,8 +1501,8 @@ struct __pyx_opt_args_9pywrapfst__shortestdistance {
   bool reverse;
 };
 
-/* "pywrapfst.pxd":589
- *                                                 bool reverse=?) except *
+/* "pywrapfst.pxd":582
+ *                             bool reverse=?) except *
  * 
  * cpdef MutableFst shortestpath(Fst ifst,             # <<<<<<<<<<<<<<
  *                               float delta=?,
@@ -1578,25 +1535,25 @@ struct __pyx_obj_9pywrapfst_Weight {
 /* "pywrapfst.pxd":107
  * 
  * 
- * cdef class _SymbolTable(object):             # <<<<<<<<<<<<<<
+ * cdef class SymbolTableView(object):             # <<<<<<<<<<<<<<
  * 
  *   cdef const fst.SymbolTable *_raw(self)
  */
-struct __pyx_obj_9pywrapfst__SymbolTable {
+struct __pyx_obj_9pywrapfst_SymbolTableView {
   PyObject_HEAD
-  struct __pyx_vtabstruct_9pywrapfst__SymbolTable *__pyx_vtab;
+  struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *__pyx_vtab;
 };
 
 
 /* "pywrapfst.pxd":138
  * 
  * 
- * cdef class _EncodeMapperSymbolTableView(_SymbolTable):             # <<<<<<<<<<<<<<
+ * cdef class _EncodeMapperSymbolTableView(SymbolTableView):             # <<<<<<<<<<<<<<
  * 
  *   # Indicates whether this view is of an input or output SymbolTable
  */
 struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView {
-  struct __pyx_obj_9pywrapfst__SymbolTable __pyx_base;
+  struct __pyx_obj_9pywrapfst_SymbolTableView __pyx_base;
   bool _input_side;
   std::shared_ptr<fst::script::EncodeMapperClass>  _mapper;
 };
@@ -1605,12 +1562,12 @@ struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView {
 /* "pywrapfst.pxd":146
  * 
  * 
- * cdef class _FstSymbolTableView(_SymbolTable):             # <<<<<<<<<<<<<<
+ * cdef class _FstSymbolTableView(SymbolTableView):             # <<<<<<<<<<<<<<
  * 
  *   # Indicates whether this view is of an input or output SymbolTable
  */
 struct __pyx_obj_9pywrapfst__FstSymbolTableView {
-  struct __pyx_obj_9pywrapfst__SymbolTable __pyx_base;
+  struct __pyx_obj_9pywrapfst_SymbolTableView __pyx_base;
   bool _input_side;
   std::shared_ptr<fst::script::FstClass>  _fst;
 };
@@ -1619,12 +1576,12 @@ struct __pyx_obj_9pywrapfst__FstSymbolTableView {
 /* "pywrapfst.pxd":154
  * 
  * 
- * cdef class _MutableSymbolTable(_SymbolTable):             # <<<<<<<<<<<<<<
+ * cdef class _MutableSymbolTable(SymbolTableView):             # <<<<<<<<<<<<<<
  * 
  *   cdef fst.SymbolTable *_mutable_raw(self)
  */
 struct __pyx_obj_9pywrapfst__MutableSymbolTable {
-  struct __pyx_obj_9pywrapfst__SymbolTable __pyx_base;
+  struct __pyx_obj_9pywrapfst_SymbolTableView __pyx_base;
 };
 
 
@@ -1660,11 +1617,11 @@ struct __pyx_obj_9pywrapfst_SymbolTable {
  * 
  * cdef class _SymbolTableIterator(object):             # <<<<<<<<<<<<<<
  * 
- *   cdef _SymbolTable _table
+ *   cdef SymbolTableView _table
  */
 struct __pyx_obj_9pywrapfst__SymbolTableIterator {
   PyObject_HEAD
-  struct __pyx_obj_9pywrapfst__SymbolTable *_table;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *_table;
   std::unique_ptr<fst::SymbolTable::iterator>  _siter;
 };
 
@@ -1697,7 +1654,7 @@ struct __pyx_obj_9pywrapfst_Fst {
 };
 
 
-/* "pywrapfst.pxd":325
+/* "pywrapfst.pxd":317
  * 
  * 
  * cdef class MutableFst(Fst):             # <<<<<<<<<<<<<<
@@ -1710,7 +1667,7 @@ struct __pyx_obj_9pywrapfst_MutableFst {
 };
 
 
-/* "pywrapfst.pxd":408
+/* "pywrapfst.pxd":400
  * 
  * 
  * cdef class VectorFst(MutableFst):             # <<<<<<<<<<<<<<
@@ -1722,7 +1679,7 @@ struct __pyx_obj_9pywrapfst_VectorFst {
 };
 
 
-/* "pywrapfst.pxd":430
+/* "pywrapfst.pxd":422
  * 
  * 
  * cdef class Arc(object):             # <<<<<<<<<<<<<<
@@ -1736,7 +1693,7 @@ struct __pyx_obj_9pywrapfst_Arc {
 };
 
 
-/* "pywrapfst.pxd":440
+/* "pywrapfst.pxd":432
  * 
  * 
  * cdef class ArcIterator(object):             # <<<<<<<<<<<<<<
@@ -1751,7 +1708,7 @@ struct __pyx_obj_9pywrapfst_ArcIterator {
 };
 
 
-/* "pywrapfst.pxd":462
+/* "pywrapfst.pxd":454
  * 
  * 
  * cdef class MutableArcIterator(object):             # <<<<<<<<<<<<<<
@@ -1766,7 +1723,7 @@ struct __pyx_obj_9pywrapfst_MutableArcIterator {
 };
 
 
-/* "pywrapfst.pxd":486
+/* "pywrapfst.pxd":478
  * 
  * 
  * cdef class StateIterator(object):             # <<<<<<<<<<<<<<
@@ -1781,7 +1738,7 @@ struct __pyx_obj_9pywrapfst_StateIterator {
 };
 
 
-/* "pywrapfst.pxd":605
+/* "pywrapfst.pxd":598
  * 
  * 
  * cdef class Compiler(object):             # <<<<<<<<<<<<<<
@@ -1805,7 +1762,7 @@ struct __pyx_obj_9pywrapfst_Compiler {
 };
 
 
-/* "pywrapfst.pxd":626
+/* "pywrapfst.pxd":619
  * # FarReader.
  * 
  * cdef class FarReader(object):             # <<<<<<<<<<<<<<
@@ -1819,7 +1776,7 @@ struct __pyx_obj_9pywrapfst_FarReader {
 };
 
 
-/* "pywrapfst.pxd":651
+/* "pywrapfst.pxd":644
  * # FarWriter.
  * 
  * cdef class FarWriter(object):             # <<<<<<<<<<<<<<
@@ -1833,7 +1790,7 @@ struct __pyx_obj_9pywrapfst_FarWriter {
 };
 
 
-/* "pywrapfst.pyx":3237
+/* "pywrapfst.pyx":3266
  * 
  *   # Magic method used to get a Pythonic Iterator API out of the C++ API.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -1847,7 +1804,7 @@ struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__ {
 
 
 
-/* "pywrapfst.pyx":339
+/* "pywrapfst.pyx":403
  * 
  * 
  * cdef class Weight:             # <<<<<<<<<<<<<<
@@ -1865,81 +1822,81 @@ struct __pyx_vtabstruct_9pywrapfst_Weight {
 static struct __pyx_vtabstruct_9pywrapfst_Weight *__pyx_vtabptr_9pywrapfst_Weight;
 
 
-/* "pywrapfst.pyx":669
+/* "pywrapfst.pyx":730
  * 
  * 
- * cdef class _SymbolTable:             # <<<<<<<<<<<<<<
+ * cdef class SymbolTableView:             # <<<<<<<<<<<<<<
  * 
  *   """
  */
 
-struct __pyx_vtabstruct_9pywrapfst__SymbolTable {
-  fst::SymbolTable const *(*_raw)(struct __pyx_obj_9pywrapfst__SymbolTable *);
-  void (*_raise_nonexistent)(struct __pyx_obj_9pywrapfst__SymbolTable *);
-  fst::SymbolTable const *(*_raw_ptr_or_raise)(struct __pyx_obj_9pywrapfst__SymbolTable *);
-  int64 (*available_key)(struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch);
-  PyObject *(*checksum)(struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch);
-  struct __pyx_obj_9pywrapfst_SymbolTable *(*copy)(struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch);
-  int64 (*get_nth_key)(struct __pyx_obj_9pywrapfst__SymbolTable *, Py_ssize_t, int __pyx_skip_dispatch);
-  PyObject *(*labeled_checksum)(struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch);
-  bool (*member)(struct __pyx_obj_9pywrapfst__SymbolTable *, PyObject *, int __pyx_skip_dispatch);
-  std::string (*name)(struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch);
-  size_t (*num_symbols)(struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch);
-  void (*write)(struct __pyx_obj_9pywrapfst__SymbolTable *, PyObject *, int __pyx_skip_dispatch);
-  void (*write_text)(struct __pyx_obj_9pywrapfst__SymbolTable *, PyObject *, int __pyx_skip_dispatch);
-  PyObject *(*write_to_string)(struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch);
+struct __pyx_vtabstruct_9pywrapfst_SymbolTableView {
+  fst::SymbolTable const *(*_raw)(struct __pyx_obj_9pywrapfst_SymbolTableView *);
+  void (*_raise_nonexistent)(struct __pyx_obj_9pywrapfst_SymbolTableView *);
+  fst::SymbolTable const *(*_raw_ptr_or_raise)(struct __pyx_obj_9pywrapfst_SymbolTableView *);
+  int64 (*available_key)(struct __pyx_obj_9pywrapfst_SymbolTableView *, int __pyx_skip_dispatch);
+  PyObject *(*checksum)(struct __pyx_obj_9pywrapfst_SymbolTableView *, int __pyx_skip_dispatch);
+  struct __pyx_obj_9pywrapfst_SymbolTable *(*copy)(struct __pyx_obj_9pywrapfst_SymbolTableView *, int __pyx_skip_dispatch);
+  int64 (*get_nth_key)(struct __pyx_obj_9pywrapfst_SymbolTableView *, Py_ssize_t, int __pyx_skip_dispatch);
+  PyObject *(*labeled_checksum)(struct __pyx_obj_9pywrapfst_SymbolTableView *, int __pyx_skip_dispatch);
+  bool (*member)(struct __pyx_obj_9pywrapfst_SymbolTableView *, PyObject *, int __pyx_skip_dispatch);
+  std::string (*name)(struct __pyx_obj_9pywrapfst_SymbolTableView *, int __pyx_skip_dispatch);
+  size_t (*num_symbols)(struct __pyx_obj_9pywrapfst_SymbolTableView *, int __pyx_skip_dispatch);
+  void (*write)(struct __pyx_obj_9pywrapfst_SymbolTableView *, PyObject *, int __pyx_skip_dispatch);
+  void (*write_text)(struct __pyx_obj_9pywrapfst_SymbolTableView *, PyObject *, int __pyx_skip_dispatch);
+  PyObject *(*write_to_string)(struct __pyx_obj_9pywrapfst_SymbolTableView *, int __pyx_skip_dispatch);
 };
-static struct __pyx_vtabstruct_9pywrapfst__SymbolTable *__pyx_vtabptr_9pywrapfst__SymbolTable;
+static struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *__pyx_vtabptr_9pywrapfst_SymbolTableView;
 
 
-/* "pywrapfst.pyx":876
+/* "pywrapfst.pyx":933
  * 
  * 
- * cdef class _EncodeMapperSymbolTableView(_SymbolTable):             # <<<<<<<<<<<<<<
+ * cdef class _EncodeMapperSymbolTableView(SymbolTableView):             # <<<<<<<<<<<<<<
  * 
  *   """
  */
 
 struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTableView {
-  struct __pyx_vtabstruct_9pywrapfst__SymbolTable __pyx_base;
+  struct __pyx_vtabstruct_9pywrapfst_SymbolTableView __pyx_base;
 };
 static struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTableView *__pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTableView;
 
 
-/* "pywrapfst.pyx":900
+/* "pywrapfst.pyx":957
  * 
  * 
- * cdef class _FstSymbolTableView(_SymbolTable):             # <<<<<<<<<<<<<<
+ * cdef class _FstSymbolTableView(SymbolTableView):             # <<<<<<<<<<<<<<
  * 
  *   """
  */
 
 struct __pyx_vtabstruct_9pywrapfst__FstSymbolTableView {
-  struct __pyx_vtabstruct_9pywrapfst__SymbolTable __pyx_base;
+  struct __pyx_vtabstruct_9pywrapfst_SymbolTableView __pyx_base;
 };
 static struct __pyx_vtabstruct_9pywrapfst__FstSymbolTableView *__pyx_vtabptr_9pywrapfst__FstSymbolTableView;
 
 
-/* "pywrapfst.pyx":923
+/* "pywrapfst.pyx":980
  * 
  * 
- * cdef class _MutableSymbolTable(_SymbolTable):             # <<<<<<<<<<<<<<
+ * cdef class _MutableSymbolTable(SymbolTableView):             # <<<<<<<<<<<<<<
  * 
  *   """
  */
 
 struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable {
-  struct __pyx_vtabstruct_9pywrapfst__SymbolTable __pyx_base;
+  struct __pyx_vtabstruct_9pywrapfst_SymbolTableView __pyx_base;
   fst::SymbolTable *(*_mutable_raw)(struct __pyx_obj_9pywrapfst__MutableSymbolTable *);
   fst::SymbolTable *(*_mutable_raw_ptr_or_raise)(struct __pyx_obj_9pywrapfst__MutableSymbolTable *);
   int64 (*add_symbol)(struct __pyx_obj_9pywrapfst__MutableSymbolTable *, PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_19_MutableSymbolTable_add_symbol *__pyx_optional_args);
-  void (*add_table)(struct __pyx_obj_9pywrapfst__MutableSymbolTable *, struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch);
+  void (*add_table)(struct __pyx_obj_9pywrapfst__MutableSymbolTable *, struct __pyx_obj_9pywrapfst_SymbolTableView *, int __pyx_skip_dispatch);
   void (*set_name)(struct __pyx_obj_9pywrapfst__MutableSymbolTable *, PyObject *, int __pyx_skip_dispatch);
 };
 static struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *__pyx_vtabptr_9pywrapfst__MutableSymbolTable;
 
 
-/* "pywrapfst.pyx":994
+/* "pywrapfst.pyx":1052
  * 
  * 
  * cdef class _MutableFstSymbolTableView(_MutableSymbolTable):             # <<<<<<<<<<<<<<
@@ -1953,7 +1910,7 @@ struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTableView {
 static struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTableView *__pyx_vtabptr_9pywrapfst__MutableFstSymbolTableView;
 
 
-/* "pywrapfst.pyx":1009
+/* "pywrapfst.pyx":1067
  * 
  * 
  * cdef class SymbolTable(_MutableSymbolTable):             # <<<<<<<<<<<<<<
@@ -1967,7 +1924,7 @@ struct __pyx_vtabstruct_9pywrapfst_SymbolTable {
 static struct __pyx_vtabstruct_9pywrapfst_SymbolTable *__pyx_vtabptr_9pywrapfst_SymbolTable;
 
 
-/* "pywrapfst.pyx":1235
+/* "pywrapfst.pyx":1295
  * 
  * 
  * cdef class EncodeMapper:             # <<<<<<<<<<<<<<
@@ -1984,13 +1941,13 @@ struct __pyx_vtabstruct_9pywrapfst_EncodeMapper {
   PyObject *(*write_to_string)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch);
   struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *(*input_symbols)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch);
   struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *(*output_symbols)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch);
-  void (*_set_input_symbols)(struct __pyx_obj_9pywrapfst_EncodeMapper *, struct __pyx_obj_9pywrapfst__SymbolTable *);
-  void (*_set_output_symbols)(struct __pyx_obj_9pywrapfst_EncodeMapper *, struct __pyx_obj_9pywrapfst__SymbolTable *);
+  void (*_set_input_symbols)(struct __pyx_obj_9pywrapfst_EncodeMapper *, struct __pyx_obj_9pywrapfst_SymbolTableView *);
+  void (*_set_output_symbols)(struct __pyx_obj_9pywrapfst_EncodeMapper *, struct __pyx_obj_9pywrapfst_SymbolTableView *);
 };
 static struct __pyx_vtabstruct_9pywrapfst_EncodeMapper *__pyx_vtabptr_9pywrapfst_EncodeMapper;
 
 
-/* "pywrapfst.pyx":1501
+/* "pywrapfst.pyx":1561
  * 
  * 
  * cdef class Fst:             # <<<<<<<<<<<<<<
@@ -2015,7 +1972,6 @@ struct __pyx_vtabstruct_9pywrapfst_Fst {
   uint64 (*properties)(struct __pyx_obj_9pywrapfst_Fst *, uint64, bool, int __pyx_skip_dispatch);
   int64 (*start)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch);
   struct __pyx_obj_9pywrapfst_StateIterator *(*states)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch);
-  std::string (*text)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_3Fst_text *__pyx_optional_args);
   bool (*verify)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch);
   std::string (*weight_type)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch);
   void (*write)(struct __pyx_obj_9pywrapfst_Fst *, PyObject *, int __pyx_skip_dispatch);
@@ -2024,7 +1980,7 @@ struct __pyx_vtabstruct_9pywrapfst_Fst {
 static struct __pyx_vtabstruct_9pywrapfst_Fst *__pyx_vtabptr_9pywrapfst_Fst;
 
 
-/* "pywrapfst.pyx":1993
+/* "pywrapfst.pyx":2026
  * 
  * 
  * cdef class MutableFst(Fst):             # <<<<<<<<<<<<<<
@@ -2050,7 +2006,7 @@ struct __pyx_vtabstruct_9pywrapfst_MutableFst {
   void (*_minimize)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__minimize *__pyx_optional_args);
   struct __pyx_obj_9pywrapfst_MutableArcIterator *(*mutable_arcs)(struct __pyx_obj_9pywrapfst_MutableFst *, int64, int __pyx_skip_dispatch);
   int64 (*num_states)(struct __pyx_obj_9pywrapfst_MutableFst *, int __pyx_skip_dispatch);
-  void (*_project)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__project *__pyx_optional_args);
+  void (*_project)(struct __pyx_obj_9pywrapfst_MutableFst *, PyObject *);
   void (*_prune)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__prune *__pyx_optional_args);
   void (*_push)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__push *__pyx_optional_args);
   void (*_relabel_pairs)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__relabel_pairs *__pyx_optional_args);
@@ -2062,14 +2018,14 @@ struct __pyx_vtabstruct_9pywrapfst_MutableFst {
   void (*_set_final)(struct __pyx_obj_9pywrapfst_MutableFst *, int64, struct __pyx_opt_args_9pywrapfst_10MutableFst__set_final *__pyx_optional_args);
   void (*_set_properties)(struct __pyx_obj_9pywrapfst_MutableFst *, uint64, uint64);
   void (*_set_start)(struct __pyx_obj_9pywrapfst_MutableFst *, int64);
-  void (*_set_input_symbols)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_obj_9pywrapfst__SymbolTable *);
-  void (*_set_output_symbols)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_obj_9pywrapfst__SymbolTable *);
+  void (*_set_input_symbols)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_obj_9pywrapfst_SymbolTableView *);
+  void (*_set_output_symbols)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_obj_9pywrapfst_SymbolTableView *);
   void (*_topsort)(struct __pyx_obj_9pywrapfst_MutableFst *);
 };
 static struct __pyx_vtabstruct_9pywrapfst_MutableFst *__pyx_vtabptr_9pywrapfst_MutableFst;
 
 
-/* "pywrapfst.pyx":2863
+/* "pywrapfst.pyx":2891
  * 
  * 
  * cdef class VectorFst(MutableFst):             # <<<<<<<<<<<<<<
@@ -2083,7 +2039,7 @@ struct __pyx_vtabstruct_9pywrapfst_VectorFst {
 static struct __pyx_vtabstruct_9pywrapfst_VectorFst *__pyx_vtabptr_9pywrapfst_VectorFst;
 
 
-/* "pywrapfst.pyx":3039
+/* "pywrapfst.pyx":3068
  * 
  * 
  * cdef class Arc:             # <<<<<<<<<<<<<<
@@ -2097,7 +2053,7 @@ struct __pyx_vtabstruct_9pywrapfst_Arc {
 static struct __pyx_vtabstruct_9pywrapfst_Arc *__pyx_vtabptr_9pywrapfst_Arc;
 
 
-/* "pywrapfst.pyx":3106
+/* "pywrapfst.pyx":3135
  * 
  * 
  * cdef class ArcIterator:             # <<<<<<<<<<<<<<
@@ -2118,7 +2074,7 @@ struct __pyx_vtabstruct_9pywrapfst_ArcIterator {
 static struct __pyx_vtabstruct_9pywrapfst_ArcIterator *__pyx_vtabptr_9pywrapfst_ArcIterator;
 
 
-/* "pywrapfst.pyx":3217
+/* "pywrapfst.pyx":3246
  * 
  * 
  * cdef class MutableArcIterator:             # <<<<<<<<<<<<<<
@@ -2140,7 +2096,7 @@ struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator {
 static struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator *__pyx_vtabptr_9pywrapfst_MutableArcIterator;
 
 
-/* "pywrapfst.pyx":3337
+/* "pywrapfst.pyx":3366
  * 
  * 
  * cdef class StateIterator:             # <<<<<<<<<<<<<<
@@ -2157,7 +2113,7 @@ struct __pyx_vtabstruct_9pywrapfst_StateIterator {
 static struct __pyx_vtabstruct_9pywrapfst_StateIterator *__pyx_vtabptr_9pywrapfst_StateIterator;
 
 
-/* "pywrapfst.pyx":4242
+/* "pywrapfst.pyx":4275
  * 
  * 
  * cdef class Compiler:             # <<<<<<<<<<<<<<
@@ -2172,7 +2128,7 @@ struct __pyx_vtabstruct_9pywrapfst_Compiler {
 static struct __pyx_vtabstruct_9pywrapfst_Compiler *__pyx_vtabptr_9pywrapfst_Compiler;
 
 
-/* "pywrapfst.pyx":4379
+/* "pywrapfst.pyx":4412
  * 
  * 
  * cdef class FarReader:             # <<<<<<<<<<<<<<
@@ -2194,7 +2150,7 @@ struct __pyx_vtabstruct_9pywrapfst_FarReader {
 static struct __pyx_vtabstruct_9pywrapfst_FarReader *__pyx_vtabptr_9pywrapfst_FarReader;
 
 
-/* "pywrapfst.pyx":4525
+/* "pywrapfst.pyx":4567
  * 
  * 
  * cdef class FarWriter:             # <<<<<<<<<<<<<<
@@ -2285,6 +2241,39 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject
 /* GetBuiltinName.proto */
 static PyObject *__Pyx_GetBuiltinName(PyObject *name);
 
+/* PyObjectFormatSimple.proto */
+#if CYTHON_COMPILING_IN_PYPY
+    #define __Pyx_PyObject_FormatSimple(s, f) (\
+        likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\
+        PyObject_Format(s, f))
+#elif PY_MAJOR_VERSION < 3
+    #define __Pyx_PyObject_FormatSimple(s, f) (\
+        likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\
+        likely(PyString_CheckExact(s)) ? PyUnicode_FromEncodedObject(s, NULL, "strict") :\
+        PyObject_Format(s, f))
+#elif CYTHON_USE_TYPE_SLOTS
+    #define __Pyx_PyObject_FormatSimple(s, f) (\
+        likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\
+        likely(PyLong_CheckExact(s)) ? PyLong_Type.tp_str(s) :\
+        likely(PyFloat_CheckExact(s)) ? PyFloat_Type.tp_str(s) :\
+        PyObject_Format(s, f))
+#else
+    #define __Pyx_PyObject_FormatSimple(s, f) (\
+        likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\
+        PyObject_Format(s, f))
+#endif
+
+/* PyObjectFormatAndDecref.proto */
+static CYTHON_INLINE PyObject* __Pyx_PyObject_FormatSimpleAndDecref(PyObject* s, PyObject* f);
+static CYTHON_INLINE PyObject* __Pyx_PyObject_FormatAndDecref(PyObject* s, PyObject* f);
+
+/* IncludeStringH.proto */
+#include <string.h>
+
+/* JoinPyUnicode.proto */
+static PyObject* __Pyx_PyUnicode_Join(PyObject* value_tuple, Py_ssize_t value_count, Py_ssize_t result_ulength,
+                                      Py_UCS4 max_char);
+
 /* PyCFunctionFastCall.proto */
 #if CYTHON_FAST_PYCCALL
 static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObject **args, Py_ssize_t nargs);
@@ -2322,9 +2311,6 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg
 #define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)
 #endif
 
-/* PyObjectCall2Args.proto */
-static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2);
-
 /* PyObjectCallMethO.proto */
 #if CYTHON_COMPILING_IN_CPYTHON
 static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg);
@@ -2333,6 +2319,45 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject
 /* PyObjectCallOneArg.proto */
 static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg);
 
+/* PyThreadStateGet.proto */
+#if CYTHON_FAST_THREAD_STATE
+#define __Pyx_PyThreadState_declare  PyThreadState *__pyx_tstate;
+#define __Pyx_PyThreadState_assign  __pyx_tstate = __Pyx_PyThreadState_Current;
+#define __Pyx_PyErr_Occurred()  __pyx_tstate->curexc_type
+#else
+#define __Pyx_PyThreadState_declare
+#define __Pyx_PyThreadState_assign
+#define __Pyx_PyErr_Occurred()  PyErr_Occurred()
+#endif
+
+/* PyErrFetchRestore.proto */
+#if CYTHON_FAST_THREAD_STATE
+#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL)
+#define __Pyx_ErrRestoreWithState(type, value, tb)  __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb)
+#define __Pyx_ErrFetchWithState(type, value, tb)    __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb)
+#define __Pyx_ErrRestore(type, value, tb)  __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb)
+#define __Pyx_ErrFetch(type, value, tb)    __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb)
+static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb);
+static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL))
+#else
+#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc)
+#endif
+#else
+#define __Pyx_PyErr_Clear() PyErr_Clear()
+#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc)
+#define __Pyx_ErrRestoreWithState(type, value, tb)  PyErr_Restore(type, value, tb)
+#define __Pyx_ErrFetchWithState(type, value, tb)  PyErr_Fetch(type, value, tb)
+#define __Pyx_ErrRestoreInState(tstate, type, value, tb)  PyErr_Restore(type, value, tb)
+#define __Pyx_ErrFetchInState(tstate, type, value, tb)  PyErr_Fetch(type, value, tb)
+#define __Pyx_ErrRestore(type, value, tb)  PyErr_Restore(type, value, tb)
+#define __Pyx_ErrFetch(type, value, tb)  PyErr_Fetch(type, value, tb)
+#endif
+
+/* RaiseException.proto */
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);
+
 /* PyDictVersioning.proto */
 #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS
 #define __PYX_DICT_VERSION_INIT  ((PY_UINT64_T) -1)
@@ -2380,45 +2405,16 @@ static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_ve
 static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name);
 #endif
 
-/* PyThreadStateGet.proto */
-#if CYTHON_FAST_THREAD_STATE
-#define __Pyx_PyThreadState_declare  PyThreadState *__pyx_tstate;
-#define __Pyx_PyThreadState_assign  __pyx_tstate = __Pyx_PyThreadState_Current;
-#define __Pyx_PyErr_Occurred()  __pyx_tstate->curexc_type
-#else
-#define __Pyx_PyThreadState_declare
-#define __Pyx_PyThreadState_assign
-#define __Pyx_PyErr_Occurred()  PyErr_Occurred()
-#endif
+/* PyObjectCall2Args.proto */
+static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2);
 
-/* PyErrFetchRestore.proto */
-#if CYTHON_FAST_THREAD_STATE
-#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL)
-#define __Pyx_ErrRestoreWithState(type, value, tb)  __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb)
-#define __Pyx_ErrFetchWithState(type, value, tb)    __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb)
-#define __Pyx_ErrRestore(type, value, tb)  __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb)
-#define __Pyx_ErrFetch(type, value, tb)    __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb)
-static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb);
-static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb);
-#if CYTHON_COMPILING_IN_CPYTHON
-#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL))
-#else
-#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc)
-#endif
+/* PyObjectFormat.proto */
+#if CYTHON_USE_UNICODE_WRITER
+static PyObject* __Pyx_PyObject_Format(PyObject* s, PyObject* f);
 #else
-#define __Pyx_PyErr_Clear() PyErr_Clear()
-#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc)
-#define __Pyx_ErrRestoreWithState(type, value, tb)  PyErr_Restore(type, value, tb)
-#define __Pyx_ErrFetchWithState(type, value, tb)  PyErr_Fetch(type, value, tb)
-#define __Pyx_ErrRestoreInState(tstate, type, value, tb)  PyErr_Restore(type, value, tb)
-#define __Pyx_ErrFetchInState(tstate, type, value, tb)  PyErr_Fetch(type, value, tb)
-#define __Pyx_ErrRestore(type, value, tb)  PyErr_Restore(type, value, tb)
-#define __Pyx_ErrFetch(type, value, tb)  PyErr_Fetch(type, value, tb)
+#define __Pyx_PyObject_Format(s, f) PyObject_Format(s, f)
 #endif
 
-/* RaiseException.proto */
-static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);
-
 /* RaiseArgTupleInvalid.proto */
 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
     Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found);
@@ -2471,18 +2467,13 @@ static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject
 #define __Pyx_ExceptionReset(type, value, tb)  PyErr_SetExcInfo(type, value, tb)
 #endif
 
-/* FastTypeChecks.proto */
-#if CYTHON_COMPILING_IN_CPYTHON
-#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type)
-static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b);
-static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type);
-static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2);
+/* PyErrExceptionMatches.proto */
+#if CYTHON_FAST_THREAD_STATE
+#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err)
+static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err);
 #else
-#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
-#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type)
-#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2))
+#define __Pyx_PyErr_ExceptionMatches(err)  PyErr_ExceptionMatches(err)
 #endif
-#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception)
 
 /* GetException.proto */
 #if CYTHON_FAST_THREAD_STATE
@@ -2514,14 +2505,6 @@ static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j);
 static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
                                                      int is_list, int wraparound, int boundscheck);
 
-/* PyErrExceptionMatches.proto */
-#if CYTHON_FAST_THREAD_STATE
-#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err)
-static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err);
-#else
-#define __Pyx_PyErr_ExceptionMatches(err)  PyErr_ExceptionMatches(err)
-#endif
-
 /* SwapException.proto */
 #if CYTHON_FAST_THREAD_STATE
 #define __Pyx_ExceptionSwap(type, value, tb)  __Pyx__ExceptionSwap(__pyx_tstate, type, value, tb)
@@ -2550,7 +2533,7 @@ static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
     if (likely(L->allocated > len)) {
         Py_INCREF(x);
         PyList_SET_ITEM(list, len, x);
-        Py_SIZE(list) = len+1;
+        __Pyx_SET_SIZE(list, len + 1);
         return 0;
     }
     return PyList_Append(list, x);
@@ -2559,9 +2542,6 @@ static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
 #define __Pyx_ListComp_Append(L,x) PyList_Append(L,x)
 #endif
 
-/* IncludeStringH.proto */
-#include <string.h>
-
 /* PyObject_GenericGetAttrNoDict.proto */
 #if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000
 static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name);
@@ -2579,6 +2559,9 @@ static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_nam
 /* SetVTable.proto */
 static int __Pyx_SetVtable(PyObject *dict, void *vtable);
 
+/* PyObjectGetAttrStrNoError.proto */
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name);
+
 /* SetupReduce.proto */
 static int __Pyx_setup_reduce(PyObject* type_obj);
 
@@ -2707,14 +2690,24 @@ static CYTHON_INLINE int32_t __Pyx_PyInt_As_int32_t(PyObject *);
 static CYTHON_INLINE uint8_t __Pyx_PyInt_As_uint8_t(PyObject *);
 
 /* CIntFromPy.proto */
-static CYTHON_INLINE time_t __Pyx_PyInt_As_time_t(PyObject *);
-
-/* CIntFromPy.proto */
 static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
 
 /* CIntFromPy.proto */
 static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);
 
+/* FastTypeChecks.proto */
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type)
+static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b);
+static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type);
+static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2);
+#else
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type)
+#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2))
+#endif
+#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception)
+
 /* FetchCommonType.proto */
 static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type);
 
@@ -2813,27 +2806,27 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_6Weight_copy(struc
 static std::string __pyx_f_9pywrapfst_6Weight_to_string(struct __pyx_obj_9pywrapfst_Weight *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static std::string __pyx_f_9pywrapfst_6Weight_type(struct __pyx_obj_9pywrapfst_Weight *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static bool __pyx_f_9pywrapfst_6Weight_member(struct __pyx_obj_9pywrapfst_Weight *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_12_SymbolTable__raw(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto*/
-static void __pyx_f_9pywrapfst_12_SymbolTable__raise_nonexistent(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto*/
-static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_12_SymbolTable__raw_ptr_or_raise(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto*/
-static int64 __pyx_f_9pywrapfst_12_SymbolTable_available_key(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_checksum(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_12_SymbolTable_copy(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, Py_ssize_t __pyx_v_pos, int __pyx_skip_dispatch); /* proto*/
-static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static bool __pyx_f_9pywrapfst_12_SymbolTable_member(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key, int __pyx_skip_dispatch); /* proto*/
-static std::string __pyx_f_9pywrapfst_12_SymbolTable_name(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static size_t __pyx_f_9pywrapfst_12_SymbolTable_num_symbols(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch); /* proto*/
-static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_write_to_string(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_15SymbolTableView__raw(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self); /* proto*/
+static void __pyx_f_9pywrapfst_15SymbolTableView__raise_nonexistent(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self); /* proto*/
+static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_15SymbolTableView__raw_ptr_or_raise(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self); /* proto*/
+static int64 __pyx_f_9pywrapfst_15SymbolTableView_available_key(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static PyObject *__pyx_f_9pywrapfst_15SymbolTableView_checksum(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_15SymbolTableView_copy(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static int64 __pyx_f_9pywrapfst_15SymbolTableView_get_nth_key(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, Py_ssize_t __pyx_v_pos, int __pyx_skip_dispatch); /* proto*/
+static PyObject *__pyx_f_9pywrapfst_15SymbolTableView_labeled_checksum(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static bool __pyx_f_9pywrapfst_15SymbolTableView_member(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, PyObject *__pyx_v_key, int __pyx_skip_dispatch); /* proto*/
+static std::string __pyx_f_9pywrapfst_15SymbolTableView_name(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static size_t __pyx_f_9pywrapfst_15SymbolTableView_num_symbols(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_15SymbolTableView_write(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_15SymbolTableView_write_text(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch); /* proto*/
+static PyObject *__pyx_f_9pywrapfst_15SymbolTableView_write_to_string(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_28_EncodeMapperSymbolTableView__raw(struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_v_self); /* proto*/
 static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_19_FstSymbolTableView__raw(struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_v_self); /* proto*/
 static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTable__raw(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self); /* proto*/
 static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTable__mutable_raw(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self); /* proto*/
 static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTable__mutable_raw_ptr_or_raise(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self); /* proto*/
 static int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self, PyObject *__pyx_v_symbol, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_19_MutableSymbolTable_add_symbol *__pyx_optional_args); /* proto*/
-static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms, int __pyx_skip_dispatch); /* proto*/
+static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self, PyObject *__pyx_v_new_name, int __pyx_skip_dispatch); /* proto*/
 static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_26_MutableFstSymbolTableView__mutable_raw(struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *__pyx_v_self); /* proto*/
 static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_11SymbolTable__mutable_raw(struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_self); /* proto*/
@@ -2845,8 +2838,8 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_write(struct __pyx_obj_9pywrapfst_
 static PyObject *__pyx_f_9pywrapfst_12EncodeMapper_write_to_string(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrapfst_12EncodeMapper_input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrapfst_12EncodeMapper_output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_12EncodeMapper__set_input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto*/
-static void __pyx_f_9pywrapfst_12EncodeMapper__set_output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto*/
+static void __pyx_f_9pywrapfst_12EncodeMapper__set_input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols); /* proto*/
+static void __pyx_f_9pywrapfst_12EncodeMapper__set_output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols); /* proto*/
 static std::string __pyx_f_9pywrapfst_3Fst__local_render_svg(std::string const &__pyx_v_dot); /* proto*/
 static std::string __pyx_f_9pywrapfst_3Fst_arc_type(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_3Fst_arcs(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int64 __pyx_v_state, int __pyx_skip_dispatch); /* proto*/
@@ -2863,7 +2856,6 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
 static uint64 __pyx_f_9pywrapfst_3Fst_properties(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, uint64 __pyx_v_mask, bool __pyx_v_test, int __pyx_skip_dispatch); /* proto*/
 static int64 __pyx_f_9pywrapfst_3Fst_start(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_3Fst_states(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static std::string __pyx_f_9pywrapfst_3Fst_text(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_3Fst_text *__pyx_optional_args); /* proto*/
 static bool __pyx_f_9pywrapfst_3Fst_verify(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static std::string __pyx_f_9pywrapfst_3Fst_weight_type(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static void __pyx_f_9pywrapfst_3Fst_write(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch); /* proto*/
@@ -2884,7 +2876,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__invert(struct __pyx_obj_9pywrapfst_
 static void __pyx_f_9pywrapfst_10MutableFst__minimize(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__minimize *__pyx_optional_args); /* proto*/
 static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_10MutableFst_mutable_arcs(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state, int __pyx_skip_dispatch); /* proto*/
 static int64 __pyx_f_9pywrapfst_10MutableFst_num_states(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
-static void __pyx_f_9pywrapfst_10MutableFst__project(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__project *__pyx_optional_args); /* proto*/
+static void __pyx_f_9pywrapfst_10MutableFst__project(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, PyObject *__pyx_v_project_type); /* proto*/
 static void __pyx_f_9pywrapfst_10MutableFst__prune(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__prune *__pyx_optional_args); /* proto*/
 static void __pyx_f_9pywrapfst_10MutableFst__push(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__push *__pyx_optional_args); /* proto*/
 static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__relabel_pairs *__pyx_optional_args); /* proto*/
@@ -2894,8 +2886,8 @@ static void __pyx_f_9pywrapfst_10MutableFst__reserve_states(struct __pyx_obj_9py
 static void __pyx_f_9pywrapfst_10MutableFst__reweight(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, PyObject *__pyx_v_potentials, struct __pyx_opt_args_9pywrapfst_10MutableFst__reweight *__pyx_optional_args); /* proto*/
 static void __pyx_f_9pywrapfst_10MutableFst__rmepsilon(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__rmepsilon *__pyx_optional_args); /* proto*/
 static void __pyx_f_9pywrapfst_10MutableFst__set_final(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state, struct __pyx_opt_args_9pywrapfst_10MutableFst__set_final *__pyx_optional_args); /* proto*/
-static void __pyx_f_9pywrapfst_10MutableFst__set_input_symbols(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto*/
-static void __pyx_f_9pywrapfst_10MutableFst__set_output_symbols(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto*/
+static void __pyx_f_9pywrapfst_10MutableFst__set_input_symbols(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols); /* proto*/
+static void __pyx_f_9pywrapfst_10MutableFst__set_output_symbols(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols); /* proto*/
 static void __pyx_f_9pywrapfst_10MutableFst__set_properties(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, uint64 __pyx_v_props, uint64 __pyx_v_mask); /* proto*/
 static void __pyx_f_9pywrapfst_10MutableFst__set_start(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state); /* proto*/
 static void __pyx_f_9pywrapfst_10MutableFst__topsort(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self); /* proto*/
@@ -2938,10 +2930,6 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_arc_type(struct __pyx_obj_9pywr
 static bool __pyx_f_9pywrapfst_9FarWriter_error(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 
-/* Module declarations from 'libc.stddef' */
-
-/* Module declarations from 'libc.time' */
-
 /* Module declarations from 'libcpp' */
 
 /* Module declarations from 'libcpp.memory' */
@@ -2956,25 +2944,25 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
 
 /* Module declarations from 'libc.stdint' */
 
-/* Module declarations from 'basictypes' */
+/* Module declarations from 'cintegral_types' */
 
-/* Module declarations from 'ios' */
+/* Module declarations from 'cios' */
 
 /* Module declarations from 'cpywrapfst' */
 
-/* Module declarations from 'posix.types' */
+/* Module declarations from 'libc.stddef' */
 
-/* Module declarations from 'posix.unistd' */
+/* Module declarations from 'libc.time' */
 
 /* Module declarations from 'libcpp.cast' */
 
-/* Module declarations from 'memory' */
+/* Module declarations from 'cmemory' */
 
-/* Module declarations from 'utility' */
+/* Module declarations from 'cutility' */
 
 /* Module declarations from 'pywrapfst' */
 static PyTypeObject *__pyx_ptype_9pywrapfst_Weight = 0;
-static PyTypeObject *__pyx_ptype_9pywrapfst__SymbolTable = 0;
+static PyTypeObject *__pyx_ptype_9pywrapfst_SymbolTableView = 0;
 static PyTypeObject *__pyx_ptype_9pywrapfst__EncodeMapperSymbolTableView = 0;
 static PyTypeObject *__pyx_ptype_9pywrapfst__FstSymbolTableView = 0;
 static PyTypeObject *__pyx_ptype_9pywrapfst__MutableSymbolTable = 0;
@@ -2995,6 +2983,7 @@ static PyTypeObject *__pyx_ptype_9pywrapfst_FarWriter = 0;
 static PyTypeObject *__pyx_ptype_9pywrapfst___pyx_scope_struct____iter__ = 0;
 static std::string __pyx_f_9pywrapfst_tostring(PyObject *); /*proto*/
 static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *); /*proto*/
+static std::string __pyx_f_9pywrapfst_path_tostring(PyObject *); /*proto*/
 static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::string const &); /*proto*/
 static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const &); /*proto*/
 static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selection(std::string const &); /*proto*/
@@ -3012,14 +3001,14 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
 static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst__init_FstSymbolTableView(std::shared_ptr<fst::script::FstClass> , bool); /*proto*/
 static struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *__pyx_f_9pywrapfst__init_MutableFstSymbolTableView(std::shared_ptr<fst::script::MutableFstClass> , bool); /*proto*/
 static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__init_SymbolTable(std::unique_ptr<fst::SymbolTable> ); /*proto*/
-static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolTable_from_string(PyObject *, int __pyx_skip_dispatch); /*proto*/
+static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolTable_from_string(std::string, int __pyx_skip_dispatch); /*proto*/
 static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__init_EncodeMapper(__pyx_t_9pywrapfst_EncodeMapperClass_ptr); /*proto*/
-static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__read_EncodeMapper_from_string(PyObject *, int __pyx_skip_dispatch); /*proto*/
+static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__read_EncodeMapper_from_string(std::string, int __pyx_skip_dispatch); /*proto*/
 static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9pywrapfst_FstClass_ptr); /*proto*/
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst__init_MutableFst(__pyx_t_9pywrapfst_MutableFstClass_ptr); /*proto*/
 static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9pywrapfst_FstClass_ptr); /*proto*/
 static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *, int __pyx_skip_dispatch); /*proto*/
-static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__read_Fst_from_string(PyObject *, int __pyx_skip_dispatch); /*proto*/
+static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__read_Fst_from_string(std::string, int __pyx_skip_dispatch); /*proto*/
 static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst__init_Arc(fst::script::ArcClass const &); /*proto*/
 static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__map(struct __pyx_obj_9pywrapfst_Fst *, struct __pyx_opt_args_9pywrapfst__map *__pyx_optional_args); /*proto*/
 static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_arcmap(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_arcmap *__pyx_optional_args); /*proto*/
@@ -3039,12 +3028,14 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst_Fst *,
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_randgen(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_randgen *__pyx_optional_args); /*proto*/
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_replace *__pyx_optional_args); /*proto*/
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_reverse(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_reverse *__pyx_optional_args); /*proto*/
-static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdistance(struct __pyx_obj_9pywrapfst_Fst *, struct __pyx_opt_args_9pywrapfst__shortestdistance *__pyx_optional_args); /*proto*/
+static void __pyx_f_9pywrapfst__shortestdistance(struct __pyx_obj_9pywrapfst_Fst *, std::vector<fst::script::WeightClass>  *, struct __pyx_opt_args_9pywrapfst__shortestdistance *__pyx_optional_args); /*proto*/
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_shortestpath(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_shortestpath *__pyx_optional_args); /*proto*/
 static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_statemap(struct __pyx_obj_9pywrapfst_Fst *, PyObject *, int __pyx_skip_dispatch); /*proto*/
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_synchronize(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch); /*proto*/
-static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_compact_symbol_table(struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch); /*proto*/
-static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_merge_symbol_table(struct __pyx_obj_9pywrapfst__SymbolTable *, struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch); /*proto*/
+static fst::FarType __pyx_f_9pywrapfst__get_far_type(std::string const &); /*proto*/
+static fst::ProjectType __pyx_f_9pywrapfst__get_project_type(std::string const &); /*proto*/
+static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_compact_symbol_table(struct __pyx_obj_9pywrapfst_SymbolTableView *, int __pyx_skip_dispatch); /*proto*/
+static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_merge_symbol_table(struct __pyx_obj_9pywrapfst_SymbolTableView *, struct __pyx_obj_9pywrapfst_SymbolTableView *, int __pyx_skip_dispatch); /*proto*/
 static std::string __pyx_convert_string_from_py_std__in_string(PyObject *); /*proto*/
 static CYTHON_INLINE PyObject *__pyx_convert_PyObject_string_to_py_std__in_string(std::string const &); /*proto*/
 static CYTHON_INLINE PyObject *__pyx_convert_PyUnicode_string_to_py_std__in_string(std::string const &); /*proto*/
@@ -3052,29 +3043,35 @@ static CYTHON_INLINE PyObject *__pyx_convert_PyStr_string_to_py_std__in_string(s
 static CYTHON_INLINE PyObject *__pyx_convert_PyBytes_string_to_py_std__in_string(std::string const &); /*proto*/
 static CYTHON_INLINE PyObject *__pyx_convert_PyByteArray_string_to_py_std__in_string(std::string const &); /*proto*/
 static std::vector<int64>  __pyx_convert_vector_from_py_int64(PyObject *); /*proto*/
+static std::vector<std::string>  __pyx_convert_vector_from_py_std_3a__3a_string(PyObject *); /*proto*/
 #define __Pyx_MODULE_NAME "pywrapfst"
 extern int __pyx_module_is_main_pywrapfst;
 int __pyx_module_is_main_pywrapfst = 0;
 
 /* Implementation of 'pywrapfst' */
-static PyObject *__pyx_builtin_DeprecationWarning;
 static PyObject *__pyx_builtin_ValueError;
-static PyObject *__pyx_builtin_RuntimeError;
 static PyObject *__pyx_builtin_IndexError;
 static PyObject *__pyx_builtin_IOError;
+static PyObject *__pyx_builtin_RuntimeError;
 static PyObject *__pyx_builtin_staticmethod;
-static PyObject *__pyx_builtin_id;
 static PyObject *__pyx_builtin_TypeError;
+static PyObject *__pyx_builtin_id;
+static PyObject *__pyx_builtin_NotImplementedError;
 static PyObject *__pyx_builtin_StopIteration;
 static PyObject *__pyx_builtin_KeyError;
+static const char __pyx_k_[] = ": ";
 static const char __pyx_k_g[] = "g";
 static const char __pyx_k_n[] = "n";
 static const char __pyx_k_w[] = "w";
-static const char __pyx_k__8[] = "";
+static const char __pyx_k_x[] = "x";
+static const char __pyx_k__2[] = "<";
+static const char __pyx_k__3[] = ">";
 static const char __pyx_k_id[] = "id";
+static const char __pyx_k_os[] = "os";
 static const char __pyx_k_Arc[] = "Arc";
 static const char __pyx_k_Fst[] = "Fst";
 static const char __pyx_k_One[] = "One";
+static const char __pyx_k__11[] = "";
 static const char __pyx_k_add[] = "add";
 static const char __pyx_k_arc[] = "arc";
 static const char __pyx_k_doc[] = "__doc__";
@@ -3082,6 +3079,7 @@ static const char __pyx_k_dot[] = "dot";
 static const char __pyx_k_key[] = "key";
 static const char __pyx_k_lhs[] = "lhs";
 static const char __pyx_k_rhs[] = "rhs";
+static const char __pyx_k_sys[] = "sys";
 static const char __pyx_k_PIPE[] = "PIPE";
 static const char __pyx_k_Tsvg[] = "-Tsvg";
 static const char __pyx_k_Zero[] = "Zero";
@@ -3104,14 +3102,11 @@ static const char __pyx_k_read[] = "read";
 static const char __pyx_k_seed[] = "seed";
 static const char __pyx_k_seek[] = "seek";
 static const char __pyx_k_send[] = "send";
-static const char __pyx_k_syms[] = "syms";
 static const char __pyx_k_test[] = "test";
-static const char __pyx_k_text[] = "text";
 static const char __pyx_k_type[] = "type";
-static const char __pyx_k_utf8[] = "utf8";
-static const char __pyx_k_warn[] = "warn";
 static const char __pyx_k_ERROR[] = "ERROR";
 static const char __pyx_k_Popen[] = "Popen";
+static const char __pyx_k_at_0x[] = " at 0x";
 static const char __pyx_k_class[] = "__class__";
 static const char __pyx_k_close[] = "close";
 static const char __pyx_k_delta[] = "delta";
@@ -3139,12 +3134,11 @@ static const char __pyx_k_write[] = "write";
 static const char __pyx_k_CYCLIC[] = "CYCLIC";
 static const char __pyx_k_Number[] = "Number";
 static const char __pyx_k_STRING[] = "STRING";
-static const char __pyx_k_Weight[] = "Weight";
-static const char __pyx_k_always[] = "always";
+static const char __pyx_k_Weight[] = " Weight ";
 static const char __pyx_k_create[] = "create";
 static const char __pyx_k_divide[] = "divide";
-static const char __pyx_k_encode[] = "encode";
-static const char __pyx_k_format[] = "format";
+static const char __pyx_k_failed[] = " failed";
+static const char __pyx_k_fspath[] = "fspath";
 static const char __pyx_k_height[] = "height";
 static const char __pyx_k_ilabel[] = "ilabel";
 static const char __pyx_k_import[] = "__import__";
@@ -3156,20 +3150,22 @@ static const char __pyx_k_nstate[] = "nstate";
 static const char __pyx_k_olabel[] = "olabel";
 static const char __pyx_k_opairs[] = "opairs";
 static const char __pyx_k_reduce[] = "__reduce__";
-static const char __pyx_k_result[] = "result";
 static const char __pyx_k_select[] = "select";
 static const char __pyx_k_source[] = "source";
 static const char __pyx_k_states[] = "states";
 static const char __pyx_k_stdout[] = "stdout";
 static const char __pyx_k_symbol[] = "symbol";
 static const char __pyx_k_test_2[] = "__test__";
+static const char __pyx_k_typing[] = "typing";
 static const char __pyx_k_unique[] = "unique";
 static const char __pyx_k_vector[] = "vector";
 static const char __pyx_k_verify[] = "verify";
 static const char __pyx_k_weight[] = "weight";
 static const char __pyx_k_ACYCLIC[] = "ACYCLIC";
+static const char __pyx_k_FarType[] = "FarType";
 static const char __pyx_k_IOError[] = "IOError";
 static const char __pyx_k_MUTABLE[] = "MUTABLE";
+static const char __pyx_k_class_2[] = "_class__";
 static const char __pyx_k_compile[] = "compile";
 static const char __pyx_k_connect[] = "connect";
 static const char __pyx_k_default[] = "default";
@@ -3182,22 +3178,26 @@ static const char __pyx_k_numbers[] = "numbers";
 static const char __pyx_k_prepare[] = "__prepare__";
 static const char __pyx_k_ranksep[] = "ranksep";
 static const char __pyx_k_reverse[] = "reverse";
+static const char __pyx_k_symbols[] = "symbols";
 static const char __pyx_k_uniform[] = "uniform";
 static const char __pyx_k_warning[] = "warning";
 static const char __pyx_k_ACCEPTOR[] = "ACCEPTOR";
 static const char __pyx_k_Compiler[] = "Compiler";
 static const char __pyx_k_EPSILONS[] = "EPSILONS";
 static const char __pyx_k_EXPANDED[] = "EXPANDED";
+static const char __pyx_k_Expected[] = "Expected ";
 static const char __pyx_k_FstError[] = "FstError";
 static const char __pyx_k_KeyError[] = "KeyError";
 static const char __pyx_k_NO_LABEL[] = "NO_LABEL";
 static const char __pyx_k_NoWeight[] = "NoWeight";
+static const char __pyx_k_SortType[] = "SortType";
 static const char __pyx_k_WEIGHTED[] = "WEIGHTED";
+static const char __pyx_k_Weight_2[] = "Weight";
 static const char __pyx_k_acceptor[] = "acceptor";
 static const char __pyx_k_arc_type[] = "arc_type";
 static const char __pyx_k_checksum[] = "checksum";
 static const char __pyx_k_det_type[] = "det_type";
-static const char __pyx_k_distance[] = "distance";
+static const char __pyx_k_distance[] = "_distance";
 static const char __pyx_k_far_type[] = "far_type";
 static const char __pyx_k_fontsize[] = "fontsize";
 static const char __pyx_k_fst_type[] = "fst_type";
@@ -3218,12 +3218,15 @@ static const char __pyx_k_standard[] = "standard";
 static const char __pyx_k_to_final[] = "to_final";
 static const char __pyx_k_tropical[] = "tropical";
 static const char __pyx_k_vertical[] = "vertical";
-static const char __pyx_k_warnings[] = "warnings";
+static const char __pyx_k_weight_2[] = "_weight";
 static const char __pyx_k_weighted[] = "weighted";
 static const char __pyx_k_ARC_FLAGS[] = "ARC_FLAGS";
+static const char __pyx_k_Arc_at_0x[] = "<Arc at 0x";
 static const char __pyx_k_FarReader[] = "FarReader";
 static const char __pyx_k_FarWriter[] = "FarWriter";
+static const char __pyx_k_Fst_at_0x[] = " Fst at 0x";
 static const char __pyx_k_NO_SYMBOL[] = "NO_SYMBOL";
+static const char __pyx_k_QueueType[] = "QueueType";
 static const char __pyx_k_TypeError[] = "TypeError";
 static const char __pyx_k_VectorFst[] = "VectorFst";
 static const char __pyx_k_add_state[] = "add_state";
@@ -3240,6 +3243,7 @@ static const char __pyx_k_set_value[] = "set_value";
 static const char __pyx_k_sort_type[] = "sort_type";
 static const char __pyx_k_to_string[] = "to_string";
 static const char __pyx_k_ACCESSIBLE[] = "ACCESSIBLE";
+static const char __pyx_k_ArcMapType[] = "ArcMapType";
 static const char __pyx_k_FstIOError[] = "FstIOError";
 static const char __pyx_k_FstOpError[] = "FstOpError";
 static const char __pyx_k_I_EPSILONS[] = "I_EPSILONS";
@@ -3250,6 +3254,7 @@ static const char __pyx_k_O_EPSILONS[] = "O_EPSILONS";
 static const char __pyx_k_TOP_SORTED[] = "TOP_SORTED";
 static const char __pyx_k_UNWEIGHTED[] = "UNWEIGHTED";
 static const char __pyx_k_ValueError[] = "ValueError";
+static const char __pyx_k_WeightLike[] = "WeightLike";
 static const char __pyx_k_add_states[] = "add_states";
 static const char __pyx_k_add_symbol[] = "add_symbol";
 static const char __pyx_k_functional[] = "functional";
@@ -3259,17 +3264,16 @@ static const char __pyx_k_potentials[] = "potentials";
 static const char __pyx_k_properties[] = "properties";
 static const char __pyx_k_pyx_vtable[] = "__pyx_vtable__";
 static const char __pyx_k_queue_type[] = "queue_type";
-static const char __pyx_k_stacklevel[] = "stacklevel";
 static const char __pyx_k_subprocess[] = "subprocess";
 static const char __pyx_k_write_text[] = "write_text";
 static const char __pyx_k_ArcIterator[] = "ArcIterator";
-static const char __pyx_k_Arc_at_0x_x[] = "<Arc at 0x{:x}>";
 static const char __pyx_k_FstArgError[] = "FstArgError";
-static const char __pyx_k_Fst_at_0x_x[] = "<{} Fst at 0x{:x}>";
 static const char __pyx_k_NO_EPSILONS[] = "NO_EPSILONS";
 static const char __pyx_k_NO_STATE_ID[] = "NO_STATE_ID";
-static const char __pyx_k_Read_failed[] = "Read failed";
-static const char __pyx_k_SymbolTable[] = "_SymbolTable";
+static const char __pyx_k_Open_failed[] = "Open failed: ";
+static const char __pyx_k_ProjectType[] = "ProjectType";
+static const char __pyx_k_Read_failed[] = "Read failed: ";
+static const char __pyx_k_SymbolTable[] = "<SymbolTable ";
 static const char __pyx_k_communicate[] = "communicate";
 static const char __pyx_k_get_nth_key[] = "get_nth_key";
 static const char __pyx_k_input_table[] = "input_table";
@@ -3285,7 +3289,10 @@ static const char __pyx_k_ENCODE_FLAGS[] = "ENCODE_FLAGS";
 static const char __pyx_k_EncodeMapper[] = "EncodeMapper";
 static const char __pyx_k_NOT_ACCEPTOR[] = "NOT_ACCEPTOR";
 static const char __pyx_k_RuntimeError[] = "RuntimeError";
+static const char __pyx_k_StateMapType[] = "StateMapType";
+static const char __pyx_k_Write_failed[] = "Write failed: ";
 static const char __pyx_k_allow_nondet[] = "allow_nondet";
+static const char __pyx_k_but_received[] = " but received ";
 static const char __pyx_k_closure_plus[] = "closure_plus";
 static const char __pyx_k_float_format[] = "float_format";
 static const char __pyx_k_mutable_arcs[] = "mutable_arcs";
@@ -3295,14 +3302,13 @@ static const char __pyx_k_old_isymbols[] = "old_isymbols";
 static const char __pyx_k_old_osymbols[] = "old_osymbols";
 static const char __pyx_k_push_weights[] = "push_weights";
 static const char __pyx_k_return_label[] = "return_label";
-static const char __pyx_k_simplefilter[] = "simplefilter";
 static const char __pyx_k_staticmethod[] = "staticmethod";
+static const char __pyx_k_ComposeFilter[] = "ComposeFilter";
+static const char __pyx_k_Conversion_to[] = "Conversion to ";
 static const char __pyx_k_ENCODE_LABELS[] = "ENCODE_LABELS";
 static const char __pyx_k_FstIndexError[] = "FstIndexError";
 static const char __pyx_k_NO_I_EPSILONS[] = "NO_I_EPSILONS";
 static const char __pyx_k_NO_O_EPSILONS[] = "NO_O_EPSILONS";
-static const char __pyx_k_Open_failed_r[] = "Open failed: {!r}";
-static const char __pyx_k_Read_failed_r[] = "Read failed: {!r}";
 static const char __pyx_k_StateIterator[] = "StateIterator";
 static const char __pyx_k_StopIteration[] = "StopIteration";
 static const char __pyx_k_SymbolTable_2[] = "SymbolTable";
@@ -3311,6 +3317,7 @@ static const char __pyx_k_encode_labels[] = "encode_labels";
 static const char __pyx_k_input_symbols[] = "input_symbols";
 static const char __pyx_k_keep_isymbols[] = "keep_isymbols";
 static const char __pyx_k_keep_osymbols[] = "keep_osymbols";
+static const char __pyx_k_pywrapfst_pyx[] = "pywrapfst.pyx";
 static const char __pyx_k_reduce_cython[] = "__reduce_cython__";
 static const char __pyx_k_ENCODE_WEIGHTS[] = "ENCODE_WEIGHTS";
 static const char __pyx_k_FST_PROPERTIES[] = "FST_PROPERTIES";
@@ -3320,18 +3327,20 @@ static const char __pyx_k_Invalid_weight[] = "Invalid weight";
 static const char __pyx_k_NOT_ACCESSIBLE[] = "NOT_ACCESSIBLE";
 static const char __pyx_k_NOT_TOP_SORTED[] = "NOT_TOP_SORTED";
 static const char __pyx_k_O_LABEL_SORTED[] = "O_LABEL_SORTED";
-static const char __pyx_k_Weight_at_0x_x[] = "<{} Weight {} at 0x{:x}>";
-static const char __pyx_k_Write_failed_r[] = "Write failed: {!r}";
 static const char __pyx_k_compose_filter[] = "compose_filter";
 static const char __pyx_k_encode_weights[] = "encode_weights";
 static const char __pyx_k_output_symbols[] = "output_symbols";
-static const char __pyx_k_project_output[] = "project_output";
 static const char __pyx_k_ARC_VALUE_FLAGS[] = "ARC_VALUE_FLAGS";
 static const char __pyx_k_COPY_PROPERTIES[] = "COPY_PROPERTIES";
+static const char __pyx_k_DeterminizeType[] = "DeterminizeType";
+static const char __pyx_k_DrawFloatFormat[] = "DrawFloatFormat";
+static const char __pyx_k_FarReader_at_0x[] = " FarReader at 0x";
+static const char __pyx_k_FarWriter_at_0x[] = " FarWriter at 0x";
 static const char __pyx_k_INITIAL_ACYCLIC[] = "INITIAL_ACYCLIC";
 static const char __pyx_k_I_DETERMINISTIC[] = "I_DETERMINISTIC";
 static const char __pyx_k_NULL_PROPERTIES[] = "NULL_PROPERTIES";
 static const char __pyx_k_O_DETERMINISTIC[] = "O_DETERMINISTIC";
+static const char __pyx_k_SymbolTableView[] = "SymbolTableView";
 static const char __pyx_k_WEIGHTED_CYCLES[] = "WEIGHTED_CYCLES";
 static const char __pyx_k_eps_norm_output[] = "eps_norm_output";
 static const char __pyx_k_setstate_cython[] = "__setstate_cython__";
@@ -3340,25 +3349,28 @@ static const char __pyx_k_unknown_isymbol[] = "unknown_isymbol";
 static const char __pyx_k_unknown_osymbol[] = "unknown_osymbol";
 static const char __pyx_k_write_to_string[] = "write_to_string";
 static const char __pyx_k_ARC_WEIGHT_VALUE[] = "ARC_WEIGHT_VALUE";
-static const char __pyx_k_Cannot_construct[] = "Cannot construct {}";
+static const char __pyx_k_Cannot_construct[] = "Cannot construct ";
 static const char __pyx_k_NOT_COACCESSIBLE[] = "NOT_COACCESSIBLE";
 static const char __pyx_k_Operation_failed[] = "Operation failed";
+static const char __pyx_k_RandArcSelection[] = "RandArcSelection";
+static const char __pyx_k_ReplaceLabelType[] = "ReplaceLabelType";
+static const char __pyx_k_Unknown_FAR_type[] = "Unknown FAR type: ";
+static const char __pyx_k_Unknown_arc_type[] = "Unknown arc type: ";
+static const char __pyx_k_Unknown_map_type[] = "Unknown map type: ";
 static const char __pyx_k_labeled_checksum[] = "labeled_checksum";
 static const char __pyx_k_read_from_string[] = "read_from_string";
 static const char __pyx_k_shortestdistance[] = "shortestdistance";
 static const char __pyx_k_ARC_I_LABEL_VALUE[] = "ARC_I_LABEL_VALUE";
 static const char __pyx_k_ARC_O_LABEL_VALUE[] = "ARC_O_LABEL_VALUE";
+static const char __pyx_k_ArcIterator_at_0x[] = "<ArcIterator at 0x";
 static const char __pyx_k_BINARY_PROPERTIES[] = "BINARY_PROPERTIES";
-static const char __pyx_k_FarReader_at_0x_x[] = "<{} FarReader at 0x{:x}>";
-static const char __pyx_k_FarWriter_at_0x_x[] = "<{} FarWriter at 0x{:x}>";
 static const char __pyx_k_FstBadWeightError[] = "FstBadWeightError";
 static const char __pyx_k_UNWEIGHTED_CYCLES[] = "UNWEIGHTED_CYCLES";
-static const char __pyx_k_Use_print_instead[] = "Use `print` instead";
+static const char __pyx_k_Unknown_sort_type[] = "Unknown sort type: ";
 static const char __pyx_k_call_arc_labeling[] = "call_arc_labeling";
-static const char __pyx_k_src_pywrapfst_pyx[] = "src/pywrapfst.pyx";
 static const char __pyx_k_ADD_ARC_PROPERTIES[] = "ADD_ARC_PROPERTIES";
 static const char __pyx_k_Compilation_failed[] = "Compilation failed";
-static const char __pyx_k_DeprecationWarning[] = "DeprecationWarning";
+static const char __pyx_k_EncodeMapper_at_0x[] = "<EncodeMapper at 0x";
 static const char __pyx_k_FstSymbolTableView[] = "_FstSymbolTableView";
 static const char __pyx_k_MutableArcIterator[] = "MutableArcIterator";
 static const char __pyx_k_MutableSymbolTable[] = "_MutableSymbolTable";
@@ -3366,17 +3378,17 @@ static const char __pyx_k_NOT_I_LABEL_SORTED[] = "NOT_I_LABEL_SORTED";
 static const char __pyx_k_NOT_O_LABEL_SORTED[] = "NOT_O_LABEL_SORTED";
 static const char __pyx_k_SET_ARC_PROPERTIES[] = "SET_ARC_PROPERTIES";
 static const char __pyx_k_TRINARY_PROPERTIES[] = "TRINARY_PROPERTIES";
-static const char __pyx_k_Unknown_arc_type_r[] = "Unknown arc type: {!r}";
-static const char __pyx_k_Unknown_map_type_r[] = "Unknown map type: {!r}";
+static const char __pyx_k_Unknown_queue_type[] = "Unknown queue type: ";
 static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback";
 static const char __pyx_k_epsilon_on_replace[] = "epsilon_on_replace";
 static const char __pyx_k_num_input_epsilons[] = "num_input_epsilons";
 static const char __pyx_k_ARC_SORT_PROPERTIES[] = "ARC_SORT_PROPERTIES";
-static const char __pyx_k_ArcIterator_at_0x_x[] = "<ArcIterator at 0x{:x}>";
+static const char __pyx_k_Fst_SymbolTableView[] = "<Fst SymbolTableView ";
 static const char __pyx_k_NON_I_DETERMINISTIC[] = "NON_I_DETERMINISTIC";
 static const char __pyx_k_NON_O_DETERMINISTIC[] = "NON_O_DETERMINISTIC";
+static const char __pyx_k_NotImplementedError[] = "NotImplementedError";
+static const char __pyx_k_StateIterator_at_0x[] = "<StateIterator at 0x";
 static const char __pyx_k_SymbolTableIterator[] = "_SymbolTableIterator";
-static const char __pyx_k_Unknown_sort_type_r[] = "Unknown sort type {!r}";
 static const char __pyx_k_attach_new_isymbols[] = "attach_new_isymbols";
 static const char __pyx_k_attach_new_osymbols[] = "attach_new_osymbols";
 static const char __pyx_k_num_output_epsilons[] = "num_output_epsilons";
@@ -3387,66 +3399,74 @@ static const char __pyx_k_subsequential_label[] = "subsequential_label";
 static const char __pyx_k_ADD_STATE_PROPERTIES[] = "ADD_STATE_PROPERTIES";
 static const char __pyx_k_ARC_NEXT_STATE_VALUE[] = "ARC_NEXT_STATE_VALUE";
 static const char __pyx_k_EXTRINSIC_PROPERTIES[] = "EXTRINSIC_PROPERTIES";
-static const char __pyx_k_EncodeMapper_at_0x_x[] = "<EncodeMapper at 0x{:x}>";
 static const char __pyx_k_INTRINSIC_PROPERTIES[] = "INTRINSIC_PROPERTIES";
+static const char __pyx_k_Read_from_FST_failed[] = "Read from FST failed: ";
 static const char __pyx_k_SET_FINAL_PROPERTIES[] = "SET_FINAL_PROPERTIES";
 static const char __pyx_k_SET_START_PROPERTIES[] = "SET_START_PROPERTIES";
-static const char __pyx_k_Unknown_queue_type_r[] = "Unknown queue type: {!r}";
 static const char __pyx_k_keep_state_numbering[] = "keep_state_numbering";
 static const char __pyx_k_read_Fst_from_string[] = "_read_Fst_from_string";
 static const char __pyx_k_require_superinitial[] = "require_superinitial";
+static const char __pyx_k_typing_Literal_e_f_g[] = "typing.Literal[\"e\", \"f\", \"g\"]";
 static const char __pyx_k_DELETE_ARC_PROPERTIES[] = "DELETE_ARC_PROPERTIES";
 static const char __pyx_k_STATE_SORT_PROPERTIES[] = "STATE_SORT_PROPERTIES";
-static const char __pyx_k_StateIterator_at_0x_x[] = "<StateIterator at 0x{:x}>";
-static const char __pyx_k_SymbolTable_r_at_0x_x[] = "<SymbolTable {!r} at 0x{:x}>";
 static const char __pyx_k_Weight_type_not_found[] = "Weight type not found";
 static const char __pyx_k_allow_negative_labels[] = "allow_negative_labels";
-static const char __pyx_k_Conversion_to_r_failed[] = "Conversion to {!r} failed";
 static const char __pyx_k_Dot_rendering_failed_s[] = "Dot rendering failed: %s";
 static const char __pyx_k_NEG_TRINARY_PROPERTIES[] = "NEG_TRINARY_PROPERTIES";
 static const char __pyx_k_POS_TRINARY_PROPERTIES[] = "POS_TRINARY_PROPERTIES";
 static const char __pyx_k_Write_to_string_failed[] = "Write to string failed";
 static const char __pyx_k_DELETE_STATE_PROPERTIES[] = "DELETE_STATE_PROPERTIES";
+static const char __pyx_k_Read_from_string_failed[] = "Read from string failed";
+static const char __pyx_k_Unknown_projection_type[] = "Unknown projection type: ";
+static const char __pyx_k_MutableArcIterator_at_0x[] = "<MutableArcIterator at 0x";
 static const char __pyx_k_RM_SUPERFINAL_PROPERTIES[] = "RM_SUPERFINAL_PROPERTIES";
 static const char __pyx_k_State_index_out_of_range[] = "State index out of range";
 static const char __pyx_k_ADD_SUPERFINAL_PROPERTIES[] = "ADD_SUPERFINAL_PROPERTIES";
-static const char __pyx_k_Cannot_encode_as_string_r[] = "Cannot encode as string: {!r}";
 static const char __pyx_k_Cannot_topsort_cyclic_FST[] = "Cannot topsort cyclic FST";
 static const char __pyx_k_MutableArcIterator___iter[] = "MutableArcIterator.__iter__";
 static const char __pyx_k_MutableFstSymbolTableView[] = "_MutableFstSymbolTableView";
-static const char __pyx_k_FstDeletedConstructorError[] = "FstDeletedConstructorError";
-static const char __pyx_k_MutableArcIterator_at_0x_x[] = "<MutableArcIterator at 0x{:x}>";
+static const char __pyx_k_SymbolTableIterator_at_0x[] = "<_SymbolTableIterator at 0x";
+static const char __pyx_k_const_Fst_SymbolTableView[] = "<const Fst SymbolTableView ";
+static const char __pyx_k_Unknown_replace_label_type[] = "Unknown replace label type: ";
 static const char __pyx_k_EncodeMapperSymbolTableView[] = "_EncodeMapperSymbolTableView";
-static const char __pyx_k_SymbolTableIterator_at_0x_x[] = "<_SymbolTableIterator at 0x{:x}>";
+static const char __pyx_k_Unknown_compose_filter_type[] = "Unknown compose filter type: ";
 static const char __pyx_k_WEIGHT_INVARIANT_PROPERTIES[] = "WEIGHT_INVARIANT_PROPERTIES";
+static const char __pyx_k_typing_Literal_input_output[] = "typing.Literal[\"input\", \"output\"]";
 static const char __pyx_k_I_LABEL_INVARIANT_PROPERTIES[] = "I_LABEL_INVARIANT_PROPERTIES";
 static const char __pyx_k_O_LABEL_INVARIANT_PROPERTIES[] = "O_LABEL_INVARIANT_PROPERTIES";
 static const char __pyx_k_SymbolTable_no_longer_exists[] = "SymbolTable no longer exists";
-static const char __pyx_k_Unknown_replace_label_type_r[] = "Unknown replace label type: {!r}";
+static const char __pyx_k_Unknown_determinization_type[] = "Unknown determinization type: ";
 static const char __pyx_k_read_SymbolTable_from_string[] = "_read_SymbolTable_from_string";
-static const char __pyx_k_Fst_SymbolTableView_r_at_0x_x[] = "<Fst SymbolTableView {!r} at 0x{:x}>";
+static const char __pyx_k_typing_Literal_ilabel_olabel[] = "typing.Literal[\"ilabel\", \"olabel\"]";
 static const char __pyx_k_No_new_SymbolTables_specified[] = "No new SymbolTables specified";
 static const char __pyx_k_No_relabeling_pairs_specified[] = "No relabeling pairs specified";
-static const char __pyx_k_Unknown_compose_filter_type_r[] = "Unknown compose filter type: {!r}";
 static const char __pyx_k_increment_subsequential_label[] = "increment_subsequential_label";
 static const char __pyx_k_read_EncodeMapper_from_string[] = "_read_EncodeMapper_from_string";
 static const char __pyx_k_Incompatible_or_invalid_weight[] = "Incompatible or invalid weight";
-static const char __pyx_k_Unknown_determinization_type_r[] = "Unknown determinization type: {!r}";
-static const char __pyx_k_const_Fst_SymbolTableView_r_at[] = "<const Fst SymbolTableView {!r} at 0x{:x}>";
-static const char __pyx_k_const_EncodeMapper_SymbolTableV[] = "<const EncodeMapper SymbolTableView {!r} at 0x{:x}>";
+static const char __pyx_k_const_EncodeMapper_SymbolTableV[] = "<const EncodeMapper SymbolTableView ";
 static const char __pyx_k_self__aiter_self__fst_cannot_be[] = "self._aiter,self._fst cannot be converted to a Python object for pickling";
 static const char __pyx_k_self__fst_self__siter_cannot_be[] = "self._fst,self._siter cannot be converted to a Python object for pickling";
 static const char __pyx_k_self__siter_cannot_be_converted[] = "self._siter cannot be converted to a Python object for pickling";
+static const char __pyx_k_typing_Literal_uniform_log_prob[] = "typing.Literal[\"uniform\", \"log_prob\", \"fast_log_prob\"]";
 static const char __pyx_k_Incompatible_or_invalid_arc_type[] = "Incompatible or invalid arc type";
 static const char __pyx_k_Incompatible_or_invalid_weight_t[] = "Incompatible or invalid weight type";
 static const char __pyx_k_Python_interface_to_the_FST_scri[] = "Python interface to the FST scripting API.\n\nOperations which construct new FSTs are implemented as traditional functions, as\nare two-argument boolean functions like `equal` and `equivalent`. Destructive\noperations---those that mutate an FST, in place---are instance methods, as is\n`write`. Operator overloading is not used. The following example, based on\nMohri et al. 2002, shows the construction of an ASR system given a pronunciation\nlexicon L, grammar G, a transducer from context-dependent phones to\ncontext-independent phones C, and an HMM set H:\n\n  L = fst.Fst.read(\"L.fst\")\n  G = fst.Fst.read(\"G.fst\")\n  C = fst.Fst.read(\"C.fst\")\n  H = fst.Fst.read(\"H.fst\")\n  LG = fst.determinize(fst.compose(L, G))\n  CLG = fst.determinize(fst.compose(C, LG))\n  HCLG = fst.determinize(fst.compose(H, CLG))\n  HCLG.minimize()                                      # NB: works in-place.\n\nPython variables here use snake_case and constants are in all caps, minus the\nnormal `k` prefix.\n";
-static const char __pyx_k_Unknown_random_arc_selection_typ[] = "Unknown random arc selection type: {!r}";
+static const char __pyx_k_Unknown_random_arc_selection_typ[] = "Unknown random arc selection type: ";
 static const char __pyx_k_no_default___reduce___due_to_non[] = "no default __reduce__ due to non-trivial __cinit__";
 static const char __pyx_k_self__aiter_self__mfst_cannot_be[] = "self._aiter,self._mfst cannot be converted to a Python object for pickling";
 static const char __pyx_k_self__arc_cannot_be_converted_to[] = "self._arc cannot be converted to a Python object for pickling";
 static const char __pyx_k_self__reader_cannot_be_converted[] = "self._reader cannot be converted to a Python object for pickling";
 static const char __pyx_k_self__weight_cannot_be_converted[] = "self._weight cannot be converted to a Python object for pickling";
 static const char __pyx_k_self__writer_cannot_be_converted[] = "self._writer cannot be converted to a Python object for pickling";
+static const char __pyx_k_typing_Literal_alt_sequence_auto[] = "typing.Literal[\"alt_sequence\", \"auto\", \"match\", \"no_match\",\n                           \"null\", \"sequence\", \"trivial\"]";
+static const char __pyx_k_typing_Literal_arc_sum_arc_uniqu[] = "typing.Literal[\"arc_sum\", \"arc_unique\", \"identity\"]";
+static const char __pyx_k_typing_Literal_auto_fifo_lifo_sh[] = "typing.Literal[\"auto\", \"fifo\", \"lifo\", \"shortest\", \"state\",\n                              \"top\"]";
+static const char __pyx_k_typing_Literal_fst_stlist_sttabl[] = "typing.Literal[\n  \"fst\",\n  \"stlist\",\n  \"sttable\",\n  \"default\"\n]";
+static const char __pyx_k_typing_Literal_functional_nonfun[] = "typing.Literal[\"functional\", \"nonfunctional\",\n                                    \"disambiguate\"]";
+static const char __pyx_k_typing_Literal_identity_input_ep[] = "typing.Literal[\"identity\", \"input_epsilon\", \"invert\",\n                               \"output_epsilon\", \"plus\", \"power\", \"quantize\",\n                               \"rmweight\", \"superfinal\", \"times\", \"to_log\",\n                               # NOTE: Both spellings of \"to_std\"\n                               \"to_log64\", \"to_std\", \"to_standard\"]";
+static const char __pyx_k_typing_Literal_neither_input_out[] = "typing.Literal[\"neither\", \"input\", \"output\", \"both\"]";
+static const char __pyx_k_typing_Union_Weight_typing_Union[] = "typing.Union[Weight, typing.Union[str, int, float]]";
+static PyObject *__pyx_kp_u_;
 static PyObject *__pyx_n_s_ACCEPTOR;
 static PyObject *__pyx_n_s_ACCESSIBLE;
 static PyObject *__pyx_n_s_ACYCLIC;
@@ -3463,22 +3483,24 @@ static PyObject *__pyx_n_s_ARC_VALUE_FLAGS;
 static PyObject *__pyx_n_s_ARC_WEIGHT_VALUE;
 static PyObject *__pyx_n_s_Arc;
 static PyObject *__pyx_n_s_ArcIterator;
-static PyObject *__pyx_kp_u_ArcIterator_at_0x_x;
-static PyObject *__pyx_kp_u_Arc_at_0x_x;
+static PyObject *__pyx_kp_u_ArcIterator_at_0x;
+static PyObject *__pyx_n_s_ArcMapType;
+static PyObject *__pyx_kp_u_Arc_at_0x;
 static PyObject *__pyx_n_s_BINARY_PROPERTIES;
 static PyObject *__pyx_n_s_COACCESSIBLE;
 static PyObject *__pyx_n_s_COPY_PROPERTIES;
 static PyObject *__pyx_n_s_CYCLIC;
 static PyObject *__pyx_kp_u_Cannot_construct;
-static PyObject *__pyx_kp_u_Cannot_encode_as_string_r;
 static PyObject *__pyx_kp_u_Cannot_topsort_cyclic_FST;
 static PyObject *__pyx_kp_u_Compilation_failed;
 static PyObject *__pyx_n_s_Compiler;
-static PyObject *__pyx_kp_u_Conversion_to_r_failed;
+static PyObject *__pyx_n_s_ComposeFilter;
+static PyObject *__pyx_kp_u_Conversion_to;
 static PyObject *__pyx_n_s_DELETE_ARC_PROPERTIES;
 static PyObject *__pyx_n_s_DELETE_STATE_PROPERTIES;
-static PyObject *__pyx_n_s_DeprecationWarning;
+static PyObject *__pyx_n_s_DeterminizeType;
 static PyObject *__pyx_kp_u_Dot_rendering_failed_s;
+static PyObject *__pyx_n_s_DrawFloatFormat;
 static PyObject *__pyx_n_s_ENCODE_FLAGS;
 static PyObject *__pyx_n_s_ENCODE_LABELS;
 static PyObject *__pyx_n_s_ENCODE_WEIGHTS;
@@ -3488,23 +3510,24 @@ static PyObject *__pyx_n_s_EXPANDED;
 static PyObject *__pyx_n_s_EXTRINSIC_PROPERTIES;
 static PyObject *__pyx_n_s_EncodeMapper;
 static PyObject *__pyx_n_s_EncodeMapperSymbolTableView;
-static PyObject *__pyx_kp_u_EncodeMapper_at_0x_x;
+static PyObject *__pyx_kp_u_EncodeMapper_at_0x;
+static PyObject *__pyx_kp_u_Expected;
 static PyObject *__pyx_n_s_FST_PROPERTIES;
 static PyObject *__pyx_n_s_FarReader;
-static PyObject *__pyx_kp_u_FarReader_at_0x_x;
+static PyObject *__pyx_kp_u_FarReader_at_0x;
+static PyObject *__pyx_n_s_FarType;
 static PyObject *__pyx_n_s_FarWriter;
-static PyObject *__pyx_kp_u_FarWriter_at_0x_x;
+static PyObject *__pyx_kp_u_FarWriter_at_0x;
 static PyObject *__pyx_n_s_Fst;
 static PyObject *__pyx_n_s_FstArgError;
 static PyObject *__pyx_n_s_FstBadWeightError;
-static PyObject *__pyx_n_s_FstDeletedConstructorError;
 static PyObject *__pyx_n_s_FstError;
 static PyObject *__pyx_n_s_FstIOError;
 static PyObject *__pyx_n_s_FstIndexError;
 static PyObject *__pyx_n_s_FstOpError;
 static PyObject *__pyx_n_s_FstSymbolTableView;
-static PyObject *__pyx_kp_u_Fst_SymbolTableView_r_at_0x_x;
-static PyObject *__pyx_kp_u_Fst_at_0x_x;
+static PyObject *__pyx_kp_u_Fst_SymbolTableView;
+static PyObject *__pyx_kp_u_Fst_at_0x;
 static PyObject *__pyx_n_s_INITIAL_ACYCLIC;
 static PyObject *__pyx_n_s_INITIAL_CYCLIC;
 static PyObject *__pyx_n_s_INTRINSIC_PROPERTIES;
@@ -3522,7 +3545,7 @@ static PyObject *__pyx_n_s_KeyError;
 static PyObject *__pyx_n_s_MUTABLE;
 static PyObject *__pyx_n_s_MutableArcIterator;
 static PyObject *__pyx_n_s_MutableArcIterator___iter;
-static PyObject *__pyx_kp_u_MutableArcIterator_at_0x_x;
+static PyObject *__pyx_kp_u_MutableArcIterator_at_0x;
 static PyObject *__pyx_n_s_MutableFst;
 static PyObject *__pyx_n_s_MutableFstSymbolTableView;
 static PyObject *__pyx_n_s_MutableSymbolTable;
@@ -3546,63 +3569,75 @@ static PyObject *__pyx_n_s_NULL_PROPERTIES;
 static PyObject *__pyx_n_s_NoWeight;
 static PyObject *__pyx_kp_u_No_new_SymbolTables_specified;
 static PyObject *__pyx_kp_u_No_relabeling_pairs_specified;
+static PyObject *__pyx_n_s_NotImplementedError;
 static PyObject *__pyx_n_s_Number;
 static PyObject *__pyx_n_s_O_DETERMINISTIC;
 static PyObject *__pyx_n_s_O_EPSILONS;
 static PyObject *__pyx_n_s_O_LABEL_INVARIANT_PROPERTIES;
 static PyObject *__pyx_n_s_O_LABEL_SORTED;
 static PyObject *__pyx_n_s_One;
-static PyObject *__pyx_kp_u_Open_failed_r;
+static PyObject *__pyx_kp_u_Open_failed;
 static PyObject *__pyx_kp_u_Operation_failed;
 static PyObject *__pyx_n_s_PIPE;
 static PyObject *__pyx_n_s_POS_TRINARY_PROPERTIES;
 static PyObject *__pyx_n_s_Popen;
+static PyObject *__pyx_n_s_ProjectType;
+static PyObject *__pyx_n_s_QueueType;
 static PyObject *__pyx_n_s_RM_SUPERFINAL_PROPERTIES;
+static PyObject *__pyx_n_s_RandArcSelection;
 static PyObject *__pyx_kp_u_Read_failed;
-static PyObject *__pyx_kp_u_Read_failed_r;
+static PyObject *__pyx_kp_u_Read_from_FST_failed;
+static PyObject *__pyx_kp_u_Read_from_string_failed;
+static PyObject *__pyx_n_s_ReplaceLabelType;
 static PyObject *__pyx_n_s_RuntimeError;
 static PyObject *__pyx_n_s_SET_ARC_PROPERTIES;
 static PyObject *__pyx_n_s_SET_FINAL_PROPERTIES;
 static PyObject *__pyx_n_s_SET_START_PROPERTIES;
 static PyObject *__pyx_n_s_STATE_SORT_PROPERTIES;
 static PyObject *__pyx_n_s_STRING;
+static PyObject *__pyx_n_s_SortType;
 static PyObject *__pyx_n_s_StateIterator;
-static PyObject *__pyx_kp_u_StateIterator_at_0x_x;
+static PyObject *__pyx_kp_u_StateIterator_at_0x;
+static PyObject *__pyx_n_s_StateMapType;
 static PyObject *__pyx_kp_u_State_index_out_of_range;
 static PyObject *__pyx_n_s_StopIteration;
-static PyObject *__pyx_n_s_SymbolTable;
+static PyObject *__pyx_kp_u_SymbolTable;
 static PyObject *__pyx_n_s_SymbolTableIterator;
-static PyObject *__pyx_kp_u_SymbolTableIterator_at_0x_x;
+static PyObject *__pyx_kp_u_SymbolTableIterator_at_0x;
+static PyObject *__pyx_n_s_SymbolTableView;
 static PyObject *__pyx_n_s_SymbolTable_2;
 static PyObject *__pyx_kp_u_SymbolTable_no_longer_exists;
-static PyObject *__pyx_kp_u_SymbolTable_r_at_0x_x;
 static PyObject *__pyx_n_s_TOP_SORTED;
 static PyObject *__pyx_n_s_TRINARY_PROPERTIES;
 static PyObject *__pyx_kp_u_Tsvg;
 static PyObject *__pyx_n_s_TypeError;
 static PyObject *__pyx_n_s_UNWEIGHTED;
 static PyObject *__pyx_n_s_UNWEIGHTED_CYCLES;
-static PyObject *__pyx_kp_u_Unknown_arc_type_r;
-static PyObject *__pyx_kp_u_Unknown_compose_filter_type_r;
-static PyObject *__pyx_kp_u_Unknown_determinization_type_r;
-static PyObject *__pyx_kp_u_Unknown_map_type_r;
-static PyObject *__pyx_kp_u_Unknown_queue_type_r;
+static PyObject *__pyx_kp_u_Unknown_FAR_type;
+static PyObject *__pyx_kp_u_Unknown_arc_type;
+static PyObject *__pyx_kp_u_Unknown_compose_filter_type;
+static PyObject *__pyx_kp_u_Unknown_determinization_type;
+static PyObject *__pyx_kp_u_Unknown_map_type;
+static PyObject *__pyx_kp_u_Unknown_projection_type;
+static PyObject *__pyx_kp_u_Unknown_queue_type;
 static PyObject *__pyx_kp_u_Unknown_random_arc_selection_typ;
-static PyObject *__pyx_kp_u_Unknown_replace_label_type_r;
-static PyObject *__pyx_kp_u_Unknown_sort_type_r;
-static PyObject *__pyx_kp_u_Use_print_instead;
+static PyObject *__pyx_kp_u_Unknown_replace_label_type;
+static PyObject *__pyx_kp_u_Unknown_sort_type;
 static PyObject *__pyx_n_s_ValueError;
 static PyObject *__pyx_n_s_VectorFst;
 static PyObject *__pyx_n_s_WEIGHTED;
 static PyObject *__pyx_n_s_WEIGHTED_CYCLES;
 static PyObject *__pyx_n_s_WEIGHT_INVARIANT_PROPERTIES;
-static PyObject *__pyx_n_s_Weight;
-static PyObject *__pyx_kp_u_Weight_at_0x_x;
+static PyObject *__pyx_kp_u_Weight;
+static PyObject *__pyx_n_s_WeightLike;
+static PyObject *__pyx_n_s_Weight_2;
 static PyObject *__pyx_kp_u_Weight_type_not_found;
-static PyObject *__pyx_kp_u_Write_failed_r;
+static PyObject *__pyx_kp_u_Write_failed;
 static PyObject *__pyx_kp_u_Write_to_string_failed;
 static PyObject *__pyx_n_s_Zero;
-static PyObject *__pyx_kp_b__8;
+static PyObject *__pyx_kp_u__11;
+static PyObject *__pyx_kp_u__2;
+static PyObject *__pyx_kp_u__3;
 static PyObject *__pyx_n_s_acceptor;
 static PyObject *__pyx_n_s_add;
 static PyObject *__pyx_n_s_add_state;
@@ -3611,18 +3646,20 @@ static PyObject *__pyx_n_s_add_symbol;
 static PyObject *__pyx_n_s_add_table;
 static PyObject *__pyx_n_s_allow_negative_labels;
 static PyObject *__pyx_n_s_allow_nondet;
-static PyObject *__pyx_n_u_always;
 static PyObject *__pyx_n_s_arc;
 static PyObject *__pyx_n_s_arc_type;
 static PyObject *__pyx_n_s_arcs;
 static PyObject *__pyx_n_s_args;
+static PyObject *__pyx_kp_u_at_0x;
 static PyObject *__pyx_n_s_attach_new_isymbols;
 static PyObject *__pyx_n_s_attach_new_osymbols;
-static PyObject *__pyx_n_b_auto;
+static PyObject *__pyx_n_u_auto;
 static PyObject *__pyx_n_s_available_key;
+static PyObject *__pyx_kp_u_but_received;
 static PyObject *__pyx_n_s_call_arc_labeling;
 static PyObject *__pyx_n_s_checksum;
 static PyObject *__pyx_n_s_class;
+static PyObject *__pyx_n_s_class_2;
 static PyObject *__pyx_n_s_cline_in_traceback;
 static PyObject *__pyx_n_s_close;
 static PyObject *__pyx_n_s_closure_plus;
@@ -3631,10 +3668,10 @@ static PyObject *__pyx_n_s_compile;
 static PyObject *__pyx_n_s_compose_filter;
 static PyObject *__pyx_n_s_connect;
 static PyObject *__pyx_kp_u_const_EncodeMapper_SymbolTableV;
-static PyObject *__pyx_kp_u_const_Fst_SymbolTableView_r_at;
+static PyObject *__pyx_kp_u_const_Fst_SymbolTableView;
 static PyObject *__pyx_n_s_copy;
 static PyObject *__pyx_n_s_create;
-static PyObject *__pyx_n_b_default;
+static PyObject *__pyx_n_u_default;
 static PyObject *__pyx_n_s_delta;
 static PyObject *__pyx_n_s_det_type;
 static PyObject *__pyx_n_s_distance;
@@ -3643,37 +3680,37 @@ static PyObject *__pyx_n_s_doc;
 static PyObject *__pyx_n_s_done;
 static PyObject *__pyx_n_u_dot;
 static PyObject *__pyx_n_s_draw;
-static PyObject *__pyx_n_s_encode;
 static PyObject *__pyx_n_s_encode_labels;
 static PyObject *__pyx_n_s_encode_weights;
 static PyObject *__pyx_n_s_eps_norm_output;
 static PyObject *__pyx_n_s_epsilon_on_replace;
 static PyObject *__pyx_n_s_error;
+static PyObject *__pyx_kp_u_failed;
 static PyObject *__pyx_n_s_far_type;
 static PyObject *__pyx_n_s_final;
 static PyObject *__pyx_n_s_find;
 static PyObject *__pyx_n_s_flags;
 static PyObject *__pyx_n_s_float_format;
 static PyObject *__pyx_n_s_fontsize;
-static PyObject *__pyx_n_s_format;
+static PyObject *__pyx_n_s_fspath;
 static PyObject *__pyx_n_s_fst_type;
-static PyObject *__pyx_n_b_functional;
-static PyObject *__pyx_n_b_g;
+static PyObject *__pyx_n_u_functional;
+static PyObject *__pyx_n_u_g;
 static PyObject *__pyx_n_s_get_fst;
 static PyObject *__pyx_n_s_get_key;
 static PyObject *__pyx_n_s_get_nth_key;
 static PyObject *__pyx_n_s_getstate;
 static PyObject *__pyx_n_s_height;
 static PyObject *__pyx_n_s_id;
-static PyObject *__pyx_n_b_identity;
+static PyObject *__pyx_n_u_identity;
 static PyObject *__pyx_n_s_ifst;
 static PyObject *__pyx_n_s_ifst1;
 static PyObject *__pyx_n_s_ifst2;
-static PyObject *__pyx_n_b_ilabel;
 static PyObject *__pyx_n_s_ilabel;
+static PyObject *__pyx_n_u_ilabel;
 static PyObject *__pyx_n_s_import;
 static PyObject *__pyx_n_s_increment_subsequential_label;
-static PyObject *__pyx_n_b_input;
+static PyObject *__pyx_n_u_input;
 static PyObject *__pyx_n_s_input_symbols;
 static PyObject *__pyx_n_s_input_table;
 static PyObject *__pyx_n_s_ipairs;
@@ -3698,7 +3735,7 @@ static PyObject *__pyx_n_s_mutable_arcs;
 static PyObject *__pyx_n_s_n;
 static PyObject *__pyx_n_s_name;
 static PyObject *__pyx_n_s_name_2;
-static PyObject *__pyx_n_b_neither;
+static PyObject *__pyx_n_u_neither;
 static PyObject *__pyx_n_s_new_isymbols;
 static PyObject *__pyx_n_s_new_osymbols;
 static PyObject *__pyx_n_s_next;
@@ -3719,6 +3756,7 @@ static PyObject *__pyx_n_s_old_isymbols;
 static PyObject *__pyx_n_s_old_osymbols;
 static PyObject *__pyx_n_s_opairs;
 static PyObject *__pyx_n_s_open;
+static PyObject *__pyx_n_s_os;
 static PyObject *__pyx_n_s_osymbols;
 static PyObject *__pyx_n_s_output_symbols;
 static PyObject *__pyx_n_s_pairs;
@@ -3730,12 +3768,12 @@ static PyObject *__pyx_n_s_power;
 static PyObject *__pyx_n_s_precision;
 static PyObject *__pyx_n_s_prepare;
 static PyObject *__pyx_n_s_print;
-static PyObject *__pyx_n_s_project_output;
 static PyObject *__pyx_n_s_properties;
 static PyObject *__pyx_n_s_props;
 static PyObject *__pyx_n_s_push_labels;
 static PyObject *__pyx_n_s_push_weights;
 static PyObject *__pyx_n_s_pywrapfst_2;
+static PyObject *__pyx_kp_s_pywrapfst_pyx;
 static PyObject *__pyx_n_s_pyx_vtable;
 static PyObject *__pyx_n_s_qualname;
 static PyObject *__pyx_n_s_queue_type;
@@ -3754,7 +3792,6 @@ static PyObject *__pyx_n_s_remove_common_affix;
 static PyObject *__pyx_n_s_remove_total_weight;
 static PyObject *__pyx_n_s_require_superinitial;
 static PyObject *__pyx_n_s_reset;
-static PyObject *__pyx_n_s_result;
 static PyObject *__pyx_n_s_return_arc_labeling;
 static PyObject *__pyx_n_s_return_label;
 static PyObject *__pyx_n_s_reverse;
@@ -3778,13 +3815,10 @@ static PyObject *__pyx_n_s_setstate;
 static PyObject *__pyx_n_s_setstate_cython;
 static PyObject *__pyx_n_s_shortestdistance;
 static PyObject *__pyx_n_s_show_weight_one;
-static PyObject *__pyx_n_s_simplefilter;
 static PyObject *__pyx_n_s_sort_type;
 static PyObject *__pyx_n_s_source;
-static PyObject *__pyx_kp_s_src_pywrapfst_pyx;
 static PyObject *__pyx_n_s_ssymbols;
-static PyObject *__pyx_n_s_stacklevel;
-static PyObject *__pyx_n_b_standard;
+static PyObject *__pyx_n_u_standard;
 static PyObject *__pyx_n_s_start;
 static PyObject *__pyx_n_s_state;
 static PyObject *__pyx_n_s_states;
@@ -3794,37 +3828,49 @@ static PyObject *__pyx_n_s_stdout;
 static PyObject *__pyx_n_s_subprocess;
 static PyObject *__pyx_n_s_subsequential_label;
 static PyObject *__pyx_n_s_symbol;
-static PyObject *__pyx_n_s_syms;
+static PyObject *__pyx_n_s_symbols;
+static PyObject *__pyx_n_s_sys;
 static PyObject *__pyx_n_s_test;
 static PyObject *__pyx_n_s_test_2;
-static PyObject *__pyx_n_s_text;
 static PyObject *__pyx_n_s_throw;
 static PyObject *__pyx_n_s_times;
 static PyObject *__pyx_n_s_title;
 static PyObject *__pyx_n_s_to_final;
 static PyObject *__pyx_n_s_to_string;
 static PyObject *__pyx_n_s_type;
-static PyObject *__pyx_n_b_uniform;
+static PyObject *__pyx_n_s_typing;
+static PyObject *__pyx_kp_u_typing_Literal_alt_sequence_auto;
+static PyObject *__pyx_kp_u_typing_Literal_arc_sum_arc_uniqu;
+static PyObject *__pyx_kp_u_typing_Literal_auto_fifo_lifo_sh;
+static PyObject *__pyx_kp_u_typing_Literal_e_f_g;
+static PyObject *__pyx_kp_u_typing_Literal_fst_stlist_sttabl;
+static PyObject *__pyx_kp_u_typing_Literal_functional_nonfun;
+static PyObject *__pyx_kp_u_typing_Literal_identity_input_ep;
+static PyObject *__pyx_kp_u_typing_Literal_ilabel_olabel;
+static PyObject *__pyx_kp_u_typing_Literal_input_output;
+static PyObject *__pyx_kp_u_typing_Literal_neither_input_out;
+static PyObject *__pyx_kp_u_typing_Literal_uniform_log_prob;
+static PyObject *__pyx_kp_u_typing_Union_Weight_typing_Union;
+static PyObject *__pyx_n_u_uniform;
 static PyObject *__pyx_n_s_unique;
 static PyObject *__pyx_n_s_unknown_isymbol;
 static PyObject *__pyx_n_s_unknown_osymbol;
 static PyObject *__pyx_kp_u_unspecified;
-static PyObject *__pyx_n_u_utf8;
 static PyObject *__pyx_n_s_value;
-static PyObject *__pyx_n_b_vector;
+static PyObject *__pyx_n_u_vector;
 static PyObject *__pyx_n_s_verify;
 static PyObject *__pyx_n_s_vertical;
 static PyObject *__pyx_n_s_w;
-static PyObject *__pyx_n_s_warn;
 static PyObject *__pyx_n_s_warning;
-static PyObject *__pyx_n_s_warnings;
 static PyObject *__pyx_n_s_weight;
+static PyObject *__pyx_n_s_weight_2;
 static PyObject *__pyx_n_s_weight_type;
 static PyObject *__pyx_n_s_weighted;
 static PyObject *__pyx_n_s_width;
 static PyObject *__pyx_n_s_write;
 static PyObject *__pyx_n_s_write_text;
 static PyObject *__pyx_n_s_write_to_string;
+static PyObject *__pyx_n_u_x;
 static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfst_Weight *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_6Weight_2__str__(struct __pyx_obj_9pywrapfst_Weight *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_6Weight_4__float__(struct __pyx_obj_9pywrapfst_Weight *__pyx_v_self); /* proto */
@@ -3844,26 +3890,25 @@ static PyObject *__pyx_pf_9pywrapfst_plus(CYTHON_UNUSED PyObject *__pyx_self, st
 static PyObject *__pyx_pf_9pywrapfst_2times(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Weight *__pyx_v_lhs, struct __pyx_obj_9pywrapfst_Weight *__pyx_v_rhs); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_4divide(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Weight *__pyx_v_lhs, struct __pyx_obj_9pywrapfst_Weight *__pyx_v_rhs); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_6power(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Weight *__pyx_v_w, size_t __pyx_v_n); /* proto */
-static int __pyx_pf_9pywrapfst_12_SymbolTable___init__(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_2__iter__(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_4__reduce__(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_6available_key(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_8checksum(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_10copy(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_12find(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_14get_nth_key(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, Py_ssize_t __pyx_v_pos); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_16labeled_checksum(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_18member(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
-static int __pyx_pf_9pywrapfst_12_SymbolTable_20__contains__(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_22name(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_24num_symbols(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_26write(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_source); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_28write_text(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_source); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_30write_to_string(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self); /* proto */
+static int __pyx_pf_9pywrapfst_15SymbolTableView___init__(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_2__iter__(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_4__reduce__(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_6available_key(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_8checksum(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_10copy(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_12find(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_14get_nth_key(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, Py_ssize_t __pyx_v_pos); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_16labeled_checksum(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_18member(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_20name(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_22num_symbols(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_24write(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, PyObject *__pyx_v_source); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_26write_text(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, PyObject *__pyx_v_source); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_28write_to_string(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_28_EncodeMapperSymbolTableView___repr__(struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_19_FstSymbolTableView___repr__(struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self, PyObject *__pyx_v_symbol, int64 __pyx_v_key); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_2add_table(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_2add_table(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_4set_name(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self, PyObject *__pyx_v_new_name); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_26_MutableFstSymbolTableView___repr__(struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_self); /* proto */
@@ -3871,11 +3916,11 @@ static int __pyx_pf_9pywrapfst_11SymbolTable_2__init__(struct __pyx_obj_9pywrapf
 static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source, bool __pyx_v_allow_negative_labels); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source, bool __pyx_v_input_table); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_8_read_SymbolTable_from_string(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_state); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_10compact_symbol_table(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12merge_symbol_table(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_lhs, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_rhs); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_8_read_SymbolTable_from_string(CYTHON_UNUSED PyObject *__pyx_self, std::string __pyx_v_state); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_10compact_symbol_table(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12merge_symbol_table(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_lhs, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_rhs); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator___repr__(struct __pyx_obj_9pywrapfst__SymbolTableIterator *__pyx_v_self); /* proto */
-static int __pyx_pf_9pywrapfst_20_SymbolTableIterator_2__init__(struct __pyx_obj_9pywrapfst__SymbolTableIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto */
+static int __pyx_pf_9pywrapfst_20_SymbolTableIterator_2__init__(struct __pyx_obj_9pywrapfst__SymbolTableIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_4__iter__(struct __pyx_obj_9pywrapfst__SymbolTableIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_6__next__(struct __pyx_obj_9pywrapfst__SymbolTableIterator *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_8__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__SymbolTableIterator *__pyx_v_self); /* proto */
@@ -3894,9 +3939,9 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_20write(struct __pyx_obj_9py
 static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_22write_to_string(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_24input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_26output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_28set_input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_30set_output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_14_read_EncodeMapper_from_string(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_state); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_28set_input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_30set_output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_14_read_EncodeMapper_from_string(CYTHON_UNUSED PyObject *__pyx_self, std::string __pyx_v_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self); /* proto */
 static int __pyx_pf_9pywrapfst_3Fst_2__init__(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Fst_4__reduce__(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self); /* proto */
@@ -3905,7 +3950,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_8__str__(struct __pyx_obj_9pywrapfst_F
 static PyObject *__pyx_pf_9pywrapfst_3Fst_10arc_type(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Fst_12arcs(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int64 __pyx_v_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Fst_14copy(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_3Fst_16draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, PyObject *__pyx_v_source, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_ssymbols, bool __pyx_v_acceptor, PyObject *__pyx_v_title, double __pyx_v_width, double __pyx_v_height, bool __pyx_v_portrait, bool __pyx_v_vertical, double __pyx_v_ranksep, double __pyx_v_nodesep, int32 __pyx_v_fontsize, int32 __pyx_v_precision, PyObject *__pyx_v_float_format, bool __pyx_v_show_weight_one); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_3Fst_16draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, PyObject *__pyx_v_source, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_isymbols, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_osymbols, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_ssymbols, bool __pyx_v_acceptor, PyObject *__pyx_v_title, double __pyx_v_width, double __pyx_v_height, bool __pyx_v_portrait, bool __pyx_v_vertical, double __pyx_v_ranksep, double __pyx_v_nodesep, int32 __pyx_v_fontsize, int32 __pyx_v_precision, PyObject *__pyx_v_float_format, bool __pyx_v_show_weight_one); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Fst_18final(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int64 __pyx_v_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Fst_20fst_type(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Fst_22input_symbols(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self); /* proto */
@@ -3913,17 +3958,16 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_24num_arcs(struct __pyx_obj_9pywrapfst
 static PyObject *__pyx_pf_9pywrapfst_3Fst_26num_input_epsilons(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int64 __pyx_v_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Fst_28num_output_epsilons(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int64 __pyx_v_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Fst_30output_symbols(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_3Fst_32print(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_ssymbols, bool __pyx_v_acceptor, bool __pyx_v_show_weight_one, PyObject *__pyx_v_missing_sym); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_3Fst_32print(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_isymbols, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_osymbols, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_ssymbols, bool __pyx_v_acceptor, bool __pyx_v_show_weight_one, PyObject *__pyx_v_missing_sym); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Fst_34properties(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, uint64 __pyx_v_mask, bool __pyx_v_test); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Fst_36read(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Fst_38read_from_string(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Fst_40start(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Fst_42states(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_3Fst_44text(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_ssymbols, bool __pyx_v_acceptor, bool __pyx_v_show_weight_one, PyObject *__pyx_v_missing_sym); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_3Fst_46verify(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_3Fst_48weight_type(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_3Fst_50write(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, PyObject *__pyx_v_source); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_3Fst_52write_to_string(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_3Fst_44verify(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_3Fst_46weight_type(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_3Fst_48write(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, PyObject *__pyx_v_source); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_3Fst_50write_to_string(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_add_arc(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_2add_state(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_4add_states(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, size_t __pyx_v_n); /* proto */
@@ -3941,25 +3985,25 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_26mutable_arcs(struct __pyx_ob
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_28mutable_input_symbols(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_30mutable_output_symbols(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_32num_states(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_10MutableFst_34project(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, bool __pyx_v_project_output); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_34project(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, PyObject *__pyx_v_project_type); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_36prune(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, float __pyx_v_delta, int64 __pyx_v_nstate, PyObject *__pyx_v_weight); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_38push(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, float __pyx_v_delta, bool __pyx_v_remove_total_weight, bool __pyx_v_to_final); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_40relabel_pairs(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, PyObject *__pyx_v_ipairs, PyObject *__pyx_v_opairs); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_10MutableFst_42relabel_tables(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_new_isymbols, PyObject *__pyx_v_unknown_isymbol, bool __pyx_v_attach_new_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_osymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_new_osymbols, PyObject *__pyx_v_unknown_osymbol, bool __pyx_v_attach_new_osymbols); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_42relabel_tables(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_old_isymbols, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_new_isymbols, PyObject *__pyx_v_unknown_isymbol, bool __pyx_v_attach_new_isymbols, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_old_osymbols, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_new_osymbols, PyObject *__pyx_v_unknown_osymbol, bool __pyx_v_attach_new_osymbols); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_44reserve_arcs(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state, size_t __pyx_v_n); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_46reserve_states(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_n); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_48reweight(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, PyObject *__pyx_v_potentials, bool __pyx_v_to_final); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_50rmepsilon(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, PyObject *__pyx_v_queue_type, bool __pyx_v_connect, PyObject *__pyx_v_weight, int64 __pyx_v_nstate, float __pyx_v_delta); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_52set_final(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state, PyObject *__pyx_v_weight); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_10MutableFst_54set_input_symbols(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_10MutableFst_56set_output_symbols(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_54set_input_symbols(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_56set_output_symbols(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_58set_properties(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, uint64 __pyx_v_props, uint64 __pyx_v_mask); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_60set_start(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_62topsort(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_64union(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, PyObject *__pyx_v_fsts2); /* proto */
 static int __pyx_pf_9pywrapfst_9VectorFst___init__(struct __pyx_obj_9pywrapfst_VectorFst *__pyx_v_self, PyObject *__pyx_v_arc_type); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_16_read_Fst(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_source); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_18_read_Fst_from_string(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_state); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_18_read_Fst_from_string(CYTHON_UNUSED PyObject *__pyx_self, std::string __pyx_v_state); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self); /* proto */
 static int __pyx_pf_9pywrapfst_3Arc_2__init__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, int64 __pyx_v_ilabel, int64 __pyx_v_olabel, PyObject *__pyx_v_weight, int64 __pyx_v_nextstate); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_3Arc_4copy(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self); /* proto */
@@ -4024,15 +4068,15 @@ static PyObject *__pyx_pf_9pywrapfst_38intersect(CYTHON_UNUSED PyObject *__pyx_s
 static PyObject *__pyx_pf_9pywrapfst_40isomorphic(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, float __pyx_v_delta); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_42prune(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, float __pyx_v_delta, int64 __pyx_v_nstate, PyObject *__pyx_v_weight); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_44push(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, float __pyx_v_delta, bool __pyx_v_push_weights, bool __pyx_v_push_labels, bool __pyx_v_remove_common_affix, bool __pyx_v_remove_total_weight, bool __pyx_v_to_final); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_46randequivalent(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, int32 __pyx_v_npath, float __pyx_v_delta, time_t __pyx_v_seed, PyObject *__pyx_v_select, int32 __pyx_v_max_length); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_48randgen(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, int32 __pyx_v_npath, time_t __pyx_v_seed, PyObject *__pyx_v_select, int32 __pyx_v_max_length, bool __pyx_v_weighted, bool __pyx_v_remove_total_weight); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_46randequivalent(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, int32 __pyx_v_npath, float __pyx_v_delta, PyObject *__pyx_v_select, int32 __pyx_v_max_length, uint64 __pyx_v_seed); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_48randgen(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, int32 __pyx_v_npath, PyObject *__pyx_v_select, int32 __pyx_v_max_length, bool __pyx_v_weighted, bool __pyx_v_remove_total_weight, uint64 __pyx_v_seed); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_50replace(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_pairs, PyObject *__pyx_v_call_arc_labeling, PyObject *__pyx_v_return_arc_labeling, bool __pyx_v_epsilon_on_replace, int64 __pyx_v_return_label); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_52reverse(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, bool __pyx_v_require_superinitial); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, float __pyx_v_delta, int64 __pyx_v_nstate, PyObject *__pyx_v_queue_type, bool __pyx_v_reverse); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_56shortestpath(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, float __pyx_v_delta, int32 __pyx_v_nshortest, int64 __pyx_v_nstate, PyObject *__pyx_v_queue_type, bool __pyx_v_unique, PyObject *__pyx_v_weight); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_58statemap(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, PyObject *__pyx_v_map_type); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_60synchronize(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst); /* proto */
-static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_Compiler *__pyx_v_self, std::string __pyx_v_fst_type, std::string __pyx_v_arc_type, struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_isymbols, struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_osymbols, struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_ssymbols, bool __pyx_v_acceptor, bool __pyx_v_keep_isymbols, bool __pyx_v_keep_osymbols, bool __pyx_v_keep_state_numbering, bool __pyx_v_allow_negative_labels); /* proto */
+static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_Compiler *__pyx_v_self, PyObject *__pyx_v_fst_type, PyObject *__pyx_v_arc_type, struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_isymbols, struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_osymbols, struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_ssymbols, bool __pyx_v_acceptor, bool __pyx_v_keep_isymbols, bool __pyx_v_keep_osymbols, bool __pyx_v_keep_state_numbering, bool __pyx_v_allow_negative_labels); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_8Compiler_2compile(struct __pyx_obj_9pywrapfst_Compiler *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_8Compiler_4write(struct __pyx_obj_9pywrapfst_Compiler *__pyx_v_self, PyObject *__pyx_v_expression); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_8Compiler_6__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_Compiler *__pyx_v_self); /* proto */
@@ -4050,8 +4094,10 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_18get_key(struct __pyx_obj_9pywr
 static PyObject *__pyx_pf_9pywrapfst_9FarReader_20next(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_9FarReader_22reset(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_9FarReader_26__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_9pywrapfst_9FarReader_28__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_9FarReader_26__next__(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_9FarReader_28__iter__(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_9FarReader_30__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_9pywrapfst_9FarReader_32__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
 static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source, PyObject *__pyx_v_arc_type, PyObject *__pyx_v_far_type); /* proto */
@@ -4063,7 +4109,7 @@ static int __pyx_pf_9pywrapfst_9FarWriter_14__setitem__(struct __pyx_obj_9pywrap
 static PyObject *__pyx_pf_9pywrapfst_9FarWriter_16__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_9pywrapfst_9FarWriter_18__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
 static PyObject *__pyx_tp_new_9pywrapfst_Weight(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
-static PyObject *__pyx_tp_new_9pywrapfst__SymbolTable(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_9pywrapfst_SymbolTableView(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
 static PyObject *__pyx_tp_new_9pywrapfst__EncodeMapperSymbolTableView(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
 static PyObject *__pyx_tp_new_9pywrapfst__FstSymbolTableView(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
 static PyObject *__pyx_tp_new_9pywrapfst__MutableSymbolTable(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
@@ -4082,58 +4128,54 @@ static PyObject *__pyx_tp_new_9pywrapfst_Compiler(PyTypeObject *t, PyObject *a,
 static PyObject *__pyx_tp_new_9pywrapfst_FarReader(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
 static PyObject *__pyx_tp_new_9pywrapfst_FarWriter(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
 static PyObject *__pyx_tp_new_9pywrapfst___pyx_scope_struct____iter__(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
-static PyObject *__pyx_int_2;
-static int64 __pyx_k__3;
-static float __pyx_k__10;
-static float __pyx_k__11;
+static int64 __pyx_k__6;
 static float __pyx_k__12;
-static int64 __pyx_k__13;
+static float __pyx_k__13;
 static float __pyx_k__14;
 static int64 __pyx_k__15;
 static float __pyx_k__16;
-static float __pyx_k__17;
-static int64 __pyx_k__18;
+static int64 __pyx_k__17;
+static float __pyx_k__18;
 static float __pyx_k__19;
 static int64 __pyx_k__20;
 static float __pyx_k__21;
-static float __pyx_k__30;
-static float __pyx_k__31;
+static int64 __pyx_k__22;
+static float __pyx_k__23;
 static float __pyx_k__32;
-static int64 __pyx_k__33;
+static float __pyx_k__33;
 static float __pyx_k__34;
 static int64 __pyx_k__35;
 static float __pyx_k__36;
-static float __pyx_k__37;
+static int64 __pyx_k__37;
 static float __pyx_k__38;
 static float __pyx_k__39;
-static int64 __pyx_k__40;
+static float __pyx_k__40;
 static float __pyx_k__41;
-static float __pyx_k__42;
-static int32 __pyx_k__43;
-static int32 __pyx_k__44;
-static float __pyx_k__45;
-static int64 __pyx_k__46;
+static int64 __pyx_k__42;
+static float __pyx_k__43;
+static float __pyx_k__44;
+static int32 __pyx_k__45;
+static int32 __pyx_k__46;
 static float __pyx_k__47;
 static int64 __pyx_k__48;
 static float __pyx_k__49;
 static int64 __pyx_k__50;
-static std::string __pyx_k__51;
-static std::string __pyx_k__52;
-static PyObject *__pyx_tuple_;
-static PyObject *__pyx_tuple__2;
+static float __pyx_k__51;
+static int64 __pyx_k__52;
 static PyObject *__pyx_tuple__4;
 static PyObject *__pyx_tuple__5;
-static PyObject *__pyx_tuple__6;
 static PyObject *__pyx_tuple__7;
+static PyObject *__pyx_tuple__8;
 static PyObject *__pyx_tuple__9;
-static PyObject *__pyx_tuple__22;
-static PyObject *__pyx_tuple__23;
+static PyObject *__pyx_tuple__10;
 static PyObject *__pyx_tuple__24;
 static PyObject *__pyx_tuple__25;
 static PyObject *__pyx_tuple__26;
 static PyObject *__pyx_tuple__27;
 static PyObject *__pyx_tuple__28;
 static PyObject *__pyx_tuple__29;
+static PyObject *__pyx_tuple__30;
+static PyObject *__pyx_tuple__31;
 static PyObject *__pyx_tuple__53;
 static PyObject *__pyx_tuple__54;
 static PyObject *__pyx_tuple__55;
@@ -4141,21 +4183,20 @@ static PyObject *__pyx_tuple__56;
 static PyObject *__pyx_tuple__57;
 static PyObject *__pyx_tuple__58;
 static PyObject *__pyx_tuple__59;
-static PyObject *__pyx_tuple__60;
-static PyObject *__pyx_tuple__62;
-static PyObject *__pyx_tuple__64;
-static PyObject *__pyx_tuple__66;
-static PyObject *__pyx_tuple__68;
-static PyObject *__pyx_tuple__70;
-static PyObject *__pyx_codeobj__61;
-static PyObject *__pyx_codeobj__63;
-static PyObject *__pyx_codeobj__65;
-static PyObject *__pyx_codeobj__67;
-static PyObject *__pyx_codeobj__69;
-static PyObject *__pyx_codeobj__71;
+static PyObject *__pyx_tuple__61;
+static PyObject *__pyx_tuple__63;
+static PyObject *__pyx_tuple__65;
+static PyObject *__pyx_tuple__67;
+static PyObject *__pyx_tuple__69;
+static PyObject *__pyx_codeobj__60;
+static PyObject *__pyx_codeobj__62;
+static PyObject *__pyx_codeobj__64;
+static PyObject *__pyx_codeobj__66;
+static PyObject *__pyx_codeobj__68;
+static PyObject *__pyx_codeobj__70;
 /* Late includes */
 
-/* "pywrapfst.pyx":150
+/* "pywrapfst.pyx":174
  * 
  * 
  * cdef string tostring(data) except *:             # <<<<<<<<<<<<<<
@@ -4170,139 +4211,123 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data) {
   int __pyx_t_2;
   std::string __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
+  Py_ssize_t __pyx_t_5;
+  Py_UCS4 __pyx_t_6;
   PyObject *__pyx_t_7 = NULL;
   PyObject *__pyx_t_8 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("tostring", 0);
 
-  /* "pywrapfst.pyx":170
+  /* "pywrapfst.pyx":193
  *   """
- *   # A Python bytestring can be implicitly cast to a C++ string.
- *   if isinstance(data, bytes):             # <<<<<<<<<<<<<<
+ *   # A Python string can be implicitly cast to a C++ string.
+ *   if isinstance(data, str):             # <<<<<<<<<<<<<<
  *     return data
- *   elif isinstance(data, unicode):
+ *   raise TypeError(f"Expected {str.__name__} but received "
  */
-  __pyx_t_1 = PyBytes_Check(__pyx_v_data); 
+  __pyx_t_1 = PyUnicode_Check(__pyx_v_data); 
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":171
- *   # A Python bytestring can be implicitly cast to a C++ string.
- *   if isinstance(data, bytes):
+    /* "pywrapfst.pyx":194
+ *   # A Python string can be implicitly cast to a C++ string.
+ *   if isinstance(data, str):
  *     return data             # <<<<<<<<<<<<<<
- *   elif isinstance(data, unicode):
- *     return data.encode("utf8")
+ *   raise TypeError(f"Expected {str.__name__} but received "
+ *                   f"{type(data).__name__}: {data!r}")
  */
-    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_v_data); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 171, __pyx_L1_error)
+    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_v_data); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 194, __pyx_L1_error)
     __pyx_r = __pyx_t_3;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":170
+    /* "pywrapfst.pyx":193
  *   """
- *   # A Python bytestring can be implicitly cast to a C++ string.
- *   if isinstance(data, bytes):             # <<<<<<<<<<<<<<
+ *   # A Python string can be implicitly cast to a C++ string.
+ *   if isinstance(data, str):             # <<<<<<<<<<<<<<
  *     return data
- *   elif isinstance(data, unicode):
+ *   raise TypeError(f"Expected {str.__name__} but received "
  */
   }
 
-  /* "pywrapfst.pyx":172
- *   if isinstance(data, bytes):
+  /* "pywrapfst.pyx":195
+ *   if isinstance(data, str):
  *     return data
- *   elif isinstance(data, unicode):             # <<<<<<<<<<<<<<
- *     return data.encode("utf8")
- *   raise FstArgError("Cannot encode as string: {!r}".format(data))
+ *   raise TypeError(f"Expected {str.__name__} but received "             # <<<<<<<<<<<<<<
+ *                   f"{type(data).__name__}: {data!r}")
+ * 
  */
-  __pyx_t_2 = PyUnicode_Check(__pyx_v_data); 
-  __pyx_t_1 = (__pyx_t_2 != 0);
-  if (__pyx_t_1) {
-
-    /* "pywrapfst.pyx":173
+  __pyx_t_4 = PyTuple_New(6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 195, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = 0;
+  __pyx_t_6 = 127;
+  __Pyx_INCREF(__pyx_kp_u_Expected);
+  __pyx_t_5 += 9;
+  __Pyx_GIVEREF(__pyx_kp_u_Expected);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_kp_u_Expected);
+  __pyx_t_7 = __Pyx_PyObject_GetAttrStr(((PyObject *)(&PyUnicode_Type)), __pyx_n_s_name); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 195, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_7);
+  __pyx_t_8 = __Pyx_PyObject_FormatSimple(__pyx_t_7, __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 195, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  __pyx_t_6 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) > __pyx_t_6) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) : __pyx_t_6;
+  __pyx_t_5 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_8);
+  __Pyx_GIVEREF(__pyx_t_8);
+  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_8);
+  __pyx_t_8 = 0;
+  __Pyx_INCREF(__pyx_kp_u_but_received);
+  __pyx_t_5 += 14;
+  __Pyx_GIVEREF(__pyx_kp_u_but_received);
+  PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_kp_u_but_received);
+
+  /* "pywrapfst.pyx":196
  *     return data
- *   elif isinstance(data, unicode):
- *     return data.encode("utf8")             # <<<<<<<<<<<<<<
- *   raise FstArgError("Cannot encode as string: {!r}".format(data))
+ *   raise TypeError(f"Expected {str.__name__} but received "
+ *                   f"{type(data).__name__}: {data!r}")             # <<<<<<<<<<<<<<
+ * 
  * 
  */
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_encode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 173, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
-      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
-      if (likely(__pyx_t_6)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-        __Pyx_INCREF(__pyx_t_6);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_5, function);
-      }
-    }
-    __pyx_t_4 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_6, __pyx_n_u_utf8) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_n_u_utf8);
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 173, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 173, __pyx_L1_error)
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_r = __pyx_t_3;
-    goto __pyx_L0;
+  __pyx_t_8 = __Pyx_PyObject_GetAttrStr(((PyObject *)Py_TYPE(__pyx_v_data)), __pyx_n_s_name); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 196, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_8);
+  __pyx_t_7 = __Pyx_PyObject_FormatSimple(__pyx_t_8, __pyx_empty_unicode); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 196, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __pyx_t_6 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) > __pyx_t_6) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) : __pyx_t_6;
+  __pyx_t_5 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_7);
+  __Pyx_GIVEREF(__pyx_t_7);
+  PyTuple_SET_ITEM(__pyx_t_4, 3, __pyx_t_7);
+  __pyx_t_7 = 0;
+  __Pyx_INCREF(__pyx_kp_u_);
+  __pyx_t_5 += 2;
+  __Pyx_GIVEREF(__pyx_kp_u_);
+  PyTuple_SET_ITEM(__pyx_t_4, 4, __pyx_kp_u_);
+  __pyx_t_7 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_data), __pyx_empty_unicode); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 196, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_7);
+  __pyx_t_6 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) > __pyx_t_6) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) : __pyx_t_6;
+  __pyx_t_5 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_7);
+  __Pyx_GIVEREF(__pyx_t_7);
+  PyTuple_SET_ITEM(__pyx_t_4, 5, __pyx_t_7);
+  __pyx_t_7 = 0;
 
-    /* "pywrapfst.pyx":172
- *   if isinstance(data, bytes):
+  /* "pywrapfst.pyx":195
+ *   if isinstance(data, str):
  *     return data
- *   elif isinstance(data, unicode):             # <<<<<<<<<<<<<<
- *     return data.encode("utf8")
- *   raise FstArgError("Cannot encode as string: {!r}".format(data))
- */
-  }
-
-  /* "pywrapfst.pyx":174
- *   elif isinstance(data, unicode):
- *     return data.encode("utf8")
- *   raise FstArgError("Cannot encode as string: {!r}".format(data))             # <<<<<<<<<<<<<<
- * 
+ *   raise TypeError(f"Expected {str.__name__} but received "             # <<<<<<<<<<<<<<
+ *                   f"{type(data).__name__}: {data!r}")
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 174, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Cannot_encode_as_string_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 174, __pyx_L1_error)
+  __pyx_t_7 = __Pyx_PyUnicode_Join(__pyx_t_4, 6, __pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 195, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_7);
-  __pyx_t_8 = NULL;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) {
-    __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7);
-    if (likely(__pyx_t_8)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
-      __Pyx_INCREF(__pyx_t_8);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_7, function);
-    }
-  }
-  __pyx_t_6 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_v_data) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_data);
-  __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
-  if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 174, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  __pyx_t_7 = NULL;
-  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
-    __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
-    if (likely(__pyx_t_7)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-      __Pyx_INCREF(__pyx_t_7);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_5, function);
-    }
-  }
-  __pyx_t_4 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_7, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 174, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 195, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   __Pyx_Raise(__pyx_t_4, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __PYX_ERR(0, 174, __pyx_L1_error)
+  __PYX_ERR(0, 195, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":150
+  /* "pywrapfst.pyx":174
  * 
  * 
  * cdef string tostring(data) except *:             # <<<<<<<<<<<<<<
@@ -4313,8 +4338,6 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data) {
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
   __Pyx_XDECREF(__pyx_t_7);
   __Pyx_XDECREF(__pyx_t_8);
   __Pyx_AddTraceback("pywrapfst.tostring", __pyx_clineno, __pyx_lineno, __pyx_filename);
@@ -4324,7 +4347,7 @@ static std::string __pyx_f_9pywrapfst_tostring(PyObject *__pyx_v_data) {
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":177
+/* "pywrapfst.pyx":199
  * 
  * 
  * cdef string weight_tostring(data) except *:             # <<<<<<<<<<<<<<
@@ -4340,268 +4363,300 @@ static std::string __pyx_f_9pywrapfst_weight_tostring(PyObject *__pyx_v_data) {
   std::string __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
+  Py_ssize_t __pyx_t_6;
+  Py_UCS4 __pyx_t_7;
   PyObject *__pyx_t_8 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("weight_tostring", 0);
 
-  /* "pywrapfst.pyx":201
+  /* "pywrapfst.pyx":221
  *   """
- *   # A Python bytestring can be implicitly cast to a C++ string.
- *   if isinstance(data, bytes):             # <<<<<<<<<<<<<<
+ *   # A Python string can be implicitly cast to a C++ string.
+ *   if isinstance(data, str):             # <<<<<<<<<<<<<<
  *     return data
- *   elif isinstance(data, unicode):
+ *   elif isinstance(data, numbers.Number):
  */
-  __pyx_t_1 = PyBytes_Check(__pyx_v_data); 
+  __pyx_t_1 = PyUnicode_Check(__pyx_v_data); 
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":202
- *   # A Python bytestring can be implicitly cast to a C++ string.
- *   if isinstance(data, bytes):
+    /* "pywrapfst.pyx":222
+ *   # A Python string can be implicitly cast to a C++ string.
+ *   if isinstance(data, str):
  *     return data             # <<<<<<<<<<<<<<
- *   elif isinstance(data, unicode):
- *     return data.encode("utf8")
+ *   elif isinstance(data, numbers.Number):
+ *     return str(data)
  */
-    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_v_data); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 202, __pyx_L1_error)
+    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_v_data); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 222, __pyx_L1_error)
     __pyx_r = __pyx_t_3;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":201
+    /* "pywrapfst.pyx":221
  *   """
- *   # A Python bytestring can be implicitly cast to a C++ string.
- *   if isinstance(data, bytes):             # <<<<<<<<<<<<<<
+ *   # A Python string can be implicitly cast to a C++ string.
+ *   if isinstance(data, str):             # <<<<<<<<<<<<<<
  *     return data
- *   elif isinstance(data, unicode):
+ *   elif isinstance(data, numbers.Number):
  */
   }
 
-  /* "pywrapfst.pyx":203
- *   if isinstance(data, bytes):
+  /* "pywrapfst.pyx":223
+ *   if isinstance(data, str):
  *     return data
- *   elif isinstance(data, unicode):             # <<<<<<<<<<<<<<
- *     return data.encode("utf8")
- *   elif isinstance(data, numbers.Number):
+ *   elif isinstance(data, numbers.Number):             # <<<<<<<<<<<<<<
+ *     return str(data)
+ *   raise TypeError(f"Expected {str.__name__} but received "
  */
-  __pyx_t_2 = PyUnicode_Check(__pyx_v_data); 
+  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_numbers); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 223, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_Number); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 223, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_2 = PyObject_IsInstance(__pyx_v_data, __pyx_t_5); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 223, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":204
+    /* "pywrapfst.pyx":224
  *     return data
- *   elif isinstance(data, unicode):
- *     return data.encode("utf8")             # <<<<<<<<<<<<<<
  *   elif isinstance(data, numbers.Number):
- *     return str(data).encode("utf8")
+ *     return str(data)             # <<<<<<<<<<<<<<
+ *   raise TypeError(f"Expected {str.__name__} but received "
+ *                   f"{type(data).__name__}: {data!r}")
  */
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_encode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 204, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_data); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 224, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
-      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
-      if (likely(__pyx_t_6)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-        __Pyx_INCREF(__pyx_t_6);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_5, function);
-      }
-    }
-    __pyx_t_4 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_6, __pyx_n_u_utf8) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_n_u_utf8);
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 204, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_5); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 224, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 204, __pyx_L1_error)
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __pyx_r = __pyx_t_3;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":203
- *   if isinstance(data, bytes):
+    /* "pywrapfst.pyx":223
+ *   if isinstance(data, str):
  *     return data
- *   elif isinstance(data, unicode):             # <<<<<<<<<<<<<<
- *     return data.encode("utf8")
- *   elif isinstance(data, numbers.Number):
+ *   elif isinstance(data, numbers.Number):             # <<<<<<<<<<<<<<
+ *     return str(data)
+ *   raise TypeError(f"Expected {str.__name__} but received "
  */
   }
 
-  /* "pywrapfst.pyx":205
- *   elif isinstance(data, unicode):
- *     return data.encode("utf8")
- *   elif isinstance(data, numbers.Number):             # <<<<<<<<<<<<<<
- *     return str(data).encode("utf8")
- *   raise FstArgError("Cannot encode as string: {!r}".format(data))
+  /* "pywrapfst.pyx":225
+ *   elif isinstance(data, numbers.Number):
+ *     return str(data)
+ *   raise TypeError(f"Expected {str.__name__} but received "             # <<<<<<<<<<<<<<
+ *                   f"{type(data).__name__}: {data!r}")
+ * 
+ */
+  __pyx_t_5 = PyTuple_New(6); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 225, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_6 = 0;
+  __pyx_t_7 = 127;
+  __Pyx_INCREF(__pyx_kp_u_Expected);
+  __pyx_t_6 += 9;
+  __Pyx_GIVEREF(__pyx_kp_u_Expected);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_kp_u_Expected);
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)(&PyUnicode_Type)), __pyx_n_s_name); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 225, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_8 = __Pyx_PyObject_FormatSimple(__pyx_t_4, __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 225, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) : __pyx_t_7;
+  __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_8);
+  __Pyx_GIVEREF(__pyx_t_8);
+  PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_8);
+  __pyx_t_8 = 0;
+  __Pyx_INCREF(__pyx_kp_u_but_received);
+  __pyx_t_6 += 14;
+  __Pyx_GIVEREF(__pyx_kp_u_but_received);
+  PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_kp_u_but_received);
+
+  /* "pywrapfst.pyx":226
+ *     return str(data)
+ *   raise TypeError(f"Expected {str.__name__} but received "
+ *                   f"{type(data).__name__}: {data!r}")             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __pyx_t_8 = __Pyx_PyObject_GetAttrStr(((PyObject *)Py_TYPE(__pyx_v_data)), __pyx_n_s_name); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 226, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_8);
+  __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_t_8, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 226, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_7;
+  __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4);
+  __pyx_t_4 = 0;
+  __Pyx_INCREF(__pyx_kp_u_);
+  __pyx_t_6 += 2;
+  __Pyx_GIVEREF(__pyx_kp_u_);
+  PyTuple_SET_ITEM(__pyx_t_5, 4, __pyx_kp_u_);
+  __pyx_t_4 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_data), __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 226, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_7;
+  __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_5, 5, __pyx_t_4);
+  __pyx_t_4 = 0;
+
+  /* "pywrapfst.pyx":225
+ *   elif isinstance(data, numbers.Number):
+ *     return str(data)
+ *   raise TypeError(f"Expected {str.__name__} but received "             # <<<<<<<<<<<<<<
+ *                   f"{type(data).__name__}: {data!r}")
+ * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_numbers); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 205, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyUnicode_Join(__pyx_t_5, 6, __pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 225, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_Number); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 205, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 225, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_1 = PyObject_IsInstance(__pyx_v_data, __pyx_t_5); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 205, __pyx_L1_error)
+  __Pyx_Raise(__pyx_t_5, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_2 = (__pyx_t_1 != 0);
-  if (__pyx_t_2) {
+  __PYX_ERR(0, 225, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":206
- *     return data.encode("utf8")
- *   elif isinstance(data, numbers.Number):
- *     return str(data).encode("utf8")             # <<<<<<<<<<<<<<
- *   raise FstArgError("Cannot encode as string: {!r}".format(data))
+  /* "pywrapfst.pyx":199
+ * 
+ * 
+ * cdef string weight_tostring(data) except *:             # <<<<<<<<<<<<<<
+ *   """Converts strings or numerics to bytestrings.
  * 
  */
-    __pyx_t_5 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_data); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 206, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_4 = PyUnicode_AsUTF8String(((PyObject*)__pyx_t_5)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 206, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 206, __pyx_L1_error)
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_r = __pyx_t_3;
-    goto __pyx_L0;
 
-    /* "pywrapfst.pyx":205
- *   elif isinstance(data, unicode):
- *     return data.encode("utf8")
- *   elif isinstance(data, numbers.Number):             # <<<<<<<<<<<<<<
- *     return str(data).encode("utf8")
- *   raise FstArgError("Cannot encode as string: {!r}".format(data))
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_AddTraceback("pywrapfst.weight_tostring", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_pretend_to_initialize(&__pyx_r);
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":229
+ * 
+ * 
+ * cdef string path_tostring(data) except *:             # <<<<<<<<<<<<<<
+ *   return tostring(os.fspath(data))
+ * 
  */
-  }
 
-  /* "pywrapfst.pyx":207
- *   elif isinstance(data, numbers.Number):
- *     return str(data).encode("utf8")
- *   raise FstArgError("Cannot encode as string: {!r}".format(data))             # <<<<<<<<<<<<<<
+static std::string __pyx_f_9pywrapfst_path_tostring(PyObject *__pyx_v_data) {
+  std::string __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  std::string __pyx_t_4;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("path_tostring", 0);
+
+  /* "pywrapfst.pyx":230
+ * 
+ * cdef string path_tostring(data) except *:
+ *   return tostring(os.fspath(data))             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 207, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Cannot_encode_as_string_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 207, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_7);
-  __pyx_t_8 = NULL;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) {
-    __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7);
-    if (likely(__pyx_t_8)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
-      __Pyx_INCREF(__pyx_t_8);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_7, function);
-    }
-  }
-  __pyx_t_6 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_v_data) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_data);
-  __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
-  if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 207, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  __pyx_t_7 = NULL;
-  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
-    __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
-    if (likely(__pyx_t_7)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-      __Pyx_INCREF(__pyx_t_7);
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_os); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 230, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_fspath); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 230, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = NULL;
+  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
+    __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+    if (likely(__pyx_t_2)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_2);
       __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_5, function);
+      __Pyx_DECREF_SET(__pyx_t_3, function);
     }
   }
-  __pyx_t_4 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_7, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 207, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __Pyx_Raise(__pyx_t_4, 0, 0, 0);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __PYX_ERR(0, 207, __pyx_L1_error)
+  __pyx_t_1 = (__pyx_t_2) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_2, __pyx_v_data) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_data);
+  __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 230, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_4 = __pyx_f_9pywrapfst_tostring(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 230, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_r = __pyx_t_4;
+  goto __pyx_L0;
 
-  /* "pywrapfst.pyx":177
+  /* "pywrapfst.pyx":229
  * 
  * 
- * cdef string weight_tostring(data) except *:             # <<<<<<<<<<<<<<
- *   """Converts strings or numerics to bytestrings.
+ * cdef string path_tostring(data) except *:             # <<<<<<<<<<<<<<
+ *   return tostring(os.fspath(data))
  * 
  */
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
-  __Pyx_XDECREF(__pyx_t_8);
-  __Pyx_AddTraceback("pywrapfst.weight_tostring", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("pywrapfst.path_tostring", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_pretend_to_initialize(&__pyx_r);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":210
+/* "pywrapfst.pyx":233
  * 
  * 
- * cdef fst.ComposeFilter _get_compose_filter(             # <<<<<<<<<<<<<<
- *     const string &compose_filter) except *:
- *   """Matches string with the appropriate ComposeFilter enum value.
+ * cdef fst.FarType _get_far_type(const string &far_type) except *:             # <<<<<<<<<<<<<<
+ *   """Matches string with the appropriate FarType enum value.
+ * 
  */
 
-static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::string const &__pyx_v_compose_filter) {
-  enum fst::ComposeFilter __pyx_v_compose_filter_enum;
-  enum fst::ComposeFilter __pyx_r;
+static fst::FarType __pyx_f_9pywrapfst__get_far_type(std::string const &__pyx_v_far_type) {
+  fst::FarType __pyx_v__far_type;
+  fst::FarType __pyx_r;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
-  __Pyx_RefNannySetupContext("_get_compose_filter", 0);
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_get_far_type", 0);
 
-  /* "pywrapfst.pyx":232
+  /* "pywrapfst.pyx":249
  *   """
- *   cdef fst.ComposeFilter compose_filter_enum
- *   if not fst.GetComposeFilter(compose_filter, addr(compose_filter_enum)):             # <<<<<<<<<<<<<<
- *     raise FstArgError("Unknown compose filter type: {!r}".format(
- *         compose_filter))
+ *   cdef fst.FarType _far_type
+ *   if not fst.GetFarType(far_type, addr(_far_type)):             # <<<<<<<<<<<<<<
+ *     raise FstArgError(f"Unknown FAR type: {far_type!r}")
+ *   return _far_type
  */
-  __pyx_t_1 = ((!(fst::script::GetComposeFilter(__pyx_v_compose_filter, (&__pyx_v_compose_filter_enum)) != 0)) != 0);
+  __pyx_t_1 = ((!(fst::script::GetFarType(__pyx_v_far_type, (&__pyx_v__far_type)) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":233
- *   cdef fst.ComposeFilter compose_filter_enum
- *   if not fst.GetComposeFilter(compose_filter, addr(compose_filter_enum)):
- *     raise FstArgError("Unknown compose filter type: {!r}".format(             # <<<<<<<<<<<<<<
- *         compose_filter))
- *   return compose_filter_enum
+    /* "pywrapfst.pyx":250
+ *   cdef fst.FarType _far_type
+ *   if not fst.GetFarType(far_type, addr(_far_type)):
+ *     raise FstArgError(f"Unknown FAR type: {far_type!r}")             # <<<<<<<<<<<<<<
+ *   return _far_type
+ * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 233, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 250, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_compose_filter_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 233, __pyx_L1_error)
+    __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_far_type); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 250, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_4), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 250, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-
-    /* "pywrapfst.pyx":234
- *   if not fst.GetComposeFilter(compose_filter, addr(compose_filter_enum)):
- *     raise FstArgError("Unknown compose filter type: {!r}".format(
- *         compose_filter))             # <<<<<<<<<<<<<<
- *   return compose_filter_enum
- * 
- */
-    __pyx_t_6 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_compose_filter); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 234, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-        __Pyx_INCREF(__pyx_t_7);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_5, function);
-      }
-    }
-    __pyx_t_4 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_7, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6);
-    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 233, __pyx_L1_error)
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_FAR_type, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 250, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -4617,33 +4672,142 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
     __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 233, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 250, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 233, __pyx_L1_error)
+    __PYX_ERR(0, 250, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":232
+    /* "pywrapfst.pyx":249
  *   """
- *   cdef fst.ComposeFilter compose_filter_enum
- *   if not fst.GetComposeFilter(compose_filter, addr(compose_filter_enum)):             # <<<<<<<<<<<<<<
- *     raise FstArgError("Unknown compose filter type: {!r}".format(
- *         compose_filter))
+ *   cdef fst.FarType _far_type
+ *   if not fst.GetFarType(far_type, addr(_far_type)):             # <<<<<<<<<<<<<<
+ *     raise FstArgError(f"Unknown FAR type: {far_type!r}")
+ *   return _far_type
  */
   }
 
-  /* "pywrapfst.pyx":235
- *     raise FstArgError("Unknown compose filter type: {!r}".format(
- *         compose_filter))
- *   return compose_filter_enum             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":251
+ *   if not fst.GetFarType(far_type, addr(_far_type)):
+ *     raise FstArgError(f"Unknown FAR type: {far_type!r}")
+ *   return _far_type             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_r = __pyx_v_compose_filter_enum;
+  __pyx_r = __pyx_v__far_type;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":210
+  /* "pywrapfst.pyx":233
+ * 
+ * 
+ * cdef fst.FarType _get_far_type(const string &far_type) except *:             # <<<<<<<<<<<<<<
+ *   """Matches string with the appropriate FarType enum value.
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("pywrapfst._get_far_type", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = (fst::FarType) 0;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":254
+ * 
+ * 
+ * cdef fst.ComposeFilter _get_compose_filter(             # <<<<<<<<<<<<<<
+ *     const string &compose_filter) except *:
+ *   """Matches string with the appropriate ComposeFilter enum value.
+ */
+
+static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::string const &__pyx_v_compose_filter) {
+  enum fst::ComposeFilter __pyx_v__compose_filter;
+  enum fst::ComposeFilter __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_get_compose_filter", 0);
+
+  /* "pywrapfst.pyx":276
+ *   """
+ *   cdef fst.ComposeFilter _compose_filter
+ *   if not fst.GetComposeFilter(compose_filter, addr(_compose_filter)):             # <<<<<<<<<<<<<<
+ *     raise FstArgError(f"Unknown compose filter type: {compose_filter!r}")
+ *   return _compose_filter
+ */
+  __pyx_t_1 = ((!(fst::script::GetComposeFilter(__pyx_v_compose_filter, (&__pyx_v__compose_filter)) != 0)) != 0);
+  if (unlikely(__pyx_t_1)) {
+
+    /* "pywrapfst.pyx":277
+ *   cdef fst.ComposeFilter _compose_filter
+ *   if not fst.GetComposeFilter(compose_filter, addr(_compose_filter)):
+ *     raise FstArgError(f"Unknown compose filter type: {compose_filter!r}")             # <<<<<<<<<<<<<<
+ *   return _compose_filter
+ * 
+ */
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 277, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_compose_filter); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 277, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_4), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 277, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_compose_filter_type, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 277, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = NULL;
+    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
+      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3);
+      if (likely(__pyx_t_5)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+        __Pyx_INCREF(__pyx_t_5);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_3, function);
+      }
+    }
+    __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4);
+    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 277, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __PYX_ERR(0, 277, __pyx_L1_error)
+
+    /* "pywrapfst.pyx":276
+ *   """
+ *   cdef fst.ComposeFilter _compose_filter
+ *   if not fst.GetComposeFilter(compose_filter, addr(_compose_filter)):             # <<<<<<<<<<<<<<
+ *     raise FstArgError(f"Unknown compose filter type: {compose_filter!r}")
+ *   return _compose_filter
+ */
+  }
+
+  /* "pywrapfst.pyx":278
+ *   if not fst.GetComposeFilter(compose_filter, addr(_compose_filter)):
+ *     raise FstArgError(f"Unknown compose filter type: {compose_filter!r}")
+ *   return _compose_filter             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __pyx_r = __pyx_v__compose_filter;
+  goto __pyx_L0;
+
+  /* "pywrapfst.pyx":254
  * 
  * 
  * cdef fst.ComposeFilter _get_compose_filter(             # <<<<<<<<<<<<<<
@@ -4657,8 +4821,6 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_AddTraceback("pywrapfst._get_compose_filter", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = (enum fst::ComposeFilter) 0;
   __pyx_L0:;
@@ -4666,7 +4828,7 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":238
+/* "pywrapfst.pyx":281
  * 
  * 
  * cdef fst.DeterminizeType _get_determinize_type(const string &det_type) except *:             # <<<<<<<<<<<<<<
@@ -4675,7 +4837,7 @@ static enum fst::ComposeFilter __pyx_f_9pywrapfst__get_compose_filter(std::strin
  */
 
 static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::string const &__pyx_v_det_type) {
-  enum fst::DeterminizeType __pyx_v_det_type_enum;
+  enum fst::DeterminizeType __pyx_v__det_type;
   enum fst::DeterminizeType __pyx_r;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
@@ -4683,47 +4845,36 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_get_determinize_type", 0);
 
-  /* "pywrapfst.pyx":254
+  /* "pywrapfst.pyx":297
  *   """
- *   cdef fst.DeterminizeType det_type_enum
- *   if not fst.GetDeterminizeType(det_type, addr(det_type_enum)):             # <<<<<<<<<<<<<<
- *     raise FstArgError("Unknown determinization type: {!r}".format(det_type))
- *   return det_type_enum
+ *   cdef fst.DeterminizeType _det_type
+ *   if not fst.GetDeterminizeType(det_type, addr(_det_type)):             # <<<<<<<<<<<<<<
+ *     raise FstArgError(f"Unknown determinization type: {det_type!r}")
+ *   return _det_type
  */
-  __pyx_t_1 = ((!(fst::script::GetDeterminizeType(__pyx_v_det_type, (&__pyx_v_det_type_enum)) != 0)) != 0);
+  __pyx_t_1 = ((!(fst::script::GetDeterminizeType(__pyx_v_det_type, (&__pyx_v__det_type)) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":255
- *   cdef fst.DeterminizeType det_type_enum
- *   if not fst.GetDeterminizeType(det_type, addr(det_type_enum)):
- *     raise FstArgError("Unknown determinization type: {!r}".format(det_type))             # <<<<<<<<<<<<<<
- *   return det_type_enum
+    /* "pywrapfst.pyx":298
+ *   cdef fst.DeterminizeType _det_type
+ *   if not fst.GetDeterminizeType(det_type, addr(_det_type)):
+ *     raise FstArgError(f"Unknown determinization type: {det_type!r}")             # <<<<<<<<<<<<<<
+ *   return _det_type
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 255, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 298, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_determinization_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 255, __pyx_L1_error)
+    __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_det_type); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 298, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_4), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 298, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_det_type); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 255, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-        __Pyx_INCREF(__pyx_t_7);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_5, function);
-      }
-    }
-    __pyx_t_4 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_7, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6);
-    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 255, __pyx_L1_error)
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_determinization_type, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 298, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -4739,33 +4890,33 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
     __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 255, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 298, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 255, __pyx_L1_error)
+    __PYX_ERR(0, 298, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":254
+    /* "pywrapfst.pyx":297
  *   """
- *   cdef fst.DeterminizeType det_type_enum
- *   if not fst.GetDeterminizeType(det_type, addr(det_type_enum)):             # <<<<<<<<<<<<<<
- *     raise FstArgError("Unknown determinization type: {!r}".format(det_type))
- *   return det_type_enum
+ *   cdef fst.DeterminizeType _det_type
+ *   if not fst.GetDeterminizeType(det_type, addr(_det_type)):             # <<<<<<<<<<<<<<
+ *     raise FstArgError(f"Unknown determinization type: {det_type!r}")
+ *   return _det_type
  */
   }
 
-  /* "pywrapfst.pyx":256
- *   if not fst.GetDeterminizeType(det_type, addr(det_type_enum)):
- *     raise FstArgError("Unknown determinization type: {!r}".format(det_type))
- *   return det_type_enum             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":299
+ *   if not fst.GetDeterminizeType(det_type, addr(_det_type)):
+ *     raise FstArgError(f"Unknown determinization type: {det_type!r}")
+ *   return _det_type             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_r = __pyx_v_det_type_enum;
+  __pyx_r = __pyx_v__det_type;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":238
+  /* "pywrapfst.pyx":281
  * 
  * 
  * cdef fst.DeterminizeType _get_determinize_type(const string &det_type) except *:             # <<<<<<<<<<<<<<
@@ -4779,8 +4930,6 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_AddTraceback("pywrapfst._get_determinize_type", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = (enum fst::DeterminizeType) 0;
   __pyx_L0:;
@@ -4788,7 +4937,116 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":259
+/* "pywrapfst.pyx":302
+ * 
+ * 
+ * cdef fst.ProjectType _get_project_type(const string &project_type) except *:             # <<<<<<<<<<<<<<
+ *   """Matches string with the appropriate ProjectType enum value.
+ * 
+ */
+
+static fst::ProjectType __pyx_f_9pywrapfst__get_project_type(std::string const &__pyx_v_project_type) {
+  fst::ProjectType __pyx_v__project_type;
+  fst::ProjectType __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_get_project_type", 0);
+
+  /* "pywrapfst.pyx":318
+ *   """
+ *   cdef fst.ProjectType _project_type
+ *   if not fst.GetProjectType(project_type, addr(_project_type)):             # <<<<<<<<<<<<<<
+ *     raise FstArgError(f"Unknown projection type: {project_type!r}")
+ *   return _project_type
+ */
+  __pyx_t_1 = ((!(fst::script::GetProjectType(__pyx_v_project_type, (&__pyx_v__project_type)) != 0)) != 0);
+  if (unlikely(__pyx_t_1)) {
+
+    /* "pywrapfst.pyx":319
+ *   cdef fst.ProjectType _project_type
+ *   if not fst.GetProjectType(project_type, addr(_project_type)):
+ *     raise FstArgError(f"Unknown projection type: {project_type!r}")             # <<<<<<<<<<<<<<
+ *   return _project_type
+ * 
+ */
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 319, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_project_type); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 319, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_4), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 319, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_projection_type, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 319, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = NULL;
+    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
+      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3);
+      if (likely(__pyx_t_5)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+        __Pyx_INCREF(__pyx_t_5);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_3, function);
+      }
+    }
+    __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4);
+    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 319, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __PYX_ERR(0, 319, __pyx_L1_error)
+
+    /* "pywrapfst.pyx":318
+ *   """
+ *   cdef fst.ProjectType _project_type
+ *   if not fst.GetProjectType(project_type, addr(_project_type)):             # <<<<<<<<<<<<<<
+ *     raise FstArgError(f"Unknown projection type: {project_type!r}")
+ *   return _project_type
+ */
+  }
+
+  /* "pywrapfst.pyx":320
+ *   if not fst.GetProjectType(project_type, addr(_project_type)):
+ *     raise FstArgError(f"Unknown projection type: {project_type!r}")
+ *   return _project_type             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __pyx_r = __pyx_v__project_type;
+  goto __pyx_L0;
+
+  /* "pywrapfst.pyx":302
+ * 
+ * 
+ * cdef fst.ProjectType _get_project_type(const string &project_type) except *:             # <<<<<<<<<<<<<<
+ *   """Matches string with the appropriate ProjectType enum value.
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("pywrapfst._get_project_type", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = (fst::ProjectType) 0;
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":323
  * 
  * 
  * cdef fst.QueueType _get_queue_type(const string &queue_type) except *:             # <<<<<<<<<<<<<<
@@ -4797,7 +5055,7 @@ static enum fst::DeterminizeType __pyx_f_9pywrapfst__get_determinize_type(std::s
  */
 
 static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const &__pyx_v_queue_type) {
-  enum fst::QueueType __pyx_v_queue_type_enum;
+  enum fst::QueueType __pyx_v__queue_type;
   enum fst::QueueType __pyx_r;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
@@ -4805,47 +5063,36 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_get_queue_type", 0);
 
-  /* "pywrapfst.pyx":278
+  /* "pywrapfst.pyx":342
  *   """
- *   cdef fst.QueueType queue_type_enum
- *   if not fst.GetQueueType(queue_type, addr(queue_type_enum)):             # <<<<<<<<<<<<<<
- *     raise FstArgError("Unknown queue type: {!r}".format(queue_type))
- *   return queue_type_enum
+ *   cdef fst.QueueType _queue_type
+ *   if not fst.GetQueueType(queue_type, addr(_queue_type)):             # <<<<<<<<<<<<<<
+ *     raise FstArgError(f"Unknown queue type: {queue_type!r}")
+ *   return _queue_type
  */
-  __pyx_t_1 = ((!(fst::script::GetQueueType(__pyx_v_queue_type, (&__pyx_v_queue_type_enum)) != 0)) != 0);
+  __pyx_t_1 = ((!(fst::script::GetQueueType(__pyx_v_queue_type, (&__pyx_v__queue_type)) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":279
- *   cdef fst.QueueType queue_type_enum
- *   if not fst.GetQueueType(queue_type, addr(queue_type_enum)):
- *     raise FstArgError("Unknown queue type: {!r}".format(queue_type))             # <<<<<<<<<<<<<<
- *   return queue_type_enum
+    /* "pywrapfst.pyx":343
+ *   cdef fst.QueueType _queue_type
+ *   if not fst.GetQueueType(queue_type, addr(_queue_type)):
+ *     raise FstArgError(f"Unknown queue type: {queue_type!r}")             # <<<<<<<<<<<<<<
+ *   return _queue_type
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 279, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 343, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_queue_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 279, __pyx_L1_error)
+    __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_queue_type); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 343, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_4), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 343, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_queue_type); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 279, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-        __Pyx_INCREF(__pyx_t_7);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_5, function);
-      }
-    }
-    __pyx_t_4 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_7, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6);
-    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 279, __pyx_L1_error)
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_queue_type, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 343, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -4861,33 +5108,33 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
     __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 279, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 343, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 279, __pyx_L1_error)
+    __PYX_ERR(0, 343, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":278
+    /* "pywrapfst.pyx":342
  *   """
- *   cdef fst.QueueType queue_type_enum
- *   if not fst.GetQueueType(queue_type, addr(queue_type_enum)):             # <<<<<<<<<<<<<<
- *     raise FstArgError("Unknown queue type: {!r}".format(queue_type))
- *   return queue_type_enum
+ *   cdef fst.QueueType _queue_type
+ *   if not fst.GetQueueType(queue_type, addr(_queue_type)):             # <<<<<<<<<<<<<<
+ *     raise FstArgError(f"Unknown queue type: {queue_type!r}")
+ *   return _queue_type
  */
   }
 
-  /* "pywrapfst.pyx":280
- *   if not fst.GetQueueType(queue_type, addr(queue_type_enum)):
- *     raise FstArgError("Unknown queue type: {!r}".format(queue_type))
- *   return queue_type_enum             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":344
+ *   if not fst.GetQueueType(queue_type, addr(_queue_type)):
+ *     raise FstArgError(f"Unknown queue type: {queue_type!r}")
+ *   return _queue_type             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_r = __pyx_v_queue_type_enum;
+  __pyx_r = __pyx_v__queue_type;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":259
+  /* "pywrapfst.pyx":323
  * 
  * 
  * cdef fst.QueueType _get_queue_type(const string &queue_type) except *:             # <<<<<<<<<<<<<<
@@ -4901,8 +5148,6 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_AddTraceback("pywrapfst._get_queue_type", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = (enum fst::QueueType) 0;
   __pyx_L0:;
@@ -4910,7 +5155,7 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":283
+/* "pywrapfst.pyx":347
  * 
  * 
  * cdef fst.RandArcSelection _get_rand_arc_selection(             # <<<<<<<<<<<<<<
@@ -4919,7 +5164,7 @@ static enum fst::QueueType __pyx_f_9pywrapfst__get_queue_type(std::string const
  */
 
 static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selection(std::string const &__pyx_v_select) {
-  enum fst::script::RandArcSelection __pyx_v_select_enum;
+  enum fst::script::RandArcSelection __pyx_v__select;
   enum fst::script::RandArcSelection __pyx_r;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
@@ -4927,47 +5172,36 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_get_rand_arc_selection", 0);
 
-  /* "pywrapfst.pyx":303
+  /* "pywrapfst.pyx":367
  *   """
- *   cdef fst.RandArcSelection select_enum
- *   if not fst.GetRandArcSelection(select, addr(select_enum)):             # <<<<<<<<<<<<<<
- *     raise FstArgError("Unknown random arc selection type: {!r}".format(select))
- *   return select_enum
+ *   cdef fst.RandArcSelection _select
+ *   if not fst.GetRandArcSelection(select, addr(_select)):             # <<<<<<<<<<<<<<
+ *     raise FstArgError(f"Unknown random arc selection type: {select!r}")
+ *   return _select
  */
-  __pyx_t_1 = ((!(fst::script::GetRandArcSelection(__pyx_v_select, (&__pyx_v_select_enum)) != 0)) != 0);
+  __pyx_t_1 = ((!(fst::script::GetRandArcSelection(__pyx_v_select, (&__pyx_v__select)) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":304
- *   cdef fst.RandArcSelection select_enum
- *   if not fst.GetRandArcSelection(select, addr(select_enum)):
- *     raise FstArgError("Unknown random arc selection type: {!r}".format(select))             # <<<<<<<<<<<<<<
- *   return select_enum
+    /* "pywrapfst.pyx":368
+ *   cdef fst.RandArcSelection _select
+ *   if not fst.GetRandArcSelection(select, addr(_select)):
+ *     raise FstArgError(f"Unknown random arc selection type: {select!r}")             # <<<<<<<<<<<<<<
+ *   return _select
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 304, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 368, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_random_arc_selection_typ, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 304, __pyx_L1_error)
+    __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_select); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 368, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_4), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 368, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_select); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 304, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-        __Pyx_INCREF(__pyx_t_7);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_5, function);
-      }
-    }
-    __pyx_t_4 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_7, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6);
-    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 304, __pyx_L1_error)
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_random_arc_selection_typ, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 368, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -4983,33 +5217,33 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
     __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 304, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 368, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 304, __pyx_L1_error)
+    __PYX_ERR(0, 368, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":303
+    /* "pywrapfst.pyx":367
  *   """
- *   cdef fst.RandArcSelection select_enum
- *   if not fst.GetRandArcSelection(select, addr(select_enum)):             # <<<<<<<<<<<<<<
- *     raise FstArgError("Unknown random arc selection type: {!r}".format(select))
- *   return select_enum
+ *   cdef fst.RandArcSelection _select
+ *   if not fst.GetRandArcSelection(select, addr(_select)):             # <<<<<<<<<<<<<<
+ *     raise FstArgError(f"Unknown random arc selection type: {select!r}")
+ *   return _select
  */
   }
 
-  /* "pywrapfst.pyx":305
- *   if not fst.GetRandArcSelection(select, addr(select_enum)):
- *     raise FstArgError("Unknown random arc selection type: {!r}".format(select))
- *   return select_enum             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":369
+ *   if not fst.GetRandArcSelection(select, addr(_select)):
+ *     raise FstArgError(f"Unknown random arc selection type: {select!r}")
+ *   return _select             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_r = __pyx_v_select_enum;
+  __pyx_r = __pyx_v__select;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":283
+  /* "pywrapfst.pyx":347
  * 
  * 
  * cdef fst.RandArcSelection _get_rand_arc_selection(             # <<<<<<<<<<<<<<
@@ -5023,8 +5257,6 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_AddTraceback("pywrapfst._get_rand_arc_selection", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = (enum fst::script::RandArcSelection) 0;
   __pyx_L0:;
@@ -5032,7 +5264,7 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":308
+/* "pywrapfst.pyx":372
  * 
  * 
  * cdef fst.ReplaceLabelType _get_replace_label_type(             # <<<<<<<<<<<<<<
@@ -5041,7 +5273,7 @@ static enum fst::script::RandArcSelection __pyx_f_9pywrapfst__get_rand_arc_selec
  */
 
 static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std::string const &__pyx_v_replace_label_type, bool __pyx_v_epsilon_on_replace) {
-  enum fst::ReplaceLabelType __pyx_v_replace_label_type_enum;
+  enum fst::ReplaceLabelType __pyx_v__replace_label_type;
   enum fst::ReplaceLabelType __pyx_r;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
@@ -5049,55 +5281,36 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_get_replace_label_type", 0);
 
-  /* "pywrapfst.pyx":329
+  /* "pywrapfst.pyx":393
  *   """
- *   cdef fst.ReplaceLabelType replace_label_type_enum
- *   if not fst.GetReplaceLabelType(replace_label_type, epsilon_on_replace,             # <<<<<<<<<<<<<<
- *                                  addr(replace_label_type_enum)):
- *     raise FstArgError("Unknown replace label type: {!r}".format(
+ *   cdef fst.ReplaceLabelType _replace_label_type
+ *   if not fst.GetReplaceLabelType(replace_label_type,             # <<<<<<<<<<<<<<
+ *                                  epsilon_on_replace,
+ *                                  addr(_replace_label_type)):
  */
-  __pyx_t_1 = ((!(fst::script::GetReplaceLabelType(__pyx_v_replace_label_type, __pyx_v_epsilon_on_replace, (&__pyx_v_replace_label_type_enum)) != 0)) != 0);
+  __pyx_t_1 = ((!(fst::script::GetReplaceLabelType(__pyx_v_replace_label_type, __pyx_v_epsilon_on_replace, (&__pyx_v__replace_label_type)) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":331
- *   if not fst.GetReplaceLabelType(replace_label_type, epsilon_on_replace,
- *                                  addr(replace_label_type_enum)):
- *     raise FstArgError("Unknown replace label type: {!r}".format(             # <<<<<<<<<<<<<<
- *                       replace_label_type))
- *   return replace_label_type_enum
+    /* "pywrapfst.pyx":396
+ *                                  epsilon_on_replace,
+ *                                  addr(_replace_label_type)):
+ *     raise FstArgError(f"Unknown replace label type: {replace_label_type!r}")             # <<<<<<<<<<<<<<
+ *   return _replace_label_type
+ * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 331, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 396, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_replace_label_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 331, __pyx_L1_error)
+    __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_replace_label_type); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 396, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_4), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 396, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-
-    /* "pywrapfst.pyx":332
- *                                  addr(replace_label_type_enum)):
- *     raise FstArgError("Unknown replace label type: {!r}".format(
- *                       replace_label_type))             # <<<<<<<<<<<<<<
- *   return replace_label_type_enum
- * 
- */
-    __pyx_t_6 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_replace_label_type); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 332, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-        __Pyx_INCREF(__pyx_t_7);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_5, function);
-      }
-    }
-    __pyx_t_4 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_7, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6);
-    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 331, __pyx_L1_error)
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_replace_label_type, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 396, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_t_5 = NULL;
@@ -5113,33 +5326,33 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
     __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 331, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 396, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 331, __pyx_L1_error)
+    __PYX_ERR(0, 396, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":329
+    /* "pywrapfst.pyx":393
  *   """
- *   cdef fst.ReplaceLabelType replace_label_type_enum
- *   if not fst.GetReplaceLabelType(replace_label_type, epsilon_on_replace,             # <<<<<<<<<<<<<<
- *                                  addr(replace_label_type_enum)):
- *     raise FstArgError("Unknown replace label type: {!r}".format(
+ *   cdef fst.ReplaceLabelType _replace_label_type
+ *   if not fst.GetReplaceLabelType(replace_label_type,             # <<<<<<<<<<<<<<
+ *                                  epsilon_on_replace,
+ *                                  addr(_replace_label_type)):
  */
   }
 
-  /* "pywrapfst.pyx":333
- *     raise FstArgError("Unknown replace label type: {!r}".format(
- *                       replace_label_type))
- *   return replace_label_type_enum             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":397
+ *                                  addr(_replace_label_type)):
+ *     raise FstArgError(f"Unknown replace label type: {replace_label_type!r}")
+ *   return _replace_label_type             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_r = __pyx_v_replace_label_type_enum;
+  __pyx_r = __pyx_v__replace_label_type;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":308
+  /* "pywrapfst.pyx":372
  * 
  * 
  * cdef fst.ReplaceLabelType _get_replace_label_type(             # <<<<<<<<<<<<<<
@@ -5153,8 +5366,6 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_AddTraceback("pywrapfst._get_replace_label_type", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = (enum fst::ReplaceLabelType) 0;
   __pyx_L0:;
@@ -5162,12 +5373,12 @@ static enum fst::ReplaceLabelType __pyx_f_9pywrapfst__get_replace_label_type(std
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":359
+/* "pywrapfst.pyx":423
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<{} Weight {} at 0x{:x}>".format(self.type(), self.to_string(),
- *                                              id(self))
+ *     return f"<{self.type()} Weight {self.to_string()} at 0x{id(self):x}>"
+ * 
  */
 
 /* Python wrapper */
@@ -5187,122 +5398,95 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_2;
+  Py_UCS4 __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  int __pyx_t_7;
-  PyObject *__pyx_t_8 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":360
+  /* "pywrapfst.pyx":424
  * 
  *   def __repr__(self):
- *     return "<{} Weight {} at 0x{:x}>".format(self.type(), self.to_string(),             # <<<<<<<<<<<<<<
- *                                              id(self))
+ *     return f"<{self.type()} Weight {self.to_string()} at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
  * 
+ *   def __str__(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Weight_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 360, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = PyTuple_New(7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 424, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 127;
+  __Pyx_INCREF(__pyx_kp_u__2);
+  __pyx_t_2 += 1;
+  __Pyx_GIVEREF(__pyx_kp_u__2);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u__2);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "type");
-    __PYX_ERR(0, 360, __pyx_L1_error)
+    __PYX_ERR(0, 424, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 360, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 424, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_4);
+  __pyx_t_4 = 0;
+  __Pyx_INCREF(__pyx_kp_u_Weight);
+  __pyx_t_2 += 8;
+  __Pyx_GIVEREF(__pyx_kp_u_Weight);
+  PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_Weight);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "to_string");
-    __PYX_ERR(0, 360, __pyx_L1_error)
+    __PYX_ERR(0, 424, __pyx_L1_error)
   }
-  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->to_string(__pyx_v_self, 0)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 360, __pyx_L1_error)
+  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->to_string(__pyx_v_self, 0)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 424, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-
-  /* "pywrapfst.pyx":361
- *   def __repr__(self):
- *     return "<{} Weight {} at 0x{:x}>".format(self.type(), self.to_string(),
- *                                              id(self))             # <<<<<<<<<<<<<<
- * 
- *   def __str__(self):
- */
-  __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 361, __pyx_L1_error)
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_t_4);
+  __pyx_t_4 = 0;
+  __Pyx_INCREF(__pyx_kp_u_at_0x);
+  __pyx_t_2 += 6;
+  __Pyx_GIVEREF(__pyx_kp_u_at_0x);
+  PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_kp_u_at_0x);
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 424, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 424, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = NULL;
-  __pyx_t_7 = 0;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
-    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_2);
-    if (likely(__pyx_t_6)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-      __Pyx_INCREF(__pyx_t_6);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_2, function);
-      __pyx_t_7 = 1;
-    }
-  }
-  #if CYTHON_FAST_PYCALL
-  if (PyFunction_Check(__pyx_t_2)) {
-    PyObject *__pyx_temp[4] = {__pyx_t_6, __pyx_t_3, __pyx_t_4, __pyx_t_5};
-    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_7, 3+__pyx_t_7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 360, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  } else
-  #endif
-  #if CYTHON_FAST_PYCCALL
-  if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
-    PyObject *__pyx_temp[4] = {__pyx_t_6, __pyx_t_3, __pyx_t_4, __pyx_t_5};
-    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_7, 3+__pyx_t_7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 360, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  } else
-  #endif
-  {
-    __pyx_t_8 = PyTuple_New(3+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 360, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_8);
-    if (__pyx_t_6) {
-      __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
-    }
-    __Pyx_GIVEREF(__pyx_t_3);
-    PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, __pyx_t_3);
-    __Pyx_GIVEREF(__pyx_t_4);
-    PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_t_4);
-    __Pyx_GIVEREF(__pyx_t_5);
-    PyTuple_SET_ITEM(__pyx_t_8, 2+__pyx_t_7, __pyx_t_5);
-    __pyx_t_3 = 0;
-    __pyx_t_4 = 0;
-    __pyx_t_5 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 360, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-  }
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_1, 5, __pyx_t_5);
+  __pyx_t_5 = 0;
+  __Pyx_INCREF(__pyx_kp_u__3);
+  __pyx_t_2 += 1;
+  __Pyx_GIVEREF(__pyx_kp_u__3);
+  PyTuple_SET_ITEM(__pyx_t_1, 6, __pyx_kp_u__3);
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 7, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 424, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":359
+  /* "pywrapfst.pyx":423
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<{} Weight {} at 0x{:x}>".format(self.type(), self.to_string(),
- *                                              id(self))
+ *     return f"<{self.type()} Weight {self.to_string()} at 0x{id(self):x}>"
+ * 
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_8);
   __Pyx_AddTraceback("pywrapfst.Weight.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -5311,8 +5495,8 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight___repr__(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":363
- *                                              id(self))
+/* "pywrapfst.pyx":426
+ *     return f"<{self.type()} Weight {self.to_string()} at 0x{id(self):x}>"
  * 
  *   def __str__(self):             # <<<<<<<<<<<<<<
  *     return self.to_string()
@@ -5336,9 +5520,12 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_2__str__(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__str__", 0);
 
-  /* "pywrapfst.pyx":364
+  /* "pywrapfst.pyx":427
  * 
  *   def __str__(self):
  *     return self.to_string()             # <<<<<<<<<<<<<<
@@ -5348,16 +5535,16 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_2__str__(struct __pyx_obj_9pywrapfs
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "to_string");
-    __PYX_ERR(0, 364, __pyx_L1_error)
+    __PYX_ERR(0, 427, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->to_string(__pyx_v_self, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 364, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->to_string(__pyx_v_self, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 427, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":363
- *                                              id(self))
+  /* "pywrapfst.pyx":426
+ *     return f"<{self.type()} Weight {self.to_string()} at 0x{id(self):x}>"
  * 
  *   def __str__(self):             # <<<<<<<<<<<<<<
  *     return self.to_string()
@@ -5375,7 +5562,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_2__str__(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":369
+/* "pywrapfst.pyx":432
  *   # ValueError when that is not appropriate.
  * 
  *   def __float__(self):             # <<<<<<<<<<<<<<
@@ -5401,9 +5588,12 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_4__float__(struct __pyx_obj_9pywrap
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__float__", 0);
 
-  /* "pywrapfst.pyx":370
+  /* "pywrapfst.pyx":433
  * 
  *   def __float__(self):
  *     return float(self.to_string())             # <<<<<<<<<<<<<<
@@ -5413,18 +5603,18 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_4__float__(struct __pyx_obj_9pywrap
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "to_string");
-    __PYX_ERR(0, 370, __pyx_L1_error)
+    __PYX_ERR(0, 433, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->to_string(__pyx_v_self, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 370, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->to_string(__pyx_v_self, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 433, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyNumber_Float(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 370, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyNumber_Float(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 433, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":369
+  /* "pywrapfst.pyx":432
  *   # ValueError when that is not appropriate.
  * 
  *   def __float__(self):             # <<<<<<<<<<<<<<
@@ -5444,7 +5634,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_4__float__(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":372
+/* "pywrapfst.pyx":435
  *     return float(self.to_string())
  * 
  *   def __init__(self, weight_type, weight):             # <<<<<<<<<<<<<<
@@ -5457,6 +5647,9 @@ static int __pyx_pw_9pywrapfst_6Weight_7__init__(PyObject *__pyx_v_self, PyObjec
 static int __pyx_pw_9pywrapfst_6Weight_7__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_weight_type = 0;
   PyObject *__pyx_v_weight = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
@@ -5483,11 +5676,11 @@ static int __pyx_pw_9pywrapfst_6Weight_7__init__(PyObject *__pyx_v_self, PyObjec
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_weight)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 372, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 435, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 372, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 435, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -5500,7 +5693,7 @@ static int __pyx_pw_9pywrapfst_6Weight_7__init__(PyObject *__pyx_v_self, PyObjec
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 372, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 435, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Weight.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -5518,9 +5711,12 @@ static int __pyx_pf_9pywrapfst_6Weight_6__init__(struct __pyx_obj_9pywrapfst_Wei
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
   std::string __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":373
+  /* "pywrapfst.pyx":436
  * 
  *   def __init__(self, weight_type, weight):
  *     self._weight.reset(new fst.WeightClass(tostring(weight_type),             # <<<<<<<<<<<<<<
@@ -5529,20 +5725,20 @@ static int __pyx_pf_9pywrapfst_6Weight_6__init__(struct __pyx_obj_9pywrapfst_Wei
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 373, __pyx_L1_error)
+    __PYX_ERR(0, 436, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 373, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 436, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":374
+  /* "pywrapfst.pyx":437
  *   def __init__(self, weight_type, weight):
  *     self._weight.reset(new fst.WeightClass(tostring(weight_type),
  *                                            weight_tostring(weight)))             # <<<<<<<<<<<<<<
  *     self._check_weight()
  * 
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 374, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 437, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":373
+  /* "pywrapfst.pyx":436
  * 
  *   def __init__(self, weight_type, weight):
  *     self._weight.reset(new fst.WeightClass(tostring(weight_type),             # <<<<<<<<<<<<<<
@@ -5551,7 +5747,7 @@ static int __pyx_pf_9pywrapfst_6Weight_6__init__(struct __pyx_obj_9pywrapfst_Wei
  */
   __pyx_v_self->_weight.reset(new fst::script::WeightClass(__pyx_t_1, __pyx_t_2));
 
-  /* "pywrapfst.pyx":375
+  /* "pywrapfst.pyx":438
  *     self._weight.reset(new fst.WeightClass(tostring(weight_type),
  *                                            weight_tostring(weight)))
  *     self._check_weight()             # <<<<<<<<<<<<<<
@@ -5560,11 +5756,11 @@ static int __pyx_pf_9pywrapfst_6Weight_6__init__(struct __pyx_obj_9pywrapfst_Wei
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_weight");
-    __PYX_ERR(0, 375, __pyx_L1_error)
+    __PYX_ERR(0, 438, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->_check_weight(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 375, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->_check_weight(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 438, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":372
+  /* "pywrapfst.pyx":435
  *     return float(self.to_string())
  * 
  *   def __init__(self, weight_type, weight):             # <<<<<<<<<<<<<<
@@ -5583,7 +5779,7 @@ static int __pyx_pf_9pywrapfst_6Weight_6__init__(struct __pyx_obj_9pywrapfst_Wei
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":377
+/* "pywrapfst.pyx":440
  *     self._check_weight()
  * 
  *   cdef void _check_weight(self) except *:             # <<<<<<<<<<<<<<
@@ -5597,9 +5793,12 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_check_weight", 0);
 
-  /* "pywrapfst.pyx":378
+  /* "pywrapfst.pyx":441
  * 
  *   cdef void _check_weight(self) except *:
  *     if self.type() == b"none":             # <<<<<<<<<<<<<<
@@ -5608,19 +5807,19 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "type");
-    __PYX_ERR(0, 378, __pyx_L1_error)
+    __PYX_ERR(0, 441, __pyx_L1_error)
   }
   __pyx_t_1 = ((((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->type(__pyx_v_self, 0) == ((char const *)"none")) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":379
+    /* "pywrapfst.pyx":442
  *   cdef void _check_weight(self) except *:
  *     if self.type() == b"none":
  *       raise FstArgError("Weight type not found")             # <<<<<<<<<<<<<<
  *     if not self.member():
  *       raise FstBadWeightError("Invalid weight")
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 379, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 442, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -5634,14 +5833,14 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Weight_type_not_found) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Weight_type_not_found);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 379, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 442, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 379, __pyx_L1_error)
+    __PYX_ERR(0, 442, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":378
+    /* "pywrapfst.pyx":441
  * 
  *   cdef void _check_weight(self) except *:
  *     if self.type() == b"none":             # <<<<<<<<<<<<<<
@@ -5650,7 +5849,7 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
  */
   }
 
-  /* "pywrapfst.pyx":380
+  /* "pywrapfst.pyx":443
  *     if self.type() == b"none":
  *       raise FstArgError("Weight type not found")
  *     if not self.member():             # <<<<<<<<<<<<<<
@@ -5659,19 +5858,19 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "member");
-    __PYX_ERR(0, 380, __pyx_L1_error)
+    __PYX_ERR(0, 443, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_self->__pyx_vtab)->member(__pyx_v_self, 0) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":381
+    /* "pywrapfst.pyx":444
  *       raise FstArgError("Weight type not found")
  *     if not self.member():
  *       raise FstBadWeightError("Invalid weight")             # <<<<<<<<<<<<<<
  * 
  *   cpdef Weight copy(self):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 381, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 444, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -5685,14 +5884,14 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Invalid_weight) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Invalid_weight);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 381, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 444, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 381, __pyx_L1_error)
+    __PYX_ERR(0, 444, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":380
+    /* "pywrapfst.pyx":443
  *     if self.type() == b"none":
  *       raise FstArgError("Weight type not found")
  *     if not self.member():             # <<<<<<<<<<<<<<
@@ -5701,7 +5900,7 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
  */
   }
 
-  /* "pywrapfst.pyx":377
+  /* "pywrapfst.pyx":440
  *     self._check_weight()
  * 
  *   cdef void _check_weight(self) except *:             # <<<<<<<<<<<<<<
@@ -5720,7 +5919,7 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":383
+/* "pywrapfst.pyx":446
  *       raise FstBadWeightError("Invalid weight")
  * 
  *   cpdef Weight copy(self):             # <<<<<<<<<<<<<<
@@ -5730,13 +5929,16 @@ static void __pyx_f_9pywrapfst_6Weight__check_weight(struct __pyx_obj_9pywrapfst
 
 static PyObject *__pyx_pw_9pywrapfst_6Weight_9copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
 static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_6Weight_copy(struct __pyx_obj_9pywrapfst_Weight *__pyx_v_self, int __pyx_skip_dispatch) {
-  struct __pyx_obj_9pywrapfst_Weight *__pyx_v_result = 0;
+  struct __pyx_obj_9pywrapfst_Weight *__pyx_v__weight = 0;
   struct __pyx_obj_9pywrapfst_Weight *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("copy", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -5747,7 +5949,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_6Weight_copy(struc
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 383, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 446, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_6Weight_9copy)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -5764,10 +5966,10 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_6Weight_copy(struc
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 383, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 446, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Weight))))) __PYX_ERR(0, 383, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Weight))))) __PYX_ERR(0, 446, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -5786,48 +5988,48 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_6Weight_copy(struc
     #endif
   }
 
-  /* "pywrapfst.pyx":389
+  /* "pywrapfst.pyx":452
  *     Returns a copy of the Weight.
  *     """
- *     cdef Weight result = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
- *     result._weight.reset(new fst.WeightClass(deref(self._weight)))
- *     return result
+ *     cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
+ *     _weight._weight.reset(new fst.WeightClass(deref(self._weight)))
+ *     return _weight
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 389, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 452, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
+  __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":390
+  /* "pywrapfst.pyx":453
  *     """
- *     cdef Weight result = Weight.__new__(Weight)
- *     result._weight.reset(new fst.WeightClass(deref(self._weight)))             # <<<<<<<<<<<<<<
- *     return result
+ *     cdef Weight _weight = Weight.__new__(Weight)
+ *     _weight._weight.reset(new fst.WeightClass(deref(self._weight)))             # <<<<<<<<<<<<<<
+ *     return _weight
  * 
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 390, __pyx_L1_error)
+    __PYX_ERR(0, 453, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 390, __pyx_L1_error)
+    __PYX_ERR(0, 453, __pyx_L1_error)
   }
-  __pyx_v_result->_weight.reset(new fst::script::WeightClass((*__pyx_v_self->_weight)));
+  __pyx_v__weight->_weight.reset(new fst::script::WeightClass((*__pyx_v_self->_weight)));
 
-  /* "pywrapfst.pyx":391
- *     cdef Weight result = Weight.__new__(Weight)
- *     result._weight.reset(new fst.WeightClass(deref(self._weight)))
- *     return result             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":454
+ *     cdef Weight _weight = Weight.__new__(Weight)
+ *     _weight._weight.reset(new fst.WeightClass(deref(self._weight)))
+ *     return _weight             # <<<<<<<<<<<<<<
  * 
  *   # To get around the inability to declare cdef class methods, we define the
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __Pyx_INCREF(((PyObject *)__pyx_v_result));
-  __pyx_r = __pyx_v_result;
+  __Pyx_INCREF(((PyObject *)__pyx_v__weight));
+  __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":383
+  /* "pywrapfst.pyx":446
  *       raise FstBadWeightError("Invalid weight")
  * 
  *   cpdef Weight copy(self):             # <<<<<<<<<<<<<<
@@ -5844,7 +6046,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_6Weight_copy(struc
   __Pyx_AddTraceback("pywrapfst.Weight.copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_result);
+  __Pyx_XDECREF((PyObject *)__pyx_v__weight);
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
@@ -5868,9 +6070,12 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_8copy(struct __pyx_obj_9pywrapfst_W
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("copy", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_6Weight_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 383, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_6Weight_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 446, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -5887,7 +6092,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_8copy(struct __pyx_obj_9pywrapfst_W
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":397
+/* "pywrapfst.pyx":460
  * 
  *   @classmethod
  *   def Zero(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -5913,9 +6118,12 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_10Zero(CYTHON_UNUSED PyTypeObject *
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("Zero", 0);
 
-  /* "pywrapfst.pyx":403
+  /* "pywrapfst.pyx":466
  *     Constructs semiring zero.
  *     """
  *     return _Zero(weight_type)             # <<<<<<<<<<<<<<
@@ -5923,13 +6131,13 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_10Zero(CYTHON_UNUSED PyTypeObject *
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__Zero(__pyx_v_weight_type)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 403, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__Zero(__pyx_v_weight_type)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 466, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":397
+  /* "pywrapfst.pyx":460
  * 
  *   @classmethod
  *   def Zero(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -5948,7 +6156,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_10Zero(CYTHON_UNUSED PyTypeObject *
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":406
+/* "pywrapfst.pyx":469
  * 
  *   @classmethod
  *   def One(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -5974,9 +6182,12 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_12One(CYTHON_UNUSED PyTypeObject *_
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("One", 0);
 
-  /* "pywrapfst.pyx":412
+  /* "pywrapfst.pyx":475
  *     Constructs semiring One.
  *     """
  *     return _One(weight_type)             # <<<<<<<<<<<<<<
@@ -5984,13 +6195,13 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_12One(CYTHON_UNUSED PyTypeObject *_
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__One(__pyx_v_weight_type)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 412, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__One(__pyx_v_weight_type)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 475, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":406
+  /* "pywrapfst.pyx":469
  * 
  *   @classmethod
  *   def One(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -6009,7 +6220,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_12One(CYTHON_UNUSED PyTypeObject *_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":415
+/* "pywrapfst.pyx":478
  * 
  *   @classmethod
  *   def NoWeight(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -6035,9 +6246,12 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_14NoWeight(CYTHON_UNUSED PyTypeObje
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("NoWeight", 0);
 
-  /* "pywrapfst.pyx":421
+  /* "pywrapfst.pyx":484
  *     Constructs a non-member weight in the semiring.
  *     """
  *     return _NoWeight(weight_type)             # <<<<<<<<<<<<<<
@@ -6045,13 +6259,13 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_14NoWeight(CYTHON_UNUSED PyTypeObje
  *   def __eq__(Weight w1, Weight w2):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__NoWeight(__pyx_v_weight_type)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 421, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__NoWeight(__pyx_v_weight_type)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 484, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":415
+  /* "pywrapfst.pyx":478
  * 
  *   @classmethod
  *   def NoWeight(cls, weight_type):             # <<<<<<<<<<<<<<
@@ -6070,7 +6284,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_14NoWeight(CYTHON_UNUSED PyTypeObje
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":423
+/* "pywrapfst.pyx":486
  *     return _NoWeight(weight_type)
  * 
  *   def __eq__(Weight w1, Weight w2):             # <<<<<<<<<<<<<<
@@ -6081,10 +6295,13 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_14NoWeight(CYTHON_UNUSED PyTypeObje
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_6Weight_17__eq__(PyObject *__pyx_v_w1, PyObject *__pyx_v_w2); /*proto*/
 static PyObject *__pyx_pw_9pywrapfst_6Weight_17__eq__(PyObject *__pyx_v_w1, PyObject *__pyx_v_w2) {
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__eq__ (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_w2), __pyx_ptype_9pywrapfst_Weight, 1, "w2", 0))) __PYX_ERR(0, 423, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_w2), __pyx_ptype_9pywrapfst_Weight, 1, "w2", 0))) __PYX_ERR(0, 486, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_6Weight_16__eq__(((struct __pyx_obj_9pywrapfst_Weight *)__pyx_v_w1), ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_v_w2));
 
   /* function exit code */
@@ -6100,9 +6317,12 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_16__eq__(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__eq__", 0);
 
-  /* "pywrapfst.pyx":424
+  /* "pywrapfst.pyx":487
  * 
  *   def __eq__(Weight w1, Weight w2):
  *     return fst.Eq(deref(w1._weight), deref(w2._weight))             # <<<<<<<<<<<<<<
@@ -6112,19 +6332,19 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_16__eq__(struct __pyx_obj_9pywrapfs
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_w1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 424, __pyx_L1_error)
+    __PYX_ERR(0, 487, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_w2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 424, __pyx_L1_error)
+    __PYX_ERR(0, 487, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_PyBool_FromLong(operator==((*__pyx_v_w1->_weight), (*__pyx_v_w2->_weight))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 424, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(operator==((*__pyx_v_w1->_weight), (*__pyx_v_w2->_weight))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 487, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":423
+  /* "pywrapfst.pyx":486
  *     return _NoWeight(weight_type)
  * 
  *   def __eq__(Weight w1, Weight w2):             # <<<<<<<<<<<<<<
@@ -6143,7 +6363,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_16__eq__(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":426
+/* "pywrapfst.pyx":489
  *     return fst.Eq(deref(w1._weight), deref(w2._weight))
  * 
  *   def __ne__(Weight w1, Weight w2):             # <<<<<<<<<<<<<<
@@ -6154,10 +6374,13 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_16__eq__(struct __pyx_obj_9pywrapfs
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_6Weight_19__ne__(PyObject *__pyx_v_w1, PyObject *__pyx_v_w2); /*proto*/
 static PyObject *__pyx_pw_9pywrapfst_6Weight_19__ne__(PyObject *__pyx_v_w1, PyObject *__pyx_v_w2) {
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__ne__ (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_w2), __pyx_ptype_9pywrapfst_Weight, 1, "w2", 0))) __PYX_ERR(0, 426, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_w2), __pyx_ptype_9pywrapfst_Weight, 1, "w2", 0))) __PYX_ERR(0, 489, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_6Weight_18__ne__(((struct __pyx_obj_9pywrapfst_Weight *)__pyx_v_w1), ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_v_w2));
 
   /* function exit code */
@@ -6174,9 +6397,12 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_18__ne__(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   int __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__ne__", 0);
 
-  /* "pywrapfst.pyx":427
+  /* "pywrapfst.pyx":490
  * 
  *   def __ne__(Weight w1, Weight w2):
  *     return not w1 == w2             # <<<<<<<<<<<<<<
@@ -6184,16 +6410,16 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_18__ne__(struct __pyx_obj_9pywrapfs
  *   cpdef string to_string(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyObject_RichCompare(((PyObject *)__pyx_v_w1), ((PyObject *)__pyx_v_w2), Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 427, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 427, __pyx_L1_error)
+  __pyx_t_1 = PyObject_RichCompare(((PyObject *)__pyx_v_w1), ((PyObject *)__pyx_v_w2), Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 490, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 490, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyBool_FromLong((!__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 427, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong((!__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 490, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":426
+  /* "pywrapfst.pyx":489
  *     return fst.Eq(deref(w1._weight), deref(w2._weight))
  * 
  *   def __ne__(Weight w1, Weight w2):             # <<<<<<<<<<<<<<
@@ -6212,7 +6438,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_18__ne__(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":429
+/* "pywrapfst.pyx":492
  *     return not w1 == w2
  * 
  *   cpdef string to_string(self):             # <<<<<<<<<<<<<<
@@ -6229,6 +6455,9 @@ static std::string __pyx_f_9pywrapfst_6Weight_to_string(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   std::string __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("to_string", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -6239,7 +6468,7 @@ static std::string __pyx_f_9pywrapfst_6Weight_to_string(struct __pyx_obj_9pywrap
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 429, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 492, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_6Weight_21to_string)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -6255,10 +6484,10 @@ static std::string __pyx_f_9pywrapfst_6Weight_to_string(struct __pyx_obj_9pywrap
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 429, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 492, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 429, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 492, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -6277,7 +6506,7 @@ static std::string __pyx_f_9pywrapfst_6Weight_to_string(struct __pyx_obj_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":430
+  /* "pywrapfst.pyx":493
  * 
  *   cpdef string to_string(self):
  *     return self._weight.get().ToString()             # <<<<<<<<<<<<<<
@@ -6286,12 +6515,12 @@ static std::string __pyx_f_9pywrapfst_6Weight_to_string(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 430, __pyx_L1_error)
+    __PYX_ERR(0, 493, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_weight.get()->ToString();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":429
+  /* "pywrapfst.pyx":492
  *     return not w1 == w2
  * 
  *   cpdef string to_string(self):             # <<<<<<<<<<<<<<
@@ -6329,9 +6558,12 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_20to_string(struct __pyx_obj_9pywra
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("to_string", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_6Weight_to_string(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 429, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_6Weight_to_string(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 492, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -6348,7 +6580,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_20to_string(struct __pyx_obj_9pywra
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":432
+/* "pywrapfst.pyx":495
  *     return self._weight.get().ToString()
  * 
  *   cpdef string type(self):             # <<<<<<<<<<<<<<
@@ -6365,6 +6597,9 @@ static std::string __pyx_f_9pywrapfst_6Weight_type(struct __pyx_obj_9pywrapfst_W
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   std::string __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("type", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -6375,7 +6610,7 @@ static std::string __pyx_f_9pywrapfst_6Weight_type(struct __pyx_obj_9pywrapfst_W
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 432, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 495, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_6Weight_23type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -6391,10 +6626,10 @@ static std::string __pyx_f_9pywrapfst_6Weight_type(struct __pyx_obj_9pywrapfst_W
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 432, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 495, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 432, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 495, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -6413,7 +6648,7 @@ static std::string __pyx_f_9pywrapfst_6Weight_type(struct __pyx_obj_9pywrapfst_W
     #endif
   }
 
-  /* "pywrapfst.pyx":437
+  /* "pywrapfst.pyx":500
  *     Returns a string indicating the weight type.
  *     """
  *     return self._weight.get().Type()             # <<<<<<<<<<<<<<
@@ -6422,12 +6657,12 @@ static std::string __pyx_f_9pywrapfst_6Weight_type(struct __pyx_obj_9pywrapfst_W
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 437, __pyx_L1_error)
+    __PYX_ERR(0, 500, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_weight.get()->Type();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":432
+  /* "pywrapfst.pyx":495
  *     return self._weight.get().ToString()
  * 
  *   cpdef string type(self):             # <<<<<<<<<<<<<<
@@ -6466,9 +6701,12 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_22type(struct __pyx_obj_9pywrapfst_
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_6Weight_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 432, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_6Weight_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 495, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -6485,7 +6723,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_22type(struct __pyx_obj_9pywrapfst_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":439
+/* "pywrapfst.pyx":502
  *     return self._weight.get().Type()
  * 
  *   cpdef bool member(self):             # <<<<<<<<<<<<<<
@@ -6502,6 +6740,9 @@ static bool __pyx_f_9pywrapfst_6Weight_member(struct __pyx_obj_9pywrapfst_Weight
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   bool __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("member", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -6512,7 +6753,7 @@ static bool __pyx_f_9pywrapfst_6Weight_member(struct __pyx_obj_9pywrapfst_Weight
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_member); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 439, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_member); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 502, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_6Weight_25member)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -6528,10 +6769,10 @@ static bool __pyx_f_9pywrapfst_6Weight_member(struct __pyx_obj_9pywrapfst_Weight
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 439, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 502, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 439, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 502, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -6550,7 +6791,7 @@ static bool __pyx_f_9pywrapfst_6Weight_member(struct __pyx_obj_9pywrapfst_Weight
     #endif
   }
 
-  /* "pywrapfst.pyx":440
+  /* "pywrapfst.pyx":503
  * 
  *   cpdef bool member(self):
  *     return self._weight.get().Member()             # <<<<<<<<<<<<<<
@@ -6559,12 +6800,12 @@ static bool __pyx_f_9pywrapfst_6Weight_member(struct __pyx_obj_9pywrapfst_Weight
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 440, __pyx_L1_error)
+    __PYX_ERR(0, 503, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_weight.get()->Member();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":439
+  /* "pywrapfst.pyx":502
  *     return self._weight.get().Type()
  * 
  *   cpdef bool member(self):             # <<<<<<<<<<<<<<
@@ -6602,9 +6843,12 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_24member(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("member", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_6Weight_member(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 439, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_6Weight_member(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 502, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -6644,6 +6888,9 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_26__reduce_cython__(CYTHON_UNUSED s
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__reduce_cython__", 0);
 
   /* "(tree fragment)":2
@@ -6652,7 +6899,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_26__reduce_cython__(CYTHON_UNUSED s
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._weight cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -6698,6 +6945,9 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_28__setstate_cython__(CYTHON_UNUSED
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__setstate_cython__", 0);
 
   /* "(tree fragment)":4
@@ -6705,7 +6955,7 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_28__setstate_cython__(CYTHON_UNUSED
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._weight cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -6728,88 +6978,91 @@ static PyObject *__pyx_pf_9pywrapfst_6Weight_28__setstate_cython__(CYTHON_UNUSED
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":443
+/* "pywrapfst.pyx":506
  * 
  * 
  * cdef Weight _plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),
  */
 
 static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx_obj_9pywrapfst_Weight *__pyx_v_lhs, struct __pyx_obj_9pywrapfst_Weight *__pyx_v_rhs) {
-  struct __pyx_obj_9pywrapfst_Weight *__pyx_v_result = 0;
+  struct __pyx_obj_9pywrapfst_Weight *__pyx_v__weight = 0;
   struct __pyx_obj_9pywrapfst_Weight *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_plus", 0);
 
-  /* "pywrapfst.pyx":444
+  /* "pywrapfst.pyx":507
  * 
  * cdef Weight _plus(Weight lhs, Weight rhs):
- *   cdef Weight result = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
- *   result._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),
- *                                                     deref(rhs._weight))))
+ *   cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
+ *   _weight._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),
+ *                                                      deref(rhs._weight))))
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 444, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 507, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
+  __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":445
+  /* "pywrapfst.pyx":508
  * cdef Weight _plus(Weight lhs, Weight rhs):
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),             # <<<<<<<<<<<<<<
- *                                                     deref(rhs._weight))))
- *   return result
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),             # <<<<<<<<<<<<<<
+ *                                                      deref(rhs._weight))))
+ *   return _weight
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 445, __pyx_L1_error)
+    __PYX_ERR(0, 508, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_lhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 445, __pyx_L1_error)
+    __PYX_ERR(0, 508, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":446
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),
- *                                                     deref(rhs._weight))))             # <<<<<<<<<<<<<<
- *   return result
+  /* "pywrapfst.pyx":509
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),
+ *                                                      deref(rhs._weight))))             # <<<<<<<<<<<<<<
+ *   return _weight
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_rhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 446, __pyx_L1_error)
+    __PYX_ERR(0, 509, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":445
+  /* "pywrapfst.pyx":508
  * cdef Weight _plus(Weight lhs, Weight rhs):
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),             # <<<<<<<<<<<<<<
- *                                                     deref(rhs._weight))))
- *   return result
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),             # <<<<<<<<<<<<<<
+ *                                                      deref(rhs._weight))))
+ *   return _weight
  */
-  __pyx_v_result->_weight.reset(new fst::script::WeightClass(fst::script::Plus((*__pyx_v_lhs->_weight), (*__pyx_v_rhs->_weight))));
+  __pyx_v__weight->_weight.reset(new fst::script::WeightClass(fst::script::Plus((*__pyx_v_lhs->_weight), (*__pyx_v_rhs->_weight))));
 
-  /* "pywrapfst.pyx":447
- *   result._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),
- *                                                     deref(rhs._weight))))
- *   return result             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":510
+ *   _weight._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),
+ *                                                      deref(rhs._weight))))
+ *   return _weight             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __Pyx_INCREF(((PyObject *)__pyx_v_result));
-  __pyx_r = __pyx_v_result;
+  __Pyx_INCREF(((PyObject *)__pyx_v__weight));
+  __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":443
+  /* "pywrapfst.pyx":506
  * 
  * 
  * cdef Weight _plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),
  */
 
   /* function exit code */
@@ -6818,13 +7071,13 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__plus(struct __pyx
   __Pyx_AddTraceback("pywrapfst._plus", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_result);
+  __Pyx_XDECREF((PyObject *)__pyx_v__weight);
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":450
+/* "pywrapfst.pyx":513
  * 
  * 
  * def plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -6839,6 +7092,9 @@ static PyMethodDef __pyx_mdef_9pywrapfst_1plus = {"plus", (PyCFunction)(void*)(P
 static PyObject *__pyx_pw_9pywrapfst_1plus(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_Weight *__pyx_v_lhs = 0;
   struct __pyx_obj_9pywrapfst_Weight *__pyx_v_rhs = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("plus (wrapper)", 0);
@@ -6865,11 +7121,11 @@ static PyObject *__pyx_pw_9pywrapfst_1plus(PyObject *__pyx_self, PyObject *__pyx
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_rhs)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("plus", 1, 2, 2, 1); __PYX_ERR(0, 450, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("plus", 1, 2, 2, 1); __PYX_ERR(0, 513, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "plus") < 0)) __PYX_ERR(0, 450, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "plus") < 0)) __PYX_ERR(0, 513, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -6882,14 +7138,14 @@ static PyObject *__pyx_pw_9pywrapfst_1plus(PyObject *__pyx_self, PyObject *__pyx
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("plus", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 450, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("plus", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 513, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.plus", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst_Weight, 1, "lhs", 0))) __PYX_ERR(0, 450, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_Weight, 1, "rhs", 0))) __PYX_ERR(0, 450, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst_Weight, 1, "lhs", 0))) __PYX_ERR(0, 513, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_Weight, 1, "rhs", 0))) __PYX_ERR(0, 513, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_plus(__pyx_self, __pyx_v_lhs, __pyx_v_rhs);
 
   /* function exit code */
@@ -6902,50 +7158,53 @@ static PyObject *__pyx_pw_9pywrapfst_1plus(PyObject *__pyx_self, PyObject *__pyx
 }
 
 static PyObject *__pyx_pf_9pywrapfst_plus(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Weight *__pyx_v_lhs, struct __pyx_obj_9pywrapfst_Weight *__pyx_v_rhs) {
-  struct __pyx_obj_9pywrapfst_Weight *__pyx_v_result = 0;
+  struct __pyx_obj_9pywrapfst_Weight *__pyx_v__weight = 0;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("plus", 0);
 
-  /* "pywrapfst.pyx":470
+  /* "pywrapfst.pyx":533
  *     FstBadWeightError: invalid weight.
  *   """
- *   cdef Weight result = _plus(lhs, rhs)             # <<<<<<<<<<<<<<
- *   result._check_weight()
- *   return result
+ *   cdef Weight _weight = _plus(lhs, rhs)             # <<<<<<<<<<<<<<
+ *   _weight._check_weight()
+ *   return _weight
  */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__plus(__pyx_v_lhs, __pyx_v_rhs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 470, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__plus(__pyx_v_lhs, __pyx_v_rhs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 533, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
+  __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":471
+  /* "pywrapfst.pyx":534
  *   """
- *   cdef Weight result = _plus(lhs, rhs)
- *   result._check_weight()             # <<<<<<<<<<<<<<
- *   return result
+ *   cdef Weight _weight = _plus(lhs, rhs)
+ *   _weight._check_weight()             # <<<<<<<<<<<<<<
+ *   return _weight
  * 
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_weight");
-    __PYX_ERR(0, 471, __pyx_L1_error)
+    __PYX_ERR(0, 534, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_result->__pyx_vtab)->_check_weight(__pyx_v_result); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 471, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v__weight->__pyx_vtab)->_check_weight(__pyx_v__weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 534, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":472
- *   cdef Weight result = _plus(lhs, rhs)
- *   result._check_weight()
- *   return result             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":535
+ *   cdef Weight _weight = _plus(lhs, rhs)
+ *   _weight._check_weight()
+ *   return _weight             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_result));
-  __pyx_r = ((PyObject *)__pyx_v_result);
+  __Pyx_INCREF(((PyObject *)__pyx_v__weight));
+  __pyx_r = ((PyObject *)__pyx_v__weight);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":450
+  /* "pywrapfst.pyx":513
  * 
  * 
  * def plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -6959,94 +7218,97 @@ static PyObject *__pyx_pf_9pywrapfst_plus(CYTHON_UNUSED PyObject *__pyx_self, st
   __Pyx_AddTraceback("pywrapfst.plus", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_result);
+  __Pyx_XDECREF((PyObject *)__pyx_v__weight);
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":475
+/* "pywrapfst.pyx":538
  * 
  * 
  * cdef Weight _times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),
  */
 
 static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __pyx_obj_9pywrapfst_Weight *__pyx_v_lhs, struct __pyx_obj_9pywrapfst_Weight *__pyx_v_rhs) {
-  struct __pyx_obj_9pywrapfst_Weight *__pyx_v_result = 0;
+  struct __pyx_obj_9pywrapfst_Weight *__pyx_v__weight = 0;
   struct __pyx_obj_9pywrapfst_Weight *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_times", 0);
 
-  /* "pywrapfst.pyx":476
+  /* "pywrapfst.pyx":539
  * 
  * cdef Weight _times(Weight lhs, Weight rhs):
- *   cdef Weight result = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
- *   result._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),
- *                                                      deref(rhs._weight))))
+ *   cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
+ *   _weight._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),
+ *                                                       deref(rhs._weight))))
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 476, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 539, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
+  __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":477
+  /* "pywrapfst.pyx":540
  * cdef Weight _times(Weight lhs, Weight rhs):
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),             # <<<<<<<<<<<<<<
- *                                                      deref(rhs._weight))))
- *   return result
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),             # <<<<<<<<<<<<<<
+ *                                                       deref(rhs._weight))))
+ *   return _weight
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 477, __pyx_L1_error)
+    __PYX_ERR(0, 540, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_lhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 477, __pyx_L1_error)
+    __PYX_ERR(0, 540, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":478
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),
- *                                                      deref(rhs._weight))))             # <<<<<<<<<<<<<<
- *   return result
+  /* "pywrapfst.pyx":541
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),
+ *                                                       deref(rhs._weight))))             # <<<<<<<<<<<<<<
+ *   return _weight
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_rhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 478, __pyx_L1_error)
+    __PYX_ERR(0, 541, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":477
+  /* "pywrapfst.pyx":540
  * cdef Weight _times(Weight lhs, Weight rhs):
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),             # <<<<<<<<<<<<<<
- *                                                      deref(rhs._weight))))
- *   return result
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),             # <<<<<<<<<<<<<<
+ *                                                       deref(rhs._weight))))
+ *   return _weight
  */
-  __pyx_v_result->_weight.reset(new fst::script::WeightClass(fst::script::Times((*__pyx_v_lhs->_weight), (*__pyx_v_rhs->_weight))));
+  __pyx_v__weight->_weight.reset(new fst::script::WeightClass(fst::script::Times((*__pyx_v_lhs->_weight), (*__pyx_v_rhs->_weight))));
 
-  /* "pywrapfst.pyx":479
- *   result._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),
- *                                                      deref(rhs._weight))))
- *   return result             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":542
+ *   _weight._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),
+ *                                                       deref(rhs._weight))))
+ *   return _weight             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __Pyx_INCREF(((PyObject *)__pyx_v_result));
-  __pyx_r = __pyx_v_result;
+  __Pyx_INCREF(((PyObject *)__pyx_v__weight));
+  __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":475
+  /* "pywrapfst.pyx":538
  * 
  * 
  * cdef Weight _times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),
  */
 
   /* function exit code */
@@ -7055,13 +7317,13 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__times(struct __py
   __Pyx_AddTraceback("pywrapfst._times", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_result);
+  __Pyx_XDECREF((PyObject *)__pyx_v__weight);
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":482
+/* "pywrapfst.pyx":545
  * 
  * 
  * def times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7076,6 +7338,9 @@ static PyMethodDef __pyx_mdef_9pywrapfst_3times = {"times", (PyCFunction)(void*)
 static PyObject *__pyx_pw_9pywrapfst_3times(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_Weight *__pyx_v_lhs = 0;
   struct __pyx_obj_9pywrapfst_Weight *__pyx_v_rhs = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("times (wrapper)", 0);
@@ -7102,11 +7367,11 @@ static PyObject *__pyx_pw_9pywrapfst_3times(PyObject *__pyx_self, PyObject *__py
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_rhs)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("times", 1, 2, 2, 1); __PYX_ERR(0, 482, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("times", 1, 2, 2, 1); __PYX_ERR(0, 545, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "times") < 0)) __PYX_ERR(0, 482, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "times") < 0)) __PYX_ERR(0, 545, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -7119,14 +7384,14 @@ static PyObject *__pyx_pw_9pywrapfst_3times(PyObject *__pyx_self, PyObject *__py
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("times", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 482, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("times", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 545, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.times", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst_Weight, 1, "lhs", 0))) __PYX_ERR(0, 482, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_Weight, 1, "rhs", 0))) __PYX_ERR(0, 482, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst_Weight, 1, "lhs", 0))) __PYX_ERR(0, 545, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_Weight, 1, "rhs", 0))) __PYX_ERR(0, 545, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_2times(__pyx_self, __pyx_v_lhs, __pyx_v_rhs);
 
   /* function exit code */
@@ -7139,50 +7404,53 @@ static PyObject *__pyx_pw_9pywrapfst_3times(PyObject *__pyx_self, PyObject *__py
 }
 
 static PyObject *__pyx_pf_9pywrapfst_2times(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Weight *__pyx_v_lhs, struct __pyx_obj_9pywrapfst_Weight *__pyx_v_rhs) {
-  struct __pyx_obj_9pywrapfst_Weight *__pyx_v_result = 0;
+  struct __pyx_obj_9pywrapfst_Weight *__pyx_v__weight = 0;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("times", 0);
 
-  /* "pywrapfst.pyx":502
+  /* "pywrapfst.pyx":565
  *     FstBadWeightError: Invalid weight.
  *   """
- *   cdef Weight result = _times(lhs, rhs)             # <<<<<<<<<<<<<<
- *   result._check_weight()
- *   return result
+ *   cdef Weight _weight = _times(lhs, rhs)             # <<<<<<<<<<<<<<
+ *   _weight._check_weight()
+ *   return _weight
  */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__times(__pyx_v_lhs, __pyx_v_rhs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 502, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__times(__pyx_v_lhs, __pyx_v_rhs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 565, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
+  __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":503
+  /* "pywrapfst.pyx":566
  *   """
- *   cdef Weight result = _times(lhs, rhs)
- *   result._check_weight()             # <<<<<<<<<<<<<<
- *   return result
+ *   cdef Weight _weight = _times(lhs, rhs)
+ *   _weight._check_weight()             # <<<<<<<<<<<<<<
+ *   return _weight
  * 
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_weight");
-    __PYX_ERR(0, 503, __pyx_L1_error)
+    __PYX_ERR(0, 566, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_result->__pyx_vtab)->_check_weight(__pyx_v_result); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 503, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v__weight->__pyx_vtab)->_check_weight(__pyx_v__weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 566, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":504
- *   cdef Weight result = _times(lhs, rhs)
- *   result._check_weight()
- *   return result             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":567
+ *   cdef Weight _weight = _times(lhs, rhs)
+ *   _weight._check_weight()
+ *   return _weight             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_result));
-  __pyx_r = ((PyObject *)__pyx_v_result);
+  __Pyx_INCREF(((PyObject *)__pyx_v__weight));
+  __pyx_r = ((PyObject *)__pyx_v__weight);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":482
+  /* "pywrapfst.pyx":545
  * 
  * 
  * def times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7196,94 +7464,97 @@ static PyObject *__pyx_pf_9pywrapfst_2times(CYTHON_UNUSED PyObject *__pyx_self,
   __Pyx_AddTraceback("pywrapfst.times", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_result);
+  __Pyx_XDECREF((PyObject *)__pyx_v__weight);
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":507
+/* "pywrapfst.pyx":570
  * 
  * 
  * cdef Weight _divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),
  */
 
 static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __pyx_obj_9pywrapfst_Weight *__pyx_v_lhs, struct __pyx_obj_9pywrapfst_Weight *__pyx_v_rhs) {
-  struct __pyx_obj_9pywrapfst_Weight *__pyx_v_result = 0;
+  struct __pyx_obj_9pywrapfst_Weight *__pyx_v__weight = 0;
   struct __pyx_obj_9pywrapfst_Weight *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_divide", 0);
 
-  /* "pywrapfst.pyx":508
+  /* "pywrapfst.pyx":571
  * 
  * cdef Weight _divide(Weight lhs, Weight rhs):
- *   cdef Weight result = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
- *   result._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),
- *                                                       deref(rhs._weight))))
+ *   cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
+ *   _weight._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),
+ *                                                        deref(rhs._weight))))
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 508, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 571, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
+  __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":509
+  /* "pywrapfst.pyx":572
  * cdef Weight _divide(Weight lhs, Weight rhs):
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),             # <<<<<<<<<<<<<<
- *                                                       deref(rhs._weight))))
- *   return result
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),             # <<<<<<<<<<<<<<
+ *                                                        deref(rhs._weight))))
+ *   return _weight
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 509, __pyx_L1_error)
+    __PYX_ERR(0, 572, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_lhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 509, __pyx_L1_error)
+    __PYX_ERR(0, 572, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":510
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),
- *                                                       deref(rhs._weight))))             # <<<<<<<<<<<<<<
- *   return result
+  /* "pywrapfst.pyx":573
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),
+ *                                                        deref(rhs._weight))))             # <<<<<<<<<<<<<<
+ *   return _weight
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_rhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 510, __pyx_L1_error)
+    __PYX_ERR(0, 573, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":509
+  /* "pywrapfst.pyx":572
  * cdef Weight _divide(Weight lhs, Weight rhs):
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),             # <<<<<<<<<<<<<<
- *                                                       deref(rhs._weight))))
- *   return result
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),             # <<<<<<<<<<<<<<
+ *                                                        deref(rhs._weight))))
+ *   return _weight
  */
-  __pyx_v_result->_weight.reset(new fst::script::WeightClass(fst::script::Divide((*__pyx_v_lhs->_weight), (*__pyx_v_rhs->_weight))));
+  __pyx_v__weight->_weight.reset(new fst::script::WeightClass(fst::script::Divide((*__pyx_v_lhs->_weight), (*__pyx_v_rhs->_weight))));
 
-  /* "pywrapfst.pyx":511
- *   result._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),
- *                                                       deref(rhs._weight))))
- *   return result             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":574
+ *   _weight._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),
+ *                                                        deref(rhs._weight))))
+ *   return _weight             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __Pyx_INCREF(((PyObject *)__pyx_v_result));
-  __pyx_r = __pyx_v_result;
+  __Pyx_INCREF(((PyObject *)__pyx_v__weight));
+  __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":507
+  /* "pywrapfst.pyx":570
  * 
  * 
  * cdef Weight _divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),
  */
 
   /* function exit code */
@@ -7292,13 +7563,13 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__divide(struct __p
   __Pyx_AddTraceback("pywrapfst._divide", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_result);
+  __Pyx_XDECREF((PyObject *)__pyx_v__weight);
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":514
+/* "pywrapfst.pyx":577
  * 
  * 
  * def divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7313,6 +7584,9 @@ static PyMethodDef __pyx_mdef_9pywrapfst_5divide = {"divide", (PyCFunction)(void
 static PyObject *__pyx_pw_9pywrapfst_5divide(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_Weight *__pyx_v_lhs = 0;
   struct __pyx_obj_9pywrapfst_Weight *__pyx_v_rhs = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("divide (wrapper)", 0);
@@ -7339,11 +7613,11 @@ static PyObject *__pyx_pw_9pywrapfst_5divide(PyObject *__pyx_self, PyObject *__p
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_rhs)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("divide", 1, 2, 2, 1); __PYX_ERR(0, 514, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("divide", 1, 2, 2, 1); __PYX_ERR(0, 577, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "divide") < 0)) __PYX_ERR(0, 514, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "divide") < 0)) __PYX_ERR(0, 577, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -7356,14 +7630,14 @@ static PyObject *__pyx_pw_9pywrapfst_5divide(PyObject *__pyx_self, PyObject *__p
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("divide", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 514, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("divide", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 577, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.divide", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst_Weight, 1, "lhs", 0))) __PYX_ERR(0, 514, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_Weight, 1, "rhs", 0))) __PYX_ERR(0, 514, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst_Weight, 1, "lhs", 0))) __PYX_ERR(0, 577, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_Weight, 1, "rhs", 0))) __PYX_ERR(0, 577, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_4divide(__pyx_self, __pyx_v_lhs, __pyx_v_rhs);
 
   /* function exit code */
@@ -7376,50 +7650,53 @@ static PyObject *__pyx_pw_9pywrapfst_5divide(PyObject *__pyx_self, PyObject *__p
 }
 
 static PyObject *__pyx_pf_9pywrapfst_4divide(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Weight *__pyx_v_lhs, struct __pyx_obj_9pywrapfst_Weight *__pyx_v_rhs) {
-  struct __pyx_obj_9pywrapfst_Weight *__pyx_v_result = 0;
+  struct __pyx_obj_9pywrapfst_Weight *__pyx_v__weight = 0;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("divide", 0);
 
-  /* "pywrapfst.pyx":536
+  /* "pywrapfst.pyx":599
  *     FstBadWeightError: Invalid weight.
  *   """
- *   cdef Weight result = _divide(lhs, rhs)             # <<<<<<<<<<<<<<
- *   result._check_weight()
- *   return result
+ *   cdef Weight _weight = _divide(lhs, rhs)             # <<<<<<<<<<<<<<
+ *   _weight._check_weight()
+ *   return _weight
  */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__divide(__pyx_v_lhs, __pyx_v_rhs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 536, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__divide(__pyx_v_lhs, __pyx_v_rhs)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 599, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
+  __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":537
+  /* "pywrapfst.pyx":600
  *   """
- *   cdef Weight result = _divide(lhs, rhs)
- *   result._check_weight()             # <<<<<<<<<<<<<<
- *   return result
+ *   cdef Weight _weight = _divide(lhs, rhs)
+ *   _weight._check_weight()             # <<<<<<<<<<<<<<
+ *   return _weight
  * 
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_weight");
-    __PYX_ERR(0, 537, __pyx_L1_error)
+    __PYX_ERR(0, 600, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_result->__pyx_vtab)->_check_weight(__pyx_v_result); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 537, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v__weight->__pyx_vtab)->_check_weight(__pyx_v__weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 600, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":538
- *   cdef Weight result = _divide(lhs, rhs)
- *   result._check_weight()
- *   return result             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":601
+ *   cdef Weight _weight = _divide(lhs, rhs)
+ *   _weight._check_weight()
+ *   return _weight             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_result));
-  __pyx_r = ((PyObject *)__pyx_v_result);
+  __Pyx_INCREF(((PyObject *)__pyx_v__weight));
+  __pyx_r = ((PyObject *)__pyx_v__weight);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":514
+  /* "pywrapfst.pyx":577
  * 
  * 
  * def divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
@@ -7433,74 +7710,77 @@ static PyObject *__pyx_pf_9pywrapfst_4divide(CYTHON_UNUSED PyObject *__pyx_self,
   __Pyx_AddTraceback("pywrapfst.divide", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_result);
+  __Pyx_XDECREF((PyObject *)__pyx_v__weight);
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":541
+/* "pywrapfst.pyx":604
  * 
  * 
  * cdef Weight _power(Weight w, size_t n):             # <<<<<<<<<<<<<<
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.Power(deref(w._weight), n)))
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(fst.Power(deref(w._weight), n)))
  */
 
 static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__power(struct __pyx_obj_9pywrapfst_Weight *__pyx_v_w, size_t __pyx_v_n) {
-  struct __pyx_obj_9pywrapfst_Weight *__pyx_v_result = 0;
+  struct __pyx_obj_9pywrapfst_Weight *__pyx_v__weight = 0;
   struct __pyx_obj_9pywrapfst_Weight *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_power", 0);
 
-  /* "pywrapfst.pyx":542
+  /* "pywrapfst.pyx":605
  * 
  * cdef Weight _power(Weight w, size_t n):
- *   cdef Weight result = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
- *   result._weight.reset(new fst.WeightClass(fst.Power(deref(w._weight), n)))
- *   return result
+ *   cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
+ *   _weight._weight.reset(new fst.WeightClass(fst.Power(deref(w._weight), n)))
+ *   return _weight
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 542, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 605, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
+  __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":543
+  /* "pywrapfst.pyx":606
  * cdef Weight _power(Weight w, size_t n):
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.Power(deref(w._weight), n)))             # <<<<<<<<<<<<<<
- *   return result
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(fst.Power(deref(w._weight), n)))             # <<<<<<<<<<<<<<
+ *   return _weight
  * 
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 543, __pyx_L1_error)
+    __PYX_ERR(0, 606, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_w) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 543, __pyx_L1_error)
+    __PYX_ERR(0, 606, __pyx_L1_error)
   }
-  __pyx_v_result->_weight.reset(new fst::script::WeightClass(fst::script::Power((*__pyx_v_w->_weight), __pyx_v_n)));
+  __pyx_v__weight->_weight.reset(new fst::script::WeightClass(fst::script::Power((*__pyx_v_w->_weight), __pyx_v_n)));
 
-  /* "pywrapfst.pyx":544
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.Power(deref(w._weight), n)))
- *   return result             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":607
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(fst.Power(deref(w._weight), n)))
+ *   return _weight             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __Pyx_INCREF(((PyObject *)__pyx_v_result));
-  __pyx_r = __pyx_v_result;
+  __Pyx_INCREF(((PyObject *)__pyx_v__weight));
+  __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":541
+  /* "pywrapfst.pyx":604
  * 
  * 
  * cdef Weight _power(Weight w, size_t n):             # <<<<<<<<<<<<<<
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.Power(deref(w._weight), n)))
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(fst.Power(deref(w._weight), n)))
  */
 
   /* function exit code */
@@ -7509,13 +7789,13 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__power(struct __py
   __Pyx_AddTraceback("pywrapfst._power", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_result);
+  __Pyx_XDECREF((PyObject *)__pyx_v__weight);
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":547
+/* "pywrapfst.pyx":610
  * 
  * 
  * def power(Weight w, size_t n):             # <<<<<<<<<<<<<<
@@ -7530,6 +7810,9 @@ static PyMethodDef __pyx_mdef_9pywrapfst_7power = {"power", (PyCFunction)(void*)
 static PyObject *__pyx_pw_9pywrapfst_7power(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_Weight *__pyx_v_w = 0;
   size_t __pyx_v_n;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("power (wrapper)", 0);
@@ -7556,11 +7839,11 @@ static PyObject *__pyx_pw_9pywrapfst_7power(PyObject *__pyx_self, PyObject *__py
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_n)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("power", 1, 2, 2, 1); __PYX_ERR(0, 547, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("power", 1, 2, 2, 1); __PYX_ERR(0, 610, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "power") < 0)) __PYX_ERR(0, 547, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "power") < 0)) __PYX_ERR(0, 610, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -7569,17 +7852,17 @@ static PyObject *__pyx_pw_9pywrapfst_7power(PyObject *__pyx_self, PyObject *__py
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
     __pyx_v_w = ((struct __pyx_obj_9pywrapfst_Weight *)values[0]);
-    __pyx_v_n = __Pyx_PyInt_As_size_t(values[1]); if (unlikely((__pyx_v_n == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 547, __pyx_L3_error)
+    __pyx_v_n = __Pyx_PyInt_As_size_t(values[1]); if (unlikely((__pyx_v_n == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 610, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("power", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 547, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("power", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 610, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.power", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_w), __pyx_ptype_9pywrapfst_Weight, 1, "w", 0))) __PYX_ERR(0, 547, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_w), __pyx_ptype_9pywrapfst_Weight, 1, "w", 0))) __PYX_ERR(0, 610, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_6power(__pyx_self, __pyx_v_w, __pyx_v_n);
 
   /* function exit code */
@@ -7592,50 +7875,53 @@ static PyObject *__pyx_pw_9pywrapfst_7power(PyObject *__pyx_self, PyObject *__py
 }
 
 static PyObject *__pyx_pf_9pywrapfst_6power(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Weight *__pyx_v_w, size_t __pyx_v_n) {
-  struct __pyx_obj_9pywrapfst_Weight *__pyx_v_result = 0;
+  struct __pyx_obj_9pywrapfst_Weight *__pyx_v__weight = 0;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("power", 0);
 
-  /* "pywrapfst.pyx":564
+  /* "pywrapfst.pyx":627
  *     FstBadWeightError: Invalid weight.
  *   """
- *   cdef Weight result = _power(w, n)             # <<<<<<<<<<<<<<
- *   result._check_weight()
- *   return result
+ *   cdef Weight _weight = _power(w, n)             # <<<<<<<<<<<<<<
+ *   _weight._check_weight()
+ *   return _weight
  */
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__power(__pyx_v_w, __pyx_v_n)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 564, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__power(__pyx_v_w, __pyx_v_n)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 627, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
+  __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":565
+  /* "pywrapfst.pyx":628
  *   """
- *   cdef Weight result = _power(w, n)
- *   result._check_weight()             # <<<<<<<<<<<<<<
- *   return result
+ *   cdef Weight _weight = _power(w, n)
+ *   _weight._check_weight()             # <<<<<<<<<<<<<<
+ *   return _weight
  * 
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_weight");
-    __PYX_ERR(0, 565, __pyx_L1_error)
+    __PYX_ERR(0, 628, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_result->__pyx_vtab)->_check_weight(__pyx_v_result); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 565, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v__weight->__pyx_vtab)->_check_weight(__pyx_v__weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 628, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":566
- *   cdef Weight result = _power(w, n)
- *   result._check_weight()
- *   return result             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":629
+ *   cdef Weight _weight = _power(w, n)
+ *   _weight._check_weight()
+ *   return _weight             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_result));
-  __pyx_r = ((PyObject *)__pyx_v_result);
+  __Pyx_INCREF(((PyObject *)__pyx_v__weight));
+  __pyx_r = ((PyObject *)__pyx_v__weight);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":547
+  /* "pywrapfst.pyx":610
  * 
  * 
  * def power(Weight w, size_t n):             # <<<<<<<<<<<<<<
@@ -7649,13 +7935,13 @@ static PyObject *__pyx_pf_9pywrapfst_6power(CYTHON_UNUSED PyObject *__pyx_self,
   __Pyx_AddTraceback("pywrapfst.power", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_result);
+  __Pyx_XDECREF((PyObject *)__pyx_v__weight);
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":569
+/* "pywrapfst.pyx":632
  * 
  * 
  * cdef fst.WeightClass _get_WeightClass_or_Zero(const string &weight_type,             # <<<<<<<<<<<<<<
@@ -7664,7 +7950,7 @@ static PyObject *__pyx_pf_9pywrapfst_6power(CYTHON_UNUSED PyObject *__pyx_self,
  */
 
 static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std::string const &__pyx_v_weight_type, PyObject *__pyx_v_weight) {
-  fst::script::WeightClass __pyx_v_result;
+  fst::script::WeightClass __pyx_v__weight;
   fst::script::WeightClass __pyx_r;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
@@ -7674,104 +7960,107 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
   PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
   PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_get_WeightClass_or_Zero", 0);
 
-  /* "pywrapfst.pyx":587
+  /* "pywrapfst.pyx":650
  *   """
- *   cdef fst.WeightClass result
+ *   cdef fst.WeightClass _weight
  *   if weight is None:             # <<<<<<<<<<<<<<
- *     result = fst.WeightClass.Zero(weight_type)
+ *     _weight = fst.WeightClass.Zero(weight_type)
  *   elif isinstance(weight, Weight):
  */
   __pyx_t_1 = (__pyx_v_weight == Py_None);
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":588
- *   cdef fst.WeightClass result
+    /* "pywrapfst.pyx":651
+ *   cdef fst.WeightClass _weight
  *   if weight is None:
- *     result = fst.WeightClass.Zero(weight_type)             # <<<<<<<<<<<<<<
+ *     _weight = fst.WeightClass.Zero(weight_type)             # <<<<<<<<<<<<<<
  *   elif isinstance(weight, Weight):
- *     result = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
+ *     _weight = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
  */
-    __pyx_v_result = fst::script::WeightClass::Zero(__pyx_v_weight_type);
+    __pyx_v__weight = fst::script::WeightClass::Zero(__pyx_v_weight_type);
 
-    /* "pywrapfst.pyx":587
+    /* "pywrapfst.pyx":650
  *   """
- *   cdef fst.WeightClass result
+ *   cdef fst.WeightClass _weight
  *   if weight is None:             # <<<<<<<<<<<<<<
- *     result = fst.WeightClass.Zero(weight_type)
+ *     _weight = fst.WeightClass.Zero(weight_type)
  *   elif isinstance(weight, Weight):
  */
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":589
+  /* "pywrapfst.pyx":652
  *   if weight is None:
- *     result = fst.WeightClass.Zero(weight_type)
+ *     _weight = fst.WeightClass.Zero(weight_type)
  *   elif isinstance(weight, Weight):             # <<<<<<<<<<<<<<
- *     result = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
+ *     _weight = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
  *   else:
  */
   __pyx_t_2 = __Pyx_TypeCheck(__pyx_v_weight, __pyx_ptype_9pywrapfst_Weight); 
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":590
- *     result = fst.WeightClass.Zero(weight_type)
+    /* "pywrapfst.pyx":653
+ *     _weight = fst.WeightClass.Zero(weight_type)
  *   elif isinstance(weight, Weight):
- *     result = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())             # <<<<<<<<<<<<<<
+ *     _weight = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())             # <<<<<<<<<<<<<<
  *   else:
- *     result = fst.WeightClass(weight_type, weight_tostring(weight))
+ *     _weight = fst.WeightClass(weight_type, weight_tostring(weight))
  */
     if (unlikely(__pyx_v_weight == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-      __PYX_ERR(0, 590, __pyx_L1_error)
+      __PYX_ERR(0, 653, __pyx_L1_error)
     }
-    __pyx_v_result = (*((fst::script::WeightClass *)((struct __pyx_obj_9pywrapfst_Weight *)__pyx_v_weight)->_weight.get()));
+    __pyx_v__weight = (*((fst::script::WeightClass *)((struct __pyx_obj_9pywrapfst_Weight *)__pyx_v_weight)->_weight.get()));
 
-    /* "pywrapfst.pyx":589
+    /* "pywrapfst.pyx":652
  *   if weight is None:
- *     result = fst.WeightClass.Zero(weight_type)
+ *     _weight = fst.WeightClass.Zero(weight_type)
  *   elif isinstance(weight, Weight):             # <<<<<<<<<<<<<<
- *     result = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
+ *     _weight = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
  *   else:
  */
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":592
- *     result = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
+  /* "pywrapfst.pyx":655
+ *     _weight = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
  *   else:
- *     result = fst.WeightClass(weight_type, weight_tostring(weight))             # <<<<<<<<<<<<<<
- *     if not result.Member():
+ *     _weight = fst.WeightClass(weight_type, weight_tostring(weight))             # <<<<<<<<<<<<<<
+ *     if not _weight.Member():
  *       raise FstBadWeightError(weight_tostring(weight))
  */
   /*else*/ {
-    __pyx_t_3 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 592, __pyx_L1_error)
-    __pyx_v_result = fst::script::WeightClass(__pyx_v_weight_type, __pyx_t_3);
+    __pyx_t_3 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 655, __pyx_L1_error)
+    __pyx_v__weight = fst::script::WeightClass(__pyx_v_weight_type, __pyx_t_3);
 
-    /* "pywrapfst.pyx":593
+    /* "pywrapfst.pyx":656
  *   else:
- *     result = fst.WeightClass(weight_type, weight_tostring(weight))
- *     if not result.Member():             # <<<<<<<<<<<<<<
+ *     _weight = fst.WeightClass(weight_type, weight_tostring(weight))
+ *     if not _weight.Member():             # <<<<<<<<<<<<<<
  *       raise FstBadWeightError(weight_tostring(weight))
- *   return result
+ *   return _weight
  */
-    __pyx_t_1 = ((!(__pyx_v_result.Member() != 0)) != 0);
+    __pyx_t_1 = ((!(__pyx_v__weight.Member() != 0)) != 0);
     if (unlikely(__pyx_t_1)) {
 
-      /* "pywrapfst.pyx":594
- *     result = fst.WeightClass(weight_type, weight_tostring(weight))
- *     if not result.Member():
+      /* "pywrapfst.pyx":657
+ *     _weight = fst.WeightClass(weight_type, weight_tostring(weight))
+ *     if not _weight.Member():
  *       raise FstBadWeightError(weight_tostring(weight))             # <<<<<<<<<<<<<<
- *   return result
+ *   return _weight
  * 
  */
-      __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 594, __pyx_L1_error)
+      __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 657, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_3 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 594, __pyx_L1_error)
-      __pyx_t_6 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 594, __pyx_L1_error)
+      __pyx_t_3 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 657, __pyx_L1_error)
+      __pyx_t_6 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 657, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_6);
       __pyx_t_7 = NULL;
       if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
@@ -7786,35 +8075,35 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
       __pyx_t_4 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_7, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6);
       __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 594, __pyx_L1_error)
+      if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 657, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_Raise(__pyx_t_4, 0, 0, 0);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __PYX_ERR(0, 594, __pyx_L1_error)
+      __PYX_ERR(0, 657, __pyx_L1_error)
 
-      /* "pywrapfst.pyx":593
+      /* "pywrapfst.pyx":656
  *   else:
- *     result = fst.WeightClass(weight_type, weight_tostring(weight))
- *     if not result.Member():             # <<<<<<<<<<<<<<
+ *     _weight = fst.WeightClass(weight_type, weight_tostring(weight))
+ *     if not _weight.Member():             # <<<<<<<<<<<<<<
  *       raise FstBadWeightError(weight_tostring(weight))
- *   return result
+ *   return _weight
  */
     }
   }
   __pyx_L3:;
 
-  /* "pywrapfst.pyx":595
- *     if not result.Member():
+  /* "pywrapfst.pyx":658
+ *     if not _weight.Member():
  *       raise FstBadWeightError(weight_tostring(weight))
- *   return result             # <<<<<<<<<<<<<<
+ *   return _weight             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_r = __pyx_v_result;
+  __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":569
+  /* "pywrapfst.pyx":632
  * 
  * 
  * cdef fst.WeightClass _get_WeightClass_or_Zero(const string &weight_type,             # <<<<<<<<<<<<<<
@@ -7835,7 +8124,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":598
+/* "pywrapfst.pyx":661
  * 
  * 
  * cdef fst.WeightClass _get_WeightClass_or_One(const string &weight_type,             # <<<<<<<<<<<<<<
@@ -7844,7 +8133,7 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_Zero(std:
  */
 
 static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::string const &__pyx_v_weight_type, PyObject *__pyx_v_weight) {
-  fst::script::WeightClass __pyx_v_result;
+  fst::script::WeightClass __pyx_v__weight;
   fst::script::WeightClass __pyx_r;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
@@ -7854,104 +8143,107 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
   PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
   PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_get_WeightClass_or_One", 0);
 
-  /* "pywrapfst.pyx":616
+  /* "pywrapfst.pyx":679
  *   """
- *   cdef fst.WeightClass result
+ *   cdef fst.WeightClass _weight
  *   if weight is None:             # <<<<<<<<<<<<<<
- *     result = fst.WeightClass.One(weight_type)
+ *     _weight = fst.WeightClass.One(weight_type)
  *   elif isinstance(weight, Weight):
  */
   __pyx_t_1 = (__pyx_v_weight == Py_None);
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":617
- *   cdef fst.WeightClass result
+    /* "pywrapfst.pyx":680
+ *   cdef fst.WeightClass _weight
  *   if weight is None:
- *     result = fst.WeightClass.One(weight_type)             # <<<<<<<<<<<<<<
+ *     _weight = fst.WeightClass.One(weight_type)             # <<<<<<<<<<<<<<
  *   elif isinstance(weight, Weight):
- *     result = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
+ *     _weight = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
  */
-    __pyx_v_result = fst::script::WeightClass::One(__pyx_v_weight_type);
+    __pyx_v__weight = fst::script::WeightClass::One(__pyx_v_weight_type);
 
-    /* "pywrapfst.pyx":616
+    /* "pywrapfst.pyx":679
  *   """
- *   cdef fst.WeightClass result
+ *   cdef fst.WeightClass _weight
  *   if weight is None:             # <<<<<<<<<<<<<<
- *     result = fst.WeightClass.One(weight_type)
+ *     _weight = fst.WeightClass.One(weight_type)
  *   elif isinstance(weight, Weight):
  */
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":618
+  /* "pywrapfst.pyx":681
  *   if weight is None:
- *     result = fst.WeightClass.One(weight_type)
+ *     _weight = fst.WeightClass.One(weight_type)
  *   elif isinstance(weight, Weight):             # <<<<<<<<<<<<<<
- *     result = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
+ *     _weight = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
  *   else:
  */
   __pyx_t_2 = __Pyx_TypeCheck(__pyx_v_weight, __pyx_ptype_9pywrapfst_Weight); 
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":619
- *     result = fst.WeightClass.One(weight_type)
+    /* "pywrapfst.pyx":682
+ *     _weight = fst.WeightClass.One(weight_type)
  *   elif isinstance(weight, Weight):
- *     result = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())             # <<<<<<<<<<<<<<
+ *     _weight = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())             # <<<<<<<<<<<<<<
  *   else:
- *     result = fst.WeightClass(weight_type, weight_tostring(weight))
+ *     _weight = fst.WeightClass(weight_type, weight_tostring(weight))
  */
     if (unlikely(__pyx_v_weight == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-      __PYX_ERR(0, 619, __pyx_L1_error)
+      __PYX_ERR(0, 682, __pyx_L1_error)
     }
-    __pyx_v_result = (*((fst::script::WeightClass *)((struct __pyx_obj_9pywrapfst_Weight *)__pyx_v_weight)->_weight.get()));
+    __pyx_v__weight = (*((fst::script::WeightClass *)((struct __pyx_obj_9pywrapfst_Weight *)__pyx_v_weight)->_weight.get()));
 
-    /* "pywrapfst.pyx":618
+    /* "pywrapfst.pyx":681
  *   if weight is None:
- *     result = fst.WeightClass.One(weight_type)
+ *     _weight = fst.WeightClass.One(weight_type)
  *   elif isinstance(weight, Weight):             # <<<<<<<<<<<<<<
- *     result = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
+ *     _weight = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
  *   else:
  */
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":621
- *     result = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
+  /* "pywrapfst.pyx":684
+ *     _weight = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
  *   else:
- *     result = fst.WeightClass(weight_type, weight_tostring(weight))             # <<<<<<<<<<<<<<
- *     if not result.Member():
+ *     _weight = fst.WeightClass(weight_type, weight_tostring(weight))             # <<<<<<<<<<<<<<
+ *     if not _weight.Member():
  *       raise FstBadWeightError(weight_tostring(weight))
  */
   /*else*/ {
-    __pyx_t_3 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 621, __pyx_L1_error)
-    __pyx_v_result = fst::script::WeightClass(__pyx_v_weight_type, __pyx_t_3);
+    __pyx_t_3 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 684, __pyx_L1_error)
+    __pyx_v__weight = fst::script::WeightClass(__pyx_v_weight_type, __pyx_t_3);
 
-    /* "pywrapfst.pyx":622
+    /* "pywrapfst.pyx":685
  *   else:
- *     result = fst.WeightClass(weight_type, weight_tostring(weight))
- *     if not result.Member():             # <<<<<<<<<<<<<<
+ *     _weight = fst.WeightClass(weight_type, weight_tostring(weight))
+ *     if not _weight.Member():             # <<<<<<<<<<<<<<
  *       raise FstBadWeightError(weight_tostring(weight))
- *   return result
+ *   return _weight
  */
-    __pyx_t_1 = ((!(__pyx_v_result.Member() != 0)) != 0);
+    __pyx_t_1 = ((!(__pyx_v__weight.Member() != 0)) != 0);
     if (unlikely(__pyx_t_1)) {
 
-      /* "pywrapfst.pyx":623
- *     result = fst.WeightClass(weight_type, weight_tostring(weight))
- *     if not result.Member():
+      /* "pywrapfst.pyx":686
+ *     _weight = fst.WeightClass(weight_type, weight_tostring(weight))
+ *     if not _weight.Member():
  *       raise FstBadWeightError(weight_tostring(weight))             # <<<<<<<<<<<<<<
- *   return result
+ *   return _weight
  * 
  */
-      __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 623, __pyx_L1_error)
+      __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstBadWeightError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 686, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_3 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 623, __pyx_L1_error)
-      __pyx_t_6 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 623, __pyx_L1_error)
+      __pyx_t_3 = __pyx_f_9pywrapfst_weight_tostring(__pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 686, __pyx_L1_error)
+      __pyx_t_6 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 686, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_6);
       __pyx_t_7 = NULL;
       if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
@@ -7966,35 +8258,35 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
       __pyx_t_4 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_7, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6);
       __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 623, __pyx_L1_error)
+      if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 686, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_Raise(__pyx_t_4, 0, 0, 0);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __PYX_ERR(0, 623, __pyx_L1_error)
+      __PYX_ERR(0, 686, __pyx_L1_error)
 
-      /* "pywrapfst.pyx":622
+      /* "pywrapfst.pyx":685
  *   else:
- *     result = fst.WeightClass(weight_type, weight_tostring(weight))
- *     if not result.Member():             # <<<<<<<<<<<<<<
+ *     _weight = fst.WeightClass(weight_type, weight_tostring(weight))
+ *     if not _weight.Member():             # <<<<<<<<<<<<<<
  *       raise FstBadWeightError(weight_tostring(weight))
- *   return result
+ *   return _weight
  */
     }
   }
   __pyx_L3:;
 
-  /* "pywrapfst.pyx":624
- *     if not result.Member():
+  /* "pywrapfst.pyx":687
+ *     if not _weight.Member():
  *       raise FstBadWeightError(weight_tostring(weight))
- *   return result             # <<<<<<<<<<<<<<
+ *   return _weight             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_r = __pyx_v_result;
+  __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":598
+  /* "pywrapfst.pyx":661
  * 
  * 
  * cdef fst.WeightClass _get_WeightClass_or_One(const string &weight_type,             # <<<<<<<<<<<<<<
@@ -8015,16 +8307,16 @@ static fst::script::WeightClass __pyx_f_9pywrapfst__get_WeightClass_or_One(std::
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":627
+/* "pywrapfst.pyx":690
  * 
  * 
  * cdef Weight _Zero(weight_type):             # <<<<<<<<<<<<<<
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.WeightClass.Zero(
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(
  */
 
 static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Zero(PyObject *__pyx_v_weight_type) {
-  struct __pyx_obj_9pywrapfst_Weight *__pyx_v_result = 0;
+  struct __pyx_obj_9pywrapfst_Weight *__pyx_v__weight = 0;
   struct __pyx_obj_9pywrapfst_Weight *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -8032,72 +8324,75 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Zero(PyObject *__
   int __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_Zero", 0);
 
-  /* "pywrapfst.pyx":628
+  /* "pywrapfst.pyx":691
  * 
  * cdef Weight _Zero(weight_type):
- *   cdef Weight result = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
- *   result._weight.reset(new fst.WeightClass(fst.WeightClass.Zero(
- *       tostring(weight_type))))
+ *   cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
+ *   _weight._weight.reset(
+ *     new fst.WeightClass(fst.WeightClass.Zero(tostring(weight_type))))
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 628, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 691, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
+  __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":629
+  /* "pywrapfst.pyx":692
  * cdef Weight _Zero(weight_type):
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.WeightClass.Zero(             # <<<<<<<<<<<<<<
- *       tostring(weight_type))))
- *   if result._weight.get().Type() == b"none":
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(             # <<<<<<<<<<<<<<
+ *     new fst.WeightClass(fst.WeightClass.Zero(tostring(weight_type))))
+ *   if _weight._weight.get().Type() == b"none":
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 629, __pyx_L1_error)
+    __PYX_ERR(0, 692, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":630
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.WeightClass.Zero(
- *       tostring(weight_type))))             # <<<<<<<<<<<<<<
- *   if result._weight.get().Type() == b"none":
+  /* "pywrapfst.pyx":693
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(
+ *     new fst.WeightClass(fst.WeightClass.Zero(tostring(weight_type))))             # <<<<<<<<<<<<<<
+ *   if _weight._weight.get().Type() == b"none":
  *     raise FstArgError("Weight type not found")
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 630, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 693, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":629
+  /* "pywrapfst.pyx":692
  * cdef Weight _Zero(weight_type):
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.WeightClass.Zero(             # <<<<<<<<<<<<<<
- *       tostring(weight_type))))
- *   if result._weight.get().Type() == b"none":
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(             # <<<<<<<<<<<<<<
+ *     new fst.WeightClass(fst.WeightClass.Zero(tostring(weight_type))))
+ *   if _weight._weight.get().Type() == b"none":
  */
-  __pyx_v_result->_weight.reset(new fst::script::WeightClass(fst::script::WeightClass::Zero(__pyx_t_2)));
+  __pyx_v__weight->_weight.reset(new fst::script::WeightClass(fst::script::WeightClass::Zero(__pyx_t_2)));
 
-  /* "pywrapfst.pyx":631
- *   result._weight.reset(new fst.WeightClass(fst.WeightClass.Zero(
- *       tostring(weight_type))))
- *   if result._weight.get().Type() == b"none":             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":694
+ *   _weight._weight.reset(
+ *     new fst.WeightClass(fst.WeightClass.Zero(tostring(weight_type))))
+ *   if _weight._weight.get().Type() == b"none":             # <<<<<<<<<<<<<<
  *     raise FstArgError("Weight type not found")
- *   return result
+ *   return _weight
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 631, __pyx_L1_error)
+    __PYX_ERR(0, 694, __pyx_L1_error)
   }
-  __pyx_t_3 = ((__pyx_v_result->_weight.get()->Type() == ((char const *)"none")) != 0);
+  __pyx_t_3 = ((__pyx_v__weight->_weight.get()->Type() == ((char const *)"none")) != 0);
   if (unlikely(__pyx_t_3)) {
 
-    /* "pywrapfst.pyx":632
- *       tostring(weight_type))))
- *   if result._weight.get().Type() == b"none":
+    /* "pywrapfst.pyx":695
+ *     new fst.WeightClass(fst.WeightClass.Zero(tostring(weight_type))))
+ *   if _weight._weight.get().Type() == b"none":
  *     raise FstArgError("Weight type not found")             # <<<<<<<<<<<<<<
- *   return result
+ *   return _weight
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 632, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 695, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
@@ -8111,40 +8406,40 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Zero(PyObject *__
     }
     __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_Weight_type_not_found) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_Weight_type_not_found);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 632, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 695, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 632, __pyx_L1_error)
+    __PYX_ERR(0, 695, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":631
- *   result._weight.reset(new fst.WeightClass(fst.WeightClass.Zero(
- *       tostring(weight_type))))
- *   if result._weight.get().Type() == b"none":             # <<<<<<<<<<<<<<
+    /* "pywrapfst.pyx":694
+ *   _weight._weight.reset(
+ *     new fst.WeightClass(fst.WeightClass.Zero(tostring(weight_type))))
+ *   if _weight._weight.get().Type() == b"none":             # <<<<<<<<<<<<<<
  *     raise FstArgError("Weight type not found")
- *   return result
+ *   return _weight
  */
   }
 
-  /* "pywrapfst.pyx":633
- *   if result._weight.get().Type() == b"none":
+  /* "pywrapfst.pyx":696
+ *   if _weight._weight.get().Type() == b"none":
  *     raise FstArgError("Weight type not found")
- *   return result             # <<<<<<<<<<<<<<
+ *   return _weight             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __Pyx_INCREF(((PyObject *)__pyx_v_result));
-  __pyx_r = __pyx_v_result;
+  __Pyx_INCREF(((PyObject *)__pyx_v__weight));
+  __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":627
+  /* "pywrapfst.pyx":690
  * 
  * 
  * cdef Weight _Zero(weight_type):             # <<<<<<<<<<<<<<
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(fst.WeightClass.Zero(
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(
  */
 
   /* function exit code */
@@ -8155,22 +8450,22 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__Zero(PyObject *__
   __Pyx_AddTraceback("pywrapfst._Zero", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_result);
+  __Pyx_XDECREF((PyObject *)__pyx_v__weight);
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":636
+/* "pywrapfst.pyx":699
  * 
  * 
  * cdef Weight _One(weight_type):             # <<<<<<<<<<<<<<
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(
  */
 
 static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__One(PyObject *__pyx_v_weight_type) {
-  struct __pyx_obj_9pywrapfst_Weight *__pyx_v_result = 0;
+  struct __pyx_obj_9pywrapfst_Weight *__pyx_v__weight = 0;
   struct __pyx_obj_9pywrapfst_Weight *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -8178,72 +8473,75 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__One(PyObject *__p
   int __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_One", 0);
 
-  /* "pywrapfst.pyx":637
+  /* "pywrapfst.pyx":700
  * 
  * cdef Weight _One(weight_type):
- *   cdef Weight result = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
- *   result._weight.reset(new fst.WeightClass(
- *         fst.WeightClass.One(tostring(weight_type))))
+ *   cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
+ *   _weight._weight.reset(
+ *     new fst.WeightClass(fst.WeightClass.One(tostring(weight_type))))
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 637, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 700, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
+  __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":638
+  /* "pywrapfst.pyx":701
  * cdef Weight _One(weight_type):
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(             # <<<<<<<<<<<<<<
- *         fst.WeightClass.One(tostring(weight_type))))
- *   if result._weight.get().Type() == b"none":
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(             # <<<<<<<<<<<<<<
+ *     new fst.WeightClass(fst.WeightClass.One(tostring(weight_type))))
+ *   if _weight._weight.get().Type() == b"none":
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 638, __pyx_L1_error)
+    __PYX_ERR(0, 701, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":639
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(
- *         fst.WeightClass.One(tostring(weight_type))))             # <<<<<<<<<<<<<<
- *   if result._weight.get().Type() == b"none":
+  /* "pywrapfst.pyx":702
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(
+ *     new fst.WeightClass(fst.WeightClass.One(tostring(weight_type))))             # <<<<<<<<<<<<<<
+ *   if _weight._weight.get().Type() == b"none":
  *     raise FstArgError("Weight type not found")
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 639, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 702, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":638
+  /* "pywrapfst.pyx":701
  * cdef Weight _One(weight_type):
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(             # <<<<<<<<<<<<<<
- *         fst.WeightClass.One(tostring(weight_type))))
- *   if result._weight.get().Type() == b"none":
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(             # <<<<<<<<<<<<<<
+ *     new fst.WeightClass(fst.WeightClass.One(tostring(weight_type))))
+ *   if _weight._weight.get().Type() == b"none":
  */
-  __pyx_v_result->_weight.reset(new fst::script::WeightClass(fst::script::WeightClass::One(__pyx_t_2)));
+  __pyx_v__weight->_weight.reset(new fst::script::WeightClass(fst::script::WeightClass::One(__pyx_t_2)));
 
-  /* "pywrapfst.pyx":640
- *   result._weight.reset(new fst.WeightClass(
- *         fst.WeightClass.One(tostring(weight_type))))
- *   if result._weight.get().Type() == b"none":             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":703
+ *   _weight._weight.reset(
+ *     new fst.WeightClass(fst.WeightClass.One(tostring(weight_type))))
+ *   if _weight._weight.get().Type() == b"none":             # <<<<<<<<<<<<<<
  *     raise FstArgError("Weight type not found")
- *   return result
+ *   return _weight
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 640, __pyx_L1_error)
+    __PYX_ERR(0, 703, __pyx_L1_error)
   }
-  __pyx_t_3 = ((__pyx_v_result->_weight.get()->Type() == ((char const *)"none")) != 0);
+  __pyx_t_3 = ((__pyx_v__weight->_weight.get()->Type() == ((char const *)"none")) != 0);
   if (unlikely(__pyx_t_3)) {
 
-    /* "pywrapfst.pyx":641
- *         fst.WeightClass.One(tostring(weight_type))))
- *   if result._weight.get().Type() == b"none":
+    /* "pywrapfst.pyx":704
+ *     new fst.WeightClass(fst.WeightClass.One(tostring(weight_type))))
+ *   if _weight._weight.get().Type() == b"none":
  *     raise FstArgError("Weight type not found")             # <<<<<<<<<<<<<<
- *   return result
+ *   return _weight
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 641, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 704, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
@@ -8257,40 +8555,40 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__One(PyObject *__p
     }
     __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_Weight_type_not_found) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_Weight_type_not_found);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 641, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 704, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 641, __pyx_L1_error)
+    __PYX_ERR(0, 704, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":640
- *   result._weight.reset(new fst.WeightClass(
- *         fst.WeightClass.One(tostring(weight_type))))
- *   if result._weight.get().Type() == b"none":             # <<<<<<<<<<<<<<
+    /* "pywrapfst.pyx":703
+ *   _weight._weight.reset(
+ *     new fst.WeightClass(fst.WeightClass.One(tostring(weight_type))))
+ *   if _weight._weight.get().Type() == b"none":             # <<<<<<<<<<<<<<
  *     raise FstArgError("Weight type not found")
- *   return result
+ *   return _weight
  */
   }
 
-  /* "pywrapfst.pyx":642
- *   if result._weight.get().Type() == b"none":
+  /* "pywrapfst.pyx":705
+ *   if _weight._weight.get().Type() == b"none":
  *     raise FstArgError("Weight type not found")
- *   return result             # <<<<<<<<<<<<<<
+ *   return _weight             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __Pyx_INCREF(((PyObject *)__pyx_v_result));
-  __pyx_r = __pyx_v_result;
+  __Pyx_INCREF(((PyObject *)__pyx_v__weight));
+  __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":636
+  /* "pywrapfst.pyx":699
  * 
  * 
  * cdef Weight _One(weight_type):             # <<<<<<<<<<<<<<
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(
  */
 
   /* function exit code */
@@ -8301,88 +8599,91 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__One(PyObject *__p
   __Pyx_AddTraceback("pywrapfst._One", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_result);
+  __Pyx_XDECREF((PyObject *)__pyx_v__weight);
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":645
+/* "pywrapfst.pyx":708
  * 
  * 
  * cdef Weight _NoWeight(weight_type):             # <<<<<<<<<<<<<<
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(
  */
 
 static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__NoWeight(PyObject *__pyx_v_weight_type) {
-  struct __pyx_obj_9pywrapfst_Weight *__pyx_v_result = 0;
+  struct __pyx_obj_9pywrapfst_Weight *__pyx_v__weight = 0;
   struct __pyx_obj_9pywrapfst_Weight *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   std::string __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_NoWeight", 0);
 
-  /* "pywrapfst.pyx":646
+  /* "pywrapfst.pyx":709
  * 
  * cdef Weight _NoWeight(weight_type):
- *   cdef Weight result = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
- *   result._weight.reset(new fst.WeightClass(
- *         fst.WeightClass.NoWeight(tostring(weight_type))))
+ *   cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
+ *   _weight._weight.reset(
+ *     new fst.WeightClass(fst.WeightClass.NoWeight(tostring(weight_type))))
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 646, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 709, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_v_result = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
+  __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":647
+  /* "pywrapfst.pyx":710
  * cdef Weight _NoWeight(weight_type):
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(             # <<<<<<<<<<<<<<
- *         fst.WeightClass.NoWeight(tostring(weight_type))))
- *   return result
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(             # <<<<<<<<<<<<<<
+ *     new fst.WeightClass(fst.WeightClass.NoWeight(tostring(weight_type))))
+ *   return _weight
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 647, __pyx_L1_error)
+    __PYX_ERR(0, 710, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":648
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(
- *         fst.WeightClass.NoWeight(tostring(weight_type))))             # <<<<<<<<<<<<<<
- *   return result
+  /* "pywrapfst.pyx":711
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(
+ *     new fst.WeightClass(fst.WeightClass.NoWeight(tostring(weight_type))))             # <<<<<<<<<<<<<<
+ *   return _weight
  * 
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 648, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_weight_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 711, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":647
+  /* "pywrapfst.pyx":710
  * cdef Weight _NoWeight(weight_type):
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(             # <<<<<<<<<<<<<<
- *         fst.WeightClass.NoWeight(tostring(weight_type))))
- *   return result
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(             # <<<<<<<<<<<<<<
+ *     new fst.WeightClass(fst.WeightClass.NoWeight(tostring(weight_type))))
+ *   return _weight
  */
-  __pyx_v_result->_weight.reset(new fst::script::WeightClass(fst::script::WeightClass::NoWeight(__pyx_t_2)));
+  __pyx_v__weight->_weight.reset(new fst::script::WeightClass(fst::script::WeightClass::NoWeight(__pyx_t_2)));
 
-  /* "pywrapfst.pyx":649
- *   result._weight.reset(new fst.WeightClass(
- *         fst.WeightClass.NoWeight(tostring(weight_type))))
- *   return result             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":712
+ *   _weight._weight.reset(
+ *     new fst.WeightClass(fst.WeightClass.NoWeight(tostring(weight_type))))
+ *   return _weight             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __Pyx_INCREF(((PyObject *)__pyx_v_result));
-  __pyx_r = __pyx_v_result;
+  __Pyx_INCREF(((PyObject *)__pyx_v__weight));
+  __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":645
+  /* "pywrapfst.pyx":708
  * 
  * 
  * cdef Weight _NoWeight(weight_type):             # <<<<<<<<<<<<<<
- *   cdef Weight result = Weight.__new__(Weight)
- *   result._weight.reset(new fst.WeightClass(
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(
  */
 
   /* function exit code */
@@ -8391,131 +8692,91 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst__NoWeight(PyObject
   __Pyx_AddTraceback("pywrapfst._NoWeight", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_result);
+  __Pyx_XDECREF((PyObject *)__pyx_v__weight);
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":683
+/* "pywrapfst.pyx":744
  *   # Doing so will allow undefined behavior.
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
- *     raise FstDeletedConstructorError(
- *         "Cannot construct {}".format(self.__class__.__name__))
+ *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")
+ * 
  */
 
 /* Python wrapper */
-static int __pyx_pw_9pywrapfst_12_SymbolTable_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static int __pyx_pw_9pywrapfst_12_SymbolTable_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static int __pyx_pw_9pywrapfst_15SymbolTableView_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_9pywrapfst_15SymbolTableView_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
   if (unlikely(PyTuple_GET_SIZE(__pyx_args) > 0)) {
     __Pyx_RaiseArgtupleInvalid("__init__", 1, 0, 0, PyTuple_GET_SIZE(__pyx_args)); return -1;}
   if (unlikely(__pyx_kwds) && unlikely(PyDict_Size(__pyx_kwds) > 0) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "__init__", 0))) return -1;
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable___init__(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_15SymbolTableView___init__(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static int __pyx_pf_9pywrapfst_12_SymbolTable___init__(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self) {
+static int __pyx_pf_9pywrapfst_15SymbolTableView___init__(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self) {
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":684
- * 
- *   def __init__(self):
- *     raise FstDeletedConstructorError(             # <<<<<<<<<<<<<<
- *         "Cannot construct {}".format(self.__class__.__name__))
+  /* "pywrapfst.pyx":745
  * 
- */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 684, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-
-  /* "pywrapfst.pyx":685
  *   def __init__(self):
- *     raise FstDeletedConstructorError(
- *         "Cannot construct {}".format(self.__class__.__name__))             # <<<<<<<<<<<<<<
+ *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")             # <<<<<<<<<<<<<<
  * 
  *   def __iter__(self):
  */
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 685, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 685, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_name); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 685, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = NULL;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) {
-    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
-    if (likely(__pyx_t_5)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-      __Pyx_INCREF(__pyx_t_5);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_4, function);
-    }
-  }
-  __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 685, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = NULL;
-  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
-    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
-    if (likely(__pyx_t_4)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-      __Pyx_INCREF(__pyx_t_4);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_2, function);
-    }
-  }
-  __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 684, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 745, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 745, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_t_2, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 745, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Cannot_construct, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 745, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_NotImplementedError, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 745, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(0, 684, __pyx_L1_error)
+  __PYX_ERR(0, 745, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":683
+  /* "pywrapfst.pyx":744
  *   # Doing so will allow undefined behavior.
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
- *     raise FstDeletedConstructorError(
- *         "Cannot construct {}".format(self.__class__.__name__))
+ *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")
+ * 
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
   __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = -1;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":687
- *         "Cannot construct {}".format(self.__class__.__name__))
+/* "pywrapfst.pyx":747
+ *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")
  * 
  *   def __iter__(self):             # <<<<<<<<<<<<<<
  *     return _SymbolTableIterator(self)
@@ -8523,25 +8784,28 @@ static int __pyx_pf_9pywrapfst_12_SymbolTable___init__(struct __pyx_obj_9pywrapf
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_3__iter__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_3__iter__(PyObject *__pyx_v_self) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_3__iter__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_3__iter__(PyObject *__pyx_v_self) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_2__iter__(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_15SymbolTableView_2__iter__(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_2__iter__(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_2__iter__(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":688
+  /* "pywrapfst.pyx":748
  * 
  *   def __iter__(self):
  *     return _SymbolTableIterator(self)             # <<<<<<<<<<<<<<
@@ -8549,14 +8813,14 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_2__iter__(struct __pyx_obj_9
  *   # Registers the class for pickling.
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyObject_CallOneArg(((PyObject *)__pyx_ptype_9pywrapfst__SymbolTableIterator), ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 688, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_CallOneArg(((PyObject *)__pyx_ptype_9pywrapfst__SymbolTableIterator), ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 748, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":687
- *         "Cannot construct {}".format(self.__class__.__name__))
+  /* "pywrapfst.pyx":747
+ *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")
  * 
  *   def __iter__(self):             # <<<<<<<<<<<<<<
  *     return _SymbolTableIterator(self)
@@ -8566,7 +8830,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_2__iter__(struct __pyx_obj_9
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.__iter__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.__iter__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -8574,7 +8838,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_2__iter__(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":692
+/* "pywrapfst.pyx":752
  *   # Registers the class for pickling.
  * 
  *   def __reduce__(self):             # <<<<<<<<<<<<<<
@@ -8583,27 +8847,30 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_2__iter__(struct __pyx_obj_9
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_5__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_5__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_5__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_5__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__reduce__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_4__reduce__(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_15SymbolTableView_4__reduce__(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_4__reduce__(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_4__reduce__(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__reduce__", 0);
 
-  /* "pywrapfst.pyx":693
+  /* "pywrapfst.pyx":753
  * 
  *   def __reduce__(self):
  *     return (_read_SymbolTable_from_string, (self.write_to_string(),))             # <<<<<<<<<<<<<<
@@ -8611,20 +8878,20 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_4__reduce__(struct __pyx_obj
  *   # Returns a raw const pointer to SymbolTable.
  */
   __Pyx_XDECREF(__pyx_r);
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_read_SymbolTable_from_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 693, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_read_SymbolTable_from_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 753, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "write_to_string");
-    __PYX_ERR(0, 693, __pyx_L1_error)
+    __PYX_ERR(0, 753, __pyx_L1_error)
   }
-  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->__pyx_vtab)->write_to_string(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 693, __pyx_L1_error)
+  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->write_to_string(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 753, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 693, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 753, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_GIVEREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
   __pyx_t_2 = 0;
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 693, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 753, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
@@ -8636,7 +8903,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_4__reduce__(struct __pyx_obj
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":692
+  /* "pywrapfst.pyx":752
  *   # Registers the class for pickling.
  * 
  *   def __reduce__(self):             # <<<<<<<<<<<<<<
@@ -8649,7 +8916,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_4__reduce__(struct __pyx_obj
   __Pyx_XDECREF(__pyx_t_1);
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.__reduce__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.__reduce__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -8657,7 +8924,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_4__reduce__(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":699
+/* "pywrapfst.pyx":759
  *   # Should not be directly accessed except by `_raw_ptr_or_raise()`.
  *   # All other methods should use the safer _raw_ptr_or_raise() instead.
  *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
@@ -8665,12 +8932,12 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_4__reduce__(struct __pyx_obj
  * 
  */
 
-static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_12_SymbolTable__raw(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self) {
+static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_15SymbolTableView__raw(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self) {
   __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_raw", 0);
 
-  /* "pywrapfst.pyx":700
+  /* "pywrapfst.pyx":760
  *   # All other methods should use the safer _raw_ptr_or_raise() instead.
  *   cdef const_SymbolTable_ptr _raw(self):
  *     return NULL             # <<<<<<<<<<<<<<
@@ -8680,7 +8947,7 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_12_SymbolTabl
   __pyx_r = NULL;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":699
+  /* "pywrapfst.pyx":759
  *   # Should not be directly accessed except by `_raw_ptr_or_raise()`.
  *   # All other methods should use the safer _raw_ptr_or_raise() instead.
  *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
@@ -8694,7 +8961,7 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_12_SymbolTabl
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":703
+/* "pywrapfst.pyx":763
  * 
  *   # Raises an FstOpError for a nonexistent SymbolTable.
  *   cdef void _raise_nonexistent(self) except *:             # <<<<<<<<<<<<<<
@@ -8702,21 +8969,24 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_12_SymbolTabl
  * 
  */
 
-static void __pyx_f_9pywrapfst_12_SymbolTable__raise_nonexistent(CYTHON_UNUSED struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self) {
+static void __pyx_f_9pywrapfst_15SymbolTableView__raise_nonexistent(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_raise_nonexistent", 0);
 
-  /* "pywrapfst.pyx":704
+  /* "pywrapfst.pyx":764
  *   # Raises an FstOpError for a nonexistent SymbolTable.
  *   cdef void _raise_nonexistent(self) except *:
  *     raise FstOpError("SymbolTable no longer exists")             # <<<<<<<<<<<<<<
  * 
  *   # Internal API method that should be used when a const pointer to an
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 704, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 764, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_t_3 = NULL;
   if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -8730,14 +9000,14 @@ static void __pyx_f_9pywrapfst_12_SymbolTable__raise_nonexistent(CYTHON_UNUSED s
   }
   __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_kp_u_SymbolTable_no_longer_exists) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_SymbolTable_no_longer_exists);
   __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 704, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 764, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(0, 704, __pyx_L1_error)
+  __PYX_ERR(0, 764, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":703
+  /* "pywrapfst.pyx":763
  * 
  *   # Raises an FstOpError for a nonexistent SymbolTable.
  *   cdef void _raise_nonexistent(self) except *:             # <<<<<<<<<<<<<<
@@ -8750,107 +9020,110 @@ static void __pyx_f_9pywrapfst_12_SymbolTable__raise_nonexistent(CYTHON_UNUSED s
   __Pyx_XDECREF(__pyx_t_1);
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable._raise_nonexistent", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView._raise_nonexistent", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":708
+/* "pywrapfst.pyx":768
  *   # Internal API method that should be used when a const pointer to an
  *   # fst.SymbolTable is required.
  *   cdef const_SymbolTable_ptr _raw_ptr_or_raise(self) except *:             # <<<<<<<<<<<<<<
- *     cdef const_SymbolTable_ptr raw = self._raw()
- *     if raw == NULL:
+ *     cdef const_SymbolTable_ptr _raw = self._raw()
+ *     if _raw == NULL:
  */
 
-static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_12_SymbolTable__raw_ptr_or_raise(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self) {
-  __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_v_raw;
+static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_15SymbolTableView__raw_ptr_or_raise(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self) {
+  __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_v__raw;
   __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_r;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_raw_ptr_or_raise", 0);
 
-  /* "pywrapfst.pyx":709
+  /* "pywrapfst.pyx":769
  *   # fst.SymbolTable is required.
  *   cdef const_SymbolTable_ptr _raw_ptr_or_raise(self) except *:
- *     cdef const_SymbolTable_ptr raw = self._raw()             # <<<<<<<<<<<<<<
- *     if raw == NULL:
+ *     cdef const_SymbolTable_ptr _raw = self._raw()             # <<<<<<<<<<<<<<
+ *     if _raw == NULL:
  *       self._raise_nonexistent()
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw");
-    __PYX_ERR(0, 709, __pyx_L1_error)
+    __PYX_ERR(0, 769, __pyx_L1_error)
   }
-  __pyx_v_raw = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->__pyx_vtab)->_raw(__pyx_v_self);
+  __pyx_v__raw = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw(__pyx_v_self);
 
-  /* "pywrapfst.pyx":710
+  /* "pywrapfst.pyx":770
  *   cdef const_SymbolTable_ptr _raw_ptr_or_raise(self) except *:
- *     cdef const_SymbolTable_ptr raw = self._raw()
- *     if raw == NULL:             # <<<<<<<<<<<<<<
+ *     cdef const_SymbolTable_ptr _raw = self._raw()
+ *     if _raw == NULL:             # <<<<<<<<<<<<<<
  *       self._raise_nonexistent()
- *     return raw
+ *     return _raw
  */
-  __pyx_t_1 = ((__pyx_v_raw == NULL) != 0);
+  __pyx_t_1 = ((__pyx_v__raw == NULL) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":711
- *     cdef const_SymbolTable_ptr raw = self._raw()
- *     if raw == NULL:
+    /* "pywrapfst.pyx":771
+ *     cdef const_SymbolTable_ptr _raw = self._raw()
+ *     if _raw == NULL:
  *       self._raise_nonexistent()             # <<<<<<<<<<<<<<
- *     return raw
+ *     return _raw
  * 
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raise_nonexistent");
-      __PYX_ERR(0, 711, __pyx_L1_error)
+      __PYX_ERR(0, 771, __pyx_L1_error)
     }
-    ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->__pyx_vtab)->_raise_nonexistent(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 711, __pyx_L1_error)
+    ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raise_nonexistent(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 771, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":710
+    /* "pywrapfst.pyx":770
  *   cdef const_SymbolTable_ptr _raw_ptr_or_raise(self) except *:
- *     cdef const_SymbolTable_ptr raw = self._raw()
- *     if raw == NULL:             # <<<<<<<<<<<<<<
+ *     cdef const_SymbolTable_ptr _raw = self._raw()
+ *     if _raw == NULL:             # <<<<<<<<<<<<<<
  *       self._raise_nonexistent()
- *     return raw
+ *     return _raw
  */
   }
 
-  /* "pywrapfst.pyx":712
- *     if raw == NULL:
+  /* "pywrapfst.pyx":772
+ *     if _raw == NULL:
  *       self._raise_nonexistent()
- *     return raw             # <<<<<<<<<<<<<<
+ *     return _raw             # <<<<<<<<<<<<<<
  * 
  *   cpdef int64 available_key(self) except *:
  */
-  __pyx_r = __pyx_v_raw;
+  __pyx_r = __pyx_v__raw;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":708
+  /* "pywrapfst.pyx":768
  *   # Internal API method that should be used when a const pointer to an
  *   # fst.SymbolTable is required.
  *   cdef const_SymbolTable_ptr _raw_ptr_or_raise(self) except *:             # <<<<<<<<<<<<<<
- *     cdef const_SymbolTable_ptr raw = self._raw()
- *     if raw == NULL:
+ *     cdef const_SymbolTable_ptr _raw = self._raw()
+ *     if _raw == NULL:
  */
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._SymbolTable._raw_ptr_or_raise", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView._raw_ptr_or_raise", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":714
- *     return raw
+/* "pywrapfst.pyx":774
+ *     return _raw
  * 
  *   cpdef int64 available_key(self) except *:             # <<<<<<<<<<<<<<
  *     """
  *     available_key(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_7available_key(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static int64 __pyx_f_9pywrapfst_12_SymbolTable_available_key(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_7available_key(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static int64 __pyx_f_9pywrapfst_15SymbolTableView_available_key(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, int __pyx_skip_dispatch) {
   int64 __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -8859,6 +9132,9 @@ static int64 __pyx_f_9pywrapfst_12_SymbolTable_available_key(struct __pyx_obj_9p
   PyObject *__pyx_t_4 = NULL;
   int64 __pyx_t_5;
   fst::SymbolTable const *__pyx_t_6;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("available_key", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -8869,9 +9145,9 @@ static int64 __pyx_f_9pywrapfst_12_SymbolTable_available_key(struct __pyx_obj_9p
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_available_key); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 714, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_available_key); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 774, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12_SymbolTable_7available_key)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_7available_key)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -8885,10 +9161,10 @@ static int64 __pyx_f_9pywrapfst_12_SymbolTable_available_key(struct __pyx_obj_9p
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 714, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 774, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 714, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 774, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -8907,7 +9183,7 @@ static int64 __pyx_f_9pywrapfst_12_SymbolTable_available_key(struct __pyx_obj_9p
     #endif
   }
 
-  /* "pywrapfst.pyx":720
+  /* "pywrapfst.pyx":780
  *     Returns an integer indicating the next available key index in the table.
  *     """
  *     return self._raw_ptr_or_raise().AvailableKey()             # <<<<<<<<<<<<<<
@@ -8916,14 +9192,14 @@ static int64 __pyx_f_9pywrapfst_12_SymbolTable_available_key(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 720, __pyx_L1_error)
+    __PYX_ERR(0, 780, __pyx_L1_error)
   }
-  __pyx_t_6 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 720, __pyx_L1_error)
+  __pyx_t_6 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 780, __pyx_L1_error)
   __pyx_r = __pyx_t_6->AvailableKey();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":714
- *     return raw
+  /* "pywrapfst.pyx":774
+ *     return _raw
  * 
  *   cpdef int64 available_key(self) except *:             # <<<<<<<<<<<<<<
  *     """
@@ -8936,7 +9212,7 @@ static int64 __pyx_f_9pywrapfst_12_SymbolTable_available_key(struct __pyx_obj_9p
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.available_key", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.available_key", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -8944,28 +9220,31 @@ static int64 __pyx_f_9pywrapfst_12_SymbolTable_available_key(struct __pyx_obj_9p
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_7available_key(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_12_SymbolTable_6available_key[] = "\n    available_key(self)\n\n    Returns an integer indicating the next available key index in the table.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_7available_key(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_7available_key(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_15SymbolTableView_6available_key[] = "\n    available_key(self)\n\n    Returns an integer indicating the next available key index in the table.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_7available_key(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("available_key (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_6available_key(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_15SymbolTableView_6available_key(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_6available_key(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_6available_key(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   int64 __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("available_key", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_12_SymbolTable_available_key(__pyx_v_self, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 714, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 714, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_available_key(__pyx_v_self, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 774, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 774, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -8974,7 +9253,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_6available_key(struct __pyx_
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.available_key", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.available_key", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -8982,7 +9261,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_6available_key(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":722
+/* "pywrapfst.pyx":782
  *     return self._raw_ptr_or_raise().AvailableKey()
  * 
  *   cpdef bytes checksum(self):             # <<<<<<<<<<<<<<
@@ -8990,8 +9269,8 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_6available_key(struct __pyx_
  *     checksum(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_9checksum(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_checksum(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_9checksum(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_f_9pywrapfst_15SymbolTableView_checksum(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, int __pyx_skip_dispatch) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -8999,6 +9278,9 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_checksum(struct __pyx_obj_9py
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   fst::SymbolTable const *__pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("checksum", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -9009,9 +9291,9 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_checksum(struct __pyx_obj_9py
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_checksum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 722, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_checksum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 782, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12_SymbolTable_9checksum)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_9checksum)) {
         __Pyx_XDECREF(__pyx_r);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
@@ -9026,10 +9308,10 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_checksum(struct __pyx_obj_9py
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 722, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 782, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 722, __pyx_L1_error)
+        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 782, __pyx_L1_error)
         __pyx_r = ((PyObject*)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -9048,7 +9330,7 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_checksum(struct __pyx_obj_9py
     #endif
   }
 
-  /* "pywrapfst.pyx":728
+  /* "pywrapfst.pyx":788
  *     Returns a bytestring indicating the label-independent MD5 checksum.
  *     """
  *     return self._raw_ptr_or_raise().CheckSum()             # <<<<<<<<<<<<<<
@@ -9058,16 +9340,16 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_checksum(struct __pyx_obj_9py
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 728, __pyx_L1_error)
+    __PYX_ERR(0, 788, __pyx_L1_error)
   }
-  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 728, __pyx_L1_error)
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_5->CheckSum()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 728, __pyx_L1_error)
+  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 788, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_5->CheckSum()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 788, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((PyObject*)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":722
+  /* "pywrapfst.pyx":782
  *     return self._raw_ptr_or_raise().AvailableKey()
  * 
  *   cpdef bytes checksum(self):             # <<<<<<<<<<<<<<
@@ -9081,7 +9363,7 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_checksum(struct __pyx_obj_9py
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.checksum", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.checksum", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -9090,26 +9372,29 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_checksum(struct __pyx_obj_9py
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_9checksum(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_12_SymbolTable_8checksum[] = "\n    checksum(self)\n\n    Returns a bytestring indicating the label-independent MD5 checksum.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_9checksum(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_9checksum(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_15SymbolTableView_8checksum[] = "\n    checksum(self)\n\n    Returns a bytestring indicating the label-independent MD5 checksum.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_9checksum(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("checksum (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_8checksum(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_15SymbolTableView_8checksum(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_8checksum(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_8checksum(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("checksum", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_12_SymbolTable_checksum(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 722, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_checksum(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 782, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -9118,7 +9403,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_8checksum(struct __pyx_obj_9
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.checksum", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.checksum", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -9126,7 +9411,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_8checksum(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":730
+/* "pywrapfst.pyx":790
  *     return self._raw_ptr_or_raise().CheckSum()
  * 
  *   cpdef SymbolTable copy(self):             # <<<<<<<<<<<<<<
@@ -9134,8 +9419,8 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_8checksum(struct __pyx_obj_9
  *     copy(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_11copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_12_SymbolTable_copy(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_11copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_15SymbolTableView_copy(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, int __pyx_skip_dispatch) {
   struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -9143,6 +9428,9 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_12_SymbolTabl
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   fst::SymbolTable const *__pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("copy", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -9153,9 +9441,9 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_12_SymbolTabl
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 730, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 790, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12_SymbolTable_11copy)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_11copy)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
@@ -9170,10 +9458,10 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_12_SymbolTabl
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 730, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 790, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_SymbolTable))))) __PYX_ERR(0, 730, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_SymbolTable))))) __PYX_ERR(0, 790, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -9192,7 +9480,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_12_SymbolTabl
     #endif
   }
 
-  /* "pywrapfst.pyx":736
+  /* "pywrapfst.pyx":796
  *     Returns a mutable copy of the SymbolTable.
  *     """
  *     return _init_SymbolTable(WrapUnique(self._raw_ptr_or_raise().Copy()))             # <<<<<<<<<<<<<<
@@ -9202,16 +9490,16 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_12_SymbolTabl
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 736, __pyx_L1_error)
+    __PYX_ERR(0, 796, __pyx_L1_error)
   }
-  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 736, __pyx_L1_error)
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::WrapUnique<fst::SymbolTable>(__pyx_t_5->Copy()))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 736, __pyx_L1_error)
+  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 796, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::WrapUnique<fst::SymbolTable>(__pyx_t_5->Copy()))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 796, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":730
+  /* "pywrapfst.pyx":790
  *     return self._raw_ptr_or_raise().CheckSum()
  * 
  *   cpdef SymbolTable copy(self):             # <<<<<<<<<<<<<<
@@ -9225,7 +9513,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_12_SymbolTabl
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
@@ -9234,26 +9522,29 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_12_SymbolTabl
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_11copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_12_SymbolTable_10copy[] = "\n    copy(self)\n\n    Returns a mutable copy of the SymbolTable.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_11copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_11copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_15SymbolTableView_10copy[] = "\n    copy(self)\n\n    Returns a mutable copy of the SymbolTable.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_11copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("copy (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_10copy(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_15SymbolTableView_10copy(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_10copy(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_10copy(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("copy", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_12_SymbolTable_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 730, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_15SymbolTableView_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 790, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -9262,7 +9553,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_10copy(struct __pyx_obj_9pyw
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -9270,7 +9561,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_10copy(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":738
+/* "pywrapfst.pyx":798
  *     return _init_SymbolTable(WrapUnique(self._raw_ptr_or_raise().Copy()))
  * 
  *   def find(self, key):             # <<<<<<<<<<<<<<
@@ -9279,21 +9570,21 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_10copy(struct __pyx_obj_9pyw
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_13find(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/
-static char __pyx_doc_9pywrapfst_12_SymbolTable_12find[] = "\n    find(self, key)\n\n    Given a symbol or index, finds the other one.\n\n    This method returns the index associated with a symbol key, or the symbol\n    associated with a index key.\n\n    Args:\n      key: Either a string or an index.\n\n    Returns:\n      If the key is a string, the associated index or NO_LABEL if not found; if\n          the key is an integer, the associated symbol or an empty string if\n          not found.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_13find(PyObject *__pyx_v_self, PyObject *__pyx_v_key) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_13find(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/
+static char __pyx_doc_9pywrapfst_15SymbolTableView_12find[] = "\n    find(self, key)\n\n    Given a symbol or index, finds the other one.\n\n    This method returns the index associated with a symbol key, or the symbol\n    associated with a index key.\n\n    Args:\n      key: Either a string or an index.\n\n    Returns:\n      If the key is a string, the associated index or NO_LABEL if not found; if\n          the key is an integer, the associated symbol or an empty string if\n          not found.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_13find(PyObject *__pyx_v_self, PyObject *__pyx_v_key) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("find (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_12find(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), ((PyObject *)__pyx_v_key));
+  __pyx_r = __pyx_pf_9pywrapfst_15SymbolTableView_12find(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self), ((PyObject *)__pyx_v_key));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_12find(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key) {
-  __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_v_raw;
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_12find(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, PyObject *__pyx_v_key) {
+  __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_v__raw;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   fst::SymbolTable const *__pyx_t_1;
@@ -9302,33 +9593,36 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_12find(struct __pyx_obj_9pyw
   PyObject *__pyx_t_4 = NULL;
   std::string __pyx_t_5;
   PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
+  int __pyx_t_7;
   PyObject *__pyx_t_8 = NULL;
   PyObject *__pyx_t_9 = NULL;
-  int __pyx_t_10;
-  int64 __pyx_t_11;
+  int64 __pyx_t_10;
+  PyObject *__pyx_t_11 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("find", 0);
 
-  /* "pywrapfst.pyx":755
+  /* "pywrapfst.pyx":815
  *           not found.
  *     """
- *     cdef const_SymbolTable_ptr raw = self._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
+ *     cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
  *     try:
- *       return raw.FindIndex(tostring(key))
+ *       return _raw.FindIndex(tostring(key))
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 755, __pyx_L1_error)
+    __PYX_ERR(0, 815, __pyx_L1_error)
   }
-  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 755, __pyx_L1_error)
-  __pyx_v_raw = __pyx_t_1;
+  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 815, __pyx_L1_error)
+  __pyx_v__raw = __pyx_t_1;
 
-  /* "pywrapfst.pyx":756
+  /* "pywrapfst.pyx":816
  *     """
- *     cdef const_SymbolTable_ptr raw = self._raw_ptr_or_raise()
+ *     cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()
  *     try:             # <<<<<<<<<<<<<<
- *       return raw.FindIndex(tostring(key))
- *     except FstArgError:
+ *       return _raw.FindIndex(tostring(key))
+ *     except TypeError:
  */
   {
     __Pyx_PyThreadState_declare
@@ -9339,80 +9633,74 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_12find(struct __pyx_obj_9pyw
     __Pyx_XGOTREF(__pyx_t_4);
     /*try:*/ {
 
-      /* "pywrapfst.pyx":757
- *     cdef const_SymbolTable_ptr raw = self._raw_ptr_or_raise()
+      /* "pywrapfst.pyx":817
+ *     cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()
  *     try:
- *       return raw.FindIndex(tostring(key))             # <<<<<<<<<<<<<<
- *     except FstArgError:
- *       return raw.FindSymbol(key)
+ *       return _raw.FindIndex(tostring(key))             # <<<<<<<<<<<<<<
+ *     except TypeError:
+ *       return _raw.FindSymbol(key)
  */
       __Pyx_XDECREF(__pyx_r);
-      __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 757, __pyx_L3_error)
-      __pyx_t_6 = __Pyx_PyInt_From_int64_t(__pyx_v_raw->Find(__pyx_t_5)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 757, __pyx_L3_error)
+      __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 817, __pyx_L3_error)
+      __pyx_t_6 = __Pyx_PyInt_From_int64_t(__pyx_v__raw->Find(__pyx_t_5)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 817, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_6);
       __pyx_r = __pyx_t_6;
       __pyx_t_6 = 0;
       goto __pyx_L7_try_return;
 
-      /* "pywrapfst.pyx":756
+      /* "pywrapfst.pyx":816
  *     """
- *     cdef const_SymbolTable_ptr raw = self._raw_ptr_or_raise()
+ *     cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()
  *     try:             # <<<<<<<<<<<<<<
- *       return raw.FindIndex(tostring(key))
- *     except FstArgError:
+ *       return _raw.FindIndex(tostring(key))
+ *     except TypeError:
  */
     }
     __pyx_L3_error:;
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-    /* "pywrapfst.pyx":758
+    /* "pywrapfst.pyx":818
  *     try:
- *       return raw.FindIndex(tostring(key))
- *     except FstArgError:             # <<<<<<<<<<<<<<
- *       return raw.FindSymbol(key)
+ *       return _raw.FindIndex(tostring(key))
+ *     except TypeError:             # <<<<<<<<<<<<<<
+ *       return _raw.FindSymbol(key)
  * 
  */
-    __Pyx_ErrFetch(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8);
-    __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 758, __pyx_L5_except_error)
-    __Pyx_GOTREF(__pyx_t_9);
-    __pyx_t_10 = __Pyx_PyErr_GivenExceptionMatches(__pyx_t_6, __pyx_t_9);
-    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-    __Pyx_ErrRestore(__pyx_t_6, __pyx_t_7, __pyx_t_8);
-    __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0;
-    if (__pyx_t_10) {
-      __Pyx_AddTraceback("pywrapfst._SymbolTable.find", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_8, &__pyx_t_7, &__pyx_t_6) < 0) __PYX_ERR(0, 758, __pyx_L5_except_error)
-      __Pyx_GOTREF(__pyx_t_8);
-      __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_7 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_TypeError);
+    if (__pyx_t_7) {
+      __Pyx_AddTraceback("pywrapfst.SymbolTableView.find", __pyx_clineno, __pyx_lineno, __pyx_filename);
+      if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_8, &__pyx_t_9) < 0) __PYX_ERR(0, 818, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_GOTREF(__pyx_t_8);
+      __Pyx_GOTREF(__pyx_t_9);
 
-      /* "pywrapfst.pyx":759
- *       return raw.FindIndex(tostring(key))
- *     except FstArgError:
- *       return raw.FindSymbol(key)             # <<<<<<<<<<<<<<
+      /* "pywrapfst.pyx":819
+ *       return _raw.FindIndex(tostring(key))
+ *     except TypeError:
+ *       return _raw.FindSymbol(key)             # <<<<<<<<<<<<<<
  * 
  *   cpdef int64 get_nth_key(self, ssize_t pos) except *:
  */
       __Pyx_XDECREF(__pyx_r);
-      __pyx_t_11 = __Pyx_PyInt_As_int64_t(__pyx_v_key); if (unlikely((__pyx_t_11 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 759, __pyx_L5_except_error)
-      __pyx_t_9 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_raw->Find(__pyx_t_11)); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 759, __pyx_L5_except_error)
-      __Pyx_GOTREF(__pyx_t_9);
-      __pyx_r = __pyx_t_9;
-      __pyx_t_9 = 0;
+      __pyx_t_10 = __Pyx_PyInt_As_int64_t(__pyx_v_key); if (unlikely((__pyx_t_10 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 819, __pyx_L5_except_error)
+      __pyx_t_11 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v__raw->Find(__pyx_t_10)); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 819, __pyx_L5_except_error)
+      __Pyx_GOTREF(__pyx_t_11);
+      __pyx_r = __pyx_t_11;
+      __pyx_t_11 = 0;
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
       goto __pyx_L6_except_return;
     }
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "pywrapfst.pyx":756
+    /* "pywrapfst.pyx":816
  *     """
- *     cdef const_SymbolTable_ptr raw = self._raw_ptr_or_raise()
+ *     cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()
  *     try:             # <<<<<<<<<<<<<<
- *       return raw.FindIndex(tostring(key))
- *     except FstArgError:
+ *       return _raw.FindIndex(tostring(key))
+ *     except TypeError:
  */
     __Pyx_XGIVEREF(__pyx_t_2);
     __Pyx_XGIVEREF(__pyx_t_3);
@@ -9433,7 +9721,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_12find(struct __pyx_obj_9pyw
     goto __pyx_L0;
   }
 
-  /* "pywrapfst.pyx":738
+  /* "pywrapfst.pyx":798
  *     return _init_SymbolTable(WrapUnique(self._raw_ptr_or_raise().Copy()))
  * 
  *   def find(self, key):             # <<<<<<<<<<<<<<
@@ -9444,10 +9732,10 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_12find(struct __pyx_obj_9pyw
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_XDECREF(__pyx_t_8);
   __Pyx_XDECREF(__pyx_t_9);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.find", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_XDECREF(__pyx_t_11);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.find", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -9455,16 +9743,16 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_12find(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":761
- *       return raw.FindSymbol(key)
+/* "pywrapfst.pyx":821
+ *       return _raw.FindSymbol(key)
  * 
  *   cpdef int64 get_nth_key(self, ssize_t pos) except *:             # <<<<<<<<<<<<<<
  *     """
  *     get_nth_key(self, pos)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_15get_nth_key(PyObject *__pyx_v_self, PyObject *__pyx_arg_pos); /*proto*/
-static int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, Py_ssize_t __pyx_v_pos, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_15get_nth_key(PyObject *__pyx_v_self, PyObject *__pyx_arg_pos); /*proto*/
+static int64 __pyx_f_9pywrapfst_15SymbolTableView_get_nth_key(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, Py_ssize_t __pyx_v_pos, int __pyx_skip_dispatch) {
   int64 __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -9474,6 +9762,9 @@ static int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(struct __pyx_obj_9pyw
   PyObject *__pyx_t_5 = NULL;
   int64 __pyx_t_6;
   fst::SymbolTable const *__pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_nth_key", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -9484,10 +9775,10 @@ static int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(struct __pyx_obj_9pyw
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_nth_key); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 761, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_nth_key); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 821, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12_SymbolTable_15get_nth_key)) {
-        __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_pos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 761, __pyx_L1_error)
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_15get_nth_key)) {
+        __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_pos); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 821, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -9503,10 +9794,10 @@ static int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(struct __pyx_obj_9pyw
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 761, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 821, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __pyx_t_6 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_6 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 761, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_6 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 821, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_6;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -9525,7 +9816,7 @@ static int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(struct __pyx_obj_9pyw
     #endif
   }
 
-  /* "pywrapfst.pyx":773
+  /* "pywrapfst.pyx":833
  *       The integer index of the n-th key, or NO_LABEL if not found.
  *     """
  *     return self._raw_ptr_or_raise().GetNthKey(pos)             # <<<<<<<<<<<<<<
@@ -9534,14 +9825,14 @@ static int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 773, __pyx_L1_error)
+    __PYX_ERR(0, 833, __pyx_L1_error)
   }
-  __pyx_t_7 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 773, __pyx_L1_error)
+  __pyx_t_7 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 833, __pyx_L1_error)
   __pyx_r = __pyx_t_7->GetNthKey(__pyx_v_pos);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":761
- *       return raw.FindSymbol(key)
+  /* "pywrapfst.pyx":821
+ *       return _raw.FindSymbol(key)
  * 
  *   cpdef int64 get_nth_key(self, ssize_t pos) except *:             # <<<<<<<<<<<<<<
  *     """
@@ -9555,7 +9846,7 @@ static int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(struct __pyx_obj_9pyw
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.get_nth_key", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.get_nth_key", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -9563,38 +9854,44 @@ static int64 __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(struct __pyx_obj_9pyw
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_15get_nth_key(PyObject *__pyx_v_self, PyObject *__pyx_arg_pos); /*proto*/
-static char __pyx_doc_9pywrapfst_12_SymbolTable_14get_nth_key[] = "\n    get_nth_key(self, pos)\n\n    Retrieves the integer index of the n-th key in the table.\n\n    Args:\n      pos: The n-th key to retrieve.\n\n    Returns:\n      The integer index of the n-th key, or NO_LABEL if not found.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_15get_nth_key(PyObject *__pyx_v_self, PyObject *__pyx_arg_pos) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_15get_nth_key(PyObject *__pyx_v_self, PyObject *__pyx_arg_pos); /*proto*/
+static char __pyx_doc_9pywrapfst_15SymbolTableView_14get_nth_key[] = "\n    get_nth_key(self, pos)\n\n    Retrieves the integer index of the n-th key in the table.\n\n    Args:\n      pos: The n-th key to retrieve.\n\n    Returns:\n      The integer index of the n-th key, or NO_LABEL if not found.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_15get_nth_key(PyObject *__pyx_v_self, PyObject *__pyx_arg_pos) {
   Py_ssize_t __pyx_v_pos;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("get_nth_key (wrapper)", 0);
   assert(__pyx_arg_pos); {
-    __pyx_v_pos = PyInt_AsSsize_t(__pyx_arg_pos); if (unlikely((__pyx_v_pos == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 761, __pyx_L3_error)
+    __pyx_v_pos = PyInt_AsSsize_t(__pyx_arg_pos); if (unlikely((__pyx_v_pos == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 821, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.get_nth_key", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.get_nth_key", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_14get_nth_key(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), ((Py_ssize_t)__pyx_v_pos));
+  __pyx_r = __pyx_pf_9pywrapfst_15SymbolTableView_14get_nth_key(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self), ((Py_ssize_t)__pyx_v_pos));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_14get_nth_key(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, Py_ssize_t __pyx_v_pos) {
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_14get_nth_key(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, Py_ssize_t __pyx_v_pos) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   int64 __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_nth_key", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_12_SymbolTable_get_nth_key(__pyx_v_self, __pyx_v_pos, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 761, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 761, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_get_nth_key(__pyx_v_self, __pyx_v_pos, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 821, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 821, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -9603,7 +9900,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_14get_nth_key(struct __pyx_o
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.get_nth_key", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.get_nth_key", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -9611,7 +9908,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_14get_nth_key(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":775
+/* "pywrapfst.pyx":835
  *     return self._raw_ptr_or_raise().GetNthKey(pos)
  * 
  *   cpdef bytes labeled_checksum(self):             # <<<<<<<<<<<<<<
@@ -9619,8 +9916,8 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_14get_nth_key(struct __pyx_o
  *     labeled_checksum(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_17labeled_checksum(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_17labeled_checksum(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_f_9pywrapfst_15SymbolTableView_labeled_checksum(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, int __pyx_skip_dispatch) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -9628,6 +9925,9 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum(struct __pyx
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   fst::SymbolTable const *__pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("labeled_checksum", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -9638,9 +9938,9 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum(struct __pyx
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_labeled_checksum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 775, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_labeled_checksum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 835, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12_SymbolTable_17labeled_checksum)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_17labeled_checksum)) {
         __Pyx_XDECREF(__pyx_r);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
@@ -9655,10 +9955,10 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum(struct __pyx
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 775, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 835, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 775, __pyx_L1_error)
+        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 835, __pyx_L1_error)
         __pyx_r = ((PyObject*)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -9677,7 +9977,7 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum(struct __pyx
     #endif
   }
 
-  /* "pywrapfst.pyx":781
+  /* "pywrapfst.pyx":841
  *     Returns a bytestring indicating the label-dependent MD5 checksum.
  *     """
  *     return self._raw_ptr_or_raise().LabeledCheckSum()             # <<<<<<<<<<<<<<
@@ -9687,16 +9987,16 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum(struct __pyx
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 781, __pyx_L1_error)
+    __PYX_ERR(0, 841, __pyx_L1_error)
   }
-  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 781, __pyx_L1_error)
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_5->LabeledCheckSum()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 781, __pyx_L1_error)
+  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 841, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_5->LabeledCheckSum()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 841, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((PyObject*)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":775
+  /* "pywrapfst.pyx":835
  *     return self._raw_ptr_or_raise().GetNthKey(pos)
  * 
  *   cpdef bytes labeled_checksum(self):             # <<<<<<<<<<<<<<
@@ -9710,7 +10010,7 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum(struct __pyx
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.labeled_checksum", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.labeled_checksum", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -9719,26 +10019,29 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum(struct __pyx
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_17labeled_checksum(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_12_SymbolTable_16labeled_checksum[] = "\n    labeled_checksum(self)\n\n    Returns a bytestring indicating the label-dependent MD5 checksum.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_17labeled_checksum(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_17labeled_checksum(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_15SymbolTableView_16labeled_checksum[] = "\n    labeled_checksum(self)\n\n    Returns a bytestring indicating the label-dependent MD5 checksum.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_17labeled_checksum(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("labeled_checksum (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_16labeled_checksum(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_15SymbolTableView_16labeled_checksum(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_16labeled_checksum(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_16labeled_checksum(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("labeled_checksum", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 775, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_labeled_checksum(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 835, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -9747,7 +10050,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_16labeled_checksum(struct __
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.labeled_checksum", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.labeled_checksum", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -9755,7 +10058,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_16labeled_checksum(struct __
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":783
+/* "pywrapfst.pyx":843
  *     return self._raw_ptr_or_raise().LabeledCheckSum()
  * 
  *   cpdef bool member(self, key) except *:             # <<<<<<<<<<<<<<
@@ -9763,9 +10066,9 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_16labeled_checksum(struct __
  *     member(self, key)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_19member(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/
-static bool __pyx_f_9pywrapfst_12_SymbolTable_member(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key, int __pyx_skip_dispatch) {
-  __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_v_raw;
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_19member(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/
+static bool __pyx_f_9pywrapfst_15SymbolTableView_member(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, PyObject *__pyx_v_key, int __pyx_skip_dispatch) {
+  __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_v__raw;
   bool __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -9780,6 +10083,9 @@ static bool __pyx_f_9pywrapfst_12_SymbolTable_member(struct __pyx_obj_9pywrapfst
   std::string __pyx_t_10;
   int __pyx_t_11;
   int64 __pyx_t_12;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("member", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -9790,9 +10096,9 @@ static bool __pyx_f_9pywrapfst_12_SymbolTable_member(struct __pyx_obj_9pywrapfst
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_member); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 783, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_member); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 843, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12_SymbolTable_19member)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_19member)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -9806,10 +10112,10 @@ static bool __pyx_f_9pywrapfst_12_SymbolTable_member(struct __pyx_obj_9pywrapfst
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_key) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_key);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 783, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 843, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 783, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 843, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -9828,26 +10134,26 @@ static bool __pyx_f_9pywrapfst_12_SymbolTable_member(struct __pyx_obj_9pywrapfst
     #endif
   }
 
-  /* "pywrapfst.pyx":799
+  /* "pywrapfst.pyx":859
  *       Whether or not the key is present (as a string or a index) in the table.
  *     """
- *     cdef const_SymbolTable_ptr raw = self._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
+ *     cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
  *     try:
- *       return raw.MemberSymbol(tostring(key))
+ *       return _raw.MemberSymbol(tostring(key))
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 799, __pyx_L1_error)
+    __PYX_ERR(0, 859, __pyx_L1_error)
   }
-  __pyx_t_6 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 799, __pyx_L1_error)
-  __pyx_v_raw = __pyx_t_6;
+  __pyx_t_6 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 859, __pyx_L1_error)
+  __pyx_v__raw = __pyx_t_6;
 
-  /* "pywrapfst.pyx":800
+  /* "pywrapfst.pyx":860
  *     """
- *     cdef const_SymbolTable_ptr raw = self._raw_ptr_or_raise()
+ *     cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()
  *     try:             # <<<<<<<<<<<<<<
- *       return raw.MemberSymbol(tostring(key))
- *     except FstArgError:
+ *       return _raw.MemberSymbol(tostring(key))
+ *     except TypeError:
  */
   {
     __Pyx_PyThreadState_declare
@@ -9858,23 +10164,23 @@ static bool __pyx_f_9pywrapfst_12_SymbolTable_member(struct __pyx_obj_9pywrapfst
     __Pyx_XGOTREF(__pyx_t_9);
     /*try:*/ {
 
-      /* "pywrapfst.pyx":801
- *     cdef const_SymbolTable_ptr raw = self._raw_ptr_or_raise()
+      /* "pywrapfst.pyx":861
+ *     cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()
  *     try:
- *       return raw.MemberSymbol(tostring(key))             # <<<<<<<<<<<<<<
- *     except FstArgError:
- *       return raw.MemberIndex(key)
+ *       return _raw.MemberSymbol(tostring(key))             # <<<<<<<<<<<<<<
+ *     except TypeError:
+ *       return _raw.MemberIndex(key)
  */
-      __pyx_t_10 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 801, __pyx_L3_error)
-      __pyx_r = __pyx_v_raw->Member(__pyx_t_10);
+      __pyx_t_10 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 861, __pyx_L3_error)
+      __pyx_r = __pyx_v__raw->Member(__pyx_t_10);
       goto __pyx_L7_try_return;
 
-      /* "pywrapfst.pyx":800
+      /* "pywrapfst.pyx":860
  *     """
- *     cdef const_SymbolTable_ptr raw = self._raw_ptr_or_raise()
+ *     cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()
  *     try:             # <<<<<<<<<<<<<<
- *       return raw.MemberSymbol(tostring(key))
- *     except FstArgError:
+ *       return _raw.MemberSymbol(tostring(key))
+ *     except TypeError:
  */
     }
     __pyx_L3_error:;
@@ -9883,36 +10189,30 @@ static bool __pyx_f_9pywrapfst_12_SymbolTable_member(struct __pyx_obj_9pywrapfst
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "pywrapfst.pyx":802
+    /* "pywrapfst.pyx":862
  *     try:
- *       return raw.MemberSymbol(tostring(key))
- *     except FstArgError:             # <<<<<<<<<<<<<<
- *       return raw.MemberIndex(key)
+ *       return _raw.MemberSymbol(tostring(key))
+ *     except TypeError:             # <<<<<<<<<<<<<<
+ *       return _raw.MemberIndex(key)
  * 
  */
-    __Pyx_ErrFetch(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3);
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 802, __pyx_L5_except_error)
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_11 = __Pyx_PyErr_GivenExceptionMatches(__pyx_t_1, __pyx_t_4);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_ErrRestore(__pyx_t_1, __pyx_t_2, __pyx_t_3);
-    __pyx_t_1 = 0; __pyx_t_2 = 0; __pyx_t_3 = 0;
+    __pyx_t_11 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_TypeError);
     if (__pyx_t_11) {
-      __Pyx_AddTraceback("pywrapfst._SymbolTable.member", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_3, &__pyx_t_2, &__pyx_t_1) < 0) __PYX_ERR(0, 802, __pyx_L5_except_error)
-      __Pyx_GOTREF(__pyx_t_3);
-      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_AddTraceback("pywrapfst.SymbolTableView.member", __pyx_clineno, __pyx_lineno, __pyx_filename);
+      if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3) < 0) __PYX_ERR(0, 862, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_GOTREF(__pyx_t_3);
 
-      /* "pywrapfst.pyx":803
- *       return raw.MemberSymbol(tostring(key))
- *     except FstArgError:
- *       return raw.MemberIndex(key)             # <<<<<<<<<<<<<<
+      /* "pywrapfst.pyx":863
+ *       return _raw.MemberSymbol(tostring(key))
+ *     except TypeError:
+ *       return _raw.MemberIndex(key)             # <<<<<<<<<<<<<<
  * 
- *   def __contains__(self, key):
+ *   cpdef string name(self) except *:
  */
-      __pyx_t_12 = __Pyx_PyInt_As_int64_t(__pyx_v_key); if (unlikely((__pyx_t_12 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 803, __pyx_L5_except_error)
-      __pyx_r = __pyx_v_raw->Member(__pyx_t_12);
+      __pyx_t_12 = __Pyx_PyInt_As_int64_t(__pyx_v_key); if (unlikely((__pyx_t_12 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 863, __pyx_L5_except_error)
+      __pyx_r = __pyx_v__raw->Member(__pyx_t_12);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -9921,12 +10221,12 @@ static bool __pyx_f_9pywrapfst_12_SymbolTable_member(struct __pyx_obj_9pywrapfst
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "pywrapfst.pyx":800
+    /* "pywrapfst.pyx":860
  *     """
- *     cdef const_SymbolTable_ptr raw = self._raw_ptr_or_raise()
+ *     cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()
  *     try:             # <<<<<<<<<<<<<<
- *       return raw.MemberSymbol(tostring(key))
- *     except FstArgError:
+ *       return _raw.MemberSymbol(tostring(key))
+ *     except TypeError:
  */
     __Pyx_XGIVEREF(__pyx_t_7);
     __Pyx_XGIVEREF(__pyx_t_8);
@@ -9947,7 +10247,7 @@ static bool __pyx_f_9pywrapfst_12_SymbolTable_member(struct __pyx_obj_9pywrapfst
     goto __pyx_L0;
   }
 
-  /* "pywrapfst.pyx":783
+  /* "pywrapfst.pyx":843
  *     return self._raw_ptr_or_raise().LabeledCheckSum()
  * 
  *   cpdef bool member(self, key) except *:             # <<<<<<<<<<<<<<
@@ -9961,7 +10261,7 @@ static bool __pyx_f_9pywrapfst_12_SymbolTable_member(struct __pyx_obj_9pywrapfst
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.member", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.member", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -9969,28 +10269,31 @@ static bool __pyx_f_9pywrapfst_12_SymbolTable_member(struct __pyx_obj_9pywrapfst
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_19member(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/
-static char __pyx_doc_9pywrapfst_12_SymbolTable_18member[] = "\n    member(self, key)\n\n    Given a symbol or index, returns whether it is found in the table.\n\n    This method returns a boolean indicating whether the given symbol or index\n    is present in the table. If one intends to perform subsequent lookup, it is\n    better to simply call the find method, catching the KeyError.\n\n    Args:\n      key: Either a string or an index.\n\n    Returns:\n      Whether or not the key is present (as a string or a index) in the table.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_19member(PyObject *__pyx_v_self, PyObject *__pyx_v_key) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_19member(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/
+static char __pyx_doc_9pywrapfst_15SymbolTableView_18member[] = "\n    member(self, key)\n\n    Given a symbol or index, returns whether it is found in the table.\n\n    This method returns a boolean indicating whether the given symbol or index\n    is present in the table. If one intends to perform subsequent lookup, it is\n    better to simply call the find method, catching the KeyError.\n\n    Args:\n      key: Either a string or an index.\n\n    Returns:\n      Whether or not the key is present (as a string or a index) in the table.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_19member(PyObject *__pyx_v_self, PyObject *__pyx_v_key) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("member (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_18member(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), ((PyObject *)__pyx_v_key));
+  __pyx_r = __pyx_pf_9pywrapfst_15SymbolTableView_18member(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self), ((PyObject *)__pyx_v_key));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_18member(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key) {
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_18member(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, PyObject *__pyx_v_key) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   bool __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("member", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_12_SymbolTable_member(__pyx_v_self, __pyx_v_key, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 783, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 783, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_member(__pyx_v_self, __pyx_v_key, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 843, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 843, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -9999,7 +10302,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_18member(struct __pyx_obj_9p
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.member", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.member", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -10007,75 +10310,16 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_18member(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":805
- *       return raw.MemberIndex(key)
- * 
- *   def __contains__(self, key):             # <<<<<<<<<<<<<<
- *     return self.member(key)
- * 
- */
-
-/* Python wrapper */
-static int __pyx_pw_9pywrapfst_12_SymbolTable_21__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/
-static int __pyx_pw_9pywrapfst_12_SymbolTable_21__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_key) {
-  int __pyx_r;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__contains__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_20__contains__(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), ((PyObject *)__pyx_v_key));
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static int __pyx_pf_9pywrapfst_12_SymbolTable_20__contains__(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_key) {
-  int __pyx_r;
-  __Pyx_RefNannyDeclarations
-  bool __pyx_t_1;
-  __Pyx_RefNannySetupContext("__contains__", 0);
-
-  /* "pywrapfst.pyx":806
- * 
- *   def __contains__(self, key):
- *     return self.member(key)             # <<<<<<<<<<<<<<
- * 
- *   cpdef string name(self) except *:
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "member");
-    __PYX_ERR(0, 806, __pyx_L1_error)
-  }
-  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->__pyx_vtab)->member(__pyx_v_self, __pyx_v_key, 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 806, __pyx_L1_error)
-  __pyx_r = __pyx_t_1;
-  goto __pyx_L0;
-
-  /* "pywrapfst.pyx":805
- *       return raw.MemberIndex(key)
- * 
- *   def __contains__(self, key):             # <<<<<<<<<<<<<<
- *     return self.member(key)
- * 
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.__contains__", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = -1;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pywrapfst.pyx":808
- *     return self.member(key)
+/* "pywrapfst.pyx":865
+ *       return _raw.MemberIndex(key)
  * 
  *   cpdef string name(self) except *:             # <<<<<<<<<<<<<<
  *     """
  *     name(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_23name(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static std::string __pyx_f_9pywrapfst_12_SymbolTable_name(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_21name(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static std::string __pyx_f_9pywrapfst_15SymbolTableView_name(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, int __pyx_skip_dispatch) {
   std::string __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -10084,6 +10328,9 @@ static std::string __pyx_f_9pywrapfst_12_SymbolTable_name(struct __pyx_obj_9pywr
   PyObject *__pyx_t_4 = NULL;
   std::string __pyx_t_5;
   fst::SymbolTable const *__pyx_t_6;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("name", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -10094,9 +10341,9 @@ static std::string __pyx_f_9pywrapfst_12_SymbolTable_name(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 808, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 865, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12_SymbolTable_23name)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_21name)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -10110,10 +10357,10 @@ static std::string __pyx_f_9pywrapfst_12_SymbolTable_name(struct __pyx_obj_9pywr
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 808, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 865, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 808, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 865, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -10132,7 +10379,7 @@ static std::string __pyx_f_9pywrapfst_12_SymbolTable_name(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":814
+  /* "pywrapfst.pyx":871
  *     Returns the symbol table's name.
  *     """
  *     return self._raw_ptr_or_raise().Name()             # <<<<<<<<<<<<<<
@@ -10141,14 +10388,14 @@ static std::string __pyx_f_9pywrapfst_12_SymbolTable_name(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 814, __pyx_L1_error)
+    __PYX_ERR(0, 871, __pyx_L1_error)
   }
-  __pyx_t_6 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 814, __pyx_L1_error)
+  __pyx_t_6 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 871, __pyx_L1_error)
   __pyx_r = __pyx_t_6->Name();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":808
- *     return self.member(key)
+  /* "pywrapfst.pyx":865
+ *       return _raw.MemberIndex(key)
  * 
  *   cpdef string name(self) except *:             # <<<<<<<<<<<<<<
  *     """
@@ -10161,7 +10408,7 @@ static std::string __pyx_f_9pywrapfst_12_SymbolTable_name(struct __pyx_obj_9pywr
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.name", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.name", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_pretend_to_initialize(&__pyx_r);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -10169,28 +10416,31 @@ static std::string __pyx_f_9pywrapfst_12_SymbolTable_name(struct __pyx_obj_9pywr
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_23name(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_12_SymbolTable_22name[] = "\n    name(self)\n\n    Returns the symbol table's name.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_23name(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_21name(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_15SymbolTableView_20name[] = "\n    name(self)\n\n    Returns the symbol table's name.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_21name(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("name (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_22name(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_15SymbolTableView_20name(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_22name(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_20name(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("name", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_12_SymbolTable_name(__pyx_v_self, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 808, __pyx_L1_error)
-  __pyx_t_2 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 808, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_name(__pyx_v_self, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 865, __pyx_L1_error)
+  __pyx_t_2 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 865, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -10199,7 +10449,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_22name(struct __pyx_obj_9pyw
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.name", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.name", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -10207,7 +10457,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_22name(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":816
+/* "pywrapfst.pyx":873
  *     return self._raw_ptr_or_raise().Name()
  * 
  *   cpdef size_t num_symbols(self) except *:             # <<<<<<<<<<<<<<
@@ -10215,8 +10465,8 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_22name(struct __pyx_obj_9pyw
  *     num_symbols(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_25num_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static size_t __pyx_f_9pywrapfst_12_SymbolTable_num_symbols(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_23num_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static size_t __pyx_f_9pywrapfst_15SymbolTableView_num_symbols(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, int __pyx_skip_dispatch) {
   size_t __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -10225,6 +10475,9 @@ static size_t __pyx_f_9pywrapfst_12_SymbolTable_num_symbols(struct __pyx_obj_9py
   PyObject *__pyx_t_4 = NULL;
   size_t __pyx_t_5;
   fst::SymbolTable const *__pyx_t_6;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("num_symbols", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -10235,9 +10488,9 @@ static size_t __pyx_f_9pywrapfst_12_SymbolTable_num_symbols(struct __pyx_obj_9py
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 816, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 873, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12_SymbolTable_25num_symbols)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_23num_symbols)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -10251,10 +10504,10 @@ static size_t __pyx_f_9pywrapfst_12_SymbolTable_num_symbols(struct __pyx_obj_9py
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 816, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 873, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_5 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 816, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_5 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 873, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -10273,7 +10526,7 @@ static size_t __pyx_f_9pywrapfst_12_SymbolTable_num_symbols(struct __pyx_obj_9py
     #endif
   }
 
-  /* "pywrapfst.pyx":822
+  /* "pywrapfst.pyx":879
  *     Returns the number of symbols in the symbol table.
  *     """
  *     return self._raw_ptr_or_raise().NumSymbols()             # <<<<<<<<<<<<<<
@@ -10282,13 +10535,13 @@ static size_t __pyx_f_9pywrapfst_12_SymbolTable_num_symbols(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 822, __pyx_L1_error)
+    __PYX_ERR(0, 879, __pyx_L1_error)
   }
-  __pyx_t_6 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 822, __pyx_L1_error)
+  __pyx_t_6 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 879, __pyx_L1_error)
   __pyx_r = __pyx_t_6->NumSymbols();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":816
+  /* "pywrapfst.pyx":873
  *     return self._raw_ptr_or_raise().Name()
  * 
  *   cpdef size_t num_symbols(self) except *:             # <<<<<<<<<<<<<<
@@ -10302,7 +10555,7 @@ static size_t __pyx_f_9pywrapfst_12_SymbolTable_num_symbols(struct __pyx_obj_9py
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.num_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.num_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -10310,28 +10563,31 @@ static size_t __pyx_f_9pywrapfst_12_SymbolTable_num_symbols(struct __pyx_obj_9py
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_25num_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_12_SymbolTable_24num_symbols[] = "\n    num_symbols(self)\n\n    Returns the number of symbols in the symbol table.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_25num_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_23num_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_15SymbolTableView_22num_symbols[] = "\n    num_symbols(self)\n\n    Returns the number of symbols in the symbol table.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_23num_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("num_symbols (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_24num_symbols(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_15SymbolTableView_22num_symbols(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_24num_symbols(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_22num_symbols(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   size_t __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("num_symbols", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_12_SymbolTable_num_symbols(__pyx_v_self, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 816, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 816, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_num_symbols(__pyx_v_self, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 873, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 873, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -10340,7 +10596,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_24num_symbols(struct __pyx_o
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.num_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.num_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -10348,7 +10604,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_24num_symbols(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":824
+/* "pywrapfst.pyx":881
  *     return self._raw_ptr_or_raise().NumSymbols()
  * 
  *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
@@ -10356,8 +10612,8 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_24num_symbols(struct __pyx_o
  *     write(self, source)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_27write(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
-static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_25write(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
+static void __pyx_f_9pywrapfst_15SymbolTableView_write(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -10366,7 +10622,9 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
   fst::SymbolTable const *__pyx_t_5;
   std::string __pyx_t_6;
   int __pyx_t_7;
-  PyObject *__pyx_t_8 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -10377,9 +10635,9 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 824, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 881, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12_SymbolTable_27write)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_25write)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -10393,7 +10651,7 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_source);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 824, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 881, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -10413,78 +10671,66 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":838
+  /* "pywrapfst.pyx":895
  *       FstIOError: Write failed.
  *     """
- *     if not self._raw_ptr_or_raise().Write(tostring(source)):             # <<<<<<<<<<<<<<
- *       raise FstIOError("Write failed: {!r}".format(source))
+ *     if not self._raw_ptr_or_raise().Write(path_tostring(source)):             # <<<<<<<<<<<<<<
+ *       raise FstIOError(f"Write failed: {source!r}")
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 838, __pyx_L1_error)
+    __PYX_ERR(0, 895, __pyx_L1_error)
   }
-  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 838, __pyx_L1_error)
-  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 838, __pyx_L1_error)
+  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 895, __pyx_L1_error)
+  __pyx_t_6 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 895, __pyx_L1_error)
   __pyx_t_7 = ((!(__pyx_t_5->Write(__pyx_t_6) != 0)) != 0);
   if (unlikely(__pyx_t_7)) {
 
-    /* "pywrapfst.pyx":839
+    /* "pywrapfst.pyx":896
  *     """
- *     if not self._raw_ptr_or_raise().Write(tostring(source)):
- *       raise FstIOError("Write failed: {!r}".format(source))             # <<<<<<<<<<<<<<
+ *     if not self._raw_ptr_or_raise().Write(path_tostring(source)):
+ *       raise FstIOError(f"Write failed: {source!r}")             # <<<<<<<<<<<<<<
  * 
  *   cpdef void write_text(self, source) except *:
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 839, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 896, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Write_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 839, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_8 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) {
-      __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_4);
-      if (likely(__pyx_t_8)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-        __Pyx_INCREF(__pyx_t_8);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_4, function);
-      }
-    }
-    __pyx_t_3 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_8, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_source);
-    __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 839, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 896, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = NULL;
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Write_failed, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 896, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
-      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
-      if (likely(__pyx_t_4)) {
+      __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+      if (likely(__pyx_t_3)) {
         PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-        __Pyx_INCREF(__pyx_t_4);
+        __Pyx_INCREF(__pyx_t_3);
         __Pyx_INCREF(function);
         __Pyx_DECREF_SET(__pyx_t_2, function);
       }
     }
-    __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
-    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 839, __pyx_L1_error)
+    __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4);
+    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 896, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 839, __pyx_L1_error)
+    __PYX_ERR(0, 896, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":838
+    /* "pywrapfst.pyx":895
  *       FstIOError: Write failed.
  *     """
- *     if not self._raw_ptr_or_raise().Write(tostring(source)):             # <<<<<<<<<<<<<<
- *       raise FstIOError("Write failed: {!r}".format(source))
+ *     if not self._raw_ptr_or_raise().Write(path_tostring(source)):             # <<<<<<<<<<<<<<
+ *       raise FstIOError(f"Write failed: {source!r}")
  * 
  */
   }
 
-  /* "pywrapfst.pyx":824
+  /* "pywrapfst.pyx":881
  *     return self._raw_ptr_or_raise().NumSymbols()
  * 
  *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
@@ -10499,34 +10745,36 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write(struct __pyx_obj_9pywrapfst_
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_8);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.write", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.write", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_27write(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
-static char __pyx_doc_9pywrapfst_12_SymbolTable_26write[] = "\n    write(self, source)\n\n    Serializes symbol table to a file.\n\n    This methods writes the SymbolTable to a file in binary format.\n\n    Args:\n      source: The string location of the output file.\n\n    Raises:\n      FstIOError: Write failed.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_27write(PyObject *__pyx_v_self, PyObject *__pyx_v_source) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_25write(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
+static char __pyx_doc_9pywrapfst_15SymbolTableView_24write[] = "\n    write(self, source)\n\n    Serializes symbol table to a file.\n\n    This methods writes the SymbolTable to a file in binary format.\n\n    Args:\n      source: The string location of the output file.\n\n    Raises:\n      FstIOError: Write failed.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_25write(PyObject *__pyx_v_self, PyObject *__pyx_v_source) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("write (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_26write(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), ((PyObject *)__pyx_v_source));
+  __pyx_r = __pyx_pf_9pywrapfst_15SymbolTableView_24write(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self), ((PyObject *)__pyx_v_source));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_26write(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_source) {
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_24write(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, PyObject *__pyx_v_source) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_12_SymbolTable_write(__pyx_v_self, __pyx_v_source, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 824, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 824, __pyx_L1_error)
+  __pyx_f_9pywrapfst_15SymbolTableView_write(__pyx_v_self, __pyx_v_source, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 881, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 881, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -10535,7 +10783,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_26write(struct __pyx_obj_9py
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.write", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.write", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -10543,16 +10791,16 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_26write(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":841
- *       raise FstIOError("Write failed: {!r}".format(source))
+/* "pywrapfst.pyx":898
+ *       raise FstIOError(f"Write failed: {source!r}")
  * 
  *   cpdef void write_text(self, source) except *:             # <<<<<<<<<<<<<<
  *     """
  *     write_text(self, source)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_29write_text(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
-static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_27write_text(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
+static void __pyx_f_9pywrapfst_15SymbolTableView_write_text(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -10561,7 +10809,9 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
   fst::SymbolTable const *__pyx_t_5;
   std::string __pyx_t_6;
   int __pyx_t_7;
-  PyObject *__pyx_t_8 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write_text", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -10572,9 +10822,9 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_text); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 841, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_text); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 898, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12_SymbolTable_29write_text)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_27write_text)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -10588,7 +10838,7 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_source);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 841, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 898, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -10608,79 +10858,67 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":855
+  /* "pywrapfst.pyx":912
  *       FstIOError: Write failed.
  *     """
- *     if not self._raw_ptr_or_raise().WriteText(tostring(source)):             # <<<<<<<<<<<<<<
- *       raise FstIOError("Write failed: {!r}".format(source))
+ *     if not self._raw_ptr_or_raise().WriteText(path_tostring(source)):             # <<<<<<<<<<<<<<
+ *       raise FstIOError(f"Write failed: {source!r}")
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 855, __pyx_L1_error)
+    __PYX_ERR(0, 912, __pyx_L1_error)
   }
-  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 855, __pyx_L1_error)
-  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 855, __pyx_L1_error)
+  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 912, __pyx_L1_error)
+  __pyx_t_6 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 912, __pyx_L1_error)
   __pyx_t_7 = ((!(__pyx_t_5->WriteText(__pyx_t_6) != 0)) != 0);
   if (unlikely(__pyx_t_7)) {
 
-    /* "pywrapfst.pyx":856
+    /* "pywrapfst.pyx":913
  *     """
- *     if not self._raw_ptr_or_raise().WriteText(tostring(source)):
- *       raise FstIOError("Write failed: {!r}".format(source))             # <<<<<<<<<<<<<<
+ *     if not self._raw_ptr_or_raise().WriteText(path_tostring(source)):
+ *       raise FstIOError(f"Write failed: {source!r}")             # <<<<<<<<<<<<<<
  * 
  *   cpdef bytes write_to_string(self):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 856, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 913, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Write_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 856, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_8 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) {
-      __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_4);
-      if (likely(__pyx_t_8)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-        __Pyx_INCREF(__pyx_t_8);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_4, function);
-      }
-    }
-    __pyx_t_3 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_8, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_source);
-    __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 856, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 913, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = NULL;
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Write_failed, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 913, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
-      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
-      if (likely(__pyx_t_4)) {
+      __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+      if (likely(__pyx_t_3)) {
         PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-        __Pyx_INCREF(__pyx_t_4);
+        __Pyx_INCREF(__pyx_t_3);
         __Pyx_INCREF(function);
         __Pyx_DECREF_SET(__pyx_t_2, function);
       }
     }
-    __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
-    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 856, __pyx_L1_error)
+    __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4);
+    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 913, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 856, __pyx_L1_error)
+    __PYX_ERR(0, 913, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":855
+    /* "pywrapfst.pyx":912
  *       FstIOError: Write failed.
  *     """
- *     if not self._raw_ptr_or_raise().WriteText(tostring(source)):             # <<<<<<<<<<<<<<
- *       raise FstIOError("Write failed: {!r}".format(source))
+ *     if not self._raw_ptr_or_raise().WriteText(path_tostring(source)):             # <<<<<<<<<<<<<<
+ *       raise FstIOError(f"Write failed: {source!r}")
  * 
  */
   }
 
-  /* "pywrapfst.pyx":841
- *       raise FstIOError("Write failed: {!r}".format(source))
+  /* "pywrapfst.pyx":898
+ *       raise FstIOError(f"Write failed: {source!r}")
  * 
  *   cpdef void write_text(self, source) except *:             # <<<<<<<<<<<<<<
  *     """
@@ -10694,34 +10932,36 @@ static void __pyx_f_9pywrapfst_12_SymbolTable_write_text(struct __pyx_obj_9pywra
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_8);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.write_text", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.write_text", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_29write_text(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
-static char __pyx_doc_9pywrapfst_12_SymbolTable_28write_text[] = "\n    write_text(self, source)\n\n    Writes symbol table to text file.\n\n    This method writes the SymbolTable to a file in human-readable format.\n\n    Args:\n      source: The string location of the output file.\n\n    Raises:\n      FstIOError: Write failed.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_29write_text(PyObject *__pyx_v_self, PyObject *__pyx_v_source) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_27write_text(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
+static char __pyx_doc_9pywrapfst_15SymbolTableView_26write_text[] = "\n    write_text(self, source)\n\n    Writes symbol table to text file.\n\n    This method writes the SymbolTable to a file in human-readable format.\n\n    Args:\n      source: The string location of the output file.\n\n    Raises:\n      FstIOError: Write failed.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_27write_text(PyObject *__pyx_v_self, PyObject *__pyx_v_source) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("write_text (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_28write_text(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), ((PyObject *)__pyx_v_source));
+  __pyx_r = __pyx_pf_9pywrapfst_15SymbolTableView_26write_text(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self), ((PyObject *)__pyx_v_source));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_28write_text(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, PyObject *__pyx_v_source) {
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_26write_text(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, PyObject *__pyx_v_source) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write_text", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_12_SymbolTable_write_text(__pyx_v_self, __pyx_v_source, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 841, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 841, __pyx_L1_error)
+  __pyx_f_9pywrapfst_15SymbolTableView_write_text(__pyx_v_self, __pyx_v_source, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 898, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 898, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -10730,7 +10970,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_28write_text(struct __pyx_ob
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.write_text", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.write_text", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -10738,17 +10978,17 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_28write_text(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":858
- *       raise FstIOError("Write failed: {!r}".format(source))
+/* "pywrapfst.pyx":915
+ *       raise FstIOError(f"Write failed: {source!r}")
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
  *     """
  *     write_to_string(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_31write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_write_to_string(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self, int __pyx_skip_dispatch) {
-  std::stringstream __pyx_v_sstrm;
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_29write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_f_9pywrapfst_15SymbolTableView_write_to_string(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self, int __pyx_skip_dispatch) {
+  std::stringstream __pyx_v__sstrm;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -10757,6 +10997,9 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_write_to_string(struct __pyx_
   PyObject *__pyx_t_4 = NULL;
   fst::SymbolTable const *__pyx_t_5;
   int __pyx_t_6;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write_to_string", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -10767,9 +11010,9 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_write_to_string(struct __pyx_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 858, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 915, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12_SymbolTable_31write_to_string)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_15SymbolTableView_29write_to_string)) {
         __Pyx_XDECREF(__pyx_r);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
@@ -10784,10 +11027,10 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_write_to_string(struct __pyx_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 858, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 915, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 858, __pyx_L1_error)
+        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 915, __pyx_L1_error)
         __pyx_r = ((PyObject*)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -10806,29 +11049,29 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_write_to_string(struct __pyx_
     #endif
   }
 
-  /* "pywrapfst.pyx":871
+  /* "pywrapfst.pyx":928
  *     """
- *     cdef stringstream sstrm
- *     if not self._raw_ptr_or_raise().Write(sstrm):             # <<<<<<<<<<<<<<
+ *     cdef stringstream _sstrm
+ *     if not self._raw_ptr_or_raise().Write(_sstrm):             # <<<<<<<<<<<<<<
  *       raise FstIOError("Write to string failed")
- *     return sstrm.str()
+ *     return _sstrm.str()
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 871, __pyx_L1_error)
+    __PYX_ERR(0, 928, __pyx_L1_error)
   }
-  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 871, __pyx_L1_error)
-  __pyx_t_6 = ((!(__pyx_t_5->Write(__pyx_v_sstrm) != 0)) != 0);
+  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 928, __pyx_L1_error)
+  __pyx_t_6 = ((!(__pyx_t_5->Write(__pyx_v__sstrm) != 0)) != 0);
   if (unlikely(__pyx_t_6)) {
 
-    /* "pywrapfst.pyx":872
- *     cdef stringstream sstrm
- *     if not self._raw_ptr_or_raise().Write(sstrm):
+    /* "pywrapfst.pyx":929
+ *     cdef stringstream _sstrm
+ *     if not self._raw_ptr_or_raise().Write(_sstrm):
  *       raise FstIOError("Write to string failed")             # <<<<<<<<<<<<<<
- *     return sstrm.str()
+ *     return _sstrm.str()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 872, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 929, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -10842,38 +11085,38 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_write_to_string(struct __pyx_
     }
     __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_kp_u_Write_to_string_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_Write_to_string_failed);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 872, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 929, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 872, __pyx_L1_error)
+    __PYX_ERR(0, 929, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":871
+    /* "pywrapfst.pyx":928
  *     """
- *     cdef stringstream sstrm
- *     if not self._raw_ptr_or_raise().Write(sstrm):             # <<<<<<<<<<<<<<
+ *     cdef stringstream _sstrm
+ *     if not self._raw_ptr_or_raise().Write(_sstrm):             # <<<<<<<<<<<<<<
  *       raise FstIOError("Write to string failed")
- *     return sstrm.str()
+ *     return _sstrm.str()
  */
   }
 
-  /* "pywrapfst.pyx":873
- *     if not self._raw_ptr_or_raise().Write(sstrm):
+  /* "pywrapfst.pyx":930
+ *     if not self._raw_ptr_or_raise().Write(_sstrm):
  *       raise FstIOError("Write to string failed")
- *     return sstrm.str()             # <<<<<<<<<<<<<<
+ *     return _sstrm.str()             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_sstrm.str()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 873, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v__sstrm.str()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 930, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((PyObject*)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":858
- *       raise FstIOError("Write failed: {!r}".format(source))
+  /* "pywrapfst.pyx":915
+ *       raise FstIOError(f"Write failed: {source!r}")
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
  *     """
@@ -10886,7 +11129,7 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_write_to_string(struct __pyx_
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.write_to_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.write_to_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -10895,26 +11138,29 @@ static PyObject *__pyx_f_9pywrapfst_12_SymbolTable_write_to_string(struct __pyx_
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_31write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_12_SymbolTable_30write_to_string[] = "\n    write_to_string(self)\n\n    Serializes SymbolTable to a string.\n\n    Returns:\n      A bytestring.\n\n    Raises:\n      FstIOError: Write to string failed.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_12_SymbolTable_31write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_29write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_15SymbolTableView_28write_to_string[] = "\n    write_to_string(self)\n\n    Serializes SymbolTable to a string.\n\n    Returns:\n      A bytestring.\n\n    Raises:\n      FstIOError: Write to string failed.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_15SymbolTableView_29write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("write_to_string (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_12_SymbolTable_30write_to_string(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_15SymbolTableView_28write_to_string(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_30write_to_string(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_15SymbolTableView_28write_to_string(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write_to_string", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_12_SymbolTable_write_to_string(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 858, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_15SymbolTableView_write_to_string(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 915, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -10923,7 +11169,7 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_30write_to_string(struct __p
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst._SymbolTable.write_to_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pywrapfst.SymbolTableView.write_to_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -10931,12 +11177,12 @@ static PyObject *__pyx_pf_9pywrapfst_12_SymbolTable_30write_to_string(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":891
+/* "pywrapfst.pyx":948
  *   # Doing so will allow undefined behavior.
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<const EncodeMapper SymbolTableView {!r} at 0x{:x}>".format(
- *       self.name(), id(self))
+ *     return (f"<const EncodeMapper SymbolTableView {self.name()!r} "
+ *             f"at 0x{id(self):x}>")
  */
 
 /* Python wrapper */
@@ -10956,111 +11202,101 @@ static PyObject *__pyx_pf_9pywrapfst_28_EncodeMapperSymbolTableView___repr__(str
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  std::string __pyx_t_3;
-  PyObject *__pyx_t_4 = NULL;
+  Py_ssize_t __pyx_t_2;
+  Py_UCS4 __pyx_t_3;
+  std::string __pyx_t_4;
   PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
-  int __pyx_t_7;
-  PyObject *__pyx_t_8 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":892
+  /* "pywrapfst.pyx":949
  * 
  *   def __repr__(self):
- *     return "<const EncodeMapper SymbolTableView {!r} at 0x{:x}>".format(             # <<<<<<<<<<<<<<
- *       self.name(), id(self))
+ *     return (f"<const EncodeMapper SymbolTableView {self.name()!r} "             # <<<<<<<<<<<<<<
+ *             f"at 0x{id(self):x}>")
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_const_EncodeMapper_SymbolTableV, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 892, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 949, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 127;
+  __Pyx_INCREF(__pyx_kp_u_const_EncodeMapper_SymbolTableV);
+  __pyx_t_2 += 36;
+  __Pyx_GIVEREF(__pyx_kp_u_const_EncodeMapper_SymbolTableV);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_const_EncodeMapper_SymbolTableV);
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "name");
+    __PYX_ERR(0, 949, __pyx_L1_error)
+  }
+  __pyx_t_4 = ((struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTableView *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.name(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self), 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 949, __pyx_L1_error)
+  __pyx_t_5 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 949, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_6 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_5), __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 949, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6);
+  __Pyx_GIVEREF(__pyx_t_6);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_6);
+  __pyx_t_6 = 0;
+  __Pyx_INCREF(__pyx_kp_u_at_0x);
+  __pyx_t_2 += 6;
+  __Pyx_GIVEREF(__pyx_kp_u_at_0x);
+  PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_at_0x);
 
-  /* "pywrapfst.pyx":893
+  /* "pywrapfst.pyx":950
  *   def __repr__(self):
- *     return "<const EncodeMapper SymbolTableView {!r} at 0x{:x}>".format(
- *       self.name(), id(self))             # <<<<<<<<<<<<<<
+ *     return (f"<const EncodeMapper SymbolTableView {self.name()!r} "
+ *             f"at 0x{id(self):x}>")             # <<<<<<<<<<<<<<
  * 
  *   cdef const_SymbolTable_ptr _raw(self):
  */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "name");
-    __PYX_ERR(0, 893, __pyx_L1_error)
-  }
-  __pyx_t_3 = ((struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTableView *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.name(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 893, __pyx_L1_error)
-  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 893, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 893, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 950, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_6, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 950, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = NULL;
-  __pyx_t_7 = 0;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
-    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_2);
-    if (likely(__pyx_t_6)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-      __Pyx_INCREF(__pyx_t_6);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_2, function);
-      __pyx_t_7 = 1;
-    }
-  }
-  #if CYTHON_FAST_PYCALL
-  if (PyFunction_Check(__pyx_t_2)) {
-    PyObject *__pyx_temp[3] = {__pyx_t_6, __pyx_t_4, __pyx_t_5};
-    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 892, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  } else
-  #endif
-  #if CYTHON_FAST_PYCCALL
-  if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
-    PyObject *__pyx_temp[3] = {__pyx_t_6, __pyx_t_4, __pyx_t_5};
-    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 892, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  } else
-  #endif
-  {
-    __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 892, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_8);
-    if (__pyx_t_6) {
-      __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
-    }
-    __Pyx_GIVEREF(__pyx_t_4);
-    PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, __pyx_t_4);
-    __Pyx_GIVEREF(__pyx_t_5);
-    PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_t_5);
-    __pyx_t_4 = 0;
-    __pyx_t_5 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 892, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-  }
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_t_5);
+  __pyx_t_5 = 0;
+  __Pyx_INCREF(__pyx_kp_u__3);
+  __pyx_t_2 += 1;
+  __Pyx_GIVEREF(__pyx_kp_u__3);
+  PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_kp_u__3);
+
+  /* "pywrapfst.pyx":949
+ * 
+ *   def __repr__(self):
+ *     return (f"<const EncodeMapper SymbolTableView {self.name()!r} "             # <<<<<<<<<<<<<<
+ *             f"at 0x{id(self):x}>")
+ * 
+ */
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 949, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":891
+  /* "pywrapfst.pyx":948
  *   # Doing so will allow undefined behavior.
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<const EncodeMapper SymbolTableView {!r} at 0x{:x}>".format(
- *       self.name(), id(self))
+ *     return (f"<const EncodeMapper SymbolTableView {self.name()!r} "
+ *             f"at 0x{id(self):x}>")
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_8);
   __Pyx_AddTraceback("pywrapfst._EncodeMapperSymbolTableView.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -11069,8 +11305,8 @@ static PyObject *__pyx_pf_9pywrapfst_28_EncodeMapperSymbolTableView___repr__(str
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":895
- *       self.name(), id(self))
+/* "pywrapfst.pyx":952
+ *             f"at 0x{id(self):x}>")
  * 
  *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
  *     return (self._mapper.get().InputSymbols() if self._input_side
@@ -11081,9 +11317,12 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_28_EncodeMapp
   __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_r;
   __Pyx_RefNannyDeclarations
   fst::SymbolTable const *__pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_raw", 0);
 
-  /* "pywrapfst.pyx":896
+  /* "pywrapfst.pyx":953
  * 
  *   cdef const_SymbolTable_ptr _raw(self):
  *     return (self._mapper.get().InputSymbols() if self._input_side             # <<<<<<<<<<<<<<
@@ -11092,17 +11331,17 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_28_EncodeMapp
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_input_side");
-    __PYX_ERR(0, 896, __pyx_L1_error)
+    __PYX_ERR(0, 953, __pyx_L1_error)
   }
   if ((__pyx_v_self->_input_side != 0)) {
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-      __PYX_ERR(0, 896, __pyx_L1_error)
+      __PYX_ERR(0, 953, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_mapper.get()->InputSymbols();
   } else {
 
-    /* "pywrapfst.pyx":897
+    /* "pywrapfst.pyx":954
  *   cdef const_SymbolTable_ptr _raw(self):
  *     return (self._mapper.get().InputSymbols() if self._input_side
  *             else self._mapper.get().OutputSymbols())             # <<<<<<<<<<<<<<
@@ -11111,15 +11350,15 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_28_EncodeMapp
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-      __PYX_ERR(0, 897, __pyx_L1_error)
+      __PYX_ERR(0, 954, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_mapper.get()->OutputSymbols();
   }
   __pyx_r = __pyx_t_1;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":895
- *       self.name(), id(self))
+  /* "pywrapfst.pyx":952
+ *             f"at 0x{id(self):x}>")
  * 
  *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
  *     return (self._mapper.get().InputSymbols() if self._input_side
@@ -11135,12 +11374,12 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_28_EncodeMapp
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":914
+/* "pywrapfst.pyx":971
  *   # Doing so will allow undefined behavior.
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<const Fst SymbolTableView {!r} at 0x{:x}>".format(self.name(),
- *                                                                id(self))
+ *     return (f"<const Fst SymbolTableView {self.name()!r} "
+ *             f"at 0x{id(self):x}>")
  */
 
 /* Python wrapper */
@@ -11160,111 +11399,101 @@ static PyObject *__pyx_pf_9pywrapfst_19_FstSymbolTableView___repr__(struct __pyx
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  std::string __pyx_t_3;
-  PyObject *__pyx_t_4 = NULL;
+  Py_ssize_t __pyx_t_2;
+  Py_UCS4 __pyx_t_3;
+  std::string __pyx_t_4;
   PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
-  int __pyx_t_7;
-  PyObject *__pyx_t_8 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":915
+  /* "pywrapfst.pyx":972
  * 
  *   def __repr__(self):
- *     return "<const Fst SymbolTableView {!r} at 0x{:x}>".format(self.name(),             # <<<<<<<<<<<<<<
- *                                                                id(self))
+ *     return (f"<const Fst SymbolTableView {self.name()!r} "             # <<<<<<<<<<<<<<
+ *             f"at 0x{id(self):x}>")
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_const_Fst_SymbolTableView_r_at, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 915, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 972, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 127;
+  __Pyx_INCREF(__pyx_kp_u_const_Fst_SymbolTableView);
+  __pyx_t_2 += 27;
+  __Pyx_GIVEREF(__pyx_kp_u_const_Fst_SymbolTableView);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_const_Fst_SymbolTableView);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "name");
-    __PYX_ERR(0, 915, __pyx_L1_error)
+    __PYX_ERR(0, 972, __pyx_L1_error)
   }
-  __pyx_t_3 = ((struct __pyx_vtabstruct_9pywrapfst__FstSymbolTableView *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.name(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 915, __pyx_L1_error)
-  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 915, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_4 = ((struct __pyx_vtabstruct_9pywrapfst__FstSymbolTableView *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.name(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self), 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 972, __pyx_L1_error)
+  __pyx_t_5 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 972, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __pyx_t_6 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_5), __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 972, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6);
+  __Pyx_GIVEREF(__pyx_t_6);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_6);
+  __pyx_t_6 = 0;
+  __Pyx_INCREF(__pyx_kp_u_at_0x);
+  __pyx_t_2 += 6;
+  __Pyx_GIVEREF(__pyx_kp_u_at_0x);
+  PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_at_0x);
 
-  /* "pywrapfst.pyx":916
+  /* "pywrapfst.pyx":973
  *   def __repr__(self):
- *     return "<const Fst SymbolTableView {!r} at 0x{:x}>".format(self.name(),
- *                                                                id(self))             # <<<<<<<<<<<<<<
+ *     return (f"<const Fst SymbolTableView {self.name()!r} "
+ *             f"at 0x{id(self):x}>")             # <<<<<<<<<<<<<<
  * 
  *   cdef const_SymbolTable_ptr _raw(self):
  */
-  __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 916, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 973, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_6, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 973, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = NULL;
-  __pyx_t_7 = 0;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
-    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_2);
-    if (likely(__pyx_t_6)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-      __Pyx_INCREF(__pyx_t_6);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_2, function);
-      __pyx_t_7 = 1;
-    }
-  }
-  #if CYTHON_FAST_PYCALL
-  if (PyFunction_Check(__pyx_t_2)) {
-    PyObject *__pyx_temp[3] = {__pyx_t_6, __pyx_t_4, __pyx_t_5};
-    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 915, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  } else
-  #endif
-  #if CYTHON_FAST_PYCCALL
-  if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
-    PyObject *__pyx_temp[3] = {__pyx_t_6, __pyx_t_4, __pyx_t_5};
-    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 915, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  } else
-  #endif
-  {
-    __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 915, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_8);
-    if (__pyx_t_6) {
-      __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
-    }
-    __Pyx_GIVEREF(__pyx_t_4);
-    PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, __pyx_t_4);
-    __Pyx_GIVEREF(__pyx_t_5);
-    PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_t_5);
-    __pyx_t_4 = 0;
-    __pyx_t_5 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 915, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-  }
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_t_5);
+  __pyx_t_5 = 0;
+  __Pyx_INCREF(__pyx_kp_u__3);
+  __pyx_t_2 += 1;
+  __Pyx_GIVEREF(__pyx_kp_u__3);
+  PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_kp_u__3);
+
+  /* "pywrapfst.pyx":972
+ * 
+ *   def __repr__(self):
+ *     return (f"<const Fst SymbolTableView {self.name()!r} "             # <<<<<<<<<<<<<<
+ *             f"at 0x{id(self):x}>")
+ * 
+ */
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 972, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":914
+  /* "pywrapfst.pyx":971
  *   # Doing so will allow undefined behavior.
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<const Fst SymbolTableView {!r} at 0x{:x}>".format(self.name(),
- *                                                                id(self))
+ *     return (f"<const Fst SymbolTableView {self.name()!r} "
+ *             f"at 0x{id(self):x}>")
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_8);
   __Pyx_AddTraceback("pywrapfst._FstSymbolTableView.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -11273,8 +11502,8 @@ static PyObject *__pyx_pf_9pywrapfst_19_FstSymbolTableView___repr__(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":918
- *                                                                id(self))
+/* "pywrapfst.pyx":975
+ *             f"at 0x{id(self):x}>")
  * 
  *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
  *     return (self._fst.get().InputSymbols() if self._input_side
@@ -11285,9 +11514,12 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_19_FstSymbolT
   __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_r;
   __Pyx_RefNannyDeclarations
   fst::SymbolTable const *__pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_raw", 0);
 
-  /* "pywrapfst.pyx":919
+  /* "pywrapfst.pyx":976
  * 
  *   cdef const_SymbolTable_ptr _raw(self):
  *     return (self._fst.get().InputSymbols() if self._input_side             # <<<<<<<<<<<<<<
@@ -11296,17 +11528,17 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_19_FstSymbolT
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_input_side");
-    __PYX_ERR(0, 919, __pyx_L1_error)
+    __PYX_ERR(0, 976, __pyx_L1_error)
   }
   if ((__pyx_v_self->_input_side != 0)) {
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 919, __pyx_L1_error)
+      __PYX_ERR(0, 976, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_fst.get()->InputSymbols();
   } else {
 
-    /* "pywrapfst.pyx":920
+    /* "pywrapfst.pyx":977
  *   cdef const_SymbolTable_ptr _raw(self):
  *     return (self._fst.get().InputSymbols() if self._input_side
  *             else self._fst.get().OutputSymbols())             # <<<<<<<<<<<<<<
@@ -11315,15 +11547,15 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_19_FstSymbolT
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 920, __pyx_L1_error)
+      __PYX_ERR(0, 977, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_fst.get()->OutputSymbols();
   }
   __pyx_r = __pyx_t_1;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":918
- *                                                                id(self))
+  /* "pywrapfst.pyx":975
+ *             f"at 0x{id(self):x}>")
  * 
  *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
  *     return (self._fst.get().InputSymbols() if self._input_side
@@ -11339,7 +11571,7 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_19_FstSymbolT
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":934
+/* "pywrapfst.pyx":991
  *   """
  * 
  *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
@@ -11350,9 +11582,12 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_19_FstSymbolT
 static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTable__raw(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self) {
   __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_r;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_raw", 0);
 
-  /* "pywrapfst.pyx":935
+  /* "pywrapfst.pyx":992
  * 
  *   cdef const_SymbolTable_ptr _raw(self):
  *     return self._mutable_raw()             # <<<<<<<<<<<<<<
@@ -11361,12 +11596,12 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSym
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mutable_raw");
-    __PYX_ERR(0, 935, __pyx_L1_error)
+    __PYX_ERR(0, 992, __pyx_L1_error)
   }
   __pyx_r = ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->_mutable_raw(__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":934
+  /* "pywrapfst.pyx":991
  *   """
  * 
  *   cdef const_SymbolTable_ptr _raw(self):             # <<<<<<<<<<<<<<
@@ -11383,7 +11618,7 @@ static __pyx_t_9pywrapfst_const_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSym
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":941
+/* "pywrapfst.pyx":998
  *   # Should not be directly accessed except by `_mutable__raw_ptr_or_raise()`.
  *   # All other methods should use the safer _mutable__raw_ptr_or_raise() instead.
  *   cdef SymbolTable_ptr _mutable_raw(self):             # <<<<<<<<<<<<<<
@@ -11396,7 +11631,7 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTab
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_mutable_raw", 0);
 
-  /* "pywrapfst.pyx":942
+  /* "pywrapfst.pyx":999
  *   # All other methods should use the safer _mutable__raw_ptr_or_raise() instead.
  *   cdef SymbolTable_ptr _mutable_raw(self):
  *     return NULL             # <<<<<<<<<<<<<<
@@ -11406,7 +11641,7 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTab
   __pyx_r = NULL;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":941
+  /* "pywrapfst.pyx":998
  *   # Should not be directly accessed except by `_mutable__raw_ptr_or_raise()`.
  *   # All other methods should use the safer _mutable__raw_ptr_or_raise() instead.
  *   cdef SymbolTable_ptr _mutable_raw(self):             # <<<<<<<<<<<<<<
@@ -11420,7 +11655,7 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTab
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":946
+/* "pywrapfst.pyx":1003
  *   # Internal API method that should be used when a mutable pointer to an
  *   # fst.SymbolTable is required.
  *   cdef SymbolTable_ptr _mutable_raw_ptr_or_raise(self) except *:             # <<<<<<<<<<<<<<
@@ -11433,9 +11668,12 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTab
   __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_r;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_mutable_raw_ptr_or_raise", 0);
 
-  /* "pywrapfst.pyx":947
+  /* "pywrapfst.pyx":1004
  *   # fst.SymbolTable is required.
  *   cdef SymbolTable_ptr _mutable_raw_ptr_or_raise(self) except *:
  *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw()             # <<<<<<<<<<<<<<
@@ -11444,11 +11682,11 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTab
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mutable_raw");
-    __PYX_ERR(0, 947, __pyx_L1_error)
+    __PYX_ERR(0, 1004, __pyx_L1_error)
   }
   __pyx_v_mutable_raw = ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->_mutable_raw(__pyx_v_self);
 
-  /* "pywrapfst.pyx":948
+  /* "pywrapfst.pyx":1005
  *   cdef SymbolTable_ptr _mutable_raw_ptr_or_raise(self) except *:
  *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw()
  *     if mutable_raw == NULL:             # <<<<<<<<<<<<<<
@@ -11458,7 +11696,7 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTab
   __pyx_t_1 = ((__pyx_v_mutable_raw == NULL) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":949
+    /* "pywrapfst.pyx":1006
  *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw()
  *     if mutable_raw == NULL:
  *       self._raise_nonexistent()             # <<<<<<<<<<<<<<
@@ -11467,11 +11705,11 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTab
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raise_nonexistent");
-      __PYX_ERR(0, 949, __pyx_L1_error)
+      __PYX_ERR(0, 1006, __pyx_L1_error)
     }
-    ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base._raise_nonexistent(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 949, __pyx_L1_error)
+    ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base._raise_nonexistent(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1006, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":948
+    /* "pywrapfst.pyx":1005
  *   cdef SymbolTable_ptr _mutable_raw_ptr_or_raise(self) except *:
  *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw()
  *     if mutable_raw == NULL:             # <<<<<<<<<<<<<<
@@ -11480,7 +11718,7 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTab
  */
   }
 
-  /* "pywrapfst.pyx":950
+  /* "pywrapfst.pyx":1007
  *     if mutable_raw == NULL:
  *       self._raise_nonexistent()
  *     return mutable_raw             # <<<<<<<<<<<<<<
@@ -11490,7 +11728,7 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTab
   __pyx_r = __pyx_v_mutable_raw;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":946
+  /* "pywrapfst.pyx":1003
  *   # Internal API method that should be used when a mutable pointer to an
  *   # fst.SymbolTable is required.
  *   cdef SymbolTable_ptr _mutable_raw_ptr_or_raise(self) except *:             # <<<<<<<<<<<<<<
@@ -11507,7 +11745,7 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTab
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":952
+/* "pywrapfst.pyx":1009
  *     return mutable_raw
  * 
  *   cpdef int64 add_symbol(self, symbol, int64 key=fst.kNoSymbol) except *:             # <<<<<<<<<<<<<<
@@ -11517,9 +11755,9 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_19_MutableSymbolTab
 
 static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_1add_symbol(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self, PyObject *__pyx_v_symbol, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_19_MutableSymbolTable_add_symbol *__pyx_optional_args) {
-  int64 __pyx_v_key = __pyx_k__3;
+  int64 __pyx_v_key = __pyx_k__6;
+  __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_v__mutable_raw;
   std::string __pyx_v__symbol;
-  __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_v_mutable_raw;
   int64 __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -11530,9 +11768,12 @@ static int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __pyx_ob
   int __pyx_t_6;
   PyObject *__pyx_t_7 = NULL;
   int64 __pyx_t_8;
-  std::string __pyx_t_9;
-  fst::SymbolTable *__pyx_t_10;
+  fst::SymbolTable *__pyx_t_9;
+  std::string __pyx_t_10;
   int __pyx_t_11;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("add_symbol", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -11548,10 +11789,10 @@ static int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __pyx_ob
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_symbol); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 952, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_symbol); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1009, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_19_MutableSymbolTable_1add_symbol)) {
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_key); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 952, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_key); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1009, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -11569,7 +11810,7 @@ static int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __pyx_ob
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_v_symbol, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 952, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1009, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -11578,14 +11819,14 @@ static int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __pyx_ob
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
           PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_v_symbol, __pyx_t_3};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 952, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1009, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         } else
         #endif
         {
-          __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 952, __pyx_L1_error)
+          __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1009, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_7);
           if (__pyx_t_5) {
             __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL;
@@ -11596,12 +11837,12 @@ static int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __pyx_ob
           __Pyx_GIVEREF(__pyx_t_3);
           PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_3);
           __pyx_t_3 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 952, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1009, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
         }
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __pyx_t_8 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_8 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 952, __pyx_L1_error)
+        __pyx_t_8 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_8 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1009, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_8;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -11620,72 +11861,72 @@ static int64 __pyx_f_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __pyx_ob
     #endif
   }
 
-  /* "pywrapfst.pyx":969
+  /* "pywrapfst.pyx":1026
  *       The integer key of the new symbol.
  *     """
- *     cdef string _symbol = tostring(symbol)             # <<<<<<<<<<<<<<
- *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw_ptr_or_raise()
- *     if key != fst.kNoSymbol:
- */
-  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_symbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 969, __pyx_L1_error)
-  __pyx_v__symbol = __pyx_t_9;
-
-  /* "pywrapfst.pyx":970
- *     """
+ *     cdef SymbolTable_ptr _mutable_raw = self._mutable_raw_ptr_or_raise()             # <<<<<<<<<<<<<<
  *     cdef string _symbol = tostring(symbol)
- *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw_ptr_or_raise()             # <<<<<<<<<<<<<<
  *     if key != fst.kNoSymbol:
- *       return mutable_raw.AddSymbol(_symbol, key)
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mutable_raw_ptr_or_raise");
-    __PYX_ERR(0, 970, __pyx_L1_error)
+    __PYX_ERR(0, 1026, __pyx_L1_error)
   }
-  __pyx_t_10 = ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->_mutable_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 970, __pyx_L1_error)
-  __pyx_v_mutable_raw = __pyx_t_10;
+  __pyx_t_9 = ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->_mutable_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1026, __pyx_L1_error)
+  __pyx_v__mutable_raw = __pyx_t_9;
 
-  /* "pywrapfst.pyx":971
+  /* "pywrapfst.pyx":1027
+ *     """
+ *     cdef SymbolTable_ptr _mutable_raw = self._mutable_raw_ptr_or_raise()
+ *     cdef string _symbol = tostring(symbol)             # <<<<<<<<<<<<<<
+ *     if key != fst.kNoSymbol:
+ *       return _mutable_raw.AddSymbol(_symbol, key)
+ */
+  __pyx_t_10 = __pyx_f_9pywrapfst_tostring(__pyx_v_symbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1027, __pyx_L1_error)
+  __pyx_v__symbol = __pyx_t_10;
+
+  /* "pywrapfst.pyx":1028
+ *     cdef SymbolTable_ptr _mutable_raw = self._mutable_raw_ptr_or_raise()
  *     cdef string _symbol = tostring(symbol)
- *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw_ptr_or_raise()
  *     if key != fst.kNoSymbol:             # <<<<<<<<<<<<<<
- *       return mutable_raw.AddSymbol(_symbol, key)
+ *       return _mutable_raw.AddSymbol(_symbol, key)
  *     else:
  */
   __pyx_t_11 = ((__pyx_v_key != fst::kNoSymbol) != 0);
   if (__pyx_t_11) {
 
-    /* "pywrapfst.pyx":972
- *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw_ptr_or_raise()
+    /* "pywrapfst.pyx":1029
+ *     cdef string _symbol = tostring(symbol)
  *     if key != fst.kNoSymbol:
- *       return mutable_raw.AddSymbol(_symbol, key)             # <<<<<<<<<<<<<<
+ *       return _mutable_raw.AddSymbol(_symbol, key)             # <<<<<<<<<<<<<<
  *     else:
- *       return mutable_raw.AddSymbol(_symbol)
+ *       return _mutable_raw.AddSymbol(_symbol)
  */
-    __pyx_r = __pyx_v_mutable_raw->AddSymbol(__pyx_v__symbol, __pyx_v_key);
+    __pyx_r = __pyx_v__mutable_raw->AddSymbol(__pyx_v__symbol, __pyx_v_key);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":971
+    /* "pywrapfst.pyx":1028
+ *     cdef SymbolTable_ptr _mutable_raw = self._mutable_raw_ptr_or_raise()
  *     cdef string _symbol = tostring(symbol)
- *     cdef SymbolTable_ptr mutable_raw = self._mutable_raw_ptr_or_raise()
  *     if key != fst.kNoSymbol:             # <<<<<<<<<<<<<<
- *       return mutable_raw.AddSymbol(_symbol, key)
+ *       return _mutable_raw.AddSymbol(_symbol, key)
  *     else:
  */
   }
 
-  /* "pywrapfst.pyx":974
- *       return mutable_raw.AddSymbol(_symbol, key)
+  /* "pywrapfst.pyx":1031
+ *       return _mutable_raw.AddSymbol(_symbol, key)
  *     else:
- *       return mutable_raw.AddSymbol(_symbol)             # <<<<<<<<<<<<<<
+ *       return _mutable_raw.AddSymbol(_symbol)             # <<<<<<<<<<<<<<
  * 
- *   cpdef void add_table(self, _SymbolTable syms) except *:
+ *   cpdef void add_table(self, SymbolTableView symbols) except *:
  */
   /*else*/ {
-    __pyx_r = __pyx_v_mutable_raw->AddSymbol(__pyx_v__symbol);
+    __pyx_r = __pyx_v__mutable_raw->AddSymbol(__pyx_v__symbol);
     goto __pyx_L0;
   }
 
-  /* "pywrapfst.pyx":952
+  /* "pywrapfst.pyx":1009
  *     return mutable_raw
  * 
  *   cpdef int64 add_symbol(self, symbol, int64 key=fst.kNoSymbol) except *:             # <<<<<<<<<<<<<<
@@ -11714,6 +11955,9 @@ static char __pyx_doc_9pywrapfst_19_MutableSymbolTable_add_symbol[] = "\n    add
 static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_1add_symbol(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_symbol = 0;
   int64 __pyx_v_key;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("add_symbol (wrapper)", 0);
@@ -11744,7 +11988,7 @@ static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_1add_symbol(PyObject
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_symbol") < 0)) __PYX_ERR(0, 952, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_symbol") < 0)) __PYX_ERR(0, 1009, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -11757,14 +12001,14 @@ static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_1add_symbol(PyObject
     }
     __pyx_v_symbol = values[0];
     if (values[1]) {
-      __pyx_v_key = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_key == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 952, __pyx_L3_error)
+      __pyx_v_key = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_key == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1009, __pyx_L3_error)
     } else {
-      __pyx_v_key = __pyx_k__3;
+      __pyx_v_key = __pyx_k__6;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("add_symbol", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 952, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("add_symbol", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1009, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._MutableSymbolTable.add_symbol", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -11783,12 +12027,15 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __p
   int64 __pyx_t_1;
   struct __pyx_opt_args_9pywrapfst_19_MutableSymbolTable_add_symbol __pyx_t_2;
   PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("add_symbol", 0);
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.key = __pyx_v_key;
-  __pyx_t_1 = __pyx_vtabptr_9pywrapfst__MutableSymbolTable->add_symbol(__pyx_v_self, __pyx_v_symbol, 1, &__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 952, __pyx_L1_error)
-  __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 952, __pyx_L1_error)
+  __pyx_t_1 = __pyx_vtabptr_9pywrapfst__MutableSymbolTable->add_symbol(__pyx_v_self, __pyx_v_symbol, 1, &__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1009, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1009, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -11805,16 +12052,16 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_add_symbol(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":976
- *       return mutable_raw.AddSymbol(_symbol)
+/* "pywrapfst.pyx":1033
+ *       return _mutable_raw.AddSymbol(_symbol)
  * 
- *   cpdef void add_table(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
+ *   cpdef void add_table(self, SymbolTableView symbols) except *:             # <<<<<<<<<<<<<<
  *     """
- *     add_table(self, syms)
+ *     add_table(self, symbols)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_3add_table(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
-static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms, int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_3add_table(PyObject *__pyx_v_self, PyObject *__pyx_v_symbols); /*proto*/
+static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -11822,6 +12069,9 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
   PyObject *__pyx_t_4 = NULL;
   fst::SymbolTable *__pyx_t_5;
   fst::SymbolTable const *__pyx_t_6;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("add_table", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -11832,7 +12082,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_table); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 976, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_table); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1033, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_19_MutableSymbolTable_3add_table)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -11846,9 +12096,9 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
             __Pyx_DECREF_SET(__pyx_t_3, function);
           }
         }
-        __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, ((PyObject *)__pyx_v_syms)) : __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_syms));
+        __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, ((PyObject *)__pyx_v_symbols)) : __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_symbols));
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 976, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1033, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -11868,31 +12118,47 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
     #endif
   }
 
-  /* "pywrapfst.pyx":988
- *       syms: A SymbolTable to be merged with the current table.
+  /* "pywrapfst.pyx":1045
+ *       symbols: A SymbolTable to be merged with the current table.
  *     """
- *     self._mutable_raw_ptr_or_raise().AddTable(deref(syms._raw_ptr_or_raise()))             # <<<<<<<<<<<<<<
+ *     self._mutable_raw_ptr_or_raise().AddTable(             # <<<<<<<<<<<<<<
+ *         deref(symbols._raw_ptr_or_raise()))
  * 
- *   cpdef void set_name(self, new_name) except *:
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mutable_raw_ptr_or_raise");
-    __PYX_ERR(0, 988, __pyx_L1_error)
+    __PYX_ERR(0, 1045, __pyx_L1_error)
   }
-  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->_mutable_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 988, __pyx_L1_error)
-  if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
+  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->_mutable_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1045, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":1046
+ *     """
+ *     self._mutable_raw_ptr_or_raise().AddTable(
+ *         deref(symbols._raw_ptr_or_raise()))             # <<<<<<<<<<<<<<
+ * 
+ *   cpdef void set_name(self, new_name) except *:
+ */
+  if (unlikely(((PyObject *)__pyx_v_symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 988, __pyx_L1_error)
+    __PYX_ERR(0, 1046, __pyx_L1_error)
   }
-  __pyx_t_6 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_syms->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_syms); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 988, __pyx_L1_error)
+  __pyx_t_6 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_symbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1046, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":1045
+ *       symbols: A SymbolTable to be merged with the current table.
+ *     """
+ *     self._mutable_raw_ptr_or_raise().AddTable(             # <<<<<<<<<<<<<<
+ *         deref(symbols._raw_ptr_or_raise()))
+ * 
+ */
   __pyx_t_5->AddTable((*__pyx_t_6));
 
-  /* "pywrapfst.pyx":976
- *       return mutable_raw.AddSymbol(_symbol)
+  /* "pywrapfst.pyx":1033
+ *       return _mutable_raw.AddSymbol(_symbol)
  * 
- *   cpdef void add_table(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
+ *   cpdef void add_table(self, SymbolTableView symbols) except *:             # <<<<<<<<<<<<<<
  *     """
- *     add_table(self, syms)
+ *     add_table(self, symbols)
  */
 
   /* function exit code */
@@ -11908,14 +12174,17 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(struct __pyx_obj_
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_3add_table(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
-static char __pyx_doc_9pywrapfst_19_MutableSymbolTable_2add_table[] = "\n    add_table(self, syms)\n\n    Adds another SymbolTable to this table.\n\n    This method merges another symbol table into the current table. All key\n    values will be offset by the current available key.\n\n    Args:\n      syms: A SymbolTable to be merged with the current table.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_3add_table(PyObject *__pyx_v_self, PyObject *__pyx_v_syms) {
+static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_3add_table(PyObject *__pyx_v_self, PyObject *__pyx_v_symbols); /*proto*/
+static char __pyx_doc_9pywrapfst_19_MutableSymbolTable_2add_table[] = "\n    add_table(self, symbols)\n\n    Adds another SymbolTable to this table.\n\n    This method merges another symbol table into the current table. All key\n    values will be offset by the current available key.\n\n    Args:\n      symbols: A SymbolTable to be merged with the current table.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_3add_table(PyObject *__pyx_v_self, PyObject *__pyx_v_symbols) {
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("add_table (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 976, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_19_MutableSymbolTable_2add_table(((struct __pyx_obj_9pywrapfst__MutableSymbolTable *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_syms));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_symbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "symbols", 0))) __PYX_ERR(0, 1033, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_19_MutableSymbolTable_2add_table(((struct __pyx_obj_9pywrapfst__MutableSymbolTable *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_symbols));
 
   /* function exit code */
   goto __pyx_L0;
@@ -11926,14 +12195,17 @@ static PyObject *__pyx_pw_9pywrapfst_19_MutableSymbolTable_3add_table(PyObject *
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_2add_table(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
+static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_2add_table(struct __pyx_obj_9pywrapfst__MutableSymbolTable *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("add_table", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(__pyx_v_self, __pyx_v_syms, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 976, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 976, __pyx_L1_error)
+  __pyx_f_9pywrapfst_19_MutableSymbolTable_add_table(__pyx_v_self, __pyx_v_symbols, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1033, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1033, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -11950,8 +12222,8 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_2add_table(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":990
- *     self._mutable_raw_ptr_or_raise().AddTable(deref(syms._raw_ptr_or_raise()))
+/* "pywrapfst.pyx":1048
+ *         deref(symbols._raw_ptr_or_raise()))
  * 
  *   cpdef void set_name(self, new_name) except *:             # <<<<<<<<<<<<<<
  *     self._mutable_raw_ptr_or_raise().SetName(tostring(new_name))
@@ -11967,6 +12239,9 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(struct __pyx_obj_9
   PyObject *__pyx_t_4 = NULL;
   fst::SymbolTable *__pyx_t_5;
   std::string __pyx_t_6;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_name", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -11977,7 +12252,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(struct __pyx_obj_9
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 990, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1048, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_19_MutableSymbolTable_5set_name)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -11993,7 +12268,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(struct __pyx_obj_9
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_new_name) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_new_name);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 990, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1048, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -12013,7 +12288,7 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(struct __pyx_obj_9
     #endif
   }
 
-  /* "pywrapfst.pyx":991
+  /* "pywrapfst.pyx":1049
  * 
  *   cpdef void set_name(self, new_name) except *:
  *     self._mutable_raw_ptr_or_raise().SetName(tostring(new_name))             # <<<<<<<<<<<<<<
@@ -12022,14 +12297,14 @@ static void __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mutable_raw_ptr_or_raise");
-    __PYX_ERR(0, 991, __pyx_L1_error)
+    __PYX_ERR(0, 1049, __pyx_L1_error)
   }
-  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->_mutable_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 991, __pyx_L1_error)
-  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_new_name); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 991, __pyx_L1_error)
+  __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable *)__pyx_v_self->__pyx_base.__pyx_vtab)->_mutable_raw_ptr_or_raise(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1049, __pyx_L1_error)
+  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_new_name); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1049, __pyx_L1_error)
   __pyx_t_5->SetName(__pyx_t_6);
 
-  /* "pywrapfst.pyx":990
- *     self._mutable_raw_ptr_or_raise().AddTable(deref(syms._raw_ptr_or_raise()))
+  /* "pywrapfst.pyx":1048
+ *         deref(symbols._raw_ptr_or_raise()))
  * 
  *   cpdef void set_name(self, new_name) except *:             # <<<<<<<<<<<<<<
  *     self._mutable_raw_ptr_or_raise().SetName(tostring(new_name))
@@ -12065,10 +12340,13 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_4set_name(struct __py
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_name", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(__pyx_v_self, __pyx_v_new_name, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 990, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 990, __pyx_L1_error)
+  __pyx_f_9pywrapfst_19_MutableSymbolTable_set_name(__pyx_v_self, __pyx_v_new_name, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1048, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1048, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -12085,11 +12363,11 @@ static PyObject *__pyx_pf_9pywrapfst_19_MutableSymbolTable_4set_name(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1001
+/* "pywrapfst.pyx":1059
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<Fst SymbolTableView {!r} at 0x{:x}>".format(self.name(), id(self))
+ *     return f"<Fst SymbolTableView {self.name()!r} at 0x{id(self):x}>"
  * 
  */
 
@@ -12110,103 +12388,85 @@ static PyObject *__pyx_pf_9pywrapfst_26_MutableFstSymbolTableView___repr__(struc
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  std::string __pyx_t_3;
-  PyObject *__pyx_t_4 = NULL;
+  Py_ssize_t __pyx_t_2;
+  Py_UCS4 __pyx_t_3;
+  std::string __pyx_t_4;
   PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
-  int __pyx_t_7;
-  PyObject *__pyx_t_8 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":1002
+  /* "pywrapfst.pyx":1060
  * 
  *   def __repr__(self):
- *     return "<Fst SymbolTableView {!r} at 0x{:x}>".format(self.name(), id(self))             # <<<<<<<<<<<<<<
+ *     return f"<Fst SymbolTableView {self.name()!r} at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
  * 
  *   cdef SymbolTable_ptr _mutable_raw(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Fst_SymbolTableView_r_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1002, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1060, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 127;
+  __Pyx_INCREF(__pyx_kp_u_Fst_SymbolTableView);
+  __pyx_t_2 += 21;
+  __Pyx_GIVEREF(__pyx_kp_u_Fst_SymbolTableView);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_Fst_SymbolTableView);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "name");
-    __PYX_ERR(0, 1002, __pyx_L1_error)
+    __PYX_ERR(0, 1060, __pyx_L1_error)
   }
-  __pyx_t_3 = ((struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTableView *)__pyx_v_self->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base.name(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1002, __pyx_L1_error)
-  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1002, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1002, __pyx_L1_error)
+  __pyx_t_4 = ((struct __pyx_vtabstruct_9pywrapfst__MutableFstSymbolTableView *)__pyx_v_self->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base.name(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self), 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1060, __pyx_L1_error)
+  __pyx_t_5 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1060, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = NULL;
-  __pyx_t_7 = 0;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
-    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_2);
-    if (likely(__pyx_t_6)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-      __Pyx_INCREF(__pyx_t_6);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_2, function);
-      __pyx_t_7 = 1;
-    }
-  }
-  #if CYTHON_FAST_PYCALL
-  if (PyFunction_Check(__pyx_t_2)) {
-    PyObject *__pyx_temp[3] = {__pyx_t_6, __pyx_t_4, __pyx_t_5};
-    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1002, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  } else
-  #endif
-  #if CYTHON_FAST_PYCCALL
-  if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
-    PyObject *__pyx_temp[3] = {__pyx_t_6, __pyx_t_4, __pyx_t_5};
-    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1002, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  } else
-  #endif
-  {
-    __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1002, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_8);
-    if (__pyx_t_6) {
-      __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
-    }
-    __Pyx_GIVEREF(__pyx_t_4);
-    PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, __pyx_t_4);
-    __Pyx_GIVEREF(__pyx_t_5);
-    PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_t_5);
-    __pyx_t_4 = 0;
-    __pyx_t_5 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1002, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-  }
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __pyx_t_6 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_5), __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1060, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6);
+  __Pyx_GIVEREF(__pyx_t_6);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_6);
+  __pyx_t_6 = 0;
+  __Pyx_INCREF(__pyx_kp_u_at_0x);
+  __pyx_t_2 += 6;
+  __Pyx_GIVEREF(__pyx_kp_u_at_0x);
+  PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_at_0x);
+  __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1060, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_6, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1060, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_t_5);
+  __pyx_t_5 = 0;
+  __Pyx_INCREF(__pyx_kp_u__3);
+  __pyx_t_2 += 1;
+  __Pyx_GIVEREF(__pyx_kp_u__3);
+  PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_kp_u__3);
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1060, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1001
+  /* "pywrapfst.pyx":1059
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<Fst SymbolTableView {!r} at 0x{:x}>".format(self.name(), id(self))
+ *     return f"<Fst SymbolTableView {self.name()!r} at 0x{id(self):x}>"
  * 
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_8);
   __Pyx_AddTraceback("pywrapfst._MutableFstSymbolTableView.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -12215,8 +12475,8 @@ static PyObject *__pyx_pf_9pywrapfst_26_MutableFstSymbolTableView___repr__(struc
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1004
- *     return "<Fst SymbolTableView {!r} at 0x{:x}>".format(self.name(), id(self))
+/* "pywrapfst.pyx":1062
+ *     return f"<Fst SymbolTableView {self.name()!r} at 0x{id(self):x}>"
  * 
  *   cdef SymbolTable_ptr _mutable_raw(self):             # <<<<<<<<<<<<<<
  *     return (self._mfst.get().MutableInputSymbols() if self._input_side else
@@ -12227,9 +12487,12 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_26_MutableFstSymbol
   __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_r;
   __Pyx_RefNannyDeclarations
   fst::SymbolTable *__pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_mutable_raw", 0);
 
-  /* "pywrapfst.pyx":1005
+  /* "pywrapfst.pyx":1063
  * 
  *   cdef SymbolTable_ptr _mutable_raw(self):
  *     return (self._mfst.get().MutableInputSymbols() if self._input_side else             # <<<<<<<<<<<<<<
@@ -12238,17 +12501,17 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_26_MutableFstSymbol
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_input_side");
-    __PYX_ERR(0, 1005, __pyx_L1_error)
+    __PYX_ERR(0, 1063, __pyx_L1_error)
   }
   if ((__pyx_v_self->_input_side != 0)) {
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 1005, __pyx_L1_error)
+      __PYX_ERR(0, 1063, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_mfst.get()->MutableInputSymbols();
   } else {
 
-    /* "pywrapfst.pyx":1006
+    /* "pywrapfst.pyx":1064
  *   cdef SymbolTable_ptr _mutable_raw(self):
  *     return (self._mfst.get().MutableInputSymbols() if self._input_side else
  *             self._mfst.get().MutableOutputSymbols())             # <<<<<<<<<<<<<<
@@ -12257,15 +12520,15 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_26_MutableFstSymbol
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 1006, __pyx_L1_error)
+      __PYX_ERR(0, 1064, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_mfst.get()->MutableOutputSymbols();
   }
   __pyx_r = __pyx_t_1;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1004
- *     return "<Fst SymbolTableView {!r} at 0x{:x}>".format(self.name(), id(self))
+  /* "pywrapfst.pyx":1062
+ *     return f"<Fst SymbolTableView {self.name()!r} at 0x{id(self):x}>"
  * 
  *   cdef SymbolTable_ptr _mutable_raw(self):             # <<<<<<<<<<<<<<
  *     return (self._mfst.get().MutableInputSymbols() if self._input_side else
@@ -12281,11 +12544,11 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_26_MutableFstSymbol
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1026
+/* "pywrapfst.pyx":1084
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))
+ *     return f"<SymbolTable {self.name()!r} at 0x{id(self):x}>"
  * 
  */
 
@@ -12306,103 +12569,85 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  std::string __pyx_t_3;
-  PyObject *__pyx_t_4 = NULL;
+  Py_ssize_t __pyx_t_2;
+  Py_UCS4 __pyx_t_3;
+  std::string __pyx_t_4;
   PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
-  int __pyx_t_7;
-  PyObject *__pyx_t_8 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":1027
+  /* "pywrapfst.pyx":1085
  * 
  *   def __repr__(self):
- *     return "<SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))             # <<<<<<<<<<<<<<
+ *     return f"<SymbolTable {self.name()!r} at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
  * 
  *   def __init__(self, name="<unspecified>"):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_SymbolTable_r_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1027, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1085, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 127;
+  __Pyx_INCREF(__pyx_kp_u_SymbolTable);
+  __pyx_t_2 += 13;
+  __Pyx_GIVEREF(__pyx_kp_u_SymbolTable);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_SymbolTable);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "name");
-    __PYX_ERR(0, 1027, __pyx_L1_error)
+    __PYX_ERR(0, 1085, __pyx_L1_error)
   }
-  __pyx_t_3 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTable *)__pyx_v_self->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base.name(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_self), 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1027, __pyx_L1_error)
-  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1027, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1027, __pyx_L1_error)
+  __pyx_t_4 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTable *)__pyx_v_self->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base.name(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_self), 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1085, __pyx_L1_error)
+  __pyx_t_5 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1085, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = NULL;
-  __pyx_t_7 = 0;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
-    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_2);
-    if (likely(__pyx_t_6)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-      __Pyx_INCREF(__pyx_t_6);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_2, function);
-      __pyx_t_7 = 1;
-    }
-  }
-  #if CYTHON_FAST_PYCALL
-  if (PyFunction_Check(__pyx_t_2)) {
-    PyObject *__pyx_temp[3] = {__pyx_t_6, __pyx_t_4, __pyx_t_5};
-    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1027, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  } else
-  #endif
-  #if CYTHON_FAST_PYCCALL
-  if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
-    PyObject *__pyx_temp[3] = {__pyx_t_6, __pyx_t_4, __pyx_t_5};
-    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1027, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  } else
-  #endif
-  {
-    __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1027, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_8);
-    if (__pyx_t_6) {
-      __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
-    }
-    __Pyx_GIVEREF(__pyx_t_4);
-    PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, __pyx_t_4);
-    __Pyx_GIVEREF(__pyx_t_5);
-    PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_t_5);
-    __pyx_t_4 = 0;
-    __pyx_t_5 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1027, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-  }
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __pyx_t_6 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_5), __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1085, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6);
+  __Pyx_GIVEREF(__pyx_t_6);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_6);
+  __pyx_t_6 = 0;
+  __Pyx_INCREF(__pyx_kp_u_at_0x);
+  __pyx_t_2 += 6;
+  __Pyx_GIVEREF(__pyx_kp_u_at_0x);
+  PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_at_0x);
+  __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1085, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_6, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1085, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_t_5);
+  __pyx_t_5 = 0;
+  __Pyx_INCREF(__pyx_kp_u__3);
+  __pyx_t_2 += 1;
+  __Pyx_GIVEREF(__pyx_kp_u__3);
+  PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_kp_u__3);
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1085, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1026
+  /* "pywrapfst.pyx":1084
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))
+ *     return f"<SymbolTable {self.name()!r} at 0x{id(self):x}>"
  * 
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_8);
   __Pyx_AddTraceback("pywrapfst.SymbolTable.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -12411,8 +12656,8 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1029
- *     return "<SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))
+/* "pywrapfst.pyx":1087
+ *     return f"<SymbolTable {self.name()!r} at 0x{id(self):x}>"
  * 
  *   def __init__(self, name="<unspecified>"):             # <<<<<<<<<<<<<<
  *     self._smart_table.reset(new fst.SymbolTable(tostring(name)))
@@ -12423,6 +12668,9 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable___repr__(struct __pyx_obj_9py
 static int __pyx_pw_9pywrapfst_11SymbolTable_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static int __pyx_pw_9pywrapfst_11SymbolTable_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_name = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
@@ -12448,7 +12696,7 @@ static int __pyx_pw_9pywrapfst_11SymbolTable_3__init__(PyObject *__pyx_v_self, P
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 1029, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 1087, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -12462,7 +12710,7 @@ static int __pyx_pw_9pywrapfst_11SymbolTable_3__init__(PyObject *__pyx_v_self, P
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1029, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1087, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.SymbolTable.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -12479,9 +12727,12 @@ static int __pyx_pf_9pywrapfst_11SymbolTable_2__init__(struct __pyx_obj_9pywrapf
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":1030
+  /* "pywrapfst.pyx":1088
  * 
  *   def __init__(self, name="<unspecified>"):
  *     self._smart_table.reset(new fst.SymbolTable(tostring(name)))             # <<<<<<<<<<<<<<
@@ -12490,13 +12741,13 @@ static int __pyx_pf_9pywrapfst_11SymbolTable_2__init__(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_smart_table");
-    __PYX_ERR(0, 1030, __pyx_L1_error)
+    __PYX_ERR(0, 1088, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_name); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1030, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_name); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1088, __pyx_L1_error)
   __pyx_v_self->_smart_table.reset(new fst::SymbolTable(__pyx_t_1));
 
-  /* "pywrapfst.pyx":1029
- *     return "<SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))
+  /* "pywrapfst.pyx":1087
+ *     return f"<SymbolTable {self.name()!r} at 0x{id(self):x}>"
  * 
  *   def __init__(self, name="<unspecified>"):             # <<<<<<<<<<<<<<
  *     self._smart_table.reset(new fst.SymbolTable(tostring(name)))
@@ -12514,7 +12765,7 @@ static int __pyx_pf_9pywrapfst_11SymbolTable_2__init__(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1032
+/* "pywrapfst.pyx":1090
  *     self._smart_table.reset(new fst.SymbolTable(tostring(name)))
  * 
  *   cdef SymbolTable_ptr _mutable_raw(self):             # <<<<<<<<<<<<<<
@@ -12525,9 +12776,12 @@ static int __pyx_pf_9pywrapfst_11SymbolTable_2__init__(struct __pyx_obj_9pywrapf
 static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_11SymbolTable__mutable_raw(struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_self) {
   __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_r;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_mutable_raw", 0);
 
-  /* "pywrapfst.pyx":1033
+  /* "pywrapfst.pyx":1091
  * 
  *   cdef SymbolTable_ptr _mutable_raw(self):
  *     return self._smart_table.get()             # <<<<<<<<<<<<<<
@@ -12536,12 +12790,12 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_11SymbolTable__muta
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_smart_table");
-    __PYX_ERR(0, 1033, __pyx_L1_error)
+    __PYX_ERR(0, 1091, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_smart_table.get();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1032
+  /* "pywrapfst.pyx":1090
  *     self._smart_table.reset(new fst.SymbolTable(tostring(name)))
  * 
  *   cdef SymbolTable_ptr _mutable_raw(self):             # <<<<<<<<<<<<<<
@@ -12558,7 +12812,7 @@ static __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_f_9pywrapfst_11SymbolTable__muta
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1036
+/* "pywrapfst.pyx":1094
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
@@ -12581,7 +12835,7 @@ static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_5read(PyObject *__pyx_v_cls,
 }
 
 static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source) {
-  std::unique_ptr<fst::SymbolTable>  __pyx_v_syms;
+  std::unique_ptr<fst::SymbolTable>  __pyx_v__symbols;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
@@ -12590,99 +12844,89 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("read", 0);
 
-  /* "pywrapfst.pyx":1051
+  /* "pywrapfst.pyx":1109
  *     """
- *     cdef unique_ptr[fst.SymbolTable] syms
- *     syms.reset(fst.SymbolTable.Read(tostring(source)))             # <<<<<<<<<<<<<<
- *     if syms.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(source))
+ *     cdef unique_ptr[fst.SymbolTable] _symbols
+ *     _symbols.reset(fst.SymbolTable.Read(path_tostring(source)))             # <<<<<<<<<<<<<<
+ *     if _symbols.get() == NULL:
+ *       raise FstIOError(f"Read failed: {source!r}")
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1051, __pyx_L1_error)
-  __pyx_v_syms.reset(fst::SymbolTable::Read(__pyx_t_1));
+  __pyx_t_1 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1109, __pyx_L1_error)
+  __pyx_v__symbols.reset(fst::SymbolTable::Read(__pyx_t_1));
 
-  /* "pywrapfst.pyx":1052
- *     cdef unique_ptr[fst.SymbolTable] syms
- *     syms.reset(fst.SymbolTable.Read(tostring(source)))
- *     if syms.get() == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Read failed: {!r}".format(source))
- *     return _init_SymbolTable(move(syms))
+  /* "pywrapfst.pyx":1110
+ *     cdef unique_ptr[fst.SymbolTable] _symbols
+ *     _symbols.reset(fst.SymbolTable.Read(path_tostring(source)))
+ *     if _symbols.get() == NULL:             # <<<<<<<<<<<<<<
+ *       raise FstIOError(f"Read failed: {source!r}")
+ *     return _init_SymbolTable(move(_symbols))
  */
-  __pyx_t_2 = ((__pyx_v_syms.get() == NULL) != 0);
+  __pyx_t_2 = ((__pyx_v__symbols.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1053
- *     syms.reset(fst.SymbolTable.Read(tostring(source)))
- *     if syms.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(source))             # <<<<<<<<<<<<<<
- *     return _init_SymbolTable(move(syms))
+    /* "pywrapfst.pyx":1111
+ *     _symbols.reset(fst.SymbolTable.Read(path_tostring(source)))
+ *     if _symbols.get() == NULL:
+ *       raise FstIOError(f"Read failed: {source!r}")             # <<<<<<<<<<<<<<
+ *     return _init_SymbolTable(move(_symbols))
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1053, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1111, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1053, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
-        __Pyx_INCREF(__pyx_t_7);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_6, function);
-      }
-    }
-    __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_source);
-    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1053, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1111, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = NULL;
+    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Read_failed, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1111, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
-      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
-      if (likely(__pyx_t_6)) {
+      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+      if (likely(__pyx_t_5)) {
         PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-        __Pyx_INCREF(__pyx_t_6);
+        __Pyx_INCREF(__pyx_t_5);
         __Pyx_INCREF(function);
         __Pyx_DECREF_SET(__pyx_t_4, function);
       }
     }
-    __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1053, __pyx_L1_error)
+    __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
+    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1111, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1053, __pyx_L1_error)
+    __PYX_ERR(0, 1111, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1052
- *     cdef unique_ptr[fst.SymbolTable] syms
- *     syms.reset(fst.SymbolTable.Read(tostring(source)))
- *     if syms.get() == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Read failed: {!r}".format(source))
- *     return _init_SymbolTable(move(syms))
+    /* "pywrapfst.pyx":1110
+ *     cdef unique_ptr[fst.SymbolTable] _symbols
+ *     _symbols.reset(fst.SymbolTable.Read(path_tostring(source)))
+ *     if _symbols.get() == NULL:             # <<<<<<<<<<<<<<
+ *       raise FstIOError(f"Read failed: {source!r}")
+ *     return _init_SymbolTable(move(_symbols))
  */
   }
 
-  /* "pywrapfst.pyx":1054
- *     if syms.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(source))
- *     return _init_SymbolTable(move(syms))             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1112
+ *     if _symbols.get() == NULL:
+ *       raise FstIOError(f"Read failed: {source!r}")
+ *     return _init_SymbolTable(move(_symbols))             # <<<<<<<<<<<<<<
  * 
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::move<std::unique_ptr<fst::SymbolTable> >(__pyx_v_syms))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1054, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::move<std::unique_ptr<fst::SymbolTable> >(__pyx_v__symbols))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1112, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1036
+  /* "pywrapfst.pyx":1094
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
@@ -12696,7 +12940,6 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_AddTraceback("pywrapfst.SymbolTable.read", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -12705,7 +12948,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_4read(CYTHON_UNUSED PyTypeObj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1057
+/* "pywrapfst.pyx":1115
  * 
  *   @classmethod
  *   def read_text(cls, source, bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
@@ -12719,6 +12962,9 @@ static char __pyx_doc_9pywrapfst_11SymbolTable_6read_text[] = "\n    SymbolTable
 static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_7read_text(PyObject *__pyx_v_cls, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_source = 0;
   bool __pyx_v_allow_negative_labels;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("read_text (wrapper)", 0);
@@ -12749,7 +12995,7 @@ static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_7read_text(PyObject *__pyx_v_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_text") < 0)) __PYX_ERR(0, 1057, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_text") < 0)) __PYX_ERR(0, 1115, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -12762,14 +13008,14 @@ static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_7read_text(PyObject *__pyx_v_
     }
     __pyx_v_source = values[0];
     if (values[1]) {
-      __pyx_v_allow_negative_labels = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_allow_negative_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1057, __pyx_L3_error)
+      __pyx_v_allow_negative_labels = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_allow_negative_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1115, __pyx_L3_error)
     } else {
       __pyx_v_allow_negative_labels = ((bool)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("read_text", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1057, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("read_text", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1115, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.SymbolTable.read_text", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -12783,8 +13029,8 @@ static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_7read_text(PyObject *__pyx_v_
 }
 
 static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source, bool __pyx_v_allow_negative_labels) {
-  std::unique_ptr<fst::SymbolTableTextOptions>  __pyx_v_opts;
-  std::unique_ptr<fst::SymbolTable>  __pyx_v_syms;
+  std::unique_ptr<fst::SymbolTableTextOptions>  __pyx_v__opts;
+  std::unique_ptr<fst::SymbolTable>  __pyx_v__symbols;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
@@ -12793,108 +13039,106 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("read_text", 0);
 
-  /* "pywrapfst.pyx":1074
+  /* "pywrapfst.pyx":1132
  *     """
- *     cdef unique_ptr[fst.SymbolTableTextOptions] opts
- *     opts.reset(new fst.SymbolTableTextOptions(allow_negative_labels))             # <<<<<<<<<<<<<<
- *     cdef unique_ptr[fst.SymbolTable] syms
- *     syms.reset(fst.SymbolTable.ReadText(tostring(source), deref(opts)))
- */
-  __pyx_v_opts.reset(new fst::SymbolTableTextOptions(__pyx_v_allow_negative_labels));
-
-  /* "pywrapfst.pyx":1076
- *     opts.reset(new fst.SymbolTableTextOptions(allow_negative_labels))
- *     cdef unique_ptr[fst.SymbolTable] syms
- *     syms.reset(fst.SymbolTable.ReadText(tostring(source), deref(opts)))             # <<<<<<<<<<<<<<
- *     if syms.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(source))
+ *     cdef unique_ptr[fst.SymbolTableTextOptions] _opts
+ *     _opts.reset(new fst.SymbolTableTextOptions(allow_negative_labels))             # <<<<<<<<<<<<<<
+ *     cdef unique_ptr[fst.SymbolTable] _symbols
+ *     _symbols.reset(fst.SymbolTable.ReadText(path_tostring(source),
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1076, __pyx_L1_error)
-  __pyx_v_syms.reset(fst::SymbolTable::ReadText(__pyx_t_1, (*__pyx_v_opts)));
+  __pyx_v__opts.reset(new fst::SymbolTableTextOptions(__pyx_v_allow_negative_labels));
 
-  /* "pywrapfst.pyx":1077
- *     cdef unique_ptr[fst.SymbolTable] syms
- *     syms.reset(fst.SymbolTable.ReadText(tostring(source), deref(opts)))
- *     if syms.get() == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Read failed: {!r}".format(source))
- *     return _init_SymbolTable(move(syms))
- */
-  __pyx_t_2 = ((__pyx_v_syms.get() == NULL) != 0);
+  /* "pywrapfst.pyx":1134
+ *     _opts.reset(new fst.SymbolTableTextOptions(allow_negative_labels))
+ *     cdef unique_ptr[fst.SymbolTable] _symbols
+ *     _symbols.reset(fst.SymbolTable.ReadText(path_tostring(source),             # <<<<<<<<<<<<<<
+ *                                             deref(_opts)))
+ *     if _symbols.get() == NULL:
+ */
+  __pyx_t_1 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1134, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":1135
+ *     cdef unique_ptr[fst.SymbolTable] _symbols
+ *     _symbols.reset(fst.SymbolTable.ReadText(path_tostring(source),
+ *                                             deref(_opts)))             # <<<<<<<<<<<<<<
+ *     if _symbols.get() == NULL:
+ *       raise FstIOError(f"Read failed: {source!r}")
+ */
+  __pyx_v__symbols.reset(fst::SymbolTable::ReadText(__pyx_t_1, (*__pyx_v__opts)));
+
+  /* "pywrapfst.pyx":1136
+ *     _symbols.reset(fst.SymbolTable.ReadText(path_tostring(source),
+ *                                             deref(_opts)))
+ *     if _symbols.get() == NULL:             # <<<<<<<<<<<<<<
+ *       raise FstIOError(f"Read failed: {source!r}")
+ *     return _init_SymbolTable(move(_symbols))
+ */
+  __pyx_t_2 = ((__pyx_v__symbols.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1078
- *     syms.reset(fst.SymbolTable.ReadText(tostring(source), deref(opts)))
- *     if syms.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(source))             # <<<<<<<<<<<<<<
- *     return _init_SymbolTable(move(syms))
+    /* "pywrapfst.pyx":1137
+ *                                             deref(_opts)))
+ *     if _symbols.get() == NULL:
+ *       raise FstIOError(f"Read failed: {source!r}")             # <<<<<<<<<<<<<<
+ *     return _init_SymbolTable(move(_symbols))
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1078, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1137, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1078, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
-        __Pyx_INCREF(__pyx_t_7);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_6, function);
-      }
-    }
-    __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_source);
-    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1078, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1137, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = NULL;
+    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Read_failed, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1137, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
-      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
-      if (likely(__pyx_t_6)) {
+      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+      if (likely(__pyx_t_5)) {
         PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-        __Pyx_INCREF(__pyx_t_6);
+        __Pyx_INCREF(__pyx_t_5);
         __Pyx_INCREF(function);
         __Pyx_DECREF_SET(__pyx_t_4, function);
       }
     }
-    __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1078, __pyx_L1_error)
+    __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
+    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1137, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1078, __pyx_L1_error)
+    __PYX_ERR(0, 1137, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1077
- *     cdef unique_ptr[fst.SymbolTable] syms
- *     syms.reset(fst.SymbolTable.ReadText(tostring(source), deref(opts)))
- *     if syms.get() == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Read failed: {!r}".format(source))
- *     return _init_SymbolTable(move(syms))
+    /* "pywrapfst.pyx":1136
+ *     _symbols.reset(fst.SymbolTable.ReadText(path_tostring(source),
+ *                                             deref(_opts)))
+ *     if _symbols.get() == NULL:             # <<<<<<<<<<<<<<
+ *       raise FstIOError(f"Read failed: {source!r}")
+ *     return _init_SymbolTable(move(_symbols))
  */
   }
 
-  /* "pywrapfst.pyx":1079
- *     if syms.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(source))
- *     return _init_SymbolTable(move(syms))             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1138
+ *     if _symbols.get() == NULL:
+ *       raise FstIOError(f"Read failed: {source!r}")
+ *     return _init_SymbolTable(move(_symbols))             # <<<<<<<<<<<<<<
  * 
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::move<std::unique_ptr<fst::SymbolTable> >(__pyx_v_syms))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1079, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::move<std::unique_ptr<fst::SymbolTable> >(__pyx_v__symbols))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1138, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1057
+  /* "pywrapfst.pyx":1115
  * 
  *   @classmethod
  *   def read_text(cls, source, bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
@@ -12908,7 +13152,6 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_AddTraceback("pywrapfst.SymbolTable.read_text", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -12917,7 +13160,7 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_6read_text(CYTHON_UNUSED PyTy
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1082
+/* "pywrapfst.pyx":1141
  * 
  *   @classmethod
  *   def read_fst(cls, source, bool input_table):             # <<<<<<<<<<<<<<
@@ -12931,6 +13174,9 @@ static char __pyx_doc_9pywrapfst_11SymbolTable_8read_fst[] = "\n    SymbolTable.
 static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_9read_fst(PyObject *__pyx_v_cls, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_source = 0;
   bool __pyx_v_input_table;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("read_fst (wrapper)", 0);
@@ -12957,11 +13203,11 @@ static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_9read_fst(PyObject *__pyx_v_c
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_input_table)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("read_fst", 1, 2, 2, 1); __PYX_ERR(0, 1082, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("read_fst", 1, 2, 2, 1); __PYX_ERR(0, 1141, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_fst") < 0)) __PYX_ERR(0, 1082, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_fst") < 0)) __PYX_ERR(0, 1141, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -12970,11 +13216,11 @@ static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_9read_fst(PyObject *__pyx_v_c
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
     __pyx_v_source = values[0];
-    __pyx_v_input_table = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_input_table == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1082, __pyx_L3_error)
+    __pyx_v_input_table = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_input_table == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1141, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("read_fst", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1082, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("read_fst", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1141, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.SymbolTable.read_fst", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -12988,7 +13234,7 @@ static PyObject *__pyx_pw_9pywrapfst_11SymbolTable_9read_fst(PyObject *__pyx_v_c
 }
 
 static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source, bool __pyx_v_input_table) {
-  std::unique_ptr<fst::SymbolTable>  __pyx_v_syms;
+  std::unique_ptr<fst::SymbolTable>  __pyx_v__symbols;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
@@ -12997,99 +13243,89 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("read_fst", 0);
 
-  /* "pywrapfst.pyx":1103
+  /* "pywrapfst.pyx":1162
  *     """
- *     cdef unique_ptr[fst.SymbolTable] syms
- *     syms.reset(fst.FstReadSymbols(tostring(source), input_table))             # <<<<<<<<<<<<<<
- *     if syms.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(source))
+ *     cdef unique_ptr[fst.SymbolTable] _symbols
+ *     _symbols.reset(fst.FstReadSymbols(path_tostring(source), input_table))             # <<<<<<<<<<<<<<
+ *     if _symbols.get() == NULL:
+ *       raise FstIOError(f"Read from FST failed: {source!r}")
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1103, __pyx_L1_error)
-  __pyx_v_syms.reset(fst::FstReadSymbols(__pyx_t_1, __pyx_v_input_table));
+  __pyx_t_1 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1162, __pyx_L1_error)
+  __pyx_v__symbols.reset(fst::FstReadSymbols(__pyx_t_1, __pyx_v_input_table));
 
-  /* "pywrapfst.pyx":1104
- *     cdef unique_ptr[fst.SymbolTable] syms
- *     syms.reset(fst.FstReadSymbols(tostring(source), input_table))
- *     if syms.get() == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Read failed: {!r}".format(source))
- *     return _init_SymbolTable(move(syms))
+  /* "pywrapfst.pyx":1163
+ *     cdef unique_ptr[fst.SymbolTable] _symbols
+ *     _symbols.reset(fst.FstReadSymbols(path_tostring(source), input_table))
+ *     if _symbols.get() == NULL:             # <<<<<<<<<<<<<<
+ *       raise FstIOError(f"Read from FST failed: {source!r}")
+ *     return _init_SymbolTable(move(_symbols))
  */
-  __pyx_t_2 = ((__pyx_v_syms.get() == NULL) != 0);
+  __pyx_t_2 = ((__pyx_v__symbols.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1105
- *     syms.reset(fst.FstReadSymbols(tostring(source), input_table))
- *     if syms.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(source))             # <<<<<<<<<<<<<<
- *     return _init_SymbolTable(move(syms))
+    /* "pywrapfst.pyx":1164
+ *     _symbols.reset(fst.FstReadSymbols(path_tostring(source), input_table))
+ *     if _symbols.get() == NULL:
+ *       raise FstIOError(f"Read from FST failed: {source!r}")             # <<<<<<<<<<<<<<
+ *     return _init_SymbolTable(move(_symbols))
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1105, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1164, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1105, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
-        __Pyx_INCREF(__pyx_t_7);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_6, function);
-      }
-    }
-    __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_source);
-    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1105, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1164, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = NULL;
+    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Read_from_FST_failed, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1164, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
-      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
-      if (likely(__pyx_t_6)) {
+      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+      if (likely(__pyx_t_5)) {
         PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-        __Pyx_INCREF(__pyx_t_6);
+        __Pyx_INCREF(__pyx_t_5);
         __Pyx_INCREF(function);
         __Pyx_DECREF_SET(__pyx_t_4, function);
       }
     }
-    __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1105, __pyx_L1_error)
+    __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
+    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1164, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1105, __pyx_L1_error)
+    __PYX_ERR(0, 1164, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1104
- *     cdef unique_ptr[fst.SymbolTable] syms
- *     syms.reset(fst.FstReadSymbols(tostring(source), input_table))
- *     if syms.get() == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Read failed: {!r}".format(source))
- *     return _init_SymbolTable(move(syms))
+    /* "pywrapfst.pyx":1163
+ *     cdef unique_ptr[fst.SymbolTable] _symbols
+ *     _symbols.reset(fst.FstReadSymbols(path_tostring(source), input_table))
+ *     if _symbols.get() == NULL:             # <<<<<<<<<<<<<<
+ *       raise FstIOError(f"Read from FST failed: {source!r}")
+ *     return _init_SymbolTable(move(_symbols))
  */
   }
 
-  /* "pywrapfst.pyx":1106
- *     if syms.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(source))
- *     return _init_SymbolTable(move(syms))             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1165
+ *     if _symbols.get() == NULL:
+ *       raise FstIOError(f"Read from FST failed: {source!r}")
+ *     return _init_SymbolTable(move(_symbols))             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::move<std::unique_ptr<fst::SymbolTable> >(__pyx_v_syms))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1106, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::move<std::unique_ptr<fst::SymbolTable> >(__pyx_v__symbols))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1165, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1082
+  /* "pywrapfst.pyx":1141
  * 
  *   @classmethod
  *   def read_fst(cls, source, bool input_table):             # <<<<<<<<<<<<<<
@@ -13103,7 +13339,6 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_AddTraceback("pywrapfst.SymbolTable.read_fst", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -13112,77 +13347,80 @@ static PyObject *__pyx_pf_9pywrapfst_11SymbolTable_8read_fst(CYTHON_UNUSED PyTyp
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1109
+/* "pywrapfst.pyx":1168
  * 
  * 
  * cdef _EncodeMapperSymbolTableView _init_EncodeMapperSymbolTableView(             # <<<<<<<<<<<<<<
  *     shared_ptr[fst.EncodeMapperClass] mapper, bool input_side):
- *   cdef _EncodeMapperSymbolTableView result = (
+ *   cdef _EncodeMapperSymbolTableView _symbols = (
  */
 
 static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrapfst__init_EncodeMapperSymbolTableView(std::shared_ptr<fst::script::EncodeMapperClass>  __pyx_v_mapper, bool __pyx_v_input_side) {
-  struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_v_result = 0;
+  struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_v__symbols = 0;
   struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_init_EncodeMapperSymbolTableView", 0);
 
-  /* "pywrapfst.pyx":1112
+  /* "pywrapfst.pyx":1171
  *     shared_ptr[fst.EncodeMapperClass] mapper, bool input_side):
- *   cdef _EncodeMapperSymbolTableView result = (
+ *   cdef _EncodeMapperSymbolTableView _symbols = (
  *       _EncodeMapperSymbolTableView.__new__(_EncodeMapperSymbolTableView))             # <<<<<<<<<<<<<<
- *   result._mapper = move(mapper)
- *   result._input_side = input_side
+ *   _symbols._mapper = move(mapper)
+ *   _symbols._input_side = input_side
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst__EncodeMapperSymbolTableView(((PyTypeObject *)__pyx_ptype_9pywrapfst__EncodeMapperSymbolTableView), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1112, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst__EncodeMapperSymbolTableView(((PyTypeObject *)__pyx_ptype_9pywrapfst__EncodeMapperSymbolTableView), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1171, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_v_result = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)__pyx_t_1);
+  __pyx_v__symbols = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1113
- *   cdef _EncodeMapperSymbolTableView result = (
+  /* "pywrapfst.pyx":1172
+ *   cdef _EncodeMapperSymbolTableView _symbols = (
  *       _EncodeMapperSymbolTableView.__new__(_EncodeMapperSymbolTableView))
- *   result._mapper = move(mapper)             # <<<<<<<<<<<<<<
- *   result._input_side = input_side
- *   return result
+ *   _symbols._mapper = move(mapper)             # <<<<<<<<<<<<<<
+ *   _symbols._input_side = input_side
+ *   return _symbols
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1113, __pyx_L1_error)
+    __PYX_ERR(0, 1172, __pyx_L1_error)
   }
-  __pyx_v_result->_mapper = fst::move<std::shared_ptr<fst::script::EncodeMapperClass> >(__pyx_v_mapper);
+  __pyx_v__symbols->_mapper = fst::move<std::shared_ptr<fst::script::EncodeMapperClass> >(__pyx_v_mapper);
 
-  /* "pywrapfst.pyx":1114
+  /* "pywrapfst.pyx":1173
  *       _EncodeMapperSymbolTableView.__new__(_EncodeMapperSymbolTableView))
- *   result._mapper = move(mapper)
- *   result._input_side = input_side             # <<<<<<<<<<<<<<
- *   return result
+ *   _symbols._mapper = move(mapper)
+ *   _symbols._input_side = input_side             # <<<<<<<<<<<<<<
+ *   return _symbols
  * 
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_input_side");
-    __PYX_ERR(0, 1114, __pyx_L1_error)
+    __PYX_ERR(0, 1173, __pyx_L1_error)
   }
-  __pyx_v_result->_input_side = __pyx_v_input_side;
+  __pyx_v__symbols->_input_side = __pyx_v_input_side;
 
-  /* "pywrapfst.pyx":1115
- *   result._mapper = move(mapper)
- *   result._input_side = input_side
- *   return result             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1174
+ *   _symbols._mapper = move(mapper)
+ *   _symbols._input_side = input_side
+ *   return _symbols             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __Pyx_INCREF(((PyObject *)__pyx_v_result));
-  __pyx_r = __pyx_v_result;
+  __Pyx_INCREF(((PyObject *)__pyx_v__symbols));
+  __pyx_r = __pyx_v__symbols;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1109
+  /* "pywrapfst.pyx":1168
  * 
  * 
  * cdef _EncodeMapperSymbolTableView _init_EncodeMapperSymbolTableView(             # <<<<<<<<<<<<<<
  *     shared_ptr[fst.EncodeMapperClass] mapper, bool input_side):
- *   cdef _EncodeMapperSymbolTableView result = (
+ *   cdef _EncodeMapperSymbolTableView _symbols = (
  */
 
   /* function exit code */
@@ -13191,83 +13429,86 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
   __Pyx_AddTraceback("pywrapfst._init_EncodeMapperSymbolTableView", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_result);
+  __Pyx_XDECREF((PyObject *)__pyx_v__symbols);
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1118
+/* "pywrapfst.pyx":1177
  * 
  * 
  * cdef _FstSymbolTableView _init_FstSymbolTableView(shared_ptr[fst.FstClass] ifst,             # <<<<<<<<<<<<<<
  *                                                   bool input_side):
- *   cdef _FstSymbolTableView result = (
+ *   cdef _FstSymbolTableView _symbols = (
  */
 
 static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst__init_FstSymbolTableView(std::shared_ptr<fst::script::FstClass>  __pyx_v_ifst, bool __pyx_v_input_side) {
-  struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_v_result = 0;
+  struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_v__symbols = 0;
   struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_init_FstSymbolTableView", 0);
 
-  /* "pywrapfst.pyx":1121
+  /* "pywrapfst.pyx":1180
  *                                                   bool input_side):
- *   cdef _FstSymbolTableView result = (
+ *   cdef _FstSymbolTableView _symbols = (
  *       _FstSymbolTableView.__new__(_FstSymbolTableView))             # <<<<<<<<<<<<<<
- *   result._fst = move(ifst)
- *   result._input_side = input_side
+ *   _symbols._fst = move(ifst)
+ *   _symbols._input_side = input_side
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst__FstSymbolTableView(((PyTypeObject *)__pyx_ptype_9pywrapfst__FstSymbolTableView), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1121, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst__FstSymbolTableView(((PyTypeObject *)__pyx_ptype_9pywrapfst__FstSymbolTableView), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1180, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_v_result = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)__pyx_t_1);
+  __pyx_v__symbols = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1122
- *   cdef _FstSymbolTableView result = (
+  /* "pywrapfst.pyx":1181
+ *   cdef _FstSymbolTableView _symbols = (
  *       _FstSymbolTableView.__new__(_FstSymbolTableView))
- *   result._fst = move(ifst)             # <<<<<<<<<<<<<<
- *   result._input_side = input_side
- *   return result
+ *   _symbols._fst = move(ifst)             # <<<<<<<<<<<<<<
+ *   _symbols._input_side = input_side
+ *   return _symbols
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1122, __pyx_L1_error)
+    __PYX_ERR(0, 1181, __pyx_L1_error)
   }
-  __pyx_v_result->_fst = fst::move<std::shared_ptr<fst::script::FstClass> >(__pyx_v_ifst);
+  __pyx_v__symbols->_fst = fst::move<std::shared_ptr<fst::script::FstClass> >(__pyx_v_ifst);
 
-  /* "pywrapfst.pyx":1123
+  /* "pywrapfst.pyx":1182
  *       _FstSymbolTableView.__new__(_FstSymbolTableView))
- *   result._fst = move(ifst)
- *   result._input_side = input_side             # <<<<<<<<<<<<<<
- *   return result
+ *   _symbols._fst = move(ifst)
+ *   _symbols._input_side = input_side             # <<<<<<<<<<<<<<
+ *   return _symbols
  * 
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_input_side");
-    __PYX_ERR(0, 1123, __pyx_L1_error)
+    __PYX_ERR(0, 1182, __pyx_L1_error)
   }
-  __pyx_v_result->_input_side = __pyx_v_input_side;
+  __pyx_v__symbols->_input_side = __pyx_v_input_side;
 
-  /* "pywrapfst.pyx":1124
- *   result._fst = move(ifst)
- *   result._input_side = input_side
- *   return result             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1183
+ *   _symbols._fst = move(ifst)
+ *   _symbols._input_side = input_side
+ *   return _symbols             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __Pyx_INCREF(((PyObject *)__pyx_v_result));
-  __pyx_r = __pyx_v_result;
+  __Pyx_INCREF(((PyObject *)__pyx_v__symbols));
+  __pyx_r = __pyx_v__symbols;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1118
+  /* "pywrapfst.pyx":1177
  * 
  * 
  * cdef _FstSymbolTableView _init_FstSymbolTableView(shared_ptr[fst.FstClass] ifst,             # <<<<<<<<<<<<<<
  *                                                   bool input_side):
- *   cdef _FstSymbolTableView result = (
+ *   cdef _FstSymbolTableView _symbols = (
  */
 
   /* function exit code */
@@ -13276,13 +13517,13 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst__init
   __Pyx_AddTraceback("pywrapfst._init_FstSymbolTableView", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_result);
+  __Pyx_XDECREF((PyObject *)__pyx_v__symbols);
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1127
+/* "pywrapfst.pyx":1186
  * 
  * 
  * cdef _MutableFstSymbolTableView _init_MutableFstSymbolTableView(             # <<<<<<<<<<<<<<
@@ -13291,63 +13532,66 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst__init
  */
 
 static struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *__pyx_f_9pywrapfst__init_MutableFstSymbolTableView(std::shared_ptr<fst::script::MutableFstClass>  __pyx_v_ifst, bool __pyx_v_input_side) {
-  struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *__pyx_v_result = 0;
+  struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *__pyx_v__symbols = 0;
   struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_init_MutableFstSymbolTableView", 0);
 
-  /* "pywrapfst.pyx":1131
+  /* "pywrapfst.pyx":1190
  *                                     bool input_side):
- *   cdef _MutableFstSymbolTableView result = (
+ *   cdef _MutableFstSymbolTableView _symbols = (
  *       _MutableFstSymbolTableView.__new__(_MutableFstSymbolTableView))             # <<<<<<<<<<<<<<
- *   result._mfst = move(ifst)
- *   result._input_side = input_side
+ *   _symbols._mfst = move(ifst)
+ *   _symbols._input_side = input_side
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst__MutableFstSymbolTableView(((PyTypeObject *)__pyx_ptype_9pywrapfst__MutableFstSymbolTableView), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1131, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst__MutableFstSymbolTableView(((PyTypeObject *)__pyx_ptype_9pywrapfst__MutableFstSymbolTableView), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1190, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_v_result = ((struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *)__pyx_t_1);
+  __pyx_v__symbols = ((struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1132
- *   cdef _MutableFstSymbolTableView result = (
+  /* "pywrapfst.pyx":1191
+ *   cdef _MutableFstSymbolTableView _symbols = (
  *       _MutableFstSymbolTableView.__new__(_MutableFstSymbolTableView))
- *   result._mfst = move(ifst)             # <<<<<<<<<<<<<<
- *   result._input_side = input_side
- *   return result
+ *   _symbols._mfst = move(ifst)             # <<<<<<<<<<<<<<
+ *   _symbols._input_side = input_side
+ *   return _symbols
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 1132, __pyx_L1_error)
+    __PYX_ERR(0, 1191, __pyx_L1_error)
   }
-  __pyx_v_result->_mfst = fst::move<std::shared_ptr<fst::script::MutableFstClass> >(__pyx_v_ifst);
+  __pyx_v__symbols->_mfst = fst::move<std::shared_ptr<fst::script::MutableFstClass> >(__pyx_v_ifst);
 
-  /* "pywrapfst.pyx":1133
+  /* "pywrapfst.pyx":1192
  *       _MutableFstSymbolTableView.__new__(_MutableFstSymbolTableView))
- *   result._mfst = move(ifst)
- *   result._input_side = input_side             # <<<<<<<<<<<<<<
- *   return result
+ *   _symbols._mfst = move(ifst)
+ *   _symbols._input_side = input_side             # <<<<<<<<<<<<<<
+ *   return _symbols
  * 
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_input_side");
-    __PYX_ERR(0, 1133, __pyx_L1_error)
+    __PYX_ERR(0, 1192, __pyx_L1_error)
   }
-  __pyx_v_result->_input_side = __pyx_v_input_side;
+  __pyx_v__symbols->_input_side = __pyx_v_input_side;
 
-  /* "pywrapfst.pyx":1134
- *   result._mfst = move(ifst)
- *   result._input_side = input_side
- *   return result             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1193
+ *   _symbols._mfst = move(ifst)
+ *   _symbols._input_side = input_side
+ *   return _symbols             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __Pyx_INCREF(((PyObject *)__pyx_v_result));
-  __pyx_r = __pyx_v_result;
+  __Pyx_INCREF(((PyObject *)__pyx_v__symbols));
+  __pyx_r = __pyx_v__symbols;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1127
+  /* "pywrapfst.pyx":1186
  * 
  * 
  * cdef _MutableFstSymbolTableView _init_MutableFstSymbolTableView(             # <<<<<<<<<<<<<<
@@ -13361,70 +13605,73 @@ static struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *__pyx_f_9pywrapfs
   __Pyx_AddTraceback("pywrapfst._init_MutableFstSymbolTableView", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_result);
+  __Pyx_XDECREF((PyObject *)__pyx_v__symbols);
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1137
+/* "pywrapfst.pyx":1196
  * 
  * 
- * cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] table):             # <<<<<<<<<<<<<<
- *   cdef SymbolTable result = SymbolTable.__new__(SymbolTable)
- *   result._smart_table = move(table)
+ * cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] symbols):             # <<<<<<<<<<<<<<
+ *   cdef SymbolTable _symbols = SymbolTable.__new__(SymbolTable)
+ *   _symbols._smart_table = move(symbols)
  */
 
-static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__init_SymbolTable(std::unique_ptr<fst::SymbolTable>  __pyx_v_table) {
-  struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_result = 0;
+static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__init_SymbolTable(std::unique_ptr<fst::SymbolTable>  __pyx_v_symbols) {
+  struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v__symbols = 0;
   struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_init_SymbolTable", 0);
 
-  /* "pywrapfst.pyx":1138
+  /* "pywrapfst.pyx":1197
  * 
- * cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] table):
- *   cdef SymbolTable result = SymbolTable.__new__(SymbolTable)             # <<<<<<<<<<<<<<
- *   result._smart_table = move(table)
- *   return result
+ * cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] symbols):
+ *   cdef SymbolTable _symbols = SymbolTable.__new__(SymbolTable)             # <<<<<<<<<<<<<<
+ *   _symbols._smart_table = move(symbols)
+ *   return _symbols
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_SymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst_SymbolTable), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1138, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_SymbolTable(((PyTypeObject *)__pyx_ptype_9pywrapfst_SymbolTable), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1197, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_v_result = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_1);
+  __pyx_v__symbols = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1139
- * cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] table):
- *   cdef SymbolTable result = SymbolTable.__new__(SymbolTable)
- *   result._smart_table = move(table)             # <<<<<<<<<<<<<<
- *   return result
+  /* "pywrapfst.pyx":1198
+ * cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] symbols):
+ *   cdef SymbolTable _symbols = SymbolTable.__new__(SymbolTable)
+ *   _symbols._smart_table = move(symbols)             # <<<<<<<<<<<<<<
+ *   return _symbols
  * 
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_smart_table");
-    __PYX_ERR(0, 1139, __pyx_L1_error)
+    __PYX_ERR(0, 1198, __pyx_L1_error)
   }
-  __pyx_v_result->_smart_table = fst::move<std::unique_ptr<fst::SymbolTable> >(__pyx_v_table);
+  __pyx_v__symbols->_smart_table = fst::move<std::unique_ptr<fst::SymbolTable> >(__pyx_v_symbols);
 
-  /* "pywrapfst.pyx":1140
- *   cdef SymbolTable result = SymbolTable.__new__(SymbolTable)
- *   result._smart_table = move(table)
- *   return result             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1199
+ *   cdef SymbolTable _symbols = SymbolTable.__new__(SymbolTable)
+ *   _symbols._smart_table = move(symbols)
+ *   return _symbols             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __Pyx_INCREF(((PyObject *)__pyx_v_result));
-  __pyx_r = __pyx_v_result;
+  __Pyx_INCREF(((PyObject *)__pyx_v__symbols));
+  __pyx_r = __pyx_v__symbols;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1137
+  /* "pywrapfst.pyx":1196
  * 
  * 
- * cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] table):             # <<<<<<<<<<<<<<
- *   cdef SymbolTable result = SymbolTable.__new__(SymbolTable)
- *   result._smart_table = move(table)
+ * cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] symbols):             # <<<<<<<<<<<<<<
+ *   cdef SymbolTable _symbols = SymbolTable.__new__(SymbolTable)
+ *   _symbols._smart_table = move(symbols)
  */
 
   /* function exit code */
@@ -13433,126 +13680,127 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__init_SymbolT
   __Pyx_AddTraceback("pywrapfst._init_SymbolTable", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_result);
+  __Pyx_XDECREF((PyObject *)__pyx_v__symbols);
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1143
+/* "pywrapfst.pyx":1202
  * 
  * 
- * cpdef SymbolTable _read_SymbolTable_from_string(state):             # <<<<<<<<<<<<<<
- *   cdef stringstream sstrm
- *   sstrm << tostring(state)
+ * cpdef SymbolTable _read_SymbolTable_from_string(string state):             # <<<<<<<<<<<<<<
+ *   cdef stringstream _sstrm
+ *   _sstrm << state
  */
 
-static PyObject *__pyx_pw_9pywrapfst_9_read_SymbolTable_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state); /*proto*/
-static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolTable_from_string(PyObject *__pyx_v_state, CYTHON_UNUSED int __pyx_skip_dispatch) {
-  std::stringstream __pyx_v_sstrm;
-  std::unique_ptr<fst::SymbolTable>  __pyx_v_syms;
+static PyObject *__pyx_pw_9pywrapfst_9_read_SymbolTable_from_string(PyObject *__pyx_self, PyObject *__pyx_arg_state); /*proto*/
+static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolTable_from_string(std::string __pyx_v_state, CYTHON_UNUSED int __pyx_skip_dispatch) {
+  std::stringstream __pyx_v__sstrm;
+  std::unique_ptr<fst::SymbolTable>  __pyx_v__symbols;
   struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  std::string __pyx_t_1;
-  int __pyx_t_2;
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_read_SymbolTable_from_string", 0);
 
-  /* "pywrapfst.pyx":1145
- * cpdef SymbolTable _read_SymbolTable_from_string(state):
- *   cdef stringstream sstrm
- *   sstrm << tostring(state)             # <<<<<<<<<<<<<<
- *   cdef unique_ptr[fst.SymbolTable] syms
- *   syms.reset(fst.SymbolTable.ReadStream(sstrm, b"<pywrapfst>"))
- */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1145, __pyx_L1_error)
-  (void)((__pyx_v_sstrm << __pyx_t_1));
-
-  /* "pywrapfst.pyx":1147
- *   sstrm << tostring(state)
- *   cdef unique_ptr[fst.SymbolTable] syms
- *   syms.reset(fst.SymbolTable.ReadStream(sstrm, b"<pywrapfst>"))             # <<<<<<<<<<<<<<
- *   if syms.get() == NULL:
- *     raise FstIOError("Read failed")
- */
-  __pyx_v_syms.reset(fst::SymbolTable::Read(__pyx_v_sstrm, __pyx_k_pywrapfst));
-
-  /* "pywrapfst.pyx":1148
- *   cdef unique_ptr[fst.SymbolTable] syms
- *   syms.reset(fst.SymbolTable.ReadStream(sstrm, b"<pywrapfst>"))
- *   if syms.get() == NULL:             # <<<<<<<<<<<<<<
- *     raise FstIOError("Read failed")
- *   return _init_SymbolTable(move(syms))
- */
-  __pyx_t_2 = ((__pyx_v_syms.get() == NULL) != 0);
-  if (unlikely(__pyx_t_2)) {
+  /* "pywrapfst.pyx":1204
+ * cpdef SymbolTable _read_SymbolTable_from_string(string state):
+ *   cdef stringstream _sstrm
+ *   _sstrm << state             # <<<<<<<<<<<<<<
+ *   cdef unique_ptr[fst.SymbolTable] _symbols
+ *   _symbols.reset(fst.SymbolTable.ReadStream(_sstrm, b"<pywrapfst>"))
+ */
+  (void)((__pyx_v__sstrm << __pyx_v_state));
 
-    /* "pywrapfst.pyx":1149
- *   syms.reset(fst.SymbolTable.ReadStream(sstrm, b"<pywrapfst>"))
- *   if syms.get() == NULL:
- *     raise FstIOError("Read failed")             # <<<<<<<<<<<<<<
- *   return _init_SymbolTable(move(syms))
+  /* "pywrapfst.pyx":1206
+ *   _sstrm << state
+ *   cdef unique_ptr[fst.SymbolTable] _symbols
+ *   _symbols.reset(fst.SymbolTable.ReadStream(_sstrm, b"<pywrapfst>"))             # <<<<<<<<<<<<<<
+ *   if _symbols.get() == NULL:
+ *     raise FstIOError("Read from string failed")
+ */
+  __pyx_v__symbols.reset(fst::SymbolTable::Read(__pyx_v__sstrm, __pyx_k_pywrapfst));
+
+  /* "pywrapfst.pyx":1207
+ *   cdef unique_ptr[fst.SymbolTable] _symbols
+ *   _symbols.reset(fst.SymbolTable.ReadStream(_sstrm, b"<pywrapfst>"))
+ *   if _symbols.get() == NULL:             # <<<<<<<<<<<<<<
+ *     raise FstIOError("Read from string failed")
+ *   return _init_SymbolTable(move(_symbols))
+ */
+  __pyx_t_1 = ((__pyx_v__symbols.get() == NULL) != 0);
+  if (unlikely(__pyx_t_1)) {
+
+    /* "pywrapfst.pyx":1208
+ *   _symbols.reset(fst.SymbolTable.ReadStream(_sstrm, b"<pywrapfst>"))
+ *   if _symbols.get() == NULL:
+ *     raise FstIOError("Read from string failed")             # <<<<<<<<<<<<<<
+ *   return _init_SymbolTable(move(_symbols))
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1149, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = NULL;
-    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
-      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
-      if (likely(__pyx_t_5)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-        __Pyx_INCREF(__pyx_t_5);
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1208, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = NULL;
+    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
+      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+      if (likely(__pyx_t_4)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+        __Pyx_INCREF(__pyx_t_4);
         __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_4, function);
+        __Pyx_DECREF_SET(__pyx_t_3, function);
       }
     }
-    __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_Read_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_Read_failed);
-    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1149, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Read_from_string_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Read_from_string_failed);
+    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1208, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1149, __pyx_L1_error)
+    __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __PYX_ERR(0, 1208, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1148
- *   cdef unique_ptr[fst.SymbolTable] syms
- *   syms.reset(fst.SymbolTable.ReadStream(sstrm, b"<pywrapfst>"))
- *   if syms.get() == NULL:             # <<<<<<<<<<<<<<
- *     raise FstIOError("Read failed")
- *   return _init_SymbolTable(move(syms))
+    /* "pywrapfst.pyx":1207
+ *   cdef unique_ptr[fst.SymbolTable] _symbols
+ *   _symbols.reset(fst.SymbolTable.ReadStream(_sstrm, b"<pywrapfst>"))
+ *   if _symbols.get() == NULL:             # <<<<<<<<<<<<<<
+ *     raise FstIOError("Read from string failed")
+ *   return _init_SymbolTable(move(_symbols))
  */
   }
 
-  /* "pywrapfst.pyx":1150
- *   if syms.get() == NULL:
- *     raise FstIOError("Read failed")
- *   return _init_SymbolTable(move(syms))             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1209
+ *   if _symbols.get() == NULL:
+ *     raise FstIOError("Read from string failed")
+ *   return _init_SymbolTable(move(_symbols))             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::move<std::unique_ptr<fst::SymbolTable> >(__pyx_v_syms))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1150, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_3);
-  __pyx_t_3 = 0;
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::move<std::unique_ptr<fst::SymbolTable> >(__pyx_v__symbols))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1209, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_2);
+  __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1143
+  /* "pywrapfst.pyx":1202
  * 
  * 
- * cpdef SymbolTable _read_SymbolTable_from_string(state):             # <<<<<<<<<<<<<<
- *   cdef stringstream sstrm
- *   sstrm << tostring(state)
+ * cpdef SymbolTable _read_SymbolTable_from_string(string state):             # <<<<<<<<<<<<<<
+ *   cdef stringstream _sstrm
+ *   _sstrm << state
  */
 
   /* function exit code */
   __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
   __Pyx_AddTraceback("pywrapfst._read_SymbolTable_from_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
@@ -13562,25 +13810,41 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst__read_SymbolT
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_9_read_SymbolTable_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_9_read_SymbolTable_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state) {
+static PyObject *__pyx_pw_9pywrapfst_9_read_SymbolTable_from_string(PyObject *__pyx_self, PyObject *__pyx_arg_state); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_9_read_SymbolTable_from_string(PyObject *__pyx_self, PyObject *__pyx_arg_state) {
+  std::string __pyx_v_state;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_read_SymbolTable_from_string (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_8_read_SymbolTable_from_string(__pyx_self, ((PyObject *)__pyx_v_state));
+  assert(__pyx_arg_state); {
+    __pyx_v_state = __pyx_convert_string_from_py_std__in_string(__pyx_arg_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1202, __pyx_L3_error)
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("pywrapfst._read_SymbolTable_from_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_9pywrapfst_8_read_SymbolTable_from_string(__pyx_self, ((std::string)__pyx_v_state));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_8_read_SymbolTable_from_string(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_state) {
+static PyObject *__pyx_pf_9pywrapfst_8_read_SymbolTable_from_string(CYTHON_UNUSED PyObject *__pyx_self, std::string __pyx_v_state) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_read_SymbolTable_from_string", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_SymbolTable_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1143, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_SymbolTable_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1202, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -13597,63 +13861,66 @@ static PyObject *__pyx_pf_9pywrapfst_8_read_SymbolTable_from_string(CYTHON_UNUSE
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1156
+/* "pywrapfst.pyx":1215
  * 
  * 
- * cpdef SymbolTable compact_symbol_table(_SymbolTable syms):             # <<<<<<<<<<<<<<
+ * cpdef SymbolTable compact_symbol_table(SymbolTableView symbols):             # <<<<<<<<<<<<<<
  *   """
- *   compact_symbol_table(syms)
+ *   compact_symbol_table(symbols)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_11compact_symbol_table(PyObject *__pyx_self, PyObject *__pyx_v_syms); /*proto*/
-static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_compact_symbol_table(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms, CYTHON_UNUSED int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_9pywrapfst_11compact_symbol_table(PyObject *__pyx_self, PyObject *__pyx_v_symbols); /*proto*/
+static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_compact_symbol_table(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols, CYTHON_UNUSED int __pyx_skip_dispatch) {
   struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   fst::SymbolTable const *__pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("compact_symbol_table", 0);
 
-  /* "pywrapfst.pyx":1168
+  /* "pywrapfst.pyx":1227
  *     A new compacted SymbolTable.
  *   """
  *   return _init_SymbolTable(WrapUnique(fst.CompactSymbolTable(             # <<<<<<<<<<<<<<
- *                                           deref(syms._raw_ptr_or_raise()))))
+ *                                           deref(symbols._raw_ptr_or_raise()))))
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
 
-  /* "pywrapfst.pyx":1169
+  /* "pywrapfst.pyx":1228
  *   """
  *   return _init_SymbolTable(WrapUnique(fst.CompactSymbolTable(
- *                                           deref(syms._raw_ptr_or_raise()))))             # <<<<<<<<<<<<<<
+ *                                           deref(symbols._raw_ptr_or_raise()))))             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v_symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 1169, __pyx_L1_error)
+    __PYX_ERR(0, 1228, __pyx_L1_error)
   }
-  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_syms->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_syms); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1169, __pyx_L1_error)
+  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_symbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1228, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1168
+  /* "pywrapfst.pyx":1227
  *     A new compacted SymbolTable.
  *   """
  *   return _init_SymbolTable(WrapUnique(fst.CompactSymbolTable(             # <<<<<<<<<<<<<<
- *                                           deref(syms._raw_ptr_or_raise()))))
+ *                                           deref(symbols._raw_ptr_or_raise()))))
  * 
  */
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::WrapUnique<fst::SymbolTable>(fst::CompactSymbolTable((*__pyx_t_1))))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1168, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::WrapUnique<fst::SymbolTable>(fst::CompactSymbolTable((*__pyx_t_1))))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1227, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_2);
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1156
+  /* "pywrapfst.pyx":1215
  * 
  * 
- * cpdef SymbolTable compact_symbol_table(_SymbolTable syms):             # <<<<<<<<<<<<<<
+ * cpdef SymbolTable compact_symbol_table(SymbolTableView symbols):             # <<<<<<<<<<<<<<
  *   """
- *   compact_symbol_table(syms)
+ *   compact_symbol_table(symbols)
  */
 
   /* function exit code */
@@ -13668,14 +13935,17 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_compact_symbo
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_11compact_symbol_table(PyObject *__pyx_self, PyObject *__pyx_v_syms); /*proto*/
-static char __pyx_doc_9pywrapfst_10compact_symbol_table[] = "\n  compact_symbol_table(syms)\n\n  Constructively relabels a SymbolTable to make it a contiguous mapping.\n\n  Args:\n    syms: Input SymbolTable.\n\n  Returns:\n    A new compacted SymbolTable.\n  ";
-static PyObject *__pyx_pw_9pywrapfst_11compact_symbol_table(PyObject *__pyx_self, PyObject *__pyx_v_syms) {
+static PyObject *__pyx_pw_9pywrapfst_11compact_symbol_table(PyObject *__pyx_self, PyObject *__pyx_v_symbols); /*proto*/
+static char __pyx_doc_9pywrapfst_10compact_symbol_table[] = "\n  compact_symbol_table(symbols)\n\n  Constructively relabels a SymbolTable to make it a contiguous mapping.\n\n  Args:\n    symbols: Input SymbolTable.\n\n  Returns:\n    A new compacted SymbolTable.\n  ";
+static PyObject *__pyx_pw_9pywrapfst_11compact_symbol_table(PyObject *__pyx_self, PyObject *__pyx_v_symbols) {
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("compact_symbol_table (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 1156, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_10compact_symbol_table(__pyx_self, ((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_syms));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_symbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "symbols", 0))) __PYX_ERR(0, 1215, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_10compact_symbol_table(__pyx_self, ((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_symbols));
 
   /* function exit code */
   goto __pyx_L0;
@@ -13686,13 +13956,16 @@ static PyObject *__pyx_pw_9pywrapfst_11compact_symbol_table(PyObject *__pyx_self
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_10compact_symbol_table(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
+static PyObject *__pyx_pf_9pywrapfst_10compact_symbol_table(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("compact_symbol_table", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_compact_symbol_table(__pyx_v_syms, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1156, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_compact_symbol_table(__pyx_v_symbols, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1215, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -13709,24 +13982,27 @@ static PyObject *__pyx_pf_9pywrapfst_10compact_symbol_table(CYTHON_UNUSED PyObje
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1172
+/* "pywrapfst.pyx":1231
  * 
  * 
- * cpdef SymbolTable merge_symbol_table(_SymbolTable lhs, _SymbolTable rhs):             # <<<<<<<<<<<<<<
+ * cpdef SymbolTable merge_symbol_table(SymbolTableView lhs,             # <<<<<<<<<<<<<<
+ *                                      SymbolTableView rhs):
  *   """
- *   merge_symbol_table(lhs, rhs)
  */
 
 static PyObject *__pyx_pw_9pywrapfst_13merge_symbol_table(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_merge_symbol_table(struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_lhs, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_rhs, CYTHON_UNUSED int __pyx_skip_dispatch) {
+static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_merge_symbol_table(struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_lhs, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_rhs, CYTHON_UNUSED int __pyx_skip_dispatch) {
   struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   fst::SymbolTable const *__pyx_t_1;
   fst::SymbolTable const *__pyx_t_2;
   PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("merge_symbol_table", 0);
 
-  /* "pywrapfst.pyx":1194
+  /* "pywrapfst.pyx":1254
  *     A new merged SymbolTable.
  *   """
  *   return _init_SymbolTable(WrapUnique(fst.MergeSymbolTable(             # <<<<<<<<<<<<<<
@@ -13735,7 +14011,7 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_merge_symbol_
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
 
-  /* "pywrapfst.pyx":1195
+  /* "pywrapfst.pyx":1255
  *   """
  *   return _init_SymbolTable(WrapUnique(fst.MergeSymbolTable(
  *                                           deref(lhs._raw_ptr_or_raise()),             # <<<<<<<<<<<<<<
@@ -13744,11 +14020,11 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_merge_symbol_
  */
   if (unlikely(((PyObject *)__pyx_v_lhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 1195, __pyx_L1_error)
+    __PYX_ERR(0, 1255, __pyx_L1_error)
   }
-  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_lhs->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_lhs); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1195, __pyx_L1_error)
+  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_lhs->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_lhs); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1255, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1196
+  /* "pywrapfst.pyx":1256
  *   return _init_SymbolTable(WrapUnique(fst.MergeSymbolTable(
  *                                           deref(lhs._raw_ptr_or_raise()),
  *                                           deref(rhs._raw_ptr_or_raise()),             # <<<<<<<<<<<<<<
@@ -13757,29 +14033,29 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_merge_symbol_
  */
   if (unlikely(((PyObject *)__pyx_v_rhs) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 1196, __pyx_L1_error)
+    __PYX_ERR(0, 1256, __pyx_L1_error)
   }
-  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_rhs->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_rhs); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1196, __pyx_L1_error)
+  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_rhs->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_rhs); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1256, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1194
+  /* "pywrapfst.pyx":1254
  *     A new merged SymbolTable.
  *   """
  *   return _init_SymbolTable(WrapUnique(fst.MergeSymbolTable(             # <<<<<<<<<<<<<<
  *                                           deref(lhs._raw_ptr_or_raise()),
  *                                           deref(rhs._raw_ptr_or_raise()),
  */
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::WrapUnique<fst::SymbolTable>(fst::MergeSymbolTable((*__pyx_t_1), (*__pyx_t_2), NULL)))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1194, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_SymbolTable(fst::WrapUnique<fst::SymbolTable>(fst::MergeSymbolTable((*__pyx_t_1), (*__pyx_t_2), NULL)))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1254, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_SymbolTable *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1172
+  /* "pywrapfst.pyx":1231
  * 
  * 
- * cpdef SymbolTable merge_symbol_table(_SymbolTable lhs, _SymbolTable rhs):             # <<<<<<<<<<<<<<
+ * cpdef SymbolTable merge_symbol_table(SymbolTableView lhs,             # <<<<<<<<<<<<<<
+ *                                      SymbolTableView rhs):
  *   """
- *   merge_symbol_table(lhs, rhs)
  */
 
   /* function exit code */
@@ -13797,8 +14073,11 @@ static struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_f_9pywrapfst_merge_symbol_
 static PyObject *__pyx_pw_9pywrapfst_13merge_symbol_table(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_12merge_symbol_table[] = "\n  merge_symbol_table(lhs, rhs)\n\n  Merges all symbols from the left table into the right.\n\n  This function creates a new SymbolTable which is the merger of the two input\n  symbol Tables. Symbols in the right-hand table that conflict with those in the\n  left-hand table will be assigned values from the left-hand table. Thus the\n  returned table will never modify symbol assignments from the left-hand side,\n  but may do so on the right.\n\n  If the left-hand table is associated with an FST, it may be necessary to\n  relabel it using the output table.\n\n  Args:\n    lhs: Left-hand side SymbolTable.\n    rhs: Left-hand side SymbolTable.\n\n  Returns:\n    A new merged SymbolTable.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_13merge_symbol_table(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_lhs = 0;
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_rhs = 0;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_lhs = 0;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_rhs = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("merge_symbol_table (wrapper)", 0);
@@ -13825,11 +14104,11 @@ static PyObject *__pyx_pw_9pywrapfst_13merge_symbol_table(PyObject *__pyx_self,
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_rhs)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("merge_symbol_table", 1, 2, 2, 1); __PYX_ERR(0, 1172, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("merge_symbol_table", 1, 2, 2, 1); __PYX_ERR(0, 1231, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "merge_symbol_table") < 0)) __PYX_ERR(0, 1172, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "merge_symbol_table") < 0)) __PYX_ERR(0, 1231, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -13837,19 +14116,19 @@ static PyObject *__pyx_pw_9pywrapfst_13merge_symbol_table(PyObject *__pyx_self,
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
-    __pyx_v_lhs = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[0]);
-    __pyx_v_rhs = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[1]);
+    __pyx_v_lhs = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)values[0]);
+    __pyx_v_rhs = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)values[1]);
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("merge_symbol_table", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1172, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("merge_symbol_table", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1231, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.merge_symbol_table", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst__SymbolTable, 1, "lhs", 0))) __PYX_ERR(0, 1172, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst__SymbolTable, 1, "rhs", 0))) __PYX_ERR(0, 1172, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lhs), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "lhs", 0))) __PYX_ERR(0, 1231, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_rhs), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "rhs", 0))) __PYX_ERR(0, 1232, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_12merge_symbol_table(__pyx_self, __pyx_v_lhs, __pyx_v_rhs);
 
   /* function exit code */
@@ -13861,13 +14140,16 @@ static PyObject *__pyx_pw_9pywrapfst_13merge_symbol_table(PyObject *__pyx_self,
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12merge_symbol_table(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_lhs, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_rhs) {
+static PyObject *__pyx_pf_9pywrapfst_12merge_symbol_table(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_lhs, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_rhs) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("merge_symbol_table", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_merge_symbol_table(__pyx_v_lhs, __pyx_v_rhs, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1172, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_merge_symbol_table(__pyx_v_lhs, __pyx_v_rhs, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1231, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -13884,11 +14166,11 @@ static PyObject *__pyx_pf_9pywrapfst_12merge_symbol_table(CYTHON_UNUSED PyObject
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1210
+/* "pywrapfst.pyx":1270
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<_SymbolTableIterator at 0x{:x}>".format(id(self))
+ *     return f"<_SymbolTableIterator at 0x{id(self):x}>"
  * 
  */
 
@@ -13909,57 +14191,65 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator___repr__(struct __py
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_2;
+  Py_UCS4 __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":1211
+  /* "pywrapfst.pyx":1271
  * 
  *   def __repr__(self):
- *     return "<_SymbolTableIterator at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
+ *     return f"<_SymbolTableIterator at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
  * 
- *   def __init__(self, _SymbolTable syms):
+ *   def __init__(self, SymbolTableView symbols):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_SymbolTableIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1211, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1211, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = NULL;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
-    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
-    if (likely(__pyx_t_4)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-      __Pyx_INCREF(__pyx_t_4);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_2, function);
-    }
-  }
-  __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1211, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1271, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 127;
+  __Pyx_INCREF(__pyx_kp_u_SymbolTableIterator_at_0x);
+  __pyx_t_2 += 27;
+  __Pyx_GIVEREF(__pyx_kp_u_SymbolTableIterator_at_0x);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_SymbolTableIterator_at_0x);
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1271, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1271, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_5);
+  __pyx_t_5 = 0;
+  __Pyx_INCREF(__pyx_kp_u__3);
+  __pyx_t_2 += 1;
+  __Pyx_GIVEREF(__pyx_kp_u__3);
+  PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u__3);
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1271, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1210
+  /* "pywrapfst.pyx":1270
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<_SymbolTableIterator at 0x{:x}>".format(id(self))
+ *     return f"<_SymbolTableIterator at 0x{id(self):x}>"
  * 
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
   __Pyx_AddTraceback("pywrapfst._SymbolTableIterator.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -13968,23 +14258,26 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator___repr__(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1213
- *     return "<_SymbolTableIterator at 0x{:x}>".format(id(self))
+/* "pywrapfst.pyx":1273
+ *     return f"<_SymbolTableIterator at 0x{id(self):x}>"
  * 
- *   def __init__(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
- *     self._table = syms
- *     self._siter.reset(new fst.SymbolTableIterator(
+ *   def __init__(self, SymbolTableView symbols):             # <<<<<<<<<<<<<<
+ *     self._table = symbols
+ *     self._siter.reset(
  */
 
 /* Python wrapper */
 static int __pyx_pw_9pywrapfst_20_SymbolTableIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static int __pyx_pw_9pywrapfst_20_SymbolTableIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms = 0;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
   {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_syms,0};
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_symbols,0};
     PyObject* values[1] = {0};
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
@@ -13998,29 +14291,29 @@ static int __pyx_pw_9pywrapfst_20_SymbolTableIterator_3__init__(PyObject *__pyx_
       kw_args = PyDict_Size(__pyx_kwds);
       switch (pos_args) {
         case  0:
-        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_syms)) != 0)) kw_args--;
+        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_symbols)) != 0)) kw_args--;
         else goto __pyx_L5_argtuple_error;
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 1213, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 1273, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
     } else {
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
     }
-    __pyx_v_syms = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[0]);
+    __pyx_v_symbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)values[0]);
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1213, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1273, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst._SymbolTableIterator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return -1;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 1213, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_20_SymbolTableIterator_2__init__(((struct __pyx_obj_9pywrapfst__SymbolTableIterator *)__pyx_v_self), __pyx_v_syms);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_symbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "symbols", 0))) __PYX_ERR(0, 1273, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_20_SymbolTableIterator_2__init__(((struct __pyx_obj_9pywrapfst__SymbolTableIterator *)__pyx_v_self), __pyx_v_symbols);
 
   /* function exit code */
   goto __pyx_L0;
@@ -14031,73 +14324,76 @@ static int __pyx_pw_9pywrapfst_20_SymbolTableIterator_3__init__(PyObject *__pyx_
   return __pyx_r;
 }
 
-static int __pyx_pf_9pywrapfst_20_SymbolTableIterator_2__init__(struct __pyx_obj_9pywrapfst__SymbolTableIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
+static int __pyx_pf_9pywrapfst_20_SymbolTableIterator_2__init__(struct __pyx_obj_9pywrapfst__SymbolTableIterator *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols) {
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   fst::SymbolTable const *__pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":1214
+  /* "pywrapfst.pyx":1274
  * 
- *   def __init__(self, _SymbolTable syms):
- *     self._table = syms             # <<<<<<<<<<<<<<
- *     self._siter.reset(new fst.SymbolTableIterator(
- *                           self._table._raw_ptr_or_raise().begin()))
+ *   def __init__(self, SymbolTableView symbols):
+ *     self._table = symbols             # <<<<<<<<<<<<<<
+ *     self._siter.reset(
+ *         new fst.SymbolTableIterator(self._table._raw_ptr_or_raise().begin()))
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 1214, __pyx_L1_error)
+    __PYX_ERR(0, 1274, __pyx_L1_error)
   }
-  __Pyx_INCREF(((PyObject *)__pyx_v_syms));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_syms));
+  __Pyx_INCREF(((PyObject *)__pyx_v_symbols));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_symbols));
   __Pyx_GOTREF(__pyx_v_self->_table);
   __Pyx_DECREF(((PyObject *)__pyx_v_self->_table));
-  __pyx_v_self->_table = __pyx_v_syms;
+  __pyx_v_self->_table = __pyx_v_symbols;
 
-  /* "pywrapfst.pyx":1215
- *   def __init__(self, _SymbolTable syms):
- *     self._table = syms
- *     self._siter.reset(new fst.SymbolTableIterator(             # <<<<<<<<<<<<<<
- *                           self._table._raw_ptr_or_raise().begin()))
+  /* "pywrapfst.pyx":1275
+ *   def __init__(self, SymbolTableView symbols):
+ *     self._table = symbols
+ *     self._siter.reset(             # <<<<<<<<<<<<<<
+ *         new fst.SymbolTableIterator(self._table._raw_ptr_or_raise().begin()))
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 1215, __pyx_L1_error)
+    __PYX_ERR(0, 1275, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1216
- *     self._table = syms
- *     self._siter.reset(new fst.SymbolTableIterator(
- *                           self._table._raw_ptr_or_raise().begin()))             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1276
+ *     self._table = symbols
+ *     self._siter.reset(
+ *         new fst.SymbolTableIterator(self._table._raw_ptr_or_raise().begin()))             # <<<<<<<<<<<<<<
  * 
  *   # This just registers this class as a possible iterator.
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 1216, __pyx_L1_error)
+    __PYX_ERR(0, 1276, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self->_table) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 1216, __pyx_L1_error)
+    __PYX_ERR(0, 1276, __pyx_L1_error)
   }
-  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->_table->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self->_table); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1216, __pyx_L1_error)
+  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->_table->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self->_table); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1276, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1215
- *   def __init__(self, _SymbolTable syms):
- *     self._table = syms
- *     self._siter.reset(new fst.SymbolTableIterator(             # <<<<<<<<<<<<<<
- *                           self._table._raw_ptr_or_raise().begin()))
+  /* "pywrapfst.pyx":1275
+ *   def __init__(self, SymbolTableView symbols):
+ *     self._table = symbols
+ *     self._siter.reset(             # <<<<<<<<<<<<<<
+ *         new fst.SymbolTableIterator(self._table._raw_ptr_or_raise().begin()))
  * 
  */
   __pyx_v_self->_siter.reset(new fst::SymbolTable::iterator(__pyx_t_1->begin()));
 
-  /* "pywrapfst.pyx":1213
- *     return "<_SymbolTableIterator at 0x{:x}>".format(id(self))
+  /* "pywrapfst.pyx":1273
+ *     return f"<_SymbolTableIterator at 0x{id(self):x}>"
  * 
- *   def __init__(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
- *     self._table = syms
- *     self._siter.reset(new fst.SymbolTableIterator(
+ *   def __init__(self, SymbolTableView symbols):             # <<<<<<<<<<<<<<
+ *     self._table = symbols
+ *     self._siter.reset(
  */
 
   /* function exit code */
@@ -14111,7 +14407,7 @@ static int __pyx_pf_9pywrapfst_20_SymbolTableIterator_2__init__(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1219
+/* "pywrapfst.pyx":1279
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -14137,7 +14433,7 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_4__iter__(struct __p
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":1220
+  /* "pywrapfst.pyx":1280
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):
  *     return self             # <<<<<<<<<<<<<<
@@ -14149,7 +14445,7 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_4__iter__(struct __p
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1219
+  /* "pywrapfst.pyx":1279
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -14164,7 +14460,7 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_4__iter__(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1223
+/* "pywrapfst.pyx":1283
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -14186,8 +14482,8 @@ static PyObject *__pyx_pw_9pywrapfst_20_SymbolTableIterator_7__next__(PyObject *
 }
 
 static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_6__next__(struct __pyx_obj_9pywrapfst__SymbolTableIterator *__pyx_v_self) {
-  int64 __pyx_v_label;
-  std::string __pyx_v_symbol;
+  int64 __pyx_v__label;
+  std::string __pyx_v__symbol;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   fst::SymbolTable const *__pyx_t_1;
@@ -14195,102 +14491,105 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_6__next__(struct __p
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__next__", 0);
 
-  /* "pywrapfst.pyx":1224
+  /* "pywrapfst.pyx":1284
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self._table._raw_ptr_or_raise().end() == deref(self._siter):             # <<<<<<<<<<<<<<
  *       raise StopIteration
- *     cdef int64 label = self._siter.get().Pair().Label()
+ *     cdef int64 _label = self._siter.get().Pair().Label()
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_table");
-    __PYX_ERR(0, 1224, __pyx_L1_error)
+    __PYX_ERR(0, 1284, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self->_table) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 1224, __pyx_L1_error)
+    __PYX_ERR(0, 1284, __pyx_L1_error)
   }
-  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_self->_table->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self->_table); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1224, __pyx_L1_error)
+  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_self->_table->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_self->_table); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1284, __pyx_L1_error)
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 1224, __pyx_L1_error)
+    __PYX_ERR(0, 1284, __pyx_L1_error)
   }
   __pyx_t_2 = ((__pyx_t_1->end() == (*__pyx_v_self->_siter)) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1225
+    /* "pywrapfst.pyx":1285
  *   def __next__(self):
  *     if self._table._raw_ptr_or_raise().end() == deref(self._siter):
  *       raise StopIteration             # <<<<<<<<<<<<<<
- *     cdef int64 label = self._siter.get().Pair().Label()
- *     cdef string symbol = self._siter.get().Pair().Symbol()
+ *     cdef int64 _label = self._siter.get().Pair().Label()
+ *     cdef string _symbol = self._siter.get().Pair().Symbol()
  */
     __Pyx_Raise(__pyx_builtin_StopIteration, 0, 0, 0);
-    __PYX_ERR(0, 1225, __pyx_L1_error)
+    __PYX_ERR(0, 1285, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1224
+    /* "pywrapfst.pyx":1284
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self._table._raw_ptr_or_raise().end() == deref(self._siter):             # <<<<<<<<<<<<<<
  *       raise StopIteration
- *     cdef int64 label = self._siter.get().Pair().Label()
+ *     cdef int64 _label = self._siter.get().Pair().Label()
  */
   }
 
-  /* "pywrapfst.pyx":1226
+  /* "pywrapfst.pyx":1286
  *     if self._table._raw_ptr_or_raise().end() == deref(self._siter):
  *       raise StopIteration
- *     cdef int64 label = self._siter.get().Pair().Label()             # <<<<<<<<<<<<<<
- *     cdef string symbol = self._siter.get().Pair().Symbol()
+ *     cdef int64 _label = self._siter.get().Pair().Label()             # <<<<<<<<<<<<<<
+ *     cdef string _symbol = self._siter.get().Pair().Symbol()
  *     inc(deref(self._siter))
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 1226, __pyx_L1_error)
+    __PYX_ERR(0, 1286, __pyx_L1_error)
   }
-  __pyx_v_label = __pyx_v_self->_siter.get()->operator*().Label();
+  __pyx_v__label = __pyx_v_self->_siter.get()->operator*().Label();
 
-  /* "pywrapfst.pyx":1227
+  /* "pywrapfst.pyx":1287
  *       raise StopIteration
- *     cdef int64 label = self._siter.get().Pair().Label()
- *     cdef string symbol = self._siter.get().Pair().Symbol()             # <<<<<<<<<<<<<<
+ *     cdef int64 _label = self._siter.get().Pair().Label()
+ *     cdef string _symbol = self._siter.get().Pair().Symbol()             # <<<<<<<<<<<<<<
  *     inc(deref(self._siter))
- *     return (label, symbol)
+ *     return (_label, _symbol)
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 1227, __pyx_L1_error)
+    __PYX_ERR(0, 1287, __pyx_L1_error)
   }
-  __pyx_v_symbol = __pyx_v_self->_siter.get()->operator*().Symbol();
+  __pyx_v__symbol = __pyx_v_self->_siter.get()->operator*().Symbol();
 
-  /* "pywrapfst.pyx":1228
- *     cdef int64 label = self._siter.get().Pair().Label()
- *     cdef string symbol = self._siter.get().Pair().Symbol()
+  /* "pywrapfst.pyx":1288
+ *     cdef int64 _label = self._siter.get().Pair().Label()
+ *     cdef string _symbol = self._siter.get().Pair().Symbol()
  *     inc(deref(self._siter))             # <<<<<<<<<<<<<<
- *     return (label, symbol)
+ *     return (_label, _symbol)
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 1228, __pyx_L1_error)
+    __PYX_ERR(0, 1288, __pyx_L1_error)
   }
   (void)((++(*__pyx_v_self->_siter)));
 
-  /* "pywrapfst.pyx":1229
- *     cdef string symbol = self._siter.get().Pair().Symbol()
+  /* "pywrapfst.pyx":1289
+ *     cdef string _symbol = self._siter.get().Pair().Symbol()
  *     inc(deref(self._siter))
- *     return (label, symbol)             # <<<<<<<<<<<<<<
+ *     return (_label, _symbol)             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_label); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1229, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v__label); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1289, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_symbol); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1229, __pyx_L1_error)
+  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v__symbol); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1289, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1229, __pyx_L1_error)
+  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1289, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_GIVEREF(__pyx_t_3);
   PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3);
@@ -14302,7 +14601,7 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_6__next__(struct __p
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1223
+  /* "pywrapfst.pyx":1283
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -14346,6 +14645,9 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_8__reduce_cython__(C
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__reduce_cython__", 0);
 
   /* "(tree fragment)":2
@@ -14354,7 +14656,7 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_8__reduce_cython__(C
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._siter cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -14400,6 +14702,9 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_10__setstate_cython_
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__setstate_cython__", 0);
 
   /* "(tree fragment)":4
@@ -14407,7 +14712,7 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_10__setstate_cython_
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._siter cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -14430,11 +14735,11 @@ static PyObject *__pyx_pf_9pywrapfst_20_SymbolTableIterator_10__setstate_cython_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1258
+/* "pywrapfst.pyx":1318
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<EncodeMapper at 0x{:x}>".format(id(self))
+ *     return f"<EncodeMapper at 0x{id(self):x}>"
  * 
  */
 
@@ -14455,57 +14760,65 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9p
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_2;
+  Py_UCS4 __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":1259
+  /* "pywrapfst.pyx":1319
  * 
  *   def __repr__(self):
- *     return "<EncodeMapper at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
+ *     return f"<EncodeMapper at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
  * 
  *   def __init__(self,
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_EncodeMapper_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1259, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1259, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = NULL;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
-    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
-    if (likely(__pyx_t_4)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-      __Pyx_INCREF(__pyx_t_4);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_2, function);
-    }
-  }
-  __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1259, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1319, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 127;
+  __Pyx_INCREF(__pyx_kp_u_EncodeMapper_at_0x);
+  __pyx_t_2 += 19;
+  __Pyx_GIVEREF(__pyx_kp_u_EncodeMapper_at_0x);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_EncodeMapper_at_0x);
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1319, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1319, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_5);
+  __pyx_t_5 = 0;
+  __Pyx_INCREF(__pyx_kp_u__3);
+  __pyx_t_2 += 1;
+  __Pyx_GIVEREF(__pyx_kp_u__3);
+  PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u__3);
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1319, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1258
+  /* "pywrapfst.pyx":1318
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<EncodeMapper at 0x{:x}>".format(id(self))
+ *     return f"<EncodeMapper at 0x{id(self):x}>"
  * 
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
   __Pyx_AddTraceback("pywrapfst.EncodeMapper.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -14514,11 +14827,11 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper___repr__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1261
- *     return "<EncodeMapper at 0x{:x}>".format(id(self))
+/* "pywrapfst.pyx":1321
+ *     return f"<EncodeMapper at 0x{id(self):x}>"
  * 
  *   def __init__(self,             # <<<<<<<<<<<<<<
- *                arc_type=b"standard",
+ *                arc_type="standard",
  *                bool encode_labels=False,
  */
 
@@ -14528,13 +14841,16 @@ static int __pyx_pw_9pywrapfst_12EncodeMapper_3__init__(PyObject *__pyx_v_self,
   PyObject *__pyx_v_arc_type = 0;
   bool __pyx_v_encode_labels;
   bool __pyx_v_encode_weights;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
   {
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_arc_type,&__pyx_n_s_encode_labels,&__pyx_n_s_encode_weights,0};
     PyObject* values[3] = {0,0,0};
-    values[0] = ((PyObject *)__pyx_n_b_standard);
+    values[0] = ((PyObject *)__pyx_n_u_standard);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -14569,7 +14885,7 @@ static int __pyx_pw_9pywrapfst_12EncodeMapper_3__init__(PyObject *__pyx_v_self,
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 1261, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 1321, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -14585,35 +14901,35 @@ static int __pyx_pw_9pywrapfst_12EncodeMapper_3__init__(PyObject *__pyx_v_self,
     }
     __pyx_v_arc_type = values[0];
     if (values[1]) {
-      __pyx_v_encode_labels = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_encode_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1263, __pyx_L3_error)
+      __pyx_v_encode_labels = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_encode_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1323, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1263
+      /* "pywrapfst.pyx":1323
  *   def __init__(self,
- *                arc_type=b"standard",
+ *                arc_type="standard",
  *                bool encode_labels=False,             # <<<<<<<<<<<<<<
  *                bool encode_weights=False):
- *     cdef uint8 flags = fst.GetEncodeFlags(encode_labels, encode_weights)
+ *     cdef uint8 _flags = fst.GetEncodeFlags(encode_labels, encode_weights)
  */
       __pyx_v_encode_labels = ((bool)0);
     }
     if (values[2]) {
-      __pyx_v_encode_weights = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_encode_weights == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1264, __pyx_L3_error)
+      __pyx_v_encode_weights = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_encode_weights == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1324, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1264
- *                arc_type=b"standard",
+      /* "pywrapfst.pyx":1324
+ *                arc_type="standard",
  *                bool encode_labels=False,
  *                bool encode_weights=False):             # <<<<<<<<<<<<<<
- *     cdef uint8 flags = fst.GetEncodeFlags(encode_labels, encode_weights)
- *     self._mapper.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
+ *     cdef uint8 _flags = fst.GetEncodeFlags(encode_labels, encode_weights)
+ *     self._mapper.reset(
  */
       __pyx_v_encode_weights = ((bool)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1261, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1321, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.EncodeMapper.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -14621,11 +14937,11 @@ static int __pyx_pw_9pywrapfst_12EncodeMapper_3__init__(PyObject *__pyx_v_self,
   __pyx_L4_argument_unpacking_done:;
   __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self), __pyx_v_arc_type, __pyx_v_encode_labels, __pyx_v_encode_weights);
 
-  /* "pywrapfst.pyx":1261
- *     return "<EncodeMapper at 0x{:x}>".format(id(self))
+  /* "pywrapfst.pyx":1321
+ *     return f"<EncodeMapper at 0x{id(self):x}>"
  * 
  *   def __init__(self,             # <<<<<<<<<<<<<<
- *                arc_type=b"standard",
+ *                arc_type="standard",
  *                bool encode_labels=False,
  */
 
@@ -14635,7 +14951,7 @@ static int __pyx_pw_9pywrapfst_12EncodeMapper_3__init__(PyObject *__pyx_v_self,
 }
 
 static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, PyObject *__pyx_v_arc_type, bool __pyx_v_encode_labels, bool __pyx_v_encode_weights) {
-  uint8 __pyx_v_flags;
+  uint8 __pyx_v__flags;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
@@ -14644,114 +14960,112 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":1265
+  /* "pywrapfst.pyx":1325
  *                bool encode_labels=False,
  *                bool encode_weights=False):
- *     cdef uint8 flags = fst.GetEncodeFlags(encode_labels, encode_weights)             # <<<<<<<<<<<<<<
- *     self._mapper.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
- *                                                  fst.ENCODE))
+ *     cdef uint8 _flags = fst.GetEncodeFlags(encode_labels, encode_weights)             # <<<<<<<<<<<<<<
+ *     self._mapper.reset(
+ *         new fst.EncodeMapperClass(tostring(arc_type), _flags, fst.ENCODE))
  */
-  __pyx_v_flags = fst::script::GetEncodeFlags(__pyx_v_encode_labels, __pyx_v_encode_weights);
+  __pyx_v__flags = fst::script::GetEncodeFlags(__pyx_v_encode_labels, __pyx_v_encode_weights);
 
-  /* "pywrapfst.pyx":1266
+  /* "pywrapfst.pyx":1326
  *                bool encode_weights=False):
- *     cdef uint8 flags = fst.GetEncodeFlags(encode_labels, encode_weights)
- *     self._mapper.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,             # <<<<<<<<<<<<<<
- *                                                  fst.ENCODE))
- *     if not self._mapper:
+ *     cdef uint8 _flags = fst.GetEncodeFlags(encode_labels, encode_weights)
+ *     self._mapper.reset(             # <<<<<<<<<<<<<<
+ *         new fst.EncodeMapperClass(tostring(arc_type), _flags, fst.ENCODE))
+ *     if self._mapper.get() == NULL:
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1266, __pyx_L1_error)
+    __PYX_ERR(0, 1326, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1266, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1267
- *     cdef uint8 flags = fst.GetEncodeFlags(encode_labels, encode_weights)
- *     self._mapper.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
- *                                                  fst.ENCODE))             # <<<<<<<<<<<<<<
- *     if not self._mapper:
- *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
+  /* "pywrapfst.pyx":1327
+ *     cdef uint8 _flags = fst.GetEncodeFlags(encode_labels, encode_weights)
+ *     self._mapper.reset(
+ *         new fst.EncodeMapperClass(tostring(arc_type), _flags, fst.ENCODE))             # <<<<<<<<<<<<<<
+ *     if self._mapper.get() == NULL:
+ *       raise FstOpError(f"Unknown arc type: {arc_type!r}")
+ */
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1327, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":1326
+ *                bool encode_weights=False):
+ *     cdef uint8 _flags = fst.GetEncodeFlags(encode_labels, encode_weights)
+ *     self._mapper.reset(             # <<<<<<<<<<<<<<
+ *         new fst.EncodeMapperClass(tostring(arc_type), _flags, fst.ENCODE))
+ *     if self._mapper.get() == NULL:
  */
-  __pyx_v_self->_mapper.reset(new fst::script::EncodeMapperClass(__pyx_t_1, __pyx_v_flags, fst::ENCODE));
+  __pyx_v_self->_mapper.reset(new fst::script::EncodeMapperClass(__pyx_t_1, __pyx_v__flags, fst::ENCODE));
 
-  /* "pywrapfst.pyx":1268
- *     self._mapper.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
- *                                                  fst.ENCODE))
- *     if not self._mapper:             # <<<<<<<<<<<<<<
- *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
+  /* "pywrapfst.pyx":1328
+ *     self._mapper.reset(
+ *         new fst.EncodeMapperClass(tostring(arc_type), _flags, fst.ENCODE))
+ *     if self._mapper.get() == NULL:             # <<<<<<<<<<<<<<
+ *       raise FstOpError(f"Unknown arc type: {arc_type!r}")
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1268, __pyx_L1_error)
+    __PYX_ERR(0, 1328, __pyx_L1_error)
   }
-  __pyx_t_2 = ((!__pyx_v_self->_mapper) != 0);
+  __pyx_t_2 = ((__pyx_v_self->_mapper.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1269
- *                                                  fst.ENCODE))
- *     if not self._mapper:
- *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))             # <<<<<<<<<<<<<<
+    /* "pywrapfst.pyx":1329
+ *         new fst.EncodeMapperClass(tostring(arc_type), _flags, fst.ENCODE))
+ *     if self._mapper.get() == NULL:
+ *       raise FstOpError(f"Unknown arc type: {arc_type!r}")             # <<<<<<<<<<<<<<
  * 
  *   # Python's equivalent to operator().
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1269, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1329, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_arc_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1269, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
-        __Pyx_INCREF(__pyx_t_7);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_6, function);
-      }
-    }
-    __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_arc_type) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_arc_type);
-    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1269, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_arc_type), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1329, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = NULL;
+    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_arc_type, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1329, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
-      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
-      if (likely(__pyx_t_6)) {
+      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+      if (likely(__pyx_t_5)) {
         PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-        __Pyx_INCREF(__pyx_t_6);
+        __Pyx_INCREF(__pyx_t_5);
         __Pyx_INCREF(function);
         __Pyx_DECREF_SET(__pyx_t_4, function);
       }
     }
-    __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1269, __pyx_L1_error)
+    __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
+    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1329, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1269, __pyx_L1_error)
+    __PYX_ERR(0, 1329, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1268
- *     self._mapper.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
- *                                                  fst.ENCODE))
- *     if not self._mapper:             # <<<<<<<<<<<<<<
- *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
+    /* "pywrapfst.pyx":1328
+ *     self._mapper.reset(
+ *         new fst.EncodeMapperClass(tostring(arc_type), _flags, fst.ENCODE))
+ *     if self._mapper.get() == NULL:             # <<<<<<<<<<<<<<
+ *       raise FstOpError(f"Unknown arc type: {arc_type!r}")
  * 
  */
   }
 
-  /* "pywrapfst.pyx":1261
- *     return "<EncodeMapper at 0x{:x}>".format(id(self))
+  /* "pywrapfst.pyx":1321
+ *     return f"<EncodeMapper at 0x{id(self):x}>"
  * 
  *   def __init__(self,             # <<<<<<<<<<<<<<
- *                arc_type=b"standard",
+ *                arc_type="standard",
  *                bool encode_labels=False,
  */
 
@@ -14763,7 +15077,6 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_AddTraceback("pywrapfst.EncodeMapper.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = -1;
   __pyx_L0:;
@@ -14771,7 +15084,7 @@ static int __pyx_pf_9pywrapfst_12EncodeMapper_2__init__(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1273
+/* "pywrapfst.pyx":1333
  *   # Python's equivalent to operator().
  * 
  *   def __call__(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -14787,6 +15100,9 @@ struct wrapperbase __pyx_wrapperbase_9pywrapfst_12EncodeMapper_4__call__;
 #endif
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_5__call__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__call__ (wrapper)", 0);
@@ -14809,7 +15125,7 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_5__call__(PyObject *__pyx_v_
         else goto __pyx_L5_argtuple_error;
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__call__") < 0)) __PYX_ERR(0, 1273, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__call__") < 0)) __PYX_ERR(0, 1333, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -14820,13 +15136,13 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_5__call__(PyObject *__pyx_v_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__call__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1273, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__call__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1333, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.EncodeMapper.__call__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 1273, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 1333, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_4__call__(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self), __pyx_v_arc);
 
   /* function exit code */
@@ -14842,9 +15158,12 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_4__call__(struct __pyx_obj_9
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__call__", 0);
 
-  /* "pywrapfst.pyx":1289
+  /* "pywrapfst.pyx":1349
  *       FstOpError: Incompatible or invalid weight.
  *     """
  *     return _init_Arc(self._mapper.get().__call__(deref(arc._arc)))             # <<<<<<<<<<<<<<
@@ -14854,19 +15173,19 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_4__call__(struct __pyx_obj_9
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1289, __pyx_L1_error)
+    __PYX_ERR(0, 1349, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_arc) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 1289, __pyx_L1_error)
+    __PYX_ERR(0, 1349, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_Arc(__pyx_v_self->_mapper.get()->operator()((*__pyx_v_arc->_arc)))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1289, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_Arc(__pyx_v_self->_mapper.get()->operator()((*__pyx_v_arc->_arc)))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1349, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1273
+  /* "pywrapfst.pyx":1333
  *   # Python's equivalent to operator().
  * 
  *   def __call__(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -14885,7 +15204,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_4__call__(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1293
+/* "pywrapfst.pyx":1353
  *   # Registers the class for pickling.
  * 
  *   def __reduce__(self):             # <<<<<<<<<<<<<<
@@ -14912,9 +15231,12 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_6__reduce__(struct __pyx_obj
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__reduce__", 0);
 
-  /* "pywrapfst.pyx":1294
+  /* "pywrapfst.pyx":1354
  * 
  *   def __reduce__(self):
  *       return (_read_EncodeMapper_from_string, (self.write_to_string(),))             # <<<<<<<<<<<<<<
@@ -14922,20 +15244,20 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_6__reduce__(struct __pyx_obj
  *   cpdef string arc_type(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_read_EncodeMapper_from_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1294, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_read_EncodeMapper_from_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1354, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "write_to_string");
-    __PYX_ERR(0, 1294, __pyx_L1_error)
+    __PYX_ERR(0, 1354, __pyx_L1_error)
   }
-  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_EncodeMapper *)__pyx_v_self->__pyx_vtab)->write_to_string(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1294, __pyx_L1_error)
+  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_EncodeMapper *)__pyx_v_self->__pyx_vtab)->write_to_string(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1354, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1294, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1354, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_GIVEREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
   __pyx_t_2 = 0;
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1294, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1354, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
@@ -14947,7 +15269,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_6__reduce__(struct __pyx_obj
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1293
+  /* "pywrapfst.pyx":1353
  *   # Registers the class for pickling.
  * 
  *   def __reduce__(self):             # <<<<<<<<<<<<<<
@@ -14968,7 +15290,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_6__reduce__(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1296
+/* "pywrapfst.pyx":1356
  *       return (_read_EncodeMapper_from_string, (self.write_to_string(),))
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -14985,6 +15307,9 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_arc_type(struct __pyx_obj_9
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   std::string __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("arc_type", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -14995,7 +15320,7 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_arc_type(struct __pyx_obj_9
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1296, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1356, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_9arc_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -15011,10 +15336,10 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_arc_type(struct __pyx_obj_9
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1296, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1356, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1296, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1356, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -15033,7 +15358,7 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_arc_type(struct __pyx_obj_9
     #endif
   }
 
-  /* "pywrapfst.pyx":1302
+  /* "pywrapfst.pyx":1362
  *     Returns a string indicating the arc type.
  *     """
  *     return self._mapper.get().ArcType()             # <<<<<<<<<<<<<<
@@ -15042,12 +15367,12 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_arc_type(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1302, __pyx_L1_error)
+    __PYX_ERR(0, 1362, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_mapper.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1296
+  /* "pywrapfst.pyx":1356
  *       return (_read_EncodeMapper_from_string, (self.write_to_string(),))
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -15086,9 +15411,12 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_8arc_type(struct __pyx_obj_9
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("arc_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_12EncodeMapper_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1296, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_12EncodeMapper_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1356, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15105,7 +15433,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_8arc_type(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1304
+/* "pywrapfst.pyx":1364
  *     return self._mapper.get().ArcType()
  * 
  *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
@@ -15122,6 +15450,9 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_ob
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   std::string __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("weight_type", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -15132,7 +15463,7 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_ob
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_weight_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1304, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_weight_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1364, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_11weight_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -15148,10 +15479,10 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_ob
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1304, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1364, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1304, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1364, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -15170,7 +15501,7 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_ob
     #endif
   }
 
-  /* "pywrapfst.pyx":1310
+  /* "pywrapfst.pyx":1370
  *     Returns a string indicating the weight type.
  *     """
  *     return self._mapper.get().WeightType()             # <<<<<<<<<<<<<<
@@ -15179,12 +15510,12 @@ static std::string __pyx_f_9pywrapfst_12EncodeMapper_weight_type(struct __pyx_ob
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1310, __pyx_L1_error)
+    __PYX_ERR(0, 1370, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_mapper.get()->WeightType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1304
+  /* "pywrapfst.pyx":1364
  *     return self._mapper.get().ArcType()
  * 
  *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
@@ -15223,9 +15554,12 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_10weight_type(struct __pyx_o
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("weight_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_12EncodeMapper_weight_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1304, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_12EncodeMapper_weight_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1364, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15242,7 +15576,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_10weight_type(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1312
+/* "pywrapfst.pyx":1372
  *     return self._mapper.get().WeightType()
  * 
  *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
@@ -15259,6 +15593,9 @@ static uint8 __pyx_f_9pywrapfst_12EncodeMapper_flags(struct __pyx_obj_9pywrapfst
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   uint8 __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("flags", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -15269,7 +15606,7 @@ static uint8 __pyx_f_9pywrapfst_12EncodeMapper_flags(struct __pyx_obj_9pywrapfst
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1312, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1372, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_13flags)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -15285,10 +15622,10 @@ static uint8 __pyx_f_9pywrapfst_12EncodeMapper_flags(struct __pyx_obj_9pywrapfst
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1312, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1372, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_uint8_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1312, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_uint8_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1372, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -15307,7 +15644,7 @@ static uint8 __pyx_f_9pywrapfst_12EncodeMapper_flags(struct __pyx_obj_9pywrapfst
     #endif
   }
 
-  /* "pywrapfst.pyx":1318
+  /* "pywrapfst.pyx":1378
  *     Returns the mapper's flags.
  *     """
  *     return self._mapper.get().Flags()             # <<<<<<<<<<<<<<
@@ -15316,12 +15653,12 @@ static uint8 __pyx_f_9pywrapfst_12EncodeMapper_flags(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1318, __pyx_L1_error)
+    __PYX_ERR(0, 1378, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_mapper.get()->Flags();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1312
+  /* "pywrapfst.pyx":1372
  *     return self._mapper.get().WeightType()
  * 
  *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
@@ -15360,9 +15697,12 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_12flags(struct __pyx_obj_9py
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("flags", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(__pyx_f_9pywrapfst_12EncodeMapper_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1312, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(__pyx_f_9pywrapfst_12EncodeMapper_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1372, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15379,7 +15719,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_12flags(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1320
+/* "pywrapfst.pyx":1380
  *     return self._mapper.get().Flags()
  * 
  *   cpdef uint64 properties(self, uint64 mask):             # <<<<<<<<<<<<<<
@@ -15397,6 +15737,9 @@ static uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(struct __pyx_obj_9pyw
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
   uint64 __pyx_t_6;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("properties", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -15407,10 +15750,10 @@ static uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(struct __pyx_obj_9pyw
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_properties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1320, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_properties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1380, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_15properties)) {
-        __pyx_t_3 = __Pyx_PyInt_From_uint64_t(__pyx_v_mask); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1320, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_uint64_t(__pyx_v_mask); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1380, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -15426,10 +15769,10 @@ static uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(struct __pyx_obj_9pyw
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1320, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1380, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __pyx_t_6 = __Pyx_PyInt_As_uint64_t(__pyx_t_2); if (unlikely((__pyx_t_6 == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1320, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyInt_As_uint64_t(__pyx_t_2); if (unlikely((__pyx_t_6 == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1380, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_6;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -15448,7 +15791,7 @@ static uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(struct __pyx_obj_9pyw
     #endif
   }
 
-  /* "pywrapfst.pyx":1334
+  /* "pywrapfst.pyx":1394
  *       A 64-bit bitmask representing the requested properties.
  *     """
  *     return self._mapper.get().Properties(mask)             # <<<<<<<<<<<<<<
@@ -15457,12 +15800,12 @@ static uint64 __pyx_f_9pywrapfst_12EncodeMapper_properties(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1334, __pyx_L1_error)
+    __PYX_ERR(0, 1394, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_mapper.get()->Properties(__pyx_v_mask);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1320
+  /* "pywrapfst.pyx":1380
  *     return self._mapper.get().Flags()
  * 
  *   cpdef uint64 properties(self, uint64 mask):             # <<<<<<<<<<<<<<
@@ -15489,11 +15832,14 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_15properties(PyObject *__pyx
 static char __pyx_doc_9pywrapfst_12EncodeMapper_14properties[] = "\n    properties(self, mask)\n\n    Provides property bits.\n\n    This method provides user access to the properties of the mapper.\n\n    Args:\n      mask: The property mask to be compared to the mapper's properties.\n\n    Returns:\n      A 64-bit bitmask representing the requested properties.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_15properties(PyObject *__pyx_v_self, PyObject *__pyx_arg_mask) {
   uint64 __pyx_v_mask;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("properties (wrapper)", 0);
   assert(__pyx_arg_mask); {
-    __pyx_v_mask = __Pyx_PyInt_As_uint64_t(__pyx_arg_mask); if (unlikely((__pyx_v_mask == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1320, __pyx_L3_error)
+    __pyx_v_mask = __Pyx_PyInt_As_uint64_t(__pyx_arg_mask); if (unlikely((__pyx_v_mask == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1380, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -15512,9 +15858,12 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_14properties(struct __pyx_ob
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("properties", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(__pyx_f_9pywrapfst_12EncodeMapper_properties(__pyx_v_self, __pyx_v_mask, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1320, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(__pyx_f_9pywrapfst_12EncodeMapper_properties(__pyx_v_self, __pyx_v_mask, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1380, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15531,7 +15880,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_14properties(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1337
+/* "pywrapfst.pyx":1397
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
@@ -15554,7 +15903,7 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_17read(PyObject *__pyx_v_cls
 }
 
 static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16read(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source) {
-  std::unique_ptr<fst::script::EncodeMapperClass>  __pyx_v_mapper;
+  std::unique_ptr<fst::script::EncodeMapperClass>  __pyx_v__mapper;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
@@ -15563,99 +15912,89 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16read(CYTHON_UNUSED PyTypeO
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("read", 0);
 
-  /* "pywrapfst.pyx":1353
+  /* "pywrapfst.pyx":1413
  *     """
- *     cdef unique_ptr[fst.EncodeMapperClass] mapper
- *     mapper.reset(fst.EncodeMapperClass.Read(tostring(source)))             # <<<<<<<<<<<<<<
- *     if mapper.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(source))
+ *     cdef unique_ptr[fst.EncodeMapperClass] _mapper
+ *     _mapper.reset(fst.EncodeMapperClass.Read(path_tostring(source)))             # <<<<<<<<<<<<<<
+ *     if _mapper.get() == NULL:
+ *       raise FstIOError(f"Read failed: {source!r}")
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1353, __pyx_L1_error)
-  __pyx_v_mapper.reset(fst::script::EncodeMapperClass::Read(__pyx_t_1));
+  __pyx_t_1 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1413, __pyx_L1_error)
+  __pyx_v__mapper.reset(fst::script::EncodeMapperClass::Read(__pyx_t_1));
 
-  /* "pywrapfst.pyx":1354
- *     cdef unique_ptr[fst.EncodeMapperClass] mapper
- *     mapper.reset(fst.EncodeMapperClass.Read(tostring(source)))
- *     if mapper.get() == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Read failed: {!r}".format(source))
- *     return _init_EncodeMapper(mapper.release())
+  /* "pywrapfst.pyx":1414
+ *     cdef unique_ptr[fst.EncodeMapperClass] _mapper
+ *     _mapper.reset(fst.EncodeMapperClass.Read(path_tostring(source)))
+ *     if _mapper.get() == NULL:             # <<<<<<<<<<<<<<
+ *       raise FstIOError(f"Read failed: {source!r}")
+ *     return _init_EncodeMapper(_mapper.release())
  */
-  __pyx_t_2 = ((__pyx_v_mapper.get() == NULL) != 0);
+  __pyx_t_2 = ((__pyx_v__mapper.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":1355
- *     mapper.reset(fst.EncodeMapperClass.Read(tostring(source)))
- *     if mapper.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(source))             # <<<<<<<<<<<<<<
- *     return _init_EncodeMapper(mapper.release())
+    /* "pywrapfst.pyx":1415
+ *     _mapper.reset(fst.EncodeMapperClass.Read(path_tostring(source)))
+ *     if _mapper.get() == NULL:
+ *       raise FstIOError(f"Read failed: {source!r}")             # <<<<<<<<<<<<<<
+ *     return _init_EncodeMapper(_mapper.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1355, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1415, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1355, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
-        __Pyx_INCREF(__pyx_t_7);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_6, function);
-      }
-    }
-    __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_source);
-    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1355, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1415, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = NULL;
+    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Read_failed, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1415, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
-      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
-      if (likely(__pyx_t_6)) {
+      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+      if (likely(__pyx_t_5)) {
         PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-        __Pyx_INCREF(__pyx_t_6);
+        __Pyx_INCREF(__pyx_t_5);
         __Pyx_INCREF(function);
         __Pyx_DECREF_SET(__pyx_t_4, function);
       }
     }
-    __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1355, __pyx_L1_error)
+    __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
+    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1415, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1355, __pyx_L1_error)
+    __PYX_ERR(0, 1415, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1354
- *     cdef unique_ptr[fst.EncodeMapperClass] mapper
- *     mapper.reset(fst.EncodeMapperClass.Read(tostring(source)))
- *     if mapper.get() == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Read failed: {!r}".format(source))
- *     return _init_EncodeMapper(mapper.release())
+    /* "pywrapfst.pyx":1414
+ *     cdef unique_ptr[fst.EncodeMapperClass] _mapper
+ *     _mapper.reset(fst.EncodeMapperClass.Read(path_tostring(source)))
+ *     if _mapper.get() == NULL:             # <<<<<<<<<<<<<<
+ *       raise FstIOError(f"Read failed: {source!r}")
+ *     return _init_EncodeMapper(_mapper.release())
  */
   }
 
-  /* "pywrapfst.pyx":1356
- *     if mapper.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(source))
- *     return _init_EncodeMapper(mapper.release())             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1416
+ *     if _mapper.get() == NULL:
+ *       raise FstIOError(f"Read failed: {source!r}")
+ *     return _init_EncodeMapper(_mapper.release())             # <<<<<<<<<<<<<<
  * 
  *   @staticmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapper(__pyx_v_mapper.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1356, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapper(__pyx_v__mapper.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1416, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1337
+  /* "pywrapfst.pyx":1397
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
@@ -15669,7 +16008,6 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16read(CYTHON_UNUSED PyTypeO
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_AddTraceback("pywrapfst.EncodeMapper.read", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -15678,7 +16016,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_16read(CYTHON_UNUSED PyTypeO
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1359
+/* "pywrapfst.pyx":1419
  * 
  *   @staticmethod
  *   def read_from_string(state):             # <<<<<<<<<<<<<<
@@ -15692,6 +16030,9 @@ static char __pyx_doc_9pywrapfst_12EncodeMapper_18read_from_string[] = "\n    re
 static PyMethodDef __pyx_mdef_9pywrapfst_12EncodeMapper_19read_from_string = {"read_from_string", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_12EncodeMapper_19read_from_string, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_12EncodeMapper_18read_from_string};
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_19read_from_string(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_state = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("read_from_string (wrapper)", 0);
@@ -15714,7 +16055,7 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_19read_from_string(CYTHON_UN
         else goto __pyx_L5_argtuple_error;
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_from_string") < 0)) __PYX_ERR(0, 1359, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "read_from_string") < 0)) __PYX_ERR(0, 1419, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -15725,7 +16066,7 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_19read_from_string(CYTHON_UN
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("read_from_string", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1359, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("read_from_string", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1419, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.EncodeMapper.read_from_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -15741,10 +16082,14 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_19read_from_string(CYTHON_UN
 static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_18read_from_string(PyObject *__pyx_v_state) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
+  std::string __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("read_from_string", 0);
 
-  /* "pywrapfst.pyx":1374
+  /* "pywrapfst.pyx":1434
  *       FstIOError: Read failed.
  *     """
  *     return _read_EncodeMapper_from_string(state)             # <<<<<<<<<<<<<<
@@ -15752,13 +16097,14 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_18read_from_string(PyObject
  *   cpdef void write(self, source) except *:
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_EncodeMapper_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1374, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __pyx_t_1 = __pyx_convert_string_from_py_std__in_string(__pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1434, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__read_EncodeMapper_from_string(__pyx_t_1, 0)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1434, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1359
+  /* "pywrapfst.pyx":1419
  * 
  *   @staticmethod
  *   def read_from_string(state):             # <<<<<<<<<<<<<<
@@ -15768,7 +16114,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_18read_from_string(PyObject
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
   __Pyx_AddTraceback("pywrapfst.EncodeMapper.read_from_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -15777,7 +16123,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_18read_from_string(PyObject
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1376
+/* "pywrapfst.pyx":1436
  *     return _read_EncodeMapper_from_string(state)
  * 
  *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
@@ -15794,7 +16140,9 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_write(struct __pyx_obj_9pywrapfst_
   PyObject *__pyx_t_4 = NULL;
   std::string __pyx_t_5;
   int __pyx_t_6;
-  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -15805,7 +16153,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_write(struct __pyx_obj_9pywrapfst_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1376, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1436, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_21write)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -15821,7 +16169,7 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_write(struct __pyx_obj_9pywrapfst_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_source);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1376, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1436, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -15841,77 +16189,65 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_write(struct __pyx_obj_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":1389
+  /* "pywrapfst.pyx":1449
  *         FstIOError: Write failed.
  *       """
- *       if not self._mapper.get().Write(tostring(source)):             # <<<<<<<<<<<<<<
- *         raise FstIOError("Write failed: {!r}".format(source))
+ *       if not self._mapper.get().Write(path_tostring(source)):             # <<<<<<<<<<<<<<
+ *         raise FstIOError(f"Write failed: {source!r}")
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1389, __pyx_L1_error)
+    __PYX_ERR(0, 1449, __pyx_L1_error)
   }
-  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1389, __pyx_L1_error)
+  __pyx_t_5 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1449, __pyx_L1_error)
   __pyx_t_6 = ((!(__pyx_v_self->_mapper.get()->Write(__pyx_t_5) != 0)) != 0);
   if (unlikely(__pyx_t_6)) {
 
-    /* "pywrapfst.pyx":1390
+    /* "pywrapfst.pyx":1450
  *       """
- *       if not self._mapper.get().Write(tostring(source)):
- *         raise FstIOError("Write failed: {!r}".format(source))             # <<<<<<<<<<<<<<
+ *       if not self._mapper.get().Write(path_tostring(source)):
+ *         raise FstIOError(f"Write failed: {source!r}")             # <<<<<<<<<<<<<<
  * 
  *   cpdef bytes write_to_string(self):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1390, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1450, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Write_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1390, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_7 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_4);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-        __Pyx_INCREF(__pyx_t_7);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_4, function);
-      }
-    }
-    __pyx_t_3 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_7, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_source);
-    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1390, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1450, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = NULL;
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Write_failed, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1450, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
-      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
-      if (likely(__pyx_t_4)) {
+      __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+      if (likely(__pyx_t_3)) {
         PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-        __Pyx_INCREF(__pyx_t_4);
+        __Pyx_INCREF(__pyx_t_3);
         __Pyx_INCREF(function);
         __Pyx_DECREF_SET(__pyx_t_2, function);
       }
     }
-    __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
-    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1390, __pyx_L1_error)
+    __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4);
+    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1450, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 1390, __pyx_L1_error)
+    __PYX_ERR(0, 1450, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1389
+    /* "pywrapfst.pyx":1449
  *         FstIOError: Write failed.
  *       """
- *       if not self._mapper.get().Write(tostring(source)):             # <<<<<<<<<<<<<<
- *         raise FstIOError("Write failed: {!r}".format(source))
+ *       if not self._mapper.get().Write(path_tostring(source)):             # <<<<<<<<<<<<<<
+ *         raise FstIOError(f"Write failed: {source!r}")
  * 
  */
   }
 
-  /* "pywrapfst.pyx":1376
+  /* "pywrapfst.pyx":1436
  *     return _read_EncodeMapper_from_string(state)
  * 
  *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
@@ -15926,7 +16262,6 @@ static void __pyx_f_9pywrapfst_12EncodeMapper_write(struct __pyx_obj_9pywrapfst_
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_AddTraceback("pywrapfst.EncodeMapper.write", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
@@ -15950,10 +16285,13 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_20write(struct __pyx_obj_9py
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_12EncodeMapper_write(__pyx_v_self, __pyx_v_source, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1376, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1376, __pyx_L1_error)
+  __pyx_f_9pywrapfst_12EncodeMapper_write(__pyx_v_self, __pyx_v_source, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1436, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1436, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -15970,8 +16308,8 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_20write(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1392
- *         raise FstIOError("Write failed: {!r}".format(source))
+/* "pywrapfst.pyx":1452
+ *         raise FstIOError(f"Write failed: {source!r}")
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
  *       """
@@ -15980,7 +16318,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_20write(struct __pyx_obj_9py
 
 static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_23write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
 static PyObject *__pyx_f_9pywrapfst_12EncodeMapper_write_to_string(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, int __pyx_skip_dispatch) {
-  std::stringstream __pyx_v_sstrm;
+  std::stringstream __pyx_v__sstrm;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -15988,6 +16326,9 @@ static PyObject *__pyx_f_9pywrapfst_12EncodeMapper_write_to_string(struct __pyx_
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   int __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write_to_string", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -15998,7 +16339,7 @@ static PyObject *__pyx_f_9pywrapfst_12EncodeMapper_write_to_string(struct __pyx_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1392, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1452, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_23write_to_string)) {
         __Pyx_XDECREF(__pyx_r);
@@ -16015,10 +16356,10 @@ static PyObject *__pyx_f_9pywrapfst_12EncodeMapper_write_to_string(struct __pyx_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1392, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1452, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 1392, __pyx_L1_error)
+        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 1452, __pyx_L1_error)
         __pyx_r = ((PyObject*)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -16037,28 +16378,28 @@ static PyObject *__pyx_f_9pywrapfst_12EncodeMapper_write_to_string(struct __pyx_
     #endif
   }
 
-  /* "pywrapfst.pyx":1405
+  /* "pywrapfst.pyx":1465
  *       """
- *       cdef stringstream sstrm
- *       if not self._mapper.get().WriteStream(sstrm, b"<pywrapfst>"):             # <<<<<<<<<<<<<<
+ *       cdef stringstream _sstrm
+ *       if not self._mapper.get().WriteStream(_sstrm, b"<pywrapfst>"):             # <<<<<<<<<<<<<<
  *         raise FstIOError("Write to string failed")
- *       return sstrm.str()
+ *       return _sstrm.str()
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1405, __pyx_L1_error)
+    __PYX_ERR(0, 1465, __pyx_L1_error)
   }
-  __pyx_t_5 = ((!(__pyx_v_self->_mapper.get()->Write(__pyx_v_sstrm, __pyx_k_pywrapfst) != 0)) != 0);
+  __pyx_t_5 = ((!(__pyx_v_self->_mapper.get()->Write(__pyx_v__sstrm, __pyx_k_pywrapfst) != 0)) != 0);
   if (unlikely(__pyx_t_5)) {
 
-    /* "pywrapfst.pyx":1406
- *       cdef stringstream sstrm
- *       if not self._mapper.get().WriteStream(sstrm, b"<pywrapfst>"):
+    /* "pywrapfst.pyx":1466
+ *       cdef stringstream _sstrm
+ *       if not self._mapper.get().WriteStream(_sstrm, b"<pywrapfst>"):
  *         raise FstIOError("Write to string failed")             # <<<<<<<<<<<<<<
- *       return sstrm.str()
+ *       return _sstrm.str()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1406, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1466, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -16072,38 +16413,38 @@ static PyObject *__pyx_f_9pywrapfst_12EncodeMapper_write_to_string(struct __pyx_
     }
     __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_kp_u_Write_to_string_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_Write_to_string_failed);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1406, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1466, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 1406, __pyx_L1_error)
+    __PYX_ERR(0, 1466, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1405
+    /* "pywrapfst.pyx":1465
  *       """
- *       cdef stringstream sstrm
- *       if not self._mapper.get().WriteStream(sstrm, b"<pywrapfst>"):             # <<<<<<<<<<<<<<
+ *       cdef stringstream _sstrm
+ *       if not self._mapper.get().WriteStream(_sstrm, b"<pywrapfst>"):             # <<<<<<<<<<<<<<
  *         raise FstIOError("Write to string failed")
- *       return sstrm.str()
+ *       return _sstrm.str()
  */
   }
 
-  /* "pywrapfst.pyx":1407
- *       if not self._mapper.get().WriteStream(sstrm, b"<pywrapfst>"):
+  /* "pywrapfst.pyx":1467
+ *       if not self._mapper.get().WriteStream(_sstrm, b"<pywrapfst>"):
  *         raise FstIOError("Write to string failed")
- *       return sstrm.str()             # <<<<<<<<<<<<<<
+ *       return _sstrm.str()             # <<<<<<<<<<<<<<
  * 
  *   cpdef _EncodeMapperSymbolTableView input_symbols(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_sstrm.str()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1407, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v__sstrm.str()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1467, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((PyObject*)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1392
- *         raise FstIOError("Write failed: {!r}".format(source))
+  /* "pywrapfst.pyx":1452
+ *         raise FstIOError(f"Write failed: {source!r}")
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
  *       """
@@ -16142,9 +16483,12 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_22write_to_string(struct __p
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write_to_string", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_12EncodeMapper_write_to_string(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1392, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_12EncodeMapper_write_to_string(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1452, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -16161,8 +16505,8 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_22write_to_string(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1409
- *       return sstrm.str()
+/* "pywrapfst.pyx":1469
+ *       return _sstrm.str()
  * 
  *   cpdef _EncodeMapperSymbolTableView input_symbols(self):             # <<<<<<<<<<<<<<
  *     """
@@ -16178,6 +16522,9 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   int __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("input_symbols", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -16188,7 +16535,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_input_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1409, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_input_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1469, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_25input_symbols)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -16205,10 +16552,10 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1409, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1469, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__EncodeMapperSymbolTableView))))) __PYX_ERR(0, 1409, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__EncodeMapperSymbolTableView))))) __PYX_ERR(0, 1469, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -16227,7 +16574,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":1415
+  /* "pywrapfst.pyx":1475
  *     Returns the mapper's input symbol table, or None if none is present.
  *     """
  *     if self._mapper.get().InputSymbols() == NULL:             # <<<<<<<<<<<<<<
@@ -16236,12 +16583,12 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1415, __pyx_L1_error)
+    __PYX_ERR(0, 1475, __pyx_L1_error)
   }
   __pyx_t_5 = ((__pyx_v_self->_mapper.get()->InputSymbols() == NULL) != 0);
   if (__pyx_t_5) {
 
-    /* "pywrapfst.pyx":1416
+    /* "pywrapfst.pyx":1476
  *     """
  *     if self._mapper.get().InputSymbols() == NULL:
  *       return             # <<<<<<<<<<<<<<
@@ -16252,7 +16599,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
     __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)Py_None); __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":1415
+    /* "pywrapfst.pyx":1475
  *     Returns the mapper's input symbol table, or None if none is present.
  *     """
  *     if self._mapper.get().InputSymbols() == NULL:             # <<<<<<<<<<<<<<
@@ -16261,7 +16608,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
  */
   }
 
-  /* "pywrapfst.pyx":1417
+  /* "pywrapfst.pyx":1477
  *     if self._mapper.get().InputSymbols() == NULL:
  *       return
  *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=True)             # <<<<<<<<<<<<<<
@@ -16271,16 +16618,16 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1417, __pyx_L1_error)
+    __PYX_ERR(0, 1477, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapperSymbolTableView(__pyx_v_self->_mapper, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1417, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapperSymbolTableView(__pyx_v_self->_mapper, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1477, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1409
- *       return sstrm.str()
+  /* "pywrapfst.pyx":1469
+ *       return _sstrm.str()
  * 
  *   cpdef _EncodeMapperSymbolTableView input_symbols(self):             # <<<<<<<<<<<<<<
  *     """
@@ -16319,9 +16666,12 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_24input_symbols(struct __pyx
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("input_symbols", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_12EncodeMapper_input_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1409, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_12EncodeMapper_input_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1469, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -16338,7 +16688,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_24input_symbols(struct __pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1419
+/* "pywrapfst.pyx":1479
  *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=True)
  * 
  *   cpdef _EncodeMapperSymbolTableView output_symbols(self):             # <<<<<<<<<<<<<<
@@ -16355,6 +16705,9 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   int __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("output_symbols", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -16365,7 +16718,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_output_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1419, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_output_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1479, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_12EncodeMapper_27output_symbols)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -16382,10 +16735,10 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1419, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1479, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__EncodeMapperSymbolTableView))))) __PYX_ERR(0, 1419, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__EncodeMapperSymbolTableView))))) __PYX_ERR(0, 1479, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -16404,7 +16757,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":1425
+  /* "pywrapfst.pyx":1485
  *     Returns the mapper's output symbol table, or None if none is present.
  *     """
  *     if self._mapper.get().OutputSymbols() == NULL:             # <<<<<<<<<<<<<<
@@ -16413,12 +16766,12 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1425, __pyx_L1_error)
+    __PYX_ERR(0, 1485, __pyx_L1_error)
   }
   __pyx_t_5 = ((__pyx_v_self->_mapper.get()->OutputSymbols() == NULL) != 0);
   if (__pyx_t_5) {
 
-    /* "pywrapfst.pyx":1426
+    /* "pywrapfst.pyx":1486
  *     """
  *     if self._mapper.get().OutputSymbols() == NULL:
  *       return             # <<<<<<<<<<<<<<
@@ -16429,7 +16782,7 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
     __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)Py_None); __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":1425
+    /* "pywrapfst.pyx":1485
  *     Returns the mapper's output symbol table, or None if none is present.
  *     """
  *     if self._mapper.get().OutputSymbols() == NULL:             # <<<<<<<<<<<<<<
@@ -16438,25 +16791,25 @@ static struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *__pyx_f_9pywrap
  */
   }
 
-  /* "pywrapfst.pyx":1427
+  /* "pywrapfst.pyx":1487
  *     if self._mapper.get().OutputSymbols() == NULL:
  *       return
  *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=False)             # <<<<<<<<<<<<<<
  * 
- *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
+ *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1427, __pyx_L1_error)
+    __PYX_ERR(0, 1487, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapperSymbolTableView(__pyx_v_self->_mapper, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1427, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapperSymbolTableView(__pyx_v_self->_mapper, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1487, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1419
+  /* "pywrapfst.pyx":1479
  *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=True)
  * 
  *   cpdef _EncodeMapperSymbolTableView output_symbols(self):             # <<<<<<<<<<<<<<
@@ -16496,9 +16849,12 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_26output_symbols(struct __py
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("output_symbols", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_12EncodeMapper_output_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1419, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_12EncodeMapper_output_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1479, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -16515,86 +16871,89 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_26output_symbols(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1429
+/* "pywrapfst.pyx":1489
  *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=False)
  * 
- *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
- *     if syms is None:
+ *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:             # <<<<<<<<<<<<<<
+ *     if symbols is None:
  *       self._mapper.get().SetInputSymbols(NULL)
  */
 
-static void __pyx_f_9pywrapfst_12EncodeMapper__set_input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
+static void __pyx_f_9pywrapfst_12EncodeMapper__set_input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols) {
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   int __pyx_t_2;
   fst::SymbolTable const *__pyx_t_3;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_set_input_symbols", 0);
 
-  /* "pywrapfst.pyx":1430
+  /* "pywrapfst.pyx":1490
  * 
- *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
- *     if syms is None:             # <<<<<<<<<<<<<<
+ *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:
+ *     if symbols is None:             # <<<<<<<<<<<<<<
  *       self._mapper.get().SetInputSymbols(NULL)
  *       return
  */
-  __pyx_t_1 = (((PyObject *)__pyx_v_syms) == Py_None);
+  __pyx_t_1 = (((PyObject *)__pyx_v_symbols) == Py_None);
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":1431
- *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
- *     if syms is None:
+    /* "pywrapfst.pyx":1491
+ *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:
+ *     if symbols is None:
  *       self._mapper.get().SetInputSymbols(NULL)             # <<<<<<<<<<<<<<
  *       return
- *     self._mapper.get().SetInputSymbols(syms._raw_ptr_or_raise())
+ *     self._mapper.get().SetInputSymbols(symbols._raw_ptr_or_raise())
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-      __PYX_ERR(0, 1431, __pyx_L1_error)
+      __PYX_ERR(0, 1491, __pyx_L1_error)
     }
     __pyx_v_self->_mapper.get()->SetInputSymbols(NULL);
 
-    /* "pywrapfst.pyx":1432
- *     if syms is None:
+    /* "pywrapfst.pyx":1492
+ *     if symbols is None:
  *       self._mapper.get().SetInputSymbols(NULL)
  *       return             # <<<<<<<<<<<<<<
- *     self._mapper.get().SetInputSymbols(syms._raw_ptr_or_raise())
+ *     self._mapper.get().SetInputSymbols(symbols._raw_ptr_or_raise())
  * 
  */
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":1430
+    /* "pywrapfst.pyx":1490
  * 
- *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
- *     if syms is None:             # <<<<<<<<<<<<<<
+ *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:
+ *     if symbols is None:             # <<<<<<<<<<<<<<
  *       self._mapper.get().SetInputSymbols(NULL)
  *       return
  */
   }
 
-  /* "pywrapfst.pyx":1433
+  /* "pywrapfst.pyx":1493
  *       self._mapper.get().SetInputSymbols(NULL)
  *       return
- *     self._mapper.get().SetInputSymbols(syms._raw_ptr_or_raise())             # <<<<<<<<<<<<<<
+ *     self._mapper.get().SetInputSymbols(symbols._raw_ptr_or_raise())             # <<<<<<<<<<<<<<
  * 
- *   def set_input_symbols(self, _SymbolTable syms):
+ *   def set_input_symbols(self, SymbolTableView symbols):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1433, __pyx_L1_error)
+    __PYX_ERR(0, 1493, __pyx_L1_error)
   }
-  if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v_symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 1433, __pyx_L1_error)
+    __PYX_ERR(0, 1493, __pyx_L1_error)
   }
-  __pyx_t_3 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_syms->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_syms); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1433, __pyx_L1_error)
+  __pyx_t_3 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_symbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1493, __pyx_L1_error)
   __pyx_v_self->_mapper.get()->SetInputSymbols(__pyx_t_3);
 
-  /* "pywrapfst.pyx":1429
+  /* "pywrapfst.pyx":1489
  *     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=False)
  * 
- *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
- *     if syms is None:
+ *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:             # <<<<<<<<<<<<<<
+ *     if symbols is None:
  *       self._mapper.get().SetInputSymbols(NULL)
  */
 
@@ -16606,23 +16965,26 @@ static void __pyx_f_9pywrapfst_12EncodeMapper__set_input_symbols(struct __pyx_ob
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1435
- *     self._mapper.get().SetInputSymbols(syms._raw_ptr_or_raise())
+/* "pywrapfst.pyx":1495
+ *     self._mapper.get().SetInputSymbols(symbols._raw_ptr_or_raise())
  * 
- *   def set_input_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
+ *   def set_input_symbols(self, SymbolTableView symbols):             # <<<<<<<<<<<<<<
  *     """
- *     set_input_symbols(self, syms)
+ *     set_input_symbols(self, symbols)
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_29set_input_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
-static char __pyx_doc_9pywrapfst_12EncodeMapper_28set_input_symbols[] = "\n    set_input_symbols(self, syms)\n\n    Sets the mapper's input symbol table.\n\n    Passing None as a value will delete the input symbol table.\n\n    Args:\n      syms: A SymbolTable.\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_29set_input_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms) {
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_29set_input_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_symbols); /*proto*/
+static char __pyx_doc_9pywrapfst_12EncodeMapper_28set_input_symbols[] = "\n    set_input_symbols(self, symbols)\n\n    Sets the mapper's input symbol table.\n\n    Passing None as a value will delete the input symbol table.\n\n    Args:\n      symbols: A SymbolTable.\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_29set_input_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_symbols) {
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_input_symbols (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 1435, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_28set_input_symbols(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_syms));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_symbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "symbols", 0))) __PYX_ERR(0, 1495, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_28set_input_symbols(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_symbols));
 
   /* function exit code */
   goto __pyx_L0;
@@ -16633,42 +16995,45 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_29set_input_symbols(PyObject
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_28set_input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_28set_input_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_input_symbols", 0);
 
-  /* "pywrapfst.pyx":1449
+  /* "pywrapfst.pyx":1509
  *       self.
  *     """
- *     self._set_input_symbols(syms)             # <<<<<<<<<<<<<<
+ *     self._set_input_symbols(symbols)             # <<<<<<<<<<<<<<
  *     return self
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_input_symbols");
-    __PYX_ERR(0, 1449, __pyx_L1_error)
+    __PYX_ERR(0, 1509, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_EncodeMapper *)__pyx_v_self->__pyx_vtab)->_set_input_symbols(__pyx_v_self, __pyx_v_syms); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1449, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_EncodeMapper *)__pyx_v_self->__pyx_vtab)->_set_input_symbols(__pyx_v_self, __pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1509, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1450
+  /* "pywrapfst.pyx":1510
  *     """
- *     self._set_input_symbols(syms)
+ *     self._set_input_symbols(symbols)
  *     return self             # <<<<<<<<<<<<<<
  * 
- *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
+ *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1435
- *     self._mapper.get().SetInputSymbols(syms._raw_ptr_or_raise())
+  /* "pywrapfst.pyx":1495
+ *     self._mapper.get().SetInputSymbols(symbols._raw_ptr_or_raise())
  * 
- *   def set_input_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
+ *   def set_input_symbols(self, SymbolTableView symbols):             # <<<<<<<<<<<<<<
  *     """
- *     set_input_symbols(self, syms)
+ *     set_input_symbols(self, symbols)
  */
 
   /* function exit code */
@@ -16681,86 +17046,89 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_28set_input_symbols(struct _
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1452
+/* "pywrapfst.pyx":1512
  *     return self
  * 
- *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
- *     if syms is None:
+ *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:             # <<<<<<<<<<<<<<
+ *     if symbols is None:
  *       self._mapper.get().SetOutputSymbols(NULL)
  */
 
-static void __pyx_f_9pywrapfst_12EncodeMapper__set_output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
+static void __pyx_f_9pywrapfst_12EncodeMapper__set_output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols) {
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   int __pyx_t_2;
   fst::SymbolTable const *__pyx_t_3;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_set_output_symbols", 0);
 
-  /* "pywrapfst.pyx":1453
+  /* "pywrapfst.pyx":1513
  * 
- *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
- *     if syms is None:             # <<<<<<<<<<<<<<
+ *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:
+ *     if symbols is None:             # <<<<<<<<<<<<<<
  *       self._mapper.get().SetOutputSymbols(NULL)
  *       return
  */
-  __pyx_t_1 = (((PyObject *)__pyx_v_syms) == Py_None);
+  __pyx_t_1 = (((PyObject *)__pyx_v_symbols) == Py_None);
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":1454
- *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
- *     if syms is None:
+    /* "pywrapfst.pyx":1514
+ *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:
+ *     if symbols is None:
  *       self._mapper.get().SetOutputSymbols(NULL)             # <<<<<<<<<<<<<<
  *       return
- *     self._mapper.get().SetOutputSymbols(syms._raw_ptr_or_raise())
+ *     self._mapper.get().SetOutputSymbols(symbols._raw_ptr_or_raise())
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-      __PYX_ERR(0, 1454, __pyx_L1_error)
+      __PYX_ERR(0, 1514, __pyx_L1_error)
     }
     __pyx_v_self->_mapper.get()->SetOutputSymbols(NULL);
 
-    /* "pywrapfst.pyx":1455
- *     if syms is None:
+    /* "pywrapfst.pyx":1515
+ *     if symbols is None:
  *       self._mapper.get().SetOutputSymbols(NULL)
  *       return             # <<<<<<<<<<<<<<
- *     self._mapper.get().SetOutputSymbols(syms._raw_ptr_or_raise())
+ *     self._mapper.get().SetOutputSymbols(symbols._raw_ptr_or_raise())
  * 
  */
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":1453
+    /* "pywrapfst.pyx":1513
  * 
- *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
- *     if syms is None:             # <<<<<<<<<<<<<<
+ *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:
+ *     if symbols is None:             # <<<<<<<<<<<<<<
  *       self._mapper.get().SetOutputSymbols(NULL)
  *       return
  */
   }
 
-  /* "pywrapfst.pyx":1456
+  /* "pywrapfst.pyx":1516
  *       self._mapper.get().SetOutputSymbols(NULL)
  *       return
- *     self._mapper.get().SetOutputSymbols(syms._raw_ptr_or_raise())             # <<<<<<<<<<<<<<
+ *     self._mapper.get().SetOutputSymbols(symbols._raw_ptr_or_raise())             # <<<<<<<<<<<<<<
  * 
- *   def set_output_symbols(self, _SymbolTable syms):
+ *   def set_output_symbols(self, SymbolTableView symbols):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1456, __pyx_L1_error)
+    __PYX_ERR(0, 1516, __pyx_L1_error)
   }
-  if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v_symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 1456, __pyx_L1_error)
+    __PYX_ERR(0, 1516, __pyx_L1_error)
   }
-  __pyx_t_3 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_syms->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_syms); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1456, __pyx_L1_error)
+  __pyx_t_3 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_symbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1516, __pyx_L1_error)
   __pyx_v_self->_mapper.get()->SetOutputSymbols(__pyx_t_3);
 
-  /* "pywrapfst.pyx":1452
+  /* "pywrapfst.pyx":1512
  *     return self
  * 
- *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
- *     if syms is None:
+ *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:             # <<<<<<<<<<<<<<
+ *     if symbols is None:
  *       self._mapper.get().SetOutputSymbols(NULL)
  */
 
@@ -16772,23 +17140,26 @@ static void __pyx_f_9pywrapfst_12EncodeMapper__set_output_symbols(struct __pyx_o
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":1458
- *     self._mapper.get().SetOutputSymbols(syms._raw_ptr_or_raise())
+/* "pywrapfst.pyx":1518
+ *     self._mapper.get().SetOutputSymbols(symbols._raw_ptr_or_raise())
  * 
- *   def set_output_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
+ *   def set_output_symbols(self, SymbolTableView symbols):             # <<<<<<<<<<<<<<
  *     """
- *     set_output_symbols(self, syms)
+ *     set_output_symbols(self, symbols)
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_31set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
-static char __pyx_doc_9pywrapfst_12EncodeMapper_30set_output_symbols[] = "\n    set_output_symbols(self, syms)\n\n    Sets the mapper's output symbol table.\n\n    Passing None as a value will delete the output symbol table.\n\n    Args:\n      syms: A SymbolTable.\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_31set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms) {
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_31set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_symbols); /*proto*/
+static char __pyx_doc_9pywrapfst_12EncodeMapper_30set_output_symbols[] = "\n    set_output_symbols(self, symbols)\n\n    Sets the mapper's output symbol table.\n\n    Passing None as a value will delete the output symbol table.\n\n    Args:\n      symbols: A SymbolTable.\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_31set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_symbols) {
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_output_symbols (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 1458, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_30set_output_symbols(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_syms));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_symbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "symbols", 0))) __PYX_ERR(0, 1518, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_12EncodeMapper_30set_output_symbols(((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_symbols));
 
   /* function exit code */
   goto __pyx_L0;
@@ -16799,27 +17170,30 @@ static PyObject *__pyx_pw_9pywrapfst_12EncodeMapper_31set_output_symbols(PyObjec
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_30set_output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
+static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_30set_output_symbols(struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_output_symbols", 0);
 
-  /* "pywrapfst.pyx":1472
+  /* "pywrapfst.pyx":1532
  *       self.
  *     """
- *     self._set_output_symbols(syms)             # <<<<<<<<<<<<<<
+ *     self._set_output_symbols(symbols)             # <<<<<<<<<<<<<<
  *     return self
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_output_symbols");
-    __PYX_ERR(0, 1472, __pyx_L1_error)
+    __PYX_ERR(0, 1532, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_EncodeMapper *)__pyx_v_self->__pyx_vtab)->_set_output_symbols(__pyx_v_self, __pyx_v_syms); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1472, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_EncodeMapper *)__pyx_v_self->__pyx_vtab)->_set_output_symbols(__pyx_v_self, __pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1532, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1473
+  /* "pywrapfst.pyx":1533
  *     """
- *     self._set_output_symbols(syms)
+ *     self._set_output_symbols(symbols)
  *     return self             # <<<<<<<<<<<<<<
  * 
  * 
@@ -16829,12 +17203,12 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_30set_output_symbols(struct
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1458
- *     self._mapper.get().SetOutputSymbols(syms._raw_ptr_or_raise())
+  /* "pywrapfst.pyx":1518
+ *     self._mapper.get().SetOutputSymbols(symbols._raw_ptr_or_raise())
  * 
- *   def set_output_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
+ *   def set_output_symbols(self, SymbolTableView symbols):             # <<<<<<<<<<<<<<
  *     """
- *     set_output_symbols(self, syms)
+ *     set_output_symbols(self, symbols)
  */
 
   /* function exit code */
@@ -16847,7 +17221,7 @@ static PyObject *__pyx_pf_9pywrapfst_12EncodeMapper_30set_output_symbols(struct
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1476
+/* "pywrapfst.pyx":1536
  * 
  * 
  * cdef EncodeMapper _init_EncodeMapper(EncodeMapperClass_ptr mapper):             # <<<<<<<<<<<<<<
@@ -16860,21 +17234,24 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__init_Encode
   struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_init_EncodeMapper", 0);
 
-  /* "pywrapfst.pyx":1477
+  /* "pywrapfst.pyx":1537
  * 
  * cdef EncodeMapper _init_EncodeMapper(EncodeMapperClass_ptr mapper):
  *   cdef EncodeMapper result = EncodeMapper.__new__(EncodeMapper)             # <<<<<<<<<<<<<<
  *   result._mapper.reset(mapper)
  *   return result
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_EncodeMapper(((PyTypeObject *)__pyx_ptype_9pywrapfst_EncodeMapper), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1477, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_EncodeMapper(((PyTypeObject *)__pyx_ptype_9pywrapfst_EncodeMapper), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1537, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   __pyx_v_result = ((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1478
+  /* "pywrapfst.pyx":1538
  * cdef EncodeMapper _init_EncodeMapper(EncodeMapperClass_ptr mapper):
  *   cdef EncodeMapper result = EncodeMapper.__new__(EncodeMapper)
  *   result._mapper.reset(mapper)             # <<<<<<<<<<<<<<
@@ -16883,11 +17260,11 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__init_Encode
  */
   if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 1478, __pyx_L1_error)
+    __PYX_ERR(0, 1538, __pyx_L1_error)
   }
   __pyx_v_result->_mapper.reset(__pyx_v_mapper);
 
-  /* "pywrapfst.pyx":1479
+  /* "pywrapfst.pyx":1539
  *   cdef EncodeMapper result = EncodeMapper.__new__(EncodeMapper)
  *   result._mapper.reset(mapper)
  *   return result             # <<<<<<<<<<<<<<
@@ -16899,7 +17276,7 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__init_Encode
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1476
+  /* "pywrapfst.pyx":1536
  * 
  * 
  * cdef EncodeMapper _init_EncodeMapper(EncodeMapperClass_ptr mapper):             # <<<<<<<<<<<<<<
@@ -16919,120 +17296,121 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__init_Encode
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1482
+/* "pywrapfst.pyx":1542
  * 
  * 
- * cpdef EncodeMapper _read_EncodeMapper_from_string(state):             # <<<<<<<<<<<<<<
- *   cdef stringstream sstrm
- *   sstrm << tostring(state)
+ * cpdef EncodeMapper _read_EncodeMapper_from_string(string state):             # <<<<<<<<<<<<<<
+ *   cdef stringstream _sstrm
+ *   _sstrm << state
  */
 
-static PyObject *__pyx_pw_9pywrapfst_15_read_EncodeMapper_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state); /*proto*/
-static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__read_EncodeMapper_from_string(PyObject *__pyx_v_state, CYTHON_UNUSED int __pyx_skip_dispatch) {
-  std::stringstream __pyx_v_sstrm;
-  std::unique_ptr<fst::script::EncodeMapperClass>  __pyx_v_mapper;
+static PyObject *__pyx_pw_9pywrapfst_15_read_EncodeMapper_from_string(PyObject *__pyx_self, PyObject *__pyx_arg_state); /*proto*/
+static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__read_EncodeMapper_from_string(std::string __pyx_v_state, CYTHON_UNUSED int __pyx_skip_dispatch) {
+  std::stringstream __pyx_v__sstrm;
+  std::unique_ptr<fst::script::EncodeMapperClass>  __pyx_v__mapper;
   struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  std::string __pyx_t_1;
-  int __pyx_t_2;
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_read_EncodeMapper_from_string", 0);
 
-  /* "pywrapfst.pyx":1484
- * cpdef EncodeMapper _read_EncodeMapper_from_string(state):
- *   cdef stringstream sstrm
- *   sstrm << tostring(state)             # <<<<<<<<<<<<<<
- *   cdef unique_ptr[fst.EncodeMapperClass] mapper
- *   mapper.reset(fst.EncodeMapperClass.ReadStream(sstrm, b"<pywrapfst>"))
+  /* "pywrapfst.pyx":1544
+ * cpdef EncodeMapper _read_EncodeMapper_from_string(string state):
+ *   cdef stringstream _sstrm
+ *   _sstrm << state             # <<<<<<<<<<<<<<
+ *   cdef unique_ptr[fst.EncodeMapperClass] _mapper
+ *   _mapper.reset(fst.EncodeMapperClass.ReadStream(_sstrm, b"<pywrapfst>"))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1484, __pyx_L1_error)
-  (void)((__pyx_v_sstrm << __pyx_t_1));
+  (void)((__pyx_v__sstrm << __pyx_v_state));
 
-  /* "pywrapfst.pyx":1486
- *   sstrm << tostring(state)
- *   cdef unique_ptr[fst.EncodeMapperClass] mapper
- *   mapper.reset(fst.EncodeMapperClass.ReadStream(sstrm, b"<pywrapfst>"))             # <<<<<<<<<<<<<<
- *   if mapper.get() == NULL:
- *     raise FstIOError("Read failed")
+  /* "pywrapfst.pyx":1546
+ *   _sstrm << state
+ *   cdef unique_ptr[fst.EncodeMapperClass] _mapper
+ *   _mapper.reset(fst.EncodeMapperClass.ReadStream(_sstrm, b"<pywrapfst>"))             # <<<<<<<<<<<<<<
+ *   if _mapper.get() == NULL:
+ *     raise FstIOError("Read from string failed")
  */
-  __pyx_v_mapper.reset(fst::script::EncodeMapperClass::Read(__pyx_v_sstrm, __pyx_k_pywrapfst));
+  __pyx_v__mapper.reset(fst::script::EncodeMapperClass::Read(__pyx_v__sstrm, __pyx_k_pywrapfst));
 
-  /* "pywrapfst.pyx":1487
- *   cdef unique_ptr[fst.EncodeMapperClass] mapper
- *   mapper.reset(fst.EncodeMapperClass.ReadStream(sstrm, b"<pywrapfst>"))
- *   if mapper.get() == NULL:             # <<<<<<<<<<<<<<
- *     raise FstIOError("Read failed")
- *   return _init_EncodeMapper(mapper.release())
+  /* "pywrapfst.pyx":1547
+ *   cdef unique_ptr[fst.EncodeMapperClass] _mapper
+ *   _mapper.reset(fst.EncodeMapperClass.ReadStream(_sstrm, b"<pywrapfst>"))
+ *   if _mapper.get() == NULL:             # <<<<<<<<<<<<<<
+ *     raise FstIOError("Read from string failed")
+ *   return _init_EncodeMapper(_mapper.release())
  */
-  __pyx_t_2 = ((__pyx_v_mapper.get() == NULL) != 0);
-  if (unlikely(__pyx_t_2)) {
+  __pyx_t_1 = ((__pyx_v__mapper.get() == NULL) != 0);
+  if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":1488
- *   mapper.reset(fst.EncodeMapperClass.ReadStream(sstrm, b"<pywrapfst>"))
- *   if mapper.get() == NULL:
- *     raise FstIOError("Read failed")             # <<<<<<<<<<<<<<
- *   return _init_EncodeMapper(mapper.release())
+    /* "pywrapfst.pyx":1548
+ *   _mapper.reset(fst.EncodeMapperClass.ReadStream(_sstrm, b"<pywrapfst>"))
+ *   if _mapper.get() == NULL:
+ *     raise FstIOError("Read from string failed")             # <<<<<<<<<<<<<<
+ *   return _init_EncodeMapper(_mapper.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1488, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = NULL;
-    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
-      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
-      if (likely(__pyx_t_5)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-        __Pyx_INCREF(__pyx_t_5);
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1548, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = NULL;
+    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
+      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+      if (likely(__pyx_t_4)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+        __Pyx_INCREF(__pyx_t_4);
         __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_4, function);
+        __Pyx_DECREF_SET(__pyx_t_3, function);
       }
     }
-    __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_Read_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_Read_failed);
-    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1488, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Read_from_string_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Read_from_string_failed);
+    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1548, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 1488, __pyx_L1_error)
+    __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __PYX_ERR(0, 1548, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1487
- *   cdef unique_ptr[fst.EncodeMapperClass] mapper
- *   mapper.reset(fst.EncodeMapperClass.ReadStream(sstrm, b"<pywrapfst>"))
- *   if mapper.get() == NULL:             # <<<<<<<<<<<<<<
- *     raise FstIOError("Read failed")
- *   return _init_EncodeMapper(mapper.release())
+    /* "pywrapfst.pyx":1547
+ *   cdef unique_ptr[fst.EncodeMapperClass] _mapper
+ *   _mapper.reset(fst.EncodeMapperClass.ReadStream(_sstrm, b"<pywrapfst>"))
+ *   if _mapper.get() == NULL:             # <<<<<<<<<<<<<<
+ *     raise FstIOError("Read from string failed")
+ *   return _init_EncodeMapper(_mapper.release())
  */
   }
 
-  /* "pywrapfst.pyx":1489
- *   if mapper.get() == NULL:
- *     raise FstIOError("Read failed")
- *   return _init_EncodeMapper(mapper.release())             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1549
+ *   if _mapper.get() == NULL:
+ *     raise FstIOError("Read from string failed")
+ *   return _init_EncodeMapper(_mapper.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapper(__pyx_v_mapper.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1489, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_t_3);
-  __pyx_t_3 = 0;
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_EncodeMapper(__pyx_v__mapper.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1549, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_t_2);
+  __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1482
+  /* "pywrapfst.pyx":1542
  * 
  * 
- * cpdef EncodeMapper _read_EncodeMapper_from_string(state):             # <<<<<<<<<<<<<<
- *   cdef stringstream sstrm
- *   sstrm << tostring(state)
+ * cpdef EncodeMapper _read_EncodeMapper_from_string(string state):             # <<<<<<<<<<<<<<
+ *   cdef stringstream _sstrm
+ *   _sstrm << state
  */
 
   /* function exit code */
   __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
   __Pyx_AddTraceback("pywrapfst._read_EncodeMapper_from_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
@@ -17042,25 +17420,41 @@ static struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_f_9pywrapfst__read_Encode
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_15_read_EncodeMapper_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_15_read_EncodeMapper_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state) {
+static PyObject *__pyx_pw_9pywrapfst_15_read_EncodeMapper_from_string(PyObject *__pyx_self, PyObject *__pyx_arg_state); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_15_read_EncodeMapper_from_string(PyObject *__pyx_self, PyObject *__pyx_arg_state) {
+  std::string __pyx_v_state;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_read_EncodeMapper_from_string (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_14_read_EncodeMapper_from_string(__pyx_self, ((PyObject *)__pyx_v_state));
+  assert(__pyx_arg_state); {
+    __pyx_v_state = __pyx_convert_string_from_py_std__in_string(__pyx_arg_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1542, __pyx_L3_error)
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("pywrapfst._read_EncodeMapper_from_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_9pywrapfst_14_read_EncodeMapper_from_string(__pyx_self, ((std::string)__pyx_v_state));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_14_read_EncodeMapper_from_string(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_state) {
+static PyObject *__pyx_pf_9pywrapfst_14_read_EncodeMapper_from_string(CYTHON_UNUSED PyObject *__pyx_self, std::string __pyx_v_state) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_read_EncodeMapper_from_string", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_EncodeMapper_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1482, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_EncodeMapper_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1542, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -17077,7 +17471,7 @@ static PyObject *__pyx_pf_9pywrapfst_14_read_EncodeMapper_from_string(CYTHON_UNU
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1515
+/* "pywrapfst.pyx":1575
  * 
  *   @staticmethod
  *   cdef string _local_render_svg(const string &dot):             # <<<<<<<<<<<<<<
@@ -17094,79 +17488,82 @@ static std::string __pyx_f_9pywrapfst_3Fst__local_render_svg(std::string const &
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   std::string __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_local_render_svg", 0);
 
-  /* "pywrapfst.pyx":1516
+  /* "pywrapfst.pyx":1576
  *   @staticmethod
  *   cdef string _local_render_svg(const string &dot):
  *     proc = subprocess.Popen(("dot", "-Tsvg"),             # <<<<<<<<<<<<<<
  *                             stdin=subprocess.PIPE,
  *                             stdout=subprocess.PIPE)
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_subprocess); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1516, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_subprocess); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1576, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_Popen); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1516, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_Popen); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1576, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1517
+  /* "pywrapfst.pyx":1577
  *   cdef string _local_render_svg(const string &dot):
  *     proc = subprocess.Popen(("dot", "-Tsvg"),
  *                             stdin=subprocess.PIPE,             # <<<<<<<<<<<<<<
  *                             stdout=subprocess.PIPE)
  *     return proc.communicate(dot.encode("utf8"))[0]
  */
-  __pyx_t_1 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1517, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1577, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_subprocess); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1517, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_subprocess); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1577, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_PIPE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1517, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_PIPE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1577, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_stdin, __pyx_t_4) < 0) __PYX_ERR(0, 1517, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_stdin, __pyx_t_4) < 0) __PYX_ERR(0, 1577, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "pywrapfst.pyx":1518
+  /* "pywrapfst.pyx":1578
  *     proc = subprocess.Popen(("dot", "-Tsvg"),
  *                             stdin=subprocess.PIPE,
  *                             stdout=subprocess.PIPE)             # <<<<<<<<<<<<<<
  *     return proc.communicate(dot.encode("utf8"))[0]
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_subprocess); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1518, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_subprocess); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1578, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_PIPE); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1518, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_PIPE); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1578, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_stdout, __pyx_t_3) < 0) __PYX_ERR(0, 1517, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_stdout, __pyx_t_3) < 0) __PYX_ERR(0, 1577, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "pywrapfst.pyx":1516
+  /* "pywrapfst.pyx":1576
  *   @staticmethod
  *   cdef string _local_render_svg(const string &dot):
  *     proc = subprocess.Popen(("dot", "-Tsvg"),             # <<<<<<<<<<<<<<
  *                             stdin=subprocess.PIPE,
  *                             stdout=subprocess.PIPE)
  */
-  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__7, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1516, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__10, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1576, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_v_proc = __pyx_t_3;
   __pyx_t_3 = 0;
 
-  /* "pywrapfst.pyx":1519
+  /* "pywrapfst.pyx":1579
  *                             stdin=subprocess.PIPE,
  *                             stdout=subprocess.PIPE)
  *     return proc.communicate(dot.encode("utf8"))[0]             # <<<<<<<<<<<<<<
  * 
  *   def _repr_svg_(self):
  */
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_proc, __pyx_n_s_communicate); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1519, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_proc, __pyx_n_s_communicate); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1579, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_dot); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1519, __pyx_L1_error)
+  __pyx_t_2 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_dot); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1579, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_4 = PyUnicode_AsUTF8String(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1519, __pyx_L1_error)
+  __pyx_t_4 = PyUnicode_AsUTF8String(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1579, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_t_2 = NULL;
@@ -17182,22 +17579,22 @@ static std::string __pyx_f_9pywrapfst_3Fst__local_render_svg(std::string const &
   __pyx_t_3 = (__pyx_t_2) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_2, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_4);
   __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1519, __pyx_L1_error)
+  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1579, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   if (unlikely(__pyx_t_3 == Py_None)) {
     PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
-    __PYX_ERR(0, 1519, __pyx_L1_error)
+    __PYX_ERR(0, 1579, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_3, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1519, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_3, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1579, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1519, __pyx_L1_error)
+  __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1579, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_5;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1515
+  /* "pywrapfst.pyx":1575
  * 
  *   @staticmethod
  *   cdef string _local_render_svg(const string &dot):             # <<<<<<<<<<<<<<
@@ -17219,7 +17616,7 @@ static std::string __pyx_f_9pywrapfst_3Fst__local_render_svg(std::string const &
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1521
+/* "pywrapfst.pyx":1581
  *     return proc.communicate(dot.encode("utf8"))[0]
  * 
  *   def _repr_svg_(self):             # <<<<<<<<<<<<<<
@@ -17242,7 +17639,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_1_repr_svg_(PyObject *__pyx_v_self, CY
 }
 
 static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self) {
-  std::stringstream __pyx_v_sstrm;
+  std::stringstream __pyx_v__sstrm;
   bool __pyx_v_acceptor;
   PyObject *__pyx_v_e = NULL;
   PyObject *__pyx_r = NULL;
@@ -17266,71 +17663,82 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
   PyObject *__pyx_t_17 = NULL;
   PyObject *__pyx_t_18 = NULL;
   PyObject *__pyx_t_19 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_repr_svg_", 0);
 
-  /* "pywrapfst.pyx":1529
+  /* "pywrapfst.pyx":1589
  *     """
- *     cdef stringstream sstrm
+ *     cdef stringstream _sstrm
  *     cdef bool acceptor = (self._fst.get().Properties(fst.kAcceptor, True) ==             # <<<<<<<<<<<<<<
  *                           fst.kAcceptor)
- *     fst.Draw(deref(self._fst), self._fst.get().InputSymbols(),
+ *     fst.Draw(deref(self._fst),
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1529, __pyx_L1_error)
+    __PYX_ERR(0, 1589, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1530
- *     cdef stringstream sstrm
+  /* "pywrapfst.pyx":1590
+ *     cdef stringstream _sstrm
  *     cdef bool acceptor = (self._fst.get().Properties(fst.kAcceptor, True) ==
  *                           fst.kAcceptor)             # <<<<<<<<<<<<<<
- *     fst.Draw(deref(self._fst), self._fst.get().InputSymbols(),
- *              self._fst.get().OutputSymbols(), NULL, acceptor, b"", 8.5, 11,
+ *     fst.Draw(deref(self._fst),
+ *              self._fst.get().InputSymbols(),
  */
   __pyx_v_acceptor = (__pyx_v_self->_fst.get()->Properties(fst::kAcceptor, 1) == fst::kAcceptor);
 
-  /* "pywrapfst.pyx":1531
+  /* "pywrapfst.pyx":1591
  *     cdef bool acceptor = (self._fst.get().Properties(fst.kAcceptor, True) ==
  *                           fst.kAcceptor)
- *     fst.Draw(deref(self._fst), self._fst.get().InputSymbols(),             # <<<<<<<<<<<<<<
- *              self._fst.get().OutputSymbols(), NULL, acceptor, b"", 8.5, 11,
- *              True, False, 0.4, 0.25, 14, 5, b"g", False, sstrm,
+ *     fst.Draw(deref(self._fst),             # <<<<<<<<<<<<<<
+ *              self._fst.get().InputSymbols(),
+ *              self._fst.get().OutputSymbols(),
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1531, __pyx_L1_error)
+    __PYX_ERR(0, 1591, __pyx_L1_error)
   }
+
+  /* "pywrapfst.pyx":1592
+ *                           fst.kAcceptor)
+ *     fst.Draw(deref(self._fst),
+ *              self._fst.get().InputSymbols(),             # <<<<<<<<<<<<<<
+ *              self._fst.get().OutputSymbols(),
+ *              NULL,
+ */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1531, __pyx_L1_error)
+    __PYX_ERR(0, 1592, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1532
- *                           fst.kAcceptor)
- *     fst.Draw(deref(self._fst), self._fst.get().InputSymbols(),
- *              self._fst.get().OutputSymbols(), NULL, acceptor, b"", 8.5, 11,             # <<<<<<<<<<<<<<
- *              True, False, 0.4, 0.25, 14, 5, b"g", False, sstrm,
- *              b"<pywrapfst>")
+  /* "pywrapfst.pyx":1593
+ *     fst.Draw(deref(self._fst),
+ *              self._fst.get().InputSymbols(),
+ *              self._fst.get().OutputSymbols(),             # <<<<<<<<<<<<<<
+ *              NULL,
+ *              acceptor,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1532, __pyx_L1_error)
+    __PYX_ERR(0, 1593, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1531
+  /* "pywrapfst.pyx":1591
  *     cdef bool acceptor = (self._fst.get().Properties(fst.kAcceptor, True) ==
  *                           fst.kAcceptor)
- *     fst.Draw(deref(self._fst), self._fst.get().InputSymbols(),             # <<<<<<<<<<<<<<
- *              self._fst.get().OutputSymbols(), NULL, acceptor, b"", 8.5, 11,
- *              True, False, 0.4, 0.25, 14, 5, b"g", False, sstrm,
+ *     fst.Draw(deref(self._fst),             # <<<<<<<<<<<<<<
+ *              self._fst.get().InputSymbols(),
+ *              self._fst.get().OutputSymbols(),
  */
-  fst::script::Draw((*__pyx_v_self->_fst), __pyx_v_self->_fst.get()->InputSymbols(), __pyx_v_self->_fst.get()->OutputSymbols(), NULL, __pyx_v_acceptor, __pyx_k__8, 8.5, 11.0, 1, 0, 0.4, 0.25, 14, 5, __pyx_k_g, 0, __pyx_v_sstrm, __pyx_k_pywrapfst);
+  fst::script::Draw((*__pyx_v_self->_fst), __pyx_v_self->_fst.get()->InputSymbols(), __pyx_v_self->_fst.get()->OutputSymbols(), NULL, __pyx_v_acceptor, __pyx_k__11, 8.5, 11.0, 1, 0, 0.4, 0.25, 14, 5, __pyx_k_g, 0, __pyx_v__sstrm, __pyx_k_pywrapfst);
 
-  /* "pywrapfst.pyx":1535
- *              True, False, 0.4, 0.25, 14, 5, b"g", False, sstrm,
+  /* "pywrapfst.pyx":1609
+ *              _sstrm,
  *              b"<pywrapfst>")
  *     try:             # <<<<<<<<<<<<<<
- *       return Fst._local_render_svg(sstrm.str())
+ *       return Fst._local_render_svg(_sstrm.str())
  *     except Exception as e:
  */
   {
@@ -17342,34 +17750,34 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
     __Pyx_XGOTREF(__pyx_t_3);
     /*try:*/ {
 
-      /* "pywrapfst.pyx":1536
+      /* "pywrapfst.pyx":1610
  *              b"<pywrapfst>")
  *     try:
- *       return Fst._local_render_svg(sstrm.str())             # <<<<<<<<<<<<<<
+ *       return Fst._local_render_svg(_sstrm.str())             # <<<<<<<<<<<<<<
  *     except Exception as e:
  *       logging.error("Dot rendering failed: %s", e)
  */
       __Pyx_XDECREF(__pyx_r);
-      __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_3Fst__local_render_svg(__pyx_v_sstrm.str())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1536, __pyx_L3_error)
+      __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_3Fst__local_render_svg(__pyx_v__sstrm.str())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1610, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_4);
       __pyx_r = __pyx_t_4;
       __pyx_t_4 = 0;
       goto __pyx_L7_try_return;
 
-      /* "pywrapfst.pyx":1535
- *              True, False, 0.4, 0.25, 14, 5, b"g", False, sstrm,
+      /* "pywrapfst.pyx":1609
+ *              _sstrm,
  *              b"<pywrapfst>")
  *     try:             # <<<<<<<<<<<<<<
- *       return Fst._local_render_svg(sstrm.str())
+ *       return Fst._local_render_svg(_sstrm.str())
  *     except Exception as e:
  */
     }
     __pyx_L3_error:;
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "pywrapfst.pyx":1537
+    /* "pywrapfst.pyx":1611
  *     try:
- *       return Fst._local_render_svg(sstrm.str())
+ *       return Fst._local_render_svg(_sstrm.str())
  *     except Exception as e:             # <<<<<<<<<<<<<<
  *       logging.error("Dot rendering failed: %s", e)
  * 
@@ -17377,7 +17785,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
     __pyx_t_5 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
     if (__pyx_t_5) {
       __Pyx_AddTraceback("pywrapfst.Fst._repr_svg_", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(0, 1537, __pyx_L5_except_error)
+      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(0, 1611, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_GOTREF(__pyx_t_6);
       __Pyx_GOTREF(__pyx_t_7);
@@ -17385,16 +17793,16 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
       __pyx_v_e = __pyx_t_6;
       /*try:*/ {
 
-        /* "pywrapfst.pyx":1538
- *       return Fst._local_render_svg(sstrm.str())
+        /* "pywrapfst.pyx":1612
+ *       return Fst._local_render_svg(_sstrm.str())
  *     except Exception as e:
  *       logging.error("Dot rendering failed: %s", e)             # <<<<<<<<<<<<<<
  * 
  *   def __init__(self):
  */
-        __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_logging); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1538, __pyx_L14_error)
+        __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_logging); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1612, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_9);
-        __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_error); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1538, __pyx_L14_error)
+        __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_error); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1612, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_10);
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
         __pyx_t_9 = NULL;
@@ -17412,7 +17820,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_10)) {
           PyObject *__pyx_temp[3] = {__pyx_t_9, __pyx_kp_u_Dot_rendering_failed_s, __pyx_v_e};
-          __pyx_t_8 = __Pyx_PyFunction_FastCall(__pyx_t_10, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1538, __pyx_L14_error)
+          __pyx_t_8 = __Pyx_PyFunction_FastCall(__pyx_t_10, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1612, __pyx_L14_error)
           __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
           __Pyx_GOTREF(__pyx_t_8);
         } else
@@ -17420,13 +17828,13 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_10)) {
           PyObject *__pyx_temp[3] = {__pyx_t_9, __pyx_kp_u_Dot_rendering_failed_s, __pyx_v_e};
-          __pyx_t_8 = __Pyx_PyCFunction_FastCall(__pyx_t_10, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1538, __pyx_L14_error)
+          __pyx_t_8 = __Pyx_PyCFunction_FastCall(__pyx_t_10, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1612, __pyx_L14_error)
           __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
           __Pyx_GOTREF(__pyx_t_8);
         } else
         #endif
         {
-          __pyx_t_11 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1538, __pyx_L14_error)
+          __pyx_t_11 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1612, __pyx_L14_error)
           __Pyx_GOTREF(__pyx_t_11);
           if (__pyx_t_9) {
             __Pyx_GIVEREF(__pyx_t_9); PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_9); __pyx_t_9 = NULL;
@@ -17437,7 +17845,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
           __Pyx_INCREF(__pyx_v_e);
           __Pyx_GIVEREF(__pyx_v_e);
           PyTuple_SET_ITEM(__pyx_t_11, 1+__pyx_t_5, __pyx_v_e);
-          __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_11, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1538, __pyx_L14_error)
+          __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_11, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1612, __pyx_L14_error)
           __Pyx_GOTREF(__pyx_t_8);
           __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
         }
@@ -17445,9 +17853,9 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
         __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
       }
 
-      /* "pywrapfst.pyx":1537
+      /* "pywrapfst.pyx":1611
  *     try:
- *       return Fst._local_render_svg(sstrm.str())
+ *       return Fst._local_render_svg(_sstrm.str())
  *     except Exception as e:             # <<<<<<<<<<<<<<
  *       logging.error("Dot rendering failed: %s", e)
  * 
@@ -17477,7 +17885,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
           __Pyx_XGOTREF(__pyx_t_19);
           __pyx_t_5 = __pyx_lineno; __pyx_t_12 = __pyx_clineno; __pyx_t_13 = __pyx_filename;
           {
-            __Pyx_DECREF(__pyx_v_e);
+            __Pyx_XDECREF(__pyx_v_e);
             __pyx_v_e = NULL;
           }
           if (PY_MAJOR_VERSION >= 3) {
@@ -17504,11 +17912,11 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "pywrapfst.pyx":1535
- *              True, False, 0.4, 0.25, 14, 5, b"g", False, sstrm,
+    /* "pywrapfst.pyx":1609
+ *              _sstrm,
  *              b"<pywrapfst>")
  *     try:             # <<<<<<<<<<<<<<
- *       return Fst._local_render_svg(sstrm.str())
+ *       return Fst._local_render_svg(_sstrm.str())
  *     except Exception as e:
  */
     __Pyx_XGIVEREF(__pyx_t_1);
@@ -17529,7 +17937,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
     __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3);
   }
 
-  /* "pywrapfst.pyx":1521
+  /* "pywrapfst.pyx":1581
  *     return proc.communicate(dot.encode("utf8"))[0]
  * 
  *   def _repr_svg_(self):             # <<<<<<<<<<<<<<
@@ -17557,12 +17965,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst__repr_svg_(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1540
+/* "pywrapfst.pyx":1614
  *       logging.error("Dot rendering failed: %s", e)
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
- *     raise FstDeletedConstructorError(
- *         "Cannot construct {}".format(self.__class__.__name__))
+ *     raise NotImplementedError(f"Cannot construct {self._class__.__name__}")
+ * 
  */
 
 /* Python wrapper */
@@ -17586,95 +17994,55 @@ static int __pyx_pf_9pywrapfst_3Fst_2__init__(struct __pyx_obj_9pywrapfst_Fst *_
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":1541
+  /* "pywrapfst.pyx":1615
  * 
  *   def __init__(self):
- *     raise FstDeletedConstructorError(             # <<<<<<<<<<<<<<
- *         "Cannot construct {}".format(self.__class__.__name__))
- * 
- */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1541, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-
-  /* "pywrapfst.pyx":1542
- *   def __init__(self):
- *     raise FstDeletedConstructorError(
- *         "Cannot construct {}".format(self.__class__.__name__))             # <<<<<<<<<<<<<<
+ *     raise NotImplementedError(f"Cannot construct {self._class__.__name__}")             # <<<<<<<<<<<<<<
  * 
  *   # Registers the class for pickling; must be repeated in any subclass which
  */
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1542, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1542, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_name); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1542, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = NULL;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) {
-    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
-    if (likely(__pyx_t_5)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-      __Pyx_INCREF(__pyx_t_5);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_4, function);
-    }
-  }
-  __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1542, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = NULL;
-  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
-    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
-    if (likely(__pyx_t_4)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-      __Pyx_INCREF(__pyx_t_4);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_2, function);
-    }
-  }
-  __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1541, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1615, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1615, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_t_2, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1615, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Cannot_construct, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1615, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_NotImplementedError, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1615, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(0, 1541, __pyx_L1_error)
+  __PYX_ERR(0, 1615, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1540
+  /* "pywrapfst.pyx":1614
  *       logging.error("Dot rendering failed: %s", e)
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
- *     raise FstDeletedConstructorError(
- *         "Cannot construct {}".format(self.__class__.__name__))
+ *     raise NotImplementedError(f"Cannot construct {self._class__.__name__}")
+ * 
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
   __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
   __Pyx_AddTraceback("pywrapfst.Fst.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = -1;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1547
+/* "pywrapfst.pyx":1620
  *   # can't be derived by _init_XFst.
  * 
  *   def __reduce__(self):             # <<<<<<<<<<<<<<
@@ -17701,9 +18069,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_4__reduce__(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__reduce__", 0);
 
-  /* "pywrapfst.pyx":1548
+  /* "pywrapfst.pyx":1621
  * 
  *   def __reduce__(self):
  *     return (_read_Fst_from_string, (self.write_to_string(),))             # <<<<<<<<<<<<<<
@@ -17711,20 +18082,20 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_4__reduce__(struct __pyx_obj_9pywrapfs
  *   def __repr__(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_read_Fst_from_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1548, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_read_Fst_from_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1621, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "write_to_string");
-    __PYX_ERR(0, 1548, __pyx_L1_error)
+    __PYX_ERR(0, 1621, __pyx_L1_error)
   }
-  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_self->__pyx_vtab)->write_to_string(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1548, __pyx_L1_error)
+  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_self->__pyx_vtab)->write_to_string(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1621, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1548, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1621, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_GIVEREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
   __pyx_t_2 = 0;
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1548, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1621, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
@@ -17736,7 +18107,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_4__reduce__(struct __pyx_obj_9pywrapfs
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1547
+  /* "pywrapfst.pyx":1620
  *   # can't be derived by _init_XFst.
  * 
  *   def __reduce__(self):             # <<<<<<<<<<<<<<
@@ -17757,11 +18128,11 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_4__reduce__(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1550
+/* "pywrapfst.pyx":1623
  *     return (_read_Fst_from_string, (self.write_to_string(),))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<{} Fst at 0x{:x}>".format(self.fst_type(), id(self))
+ *     return f"<{self.fst_type()} Fst at 0x{id(self):x}>"
  * 
  */
 
@@ -17782,101 +18153,80 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_6__repr__(struct __pyx_obj_9pywrapfst_
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_2;
+  Py_UCS4 __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
-  int __pyx_t_6;
-  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":1551
+  /* "pywrapfst.pyx":1624
  * 
  *   def __repr__(self):
- *     return "<{} Fst at 0x{:x}>".format(self.fst_type(), id(self))             # <<<<<<<<<<<<<<
+ *     return f"<{self.fst_type()} Fst at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
  * 
  *   def __str__(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Fst_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1551, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1624, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 127;
+  __Pyx_INCREF(__pyx_kp_u__2);
+  __pyx_t_2 += 1;
+  __Pyx_GIVEREF(__pyx_kp_u__2);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u__2);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "fst_type");
-    __PYX_ERR(0, 1551, __pyx_L1_error)
+    __PYX_ERR(0, 1624, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_self->__pyx_vtab)->fst_type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1551, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1551, __pyx_L1_error)
+  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_self->__pyx_vtab)->fst_type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1624, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = NULL;
-  __pyx_t_6 = 0;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
-    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2);
-    if (likely(__pyx_t_5)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-      __Pyx_INCREF(__pyx_t_5);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_2, function);
-      __pyx_t_6 = 1;
-    }
-  }
-  #if CYTHON_FAST_PYCALL
-  if (PyFunction_Check(__pyx_t_2)) {
-    PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1551, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  } else
-  #endif
-  #if CYTHON_FAST_PYCCALL
-  if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
-    PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1551, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  } else
-  #endif
-  {
-    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1551, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_7);
-    if (__pyx_t_5) {
-      __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL;
-    }
-    __Pyx_GIVEREF(__pyx_t_3);
-    PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_6, __pyx_t_3);
-    __Pyx_GIVEREF(__pyx_t_4);
-    PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_4);
-    __pyx_t_3 = 0;
-    __pyx_t_4 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1551, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  }
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_4);
+  __pyx_t_4 = 0;
+  __Pyx_INCREF(__pyx_kp_u_Fst_at_0x);
+  __pyx_t_2 += 10;
+  __Pyx_GIVEREF(__pyx_kp_u_Fst_at_0x);
+  PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_Fst_at_0x);
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1624, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1624, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_t_5);
+  __pyx_t_5 = 0;
+  __Pyx_INCREF(__pyx_kp_u__3);
+  __pyx_t_2 += 1;
+  __Pyx_GIVEREF(__pyx_kp_u__3);
+  PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_kp_u__3);
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1624, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1550
+  /* "pywrapfst.pyx":1623
  *     return (_read_Fst_from_string, (self.write_to_string(),))
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<{} Fst at 0x{:x}>".format(self.fst_type(), id(self))
+ *     return f"<{self.fst_type()} Fst at 0x{id(self):x}>"
  * 
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_AddTraceback("pywrapfst.Fst.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -17885,8 +18235,8 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_6__repr__(struct __pyx_obj_9pywrapfst_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1553
- *     return "<{} Fst at 0x{:x}>".format(self.fst_type(), id(self))
+/* "pywrapfst.pyx":1626
+ *     return f"<{self.fst_type()} Fst at 0x{id(self):x}>"
  * 
  *   def __str__(self):             # <<<<<<<<<<<<<<
  *     return self.print()
@@ -17911,9 +18261,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_8__str__(struct __pyx_obj_9pywrapfst_F
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__str__", 0);
 
-  /* "pywrapfst.pyx":1554
+  /* "pywrapfst.pyx":1627
  * 
  *   def __str__(self):
  *     return self.print()             # <<<<<<<<<<<<<<
@@ -17923,17 +18276,17 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_8__str__(struct __pyx_obj_9pywrapfst_F
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "print");
-    __PYX_ERR(0, 1554, __pyx_L1_error)
+    __PYX_ERR(0, 1627, __pyx_L1_error)
   }
-  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_self->__pyx_vtab)->print(__pyx_v_self, 0, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1554, __pyx_L1_error)
-  __pyx_t_2 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1554, __pyx_L1_error)
+  __pyx_t_1 = ((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_self->__pyx_vtab)->print(__pyx_v_self, 0, NULL); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1627, __pyx_L1_error)
+  __pyx_t_2 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1627, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1553
- *     return "<{} Fst at 0x{:x}>".format(self.fst_type(), id(self))
+  /* "pywrapfst.pyx":1626
+ *     return f"<{self.fst_type()} Fst at 0x{id(self):x}>"
  * 
  *   def __str__(self):             # <<<<<<<<<<<<<<
  *     return self.print()
@@ -17951,7 +18304,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_8__str__(struct __pyx_obj_9pywrapfst_F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1556
+/* "pywrapfst.pyx":1629
  *     return self.print()
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -17968,6 +18321,9 @@ static std::string __pyx_f_9pywrapfst_3Fst_arc_type(struct __pyx_obj_9pywrapfst_
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   std::string __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("arc_type", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -17978,7 +18334,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_arc_type(struct __pyx_obj_9pywrapfst_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1556, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1629, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_11arc_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -17994,10 +18350,10 @@ static std::string __pyx_f_9pywrapfst_3Fst_arc_type(struct __pyx_obj_9pywrapfst_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1556, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1629, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1556, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1629, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -18016,7 +18372,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_arc_type(struct __pyx_obj_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":1562
+  /* "pywrapfst.pyx":1635
  *     Returns a string indicating the arc type.
  *     """
  *     return self._fst.get().ArcType()             # <<<<<<<<<<<<<<
@@ -18025,12 +18381,12 @@ static std::string __pyx_f_9pywrapfst_3Fst_arc_type(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1562, __pyx_L1_error)
+    __PYX_ERR(0, 1635, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1556
+  /* "pywrapfst.pyx":1629
  *     return self.print()
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -18069,9 +18425,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_10arc_type(struct __pyx_obj_9pywrapfst
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("arc_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_3Fst_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1556, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_3Fst_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1629, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -18088,7 +18447,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_10arc_type(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1564
+/* "pywrapfst.pyx":1637
  *     return self._fst.get().ArcType()
  * 
  *   cpdef ArcIterator arcs(self, int64 state):             # <<<<<<<<<<<<<<
@@ -18105,6 +18464,9 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_3Fst_arcs(str
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("arcs", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -18115,11 +18477,11 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_3Fst_arcs(str
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arcs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1564, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arcs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1637, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_13arcs)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1564, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1637, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -18135,10 +18497,10 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_3Fst_arcs(str
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1564, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1637, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_ArcIterator))))) __PYX_ERR(0, 1564, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_ArcIterator))))) __PYX_ERR(0, 1637, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst_ArcIterator *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -18157,7 +18519,7 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_3Fst_arcs(str
     #endif
   }
 
-  /* "pywrapfst.pyx":1576
+  /* "pywrapfst.pyx":1649
  *       An ArcIterator.
  *     """
  *     return ArcIterator(self, state)             # <<<<<<<<<<<<<<
@@ -18165,9 +18527,9 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_3Fst_arcs(str
  *   cpdef Fst copy(self):
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1576, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1649, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1576, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1649, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
@@ -18175,14 +18537,14 @@ static struct __pyx_obj_9pywrapfst_ArcIterator *__pyx_f_9pywrapfst_3Fst_arcs(str
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_1);
   __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_ArcIterator), __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1576, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_ArcIterator), __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1649, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_r = ((struct __pyx_obj_9pywrapfst_ArcIterator *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1564
+  /* "pywrapfst.pyx":1637
  *     return self._fst.get().ArcType()
  * 
  *   cpdef ArcIterator arcs(self, int64 state):             # <<<<<<<<<<<<<<
@@ -18210,11 +18572,14 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_13arcs(PyObject *__pyx_v_self, PyObjec
 static char __pyx_doc_9pywrapfst_3Fst_12arcs[] = "\n    arcs(self, state)\n\n    Returns an iterator over arcs leaving the specified state.\n\n    Args:\n      state: The source state ID.\n\n    Returns:\n      An ArcIterator.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_3Fst_13arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
   int64 __pyx_v_state;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("arcs (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1564, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1637, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -18233,9 +18598,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_12arcs(struct __pyx_obj_9pywrapfst_Fst
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("arcs", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_arcs(__pyx_v_self, __pyx_v_state, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1564, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_arcs(__pyx_v_self, __pyx_v_state, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1637, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -18252,7 +18620,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_12arcs(struct __pyx_obj_9pywrapfst_Fst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1578
+/* "pywrapfst.pyx":1651
  *     return ArcIterator(self, state)
  * 
  *   cpdef Fst copy(self):             # <<<<<<<<<<<<<<
@@ -18268,6 +18636,9 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_3Fst_copy(struct __py
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("copy", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -18278,7 +18649,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_3Fst_copy(struct __py
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1578, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1651, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_15copy)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -18295,10 +18666,10 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_3Fst_copy(struct __py
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1578, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1651, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 1578, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 1651, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -18317,7 +18688,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_3Fst_copy(struct __py
     #endif
   }
 
-  /* "pywrapfst.pyx":1584
+  /* "pywrapfst.pyx":1657
  *     Makes a copy of the FST.
  *     """
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))             # <<<<<<<<<<<<<<
@@ -18327,15 +18698,15 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_3Fst_copy(struct __py
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1584, __pyx_L1_error)
+    __PYX_ERR(0, 1657, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(new fst::script::FstClass((*__pyx_v_self->_fst)))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1584, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(new fst::script::FstClass((*__pyx_v_self->_fst)))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1657, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1578
+  /* "pywrapfst.pyx":1651
  *     return ArcIterator(self, state)
  * 
  *   cpdef Fst copy(self):             # <<<<<<<<<<<<<<
@@ -18375,9 +18746,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_14copy(struct __pyx_obj_9pywrapfst_Fst
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("copy", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1578, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1651, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -18394,57 +18768,57 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_14copy(struct __pyx_obj_9pywrapfst_Fst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1586
+/* "pywrapfst.pyx":1659
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
  *                   source,
- *                   _SymbolTable isymbols=None,
+ *                   SymbolTableView isymbols=None,
  */
 
 static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_3Fst_draw *__pyx_optional_args) {
 
-  /* "pywrapfst.pyx":1588
+  /* "pywrapfst.pyx":1661
  *   cpdef void draw(self,
  *                   source,
- *                   _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
- *                   _SymbolTable osymbols=None,
- *                   _SymbolTable ssymbols=None,
+ *                   SymbolTableView isymbols=None,             # <<<<<<<<<<<<<<
+ *                   SymbolTableView osymbols=None,
+ *                   SymbolTableView ssymbols=None,
  */
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_isymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-  /* "pywrapfst.pyx":1589
+  /* "pywrapfst.pyx":1662
  *                   source,
- *                   _SymbolTable isymbols=None,
- *                   _SymbolTable osymbols=None,             # <<<<<<<<<<<<<<
- *                   _SymbolTable ssymbols=None,
+ *                   SymbolTableView isymbols=None,
+ *                   SymbolTableView osymbols=None,             # <<<<<<<<<<<<<<
+ *                   SymbolTableView ssymbols=None,
  *                   bool acceptor=False,
  */
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-  /* "pywrapfst.pyx":1590
- *                   _SymbolTable isymbols=None,
- *                   _SymbolTable osymbols=None,
- *                   _SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1663
+ *                   SymbolTableView isymbols=None,
+ *                   SymbolTableView osymbols=None,
+ *                   SymbolTableView ssymbols=None,             # <<<<<<<<<<<<<<
  *                   bool acceptor=False,
- *                   title=b"",
+ *                   title="",
  */
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-  /* "pywrapfst.pyx":1591
- *                   _SymbolTable osymbols=None,
- *                   _SymbolTable ssymbols=None,
+  /* "pywrapfst.pyx":1664
+ *                   SymbolTableView osymbols=None,
+ *                   SymbolTableView ssymbols=None,
  *                   bool acceptor=False,             # <<<<<<<<<<<<<<
- *                   title=b"",
+ *                   title="",
  *                   double width=8.5,
  */
   bool __pyx_v_acceptor = ((bool)0);
-  PyObject *__pyx_v_title = ((PyObject *)__pyx_kp_b__8);
+  PyObject *__pyx_v_title = ((PyObject *)__pyx_kp_u__11);
   double __pyx_v_width = ((double)8.5);
   double __pyx_v_height = ((double)11.0);
 
-  /* "pywrapfst.pyx":1595
+  /* "pywrapfst.pyx":1668
  *                   double width=8.5,
  *                   double height=11,
  *                   bool portrait=False,             # <<<<<<<<<<<<<<
@@ -18453,7 +18827,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
   bool __pyx_v_portrait = ((bool)0);
 
-  /* "pywrapfst.pyx":1596
+  /* "pywrapfst.pyx":1669
  *                   double height=11,
  *                   bool portrait=False,
  *                   bool vertical=False,             # <<<<<<<<<<<<<<
@@ -18465,18 +18839,18 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
   double __pyx_v_nodesep = ((double)0.25);
   int32 __pyx_v_fontsize = ((int32)14);
   int32 __pyx_v_precision = ((int32)5);
-  PyObject *__pyx_v_float_format = ((PyObject *)__pyx_n_b_g);
+  PyObject *__pyx_v_float_format = ((PyObject *)__pyx_n_u_g);
 
-  /* "pywrapfst.pyx":1602
+  /* "pywrapfst.pyx":1675
  *                   int32 precision=5,
- *                   float_format=b"g",
+ *                   float_format="g",
  *                   bool show_weight_one=False) except *:             # <<<<<<<<<<<<<<
  *     """
  *     draw(self, source, isymbols=None, osymbols=None, ssymbols=None,
  */
   bool __pyx_v_show_weight_one = ((bool)0);
-  std::string __pyx_v_source_string;
-  std::unique_ptr<std::ostream>  __pyx_v_fstrm;
+  std::string __pyx_v__source;
+  std::unique_ptr<std::ostream>  __pyx_v__fstrm;
   fst::SymbolTable const *__pyx_v__isymbols;
   fst::SymbolTable const *__pyx_v__osymbols;
   fst::SymbolTable const *__pyx_v__ssymbols;
@@ -18502,6 +18876,9 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
   int __pyx_t_19;
   fst::SymbolTable const *__pyx_t_20;
   std::string __pyx_t_21;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("draw", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -18551,12 +18928,12 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
     }
   }
 
-  /* "pywrapfst.pyx":1586
+  /* "pywrapfst.pyx":1659
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
  *                   source,
- *                   _SymbolTable isymbols=None,
+ *                   SymbolTableView isymbols=None,
  */
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -18567,28 +18944,28 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_draw); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1586, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_draw); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1659, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_17draw)) {
-        __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_acceptor); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1586, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_acceptor); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1659, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_4 = PyFloat_FromDouble(__pyx_v_width); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1586, __pyx_L1_error)
+        __pyx_t_4 = PyFloat_FromDouble(__pyx_v_width); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1659, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
-        __pyx_t_5 = PyFloat_FromDouble(__pyx_v_height); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1586, __pyx_L1_error)
+        __pyx_t_5 = PyFloat_FromDouble(__pyx_v_height); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1659, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_5);
-        __pyx_t_6 = __Pyx_PyBool_FromLong(__pyx_v_portrait); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1586, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyBool_FromLong(__pyx_v_portrait); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1659, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_6);
-        __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_vertical); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1586, __pyx_L1_error)
+        __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_vertical); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1659, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_7);
-        __pyx_t_8 = PyFloat_FromDouble(__pyx_v_ranksep); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1586, __pyx_L1_error)
+        __pyx_t_8 = PyFloat_FromDouble(__pyx_v_ranksep); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1659, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
-        __pyx_t_9 = PyFloat_FromDouble(__pyx_v_nodesep); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1586, __pyx_L1_error)
+        __pyx_t_9 = PyFloat_FromDouble(__pyx_v_nodesep); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1659, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_9);
-        __pyx_t_10 = __Pyx_PyInt_From_int32_t(__pyx_v_fontsize); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1586, __pyx_L1_error)
+        __pyx_t_10 = __Pyx_PyInt_From_int32_t(__pyx_v_fontsize); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1659, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_10);
-        __pyx_t_11 = __Pyx_PyInt_From_int32_t(__pyx_v_precision); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1586, __pyx_L1_error)
+        __pyx_t_11 = __Pyx_PyInt_From_int32_t(__pyx_v_precision); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1659, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_11);
-        __pyx_t_12 = __Pyx_PyBool_FromLong(__pyx_v_show_weight_one); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1586, __pyx_L1_error)
+        __pyx_t_12 = __Pyx_PyBool_FromLong(__pyx_v_show_weight_one); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1659, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_12);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_13 = __pyx_t_1; __pyx_t_14 = NULL;
@@ -18606,7 +18983,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_13)) {
           PyObject *__pyx_temp[17] = {__pyx_t_14, __pyx_v_source, ((PyObject *)__pyx_v_isymbols), ((PyObject *)__pyx_v_osymbols), ((PyObject *)__pyx_v_ssymbols), __pyx_t_3, __pyx_v_title, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7, __pyx_t_8, __pyx_t_9, __pyx_t_10, __pyx_t_11, __pyx_v_float_format, __pyx_t_12};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_13, __pyx_temp+1-__pyx_t_15, 16+__pyx_t_15); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1586, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_13, __pyx_temp+1-__pyx_t_15, 16+__pyx_t_15); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1659, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -18624,7 +19001,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_13)) {
           PyObject *__pyx_temp[17] = {__pyx_t_14, __pyx_v_source, ((PyObject *)__pyx_v_isymbols), ((PyObject *)__pyx_v_osymbols), ((PyObject *)__pyx_v_ssymbols), __pyx_t_3, __pyx_v_title, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7, __pyx_t_8, __pyx_t_9, __pyx_t_10, __pyx_t_11, __pyx_v_float_format, __pyx_t_12};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_13, __pyx_temp+1-__pyx_t_15, 16+__pyx_t_15); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1586, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_13, __pyx_temp+1-__pyx_t_15, 16+__pyx_t_15); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1659, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -18640,7 +19017,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
         } else
         #endif
         {
-          __pyx_t_16 = PyTuple_New(16+__pyx_t_15); if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 1586, __pyx_L1_error)
+          __pyx_t_16 = PyTuple_New(16+__pyx_t_15); if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 1659, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_16);
           if (__pyx_t_14) {
             __Pyx_GIVEREF(__pyx_t_14); PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_14); __pyx_t_14 = NULL;
@@ -18693,7 +19070,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
           __pyx_t_10 = 0;
           __pyx_t_11 = 0;
           __pyx_t_12 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_13, __pyx_t_16, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1586, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_13, __pyx_t_16, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1659, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
         }
@@ -18715,40 +19092,40 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
     #endif
   }
 
-  /* "pywrapfst.pyx":1634
+  /* "pywrapfst.pyx":1707
  *       show_weight_one: Should weights equivalent to semiring One be printed?
  *     """
- *     cdef string source_string = tostring(source)             # <<<<<<<<<<<<<<
- *     cdef unique_ptr[ostream] fstrm
- *     fstrm.reset(new ofstream(source_string))
+ *     cdef string _source = path_tostring(source)             # <<<<<<<<<<<<<<
+ *     cdef unique_ptr[ostream] _fstrm
+ *     _fstrm.reset(new ofstream(_source))
  */
-  __pyx_t_17 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1634, __pyx_L1_error)
-  __pyx_v_source_string = __pyx_t_17;
+  __pyx_t_17 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1707, __pyx_L1_error)
+  __pyx_v__source = __pyx_t_17;
 
-  /* "pywrapfst.pyx":1636
- *     cdef string source_string = tostring(source)
- *     cdef unique_ptr[ostream] fstrm
- *     fstrm.reset(new ofstream(source_string))             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1709
+ *     cdef string _source = path_tostring(source)
+ *     cdef unique_ptr[ostream] _fstrm
+ *     _fstrm.reset(new ofstream(_source))             # <<<<<<<<<<<<<<
  *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
  *     if isymbols is not None:
  */
-  __pyx_v_fstrm.reset(new std::ofstream(__pyx_v_source_string));
+  __pyx_v__fstrm.reset(new std::ofstream(__pyx_v__source));
 
-  /* "pywrapfst.pyx":1637
- *     cdef unique_ptr[ostream] fstrm
- *     fstrm.reset(new ofstream(source_string))
+  /* "pywrapfst.pyx":1710
+ *     cdef unique_ptr[ostream] _fstrm
+ *     _fstrm.reset(new ofstream(_source))
  *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()             # <<<<<<<<<<<<<<
  *     if isymbols is not None:
  *        _isymbols = isymbols._raw_ptr_or_raise()
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1637, __pyx_L1_error)
+    __PYX_ERR(0, 1710, __pyx_L1_error)
   }
   __pyx_v__isymbols = __pyx_v_self->_fst.get()->InputSymbols();
 
-  /* "pywrapfst.pyx":1638
- *     fstrm.reset(new ofstream(source_string))
+  /* "pywrapfst.pyx":1711
+ *     _fstrm.reset(new ofstream(_source))
  *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
  *        _isymbols = isymbols._raw_ptr_or_raise()
@@ -18758,7 +19135,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
   __pyx_t_19 = (__pyx_t_18 != 0);
   if (__pyx_t_19) {
 
-    /* "pywrapfst.pyx":1639
+    /* "pywrapfst.pyx":1712
  *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
  *     if isymbols is not None:
  *        _isymbols = isymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -18767,13 +19144,13 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
     if (unlikely(((PyObject *)__pyx_v_isymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 1639, __pyx_L1_error)
+      __PYX_ERR(0, 1712, __pyx_L1_error)
     }
-    __pyx_t_20 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_isymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_isymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1639, __pyx_L1_error)
+    __pyx_t_20 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_isymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_isymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1712, __pyx_L1_error)
     __pyx_v__isymbols = __pyx_t_20;
 
-    /* "pywrapfst.pyx":1638
- *     fstrm.reset(new ofstream(source_string))
+    /* "pywrapfst.pyx":1711
+ *     _fstrm.reset(new ofstream(_source))
  *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
  *        _isymbols = isymbols._raw_ptr_or_raise()
@@ -18781,7 +19158,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
   }
 
-  /* "pywrapfst.pyx":1640
+  /* "pywrapfst.pyx":1713
  *     if isymbols is not None:
  *        _isymbols = isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()             # <<<<<<<<<<<<<<
@@ -18790,11 +19167,11 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1640, __pyx_L1_error)
+    __PYX_ERR(0, 1713, __pyx_L1_error)
   }
   __pyx_v__osymbols = __pyx_v_self->_fst.get()->OutputSymbols();
 
-  /* "pywrapfst.pyx":1641
+  /* "pywrapfst.pyx":1714
  *        _isymbols = isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
@@ -18805,7 +19182,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
   __pyx_t_18 = (__pyx_t_19 != 0);
   if (__pyx_t_18) {
 
-    /* "pywrapfst.pyx":1642
+    /* "pywrapfst.pyx":1715
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  *     if osymbols is not None:
  *        _osymbols = osymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -18814,12 +19191,12 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
     if (unlikely(((PyObject *)__pyx_v_osymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 1642, __pyx_L1_error)
+      __PYX_ERR(0, 1715, __pyx_L1_error)
     }
-    __pyx_t_20 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_osymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_osymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1642, __pyx_L1_error)
+    __pyx_t_20 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_osymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_osymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1715, __pyx_L1_error)
     __pyx_v__osymbols = __pyx_t_20;
 
-    /* "pywrapfst.pyx":1641
+    /* "pywrapfst.pyx":1714
  *        _isymbols = isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
@@ -18828,7 +19205,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
   }
 
-  /* "pywrapfst.pyx":1643
+  /* "pywrapfst.pyx":1716
  *     if osymbols is not None:
  *        _osymbols = osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_ssymbols = NULL             # <<<<<<<<<<<<<<
@@ -18837,7 +19214,7 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
   __pyx_v__ssymbols = NULL;
 
-  /* "pywrapfst.pyx":1644
+  /* "pywrapfst.pyx":1717
  *        _osymbols = osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
@@ -18848,21 +19225,21 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
   __pyx_t_19 = (__pyx_t_18 != 0);
   if (__pyx_t_19) {
 
-    /* "pywrapfst.pyx":1645
+    /* "pywrapfst.pyx":1718
  *     cdef const fst.SymbolTable *_ssymbols = NULL
  *     if ssymbols is not None:
  *       _ssymbols = ssymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
  *     fst.Draw(deref(self._fst),
- *         _isymbols,
+ *              _isymbols,
  */
     if (unlikely(((PyObject *)__pyx_v_ssymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 1645, __pyx_L1_error)
+      __PYX_ERR(0, 1718, __pyx_L1_error)
     }
-    __pyx_t_20 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_ssymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_ssymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1645, __pyx_L1_error)
+    __pyx_t_20 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_ssymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_ssymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1718, __pyx_L1_error)
     __pyx_v__ssymbols = __pyx_t_20;
 
-    /* "pywrapfst.pyx":1644
+    /* "pywrapfst.pyx":1717
  *        _osymbols = osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
@@ -18871,51 +19248,51 @@ static void __pyx_f_9pywrapfst_3Fst_draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_
  */
   }
 
-  /* "pywrapfst.pyx":1646
+  /* "pywrapfst.pyx":1719
  *     if ssymbols is not None:
  *       _ssymbols = ssymbols._raw_ptr_or_raise()
  *     fst.Draw(deref(self._fst),             # <<<<<<<<<<<<<<
- *         _isymbols,
- *         _osymbols,
+ *              _isymbols,
+ *              _osymbols,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1646, __pyx_L1_error)
+    __PYX_ERR(0, 1719, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1651
- *         _ssymbols,
- *         acceptor,
- *         tostring(title),             # <<<<<<<<<<<<<<
- *         width,
- *         height,
+  /* "pywrapfst.pyx":1724
+ *              _ssymbols,
+ *              acceptor,
+ *              tostring(title),             # <<<<<<<<<<<<<<
+ *              width,
+ *              height,
  */
-  __pyx_t_17 = __pyx_f_9pywrapfst_tostring(__pyx_v_title); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1651, __pyx_L1_error)
+  __pyx_t_17 = __pyx_f_9pywrapfst_tostring(__pyx_v_title); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1724, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1660
- *         fontsize,
- *         precision,
- *         tostring(float_format),             # <<<<<<<<<<<<<<
- *         show_weight_one,
- *         deref(fstrm),
+  /* "pywrapfst.pyx":1733
+ *              fontsize,
+ *              precision,
+ *              tostring(float_format),             # <<<<<<<<<<<<<<
+ *              show_weight_one,
+ *              deref(_fstrm),
  */
-  __pyx_t_21 = __pyx_f_9pywrapfst_tostring(__pyx_v_float_format); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1660, __pyx_L1_error)
+  __pyx_t_21 = __pyx_f_9pywrapfst_tostring(__pyx_v_float_format); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1733, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1646
+  /* "pywrapfst.pyx":1719
  *     if ssymbols is not None:
  *       _ssymbols = ssymbols._raw_ptr_or_raise()
  *     fst.Draw(deref(self._fst),             # <<<<<<<<<<<<<<
- *         _isymbols,
- *         _osymbols,
+ *              _isymbols,
+ *              _osymbols,
  */
-  fst::script::Draw((*__pyx_v_self->_fst), __pyx_v__isymbols, __pyx_v__osymbols, __pyx_v__ssymbols, __pyx_v_acceptor, __pyx_t_17, __pyx_v_width, __pyx_v_height, __pyx_v_portrait, __pyx_v_vertical, __pyx_v_ranksep, __pyx_v_nodesep, __pyx_v_fontsize, __pyx_v_precision, __pyx_t_21, __pyx_v_show_weight_one, (*__pyx_v_fstrm), __pyx_v_source_string);
+  fst::script::Draw((*__pyx_v_self->_fst), __pyx_v__isymbols, __pyx_v__osymbols, __pyx_v__ssymbols, __pyx_v_acceptor, __pyx_t_17, __pyx_v_width, __pyx_v_height, __pyx_v_portrait, __pyx_v_vertical, __pyx_v_ranksep, __pyx_v_nodesep, __pyx_v_fontsize, __pyx_v_precision, __pyx_t_21, __pyx_v_show_weight_one, (*__pyx_v__fstrm), __pyx_v__source);
 
-  /* "pywrapfst.pyx":1586
+  /* "pywrapfst.pyx":1659
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
  *                   source,
- *                   _SymbolTable isymbols=None,
+ *                   SymbolTableView isymbols=None,
  */
 
   /* function exit code */
@@ -18946,9 +19323,9 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObjec
 static char __pyx_doc_9pywrapfst_3Fst_16draw[] = "\n    draw(self, source, isymbols=None, osymbols=None, ssymbols=None,\n         acceptor=False, title=\"\", width=8.5, height=11, portrait=False,\n         vertical=False, ranksep=0.4, nodesep=0.25, fontsize=14,\n         precision=5, float_format=\"g\", show_weight_one=False):\n\n    Writes out the FST in Graphviz text format.\n\n    This method writes out the FST in the dot graph description language. The\n    graph can be rendered using the `dot` executable provided by Graphviz.\n\n    Args:\n      source: The string location of the output dot/Graphviz file.\n      isymbols: An optional symbol table used to label input symbols.\n      osymbols: An optional symbol table used to label output symbols.\n      ssymbols: An optional symbol table used to label states.\n      acceptor: Should the figure be rendered in acceptor format if possible?\n      title: An optional string indicating the figure title.\n      width: The figure width, in inches.\n      height: The figure height, in inches.\n      portrait: Should the figure be rendered in portrait rather than\n          landscape?\n      vertical: Should the figure be rendered bottom-to-top rather than\n          left-to-right?\n      ranksep: The minimum separation separation between ranks, in inches.\n      nodesep: The minimum separation between nodes, in inches.\n      fontsize: Font size, in points.\n      precision: Numeric precision for floats, in number of chars.\n      float_format: One of: 'e', 'f' or 'g'.\n      show_weight_one: Should weights equivalent to semiring One be printed?\n    ";
 static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_source = 0;
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols = 0;
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols = 0;
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_ssymbols = 0;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_isymbols = 0;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_osymbols = 0;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_ssymbols = 0;
   bool __pyx_v_acceptor;
   PyObject *__pyx_v_title = 0;
   double __pyx_v_width;
@@ -18961,6 +19338,9 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObjec
   int32 __pyx_v_precision;
   PyObject *__pyx_v_float_format = 0;
   bool __pyx_v_show_weight_one;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("draw (wrapper)", 0);
@@ -18968,34 +19348,34 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObjec
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_source,&__pyx_n_s_isymbols,&__pyx_n_s_osymbols,&__pyx_n_s_ssymbols,&__pyx_n_s_acceptor,&__pyx_n_s_title,&__pyx_n_s_width,&__pyx_n_s_height,&__pyx_n_s_portrait,&__pyx_n_s_vertical,&__pyx_n_s_ranksep,&__pyx_n_s_nodesep,&__pyx_n_s_fontsize,&__pyx_n_s_precision,&__pyx_n_s_float_format,&__pyx_n_s_show_weight_one,0};
     PyObject* values[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
 
-    /* "pywrapfst.pyx":1588
+    /* "pywrapfst.pyx":1661
  *   cpdef void draw(self,
  *                   source,
- *                   _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
- *                   _SymbolTable osymbols=None,
- *                   _SymbolTable ssymbols=None,
+ *                   SymbolTableView isymbols=None,             # <<<<<<<<<<<<<<
+ *                   SymbolTableView osymbols=None,
+ *                   SymbolTableView ssymbols=None,
  */
-    values[1] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
+    values[1] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-    /* "pywrapfst.pyx":1589
+    /* "pywrapfst.pyx":1662
  *                   source,
- *                   _SymbolTable isymbols=None,
- *                   _SymbolTable osymbols=None,             # <<<<<<<<<<<<<<
- *                   _SymbolTable ssymbols=None,
+ *                   SymbolTableView isymbols=None,
+ *                   SymbolTableView osymbols=None,             # <<<<<<<<<<<<<<
+ *                   SymbolTableView ssymbols=None,
  *                   bool acceptor=False,
  */
-    values[2] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
+    values[2] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-    /* "pywrapfst.pyx":1590
- *                   _SymbolTable isymbols=None,
- *                   _SymbolTable osymbols=None,
- *                   _SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
+    /* "pywrapfst.pyx":1663
+ *                   SymbolTableView isymbols=None,
+ *                   SymbolTableView osymbols=None,
+ *                   SymbolTableView ssymbols=None,             # <<<<<<<<<<<<<<
  *                   bool acceptor=False,
- *                   title=b"",
+ *                   title="",
  */
-    values[3] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
-    values[5] = ((PyObject *)__pyx_kp_b__8);
-    values[14] = ((PyObject *)__pyx_n_b_g);
+    values[3] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
+    values[5] = ((PyObject *)__pyx_kp_u__11);
+    values[14] = ((PyObject *)__pyx_n_u_g);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -19132,7 +19512,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObjec
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "draw") < 0)) __PYX_ERR(0, 1586, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "draw") < 0)) __PYX_ERR(0, 1659, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -19172,38 +19552,38 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObjec
       }
     }
     __pyx_v_source = values[0];
-    __pyx_v_isymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[1]);
-    __pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[2]);
-    __pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[3]);
+    __pyx_v_isymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)values[1]);
+    __pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)values[2]);
+    __pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)values[3]);
     if (values[4]) {
-      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1591, __pyx_L3_error)
+      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1664, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1591
- *                   _SymbolTable osymbols=None,
- *                   _SymbolTable ssymbols=None,
+      /* "pywrapfst.pyx":1664
+ *                   SymbolTableView osymbols=None,
+ *                   SymbolTableView ssymbols=None,
  *                   bool acceptor=False,             # <<<<<<<<<<<<<<
- *                   title=b"",
+ *                   title="",
  *                   double width=8.5,
  */
       __pyx_v_acceptor = ((bool)0);
     }
     __pyx_v_title = values[5];
     if (values[6]) {
-      __pyx_v_width = __pyx_PyFloat_AsDouble(values[6]); if (unlikely((__pyx_v_width == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1593, __pyx_L3_error)
+      __pyx_v_width = __pyx_PyFloat_AsDouble(values[6]); if (unlikely((__pyx_v_width == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1666, __pyx_L3_error)
     } else {
       __pyx_v_width = ((double)8.5);
     }
     if (values[7]) {
-      __pyx_v_height = __pyx_PyFloat_AsDouble(values[7]); if (unlikely((__pyx_v_height == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1594, __pyx_L3_error)
+      __pyx_v_height = __pyx_PyFloat_AsDouble(values[7]); if (unlikely((__pyx_v_height == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1667, __pyx_L3_error)
     } else {
       __pyx_v_height = ((double)11.0);
     }
     if (values[8]) {
-      __pyx_v_portrait = __Pyx_PyObject_IsTrue(values[8]); if (unlikely((__pyx_v_portrait == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1595, __pyx_L3_error)
+      __pyx_v_portrait = __Pyx_PyObject_IsTrue(values[8]); if (unlikely((__pyx_v_portrait == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1668, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1595
+      /* "pywrapfst.pyx":1668
  *                   double width=8.5,
  *                   double height=11,
  *                   bool portrait=False,             # <<<<<<<<<<<<<<
@@ -19213,10 +19593,10 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObjec
       __pyx_v_portrait = ((bool)0);
     }
     if (values[9]) {
-      __pyx_v_vertical = __Pyx_PyObject_IsTrue(values[9]); if (unlikely((__pyx_v_vertical == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1596, __pyx_L3_error)
+      __pyx_v_vertical = __Pyx_PyObject_IsTrue(values[9]); if (unlikely((__pyx_v_vertical == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1669, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1596
+      /* "pywrapfst.pyx":1669
  *                   double height=11,
  *                   bool portrait=False,
  *                   bool vertical=False,             # <<<<<<<<<<<<<<
@@ -19226,33 +19606,33 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObjec
       __pyx_v_vertical = ((bool)0);
     }
     if (values[10]) {
-      __pyx_v_ranksep = __pyx_PyFloat_AsDouble(values[10]); if (unlikely((__pyx_v_ranksep == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1597, __pyx_L3_error)
+      __pyx_v_ranksep = __pyx_PyFloat_AsDouble(values[10]); if (unlikely((__pyx_v_ranksep == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1670, __pyx_L3_error)
     } else {
       __pyx_v_ranksep = ((double)0.4);
     }
     if (values[11]) {
-      __pyx_v_nodesep = __pyx_PyFloat_AsDouble(values[11]); if (unlikely((__pyx_v_nodesep == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1598, __pyx_L3_error)
+      __pyx_v_nodesep = __pyx_PyFloat_AsDouble(values[11]); if (unlikely((__pyx_v_nodesep == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 1671, __pyx_L3_error)
     } else {
       __pyx_v_nodesep = ((double)0.25);
     }
     if (values[12]) {
-      __pyx_v_fontsize = __Pyx_PyInt_As_int32_t(values[12]); if (unlikely((__pyx_v_fontsize == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1599, __pyx_L3_error)
+      __pyx_v_fontsize = __Pyx_PyInt_As_int32_t(values[12]); if (unlikely((__pyx_v_fontsize == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1672, __pyx_L3_error)
     } else {
       __pyx_v_fontsize = ((int32)14);
     }
     if (values[13]) {
-      __pyx_v_precision = __Pyx_PyInt_As_int32_t(values[13]); if (unlikely((__pyx_v_precision == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1600, __pyx_L3_error)
+      __pyx_v_precision = __Pyx_PyInt_As_int32_t(values[13]); if (unlikely((__pyx_v_precision == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1673, __pyx_L3_error)
     } else {
       __pyx_v_precision = ((int32)5);
     }
     __pyx_v_float_format = values[14];
     if (values[15]) {
-      __pyx_v_show_weight_one = __Pyx_PyObject_IsTrue(values[15]); if (unlikely((__pyx_v_show_weight_one == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1602, __pyx_L3_error)
+      __pyx_v_show_weight_one = __Pyx_PyObject_IsTrue(values[15]); if (unlikely((__pyx_v_show_weight_one == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1675, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1602
+      /* "pywrapfst.pyx":1675
  *                   int32 precision=5,
- *                   float_format=b"g",
+ *                   float_format="g",
  *                   bool show_weight_one=False) except *:             # <<<<<<<<<<<<<<
  *     """
  *     draw(self, source, isymbols=None, osymbols=None, ssymbols=None,
@@ -19262,23 +19642,23 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObjec
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("draw", 0, 1, 16, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1586, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("draw", 0, 1, 16, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1659, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Fst.draw", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "isymbols", 0))) __PYX_ERR(0, 1588, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 1589, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 1590, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "isymbols", 0))) __PYX_ERR(0, 1661, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "osymbols", 0))) __PYX_ERR(0, 1662, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "ssymbols", 0))) __PYX_ERR(0, 1663, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_3Fst_16draw(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), __pyx_v_source, __pyx_v_isymbols, __pyx_v_osymbols, __pyx_v_ssymbols, __pyx_v_acceptor, __pyx_v_title, __pyx_v_width, __pyx_v_height, __pyx_v_portrait, __pyx_v_vertical, __pyx_v_ranksep, __pyx_v_nodesep, __pyx_v_fontsize, __pyx_v_precision, __pyx_v_float_format, __pyx_v_show_weight_one);
 
-  /* "pywrapfst.pyx":1586
+  /* "pywrapfst.pyx":1659
  *     return _init_XFst(new fst.FstClass(deref(self._fst)))
  * 
  *   cpdef void draw(self,             # <<<<<<<<<<<<<<
  *                   source,
- *                   _SymbolTable isymbols=None,
+ *                   SymbolTableView isymbols=None,
  */
 
   /* function exit code */
@@ -19290,11 +19670,14 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_17draw(PyObject *__pyx_v_self, PyObjec
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_3Fst_16draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, PyObject *__pyx_v_source, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_ssymbols, bool __pyx_v_acceptor, PyObject *__pyx_v_title, double __pyx_v_width, double __pyx_v_height, bool __pyx_v_portrait, bool __pyx_v_vertical, double __pyx_v_ranksep, double __pyx_v_nodesep, int32 __pyx_v_fontsize, int32 __pyx_v_precision, PyObject *__pyx_v_float_format, bool __pyx_v_show_weight_one) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_16draw(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, PyObject *__pyx_v_source, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_isymbols, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_osymbols, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_ssymbols, bool __pyx_v_acceptor, PyObject *__pyx_v_title, double __pyx_v_width, double __pyx_v_height, bool __pyx_v_portrait, bool __pyx_v_vertical, double __pyx_v_ranksep, double __pyx_v_nodesep, int32 __pyx_v_fontsize, int32 __pyx_v_precision, PyObject *__pyx_v_float_format, bool __pyx_v_show_weight_one) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_3Fst_draw __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("draw", 0);
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_1.__pyx_n = 15;
@@ -19313,8 +19696,8 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_16draw(struct __pyx_obj_9pywrapfst_Fst
   __pyx_t_1.precision = __pyx_v_precision;
   __pyx_t_1.float_format = __pyx_v_float_format;
   __pyx_t_1.show_weight_one = __pyx_v_show_weight_one;
-  __pyx_vtabptr_9pywrapfst_Fst->draw(__pyx_v_self, __pyx_v_source, 1, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1586, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1586, __pyx_L1_error)
+  __pyx_vtabptr_9pywrapfst_Fst->draw(__pyx_v_self, __pyx_v_source, 1, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1659, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1659, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -19331,8 +19714,8 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_16draw(struct __pyx_obj_9pywrapfst_Fst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1665
- *         source_string)
+/* "pywrapfst.pyx":1738
+ *              _source)
  * 
  *   cpdef Weight final(self, int64 state):             # <<<<<<<<<<<<<<
  *     """
@@ -19341,7 +19724,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_16draw(struct __pyx_obj_9pywrapfst_Fst
 
 static PyObject *__pyx_pw_9pywrapfst_3Fst_19final(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
 static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_3Fst_final(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int64 __pyx_v_state, int __pyx_skip_dispatch) {
-  struct __pyx_obj_9pywrapfst_Weight *__pyx_v_weight = 0;
+  struct __pyx_obj_9pywrapfst_Weight *__pyx_v__weight = 0;
   struct __pyx_obj_9pywrapfst_Weight *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -19350,6 +19733,9 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_3Fst_final(struct
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
   int __pyx_t_6;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("final", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -19360,11 +19746,11 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_3Fst_final(struct
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_final); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1665, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_final); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1738, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_19final)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1665, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1738, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -19380,10 +19766,10 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_3Fst_final(struct
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1665, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1738, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Weight))))) __PYX_ERR(0, 1665, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Weight))))) __PYX_ERR(0, 1738, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -19402,57 +19788,57 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_3Fst_final(struct
     #endif
   }
 
-  /* "pywrapfst.pyx":1680
+  /* "pywrapfst.pyx":1753
  *       FstIndexError: State index out of range.
  *     """
- *     cdef Weight weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
- *     weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
- *     if not weight.member():
+ *     cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
+ *     _weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
+ *     if not _weight.member():
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1680, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1753, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_v_weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
+  __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":1681
+  /* "pywrapfst.pyx":1754
  *     """
- *     cdef Weight weight = Weight.__new__(Weight)
- *     weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))             # <<<<<<<<<<<<<<
- *     if not weight.member():
+ *     cdef Weight _weight = Weight.__new__(Weight)
+ *     _weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))             # <<<<<<<<<<<<<<
+ *     if not _weight.member():
  *       raise FstIndexError("State index out of range")
  */
-  if (unlikely(((PyObject *)__pyx_v_weight) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 1681, __pyx_L1_error)
+    __PYX_ERR(0, 1754, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1681, __pyx_L1_error)
+    __PYX_ERR(0, 1754, __pyx_L1_error)
   }
-  __pyx_v_weight->_weight.reset(new fst::script::WeightClass(__pyx_v_self->_fst.get()->Final(__pyx_v_state)));
+  __pyx_v__weight->_weight.reset(new fst::script::WeightClass(__pyx_v_self->_fst.get()->Final(__pyx_v_state)));
 
-  /* "pywrapfst.pyx":1682
- *     cdef Weight weight = Weight.__new__(Weight)
- *     weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
- *     if not weight.member():             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":1755
+ *     cdef Weight _weight = Weight.__new__(Weight)
+ *     _weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
+ *     if not _weight.member():             # <<<<<<<<<<<<<<
  *       raise FstIndexError("State index out of range")
- *     return weight
+ *     return _weight
  */
-  if (unlikely(((PyObject *)__pyx_v_weight) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "member");
-    __PYX_ERR(0, 1682, __pyx_L1_error)
+    __PYX_ERR(0, 1755, __pyx_L1_error)
   }
-  __pyx_t_6 = ((!(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v_weight->__pyx_vtab)->member(__pyx_v_weight, 0) != 0)) != 0);
+  __pyx_t_6 = ((!(((struct __pyx_vtabstruct_9pywrapfst_Weight *)__pyx_v__weight->__pyx_vtab)->member(__pyx_v__weight, 0) != 0)) != 0);
   if (unlikely(__pyx_t_6)) {
 
-    /* "pywrapfst.pyx":1683
- *     weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
- *     if not weight.member():
+    /* "pywrapfst.pyx":1756
+ *     _weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
+ *     if not _weight.member():
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
- *     return weight
+ *     return _weight
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1683, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1756, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -19466,36 +19852,36 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_3Fst_final(struct
     }
     __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1683, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1756, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 1683, __pyx_L1_error)
+    __PYX_ERR(0, 1756, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1682
- *     cdef Weight weight = Weight.__new__(Weight)
- *     weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
- *     if not weight.member():             # <<<<<<<<<<<<<<
+    /* "pywrapfst.pyx":1755
+ *     cdef Weight _weight = Weight.__new__(Weight)
+ *     _weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
+ *     if not _weight.member():             # <<<<<<<<<<<<<<
  *       raise FstIndexError("State index out of range")
- *     return weight
+ *     return _weight
  */
   }
 
-  /* "pywrapfst.pyx":1684
- *     if not weight.member():
+  /* "pywrapfst.pyx":1757
+ *     if not _weight.member():
  *       raise FstIndexError("State index out of range")
- *     return weight             # <<<<<<<<<<<<<<
+ *     return _weight             # <<<<<<<<<<<<<<
  * 
  *   cpdef string fst_type(self):
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __Pyx_INCREF(((PyObject *)__pyx_v_weight));
-  __pyx_r = __pyx_v_weight;
+  __Pyx_INCREF(((PyObject *)__pyx_v__weight));
+  __pyx_r = __pyx_v__weight;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1665
- *         source_string)
+  /* "pywrapfst.pyx":1738
+ *              _source)
  * 
  *   cpdef Weight final(self, int64 state):             # <<<<<<<<<<<<<<
  *     """
@@ -19512,7 +19898,7 @@ static struct __pyx_obj_9pywrapfst_Weight *__pyx_f_9pywrapfst_3Fst_final(struct
   __Pyx_AddTraceback("pywrapfst.Fst.final", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_weight);
+  __Pyx_XDECREF((PyObject *)__pyx_v__weight);
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
@@ -19523,11 +19909,14 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_19final(PyObject *__pyx_v_self, PyObje
 static char __pyx_doc_9pywrapfst_3Fst_18final[] = "\n    final(self, state)\n\n    Returns the final weight of a state.\n\n    Args:\n      state: The integer index of a state.\n\n    Returns:\n      The final Weight of that state.\n\n    Raises:\n      FstIndexError: State index out of range.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_3Fst_19final(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
   int64 __pyx_v_state;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("final (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1665, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1738, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -19546,9 +19935,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_18final(struct __pyx_obj_9pywrapfst_Fs
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("final", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_final(__pyx_v_self, __pyx_v_state, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1665, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_final(__pyx_v_self, __pyx_v_state, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1738, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -19565,8 +19957,8 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_18final(struct __pyx_obj_9pywrapfst_Fs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1686
- *     return weight
+/* "pywrapfst.pyx":1759
+ *     return _weight
  * 
  *   cpdef string fst_type(self):             # <<<<<<<<<<<<<<
  *     """
@@ -19582,6 +19974,9 @@ static std::string __pyx_f_9pywrapfst_3Fst_fst_type(struct __pyx_obj_9pywrapfst_
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   std::string __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("fst_type", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -19592,7 +19987,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_fst_type(struct __pyx_obj_9pywrapfst_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_fst_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1686, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_fst_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1759, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_21fst_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -19608,10 +20003,10 @@ static std::string __pyx_f_9pywrapfst_3Fst_fst_type(struct __pyx_obj_9pywrapfst_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1686, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1759, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1686, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1759, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -19630,7 +20025,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_fst_type(struct __pyx_obj_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":1692
+  /* "pywrapfst.pyx":1765
  *     Returns a string indicating the FST type.
  *     """
  *     return self._fst.get().FstType()             # <<<<<<<<<<<<<<
@@ -19639,13 +20034,13 @@ static std::string __pyx_f_9pywrapfst_3Fst_fst_type(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1692, __pyx_L1_error)
+    __PYX_ERR(0, 1765, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->FstType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1686
- *     return weight
+  /* "pywrapfst.pyx":1759
+ *     return _weight
  * 
  *   cpdef string fst_type(self):             # <<<<<<<<<<<<<<
  *     """
@@ -19683,9 +20078,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_20fst_type(struct __pyx_obj_9pywrapfst
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("fst_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_3Fst_fst_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1686, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_3Fst_fst_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1759, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -19702,7 +20100,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_20fst_type(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1694
+/* "pywrapfst.pyx":1767
  *     return self._fst.get().FstType()
  * 
  *   cpdef _FstSymbolTableView input_symbols(self):             # <<<<<<<<<<<<<<
@@ -19712,7 +20110,6 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_20fst_type(struct __pyx_obj_9pywrapfst
 
 static PyObject *__pyx_pw_9pywrapfst_3Fst_23input_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
 static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_input_symbols(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch) {
-  fst::SymbolTable const *__pyx_v_syms;
   struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -19720,6 +20117,9 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   int __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("input_symbols", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -19730,7 +20130,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_input_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1694, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_input_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1767, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_23input_symbols)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -19747,10 +20147,10 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1694, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1767, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__FstSymbolTableView))))) __PYX_ERR(0, 1694, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__FstSymbolTableView))))) __PYX_ERR(0, 1767, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -19769,32 +20169,23 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
     #endif
   }
 
-  /* "pywrapfst.pyx":1700
+  /* "pywrapfst.pyx":1773
  *     Returns the FST's input symbol table, or None if none is present.
  *     """
- *     cdef const fst.SymbolTable *syms = self._fst.get().InputSymbols()             # <<<<<<<<<<<<<<
- *     if syms == NULL:
+ *     if self._fst.get().InputSymbols() == NULL:             # <<<<<<<<<<<<<<
  *       return
+ *     return _init_FstSymbolTableView(self._fst, input_side=True)
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1700, __pyx_L1_error)
+    __PYX_ERR(0, 1773, __pyx_L1_error)
   }
-  __pyx_v_syms = __pyx_v_self->_fst.get()->InputSymbols();
-
-  /* "pywrapfst.pyx":1701
- *     """
- *     cdef const fst.SymbolTable *syms = self._fst.get().InputSymbols()
- *     if syms == NULL:             # <<<<<<<<<<<<<<
- *       return
- *     return _init_FstSymbolTableView(self._fst, input_side=True)
- */
-  __pyx_t_5 = ((__pyx_v_syms == NULL) != 0);
+  __pyx_t_5 = ((__pyx_v_self->_fst.get()->InputSymbols() == NULL) != 0);
   if (__pyx_t_5) {
 
-    /* "pywrapfst.pyx":1702
- *     cdef const fst.SymbolTable *syms = self._fst.get().InputSymbols()
- *     if syms == NULL:
+    /* "pywrapfst.pyx":1774
+ *     """
+ *     if self._fst.get().InputSymbols() == NULL:
  *       return             # <<<<<<<<<<<<<<
  *     return _init_FstSymbolTableView(self._fst, input_side=True)
  * 
@@ -19803,17 +20194,17 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
     __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)Py_None); __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":1701
+    /* "pywrapfst.pyx":1773
+ *     Returns the FST's input symbol table, or None if none is present.
  *     """
- *     cdef const fst.SymbolTable *syms = self._fst.get().InputSymbols()
- *     if syms == NULL:             # <<<<<<<<<<<<<<
+ *     if self._fst.get().InputSymbols() == NULL:             # <<<<<<<<<<<<<<
  *       return
  *     return _init_FstSymbolTableView(self._fst, input_side=True)
  */
   }
 
-  /* "pywrapfst.pyx":1703
- *     if syms == NULL:
+  /* "pywrapfst.pyx":1775
+ *     if self._fst.get().InputSymbols() == NULL:
  *       return
  *     return _init_FstSymbolTableView(self._fst, input_side=True)             # <<<<<<<<<<<<<<
  * 
@@ -19822,15 +20213,15 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1703, __pyx_L1_error)
+    __PYX_ERR(0, 1775, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_FstSymbolTableView(__pyx_v_self->_fst, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1703, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_FstSymbolTableView(__pyx_v_self->_fst, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1775, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1694
+  /* "pywrapfst.pyx":1767
  *     return self._fst.get().FstType()
  * 
  *   cpdef _FstSymbolTableView input_symbols(self):             # <<<<<<<<<<<<<<
@@ -19870,9 +20261,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_22input_symbols(struct __pyx_obj_9pywr
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("input_symbols", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_input_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1694, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_input_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1767, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -19889,7 +20283,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_22input_symbols(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1705
+/* "pywrapfst.pyx":1777
  *     return _init_FstSymbolTableView(self._fst, input_side=True)
  * 
  *   cpdef size_t num_arcs(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -19899,7 +20293,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_22input_symbols(struct __pyx_obj_9pywr
 
 static PyObject *__pyx_pw_9pywrapfst_3Fst_25num_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
 static size_t __pyx_f_9pywrapfst_3Fst_num_arcs(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int64 __pyx_v_state, int __pyx_skip_dispatch) {
-  size_t __pyx_v_result;
+  size_t __pyx_v__result;
   size_t __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -19909,6 +20303,9 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_arcs(struct __pyx_obj_9pywrapfst_Fst *
   PyObject *__pyx_t_5 = NULL;
   size_t __pyx_t_6;
   int __pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("num_arcs", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -19919,10 +20316,10 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_arcs(struct __pyx_obj_9pywrapfst_Fst *
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_arcs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1705, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_arcs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1777, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_25num_arcs)) {
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1705, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1777, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -19938,10 +20335,10 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_arcs(struct __pyx_obj_9pywrapfst_Fst *
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1705, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1777, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __pyx_t_6 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_6 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1705, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_6 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1777, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_6;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -19960,37 +20357,37 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_arcs(struct __pyx_obj_9pywrapfst_Fst *
     #endif
   }
 
-  /* "pywrapfst.pyx":1720
+  /* "pywrapfst.pyx":1792
  *       FstIndexError: State index out of range.
  *     """
- *     cdef size_t result = self._fst.get().NumArcs(state)             # <<<<<<<<<<<<<<
- *     if result == SIZE_MAX:
+ *     cdef size_t _result = self._fst.get().NumArcs(state)             # <<<<<<<<<<<<<<
+ *     if _result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1720, __pyx_L1_error)
+    __PYX_ERR(0, 1792, __pyx_L1_error)
   }
-  __pyx_v_result = __pyx_v_self->_fst.get()->NumArcs(__pyx_v_state);
+  __pyx_v__result = __pyx_v_self->_fst.get()->NumArcs(__pyx_v_state);
 
-  /* "pywrapfst.pyx":1721
+  /* "pywrapfst.pyx":1793
  *     """
- *     cdef size_t result = self._fst.get().NumArcs(state)
- *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
+ *     cdef size_t _result = self._fst.get().NumArcs(state)
+ *     if _result == SIZE_MAX:             # <<<<<<<<<<<<<<
  *       raise FstIndexError("State index out of range")
- *     return result
+ *     return _result
  */
-  __pyx_t_7 = ((__pyx_v_result == SIZE_MAX) != 0);
+  __pyx_t_7 = ((__pyx_v__result == SIZE_MAX) != 0);
   if (unlikely(__pyx_t_7)) {
 
-    /* "pywrapfst.pyx":1722
- *     cdef size_t result = self._fst.get().NumArcs(state)
- *     if result == SIZE_MAX:
+    /* "pywrapfst.pyx":1794
+ *     cdef size_t _result = self._fst.get().NumArcs(state)
+ *     if _result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
- *     return result
+ *     return _result
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1722, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1794, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -20004,33 +20401,33 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_arcs(struct __pyx_obj_9pywrapfst_Fst *
     }
     __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1722, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1794, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 1722, __pyx_L1_error)
+    __PYX_ERR(0, 1794, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1721
+    /* "pywrapfst.pyx":1793
  *     """
- *     cdef size_t result = self._fst.get().NumArcs(state)
- *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
+ *     cdef size_t _result = self._fst.get().NumArcs(state)
+ *     if _result == SIZE_MAX:             # <<<<<<<<<<<<<<
  *       raise FstIndexError("State index out of range")
- *     return result
+ *     return _result
  */
   }
 
-  /* "pywrapfst.pyx":1723
- *     if result == SIZE_MAX:
+  /* "pywrapfst.pyx":1795
+ *     if _result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")
- *     return result             # <<<<<<<<<<<<<<
+ *     return _result             # <<<<<<<<<<<<<<
  * 
  *   cpdef size_t num_input_epsilons(self, int64 state) except *:
  */
-  __pyx_r = __pyx_v_result;
+  __pyx_r = __pyx_v__result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1705
+  /* "pywrapfst.pyx":1777
  *     return _init_FstSymbolTableView(self._fst, input_side=True)
  * 
  *   cpdef size_t num_arcs(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -20057,11 +20454,14 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_25num_arcs(PyObject *__pyx_v_self, PyO
 static char __pyx_doc_9pywrapfst_3Fst_24num_arcs[] = "\n    num_arcs(self, state)\n\n    Returns the number of arcs leaving a state.\n\n    Args:\n      state: The integer index of a state.\n\n    Returns:\n      The number of arcs leaving that state.\n\n    Raises:\n      FstIndexError: State index out of range.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_3Fst_25num_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
   int64 __pyx_v_state;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("num_arcs (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1705, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1777, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -20081,10 +20481,13 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_24num_arcs(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyDeclarations
   size_t __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("num_arcs", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_3Fst_num_arcs(__pyx_v_self, __pyx_v_state, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1705, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1705, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_3Fst_num_arcs(__pyx_v_self, __pyx_v_state, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1777, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1777, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -20101,8 +20504,8 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_24num_arcs(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1725
- *     return result
+/* "pywrapfst.pyx":1797
+ *     return _result
  * 
  *   cpdef size_t num_input_epsilons(self, int64 state) except *:             # <<<<<<<<<<<<<<
  *     """
@@ -20111,7 +20514,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_24num_arcs(struct __pyx_obj_9pywrapfst
 
 static PyObject *__pyx_pw_9pywrapfst_3Fst_27num_input_epsilons(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
 static size_t __pyx_f_9pywrapfst_3Fst_num_input_epsilons(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int64 __pyx_v_state, int __pyx_skip_dispatch) {
-  size_t __pyx_v_result;
+  size_t __pyx_v__result;
   size_t __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -20121,6 +20524,9 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_input_epsilons(struct __pyx_obj_9pywra
   PyObject *__pyx_t_5 = NULL;
   size_t __pyx_t_6;
   int __pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("num_input_epsilons", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -20131,10 +20537,10 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_input_epsilons(struct __pyx_obj_9pywra
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_input_epsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1725, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_input_epsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1797, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_27num_input_epsilons)) {
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1725, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1797, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -20150,10 +20556,10 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_input_epsilons(struct __pyx_obj_9pywra
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1725, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1797, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __pyx_t_6 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_6 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1725, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_6 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1797, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_6;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -20172,37 +20578,37 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_input_epsilons(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":1740
+  /* "pywrapfst.pyx":1812
  *       FstIndexError: State index out of range.
  *     """
- *     cdef size_t result = self._fst.get().NumInputEpsilons(state)             # <<<<<<<<<<<<<<
- *     if result == SIZE_MAX:
+ *     cdef size_t _result = self._fst.get().NumInputEpsilons(state)             # <<<<<<<<<<<<<<
+ *     if _result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1740, __pyx_L1_error)
+    __PYX_ERR(0, 1812, __pyx_L1_error)
   }
-  __pyx_v_result = __pyx_v_self->_fst.get()->NumInputEpsilons(__pyx_v_state);
+  __pyx_v__result = __pyx_v_self->_fst.get()->NumInputEpsilons(__pyx_v_state);
 
-  /* "pywrapfst.pyx":1741
+  /* "pywrapfst.pyx":1813
  *     """
- *     cdef size_t result = self._fst.get().NumInputEpsilons(state)
- *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
+ *     cdef size_t _result = self._fst.get().NumInputEpsilons(state)
+ *     if _result == SIZE_MAX:             # <<<<<<<<<<<<<<
  *       raise FstIndexError("State index out of range")
- *     return result
+ *     return _result
  */
-  __pyx_t_7 = ((__pyx_v_result == SIZE_MAX) != 0);
+  __pyx_t_7 = ((__pyx_v__result == SIZE_MAX) != 0);
   if (unlikely(__pyx_t_7)) {
 
-    /* "pywrapfst.pyx":1742
- *     cdef size_t result = self._fst.get().NumInputEpsilons(state)
- *     if result == SIZE_MAX:
+    /* "pywrapfst.pyx":1814
+ *     cdef size_t _result = self._fst.get().NumInputEpsilons(state)
+ *     if _result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
- *     return result
+ *     return _result
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1742, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1814, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -20216,34 +20622,34 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_input_epsilons(struct __pyx_obj_9pywra
     }
     __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1742, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1814, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 1742, __pyx_L1_error)
+    __PYX_ERR(0, 1814, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1741
+    /* "pywrapfst.pyx":1813
  *     """
- *     cdef size_t result = self._fst.get().NumInputEpsilons(state)
- *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
+ *     cdef size_t _result = self._fst.get().NumInputEpsilons(state)
+ *     if _result == SIZE_MAX:             # <<<<<<<<<<<<<<
  *       raise FstIndexError("State index out of range")
- *     return result
+ *     return _result
  */
   }
 
-  /* "pywrapfst.pyx":1743
- *     if result == SIZE_MAX:
+  /* "pywrapfst.pyx":1815
+ *     if _result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")
- *     return result             # <<<<<<<<<<<<<<
+ *     return _result             # <<<<<<<<<<<<<<
  * 
  *   cpdef size_t num_output_epsilons(self, int64 state) except *:
  */
-  __pyx_r = __pyx_v_result;
+  __pyx_r = __pyx_v__result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1725
- *     return result
+  /* "pywrapfst.pyx":1797
+ *     return _result
  * 
  *   cpdef size_t num_input_epsilons(self, int64 state) except *:             # <<<<<<<<<<<<<<
  *     """
@@ -20269,11 +20675,14 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_27num_input_epsilons(PyObject *__pyx_v
 static char __pyx_doc_9pywrapfst_3Fst_26num_input_epsilons[] = "\n    num_input_epsilons(self, state)\n\n    Returns the number of arcs with epsilon input labels leaving a state.\n\n    Args:\n      state: The integer index of a state.\n\n    Returns:\n      The number of epsilon-input-labeled arcs leaving that state.\n\n    Raises:\n      FstIndexError: State index out of range.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_3Fst_27num_input_epsilons(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
   int64 __pyx_v_state;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("num_input_epsilons (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1725, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1797, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -20293,10 +20702,13 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_26num_input_epsilons(struct __pyx_obj_
   __Pyx_RefNannyDeclarations
   size_t __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("num_input_epsilons", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_3Fst_num_input_epsilons(__pyx_v_self, __pyx_v_state, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1725, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1725, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_3Fst_num_input_epsilons(__pyx_v_self, __pyx_v_state, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1797, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1797, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -20313,8 +20725,8 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_26num_input_epsilons(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1745
- *     return result
+/* "pywrapfst.pyx":1817
+ *     return _result
  * 
  *   cpdef size_t num_output_epsilons(self, int64 state) except *:             # <<<<<<<<<<<<<<
  *     """
@@ -20323,7 +20735,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_26num_input_epsilons(struct __pyx_obj_
 
 static PyObject *__pyx_pw_9pywrapfst_3Fst_29num_output_epsilons(PyObject *__pyx_v_self, PyObject *__pyx_arg_state); /*proto*/
 static size_t __pyx_f_9pywrapfst_3Fst_num_output_epsilons(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int64 __pyx_v_state, int __pyx_skip_dispatch) {
-  size_t __pyx_v_result;
+  size_t __pyx_v__result;
   size_t __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -20333,6 +20745,9 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_output_epsilons(struct __pyx_obj_9pywr
   PyObject *__pyx_t_5 = NULL;
   size_t __pyx_t_6;
   int __pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("num_output_epsilons", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -20343,10 +20758,10 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_output_epsilons(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_output_epsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1745, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_output_epsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1817, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_29num_output_epsilons)) {
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1745, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1817, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -20362,10 +20777,10 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_output_epsilons(struct __pyx_obj_9pywr
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1745, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1817, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __pyx_t_6 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_6 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1745, __pyx_L1_error)
+        __pyx_t_6 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_6 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1817, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_6;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -20384,37 +20799,37 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_output_epsilons(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":1760
+  /* "pywrapfst.pyx":1832
  *       FstIndexError: State index out of range.
  *     """
- *     cdef size_t result = self._fst.get().NumOutputEpsilons(state)             # <<<<<<<<<<<<<<
- *     if result == SIZE_MAX:
+ *     cdef size_t _result = self._fst.get().NumOutputEpsilons(state)             # <<<<<<<<<<<<<<
+ *     if _result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1760, __pyx_L1_error)
+    __PYX_ERR(0, 1832, __pyx_L1_error)
   }
-  __pyx_v_result = __pyx_v_self->_fst.get()->NumOutputEpsilons(__pyx_v_state);
+  __pyx_v__result = __pyx_v_self->_fst.get()->NumOutputEpsilons(__pyx_v_state);
 
-  /* "pywrapfst.pyx":1761
+  /* "pywrapfst.pyx":1833
  *     """
- *     cdef size_t result = self._fst.get().NumOutputEpsilons(state)
- *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
+ *     cdef size_t _result = self._fst.get().NumOutputEpsilons(state)
+ *     if _result == SIZE_MAX:             # <<<<<<<<<<<<<<
  *       raise FstIndexError("State index out of range")
- *     return result
+ *     return _result
  */
-  __pyx_t_7 = ((__pyx_v_result == SIZE_MAX) != 0);
+  __pyx_t_7 = ((__pyx_v__result == SIZE_MAX) != 0);
   if (unlikely(__pyx_t_7)) {
 
-    /* "pywrapfst.pyx":1762
- *     cdef size_t result = self._fst.get().NumOutputEpsilons(state)
- *     if result == SIZE_MAX:
+    /* "pywrapfst.pyx":1834
+ *     cdef size_t _result = self._fst.get().NumOutputEpsilons(state)
+ *     if _result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
- *     return result
+ *     return _result
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1762, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1834, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -20428,34 +20843,34 @@ static size_t __pyx_f_9pywrapfst_3Fst_num_output_epsilons(struct __pyx_obj_9pywr
     }
     __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1762, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1834, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 1762, __pyx_L1_error)
+    __PYX_ERR(0, 1834, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1761
+    /* "pywrapfst.pyx":1833
  *     """
- *     cdef size_t result = self._fst.get().NumOutputEpsilons(state)
- *     if result == SIZE_MAX:             # <<<<<<<<<<<<<<
+ *     cdef size_t _result = self._fst.get().NumOutputEpsilons(state)
+ *     if _result == SIZE_MAX:             # <<<<<<<<<<<<<<
  *       raise FstIndexError("State index out of range")
- *     return result
+ *     return _result
  */
   }
 
-  /* "pywrapfst.pyx":1763
- *     if result == SIZE_MAX:
+  /* "pywrapfst.pyx":1835
+ *     if _result == SIZE_MAX:
  *       raise FstIndexError("State index out of range")
- *     return result             # <<<<<<<<<<<<<<
+ *     return _result             # <<<<<<<<<<<<<<
  * 
  *   cpdef _FstSymbolTableView output_symbols(self):
  */
-  __pyx_r = __pyx_v_result;
+  __pyx_r = __pyx_v__result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1745
- *     return result
+  /* "pywrapfst.pyx":1817
+ *     return _result
  * 
  *   cpdef size_t num_output_epsilons(self, int64 state) except *:             # <<<<<<<<<<<<<<
  *     """
@@ -20481,11 +20896,14 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_29num_output_epsilons(PyObject *__pyx_
 static char __pyx_doc_9pywrapfst_3Fst_28num_output_epsilons[] = "\n    num_output_epsilons(self, state)\n\n    Returns the number of arcs with epsilon output labels leaving a state.\n\n    Args:\n      state: The integer index of a state.\n\n    Returns:\n      The number of epsilon-output-labeled arcs leaving that state.\n\n    Raises:\n      FstIndexError: State index out of range.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_3Fst_29num_output_epsilons(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
   int64 __pyx_v_state;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("num_output_epsilons (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1745, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1817, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -20505,10 +20923,13 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_28num_output_epsilons(struct __pyx_obj
   __Pyx_RefNannyDeclarations
   size_t __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("num_output_epsilons", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_3Fst_num_output_epsilons(__pyx_v_self, __pyx_v_state, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1745, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1745, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_3Fst_num_output_epsilons(__pyx_v_self, __pyx_v_state, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1817, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1817, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
@@ -20525,8 +20946,8 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_28num_output_epsilons(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1765
- *     return result
+/* "pywrapfst.pyx":1837
+ *     return _result
  * 
  *   cpdef _FstSymbolTableView output_symbols(self):             # <<<<<<<<<<<<<<
  *     """
@@ -20535,7 +20956,6 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_28num_output_epsilons(struct __pyx_obj
 
 static PyObject *__pyx_pw_9pywrapfst_3Fst_31output_symbols(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
 static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_output_symbols(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch) {
-  fst::SymbolTable const *__pyx_v_syms;
   struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -20543,6 +20963,9 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   int __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("output_symbols", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -20553,7 +20976,7 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_output_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1765, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_output_symbols); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1837, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_31output_symbols)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -20570,10 +20993,10 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1765, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1837, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__FstSymbolTableView))))) __PYX_ERR(0, 1765, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst__FstSymbolTableView))))) __PYX_ERR(0, 1837, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -20592,32 +21015,23 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
     #endif
   }
 
-  /* "pywrapfst.pyx":1771
+  /* "pywrapfst.pyx":1843
  *     Returns the FST's output symbol table, or None if none is present.
  *     """
- *     cdef const fst.SymbolTable *syms = self._fst.get().OutputSymbols()             # <<<<<<<<<<<<<<
- *     if syms == NULL:
+ *     if self._fst.get().OutputSymbols() == NULL:             # <<<<<<<<<<<<<<
  *       return
+ *     return _init_FstSymbolTableView(self._fst, input_side=False)
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1771, __pyx_L1_error)
+    __PYX_ERR(0, 1843, __pyx_L1_error)
   }
-  __pyx_v_syms = __pyx_v_self->_fst.get()->OutputSymbols();
-
-  /* "pywrapfst.pyx":1772
- *     """
- *     cdef const fst.SymbolTable *syms = self._fst.get().OutputSymbols()
- *     if syms == NULL:             # <<<<<<<<<<<<<<
- *       return
- *     return _init_FstSymbolTableView(self._fst, input_side=False)
- */
-  __pyx_t_5 = ((__pyx_v_syms == NULL) != 0);
+  __pyx_t_5 = ((__pyx_v_self->_fst.get()->OutputSymbols() == NULL) != 0);
   if (__pyx_t_5) {
 
-    /* "pywrapfst.pyx":1773
- *     cdef const fst.SymbolTable *syms = self._fst.get().OutputSymbols()
- *     if syms == NULL:
+    /* "pywrapfst.pyx":1844
+ *     """
+ *     if self._fst.get().OutputSymbols() == NULL:
  *       return             # <<<<<<<<<<<<<<
  *     return _init_FstSymbolTableView(self._fst, input_side=False)
  * 
@@ -20626,35 +21040,35 @@ static struct __pyx_obj_9pywrapfst__FstSymbolTableView *__pyx_f_9pywrapfst_3Fst_
     __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)Py_None); __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":1772
+    /* "pywrapfst.pyx":1843
+ *     Returns the FST's output symbol table, or None if none is present.
  *     """
- *     cdef const fst.SymbolTable *syms = self._fst.get().OutputSymbols()
- *     if syms == NULL:             # <<<<<<<<<<<<<<
+ *     if self._fst.get().OutputSymbols() == NULL:             # <<<<<<<<<<<<<<
  *       return
  *     return _init_FstSymbolTableView(self._fst, input_side=False)
  */
   }
 
-  /* "pywrapfst.pyx":1774
- *     if syms == NULL:
+  /* "pywrapfst.pyx":1845
+ *     if self._fst.get().OutputSymbols() == NULL:
  *       return
  *     return _init_FstSymbolTableView(self._fst, input_side=False)             # <<<<<<<<<<<<<<
  * 
- *   cpdef string print(self, _SymbolTable isymbols=None,
+ *   cpdef string print(self, SymbolTableView isymbols=None,
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1774, __pyx_L1_error)
+    __PYX_ERR(0, 1845, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_FstSymbolTableView(__pyx_v_self->_fst, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1774, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_FstSymbolTableView(__pyx_v_self->_fst, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1845, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1765
- *     return result
+  /* "pywrapfst.pyx":1837
+ *     return _result
  * 
  *   cpdef _FstSymbolTableView output_symbols(self):             # <<<<<<<<<<<<<<
  *     """
@@ -20693,9 +21107,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_30output_symbols(struct __pyx_obj_9pyw
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("output_symbols", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_output_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1765, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_output_symbols(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1837, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -20712,42 +21129,42 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_30output_symbols(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1776
+/* "pywrapfst.pyx":1847
  *     return _init_FstSymbolTableView(self._fst, input_side=False)
  * 
- *   cpdef string print(self, _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
- *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
+ *   cpdef string print(self, SymbolTableView isymbols=None,             # <<<<<<<<<<<<<<
+ *       SymbolTableView osymbols=None, SymbolTableView ssymbols=None,
  *       bool acceptor=False, bool show_weight_one=False,
  */
 
 static PyObject *__pyx_pw_9pywrapfst_3Fst_33print(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_3Fst_print *__pyx_optional_args) {
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_isymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-  /* "pywrapfst.pyx":1777
+  /* "pywrapfst.pyx":1848
  * 
- *   cpdef string print(self, _SymbolTable isymbols=None,
- *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
+ *   cpdef string print(self, SymbolTableView isymbols=None,
+ *       SymbolTableView osymbols=None, SymbolTableView ssymbols=None,             # <<<<<<<<<<<<<<
  *       bool acceptor=False, bool show_weight_one=False,
- *       missing_sym=b"") except *:
+ *       missing_sym="") except *:
  */
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-  /* "pywrapfst.pyx":1778
- *   cpdef string print(self, _SymbolTable isymbols=None,
- *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
+  /* "pywrapfst.pyx":1849
+ *   cpdef string print(self, SymbolTableView isymbols=None,
+ *       SymbolTableView osymbols=None, SymbolTableView ssymbols=None,
  *       bool acceptor=False, bool show_weight_one=False,             # <<<<<<<<<<<<<<
- *       missing_sym=b"") except *:
+ *       missing_sym="") except *:
  *     """
  */
   bool __pyx_v_acceptor = ((bool)0);
   bool __pyx_v_show_weight_one = ((bool)0);
-  PyObject *__pyx_v_missing_sym = ((PyObject *)__pyx_kp_b__8);
+  PyObject *__pyx_v_missing_sym = ((PyObject *)__pyx_kp_u__11);
   fst::SymbolTable const *__pyx_v__isymbols;
   fst::SymbolTable const *__pyx_v__osymbols;
   fst::SymbolTable const *__pyx_v__ssymbols;
-  std::stringstream __pyx_v_sstrm;
+  std::stringstream __pyx_v__sstrm;
   std::string __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -20762,6 +21179,9 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
   int __pyx_t_10;
   int __pyx_t_11;
   fst::SymbolTable const *__pyx_t_12;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("print", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -20784,11 +21204,11 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
     }
   }
 
-  /* "pywrapfst.pyx":1776
+  /* "pywrapfst.pyx":1847
  *     return _init_FstSymbolTableView(self._fst, input_side=False)
  * 
- *   cpdef string print(self, _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
- *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
+ *   cpdef string print(self, SymbolTableView isymbols=None,             # <<<<<<<<<<<<<<
+ *       SymbolTableView osymbols=None, SymbolTableView ssymbols=None,
  *       bool acceptor=False, bool show_weight_one=False,
  */
   /* Check if called by wrapper */
@@ -20800,12 +21220,12 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_print); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1776, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_print); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1847, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_33print)) {
-        __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_acceptor); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1776, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_acceptor); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1847, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_show_weight_one); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1776, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_show_weight_one); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1847, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
@@ -20823,7 +21243,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_5)) {
           PyObject *__pyx_temp[7] = {__pyx_t_6, ((PyObject *)__pyx_v_isymbols), ((PyObject *)__pyx_v_osymbols), ((PyObject *)__pyx_v_ssymbols), __pyx_t_3, __pyx_t_4, __pyx_v_missing_sym};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 6+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1776, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 6+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1847, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -20833,7 +21253,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
           PyObject *__pyx_temp[7] = {__pyx_t_6, ((PyObject *)__pyx_v_isymbols), ((PyObject *)__pyx_v_osymbols), ((PyObject *)__pyx_v_ssymbols), __pyx_t_3, __pyx_t_4, __pyx_v_missing_sym};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 6+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1776, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 6+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1847, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -20841,7 +21261,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
         } else
         #endif
         {
-          __pyx_t_8 = PyTuple_New(6+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1776, __pyx_L1_error)
+          __pyx_t_8 = PyTuple_New(6+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1847, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_8);
           if (__pyx_t_6) {
             __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
@@ -20864,12 +21284,12 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
           PyTuple_SET_ITEM(__pyx_t_8, 5+__pyx_t_7, __pyx_v_missing_sym);
           __pyx_t_3 = 0;
           __pyx_t_4 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1776, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1847, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         }
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-        __pyx_t_9 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1776, __pyx_L1_error)
+        __pyx_t_9 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1847, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_9;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -20888,7 +21308,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
     #endif
   }
 
-  /* "pywrapfst.pyx":1802
+  /* "pywrapfst.pyx":1873
  *     """
  *     # Prints FST to stringstream, then returns resulting string.
  *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()             # <<<<<<<<<<<<<<
@@ -20897,11 +21317,11 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1802, __pyx_L1_error)
+    __PYX_ERR(0, 1873, __pyx_L1_error)
   }
   __pyx_v__isymbols = __pyx_v_self->_fst.get()->InputSymbols();
 
-  /* "pywrapfst.pyx":1803
+  /* "pywrapfst.pyx":1874
  *     # Prints FST to stringstream, then returns resulting string.
  *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
@@ -20912,7 +21332,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
   __pyx_t_11 = (__pyx_t_10 != 0);
   if (__pyx_t_11) {
 
-    /* "pywrapfst.pyx":1804
+    /* "pywrapfst.pyx":1875
  *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
  *     if isymbols is not None:
  *        _isymbols = isymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -20921,12 +21341,12 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
  */
     if (unlikely(((PyObject *)__pyx_v_isymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 1804, __pyx_L1_error)
+      __PYX_ERR(0, 1875, __pyx_L1_error)
     }
-    __pyx_t_12 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_isymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_isymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1804, __pyx_L1_error)
+    __pyx_t_12 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_isymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_isymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1875, __pyx_L1_error)
     __pyx_v__isymbols = __pyx_t_12;
 
-    /* "pywrapfst.pyx":1803
+    /* "pywrapfst.pyx":1874
  *     # Prints FST to stringstream, then returns resulting string.
  *     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
@@ -20935,7 +21355,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
  */
   }
 
-  /* "pywrapfst.pyx":1805
+  /* "pywrapfst.pyx":1876
  *     if isymbols is not None:
  *        _isymbols = isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()             # <<<<<<<<<<<<<<
@@ -20944,11 +21364,11 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1805, __pyx_L1_error)
+    __PYX_ERR(0, 1876, __pyx_L1_error)
   }
   __pyx_v__osymbols = __pyx_v_self->_fst.get()->OutputSymbols();
 
-  /* "pywrapfst.pyx":1806
+  /* "pywrapfst.pyx":1877
  *        _isymbols = isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
@@ -20959,7 +21379,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
   __pyx_t_10 = (__pyx_t_11 != 0);
   if (__pyx_t_10) {
 
-    /* "pywrapfst.pyx":1807
+    /* "pywrapfst.pyx":1878
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  *     if osymbols is not None:
  *        _osymbols = osymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -20968,12 +21388,12 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
  */
     if (unlikely(((PyObject *)__pyx_v_osymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 1807, __pyx_L1_error)
+      __PYX_ERR(0, 1878, __pyx_L1_error)
     }
-    __pyx_t_12 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_osymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_osymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1807, __pyx_L1_error)
+    __pyx_t_12 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_osymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_osymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1878, __pyx_L1_error)
     __pyx_v__osymbols = __pyx_t_12;
 
-    /* "pywrapfst.pyx":1806
+    /* "pywrapfst.pyx":1877
  *        _isymbols = isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_osymbols = self._fst.get().OutputSymbols()
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
@@ -20982,7 +21402,7 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
  */
   }
 
-  /* "pywrapfst.pyx":1808
+  /* "pywrapfst.pyx":1879
  *     if osymbols is not None:
  *        _osymbols = osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_ssymbols = NULL             # <<<<<<<<<<<<<<
@@ -20991,85 +21411,85 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
  */
   __pyx_v__ssymbols = NULL;
 
-  /* "pywrapfst.pyx":1809
+  /* "pywrapfst.pyx":1880
  *        _osymbols = osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
  *       _ssymbols = ssymbols._raw_ptr_or_raise()
- *     cdef stringstream sstrm
+ *     cdef stringstream _sstrm
  */
   __pyx_t_10 = (((PyObject *)__pyx_v_ssymbols) != Py_None);
   __pyx_t_11 = (__pyx_t_10 != 0);
   if (__pyx_t_11) {
 
-    /* "pywrapfst.pyx":1810
+    /* "pywrapfst.pyx":1881
  *     cdef const fst.SymbolTable *_ssymbols = NULL
  *     if ssymbols is not None:
  *       _ssymbols = ssymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
- *     cdef stringstream sstrm
+ *     cdef stringstream _sstrm
  *     fst.Print(deref(self._fst),
  */
     if (unlikely(((PyObject *)__pyx_v_ssymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 1810, __pyx_L1_error)
+      __PYX_ERR(0, 1881, __pyx_L1_error)
     }
-    __pyx_t_12 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_ssymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_ssymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1810, __pyx_L1_error)
+    __pyx_t_12 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_ssymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_ssymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1881, __pyx_L1_error)
     __pyx_v__ssymbols = __pyx_t_12;
 
-    /* "pywrapfst.pyx":1809
+    /* "pywrapfst.pyx":1880
  *        _osymbols = osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
  *       _ssymbols = ssymbols._raw_ptr_or_raise()
- *     cdef stringstream sstrm
+ *     cdef stringstream _sstrm
  */
   }
 
-  /* "pywrapfst.pyx":1812
+  /* "pywrapfst.pyx":1883
  *       _ssymbols = ssymbols._raw_ptr_or_raise()
- *     cdef stringstream sstrm
+ *     cdef stringstream _sstrm
  *     fst.Print(deref(self._fst),             # <<<<<<<<<<<<<<
- *               sstrm,
+ *               _sstrm,
  *               b"<pywrapfst>",
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1812, __pyx_L1_error)
+    __PYX_ERR(0, 1883, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":1820
+  /* "pywrapfst.pyx":1891
  *               acceptor,
  *               show_weight_one,
  *               tostring(missing_sym))             # <<<<<<<<<<<<<<
- *     return sstrm.str()
+ *     return _sstrm.str()
  * 
  */
-  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_missing_sym); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1820, __pyx_L1_error)
+  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_missing_sym); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1891, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1812
+  /* "pywrapfst.pyx":1883
  *       _ssymbols = ssymbols._raw_ptr_or_raise()
- *     cdef stringstream sstrm
+ *     cdef stringstream _sstrm
  *     fst.Print(deref(self._fst),             # <<<<<<<<<<<<<<
- *               sstrm,
+ *               _sstrm,
  *               b"<pywrapfst>",
  */
-  fst::script::Print((*__pyx_v_self->_fst), __pyx_v_sstrm, __pyx_k_pywrapfst, __pyx_v__isymbols, __pyx_v__osymbols, __pyx_v__ssymbols, __pyx_v_acceptor, __pyx_v_show_weight_one, __pyx_t_9);
+  fst::script::Print((*__pyx_v_self->_fst), __pyx_v__sstrm, __pyx_k_pywrapfst, __pyx_v__isymbols, __pyx_v__osymbols, __pyx_v__ssymbols, __pyx_v_acceptor, __pyx_v_show_weight_one, __pyx_t_9);
 
-  /* "pywrapfst.pyx":1821
+  /* "pywrapfst.pyx":1892
  *               show_weight_one,
  *               tostring(missing_sym))
- *     return sstrm.str()             # <<<<<<<<<<<<<<
+ *     return _sstrm.str()             # <<<<<<<<<<<<<<
  * 
  *   cpdef uint64 properties(self, uint64 mask, bool test):
  */
-  __pyx_r = __pyx_v_sstrm.str();
+  __pyx_r = __pyx_v__sstrm.str();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1776
+  /* "pywrapfst.pyx":1847
  *     return _init_FstSymbolTableView(self._fst, input_side=False)
  * 
- *   cpdef string print(self, _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
- *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
+ *   cpdef string print(self, SymbolTableView isymbols=None,             # <<<<<<<<<<<<<<
+ *       SymbolTableView osymbols=None, SymbolTableView ssymbols=None,
  *       bool acceptor=False, bool show_weight_one=False,
  */
 
@@ -21093,30 +21513,33 @@ static std::string __pyx_f_9pywrapfst_3Fst_print(struct __pyx_obj_9pywrapfst_Fst
 static PyObject *__pyx_pw_9pywrapfst_3Fst_33print(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_3Fst_32print[] = "\n    print(self, isymbols=None, osymbols=None, ssymbols=None, acceptor=False,\n          show_weight_one=False, missing_sym=\"\")\n\n    Produces a human-readable string representation of the FST.\n\n    This method generates a human-readable string representation of the FST.\n    The caller may optionally specify SymbolTables used to label input labels,\n    output labels, or state labels, respectively.\n\n    Args:\n      isymbols: An optional symbol table used to label input symbols.\n      osymbols: An optional symbol table used to label output symbols.\n      ssymbols: An optional symbol table used to label states.\n      acceptor: Should the FST be rendered in acceptor format if possible?\n      show_weight_one: Should weights equivalent to semiring One be printed?\n      missing_symbol: The string to be printed when symbol table lookup fails.\n\n    Returns:\n      A formatted string representing the machine.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_3Fst_33print(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols = 0;
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols = 0;
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_ssymbols = 0;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_isymbols = 0;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_osymbols = 0;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_ssymbols = 0;
   bool __pyx_v_acceptor;
   bool __pyx_v_show_weight_one;
   PyObject *__pyx_v_missing_sym = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("print (wrapper)", 0);
   {
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_isymbols,&__pyx_n_s_osymbols,&__pyx_n_s_ssymbols,&__pyx_n_s_acceptor,&__pyx_n_s_show_weight_one,&__pyx_n_s_missing_sym,0};
     PyObject* values[6] = {0,0,0,0,0,0};
-    values[0] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
+    values[0] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-    /* "pywrapfst.pyx":1777
+    /* "pywrapfst.pyx":1848
  * 
- *   cpdef string print(self, _SymbolTable isymbols=None,
- *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
+ *   cpdef string print(self, SymbolTableView isymbols=None,
+ *       SymbolTableView osymbols=None, SymbolTableView ssymbols=None,             # <<<<<<<<<<<<<<
  *       bool acceptor=False, bool show_weight_one=False,
- *       missing_sym=b"") except *:
+ *       missing_sym="") except *:
  */
-    values[1] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
-    values[2] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
-    values[5] = ((PyObject *)__pyx_kp_b__8);
+    values[1] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
+    values[2] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
+    values[5] = ((PyObject *)__pyx_kp_u__11);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -21175,7 +21598,7 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_33print(PyObject *__pyx_v_self, PyObje
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "print") < 0)) __PYX_ERR(0, 1776, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "print") < 0)) __PYX_ERR(0, 1847, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -21195,24 +21618,24 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_33print(PyObject *__pyx_v_self, PyObje
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_isymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[0]);
-    __pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[1]);
-    __pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[2]);
+    __pyx_v_isymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)values[0]);
+    __pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)values[1]);
+    __pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)values[2]);
     if (values[3]) {
-      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1778, __pyx_L3_error)
+      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1849, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":1778
- *   cpdef string print(self, _SymbolTable isymbols=None,
- *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
+      /* "pywrapfst.pyx":1849
+ *   cpdef string print(self, SymbolTableView isymbols=None,
+ *       SymbolTableView osymbols=None, SymbolTableView ssymbols=None,
  *       bool acceptor=False, bool show_weight_one=False,             # <<<<<<<<<<<<<<
- *       missing_sym=b"") except *:
+ *       missing_sym="") except *:
  *     """
  */
       __pyx_v_acceptor = ((bool)0);
     }
     if (values[4]) {
-      __pyx_v_show_weight_one = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_show_weight_one == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1778, __pyx_L3_error)
+      __pyx_v_show_weight_one = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_show_weight_one == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1849, __pyx_L3_error)
     } else {
       __pyx_v_show_weight_one = ((bool)0);
     }
@@ -21220,22 +21643,22 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_33print(PyObject *__pyx_v_self, PyObje
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("print", 0, 0, 6, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1776, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("print", 0, 0, 6, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1847, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Fst.print", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "isymbols", 0))) __PYX_ERR(0, 1776, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 1777, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 1777, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "isymbols", 0))) __PYX_ERR(0, 1847, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "osymbols", 0))) __PYX_ERR(0, 1848, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "ssymbols", 0))) __PYX_ERR(0, 1848, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_3Fst_32print(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), __pyx_v_isymbols, __pyx_v_osymbols, __pyx_v_ssymbols, __pyx_v_acceptor, __pyx_v_show_weight_one, __pyx_v_missing_sym);
 
-  /* "pywrapfst.pyx":1776
+  /* "pywrapfst.pyx":1847
  *     return _init_FstSymbolTableView(self._fst, input_side=False)
  * 
- *   cpdef string print(self, _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
- *       _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
+ *   cpdef string print(self, SymbolTableView isymbols=None,             # <<<<<<<<<<<<<<
+ *       SymbolTableView osymbols=None, SymbolTableView ssymbols=None,
  *       bool acceptor=False, bool show_weight_one=False,
  */
 
@@ -21248,12 +21671,15 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_33print(PyObject *__pyx_v_self, PyObje
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_3Fst_32print(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_ssymbols, bool __pyx_v_acceptor, bool __pyx_v_show_weight_one, PyObject *__pyx_v_missing_sym) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_32print(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_isymbols, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_osymbols, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_ssymbols, bool __pyx_v_acceptor, bool __pyx_v_show_weight_one, PyObject *__pyx_v_missing_sym) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
   struct __pyx_opt_args_9pywrapfst_3Fst_print __pyx_t_2;
   PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("print", 0);
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 6;
@@ -21263,8 +21689,8 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_32print(struct __pyx_obj_9pywrapfst_Fs
   __pyx_t_2.acceptor = __pyx_v_acceptor;
   __pyx_t_2.show_weight_one = __pyx_v_show_weight_one;
   __pyx_t_2.missing_sym = __pyx_v_missing_sym;
-  __pyx_t_1 = __pyx_vtabptr_9pywrapfst_Fst->print(__pyx_v_self, 1, &__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1776, __pyx_L1_error)
-  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1776, __pyx_L1_error)
+  __pyx_t_1 = __pyx_vtabptr_9pywrapfst_Fst->print(__pyx_v_self, 1, &__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1847, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1847, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -21281,8 +21707,8 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_32print(struct __pyx_obj_9pywrapfst_Fs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1823
- *     return sstrm.str()
+/* "pywrapfst.pyx":1894
+ *     return _sstrm.str()
  * 
  *   cpdef uint64 properties(self, uint64 mask, bool test):             # <<<<<<<<<<<<<<
  *     """
@@ -21302,6 +21728,9 @@ static uint64 __pyx_f_9pywrapfst_3Fst_properties(struct __pyx_obj_9pywrapfst_Fst
   int __pyx_t_7;
   PyObject *__pyx_t_8 = NULL;
   uint64 __pyx_t_9;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("properties", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -21312,12 +21741,12 @@ static uint64 __pyx_f_9pywrapfst_3Fst_properties(struct __pyx_obj_9pywrapfst_Fst
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_properties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1823, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_properties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1894, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_35properties)) {
-        __pyx_t_3 = __Pyx_PyInt_From_uint64_t(__pyx_v_mask); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1823, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_uint64_t(__pyx_v_mask); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1894, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_test); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1823, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_test); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1894, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
@@ -21335,7 +21764,7 @@ static uint64 __pyx_f_9pywrapfst_3Fst_properties(struct __pyx_obj_9pywrapfst_Fst
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_5)) {
           PyObject *__pyx_temp[3] = {__pyx_t_6, __pyx_t_3, __pyx_t_4};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1823, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1894, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -21345,7 +21774,7 @@ static uint64 __pyx_f_9pywrapfst_3Fst_properties(struct __pyx_obj_9pywrapfst_Fst
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
           PyObject *__pyx_temp[3] = {__pyx_t_6, __pyx_t_3, __pyx_t_4};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1823, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1894, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -21353,7 +21782,7 @@ static uint64 __pyx_f_9pywrapfst_3Fst_properties(struct __pyx_obj_9pywrapfst_Fst
         } else
         #endif
         {
-          __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1823, __pyx_L1_error)
+          __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1894, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_8);
           if (__pyx_t_6) {
             __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
@@ -21364,12 +21793,12 @@ static uint64 __pyx_f_9pywrapfst_3Fst_properties(struct __pyx_obj_9pywrapfst_Fst
           PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_t_4);
           __pyx_t_3 = 0;
           __pyx_t_4 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1823, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1894, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         }
         __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-        __pyx_t_9 = __Pyx_PyInt_As_uint64_t(__pyx_t_2); if (unlikely((__pyx_t_9 == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1823, __pyx_L1_error)
+        __pyx_t_9 = __Pyx_PyInt_As_uint64_t(__pyx_t_2); if (unlikely((__pyx_t_9 == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1894, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_9;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -21388,7 +21817,7 @@ static uint64 __pyx_f_9pywrapfst_3Fst_properties(struct __pyx_obj_9pywrapfst_Fst
     #endif
   }
 
-  /* "pywrapfst.pyx":1841
+  /* "pywrapfst.pyx":1912
  *       A 64-bit bitmask representing the requested properties.
  *     """
  *     return self._fst.get().Properties(mask, test)             # <<<<<<<<<<<<<<
@@ -21397,13 +21826,13 @@ static uint64 __pyx_f_9pywrapfst_3Fst_properties(struct __pyx_obj_9pywrapfst_Fst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1841, __pyx_L1_error)
+    __PYX_ERR(0, 1912, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->Properties(__pyx_v_mask, __pyx_v_test);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1823
- *     return sstrm.str()
+  /* "pywrapfst.pyx":1894
+ *     return _sstrm.str()
  * 
  *   cpdef uint64 properties(self, uint64 mask, bool test):             # <<<<<<<<<<<<<<
  *     """
@@ -21432,6 +21861,9 @@ static char __pyx_doc_9pywrapfst_3Fst_34properties[] = "\n    properties(self, m
 static PyObject *__pyx_pw_9pywrapfst_3Fst_35properties(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   uint64 __pyx_v_mask;
   bool __pyx_v_test;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("properties (wrapper)", 0);
@@ -21458,11 +21890,11 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_35properties(PyObject *__pyx_v_self, P
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_test)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("properties", 1, 2, 2, 1); __PYX_ERR(0, 1823, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("properties", 1, 2, 2, 1); __PYX_ERR(0, 1894, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "properties") < 0)) __PYX_ERR(0, 1823, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "properties") < 0)) __PYX_ERR(0, 1894, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -21470,12 +21902,12 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_35properties(PyObject *__pyx_v_self, P
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
-    __pyx_v_mask = __Pyx_PyInt_As_uint64_t(values[0]); if (unlikely((__pyx_v_mask == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1823, __pyx_L3_error)
-    __pyx_v_test = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_test == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1823, __pyx_L3_error)
+    __pyx_v_mask = __Pyx_PyInt_As_uint64_t(values[0]); if (unlikely((__pyx_v_mask == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1894, __pyx_L3_error)
+    __pyx_v_test = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_test == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1894, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("properties", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1823, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("properties", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1894, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Fst.properties", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -21492,9 +21924,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_34properties(struct __pyx_obj_9pywrapf
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("properties", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(__pyx_f_9pywrapfst_3Fst_properties(__pyx_v_self, __pyx_v_mask, __pyx_v_test, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1823, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(__pyx_f_9pywrapfst_3Fst_properties(__pyx_v_self, __pyx_v_mask, __pyx_v_test, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1894, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -21511,7 +21946,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_34properties(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1844
+/* "pywrapfst.pyx":1915
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
@@ -21537,9 +21972,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_36read(CYTHON_UNUSED PyTypeObject *__p
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("read", 0);
 
-  /* "pywrapfst.pyx":1859
+  /* "pywrapfst.pyx":1930
  *       FstIOError: Read failed.
  *     """
  *     return _read_Fst(source)             # <<<<<<<<<<<<<<
@@ -21547,13 +21985,13 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_36read(CYTHON_UNUSED PyTypeObject *__p
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_Fst(__pyx_v_source, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1859, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_Fst(__pyx_v_source, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1930, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1844
+  /* "pywrapfst.pyx":1915
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
@@ -21572,7 +22010,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_36read(CYTHON_UNUSED PyTypeObject *__p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1862
+/* "pywrapfst.pyx":1933
  * 
  *   @classmethod
  *   def read_from_string(cls, state):             # <<<<<<<<<<<<<<
@@ -21597,10 +22035,14 @@ static PyObject *__pyx_pw_9pywrapfst_3Fst_39read_from_string(PyObject *__pyx_v_c
 static PyObject *__pyx_pf_9pywrapfst_3Fst_38read_from_string(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_state) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
+  std::string __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("read_from_string", 0);
 
-  /* "pywrapfst.pyx":1877
+  /* "pywrapfst.pyx":1948
  *       FstIOError: Read failed.
  *     """
  *     return _read_Fst_from_string(state)             # <<<<<<<<<<<<<<
@@ -21608,13 +22050,14 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_38read_from_string(CYTHON_UNUSED PyTyp
  *   cpdef int64 start(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_Fst_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1877, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __pyx_t_1 = __pyx_convert_string_from_py_std__in_string(__pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1948, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__read_Fst_from_string(__pyx_t_1, 0)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1948, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1862
+  /* "pywrapfst.pyx":1933
  * 
  *   @classmethod
  *   def read_from_string(cls, state):             # <<<<<<<<<<<<<<
@@ -21624,7 +22067,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_38read_from_string(CYTHON_UNUSED PyTyp
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
   __Pyx_AddTraceback("pywrapfst.Fst.read_from_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -21633,7 +22076,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_38read_from_string(CYTHON_UNUSED PyTyp
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1879
+/* "pywrapfst.pyx":1950
  *     return _read_Fst_from_string(state)
  * 
  *   cpdef int64 start(self):             # <<<<<<<<<<<<<<
@@ -21650,6 +22093,9 @@ static int64 __pyx_f_9pywrapfst_3Fst_start(struct __pyx_obj_9pywrapfst_Fst *__py
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   int64 __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("start", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -21660,7 +22106,7 @@ static int64 __pyx_f_9pywrapfst_3Fst_start(struct __pyx_obj_9pywrapfst_Fst *__py
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_start); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1879, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_start); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1950, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_41start)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -21676,10 +22122,10 @@ static int64 __pyx_f_9pywrapfst_3Fst_start(struct __pyx_obj_9pywrapfst_Fst *__py
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1879, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1950, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1879, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1950, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -21698,7 +22144,7 @@ static int64 __pyx_f_9pywrapfst_3Fst_start(struct __pyx_obj_9pywrapfst_Fst *__py
     #endif
   }
 
-  /* "pywrapfst.pyx":1885
+  /* "pywrapfst.pyx":1956
  *     Returns the start state.
  *     """
  *     return self._fst.get().Start()             # <<<<<<<<<<<<<<
@@ -21707,12 +22153,12 @@ static int64 __pyx_f_9pywrapfst_3Fst_start(struct __pyx_obj_9pywrapfst_Fst *__py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1885, __pyx_L1_error)
+    __PYX_ERR(0, 1956, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->Start();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1879
+  /* "pywrapfst.pyx":1950
  *     return _read_Fst_from_string(state)
  * 
  *   cpdef int64 start(self):             # <<<<<<<<<<<<<<
@@ -21751,9 +22197,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_40start(struct __pyx_obj_9pywrapfst_Fs
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("start", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_3Fst_start(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1879, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_3Fst_start(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1950, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -21770,7 +22219,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_40start(struct __pyx_obj_9pywrapfst_Fs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1887
+/* "pywrapfst.pyx":1958
  *     return self._fst.get().Start()
  * 
  *   cpdef StateIterator states(self):             # <<<<<<<<<<<<<<
@@ -21786,6 +22235,9 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_3Fst_states
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("states", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -21796,7 +22248,7 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_3Fst_states
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1887, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1958, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_43states)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -21813,10 +22265,10 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_3Fst_states
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1887, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1958, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_StateIterator))))) __PYX_ERR(0, 1887, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_StateIterator))))) __PYX_ERR(0, 1958, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst_StateIterator *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -21835,21 +22287,21 @@ static struct __pyx_obj_9pywrapfst_StateIterator *__pyx_f_9pywrapfst_3Fst_states
     #endif
   }
 
-  /* "pywrapfst.pyx":1896
+  /* "pywrapfst.pyx":1967
  *       A StateIterator object for the FST.
  *     """
  *     return StateIterator(self)             # <<<<<<<<<<<<<<
  * 
- *   # TODO(kbg): Deprecated; remove on next release.
+ *   cpdef bool verify(self):
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = __Pyx_PyObject_CallOneArg(((PyObject *)__pyx_ptype_9pywrapfst_StateIterator), ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1896, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_CallOneArg(((PyObject *)__pyx_ptype_9pywrapfst_StateIterator), ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1967, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_StateIterator *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1887
+  /* "pywrapfst.pyx":1958
  *     return self._fst.get().Start()
  * 
  *   cpdef StateIterator states(self):             # <<<<<<<<<<<<<<
@@ -21889,9 +22341,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_42states(struct __pyx_obj_9pywrapfst_F
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("states", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_states(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1887, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Fst_states(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1958, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -21908,103 +22363,27 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_42states(struct __pyx_obj_9pywrapfst_F
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1899
+/* "pywrapfst.pyx":1969
+ *     return StateIterator(self)
  * 
- *   # TODO(kbg): Deprecated; remove on next release.
- *   cpdef string text(self,             # <<<<<<<<<<<<<<
- *                     _SymbolTable isymbols=None,
- *                     _SymbolTable osymbols=None,
- */
-
-static PyObject *__pyx_pw_9pywrapfst_3Fst_45text(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static std::string __pyx_f_9pywrapfst_3Fst_text(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_3Fst_text *__pyx_optional_args) {
-
-  /* "pywrapfst.pyx":1900
- *   # TODO(kbg): Deprecated; remove on next release.
- *   cpdef string text(self,
- *                     _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
- *                     _SymbolTable osymbols=None,
- *                     _SymbolTable ssymbols=None,
- */
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
-
-  /* "pywrapfst.pyx":1901
- *   cpdef string text(self,
- *                     _SymbolTable isymbols=None,
- *                     _SymbolTable osymbols=None,             # <<<<<<<<<<<<<<
- *                     _SymbolTable ssymbols=None,
- *                     bool acceptor=False,
- */
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
-
-  /* "pywrapfst.pyx":1902
- *                     _SymbolTable isymbols=None,
- *                     _SymbolTable osymbols=None,
- *                     _SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
- *                     bool acceptor=False,
- *                     bool show_weight_one=False,
- */
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
-
-  /* "pywrapfst.pyx":1903
- *                     _SymbolTable osymbols=None,
- *                     _SymbolTable ssymbols=None,
- *                     bool acceptor=False,             # <<<<<<<<<<<<<<
- *                     bool show_weight_one=False,
- *                     missing_sym=b"") except *:
- */
-  bool __pyx_v_acceptor = ((bool)0);
-
-  /* "pywrapfst.pyx":1904
- *                     _SymbolTable ssymbols=None,
- *                     bool acceptor=False,
- *                     bool show_weight_one=False,             # <<<<<<<<<<<<<<
- *                     missing_sym=b"") except *:
+ *   cpdef bool verify(self):             # <<<<<<<<<<<<<<
  *     """
+ *     verify(self)
  */
-  bool __pyx_v_show_weight_one = ((bool)0);
-  PyObject *__pyx_v_missing_sym = ((PyObject *)__pyx_kp_b__8);
-  std::string __pyx_r;
+
+static PyObject *__pyx_pw_9pywrapfst_3Fst_45verify(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static bool __pyx_f_9pywrapfst_3Fst_verify(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch) {
+  bool __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  int __pyx_t_7;
-  PyObject *__pyx_t_8 = NULL;
-  std::string __pyx_t_9;
-  struct __pyx_opt_args_9pywrapfst_3Fst_print __pyx_t_10;
-  __Pyx_RefNannySetupContext("text", 0);
-  if (__pyx_optional_args) {
-    if (__pyx_optional_args->__pyx_n > 0) {
-      __pyx_v_isymbols = __pyx_optional_args->isymbols;
-      if (__pyx_optional_args->__pyx_n > 1) {
-        __pyx_v_osymbols = __pyx_optional_args->osymbols;
-        if (__pyx_optional_args->__pyx_n > 2) {
-          __pyx_v_ssymbols = __pyx_optional_args->ssymbols;
-          if (__pyx_optional_args->__pyx_n > 3) {
-            __pyx_v_acceptor = __pyx_optional_args->acceptor;
-            if (__pyx_optional_args->__pyx_n > 4) {
-              __pyx_v_show_weight_one = __pyx_optional_args->show_weight_one;
-              if (__pyx_optional_args->__pyx_n > 5) {
-                __pyx_v_missing_sym = __pyx_optional_args->missing_sym;
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-
-  /* "pywrapfst.pyx":1899
- * 
- *   # TODO(kbg): Deprecated; remove on next release.
- *   cpdef string text(self,             # <<<<<<<<<<<<<<
- *                     _SymbolTable isymbols=None,
- *                     _SymbolTable osymbols=None,
- */
+  bool __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("verify", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
@@ -22014,78 +22393,28 @@ static std::string __pyx_f_9pywrapfst_3Fst_text(struct __pyx_obj_9pywrapfst_Fst
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_text); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1899, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_verify); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1969, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_45text)) {
-        __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_acceptor); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1899, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_show_weight_one); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1899, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_4);
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_45verify)) {
         __Pyx_INCREF(__pyx_t_1);
-        __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
-        __pyx_t_7 = 0;
-        if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
-          __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
-          if (likely(__pyx_t_6)) {
-            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-            __Pyx_INCREF(__pyx_t_6);
+        __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
+        if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
+          __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+          if (likely(__pyx_t_4)) {
+            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+            __Pyx_INCREF(__pyx_t_4);
             __Pyx_INCREF(function);
-            __Pyx_DECREF_SET(__pyx_t_5, function);
-            __pyx_t_7 = 1;
+            __Pyx_DECREF_SET(__pyx_t_3, function);
           }
         }
-        #if CYTHON_FAST_PYCALL
-        if (PyFunction_Check(__pyx_t_5)) {
-          PyObject *__pyx_temp[7] = {__pyx_t_6, ((PyObject *)__pyx_v_isymbols), ((PyObject *)__pyx_v_osymbols), ((PyObject *)__pyx_v_ssymbols), __pyx_t_3, __pyx_t_4, __pyx_v_missing_sym};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 6+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1899, __pyx_L1_error)
-          __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-          __Pyx_GOTREF(__pyx_t_2);
-          __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-          __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        } else
-        #endif
-        #if CYTHON_FAST_PYCCALL
-        if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
-          PyObject *__pyx_temp[7] = {__pyx_t_6, ((PyObject *)__pyx_v_isymbols), ((PyObject *)__pyx_v_osymbols), ((PyObject *)__pyx_v_ssymbols), __pyx_t_3, __pyx_t_4, __pyx_v_missing_sym};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 6+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1899, __pyx_L1_error)
-          __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-          __Pyx_GOTREF(__pyx_t_2);
-          __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-          __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        } else
-        #endif
-        {
-          __pyx_t_8 = PyTuple_New(6+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1899, __pyx_L1_error)
-          __Pyx_GOTREF(__pyx_t_8);
-          if (__pyx_t_6) {
-            __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
-          }
-          __Pyx_INCREF(((PyObject *)__pyx_v_isymbols));
-          __Pyx_GIVEREF(((PyObject *)__pyx_v_isymbols));
-          PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, ((PyObject *)__pyx_v_isymbols));
-          __Pyx_INCREF(((PyObject *)__pyx_v_osymbols));
-          __Pyx_GIVEREF(((PyObject *)__pyx_v_osymbols));
-          PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, ((PyObject *)__pyx_v_osymbols));
-          __Pyx_INCREF(((PyObject *)__pyx_v_ssymbols));
-          __Pyx_GIVEREF(((PyObject *)__pyx_v_ssymbols));
-          PyTuple_SET_ITEM(__pyx_t_8, 2+__pyx_t_7, ((PyObject *)__pyx_v_ssymbols));
-          __Pyx_GIVEREF(__pyx_t_3);
-          PyTuple_SET_ITEM(__pyx_t_8, 3+__pyx_t_7, __pyx_t_3);
-          __Pyx_GIVEREF(__pyx_t_4);
-          PyTuple_SET_ITEM(__pyx_t_8, 4+__pyx_t_7, __pyx_t_4);
-          __Pyx_INCREF(__pyx_v_missing_sym);
-          __Pyx_GIVEREF(__pyx_v_missing_sym);
-          PyTuple_SET_ITEM(__pyx_t_8, 5+__pyx_t_7, __pyx_v_missing_sym);
-          __pyx_t_3 = 0;
-          __pyx_t_4 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1899, __pyx_L1_error)
-          __Pyx_GOTREF(__pyx_t_2);
-          __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-        }
-        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-        __pyx_t_9 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1899, __pyx_L1_error)
+        __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
+        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1969, __pyx_L1_error)
+        __Pyx_GOTREF(__pyx_t_2);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1969, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-        __pyx_r = __pyx_t_9;
+        __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
         goto __pyx_L0;
       }
@@ -22102,63 +22431,26 @@ static std::string __pyx_f_9pywrapfst_3Fst_text(struct __pyx_obj_9pywrapfst_Fst
     #endif
   }
 
-  /* "pywrapfst.pyx":1927
- *       A formatted string representing the machine.
- *     """
- *     warnings.warn("Use `print` instead", DeprecationWarning, stacklevel=2)             # <<<<<<<<<<<<<<
- *     return self.print(isymbols,
- *                       osymbols,
- */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_warnings); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1927, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_warn); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1927, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1927, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_stacklevel, __pyx_int_2) < 0) __PYX_ERR(0, 1927, __pyx_L1_error)
-  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__9, __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1927, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-
-  /* "pywrapfst.pyx":1928
+  /* "pywrapfst.pyx":1978
+ *       True if the contents are sane, False otherwise.
  *     """
- *     warnings.warn("Use `print` instead", DeprecationWarning, stacklevel=2)
- *     return self.print(isymbols,             # <<<<<<<<<<<<<<
- *                       osymbols,
- *                       ssymbols,
+ *     return fst.Verify(deref(self._fst))             # <<<<<<<<<<<<<<
+ * 
+ *   cpdef string weight_type(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "print");
-    __PYX_ERR(0, 1928, __pyx_L1_error)
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
+    __PYX_ERR(0, 1978, __pyx_L1_error)
   }
-
-  /* "pywrapfst.pyx":1933
- *                       acceptor,
- *                       show_weight_one,
- *                       missing_sym)             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __pyx_t_10.__pyx_n = 6;
-  __pyx_t_10.isymbols = __pyx_v_isymbols;
-  __pyx_t_10.osymbols = __pyx_v_osymbols;
-  __pyx_t_10.ssymbols = __pyx_v_ssymbols;
-  __pyx_t_10.acceptor = __pyx_v_acceptor;
-  __pyx_t_10.show_weight_one = __pyx_v_show_weight_one;
-  __pyx_t_10.missing_sym = __pyx_v_missing_sym;
-  __pyx_t_9 = ((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_self->__pyx_vtab)->print(__pyx_v_self, 0, &__pyx_t_10); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1928, __pyx_L1_error)
-  __pyx_r = __pyx_t_9;
+  __pyx_r = fst::script::Verify((*__pyx_v_self->_fst));
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1899
+  /* "pywrapfst.pyx":1969
+ *     return StateIterator(self)
  * 
- *   # TODO(kbg): Deprecated; remove on next release.
- *   cpdef string text(self,             # <<<<<<<<<<<<<<
- *                     _SymbolTable isymbols=None,
- *                     _SymbolTable osymbols=None,
+ *   cpdef bool verify(self):             # <<<<<<<<<<<<<<
+ *     """
+ *     verify(self)
  */
 
   /* function exit code */
@@ -22167,225 +22459,46 @@ static std::string __pyx_f_9pywrapfst_3Fst_text(struct __pyx_obj_9pywrapfst_Fst
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_8);
-  __Pyx_AddTraceback("pywrapfst.Fst.text", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_pretend_to_initialize(&__pyx_r);
+  __Pyx_WriteUnraisable("pywrapfst.Fst.verify", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
+  __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_3Fst_45text(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_3Fst_44text[] = "\n    text(self, isymbols=None, osymbols=None, ssymbols=None, acceptor=False,\n          show_weight_one=False, missing_sym=\"\")\n\n    Produces a human-readable string representation of the FST.\n\n    This method generates a human-readable string representation of the FST.\n    The caller may optionally specify SymbolTables used to label input labels,\n    output labels, or state labels, respectively.\n\n    Args:\n      isymbols: An optional symbol table used to label input symbols.\n      osymbols: An optional symbol table used to label output symbols.\n      ssymbols: An optional symbol table used to label states.\n      acceptor: Should the FST be rendered in acceptor format if possible?\n      show_weight_one: Should weights equivalent to semiring One be printed?\n      missing_symbol: The string to be printed when symbol table lookup fails.\n\n    Returns:\n      A formatted string representing the machine.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_3Fst_45text(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols = 0;
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols = 0;
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_ssymbols = 0;
-  bool __pyx_v_acceptor;
-  bool __pyx_v_show_weight_one;
-  PyObject *__pyx_v_missing_sym = 0;
+static PyObject *__pyx_pw_9pywrapfst_3Fst_45verify(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_3Fst_44verify[] = "\n    verify(self)\n\n    Verifies that an FST's contents are sane.\n\n    Returns:\n      True if the contents are sane, False otherwise.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_3Fst_45verify(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("text (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_isymbols,&__pyx_n_s_osymbols,&__pyx_n_s_ssymbols,&__pyx_n_s_acceptor,&__pyx_n_s_show_weight_one,&__pyx_n_s_missing_sym,0};
-    PyObject* values[6] = {0,0,0,0,0,0};
-
-    /* "pywrapfst.pyx":1900
- *   # TODO(kbg): Deprecated; remove on next release.
- *   cpdef string text(self,
- *                     _SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
- *                     _SymbolTable osymbols=None,
- *                     _SymbolTable ssymbols=None,
- */
-    values[0] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
-
-    /* "pywrapfst.pyx":1901
- *   cpdef string text(self,
- *                     _SymbolTable isymbols=None,
- *                     _SymbolTable osymbols=None,             # <<<<<<<<<<<<<<
- *                     _SymbolTable ssymbols=None,
- *                     bool acceptor=False,
- */
-    values[1] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
-
-    /* "pywrapfst.pyx":1902
- *                     _SymbolTable isymbols=None,
- *                     _SymbolTable osymbols=None,
- *                     _SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
- *                     bool acceptor=False,
- *                     bool show_weight_one=False,
- */
-    values[2] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
-    values[5] = ((PyObject *)__pyx_kp_b__8);
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
-        CYTHON_FALLTHROUGH;
-        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
-        CYTHON_FALLTHROUGH;
-        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-        CYTHON_FALLTHROUGH;
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        CYTHON_FALLTHROUGH;
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        CYTHON_FALLTHROUGH;
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        CYTHON_FALLTHROUGH;
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (kw_args > 0) {
-          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_isymbols);
-          if (value) { values[0] = value; kw_args--; }
-        }
-        CYTHON_FALLTHROUGH;
-        case  1:
-        if (kw_args > 0) {
-          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_osymbols);
-          if (value) { values[1] = value; kw_args--; }
-        }
-        CYTHON_FALLTHROUGH;
-        case  2:
-        if (kw_args > 0) {
-          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ssymbols);
-          if (value) { values[2] = value; kw_args--; }
-        }
-        CYTHON_FALLTHROUGH;
-        case  3:
-        if (kw_args > 0) {
-          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_acceptor);
-          if (value) { values[3] = value; kw_args--; }
-        }
-        CYTHON_FALLTHROUGH;
-        case  4:
-        if (kw_args > 0) {
-          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_show_weight_one);
-          if (value) { values[4] = value; kw_args--; }
-        }
-        CYTHON_FALLTHROUGH;
-        case  5:
-        if (kw_args > 0) {
-          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_missing_sym);
-          if (value) { values[5] = value; kw_args--; }
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "text") < 0)) __PYX_ERR(0, 1899, __pyx_L3_error)
-      }
-    } else {
-      switch (PyTuple_GET_SIZE(__pyx_args)) {
-        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
-        CYTHON_FALLTHROUGH;
-        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
-        CYTHON_FALLTHROUGH;
-        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-        CYTHON_FALLTHROUGH;
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        CYTHON_FALLTHROUGH;
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        CYTHON_FALLTHROUGH;
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        CYTHON_FALLTHROUGH;
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-    }
-    __pyx_v_isymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[0]);
-    __pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[1]);
-    __pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[2]);
-    if (values[3]) {
-      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1903, __pyx_L3_error)
-    } else {
-
-      /* "pywrapfst.pyx":1903
- *                     _SymbolTable osymbols=None,
- *                     _SymbolTable ssymbols=None,
- *                     bool acceptor=False,             # <<<<<<<<<<<<<<
- *                     bool show_weight_one=False,
- *                     missing_sym=b"") except *:
- */
-      __pyx_v_acceptor = ((bool)0);
-    }
-    if (values[4]) {
-      __pyx_v_show_weight_one = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_show_weight_one == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1904, __pyx_L3_error)
-    } else {
-
-      /* "pywrapfst.pyx":1904
- *                     _SymbolTable ssymbols=None,
- *                     bool acceptor=False,
- *                     bool show_weight_one=False,             # <<<<<<<<<<<<<<
- *                     missing_sym=b"") except *:
- *     """
- */
-      __pyx_v_show_weight_one = ((bool)0);
-    }
-    __pyx_v_missing_sym = values[5];
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("text", 0, 0, 6, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1899, __pyx_L3_error)
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst.Fst.text", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "isymbols", 0))) __PYX_ERR(0, 1900, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 1901, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 1902, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_3Fst_44text(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), __pyx_v_isymbols, __pyx_v_osymbols, __pyx_v_ssymbols, __pyx_v_acceptor, __pyx_v_show_weight_one, __pyx_v_missing_sym);
-
-  /* "pywrapfst.pyx":1899
- * 
- *   # TODO(kbg): Deprecated; remove on next release.
- *   cpdef string text(self,             # <<<<<<<<<<<<<<
- *                     _SymbolTable isymbols=None,
- *                     _SymbolTable osymbols=None,
- */
+  __Pyx_RefNannySetupContext("verify (wrapper)", 0);
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_44verify(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self));
 
   /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_3Fst_44text(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_osymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_ssymbols, bool __pyx_v_acceptor, bool __pyx_v_show_weight_one, PyObject *__pyx_v_missing_sym) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_44verify(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  std::string __pyx_t_1;
-  struct __pyx_opt_args_9pywrapfst_3Fst_text __pyx_t_2;
-  PyObject *__pyx_t_3 = NULL;
-  __Pyx_RefNannySetupContext("text", 0);
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("verify", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2.__pyx_n = 6;
-  __pyx_t_2.isymbols = __pyx_v_isymbols;
-  __pyx_t_2.osymbols = __pyx_v_osymbols;
-  __pyx_t_2.ssymbols = __pyx_v_ssymbols;
-  __pyx_t_2.acceptor = __pyx_v_acceptor;
-  __pyx_t_2.show_weight_one = __pyx_v_show_weight_one;
-  __pyx_t_2.missing_sym = __pyx_v_missing_sym;
-  __pyx_t_1 = __pyx_vtabptr_9pywrapfst_Fst->text(__pyx_v_self, 1, &__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1899, __pyx_L1_error)
-  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1899, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_r = __pyx_t_3;
-  __pyx_t_3 = 0;
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_3Fst_verify(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1969, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
   goto __pyx_L0;
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_AddTraceback("pywrapfst.Fst.text", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pywrapfst.Fst.verify", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -22393,24 +22506,27 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_44text(struct __pyx_obj_9pywrapfst_Fst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1936
- * 
+/* "pywrapfst.pyx":1980
+ *     return fst.Verify(deref(self._fst))
  * 
- *   cpdef bool verify(self):             # <<<<<<<<<<<<<<
+ *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
  *     """
- *     verify(self)
+ *     weight_type(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_3Fst_47verify(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static bool __pyx_f_9pywrapfst_3Fst_verify(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch) {
-  bool __pyx_r;
+static PyObject *__pyx_pw_9pywrapfst_3Fst_47weight_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static std::string __pyx_f_9pywrapfst_3Fst_weight_type(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch) {
+  std::string __pyx_r;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  bool __pyx_t_5;
-  __Pyx_RefNannySetupContext("verify", 0);
+  std::string __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("weight_type", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
   /* Check if overridden in Python */
@@ -22420,9 +22536,9 @@ static bool __pyx_f_9pywrapfst_3Fst_verify(struct __pyx_obj_9pywrapfst_Fst *__py
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_verify); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1936, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_weight_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1980, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_47verify)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_47weight_type)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -22436,10 +22552,10 @@ static bool __pyx_f_9pywrapfst_3Fst_verify(struct __pyx_obj_9pywrapfst_Fst *__py
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1936, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1980, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1936, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1980, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -22458,144 +22574,7 @@ static bool __pyx_f_9pywrapfst_3Fst_verify(struct __pyx_obj_9pywrapfst_Fst *__py
     #endif
   }
 
-  /* "pywrapfst.pyx":1945
- *       True if the contents are sane, False otherwise.
- *     """
- *     return fst.Verify(deref(self._fst))             # <<<<<<<<<<<<<<
- * 
- *   cpdef string weight_type(self):
- */
-  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1945, __pyx_L1_error)
-  }
-  __pyx_r = fst::script::Verify((*__pyx_v_self->_fst));
-  goto __pyx_L0;
-
-  /* "pywrapfst.pyx":1936
- * 
- * 
- *   cpdef bool verify(self):             # <<<<<<<<<<<<<<
- *     """
- *     verify(self)
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_WriteUnraisable("pywrapfst.Fst.verify", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
-  __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_3Fst_47verify(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_3Fst_46verify[] = "\n    verify(self)\n\n    Verifies that an FST's contents are sane.\n\n    Returns:\n      True if the contents are sane, False otherwise.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_3Fst_47verify(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("verify (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_3Fst_46verify(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self));
-
-  /* function exit code */
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_9pywrapfst_3Fst_46verify(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  __Pyx_RefNannySetupContext("verify", 0);
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_3Fst_verify(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1936, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pywrapfst.Fst.verify", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pywrapfst.pyx":1947
- *     return fst.Verify(deref(self._fst))
- * 
- *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
- *     """
- *     weight_type(self)
- */
-
-static PyObject *__pyx_pw_9pywrapfst_3Fst_49weight_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static std::string __pyx_f_9pywrapfst_3Fst_weight_type(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch) {
-  std::string __pyx_r;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  std::string __pyx_t_5;
-  __Pyx_RefNannySetupContext("weight_type", 0);
-  /* Check if called by wrapper */
-  if (unlikely(__pyx_skip_dispatch)) ;
-  /* Check if overridden in Python */
-  else if (unlikely((Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0) || (Py_TYPE(((PyObject *)__pyx_v_self))->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)))) {
-    #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
-    static PY_UINT64_T __pyx_tp_dict_version = __PYX_DICT_VERSION_INIT, __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
-    if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
-      PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
-      #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_weight_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1947, __pyx_L1_error)
-      __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_49weight_type)) {
-        __Pyx_INCREF(__pyx_t_1);
-        __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
-        if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
-          __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
-          if (likely(__pyx_t_4)) {
-            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
-            __Pyx_INCREF(__pyx_t_4);
-            __Pyx_INCREF(function);
-            __Pyx_DECREF_SET(__pyx_t_3, function);
-          }
-        }
-        __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
-        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1947, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_2);
-        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1947, __pyx_L1_error)
-        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-        __pyx_r = __pyx_t_5;
-        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-        goto __pyx_L0;
-      }
-      #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
-      __pyx_tp_dict_version = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
-      __pyx_obj_dict_version = __Pyx_get_object_dict_version(((PyObject *)__pyx_v_self));
-      if (unlikely(__pyx_type_dict_guard != __pyx_tp_dict_version)) {
-        __pyx_tp_dict_version = __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT;
-      }
-      #endif
-      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
-    }
-    #endif
-  }
-
-  /* "pywrapfst.pyx":1956
+  /* "pywrapfst.pyx":1989
  *       A string representing the weight type.
  *     """
  *     return self._fst.get().WeightType()             # <<<<<<<<<<<<<<
@@ -22604,12 +22583,12 @@ static std::string __pyx_f_9pywrapfst_3Fst_weight_type(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1956, __pyx_L1_error)
+    __PYX_ERR(0, 1989, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_fst.get()->WeightType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1947
+  /* "pywrapfst.pyx":1980
  *     return fst.Verify(deref(self._fst))
  * 
  *   cpdef string weight_type(self):             # <<<<<<<<<<<<<<
@@ -22631,26 +22610,29 @@ static std::string __pyx_f_9pywrapfst_3Fst_weight_type(struct __pyx_obj_9pywrapf
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_3Fst_49weight_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_3Fst_48weight_type[] = "\n    weight_type(self)\n\n    Provides the FST's weight type.\n\n    Returns:\n      A string representing the weight type.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_3Fst_49weight_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_3Fst_47weight_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_3Fst_46weight_type[] = "\n    weight_type(self)\n\n    Provides the FST's weight type.\n\n    Returns:\n      A string representing the weight type.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_3Fst_47weight_type(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("weight_type (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_3Fst_48weight_type(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_46weight_type(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_3Fst_48weight_type(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_46weight_type(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("weight_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_3Fst_weight_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1947, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_3Fst_weight_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1980, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -22667,7 +22649,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_48weight_type(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1958
+/* "pywrapfst.pyx":1991
  *     return self._fst.get().WeightType()
  * 
  *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
@@ -22675,7 +22657,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_48weight_type(struct __pyx_obj_9pywrap
  *     write(self, source)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_3Fst_51write(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_3Fst_49write(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
 static void __pyx_f_9pywrapfst_3Fst_write(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, PyObject *__pyx_v_source, int __pyx_skip_dispatch) {
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -22684,7 +22666,9 @@ static void __pyx_f_9pywrapfst_3Fst_write(struct __pyx_obj_9pywrapfst_Fst *__pyx
   PyObject *__pyx_t_4 = NULL;
   std::string __pyx_t_5;
   int __pyx_t_6;
-  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -22695,9 +22679,9 @@ static void __pyx_f_9pywrapfst_3Fst_write(struct __pyx_obj_9pywrapfst_Fst *__pyx
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1958, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1991, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_51write)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_49write)) {
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
         if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -22711,7 +22695,7 @@ static void __pyx_f_9pywrapfst_3Fst_write(struct __pyx_obj_9pywrapfst_Fst *__pyx
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_source);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1958, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1991, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -22731,77 +22715,65 @@ static void __pyx_f_9pywrapfst_3Fst_write(struct __pyx_obj_9pywrapfst_Fst *__pyx
     #endif
   }
 
-  /* "pywrapfst.pyx":1972
+  /* "pywrapfst.pyx":2005
  *       FstIOError: Write failed.
  *     """
- *     if not self._fst.get().Write(tostring(source)):             # <<<<<<<<<<<<<<
- *       raise FstIOError("Write failed: {!r}".format(source))
+ *     if not self._fst.get().Write(path_tostring(source)):             # <<<<<<<<<<<<<<
+ *       raise FstIOError(f"Write failed: {source!r}")
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1972, __pyx_L1_error)
+    __PYX_ERR(0, 2005, __pyx_L1_error)
   }
-  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1972, __pyx_L1_error)
+  __pyx_t_5 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2005, __pyx_L1_error)
   __pyx_t_6 = ((!(__pyx_v_self->_fst.get()->Write(__pyx_t_5) != 0)) != 0);
   if (unlikely(__pyx_t_6)) {
 
-    /* "pywrapfst.pyx":1973
+    /* "pywrapfst.pyx":2006
  *     """
- *     if not self._fst.get().Write(tostring(source)):
- *       raise FstIOError("Write failed: {!r}".format(source))             # <<<<<<<<<<<<<<
+ *     if not self._fst.get().Write(path_tostring(source)):
+ *       raise FstIOError(f"Write failed: {source!r}")             # <<<<<<<<<<<<<<
  * 
  *   cpdef bytes write_to_string(self):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1973, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2006, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Write_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1973, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_7 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_4);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-        __Pyx_INCREF(__pyx_t_7);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_4, function);
-      }
-    }
-    __pyx_t_3 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_7, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_source);
-    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1973, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2006, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = NULL;
+    __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Write_failed, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2006, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
-      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
-      if (likely(__pyx_t_4)) {
+      __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+      if (likely(__pyx_t_3)) {
         PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-        __Pyx_INCREF(__pyx_t_4);
+        __Pyx_INCREF(__pyx_t_3);
         __Pyx_INCREF(function);
         __Pyx_DECREF_SET(__pyx_t_2, function);
       }
     }
-    __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
-    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1973, __pyx_L1_error)
+    __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4);
+    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2006, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 1973, __pyx_L1_error)
+    __PYX_ERR(0, 2006, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1972
+    /* "pywrapfst.pyx":2005
  *       FstIOError: Write failed.
  *     """
- *     if not self._fst.get().Write(tostring(source)):             # <<<<<<<<<<<<<<
- *       raise FstIOError("Write failed: {!r}".format(source))
+ *     if not self._fst.get().Write(path_tostring(source)):             # <<<<<<<<<<<<<<
+ *       raise FstIOError(f"Write failed: {source!r}")
  * 
  */
   }
 
-  /* "pywrapfst.pyx":1958
+  /* "pywrapfst.pyx":1991
  *     return self._fst.get().WeightType()
  * 
  *   cpdef void write(self, source) except *:             # <<<<<<<<<<<<<<
@@ -22816,34 +22788,36 @@ static void __pyx_f_9pywrapfst_3Fst_write(struct __pyx_obj_9pywrapfst_Fst *__pyx
   __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_AddTraceback("pywrapfst.Fst.write", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_3Fst_51write(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
-static char __pyx_doc_9pywrapfst_3Fst_50write[] = "\n    write(self, source)\n\n    Serializes FST to a file.\n\n    This method writes the FST to a file in a binary format.\n\n    Args:\n      source: The string location of the output file.\n\n    Raises:\n      FstIOError: Write failed.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_3Fst_51write(PyObject *__pyx_v_self, PyObject *__pyx_v_source) {
+static PyObject *__pyx_pw_9pywrapfst_3Fst_49write(PyObject *__pyx_v_self, PyObject *__pyx_v_source); /*proto*/
+static char __pyx_doc_9pywrapfst_3Fst_48write[] = "\n    write(self, source)\n\n    Serializes FST to a file.\n\n    This method writes the FST to a file in a binary format.\n\n    Args:\n      source: The string location of the output file.\n\n    Raises:\n      FstIOError: Write failed.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_3Fst_49write(PyObject *__pyx_v_self, PyObject *__pyx_v_source) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("write (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_3Fst_50write(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), ((PyObject *)__pyx_v_source));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_48write(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), ((PyObject *)__pyx_v_source));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_3Fst_50write(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, PyObject *__pyx_v_source) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_48write(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, PyObject *__pyx_v_source) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_3Fst_write(__pyx_v_self, __pyx_v_source, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1958, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1958, __pyx_L1_error)
+  __pyx_f_9pywrapfst_3Fst_write(__pyx_v_self, __pyx_v_source, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1991, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1991, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -22860,17 +22834,17 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_50write(struct __pyx_obj_9pywrapfst_Fs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":1975
- *       raise FstIOError("Write failed: {!r}".format(source))
+/* "pywrapfst.pyx":2008
+ *       raise FstIOError(f"Write failed: {source!r}")
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
  *     """
  *     write_to_string(self)
  */
 
-static PyObject *__pyx_pw_9pywrapfst_3Fst_53write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_3Fst_51write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
 static PyObject *__pyx_f_9pywrapfst_3Fst_write_to_string(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self, int __pyx_skip_dispatch) {
-  std::stringstream __pyx_v_sstrm;
+  std::stringstream __pyx_v__sstrm;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -22878,6 +22852,9 @@ static PyObject *__pyx_f_9pywrapfst_3Fst_write_to_string(struct __pyx_obj_9pywra
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   int __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write_to_string", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -22888,9 +22865,9 @@ static PyObject *__pyx_f_9pywrapfst_3Fst_write_to_string(struct __pyx_obj_9pywra
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1975, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2008, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
-      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_53write_to_string)) {
+      if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Fst_51write_to_string)) {
         __Pyx_XDECREF(__pyx_r);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
@@ -22905,10 +22882,10 @@ static PyObject *__pyx_f_9pywrapfst_3Fst_write_to_string(struct __pyx_obj_9pywra
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1975, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2008, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 1975, __pyx_L1_error)
+        if (!(likely(PyBytes_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 2008, __pyx_L1_error)
         __pyx_r = ((PyObject*)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -22927,28 +22904,28 @@ static PyObject *__pyx_f_9pywrapfst_3Fst_write_to_string(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":1988
+  /* "pywrapfst.pyx":2021
  *     """
- *     cdef stringstream sstrm
- *     if not self._fst.get().Write(sstrm, b"<pywrapfst>"):             # <<<<<<<<<<<<<<
+ *     cdef stringstream _sstrm
+ *     if not self._fst.get().Write(_sstrm, b"<pywrapfst>"):             # <<<<<<<<<<<<<<
  *       raise FstIOError("Write to string failed")
- *     return sstrm.str()
+ *     return _sstrm.str()
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 1988, __pyx_L1_error)
+    __PYX_ERR(0, 2021, __pyx_L1_error)
   }
-  __pyx_t_5 = ((!(__pyx_v_self->_fst.get()->Write(__pyx_v_sstrm, __pyx_k_pywrapfst) != 0)) != 0);
+  __pyx_t_5 = ((!(__pyx_v_self->_fst.get()->Write(__pyx_v__sstrm, __pyx_k_pywrapfst) != 0)) != 0);
   if (unlikely(__pyx_t_5)) {
 
-    /* "pywrapfst.pyx":1989
- *     cdef stringstream sstrm
- *     if not self._fst.get().Write(sstrm, b"<pywrapfst>"):
+    /* "pywrapfst.pyx":2022
+ *     cdef stringstream _sstrm
+ *     if not self._fst.get().Write(_sstrm, b"<pywrapfst>"):
  *       raise FstIOError("Write to string failed")             # <<<<<<<<<<<<<<
- *     return sstrm.str()
+ *     return _sstrm.str()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1989, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2022, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -22962,38 +22939,38 @@ static PyObject *__pyx_f_9pywrapfst_3Fst_write_to_string(struct __pyx_obj_9pywra
     }
     __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_kp_u_Write_to_string_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_Write_to_string_failed);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1989, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2022, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 1989, __pyx_L1_error)
+    __PYX_ERR(0, 2022, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":1988
+    /* "pywrapfst.pyx":2021
  *     """
- *     cdef stringstream sstrm
- *     if not self._fst.get().Write(sstrm, b"<pywrapfst>"):             # <<<<<<<<<<<<<<
+ *     cdef stringstream _sstrm
+ *     if not self._fst.get().Write(_sstrm, b"<pywrapfst>"):             # <<<<<<<<<<<<<<
  *       raise FstIOError("Write to string failed")
- *     return sstrm.str()
+ *     return _sstrm.str()
  */
   }
 
-  /* "pywrapfst.pyx":1990
- *     if not self._fst.get().Write(sstrm, b"<pywrapfst>"):
+  /* "pywrapfst.pyx":2023
+ *     if not self._fst.get().Write(_sstrm, b"<pywrapfst>"):
  *       raise FstIOError("Write to string failed")
- *     return sstrm.str()             # <<<<<<<<<<<<<<
+ *     return _sstrm.str()             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_sstrm.str()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1990, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v__sstrm.str()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2023, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((PyObject*)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":1975
- *       raise FstIOError("Write failed: {!r}".format(source))
+  /* "pywrapfst.pyx":2008
+ *       raise FstIOError(f"Write failed: {source!r}")
  * 
  *   cpdef bytes write_to_string(self):             # <<<<<<<<<<<<<<
  *     """
@@ -23015,26 +22992,29 @@ static PyObject *__pyx_f_9pywrapfst_3Fst_write_to_string(struct __pyx_obj_9pywra
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_3Fst_53write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_9pywrapfst_3Fst_52write_to_string[] = "\n    write_to_string(self)\n\n    Serializes FST to a string.\n\n    Returns:\n      A bytestring.\n\n    Raises:\n      FstIOError: Write to string failed.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_3Fst_53write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_3Fst_51write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_9pywrapfst_3Fst_50write_to_string[] = "\n    write_to_string(self)\n\n    Serializes FST to a string.\n\n    Returns:\n      A bytestring.\n\n    Raises:\n      FstIOError: Write to string failed.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_3Fst_51write_to_string(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("write_to_string (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_3Fst_52write_to_string(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_3Fst_50write_to_string(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_3Fst_52write_to_string(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_3Fst_50write_to_string(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write_to_string", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_3Fst_write_to_string(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1975, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_3Fst_write_to_string(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2008, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -23051,7 +23031,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Fst_52write_to_string(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2003
+/* "pywrapfst.pyx":2036
  *   """
  * 
  *   cdef void _check_mutating_imethod(self) except *:             # <<<<<<<<<<<<<<
@@ -23065,9 +23045,12 @@ static void __pyx_f_9pywrapfst_10MutableFst__check_mutating_imethod(struct __pyx
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_check_mutating_imethod", 0);
 
-  /* "pywrapfst.pyx":2008
+  /* "pywrapfst.pyx":2041
  *     This function is not visible to Python users.
  *     """
  *     if self._fst.get().Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -23076,19 +23059,19 @@ static void __pyx_f_9pywrapfst_10MutableFst__check_mutating_imethod(struct __pyx
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2008, __pyx_L1_error)
+    __PYX_ERR(0, 2041, __pyx_L1_error)
   }
   __pyx_t_1 = ((__pyx_v_self->__pyx_base._fst.get()->Properties(fst::kError, 1) == fst::kError) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2009
+    /* "pywrapfst.pyx":2042
  *     """
  *     if self._fst.get().Properties(fst.kError, True) == fst.kError:
  *       raise FstOpError("Operation failed")             # <<<<<<<<<<<<<<
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:
  *     if not self._fst.get().ValidStateId(state):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2009, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2042, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -23102,14 +23085,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__check_mutating_imethod(struct __pyx
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Operation_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Operation_failed);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2009, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2042, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 2009, __pyx_L1_error)
+    __PYX_ERR(0, 2042, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2008
+    /* "pywrapfst.pyx":2041
  *     This function is not visible to Python users.
  *     """
  *     if self._fst.get().Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
@@ -23118,7 +23101,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__check_mutating_imethod(struct __pyx
  */
   }
 
-  /* "pywrapfst.pyx":2003
+  /* "pywrapfst.pyx":2036
  *   """
  * 
  *   cdef void _check_mutating_imethod(self) except *:             # <<<<<<<<<<<<<<
@@ -23137,7 +23120,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__check_mutating_imethod(struct __pyx
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2010
+/* "pywrapfst.pyx":2043
  *     if self._fst.get().Properties(fst.kError, True) == fst.kError:
  *       raise FstOpError("Operation failed")
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:             # <<<<<<<<<<<<<<
@@ -23151,9 +23134,12 @@ static void __pyx_f_9pywrapfst_10MutableFst__add_arc(struct __pyx_obj_9pywrapfst
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_add_arc", 0);
 
-  /* "pywrapfst.pyx":2011
+  /* "pywrapfst.pyx":2044
  *       raise FstOpError("Operation failed")
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:
  *     if not self._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -23162,19 +23148,19 @@ static void __pyx_f_9pywrapfst_10MutableFst__add_arc(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2011, __pyx_L1_error)
+    __PYX_ERR(0, 2044, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->__pyx_base._fst.get()->ValidStateId(__pyx_v_state) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2012
+    /* "pywrapfst.pyx":2045
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:
  *     if not self._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     if not self._mfst.get().AddArc(state, deref(arc._arc)):
  *       raise FstOpError("Incompatible or invalid weight type")
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2012, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2045, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -23188,14 +23174,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__add_arc(struct __pyx_obj_9pywrapfst
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2012, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2045, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 2012, __pyx_L1_error)
+    __PYX_ERR(0, 2045, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2011
+    /* "pywrapfst.pyx":2044
  *       raise FstOpError("Operation failed")
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:
  *     if not self._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -23204,7 +23190,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__add_arc(struct __pyx_obj_9pywrapfst
  */
   }
 
-  /* "pywrapfst.pyx":2013
+  /* "pywrapfst.pyx":2046
  *     if not self._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")
  *     if not self._mfst.get().AddArc(state, deref(arc._arc)):             # <<<<<<<<<<<<<<
@@ -23213,23 +23199,23 @@ static void __pyx_f_9pywrapfst_10MutableFst__add_arc(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2013, __pyx_L1_error)
+    __PYX_ERR(0, 2046, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_arc) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 2013, __pyx_L1_error)
+    __PYX_ERR(0, 2046, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->AddArc(__pyx_v_state, (*__pyx_v_arc->_arc)) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2014
+    /* "pywrapfst.pyx":2047
  *       raise FstIndexError("State index out of range")
  *     if not self._mfst.get().AddArc(state, deref(arc._arc)):
  *       raise FstOpError("Incompatible or invalid weight type")             # <<<<<<<<<<<<<<
  * 
  *   def add_arc(self, int64 state, Arc arc):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2014, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2047, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -23243,14 +23229,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__add_arc(struct __pyx_obj_9pywrapfst
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Incompatible_or_invalid_weight_t) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Incompatible_or_invalid_weight_t);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2014, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2047, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 2014, __pyx_L1_error)
+    __PYX_ERR(0, 2047, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2013
+    /* "pywrapfst.pyx":2046
  *     if not self._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")
  *     if not self._mfst.get().AddArc(state, deref(arc._arc)):             # <<<<<<<<<<<<<<
@@ -23259,7 +23245,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__add_arc(struct __pyx_obj_9pywrapfst
  */
   }
 
-  /* "pywrapfst.pyx":2010
+  /* "pywrapfst.pyx":2043
  *     if self._fst.get().Properties(fst.kError, True) == fst.kError:
  *       raise FstOpError("Operation failed")
  *   cdef void _add_arc(self, int64 state, Arc arc) except *:             # <<<<<<<<<<<<<<
@@ -23278,7 +23264,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__add_arc(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2016
+/* "pywrapfst.pyx":2049
  *       raise FstOpError("Incompatible or invalid weight type")
  * 
  *   def add_arc(self, int64 state, Arc arc):             # <<<<<<<<<<<<<<
@@ -23292,6 +23278,9 @@ static char __pyx_doc_9pywrapfst_10MutableFst_add_arc[] = "\n    add_arc(self, s
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_1add_arc(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   int64 __pyx_v_state;
   struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("add_arc (wrapper)", 0);
@@ -23318,11 +23307,11 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_1add_arc(PyObject *__pyx_v_sel
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_arc)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("add_arc", 1, 2, 2, 1); __PYX_ERR(0, 2016, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("add_arc", 1, 2, 2, 1); __PYX_ERR(0, 2049, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_arc") < 0)) __PYX_ERR(0, 2016, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_arc") < 0)) __PYX_ERR(0, 2049, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -23330,18 +23319,18 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_1add_arc(PyObject *__pyx_v_sel
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2016, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2049, __pyx_L3_error)
     __pyx_v_arc = ((struct __pyx_obj_9pywrapfst_Arc *)values[1]);
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("add_arc", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2016, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("add_arc", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2049, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.add_arc", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 2016, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 2049, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_add_arc(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_state, __pyx_v_arc);
 
   /* function exit code */
@@ -23356,9 +23345,12 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_1add_arc(PyObject *__pyx_v_sel
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_add_arc(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state, struct __pyx_obj_9pywrapfst_Arc *__pyx_v_arc) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("add_arc", 0);
 
-  /* "pywrapfst.pyx":2033
+  /* "pywrapfst.pyx":2066
  *       FstOpdexError: Incompatible or invalid weight type.
  *     """
  *     self._add_arc(state, arc)             # <<<<<<<<<<<<<<
@@ -23367,11 +23359,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_add_arc(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_add_arc");
-    __PYX_ERR(0, 2033, __pyx_L1_error)
+    __PYX_ERR(0, 2066, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_add_arc(__pyx_v_self, __pyx_v_state, __pyx_v_arc); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2033, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_add_arc(__pyx_v_self, __pyx_v_state, __pyx_v_arc); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2066, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2034
+  /* "pywrapfst.pyx":2067
  *     """
  *     self._add_arc(state, arc)
  *     return self             # <<<<<<<<<<<<<<
@@ -23383,7 +23375,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_add_arc(struct __pyx_obj_9pywr
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2016
+  /* "pywrapfst.pyx":2049
  *       raise FstOpError("Incompatible or invalid weight type")
  * 
  *   def add_arc(self, int64 state, Arc arc):             # <<<<<<<<<<<<<<
@@ -23401,7 +23393,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_add_arc(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2036
+/* "pywrapfst.pyx":2069
  *     return self
  * 
  *   cpdef int64 add_state(self):             # <<<<<<<<<<<<<<
@@ -23418,6 +23410,9 @@ static int64 __pyx_f_9pywrapfst_10MutableFst_add_state(struct __pyx_obj_9pywrapf
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   int64 __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("add_state", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -23428,7 +23423,7 @@ static int64 __pyx_f_9pywrapfst_10MutableFst_add_state(struct __pyx_obj_9pywrapf
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2036, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2069, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_10MutableFst_3add_state)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -23444,10 +23439,10 @@ static int64 __pyx_f_9pywrapfst_10MutableFst_add_state(struct __pyx_obj_9pywrapf
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2036, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2069, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2036, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2069, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -23466,7 +23461,7 @@ static int64 __pyx_f_9pywrapfst_10MutableFst_add_state(struct __pyx_obj_9pywrapf
     #endif
   }
 
-  /* "pywrapfst.pyx":2045
+  /* "pywrapfst.pyx":2078
  *       The integer index of the new state.
  *     """
  *     return self._mfst.get().AddState()             # <<<<<<<<<<<<<<
@@ -23475,12 +23470,12 @@ static int64 __pyx_f_9pywrapfst_10MutableFst_add_state(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2045, __pyx_L1_error)
+    __PYX_ERR(0, 2078, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_mfst.get()->AddState();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2036
+  /* "pywrapfst.pyx":2069
  *     return self
  * 
  *   cpdef int64 add_state(self):             # <<<<<<<<<<<<<<
@@ -23519,9 +23514,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_2add_state(struct __pyx_obj_9p
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("add_state", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_10MutableFst_add_state(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2036, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_10MutableFst_add_state(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2069, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -23538,7 +23536,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_2add_state(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2047
+/* "pywrapfst.pyx":2080
  *     return self._mfst.get().AddState()
  * 
  *   cpdef void add_states(self, size_t n):             # <<<<<<<<<<<<<<
@@ -23554,6 +23552,9 @@ static void __pyx_f_9pywrapfst_10MutableFst_add_states(struct __pyx_obj_9pywrapf
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("add_states", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -23564,10 +23565,10 @@ static void __pyx_f_9pywrapfst_10MutableFst_add_states(struct __pyx_obj_9pywrapf
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2047, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2080, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_10MutableFst_5add_states)) {
-        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_n); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2047, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_n); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2080, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -23583,7 +23584,7 @@ static void __pyx_f_9pywrapfst_10MutableFst_add_states(struct __pyx_obj_9pywrapf
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2047, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2080, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -23603,20 +23604,20 @@ static void __pyx_f_9pywrapfst_10MutableFst_add_states(struct __pyx_obj_9pywrapf
     #endif
   }
 
-  /* "pywrapfst.pyx":2056
+  /* "pywrapfst.pyx":2089
  *       n: The number of states to add.
  *     """
  *     self._mfst.get().AddStates(n)             # <<<<<<<<<<<<<<
  * 
- *   cdef void _arcsort(self, sort_type=b"ilabel") except *:
+ *   cdef void _arcsort(self, sort_type="ilabel") except *:
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2056, __pyx_L1_error)
+    __PYX_ERR(0, 2089, __pyx_L1_error)
   }
   __pyx_v_self->_mfst.get()->AddStates(__pyx_v_n);
 
-  /* "pywrapfst.pyx":2047
+  /* "pywrapfst.pyx":2080
  *     return self._mfst.get().AddState()
  * 
  *   cpdef void add_states(self, size_t n):             # <<<<<<<<<<<<<<
@@ -23642,11 +23643,14 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_5add_states(PyObject *__pyx_v_
 static char __pyx_doc_9pywrapfst_10MutableFst_4add_states[] = "\n    add_states(self, n)\n\n    Adds n new states to the FST.\n\n    Args:\n      n: The number of states to add.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_5add_states(PyObject *__pyx_v_self, PyObject *__pyx_arg_n) {
   size_t __pyx_v_n;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("add_states (wrapper)", 0);
   assert(__pyx_arg_n); {
-    __pyx_v_n = __Pyx_PyInt_As_size_t(__pyx_arg_n); if (unlikely((__pyx_v_n == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 2047, __pyx_L3_error)
+    __pyx_v_n = __Pyx_PyInt_As_size_t(__pyx_arg_n); if (unlikely((__pyx_v_n == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 2080, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -23665,9 +23669,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_4add_states(struct __pyx_obj_9
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("add_states", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_10MutableFst_add_states(__pyx_v_self, __pyx_v_n, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2047, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_10MutableFst_add_states(__pyx_v_self, __pyx_v_n, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2080, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -23684,17 +23691,17 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_4add_states(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2058
+/* "pywrapfst.pyx":2091
  *     self._mfst.get().AddStates(n)
  * 
- *   cdef void _arcsort(self, sort_type=b"ilabel") except *:             # <<<<<<<<<<<<<<
- *     cdef fst.ArcSortType sort_type_enum
- *     if not fst.GetArcSortType(tostring(sort_type), addr(sort_type_enum)):
+ *   cdef void _arcsort(self, sort_type="ilabel") except *:             # <<<<<<<<<<<<<<
+ *     cdef fst.ArcSortType _sort_type
+ *     if not fst.GetArcSortType(tostring(sort_type), addr(_sort_type)):
  */
 
 static void __pyx_f_9pywrapfst_10MutableFst__arcsort(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__arcsort *__pyx_optional_args) {
-  PyObject *__pyx_v_sort_type = ((PyObject *)__pyx_n_b_ilabel);
-  enum fst::script::ArcSortType __pyx_v_sort_type_enum;
+  PyObject *__pyx_v_sort_type = ((PyObject *)__pyx_n_u_ilabel);
+  enum fst::script::ArcSortType __pyx_v__sort_type;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
   int __pyx_t_2;
@@ -23702,7 +23709,9 @@ static void __pyx_f_9pywrapfst_10MutableFst__arcsort(struct __pyx_obj_9pywrapfst
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_arcsort", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -23710,91 +23719,79 @@ static void __pyx_f_9pywrapfst_10MutableFst__arcsort(struct __pyx_obj_9pywrapfst
     }
   }
 
-  /* "pywrapfst.pyx":2060
- *   cdef void _arcsort(self, sort_type=b"ilabel") except *:
- *     cdef fst.ArcSortType sort_type_enum
- *     if not fst.GetArcSortType(tostring(sort_type), addr(sort_type_enum)):             # <<<<<<<<<<<<<<
- *       raise FstArgError("Unknown sort type {!r}".format(sort_type))
- *     fst.ArcSort(self._mfst.get(), sort_type_enum)
+  /* "pywrapfst.pyx":2093
+ *   cdef void _arcsort(self, sort_type="ilabel") except *:
+ *     cdef fst.ArcSortType _sort_type
+ *     if not fst.GetArcSortType(tostring(sort_type), addr(_sort_type)):             # <<<<<<<<<<<<<<
+ *       raise FstArgError(f"Unknown sort type: {sort_type!r}")
+ *     fst.ArcSort(self._mfst.get(), _sort_type)
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_sort_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2060, __pyx_L1_error)
-  __pyx_t_2 = ((!(fst::script::GetArcSortType(__pyx_t_1, (&__pyx_v_sort_type_enum)) != 0)) != 0);
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_sort_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2093, __pyx_L1_error)
+  __pyx_t_2 = ((!(fst::script::GetArcSortType(__pyx_t_1, (&__pyx_v__sort_type)) != 0)) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":2061
- *     cdef fst.ArcSortType sort_type_enum
- *     if not fst.GetArcSortType(tostring(sort_type), addr(sort_type_enum)):
- *       raise FstArgError("Unknown sort type {!r}".format(sort_type))             # <<<<<<<<<<<<<<
- *     fst.ArcSort(self._mfst.get(), sort_type_enum)
+    /* "pywrapfst.pyx":2094
+ *     cdef fst.ArcSortType _sort_type
+ *     if not fst.GetArcSortType(tostring(sort_type), addr(_sort_type)):
+ *       raise FstArgError(f"Unknown sort type: {sort_type!r}")             # <<<<<<<<<<<<<<
+ *     fst.ArcSort(self._mfst.get(), _sort_type)
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2061, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2094, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_sort_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2061, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
-        __Pyx_INCREF(__pyx_t_7);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_6, function);
-      }
-    }
-    __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_sort_type) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_sort_type);
-    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2061, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_sort_type), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2094, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = NULL;
+    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_sort_type, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2094, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
-      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
-      if (likely(__pyx_t_6)) {
+      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+      if (likely(__pyx_t_5)) {
         PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-        __Pyx_INCREF(__pyx_t_6);
+        __Pyx_INCREF(__pyx_t_5);
         __Pyx_INCREF(function);
         __Pyx_DECREF_SET(__pyx_t_4, function);
       }
     }
-    __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2061, __pyx_L1_error)
+    __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
+    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2094, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2061, __pyx_L1_error)
+    __PYX_ERR(0, 2094, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2060
- *   cdef void _arcsort(self, sort_type=b"ilabel") except *:
- *     cdef fst.ArcSortType sort_type_enum
- *     if not fst.GetArcSortType(tostring(sort_type), addr(sort_type_enum)):             # <<<<<<<<<<<<<<
- *       raise FstArgError("Unknown sort type {!r}".format(sort_type))
- *     fst.ArcSort(self._mfst.get(), sort_type_enum)
+    /* "pywrapfst.pyx":2093
+ *   cdef void _arcsort(self, sort_type="ilabel") except *:
+ *     cdef fst.ArcSortType _sort_type
+ *     if not fst.GetArcSortType(tostring(sort_type), addr(_sort_type)):             # <<<<<<<<<<<<<<
+ *       raise FstArgError(f"Unknown sort type: {sort_type!r}")
+ *     fst.ArcSort(self._mfst.get(), _sort_type)
  */
   }
 
-  /* "pywrapfst.pyx":2062
- *     if not fst.GetArcSortType(tostring(sort_type), addr(sort_type_enum)):
- *       raise FstArgError("Unknown sort type {!r}".format(sort_type))
- *     fst.ArcSort(self._mfst.get(), sort_type_enum)             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":2095
+ *     if not fst.GetArcSortType(tostring(sort_type), addr(_sort_type)):
+ *       raise FstArgError(f"Unknown sort type: {sort_type!r}")
+ *     fst.ArcSort(self._mfst.get(), _sort_type)             # <<<<<<<<<<<<<<
  * 
- *   def arcsort(self, sort_type=b"ilabel"):
+ *   def arcsort(self, sort_type="ilabel"):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2062, __pyx_L1_error)
+    __PYX_ERR(0, 2095, __pyx_L1_error)
   }
-  fst::script::ArcSort(__pyx_v_self->_mfst.get(), __pyx_v_sort_type_enum);
+  fst::script::ArcSort(__pyx_v_self->_mfst.get(), __pyx_v__sort_type);
 
-  /* "pywrapfst.pyx":2058
+  /* "pywrapfst.pyx":2091
  *     self._mfst.get().AddStates(n)
  * 
- *   cdef void _arcsort(self, sort_type=b"ilabel") except *:             # <<<<<<<<<<<<<<
- *     cdef fst.ArcSortType sort_type_enum
- *     if not fst.GetArcSortType(tostring(sort_type), addr(sort_type_enum)):
+ *   cdef void _arcsort(self, sort_type="ilabel") except *:             # <<<<<<<<<<<<<<
+ *     cdef fst.ArcSortType _sort_type
+ *     if not fst.GetArcSortType(tostring(sort_type), addr(_sort_type)):
  */
 
   /* function exit code */
@@ -23804,16 +23801,15 @@ static void __pyx_f_9pywrapfst_10MutableFst__arcsort(struct __pyx_obj_9pywrapfst
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_AddTraceback("pywrapfst.MutableFst._arcsort", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2064
- *     fst.ArcSort(self._mfst.get(), sort_type_enum)
+/* "pywrapfst.pyx":2097
+ *     fst.ArcSort(self._mfst.get(), _sort_type)
  * 
- *   def arcsort(self, sort_type=b"ilabel"):             # <<<<<<<<<<<<<<
+ *   def arcsort(self, sort_type="ilabel"):             # <<<<<<<<<<<<<<
  *     """
  *     arcsort(self, sort_type="ilabel")
  */
@@ -23823,13 +23819,16 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_7arcsort(PyObject *__pyx_v_sel
 static char __pyx_doc_9pywrapfst_10MutableFst_6arcsort[] = "\n    arcsort(self, sort_type=\"ilabel\")\n\n    Sorts arcs leaving each state of the FST.\n\n    This operation destructively sorts arcs leaving each state using either\n    input or output labels.\n\n    Args:\n      sort_type: Either \"ilabel\" (sort arcs according to input labels) or\n          \"olabel\" (sort arcs according to output labels).\n\n    Returns:\n      self.\n\n    Raises:\n      FstArgError: Unknown sort type.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_7arcsort(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_sort_type = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("arcsort (wrapper)", 0);
   {
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_sort_type,0};
     PyObject* values[1] = {0};
-    values[0] = ((PyObject *)__pyx_n_b_ilabel);
+    values[0] = ((PyObject *)__pyx_n_u_ilabel);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -23848,7 +23847,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_7arcsort(PyObject *__pyx_v_sel
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "arcsort") < 0)) __PYX_ERR(0, 2064, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "arcsort") < 0)) __PYX_ERR(0, 2097, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -23862,7 +23861,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_7arcsort(PyObject *__pyx_v_sel
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("arcsort", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2064, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("arcsort", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2097, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.arcsort", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -23879,9 +23878,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_6arcsort(struct __pyx_obj_9pyw
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_10MutableFst__arcsort __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("arcsort", 0);
 
-  /* "pywrapfst.pyx":2083
+  /* "pywrapfst.pyx":2116
  *       FstArgError: Unknown sort type.
  *     """
  *     self._arcsort(sort_type)             # <<<<<<<<<<<<<<
@@ -23890,13 +23892,13 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_6arcsort(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arcsort");
-    __PYX_ERR(0, 2083, __pyx_L1_error)
+    __PYX_ERR(0, 2116, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 1;
   __pyx_t_1.sort_type = __pyx_v_sort_type;
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_arcsort(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2083, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_arcsort(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2116, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2084
+  /* "pywrapfst.pyx":2117
  *     """
  *     self._arcsort(sort_type)
  *     return self             # <<<<<<<<<<<<<<
@@ -23908,10 +23910,10 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_6arcsort(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2064
- *     fst.ArcSort(self._mfst.get(), sort_type_enum)
+  /* "pywrapfst.pyx":2097
+ *     fst.ArcSort(self._mfst.get(), _sort_type)
  * 
- *   def arcsort(self, sort_type=b"ilabel"):             # <<<<<<<<<<<<<<
+ *   def arcsort(self, sort_type="ilabel"):             # <<<<<<<<<<<<<<
  *     """
  *     arcsort(self, sort_type="ilabel")
  */
@@ -23926,7 +23928,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_6arcsort(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2086
+/* "pywrapfst.pyx":2119
  *     return self
  * 
  *   cdef void _closure(self, bool closure_plus=False):             # <<<<<<<<<<<<<<
@@ -23937,6 +23939,9 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_6arcsort(struct __pyx_obj_9pyw
 static void __pyx_f_9pywrapfst_10MutableFst__closure(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__closure *__pyx_optional_args) {
   bool __pyx_v_closure_plus = ((bool)0);
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_closure", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -23944,7 +23949,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__closure(struct __pyx_obj_9pywrapfst
     }
   }
 
-  /* "pywrapfst.pyx":2087
+  /* "pywrapfst.pyx":2120
  * 
  *   cdef void _closure(self, bool closure_plus=False):
  *     fst.Closure(self._mfst.get(), fst.GetClosureType(closure_plus))             # <<<<<<<<<<<<<<
@@ -23953,11 +23958,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__closure(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2087, __pyx_L1_error)
+    __PYX_ERR(0, 2120, __pyx_L1_error)
   }
   fst::script::Closure(__pyx_v_self->_mfst.get(), fst::script::GetClosureType(__pyx_v_closure_plus));
 
-  /* "pywrapfst.pyx":2086
+  /* "pywrapfst.pyx":2119
  *     return self
  * 
  *   cdef void _closure(self, bool closure_plus=False):             # <<<<<<<<<<<<<<
@@ -23973,7 +23978,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__closure(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2089
+/* "pywrapfst.pyx":2122
  *     fst.Closure(self._mfst.get(), fst.GetClosureType(closure_plus))
  * 
  *   def closure(self, bool closure_plus=False):             # <<<<<<<<<<<<<<
@@ -23986,6 +23991,9 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_9closure(PyObject *__pyx_v_sel
 static char __pyx_doc_9pywrapfst_10MutableFst_8closure[] = "\n    closure(self, closure_plus=False)\n\n    Computes concatenative closure.\n\n    This operation destructively converts the FST to its concatenative closure.\n    If A transduces string x to y with weight a, then the closure transduces x\n    to y with weight a, xx to yy with weight a \\otimes a, xxx to yyy with weight\n    a \\otimes a \\otimes a, and so on. The empty string is also transduced to\n    itself with semiring One if `closure_plus` is False.\n\n    Args:\n      closure_plus: If False, do not accept the empty string.\n\n    Returns:\n      self.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_9closure(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   bool __pyx_v_closure_plus;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("closure (wrapper)", 0);
@@ -24010,7 +24018,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_9closure(PyObject *__pyx_v_sel
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "closure") < 0)) __PYX_ERR(0, 2089, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "closure") < 0)) __PYX_ERR(0, 2122, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -24021,14 +24029,14 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_9closure(PyObject *__pyx_v_sel
       }
     }
     if (values[0]) {
-      __pyx_v_closure_plus = __Pyx_PyObject_IsTrue(values[0]); if (unlikely((__pyx_v_closure_plus == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2089, __pyx_L3_error)
+      __pyx_v_closure_plus = __Pyx_PyObject_IsTrue(values[0]); if (unlikely((__pyx_v_closure_plus == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2122, __pyx_L3_error)
     } else {
       __pyx_v_closure_plus = ((bool)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("closure", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2089, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("closure", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2122, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.closure", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -24045,9 +24053,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_8closure(struct __pyx_obj_9pyw
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_10MutableFst__closure __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("closure", 0);
 
-  /* "pywrapfst.pyx":2107
+  /* "pywrapfst.pyx":2140
  *       self.
  *     """
  *     self._closure(closure_plus)             # <<<<<<<<<<<<<<
@@ -24056,13 +24067,13 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_8closure(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_closure");
-    __PYX_ERR(0, 2107, __pyx_L1_error)
+    __PYX_ERR(0, 2140, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 1;
   __pyx_t_1.closure_plus = __pyx_v_closure_plus;
   ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_closure(__pyx_v_self, &__pyx_t_1); 
 
-  /* "pywrapfst.pyx":2108
+  /* "pywrapfst.pyx":2141
  *     """
  *     self._closure(closure_plus)
  *     return self             # <<<<<<<<<<<<<<
@@ -24074,7 +24085,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_8closure(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2089
+  /* "pywrapfst.pyx":2122
  *     fst.Closure(self._mfst.get(), fst.GetClosureType(closure_plus))
  * 
  *   def closure(self, bool closure_plus=False):             # <<<<<<<<<<<<<<
@@ -24092,7 +24103,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_8closure(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2110
+/* "pywrapfst.pyx":2143
  *     return self
  * 
  *   cdef void _concat(self, Fst fst2) except *:             # <<<<<<<<<<<<<<
@@ -24102,9 +24113,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_8closure(struct __pyx_obj_9pyw
 
 static void __pyx_f_9pywrapfst_10MutableFst__concat(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_fst2) {
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_concat", 0);
 
-  /* "pywrapfst.pyx":2111
+  /* "pywrapfst.pyx":2144
  * 
  *   cdef void _concat(self, Fst fst2) except *:
  *     fst.Concat(self._mfst.get(), deref(fst2._fst))             # <<<<<<<<<<<<<<
@@ -24113,15 +24127,15 @@ static void __pyx_f_9pywrapfst_10MutableFst__concat(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2111, __pyx_L1_error)
+    __PYX_ERR(0, 2144, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_fst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2111, __pyx_L1_error)
+    __PYX_ERR(0, 2144, __pyx_L1_error)
   }
   fst::script::Concat(__pyx_v_self->_mfst.get(), (*__pyx_v_fst2->_fst));
 
-  /* "pywrapfst.pyx":2112
+  /* "pywrapfst.pyx":2145
  *   cdef void _concat(self, Fst fst2) except *:
  *     fst.Concat(self._mfst.get(), deref(fst2._fst))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -24130,11 +24144,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__concat(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2112, __pyx_L1_error)
+    __PYX_ERR(0, 2145, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2112, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2145, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2110
+  /* "pywrapfst.pyx":2143
  *     return self
  * 
  *   cdef void _concat(self, Fst fst2) except *:             # <<<<<<<<<<<<<<
@@ -24150,7 +24164,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__concat(struct __pyx_obj_9pywrapfst_
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2114
+/* "pywrapfst.pyx":2147
  *     self._check_mutating_imethod()
  * 
  *   def concat(self, Fst fst2):             # <<<<<<<<<<<<<<
@@ -24162,10 +24176,13 @@ static void __pyx_f_9pywrapfst_10MutableFst__concat(struct __pyx_obj_9pywrapfst_
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_11concat(PyObject *__pyx_v_self, PyObject *__pyx_v_fst2); /*proto*/
 static char __pyx_doc_9pywrapfst_10MutableFst_10concat[] = "\n    concat(self, fst2)\n\n    Computes the concatenation (product) of two FSTs.\n\n    This operation destructively concatenates the FST with a second FST. If A\n    transduces string x to y with weight a and B transduces string w to v with\n    weight b, then their concatenation transduces string xw to yv with weight a\n    \\otimes b.\n\n    Args:\n      fst2: The second input FST.\n\n    Returns:\n      self.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_11concat(PyObject *__pyx_v_self, PyObject *__pyx_v_fst2) {
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("concat (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fst2), __pyx_ptype_9pywrapfst_Fst, 1, "fst2", 0))) __PYX_ERR(0, 2114, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fst2), __pyx_ptype_9pywrapfst_Fst, 1, "fst2", 0))) __PYX_ERR(0, 2147, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_10concat(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_fst2));
 
   /* function exit code */
@@ -24180,9 +24197,12 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_11concat(PyObject *__pyx_v_sel
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_10concat(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_fst2) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("concat", 0);
 
-  /* "pywrapfst.pyx":2131
+  /* "pywrapfst.pyx":2164
  *       self.
  *     """
  *     self._concat(fst2)             # <<<<<<<<<<<<<<
@@ -24191,11 +24211,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_10concat(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_concat");
-    __PYX_ERR(0, 2131, __pyx_L1_error)
+    __PYX_ERR(0, 2164, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_concat(__pyx_v_self, __pyx_v_fst2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2131, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_concat(__pyx_v_self, __pyx_v_fst2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2164, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2132
+  /* "pywrapfst.pyx":2165
  *     """
  *     self._concat(fst2)
  *     return self             # <<<<<<<<<<<<<<
@@ -24207,7 +24227,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_10concat(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2114
+  /* "pywrapfst.pyx":2147
  *     self._check_mutating_imethod()
  * 
  *   def concat(self, Fst fst2):             # <<<<<<<<<<<<<<
@@ -24225,7 +24245,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_10concat(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2134
+/* "pywrapfst.pyx":2167
  *     return self
  * 
  *   cdef void _connect(self):             # <<<<<<<<<<<<<<
@@ -24235,9 +24255,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_10concat(struct __pyx_obj_9pyw
 
 static void __pyx_f_9pywrapfst_10MutableFst__connect(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self) {
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_connect", 0);
 
-  /* "pywrapfst.pyx":2135
+  /* "pywrapfst.pyx":2168
  * 
  *   cdef void _connect(self):
  *     fst.Connect(self._mfst.get())             # <<<<<<<<<<<<<<
@@ -24246,11 +24269,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__connect(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2135, __pyx_L1_error)
+    __PYX_ERR(0, 2168, __pyx_L1_error)
   }
   fst::script::Connect(__pyx_v_self->_mfst.get());
 
-  /* "pywrapfst.pyx":2134
+  /* "pywrapfst.pyx":2167
  *     return self
  * 
  *   cdef void _connect(self):             # <<<<<<<<<<<<<<
@@ -24266,7 +24289,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__connect(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2137
+/* "pywrapfst.pyx":2170
  *     fst.Connect(self._mfst.get())
  * 
  *   def connect(self):             # <<<<<<<<<<<<<<
@@ -24291,9 +24314,12 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_13connect(PyObject *__pyx_v_se
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_12connect(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("connect", 0);
 
-  /* "pywrapfst.pyx":2149
+  /* "pywrapfst.pyx":2182
  *       self.
  *     """
  *     self._connect()             # <<<<<<<<<<<<<<
@@ -24302,11 +24328,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_12connect(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_connect");
-    __PYX_ERR(0, 2149, __pyx_L1_error)
+    __PYX_ERR(0, 2182, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_connect(__pyx_v_self);
 
-  /* "pywrapfst.pyx":2150
+  /* "pywrapfst.pyx":2183
  *     """
  *     self._connect()
  *     return self             # <<<<<<<<<<<<<<
@@ -24318,7 +24344,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_12connect(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2137
+  /* "pywrapfst.pyx":2170
  *     fst.Connect(self._mfst.get())
  * 
  *   def connect(self):             # <<<<<<<<<<<<<<
@@ -24336,7 +24362,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_12connect(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2152
+/* "pywrapfst.pyx":2185
  *     return self
  * 
  *   cdef void _decode(self, EncodeMapper mapper) except *:             # <<<<<<<<<<<<<<
@@ -24346,9 +24372,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_12connect(struct __pyx_obj_9py
 
 static void __pyx_f_9pywrapfst_10MutableFst__decode(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper) {
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_decode", 0);
 
-  /* "pywrapfst.pyx":2153
+  /* "pywrapfst.pyx":2186
  * 
  *   cdef void _decode(self, EncodeMapper mapper) except *:
  *     fst.Decode(self._mfst.get(), deref(mapper._mapper))             # <<<<<<<<<<<<<<
@@ -24357,15 +24386,15 @@ static void __pyx_f_9pywrapfst_10MutableFst__decode(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2153, __pyx_L1_error)
+    __PYX_ERR(0, 2186, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_mapper) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 2153, __pyx_L1_error)
+    __PYX_ERR(0, 2186, __pyx_L1_error)
   }
   fst::script::Decode(__pyx_v_self->_mfst.get(), (*__pyx_v_mapper->_mapper));
 
-  /* "pywrapfst.pyx":2154
+  /* "pywrapfst.pyx":2187
  *   cdef void _decode(self, EncodeMapper mapper) except *:
  *     fst.Decode(self._mfst.get(), deref(mapper._mapper))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -24374,11 +24403,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__decode(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2154, __pyx_L1_error)
+    __PYX_ERR(0, 2187, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2154, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2187, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2152
+  /* "pywrapfst.pyx":2185
  *     return self
  * 
  *   cdef void _decode(self, EncodeMapper mapper) except *:             # <<<<<<<<<<<<<<
@@ -24394,7 +24423,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__decode(struct __pyx_obj_9pywrapfst_
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2156
+/* "pywrapfst.pyx":2189
  *     self._check_mutating_imethod()
  * 
  *   def decode(self, EncodeMapper mapper):             # <<<<<<<<<<<<<<
@@ -24406,10 +24435,13 @@ static void __pyx_f_9pywrapfst_10MutableFst__decode(struct __pyx_obj_9pywrapfst_
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_15decode(PyObject *__pyx_v_self, PyObject *__pyx_v_mapper); /*proto*/
 static char __pyx_doc_9pywrapfst_10MutableFst_14decode[] = "\n    decode(self, mapper)\n\n    Decodes encoded labels and/or weights.\n\n    This operation reverses the encoding performed by `encode`.\n\n    Args:\n      mapper: An EncodeMapper object used to encode the FST.\n\n    Returns:\n      self.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_15decode(PyObject *__pyx_v_self, PyObject *__pyx_v_mapper) {
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("decode (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mapper), __pyx_ptype_9pywrapfst_EncodeMapper, 1, "mapper", 0))) __PYX_ERR(0, 2156, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mapper), __pyx_ptype_9pywrapfst_EncodeMapper, 1, "mapper", 0))) __PYX_ERR(0, 2189, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_14decode(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_mapper));
 
   /* function exit code */
@@ -24424,9 +24456,12 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_15decode(PyObject *__pyx_v_sel
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_14decode(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("decode", 0);
 
-  /* "pywrapfst.pyx":2170
+  /* "pywrapfst.pyx":2203
  *       self.
  *     """
  *     self._decode(mapper)             # <<<<<<<<<<<<<<
@@ -24435,11 +24470,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_14decode(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_decode");
-    __PYX_ERR(0, 2170, __pyx_L1_error)
+    __PYX_ERR(0, 2203, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_decode(__pyx_v_self, __pyx_v_mapper); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2170, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_decode(__pyx_v_self, __pyx_v_mapper); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2203, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2171
+  /* "pywrapfst.pyx":2204
  *     """
  *     self._decode(mapper)
  *     return self             # <<<<<<<<<<<<<<
@@ -24451,7 +24486,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_14decode(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2156
+  /* "pywrapfst.pyx":2189
  *     self._check_mutating_imethod()
  * 
  *   def decode(self, EncodeMapper mapper):             # <<<<<<<<<<<<<<
@@ -24469,7 +24504,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_14decode(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2173
+/* "pywrapfst.pyx":2206
  *     return self
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:             # <<<<<<<<<<<<<<
@@ -24485,6 +24520,9 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_arcs(struct __pyx_obj_9pywra
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_delete_arcs", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -24492,7 +24530,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_arcs(struct __pyx_obj_9pywra
     }
   }
 
-  /* "pywrapfst.pyx":2174
+  /* "pywrapfst.pyx":2207
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else             # <<<<<<<<<<<<<<
@@ -24502,12 +24540,12 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_arcs(struct __pyx_obj_9pywra
   if ((__pyx_v_n != 0)) {
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 2174, __pyx_L1_error)
+      __PYX_ERR(0, 2207, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_mfst.get()->DeleteArcs(__pyx_v_state, __pyx_v_n);
   } else {
 
-    /* "pywrapfst.pyx":2175
+    /* "pywrapfst.pyx":2208
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else
  *             self._mfst.get().DeleteArcs(state)):             # <<<<<<<<<<<<<<
@@ -24516,12 +24554,12 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_arcs(struct __pyx_obj_9pywra
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 2175, __pyx_L1_error)
+      __PYX_ERR(0, 2208, __pyx_L1_error)
     }
     __pyx_t_1 = __pyx_v_self->_mfst.get()->DeleteArcs(__pyx_v_state);
   }
 
-  /* "pywrapfst.pyx":2174
+  /* "pywrapfst.pyx":2207
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else             # <<<<<<<<<<<<<<
@@ -24531,14 +24569,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_arcs(struct __pyx_obj_9pywra
   __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":2176
+    /* "pywrapfst.pyx":2209
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else
  *             self._mfst.get().DeleteArcs(state)):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2176, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2209, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
@@ -24552,14 +24590,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_arcs(struct __pyx_obj_9pywra
     }
     __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2176, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2209, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2176, __pyx_L1_error)
+    __PYX_ERR(0, 2209, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2174
+    /* "pywrapfst.pyx":2207
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:
  *     if not (self._mfst.get().DeleteArcs(state, n) if n else             # <<<<<<<<<<<<<<
@@ -24568,7 +24606,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_arcs(struct __pyx_obj_9pywra
  */
   }
 
-  /* "pywrapfst.pyx":2177
+  /* "pywrapfst.pyx":2210
  *             self._mfst.get().DeleteArcs(state)):
  *       raise FstIndexError("State index out of range")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -24577,11 +24615,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_arcs(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2177, __pyx_L1_error)
+    __PYX_ERR(0, 2210, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2177, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2210, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2173
+  /* "pywrapfst.pyx":2206
  *     return self
  * 
  *   cdef void _delete_arcs(self, int64 state, size_t n=0) except *:             # <<<<<<<<<<<<<<
@@ -24600,7 +24638,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_arcs(struct __pyx_obj_9pywra
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2179
+/* "pywrapfst.pyx":2212
  *     self._check_mutating_imethod()
  * 
  *   def delete_arcs(self, int64 state, size_t n=0):             # <<<<<<<<<<<<<<
@@ -24614,6 +24652,9 @@ static char __pyx_doc_9pywrapfst_10MutableFst_16delete_arcs[] = "\n    delete_ar
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_17delete_arcs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   int64 __pyx_v_state;
   size_t __pyx_v_n;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("delete_arcs (wrapper)", 0);
@@ -24644,7 +24685,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_17delete_arcs(PyObject *__pyx_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "delete_arcs") < 0)) __PYX_ERR(0, 2179, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "delete_arcs") < 0)) __PYX_ERR(0, 2212, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -24655,16 +24696,16 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_17delete_arcs(PyObject *__pyx_
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2179, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2212, __pyx_L3_error)
     if (values[1]) {
-      __pyx_v_n = __Pyx_PyInt_As_size_t(values[1]); if (unlikely((__pyx_v_n == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 2179, __pyx_L3_error)
+      __pyx_v_n = __Pyx_PyInt_As_size_t(values[1]); if (unlikely((__pyx_v_n == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 2212, __pyx_L3_error)
     } else {
       __pyx_v_n = ((size_t)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("delete_arcs", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2179, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("delete_arcs", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2212, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.delete_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -24681,9 +24722,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_16delete_arcs(struct __pyx_obj
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_10MutableFst__delete_arcs __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("delete_arcs", 0);
 
-  /* "pywrapfst.pyx":2197
+  /* "pywrapfst.pyx":2230
  *       FstIndexError: State index out of range.
  *     """
  *     self._delete_arcs(state, n)             # <<<<<<<<<<<<<<
@@ -24692,13 +24736,13 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_16delete_arcs(struct __pyx_obj
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_delete_arcs");
-    __PYX_ERR(0, 2197, __pyx_L1_error)
+    __PYX_ERR(0, 2230, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 1;
   __pyx_t_1.n = __pyx_v_n;
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_delete_arcs(__pyx_v_self, __pyx_v_state, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2197, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_delete_arcs(__pyx_v_self, __pyx_v_state, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2230, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2198
+  /* "pywrapfst.pyx":2231
  *     """
  *     self._delete_arcs(state, n)
  *     return self             # <<<<<<<<<<<<<<
@@ -24710,7 +24754,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_16delete_arcs(struct __pyx_obj
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2179
+  /* "pywrapfst.pyx":2212
  *     self._check_mutating_imethod()
  * 
  *   def delete_arcs(self, int64 state, size_t n=0):             # <<<<<<<<<<<<<<
@@ -24728,7 +24772,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_16delete_arcs(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2200
+/* "pywrapfst.pyx":2233
  *     return self
  * 
  *   cdef void _delete_states(self, states=None) except *:             # <<<<<<<<<<<<<<
@@ -24744,6 +24788,9 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_states(struct __pyx_obj_9pyw
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_delete_states", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -24751,17 +24798,17 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_states(struct __pyx_obj_9pyw
     }
   }
 
-  /* "pywrapfst.pyx":2202
+  /* "pywrapfst.pyx":2235
  *   cdef void _delete_states(self, states=None) except *:
  *     # Only the former signature has a possible indexing failure.
  *     if states:             # <<<<<<<<<<<<<<
  *       if not self._mfst.get().DeleteStates(<const vector[int64]> states):
  *         raise FstIndexError("State index out of range")
  */
-  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_states); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 2202, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_states); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 2235, __pyx_L1_error)
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2203
+    /* "pywrapfst.pyx":2236
  *     # Only the former signature has a possible indexing failure.
  *     if states:
  *       if not self._mfst.get().DeleteStates(<const vector[int64]> states):             # <<<<<<<<<<<<<<
@@ -24770,20 +24817,20 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_states(struct __pyx_obj_9pyw
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 2203, __pyx_L1_error)
+      __PYX_ERR(0, 2236, __pyx_L1_error)
     }
-    __pyx_t_2 = __pyx_convert_vector_from_py_int64(__pyx_v_states); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2203, __pyx_L1_error)
+    __pyx_t_2 = __pyx_convert_vector_from_py_int64(__pyx_v_states); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2236, __pyx_L1_error)
     __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->DeleteStates(((std::vector<int64>  const )__pyx_t_2)) != 0)) != 0);
     if (unlikely(__pyx_t_1)) {
 
-      /* "pywrapfst.pyx":2204
+      /* "pywrapfst.pyx":2237
  *     if states:
  *       if not self._mfst.get().DeleteStates(<const vector[int64]> states):
  *         raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     else:
  *       self._mfst.get().DeleteStates()
  */
-      __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2204, __pyx_L1_error)
+      __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2237, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_4);
       __pyx_t_5 = NULL;
       if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
@@ -24797,14 +24844,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_states(struct __pyx_obj_9pyw
       }
       __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_State_index_out_of_range);
       __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2204, __pyx_L1_error)
+      if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2237, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_Raise(__pyx_t_3, 0, 0, 0);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __PYX_ERR(0, 2204, __pyx_L1_error)
+      __PYX_ERR(0, 2237, __pyx_L1_error)
 
-      /* "pywrapfst.pyx":2203
+      /* "pywrapfst.pyx":2236
  *     # Only the former signature has a possible indexing failure.
  *     if states:
  *       if not self._mfst.get().DeleteStates(<const vector[int64]> states):             # <<<<<<<<<<<<<<
@@ -24813,7 +24860,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_states(struct __pyx_obj_9pyw
  */
     }
 
-    /* "pywrapfst.pyx":2202
+    /* "pywrapfst.pyx":2235
  *   cdef void _delete_states(self, states=None) except *:
  *     # Only the former signature has a possible indexing failure.
  *     if states:             # <<<<<<<<<<<<<<
@@ -24823,7 +24870,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_states(struct __pyx_obj_9pyw
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":2206
+  /* "pywrapfst.pyx":2239
  *         raise FstIndexError("State index out of range")
  *     else:
  *       self._mfst.get().DeleteStates()             # <<<<<<<<<<<<<<
@@ -24833,13 +24880,13 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_states(struct __pyx_obj_9pyw
   /*else*/ {
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 2206, __pyx_L1_error)
+      __PYX_ERR(0, 2239, __pyx_L1_error)
     }
     __pyx_v_self->_mfst.get()->DeleteStates();
   }
   __pyx_L3:;
 
-  /* "pywrapfst.pyx":2207
+  /* "pywrapfst.pyx":2240
  *     else:
  *       self._mfst.get().DeleteStates()
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -24848,11 +24895,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_states(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2207, __pyx_L1_error)
+    __PYX_ERR(0, 2240, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2207, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2240, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2200
+  /* "pywrapfst.pyx":2233
  *     return self
  * 
  *   cdef void _delete_states(self, states=None) except *:             # <<<<<<<<<<<<<<
@@ -24871,7 +24918,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__delete_states(struct __pyx_obj_9pyw
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2209
+/* "pywrapfst.pyx":2242
  *     self._check_mutating_imethod()
  * 
  *   def delete_states(self, states=None):             # <<<<<<<<<<<<<<
@@ -24884,6 +24931,9 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_19delete_states(PyObject *__py
 static char __pyx_doc_9pywrapfst_10MutableFst_18delete_states[] = "\n    delete_states(self, states=None)\n\n    Deletes states.\n\n    Args:\n      states: An optional iterable of integer indices of the states to be\n          deleted. If this argument is omitted, all states are deleted.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_19delete_states(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_states = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("delete_states (wrapper)", 0);
@@ -24909,7 +24959,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_19delete_states(PyObject *__py
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "delete_states") < 0)) __PYX_ERR(0, 2209, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "delete_states") < 0)) __PYX_ERR(0, 2242, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -24923,7 +24973,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_19delete_states(PyObject *__py
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("delete_states", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2209, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("delete_states", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2242, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.delete_states", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -24940,9 +24990,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_18delete_states(struct __pyx_o
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_10MutableFst__delete_states __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("delete_states", 0);
 
-  /* "pywrapfst.pyx":2225
+  /* "pywrapfst.pyx":2258
  *       FstIndexError: State index out of range.
  *     """
  *     self._delete_states(states)             # <<<<<<<<<<<<<<
@@ -24951,13 +25004,13 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_18delete_states(struct __pyx_o
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_delete_states");
-    __PYX_ERR(0, 2225, __pyx_L1_error)
+    __PYX_ERR(0, 2258, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 1;
   __pyx_t_1.states = __pyx_v_states;
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_delete_states(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2225, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_delete_states(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2258, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2226
+  /* "pywrapfst.pyx":2259
  *     """
  *     self._delete_states(states)
  *     return self             # <<<<<<<<<<<<<<
@@ -24969,7 +25022,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_18delete_states(struct __pyx_o
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2209
+  /* "pywrapfst.pyx":2242
  *     self._check_mutating_imethod()
  * 
  *   def delete_states(self, states=None):             # <<<<<<<<<<<<<<
@@ -24987,7 +25040,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_18delete_states(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2228
+/* "pywrapfst.pyx":2261
  *     return self
  * 
  *   cdef void _encode(self, EncodeMapper mapper) except *:             # <<<<<<<<<<<<<<
@@ -24997,9 +25050,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_18delete_states(struct __pyx_o
 
 static void __pyx_f_9pywrapfst_10MutableFst__encode(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper) {
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_encode", 0);
 
-  /* "pywrapfst.pyx":2229
+  /* "pywrapfst.pyx":2262
  * 
  *   cdef void _encode(self, EncodeMapper mapper) except *:
  *     fst.Encode(self._mfst.get(), mapper._mapper.get())             # <<<<<<<<<<<<<<
@@ -25008,15 +25064,15 @@ static void __pyx_f_9pywrapfst_10MutableFst__encode(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2229, __pyx_L1_error)
+    __PYX_ERR(0, 2262, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_mapper) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mapper");
-    __PYX_ERR(0, 2229, __pyx_L1_error)
+    __PYX_ERR(0, 2262, __pyx_L1_error)
   }
   fst::script::Encode(__pyx_v_self->_mfst.get(), __pyx_v_mapper->_mapper.get());
 
-  /* "pywrapfst.pyx":2230
+  /* "pywrapfst.pyx":2263
  *   cdef void _encode(self, EncodeMapper mapper) except *:
  *     fst.Encode(self._mfst.get(), mapper._mapper.get())
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -25025,11 +25081,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__encode(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2230, __pyx_L1_error)
+    __PYX_ERR(0, 2263, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2230, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2263, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2228
+  /* "pywrapfst.pyx":2261
  *     return self
  * 
  *   cdef void _encode(self, EncodeMapper mapper) except *:             # <<<<<<<<<<<<<<
@@ -25045,7 +25101,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__encode(struct __pyx_obj_9pywrapfst_
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2232
+/* "pywrapfst.pyx":2265
  *     self._check_mutating_imethod()
  * 
  *   def encode(self, EncodeMapper mapper):             # <<<<<<<<<<<<<<
@@ -25057,10 +25113,13 @@ static void __pyx_f_9pywrapfst_10MutableFst__encode(struct __pyx_obj_9pywrapfst_
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_21encode(PyObject *__pyx_v_self, PyObject *__pyx_v_mapper); /*proto*/
 static char __pyx_doc_9pywrapfst_10MutableFst_20encode[] = "\n    encode(self, mapper)\n\n    Encodes labels and/or weights.\n\n    This operation allows for the representation of a weighted transducer as a\n    weighted acceptor, an unweighted transducer, or an unweighted acceptor by\n    considering the pair (input label, output label), the pair (input label,\n    weight), or the triple (input label, output label, weight) as a single\n    label. Applying this operation mutates the EncodeMapper argument, which\n    can then be used to decode.\n\n    Args:\n      mapper: An EncodeMapper object to be used as the mapper.\n\n    Returns:\n      self.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_21encode(PyObject *__pyx_v_self, PyObject *__pyx_v_mapper) {
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("encode (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mapper), __pyx_ptype_9pywrapfst_EncodeMapper, 1, "mapper", 0))) __PYX_ERR(0, 2232, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mapper), __pyx_ptype_9pywrapfst_EncodeMapper, 1, "mapper", 0))) __PYX_ERR(0, 2265, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_20encode(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_EncodeMapper *)__pyx_v_mapper));
 
   /* function exit code */
@@ -25075,9 +25134,12 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_21encode(PyObject *__pyx_v_sel
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_20encode(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_EncodeMapper *__pyx_v_mapper) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("encode", 0);
 
-  /* "pywrapfst.pyx":2251
+  /* "pywrapfst.pyx":2284
  *       self.
  *     """
  *     self._encode(mapper)             # <<<<<<<<<<<<<<
@@ -25086,11 +25148,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_20encode(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_encode");
-    __PYX_ERR(0, 2251, __pyx_L1_error)
+    __PYX_ERR(0, 2284, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_encode(__pyx_v_self, __pyx_v_mapper); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2251, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_encode(__pyx_v_self, __pyx_v_mapper); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2284, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2252
+  /* "pywrapfst.pyx":2285
  *     """
  *     self._encode(mapper)
  *     return self             # <<<<<<<<<<<<<<
@@ -25102,7 +25164,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_20encode(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2232
+  /* "pywrapfst.pyx":2265
  *     self._check_mutating_imethod()
  * 
  *   def encode(self, EncodeMapper mapper):             # <<<<<<<<<<<<<<
@@ -25120,7 +25182,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_20encode(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2254
+/* "pywrapfst.pyx":2287
  *     return self
  * 
  *   cdef void _invert(self):             # <<<<<<<<<<<<<<
@@ -25130,9 +25192,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_20encode(struct __pyx_obj_9pyw
 
 static void __pyx_f_9pywrapfst_10MutableFst__invert(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self) {
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_invert", 0);
 
-  /* "pywrapfst.pyx":2255
+  /* "pywrapfst.pyx":2288
  * 
  *   cdef void _invert(self):
  *     fst.Invert(self._mfst.get())             # <<<<<<<<<<<<<<
@@ -25141,11 +25206,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__invert(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2255, __pyx_L1_error)
+    __PYX_ERR(0, 2288, __pyx_L1_error)
   }
   fst::script::Invert(__pyx_v_self->_mfst.get());
 
-  /* "pywrapfst.pyx":2254
+  /* "pywrapfst.pyx":2287
  *     return self
  * 
  *   cdef void _invert(self):             # <<<<<<<<<<<<<<
@@ -25161,7 +25226,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__invert(struct __pyx_obj_9pywrapfst_
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2257
+/* "pywrapfst.pyx":2290
  *     fst.Invert(self._mfst.get())
  * 
  *   def invert(self):             # <<<<<<<<<<<<<<
@@ -25186,9 +25251,12 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_23invert(PyObject *__pyx_v_sel
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_22invert(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("invert", 0);
 
-  /* "pywrapfst.pyx":2269
+  /* "pywrapfst.pyx":2302
  *       self.
  *     """
  *     self._invert()             # <<<<<<<<<<<<<<
@@ -25197,11 +25265,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_22invert(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_invert");
-    __PYX_ERR(0, 2269, __pyx_L1_error)
+    __PYX_ERR(0, 2302, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_invert(__pyx_v_self);
 
-  /* "pywrapfst.pyx":2270
+  /* "pywrapfst.pyx":2303
  *     """
  *     self._invert()
  *     return self             # <<<<<<<<<<<<<<
@@ -25213,7 +25281,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_22invert(struct __pyx_obj_9pyw
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2257
+  /* "pywrapfst.pyx":2290
  *     fst.Invert(self._mfst.get())
  * 
  *   def invert(self):             # <<<<<<<<<<<<<<
@@ -25231,7 +25299,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_22invert(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2272
+/* "pywrapfst.pyx":2305
  *     return self
  * 
  *   cdef void _minimize(self,             # <<<<<<<<<<<<<<
@@ -25240,9 +25308,9 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_22invert(struct __pyx_obj_9pyw
  */
 
 static void __pyx_f_9pywrapfst_10MutableFst__minimize(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__minimize *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__10;
+  float __pyx_v_delta = __pyx_k__12;
 
-  /* "pywrapfst.pyx":2274
+  /* "pywrapfst.pyx":2307
  *   cdef void _minimize(self,
  *                       float delta=fst.kShortestDelta,
  *                       bool allow_nondet=False) except *:             # <<<<<<<<<<<<<<
@@ -25251,6 +25319,9 @@ static void __pyx_f_9pywrapfst_10MutableFst__minimize(struct __pyx_obj_9pywrapfs
  */
   bool __pyx_v_allow_nondet = ((bool)0);
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_minimize", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -25261,7 +25332,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__minimize(struct __pyx_obj_9pywrapfs
     }
   }
 
-  /* "pywrapfst.pyx":2276
+  /* "pywrapfst.pyx":2309
  *                       bool allow_nondet=False) except *:
  *     # This runs in-place when the second argument is null.
  *     fst.Minimize(self._mfst.get(), NULL, delta, allow_nondet)             # <<<<<<<<<<<<<<
@@ -25270,11 +25341,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__minimize(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2276, __pyx_L1_error)
+    __PYX_ERR(0, 2309, __pyx_L1_error)
   }
   fst::script::Minimize(__pyx_v_self->_mfst.get(), NULL, __pyx_v_delta, __pyx_v_allow_nondet);
 
-  /* "pywrapfst.pyx":2277
+  /* "pywrapfst.pyx":2310
  *     # This runs in-place when the second argument is null.
  *     fst.Minimize(self._mfst.get(), NULL, delta, allow_nondet)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -25283,11 +25354,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__minimize(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2277, __pyx_L1_error)
+    __PYX_ERR(0, 2310, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2277, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2310, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2272
+  /* "pywrapfst.pyx":2305
  *     return self
  * 
  *   cdef void _minimize(self,             # <<<<<<<<<<<<<<
@@ -25303,7 +25374,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__minimize(struct __pyx_obj_9pywrapfs
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2279
+/* "pywrapfst.pyx":2312
  *     self._check_mutating_imethod()
  * 
  *   def minimize(self, float delta=fst.kShortestDelta, bool allow_nondet=False):             # <<<<<<<<<<<<<<
@@ -25317,6 +25388,9 @@ static char __pyx_doc_9pywrapfst_10MutableFst_24minimize[] = "\n    minimize(sel
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_25minimize(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   float __pyx_v_delta;
   bool __pyx_v_allow_nondet;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("minimize (wrapper)", 0);
@@ -25349,7 +25423,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_25minimize(PyObject *__pyx_v_s
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "minimize") < 0)) __PYX_ERR(0, 2279, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "minimize") < 0)) __PYX_ERR(0, 2312, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -25362,19 +25436,19 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_25minimize(PyObject *__pyx_v_s
       }
     }
     if (values[0]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2279, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2312, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__11;
+      __pyx_v_delta = __pyx_k__13;
     }
     if (values[1]) {
-      __pyx_v_allow_nondet = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_allow_nondet == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2279, __pyx_L3_error)
+      __pyx_v_allow_nondet = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_allow_nondet == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2312, __pyx_L3_error)
     } else {
       __pyx_v_allow_nondet = ((bool)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("minimize", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2279, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("minimize", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2312, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.minimize", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -25391,9 +25465,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_24minimize(struct __pyx_obj_9p
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_10MutableFst__minimize __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("minimize", 0);
 
-  /* "pywrapfst.pyx":2305
+  /* "pywrapfst.pyx":2338
  *       self.
  *     """
  *     self._minimize(delta, allow_nondet)             # <<<<<<<<<<<<<<
@@ -25402,14 +25479,14 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_24minimize(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_minimize");
-    __PYX_ERR(0, 2305, __pyx_L1_error)
+    __PYX_ERR(0, 2338, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 2;
   __pyx_t_1.delta = __pyx_v_delta;
   __pyx_t_1.allow_nondet = __pyx_v_allow_nondet;
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_minimize(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2305, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_minimize(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2338, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2306
+  /* "pywrapfst.pyx":2339
  *     """
  *     self._minimize(delta, allow_nondet)
  *     return self             # <<<<<<<<<<<<<<
@@ -25421,7 +25498,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_24minimize(struct __pyx_obj_9p
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2279
+  /* "pywrapfst.pyx":2312
  *     self._check_mutating_imethod()
  * 
  *   def minimize(self, float delta=fst.kShortestDelta, bool allow_nondet=False):             # <<<<<<<<<<<<<<
@@ -25439,7 +25516,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_24minimize(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2308
+/* "pywrapfst.pyx":2341
  *     return self
  * 
  *   cpdef MutableArcIterator mutable_arcs(self, int64 state):             # <<<<<<<<<<<<<<
@@ -25456,6 +25533,9 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_10Muta
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("mutable_arcs", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -25466,11 +25546,11 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_10Muta
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_mutable_arcs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2308, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_mutable_arcs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2341, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_10MutableFst_27mutable_arcs)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
-        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2308, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2341, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -25486,10 +25566,10 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_10Muta
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2308, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2341, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_MutableArcIterator))))) __PYX_ERR(0, 2308, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_MutableArcIterator))))) __PYX_ERR(0, 2341, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -25508,7 +25588,7 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_10Muta
     #endif
   }
 
-  /* "pywrapfst.pyx":2320
+  /* "pywrapfst.pyx":2353
  *       A MutableArcIterator.
  *     """
  *     return MutableArcIterator(self, state)             # <<<<<<<<<<<<<<
@@ -25516,9 +25596,9 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_10Muta
  *   def mutable_input_symbols(self):
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2320, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_state); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2353, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2320, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2353, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
@@ -25526,14 +25606,14 @@ static struct __pyx_obj_9pywrapfst_MutableArcIterator *__pyx_f_9pywrapfst_10Muta
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_1);
   __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_MutableArcIterator), __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2320, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_MutableArcIterator), __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2353, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2308
+  /* "pywrapfst.pyx":2341
  *     return self
  * 
  *   cpdef MutableArcIterator mutable_arcs(self, int64 state):             # <<<<<<<<<<<<<<
@@ -25561,11 +25641,14 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_27mutable_arcs(PyObject *__pyx
 static char __pyx_doc_9pywrapfst_10MutableFst_26mutable_arcs[] = "\n    mutable_arcs(self, state)\n\n    Returns a mutable iterator over arcs leaving the specified state.\n\n    Args:\n      state: The source state ID.\n\n    Returns:\n      A MutableArcIterator.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_27mutable_arcs(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
   int64 __pyx_v_state;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("mutable_arcs (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2308, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2341, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -25584,9 +25667,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_26mutable_arcs(struct __pyx_ob
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("mutable_arcs", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_10MutableFst_mutable_arcs(__pyx_v_self, __pyx_v_state, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2308, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_10MutableFst_mutable_arcs(__pyx_v_self, __pyx_v_state, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2341, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -25603,7 +25689,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_26mutable_arcs(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2322
+/* "pywrapfst.pyx":2355
  *     return MutableArcIterator(self, state)
  * 
  *   def mutable_input_symbols(self):             # <<<<<<<<<<<<<<
@@ -25626,39 +25712,32 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_29mutable_input_symbols(PyObje
 }
 
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_28mutable_input_symbols(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self) {
-  fst::SymbolTable *__pyx_v_syms;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("mutable_input_symbols", 0);
 
-  /* "pywrapfst.pyx":2328
+  /* "pywrapfst.pyx":2361
  *     Returns the FST's (mutable) input symbol table, or None if none is present.
  *     """
- *     cdef fst.SymbolTable *syms = self._mfst.get().MutableInputSymbols()             # <<<<<<<<<<<<<<
- *     if syms == NULL:
+ *     if self._mfst.get().MutableInputSymbols() == NULL:             # <<<<<<<<<<<<<<
  *       return
+ *     return _init_MutableFstSymbolTableView(self._mfst, input_side=True)
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2328, __pyx_L1_error)
+    __PYX_ERR(0, 2361, __pyx_L1_error)
   }
-  __pyx_v_syms = __pyx_v_self->_mfst.get()->MutableInputSymbols();
-
-  /* "pywrapfst.pyx":2329
- *     """
- *     cdef fst.SymbolTable *syms = self._mfst.get().MutableInputSymbols()
- *     if syms == NULL:             # <<<<<<<<<<<<<<
- *       return
- *     return _init_MutableFstSymbolTableView(self._mfst, input_side=True)
- */
-  __pyx_t_1 = ((__pyx_v_syms == NULL) != 0);
+  __pyx_t_1 = ((__pyx_v_self->_mfst.get()->MutableInputSymbols() == NULL) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2330
- *     cdef fst.SymbolTable *syms = self._mfst.get().MutableInputSymbols()
- *     if syms == NULL:
+    /* "pywrapfst.pyx":2362
+ *     """
+ *     if self._mfst.get().MutableInputSymbols() == NULL:
  *       return             # <<<<<<<<<<<<<<
  *     return _init_MutableFstSymbolTableView(self._mfst, input_side=True)
  * 
@@ -25667,17 +25746,17 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_28mutable_input_symbols(struct
     __pyx_r = Py_None; __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2329
+    /* "pywrapfst.pyx":2361
+ *     Returns the FST's (mutable) input symbol table, or None if none is present.
  *     """
- *     cdef fst.SymbolTable *syms = self._mfst.get().MutableInputSymbols()
- *     if syms == NULL:             # <<<<<<<<<<<<<<
+ *     if self._mfst.get().MutableInputSymbols() == NULL:             # <<<<<<<<<<<<<<
  *       return
  *     return _init_MutableFstSymbolTableView(self._mfst, input_side=True)
  */
   }
 
-  /* "pywrapfst.pyx":2331
- *     if syms == NULL:
+  /* "pywrapfst.pyx":2363
+ *     if self._mfst.get().MutableInputSymbols() == NULL:
  *       return
  *     return _init_MutableFstSymbolTableView(self._mfst, input_side=True)             # <<<<<<<<<<<<<<
  * 
@@ -25686,15 +25765,15 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_28mutable_input_symbols(struct
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2331, __pyx_L1_error)
+    __PYX_ERR(0, 2363, __pyx_L1_error)
   }
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTableView(__pyx_v_self->_mfst, 1)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2331, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTableView(__pyx_v_self->_mfst, 1)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2363, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2322
+  /* "pywrapfst.pyx":2355
  *     return MutableArcIterator(self, state)
  * 
  *   def mutable_input_symbols(self):             # <<<<<<<<<<<<<<
@@ -25713,7 +25792,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_28mutable_input_symbols(struct
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2333
+/* "pywrapfst.pyx":2365
  *     return _init_MutableFstSymbolTableView(self._mfst, input_side=True)
  * 
  *   def mutable_output_symbols(self):             # <<<<<<<<<<<<<<
@@ -25736,39 +25815,32 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_31mutable_output_symbols(PyObj
 }
 
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_30mutable_output_symbols(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self) {
-  __pyx_t_9pywrapfst_SymbolTable_ptr __pyx_v_syms;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("mutable_output_symbols", 0);
 
-  /* "pywrapfst.pyx":2339
+  /* "pywrapfst.pyx":2371
  *     Returns the FST's (mutable) output symbol table, or None if none is present.
  *     """
- *     cdef SymbolTable_ptr syms = self._mfst.get().MutableOutputSymbols()             # <<<<<<<<<<<<<<
- *     if syms == NULL:
+ *     if self._mfst.get().MutableOutputSymbols() == NULL:             # <<<<<<<<<<<<<<
  *       return
+ *     return _init_MutableFstSymbolTableView(self._mfst, input_side=False)
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2339, __pyx_L1_error)
+    __PYX_ERR(0, 2371, __pyx_L1_error)
   }
-  __pyx_v_syms = __pyx_v_self->_mfst.get()->MutableOutputSymbols();
-
-  /* "pywrapfst.pyx":2340
- *     """
- *     cdef SymbolTable_ptr syms = self._mfst.get().MutableOutputSymbols()
- *     if syms == NULL:             # <<<<<<<<<<<<<<
- *       return
- *     return _init_MutableFstSymbolTableView(self._mfst, input_side=False)
- */
-  __pyx_t_1 = ((__pyx_v_syms == NULL) != 0);
+  __pyx_t_1 = ((__pyx_v_self->_mfst.get()->MutableOutputSymbols() == NULL) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2341
- *     cdef SymbolTable_ptr syms = self._mfst.get().MutableOutputSymbols()
- *     if syms == NULL:
+    /* "pywrapfst.pyx":2372
+ *     """
+ *     if self._mfst.get().MutableOutputSymbols() == NULL:
  *       return             # <<<<<<<<<<<<<<
  *     return _init_MutableFstSymbolTableView(self._mfst, input_side=False)
  * 
@@ -25777,17 +25849,17 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_30mutable_output_symbols(struc
     __pyx_r = Py_None; __Pyx_INCREF(Py_None);
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2340
+    /* "pywrapfst.pyx":2371
+ *     Returns the FST's (mutable) output symbol table, or None if none is present.
  *     """
- *     cdef SymbolTable_ptr syms = self._mfst.get().MutableOutputSymbols()
- *     if syms == NULL:             # <<<<<<<<<<<<<<
+ *     if self._mfst.get().MutableOutputSymbols() == NULL:             # <<<<<<<<<<<<<<
  *       return
  *     return _init_MutableFstSymbolTableView(self._mfst, input_side=False)
  */
   }
 
-  /* "pywrapfst.pyx":2342
- *     if syms == NULL:
+  /* "pywrapfst.pyx":2373
+ *     if self._mfst.get().MutableOutputSymbols() == NULL:
  *       return
  *     return _init_MutableFstSymbolTableView(self._mfst, input_side=False)             # <<<<<<<<<<<<<<
  * 
@@ -25796,15 +25868,15 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_30mutable_output_symbols(struc
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2342, __pyx_L1_error)
+    __PYX_ERR(0, 2373, __pyx_L1_error)
   }
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTableView(__pyx_v_self->_mfst, 0)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2342, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFstSymbolTableView(__pyx_v_self->_mfst, 0)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2373, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2333
+  /* "pywrapfst.pyx":2365
  *     return _init_MutableFstSymbolTableView(self._mfst, input_side=True)
  * 
  *   def mutable_output_symbols(self):             # <<<<<<<<<<<<<<
@@ -25823,7 +25895,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_30mutable_output_symbols(struc
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2344
+/* "pywrapfst.pyx":2375
  *     return _init_MutableFstSymbolTableView(self._mfst, input_side=False)
  * 
  *   cpdef int64 num_states(self):             # <<<<<<<<<<<<<<
@@ -25840,6 +25912,9 @@ static int64 __pyx_f_9pywrapfst_10MutableFst_num_states(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   int64 __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("num_states", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -25850,7 +25925,7 @@ static int64 __pyx_f_9pywrapfst_10MutableFst_num_states(struct __pyx_obj_9pywrap
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2344, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_num_states); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2375, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_10MutableFst_33num_states)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -25866,10 +25941,10 @@ static int64 __pyx_f_9pywrapfst_10MutableFst_num_states(struct __pyx_obj_9pywrap
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2344, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2375, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2344, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2375, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -25888,21 +25963,21 @@ static int64 __pyx_f_9pywrapfst_10MutableFst_num_states(struct __pyx_obj_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":2350
+  /* "pywrapfst.pyx":2381
  *     Returns the number of states.
  *     """
  *     return self._mfst.get().NumStates()             # <<<<<<<<<<<<<<
  * 
- *   cdef void _project(self, bool project_output=False) except *:
+ *   cdef void _project(self, project_type) except *:
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2350, __pyx_L1_error)
+    __PYX_ERR(0, 2381, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_mfst.get()->NumStates();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2344
+  /* "pywrapfst.pyx":2375
  *     return _init_MutableFstSymbolTableView(self._mfst, input_side=False)
  * 
  *   cpdef int64 num_states(self):             # <<<<<<<<<<<<<<
@@ -25941,9 +26016,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_32num_states(struct __pyx_obj_
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("num_states", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_10MutableFst_num_states(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2344, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_10MutableFst_num_states(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2375, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -25960,42 +26038,43 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_32num_states(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2352
+/* "pywrapfst.pyx":2383
  *     return self._mfst.get().NumStates()
  * 
- *   cdef void _project(self, bool project_output=False) except *:             # <<<<<<<<<<<<<<
- *     fst.Project(self._mfst.get(), fst.GetProjectType(project_output))
+ *   cdef void _project(self, project_type) except *:             # <<<<<<<<<<<<<<
+ *     fst.Project(self._mfst.get(), _get_project_type(tostring(project_type)))
  * 
  */
 
-static void __pyx_f_9pywrapfst_10MutableFst__project(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__project *__pyx_optional_args) {
-  bool __pyx_v_project_output = ((bool)0);
+static void __pyx_f_9pywrapfst_10MutableFst__project(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, PyObject *__pyx_v_project_type) {
   __Pyx_RefNannyDeclarations
+  std::string __pyx_t_1;
+  fst::ProjectType __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_project", 0);
-  if (__pyx_optional_args) {
-    if (__pyx_optional_args->__pyx_n > 0) {
-      __pyx_v_project_output = __pyx_optional_args->project_output;
-    }
-  }
 
-  /* "pywrapfst.pyx":2353
+  /* "pywrapfst.pyx":2384
  * 
- *   cdef void _project(self, bool project_output=False) except *:
- *     fst.Project(self._mfst.get(), fst.GetProjectType(project_output))             # <<<<<<<<<<<<<<
+ *   cdef void _project(self, project_type) except *:
+ *     fst.Project(self._mfst.get(), _get_project_type(tostring(project_type)))             # <<<<<<<<<<<<<<
  * 
- *   def project(self, bool project_output=False):
+ *   def project(self, project_type):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2353, __pyx_L1_error)
+    __PYX_ERR(0, 2384, __pyx_L1_error)
   }
-  fst::script::Project(__pyx_v_self->_mfst.get(), fst::script::GetProjectType(__pyx_v_project_output));
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_project_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2384, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_project_type(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2384, __pyx_L1_error)
+  fst::script::Project(__pyx_v_self->_mfst.get(), __pyx_t_2);
 
-  /* "pywrapfst.pyx":2352
+  /* "pywrapfst.pyx":2383
  *     return self._mfst.get().NumStates()
  * 
- *   cdef void _project(self, bool project_output=False) except *:             # <<<<<<<<<<<<<<
- *     fst.Project(self._mfst.get(), fst.GetProjectType(project_output))
+ *   cdef void _project(self, project_type) except *:             # <<<<<<<<<<<<<<
+ *     fst.Project(self._mfst.get(), _get_project_type(tostring(project_type)))
  * 
  */
 
@@ -26007,98 +26086,52 @@ static void __pyx_f_9pywrapfst_10MutableFst__project(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2355
- *     fst.Project(self._mfst.get(), fst.GetProjectType(project_output))
+/* "pywrapfst.pyx":2386
+ *     fst.Project(self._mfst.get(), _get_project_type(tostring(project_type)))
  * 
- *   def project(self, bool project_output=False):             # <<<<<<<<<<<<<<
+ *   def project(self, project_type):             # <<<<<<<<<<<<<<
  *     """
- *     project(self, project_output=False)
+ *     project(self, project_type)
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_10MutableFst_35project(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_10MutableFst_34project[] = "\n    project(self, project_output=False)\n\n    Converts the FST to an acceptor using input or output labels.\n\n    This operation destructively projects an FST onto its domain or range by\n    either copying each arc's input label to its output label (the default) or\n    vice versa.\n\n    Args:\n      project_output: Should the output labels be projected?\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_10MutableFst_35project(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  bool __pyx_v_project_output;
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_35project(PyObject *__pyx_v_self, PyObject *__pyx_v_project_type); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_34project[] = "\n    project(self, project_type)\n\n    Converts the FST to an acceptor using input or output labels.\n\n    This operation destructively projects an FST onto its domain or range by\n    either copying each arc's input label to its output label (the default) or\n    vice versa.\n\n    Args:\n      project_type: A string matching a known projection type; one of:\n          \"input\", \"output\".\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_35project(PyObject *__pyx_v_self, PyObject *__pyx_v_project_type) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("project (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_project_output,0};
-    PyObject* values[1] = {0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        CYTHON_FALLTHROUGH;
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (kw_args > 0) {
-          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_project_output);
-          if (value) { values[0] = value; kw_args--; }
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "project") < 0)) __PYX_ERR(0, 2355, __pyx_L3_error)
-      }
-    } else {
-      switch (PyTuple_GET_SIZE(__pyx_args)) {
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        CYTHON_FALLTHROUGH;
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-    }
-    if (values[0]) {
-      __pyx_v_project_output = __Pyx_PyObject_IsTrue(values[0]); if (unlikely((__pyx_v_project_output == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2355, __pyx_L3_error)
-    } else {
-      __pyx_v_project_output = ((bool)0);
-    }
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("project", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2355, __pyx_L3_error)
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("pywrapfst.MutableFst.project", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_34project(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_project_output);
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_34project(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), ((PyObject *)__pyx_v_project_type));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_10MutableFst_34project(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, bool __pyx_v_project_output) {
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_34project(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, PyObject *__pyx_v_project_type) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  struct __pyx_opt_args_9pywrapfst_10MutableFst__project __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("project", 0);
 
-  /* "pywrapfst.pyx":2371
+  /* "pywrapfst.pyx":2403
  *       self.
  *     """
- *     self._project(project_output)             # <<<<<<<<<<<<<<
+ *     self._project(project_type)             # <<<<<<<<<<<<<<
  *     return self
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_project");
-    __PYX_ERR(0, 2371, __pyx_L1_error)
+    __PYX_ERR(0, 2403, __pyx_L1_error)
   }
-  __pyx_t_1.__pyx_n = 1;
-  __pyx_t_1.project_output = __pyx_v_project_output;
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_project(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2371, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_project(__pyx_v_self, __pyx_v_project_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2403, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2372
+  /* "pywrapfst.pyx":2404
  *     """
- *     self._project(project_output)
+ *     self._project(project_type)
  *     return self             # <<<<<<<<<<<<<<
  * 
  *   cdef void _prune(self,
@@ -26108,12 +26141,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_34project(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2355
- *     fst.Project(self._mfst.get(), fst.GetProjectType(project_output))
+  /* "pywrapfst.pyx":2386
+ *     fst.Project(self._mfst.get(), _get_project_type(tostring(project_type)))
  * 
- *   def project(self, bool project_output=False):             # <<<<<<<<<<<<<<
+ *   def project(self, project_type):             # <<<<<<<<<<<<<<
  *     """
- *     project(self, project_output=False)
+ *     project(self, project_type)
  */
 
   /* function exit code */
@@ -26126,7 +26159,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_34project(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2374
+/* "pywrapfst.pyx":2406
  *     return self
  * 
  *   cdef void _prune(self,             # <<<<<<<<<<<<<<
@@ -26135,20 +26168,23 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_34project(struct __pyx_obj_9py
  */
 
 static void __pyx_f_9pywrapfst_10MutableFst__prune(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__prune *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__12;
-  int64 __pyx_v_nstate = __pyx_k__13;
+  float __pyx_v_delta = __pyx_k__14;
+  int64 __pyx_v_nstate = __pyx_k__15;
 
-  /* "pywrapfst.pyx":2377
+  /* "pywrapfst.pyx":2409
  *                    float delta=fst.kDelta,
  *                    int64 nstate=fst.kNoStateId,
  *                    weight=None) except *:             # <<<<<<<<<<<<<<
  *     # Threshold is set to semiring Zero (no pruning) if no weight is specified.
- *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),
+ *     cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(self.weight_type(),
  */
   PyObject *__pyx_v_weight = ((PyObject *)Py_None);
-  fst::script::WeightClass __pyx_v_wc;
+  fst::script::WeightClass __pyx_v__weight;
   __Pyx_RefNannyDeclarations
   fst::script::WeightClass __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_prune", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -26162,55 +26198,55 @@ static void __pyx_f_9pywrapfst_10MutableFst__prune(struct __pyx_obj_9pywrapfst_M
     }
   }
 
-  /* "pywrapfst.pyx":2379
+  /* "pywrapfst.pyx":2411
  *                    weight=None) except *:
  *     # Threshold is set to semiring Zero (no pruning) if no weight is specified.
- *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),             # <<<<<<<<<<<<<<
- *                                                        weight)
- *     fst.Prune(self._mfst.get(), wc, nstate, delta)
+ *     cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(self.weight_type(),             # <<<<<<<<<<<<<<
+ *                                                             weight)
+ *     fst.Prune(self._mfst.get(), _weight, nstate, delta)
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 2379, __pyx_L1_error)
+    __PYX_ERR(0, 2411, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2380
+  /* "pywrapfst.pyx":2412
  *     # Threshold is set to semiring Zero (no pruning) if no weight is specified.
- *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),
- *                                                        weight)             # <<<<<<<<<<<<<<
- *     fst.Prune(self._mfst.get(), wc, nstate, delta)
+ *     cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(self.weight_type(),
+ *                                                             weight)             # <<<<<<<<<<<<<<
+ *     fst.Prune(self._mfst.get(), _weight, nstate, delta)
  *     self._check_mutating_imethod()
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_Zero(((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.weight_type(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2379, __pyx_L1_error)
-  __pyx_v_wc = __pyx_t_1;
+  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_Zero(((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.weight_type(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2411, __pyx_L1_error)
+  __pyx_v__weight = __pyx_t_1;
 
-  /* "pywrapfst.pyx":2381
- *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),
- *                                                        weight)
- *     fst.Prune(self._mfst.get(), wc, nstate, delta)             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":2413
+ *     cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(self.weight_type(),
+ *                                                             weight)
+ *     fst.Prune(self._mfst.get(), _weight, nstate, delta)             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2381, __pyx_L1_error)
+    __PYX_ERR(0, 2413, __pyx_L1_error)
   }
-  fst::script::Prune(__pyx_v_self->_mfst.get(), __pyx_v_wc, __pyx_v_nstate, __pyx_v_delta);
+  fst::script::Prune(__pyx_v_self->_mfst.get(), __pyx_v__weight, __pyx_v_nstate, __pyx_v_delta);
 
-  /* "pywrapfst.pyx":2382
- *                                                        weight)
- *     fst.Prune(self._mfst.get(), wc, nstate, delta)
+  /* "pywrapfst.pyx":2414
+ *                                                             weight)
+ *     fst.Prune(self._mfst.get(), _weight, nstate, delta)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
  * 
  *   def prune(self,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2382, __pyx_L1_error)
+    __PYX_ERR(0, 2414, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2382, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2414, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2374
+  /* "pywrapfst.pyx":2406
  *     return self
  * 
  *   cdef void _prune(self,             # <<<<<<<<<<<<<<
@@ -26226,7 +26262,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__prune(struct __pyx_obj_9pywrapfst_M
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2384
+/* "pywrapfst.pyx":2416
  *     self._check_mutating_imethod()
  * 
  *   def prune(self,             # <<<<<<<<<<<<<<
@@ -26241,6 +26277,9 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_37prune(PyObject *__pyx_v_self
   float __pyx_v_delta;
   int64 __pyx_v_nstate;
   PyObject *__pyx_v_weight = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("prune (wrapper)", 0);
@@ -26248,7 +26287,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_37prune(PyObject *__pyx_v_self
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_delta,&__pyx_n_s_nstate,&__pyx_n_s_weight,0};
     PyObject* values[3] = {0,0,0};
 
-    /* "pywrapfst.pyx":2387
+    /* "pywrapfst.pyx":2419
  *             float delta=fst.kDelta,
  *             int64 nstate=fst.kNoStateId,
  *             weight=None):             # <<<<<<<<<<<<<<
@@ -26290,7 +26329,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_37prune(PyObject *__pyx_v_self
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "prune") < 0)) __PYX_ERR(0, 2384, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "prune") < 0)) __PYX_ERR(0, 2416, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -26305,20 +26344,20 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_37prune(PyObject *__pyx_v_self
       }
     }
     if (values[0]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2385, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2417, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__14;
+      __pyx_v_delta = __pyx_k__16;
     }
     if (values[1]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2386, __pyx_L3_error)
+      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2418, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__15;
+      __pyx_v_nstate = __pyx_k__17;
     }
     __pyx_v_weight = values[2];
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("prune", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2384, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("prune", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2416, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.prune", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -26326,7 +26365,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_37prune(PyObject *__pyx_v_self
   __pyx_L4_argument_unpacking_done:;
   __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_36prune(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_delta, __pyx_v_nstate, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":2384
+  /* "pywrapfst.pyx":2416
  *     self._check_mutating_imethod()
  * 
  *   def prune(self,             # <<<<<<<<<<<<<<
@@ -26343,9 +26382,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_36prune(struct __pyx_obj_9pywr
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_10MutableFst__prune __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("prune", 0);
 
-  /* "pywrapfst.pyx":2407
+  /* "pywrapfst.pyx":2439
  *       self.
  *     """
  *     self._prune(delta, nstate, weight)             # <<<<<<<<<<<<<<
@@ -26354,15 +26396,15 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_36prune(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_prune");
-    __PYX_ERR(0, 2407, __pyx_L1_error)
+    __PYX_ERR(0, 2439, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 3;
   __pyx_t_1.delta = __pyx_v_delta;
   __pyx_t_1.nstate = __pyx_v_nstate;
   __pyx_t_1.weight = __pyx_v_weight;
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_prune(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2407, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_prune(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2439, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2408
+  /* "pywrapfst.pyx":2440
  *     """
  *     self._prune(delta, nstate, weight)
  *     return self             # <<<<<<<<<<<<<<
@@ -26374,7 +26416,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_36prune(struct __pyx_obj_9pywr
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2384
+  /* "pywrapfst.pyx":2416
  *     self._check_mutating_imethod()
  * 
  *   def prune(self,             # <<<<<<<<<<<<<<
@@ -26392,7 +26434,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_36prune(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2410
+/* "pywrapfst.pyx":2442
  *     return self
  * 
  *   cdef void _push(self,             # <<<<<<<<<<<<<<
@@ -26401,26 +26443,29 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_36prune(struct __pyx_obj_9pywr
  */
 
 static void __pyx_f_9pywrapfst_10MutableFst__push(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__push *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__16;
+  float __pyx_v_delta = __pyx_k__18;
 
-  /* "pywrapfst.pyx":2412
+  /* "pywrapfst.pyx":2444
  *   cdef void _push(self,
  *                   float delta=fst.kShortestDelta,
  *                   bool remove_total_weight=False,             # <<<<<<<<<<<<<<
  *                   bool to_final=False):
- *     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,
+ *     fst.Push(self._mfst.get(),
  */
   bool __pyx_v_remove_total_weight = ((bool)0);
 
-  /* "pywrapfst.pyx":2413
+  /* "pywrapfst.pyx":2445
  *                   float delta=fst.kShortestDelta,
  *                   bool remove_total_weight=False,
  *                   bool to_final=False):             # <<<<<<<<<<<<<<
- *     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,
- *              remove_total_weight)
+ *     fst.Push(self._mfst.get(),
+ *              fst.GetReweightType(to_final),
  */
   bool __pyx_v_to_final = ((bool)0);
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_push", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -26434,28 +26479,28 @@ static void __pyx_f_9pywrapfst_10MutableFst__push(struct __pyx_obj_9pywrapfst_Mu
     }
   }
 
-  /* "pywrapfst.pyx":2414
+  /* "pywrapfst.pyx":2446
  *                   bool remove_total_weight=False,
  *                   bool to_final=False):
- *     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,             # <<<<<<<<<<<<<<
- *              remove_total_weight)
- * 
+ *     fst.Push(self._mfst.get(),             # <<<<<<<<<<<<<<
+ *              fst.GetReweightType(to_final),
+ *              delta,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2414, __pyx_L1_error)
+    __PYX_ERR(0, 2446, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2415
- *                   bool to_final=False):
- *     fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,
+  /* "pywrapfst.pyx":2449
+ *              fst.GetReweightType(to_final),
+ *              delta,
  *              remove_total_weight)             # <<<<<<<<<<<<<<
  * 
  *   def push(self,
  */
   fst::script::Push(__pyx_v_self->_mfst.get(), fst::script::GetReweightType(__pyx_v_to_final), __pyx_v_delta, __pyx_v_remove_total_weight);
 
-  /* "pywrapfst.pyx":2410
+  /* "pywrapfst.pyx":2442
  *     return self
  * 
  *   cdef void _push(self,             # <<<<<<<<<<<<<<
@@ -26471,7 +26516,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__push(struct __pyx_obj_9pywrapfst_Mu
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2417
+/* "pywrapfst.pyx":2451
  *              remove_total_weight)
  * 
  *   def push(self,             # <<<<<<<<<<<<<<
@@ -26486,6 +26531,9 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_39push(PyObject *__pyx_v_self,
   float __pyx_v_delta;
   bool __pyx_v_remove_total_weight;
   bool __pyx_v_to_final;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("push (wrapper)", 0);
@@ -26526,7 +26574,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_39push(PyObject *__pyx_v_self,
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "push") < 0)) __PYX_ERR(0, 2417, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "push") < 0)) __PYX_ERR(0, 2451, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -26541,15 +26589,15 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_39push(PyObject *__pyx_v_self,
       }
     }
     if (values[0]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2418, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[0]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2452, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__17;
+      __pyx_v_delta = __pyx_k__19;
     }
     if (values[1]) {
-      __pyx_v_remove_total_weight = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_remove_total_weight == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2419, __pyx_L3_error)
+      __pyx_v_remove_total_weight = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_remove_total_weight == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2453, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2419
+      /* "pywrapfst.pyx":2453
  *   def push(self,
  *            float delta=fst.kShortestDelta,
  *            bool remove_total_weight=False,             # <<<<<<<<<<<<<<
@@ -26559,10 +26607,10 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_39push(PyObject *__pyx_v_self,
       __pyx_v_remove_total_weight = ((bool)0);
     }
     if (values[2]) {
-      __pyx_v_to_final = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_to_final == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2420, __pyx_L3_error)
+      __pyx_v_to_final = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_to_final == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2454, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2420
+      /* "pywrapfst.pyx":2454
  *            float delta=fst.kShortestDelta,
  *            bool remove_total_weight=False,
  *            bool to_final=False):             # <<<<<<<<<<<<<<
@@ -26574,7 +26622,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_39push(PyObject *__pyx_v_self,
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("push", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2417, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("push", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2451, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.push", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -26582,7 +26630,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_39push(PyObject *__pyx_v_self,
   __pyx_L4_argument_unpacking_done:;
   __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_38push(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_delta, __pyx_v_remove_total_weight, __pyx_v_to_final);
 
-  /* "pywrapfst.pyx":2417
+  /* "pywrapfst.pyx":2451
  *              remove_total_weight)
  * 
  *   def push(self,             # <<<<<<<<<<<<<<
@@ -26599,9 +26647,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_38push(struct __pyx_obj_9pywra
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_10MutableFst__push __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("push", 0);
 
-  /* "pywrapfst.pyx":2444
+  /* "pywrapfst.pyx":2478
  *       self.
  *     """
  *     self._push(delta, remove_total_weight, to_final)             # <<<<<<<<<<<<<<
@@ -26610,7 +26661,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_38push(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_push");
-    __PYX_ERR(0, 2444, __pyx_L1_error)
+    __PYX_ERR(0, 2478, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 3;
   __pyx_t_1.delta = __pyx_v_delta;
@@ -26618,7 +26669,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_38push(struct __pyx_obj_9pywra
   __pyx_t_1.to_final = __pyx_v_to_final;
   ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_push(__pyx_v_self, &__pyx_t_1); 
 
-  /* "pywrapfst.pyx":2445
+  /* "pywrapfst.pyx":2479
  *     """
  *     self._push(delta, remove_total_weight, to_final)
  *     return self             # <<<<<<<<<<<<<<
@@ -26630,7 +26681,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_38push(struct __pyx_obj_9pywra
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2417
+  /* "pywrapfst.pyx":2451
  *              remove_total_weight)
  * 
  *   def push(self,             # <<<<<<<<<<<<<<
@@ -26648,36 +26699,38 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_38push(struct __pyx_obj_9pywra
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2447
+/* "pywrapfst.pyx":2481
  *     return self
  * 
  *   cdef void _relabel_pairs(self, ipairs=None, opairs=None) except *:             # <<<<<<<<<<<<<<
- *     cdef unique_ptr[vector[fst.LabelPair]] _ipairs
- *     _ipairs.reset(new vector[fst.LabelPair]())
+ *     cdef vector[fst.LabelPair] _ipairs
+ *     cdef vector[fst.LabelPair] _opairs
  */
 
 static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__relabel_pairs *__pyx_optional_args) {
   PyObject *__pyx_v_ipairs = ((PyObject *)Py_None);
   PyObject *__pyx_v_opairs = ((PyObject *)Py_None);
-  std::unique_ptr<std::vector<__pyx_t_10cpywrapfst_LabelPair> >  __pyx_v__ipairs;
-  std::unique_ptr<std::vector<__pyx_t_10cpywrapfst_LabelPair> >  __pyx_v__opairs;
-  int64 __pyx_v_before;
-  int64 __pyx_v_after;
+  std::vector<__pyx_t_10cpywrapfst_LabelPair>  __pyx_v__ipairs;
+  std::vector<__pyx_t_10cpywrapfst_LabelPair>  __pyx_v__opairs;
+  PyObject *__pyx_v_before = NULL;
+  PyObject *__pyx_v_after = NULL;
   __Pyx_RefNannyDeclarations
-  std::vector<__pyx_t_10cpywrapfst_LabelPair>  *__pyx_t_1;
-  int __pyx_t_2;
-  PyObject *__pyx_t_3 = NULL;
-  Py_ssize_t __pyx_t_4;
-  PyObject *(*__pyx_t_5)(PyObject *);
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  Py_ssize_t __pyx_t_3;
+  PyObject *(*__pyx_t_4)(PyObject *);
+  PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
   PyObject *__pyx_t_7 = NULL;
   PyObject *__pyx_t_8 = NULL;
-  PyObject *__pyx_t_9 = NULL;
-  PyObject *(*__pyx_t_10)(PyObject *);
+  PyObject *(*__pyx_t_9)(PyObject *);
+  int64 __pyx_t_10;
   int64 __pyx_t_11;
-  int64 __pyx_t_12;
-  __pyx_t_10cpywrapfst_LabelPair __pyx_t_13;
-  int __pyx_t_14;
+  __pyx_t_10cpywrapfst_LabelPair __pyx_t_12;
+  int __pyx_t_13;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_relabel_pairs", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -26688,435 +26741,407 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_pairs(struct __pyx_obj_9pyw
     }
   }
 
-  /* "pywrapfst.pyx":2449
- *   cdef void _relabel_pairs(self, ipairs=None, opairs=None) except *:
- *     cdef unique_ptr[vector[fst.LabelPair]] _ipairs
- *     _ipairs.reset(new vector[fst.LabelPair]())             # <<<<<<<<<<<<<<
- *     cdef unique_ptr[vector[fst.LabelPair]] _opairs
- *     _opairs.reset(new vector[fst.LabelPair]())
- */
-  try {
-    __pyx_t_1 = new std::vector<__pyx_t_10cpywrapfst_LabelPair> ();
-  } catch(...) {
-    __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 2449, __pyx_L1_error)
-  }
-  __pyx_v__ipairs.reset(__pyx_t_1);
-
-  /* "pywrapfst.pyx":2451
- *     _ipairs.reset(new vector[fst.LabelPair]())
- *     cdef unique_ptr[vector[fst.LabelPair]] _opairs
- *     _opairs.reset(new vector[fst.LabelPair]())             # <<<<<<<<<<<<<<
- *     cdef int64 before
- *     cdef int64 after
- */
-  try {
-    __pyx_t_1 = new std::vector<__pyx_t_10cpywrapfst_LabelPair> ();
-  } catch(...) {
-    __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 2451, __pyx_L1_error)
-  }
-  __pyx_v__opairs.reset(__pyx_t_1);
-
-  /* "pywrapfst.pyx":2454
- *     cdef int64 before
- *     cdef int64 after
+  /* "pywrapfst.pyx":2484
+ *     cdef vector[fst.LabelPair] _ipairs
+ *     cdef vector[fst.LabelPair] _opairs
  *     if ipairs:             # <<<<<<<<<<<<<<
  *       for (before, after) in ipairs:
- *         _ipairs.get().push_back(fst.LabelPair(before, after))
+ *         _ipairs.push_back(fst.LabelPair(before, after))
  */
-  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_ipairs); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 2454, __pyx_L1_error)
-  if (__pyx_t_2) {
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_ipairs); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 2484, __pyx_L1_error)
+  if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2455
- *     cdef int64 after
+    /* "pywrapfst.pyx":2485
+ *     cdef vector[fst.LabelPair] _opairs
  *     if ipairs:
  *       for (before, after) in ipairs:             # <<<<<<<<<<<<<<
- *         _ipairs.get().push_back(fst.LabelPair(before, after))
+ *         _ipairs.push_back(fst.LabelPair(before, after))
  *     if opairs:
  */
     if (likely(PyList_CheckExact(__pyx_v_ipairs)) || PyTuple_CheckExact(__pyx_v_ipairs)) {
-      __pyx_t_3 = __pyx_v_ipairs; __Pyx_INCREF(__pyx_t_3); __pyx_t_4 = 0;
-      __pyx_t_5 = NULL;
+      __pyx_t_2 = __pyx_v_ipairs; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
+      __pyx_t_4 = NULL;
     } else {
-      __pyx_t_4 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_ipairs); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2455, __pyx_L1_error)
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2455, __pyx_L1_error)
+      __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_ipairs); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2485, __pyx_L1_error)
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2485, __pyx_L1_error)
     }
     for (;;) {
-      if (likely(!__pyx_t_5)) {
-        if (likely(PyList_CheckExact(__pyx_t_3))) {
-          if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_3)) break;
+      if (likely(!__pyx_t_4)) {
+        if (likely(PyList_CheckExact(__pyx_t_2))) {
+          if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
           #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-          __pyx_t_6 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_6); __pyx_t_4++; if (unlikely(0 < 0)) __PYX_ERR(0, 2455, __pyx_L1_error)
+          __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 2485, __pyx_L1_error)
           #else
-          __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2455, __pyx_L1_error)
-          __Pyx_GOTREF(__pyx_t_6);
+          __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2485, __pyx_L1_error)
+          __Pyx_GOTREF(__pyx_t_5);
           #endif
         } else {
-          if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+          if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
           #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-          __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_6); __pyx_t_4++; if (unlikely(0 < 0)) __PYX_ERR(0, 2455, __pyx_L1_error)
+          __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 2485, __pyx_L1_error)
           #else
-          __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2455, __pyx_L1_error)
-          __Pyx_GOTREF(__pyx_t_6);
+          __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2485, __pyx_L1_error)
+          __Pyx_GOTREF(__pyx_t_5);
           #endif
         }
       } else {
-        __pyx_t_6 = __pyx_t_5(__pyx_t_3);
-        if (unlikely(!__pyx_t_6)) {
+        __pyx_t_5 = __pyx_t_4(__pyx_t_2);
+        if (unlikely(!__pyx_t_5)) {
           PyObject* exc_type = PyErr_Occurred();
           if (exc_type) {
             if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-            else __PYX_ERR(0, 2455, __pyx_L1_error)
+            else __PYX_ERR(0, 2485, __pyx_L1_error)
           }
           break;
         }
-        __Pyx_GOTREF(__pyx_t_6);
+        __Pyx_GOTREF(__pyx_t_5);
       }
-      if ((likely(PyTuple_CheckExact(__pyx_t_6))) || (PyList_CheckExact(__pyx_t_6))) {
-        PyObject* sequence = __pyx_t_6;
+      if ((likely(PyTuple_CheckExact(__pyx_t_5))) || (PyList_CheckExact(__pyx_t_5))) {
+        PyObject* sequence = __pyx_t_5;
         Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);
         if (unlikely(size != 2)) {
           if (size > 2) __Pyx_RaiseTooManyValuesError(2);
           else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-          __PYX_ERR(0, 2455, __pyx_L1_error)
+          __PYX_ERR(0, 2485, __pyx_L1_error)
         }
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
         if (likely(PyTuple_CheckExact(sequence))) {
-          __pyx_t_7 = PyTuple_GET_ITEM(sequence, 0); 
-          __pyx_t_8 = PyTuple_GET_ITEM(sequence, 1); 
+          __pyx_t_6 = PyTuple_GET_ITEM(sequence, 0); 
+          __pyx_t_7 = PyTuple_GET_ITEM(sequence, 1); 
         } else {
-          __pyx_t_7 = PyList_GET_ITEM(sequence, 0); 
-          __pyx_t_8 = PyList_GET_ITEM(sequence, 1); 
+          __pyx_t_6 = PyList_GET_ITEM(sequence, 0); 
+          __pyx_t_7 = PyList_GET_ITEM(sequence, 1); 
         }
+        __Pyx_INCREF(__pyx_t_6);
         __Pyx_INCREF(__pyx_t_7);
-        __Pyx_INCREF(__pyx_t_8);
         #else
-        __pyx_t_7 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2455, __pyx_L1_error)
+        __pyx_t_6 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2485, __pyx_L1_error)
+        __Pyx_GOTREF(__pyx_t_6);
+        __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2485, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_7);
-        __pyx_t_8 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2455, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_8);
         #endif
-        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       } else {
         Py_ssize_t index = -1;
-        __pyx_t_9 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 2455, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_9);
-        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-        __pyx_t_10 = Py_TYPE(__pyx_t_9)->tp_iternext;
-        index = 0; __pyx_t_7 = __pyx_t_10(__pyx_t_9); if (unlikely(!__pyx_t_7)) goto __pyx_L6_unpacking_failed;
-        __Pyx_GOTREF(__pyx_t_7);
-        index = 1; __pyx_t_8 = __pyx_t_10(__pyx_t_9); if (unlikely(!__pyx_t_8)) goto __pyx_L6_unpacking_failed;
+        __pyx_t_8 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2485, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
-        if (__Pyx_IternextUnpackEndCheck(__pyx_t_10(__pyx_t_9), 2) < 0) __PYX_ERR(0, 2455, __pyx_L1_error)
-        __pyx_t_10 = NULL;
-        __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        __pyx_t_9 = Py_TYPE(__pyx_t_8)->tp_iternext;
+        index = 0; __pyx_t_6 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_6)) goto __pyx_L6_unpacking_failed;
+        __Pyx_GOTREF(__pyx_t_6);
+        index = 1; __pyx_t_7 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_7)) goto __pyx_L6_unpacking_failed;
+        __Pyx_GOTREF(__pyx_t_7);
+        if (__Pyx_IternextUnpackEndCheck(__pyx_t_9(__pyx_t_8), 2) < 0) __PYX_ERR(0, 2485, __pyx_L1_error)
+        __pyx_t_9 = NULL;
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         goto __pyx_L7_unpacking_done;
         __pyx_L6_unpacking_failed:;
-        __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-        __pyx_t_10 = NULL;
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        __pyx_t_9 = NULL;
         if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-        __PYX_ERR(0, 2455, __pyx_L1_error)
+        __PYX_ERR(0, 2485, __pyx_L1_error)
         __pyx_L7_unpacking_done:;
       }
-      __pyx_t_11 = __Pyx_PyInt_As_int64_t(__pyx_t_7); if (unlikely((__pyx_t_11 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2455, __pyx_L1_error)
-      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-      __pyx_t_12 = __Pyx_PyInt_As_int64_t(__pyx_t_8); if (unlikely((__pyx_t_12 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2455, __pyx_L1_error)
-      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_v_before = __pyx_t_11;
-      __pyx_v_after = __pyx_t_12;
+      __Pyx_XDECREF_SET(__pyx_v_before, __pyx_t_6);
+      __pyx_t_6 = 0;
+      __Pyx_XDECREF_SET(__pyx_v_after, __pyx_t_7);
+      __pyx_t_7 = 0;
 
-      /* "pywrapfst.pyx":2456
+      /* "pywrapfst.pyx":2486
  *     if ipairs:
  *       for (before, after) in ipairs:
- *         _ipairs.get().push_back(fst.LabelPair(before, after))             # <<<<<<<<<<<<<<
+ *         _ipairs.push_back(fst.LabelPair(before, after))             # <<<<<<<<<<<<<<
  *     if opairs:
  *       for (before, after) in opairs:
  */
+      __pyx_t_10 = __Pyx_PyInt_As_int64_t(__pyx_v_before); if (unlikely((__pyx_t_10 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2486, __pyx_L1_error)
+      __pyx_t_11 = __Pyx_PyInt_As_int64_t(__pyx_v_after); if (unlikely((__pyx_t_11 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2486, __pyx_L1_error)
       try {
-        __pyx_t_13 = __pyx_t_10cpywrapfst_LabelPair(__pyx_v_before, __pyx_v_after);
+        __pyx_t_12 = __pyx_t_10cpywrapfst_LabelPair(__pyx_t_10, __pyx_t_11);
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 2456, __pyx_L1_error)
+        __PYX_ERR(0, 2486, __pyx_L1_error)
       }
       try {
-        __pyx_v__ipairs.get()->push_back(__pyx_t_13);
+        __pyx_v__ipairs.push_back(__pyx_t_12);
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 2456, __pyx_L1_error)
+        __PYX_ERR(0, 2486, __pyx_L1_error)
       }
 
-      /* "pywrapfst.pyx":2455
- *     cdef int64 after
+      /* "pywrapfst.pyx":2485
+ *     cdef vector[fst.LabelPair] _opairs
  *     if ipairs:
  *       for (before, after) in ipairs:             # <<<<<<<<<<<<<<
- *         _ipairs.get().push_back(fst.LabelPair(before, after))
+ *         _ipairs.push_back(fst.LabelPair(before, after))
  *     if opairs:
  */
     }
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-    /* "pywrapfst.pyx":2454
- *     cdef int64 before
- *     cdef int64 after
+    /* "pywrapfst.pyx":2484
+ *     cdef vector[fst.LabelPair] _ipairs
+ *     cdef vector[fst.LabelPair] _opairs
  *     if ipairs:             # <<<<<<<<<<<<<<
  *       for (before, after) in ipairs:
- *         _ipairs.get().push_back(fst.LabelPair(before, after))
+ *         _ipairs.push_back(fst.LabelPair(before, after))
  */
   }
 
-  /* "pywrapfst.pyx":2457
+  /* "pywrapfst.pyx":2487
  *       for (before, after) in ipairs:
- *         _ipairs.get().push_back(fst.LabelPair(before, after))
+ *         _ipairs.push_back(fst.LabelPair(before, after))
  *     if opairs:             # <<<<<<<<<<<<<<
  *       for (before, after) in opairs:
- *         _opairs.get().push_back(fst.LabelPair(before, after))
+ *         _opairs.push_back(fst.LabelPair(before, after))
  */
-  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_opairs); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 2457, __pyx_L1_error)
-  if (__pyx_t_2) {
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_opairs); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 2487, __pyx_L1_error)
+  if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2458
- *         _ipairs.get().push_back(fst.LabelPair(before, after))
+    /* "pywrapfst.pyx":2488
+ *         _ipairs.push_back(fst.LabelPair(before, after))
  *     if opairs:
  *       for (before, after) in opairs:             # <<<<<<<<<<<<<<
- *         _opairs.get().push_back(fst.LabelPair(before, after))
- *     if _ipairs.get().empty() and _opairs.get().empty():
+ *         _opairs.push_back(fst.LabelPair(before, after))
+ *     if _ipairs.empty() and _opairs.empty():
  */
     if (likely(PyList_CheckExact(__pyx_v_opairs)) || PyTuple_CheckExact(__pyx_v_opairs)) {
-      __pyx_t_3 = __pyx_v_opairs; __Pyx_INCREF(__pyx_t_3); __pyx_t_4 = 0;
-      __pyx_t_5 = NULL;
+      __pyx_t_2 = __pyx_v_opairs; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
+      __pyx_t_4 = NULL;
     } else {
-      __pyx_t_4 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_opairs); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2458, __pyx_L1_error)
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_5 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2458, __pyx_L1_error)
+      __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_opairs); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2488, __pyx_L1_error)
+      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2488, __pyx_L1_error)
     }
     for (;;) {
-      if (likely(!__pyx_t_5)) {
-        if (likely(PyList_CheckExact(__pyx_t_3))) {
-          if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_3)) break;
+      if (likely(!__pyx_t_4)) {
+        if (likely(PyList_CheckExact(__pyx_t_2))) {
+          if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
           #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-          __pyx_t_6 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_6); __pyx_t_4++; if (unlikely(0 < 0)) __PYX_ERR(0, 2458, __pyx_L1_error)
+          __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 2488, __pyx_L1_error)
           #else
-          __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2458, __pyx_L1_error)
-          __Pyx_GOTREF(__pyx_t_6);
+          __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2488, __pyx_L1_error)
+          __Pyx_GOTREF(__pyx_t_5);
           #endif
         } else {
-          if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+          if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
           #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-          __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_4); __Pyx_INCREF(__pyx_t_6); __pyx_t_4++; if (unlikely(0 < 0)) __PYX_ERR(0, 2458, __pyx_L1_error)
+          __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 2488, __pyx_L1_error)
           #else
-          __pyx_t_6 = PySequence_ITEM(__pyx_t_3, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2458, __pyx_L1_error)
-          __Pyx_GOTREF(__pyx_t_6);
+          __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2488, __pyx_L1_error)
+          __Pyx_GOTREF(__pyx_t_5);
           #endif
         }
       } else {
-        __pyx_t_6 = __pyx_t_5(__pyx_t_3);
-        if (unlikely(!__pyx_t_6)) {
+        __pyx_t_5 = __pyx_t_4(__pyx_t_2);
+        if (unlikely(!__pyx_t_5)) {
           PyObject* exc_type = PyErr_Occurred();
           if (exc_type) {
             if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-            else __PYX_ERR(0, 2458, __pyx_L1_error)
+            else __PYX_ERR(0, 2488, __pyx_L1_error)
           }
           break;
         }
-        __Pyx_GOTREF(__pyx_t_6);
+        __Pyx_GOTREF(__pyx_t_5);
       }
-      if ((likely(PyTuple_CheckExact(__pyx_t_6))) || (PyList_CheckExact(__pyx_t_6))) {
-        PyObject* sequence = __pyx_t_6;
+      if ((likely(PyTuple_CheckExact(__pyx_t_5))) || (PyList_CheckExact(__pyx_t_5))) {
+        PyObject* sequence = __pyx_t_5;
         Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);
         if (unlikely(size != 2)) {
           if (size > 2) __Pyx_RaiseTooManyValuesError(2);
           else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-          __PYX_ERR(0, 2458, __pyx_L1_error)
+          __PYX_ERR(0, 2488, __pyx_L1_error)
         }
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
         if (likely(PyTuple_CheckExact(sequence))) {
-          __pyx_t_8 = PyTuple_GET_ITEM(sequence, 0); 
-          __pyx_t_7 = PyTuple_GET_ITEM(sequence, 1); 
+          __pyx_t_7 = PyTuple_GET_ITEM(sequence, 0); 
+          __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); 
         } else {
-          __pyx_t_8 = PyList_GET_ITEM(sequence, 0); 
-          __pyx_t_7 = PyList_GET_ITEM(sequence, 1); 
+          __pyx_t_7 = PyList_GET_ITEM(sequence, 0); 
+          __pyx_t_6 = PyList_GET_ITEM(sequence, 1); 
         }
-        __Pyx_INCREF(__pyx_t_8);
         __Pyx_INCREF(__pyx_t_7);
+        __Pyx_INCREF(__pyx_t_6);
         #else
-        __pyx_t_8 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2458, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_8);
-        __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2458, __pyx_L1_error)
+        __pyx_t_7 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 2488, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2488, __pyx_L1_error)
+        __Pyx_GOTREF(__pyx_t_6);
         #endif
-        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
       } else {
         Py_ssize_t index = -1;
-        __pyx_t_9 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 2458, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_9);
-        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-        __pyx_t_10 = Py_TYPE(__pyx_t_9)->tp_iternext;
-        index = 0; __pyx_t_8 = __pyx_t_10(__pyx_t_9); if (unlikely(!__pyx_t_8)) goto __pyx_L11_unpacking_failed;
+        __pyx_t_8 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 2488, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_8);
-        index = 1; __pyx_t_7 = __pyx_t_10(__pyx_t_9); if (unlikely(!__pyx_t_7)) goto __pyx_L11_unpacking_failed;
+        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+        __pyx_t_9 = Py_TYPE(__pyx_t_8)->tp_iternext;
+        index = 0; __pyx_t_7 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_7)) goto __pyx_L11_unpacking_failed;
         __Pyx_GOTREF(__pyx_t_7);
-        if (__Pyx_IternextUnpackEndCheck(__pyx_t_10(__pyx_t_9), 2) < 0) __PYX_ERR(0, 2458, __pyx_L1_error)
-        __pyx_t_10 = NULL;
-        __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+        index = 1; __pyx_t_6 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_6)) goto __pyx_L11_unpacking_failed;
+        __Pyx_GOTREF(__pyx_t_6);
+        if (__Pyx_IternextUnpackEndCheck(__pyx_t_9(__pyx_t_8), 2) < 0) __PYX_ERR(0, 2488, __pyx_L1_error)
+        __pyx_t_9 = NULL;
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         goto __pyx_L12_unpacking_done;
         __pyx_L11_unpacking_failed:;
-        __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-        __pyx_t_10 = NULL;
+        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+        __pyx_t_9 = NULL;
         if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-        __PYX_ERR(0, 2458, __pyx_L1_error)
+        __PYX_ERR(0, 2488, __pyx_L1_error)
         __pyx_L12_unpacking_done:;
       }
-      __pyx_t_12 = __Pyx_PyInt_As_int64_t(__pyx_t_8); if (unlikely((__pyx_t_12 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2458, __pyx_L1_error)
-      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      __pyx_t_11 = __Pyx_PyInt_As_int64_t(__pyx_t_7); if (unlikely((__pyx_t_11 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2458, __pyx_L1_error)
-      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-      __pyx_v_before = __pyx_t_12;
-      __pyx_v_after = __pyx_t_11;
+      __Pyx_XDECREF_SET(__pyx_v_before, __pyx_t_7);
+      __pyx_t_7 = 0;
+      __Pyx_XDECREF_SET(__pyx_v_after, __pyx_t_6);
+      __pyx_t_6 = 0;
 
-      /* "pywrapfst.pyx":2459
+      /* "pywrapfst.pyx":2489
  *     if opairs:
  *       for (before, after) in opairs:
- *         _opairs.get().push_back(fst.LabelPair(before, after))             # <<<<<<<<<<<<<<
- *     if _ipairs.get().empty() and _opairs.get().empty():
+ *         _opairs.push_back(fst.LabelPair(before, after))             # <<<<<<<<<<<<<<
+ *     if _ipairs.empty() and _opairs.empty():
  *       raise FstArgError("No relabeling pairs specified")
  */
+      __pyx_t_11 = __Pyx_PyInt_As_int64_t(__pyx_v_before); if (unlikely((__pyx_t_11 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2489, __pyx_L1_error)
+      __pyx_t_10 = __Pyx_PyInt_As_int64_t(__pyx_v_after); if (unlikely((__pyx_t_10 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2489, __pyx_L1_error)
       try {
-        __pyx_t_13 = __pyx_t_10cpywrapfst_LabelPair(__pyx_v_before, __pyx_v_after);
+        __pyx_t_12 = __pyx_t_10cpywrapfst_LabelPair(__pyx_t_11, __pyx_t_10);
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 2459, __pyx_L1_error)
+        __PYX_ERR(0, 2489, __pyx_L1_error)
       }
       try {
-        __pyx_v__opairs.get()->push_back(__pyx_t_13);
+        __pyx_v__opairs.push_back(__pyx_t_12);
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 2459, __pyx_L1_error)
+        __PYX_ERR(0, 2489, __pyx_L1_error)
       }
 
-      /* "pywrapfst.pyx":2458
- *         _ipairs.get().push_back(fst.LabelPair(before, after))
+      /* "pywrapfst.pyx":2488
+ *         _ipairs.push_back(fst.LabelPair(before, after))
  *     if opairs:
  *       for (before, after) in opairs:             # <<<<<<<<<<<<<<
- *         _opairs.get().push_back(fst.LabelPair(before, after))
- *     if _ipairs.get().empty() and _opairs.get().empty():
+ *         _opairs.push_back(fst.LabelPair(before, after))
+ *     if _ipairs.empty() and _opairs.empty():
  */
     }
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-    /* "pywrapfst.pyx":2457
+    /* "pywrapfst.pyx":2487
  *       for (before, after) in ipairs:
- *         _ipairs.get().push_back(fst.LabelPair(before, after))
+ *         _ipairs.push_back(fst.LabelPair(before, after))
  *     if opairs:             # <<<<<<<<<<<<<<
  *       for (before, after) in opairs:
- *         _opairs.get().push_back(fst.LabelPair(before, after))
+ *         _opairs.push_back(fst.LabelPair(before, after))
  */
   }
 
-  /* "pywrapfst.pyx":2460
+  /* "pywrapfst.pyx":2490
  *       for (before, after) in opairs:
- *         _opairs.get().push_back(fst.LabelPair(before, after))
- *     if _ipairs.get().empty() and _opairs.get().empty():             # <<<<<<<<<<<<<<
+ *         _opairs.push_back(fst.LabelPair(before, after))
+ *     if _ipairs.empty() and _opairs.empty():             # <<<<<<<<<<<<<<
  *       raise FstArgError("No relabeling pairs specified")
- *     fst.Relabel(self._mfst.get(), deref(_ipairs), deref(_opairs))
+ *     fst.Relabel(self._mfst.get(), _ipairs, _opairs)
  */
-  __pyx_t_14 = (__pyx_v__ipairs.get()->empty() != 0);
-  if (__pyx_t_14) {
+  __pyx_t_13 = (__pyx_v__ipairs.empty() != 0);
+  if (__pyx_t_13) {
   } else {
-    __pyx_t_2 = __pyx_t_14;
+    __pyx_t_1 = __pyx_t_13;
     goto __pyx_L14_bool_binop_done;
   }
-  __pyx_t_14 = (__pyx_v__opairs.get()->empty() != 0);
-  __pyx_t_2 = __pyx_t_14;
+  __pyx_t_13 = (__pyx_v__opairs.empty() != 0);
+  __pyx_t_1 = __pyx_t_13;
   __pyx_L14_bool_binop_done:;
-  if (unlikely(__pyx_t_2)) {
+  if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2461
- *         _opairs.get().push_back(fst.LabelPair(before, after))
- *     if _ipairs.get().empty() and _opairs.get().empty():
+    /* "pywrapfst.pyx":2491
+ *         _opairs.push_back(fst.LabelPair(before, after))
+ *     if _ipairs.empty() and _opairs.empty():
  *       raise FstArgError("No relabeling pairs specified")             # <<<<<<<<<<<<<<
- *     fst.Relabel(self._mfst.get(), deref(_ipairs), deref(_opairs))
+ *     fst.Relabel(self._mfst.get(), _ipairs, _opairs)
  *     self._check_mutating_imethod()
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2461, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = NULL;
-    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_6))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
-        __Pyx_INCREF(__pyx_t_7);
+    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2491, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_6 = NULL;
+    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
+      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
+      if (likely(__pyx_t_6)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+        __Pyx_INCREF(__pyx_t_6);
         __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_6, function);
+        __Pyx_DECREF_SET(__pyx_t_5, function);
       }
     }
-    __pyx_t_3 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_kp_u_No_relabeling_pairs_specified) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_kp_u_No_relabeling_pairs_specified);
-    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2461, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2461, __pyx_L1_error)
+    __pyx_t_2 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_6, __pyx_kp_u_No_relabeling_pairs_specified) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_kp_u_No_relabeling_pairs_specified);
+    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2491, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __PYX_ERR(0, 2491, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2460
+    /* "pywrapfst.pyx":2490
  *       for (before, after) in opairs:
- *         _opairs.get().push_back(fst.LabelPair(before, after))
- *     if _ipairs.get().empty() and _opairs.get().empty():             # <<<<<<<<<<<<<<
+ *         _opairs.push_back(fst.LabelPair(before, after))
+ *     if _ipairs.empty() and _opairs.empty():             # <<<<<<<<<<<<<<
  *       raise FstArgError("No relabeling pairs specified")
- *     fst.Relabel(self._mfst.get(), deref(_ipairs), deref(_opairs))
+ *     fst.Relabel(self._mfst.get(), _ipairs, _opairs)
  */
   }
 
-  /* "pywrapfst.pyx":2462
- *     if _ipairs.get().empty() and _opairs.get().empty():
+  /* "pywrapfst.pyx":2492
+ *     if _ipairs.empty() and _opairs.empty():
  *       raise FstArgError("No relabeling pairs specified")
- *     fst.Relabel(self._mfst.get(), deref(_ipairs), deref(_opairs))             # <<<<<<<<<<<<<<
+ *     fst.Relabel(self._mfst.get(), _ipairs, _opairs)             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2462, __pyx_L1_error)
+    __PYX_ERR(0, 2492, __pyx_L1_error)
   }
-  fst::script::Relabel(__pyx_v_self->_mfst.get(), (*__pyx_v__ipairs), (*__pyx_v__opairs));
+  fst::script::Relabel(__pyx_v_self->_mfst.get(), __pyx_v__ipairs, __pyx_v__opairs);
 
-  /* "pywrapfst.pyx":2463
+  /* "pywrapfst.pyx":2493
  *       raise FstArgError("No relabeling pairs specified")
- *     fst.Relabel(self._mfst.get(), deref(_ipairs), deref(_opairs))
+ *     fst.Relabel(self._mfst.get(), _ipairs, _opairs)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
  * 
  *   def relabel_pairs(self, ipairs=None, opairs=None):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2463, __pyx_L1_error)
+    __PYX_ERR(0, 2493, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2463, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2493, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2447
+  /* "pywrapfst.pyx":2481
  *     return self
  * 
  *   cdef void _relabel_pairs(self, ipairs=None, opairs=None) except *:             # <<<<<<<<<<<<<<
- *     cdef unique_ptr[vector[fst.LabelPair]] _ipairs
- *     _ipairs.reset(new vector[fst.LabelPair]())
+ *     cdef vector[fst.LabelPair] _ipairs
+ *     cdef vector[fst.LabelPair] _opairs
  */
 
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
   __Pyx_XDECREF(__pyx_t_7);
   __Pyx_XDECREF(__pyx_t_8);
-  __Pyx_XDECREF(__pyx_t_9);
   __Pyx_AddTraceback("pywrapfst.MutableFst._relabel_pairs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_before);
+  __Pyx_XDECREF(__pyx_v_after);
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2465
+/* "pywrapfst.pyx":2495
  *     self._check_mutating_imethod()
  * 
  *   def relabel_pairs(self, ipairs=None, opairs=None):             # <<<<<<<<<<<<<<
@@ -27130,6 +27155,9 @@ static char __pyx_doc_9pywrapfst_10MutableFst_40relabel_pairs[] = "\n    relabel
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_41relabel_pairs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_ipairs = 0;
   PyObject *__pyx_v_opairs = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("relabel_pairs (wrapper)", 0);
@@ -27164,7 +27192,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_41relabel_pairs(PyObject *__py
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "relabel_pairs") < 0)) __PYX_ERR(0, 2465, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "relabel_pairs") < 0)) __PYX_ERR(0, 2495, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -27181,7 +27209,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_41relabel_pairs(PyObject *__py
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("relabel_pairs", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2465, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("relabel_pairs", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2495, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.relabel_pairs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -27198,9 +27226,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_40relabel_pairs(struct __pyx_o
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_10MutableFst__relabel_pairs __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("relabel_pairs", 0);
 
-  /* "pywrapfst.pyx":2485
+  /* "pywrapfst.pyx":2515
  *       FstArgError: No relabeling pairs specified.
  *     """
  *     self._relabel_pairs(ipairs, opairs)             # <<<<<<<<<<<<<<
@@ -27209,14 +27240,14 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_40relabel_pairs(struct __pyx_o
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_relabel_pairs");
-    __PYX_ERR(0, 2485, __pyx_L1_error)
+    __PYX_ERR(0, 2515, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 2;
   __pyx_t_1.ipairs = __pyx_v_ipairs;
   __pyx_t_1.opairs = __pyx_v_opairs;
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_relabel_pairs(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2485, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_relabel_pairs(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2515, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2486
+  /* "pywrapfst.pyx":2516
  *     """
  *     self._relabel_pairs(ipairs, opairs)
  *     return self             # <<<<<<<<<<<<<<
@@ -27228,7 +27259,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_40relabel_pairs(struct __pyx_o
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2465
+  /* "pywrapfst.pyx":2495
  *     self._check_mutating_imethod()
  * 
  *   def relabel_pairs(self, ipairs=None, opairs=None):             # <<<<<<<<<<<<<<
@@ -27246,66 +27277,66 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_40relabel_pairs(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2488
+/* "pywrapfst.pyx":2518
  *     return self
  * 
  *   cdef void _relabel_tables(self,             # <<<<<<<<<<<<<<
- *                             _SymbolTable old_isymbols=None,
- *                             _SymbolTable new_isymbols=None,
+ *                             SymbolTableView old_isymbols=None,
+ *                             SymbolTableView new_isymbols=None,
  */
 
 static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__relabel_tables *__pyx_optional_args) {
 
-  /* "pywrapfst.pyx":2489
+  /* "pywrapfst.pyx":2519
  * 
  *   cdef void _relabel_tables(self,
- *                             _SymbolTable old_isymbols=None,             # <<<<<<<<<<<<<<
- *                             _SymbolTable new_isymbols=None,
- *                             unknown_isymbol=b"",
+ *                             SymbolTableView old_isymbols=None,             # <<<<<<<<<<<<<<
+ *                             SymbolTableView new_isymbols=None,
+ *                             unknown_isymbol="",
  */
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_isymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_old_isymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-  /* "pywrapfst.pyx":2490
+  /* "pywrapfst.pyx":2520
  *   cdef void _relabel_tables(self,
- *                             _SymbolTable old_isymbols=None,
- *                             _SymbolTable new_isymbols=None,             # <<<<<<<<<<<<<<
- *                             unknown_isymbol=b"",
+ *                             SymbolTableView old_isymbols=None,
+ *                             SymbolTableView new_isymbols=None,             # <<<<<<<<<<<<<<
+ *                             unknown_isymbol="",
  *                             bool attach_new_isymbols=True,
  */
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_new_isymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
-  PyObject *__pyx_v_unknown_isymbol = ((PyObject *)__pyx_kp_b__8);
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_new_isymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
+  PyObject *__pyx_v_unknown_isymbol = ((PyObject *)__pyx_kp_u__11);
 
-  /* "pywrapfst.pyx":2492
- *                             _SymbolTable new_isymbols=None,
- *                             unknown_isymbol=b"",
+  /* "pywrapfst.pyx":2522
+ *                             SymbolTableView new_isymbols=None,
+ *                             unknown_isymbol="",
  *                             bool attach_new_isymbols=True,             # <<<<<<<<<<<<<<
- *                             _SymbolTable old_osymbols=None,
- *                             _SymbolTable new_osymbols=None,
+ *                             SymbolTableView old_osymbols=None,
+ *                             SymbolTableView new_osymbols=None,
  */
   bool __pyx_v_attach_new_isymbols = ((bool)1);
 
-  /* "pywrapfst.pyx":2493
- *                             unknown_isymbol=b"",
+  /* "pywrapfst.pyx":2523
+ *                             unknown_isymbol="",
  *                             bool attach_new_isymbols=True,
- *                             _SymbolTable old_osymbols=None,             # <<<<<<<<<<<<<<
- *                             _SymbolTable new_osymbols=None,
- *                             unknown_osymbol=b"",
+ *                             SymbolTableView old_osymbols=None,             # <<<<<<<<<<<<<<
+ *                             SymbolTableView new_osymbols=None,
+ *                             unknown_osymbol="",
  */
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_old_osymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-  /* "pywrapfst.pyx":2494
+  /* "pywrapfst.pyx":2524
  *                             bool attach_new_isymbols=True,
- *                             _SymbolTable old_osymbols=None,
- *                             _SymbolTable new_osymbols=None,             # <<<<<<<<<<<<<<
- *                             unknown_osymbol=b"",
+ *                             SymbolTableView old_osymbols=None,
+ *                             SymbolTableView new_osymbols=None,             # <<<<<<<<<<<<<<
+ *                             unknown_osymbol="",
  *                             bool attach_new_osymbols=True) except *:
  */
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_new_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
-  PyObject *__pyx_v_unknown_osymbol = ((PyObject *)__pyx_kp_b__8);
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_new_osymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
+  PyObject *__pyx_v_unknown_osymbol = ((PyObject *)__pyx_kp_u__11);
 
-  /* "pywrapfst.pyx":2496
- *                             _SymbolTable new_osymbols=None,
- *                             unknown_osymbol=b"",
+  /* "pywrapfst.pyx":2526
+ *                             SymbolTableView new_osymbols=None,
+ *                             unknown_osymbol="",
  *                             bool attach_new_osymbols=True) except *:             # <<<<<<<<<<<<<<
  *     if new_isymbols is None and new_osymbols is None:
  *       raise FstArgError("No new SymbolTables specified")
@@ -27325,6 +27356,9 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
   fst::SymbolTable const *__pyx_t_7;
   std::string __pyx_t_8;
   std::string __pyx_t_9;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_relabel_tables", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -27353,8 +27387,8 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
     }
   }
 
-  /* "pywrapfst.pyx":2497
- *                             unknown_osymbol=b"",
+  /* "pywrapfst.pyx":2527
+ *                             unknown_osymbol="",
  *                             bool attach_new_osymbols=True) except *:
  *     if new_isymbols is None and new_osymbols is None:             # <<<<<<<<<<<<<<
  *       raise FstArgError("No new SymbolTables specified")
@@ -27373,14 +27407,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
   __pyx_L4_bool_binop_done:;
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2498
+    /* "pywrapfst.pyx":2528
  *                             bool attach_new_osymbols=True) except *:
  *     if new_isymbols is None and new_osymbols is None:
  *       raise FstArgError("No new SymbolTables specified")             # <<<<<<<<<<<<<<
  *     cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()
  *     if old_isymbols is not None:
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2498, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2528, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __pyx_t_6 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
@@ -27394,15 +27428,15 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
     }
     __pyx_t_4 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_6, __pyx_kp_u_No_new_SymbolTables_specified) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_kp_u_No_new_SymbolTables_specified);
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2498, __pyx_L1_error)
+    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2528, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_Raise(__pyx_t_4, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __PYX_ERR(0, 2498, __pyx_L1_error)
+    __PYX_ERR(0, 2528, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2497
- *                             unknown_osymbol=b"",
+    /* "pywrapfst.pyx":2527
+ *                             unknown_osymbol="",
  *                             bool attach_new_osymbols=True) except *:
  *     if new_isymbols is None and new_osymbols is None:             # <<<<<<<<<<<<<<
  *       raise FstArgError("No new SymbolTables specified")
@@ -27410,7 +27444,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":2499
+  /* "pywrapfst.pyx":2529
  *     if new_isymbols is None and new_osymbols is None:
  *       raise FstArgError("No new SymbolTables specified")
  *     cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()             # <<<<<<<<<<<<<<
@@ -27419,11 +27453,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2499, __pyx_L1_error)
+    __PYX_ERR(0, 2529, __pyx_L1_error)
   }
   __pyx_v__old_isymbols = __pyx_v_self->__pyx_base._fst.get()->InputSymbols();
 
-  /* "pywrapfst.pyx":2500
+  /* "pywrapfst.pyx":2530
  *       raise FstArgError("No new SymbolTables specified")
  *     cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()
  *     if old_isymbols is not None:             # <<<<<<<<<<<<<<
@@ -27434,7 +27468,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2501
+    /* "pywrapfst.pyx":2531
  *     cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()
  *     if old_isymbols is not None:
  *       _old_isymbols = old_isymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -27443,12 +27477,12 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
     if (unlikely(((PyObject *)__pyx_v_old_isymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 2501, __pyx_L1_error)
+      __PYX_ERR(0, 2531, __pyx_L1_error)
     }
-    __pyx_t_7 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_old_isymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_old_isymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2501, __pyx_L1_error)
+    __pyx_t_7 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_old_isymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_old_isymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2531, __pyx_L1_error)
     __pyx_v__old_isymbols = __pyx_t_7;
 
-    /* "pywrapfst.pyx":2500
+    /* "pywrapfst.pyx":2530
  *       raise FstArgError("No new SymbolTables specified")
  *     cdef const fst.SymbolTable *_old_isymbols = self._fst.get().InputSymbols()
  *     if old_isymbols is not None:             # <<<<<<<<<<<<<<
@@ -27457,7 +27491,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":2502
+  /* "pywrapfst.pyx":2532
  *     if old_isymbols is not None:
  *       _old_isymbols = old_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()             # <<<<<<<<<<<<<<
@@ -27466,11 +27500,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2502, __pyx_L1_error)
+    __PYX_ERR(0, 2532, __pyx_L1_error)
   }
   __pyx_v__old_osymbols = __pyx_v_self->__pyx_base._fst.get()->OutputSymbols();
 
-  /* "pywrapfst.pyx":2503
+  /* "pywrapfst.pyx":2533
  *       _old_isymbols = old_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()
  *     if old_osymbols is not None:             # <<<<<<<<<<<<<<
@@ -27481,7 +27515,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2504
+    /* "pywrapfst.pyx":2534
  *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()
  *     if old_osymbols is not None:
  *        _old_osymbols = old_osymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -27490,12 +27524,12 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
     if (unlikely(((PyObject *)__pyx_v_old_osymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 2504, __pyx_L1_error)
+      __PYX_ERR(0, 2534, __pyx_L1_error)
     }
-    __pyx_t_7 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_old_osymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_old_osymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2504, __pyx_L1_error)
+    __pyx_t_7 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_old_osymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_old_osymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2534, __pyx_L1_error)
     __pyx_v__old_osymbols = __pyx_t_7;
 
-    /* "pywrapfst.pyx":2503
+    /* "pywrapfst.pyx":2533
  *       _old_isymbols = old_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_old_osymbols = self._fst.get().OutputSymbols()
  *     if old_osymbols is not None:             # <<<<<<<<<<<<<<
@@ -27504,7 +27538,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":2505
+  /* "pywrapfst.pyx":2535
  *     if old_osymbols is not None:
  *        _old_osymbols = old_osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_isymbols = NULL             # <<<<<<<<<<<<<<
@@ -27513,7 +27547,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   __pyx_v__new_isymbols = NULL;
 
-  /* "pywrapfst.pyx":2506
+  /* "pywrapfst.pyx":2536
  *        _old_osymbols = old_osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_isymbols = NULL
  *     if new_isymbols is not None:             # <<<<<<<<<<<<<<
@@ -27524,7 +27558,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2507
+    /* "pywrapfst.pyx":2537
  *     cdef const fst.SymbolTable *_new_isymbols = NULL
  *     if new_isymbols is not None:
  *       _new_isymbols = new_isymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -27533,12 +27567,12 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
     if (unlikely(((PyObject *)__pyx_v_new_isymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 2507, __pyx_L1_error)
+      __PYX_ERR(0, 2537, __pyx_L1_error)
     }
-    __pyx_t_7 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_new_isymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_new_isymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2507, __pyx_L1_error)
+    __pyx_t_7 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_new_isymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_new_isymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2537, __pyx_L1_error)
     __pyx_v__new_isymbols = __pyx_t_7;
 
-    /* "pywrapfst.pyx":2506
+    /* "pywrapfst.pyx":2536
  *        _old_osymbols = old_osymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_isymbols = NULL
  *     if new_isymbols is not None:             # <<<<<<<<<<<<<<
@@ -27547,7 +27581,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":2508
+  /* "pywrapfst.pyx":2538
  *     if new_isymbols is not None:
  *       _new_isymbols = new_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_osymbols = NULL             # <<<<<<<<<<<<<<
@@ -27556,7 +27590,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   __pyx_v__new_osymbols = NULL;
 
-  /* "pywrapfst.pyx":2509
+  /* "pywrapfst.pyx":2539
  *       _new_isymbols = new_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_osymbols = NULL
  *     if new_osymbols is not None:             # <<<<<<<<<<<<<<
@@ -27567,7 +27601,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
   __pyx_t_1 = (__pyx_t_2 != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2510
+    /* "pywrapfst.pyx":2540
  *     cdef const fst.SymbolTable *_new_osymbols = NULL
  *     if new_osymbols is not None:
  *       _new_osymbols = new_osymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -27576,12 +27610,12 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
     if (unlikely(((PyObject *)__pyx_v_new_osymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 2510, __pyx_L1_error)
+      __PYX_ERR(0, 2540, __pyx_L1_error)
     }
-    __pyx_t_7 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_new_osymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_new_osymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2510, __pyx_L1_error)
+    __pyx_t_7 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_new_osymbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_new_osymbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2540, __pyx_L1_error)
     __pyx_v__new_osymbols = __pyx_t_7;
 
-    /* "pywrapfst.pyx":2509
+    /* "pywrapfst.pyx":2539
  *       _new_isymbols = new_isymbols._raw_ptr_or_raise()
  *     cdef const fst.SymbolTable *_new_osymbols = NULL
  *     if new_osymbols is not None:             # <<<<<<<<<<<<<<
@@ -27590,7 +27624,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   }
 
-  /* "pywrapfst.pyx":2511
+  /* "pywrapfst.pyx":2541
  *     if new_osymbols is not None:
  *       _new_osymbols = new_osymbols._raw_ptr_or_raise()
  *     fst.Relabel(self._mfst.get(),             # <<<<<<<<<<<<<<
@@ -27599,28 +27633,28 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2511, __pyx_L1_error)
+    __PYX_ERR(0, 2541, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2514
+  /* "pywrapfst.pyx":2544
  *         _old_isymbols,
  *         _new_isymbols,
  *         tostring(unknown_isymbol),             # <<<<<<<<<<<<<<
  *         attach_new_isymbols,
  *         _old_osymbols,
  */
-  __pyx_t_8 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_isymbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2514, __pyx_L1_error)
+  __pyx_t_8 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_isymbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2544, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2518
+  /* "pywrapfst.pyx":2548
  *         _old_osymbols,
  *         _new_osymbols,
  *         tostring(unknown_osymbol),             # <<<<<<<<<<<<<<
  *         attach_new_osymbols)
  *     self._check_mutating_imethod()
  */
-  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_osymbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2518, __pyx_L1_error)
+  __pyx_t_9 = __pyx_f_9pywrapfst_tostring(__pyx_v_unknown_osymbol); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2548, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2511
+  /* "pywrapfst.pyx":2541
  *     if new_osymbols is not None:
  *       _new_osymbols = new_osymbols._raw_ptr_or_raise()
  *     fst.Relabel(self._mfst.get(),             # <<<<<<<<<<<<<<
@@ -27629,7 +27663,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   fst::script::Relabel(__pyx_v_self->_mfst.get(), __pyx_v__old_isymbols, __pyx_v__new_isymbols, __pyx_t_8, __pyx_v_attach_new_isymbols, __pyx_v__old_osymbols, __pyx_v__new_osymbols, __pyx_t_9, __pyx_v_attach_new_osymbols);
 
-  /* "pywrapfst.pyx":2520
+  /* "pywrapfst.pyx":2550
  *         tostring(unknown_osymbol),
  *         attach_new_osymbols)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -27638,16 +27672,16 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2520, __pyx_L1_error)
+    __PYX_ERR(0, 2550, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2520, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2550, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2488
+  /* "pywrapfst.pyx":2518
  *     return self
  * 
  *   cdef void _relabel_tables(self,             # <<<<<<<<<<<<<<
- *                             _SymbolTable old_isymbols=None,
- *                             _SymbolTable new_isymbols=None,
+ *                             SymbolTableView old_isymbols=None,
+ *                             SymbolTableView new_isymbols=None,
  */
 
   /* function exit code */
@@ -27661,26 +27695,29 @@ static void __pyx_f_9pywrapfst_10MutableFst__relabel_tables(struct __pyx_obj_9py
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2522
+/* "pywrapfst.pyx":2552
  *     self._check_mutating_imethod()
  * 
  *   def relabel_tables(self,             # <<<<<<<<<<<<<<
- *                      _SymbolTable old_isymbols=None,
- *                      _SymbolTable new_isymbols=None,
+ *                      SymbolTableView old_isymbols=None,
+ *                      SymbolTableView new_isymbols=None,
  */
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_43relabel_tables(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static char __pyx_doc_9pywrapfst_10MutableFst_42relabel_tables[] = "\n    relabel_tables(self, old_isymbols=None, new_isymbols=None,\n                   unknown_isymbol=\"\", attach_new_isymbols=True,\n                   old_osymbols=None, new_osymbols=None,\n                   unknown_osymbol=\"\", attach_new_osymbols=True)\n\n    Replaces input and/or output labels using SymbolTables.\n\n    This operation destructively relabels the input and/or output labels of the\n    FST using user-specified symbol tables; omitted symbols are identity-mapped.\n\n    Args:\n       old_isymbols: The old SymbolTable for input labels, defaulting to the\n          FST's input symbol table.\n       new_isymbols: A SymbolTable used to relabel the input labels\n       unknown_isymbol: Input symbol to use to relabel OOVs (if empty,\n          OOVs raise an exception)\n       attach_new_isymbols: Should new_isymbols be made the FST's input symbol\n          table?\n       old_osymbols: The old SymbolTable for output labels, defaulting to the\n          FST's output symbol table.\n       new_osymbols: A SymbolTable used to relabel the output labels.\n       unknown_osymbol: Outnput symbol to use to relabel OOVs (if empty,\n          OOVs raise an exception)\n       attach_new_isymbols: Should new_osymbols be made the FST's output symbol\n          table?\n\n    Returns:\n      self.\n\n    Raises:\n      FstArgError: No SymbolTable specified.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_43relabel_tables(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_isymbols = 0;
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_new_isymbols = 0;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_old_isymbols = 0;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_new_isymbols = 0;
   PyObject *__pyx_v_unknown_isymbol = 0;
   bool __pyx_v_attach_new_isymbols;
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_osymbols = 0;
-  struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_new_osymbols = 0;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_old_osymbols = 0;
+  struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_new_osymbols = 0;
   PyObject *__pyx_v_unknown_osymbol = 0;
   bool __pyx_v_attach_new_osymbols;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("relabel_tables (wrapper)", 0);
@@ -27688,43 +27725,43 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_43relabel_tables(PyObject *__p
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_old_isymbols,&__pyx_n_s_new_isymbols,&__pyx_n_s_unknown_isymbol,&__pyx_n_s_attach_new_isymbols,&__pyx_n_s_old_osymbols,&__pyx_n_s_new_osymbols,&__pyx_n_s_unknown_osymbol,&__pyx_n_s_attach_new_osymbols,0};
     PyObject* values[8] = {0,0,0,0,0,0,0,0};
 
-    /* "pywrapfst.pyx":2523
+    /* "pywrapfst.pyx":2553
  * 
  *   def relabel_tables(self,
- *                      _SymbolTable old_isymbols=None,             # <<<<<<<<<<<<<<
- *                      _SymbolTable new_isymbols=None,
- *                      unknown_isymbol=b"",
+ *                      SymbolTableView old_isymbols=None,             # <<<<<<<<<<<<<<
+ *                      SymbolTableView new_isymbols=None,
+ *                      unknown_isymbol="",
  */
-    values[0] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
+    values[0] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-    /* "pywrapfst.pyx":2524
+    /* "pywrapfst.pyx":2554
  *   def relabel_tables(self,
- *                      _SymbolTable old_isymbols=None,
- *                      _SymbolTable new_isymbols=None,             # <<<<<<<<<<<<<<
- *                      unknown_isymbol=b"",
+ *                      SymbolTableView old_isymbols=None,
+ *                      SymbolTableView new_isymbols=None,             # <<<<<<<<<<<<<<
+ *                      unknown_isymbol="",
  *                      bool attach_new_isymbols=True,
  */
-    values[1] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
-    values[2] = ((PyObject *)__pyx_kp_b__8);
+    values[1] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
+    values[2] = ((PyObject *)__pyx_kp_u__11);
 
-    /* "pywrapfst.pyx":2527
- *                      unknown_isymbol=b"",
+    /* "pywrapfst.pyx":2557
+ *                      unknown_isymbol="",
  *                      bool attach_new_isymbols=True,
- *                      _SymbolTable old_osymbols=None,             # <<<<<<<<<<<<<<
- *                      _SymbolTable new_osymbols=None,
- *                      unknown_osymbol=b"",
+ *                      SymbolTableView old_osymbols=None,             # <<<<<<<<<<<<<<
+ *                      SymbolTableView new_osymbols=None,
+ *                      unknown_osymbol="",
  */
-    values[4] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
+    values[4] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
 
-    /* "pywrapfst.pyx":2528
+    /* "pywrapfst.pyx":2558
  *                      bool attach_new_isymbols=True,
- *                      _SymbolTable old_osymbols=None,
- *                      _SymbolTable new_osymbols=None,             # <<<<<<<<<<<<<<
- *                      unknown_osymbol=b"",
+ *                      SymbolTableView old_osymbols=None,
+ *                      SymbolTableView new_osymbols=None,             # <<<<<<<<<<<<<<
+ *                      unknown_osymbol="",
  *                      bool attach_new_osymbols=True):
  */
-    values[5] = (PyObject *)((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None);
-    values[6] = ((PyObject *)__pyx_kp_b__8);
+    values[5] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None);
+    values[6] = ((PyObject *)__pyx_kp_u__11);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -27799,7 +27836,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_43relabel_tables(PyObject *__p
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "relabel_tables") < 0)) __PYX_ERR(0, 2522, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "relabel_tables") < 0)) __PYX_ERR(0, 2552, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -27823,32 +27860,32 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_43relabel_tables(PyObject *__p
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_old_isymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[0]);
-    __pyx_v_new_isymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[1]);
+    __pyx_v_old_isymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)values[0]);
+    __pyx_v_new_isymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)values[1]);
     __pyx_v_unknown_isymbol = values[2];
     if (values[3]) {
-      __pyx_v_attach_new_isymbols = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_attach_new_isymbols == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2526, __pyx_L3_error)
+      __pyx_v_attach_new_isymbols = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_attach_new_isymbols == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2556, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2526
- *                      _SymbolTable new_isymbols=None,
- *                      unknown_isymbol=b"",
+      /* "pywrapfst.pyx":2556
+ *                      SymbolTableView new_isymbols=None,
+ *                      unknown_isymbol="",
  *                      bool attach_new_isymbols=True,             # <<<<<<<<<<<<<<
- *                      _SymbolTable old_osymbols=None,
- *                      _SymbolTable new_osymbols=None,
+ *                      SymbolTableView old_osymbols=None,
+ *                      SymbolTableView new_osymbols=None,
  */
       __pyx_v_attach_new_isymbols = ((bool)1);
     }
-    __pyx_v_old_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[4]);
-    __pyx_v_new_osymbols = ((struct __pyx_obj_9pywrapfst__SymbolTable *)values[5]);
+    __pyx_v_old_osymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)values[4]);
+    __pyx_v_new_osymbols = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)values[5]);
     __pyx_v_unknown_osymbol = values[6];
     if (values[7]) {
-      __pyx_v_attach_new_osymbols = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_attach_new_osymbols == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2530, __pyx_L3_error)
+      __pyx_v_attach_new_osymbols = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_attach_new_osymbols == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2560, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2530
- *                      _SymbolTable new_osymbols=None,
- *                      unknown_osymbol=b"",
+      /* "pywrapfst.pyx":2560
+ *                      SymbolTableView new_osymbols=None,
+ *                      unknown_osymbol="",
  *                      bool attach_new_osymbols=True):             # <<<<<<<<<<<<<<
  *     """
  *     relabel_tables(self, old_isymbols=None, new_isymbols=None,
@@ -27858,24 +27895,24 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_43relabel_tables(PyObject *__p
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("relabel_tables", 0, 0, 8, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2522, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("relabel_tables", 0, 0, 8, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2552, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.relabel_tables", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_old_isymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "old_isymbols", 0))) __PYX_ERR(0, 2523, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_isymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "new_isymbols", 0))) __PYX_ERR(0, 2524, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_old_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "old_osymbols", 0))) __PYX_ERR(0, 2527, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_osymbols), __pyx_ptype_9pywrapfst__SymbolTable, 1, "new_osymbols", 0))) __PYX_ERR(0, 2528, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_old_isymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "old_isymbols", 0))) __PYX_ERR(0, 2553, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_isymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "new_isymbols", 0))) __PYX_ERR(0, 2554, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_old_osymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "old_osymbols", 0))) __PYX_ERR(0, 2557, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_new_osymbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "new_osymbols", 0))) __PYX_ERR(0, 2558, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_42relabel_tables(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_old_isymbols, __pyx_v_new_isymbols, __pyx_v_unknown_isymbol, __pyx_v_attach_new_isymbols, __pyx_v_old_osymbols, __pyx_v_new_osymbols, __pyx_v_unknown_osymbol, __pyx_v_attach_new_osymbols);
 
-  /* "pywrapfst.pyx":2522
+  /* "pywrapfst.pyx":2552
  *     self._check_mutating_imethod()
  * 
  *   def relabel_tables(self,             # <<<<<<<<<<<<<<
- *                      _SymbolTable old_isymbols=None,
- *                      _SymbolTable new_isymbols=None,
+ *                      SymbolTableView old_isymbols=None,
+ *                      SymbolTableView new_isymbols=None,
  */
 
   /* function exit code */
@@ -27887,13 +27924,16 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_43relabel_tables(PyObject *__p
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_10MutableFst_42relabel_tables(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_new_isymbols, PyObject *__pyx_v_unknown_isymbol, bool __pyx_v_attach_new_isymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_old_osymbols, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_new_osymbols, PyObject *__pyx_v_unknown_osymbol, bool __pyx_v_attach_new_osymbols) {
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_42relabel_tables(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_old_isymbols, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_new_isymbols, PyObject *__pyx_v_unknown_isymbol, bool __pyx_v_attach_new_isymbols, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_old_osymbols, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_new_osymbols, PyObject *__pyx_v_unknown_osymbol, bool __pyx_v_attach_new_osymbols) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_10MutableFst__relabel_tables __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("relabel_tables", 0);
 
-  /* "pywrapfst.pyx":2564
+  /* "pywrapfst.pyx":2594
  *       FstArgError: No SymbolTable specified.
  *     """
  *     self._relabel_tables(old_isymbols,             # <<<<<<<<<<<<<<
@@ -27902,10 +27942,10 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_42relabel_tables(struct __pyx_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_relabel_tables");
-    __PYX_ERR(0, 2564, __pyx_L1_error)
+    __PYX_ERR(0, 2594, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2571
+  /* "pywrapfst.pyx":2601
  *                          new_osymbols,
  *                          unknown_osymbol,
  *                          attach_new_osymbols)             # <<<<<<<<<<<<<<
@@ -27921,9 +27961,9 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_42relabel_tables(struct __pyx_
   __pyx_t_1.new_osymbols = __pyx_v_new_osymbols;
   __pyx_t_1.unknown_osymbol = __pyx_v_unknown_osymbol;
   __pyx_t_1.attach_new_osymbols = __pyx_v_attach_new_osymbols;
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_relabel_tables(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2564, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_relabel_tables(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2594, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2572
+  /* "pywrapfst.pyx":2602
  *                          unknown_osymbol,
  *                          attach_new_osymbols)
  *     return self             # <<<<<<<<<<<<<<
@@ -27935,12 +27975,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_42relabel_tables(struct __pyx_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2522
+  /* "pywrapfst.pyx":2552
  *     self._check_mutating_imethod()
  * 
  *   def relabel_tables(self,             # <<<<<<<<<<<<<<
- *                      _SymbolTable old_isymbols=None,
- *                      _SymbolTable new_isymbols=None,
+ *                      SymbolTableView old_isymbols=None,
+ *                      SymbolTableView new_isymbols=None,
  */
 
   /* function exit code */
@@ -27953,7 +27993,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_42relabel_tables(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2574
+/* "pywrapfst.pyx":2604
  *     return self
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:             # <<<<<<<<<<<<<<
@@ -27967,9 +28007,12 @@ static void __pyx_f_9pywrapfst_10MutableFst__reserve_arcs(struct __pyx_obj_9pywr
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_reserve_arcs", 0);
 
-  /* "pywrapfst.pyx":2575
+  /* "pywrapfst.pyx":2605
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:
  *     if not self._mfst.get().ReserveArcs(state, n):             # <<<<<<<<<<<<<<
@@ -27978,19 +28021,19 @@ static void __pyx_f_9pywrapfst_10MutableFst__reserve_arcs(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2575, __pyx_L1_error)
+    __PYX_ERR(0, 2605, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->ReserveArcs(__pyx_v_state, __pyx_v_n) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2576
+    /* "pywrapfst.pyx":2606
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:
  *     if not self._mfst.get().ReserveArcs(state, n):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2576, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2606, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -28004,14 +28047,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__reserve_arcs(struct __pyx_obj_9pywr
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2576, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2606, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 2576, __pyx_L1_error)
+    __PYX_ERR(0, 2606, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2575
+    /* "pywrapfst.pyx":2605
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:
  *     if not self._mfst.get().ReserveArcs(state, n):             # <<<<<<<<<<<<<<
@@ -28020,7 +28063,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__reserve_arcs(struct __pyx_obj_9pywr
  */
   }
 
-  /* "pywrapfst.pyx":2577
+  /* "pywrapfst.pyx":2607
  *     if not self._mfst.get().ReserveArcs(state, n):
  *       raise FstIndexError("State index out of range")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
@@ -28029,11 +28072,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__reserve_arcs(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2577, __pyx_L1_error)
+    __PYX_ERR(0, 2607, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2577, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2607, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2574
+  /* "pywrapfst.pyx":2604
  *     return self
  * 
  *   cdef void _reserve_arcs(self, int64 state, size_t n) except *:             # <<<<<<<<<<<<<<
@@ -28052,7 +28095,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__reserve_arcs(struct __pyx_obj_9pywr
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2579
+/* "pywrapfst.pyx":2609
  *     self._check_mutating_imethod()
  * 
  *   def reserve_arcs(self, int64 state, size_t n):             # <<<<<<<<<<<<<<
@@ -28066,6 +28109,9 @@ static char __pyx_doc_9pywrapfst_10MutableFst_44reserve_arcs[] = "\n    reserve_
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_45reserve_arcs(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   int64 __pyx_v_state;
   size_t __pyx_v_n;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("reserve_arcs (wrapper)", 0);
@@ -28092,11 +28138,11 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_45reserve_arcs(PyObject *__pyx
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_n)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("reserve_arcs", 1, 2, 2, 1); __PYX_ERR(0, 2579, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("reserve_arcs", 1, 2, 2, 1); __PYX_ERR(0, 2609, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reserve_arcs") < 0)) __PYX_ERR(0, 2579, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reserve_arcs") < 0)) __PYX_ERR(0, 2609, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -28104,12 +28150,12 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_45reserve_arcs(PyObject *__pyx
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2579, __pyx_L3_error)
-    __pyx_v_n = __Pyx_PyInt_As_size_t(values[1]); if (unlikely((__pyx_v_n == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 2579, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2609, __pyx_L3_error)
+    __pyx_v_n = __Pyx_PyInt_As_size_t(values[1]); if (unlikely((__pyx_v_n == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 2609, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("reserve_arcs", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2579, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("reserve_arcs", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2609, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.reserve_arcs", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -28125,9 +28171,12 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_45reserve_arcs(PyObject *__pyx
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_44reserve_arcs(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state, size_t __pyx_v_n) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reserve_arcs", 0);
 
-  /* "pywrapfst.pyx":2595
+  /* "pywrapfst.pyx":2625
  *       FstIndexError: State index out of range.
  *     """
  *     self._reserve_arcs(state, n)             # <<<<<<<<<<<<<<
@@ -28136,11 +28185,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_44reserve_arcs(struct __pyx_ob
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reserve_arcs");
-    __PYX_ERR(0, 2595, __pyx_L1_error)
+    __PYX_ERR(0, 2625, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_reserve_arcs(__pyx_v_self, __pyx_v_state, __pyx_v_n); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2595, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_reserve_arcs(__pyx_v_self, __pyx_v_state, __pyx_v_n); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2625, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2596
+  /* "pywrapfst.pyx":2626
  *     """
  *     self._reserve_arcs(state, n)
  *     return self             # <<<<<<<<<<<<<<
@@ -28152,7 +28201,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_44reserve_arcs(struct __pyx_ob
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2579
+  /* "pywrapfst.pyx":2609
  *     self._check_mutating_imethod()
  * 
  *   def reserve_arcs(self, int64 state, size_t n):             # <<<<<<<<<<<<<<
@@ -28170,7 +28219,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_44reserve_arcs(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2598
+/* "pywrapfst.pyx":2628
  *     return self
  * 
  *   cdef void _reserve_states(self, int64 n):             # <<<<<<<<<<<<<<
@@ -28180,9 +28229,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_44reserve_arcs(struct __pyx_ob
 
 static void __pyx_f_9pywrapfst_10MutableFst__reserve_states(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_n) {
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_reserve_states", 0);
 
-  /* "pywrapfst.pyx":2599
+  /* "pywrapfst.pyx":2629
  * 
  *   cdef void _reserve_states(self, int64 n):
  *     self._mfst.get().ReserveStates(n)             # <<<<<<<<<<<<<<
@@ -28191,11 +28243,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__reserve_states(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2599, __pyx_L1_error)
+    __PYX_ERR(0, 2629, __pyx_L1_error)
   }
   __pyx_v_self->_mfst.get()->ReserveStates(__pyx_v_n);
 
-  /* "pywrapfst.pyx":2598
+  /* "pywrapfst.pyx":2628
  *     return self
  * 
  *   cdef void _reserve_states(self, int64 n):             # <<<<<<<<<<<<<<
@@ -28211,7 +28263,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__reserve_states(struct __pyx_obj_9py
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2601
+/* "pywrapfst.pyx":2631
  *     self._mfst.get().ReserveStates(n)
  * 
  *   def reserve_states(self, int64 n):             # <<<<<<<<<<<<<<
@@ -28224,11 +28276,14 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_47reserve_states(PyObject *__p
 static char __pyx_doc_9pywrapfst_10MutableFst_46reserve_states[] = "\n    reserve_states(self, n)\n\n    Reserve n states (best effort).\n\n    Args:\n      n: The number of states to reserve.\n\n    Returns:\n      self.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_47reserve_states(PyObject *__pyx_v_self, PyObject *__pyx_arg_n) {
   int64 __pyx_v_n;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("reserve_states (wrapper)", 0);
   assert(__pyx_arg_n); {
-    __pyx_v_n = __Pyx_PyInt_As_int64_t(__pyx_arg_n); if (unlikely((__pyx_v_n == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2601, __pyx_L3_error)
+    __pyx_v_n = __Pyx_PyInt_As_int64_t(__pyx_arg_n); if (unlikely((__pyx_v_n == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2631, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -28246,9 +28301,12 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_47reserve_states(PyObject *__p
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_46reserve_states(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_n) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reserve_states", 0);
 
-  /* "pywrapfst.pyx":2613
+  /* "pywrapfst.pyx":2643
  *       self.
  *     """
  *     self._reserve_states(n)             # <<<<<<<<<<<<<<
@@ -28257,11 +28315,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_46reserve_states(struct __pyx_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reserve_states");
-    __PYX_ERR(0, 2613, __pyx_L1_error)
+    __PYX_ERR(0, 2643, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_reserve_states(__pyx_v_self, __pyx_v_n);
 
-  /* "pywrapfst.pyx":2614
+  /* "pywrapfst.pyx":2644
  *     """
  *     self._reserve_states(n)
  *     return self             # <<<<<<<<<<<<<<
@@ -28273,7 +28331,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_46reserve_states(struct __pyx_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2601
+  /* "pywrapfst.pyx":2631
  *     self._mfst.get().ReserveStates(n)
  * 
  *   def reserve_states(self, int64 n):             # <<<<<<<<<<<<<<
@@ -28291,26 +28349,28 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_46reserve_states(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2616
+/* "pywrapfst.pyx":2646
  *     return self
  * 
  *   cdef void _reweight(self, potentials, bool to_final=False) except *:             # <<<<<<<<<<<<<<
- *     cdef unique_ptr[vector[fst.WeightClass]] _potentials
- *     _potentials.reset(new vector[fst.WeightClass]())
+ *     cdef string _weight_type = self.weight_type()
+ *     cdef vector[fst.WeightClass] _potentials
  */
 
 static void __pyx_f_9pywrapfst_10MutableFst__reweight(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, PyObject *__pyx_v_potentials, struct __pyx_opt_args_9pywrapfst_10MutableFst__reweight *__pyx_optional_args) {
   bool __pyx_v_to_final = ((bool)0);
-  std::unique_ptr<std::vector<fst::script::WeightClass> >  __pyx_v__potentials;
-  CYTHON_UNUSED std::string __pyx_v_weight_type;
+  std::string __pyx_v__weight_type;
+  std::vector<fst::script::WeightClass>  __pyx_v__potentials;
   PyObject *__pyx_v_weight = NULL;
   __Pyx_RefNannyDeclarations
-  std::vector<fst::script::WeightClass>  *__pyx_t_1;
-  PyObject *__pyx_t_2 = NULL;
-  Py_ssize_t __pyx_t_3;
-  PyObject *(*__pyx_t_4)(PyObject *);
-  PyObject *__pyx_t_5 = NULL;
-  fst::script::WeightClass __pyx_t_6;
+  PyObject *__pyx_t_1 = NULL;
+  Py_ssize_t __pyx_t_2;
+  PyObject *(*__pyx_t_3)(PyObject *);
+  PyObject *__pyx_t_4 = NULL;
+  fst::script::WeightClass __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_reweight", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -28318,182 +28378,139 @@ static void __pyx_f_9pywrapfst_10MutableFst__reweight(struct __pyx_obj_9pywrapfs
     }
   }
 
-  /* "pywrapfst.pyx":2618
+  /* "pywrapfst.pyx":2647
+ * 
  *   cdef void _reweight(self, potentials, bool to_final=False) except *:
- *     cdef unique_ptr[vector[fst.WeightClass]] _potentials
- *     _potentials.reset(new vector[fst.WeightClass]())             # <<<<<<<<<<<<<<
- *     cdef string weight_type = self.weight_type()
+ *     cdef string _weight_type = self.weight_type()             # <<<<<<<<<<<<<<
+ *     cdef vector[fst.WeightClass] _potentials
  *     for weight in potentials:
  */
-  try {
-    __pyx_t_1 = new std::vector<fst::script::WeightClass> ();
-  } catch(...) {
-    __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 2618, __pyx_L1_error)
-  }
-  __pyx_v__potentials.reset(__pyx_t_1);
-
-  /* "pywrapfst.pyx":2619
- *     cdef unique_ptr[vector[fst.WeightClass]] _potentials
- *     _potentials.reset(new vector[fst.WeightClass]())
- *     cdef string weight_type = self.weight_type()             # <<<<<<<<<<<<<<
- *     for weight in potentials:
- *         _potentials.get().push_back(_get_WeightClass_or_One(self.weight_type(),
- */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 2619, __pyx_L1_error)
+    __PYX_ERR(0, 2647, __pyx_L1_error)
   }
-  __pyx_v_weight_type = ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.weight_type(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), 0);
+  __pyx_v__weight_type = ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.weight_type(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), 0);
 
-  /* "pywrapfst.pyx":2620
- *     _potentials.reset(new vector[fst.WeightClass]())
- *     cdef string weight_type = self.weight_type()
+  /* "pywrapfst.pyx":2649
+ *     cdef string _weight_type = self.weight_type()
+ *     cdef vector[fst.WeightClass] _potentials
  *     for weight in potentials:             # <<<<<<<<<<<<<<
- *         _potentials.get().push_back(_get_WeightClass_or_One(self.weight_type(),
- *                                                             weight))
+ *       _potentials.push_back(_get_WeightClass_or_One(_weight_type, weight))
+ *     fst.Reweight(self._mfst.get(), _potentials, fst.GetReweightType(to_final))
  */
   if (likely(PyList_CheckExact(__pyx_v_potentials)) || PyTuple_CheckExact(__pyx_v_potentials)) {
-    __pyx_t_2 = __pyx_v_potentials; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
-    __pyx_t_4 = NULL;
+    __pyx_t_1 = __pyx_v_potentials; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+    __pyx_t_3 = NULL;
   } else {
-    __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_potentials); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2620, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2620, __pyx_L1_error)
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_potentials); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2649, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2649, __pyx_L1_error)
   }
   for (;;) {
-    if (likely(!__pyx_t_4)) {
-      if (likely(PyList_CheckExact(__pyx_t_2))) {
-        if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
+    if (likely(!__pyx_t_3)) {
+      if (likely(PyList_CheckExact(__pyx_t_1))) {
+        if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-        __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 2620, __pyx_L1_error)
+        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 2649, __pyx_L1_error)
         #else
-        __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2620, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_5);
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2649, __pyx_L1_error)
+        __Pyx_GOTREF(__pyx_t_4);
         #endif
       } else {
-        if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
+        if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-        __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 2620, __pyx_L1_error)
+        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 2649, __pyx_L1_error)
         #else
-        __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2620, __pyx_L1_error)
-        __Pyx_GOTREF(__pyx_t_5);
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2649, __pyx_L1_error)
+        __Pyx_GOTREF(__pyx_t_4);
         #endif
       }
     } else {
-      __pyx_t_5 = __pyx_t_4(__pyx_t_2);
-      if (unlikely(!__pyx_t_5)) {
+      __pyx_t_4 = __pyx_t_3(__pyx_t_1);
+      if (unlikely(!__pyx_t_4)) {
         PyObject* exc_type = PyErr_Occurred();
         if (exc_type) {
           if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-          else __PYX_ERR(0, 2620, __pyx_L1_error)
+          else __PYX_ERR(0, 2649, __pyx_L1_error)
         }
         break;
       }
-      __Pyx_GOTREF(__pyx_t_5);
-    }
-    __Pyx_XDECREF_SET(__pyx_v_weight, __pyx_t_5);
-    __pyx_t_5 = 0;
-
-    /* "pywrapfst.pyx":2621
- *     cdef string weight_type = self.weight_type()
- *     for weight in potentials:
- *         _potentials.get().push_back(_get_WeightClass_or_One(self.weight_type(),             # <<<<<<<<<<<<<<
- *                                                             weight))
- *     fst.Reweight(self._mfst.get(), deref(_potentials),
- */
-    if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
-      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-      __PYX_ERR(0, 2621, __pyx_L1_error)
+      __Pyx_GOTREF(__pyx_t_4);
     }
+    __Pyx_XDECREF_SET(__pyx_v_weight, __pyx_t_4);
+    __pyx_t_4 = 0;
 
-    /* "pywrapfst.pyx":2622
- *     for weight in potentials:
- *         _potentials.get().push_back(_get_WeightClass_or_One(self.weight_type(),
- *                                                             weight))             # <<<<<<<<<<<<<<
- *     fst.Reweight(self._mfst.get(), deref(_potentials),
- *                  fst.GetReweightType(to_final))
- */
-    __pyx_t_6 = __pyx_f_9pywrapfst__get_WeightClass_or_One(((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.weight_type(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2621, __pyx_L1_error)
-
-    /* "pywrapfst.pyx":2621
- *     cdef string weight_type = self.weight_type()
+    /* "pywrapfst.pyx":2650
+ *     cdef vector[fst.WeightClass] _potentials
  *     for weight in potentials:
- *         _potentials.get().push_back(_get_WeightClass_or_One(self.weight_type(),             # <<<<<<<<<<<<<<
- *                                                             weight))
- *     fst.Reweight(self._mfst.get(), deref(_potentials),
+ *       _potentials.push_back(_get_WeightClass_or_One(_weight_type, weight))             # <<<<<<<<<<<<<<
+ *     fst.Reweight(self._mfst.get(), _potentials, fst.GetReweightType(to_final))
+ *     self._check_mutating_imethod()
  */
+    __pyx_t_5 = __pyx_f_9pywrapfst__get_WeightClass_or_One(__pyx_v__weight_type, __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2650, __pyx_L1_error)
     try {
-      __pyx_v__potentials.get()->push_back(__pyx_t_6);
+      __pyx_v__potentials.push_back(__pyx_t_5);
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 2621, __pyx_L1_error)
+      __PYX_ERR(0, 2650, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":2620
- *     _potentials.reset(new vector[fst.WeightClass]())
- *     cdef string weight_type = self.weight_type()
+    /* "pywrapfst.pyx":2649
+ *     cdef string _weight_type = self.weight_type()
+ *     cdef vector[fst.WeightClass] _potentials
  *     for weight in potentials:             # <<<<<<<<<<<<<<
- *         _potentials.get().push_back(_get_WeightClass_or_One(self.weight_type(),
- *                                                             weight))
+ *       _potentials.push_back(_get_WeightClass_or_One(_weight_type, weight))
+ *     fst.Reweight(self._mfst.get(), _potentials, fst.GetReweightType(to_final))
  */
   }
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2623
- *         _potentials.get().push_back(_get_WeightClass_or_One(self.weight_type(),
- *                                                             weight))
- *     fst.Reweight(self._mfst.get(), deref(_potentials),             # <<<<<<<<<<<<<<
- *                  fst.GetReweightType(to_final))
+  /* "pywrapfst.pyx":2651
+ *     for weight in potentials:
+ *       _potentials.push_back(_get_WeightClass_or_One(_weight_type, weight))
+ *     fst.Reweight(self._mfst.get(), _potentials, fst.GetReweightType(to_final))             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
+ * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2623, __pyx_L1_error)
+    __PYX_ERR(0, 2651, __pyx_L1_error)
   }
+  fst::script::Reweight(__pyx_v_self->_mfst.get(), __pyx_v__potentials, fst::script::GetReweightType(__pyx_v_to_final));
 
-  /* "pywrapfst.pyx":2624
- *                                                             weight))
- *     fst.Reweight(self._mfst.get(), deref(_potentials),
- *                  fst.GetReweightType(to_final))             # <<<<<<<<<<<<<<
- *     self._check_mutating_imethod()
- * 
- */
-  fst::script::Reweight(__pyx_v_self->_mfst.get(), (*__pyx_v__potentials), fst::script::GetReweightType(__pyx_v_to_final));
-
-  /* "pywrapfst.pyx":2625
- *     fst.Reweight(self._mfst.get(), deref(_potentials),
- *                  fst.GetReweightType(to_final))
+  /* "pywrapfst.pyx":2652
+ *       _potentials.push_back(_get_WeightClass_or_One(_weight_type, weight))
+ *     fst.Reweight(self._mfst.get(), _potentials, fst.GetReweightType(to_final))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
  * 
  *   def reweight(self, potentials, bool to_final=False):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2625, __pyx_L1_error)
+    __PYX_ERR(0, 2652, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2625, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2652, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2616
+  /* "pywrapfst.pyx":2646
  *     return self
  * 
  *   cdef void _reweight(self, potentials, bool to_final=False) except *:             # <<<<<<<<<<<<<<
- *     cdef unique_ptr[vector[fst.WeightClass]] _potentials
- *     _potentials.reset(new vector[fst.WeightClass]())
+ *     cdef string _weight_type = self.weight_type()
+ *     cdef vector[fst.WeightClass] _potentials
  */
 
   /* function exit code */
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_4);
   __Pyx_AddTraceback("pywrapfst.MutableFst._reweight", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_L0:;
   __Pyx_XDECREF(__pyx_v_weight);
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2627
+/* "pywrapfst.pyx":2654
  *     self._check_mutating_imethod()
  * 
  *   def reweight(self, potentials, bool to_final=False):             # <<<<<<<<<<<<<<
@@ -28507,6 +28524,9 @@ static char __pyx_doc_9pywrapfst_10MutableFst_48reweight[] = "\n    reweight(sel
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_49reweight(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_potentials = 0;
   bool __pyx_v_to_final;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("reweight (wrapper)", 0);
@@ -28537,7 +28557,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_49reweight(PyObject *__pyx_v_s
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reweight") < 0)) __PYX_ERR(0, 2627, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reweight") < 0)) __PYX_ERR(0, 2654, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -28550,14 +28570,14 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_49reweight(PyObject *__pyx_v_s
     }
     __pyx_v_potentials = values[0];
     if (values[1]) {
-      __pyx_v_to_final = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_to_final == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2627, __pyx_L3_error)
+      __pyx_v_to_final = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_to_final == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2654, __pyx_L3_error)
     } else {
       __pyx_v_to_final = ((bool)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("reweight", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2627, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("reweight", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2654, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.reweight", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -28574,9 +28594,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_48reweight(struct __pyx_obj_9p
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_10MutableFst__reweight __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reweight", 0);
 
-  /* "pywrapfst.pyx":2649
+  /* "pywrapfst.pyx":2676
  *       self.
  *     """
  *     self._reweight(potentials, to_final)             # <<<<<<<<<<<<<<
@@ -28585,13 +28608,13 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_48reweight(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reweight");
-    __PYX_ERR(0, 2649, __pyx_L1_error)
+    __PYX_ERR(0, 2676, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 1;
   __pyx_t_1.to_final = __pyx_v_to_final;
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_reweight(__pyx_v_self, __pyx_v_potentials, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2649, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_reweight(__pyx_v_self, __pyx_v_potentials, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2676, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2650
+  /* "pywrapfst.pyx":2677
  *     """
  *     self._reweight(potentials, to_final)
  *     return self             # <<<<<<<<<<<<<<
@@ -28603,7 +28626,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_48reweight(struct __pyx_obj_9p
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2627
+  /* "pywrapfst.pyx":2654
  *     self._check_mutating_imethod()
  * 
  *   def reweight(self, potentials, bool to_final=False):             # <<<<<<<<<<<<<<
@@ -28621,42 +28644,45 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_48reweight(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2652
+/* "pywrapfst.pyx":2679
  *     return self
  * 
  *   cdef void _rmepsilon(self,             # <<<<<<<<<<<<<<
- *                        queue_type=b"auto",
+ *                        queue_type="auto",
  *                        bool connect=True,
  */
 
 static void __pyx_f_9pywrapfst_10MutableFst__rmepsilon(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_opt_args_9pywrapfst_10MutableFst__rmepsilon *__pyx_optional_args) {
-  PyObject *__pyx_v_queue_type = ((PyObject *)__pyx_n_b_auto);
+  PyObject *__pyx_v_queue_type = ((PyObject *)__pyx_n_u_auto);
 
-  /* "pywrapfst.pyx":2654
+  /* "pywrapfst.pyx":2681
  *   cdef void _rmepsilon(self,
- *                        queue_type=b"auto",
+ *                        queue_type="auto",
  *                        bool connect=True,             # <<<<<<<<<<<<<<
  *                        weight=None,
  *                        int64 nstate=fst.kNoStateId,
  */
   bool __pyx_v_connect = ((bool)1);
 
-  /* "pywrapfst.pyx":2655
- *                        queue_type=b"auto",
+  /* "pywrapfst.pyx":2682
+ *                        queue_type="auto",
  *                        bool connect=True,
  *                        weight=None,             # <<<<<<<<<<<<<<
  *                        int64 nstate=fst.kNoStateId,
  *                        float delta=fst.kShortestDelta) except *:
  */
   PyObject *__pyx_v_weight = ((PyObject *)Py_None);
-  int64 __pyx_v_nstate = __pyx_k__18;
-  float __pyx_v_delta = __pyx_k__19;
-  fst::script::WeightClass __pyx_v_wc;
-  std::unique_ptr<fst::script::RmEpsilonOptions>  __pyx_v_opts;
+  int64 __pyx_v_nstate = __pyx_k__20;
+  float __pyx_v_delta = __pyx_k__21;
+  fst::script::WeightClass __pyx_v__weight;
+  std::unique_ptr<fst::script::RmEpsilonOptions>  __pyx_v__opts;
   __Pyx_RefNannyDeclarations
   fst::script::WeightClass __pyx_t_1;
   std::string __pyx_t_2;
   enum fst::QueueType __pyx_t_3;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_rmepsilon", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -28676,78 +28702,78 @@ static void __pyx_f_9pywrapfst_10MutableFst__rmepsilon(struct __pyx_obj_9pywrapf
     }
   }
 
-  /* "pywrapfst.pyx":2658
+  /* "pywrapfst.pyx":2685
  *                        int64 nstate=fst.kNoStateId,
  *                        float delta=fst.kShortestDelta) except *:
- *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),             # <<<<<<<<<<<<<<
- *                                                        weight)
- *     cdef unique_ptr[fst.RmEpsilonOptions] opts
+ *     cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(self.weight_type(),             # <<<<<<<<<<<<<<
+ *                                                             weight)
+ *     cdef unique_ptr[fst.RmEpsilonOptions] _opts
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 2658, __pyx_L1_error)
+    __PYX_ERR(0, 2685, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2659
+  /* "pywrapfst.pyx":2686
  *                        float delta=fst.kShortestDelta) except *:
- *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),
- *                                                        weight)             # <<<<<<<<<<<<<<
- *     cdef unique_ptr[fst.RmEpsilonOptions] opts
- *     opts.reset(new fst.RmEpsilonOptions(_get_queue_type(tostring(queue_type)),
- */
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_Zero(((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.weight_type(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2658, __pyx_L1_error)
-  __pyx_v_wc = __pyx_t_1;
-
-  /* "pywrapfst.pyx":2661
- *                                                        weight)
- *     cdef unique_ptr[fst.RmEpsilonOptions] opts
- *     opts.reset(new fst.RmEpsilonOptions(_get_queue_type(tostring(queue_type)),             # <<<<<<<<<<<<<<
- *                                         connect,
- *                                         wc,
- */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2661, __pyx_L1_error)
-  __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2661, __pyx_L1_error)
-
-  /* "pywrapfst.pyx":2665
- *                                         wc,
- *                                         nstate,
- *                                         delta))             # <<<<<<<<<<<<<<
- *     fst.RmEpsilon(self._mfst.get(), deref(opts))
- *     self._check_mutating_imethod()
- */
-  __pyx_v_opts.reset(new fst::script::RmEpsilonOptions(__pyx_t_3, __pyx_v_connect, __pyx_v_wc, __pyx_v_nstate, __pyx_v_delta));
-
-  /* "pywrapfst.pyx":2666
- *                                         nstate,
- *                                         delta))
- *     fst.RmEpsilon(self._mfst.get(), deref(opts))             # <<<<<<<<<<<<<<
+ *     cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(self.weight_type(),
+ *                                                             weight)             # <<<<<<<<<<<<<<
+ *     cdef unique_ptr[fst.RmEpsilonOptions] _opts
+ *     _opts.reset(
+ */
+  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_Zero(((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.weight_type(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2685, __pyx_L1_error)
+  __pyx_v__weight = __pyx_t_1;
+
+  /* "pywrapfst.pyx":2689
+ *     cdef unique_ptr[fst.RmEpsilonOptions] _opts
+ *     _opts.reset(
+ *         new fst.RmEpsilonOptions(_get_queue_type(tostring(queue_type)),             # <<<<<<<<<<<<<<
+ *                                  connect,
+ *                                  _weight,
+ */
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2689, __pyx_L1_error)
+  __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2689, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":2688
+ *                                                             weight)
+ *     cdef unique_ptr[fst.RmEpsilonOptions] _opts
+ *     _opts.reset(             # <<<<<<<<<<<<<<
+ *         new fst.RmEpsilonOptions(_get_queue_type(tostring(queue_type)),
+ *                                  connect,
+ */
+  __pyx_v__opts.reset(new fst::script::RmEpsilonOptions(__pyx_t_3, __pyx_v_connect, __pyx_v__weight, __pyx_v_nstate, __pyx_v_delta));
+
+  /* "pywrapfst.pyx":2694
+ *                                  nstate,
+ *                                  delta))
+ *     fst.RmEpsilon(self._mfst.get(), deref(_opts))             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2666, __pyx_L1_error)
+    __PYX_ERR(0, 2694, __pyx_L1_error)
   }
-  fst::script::RmEpsilon(__pyx_v_self->_mfst.get(), (*__pyx_v_opts));
+  fst::script::RmEpsilon(__pyx_v_self->_mfst.get(), (*__pyx_v__opts));
 
-  /* "pywrapfst.pyx":2667
- *                                         delta))
- *     fst.RmEpsilon(self._mfst.get(), deref(opts))
+  /* "pywrapfst.pyx":2695
+ *                                  delta))
+ *     fst.RmEpsilon(self._mfst.get(), deref(_opts))
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
  * 
  *   def rmepsilon(self,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2667, __pyx_L1_error)
+    __PYX_ERR(0, 2695, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2667, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2695, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2652
+  /* "pywrapfst.pyx":2679
  *     return self
  * 
  *   cdef void _rmepsilon(self,             # <<<<<<<<<<<<<<
- *                        queue_type=b"auto",
+ *                        queue_type="auto",
  *                        bool connect=True,
  */
 
@@ -28759,11 +28785,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__rmepsilon(struct __pyx_obj_9pywrapf
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2669
+/* "pywrapfst.pyx":2697
  *     self._check_mutating_imethod()
  * 
  *   def rmepsilon(self,             # <<<<<<<<<<<<<<
- *                 queue_type=b"auto",
+ *                 queue_type="auto",
  *                 bool connect=True,
  */
 
@@ -28776,16 +28802,19 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_51rmepsilon(PyObject *__pyx_v_
   PyObject *__pyx_v_weight = 0;
   int64 __pyx_v_nstate;
   float __pyx_v_delta;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("rmepsilon (wrapper)", 0);
   {
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_queue_type,&__pyx_n_s_connect,&__pyx_n_s_weight,&__pyx_n_s_nstate,&__pyx_n_s_delta,0};
     PyObject* values[5] = {0,0,0,0,0};
-    values[0] = ((PyObject *)__pyx_n_b_auto);
+    values[0] = ((PyObject *)__pyx_n_u_auto);
 
-    /* "pywrapfst.pyx":2672
- *                 queue_type=b"auto",
+    /* "pywrapfst.pyx":2700
+ *                 queue_type="auto",
  *                 bool connect=True,
  *                 weight=None,             # <<<<<<<<<<<<<<
  *                 int64 nstate=fst.kNoStateId,
@@ -28842,7 +28871,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_51rmepsilon(PyObject *__pyx_v_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "rmepsilon") < 0)) __PYX_ERR(0, 2669, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "rmepsilon") < 0)) __PYX_ERR(0, 2697, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -28862,12 +28891,12 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_51rmepsilon(PyObject *__pyx_v_
     }
     __pyx_v_queue_type = values[0];
     if (values[1]) {
-      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2671, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2699, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":2671
+      /* "pywrapfst.pyx":2699
  *   def rmepsilon(self,
- *                 queue_type=b"auto",
+ *                 queue_type="auto",
  *                 bool connect=True,             # <<<<<<<<<<<<<<
  *                 weight=None,
  *                 int64 nstate=fst.kNoStateId,
@@ -28876,19 +28905,19 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_51rmepsilon(PyObject *__pyx_v_
     }
     __pyx_v_weight = values[2];
     if (values[3]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2673, __pyx_L3_error)
+      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2701, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__20;
+      __pyx_v_nstate = __pyx_k__22;
     }
     if (values[4]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[4]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2674, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[4]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 2702, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__21;
+      __pyx_v_delta = __pyx_k__23;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("rmepsilon", 0, 0, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2669, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("rmepsilon", 0, 0, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2697, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.rmepsilon", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -28896,11 +28925,11 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_51rmepsilon(PyObject *__pyx_v_
   __pyx_L4_argument_unpacking_done:;
   __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_50rmepsilon(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), __pyx_v_queue_type, __pyx_v_connect, __pyx_v_weight, __pyx_v_nstate, __pyx_v_delta);
 
-  /* "pywrapfst.pyx":2669
+  /* "pywrapfst.pyx":2697
  *     self._check_mutating_imethod()
  * 
  *   def rmepsilon(self,             # <<<<<<<<<<<<<<
- *                 queue_type=b"auto",
+ *                 queue_type="auto",
  *                 bool connect=True,
  */
 
@@ -28913,9 +28942,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_50rmepsilon(struct __pyx_obj_9
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_10MutableFst__rmepsilon __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("rmepsilon", 0);
 
-  /* "pywrapfst.pyx":2696
+  /* "pywrapfst.pyx":2724
  *       self.
  *     """
  *     self._rmepsilon(queue_type, connect, weight, nstate, delta)             # <<<<<<<<<<<<<<
@@ -28924,7 +28956,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_50rmepsilon(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_rmepsilon");
-    __PYX_ERR(0, 2696, __pyx_L1_error)
+    __PYX_ERR(0, 2724, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 5;
   __pyx_t_1.queue_type = __pyx_v_queue_type;
@@ -28932,9 +28964,9 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_50rmepsilon(struct __pyx_obj_9
   __pyx_t_1.weight = __pyx_v_weight;
   __pyx_t_1.nstate = __pyx_v_nstate;
   __pyx_t_1.delta = __pyx_v_delta;
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_rmepsilon(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2696, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_rmepsilon(__pyx_v_self, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2724, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2697
+  /* "pywrapfst.pyx":2725
  *     """
  *     self._rmepsilon(queue_type, connect, weight, nstate, delta)
  *     return self             # <<<<<<<<<<<<<<
@@ -28946,11 +28978,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_50rmepsilon(struct __pyx_obj_9
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2669
+  /* "pywrapfst.pyx":2697
  *     self._check_mutating_imethod()
  * 
  *   def rmepsilon(self,             # <<<<<<<<<<<<<<
- *                 queue_type=b"auto",
+ *                 queue_type="auto",
  *                 bool connect=True,
  */
 
@@ -28964,7 +28996,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_50rmepsilon(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2699
+/* "pywrapfst.pyx":2727
  *     return self
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:             # <<<<<<<<<<<<<<
@@ -28974,13 +29006,16 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_50rmepsilon(struct __pyx_obj_9
 
 static void __pyx_f_9pywrapfst_10MutableFst__set_final(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state, struct __pyx_opt_args_9pywrapfst_10MutableFst__set_final *__pyx_optional_args) {
   PyObject *__pyx_v_weight = ((PyObject *)Py_None);
-  fst::script::WeightClass __pyx_v_wc;
+  fst::script::WeightClass __pyx_v__weight;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   fst::script::WeightClass __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_set_final", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -28988,28 +29023,28 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_final(struct __pyx_obj_9pywrapf
     }
   }
 
-  /* "pywrapfst.pyx":2700
+  /* "pywrapfst.pyx":2728
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:
  *     if not self._mfst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
  *       raise FstIndexError("State index out of range")
- *     cdef fst.WeightClass wc = _get_WeightClass_or_One(self.weight_type(),
+ *     cdef fst.WeightClass _weight = _get_WeightClass_or_One(self.weight_type(),
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2700, __pyx_L1_error)
+    __PYX_ERR(0, 2728, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->ValidStateId(__pyx_v_state) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2701
+    /* "pywrapfst.pyx":2729
  *   cdef void _set_final(self, int64 state, weight=None) except *:
  *     if not self._mfst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
- *     cdef fst.WeightClass wc = _get_WeightClass_or_One(self.weight_type(),
- *                                                       weight)
+ *     cdef fst.WeightClass _weight = _get_WeightClass_or_One(self.weight_type(),
+ *                                                           weight)
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2701, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2729, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -29023,66 +29058,66 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_final(struct __pyx_obj_9pywrapf
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2701, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2729, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 2701, __pyx_L1_error)
+    __PYX_ERR(0, 2729, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2700
+    /* "pywrapfst.pyx":2728
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:
  *     if not self._mfst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
  *       raise FstIndexError("State index out of range")
- *     cdef fst.WeightClass wc = _get_WeightClass_or_One(self.weight_type(),
+ *     cdef fst.WeightClass _weight = _get_WeightClass_or_One(self.weight_type(),
  */
   }
 
-  /* "pywrapfst.pyx":2702
+  /* "pywrapfst.pyx":2730
  *     if not self._mfst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")
- *     cdef fst.WeightClass wc = _get_WeightClass_or_One(self.weight_type(),             # <<<<<<<<<<<<<<
- *                                                       weight)
- *     if not self._mfst.get().SetFinal(state, wc):
+ *     cdef fst.WeightClass _weight = _get_WeightClass_or_One(self.weight_type(),             # <<<<<<<<<<<<<<
+ *                                                           weight)
+ *     if not self._mfst.get().SetFinal(state, _weight):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 2702, __pyx_L1_error)
+    __PYX_ERR(0, 2730, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2703
+  /* "pywrapfst.pyx":2731
  *       raise FstIndexError("State index out of range")
- *     cdef fst.WeightClass wc = _get_WeightClass_or_One(self.weight_type(),
- *                                                       weight)             # <<<<<<<<<<<<<<
- *     if not self._mfst.get().SetFinal(state, wc):
+ *     cdef fst.WeightClass _weight = _get_WeightClass_or_One(self.weight_type(),
+ *                                                           weight)             # <<<<<<<<<<<<<<
+ *     if not self._mfst.get().SetFinal(state, _weight):
  *       raise FstOpError("Incompatible or invalid weight")
  */
-  __pyx_t_5 = __pyx_f_9pywrapfst__get_WeightClass_or_One(((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.weight_type(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2702, __pyx_L1_error)
-  __pyx_v_wc = __pyx_t_5;
+  __pyx_t_5 = __pyx_f_9pywrapfst__get_WeightClass_or_One(((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.weight_type(((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_self), 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2730, __pyx_L1_error)
+  __pyx_v__weight = __pyx_t_5;
 
-  /* "pywrapfst.pyx":2704
- *     cdef fst.WeightClass wc = _get_WeightClass_or_One(self.weight_type(),
- *                                                       weight)
- *     if not self._mfst.get().SetFinal(state, wc):             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":2732
+ *     cdef fst.WeightClass _weight = _get_WeightClass_or_One(self.weight_type(),
+ *                                                           weight)
+ *     if not self._mfst.get().SetFinal(state, _weight):             # <<<<<<<<<<<<<<
  *       raise FstOpError("Incompatible or invalid weight")
  *     self._check_mutating_imethod()
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2704, __pyx_L1_error)
+    __PYX_ERR(0, 2732, __pyx_L1_error)
   }
-  __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->SetFinal(__pyx_v_state, __pyx_v_wc) != 0)) != 0);
+  __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->SetFinal(__pyx_v_state, __pyx_v__weight) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2705
- *                                                       weight)
- *     if not self._mfst.get().SetFinal(state, wc):
+    /* "pywrapfst.pyx":2733
+ *                                                           weight)
+ *     if not self._mfst.get().SetFinal(state, _weight):
  *       raise FstOpError("Incompatible or invalid weight")             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2705, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2733, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -29096,24 +29131,24 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_final(struct __pyx_obj_9pywrapf
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Incompatible_or_invalid_weight) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Incompatible_or_invalid_weight);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2705, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2733, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 2705, __pyx_L1_error)
+    __PYX_ERR(0, 2733, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2704
- *     cdef fst.WeightClass wc = _get_WeightClass_or_One(self.weight_type(),
- *                                                       weight)
- *     if not self._mfst.get().SetFinal(state, wc):             # <<<<<<<<<<<<<<
+    /* "pywrapfst.pyx":2732
+ *     cdef fst.WeightClass _weight = _get_WeightClass_or_One(self.weight_type(),
+ *                                                           weight)
+ *     if not self._mfst.get().SetFinal(state, _weight):             # <<<<<<<<<<<<<<
  *       raise FstOpError("Incompatible or invalid weight")
  *     self._check_mutating_imethod()
  */
   }
 
-  /* "pywrapfst.pyx":2706
- *     if not self._mfst.get().SetFinal(state, wc):
+  /* "pywrapfst.pyx":2734
+ *     if not self._mfst.get().SetFinal(state, _weight):
  *       raise FstOpError("Incompatible or invalid weight")
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
  * 
@@ -29121,11 +29156,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_final(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2706, __pyx_L1_error)
+    __PYX_ERR(0, 2734, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2706, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2734, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2699
+  /* "pywrapfst.pyx":2727
  *     return self
  * 
  *   cdef void _set_final(self, int64 state, weight=None) except *:             # <<<<<<<<<<<<<<
@@ -29144,7 +29179,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_final(struct __pyx_obj_9pywrapf
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2708
+/* "pywrapfst.pyx":2736
  *     self._check_mutating_imethod()
  * 
  *   def set_final(self, int64 state, weight=None):             # <<<<<<<<<<<<<<
@@ -29158,6 +29193,9 @@ static char __pyx_doc_9pywrapfst_10MutableFst_52set_final[] = "\n    set_final(s
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_53set_final(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   int64 __pyx_v_state;
   PyObject *__pyx_v_weight = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_final (wrapper)", 0);
@@ -29189,7 +29227,7 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_53set_final(PyObject *__pyx_v_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_final") < 0)) __PYX_ERR(0, 2708, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_final") < 0)) __PYX_ERR(0, 2736, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -29200,12 +29238,12 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_53set_final(PyObject *__pyx_v_
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2708, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2736, __pyx_L3_error)
     __pyx_v_weight = values[1];
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("set_final", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2708, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_final", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2736, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.set_final", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -29222,9 +29260,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_52set_final(struct __pyx_obj_9
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   struct __pyx_opt_args_9pywrapfst_10MutableFst__set_final __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_final", 0);
 
-  /* "pywrapfst.pyx":2726
+  /* "pywrapfst.pyx":2754
  *       FstOpError: Incompatible or invalid weight.
  *     """
  *     self._set_final(state, weight)             # <<<<<<<<<<<<<<
@@ -29233,25 +29274,25 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_52set_final(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_final");
-    __PYX_ERR(0, 2726, __pyx_L1_error)
+    __PYX_ERR(0, 2754, __pyx_L1_error)
   }
   __pyx_t_1.__pyx_n = 1;
   __pyx_t_1.weight = __pyx_v_weight;
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_final(__pyx_v_self, __pyx_v_state, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2726, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_final(__pyx_v_self, __pyx_v_state, &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2754, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2727
+  /* "pywrapfst.pyx":2755
  *     """
  *     self._set_final(state, weight)
  *     return self             # <<<<<<<<<<<<<<
  * 
- *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
+ *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2708
+  /* "pywrapfst.pyx":2736
  *     self._check_mutating_imethod()
  * 
  *   def set_final(self, int64 state, weight=None):             # <<<<<<<<<<<<<<
@@ -29269,86 +29310,89 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_52set_final(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2729
+/* "pywrapfst.pyx":2757
  *     return self
  * 
- *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
- *     if syms is None:
+ *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:             # <<<<<<<<<<<<<<
+ *     if symbols is None:
  *       self._mfst.get().SetInputSymbols(NULL)
  */
 
-static void __pyx_f_9pywrapfst_10MutableFst__set_input_symbols(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
+static void __pyx_f_9pywrapfst_10MutableFst__set_input_symbols(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols) {
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   int __pyx_t_2;
   fst::SymbolTable const *__pyx_t_3;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_set_input_symbols", 0);
 
-  /* "pywrapfst.pyx":2730
+  /* "pywrapfst.pyx":2758
  * 
- *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
- *     if syms is None:             # <<<<<<<<<<<<<<
+ *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:
+ *     if symbols is None:             # <<<<<<<<<<<<<<
  *       self._mfst.get().SetInputSymbols(NULL)
  *       return
  */
-  __pyx_t_1 = (((PyObject *)__pyx_v_syms) == Py_None);
+  __pyx_t_1 = (((PyObject *)__pyx_v_symbols) == Py_None);
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2731
- *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
- *     if syms is None:
+    /* "pywrapfst.pyx":2759
+ *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:
+ *     if symbols is None:
  *       self._mfst.get().SetInputSymbols(NULL)             # <<<<<<<<<<<<<<
  *       return
- *     self._mfst.get().SetInputSymbols(syms._raw_ptr_or_raise())
+ *     self._mfst.get().SetInputSymbols(symbols._raw_ptr_or_raise())
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 2731, __pyx_L1_error)
+      __PYX_ERR(0, 2759, __pyx_L1_error)
     }
     __pyx_v_self->_mfst.get()->SetInputSymbols(NULL);
 
-    /* "pywrapfst.pyx":2732
- *     if syms is None:
+    /* "pywrapfst.pyx":2760
+ *     if symbols is None:
  *       self._mfst.get().SetInputSymbols(NULL)
  *       return             # <<<<<<<<<<<<<<
- *     self._mfst.get().SetInputSymbols(syms._raw_ptr_or_raise())
+ *     self._mfst.get().SetInputSymbols(symbols._raw_ptr_or_raise())
  * 
  */
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2730
+    /* "pywrapfst.pyx":2758
  * 
- *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:
- *     if syms is None:             # <<<<<<<<<<<<<<
+ *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:
+ *     if symbols is None:             # <<<<<<<<<<<<<<
  *       self._mfst.get().SetInputSymbols(NULL)
  *       return
  */
   }
 
-  /* "pywrapfst.pyx":2733
+  /* "pywrapfst.pyx":2761
  *       self._mfst.get().SetInputSymbols(NULL)
  *       return
- *     self._mfst.get().SetInputSymbols(syms._raw_ptr_or_raise())             # <<<<<<<<<<<<<<
+ *     self._mfst.get().SetInputSymbols(symbols._raw_ptr_or_raise())             # <<<<<<<<<<<<<<
  * 
- *   def set_input_symbols(self, _SymbolTable syms):
+ *   def set_input_symbols(self, SymbolTableView symbols):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2733, __pyx_L1_error)
+    __PYX_ERR(0, 2761, __pyx_L1_error)
   }
-  if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v_symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 2733, __pyx_L1_error)
+    __PYX_ERR(0, 2761, __pyx_L1_error)
   }
-  __pyx_t_3 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_syms->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_syms); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2733, __pyx_L1_error)
+  __pyx_t_3 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_symbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2761, __pyx_L1_error)
   __pyx_v_self->_mfst.get()->SetInputSymbols(__pyx_t_3);
 
-  /* "pywrapfst.pyx":2729
+  /* "pywrapfst.pyx":2757
  *     return self
  * 
- *   cdef void _set_input_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
- *     if syms is None:
+ *   cdef void _set_input_symbols(self, SymbolTableView symbols) except *:             # <<<<<<<<<<<<<<
+ *     if symbols is None:
  *       self._mfst.get().SetInputSymbols(NULL)
  */
 
@@ -29360,23 +29404,26 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_input_symbols(struct __pyx_obj_
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2735
- *     self._mfst.get().SetInputSymbols(syms._raw_ptr_or_raise())
+/* "pywrapfst.pyx":2763
+ *     self._mfst.get().SetInputSymbols(symbols._raw_ptr_or_raise())
  * 
- *   def set_input_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
+ *   def set_input_symbols(self, SymbolTableView symbols):             # <<<<<<<<<<<<<<
  *     """
- *     set_input_symbols(self, syms)
+ *     set_input_symbols(self, symbols)
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_10MutableFst_55set_input_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
-static char __pyx_doc_9pywrapfst_10MutableFst_54set_input_symbols[] = "\n    set_input_symbols(self, syms)\n\n    Sets the input symbol table.\n\n    Passing None as a value will delete the input symbol table.\n\n    Args:\n      syms: A SymbolTable.\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_10MutableFst_55set_input_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_55set_input_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_symbols); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_54set_input_symbols[] = "\n    set_input_symbols(self, symbols)\n\n    Sets the input symbol table.\n\n    Passing None as a value will delete the input symbol table.\n\n    Args:\n      symbols: A SymbolTable.\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_55set_input_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_symbols) {
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_input_symbols (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 2735, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_54set_input_symbols(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_syms));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_symbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "symbols", 0))) __PYX_ERR(0, 2763, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_54set_input_symbols(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_symbols));
 
   /* function exit code */
   goto __pyx_L0;
@@ -29387,42 +29434,45 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_55set_input_symbols(PyObject *
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_10MutableFst_54set_input_symbols(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_54set_input_symbols(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_input_symbols", 0);
 
-  /* "pywrapfst.pyx":2749
+  /* "pywrapfst.pyx":2777
  *       self.
  *     """
- *     self._set_input_symbols(syms)             # <<<<<<<<<<<<<<
+ *     self._set_input_symbols(symbols)             # <<<<<<<<<<<<<<
  *     return self
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_input_symbols");
-    __PYX_ERR(0, 2749, __pyx_L1_error)
+    __PYX_ERR(0, 2777, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_input_symbols(__pyx_v_self, __pyx_v_syms); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2749, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_input_symbols(__pyx_v_self, __pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2777, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2750
+  /* "pywrapfst.pyx":2778
  *     """
- *     self._set_input_symbols(syms)
+ *     self._set_input_symbols(symbols)
  *     return self             # <<<<<<<<<<<<<<
  * 
- *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
+ *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:
  */
   __Pyx_XDECREF(__pyx_r);
   __Pyx_INCREF(((PyObject *)__pyx_v_self));
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2735
- *     self._mfst.get().SetInputSymbols(syms._raw_ptr_or_raise())
+  /* "pywrapfst.pyx":2763
+ *     self._mfst.get().SetInputSymbols(symbols._raw_ptr_or_raise())
  * 
- *   def set_input_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
+ *   def set_input_symbols(self, SymbolTableView symbols):             # <<<<<<<<<<<<<<
  *     """
- *     set_input_symbols(self, syms)
+ *     set_input_symbols(self, symbols)
  */
 
   /* function exit code */
@@ -29435,86 +29485,89 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_54set_input_symbols(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2752
+/* "pywrapfst.pyx":2780
  *     return self
  * 
- *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
- *     if syms is None:
+ *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:             # <<<<<<<<<<<<<<
+ *     if symbols is None:
  *       self._mfst.get().SetOutputSymbols(NULL)
  */
 
-static void __pyx_f_9pywrapfst_10MutableFst__set_output_symbols(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
+static void __pyx_f_9pywrapfst_10MutableFst__set_output_symbols(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols) {
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   int __pyx_t_2;
   fst::SymbolTable const *__pyx_t_3;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_set_output_symbols", 0);
 
-  /* "pywrapfst.pyx":2753
+  /* "pywrapfst.pyx":2781
  * 
- *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
- *     if syms is None:             # <<<<<<<<<<<<<<
+ *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:
+ *     if symbols is None:             # <<<<<<<<<<<<<<
  *       self._mfst.get().SetOutputSymbols(NULL)
  *       return
  */
-  __pyx_t_1 = (((PyObject *)__pyx_v_syms) == Py_None);
+  __pyx_t_1 = (((PyObject *)__pyx_v_symbols) == Py_None);
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":2754
- *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
- *     if syms is None:
+    /* "pywrapfst.pyx":2782
+ *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:
+ *     if symbols is None:
  *       self._mfst.get().SetOutputSymbols(NULL)             # <<<<<<<<<<<<<<
  *       return
- *     self._mfst.get().SetOutputSymbols(syms._raw_ptr_or_raise())
+ *     self._mfst.get().SetOutputSymbols(symbols._raw_ptr_or_raise())
  */
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-      __PYX_ERR(0, 2754, __pyx_L1_error)
+      __PYX_ERR(0, 2782, __pyx_L1_error)
     }
     __pyx_v_self->_mfst.get()->SetOutputSymbols(NULL);
 
-    /* "pywrapfst.pyx":2755
- *     if syms is None:
+    /* "pywrapfst.pyx":2783
+ *     if symbols is None:
  *       self._mfst.get().SetOutputSymbols(NULL)
  *       return             # <<<<<<<<<<<<<<
- *     self._mfst.get().SetOutputSymbols(syms._raw_ptr_or_raise())
+ *     self._mfst.get().SetOutputSymbols(symbols._raw_ptr_or_raise())
  * 
  */
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2753
+    /* "pywrapfst.pyx":2781
  * 
- *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:
- *     if syms is None:             # <<<<<<<<<<<<<<
+ *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:
+ *     if symbols is None:             # <<<<<<<<<<<<<<
  *       self._mfst.get().SetOutputSymbols(NULL)
  *       return
  */
   }
 
-  /* "pywrapfst.pyx":2756
+  /* "pywrapfst.pyx":2784
  *       self._mfst.get().SetOutputSymbols(NULL)
  *       return
- *     self._mfst.get().SetOutputSymbols(syms._raw_ptr_or_raise())             # <<<<<<<<<<<<<<
+ *     self._mfst.get().SetOutputSymbols(symbols._raw_ptr_or_raise())             # <<<<<<<<<<<<<<
  * 
- *   def set_output_symbols(self, _SymbolTable syms):
+ *   def set_output_symbols(self, SymbolTableView symbols):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2756, __pyx_L1_error)
+    __PYX_ERR(0, 2784, __pyx_L1_error)
   }
-  if (unlikely(((PyObject *)__pyx_v_syms) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v_symbols) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-    __PYX_ERR(0, 2756, __pyx_L1_error)
+    __PYX_ERR(0, 2784, __pyx_L1_error)
   }
-  __pyx_t_3 = ((struct __pyx_vtabstruct_9pywrapfst__SymbolTable *)__pyx_v_syms->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_syms); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2756, __pyx_L1_error)
+  __pyx_t_3 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTableView *)__pyx_v_symbols->__pyx_vtab)->_raw_ptr_or_raise(__pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2784, __pyx_L1_error)
   __pyx_v_self->_mfst.get()->SetOutputSymbols(__pyx_t_3);
 
-  /* "pywrapfst.pyx":2752
+  /* "pywrapfst.pyx":2780
  *     return self
  * 
- *   cdef void _set_output_symbols(self, _SymbolTable syms) except *:             # <<<<<<<<<<<<<<
- *     if syms is None:
+ *   cdef void _set_output_symbols(self, SymbolTableView symbols) except *:             # <<<<<<<<<<<<<<
+ *     if symbols is None:
  *       self._mfst.get().SetOutputSymbols(NULL)
  */
 
@@ -29526,23 +29579,26 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_output_symbols(struct __pyx_obj
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2758
- *     self._mfst.get().SetOutputSymbols(syms._raw_ptr_or_raise())
+/* "pywrapfst.pyx":2786
+ *     self._mfst.get().SetOutputSymbols(symbols._raw_ptr_or_raise())
  * 
- *   def set_output_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
+ *   def set_output_symbols(self, SymbolTableView symbols):             # <<<<<<<<<<<<<<
  *     """
- *     set_output_symbols(self, syms)
+ *     set_output_symbols(self, symbols)
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_10MutableFst_57set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms); /*proto*/
-static char __pyx_doc_9pywrapfst_10MutableFst_56set_output_symbols[] = "\n    set_output_symbols(self, syms)\n\n    Sets the output symbol table.\n\n    Passing None as a value will delete the output symbol table.\n\n    Args:\n      syms: A SymbolTable.\n\n    Returns:\n      self.\n    ";
-static PyObject *__pyx_pw_9pywrapfst_10MutableFst_57set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_syms) {
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_57set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_symbols); /*proto*/
+static char __pyx_doc_9pywrapfst_10MutableFst_56set_output_symbols[] = "\n    set_output_symbols(self, symbols)\n\n    Sets the output symbol table.\n\n    Passing None as a value will delete the output symbol table.\n\n    Args:\n      symbols: A SymbolTable.\n\n    Returns:\n      self.\n    ";
+static PyObject *__pyx_pw_9pywrapfst_10MutableFst_57set_output_symbols(PyObject *__pyx_v_self, PyObject *__pyx_v_symbols) {
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_output_symbols (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_syms), __pyx_ptype_9pywrapfst__SymbolTable, 1, "syms", 0))) __PYX_ERR(0, 2758, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_56set_output_symbols(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_syms));
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_symbols), __pyx_ptype_9pywrapfst_SymbolTableView, 1, "symbols", 0))) __PYX_ERR(0, 2786, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_10MutableFst_56set_output_symbols(((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_symbols));
 
   /* function exit code */
   goto __pyx_L0;
@@ -29553,27 +29609,30 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_57set_output_symbols(PyObject
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_10MutableFst_56set_output_symbols(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst__SymbolTable *__pyx_v_syms) {
+static PyObject *__pyx_pf_9pywrapfst_10MutableFst_56set_output_symbols(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, struct __pyx_obj_9pywrapfst_SymbolTableView *__pyx_v_symbols) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_output_symbols", 0);
 
-  /* "pywrapfst.pyx":2772
+  /* "pywrapfst.pyx":2800
  *       self.
  *     """
- *     self._set_output_symbols(syms)             # <<<<<<<<<<<<<<
+ *     self._set_output_symbols(symbols)             # <<<<<<<<<<<<<<
  *     return self
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_output_symbols");
-    __PYX_ERR(0, 2772, __pyx_L1_error)
+    __PYX_ERR(0, 2800, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_output_symbols(__pyx_v_self, __pyx_v_syms); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2772, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_output_symbols(__pyx_v_self, __pyx_v_symbols); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2800, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2773
+  /* "pywrapfst.pyx":2801
  *     """
- *     self._set_output_symbols(syms)
+ *     self._set_output_symbols(symbols)
  *     return self             # <<<<<<<<<<<<<<
  * 
  *   cdef void _set_properties(self, uint64 props, uint64 mask):
@@ -29583,12 +29642,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_56set_output_symbols(struct __
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2758
- *     self._mfst.get().SetOutputSymbols(syms._raw_ptr_or_raise())
+  /* "pywrapfst.pyx":2786
+ *     self._mfst.get().SetOutputSymbols(symbols._raw_ptr_or_raise())
  * 
- *   def set_output_symbols(self, _SymbolTable syms):             # <<<<<<<<<<<<<<
+ *   def set_output_symbols(self, SymbolTableView symbols):             # <<<<<<<<<<<<<<
  *     """
- *     set_output_symbols(self, syms)
+ *     set_output_symbols(self, symbols)
  */
 
   /* function exit code */
@@ -29601,7 +29660,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_56set_output_symbols(struct __
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2775
+/* "pywrapfst.pyx":2803
  *     return self
  * 
  *   cdef void _set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
@@ -29611,9 +29670,12 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_56set_output_symbols(struct __
 
 static void __pyx_f_9pywrapfst_10MutableFst__set_properties(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, uint64 __pyx_v_props, uint64 __pyx_v_mask) {
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_set_properties", 0);
 
-  /* "pywrapfst.pyx":2776
+  /* "pywrapfst.pyx":2804
  * 
  *   cdef void _set_properties(self, uint64 props, uint64 mask):
  *     self._mfst.get().SetProperties(props, mask)             # <<<<<<<<<<<<<<
@@ -29622,11 +29684,11 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_properties(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2776, __pyx_L1_error)
+    __PYX_ERR(0, 2804, __pyx_L1_error)
   }
   __pyx_v_self->_mfst.get()->SetProperties(__pyx_v_props, __pyx_v_mask);
 
-  /* "pywrapfst.pyx":2775
+  /* "pywrapfst.pyx":2803
  *     return self
  * 
  *   cdef void _set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
@@ -29642,7 +29704,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_properties(struct __pyx_obj_9py
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2778
+/* "pywrapfst.pyx":2806
  *     self._mfst.get().SetProperties(props, mask)
  * 
  *   def set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
@@ -29656,6 +29718,9 @@ static char __pyx_doc_9pywrapfst_10MutableFst_58set_properties[] = "\n    set_pr
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_59set_properties(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   uint64 __pyx_v_props;
   uint64 __pyx_v_mask;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_properties (wrapper)", 0);
@@ -29682,11 +29747,11 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_59set_properties(PyObject *__p
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mask)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("set_properties", 1, 2, 2, 1); __PYX_ERR(0, 2778, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("set_properties", 1, 2, 2, 1); __PYX_ERR(0, 2806, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_properties") < 0)) __PYX_ERR(0, 2778, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_properties") < 0)) __PYX_ERR(0, 2806, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -29694,12 +29759,12 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_59set_properties(PyObject *__p
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
-    __pyx_v_props = __Pyx_PyInt_As_uint64_t(values[0]); if (unlikely((__pyx_v_props == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2778, __pyx_L3_error)
-    __pyx_v_mask = __Pyx_PyInt_As_uint64_t(values[1]); if (unlikely((__pyx_v_mask == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2778, __pyx_L3_error)
+    __pyx_v_props = __Pyx_PyInt_As_uint64_t(values[0]); if (unlikely((__pyx_v_props == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2806, __pyx_L3_error)
+    __pyx_v_mask = __Pyx_PyInt_As_uint64_t(values[1]); if (unlikely((__pyx_v_mask == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2806, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("set_properties", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2778, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_properties", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2806, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableFst.set_properties", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -29715,9 +29780,12 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_59set_properties(PyObject *__p
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_58set_properties(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, uint64 __pyx_v_props, uint64 __pyx_v_mask) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_properties", 0);
 
-  /* "pywrapfst.pyx":2792
+  /* "pywrapfst.pyx":2820
  *       self.
  *     """
  *     self._set_properties(props, mask)             # <<<<<<<<<<<<<<
@@ -29726,11 +29794,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_58set_properties(struct __pyx_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_properties");
-    __PYX_ERR(0, 2792, __pyx_L1_error)
+    __PYX_ERR(0, 2820, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_properties(__pyx_v_self, __pyx_v_props, __pyx_v_mask);
 
-  /* "pywrapfst.pyx":2793
+  /* "pywrapfst.pyx":2821
  *     """
  *     self._set_properties(props, mask)
  *     return self             # <<<<<<<<<<<<<<
@@ -29742,7 +29810,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_58set_properties(struct __pyx_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2778
+  /* "pywrapfst.pyx":2806
  *     self._mfst.get().SetProperties(props, mask)
  * 
  *   def set_properties(self, uint64 props, uint64 mask):             # <<<<<<<<<<<<<<
@@ -29760,7 +29828,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_58set_properties(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2795
+/* "pywrapfst.pyx":2823
  *     return self
  * 
  *   cdef void _set_start(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -29774,9 +29842,12 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_start(struct __pyx_obj_9pywrapf
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_set_start", 0);
 
-  /* "pywrapfst.pyx":2796
+  /* "pywrapfst.pyx":2824
  * 
  *   cdef void _set_start(self, int64 state) except *:
  *     if not self._mfst.get().SetStart(state):             # <<<<<<<<<<<<<<
@@ -29785,19 +29856,19 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_start(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2796, __pyx_L1_error)
+    __PYX_ERR(0, 2824, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_self->_mfst.get()->SetStart(__pyx_v_state) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2797
+    /* "pywrapfst.pyx":2825
  *   cdef void _set_start(self, int64 state) except *:
  *     if not self._mfst.get().SetStart(state):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  * 
  *   def set_start(self, int64 state):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2797, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2825, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -29811,14 +29882,14 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_start(struct __pyx_obj_9pywrapf
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2797, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2825, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 2797, __pyx_L1_error)
+    __PYX_ERR(0, 2825, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2796
+    /* "pywrapfst.pyx":2824
  * 
  *   cdef void _set_start(self, int64 state) except *:
  *     if not self._mfst.get().SetStart(state):             # <<<<<<<<<<<<<<
@@ -29827,7 +29898,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_start(struct __pyx_obj_9pywrapf
  */
   }
 
-  /* "pywrapfst.pyx":2795
+  /* "pywrapfst.pyx":2823
  *     return self
  * 
  *   cdef void _set_start(self, int64 state) except *:             # <<<<<<<<<<<<<<
@@ -29846,7 +29917,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__set_start(struct __pyx_obj_9pywrapf
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2799
+/* "pywrapfst.pyx":2827
  *       raise FstIndexError("State index out of range")
  * 
  *   def set_start(self, int64 state):             # <<<<<<<<<<<<<<
@@ -29859,11 +29930,14 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_61set_start(PyObject *__pyx_v_
 static char __pyx_doc_9pywrapfst_10MutableFst_60set_start[] = "\n    set_start(self, state)\n\n    Sets a state to be the initial state state.\n\n    Args:\n      state: The integer index of a state.\n\n    Returns:\n      self.\n\n    Raises:\n      FstIndexError: State index out of range.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_10MutableFst_61set_start(PyObject *__pyx_v_self, PyObject *__pyx_arg_state) {
   int64 __pyx_v_state;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_start (wrapper)", 0);
   assert(__pyx_arg_state); {
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2799, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(__pyx_arg_state); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 2827, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -29881,9 +29955,12 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_61set_start(PyObject *__pyx_v_
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_60set_start(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, int64 __pyx_v_state) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_start", 0);
 
-  /* "pywrapfst.pyx":2814
+  /* "pywrapfst.pyx":2842
  *       FstIndexError: State index out of range.
  *     """
  *     self._set_start(state)             # <<<<<<<<<<<<<<
@@ -29892,11 +29969,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_60set_start(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_set_start");
-    __PYX_ERR(0, 2814, __pyx_L1_error)
+    __PYX_ERR(0, 2842, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_start(__pyx_v_self, __pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2814, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_set_start(__pyx_v_self, __pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2842, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2815
+  /* "pywrapfst.pyx":2843
  *     """
  *     self._set_start(state)
  *     return self             # <<<<<<<<<<<<<<
@@ -29908,7 +29985,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_60set_start(struct __pyx_obj_9
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2799
+  /* "pywrapfst.pyx":2827
  *       raise FstIndexError("State index out of range")
  * 
  *   def set_start(self, int64 state):             # <<<<<<<<<<<<<<
@@ -29926,7 +30003,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_60set_start(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2817
+/* "pywrapfst.pyx":2845
  *     return self
  * 
  *   cdef void _topsort(self):             # <<<<<<<<<<<<<<
@@ -29940,9 +30017,12 @@ static void __pyx_f_9pywrapfst_10MutableFst__topsort(struct __pyx_obj_9pywrapfst
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_topsort", 0);
 
-  /* "pywrapfst.pyx":2819
+  /* "pywrapfst.pyx":2847
  *   cdef void _topsort(self):
  *     # TopSort returns False if the FST is cyclic, and thus can't be TopSorted.
  *     if not fst.TopSort(self._mfst.get()):             # <<<<<<<<<<<<<<
@@ -29951,21 +30031,21 @@ static void __pyx_f_9pywrapfst_10MutableFst__topsort(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2819, __pyx_L1_error)
+    __PYX_ERR(0, 2847, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(fst::script::TopSort(__pyx_v_self->_mfst.get()) != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2820
+    /* "pywrapfst.pyx":2848
  *     # TopSort returns False if the FST is cyclic, and thus can't be TopSorted.
  *     if not fst.TopSort(self._mfst.get()):
  *       logging.warning("Cannot topsort cyclic FST")             # <<<<<<<<<<<<<<
  * 
  *   def topsort(self):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_logging); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2820, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_logging); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2848, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_warning); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2820, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_warning); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2848, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __pyx_t_3 = NULL;
@@ -29980,12 +30060,12 @@ static void __pyx_f_9pywrapfst_10MutableFst__topsort(struct __pyx_obj_9pywrapfst
     }
     __pyx_t_2 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_3, __pyx_kp_u_Cannot_topsort_cyclic_FST) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_Cannot_topsort_cyclic_FST);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2820, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2848, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-    /* "pywrapfst.pyx":2819
+    /* "pywrapfst.pyx":2847
  *   cdef void _topsort(self):
  *     # TopSort returns False if the FST is cyclic, and thus can't be TopSorted.
  *     if not fst.TopSort(self._mfst.get()):             # <<<<<<<<<<<<<<
@@ -29994,7 +30074,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__topsort(struct __pyx_obj_9pywrapfst
  */
   }
 
-  /* "pywrapfst.pyx":2817
+  /* "pywrapfst.pyx":2845
  *     return self
  * 
  *   cdef void _topsort(self):             # <<<<<<<<<<<<<<
@@ -30013,7 +30093,7 @@ static void __pyx_f_9pywrapfst_10MutableFst__topsort(struct __pyx_obj_9pywrapfst
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":2822
+/* "pywrapfst.pyx":2850
  *       logging.warning("Cannot topsort cyclic FST")
  * 
  *   def topsort(self):             # <<<<<<<<<<<<<<
@@ -30038,9 +30118,12 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_63topsort(PyObject *__pyx_v_se
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_62topsort(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("topsort", 0);
 
-  /* "pywrapfst.pyx":2835
+  /* "pywrapfst.pyx":2863
  *        self.
  *     """
  *     self._topsort()             # <<<<<<<<<<<<<<
@@ -30049,11 +30132,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_62topsort(struct __pyx_obj_9py
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_topsort");
-    __PYX_ERR(0, 2835, __pyx_L1_error)
+    __PYX_ERR(0, 2863, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_topsort(__pyx_v_self);
 
-  /* "pywrapfst.pyx":2836
+  /* "pywrapfst.pyx":2864
  *     """
  *     self._topsort()
  *     return self             # <<<<<<<<<<<<<<
@@ -30065,7 +30148,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_62topsort(struct __pyx_obj_9py
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2822
+  /* "pywrapfst.pyx":2850
  *       logging.warning("Cannot topsort cyclic FST")
  * 
  *   def topsort(self):             # <<<<<<<<<<<<<<
@@ -30083,7 +30166,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_62topsort(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2838
+/* "pywrapfst.pyx":2866
  *     return self
  * 
  *   def union(self, *fsts2):             # <<<<<<<<<<<<<<
@@ -30111,78 +30194,81 @@ static PyObject *__pyx_pw_9pywrapfst_10MutableFst_65union(PyObject *__pyx_v_self
 }
 
 static PyObject *__pyx_pf_9pywrapfst_10MutableFst_64union(struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_self, PyObject *__pyx_v_fsts2) {
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v__fst2 = 0;
   std::vector<__pyx_t_9pywrapfst_const_FstClass_ptr>  __pyx_v__fsts2;
-  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_fst2 = 0;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   Py_ssize_t __pyx_t_2;
   PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("union", 0);
 
-  /* "pywrapfst.pyx":2856
+  /* "pywrapfst.pyx":2884
+ *     cdef Fst _fst2
  *     cdef vector[const_FstClass_ptr] _fsts2
- *     cdef Fst fst2
- *     for fst2 in fsts2:             # <<<<<<<<<<<<<<
- *       _fsts2.push_back(fst2._fst.get())
+ *     for _fst2 in fsts2:             # <<<<<<<<<<<<<<
+ *       _fsts2.push_back(_fst2._fst.get())
  *     fst.Union(self._mfst.get(), _fsts2)
  */
   __pyx_t_1 = __pyx_v_fsts2; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
   for (;;) {
     if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
     #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-    __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 2856, __pyx_L1_error)
+    __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 2884, __pyx_L1_error)
     #else
-    __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2856, __pyx_L1_error)
+    __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2884, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     #endif
-    if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 2856, __pyx_L1_error)
-    __Pyx_XDECREF_SET(__pyx_v_fst2, ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_3));
+    if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 2884, __pyx_L1_error)
+    __Pyx_XDECREF_SET(__pyx_v__fst2, ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_3));
     __pyx_t_3 = 0;
 
-    /* "pywrapfst.pyx":2857
- *     cdef Fst fst2
- *     for fst2 in fsts2:
- *       _fsts2.push_back(fst2._fst.get())             # <<<<<<<<<<<<<<
+    /* "pywrapfst.pyx":2885
+ *     cdef vector[const_FstClass_ptr] _fsts2
+ *     for _fst2 in fsts2:
+ *       _fsts2.push_back(_fst2._fst.get())             # <<<<<<<<<<<<<<
  *     fst.Union(self._mfst.get(), _fsts2)
  *     self._check_mutating_imethod()
  */
-    if (unlikely(((PyObject *)__pyx_v_fst2) == Py_None)) {
+    if (unlikely(((PyObject *)__pyx_v__fst2) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 2857, __pyx_L1_error)
+      __PYX_ERR(0, 2885, __pyx_L1_error)
     }
     try {
-      __pyx_v__fsts2.push_back(__pyx_v_fst2->_fst.get());
+      __pyx_v__fsts2.push_back(__pyx_v__fst2->_fst.get());
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 2857, __pyx_L1_error)
+      __PYX_ERR(0, 2885, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":2856
+    /* "pywrapfst.pyx":2884
+ *     cdef Fst _fst2
  *     cdef vector[const_FstClass_ptr] _fsts2
- *     cdef Fst fst2
- *     for fst2 in fsts2:             # <<<<<<<<<<<<<<
- *       _fsts2.push_back(fst2._fst.get())
+ *     for _fst2 in fsts2:             # <<<<<<<<<<<<<<
+ *       _fsts2.push_back(_fst2._fst.get())
  *     fst.Union(self._mfst.get(), _fsts2)
  */
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":2858
- *     for fst2 in fsts2:
- *       _fsts2.push_back(fst2._fst.get())
+  /* "pywrapfst.pyx":2886
+ *     for _fst2 in fsts2:
+ *       _fsts2.push_back(_fst2._fst.get())
  *     fst.Union(self._mfst.get(), _fsts2)             # <<<<<<<<<<<<<<
  *     self._check_mutating_imethod()
  *     return self
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2858, __pyx_L1_error)
+    __PYX_ERR(0, 2886, __pyx_L1_error)
   }
   fst::script::Union(__pyx_v_self->_mfst.get(), __pyx_v__fsts2);
 
-  /* "pywrapfst.pyx":2859
- *       _fsts2.push_back(fst2._fst.get())
+  /* "pywrapfst.pyx":2887
+ *       _fsts2.push_back(_fst2._fst.get())
  *     fst.Union(self._mfst.get(), _fsts2)
  *     self._check_mutating_imethod()             # <<<<<<<<<<<<<<
  *     return self
@@ -30190,11 +30276,11 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_64union(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_check_mutating_imethod");
-    __PYX_ERR(0, 2859, __pyx_L1_error)
+    __PYX_ERR(0, 2887, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2859, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_MutableFst *)__pyx_v_self->__pyx_base.__pyx_vtab)->_check_mutating_imethod(__pyx_v_self); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2887, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":2860
+  /* "pywrapfst.pyx":2888
  *     fst.Union(self._mfst.get(), _fsts2)
  *     self._check_mutating_imethod()
  *     return self             # <<<<<<<<<<<<<<
@@ -30206,7 +30292,7 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_64union(struct __pyx_obj_9pywr
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2838
+  /* "pywrapfst.pyx":2866
  *     return self
  * 
  *   def union(self, *fsts2):             # <<<<<<<<<<<<<<
@@ -30221,31 +30307,34 @@ static PyObject *__pyx_pf_9pywrapfst_10MutableFst_64union(struct __pyx_obj_9pywr
   __Pyx_AddTraceback("pywrapfst.MutableFst.union", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_fst2);
+  __Pyx_XDECREF((PyObject *)__pyx_v__fst2);
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2876
+/* "pywrapfst.pyx":2904
  *   """
  * 
- *   def __init__(self, arc_type=b"standard"):             # <<<<<<<<<<<<<<
- *     cdef unique_ptr[fst.MutableFstClass] tfst
- *     tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
+ *   def __init__(self, arc_type="standard"):             # <<<<<<<<<<<<<<
+ *     cdef unique_ptr[fst.MutableFstClass] _tfst
+ *     _tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
  */
 
 /* Python wrapper */
 static int __pyx_pw_9pywrapfst_9VectorFst_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static int __pyx_pw_9pywrapfst_9VectorFst_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_arc_type = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
   {
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_arc_type,0};
     PyObject* values[1] = {0};
-    values[0] = ((PyObject *)__pyx_n_b_standard);
+    values[0] = ((PyObject *)__pyx_n_u_standard);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -30264,7 +30353,7 @@ static int __pyx_pw_9pywrapfst_9VectorFst_1__init__(PyObject *__pyx_v_self, PyOb
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 2876, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 2904, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -30278,7 +30367,7 @@ static int __pyx_pw_9pywrapfst_9VectorFst_1__init__(PyObject *__pyx_v_self, PyOb
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2876, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2904, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.VectorFst.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -30292,7 +30381,7 @@ static int __pyx_pw_9pywrapfst_9VectorFst_1__init__(PyObject *__pyx_v_self, PyOb
 }
 
 static int __pyx_pf_9pywrapfst_9VectorFst___init__(struct __pyx_obj_9pywrapfst_VectorFst *__pyx_v_self, PyObject *__pyx_v_arc_type) {
-  std::unique_ptr<fst::script::MutableFstClass>  __pyx_v_tfst;
+  std::unique_ptr<fst::script::MutableFstClass>  __pyx_v__tfst;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
@@ -30301,99 +30390,89 @@ static int __pyx_pf_9pywrapfst_9VectorFst___init__(struct __pyx_obj_9pywrapfst_V
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":2878
- *   def __init__(self, arc_type=b"standard"):
- *     cdef unique_ptr[fst.MutableFstClass] tfst
- *     tfst.reset(new fst.VectorFstClass(tostring(arc_type)))             # <<<<<<<<<<<<<<
- *     if tfst.get().Properties(fst.kError, True) == fst.kError:
- *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
+  /* "pywrapfst.pyx":2906
+ *   def __init__(self, arc_type="standard"):
+ *     cdef unique_ptr[fst.MutableFstClass] _tfst
+ *     _tfst.reset(new fst.VectorFstClass(tostring(arc_type)))             # <<<<<<<<<<<<<<
+ *     if _tfst.get().Properties(fst.kError, True) == fst.kError:
+ *       raise FstOpError(f"Unknown arc type: {arc_type!r}")
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2878, __pyx_L1_error)
-  __pyx_v_tfst.reset(new fst::script::VectorFstClass(__pyx_t_1));
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2906, __pyx_L1_error)
+  __pyx_v__tfst.reset(new fst::script::VectorFstClass(__pyx_t_1));
 
-  /* "pywrapfst.pyx":2879
- *     cdef unique_ptr[fst.MutableFstClass] tfst
- *     tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
- *     if tfst.get().Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
- *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
- *     self._fst.reset(tfst.release())
+  /* "pywrapfst.pyx":2907
+ *     cdef unique_ptr[fst.MutableFstClass] _tfst
+ *     _tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
+ *     if _tfst.get().Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
+ *       raise FstOpError(f"Unknown arc type: {arc_type!r}")
+ *     self._fst.reset(_tfst.release())
  */
-  __pyx_t_2 = ((__pyx_v_tfst.get()->Properties(fst::kError, 1) == fst::kError) != 0);
+  __pyx_t_2 = ((__pyx_v__tfst.get()->Properties(fst::kError, 1) == fst::kError) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":2880
- *     tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
- *     if tfst.get().Properties(fst.kError, True) == fst.kError:
- *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))             # <<<<<<<<<<<<<<
- *     self._fst.reset(tfst.release())
+    /* "pywrapfst.pyx":2908
+ *     _tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
+ *     if _tfst.get().Properties(fst.kError, True) == fst.kError:
+ *       raise FstOpError(f"Unknown arc type: {arc_type!r}")             # <<<<<<<<<<<<<<
+ *     self._fst.reset(_tfst.release())
  *     self._mfst = static_pointer_cast[fst.MutableFstClass,
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2880, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2908, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_arc_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2880, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
-        __Pyx_INCREF(__pyx_t_7);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_6, function);
-      }
-    }
-    __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_arc_type) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_arc_type);
-    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2880, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_arc_type), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2908, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = NULL;
+    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_arc_type, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2908, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
-      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
-      if (likely(__pyx_t_6)) {
+      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+      if (likely(__pyx_t_5)) {
         PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-        __Pyx_INCREF(__pyx_t_6);
+        __Pyx_INCREF(__pyx_t_5);
         __Pyx_INCREF(function);
         __Pyx_DECREF_SET(__pyx_t_4, function);
       }
     }
-    __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2880, __pyx_L1_error)
+    __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
+    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2908, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2880, __pyx_L1_error)
+    __PYX_ERR(0, 2908, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2879
- *     cdef unique_ptr[fst.MutableFstClass] tfst
- *     tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
- *     if tfst.get().Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
- *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
- *     self._fst.reset(tfst.release())
+    /* "pywrapfst.pyx":2907
+ *     cdef unique_ptr[fst.MutableFstClass] _tfst
+ *     _tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
+ *     if _tfst.get().Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
+ *       raise FstOpError(f"Unknown arc type: {arc_type!r}")
+ *     self._fst.reset(_tfst.release())
  */
   }
 
-  /* "pywrapfst.pyx":2881
- *     if tfst.get().Properties(fst.kError, True) == fst.kError:
- *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
- *     self._fst.reset(tfst.release())             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":2909
+ *     if _tfst.get().Properties(fst.kError, True) == fst.kError:
+ *       raise FstOpError(f"Unknown arc type: {arc_type!r}")
+ *     self._fst.reset(_tfst.release())             # <<<<<<<<<<<<<<
  *     self._mfst = static_pointer_cast[fst.MutableFstClass,
  *                                      fst.FstClass](self._fst)
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2881, __pyx_L1_error)
+    __PYX_ERR(0, 2909, __pyx_L1_error)
   }
-  __pyx_v_self->__pyx_base.__pyx_base._fst.reset(__pyx_v_tfst.release());
+  __pyx_v_self->__pyx_base.__pyx_base._fst.reset(__pyx_v__tfst.release());
 
-  /* "pywrapfst.pyx":2883
- *     self._fst.reset(tfst.release())
+  /* "pywrapfst.pyx":2911
+ *     self._fst.reset(_tfst.release())
  *     self._mfst = static_pointer_cast[fst.MutableFstClass,
  *                                      fst.FstClass](self._fst)             # <<<<<<<<<<<<<<
  * 
@@ -30401,28 +30480,28 @@ static int __pyx_pf_9pywrapfst_9VectorFst___init__(struct __pyx_obj_9pywrapfst_V
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2883, __pyx_L1_error)
+    __PYX_ERR(0, 2911, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":2882
- *       raise FstOpError("Unknown arc type: {!r}".format(arc_type))
- *     self._fst.reset(tfst.release())
+  /* "pywrapfst.pyx":2910
+ *       raise FstOpError(f"Unknown arc type: {arc_type!r}")
+ *     self._fst.reset(_tfst.release())
  *     self._mfst = static_pointer_cast[fst.MutableFstClass,             # <<<<<<<<<<<<<<
  *                                      fst.FstClass](self._fst)
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2882, __pyx_L1_error)
+    __PYX_ERR(0, 2910, __pyx_L1_error)
   }
   __pyx_v_self->__pyx_base._mfst = std::static_pointer_cast<fst::script::MutableFstClass,fst::script::FstClass>(__pyx_v_self->__pyx_base.__pyx_base._fst);
 
-  /* "pywrapfst.pyx":2876
+  /* "pywrapfst.pyx":2904
  *   """
  * 
- *   def __init__(self, arc_type=b"standard"):             # <<<<<<<<<<<<<<
- *     cdef unique_ptr[fst.MutableFstClass] tfst
- *     tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
+ *   def __init__(self, arc_type="standard"):             # <<<<<<<<<<<<<<
+ *     cdef unique_ptr[fst.MutableFstClass] _tfst
+ *     _tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
  */
 
   /* function exit code */
@@ -30433,7 +30512,6 @@ static int __pyx_pf_9pywrapfst_9VectorFst___init__(struct __pyx_obj_9pywrapfst_V
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_AddTraceback("pywrapfst.VectorFst.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = -1;
   __pyx_L0:;
@@ -30441,7 +30519,7 @@ static int __pyx_pf_9pywrapfst_9VectorFst___init__(struct __pyx_obj_9pywrapfst_V
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2902
+/* "pywrapfst.pyx":2930
  * 
  * 
  * cdef Fst _init_Fst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -30450,33 +30528,36 @@ static int __pyx_pf_9pywrapfst_9VectorFst___init__(struct __pyx_obj_9pywrapfst_V
  */
 
 static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9pywrapfst_FstClass_ptr __pyx_v_tfst) {
-  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ofst = 0;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v__ofst = 0;
   struct __pyx_obj_9pywrapfst_Fst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_init_Fst", 0);
 
-  /* "pywrapfst.pyx":2903
+  /* "pywrapfst.pyx":2931
  * 
  * cdef Fst _init_Fst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
  *     raise FstOpError("Operation failed")
- *   cdef Fst ofst = Fst.__new__(Fst)
+ *   cdef Fst _ofst = Fst.__new__(Fst)
  */
   __pyx_t_1 = ((__pyx_v_tfst->Properties(fst::kError, 1) == fst::kError) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2904
+    /* "pywrapfst.pyx":2932
  * cdef Fst _init_Fst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:
  *     raise FstOpError("Operation failed")             # <<<<<<<<<<<<<<
- *   cdef Fst ofst = Fst.__new__(Fst)
- *   ofst._fst.reset(tfst)
+ *   cdef Fst _ofst = Fst.__new__(Fst)
+ *   _ofst._fst.reset(tfst)
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2904, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2932, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -30490,60 +30571,60 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9py
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Operation_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Operation_failed);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2904, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2932, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 2904, __pyx_L1_error)
+    __PYX_ERR(0, 2932, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2903
+    /* "pywrapfst.pyx":2931
  * 
  * cdef Fst _init_Fst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
  *     raise FstOpError("Operation failed")
- *   cdef Fst ofst = Fst.__new__(Fst)
+ *   cdef Fst _ofst = Fst.__new__(Fst)
  */
   }
 
-  /* "pywrapfst.pyx":2905
+  /* "pywrapfst.pyx":2933
  *   if tfst.Properties(fst.kError, True) == fst.kError:
  *     raise FstOpError("Operation failed")
- *   cdef Fst ofst = Fst.__new__(Fst)             # <<<<<<<<<<<<<<
- *   ofst._fst.reset(tfst)
- *   return ofst
+ *   cdef Fst _ofst = Fst.__new__(Fst)             # <<<<<<<<<<<<<<
+ *   _ofst._fst.reset(tfst)
+ *   return _ofst
  */
-  __pyx_t_2 = ((PyObject *)__pyx_tp_new_9pywrapfst_Fst(((PyTypeObject *)__pyx_ptype_9pywrapfst_Fst), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2905, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_tp_new_9pywrapfst_Fst(((PyTypeObject *)__pyx_ptype_9pywrapfst_Fst), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2933, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_2));
-  __pyx_v_ofst = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_2);
+  __pyx_v__ofst = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_2);
   __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2906
+  /* "pywrapfst.pyx":2934
  *     raise FstOpError("Operation failed")
- *   cdef Fst ofst = Fst.__new__(Fst)
- *   ofst._fst.reset(tfst)             # <<<<<<<<<<<<<<
- *   return ofst
+ *   cdef Fst _ofst = Fst.__new__(Fst)
+ *   _ofst._fst.reset(tfst)             # <<<<<<<<<<<<<<
+ *   return _ofst
  * 
  */
-  if (unlikely(((PyObject *)__pyx_v_ofst) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__ofst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2906, __pyx_L1_error)
+    __PYX_ERR(0, 2934, __pyx_L1_error)
   }
-  __pyx_v_ofst->_fst.reset(__pyx_v_tfst);
+  __pyx_v__ofst->_fst.reset(__pyx_v_tfst);
 
-  /* "pywrapfst.pyx":2907
- *   cdef Fst ofst = Fst.__new__(Fst)
- *   ofst._fst.reset(tfst)
- *   return ofst             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":2935
+ *   cdef Fst _ofst = Fst.__new__(Fst)
+ *   _ofst._fst.reset(tfst)
+ *   return _ofst             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __Pyx_INCREF(((PyObject *)__pyx_v_ofst));
-  __pyx_r = __pyx_v_ofst;
+  __Pyx_INCREF(((PyObject *)__pyx_v__ofst));
+  __pyx_r = __pyx_v__ofst;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2902
+  /* "pywrapfst.pyx":2930
  * 
  * 
  * cdef Fst _init_Fst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -30559,13 +30640,13 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9py
   __Pyx_AddTraceback("pywrapfst._init_Fst", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_ofst);
+  __Pyx_XDECREF((PyObject *)__pyx_v__ofst);
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2910
+/* "pywrapfst.pyx":2938
  * 
  * 
  * cdef MutableFst _init_MutableFst(MutableFstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -30574,33 +30655,36 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_Fst(__pyx_t_9py
  */
 
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst__init_MutableFst(__pyx_t_9pywrapfst_MutableFstClass_ptr __pyx_v_tfst) {
-  struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_ofst = 0;
+  struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v__ofst = 0;
   struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_init_MutableFst", 0);
 
-  /* "pywrapfst.pyx":2911
+  /* "pywrapfst.pyx":2939
  * 
  * cdef MutableFst _init_MutableFst(MutableFstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
  *     raise FstOpError("Operation failed")
- *   cdef MutableFst ofst = MutableFst.__new__(MutableFst)
+ *   cdef MutableFst _ofst = MutableFst.__new__(MutableFst)
  */
   __pyx_t_1 = ((__pyx_v_tfst->Properties(fst::kError, 1) == fst::kError) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2912
+    /* "pywrapfst.pyx":2940
  * cdef MutableFst _init_MutableFst(MutableFstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:
  *     raise FstOpError("Operation failed")             # <<<<<<<<<<<<<<
- *   cdef MutableFst ofst = MutableFst.__new__(MutableFst)
- *   ofst._fst.reset(tfst)
+ *   cdef MutableFst _ofst = MutableFst.__new__(MutableFst)
+ *   _ofst._fst.reset(tfst)
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2912, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2940, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -30614,77 +30698,85 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst__init_MutableF
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Operation_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Operation_failed);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2912, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2940, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 2912, __pyx_L1_error)
+    __PYX_ERR(0, 2940, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2911
+    /* "pywrapfst.pyx":2939
  * 
  * cdef MutableFst _init_MutableFst(MutableFstClass_ptr tfst):
  *   if tfst.Properties(fst.kError, True) == fst.kError:             # <<<<<<<<<<<<<<
  *     raise FstOpError("Operation failed")
- *   cdef MutableFst ofst = MutableFst.__new__(MutableFst)
+ *   cdef MutableFst _ofst = MutableFst.__new__(MutableFst)
  */
   }
 
-  /* "pywrapfst.pyx":2913
+  /* "pywrapfst.pyx":2941
  *   if tfst.Properties(fst.kError, True) == fst.kError:
  *     raise FstOpError("Operation failed")
- *   cdef MutableFst ofst = MutableFst.__new__(MutableFst)             # <<<<<<<<<<<<<<
- *   ofst._fst.reset(tfst)
+ *   cdef MutableFst _ofst = MutableFst.__new__(MutableFst)             # <<<<<<<<<<<<<<
+ *   _ofst._fst.reset(tfst)
  *   # Makes a copy of it as the derived type! Cool.
  */
-  __pyx_t_2 = ((PyObject *)__pyx_tp_new_9pywrapfst_MutableFst(((PyTypeObject *)__pyx_ptype_9pywrapfst_MutableFst), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2913, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_tp_new_9pywrapfst_MutableFst(((PyTypeObject *)__pyx_ptype_9pywrapfst_MutableFst), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2941, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_2));
-  __pyx_v_ofst = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_2);
+  __pyx_v__ofst = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_2);
   __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2914
+  /* "pywrapfst.pyx":2942
  *     raise FstOpError("Operation failed")
- *   cdef MutableFst ofst = MutableFst.__new__(MutableFst)
- *   ofst._fst.reset(tfst)             # <<<<<<<<<<<<<<
+ *   cdef MutableFst _ofst = MutableFst.__new__(MutableFst)
+ *   _ofst._fst.reset(tfst)             # <<<<<<<<<<<<<<
  *   # Makes a copy of it as the derived type! Cool.
- *   ofst._mfst = static_pointer_cast[fst.MutableFstClass, fst.FstClass](ofst._fst)
+ *   _ofst._mfst = static_pointer_cast[fst.MutableFstClass,
  */
-  if (unlikely(((PyObject *)__pyx_v_ofst) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__ofst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2914, __pyx_L1_error)
+    __PYX_ERR(0, 2942, __pyx_L1_error)
   }
-  __pyx_v_ofst->__pyx_base._fst.reset(__pyx_v_tfst);
+  __pyx_v__ofst->__pyx_base._fst.reset(__pyx_v_tfst);
 
-  /* "pywrapfst.pyx":2916
- *   ofst._fst.reset(tfst)
+  /* "pywrapfst.pyx":2945
  *   # Makes a copy of it as the derived type! Cool.
- *   ofst._mfst = static_pointer_cast[fst.MutableFstClass, fst.FstClass](ofst._fst)             # <<<<<<<<<<<<<<
- *   return ofst
+ *   _ofst._mfst = static_pointer_cast[fst.MutableFstClass,
+ *                                     fst.FstClass](_ofst._fst)             # <<<<<<<<<<<<<<
+ *   return _ofst
  * 
  */
-  if (unlikely(((PyObject *)__pyx_v_ofst) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__ofst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 2916, __pyx_L1_error)
+    __PYX_ERR(0, 2945, __pyx_L1_error)
   }
-  if (unlikely(((PyObject *)__pyx_v_ofst) == Py_None)) {
+
+  /* "pywrapfst.pyx":2944
+ *   _ofst._fst.reset(tfst)
+ *   # Makes a copy of it as the derived type! Cool.
+ *   _ofst._mfst = static_pointer_cast[fst.MutableFstClass,             # <<<<<<<<<<<<<<
+ *                                     fst.FstClass](_ofst._fst)
+ *   return _ofst
+ */
+  if (unlikely(((PyObject *)__pyx_v__ofst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 2916, __pyx_L1_error)
+    __PYX_ERR(0, 2944, __pyx_L1_error)
   }
-  __pyx_v_ofst->_mfst = std::static_pointer_cast<fst::script::MutableFstClass,fst::script::FstClass>(__pyx_v_ofst->__pyx_base._fst);
+  __pyx_v__ofst->_mfst = std::static_pointer_cast<fst::script::MutableFstClass,fst::script::FstClass>(__pyx_v__ofst->__pyx_base._fst);
 
-  /* "pywrapfst.pyx":2917
- *   # Makes a copy of it as the derived type! Cool.
- *   ofst._mfst = static_pointer_cast[fst.MutableFstClass, fst.FstClass](ofst._fst)
- *   return ofst             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":2946
+ *   _ofst._mfst = static_pointer_cast[fst.MutableFstClass,
+ *                                     fst.FstClass](_ofst._fst)
+ *   return _ofst             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __Pyx_INCREF(((PyObject *)__pyx_v_ofst));
-  __pyx_r = __pyx_v_ofst;
+  __Pyx_INCREF(((PyObject *)__pyx_v__ofst));
+  __pyx_r = __pyx_v__ofst;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2910
+  /* "pywrapfst.pyx":2938
  * 
  * 
  * cdef MutableFst _init_MutableFst(MutableFstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -30700,13 +30792,13 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst__init_MutableF
   __Pyx_AddTraceback("pywrapfst._init_MutableFst", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_ofst);
+  __Pyx_XDECREF((PyObject *)__pyx_v__ofst);
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2920
+/* "pywrapfst.pyx":2949
  * 
  * 
  * cdef Fst _init_XFst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -30719,9 +30811,12 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9p
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_init_XFst", 0);
 
-  /* "pywrapfst.pyx":2921
+  /* "pywrapfst.pyx":2950
  * 
  * cdef Fst _init_XFst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kMutable, True) == fst.kMutable:             # <<<<<<<<<<<<<<
@@ -30731,7 +30826,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9p
   __pyx_t_1 = ((__pyx_v_tfst->Properties(fst::kMutable, 1) == fst::kMutable) != 0);
   if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":2922
+    /* "pywrapfst.pyx":2951
  * cdef Fst _init_XFst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kMutable, True) == fst.kMutable:
  *     return _init_MutableFst(static_cast[MutableFstClass_ptr](tfst))             # <<<<<<<<<<<<<<
@@ -30739,13 +30834,13 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9p
  *     return _init_Fst(tfst)
  */
     __Pyx_XDECREF(((PyObject *)__pyx_r));
-    __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(static_cast<__pyx_t_9pywrapfst_MutableFstClass_ptr>(__pyx_v_tfst))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2922, __pyx_L1_error)
+    __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(static_cast<__pyx_t_9pywrapfst_MutableFstClass_ptr>(__pyx_v_tfst))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2951, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_2);
     __pyx_t_2 = 0;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":2921
+    /* "pywrapfst.pyx":2950
  * 
  * cdef Fst _init_XFst(FstClass_ptr tfst):
  *   if tfst.Properties(fst.kMutable, True) == fst.kMutable:             # <<<<<<<<<<<<<<
@@ -30754,7 +30849,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9p
  */
   }
 
-  /* "pywrapfst.pyx":2924
+  /* "pywrapfst.pyx":2953
  *     return _init_MutableFst(static_cast[MutableFstClass_ptr](tfst))
  *   else:
  *     return _init_Fst(tfst)             # <<<<<<<<<<<<<<
@@ -30763,14 +30858,14 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9p
  */
   /*else*/ {
     __Pyx_XDECREF(((PyObject *)__pyx_r));
-    __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_Fst(__pyx_v_tfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2924, __pyx_L1_error)
+    __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_Fst(__pyx_v_tfst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2953, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_2);
     __pyx_t_2 = 0;
     goto __pyx_L0;
   }
 
-  /* "pywrapfst.pyx":2920
+  /* "pywrapfst.pyx":2949
  * 
  * 
  * cdef Fst _init_XFst(FstClass_ptr tfst):             # <<<<<<<<<<<<<<
@@ -30789,17 +30884,17 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__init_XFst(__pyx_t_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2927
+/* "pywrapfst.pyx":2956
  * 
  * 
  * cpdef Fst _read_Fst(source):             # <<<<<<<<<<<<<<
- *   cdef unique_ptr[fst.FstClass] tfst
- *   tfst.reset(fst.FstClass.Read(tostring(source)))
+ *   cdef unique_ptr[fst.FstClass] _tfst
+ *   _tfst.reset(fst.FstClass.Read(path_tostring(source)))
  */
 
 static PyObject *__pyx_pw_9pywrapfst_17_read_Fst(PyObject *__pyx_self, PyObject *__pyx_v_source); /*proto*/
 static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *__pyx_v_source, CYTHON_UNUSED int __pyx_skip_dispatch) {
-  std::unique_ptr<fst::script::FstClass>  __pyx_v_tfst;
+  std::unique_ptr<fst::script::FstClass>  __pyx_v__tfst;
   struct __pyx_obj_9pywrapfst_Fst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
@@ -30808,104 +30903,94 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *_
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_read_Fst", 0);
 
-  /* "pywrapfst.pyx":2929
+  /* "pywrapfst.pyx":2958
  * cpdef Fst _read_Fst(source):
- *   cdef unique_ptr[fst.FstClass] tfst
- *   tfst.reset(fst.FstClass.Read(tostring(source)))             # <<<<<<<<<<<<<<
- *   if tfst.get() == NULL:
- *     raise FstIOError("Read failed: {!r}".format(source))
+ *   cdef unique_ptr[fst.FstClass] _tfst
+ *   _tfst.reset(fst.FstClass.Read(path_tostring(source)))             # <<<<<<<<<<<<<<
+ *   if _tfst.get() == NULL:
+ *     raise FstIOError(f"Read failed: {source!r}")
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2929, __pyx_L1_error)
-  __pyx_v_tfst.reset(fst::script::FstClass::Read(__pyx_t_1));
+  __pyx_t_1 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2958, __pyx_L1_error)
+  __pyx_v__tfst.reset(fst::script::FstClass::Read(__pyx_t_1));
 
-  /* "pywrapfst.pyx":2930
- *   cdef unique_ptr[fst.FstClass] tfst
- *   tfst.reset(fst.FstClass.Read(tostring(source)))
- *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
- *     raise FstIOError("Read failed: {!r}".format(source))
- *   return _init_XFst(tfst.release())
+  /* "pywrapfst.pyx":2959
+ *   cdef unique_ptr[fst.FstClass] _tfst
+ *   _tfst.reset(fst.FstClass.Read(path_tostring(source)))
+ *   if _tfst.get() == NULL:             # <<<<<<<<<<<<<<
+ *     raise FstIOError(f"Read failed: {source!r}")
+ *   return _init_XFst(_tfst.release())
  */
-  __pyx_t_2 = ((__pyx_v_tfst.get() == NULL) != 0);
+  __pyx_t_2 = ((__pyx_v__tfst.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":2931
- *   tfst.reset(fst.FstClass.Read(tostring(source)))
- *   if tfst.get() == NULL:
- *     raise FstIOError("Read failed: {!r}".format(source))             # <<<<<<<<<<<<<<
- *   return _init_XFst(tfst.release())
+    /* "pywrapfst.pyx":2960
+ *   _tfst.reset(fst.FstClass.Read(path_tostring(source)))
+ *   if _tfst.get() == NULL:
+ *     raise FstIOError(f"Read failed: {source!r}")             # <<<<<<<<<<<<<<
+ *   return _init_XFst(_tfst.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2931, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2960, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2931, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
-        __Pyx_INCREF(__pyx_t_7);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_6, function);
-      }
-    }
-    __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_source);
-    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2931, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2960, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = NULL;
+    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Read_failed, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 2960, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
-      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
-      if (likely(__pyx_t_6)) {
+      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+      if (likely(__pyx_t_5)) {
         PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-        __Pyx_INCREF(__pyx_t_6);
+        __Pyx_INCREF(__pyx_t_5);
         __Pyx_INCREF(function);
         __Pyx_DECREF_SET(__pyx_t_4, function);
       }
     }
-    __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2931, __pyx_L1_error)
+    __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
+    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2960, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2931, __pyx_L1_error)
+    __PYX_ERR(0, 2960, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2930
- *   cdef unique_ptr[fst.FstClass] tfst
- *   tfst.reset(fst.FstClass.Read(tostring(source)))
- *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
- *     raise FstIOError("Read failed: {!r}".format(source))
- *   return _init_XFst(tfst.release())
+    /* "pywrapfst.pyx":2959
+ *   cdef unique_ptr[fst.FstClass] _tfst
+ *   _tfst.reset(fst.FstClass.Read(path_tostring(source)))
+ *   if _tfst.get() == NULL:             # <<<<<<<<<<<<<<
+ *     raise FstIOError(f"Read failed: {source!r}")
+ *   return _init_XFst(_tfst.release())
  */
   }
 
-  /* "pywrapfst.pyx":2932
- *   if tfst.get() == NULL:
- *     raise FstIOError("Read failed: {!r}".format(source))
- *   return _init_XFst(tfst.release())             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":2961
+ *   if _tfst.get() == NULL:
+ *     raise FstIOError(f"Read failed: {source!r}")
+ *   return _init_XFst(_tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2932, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2961, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2927
+  /* "pywrapfst.pyx":2956
  * 
  * 
  * cpdef Fst _read_Fst(source):             # <<<<<<<<<<<<<<
- *   cdef unique_ptr[fst.FstClass] tfst
- *   tfst.reset(fst.FstClass.Read(tostring(source)))
+ *   cdef unique_ptr[fst.FstClass] _tfst
+ *   _tfst.reset(fst.FstClass.Read(path_tostring(source)))
  */
 
   /* function exit code */
@@ -30914,7 +30999,6 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__read_Fst(PyObject *_
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_AddTraceback("pywrapfst._read_Fst", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
@@ -30940,9 +31024,12 @@ static PyObject *__pyx_pf_9pywrapfst_16_read_Fst(CYTHON_UNUSED PyObject *__pyx_s
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_read_Fst", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_Fst(__pyx_v_source, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2927, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_Fst(__pyx_v_source, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2956, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -30959,120 +31046,121 @@ static PyObject *__pyx_pf_9pywrapfst_16_read_Fst(CYTHON_UNUSED PyObject *__pyx_s
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":2935
+/* "pywrapfst.pyx":2964
  * 
  * 
- * cpdef Fst _read_Fst_from_string(state):             # <<<<<<<<<<<<<<
- *   cdef stringstream sstrm
- *   sstrm << tostring(state)
+ * cpdef Fst _read_Fst_from_string(string state):             # <<<<<<<<<<<<<<
+ *   cdef stringstream _sstrm
+ *   _sstrm << state
  */
 
-static PyObject *__pyx_pw_9pywrapfst_19_read_Fst_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state); /*proto*/
-static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__read_Fst_from_string(PyObject *__pyx_v_state, CYTHON_UNUSED int __pyx_skip_dispatch) {
-  std::stringstream __pyx_v_sstrm;
-  std::unique_ptr<fst::script::FstClass>  __pyx_v_tfst;
+static PyObject *__pyx_pw_9pywrapfst_19_read_Fst_from_string(PyObject *__pyx_self, PyObject *__pyx_arg_state); /*proto*/
+static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__read_Fst_from_string(std::string __pyx_v_state, CYTHON_UNUSED int __pyx_skip_dispatch) {
+  std::stringstream __pyx_v__sstrm;
+  std::unique_ptr<fst::script::FstClass>  __pyx_v__tfst;
   struct __pyx_obj_9pywrapfst_Fst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  std::string __pyx_t_1;
-  int __pyx_t_2;
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_read_Fst_from_string", 0);
 
-  /* "pywrapfst.pyx":2937
- * cpdef Fst _read_Fst_from_string(state):
- *   cdef stringstream sstrm
- *   sstrm << tostring(state)             # <<<<<<<<<<<<<<
- *   cdef unique_ptr[fst.FstClass] tfst
- *   tfst.reset(fst.FstClass.ReadStream(sstrm, b"<pywrapfst>"))
+  /* "pywrapfst.pyx":2966
+ * cpdef Fst _read_Fst_from_string(string state):
+ *   cdef stringstream _sstrm
+ *   _sstrm << state             # <<<<<<<<<<<<<<
+ *   cdef unique_ptr[fst.FstClass] _tfst
+ *   _tfst.reset(fst.FstClass.ReadStream(_sstrm, b"<pywrapfst>"))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2937, __pyx_L1_error)
-  (void)((__pyx_v_sstrm << __pyx_t_1));
+  (void)((__pyx_v__sstrm << __pyx_v_state));
 
-  /* "pywrapfst.pyx":2939
- *   sstrm << tostring(state)
- *   cdef unique_ptr[fst.FstClass] tfst
- *   tfst.reset(fst.FstClass.ReadStream(sstrm, b"<pywrapfst>"))             # <<<<<<<<<<<<<<
- *   if tfst.get() == NULL:
- *     raise FstIOError("Read failed")
- */
-  __pyx_v_tfst.reset(fst::script::FstClass::Read(__pyx_v_sstrm, __pyx_k_pywrapfst));
-
-  /* "pywrapfst.pyx":2940
- *   cdef unique_ptr[fst.FstClass] tfst
- *   tfst.reset(fst.FstClass.ReadStream(sstrm, b"<pywrapfst>"))
- *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
- *     raise FstIOError("Read failed")
- *   return _init_XFst(tfst.release())
- */
-  __pyx_t_2 = ((__pyx_v_tfst.get() == NULL) != 0);
-  if (unlikely(__pyx_t_2)) {
+  /* "pywrapfst.pyx":2968
+ *   _sstrm << state
+ *   cdef unique_ptr[fst.FstClass] _tfst
+ *   _tfst.reset(fst.FstClass.ReadStream(_sstrm, b"<pywrapfst>"))             # <<<<<<<<<<<<<<
+ *   if _tfst.get() == NULL:
+ *     raise FstIOError("Read from string failed")
+ */
+  __pyx_v__tfst.reset(fst::script::FstClass::Read(__pyx_v__sstrm, __pyx_k_pywrapfst));
+
+  /* "pywrapfst.pyx":2969
+ *   cdef unique_ptr[fst.FstClass] _tfst
+ *   _tfst.reset(fst.FstClass.ReadStream(_sstrm, b"<pywrapfst>"))
+ *   if _tfst.get() == NULL:             # <<<<<<<<<<<<<<
+ *     raise FstIOError("Read from string failed")
+ *   return _init_XFst(_tfst.release())
+ */
+  __pyx_t_1 = ((__pyx_v__tfst.get() == NULL) != 0);
+  if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":2941
- *   tfst.reset(fst.FstClass.ReadStream(sstrm, b"<pywrapfst>"))
- *   if tfst.get() == NULL:
- *     raise FstIOError("Read failed")             # <<<<<<<<<<<<<<
- *   return _init_XFst(tfst.release())
+    /* "pywrapfst.pyx":2970
+ *   _tfst.reset(fst.FstClass.ReadStream(_sstrm, b"<pywrapfst>"))
+ *   if _tfst.get() == NULL:
+ *     raise FstIOError("Read from string failed")             # <<<<<<<<<<<<<<
+ *   return _init_XFst(_tfst.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2941, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = NULL;
-    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
-      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
-      if (likely(__pyx_t_5)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-        __Pyx_INCREF(__pyx_t_5);
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2970, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = NULL;
+    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
+      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+      if (likely(__pyx_t_4)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+        __Pyx_INCREF(__pyx_t_4);
         __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_4, function);
+        __Pyx_DECREF_SET(__pyx_t_3, function);
       }
     }
-    __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_Read_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_Read_failed);
-    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2941, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_Read_from_string_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_Read_from_string_failed);
+    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2970, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 2941, __pyx_L1_error)
+    __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __PYX_ERR(0, 2970, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":2940
- *   cdef unique_ptr[fst.FstClass] tfst
- *   tfst.reset(fst.FstClass.ReadStream(sstrm, b"<pywrapfst>"))
- *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
- *     raise FstIOError("Read failed")
- *   return _init_XFst(tfst.release())
+    /* "pywrapfst.pyx":2969
+ *   cdef unique_ptr[fst.FstClass] _tfst
+ *   _tfst.reset(fst.FstClass.ReadStream(_sstrm, b"<pywrapfst>"))
+ *   if _tfst.get() == NULL:             # <<<<<<<<<<<<<<
+ *     raise FstIOError("Read from string failed")
+ *   return _init_XFst(_tfst.release())
  */
   }
 
-  /* "pywrapfst.pyx":2942
- *   if tfst.get() == NULL:
- *     raise FstIOError("Read failed")
- *   return _init_XFst(tfst.release())             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":2971
+ *   if _tfst.get() == NULL:
+ *     raise FstIOError("Read from string failed")
+ *   return _init_XFst(_tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2942, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_3);
-  __pyx_t_3 = 0;
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2971, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_2);
+  __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":2935
+  /* "pywrapfst.pyx":2964
  * 
  * 
- * cpdef Fst _read_Fst_from_string(state):             # <<<<<<<<<<<<<<
- *   cdef stringstream sstrm
- *   sstrm << tostring(state)
+ * cpdef Fst _read_Fst_from_string(string state):             # <<<<<<<<<<<<<<
+ *   cdef stringstream _sstrm
+ *   _sstrm << state
  */
 
   /* function exit code */
   __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
   __Pyx_AddTraceback("pywrapfst._read_Fst_from_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
@@ -31082,25 +31170,41 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__read_Fst_from_string
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_19_read_Fst_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_19_read_Fst_from_string(PyObject *__pyx_self, PyObject *__pyx_v_state) {
+static PyObject *__pyx_pw_9pywrapfst_19_read_Fst_from_string(PyObject *__pyx_self, PyObject *__pyx_arg_state); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_19_read_Fst_from_string(PyObject *__pyx_self, PyObject *__pyx_arg_state) {
+  std::string __pyx_v_state;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("_read_Fst_from_string (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_18_read_Fst_from_string(__pyx_self, ((PyObject *)__pyx_v_state));
+  assert(__pyx_arg_state); {
+    __pyx_v_state = __pyx_convert_string_from_py_std__in_string(__pyx_arg_state); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 2964, __pyx_L3_error)
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("pywrapfst._read_Fst_from_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_9pywrapfst_18_read_Fst_from_string(__pyx_self, ((std::string)__pyx_v_state));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_18_read_Fst_from_string(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_state) {
+static PyObject *__pyx_pf_9pywrapfst_18_read_Fst_from_string(CYTHON_UNUSED PyObject *__pyx_self, std::string __pyx_v_state) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_read_Fst_from_string", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_Fst_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2935, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__read_Fst_from_string(__pyx_v_state, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2964, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -31117,11 +31221,11 @@ static PyObject *__pyx_pf_9pywrapfst_18_read_Fst_from_string(CYTHON_UNUSED PyObj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3055
+/* "pywrapfst.pyx":3084
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<Arc at 0x{:x}>".format(id(self))
+ *     return f"<Arc at 0x{id(self):x}>"
  * 
  */
 
@@ -31142,57 +31246,65 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_2;
+  Py_UCS4 __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":3056
+  /* "pywrapfst.pyx":3085
  * 
  *   def __repr__(self):
- *     return "<Arc at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
+ *     return f"<Arc at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
  * 
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Arc_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3056, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3056, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = NULL;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
-    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
-    if (likely(__pyx_t_4)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-      __Pyx_INCREF(__pyx_t_4);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_2, function);
-    }
-  }
-  __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3056, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3085, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 127;
+  __Pyx_INCREF(__pyx_kp_u_Arc_at_0x);
+  __pyx_t_2 += 10;
+  __Pyx_GIVEREF(__pyx_kp_u_Arc_at_0x);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_Arc_at_0x);
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3085, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3085, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_5);
+  __pyx_t_5 = 0;
+  __Pyx_INCREF(__pyx_kp_u__3);
+  __pyx_t_2 += 1;
+  __Pyx_GIVEREF(__pyx_kp_u__3);
+  PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u__3);
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3085, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3055
+  /* "pywrapfst.pyx":3084
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<Arc at 0x{:x}>".format(id(self))
+ *     return f"<Arc at 0x{id(self):x}>"
  * 
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
   __Pyx_AddTraceback("pywrapfst.Arc.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -31201,12 +31313,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc___repr__(struct __pyx_obj_9pywrapfst_A
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3058
- *     return "<Arc at 0x{:x}>".format(id(self))
+/* "pywrapfst.pyx":3087
+ *     return f"<Arc at 0x{id(self):x}>"
  * 
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):             # <<<<<<<<<<<<<<
- *     cdef fst.WeightClass wc = _get_WeightClass_or_One(b"tropical", weight)
- *     self._arc.reset(new fst.ArcClass(ilabel, olabel, wc, nextstate))
+ *     cdef fst.WeightClass _weight = _get_WeightClass_or_One(b"tropical", weight)
+ *     self._arc.reset(new fst.ArcClass(ilabel, olabel, _weight, nextstate))
  */
 
 /* Python wrapper */
@@ -31216,6 +31328,9 @@ static int __pyx_pw_9pywrapfst_3Arc_3__init__(PyObject *__pyx_v_self, PyObject *
   int64 __pyx_v_olabel;
   PyObject *__pyx_v_weight = 0;
   int64 __pyx_v_nextstate;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
@@ -31246,23 +31361,23 @@ static int __pyx_pw_9pywrapfst_3Arc_3__init__(PyObject *__pyx_v_self, PyObject *
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_olabel)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 1); __PYX_ERR(0, 3058, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 1); __PYX_ERR(0, 3087, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
         if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_weight)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 2); __PYX_ERR(0, 3058, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 2); __PYX_ERR(0, 3087, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  3:
         if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_nextstate)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 3); __PYX_ERR(0, 3058, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, 3); __PYX_ERR(0, 3087, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3058, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3087, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
       goto __pyx_L5_argtuple_error;
@@ -31272,14 +31387,14 @@ static int __pyx_pw_9pywrapfst_3Arc_3__init__(PyObject *__pyx_v_self, PyObject *
       values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
       values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
     }
-    __pyx_v_ilabel = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_ilabel == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3058, __pyx_L3_error)
-    __pyx_v_olabel = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_olabel == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3058, __pyx_L3_error)
+    __pyx_v_ilabel = __Pyx_PyInt_As_int64_t(values[0]); if (unlikely((__pyx_v_ilabel == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3087, __pyx_L3_error)
+    __pyx_v_olabel = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_olabel == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3087, __pyx_L3_error)
     __pyx_v_weight = values[2];
-    __pyx_v_nextstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nextstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3058, __pyx_L3_error)
+    __pyx_v_nextstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nextstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3087, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3058, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3087, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Arc.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -31293,41 +31408,44 @@ static int __pyx_pw_9pywrapfst_3Arc_3__init__(PyObject *__pyx_v_self, PyObject *
 }
 
 static int __pyx_pf_9pywrapfst_3Arc_2__init__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, int64 __pyx_v_ilabel, int64 __pyx_v_olabel, PyObject *__pyx_v_weight, int64 __pyx_v_nextstate) {
-  fst::script::WeightClass __pyx_v_wc;
+  fst::script::WeightClass __pyx_v__weight;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   fst::script::WeightClass __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":3059
+  /* "pywrapfst.pyx":3088
  * 
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):
- *     cdef fst.WeightClass wc = _get_WeightClass_or_One(b"tropical", weight)             # <<<<<<<<<<<<<<
- *     self._arc.reset(new fst.ArcClass(ilabel, olabel, wc, nextstate))
+ *     cdef fst.WeightClass _weight = _get_WeightClass_or_One(b"tropical", weight)             # <<<<<<<<<<<<<<
+ *     self._arc.reset(new fst.ArcClass(ilabel, olabel, _weight, nextstate))
  * 
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_One(__pyx_k_tropical, __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3059, __pyx_L1_error)
-  __pyx_v_wc = __pyx_t_1;
+  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_One(__pyx_k_tropical, __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3088, __pyx_L1_error)
+  __pyx_v__weight = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3060
+  /* "pywrapfst.pyx":3089
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):
- *     cdef fst.WeightClass wc = _get_WeightClass_or_One(b"tropical", weight)
- *     self._arc.reset(new fst.ArcClass(ilabel, olabel, wc, nextstate))             # <<<<<<<<<<<<<<
+ *     cdef fst.WeightClass _weight = _get_WeightClass_or_One(b"tropical", weight)
+ *     self._arc.reset(new fst.ArcClass(ilabel, olabel, _weight, nextstate))             # <<<<<<<<<<<<<<
  * 
  *   cpdef Arc copy(self):
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3060, __pyx_L1_error)
+    __PYX_ERR(0, 3089, __pyx_L1_error)
   }
-  __pyx_v_self->_arc.reset(new fst::script::ArcClass(__pyx_v_ilabel, __pyx_v_olabel, __pyx_v_wc, __pyx_v_nextstate));
+  __pyx_v_self->_arc.reset(new fst::script::ArcClass(__pyx_v_ilabel, __pyx_v_olabel, __pyx_v__weight, __pyx_v_nextstate));
 
-  /* "pywrapfst.pyx":3058
- *     return "<Arc at 0x{:x}>".format(id(self))
+  /* "pywrapfst.pyx":3087
+ *     return f"<Arc at 0x{id(self):x}>"
  * 
  *   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):             # <<<<<<<<<<<<<<
- *     cdef fst.WeightClass wc = _get_WeightClass_or_One(b"tropical", weight)
- *     self._arc.reset(new fst.ArcClass(ilabel, olabel, wc, nextstate))
+ *     cdef fst.WeightClass _weight = _get_WeightClass_or_One(b"tropical", weight)
+ *     self._arc.reset(new fst.ArcClass(ilabel, olabel, _weight, nextstate))
  */
 
   /* function exit code */
@@ -31341,8 +31459,8 @@ static int __pyx_pf_9pywrapfst_3Arc_2__init__(struct __pyx_obj_9pywrapfst_Arc *_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3062
- *     self._arc.reset(new fst.ArcClass(ilabel, olabel, wc, nextstate))
+/* "pywrapfst.pyx":3091
+ *     self._arc.reset(new fst.ArcClass(ilabel, olabel, _weight, nextstate))
  * 
  *   cpdef Arc copy(self):             # <<<<<<<<<<<<<<
  *     return Arc(self.ilabel, self.olabel, self.weight, self.nextstate)
@@ -31358,6 +31476,9 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __py
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("copy", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -31368,7 +31489,7 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __py
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3062, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_copy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3091, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_3Arc_5copy)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -31385,10 +31506,10 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __py
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3062, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3091, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Arc))))) __PYX_ERR(0, 3062, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Arc))))) __PYX_ERR(0, 3091, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst_Arc *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -31407,7 +31528,7 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __py
     #endif
   }
 
-  /* "pywrapfst.pyx":3063
+  /* "pywrapfst.pyx":3092
  * 
  *   cpdef Arc copy(self):
  *     return Arc(self.ilabel, self.olabel, self.weight, self.nextstate)             # <<<<<<<<<<<<<<
@@ -31415,15 +31536,15 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __py
  *   property ilabel:
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_ilabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3063, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_ilabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3092, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_olabel); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3063, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_olabel); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3092, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_weight); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3063, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_weight); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3092, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_nextstate); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3063, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_nextstate); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3092, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3063, __pyx_L1_error)
+  __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3092, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
@@ -31437,15 +31558,15 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst_3Arc_copy(struct __py
   __pyx_t_2 = 0;
   __pyx_t_3 = 0;
   __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_Arc), __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3063, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_Arc), __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3092, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_r = ((struct __pyx_obj_9pywrapfst_Arc *)__pyx_t_4);
   __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3062
- *     self._arc.reset(new fst.ArcClass(ilabel, olabel, wc, nextstate))
+  /* "pywrapfst.pyx":3091
+ *     self._arc.reset(new fst.ArcClass(ilabel, olabel, _weight, nextstate))
  * 
  *   cpdef Arc copy(self):             # <<<<<<<<<<<<<<
  *     return Arc(self.ilabel, self.olabel, self.weight, self.nextstate)
@@ -31484,9 +31605,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_4copy(struct __pyx_obj_9pywrapfst_Arc
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("copy", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Arc_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3062, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_3Arc_copy(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3091, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -31503,7 +31627,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_4copy(struct __pyx_obj_9pywrapfst_Arc
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3067
+/* "pywrapfst.pyx":3096
  *   property ilabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31528,9 +31652,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6ilabel___get__(struct __pyx_obj_9pywr
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":3068
+  /* "pywrapfst.pyx":3097
  * 
  *     def __get__(self):
  *       return deref(self._arc).ilabel             # <<<<<<<<<<<<<<
@@ -31540,15 +31667,15 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6ilabel___get__(struct __pyx_obj_9pywr
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3068, __pyx_L1_error)
+    __PYX_ERR(0, 3097, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).ilabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3068, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).ilabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3097, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3067
+  /* "pywrapfst.pyx":3096
  *   property ilabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31567,7 +31694,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6ilabel___get__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3070
+/* "pywrapfst.pyx":3099
  *       return deref(self._arc).ilabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -31579,11 +31706,14 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6ilabel___get__(struct __pyx_obj_9pywr
 static int __pyx_pw_9pywrapfst_3Arc_6ilabel_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_arg_value); /*proto*/
 static int __pyx_pw_9pywrapfst_3Arc_6ilabel_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_arg_value) {
   int64 __pyx_v_value;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
   assert(__pyx_arg_value); {
-    __pyx_v_value = __Pyx_PyInt_As_int64_t(__pyx_arg_value); if (unlikely((__pyx_v_value == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3070, __pyx_L3_error)
+    __pyx_v_value = __Pyx_PyInt_As_int64_t(__pyx_arg_value); if (unlikely((__pyx_v_value == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3099, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -31601,9 +31731,12 @@ static int __pyx_pw_9pywrapfst_3Arc_6ilabel_3__set__(PyObject *__pyx_v_self, PyO
 static int __pyx_pf_9pywrapfst_3Arc_6ilabel_2__set__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, int64 __pyx_v_value) {
   int __pyx_r;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":3071
+  /* "pywrapfst.pyx":3100
  * 
  *     def __set__(self, int64 value):
  *       deref(self._arc).ilabel = value             # <<<<<<<<<<<<<<
@@ -31612,11 +31745,11 @@ static int __pyx_pf_9pywrapfst_3Arc_6ilabel_2__set__(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3071, __pyx_L1_error)
+    __PYX_ERR(0, 3100, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).ilabel = __pyx_v_value;
 
-  /* "pywrapfst.pyx":3070
+  /* "pywrapfst.pyx":3099
  *       return deref(self._arc).ilabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -31635,7 +31768,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6ilabel_2__set__(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3075
+/* "pywrapfst.pyx":3104
  *   property olabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31660,9 +31793,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6olabel___get__(struct __pyx_obj_9pywr
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":3076
+  /* "pywrapfst.pyx":3105
  * 
  *     def __get__(self):
  *       return deref(self._arc).olabel             # <<<<<<<<<<<<<<
@@ -31672,15 +31808,15 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6olabel___get__(struct __pyx_obj_9pywr
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3076, __pyx_L1_error)
+    __PYX_ERR(0, 3105, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).olabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3076, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).olabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3105, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3075
+  /* "pywrapfst.pyx":3104
  *   property olabel:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31699,7 +31835,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6olabel___get__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3078
+/* "pywrapfst.pyx":3107
  *       return deref(self._arc).olabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -31711,11 +31847,14 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6olabel___get__(struct __pyx_obj_9pywr
 static int __pyx_pw_9pywrapfst_3Arc_6olabel_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_arg_value); /*proto*/
 static int __pyx_pw_9pywrapfst_3Arc_6olabel_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_arg_value) {
   int64 __pyx_v_value;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
   assert(__pyx_arg_value); {
-    __pyx_v_value = __Pyx_PyInt_As_int64_t(__pyx_arg_value); if (unlikely((__pyx_v_value == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3078, __pyx_L3_error)
+    __pyx_v_value = __Pyx_PyInt_As_int64_t(__pyx_arg_value); if (unlikely((__pyx_v_value == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3107, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -31733,9 +31872,12 @@ static int __pyx_pw_9pywrapfst_3Arc_6olabel_3__set__(PyObject *__pyx_v_self, PyO
 static int __pyx_pf_9pywrapfst_3Arc_6olabel_2__set__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, int64 __pyx_v_value) {
   int __pyx_r;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":3079
+  /* "pywrapfst.pyx":3108
  * 
  *     def __set__(self, int64 value):
  *       deref(self._arc).olabel = value             # <<<<<<<<<<<<<<
@@ -31744,11 +31886,11 @@ static int __pyx_pf_9pywrapfst_3Arc_6olabel_2__set__(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3079, __pyx_L1_error)
+    __PYX_ERR(0, 3108, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).olabel = __pyx_v_value;
 
-  /* "pywrapfst.pyx":3078
+  /* "pywrapfst.pyx":3107
  *       return deref(self._arc).olabel
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -31767,12 +31909,12 @@ static int __pyx_pf_9pywrapfst_3Arc_6olabel_2__set__(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3083
+/* "pywrapfst.pyx":3112
  *   property weight:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
- *       cdef Weight weight = Weight.__new__(Weight)
- *       weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))
+ *       cdef Weight _weight = Weight.__new__(Weight)
+ *       _weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))
  */
 
 /* Python wrapper */
@@ -31789,59 +31931,62 @@ static PyObject *__pyx_pw_9pywrapfst_3Arc_6weight_1__get__(PyObject *__pyx_v_sel
 }
 
 static PyObject *__pyx_pf_9pywrapfst_3Arc_6weight___get__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self) {
-  struct __pyx_obj_9pywrapfst_Weight *__pyx_v_weight = 0;
+  struct __pyx_obj_9pywrapfst_Weight *__pyx_v__weight = 0;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":3084
+  /* "pywrapfst.pyx":3113
  * 
  *     def __get__(self):
- *       cdef Weight weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
- *       weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))
- *       return weight
+ *       cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
+ *       _weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))
+ *       return _weight
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3084, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3113, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_v_weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
+  __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":3085
+  /* "pywrapfst.pyx":3114
  *     def __get__(self):
- *       cdef Weight weight = Weight.__new__(Weight)
- *       weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))             # <<<<<<<<<<<<<<
- *       return weight
+ *       cdef Weight _weight = Weight.__new__(Weight)
+ *       _weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))             # <<<<<<<<<<<<<<
+ *       return _weight
  * 
  */
-  if (unlikely(((PyObject *)__pyx_v_weight) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 3085, __pyx_L1_error)
+    __PYX_ERR(0, 3114, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3085, __pyx_L1_error)
+    __PYX_ERR(0, 3114, __pyx_L1_error)
   }
-  __pyx_v_weight->_weight.reset(new fst::script::WeightClass((*__pyx_v_self->_arc).weight));
+  __pyx_v__weight->_weight.reset(new fst::script::WeightClass((*__pyx_v_self->_arc).weight));
 
-  /* "pywrapfst.pyx":3086
- *       cdef Weight weight = Weight.__new__(Weight)
- *       weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))
- *       return weight             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3115
+ *       cdef Weight _weight = Weight.__new__(Weight)
+ *       _weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))
+ *       return _weight             # <<<<<<<<<<<<<<
  * 
  *     def __set__(self, weight):
  */
   __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_weight));
-  __pyx_r = ((PyObject *)__pyx_v_weight);
+  __Pyx_INCREF(((PyObject *)__pyx_v__weight));
+  __pyx_r = ((PyObject *)__pyx_v__weight);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3083
+  /* "pywrapfst.pyx":3112
  *   property weight:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
- *       cdef Weight weight = Weight.__new__(Weight)
- *       weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))
+ *       cdef Weight _weight = Weight.__new__(Weight)
+ *       _weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))
  */
 
   /* function exit code */
@@ -31850,14 +31995,14 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6weight___get__(struct __pyx_obj_9pywr
   __Pyx_AddTraceback("pywrapfst.Arc.weight.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_weight);
+  __Pyx_XDECREF((PyObject *)__pyx_v__weight);
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3088
- *       return weight
+/* "pywrapfst.pyx":3117
+ *       return _weight
  * 
  *     def __set__(self, weight):             # <<<<<<<<<<<<<<
  *       deref(self._arc).weight = _get_WeightClass_or_One(b"tropical", weight)
@@ -31881,24 +32026,27 @@ static int __pyx_pf_9pywrapfst_3Arc_6weight_2__set__(struct __pyx_obj_9pywrapfst
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   fst::script::WeightClass __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":3089
+  /* "pywrapfst.pyx":3118
  * 
  *     def __set__(self, weight):
  *       deref(self._arc).weight = _get_WeightClass_or_One(b"tropical", weight)             # <<<<<<<<<<<<<<
  * 
  *   property nextstate:
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_One(__pyx_k_tropical, __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3089, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_One(__pyx_k_tropical, __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3118, __pyx_L1_error)
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3089, __pyx_L1_error)
+    __PYX_ERR(0, 3118, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).weight = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3088
- *       return weight
+  /* "pywrapfst.pyx":3117
+ *       return _weight
  * 
  *     def __set__(self, weight):             # <<<<<<<<<<<<<<
  *       deref(self._arc).weight = _get_WeightClass_or_One(b"tropical", weight)
@@ -31916,7 +32064,7 @@ static int __pyx_pf_9pywrapfst_3Arc_6weight_2__set__(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3093
+/* "pywrapfst.pyx":3122
  *   property nextstate:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31941,9 +32089,12 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_9nextstate___get__(struct __pyx_obj_9p
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "pywrapfst.pyx":3094
+  /* "pywrapfst.pyx":3123
  * 
  *     def __get__(self):
  *       return deref(self._arc).nextstate             # <<<<<<<<<<<<<<
@@ -31953,15 +32104,15 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_9nextstate___get__(struct __pyx_obj_9p
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3094, __pyx_L1_error)
+    __PYX_ERR(0, 3123, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).nextstate); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3094, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t((*__pyx_v_self->_arc).nextstate); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3123, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3093
+  /* "pywrapfst.pyx":3122
  *   property nextstate:
  * 
  *     def __get__(self):             # <<<<<<<<<<<<<<
@@ -31980,7 +32131,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_9nextstate___get__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3096
+/* "pywrapfst.pyx":3125
  *       return deref(self._arc).nextstate
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -31992,11 +32143,14 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_9nextstate___get__(struct __pyx_obj_9p
 static int __pyx_pw_9pywrapfst_3Arc_9nextstate_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_arg_value); /*proto*/
 static int __pyx_pw_9pywrapfst_3Arc_9nextstate_3__set__(PyObject *__pyx_v_self, PyObject *__pyx_arg_value) {
   int64 __pyx_v_value;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__set__ (wrapper)", 0);
   assert(__pyx_arg_value); {
-    __pyx_v_value = __Pyx_PyInt_As_int64_t(__pyx_arg_value); if (unlikely((__pyx_v_value == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3096, __pyx_L3_error)
+    __pyx_v_value = __Pyx_PyInt_As_int64_t(__pyx_arg_value); if (unlikely((__pyx_v_value == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3125, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -32014,9 +32168,12 @@ static int __pyx_pw_9pywrapfst_3Arc_9nextstate_3__set__(PyObject *__pyx_v_self,
 static int __pyx_pf_9pywrapfst_3Arc_9nextstate_2__set__(struct __pyx_obj_9pywrapfst_Arc *__pyx_v_self, int64 __pyx_v_value) {
   int __pyx_r;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__set__", 0);
 
-  /* "pywrapfst.pyx":3097
+  /* "pywrapfst.pyx":3126
  * 
  *     def __set__(self, int64 value):
  *       deref(self._arc).nextstate = value             # <<<<<<<<<<<<<<
@@ -32025,11 +32182,11 @@ static int __pyx_pf_9pywrapfst_3Arc_9nextstate_2__set__(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3097, __pyx_L1_error)
+    __PYX_ERR(0, 3126, __pyx_L1_error)
   }
   (*__pyx_v_self->_arc).nextstate = __pyx_v_value;
 
-  /* "pywrapfst.pyx":3096
+  /* "pywrapfst.pyx":3125
  *       return deref(self._arc).nextstate
  * 
  *     def __set__(self, int64 value):             # <<<<<<<<<<<<<<
@@ -32071,6 +32228,9 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6__reduce_cython__(CYTHON_UNUSED struc
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__reduce_cython__", 0);
 
   /* "(tree fragment)":2
@@ -32079,7 +32239,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_6__reduce_cython__(CYTHON_UNUSED struc
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._arc cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__22, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__24, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -32125,6 +32285,9 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_8__setstate_cython__(CYTHON_UNUSED str
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__setstate_cython__", 0);
 
   /* "(tree fragment)":4
@@ -32132,7 +32295,7 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_8__setstate_cython__(CYTHON_UNUSED str
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._arc cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__23, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__25, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -32155,90 +32318,93 @@ static PyObject *__pyx_pf_9pywrapfst_3Arc_8__setstate_cython__(CYTHON_UNUSED str
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3100
+/* "pywrapfst.pyx":3129
  * 
  * 
  * cdef Arc _init_Arc(const fst.ArcClass &arc):             # <<<<<<<<<<<<<<
- *   cdef Weight weight = Weight.__new__(Weight)
- *   weight._weight.reset(new fst.WeightClass(arc.weight))
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(arc.weight))
  */
 
 static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst__init_Arc(fst::script::ArcClass const &__pyx_v_arc) {
-  struct __pyx_obj_9pywrapfst_Weight *__pyx_v_weight = 0;
+  struct __pyx_obj_9pywrapfst_Weight *__pyx_v__weight = 0;
   struct __pyx_obj_9pywrapfst_Arc *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_init_Arc", 0);
 
-  /* "pywrapfst.pyx":3101
+  /* "pywrapfst.pyx":3130
  * 
  * cdef Arc _init_Arc(const fst.ArcClass &arc):
- *   cdef Weight weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
- *   weight._weight.reset(new fst.WeightClass(arc.weight))
- *   return Arc(arc.ilabel, arc.olabel, weight, arc.nextstate)
+ *   cdef Weight _weight = Weight.__new__(Weight)             # <<<<<<<<<<<<<<
+ *   _weight._weight.reset(new fst.WeightClass(arc.weight))
+ *   return Arc(arc.ilabel, arc.olabel, _weight, arc.nextstate)
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3101, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_Weight(((PyTypeObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3130, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_v_weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
+  __pyx_v__weight = ((struct __pyx_obj_9pywrapfst_Weight *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":3102
+  /* "pywrapfst.pyx":3131
  * cdef Arc _init_Arc(const fst.ArcClass &arc):
- *   cdef Weight weight = Weight.__new__(Weight)
- *   weight._weight.reset(new fst.WeightClass(arc.weight))             # <<<<<<<<<<<<<<
- *   return Arc(arc.ilabel, arc.olabel, weight, arc.nextstate)
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(arc.weight))             # <<<<<<<<<<<<<<
+ *   return Arc(arc.ilabel, arc.olabel, _weight, arc.nextstate)
  * 
  */
-  if (unlikely(((PyObject *)__pyx_v_weight) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v__weight) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_weight");
-    __PYX_ERR(0, 3102, __pyx_L1_error)
+    __PYX_ERR(0, 3131, __pyx_L1_error)
   }
-  __pyx_v_weight->_weight.reset(new fst::script::WeightClass(__pyx_v_arc.weight));
+  __pyx_v__weight->_weight.reset(new fst::script::WeightClass(__pyx_v_arc.weight));
 
-  /* "pywrapfst.pyx":3103
- *   cdef Weight weight = Weight.__new__(Weight)
- *   weight._weight.reset(new fst.WeightClass(arc.weight))
- *   return Arc(arc.ilabel, arc.olabel, weight, arc.nextstate)             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3132
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(arc.weight))
+ *   return Arc(arc.ilabel, arc.olabel, _weight, arc.nextstate)             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.ilabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3103, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.ilabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3132, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.olabel); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3103, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.olabel); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3132, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.nextstate); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3103, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_v_arc.nextstate); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3132, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = PyTuple_New(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3103, __pyx_L1_error)
+  __pyx_t_4 = PyTuple_New(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3132, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
-  __Pyx_INCREF(((PyObject *)__pyx_v_weight));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_weight));
-  PyTuple_SET_ITEM(__pyx_t_4, 2, ((PyObject *)__pyx_v_weight));
+  __Pyx_INCREF(((PyObject *)__pyx_v__weight));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v__weight));
+  PyTuple_SET_ITEM(__pyx_t_4, 2, ((PyObject *)__pyx_v__weight));
   __Pyx_GIVEREF(__pyx_t_3);
   PyTuple_SET_ITEM(__pyx_t_4, 3, __pyx_t_3);
   __pyx_t_1 = 0;
   __pyx_t_2 = 0;
   __pyx_t_3 = 0;
-  __pyx_t_3 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_Arc), __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3103, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_Arc), __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3132, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_r = ((struct __pyx_obj_9pywrapfst_Arc *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3100
+  /* "pywrapfst.pyx":3129
  * 
  * 
  * cdef Arc _init_Arc(const fst.ArcClass &arc):             # <<<<<<<<<<<<<<
- *   cdef Weight weight = Weight.__new__(Weight)
- *   weight._weight.reset(new fst.WeightClass(arc.weight))
+ *   cdef Weight _weight = Weight.__new__(Weight)
+ *   _weight._weight.reset(new fst.WeightClass(arc.weight))
  */
 
   /* function exit code */
@@ -32250,17 +32416,17 @@ static struct __pyx_obj_9pywrapfst_Arc *__pyx_f_9pywrapfst__init_Arc(fst::script
   __Pyx_AddTraceback("pywrapfst._init_Arc", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_weight);
+  __Pyx_XDECREF((PyObject *)__pyx_v__weight);
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3114
+/* "pywrapfst.pyx":3143
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<ArcIterator at 0x{:x}>".format(id(self))
+ *     return f"<ArcIterator at 0x{id(self):x}>"
  * 
  */
 
@@ -32281,57 +32447,65 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_2;
+  Py_UCS4 __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":3115
+  /* "pywrapfst.pyx":3144
  * 
  *   def __repr__(self):
- *     return "<ArcIterator at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
+ *     return f"<ArcIterator at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
  * 
  *   def __init__(self, Fst ifst, int64 state):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_ArcIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3115, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3115, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = NULL;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
-    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
-    if (likely(__pyx_t_4)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-      __Pyx_INCREF(__pyx_t_4);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_2, function);
-    }
-  }
-  __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3115, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3144, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 127;
+  __Pyx_INCREF(__pyx_kp_u_ArcIterator_at_0x);
+  __pyx_t_2 += 18;
+  __Pyx_GIVEREF(__pyx_kp_u_ArcIterator_at_0x);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_ArcIterator_at_0x);
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3144, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3144, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_5);
+  __pyx_t_5 = 0;
+  __Pyx_INCREF(__pyx_kp_u__3);
+  __pyx_t_2 += 1;
+  __Pyx_GIVEREF(__pyx_kp_u__3);
+  PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u__3);
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3144, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3114
+  /* "pywrapfst.pyx":3143
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<ArcIterator at 0x{:x}>".format(id(self))
+ *     return f"<ArcIterator at 0x{id(self):x}>"
  * 
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
   __Pyx_AddTraceback("pywrapfst.ArcIterator.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -32340,8 +32514,8 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator___repr__(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3117
- *     return "<ArcIterator at 0x{:x}>".format(id(self))
+/* "pywrapfst.pyx":3146
+ *     return f"<ArcIterator at 0x{id(self):x}>"
  * 
  *   def __init__(self, Fst ifst, int64 state):             # <<<<<<<<<<<<<<
  *     if not ifst._fst.get().ValidStateId(state):
@@ -32353,6 +32527,9 @@ static int __pyx_pw_9pywrapfst_11ArcIterator_3__init__(PyObject *__pyx_v_self, P
 static int __pyx_pw_9pywrapfst_11ArcIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   int64 __pyx_v_state;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
@@ -32379,11 +32556,11 @@ static int __pyx_pw_9pywrapfst_11ArcIterator_3__init__(PyObject *__pyx_v_self, P
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_state)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 3117, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 3146, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3117, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3146, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -32392,17 +32569,17 @@ static int __pyx_pw_9pywrapfst_11ArcIterator_3__init__(PyObject *__pyx_v_self, P
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3117, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3146, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3117, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3146, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.ArcIterator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return -1;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3117, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3146, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_11ArcIterator_2__init__(((struct __pyx_obj_9pywrapfst_ArcIterator *)__pyx_v_self), __pyx_v_ifst, __pyx_v_state);
 
   /* function exit code */
@@ -32422,9 +32599,12 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   std::shared_ptr<fst::script::FstClass>  __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":3118
+  /* "pywrapfst.pyx":3147
  * 
  *   def __init__(self, Fst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -32433,19 +32613,19 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3118, __pyx_L1_error)
+    __PYX_ERR(0, 3147, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_ifst->_fst.get()->ValidStateId(__pyx_v_state) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":3119
+    /* "pywrapfst.pyx":3148
  *   def __init__(self, Fst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._fst = ifst._fst
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3119, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3148, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -32459,14 +32639,14 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3119, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3148, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 3119, __pyx_L1_error)
+    __PYX_ERR(0, 3148, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3118
+    /* "pywrapfst.pyx":3147
  * 
  *   def __init__(self, Fst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -32475,7 +32655,7 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
  */
   }
 
-  /* "pywrapfst.pyx":3121
+  /* "pywrapfst.pyx":3150
  *       raise FstIndexError("State index out of range")
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._fst = ifst._fst             # <<<<<<<<<<<<<<
@@ -32484,16 +32664,16 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3121, __pyx_L1_error)
+    __PYX_ERR(0, 3150, __pyx_L1_error)
   }
   __pyx_t_5 = __pyx_v_ifst->_fst;
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3121, __pyx_L1_error)
+    __PYX_ERR(0, 3150, __pyx_L1_error)
   }
   __pyx_v_self->_fst = __pyx_t_5;
 
-  /* "pywrapfst.pyx":3122
+  /* "pywrapfst.pyx":3151
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._fst = ifst._fst
  *     self._aiter.reset(new fst.ArcIteratorClass(deref(self._fst), state))             # <<<<<<<<<<<<<<
@@ -32502,16 +32682,16 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3122, __pyx_L1_error)
+    __PYX_ERR(0, 3151, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3122, __pyx_L1_error)
+    __PYX_ERR(0, 3151, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.reset(new fst::script::ArcIteratorClass((*__pyx_v_self->_fst), __pyx_v_state));
 
-  /* "pywrapfst.pyx":3117
- *     return "<ArcIterator at 0x{:x}>".format(id(self))
+  /* "pywrapfst.pyx":3146
+ *     return f"<ArcIterator at 0x{id(self):x}>"
  * 
  *   def __init__(self, Fst ifst, int64 state):             # <<<<<<<<<<<<<<
  *     if not ifst._fst.get().ValidStateId(state):
@@ -32532,7 +32712,7 @@ static int __pyx_pf_9pywrapfst_11ArcIterator_2__init__(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3125
+/* "pywrapfst.pyx":3154
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -32558,7 +32738,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_4__iter__(struct __pyx_obj_9p
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":3126
+  /* "pywrapfst.pyx":3155
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):
  *     return self             # <<<<<<<<<<<<<<
@@ -32570,7 +32750,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_4__iter__(struct __pyx_obj_9p
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3125
+  /* "pywrapfst.pyx":3154
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -32585,7 +32765,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_4__iter__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3129
+/* "pywrapfst.pyx":3158
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -32612,9 +32792,12 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__next__", 0);
 
-  /* "pywrapfst.pyx":3130
+  /* "pywrapfst.pyx":3159
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -32623,12 +32806,12 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "done");
-    __PYX_ERR(0, 3130, __pyx_L1_error)
+    __PYX_ERR(0, 3159, __pyx_L1_error)
   }
   __pyx_t_1 = (((struct __pyx_vtabstruct_9pywrapfst_ArcIterator *)__pyx_v_self->__pyx_vtab)->done(__pyx_v_self, 0) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":3131
+    /* "pywrapfst.pyx":3160
  *   def __next__(self):
  *     if self.done():
  *       raise StopIteration             # <<<<<<<<<<<<<<
@@ -32636,9 +32819,9 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
  *     self.next()
  */
     __Pyx_Raise(__pyx_builtin_StopIteration, 0, 0, 0);
-    __PYX_ERR(0, 3131, __pyx_L1_error)
+    __PYX_ERR(0, 3160, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3130
+    /* "pywrapfst.pyx":3159
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -32647,7 +32830,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
  */
   }
 
-  /* "pywrapfst.pyx":3132
+  /* "pywrapfst.pyx":3161
  *     if self.done():
  *       raise StopIteration
  *     result = self.value()             # <<<<<<<<<<<<<<
@@ -32656,14 +32839,14 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "value");
-    __PYX_ERR(0, 3132, __pyx_L1_error)
+    __PYX_ERR(0, 3161, __pyx_L1_error)
   }
-  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_ArcIterator *)__pyx_v_self->__pyx_vtab)->value(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3132, __pyx_L1_error)
+  __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_ArcIterator *)__pyx_v_self->__pyx_vtab)->value(__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3161, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_v_result = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3133
+  /* "pywrapfst.pyx":3162
  *       raise StopIteration
  *     result = self.value()
  *     self.next()             # <<<<<<<<<<<<<<
@@ -32672,11 +32855,11 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "next");
-    __PYX_ERR(0, 3133, __pyx_L1_error)
+    __PYX_ERR(0, 3162, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_ArcIterator *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":3134
+  /* "pywrapfst.pyx":3163
  *     result = self.value()
  *     self.next()
  *     return result             # <<<<<<<<<<<<<<
@@ -32688,7 +32871,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
   __pyx_r = __pyx_v_result;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3129
+  /* "pywrapfst.pyx":3158
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -32708,7 +32891,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_6__next__(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3136
+/* "pywrapfst.pyx":3165
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -32725,6 +32908,9 @@ static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_Ar
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   bool __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("done", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -32735,7 +32921,7 @@ static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_Ar
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3136, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3165, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_9done)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -32751,10 +32937,10 @@ static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_Ar
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3136, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3165, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3136, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3165, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -32773,7 +32959,7 @@ static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_Ar
     #endif
   }
 
-  /* "pywrapfst.pyx":3145
+  /* "pywrapfst.pyx":3174
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._aiter.get().Done()             # <<<<<<<<<<<<<<
@@ -32782,12 +32968,12 @@ static bool __pyx_f_9pywrapfst_11ArcIterator_done(struct __pyx_obj_9pywrapfst_Ar
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3145, __pyx_L1_error)
+    __PYX_ERR(0, 3174, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3136
+  /* "pywrapfst.pyx":3165
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -32826,9 +33012,12 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_8done(struct __pyx_obj_9pywra
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("done", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_11ArcIterator_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3136, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_11ArcIterator_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3165, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -32845,7 +33034,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_8done(struct __pyx_obj_9pywra
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3147
+/* "pywrapfst.pyx":3176
  *     return self._aiter.get().Done()
  * 
  *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
@@ -32862,6 +33051,9 @@ static uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct __pyx_obj_9pywrapfst_
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   uint8 __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("flags", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -32872,7 +33064,7 @@ static uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct __pyx_obj_9pywrapfst_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3147, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3176, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_11flags)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -32888,10 +33080,10 @@ static uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct __pyx_obj_9pywrapfst_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3147, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3176, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_uint8_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3147, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_uint8_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3176, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -32910,7 +33102,7 @@ static uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct __pyx_obj_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":3156
+  /* "pywrapfst.pyx":3185
  *       The current iterator behavioral flags as an integer.
  *     """
  *     return self._aiter.get().Flags()             # <<<<<<<<<<<<<<
@@ -32919,12 +33111,12 @@ static uint8 __pyx_f_9pywrapfst_11ArcIterator_flags(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3156, __pyx_L1_error)
+    __PYX_ERR(0, 3185, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Flags();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3147
+  /* "pywrapfst.pyx":3176
  *     return self._aiter.get().Done()
  * 
  *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
@@ -32963,9 +33155,12 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_10flags(struct __pyx_obj_9pyw
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("flags", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(__pyx_f_9pywrapfst_11ArcIterator_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3147, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(__pyx_f_9pywrapfst_11ArcIterator_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3176, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -32982,7 +33177,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_10flags(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3158
+/* "pywrapfst.pyx":3187
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -32997,6 +33192,9 @@ static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_Ar
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("next", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -33007,7 +33205,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_Ar
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3158, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3187, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_13next)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -33023,7 +33221,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_Ar
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3158, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3187, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -33043,7 +33241,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_Ar
     #endif
   }
 
-  /* "pywrapfst.pyx":3164
+  /* "pywrapfst.pyx":3193
  *     Advances the iterator.
  *     """
  *     self._aiter.get().Next()             # <<<<<<<<<<<<<<
@@ -33052,11 +33250,11 @@ static void __pyx_f_9pywrapfst_11ArcIterator_next(struct __pyx_obj_9pywrapfst_Ar
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3164, __pyx_L1_error)
+    __PYX_ERR(0, 3193, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Next();
 
-  /* "pywrapfst.pyx":3158
+  /* "pywrapfst.pyx":3187
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -33094,9 +33292,12 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_12next(struct __pyx_obj_9pywr
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("next", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_11ArcIterator_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3158, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_11ArcIterator_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3187, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33113,7 +33314,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_12next(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3166
+/* "pywrapfst.pyx":3195
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
@@ -33130,6 +33331,9 @@ static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   size_t __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("position", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -33140,7 +33344,7 @@ static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrap
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_position); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3166, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_position); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3195, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_15position)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -33156,10 +33360,10 @@ static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrap
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3166, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3195, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_5 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 3166, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_5 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 3195, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -33178,7 +33382,7 @@ static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":3175
+  /* "pywrapfst.pyx":3204
  *       The iterator's position, expressed as an integer.
  *     """
  *     return self._aiter.get().Position()             # <<<<<<<<<<<<<<
@@ -33187,12 +33391,12 @@ static size_t __pyx_f_9pywrapfst_11ArcIterator_position(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3175, __pyx_L1_error)
+    __PYX_ERR(0, 3204, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Position();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3166
+  /* "pywrapfst.pyx":3195
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
@@ -33231,9 +33435,12 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_14position(struct __pyx_obj_9
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("position", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_f_9pywrapfst_11ArcIterator_position(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3166, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_f_9pywrapfst_11ArcIterator_position(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3195, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33250,7 +33457,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_14position(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3177
+/* "pywrapfst.pyx":3206
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -33265,6 +33472,9 @@ static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_A
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reset", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -33275,7 +33485,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_A
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3177, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3206, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_17reset)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -33291,7 +33501,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_A
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3177, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3206, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -33311,7 +33521,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_A
     #endif
   }
 
-  /* "pywrapfst.pyx":3183
+  /* "pywrapfst.pyx":3212
  *     Resets the iterator to the initial position.
  *     """
  *     self._aiter.get().Reset()             # <<<<<<<<<<<<<<
@@ -33320,11 +33530,11 @@ static void __pyx_f_9pywrapfst_11ArcIterator_reset(struct __pyx_obj_9pywrapfst_A
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3183, __pyx_L1_error)
+    __PYX_ERR(0, 3212, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Reset();
 
-  /* "pywrapfst.pyx":3177
+  /* "pywrapfst.pyx":3206
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -33362,9 +33572,12 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_16reset(struct __pyx_obj_9pyw
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reset", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_11ArcIterator_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3177, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_11ArcIterator_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3206, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33381,7 +33594,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_16reset(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3185
+/* "pywrapfst.pyx":3214
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -33397,6 +33610,9 @@ static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_Ar
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("seek", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -33407,10 +33623,10 @@ static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_Ar
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_seek); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3185, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_seek); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3214, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_19seek)) {
-        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3185, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3214, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -33426,7 +33642,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_Ar
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3185, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3214, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -33446,7 +33662,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_Ar
     #endif
   }
 
-  /* "pywrapfst.pyx":3194
+  /* "pywrapfst.pyx":3223
  *       a: The position to seek to.
  *     """
  *     self._aiter.get().Seek(a)             # <<<<<<<<<<<<<<
@@ -33455,11 +33671,11 @@ static void __pyx_f_9pywrapfst_11ArcIterator_seek(struct __pyx_obj_9pywrapfst_Ar
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3194, __pyx_L1_error)
+    __PYX_ERR(0, 3223, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Seek(__pyx_v_a);
 
-  /* "pywrapfst.pyx":3185
+  /* "pywrapfst.pyx":3214
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -33485,11 +33701,14 @@ static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_19seek(PyObject *__pyx_v_self
 static char __pyx_doc_9pywrapfst_11ArcIterator_18seek[] = "\n    seek(self, a)\n\n    Advance the iterator to a new position.\n\n    Args:\n      a: The position to seek to.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_19seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a) {
   size_t __pyx_v_a;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("seek (wrapper)", 0);
   assert(__pyx_arg_a); {
-    __pyx_v_a = __Pyx_PyInt_As_size_t(__pyx_arg_a); if (unlikely((__pyx_v_a == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 3185, __pyx_L3_error)
+    __pyx_v_a = __Pyx_PyInt_As_size_t(__pyx_arg_a); if (unlikely((__pyx_v_a == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 3214, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -33508,9 +33727,12 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_18seek(struct __pyx_obj_9pywr
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("seek", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_11ArcIterator_seek(__pyx_v_self, __pyx_v_a, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3185, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_11ArcIterator_seek(__pyx_v_self, __pyx_v_a, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3214, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33527,7 +33749,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_18seek(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3196
+/* "pywrapfst.pyx":3225
  *     self._aiter.get().Seek(a)
  * 
  *   cpdef void set_flags(self, uint8 flags, uint8 mask):             # <<<<<<<<<<<<<<
@@ -33546,6 +33768,9 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
   PyObject *__pyx_t_6 = NULL;
   int __pyx_t_7;
   PyObject *__pyx_t_8 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_flags", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -33556,12 +33781,12 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3196, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3225, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_21set_flags)) {
-        __pyx_t_3 = __Pyx_PyInt_From_uint8_t(__pyx_v_flags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3196, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_uint8_t(__pyx_v_flags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3225, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_4 = __Pyx_PyInt_From_uint8_t(__pyx_v_mask); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3196, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyInt_From_uint8_t(__pyx_v_mask); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3225, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
@@ -33579,7 +33804,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_5)) {
           PyObject *__pyx_temp[3] = {__pyx_t_6, __pyx_t_3, __pyx_t_4};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3196, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3225, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -33589,7 +33814,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
           PyObject *__pyx_temp[3] = {__pyx_t_6, __pyx_t_3, __pyx_t_4};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3196, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3225, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -33597,7 +33822,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
         } else
         #endif
         {
-          __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3196, __pyx_L1_error)
+          __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3225, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_8);
           if (__pyx_t_6) {
             __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
@@ -33608,7 +33833,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
           PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_t_4);
           __pyx_t_3 = 0;
           __pyx_t_4 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3196, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3225, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         }
@@ -33630,7 +33855,7 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
     #endif
   }
 
-  /* "pywrapfst.pyx":3206
+  /* "pywrapfst.pyx":3235
  *       mask: A mask to be applied to the `flags` argument before setting them.
  *     """
  *     self._aiter.get().SetFlags(flags, mask)             # <<<<<<<<<<<<<<
@@ -33639,11 +33864,11 @@ static void __pyx_f_9pywrapfst_11ArcIterator_set_flags(struct __pyx_obj_9pywrapf
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3206, __pyx_L1_error)
+    __PYX_ERR(0, 3235, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->SetFlags(__pyx_v_flags, __pyx_v_mask);
 
-  /* "pywrapfst.pyx":3196
+  /* "pywrapfst.pyx":3225
  *     self._aiter.get().Seek(a)
  * 
  *   cpdef void set_flags(self, uint8 flags, uint8 mask):             # <<<<<<<<<<<<<<
@@ -33672,6 +33897,9 @@ static char __pyx_doc_9pywrapfst_11ArcIterator_20set_flags[] = "\n    set_flags(
 static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_21set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   uint8 __pyx_v_flags;
   uint8 __pyx_v_mask;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_flags (wrapper)", 0);
@@ -33698,11 +33926,11 @@ static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_21set_flags(PyObject *__pyx_v
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mask)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, 1); __PYX_ERR(0, 3196, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, 1); __PYX_ERR(0, 3225, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_flags") < 0)) __PYX_ERR(0, 3196, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_flags") < 0)) __PYX_ERR(0, 3225, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -33710,12 +33938,12 @@ static PyObject *__pyx_pw_9pywrapfst_11ArcIterator_21set_flags(PyObject *__pyx_v
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
-    __pyx_v_flags = __Pyx_PyInt_As_uint8_t(values[0]); if (unlikely((__pyx_v_flags == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3196, __pyx_L3_error)
-    __pyx_v_mask = __Pyx_PyInt_As_uint8_t(values[1]); if (unlikely((__pyx_v_mask == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3196, __pyx_L3_error)
+    __pyx_v_flags = __Pyx_PyInt_As_uint8_t(values[0]); if (unlikely((__pyx_v_flags == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3225, __pyx_L3_error)
+    __pyx_v_mask = __Pyx_PyInt_As_uint8_t(values[1]); if (unlikely((__pyx_v_mask == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3225, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3196, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3225, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.ArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -33732,9 +33960,12 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_flags", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_11ArcIterator_set_flags(__pyx_v_self, __pyx_v_flags, __pyx_v_mask, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3196, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_11ArcIterator_set_flags(__pyx_v_self, __pyx_v_flags, __pyx_v_mask, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3225, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33751,7 +33982,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_20set_flags(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3208
+/* "pywrapfst.pyx":3237
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -33767,6 +33998,9 @@ static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrap
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("value", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -33777,7 +34011,7 @@ static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrap
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3208, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3237, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_11ArcIterator_23value)) {
         __Pyx_XDECREF(__pyx_r);
@@ -33794,7 +34028,7 @@ static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrap
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3208, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3237, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __pyx_r = __pyx_t_2;
@@ -33815,7 +34049,7 @@ static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrap
     #endif
   }
 
-  /* "pywrapfst.pyx":3214
+  /* "pywrapfst.pyx":3243
  *     Returns the current arc.
  *     """
  *     return _init_Arc(self._aiter.get().Value())             # <<<<<<<<<<<<<<
@@ -33825,15 +34059,15 @@ static PyObject *__pyx_f_9pywrapfst_11ArcIterator_value(struct __pyx_obj_9pywrap
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3214, __pyx_L1_error)
+    __PYX_ERR(0, 3243, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_Arc(__pyx_v_self->_aiter.get()->Value())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3214, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_Arc(__pyx_v_self->_aiter.get()->Value())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3243, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3208
+  /* "pywrapfst.pyx":3237
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -33873,9 +34107,12 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_22value(struct __pyx_obj_9pyw
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("value", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_11ArcIterator_value(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3208, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_11ArcIterator_value(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3237, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -33915,6 +34152,9 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_24__reduce_cython__(CYTHON_UN
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__reduce_cython__", 0);
 
   /* "(tree fragment)":2
@@ -33923,7 +34163,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_24__reduce_cython__(CYTHON_UN
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._aiter,self._fst cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__24, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__26, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -33969,6 +34209,9 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_26__setstate_cython__(CYTHON_
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__setstate_cython__", 0);
 
   /* "(tree fragment)":4
@@ -33976,7 +34219,7 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_26__setstate_cython__(CYTHON_
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._aiter,self._fst cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__25, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__27, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -33999,11 +34242,11 @@ static PyObject *__pyx_pf_9pywrapfst_11ArcIterator_26__setstate_cython__(CYTHON_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3226
+/* "pywrapfst.pyx":3255
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<MutableArcIterator at 0x{:x}>".format(id(self))
+ *     return f"<MutableArcIterator at 0x{id(self):x}>"
  * 
  */
 
@@ -34024,57 +34267,65 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_2;
+  Py_UCS4 __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":3227
+  /* "pywrapfst.pyx":3256
  * 
  *   def __repr__(self):
- *     return "<MutableArcIterator at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
+ *     return f"<MutableArcIterator at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
  * 
  *   def __init__(self, MutableFst ifst, int64 state):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_MutableArcIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3227, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3227, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = NULL;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
-    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
-    if (likely(__pyx_t_4)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-      __Pyx_INCREF(__pyx_t_4);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_2, function);
-    }
-  }
-  __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3227, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3256, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 127;
+  __Pyx_INCREF(__pyx_kp_u_MutableArcIterator_at_0x);
+  __pyx_t_2 += 25;
+  __Pyx_GIVEREF(__pyx_kp_u_MutableArcIterator_at_0x);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_MutableArcIterator_at_0x);
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3256, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3256, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_5);
+  __pyx_t_5 = 0;
+  __Pyx_INCREF(__pyx_kp_u__3);
+  __pyx_t_2 += 1;
+  __Pyx_GIVEREF(__pyx_kp_u__3);
+  PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u__3);
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3256, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3226
+  /* "pywrapfst.pyx":3255
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<MutableArcIterator at 0x{:x}>".format(id(self))
+ *     return f"<MutableArcIterator at 0x{id(self):x}>"
  * 
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
   __Pyx_AddTraceback("pywrapfst.MutableArcIterator.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -34083,8 +34334,8 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator___repr__(struct __pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3229
- *     return "<MutableArcIterator at 0x{:x}>".format(id(self))
+/* "pywrapfst.pyx":3258
+ *     return f"<MutableArcIterator at 0x{id(self):x}>"
  * 
  *   def __init__(self, MutableFst ifst, int64 state):             # <<<<<<<<<<<<<<
  *     if not ifst._fst.get().ValidStateId(state):
@@ -34096,6 +34347,9 @@ static int __pyx_pw_9pywrapfst_18MutableArcIterator_3__init__(PyObject *__pyx_v_
 static int __pyx_pw_9pywrapfst_18MutableArcIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_MutableFst *__pyx_v_ifst = 0;
   int64 __pyx_v_state;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
@@ -34122,11 +34376,11 @@ static int __pyx_pw_9pywrapfst_18MutableArcIterator_3__init__(PyObject *__pyx_v_
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_state)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 3229, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 3258, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3229, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3258, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -34135,17 +34389,17 @@ static int __pyx_pw_9pywrapfst_18MutableArcIterator_3__init__(PyObject *__pyx_v_
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_MutableFst *)values[0]);
-    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3229, __pyx_L3_error)
+    __pyx_v_state = __Pyx_PyInt_As_int64_t(values[1]); if (unlikely((__pyx_v_state == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3258, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3229, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3258, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableArcIterator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return -1;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_MutableFst, 1, "ifst", 0))) __PYX_ERR(0, 3229, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_MutableFst, 1, "ifst", 0))) __PYX_ERR(0, 3258, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self), __pyx_v_ifst, __pyx_v_state);
 
   /* function exit code */
@@ -34165,9 +34419,12 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   std::shared_ptr<fst::script::MutableFstClass>  __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":3230
+  /* "pywrapfst.pyx":3259
  * 
  *   def __init__(self, MutableFst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -34176,19 +34433,19 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3230, __pyx_L1_error)
+    __PYX_ERR(0, 3259, __pyx_L1_error)
   }
   __pyx_t_1 = ((!(__pyx_v_ifst->__pyx_base._fst.get()->ValidStateId(__pyx_v_state) != 0)) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":3231
+    /* "pywrapfst.pyx":3260
  *   def __init__(self, MutableFst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):
  *       raise FstIndexError("State index out of range")             # <<<<<<<<<<<<<<
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._mfst = ifst._mfst
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3231, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIndexError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3260, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_4 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
@@ -34202,14 +34459,14 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
     }
     __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_kp_u_State_index_out_of_range) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_kp_u_State_index_out_of_range);
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3231, __pyx_L1_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3260, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 3231, __pyx_L1_error)
+    __PYX_ERR(0, 3260, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3230
+    /* "pywrapfst.pyx":3259
  * 
  *   def __init__(self, MutableFst ifst, int64 state):
  *     if not ifst._fst.get().ValidStateId(state):             # <<<<<<<<<<<<<<
@@ -34218,7 +34475,7 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
  */
   }
 
-  /* "pywrapfst.pyx":3233
+  /* "pywrapfst.pyx":3262
  *       raise FstIndexError("State index out of range")
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._mfst = ifst._mfst             # <<<<<<<<<<<<<<
@@ -34227,16 +34484,16 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 3233, __pyx_L1_error)
+    __PYX_ERR(0, 3262, __pyx_L1_error)
   }
   __pyx_t_5 = __pyx_v_ifst->_mfst;
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 3233, __pyx_L1_error)
+    __PYX_ERR(0, 3262, __pyx_L1_error)
   }
   __pyx_v_self->_mfst = __pyx_t_5;
 
-  /* "pywrapfst.pyx":3234
+  /* "pywrapfst.pyx":3263
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._mfst = ifst._mfst
  *     self._aiter.reset(new fst.MutableArcIteratorClass(ifst._mfst.get(), state))             # <<<<<<<<<<<<<<
@@ -34245,16 +34502,16 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3234, __pyx_L1_error)
+    __PYX_ERR(0, 3263, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_mfst");
-    __PYX_ERR(0, 3234, __pyx_L1_error)
+    __PYX_ERR(0, 3263, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.reset(new fst::script::MutableArcIteratorClass(__pyx_v_ifst->_mfst.get(), __pyx_v_state));
 
-  /* "pywrapfst.pyx":3229
- *     return "<MutableArcIterator at 0x{:x}>".format(id(self))
+  /* "pywrapfst.pyx":3258
+ *     return f"<MutableArcIterator at 0x{id(self):x}>"
  * 
  *   def __init__(self, MutableFst ifst, int64 state):             # <<<<<<<<<<<<<<
  *     if not ifst._fst.get().ValidStateId(state):
@@ -34276,7 +34533,7 @@ static int __pyx_pf_9pywrapfst_18MutableArcIterator_2__init__(struct __pyx_obj_9
 }
 static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */
 
-/* "pywrapfst.pyx":3237
+/* "pywrapfst.pyx":3266
  * 
  *   # Magic method used to get a Pythonic Iterator API out of the C++ API.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -34301,12 +34558,15 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_4__iter__(struct __pyx
   struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__ *__pyx_cur_scope;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__iter__", 0);
   __pyx_cur_scope = (struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__ *)__pyx_tp_new_9pywrapfst___pyx_scope_struct____iter__(__pyx_ptype_9pywrapfst___pyx_scope_struct____iter__, __pyx_empty_tuple, NULL);
   if (unlikely(!__pyx_cur_scope)) {
     __pyx_cur_scope = ((struct __pyx_obj_9pywrapfst___pyx_scope_struct____iter__ *)Py_None);
     __Pyx_INCREF(Py_None);
-    __PYX_ERR(0, 3237, __pyx_L1_error)
+    __PYX_ERR(0, 3266, __pyx_L1_error)
   } else {
     __Pyx_GOTREF(__pyx_cur_scope);
   }
@@ -34314,7 +34574,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_4__iter__(struct __pyx
   __Pyx_INCREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
   __Pyx_GIVEREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
   {
-    __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9pywrapfst_18MutableArcIterator_6generator, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_iter, __pyx_n_s_MutableArcIterator___iter, __pyx_n_s_pywrapfst_2); if (unlikely(!gen)) __PYX_ERR(0, 3237, __pyx_L1_error)
+    __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_9pywrapfst_18MutableArcIterator_6generator, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_iter, __pyx_n_s_MutableArcIterator___iter, __pyx_n_s_pywrapfst_2); if (unlikely(!gen)) __PYX_ERR(0, 3266, __pyx_L1_error)
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -34336,6 +34596,9 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
   PyObject *__pyx_r = NULL;
   int __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__", 0);
   switch (__pyx_generator->resume_label) {
@@ -34346,9 +34609,9 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 3237, __pyx_L1_error)
+  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 3266, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3238
+  /* "pywrapfst.pyx":3267
  *   # Magic method used to get a Pythonic Iterator API out of the C++ API.
  *   def __iter__(self):
  *     while not self.done():             # <<<<<<<<<<<<<<
@@ -34358,12 +34621,12 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
   while (1) {
     if (unlikely(((PyObject *)__pyx_cur_scope->__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "done");
-      __PYX_ERR(0, 3238, __pyx_L1_error)
+      __PYX_ERR(0, 3267, __pyx_L1_error)
     }
     __pyx_t_1 = ((!(((struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->done(__pyx_cur_scope->__pyx_v_self, 0) != 0)) != 0);
     if (!__pyx_t_1) break;
 
-    /* "pywrapfst.pyx":3239
+    /* "pywrapfst.pyx":3268
  *   def __iter__(self):
  *     while not self.done():
  *       yield self.value()             # <<<<<<<<<<<<<<
@@ -34372,9 +34635,9 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
  */
     if (unlikely(((PyObject *)__pyx_cur_scope->__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "value");
-      __PYX_ERR(0, 3239, __pyx_L1_error)
+      __PYX_ERR(0, 3268, __pyx_L1_error)
     }
-    __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->value(__pyx_cur_scope->__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3239, __pyx_L1_error)
+    __pyx_t_2 = ((struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->value(__pyx_cur_scope->__pyx_v_self, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3268, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_r = __pyx_t_2;
     __pyx_t_2 = 0;
@@ -34385,9 +34648,9 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
     __pyx_generator->resume_label = 1;
     return __pyx_r;
     __pyx_L6_resume_from_yield:;
-    if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 3239, __pyx_L1_error)
+    if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 3268, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3240
+    /* "pywrapfst.pyx":3269
  *     while not self.done():
  *       yield self.value()
  *       self.next()             # <<<<<<<<<<<<<<
@@ -34396,13 +34659,13 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
  */
     if (unlikely(((PyObject *)__pyx_cur_scope->__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "next");
-      __PYX_ERR(0, 3240, __pyx_L1_error)
+      __PYX_ERR(0, 3269, __pyx_L1_error)
     }
     ((struct __pyx_vtabstruct_9pywrapfst_MutableArcIterator *)__pyx_cur_scope->__pyx_v_self->__pyx_vtab)->next(__pyx_cur_scope->__pyx_v_self, 0);
   }
   CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope);
 
-  /* "pywrapfst.pyx":3237
+  /* "pywrapfst.pyx":3266
  * 
  *   # Magic method used to get a Pythonic Iterator API out of the C++ API.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -34427,7 +34690,7 @@ static PyObject *__pyx_gb_9pywrapfst_18MutableArcIterator_6generator(__pyx_Corou
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3242
+/* "pywrapfst.pyx":3271
  *       self.next()
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -34444,6 +34707,9 @@ static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywra
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   bool __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("done", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -34454,7 +34720,7 @@ static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywra
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3242, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3271, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_8done)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -34470,10 +34736,10 @@ static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywra
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3242, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3271, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3242, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3271, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -34492,7 +34758,7 @@ static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":3251
+  /* "pywrapfst.pyx":3280
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._aiter.get().Done()             # <<<<<<<<<<<<<<
@@ -34501,12 +34767,12 @@ static bool __pyx_f_9pywrapfst_18MutableArcIterator_done(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3251, __pyx_L1_error)
+    __PYX_ERR(0, 3280, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3242
+  /* "pywrapfst.pyx":3271
  *       self.next()
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -34545,9 +34811,12 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_7done(struct __pyx_obj
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("done", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_18MutableArcIterator_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3242, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_18MutableArcIterator_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3271, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34564,7 +34833,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_7done(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3253
+/* "pywrapfst.pyx":3282
  *     return self._aiter.get().Done()
  * 
  *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
@@ -34581,6 +34850,9 @@ static uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(struct __pyx_obj_9pyw
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   uint8 __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("flags", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -34591,7 +34863,7 @@ static uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(struct __pyx_obj_9pyw
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3253, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3282, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_10flags)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -34607,10 +34879,10 @@ static uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(struct __pyx_obj_9pyw
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3253, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3282, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_uint8_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3253, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_uint8_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3282, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -34629,7 +34901,7 @@ static uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(struct __pyx_obj_9pyw
     #endif
   }
 
-  /* "pywrapfst.pyx":3262
+  /* "pywrapfst.pyx":3291
  *       The current iterator behavioral flags as an integer.
  *     """
  *     return self._aiter.get().Flags()             # <<<<<<<<<<<<<<
@@ -34638,12 +34910,12 @@ static uint8 __pyx_f_9pywrapfst_18MutableArcIterator_flags(struct __pyx_obj_9pyw
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3262, __pyx_L1_error)
+    __PYX_ERR(0, 3291, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Flags();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3253
+  /* "pywrapfst.pyx":3282
  *     return self._aiter.get().Done()
  * 
  *   cpdef uint8 flags(self):             # <<<<<<<<<<<<<<
@@ -34682,9 +34954,12 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_9flags(struct __pyx_ob
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("flags", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(__pyx_f_9pywrapfst_18MutableArcIterator_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3253, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(__pyx_f_9pywrapfst_18MutableArcIterator_flags(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3282, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34701,7 +34976,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_9flags(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3264
+/* "pywrapfst.pyx":3293
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -34716,6 +34991,9 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywra
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("next", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -34726,7 +35004,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywra
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3264, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3293, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_12next)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -34742,7 +35020,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywra
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3264, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3293, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -34762,7 +35040,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":3270
+  /* "pywrapfst.pyx":3299
  *     Advances the iterator.
  *     """
  *     self._aiter.get().Next()             # <<<<<<<<<<<<<<
@@ -34771,11 +35049,11 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_next(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3270, __pyx_L1_error)
+    __PYX_ERR(0, 3299, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Next();
 
-  /* "pywrapfst.pyx":3264
+  /* "pywrapfst.pyx":3293
  *     return self._aiter.get().Flags()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -34813,9 +35091,12 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_11next(struct __pyx_ob
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("next", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_18MutableArcIterator_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3264, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_18MutableArcIterator_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3293, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34832,7 +35113,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_11next(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3272
+/* "pywrapfst.pyx":3301
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
@@ -34849,6 +35130,9 @@ static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   size_t __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("position", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -34859,7 +35143,7 @@ static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_position); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3272, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_position); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3301, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_14position)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -34875,10 +35159,10 @@ static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3272, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3301, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_5 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 3272, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_5 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 3301, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -34897,7 +35181,7 @@ static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_
     #endif
   }
 
-  /* "pywrapfst.pyx":3281
+  /* "pywrapfst.pyx":3310
  *       The iterator's position, expressed as an integer.
  *     """
  *     return self._aiter.get().Position()             # <<<<<<<<<<<<<<
@@ -34906,12 +35190,12 @@ static size_t __pyx_f_9pywrapfst_18MutableArcIterator_position(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3281, __pyx_L1_error)
+    __PYX_ERR(0, 3310, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_aiter.get()->Position();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3272
+  /* "pywrapfst.pyx":3301
  *     self._aiter.get().Next()
  * 
  *   cpdef size_t position(self):             # <<<<<<<<<<<<<<
@@ -34950,9 +35234,12 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_13position(struct __py
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("position", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_f_9pywrapfst_18MutableArcIterator_position(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3272, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_f_9pywrapfst_18MutableArcIterator_position(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3301, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -34969,7 +35256,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_13position(struct __py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3283
+/* "pywrapfst.pyx":3312
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -34984,6 +35271,9 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywr
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reset", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -34994,7 +35284,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3283, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3312, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_16reset)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -35010,7 +35300,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywr
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3283, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3312, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -35030,7 +35320,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":3289
+  /* "pywrapfst.pyx":3318
  *     Resets the iterator to the initial position.
  *     """
  *     self._aiter.get().Reset()             # <<<<<<<<<<<<<<
@@ -35039,11 +35329,11 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_reset(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3289, __pyx_L1_error)
+    __PYX_ERR(0, 3318, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Reset();
 
-  /* "pywrapfst.pyx":3283
+  /* "pywrapfst.pyx":3312
  *     return self._aiter.get().Position()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -35081,9 +35371,12 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_15reset(struct __pyx_o
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reset", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_18MutableArcIterator_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3283, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_18MutableArcIterator_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3312, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35100,7 +35393,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_15reset(struct __pyx_o
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3291
+/* "pywrapfst.pyx":3320
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -35116,6 +35409,9 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywra
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("seek", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -35126,10 +35422,10 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywra
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_seek); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3291, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_seek); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3320, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_18seek)) {
-        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3291, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_a); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3320, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
@@ -35145,7 +35441,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywra
         __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3);
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3291, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3320, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -35165,7 +35461,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":3300
+  /* "pywrapfst.pyx":3329
  *       a: The position to seek to.
  *     """
  *     self._aiter.get().Seek(a)             # <<<<<<<<<<<<<<
@@ -35174,11 +35470,11 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_seek(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3300, __pyx_L1_error)
+    __PYX_ERR(0, 3329, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->Seek(__pyx_v_a);
 
-  /* "pywrapfst.pyx":3291
+  /* "pywrapfst.pyx":3320
  *     self._aiter.get().Reset()
  * 
  *   cpdef void seek(self, size_t a):             # <<<<<<<<<<<<<<
@@ -35204,11 +35500,14 @@ static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_18seek(PyObject *__pyx
 static char __pyx_doc_9pywrapfst_18MutableArcIterator_17seek[] = "\n    seek(self, a)\n\n    Advance the iterator to a new position.\n\n    Args:\n      a: The position to seek to.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_18seek(PyObject *__pyx_v_self, PyObject *__pyx_arg_a) {
   size_t __pyx_v_a;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("seek (wrapper)", 0);
   assert(__pyx_arg_a); {
-    __pyx_v_a = __Pyx_PyInt_As_size_t(__pyx_arg_a); if (unlikely((__pyx_v_a == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 3291, __pyx_L3_error)
+    __pyx_v_a = __Pyx_PyInt_As_size_t(__pyx_arg_a); if (unlikely((__pyx_v_a == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 3320, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -35227,9 +35526,12 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_17seek(struct __pyx_ob
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("seek", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_18MutableArcIterator_seek(__pyx_v_self, __pyx_v_a, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3291, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_18MutableArcIterator_seek(__pyx_v_self, __pyx_v_a, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3320, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35246,7 +35548,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_17seek(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3302
+/* "pywrapfst.pyx":3331
  *     self._aiter.get().Seek(a)
  * 
  *   cpdef void set_flags(self, uint8 flags, uint8 mask):             # <<<<<<<<<<<<<<
@@ -35265,6 +35567,9 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
   PyObject *__pyx_t_6 = NULL;
   int __pyx_t_7;
   PyObject *__pyx_t_8 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_flags", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -35275,12 +35580,12 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3302, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3331, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags)) {
-        __pyx_t_3 = __Pyx_PyInt_From_uint8_t(__pyx_v_flags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3302, __pyx_L1_error)
+        __pyx_t_3 = __Pyx_PyInt_From_uint8_t(__pyx_v_flags); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3331, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_3);
-        __pyx_t_4 = __Pyx_PyInt_From_uint8_t(__pyx_v_mask); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3302, __pyx_L1_error)
+        __pyx_t_4 = __Pyx_PyInt_From_uint8_t(__pyx_v_mask); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3331, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_INCREF(__pyx_t_1);
         __pyx_t_5 = __pyx_t_1; __pyx_t_6 = NULL;
@@ -35298,7 +35603,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_5)) {
           PyObject *__pyx_temp[3] = {__pyx_t_6, __pyx_t_3, __pyx_t_4};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3302, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3331, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -35308,7 +35613,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
           PyObject *__pyx_temp[3] = {__pyx_t_6, __pyx_t_3, __pyx_t_4};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3302, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_7, 2+__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3331, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -35316,7 +35621,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
         } else
         #endif
         {
-          __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3302, __pyx_L1_error)
+          __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3331, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_8);
           if (__pyx_t_6) {
             __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __pyx_t_6 = NULL;
@@ -35327,7 +35632,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
           PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_t_4);
           __pyx_t_3 = 0;
           __pyx_t_4 = 0;
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3302, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3331, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         }
@@ -35349,7 +35654,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
     #endif
   }
 
-  /* "pywrapfst.pyx":3312
+  /* "pywrapfst.pyx":3341
  *       mask: A mask to be applied to the `flags` argument before setting them.
  *     """
  *     self._aiter.get().SetFlags(flags, mask)             # <<<<<<<<<<<<<<
@@ -35358,11 +35663,11 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_flags(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3312, __pyx_L1_error)
+    __PYX_ERR(0, 3341, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->SetFlags(__pyx_v_flags, __pyx_v_mask);
 
-  /* "pywrapfst.pyx":3302
+  /* "pywrapfst.pyx":3331
  *     self._aiter.get().Seek(a)
  * 
  *   cpdef void set_flags(self, uint8 flags, uint8 mask):             # <<<<<<<<<<<<<<
@@ -35391,6 +35696,9 @@ static char __pyx_doc_9pywrapfst_18MutableArcIterator_19set_flags[] = "\n    set
 static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   uint8 __pyx_v_flags;
   uint8 __pyx_v_mask;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_flags (wrapper)", 0);
@@ -35417,11 +35725,11 @@ static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags(PyObject *
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mask)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, 1); __PYX_ERR(0, 3302, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, 1); __PYX_ERR(0, 3331, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_flags") < 0)) __PYX_ERR(0, 3302, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "set_flags") < 0)) __PYX_ERR(0, 3331, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -35429,12 +35737,12 @@ static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_20set_flags(PyObject *
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
-    __pyx_v_flags = __Pyx_PyInt_As_uint8_t(values[0]); if (unlikely((__pyx_v_flags == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3302, __pyx_L3_error)
-    __pyx_v_mask = __Pyx_PyInt_As_uint8_t(values[1]); if (unlikely((__pyx_v_mask == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3302, __pyx_L3_error)
+    __pyx_v_flags = __Pyx_PyInt_As_uint8_t(values[0]); if (unlikely((__pyx_v_flags == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3331, __pyx_L3_error)
+    __pyx_v_mask = __Pyx_PyInt_As_uint8_t(values[1]); if (unlikely((__pyx_v_mask == ((uint8)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3331, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3302, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("set_flags", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3331, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.MutableArcIterator.set_flags", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -35451,9 +35759,12 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_19set_flags(struct __p
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_flags", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_18MutableArcIterator_set_flags(__pyx_v_self, __pyx_v_flags, __pyx_v_mask, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3302, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_18MutableArcIterator_set_flags(__pyx_v_self, __pyx_v_flags, __pyx_v_mask, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3331, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35470,7 +35781,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_19set_flags(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3314
+/* "pywrapfst.pyx":3343
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef void set_value(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -35485,6 +35796,9 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_value", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -35495,7 +35809,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3314, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_set_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3343, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_22set_value)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -35511,7 +35825,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, ((PyObject *)__pyx_v_arc)) : __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_arc));
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3314, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3343, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -35531,7 +35845,7 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
     #endif
   }
 
-  /* "pywrapfst.pyx":3323
+  /* "pywrapfst.pyx":3352
  *       arc: The arc to replace the current arc with.
  *     """
  *     self._aiter.get().SetValue(deref(arc._arc))             # <<<<<<<<<<<<<<
@@ -35540,15 +35854,15 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3323, __pyx_L1_error)
+    __PYX_ERR(0, 3352, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_arc) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc");
-    __PYX_ERR(0, 3323, __pyx_L1_error)
+    __PYX_ERR(0, 3352, __pyx_L1_error)
   }
   __pyx_v_self->_aiter.get()->SetValue((*__pyx_v_arc->_arc));
 
-  /* "pywrapfst.pyx":3314
+  /* "pywrapfst.pyx":3343
  *     self._aiter.get().SetFlags(flags, mask)
  * 
  *   cpdef void set_value(self, Arc arc):             # <<<<<<<<<<<<<<
@@ -35572,10 +35886,13 @@ static void __pyx_f_9pywrapfst_18MutableArcIterator_set_value(struct __pyx_obj_9
 static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_22set_value(PyObject *__pyx_v_self, PyObject *__pyx_v_arc); /*proto*/
 static char __pyx_doc_9pywrapfst_18MutableArcIterator_21set_value[] = "\n    set_value(self, arc)\n\n    Replace the current arc with a new arc.\n\n    Args:\n      arc: The arc to replace the current arc with.\n    ";
 static PyObject *__pyx_pw_9pywrapfst_18MutableArcIterator_22set_value(PyObject *__pyx_v_self, PyObject *__pyx_v_arc) {
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_value (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 3314, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc), __pyx_ptype_9pywrapfst_Arc, 1, "arc", 0))) __PYX_ERR(0, 3343, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_18MutableArcIterator_21set_value(((struct __pyx_obj_9pywrapfst_MutableArcIterator *)__pyx_v_self), ((struct __pyx_obj_9pywrapfst_Arc *)__pyx_v_arc));
 
   /* function exit code */
@@ -35591,9 +35908,12 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_21set_value(struct __p
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_value", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_18MutableArcIterator_set_value(__pyx_v_self, __pyx_v_arc, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3314, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_18MutableArcIterator_set_value(__pyx_v_self, __pyx_v_arc, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3343, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35610,7 +35930,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_21set_value(struct __p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3325
+/* "pywrapfst.pyx":3354
  *     self._aiter.get().SetValue(deref(arc._arc))
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -35626,6 +35946,9 @@ static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("value", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -35636,7 +35959,7 @@ static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3325, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3354, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_18MutableArcIterator_24value)) {
         __Pyx_XDECREF(__pyx_r);
@@ -35653,7 +35976,7 @@ static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3325, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3354, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __pyx_r = __pyx_t_2;
@@ -35674,7 +35997,7 @@ static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_
     #endif
   }
 
-  /* "pywrapfst.pyx":3331
+  /* "pywrapfst.pyx":3360
  *     Returns the current arc.
  *     """
  *     return _init_Arc(self._aiter.get().Value())             # <<<<<<<<<<<<<<
@@ -35684,15 +36007,15 @@ static PyObject *__pyx_f_9pywrapfst_18MutableArcIterator_value(struct __pyx_obj_
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_aiter");
-    __PYX_ERR(0, 3331, __pyx_L1_error)
+    __PYX_ERR(0, 3360, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_Arc(__pyx_v_self->_aiter.get()->Value())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3331, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_Arc(__pyx_v_self->_aiter.get()->Value())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3360, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3325
+  /* "pywrapfst.pyx":3354
  *     self._aiter.get().SetValue(deref(arc._arc))
  * 
  *   cpdef object value(self):             # <<<<<<<<<<<<<<
@@ -35732,9 +36055,12 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_23value(struct __pyx_o
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("value", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_9pywrapfst_18MutableArcIterator_value(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3325, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_18MutableArcIterator_value(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3354, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -35774,6 +36100,9 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_25__reduce_cython__(CY
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__reduce_cython__", 0);
 
   /* "(tree fragment)":2
@@ -35782,7 +36111,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_25__reduce_cython__(CY
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._aiter,self._mfst cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__26, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__28, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -35828,6 +36157,9 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_27__setstate_cython__(
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__setstate_cython__", 0);
 
   /* "(tree fragment)":4
@@ -35835,7 +36167,7 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_27__setstate_cython__(
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._aiter,self._mfst cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__27, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__29, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -35858,11 +36190,11 @@ static PyObject *__pyx_pf_9pywrapfst_18MutableArcIterator_27__setstate_cython__(
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3345
+/* "pywrapfst.pyx":3374
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<StateIterator at 0x{:x}>".format(id(self))
+ *     return f"<StateIterator at 0x{id(self):x}>"
  * 
  */
 
@@ -35883,57 +36215,65 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_2;
+  Py_UCS4 __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":3346
+  /* "pywrapfst.pyx":3375
  * 
  *   def __repr__(self):
- *     return "<StateIterator at 0x{:x}>".format(id(self))             # <<<<<<<<<<<<<<
+ *     return f"<StateIterator at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
  * 
  *   def __init__(self, Fst ifst):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_StateIterator_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3346, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3346, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = NULL;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
-    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
-    if (likely(__pyx_t_4)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-      __Pyx_INCREF(__pyx_t_4);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_2, function);
-    }
-  }
-  __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3346, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3375, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 127;
+  __Pyx_INCREF(__pyx_kp_u_StateIterator_at_0x);
+  __pyx_t_2 += 20;
+  __Pyx_GIVEREF(__pyx_kp_u_StateIterator_at_0x);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_StateIterator_at_0x);
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3375, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3375, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_5);
+  __pyx_t_5 = 0;
+  __Pyx_INCREF(__pyx_kp_u__3);
+  __pyx_t_2 += 1;
+  __Pyx_GIVEREF(__pyx_kp_u__3);
+  PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u__3);
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3375, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3345
+  /* "pywrapfst.pyx":3374
  *   """
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<StateIterator at 0x{:x}>".format(id(self))
+ *     return f"<StateIterator at 0x{id(self):x}>"
  * 
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
   __Pyx_AddTraceback("pywrapfst.StateIterator.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -35942,8 +36282,8 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3348
- *     return "<StateIterator at 0x{:x}>".format(id(self))
+/* "pywrapfst.pyx":3377
+ *     return f"<StateIterator at 0x{id(self):x}>"
  * 
  *   def __init__(self, Fst ifst):             # <<<<<<<<<<<<<<
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
@@ -35954,6 +36294,9 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator___repr__(struct __pyx_obj_9
 static int __pyx_pw_9pywrapfst_13StateIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static int __pyx_pw_9pywrapfst_13StateIterator_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
@@ -35976,7 +36319,7 @@ static int __pyx_pw_9pywrapfst_13StateIterator_3__init__(PyObject *__pyx_v_self,
         else goto __pyx_L5_argtuple_error;
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3348, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 3377, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -35987,13 +36330,13 @@ static int __pyx_pw_9pywrapfst_13StateIterator_3__init__(PyObject *__pyx_v_self,
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3348, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3377, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.StateIterator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return -1;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3348, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3377, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_13StateIterator_2__init__(((struct __pyx_obj_9pywrapfst_StateIterator *)__pyx_v_self), __pyx_v_ifst);
 
   /* function exit code */
@@ -36009,9 +36352,12 @@ static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywra
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   std::shared_ptr<fst::script::FstClass>  __pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":3350
+  /* "pywrapfst.pyx":3379
  *   def __init__(self, Fst ifst):
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._fst = ifst._fst             # <<<<<<<<<<<<<<
@@ -36020,16 +36366,16 @@ static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3350, __pyx_L1_error)
+    __PYX_ERR(0, 3379, __pyx_L1_error)
   }
   __pyx_t_1 = __pyx_v_ifst->_fst;
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3350, __pyx_L1_error)
+    __PYX_ERR(0, 3379, __pyx_L1_error)
   }
   __pyx_v_self->_fst = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3351
+  /* "pywrapfst.pyx":3380
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
  *     self._fst = ifst._fst
  *     self._siter.reset(new fst.StateIteratorClass(deref(self._fst)))             # <<<<<<<<<<<<<<
@@ -36038,16 +36384,16 @@ static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 3351, __pyx_L1_error)
+    __PYX_ERR(0, 3380, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3351, __pyx_L1_error)
+    __PYX_ERR(0, 3380, __pyx_L1_error)
   }
   __pyx_v_self->_siter.reset(new fst::script::StateIteratorClass((*__pyx_v_self->_fst)));
 
-  /* "pywrapfst.pyx":3348
- *     return "<StateIterator at 0x{:x}>".format(id(self))
+  /* "pywrapfst.pyx":3377
+ *     return f"<StateIterator at 0x{id(self):x}>"
  * 
  *   def __init__(self, Fst ifst):             # <<<<<<<<<<<<<<
  *     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
@@ -36065,7 +36411,7 @@ static int __pyx_pf_9pywrapfst_13StateIterator_2__init__(struct __pyx_obj_9pywra
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3354
+/* "pywrapfst.pyx":3383
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -36091,7 +36437,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__iter__", 0);
 
-  /* "pywrapfst.pyx":3355
+  /* "pywrapfst.pyx":3384
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):
  *     return self             # <<<<<<<<<<<<<<
@@ -36103,7 +36449,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3354
+  /* "pywrapfst.pyx":3383
  * 
  *   # This just registers this class as a possible iterator.
  *   def __iter__(self):             # <<<<<<<<<<<<<<
@@ -36118,7 +36464,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_4__iter__(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3358
+/* "pywrapfst.pyx":3387
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -36145,9 +36491,12 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
   __Pyx_RefNannyDeclarations
   int __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__next__", 0);
 
-  /* "pywrapfst.pyx":3359
+  /* "pywrapfst.pyx":3388
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -36156,12 +36505,12 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "done");
-    __PYX_ERR(0, 3359, __pyx_L1_error)
+    __PYX_ERR(0, 3388, __pyx_L1_error)
   }
   __pyx_t_1 = (((struct __pyx_vtabstruct_9pywrapfst_StateIterator *)__pyx_v_self->__pyx_vtab)->done(__pyx_v_self, 0) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "pywrapfst.pyx":3360
+    /* "pywrapfst.pyx":3389
  *   def __next__(self):
  *     if self.done():
  *       raise StopIteration             # <<<<<<<<<<<<<<
@@ -36169,9 +36518,9 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
  *     self.next()
  */
     __Pyx_Raise(__pyx_builtin_StopIteration, 0, 0, 0);
-    __PYX_ERR(0, 3360, __pyx_L1_error)
+    __PYX_ERR(0, 3389, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3359
+    /* "pywrapfst.pyx":3388
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):
  *     if self.done():             # <<<<<<<<<<<<<<
@@ -36180,7 +36529,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
  */
   }
 
-  /* "pywrapfst.pyx":3361
+  /* "pywrapfst.pyx":3390
  *     if self.done():
  *       raise StopIteration
  *     cdef int64 result = self.value()             # <<<<<<<<<<<<<<
@@ -36189,11 +36538,11 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "value");
-    __PYX_ERR(0, 3361, __pyx_L1_error)
+    __PYX_ERR(0, 3390, __pyx_L1_error)
   }
   __pyx_v_result = ((struct __pyx_vtabstruct_9pywrapfst_StateIterator *)__pyx_v_self->__pyx_vtab)->value(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":3362
+  /* "pywrapfst.pyx":3391
  *       raise StopIteration
  *     cdef int64 result = self.value()
  *     self.next()             # <<<<<<<<<<<<<<
@@ -36202,11 +36551,11 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "next");
-    __PYX_ERR(0, 3362, __pyx_L1_error)
+    __PYX_ERR(0, 3391, __pyx_L1_error)
   }
   ((struct __pyx_vtabstruct_9pywrapfst_StateIterator *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
 
-  /* "pywrapfst.pyx":3363
+  /* "pywrapfst.pyx":3392
  *     cdef int64 result = self.value()
  *     self.next()
  *     return result             # <<<<<<<<<<<<<<
@@ -36214,13 +36563,13 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
  *   cpdef bool done(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_result); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3363, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_result); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3392, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3358
+  /* "pywrapfst.pyx":3387
  * 
  *   # Magic method used to get a Pythonic API out of the C++ API.
  *   def __next__(self):             # <<<<<<<<<<<<<<
@@ -36239,7 +36588,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_6__next__(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3365
+/* "pywrapfst.pyx":3394
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -36256,6 +36605,9 @@ static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   bool __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("done", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -36266,7 +36618,7 @@ static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3365, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3394, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_13StateIterator_9done)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -36282,10 +36634,10 @@ static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3365, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3394, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3365, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3394, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -36304,7 +36656,7 @@ static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":3374
+  /* "pywrapfst.pyx":3403
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._siter.get().Done()             # <<<<<<<<<<<<<<
@@ -36313,12 +36665,12 @@ static bool __pyx_f_9pywrapfst_13StateIterator_done(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 3374, __pyx_L1_error)
+    __PYX_ERR(0, 3403, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_siter.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3365
+  /* "pywrapfst.pyx":3394
  *     return result
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -36357,9 +36709,12 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_8done(struct __pyx_obj_9pyw
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("done", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_13StateIterator_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3365, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_13StateIterator_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3394, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -36376,7 +36731,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_8done(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3376
+/* "pywrapfst.pyx":3405
  *     return self._siter.get().Done()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -36391,6 +36746,9 @@ static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("next", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -36401,7 +36759,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3376, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3405, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_13StateIterator_11next)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -36417,7 +36775,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3376, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3405, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -36437,7 +36795,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_
     #endif
   }
 
-  /* "pywrapfst.pyx":3382
+  /* "pywrapfst.pyx":3411
  *     Advances the iterator.
  *     """
  *     self._siter.get().Next()             # <<<<<<<<<<<<<<
@@ -36446,11 +36804,11 @@ static void __pyx_f_9pywrapfst_13StateIterator_next(struct __pyx_obj_9pywrapfst_
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 3382, __pyx_L1_error)
+    __PYX_ERR(0, 3411, __pyx_L1_error)
   }
   __pyx_v_self->_siter.get()->Next();
 
-  /* "pywrapfst.pyx":3376
+  /* "pywrapfst.pyx":3405
  *     return self._siter.get().Done()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -36488,9 +36846,12 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_10next(struct __pyx_obj_9py
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("next", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_13StateIterator_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3376, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_13StateIterator_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3405, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -36507,7 +36868,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_10next(struct __pyx_obj_9py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3384
+/* "pywrapfst.pyx":3413
  *     self._siter.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -36522,6 +36883,9 @@ static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reset", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -36532,7 +36896,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3384, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3413, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_13StateIterator_13reset)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -36548,7 +36912,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3384, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3413, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -36568,7 +36932,7 @@ static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst
     #endif
   }
 
-  /* "pywrapfst.pyx":3390
+  /* "pywrapfst.pyx":3419
  *     Resets the iterator to the initial position.
  *     """
  *     self._siter.get().Reset()             # <<<<<<<<<<<<<<
@@ -36577,11 +36941,11 @@ static void __pyx_f_9pywrapfst_13StateIterator_reset(struct __pyx_obj_9pywrapfst
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 3390, __pyx_L1_error)
+    __PYX_ERR(0, 3419, __pyx_L1_error)
   }
   __pyx_v_self->_siter.get()->Reset();
 
-  /* "pywrapfst.pyx":3384
+  /* "pywrapfst.pyx":3413
  *     self._siter.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -36619,9 +36983,12 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_12reset(struct __pyx_obj_9p
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reset", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_13StateIterator_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3384, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_13StateIterator_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3413, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -36638,7 +37005,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_12reset(struct __pyx_obj_9p
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3392
+/* "pywrapfst.pyx":3421
  *     self._siter.get().Reset()
  * 
  *   cpdef int64 value(self):             # <<<<<<<<<<<<<<
@@ -36655,6 +37022,9 @@ static int64 __pyx_f_9pywrapfst_13StateIterator_value(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   int64 __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("value", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -36665,7 +37035,7 @@ static int64 __pyx_f_9pywrapfst_13StateIterator_value(struct __pyx_obj_9pywrapfs
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3392, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3421, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_13StateIterator_15value)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -36681,10 +37051,10 @@ static int64 __pyx_f_9pywrapfst_13StateIterator_value(struct __pyx_obj_9pywrapfs
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3392, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3421, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3392, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3421, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -36703,7 +37073,7 @@ static int64 __pyx_f_9pywrapfst_13StateIterator_value(struct __pyx_obj_9pywrapfs
     #endif
   }
 
-  /* "pywrapfst.pyx":3398
+  /* "pywrapfst.pyx":3427
  *     Returns the current state index.
  *     """
  *     return self._siter.get().Value()             # <<<<<<<<<<<<<<
@@ -36712,12 +37082,12 @@ static int64 __pyx_f_9pywrapfst_13StateIterator_value(struct __pyx_obj_9pywrapfs
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_siter");
-    __PYX_ERR(0, 3398, __pyx_L1_error)
+    __PYX_ERR(0, 3427, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_siter.get()->Value();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3392
+  /* "pywrapfst.pyx":3421
  *     self._siter.get().Reset()
  * 
  *   cpdef int64 value(self):             # <<<<<<<<<<<<<<
@@ -36756,9 +37126,12 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_14value(struct __pyx_obj_9p
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("value", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_13StateIterator_value(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3392, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_f_9pywrapfst_13StateIterator_value(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3421, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -36798,6 +37171,9 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_16__reduce_cython__(CYTHON_
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__reduce_cython__", 0);
 
   /* "(tree fragment)":2
@@ -36806,7 +37182,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_16__reduce_cython__(CYTHON_
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._fst,self._siter cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__28, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__30, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -36852,6 +37228,9 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_18__setstate_cython__(CYTHO
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__setstate_cython__", 0);
 
   /* "(tree fragment)":4
@@ -36859,7 +37238,7 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_18__setstate_cython__(CYTHO
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._fst,self._siter cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__29, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__31, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -36882,29 +37261,29 @@ static PyObject *__pyx_pf_9pywrapfst_13StateIterator_18__setstate_cython__(CYTHO
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3404
+/* "pywrapfst.pyx":3433
  * 
  * 
  * cdef Fst _map(Fst ifst,             # <<<<<<<<<<<<<<
  *                float delta=fst.kDelta,
- *                map_type=b"identity",
+ *                map_type="identity",
  */
 
 static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__map(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, struct __pyx_opt_args_9pywrapfst__map *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__30;
-  PyObject *__pyx_v_map_type = ((PyObject *)__pyx_n_b_identity);
+  float __pyx_v_delta = __pyx_k__32;
+  PyObject *__pyx_v_map_type = ((PyObject *)__pyx_n_u_identity);
   double __pyx_v_power = ((double)1.);
 
-  /* "pywrapfst.pyx":3408
- *                map_type=b"identity",
+  /* "pywrapfst.pyx":3437
+ *                map_type="identity",
  *                double power=1.,
  *                weight=None):             # <<<<<<<<<<<<<<
- *   cdef fst.MapType map_type_enum
- *   if not fst.GetMapType(tostring(map_type), addr(map_type_enum)):
+ *   cdef fst.MapType _map_type
+ *   if not fst.GetMapType(tostring(map_type), addr(_map_type)):
  */
   PyObject *__pyx_v_weight = ((PyObject *)Py_None);
-  enum fst::script::MapType __pyx_v_map_type_enum;
-  fst::script::WeightClass __pyx_v_wc;
+  enum fst::script::MapType __pyx_v__map_type;
+  fst::script::WeightClass __pyx_v__weight;
   struct __pyx_obj_9pywrapfst_Fst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
@@ -36913,8 +37292,10 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__map(struct __pyx_obj
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
-  fst::script::WeightClass __pyx_t_8;
+  fst::script::WeightClass __pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_map", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -36931,147 +37312,135 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__map(struct __pyx_obj
     }
   }
 
-  /* "pywrapfst.pyx":3410
+  /* "pywrapfst.pyx":3439
  *                weight=None):
- *   cdef fst.MapType map_type_enum
- *   if not fst.GetMapType(tostring(map_type), addr(map_type_enum)):             # <<<<<<<<<<<<<<
- *     raise FstArgError("Unknown map type: {!r}".format(map_type))
- *   cdef fst.WeightClass wc
+ *   cdef fst.MapType _map_type
+ *   if not fst.GetMapType(tostring(map_type), addr(_map_type)):             # <<<<<<<<<<<<<<
+ *     raise FstArgError(f"Unknown map type: {map_type!r}")
+ *   cdef fst.WeightClass _weight
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_map_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3410, __pyx_L1_error)
-  __pyx_t_2 = ((!(fst::script::GetMapType(__pyx_t_1, (&__pyx_v_map_type_enum)) != 0)) != 0);
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_map_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3439, __pyx_L1_error)
+  __pyx_t_2 = ((!(fst::script::GetMapType(__pyx_t_1, (&__pyx_v__map_type)) != 0)) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":3411
- *   cdef fst.MapType map_type_enum
- *   if not fst.GetMapType(tostring(map_type), addr(map_type_enum)):
- *     raise FstArgError("Unknown map type: {!r}".format(map_type))             # <<<<<<<<<<<<<<
- *   cdef fst.WeightClass wc
- *   if map_type_enum == fst.TIMES_MAPPER:
+    /* "pywrapfst.pyx":3440
+ *   cdef fst.MapType _map_type
+ *   if not fst.GetMapType(tostring(map_type), addr(_map_type)):
+ *     raise FstArgError(f"Unknown map type: {map_type!r}")             # <<<<<<<<<<<<<<
+ *   cdef fst.WeightClass _weight
+ *   if _map_type == fst.TIMES_MAPPER:
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3411, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3440, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_map_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3411, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
-        __Pyx_INCREF(__pyx_t_7);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_6, function);
-      }
-    }
-    __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_map_type) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_map_type);
-    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3411, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_map_type), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3440, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = NULL;
+    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_map_type, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3440, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
-      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
-      if (likely(__pyx_t_6)) {
+      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+      if (likely(__pyx_t_5)) {
         PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-        __Pyx_INCREF(__pyx_t_6);
+        __Pyx_INCREF(__pyx_t_5);
         __Pyx_INCREF(function);
         __Pyx_DECREF_SET(__pyx_t_4, function);
       }
     }
-    __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3411, __pyx_L1_error)
+    __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
+    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3440, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 3411, __pyx_L1_error)
+    __PYX_ERR(0, 3440, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3410
+    /* "pywrapfst.pyx":3439
  *                weight=None):
- *   cdef fst.MapType map_type_enum
- *   if not fst.GetMapType(tostring(map_type), addr(map_type_enum)):             # <<<<<<<<<<<<<<
- *     raise FstArgError("Unknown map type: {!r}".format(map_type))
- *   cdef fst.WeightClass wc
+ *   cdef fst.MapType _map_type
+ *   if not fst.GetMapType(tostring(map_type), addr(_map_type)):             # <<<<<<<<<<<<<<
+ *     raise FstArgError(f"Unknown map type: {map_type!r}")
+ *   cdef fst.WeightClass _weight
  */
   }
 
-  /* "pywrapfst.pyx":3413
- *     raise FstArgError("Unknown map type: {!r}".format(map_type))
- *   cdef fst.WeightClass wc
- *   if map_type_enum == fst.TIMES_MAPPER:             # <<<<<<<<<<<<<<
- *       wc = _get_WeightClass_or_One(ifst.weight_type(), weight)
+  /* "pywrapfst.pyx":3442
+ *     raise FstArgError(f"Unknown map type: {map_type!r}")
+ *   cdef fst.WeightClass _weight
+ *   if _map_type == fst.TIMES_MAPPER:             # <<<<<<<<<<<<<<
+ *       _weight = _get_WeightClass_or_One(ifst.weight_type(), weight)
  *   else:
  */
-  __pyx_t_2 = ((__pyx_v_map_type_enum == fst::script::TIMES_MAPPER) != 0);
+  __pyx_t_2 = ((__pyx_v__map_type == fst::script::TIMES_MAPPER) != 0);
   if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":3414
- *   cdef fst.WeightClass wc
- *   if map_type_enum == fst.TIMES_MAPPER:
- *       wc = _get_WeightClass_or_One(ifst.weight_type(), weight)             # <<<<<<<<<<<<<<
+    /* "pywrapfst.pyx":3443
+ *   cdef fst.WeightClass _weight
+ *   if _map_type == fst.TIMES_MAPPER:
+ *       _weight = _get_WeightClass_or_One(ifst.weight_type(), weight)             # <<<<<<<<<<<<<<
  *   else:
- *       wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
+ *       _weight = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
  */
     if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-      __PYX_ERR(0, 3414, __pyx_L1_error)
+      __PYX_ERR(0, 3443, __pyx_L1_error)
     }
-    __pyx_t_8 = __pyx_f_9pywrapfst__get_WeightClass_or_One(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3414, __pyx_L1_error)
-    __pyx_v_wc = __pyx_t_8;
+    __pyx_t_7 = __pyx_f_9pywrapfst__get_WeightClass_or_One(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3443, __pyx_L1_error)
+    __pyx_v__weight = __pyx_t_7;
 
-    /* "pywrapfst.pyx":3413
- *     raise FstArgError("Unknown map type: {!r}".format(map_type))
- *   cdef fst.WeightClass wc
- *   if map_type_enum == fst.TIMES_MAPPER:             # <<<<<<<<<<<<<<
- *       wc = _get_WeightClass_or_One(ifst.weight_type(), weight)
+    /* "pywrapfst.pyx":3442
+ *     raise FstArgError(f"Unknown map type: {map_type!r}")
+ *   cdef fst.WeightClass _weight
+ *   if _map_type == fst.TIMES_MAPPER:             # <<<<<<<<<<<<<<
+ *       _weight = _get_WeightClass_or_One(ifst.weight_type(), weight)
  *   else:
  */
     goto __pyx_L4;
   }
 
-  /* "pywrapfst.pyx":3416
- *       wc = _get_WeightClass_or_One(ifst.weight_type(), weight)
+  /* "pywrapfst.pyx":3445
+ *       _weight = _get_WeightClass_or_One(ifst.weight_type(), weight)
  *   else:
- *       wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)             # <<<<<<<<<<<<<<
- *   return _init_XFst(fst.Map(deref(ifst._fst), map_type_enum, delta, power, wc))
+ *       _weight = _get_WeightClass_or_Zero(ifst.weight_type(), weight)             # <<<<<<<<<<<<<<
+ *   return _init_XFst(fst.Map(deref(ifst._fst), _map_type, delta, power, _weight))
  * 
  */
   /*else*/ {
     if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-      __PYX_ERR(0, 3416, __pyx_L1_error)
+      __PYX_ERR(0, 3445, __pyx_L1_error)
     }
-    __pyx_t_8 = __pyx_f_9pywrapfst__get_WeightClass_or_Zero(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3416, __pyx_L1_error)
-    __pyx_v_wc = __pyx_t_8;
+    __pyx_t_7 = __pyx_f_9pywrapfst__get_WeightClass_or_Zero(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3445, __pyx_L1_error)
+    __pyx_v__weight = __pyx_t_7;
   }
   __pyx_L4:;
 
-  /* "pywrapfst.pyx":3417
+  /* "pywrapfst.pyx":3446
  *   else:
- *       wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
- *   return _init_XFst(fst.Map(deref(ifst._fst), map_type_enum, delta, power, wc))             # <<<<<<<<<<<<<<
+ *       _weight = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
+ *   return _init_XFst(fst.Map(deref(ifst._fst), _map_type, delta, power, _weight))             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3417, __pyx_L1_error)
+    __PYX_ERR(0, 3446, __pyx_L1_error)
   }
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(fst::script::Map((*__pyx_v_ifst->_fst), __pyx_v_map_type_enum, __pyx_v_delta, __pyx_v_power, __pyx_v_wc))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3417, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(fst::script::Map((*__pyx_v_ifst->_fst), __pyx_v__map_type, __pyx_v_delta, __pyx_v_power, __pyx_v__weight))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3446, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3404
+  /* "pywrapfst.pyx":3433
  * 
  * 
  * cdef Fst _map(Fst ifst,             # <<<<<<<<<<<<<<
  *                float delta=fst.kDelta,
- *                map_type=b"identity",
+ *                map_type="identity",
  */
 
   /* function exit code */
@@ -37080,7 +37449,6 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__map(struct __pyx_obj
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_AddTraceback("pywrapfst._map", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
@@ -37089,22 +37457,22 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst__map(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3420
+/* "pywrapfst.pyx":3449
  * 
  * 
  * cpdef Fst arcmap(Fst ifst,             # <<<<<<<<<<<<<<
  *                  float delta=fst.kDelta,
- *                  map_type=b"identity",
+ *                  map_type="identity",
  */
 
 static PyObject *__pyx_pw_9pywrapfst_21arcmap(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_arcmap(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_arcmap *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__31;
-  PyObject *__pyx_v_map_type = ((PyObject *)__pyx_n_b_identity);
+  float __pyx_v_delta = __pyx_k__33;
+  PyObject *__pyx_v_map_type = ((PyObject *)__pyx_n_u_identity);
   double __pyx_v_power = ((double)1.);
 
-  /* "pywrapfst.pyx":3424
- *                  map_type=b"identity",
+  /* "pywrapfst.pyx":3453
+ *                  map_type="identity",
  *                  double power=1.,
  *                  weight=None):             # <<<<<<<<<<<<<<
  *   """
@@ -37115,6 +37483,9 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_arcmap(struct __pyx_o
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   struct __pyx_opt_args_9pywrapfst__map __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("arcmap", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -37131,7 +37502,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_arcmap(struct __pyx_o
     }
   }
 
-  /* "pywrapfst.pyx":3465
+  /* "pywrapfst.pyx":3493
  *     FstArgError: Unknown map type.
  *   """
  *   return _map(ifst, delta, map_type, power, weight)             # <<<<<<<<<<<<<<
@@ -37144,18 +37515,18 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_arcmap(struct __pyx_o
   __pyx_t_2.map_type = __pyx_v_map_type;
   __pyx_t_2.power = __pyx_v_power;
   __pyx_t_2.weight = __pyx_v_weight;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__map(__pyx_v_ifst, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3465, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__map(__pyx_v_ifst, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3493, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3420
+  /* "pywrapfst.pyx":3449
  * 
  * 
  * cpdef Fst arcmap(Fst ifst,             # <<<<<<<<<<<<<<
  *                  float delta=fst.kDelta,
- *                  map_type=b"identity",
+ *                  map_type="identity",
  */
 
   /* function exit code */
@@ -37171,23 +37542,26 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_arcmap(struct __pyx_o
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_21arcmap(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_20arcmap[] = "\n  arcmap(ifst, delta=0.0009765625, map_type=\"identity\", power=1., weight=None)\n\n  Constructively applies a transform to all arcs and final states.\n\n  This operation transforms each arc and final state in the input FST using\n  one of the following:\n\n    * identity: maps to self.\n    * input_epsilon: replaces all input labels with epsilon.\n    * invert: reciprocates all non-Zero weights.\n    * float_power: raises all weights to a floating-point power.\n    * output_epsilon: replaces all output labels with epsilon.\n    * quantize: quantizes weights.\n    * plus: adds a constant to all weights.\n    * power: raises all weights to an integral power.\n    * rmweight: replaces all non-Zero weights with 1.\n    * superfinal: redirects final states to a new superfinal state.\n    * times: right-multiplies a constant by all weights.\n    * to_log: converts weights to the log semiring.\n    * to_log64: converts weights to the log64 semiring.\n    * to_standard: converts weights to the tropical (\"standard\") semiring.\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta (ignored unless `map_type` is\n        `quantize`).\n    map_type: A string matching a known mapping operation (see above).\n    power: A positive scalar or integer power; ignored unless `map_type` is\n        `float_power` or `power` (in which case it defaults to 1).\n    weight: A Weight or weight string passed to the arc-mapper; ignored unless\n        `map_type` is `plus` (in which case it defaults to semiring Zero) or\n        `times` (in which case it defaults to semiring One).\n\n  Returns:\n    An FST with arcs and final states remapped.\n\n  Raises:\n    FstArgError: Unknown map type.\n  ";
+static char __pyx_doc_9pywrapfst_20arcmap[] = "\n  arcmap(ifst, delta=0.0009765625, map_type=\"identity\", power=1., weight=None)\n\n  Constructively applies a transform to all arcs and final states.\n\n  This operation transforms each arc and final state in the input FST using\n  one of the following:\n\n    * identity: maps to self.\n    * input_epsilon: replaces all input labels with epsilon.\n    * invert: reciprocates all non-Zero weights.\n    * output_epsilon: replaces all output labels with epsilon.\n    * quantize: quantizes weights.\n    * plus: adds a constant to all weights.\n    * power: raises all weights to a power.\n    * rmweight: replaces all non-Zero weights with 1.\n    * superfinal: redirects final states to a new superfinal state.\n    * times: right-multiplies a constant by all weights.\n    * to_log: converts weights to the log semiring.\n    * to_log64: converts weights to the log64 semiring.\n    * to_std: converts weights to the tropical semiring.\n\n  Args:\n    ifst: The input FST.\n    delta: Comparison/quantization delta (ignored unless `map_type` is\n        `quantize`).\n    map_type: A string matching a known mapping operation (see above).\n    power: A positive scalar or integer power; ignored unless `map_type` is\n        `power` (in which case it defaults to 1).\n    weight: A Weight or weight string passed to the arc-mapper; ignored unless\n        `map_type` is `plus` (in which case it defaults to semiring Zero) or\n        `times` (in which case it defaults to semiring One).\n\n  Returns:\n    An FST with arcs and final states remapped.\n\n  Raises:\n    FstArgError: Unknown map type.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_21arcmap(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   float __pyx_v_delta;
   PyObject *__pyx_v_map_type = 0;
   double __pyx_v_power;
   PyObject *__pyx_v_weight = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("arcmap (wrapper)", 0);
   {
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ifst,&__pyx_n_s_delta,&__pyx_n_s_map_type,&__pyx_n_s_power,&__pyx_n_s_weight,0};
     PyObject* values[5] = {0,0,0,0,0};
-    values[2] = ((PyObject *)__pyx_n_b_identity);
+    values[2] = ((PyObject *)__pyx_n_u_identity);
 
-    /* "pywrapfst.pyx":3424
- *                  map_type=b"identity",
+    /* "pywrapfst.pyx":3453
+ *                  map_type="identity",
  *                  double power=1.,
  *                  weight=None):             # <<<<<<<<<<<<<<
  *   """
@@ -37242,7 +37616,7 @@ static PyObject *__pyx_pw_9pywrapfst_21arcmap(PyObject *__pyx_self, PyObject *__
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "arcmap") < 0)) __PYX_ERR(0, 3420, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "arcmap") < 0)) __PYX_ERR(0, 3449, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37261,13 +37635,13 @@ static PyObject *__pyx_pw_9pywrapfst_21arcmap(PyObject *__pyx_self, PyObject *__
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3421, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3450, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__31;
+      __pyx_v_delta = __pyx_k__33;
     }
     __pyx_v_map_type = values[2];
     if (values[3]) {
-      __pyx_v_power = __pyx_PyFloat_AsDouble(values[3]); if (unlikely((__pyx_v_power == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 3423, __pyx_L3_error)
+      __pyx_v_power = __pyx_PyFloat_AsDouble(values[3]); if (unlikely((__pyx_v_power == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 3452, __pyx_L3_error)
     } else {
       __pyx_v_power = ((double)1.);
     }
@@ -37275,21 +37649,21 @@ static PyObject *__pyx_pw_9pywrapfst_21arcmap(PyObject *__pyx_self, PyObject *__
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("arcmap", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3420, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("arcmap", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3449, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.arcmap", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3420, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3449, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_20arcmap(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_map_type, __pyx_v_power, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":3420
+  /* "pywrapfst.pyx":3449
  * 
  * 
  * cpdef Fst arcmap(Fst ifst,             # <<<<<<<<<<<<<<
  *                  float delta=fst.kDelta,
- *                  map_type=b"identity",
+ *                  map_type="identity",
  */
 
   /* function exit code */
@@ -37306,6 +37680,9 @@ static PyObject *__pyx_pf_9pywrapfst_20arcmap(CYTHON_UNUSED PyObject *__pyx_self
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   struct __pyx_opt_args_9pywrapfst_arcmap __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("arcmap", 0);
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 4;
@@ -37313,7 +37690,7 @@ static PyObject *__pyx_pf_9pywrapfst_20arcmap(CYTHON_UNUSED PyObject *__pyx_self
   __pyx_t_2.map_type = __pyx_v_map_type;
   __pyx_t_2.power = __pyx_v_power;
   __pyx_t_2.weight = __pyx_v_weight;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_arcmap(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3420, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_arcmap(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3449, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37330,33 +37707,36 @@ static PyObject *__pyx_pf_9pywrapfst_20arcmap(CYTHON_UNUSED PyObject *__pyx_self
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3468
+/* "pywrapfst.pyx":3496
  * 
  * 
  * cpdef MutableFst compose(Fst ifst1,             # <<<<<<<<<<<<<<
  *                          Fst ifst2,
- *                          compose_filter=b"auto",
+ *                          compose_filter="auto",
  */
 
 static PyObject *__pyx_pw_9pywrapfst_23compose(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_compose(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_compose *__pyx_optional_args) {
-  PyObject *__pyx_v_compose_filter = ((PyObject *)__pyx_n_b_auto);
+  PyObject *__pyx_v_compose_filter = ((PyObject *)__pyx_n_u_auto);
 
-  /* "pywrapfst.pyx":3471
+  /* "pywrapfst.pyx":3499
  *                          Fst ifst2,
- *                          compose_filter=b"auto",
+ *                          compose_filter="auto",
  *                          bool connect=True):             # <<<<<<<<<<<<<<
  *   """
  *   compose(ifst1, ifst2, compose_filter="auto", connect=True)
  */
   bool __pyx_v_connect = ((bool)1);
-  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v_tfst;
-  std::unique_ptr<fst::ComposeOptions>  __pyx_v_opts;
+  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v__tfst;
+  std::unique_ptr<fst::ComposeOptions>  __pyx_v__opts;
   struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
   enum fst::ComposeFilter __pyx_t_2;
   PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("compose", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -37367,75 +37747,75 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_compose(struct
     }
   }
 
-  /* "pywrapfst.pyx":3495
+  /* "pywrapfst.pyx":3523
  *   """
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))             # <<<<<<<<<<<<<<
- *   cdef unique_ptr[fst.ComposeOptions] opts
- *   opts.reset(new fst.ComposeOptions(
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))             # <<<<<<<<<<<<<<
+ *   cdef unique_ptr[fst.ComposeOptions] _opts
+ *   _opts.reset(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3495, __pyx_L1_error)
+    __PYX_ERR(0, 3523, __pyx_L1_error)
   }
-  __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst1->__pyx_vtab)->arc_type(__pyx_v_ifst1, 0)));
+  __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst1->__pyx_vtab)->arc_type(__pyx_v_ifst1, 0)));
 
-  /* "pywrapfst.pyx":3499
- *   opts.reset(new fst.ComposeOptions(
- *       connect,
- *       _get_compose_filter(tostring(compose_filter))))             # <<<<<<<<<<<<<<
- *   fst.Compose(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
- *   return _init_MutableFst(tfst.release())
+  /* "pywrapfst.pyx":3527
+ *   _opts.reset(
+ *       new fst.ComposeOptions(connect,
+ *                              _get_compose_filter(tostring(compose_filter))))             # <<<<<<<<<<<<<<
+ *   fst.Compose(deref(ifst1._fst), deref(ifst2._fst), _tfst.get(), deref(_opts))
+ *   return _init_MutableFst(_tfst.release())
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3499, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3499, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3527, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3527, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3497
- *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
- *   cdef unique_ptr[fst.ComposeOptions] opts
- *   opts.reset(new fst.ComposeOptions(             # <<<<<<<<<<<<<<
- *       connect,
- *       _get_compose_filter(tostring(compose_filter))))
+  /* "pywrapfst.pyx":3525
+ *   _tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
+ *   cdef unique_ptr[fst.ComposeOptions] _opts
+ *   _opts.reset(             # <<<<<<<<<<<<<<
+ *       new fst.ComposeOptions(connect,
+ *                              _get_compose_filter(tostring(compose_filter))))
  */
-  __pyx_v_opts.reset(new fst::ComposeOptions(__pyx_v_connect, __pyx_t_2));
+  __pyx_v__opts.reset(new fst::ComposeOptions(__pyx_v_connect, __pyx_t_2));
 
-  /* "pywrapfst.pyx":3500
- *       connect,
- *       _get_compose_filter(tostring(compose_filter))))
- *   fst.Compose(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
- *   return _init_MutableFst(tfst.release())
+  /* "pywrapfst.pyx":3528
+ *       new fst.ComposeOptions(connect,
+ *                              _get_compose_filter(tostring(compose_filter))))
+ *   fst.Compose(deref(ifst1._fst), deref(ifst2._fst), _tfst.get(), deref(_opts))             # <<<<<<<<<<<<<<
+ *   return _init_MutableFst(_tfst.release())
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3500, __pyx_L1_error)
+    __PYX_ERR(0, 3528, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3500, __pyx_L1_error)
+    __PYX_ERR(0, 3528, __pyx_L1_error)
   }
-  fst::script::Compose((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
+  fst::script::Compose((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v__tfst.get(), (*__pyx_v__opts));
 
-  /* "pywrapfst.pyx":3501
- *       _get_compose_filter(tostring(compose_filter))))
- *   fst.Compose(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
- *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3529
+ *                              _get_compose_filter(tostring(compose_filter))))
+ *   fst.Compose(deref(ifst1._fst), deref(ifst2._fst), _tfst.get(), deref(_opts))
+ *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3501, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3529, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3468
+  /* "pywrapfst.pyx":3496
  * 
  * 
  * cpdef MutableFst compose(Fst ifst1,             # <<<<<<<<<<<<<<
  *                          Fst ifst2,
- *                          compose_filter=b"auto",
+ *                          compose_filter="auto",
  */
 
   /* function exit code */
@@ -37457,13 +37837,16 @@ static PyObject *__pyx_pw_9pywrapfst_23compose(PyObject *__pyx_self, PyObject *_
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2 = 0;
   PyObject *__pyx_v_compose_filter = 0;
   bool __pyx_v_connect;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("compose (wrapper)", 0);
   {
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ifst1,&__pyx_n_s_ifst2,&__pyx_n_s_compose_filter,&__pyx_n_s_connect,0};
     PyObject* values[4] = {0,0,0,0};
-    values[2] = ((PyObject *)__pyx_n_b_auto);
+    values[2] = ((PyObject *)__pyx_n_u_auto);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -37488,7 +37871,7 @@ static PyObject *__pyx_pw_9pywrapfst_23compose(PyObject *__pyx_self, PyObject *_
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("compose", 0, 2, 4, 1); __PYX_ERR(0, 3468, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("compose", 0, 2, 4, 1); __PYX_ERR(0, 3496, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -37504,7 +37887,7 @@ static PyObject *__pyx_pw_9pywrapfst_23compose(PyObject *__pyx_self, PyObject *_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "compose") < 0)) __PYX_ERR(0, 3468, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "compose") < 0)) __PYX_ERR(0, 3496, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37522,12 +37905,12 @@ static PyObject *__pyx_pw_9pywrapfst_23compose(PyObject *__pyx_self, PyObject *_
     __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst_Fst *)values[1]);
     __pyx_v_compose_filter = values[2];
     if (values[3]) {
-      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3471, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3499, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3471
+      /* "pywrapfst.pyx":3499
  *                          Fst ifst2,
- *                          compose_filter=b"auto",
+ *                          compose_filter="auto",
  *                          bool connect=True):             # <<<<<<<<<<<<<<
  *   """
  *   compose(ifst1, ifst2, compose_filter="auto", connect=True)
@@ -37537,22 +37920,22 @@ static PyObject *__pyx_pw_9pywrapfst_23compose(PyObject *__pyx_self, PyObject *_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("compose", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3468, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("compose", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3496, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.compose", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3468, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3469, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3496, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3497, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_22compose(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_compose_filter, __pyx_v_connect);
 
-  /* "pywrapfst.pyx":3468
+  /* "pywrapfst.pyx":3496
  * 
  * 
  * cpdef MutableFst compose(Fst ifst1,             # <<<<<<<<<<<<<<
  *                          Fst ifst2,
- *                          compose_filter=b"auto",
+ *                          compose_filter="auto",
  */
 
   /* function exit code */
@@ -37569,12 +37952,15 @@ static PyObject *__pyx_pf_9pywrapfst_22compose(CYTHON_UNUSED PyObject *__pyx_sel
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   struct __pyx_opt_args_9pywrapfst_compose __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("compose", 0);
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 2;
   __pyx_t_2.compose_filter = __pyx_v_compose_filter;
   __pyx_t_2.connect = __pyx_v_connect;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_compose(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3468, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_compose(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3496, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37591,19 +37977,19 @@ static PyObject *__pyx_pf_9pywrapfst_22compose(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3504
+/* "pywrapfst.pyx":3532
  * 
  * 
- * cpdef Fst convert(Fst ifst, fst_type=b""):             # <<<<<<<<<<<<<<
+ * cpdef Fst convert(Fst ifst, fst_type=""):             # <<<<<<<<<<<<<<
  *   """
  *   convert(ifst, fst_type="")
  */
 
 static PyObject *__pyx_pw_9pywrapfst_25convert(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_convert(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_convert *__pyx_optional_args) {
-  PyObject *__pyx_v_fst_type = ((PyObject *)__pyx_kp_b__8);
-  std::string __pyx_v_fst_type_string;
-  std::unique_ptr<fst::script::FstClass>  __pyx_v_tfst;
+  PyObject *__pyx_v_fst_type = ((PyObject *)__pyx_kp_u__11);
+  std::string __pyx_v__fst_type;
+  std::unique_ptr<fst::script::FstClass>  __pyx_v__tfst;
   struct __pyx_obj_9pywrapfst_Fst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
@@ -37611,8 +37997,12 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_convert(struct __pyx_
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
+  Py_ssize_t __pyx_t_6;
+  Py_UCS4 __pyx_t_7;
+  PyObject *__pyx_t_8 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("convert", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -37620,112 +38010,117 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_convert(struct __pyx_
     }
   }
 
-  /* "pywrapfst.pyx":3521
+  /* "pywrapfst.pyx":3549
  *     FstOpError: Conversion failed.
  *   """
- *   cdef string fst_type_string = tostring(fst_type)             # <<<<<<<<<<<<<<
- *   cdef unique_ptr[fst.FstClass] tfst
- *   tfst.reset(fst.Convert(deref(ifst._fst), fst_type_string))
+ *   cdef string _fst_type = tostring(fst_type)             # <<<<<<<<<<<<<<
+ *   cdef unique_ptr[fst.FstClass] _tfst
+ *   _tfst.reset(fst.Convert(deref(ifst._fst), _fst_type))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_fst_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3521, __pyx_L1_error)
-  __pyx_v_fst_type_string = __pyx_t_1;
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_fst_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3549, __pyx_L1_error)
+  __pyx_v__fst_type = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3523
- *   cdef string fst_type_string = tostring(fst_type)
- *   cdef unique_ptr[fst.FstClass] tfst
- *   tfst.reset(fst.Convert(deref(ifst._fst), fst_type_string))             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3551
+ *   cdef string _fst_type = tostring(fst_type)
+ *   cdef unique_ptr[fst.FstClass] _tfst
+ *   _tfst.reset(fst.Convert(deref(ifst._fst), _fst_type))             # <<<<<<<<<<<<<<
  *   # Script-land Convert returns a null pointer to signal failure.
- *   if tfst.get() == NULL:
+ *   if _tfst.get() == NULL:
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3523, __pyx_L1_error)
+    __PYX_ERR(0, 3551, __pyx_L1_error)
   }
-  __pyx_v_tfst.reset(fst::script::Convert((*__pyx_v_ifst->_fst), __pyx_v_fst_type_string));
+  __pyx_v__tfst.reset(fst::script::Convert((*__pyx_v_ifst->_fst), __pyx_v__fst_type));
 
-  /* "pywrapfst.pyx":3525
- *   tfst.reset(fst.Convert(deref(ifst._fst), fst_type_string))
+  /* "pywrapfst.pyx":3553
+ *   _tfst.reset(fst.Convert(deref(ifst._fst), _fst_type))
  *   # Script-land Convert returns a null pointer to signal failure.
- *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
- *     raise FstOpError("Conversion to {!r} failed".format(fst_type))
- *   return _init_XFst(tfst.release())
+ *   if _tfst.get() == NULL:             # <<<<<<<<<<<<<<
+ *     raise FstOpError(f"Conversion to {fst_type!r} failed")
+ *   return _init_XFst(_tfst.release())
  */
-  __pyx_t_2 = ((__pyx_v_tfst.get() == NULL) != 0);
+  __pyx_t_2 = ((__pyx_v__tfst.get() == NULL) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":3526
+    /* "pywrapfst.pyx":3554
  *   # Script-land Convert returns a null pointer to signal failure.
- *   if tfst.get() == NULL:
- *     raise FstOpError("Conversion to {!r} failed".format(fst_type))             # <<<<<<<<<<<<<<
- *   return _init_XFst(tfst.release())
+ *   if _tfst.get() == NULL:
+ *     raise FstOpError(f"Conversion to {fst_type!r} failed")             # <<<<<<<<<<<<<<
+ *   return _init_XFst(_tfst.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3526, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3554, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Conversion_to_r_failed, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3526, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
-        __Pyx_INCREF(__pyx_t_7);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_6, function);
-      }
-    }
-    __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_7, __pyx_v_fst_type) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_fst_type);
-    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3526, __pyx_L1_error)
+    __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3554, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = NULL;
+    __pyx_t_6 = 0;
+    __pyx_t_7 = 127;
+    __Pyx_INCREF(__pyx_kp_u_Conversion_to);
+    __pyx_t_6 += 14;
+    __Pyx_GIVEREF(__pyx_kp_u_Conversion_to);
+    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_kp_u_Conversion_to);
+    __pyx_t_8 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_fst_type), __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3554, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_8);
+    __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) : __pyx_t_7;
+    __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_8);
+    __Pyx_GIVEREF(__pyx_t_8);
+    PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_8);
+    __pyx_t_8 = 0;
+    __Pyx_INCREF(__pyx_kp_u_failed);
+    __pyx_t_6 += 7;
+    __Pyx_GIVEREF(__pyx_kp_u_failed);
+    PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_kp_u_failed);
+    __pyx_t_8 = __Pyx_PyUnicode_Join(__pyx_t_5, 3, __pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 3554, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_8);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
-      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
-      if (likely(__pyx_t_6)) {
+      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+      if (likely(__pyx_t_5)) {
         PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-        __Pyx_INCREF(__pyx_t_6);
+        __Pyx_INCREF(__pyx_t_5);
         __Pyx_INCREF(function);
         __Pyx_DECREF_SET(__pyx_t_4, function);
       }
     }
-    __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5);
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3526, __pyx_L1_error)
+    __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_8) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_8);
+    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3554, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 3526, __pyx_L1_error)
+    __PYX_ERR(0, 3554, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3525
- *   tfst.reset(fst.Convert(deref(ifst._fst), fst_type_string))
+    /* "pywrapfst.pyx":3553
+ *   _tfst.reset(fst.Convert(deref(ifst._fst), _fst_type))
  *   # Script-land Convert returns a null pointer to signal failure.
- *   if tfst.get() == NULL:             # <<<<<<<<<<<<<<
- *     raise FstOpError("Conversion to {!r} failed".format(fst_type))
- *   return _init_XFst(tfst.release())
+ *   if _tfst.get() == NULL:             # <<<<<<<<<<<<<<
+ *     raise FstOpError(f"Conversion to {fst_type!r} failed")
+ *   return _init_XFst(_tfst.release())
  */
   }
 
-  /* "pywrapfst.pyx":3527
- *   if tfst.get() == NULL:
- *     raise FstOpError("Conversion to {!r} failed".format(fst_type))
- *   return _init_XFst(tfst.release())             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3555
+ *   if _tfst.get() == NULL:
+ *     raise FstOpError(f"Conversion to {fst_type!r} failed")
+ *   return _init_XFst(_tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3527, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3555, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3504
+  /* "pywrapfst.pyx":3532
  * 
  * 
- * cpdef Fst convert(Fst ifst, fst_type=b""):             # <<<<<<<<<<<<<<
+ * cpdef Fst convert(Fst ifst, fst_type=""):             # <<<<<<<<<<<<<<
  *   """
  *   convert(ifst, fst_type="")
  */
@@ -37735,8 +38130,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_convert(struct __pyx_
   __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_8);
   __Pyx_AddTraceback("pywrapfst.convert", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
@@ -37751,13 +38145,16 @@ static char __pyx_doc_9pywrapfst_24convert[] = "\n  convert(ifst, fst_type=\"\")
 static PyObject *__pyx_pw_9pywrapfst_25convert(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   PyObject *__pyx_v_fst_type = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("convert (wrapper)", 0);
   {
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ifst,&__pyx_n_s_fst_type,0};
     PyObject* values[2] = {0,0};
-    values[1] = ((PyObject *)__pyx_kp_b__8);
+    values[1] = ((PyObject *)__pyx_kp_u__11);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -37782,7 +38179,7 @@ static PyObject *__pyx_pw_9pywrapfst_25convert(PyObject *__pyx_self, PyObject *_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "convert") < 0)) __PYX_ERR(0, 3504, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "convert") < 0)) __PYX_ERR(0, 3532, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -37798,13 +38195,13 @@ static PyObject *__pyx_pw_9pywrapfst_25convert(PyObject *__pyx_self, PyObject *_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("convert", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3504, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("convert", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3532, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.convert", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3504, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3532, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_24convert(__pyx_self, __pyx_v_ifst, __pyx_v_fst_type);
 
   /* function exit code */
@@ -37821,11 +38218,14 @@ static PyObject *__pyx_pf_9pywrapfst_24convert(CYTHON_UNUSED PyObject *__pyx_sel
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   struct __pyx_opt_args_9pywrapfst_convert __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("convert", 0);
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.fst_type = __pyx_v_fst_type;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_convert(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3504, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_convert(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3532, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -37842,22 +38242,22 @@ static PyObject *__pyx_pf_9pywrapfst_24convert(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3530
+/* "pywrapfst.pyx":3558
  * 
  * 
  * cpdef MutableFst determinize(Fst ifst,             # <<<<<<<<<<<<<<
  *                              float delta=fst.kShortestDelta,
- *                              det_type=b"functional",
+ *                              det_type="functional",
  */
 
 static PyObject *__pyx_pw_9pywrapfst_27determinize(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_determinize(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_determinize *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__32;
-  PyObject *__pyx_v_det_type = ((PyObject *)__pyx_n_b_functional);
-  int64 __pyx_v_nstate = __pyx_k__33;
+  float __pyx_v_delta = __pyx_k__34;
+  PyObject *__pyx_v_det_type = ((PyObject *)__pyx_n_u_functional);
+  int64 __pyx_v_nstate = __pyx_k__35;
   int64 __pyx_v_subsequential_label = ((int64)0);
 
-  /* "pywrapfst.pyx":3535
+  /* "pywrapfst.pyx":3563
  *                              int64 nstate=fst.kNoStateId,
  *                              int64 subsequential_label=0,
  *                              weight=None,             # <<<<<<<<<<<<<<
@@ -37866,7 +38266,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_determinize(st
  */
   PyObject *__pyx_v_weight = ((PyObject *)Py_None);
 
-  /* "pywrapfst.pyx":3536
+  /* "pywrapfst.pyx":3564
  *                              int64 subsequential_label=0,
  *                              weight=None,
  *                              bool increment_subsequential_label=False):             # <<<<<<<<<<<<<<
@@ -37874,10 +38274,10 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_determinize(st
  *   determinize(ifst, delta=1e-6, det_type="functional",
  */
   bool __pyx_v_increment_subsequential_label = ((bool)0);
-  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v_tfst;
-  fst::script::WeightClass __pyx_v_wc;
-  enum fst::DeterminizeType __pyx_v_determinize_type_enum;
-  std::unique_ptr<fst::script::DeterminizeOptions>  __pyx_v_opts;
+  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v__tfst;
+  fst::script::WeightClass __pyx_v__weight;
+  enum fst::DeterminizeType __pyx_v__det_type;
+  std::unique_ptr<fst::script::DeterminizeOptions>  __pyx_v__opts;
   struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   fst::script::WeightClass __pyx_t_1;
@@ -37887,7 +38287,9 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_determinize(st
   PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
   PyObject *__pyx_t_7 = NULL;
-  PyObject *__pyx_t_8 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("determinize", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -37910,165 +38312,137 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_determinize(st
     }
   }
 
-  /* "pywrapfst.pyx":3570
+  /* "pywrapfst.pyx":3598
  *   """
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
  *   # Threshold is set to semiring Zero (no pruning) if weight unspecified.
- *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(),
+ *   cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(ifst.weight_type(),
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3570, __pyx_L1_error)
+    __PYX_ERR(0, 3598, __pyx_L1_error)
   }
-  __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
+  __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":3572
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+  /* "pywrapfst.pyx":3600
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   # Threshold is set to semiring Zero (no pruning) if weight unspecified.
- *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(),             # <<<<<<<<<<<<<<
- *                                                      weight)
- *   cdef fst.DeterminizeType determinize_type_enum
+ *   cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(ifst.weight_type(),             # <<<<<<<<<<<<<<
+ *                                                           weight)
+ *   cdef fst.DeterminizeType _det_type
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 3572, __pyx_L1_error)
+    __PYX_ERR(0, 3600, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3573
+  /* "pywrapfst.pyx":3601
  *   # Threshold is set to semiring Zero (no pruning) if weight unspecified.
- *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(),
- *                                                      weight)             # <<<<<<<<<<<<<<
- *   cdef fst.DeterminizeType determinize_type_enum
- *   if not fst.GetDeterminizeType(tostring(det_type),
- */
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_Zero(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3572, __pyx_L1_error)
-  __pyx_v_wc = __pyx_t_1;
-
-  /* "pywrapfst.pyx":3575
- *                                                      weight)
- *   cdef fst.DeterminizeType determinize_type_enum
- *   if not fst.GetDeterminizeType(tostring(det_type),             # <<<<<<<<<<<<<<
- *                                 addr(determinize_type_enum)):
- *     raise FstArgError("Unknown determinization type: {!r}".format(det_type))
- */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_det_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3575, __pyx_L1_error)
-
-  /* "pywrapfst.pyx":3576
- *   cdef fst.DeterminizeType determinize_type_enum
- *   if not fst.GetDeterminizeType(tostring(det_type),
- *                                 addr(determinize_type_enum)):             # <<<<<<<<<<<<<<
- *     raise FstArgError("Unknown determinization type: {!r}".format(det_type))
- *   cdef unique_ptr[fst.DeterminizeOptions] opts
- */
-  __pyx_t_3 = ((!(fst::script::GetDeterminizeType(__pyx_t_2, (&__pyx_v_determinize_type_enum)) != 0)) != 0);
-
-  /* "pywrapfst.pyx":3575
- *                                                      weight)
- *   cdef fst.DeterminizeType determinize_type_enum
- *   if not fst.GetDeterminizeType(tostring(det_type),             # <<<<<<<<<<<<<<
- *                                 addr(determinize_type_enum)):
- *     raise FstArgError("Unknown determinization type: {!r}".format(det_type))
- */
+ *   cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(ifst.weight_type(),
+ *                                                           weight)             # <<<<<<<<<<<<<<
+ *   cdef fst.DeterminizeType _det_type
+ *   if not fst.GetDeterminizeType(tostring(det_type), addr(_det_type)):
+ */
+  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_Zero(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3600, __pyx_L1_error)
+  __pyx_v__weight = __pyx_t_1;
+
+  /* "pywrapfst.pyx":3603
+ *                                                           weight)
+ *   cdef fst.DeterminizeType _det_type
+ *   if not fst.GetDeterminizeType(tostring(det_type), addr(_det_type)):             # <<<<<<<<<<<<<<
+ *     raise FstArgError(f"Unknown determinization type: {det_type!r}")
+ *   cdef unique_ptr[fst.DeterminizeOptions] _opts
+ */
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_det_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3603, __pyx_L1_error)
+  __pyx_t_3 = ((!(fst::script::GetDeterminizeType(__pyx_t_2, (&__pyx_v__det_type)) != 0)) != 0);
   if (unlikely(__pyx_t_3)) {
 
-    /* "pywrapfst.pyx":3577
- *   if not fst.GetDeterminizeType(tostring(det_type),
- *                                 addr(determinize_type_enum)):
- *     raise FstArgError("Unknown determinization type: {!r}".format(det_type))             # <<<<<<<<<<<<<<
- *   cdef unique_ptr[fst.DeterminizeOptions] opts
- *   opts.reset(new fst.DeterminizeOptions(delta,
+    /* "pywrapfst.pyx":3604
+ *   cdef fst.DeterminizeType _det_type
+ *   if not fst.GetDeterminizeType(tostring(det_type), addr(_det_type)):
+ *     raise FstArgError(f"Unknown determinization type: {det_type!r}")             # <<<<<<<<<<<<<<
+ *   cdef unique_ptr[fst.DeterminizeOptions] _opts
+ *   _opts.reset(
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3577, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstArgError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 3604, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Unknown_determinization_type_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 3577, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_7);
-    __pyx_t_8 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) {
-      __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7);
-      if (likely(__pyx_t_8)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
-        __Pyx_INCREF(__pyx_t_8);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_7, function);
-      }
-    }
-    __pyx_t_6 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_v_det_type) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_det_type);
-    __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
-    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3577, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_det_type), __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 3604, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
-    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-    __pyx_t_7 = NULL;
+    __pyx_t_7 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unknown_determinization_type, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 3604, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_7);
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __pyx_t_6 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
-      if (likely(__pyx_t_7)) {
+      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
+      if (likely(__pyx_t_6)) {
         PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-        __Pyx_INCREF(__pyx_t_7);
+        __Pyx_INCREF(__pyx_t_6);
         __Pyx_INCREF(function);
         __Pyx_DECREF_SET(__pyx_t_5, function);
       }
     }
-    __pyx_t_4 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_7, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6);
-    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3577, __pyx_L1_error)
+    __pyx_t_4 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_6, __pyx_t_7) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_7);
+    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3604, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_Raise(__pyx_t_4, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __PYX_ERR(0, 3577, __pyx_L1_error)
+    __PYX_ERR(0, 3604, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":3575
- *                                                      weight)
- *   cdef fst.DeterminizeType determinize_type_enum
- *   if not fst.GetDeterminizeType(tostring(det_type),             # <<<<<<<<<<<<<<
- *                                 addr(determinize_type_enum)):
- *     raise FstArgError("Unknown determinization type: {!r}".format(det_type))
+    /* "pywrapfst.pyx":3603
+ *                                                           weight)
+ *   cdef fst.DeterminizeType _det_type
+ *   if not fst.GetDeterminizeType(tostring(det_type), addr(_det_type)):             # <<<<<<<<<<<<<<
+ *     raise FstArgError(f"Unknown determinization type: {det_type!r}")
+ *   cdef unique_ptr[fst.DeterminizeOptions] _opts
  */
   }
 
-  /* "pywrapfst.pyx":3579
- *     raise FstArgError("Unknown determinization type: {!r}".format(det_type))
- *   cdef unique_ptr[fst.DeterminizeOptions] opts
- *   opts.reset(new fst.DeterminizeOptions(delta,             # <<<<<<<<<<<<<<
- *                                         wc,
- *                                         nstate,
+  /* "pywrapfst.pyx":3606
+ *     raise FstArgError(f"Unknown determinization type: {det_type!r}")
+ *   cdef unique_ptr[fst.DeterminizeOptions] _opts
+ *   _opts.reset(             # <<<<<<<<<<<<<<
+ *       new fst.DeterminizeOptions(delta,
+ *                                  _weight,
  */
-  __pyx_v_opts.reset(new fst::script::DeterminizeOptions(__pyx_v_delta, __pyx_v_wc, __pyx_v_nstate, __pyx_v_subsequential_label, __pyx_v_determinize_type_enum, __pyx_v_increment_subsequential_label));
+  __pyx_v__opts.reset(new fst::script::DeterminizeOptions(__pyx_v_delta, __pyx_v__weight, __pyx_v_nstate, __pyx_v_subsequential_label, __pyx_v__det_type, __pyx_v_increment_subsequential_label));
 
-  /* "pywrapfst.pyx":3585
- *                                         determinize_type_enum,
- *                                         increment_subsequential_label))
- *   fst.Determinize(deref(ifst._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
- *   return _init_MutableFst(tfst.release())
+  /* "pywrapfst.pyx":3613
+ *                                  _det_type,
+ *                                  increment_subsequential_label))
+ *   fst.Determinize(deref(ifst._fst), _tfst.get(), deref(_opts))             # <<<<<<<<<<<<<<
+ *   return _init_MutableFst(_tfst.release())
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3585, __pyx_L1_error)
+    __PYX_ERR(0, 3613, __pyx_L1_error)
   }
-  fst::script::Determinize((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
+  fst::script::Determinize((*__pyx_v_ifst->_fst), __pyx_v__tfst.get(), (*__pyx_v__opts));
 
-  /* "pywrapfst.pyx":3586
- *                                         increment_subsequential_label))
- *   fst.Determinize(deref(ifst._fst), tfst.get(), deref(opts))
- *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3614
+ *                                  increment_subsequential_label))
+ *   fst.Determinize(deref(ifst._fst), _tfst.get(), deref(_opts))
+ *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3586, __pyx_L1_error)
+  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3614, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_4);
   __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3530
+  /* "pywrapfst.pyx":3558
  * 
  * 
  * cpdef MutableFst determinize(Fst ifst,             # <<<<<<<<<<<<<<
  *                              float delta=fst.kShortestDelta,
- *                              det_type=b"functional",
+ *                              det_type="functional",
  */
 
   /* function exit code */
@@ -38077,7 +38451,6 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_determinize(st
   __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
   __Pyx_XDECREF(__pyx_t_7);
-  __Pyx_XDECREF(__pyx_t_8);
   __Pyx_AddTraceback("pywrapfst.determinize", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
@@ -38097,15 +38470,18 @@ static PyObject *__pyx_pw_9pywrapfst_27determinize(PyObject *__pyx_self, PyObjec
   int64 __pyx_v_subsequential_label;
   PyObject *__pyx_v_weight = 0;
   bool __pyx_v_increment_subsequential_label;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("determinize (wrapper)", 0);
   {
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ifst,&__pyx_n_s_delta,&__pyx_n_s_det_type,&__pyx_n_s_nstate,&__pyx_n_s_subsequential_label,&__pyx_n_s_weight,&__pyx_n_s_increment_subsequential_label,0};
     PyObject* values[7] = {0,0,0,0,0,0,0};
-    values[2] = ((PyObject *)__pyx_n_b_functional);
+    values[2] = ((PyObject *)__pyx_n_u_functional);
 
-    /* "pywrapfst.pyx":3535
+    /* "pywrapfst.pyx":3563
  *                              int64 nstate=fst.kNoStateId,
  *                              int64 subsequential_label=0,
  *                              weight=None,             # <<<<<<<<<<<<<<
@@ -38177,7 +38553,7 @@ static PyObject *__pyx_pw_9pywrapfst_27determinize(PyObject *__pyx_self, PyObjec
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "determinize") < 0)) __PYX_ERR(0, 3530, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "determinize") < 0)) __PYX_ERR(0, 3558, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38200,27 +38576,27 @@ static PyObject *__pyx_pw_9pywrapfst_27determinize(PyObject *__pyx_self, PyObjec
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3531, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3559, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__32;
+      __pyx_v_delta = __pyx_k__34;
     }
     __pyx_v_det_type = values[2];
     if (values[3]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3533, __pyx_L3_error)
+      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3561, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__33;
+      __pyx_v_nstate = __pyx_k__35;
     }
     if (values[4]) {
-      __pyx_v_subsequential_label = __Pyx_PyInt_As_int64_t(values[4]); if (unlikely((__pyx_v_subsequential_label == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3534, __pyx_L3_error)
+      __pyx_v_subsequential_label = __Pyx_PyInt_As_int64_t(values[4]); if (unlikely((__pyx_v_subsequential_label == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3562, __pyx_L3_error)
     } else {
       __pyx_v_subsequential_label = ((int64)0);
     }
     __pyx_v_weight = values[5];
     if (values[6]) {
-      __pyx_v_increment_subsequential_label = __Pyx_PyObject_IsTrue(values[6]); if (unlikely((__pyx_v_increment_subsequential_label == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3536, __pyx_L3_error)
+      __pyx_v_increment_subsequential_label = __Pyx_PyObject_IsTrue(values[6]); if (unlikely((__pyx_v_increment_subsequential_label == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3564, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3536
+      /* "pywrapfst.pyx":3564
  *                              int64 subsequential_label=0,
  *                              weight=None,
  *                              bool increment_subsequential_label=False):             # <<<<<<<<<<<<<<
@@ -38232,21 +38608,21 @@ static PyObject *__pyx_pw_9pywrapfst_27determinize(PyObject *__pyx_self, PyObjec
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("determinize", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3530, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("determinize", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3558, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.determinize", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3530, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3558, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_26determinize(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_det_type, __pyx_v_nstate, __pyx_v_subsequential_label, __pyx_v_weight, __pyx_v_increment_subsequential_label);
 
-  /* "pywrapfst.pyx":3530
+  /* "pywrapfst.pyx":3558
  * 
  * 
  * cpdef MutableFst determinize(Fst ifst,             # <<<<<<<<<<<<<<
  *                              float delta=fst.kShortestDelta,
- *                              det_type=b"functional",
+ *                              det_type="functional",
  */
 
   /* function exit code */
@@ -38263,6 +38639,9 @@ static PyObject *__pyx_pf_9pywrapfst_26determinize(CYTHON_UNUSED PyObject *__pyx
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   struct __pyx_opt_args_9pywrapfst_determinize __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("determinize", 0);
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 6;
@@ -38272,7 +38651,7 @@ static PyObject *__pyx_pf_9pywrapfst_26determinize(CYTHON_UNUSED PyObject *__pyx
   __pyx_t_2.subsequential_label = __pyx_v_subsequential_label;
   __pyx_t_2.weight = __pyx_v_weight;
   __pyx_t_2.increment_subsequential_label = __pyx_v_increment_subsequential_label;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_determinize(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3530, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_determinize(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3558, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -38289,33 +38668,36 @@ static PyObject *__pyx_pf_9pywrapfst_26determinize(CYTHON_UNUSED PyObject *__pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3589
+/* "pywrapfst.pyx":3617
  * 
  * 
  * cpdef MutableFst difference(Fst ifst1,             # <<<<<<<<<<<<<<
  *                             Fst ifst2,
- *                             compose_filter=b"auto",
+ *                             compose_filter="auto",
  */
 
 static PyObject *__pyx_pw_9pywrapfst_29difference(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_difference(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_difference *__pyx_optional_args) {
-  PyObject *__pyx_v_compose_filter = ((PyObject *)__pyx_n_b_auto);
+  PyObject *__pyx_v_compose_filter = ((PyObject *)__pyx_n_u_auto);
 
-  /* "pywrapfst.pyx":3592
+  /* "pywrapfst.pyx":3620
  *                             Fst ifst2,
- *                             compose_filter=b"auto",
+ *                             compose_filter="auto",
  *                             bool connect=True):             # <<<<<<<<<<<<<<
  *   """
  *   difference(ifst1, ifst2, compose_filter="auto", connect=True)
  */
   bool __pyx_v_connect = ((bool)1);
-  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v_tfst;
-  std::unique_ptr<fst::ComposeOptions>  __pyx_v_opts;
+  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v__tfst;
+  std::unique_ptr<fst::ComposeOptions>  __pyx_v__opts;
   struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
   enum fst::ComposeFilter __pyx_t_2;
   PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("difference", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -38326,75 +38708,91 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_difference(str
     }
   }
 
-  /* "pywrapfst.pyx":3617
+  /* "pywrapfst.pyx":3645
  *   """
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))             # <<<<<<<<<<<<<<
- *   cdef unique_ptr[fst.ComposeOptions] opts
- *   opts.reset(new fst.ComposeOptions(
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))             # <<<<<<<<<<<<<<
+ *   cdef unique_ptr[fst.ComposeOptions] _opts
+ *   _opts.reset(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3617, __pyx_L1_error)
+    __PYX_ERR(0, 3645, __pyx_L1_error)
   }
-  __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst1->__pyx_vtab)->arc_type(__pyx_v_ifst1, 0)));
+  __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst1->__pyx_vtab)->arc_type(__pyx_v_ifst1, 0)));
 
-  /* "pywrapfst.pyx":3621
- *   opts.reset(new fst.ComposeOptions(
- *       connect,
- *       _get_compose_filter(tostring(compose_filter))))             # <<<<<<<<<<<<<<
- *   fst.Difference(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
- *   return _init_MutableFst(tfst.release())
+  /* "pywrapfst.pyx":3649
+ *   _opts.reset(
+ *       new fst.ComposeOptions(connect,
+ *                             _get_compose_filter(tostring(compose_filter))))             # <<<<<<<<<<<<<<
+ *   fst.Difference(deref(ifst1._fst),
+ *                  deref(ifst2._fst),
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3621, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3621, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3649, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3649, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3619
- *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
- *   cdef unique_ptr[fst.ComposeOptions] opts
- *   opts.reset(new fst.ComposeOptions(             # <<<<<<<<<<<<<<
- *       connect,
- *       _get_compose_filter(tostring(compose_filter))))
+  /* "pywrapfst.pyx":3647
+ *   _tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
+ *   cdef unique_ptr[fst.ComposeOptions] _opts
+ *   _opts.reset(             # <<<<<<<<<<<<<<
+ *       new fst.ComposeOptions(connect,
+ *                             _get_compose_filter(tostring(compose_filter))))
  */
-  __pyx_v_opts.reset(new fst::ComposeOptions(__pyx_v_connect, __pyx_t_2));
+  __pyx_v__opts.reset(new fst::ComposeOptions(__pyx_v_connect, __pyx_t_2));
 
-  /* "pywrapfst.pyx":3622
- *       connect,
- *       _get_compose_filter(tostring(compose_filter))))
- *   fst.Difference(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
- *   return _init_MutableFst(tfst.release())
- * 
+  /* "pywrapfst.pyx":3650
+ *       new fst.ComposeOptions(connect,
+ *                             _get_compose_filter(tostring(compose_filter))))
+ *   fst.Difference(deref(ifst1._fst),             # <<<<<<<<<<<<<<
+ *                  deref(ifst2._fst),
+ *                  _tfst.get(),
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3622, __pyx_L1_error)
+    __PYX_ERR(0, 3650, __pyx_L1_error)
   }
+
+  /* "pywrapfst.pyx":3651
+ *                             _get_compose_filter(tostring(compose_filter))))
+ *   fst.Difference(deref(ifst1._fst),
+ *                  deref(ifst2._fst),             # <<<<<<<<<<<<<<
+ *                  _tfst.get(),
+ *                  deref(_opts))
+ */
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3622, __pyx_L1_error)
+    __PYX_ERR(0, 3651, __pyx_L1_error)
   }
-  fst::script::Difference((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
 
-  /* "pywrapfst.pyx":3623
- *       _get_compose_filter(tostring(compose_filter))))
- *   fst.Difference(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
- *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3650
+ *       new fst.ComposeOptions(connect,
+ *                             _get_compose_filter(tostring(compose_filter))))
+ *   fst.Difference(deref(ifst1._fst),             # <<<<<<<<<<<<<<
+ *                  deref(ifst2._fst),
+ *                  _tfst.get(),
+ */
+  fst::script::Difference((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v__tfst.get(), (*__pyx_v__opts));
+
+  /* "pywrapfst.pyx":3654
+ *                  _tfst.get(),
+ *                  deref(_opts))
+ *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3623, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3654, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3589
+  /* "pywrapfst.pyx":3617
  * 
  * 
  * cpdef MutableFst difference(Fst ifst1,             # <<<<<<<<<<<<<<
  *                             Fst ifst2,
- *                             compose_filter=b"auto",
+ *                             compose_filter="auto",
  */
 
   /* function exit code */
@@ -38416,13 +38814,16 @@ static PyObject *__pyx_pw_9pywrapfst_29difference(PyObject *__pyx_self, PyObject
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2 = 0;
   PyObject *__pyx_v_compose_filter = 0;
   bool __pyx_v_connect;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("difference (wrapper)", 0);
   {
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ifst1,&__pyx_n_s_ifst2,&__pyx_n_s_compose_filter,&__pyx_n_s_connect,0};
     PyObject* values[4] = {0,0,0,0};
-    values[2] = ((PyObject *)__pyx_n_b_auto);
+    values[2] = ((PyObject *)__pyx_n_u_auto);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -38447,7 +38848,7 @@ static PyObject *__pyx_pw_9pywrapfst_29difference(PyObject *__pyx_self, PyObject
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("difference", 0, 2, 4, 1); __PYX_ERR(0, 3589, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("difference", 0, 2, 4, 1); __PYX_ERR(0, 3617, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -38463,7 +38864,7 @@ static PyObject *__pyx_pw_9pywrapfst_29difference(PyObject *__pyx_self, PyObject
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "difference") < 0)) __PYX_ERR(0, 3589, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "difference") < 0)) __PYX_ERR(0, 3617, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38481,12 +38882,12 @@ static PyObject *__pyx_pw_9pywrapfst_29difference(PyObject *__pyx_self, PyObject
     __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst_Fst *)values[1]);
     __pyx_v_compose_filter = values[2];
     if (values[3]) {
-      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3592, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3620, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3592
+      /* "pywrapfst.pyx":3620
  *                             Fst ifst2,
- *                             compose_filter=b"auto",
+ *                             compose_filter="auto",
  *                             bool connect=True):             # <<<<<<<<<<<<<<
  *   """
  *   difference(ifst1, ifst2, compose_filter="auto", connect=True)
@@ -38496,22 +38897,22 @@ static PyObject *__pyx_pw_9pywrapfst_29difference(PyObject *__pyx_self, PyObject
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("difference", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3589, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("difference", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3617, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.difference", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3589, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3590, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3617, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3618, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_28difference(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_compose_filter, __pyx_v_connect);
 
-  /* "pywrapfst.pyx":3589
+  /* "pywrapfst.pyx":3617
  * 
  * 
  * cpdef MutableFst difference(Fst ifst1,             # <<<<<<<<<<<<<<
  *                             Fst ifst2,
- *                             compose_filter=b"auto",
+ *                             compose_filter="auto",
  */
 
   /* function exit code */
@@ -38528,12 +38929,15 @@ static PyObject *__pyx_pf_9pywrapfst_28difference(CYTHON_UNUSED PyObject *__pyx_
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   struct __pyx_opt_args_9pywrapfst_difference __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("difference", 0);
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 2;
   __pyx_t_2.compose_filter = __pyx_v_compose_filter;
   __pyx_t_2.connect = __pyx_v_connect;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_difference(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3589, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_difference(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3617, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -38550,7 +38954,7 @@ static PyObject *__pyx_pf_9pywrapfst_28difference(CYTHON_UNUSED PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3626
+/* "pywrapfst.pyx":3657
  * 
  * 
  * cpdef MutableFst disambiguate(Fst ifst,             # <<<<<<<<<<<<<<
@@ -38560,11 +38964,11 @@ static PyObject *__pyx_pf_9pywrapfst_28difference(CYTHON_UNUSED PyObject *__pyx_
 
 static PyObject *__pyx_pw_9pywrapfst_31disambiguate(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_disambiguate(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_disambiguate *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__34;
-  int64 __pyx_v_nstate = __pyx_k__35;
+  float __pyx_v_delta = __pyx_k__36;
+  int64 __pyx_v_nstate = __pyx_k__37;
   int64 __pyx_v_subsequential_label = ((int64)0);
 
-  /* "pywrapfst.pyx":3630
+  /* "pywrapfst.pyx":3661
  *                               int64 nstate=fst.kNoStateId,
  *                               int64 subsequential_label=0,
  *                               weight=None):             # <<<<<<<<<<<<<<
@@ -38572,13 +38976,16 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_disambiguate(s
  *   disambiguate(ifst, delta=0.0009765625, nstate=NO_STATE_ID,
  */
   PyObject *__pyx_v_weight = ((PyObject *)Py_None);
-  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v_tfst;
-  fst::script::WeightClass __pyx_v_wc;
-  std::unique_ptr<fst::script::DisambiguateOptions>  __pyx_v_opts;
+  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v__tfst;
+  fst::script::WeightClass __pyx_v__weight;
+  std::unique_ptr<fst::script::DisambiguateOptions>  __pyx_v__opts;
   struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   fst::script::WeightClass __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("disambiguate", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -38595,78 +39002,78 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_disambiguate(s
     }
   }
 
-  /* "pywrapfst.pyx":3655
+  /* "pywrapfst.pyx":3686
  *   """
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
  *   # Threshold is set to semiring Zero (no pruning) if no weight is specified.
- *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(),
+ *   cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(ifst.weight_type(),
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3655, __pyx_L1_error)
+    __PYX_ERR(0, 3686, __pyx_L1_error)
   }
-  __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
+  __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":3657
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+  /* "pywrapfst.pyx":3688
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   # Threshold is set to semiring Zero (no pruning) if no weight is specified.
- *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(),             # <<<<<<<<<<<<<<
+ *   cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(ifst.weight_type(),             # <<<<<<<<<<<<<<
  *                                                      weight)
- *   cdef unique_ptr[fst.DisambiguateOptions] opts
+ *   cdef unique_ptr[fst.DisambiguateOptions] _opts
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 3657, __pyx_L1_error)
+    __PYX_ERR(0, 3688, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3658
+  /* "pywrapfst.pyx":3689
  *   # Threshold is set to semiring Zero (no pruning) if no weight is specified.
- *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(),
+ *   cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(ifst.weight_type(),
  *                                                      weight)             # <<<<<<<<<<<<<<
- *   cdef unique_ptr[fst.DisambiguateOptions] opts
- *   opts.reset(new fst.DisambiguateOptions(delta,
+ *   cdef unique_ptr[fst.DisambiguateOptions] _opts
+ *   _opts.reset(
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_Zero(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3657, __pyx_L1_error)
-  __pyx_v_wc = __pyx_t_1;
+  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_Zero(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3688, __pyx_L1_error)
+  __pyx_v__weight = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3660
+  /* "pywrapfst.pyx":3691
  *                                                      weight)
- *   cdef unique_ptr[fst.DisambiguateOptions] opts
- *   opts.reset(new fst.DisambiguateOptions(delta,             # <<<<<<<<<<<<<<
- *                                          wc,
- *                                          nstate,
+ *   cdef unique_ptr[fst.DisambiguateOptions] _opts
+ *   _opts.reset(             # <<<<<<<<<<<<<<
+ *       new fst.DisambiguateOptions(delta,
+ *                                   _weight,
  */
-  __pyx_v_opts.reset(new fst::script::DisambiguateOptions(__pyx_v_delta, __pyx_v_wc, __pyx_v_nstate, __pyx_v_subsequential_label));
+  __pyx_v__opts.reset(new fst::script::DisambiguateOptions(__pyx_v_delta, __pyx_v__weight, __pyx_v_nstate, __pyx_v_subsequential_label));
 
-  /* "pywrapfst.pyx":3664
- *                                          nstate,
- *                                          subsequential_label))
- *   fst.Disambiguate(deref(ifst._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
- *   return _init_MutableFst(tfst.release())
+  /* "pywrapfst.pyx":3696
+ *                                   nstate,
+ *                                   subsequential_label))
+ *   fst.Disambiguate(deref(ifst._fst), _tfst.get(), deref(_opts))             # <<<<<<<<<<<<<<
+ *   return _init_MutableFst(_tfst.release())
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3664, __pyx_L1_error)
+    __PYX_ERR(0, 3696, __pyx_L1_error)
   }
-  fst::script::Disambiguate((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
+  fst::script::Disambiguate((*__pyx_v_ifst->_fst), __pyx_v__tfst.get(), (*__pyx_v__opts));
 
-  /* "pywrapfst.pyx":3665
- *                                          subsequential_label))
- *   fst.Disambiguate(deref(ifst._fst), tfst.get(), deref(opts))
- *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3697
+ *                                   subsequential_label))
+ *   fst.Disambiguate(deref(ifst._fst), _tfst.get(), deref(_opts))
+ *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3665, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3697, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_2);
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3626
+  /* "pywrapfst.pyx":3657
  * 
  * 
  * cpdef MutableFst disambiguate(Fst ifst,             # <<<<<<<<<<<<<<
@@ -38694,6 +39101,9 @@ static PyObject *__pyx_pw_9pywrapfst_31disambiguate(PyObject *__pyx_self, PyObje
   int64 __pyx_v_nstate;
   int64 __pyx_v_subsequential_label;
   PyObject *__pyx_v_weight = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("disambiguate (wrapper)", 0);
@@ -38701,7 +39111,7 @@ static PyObject *__pyx_pw_9pywrapfst_31disambiguate(PyObject *__pyx_self, PyObje
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ifst,&__pyx_n_s_delta,&__pyx_n_s_nstate,&__pyx_n_s_subsequential_label,&__pyx_n_s_weight,0};
     PyObject* values[5] = {0,0,0,0,0};
 
-    /* "pywrapfst.pyx":3630
+    /* "pywrapfst.pyx":3661
  *                               int64 nstate=fst.kNoStateId,
  *                               int64 subsequential_label=0,
  *                               weight=None):             # <<<<<<<<<<<<<<
@@ -38757,7 +39167,7 @@ static PyObject *__pyx_pw_9pywrapfst_31disambiguate(PyObject *__pyx_self, PyObje
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "disambiguate") < 0)) __PYX_ERR(0, 3626, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "disambiguate") < 0)) __PYX_ERR(0, 3657, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -38776,17 +39186,17 @@ static PyObject *__pyx_pw_9pywrapfst_31disambiguate(PyObject *__pyx_self, PyObje
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3627, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3658, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__34;
+      __pyx_v_delta = __pyx_k__36;
     }
     if (values[2]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[2]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3628, __pyx_L3_error)
+      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[2]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3659, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__35;
+      __pyx_v_nstate = __pyx_k__37;
     }
     if (values[3]) {
-      __pyx_v_subsequential_label = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_subsequential_label == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3629, __pyx_L3_error)
+      __pyx_v_subsequential_label = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_subsequential_label == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3660, __pyx_L3_error)
     } else {
       __pyx_v_subsequential_label = ((int64)0);
     }
@@ -38794,16 +39204,16 @@ static PyObject *__pyx_pw_9pywrapfst_31disambiguate(PyObject *__pyx_self, PyObje
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("disambiguate", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3626, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("disambiguate", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3657, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.disambiguate", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3626, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3657, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_30disambiguate(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nstate, __pyx_v_subsequential_label, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":3626
+  /* "pywrapfst.pyx":3657
  * 
  * 
  * cpdef MutableFst disambiguate(Fst ifst,             # <<<<<<<<<<<<<<
@@ -38825,6 +39235,9 @@ static PyObject *__pyx_pf_9pywrapfst_30disambiguate(CYTHON_UNUSED PyObject *__py
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   struct __pyx_opt_args_9pywrapfst_disambiguate __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("disambiguate", 0);
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 4;
@@ -38832,7 +39245,7 @@ static PyObject *__pyx_pf_9pywrapfst_30disambiguate(CYTHON_UNUSED PyObject *__py
   __pyx_t_2.nstate = __pyx_v_nstate;
   __pyx_t_2.subsequential_label = __pyx_v_subsequential_label;
   __pyx_t_2.weight = __pyx_v_weight;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_disambiguate(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3626, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_disambiguate(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3657, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -38849,7 +39262,7 @@ static PyObject *__pyx_pf_9pywrapfst_30disambiguate(CYTHON_UNUSED PyObject *__py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3668
+/* "pywrapfst.pyx":3700
  * 
  * 
  * cpdef MutableFst epsnormalize(Fst ifst, bool eps_norm_output=False):             # <<<<<<<<<<<<<<
@@ -38860,11 +39273,14 @@ static PyObject *__pyx_pf_9pywrapfst_30disambiguate(CYTHON_UNUSED PyObject *__py
 static PyObject *__pyx_pw_9pywrapfst_33epsnormalize(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_epsnormalize(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_epsnormalize *__pyx_optional_args) {
   bool __pyx_v_eps_norm_output = ((bool)0);
-  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v_tfst;
+  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v__tfst;
   struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   enum fst::EpsNormalizeType __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("epsnormalize", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -38872,36 +39288,36 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_epsnormalize(s
     }
   }
 
-  /* "pywrapfst.pyx":3689
+  /* "pywrapfst.pyx":3721
  *   """
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
  *   fst.EpsNormalize(
  *       deref(ifst._fst),
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3689, __pyx_L1_error)
+    __PYX_ERR(0, 3721, __pyx_L1_error)
   }
-  __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
+  __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":3691
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+  /* "pywrapfst.pyx":3723
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.EpsNormalize(
  *       deref(ifst._fst),             # <<<<<<<<<<<<<<
- *       tfst.get(),
+ *       _tfst.get(),
  *       fst.EPS_NORM_OUTPUT if eps_norm_output else fst.EPS_NORM_INPUT)
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3691, __pyx_L1_error)
+    __PYX_ERR(0, 3723, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3693
+  /* "pywrapfst.pyx":3725
  *       deref(ifst._fst),
- *       tfst.get(),
+ *       _tfst.get(),
  *       fst.EPS_NORM_OUTPUT if eps_norm_output else fst.EPS_NORM_INPUT)             # <<<<<<<<<<<<<<
- *   return _init_MutableFst(tfst.release())
+ *   return _init_MutableFst(_tfst.release())
  * 
  */
   if ((__pyx_v_eps_norm_output != 0)) {
@@ -38910,30 +39326,30 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_epsnormalize(s
     __pyx_t_1 = fst::EPS_NORM_INPUT;
   }
 
-  /* "pywrapfst.pyx":3690
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+  /* "pywrapfst.pyx":3722
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   fst.EpsNormalize(             # <<<<<<<<<<<<<<
  *       deref(ifst._fst),
- *       tfst.get(),
+ *       _tfst.get(),
  */
-  fst::script::EpsNormalize((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), __pyx_t_1);
+  fst::script::EpsNormalize((*__pyx_v_ifst->_fst), __pyx_v__tfst.get(), __pyx_t_1);
 
-  /* "pywrapfst.pyx":3694
- *       tfst.get(),
+  /* "pywrapfst.pyx":3726
+ *       _tfst.get(),
  *       fst.EPS_NORM_OUTPUT if eps_norm_output else fst.EPS_NORM_INPUT)
- *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
+ *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3694, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3726, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_2);
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3668
+  /* "pywrapfst.pyx":3700
  * 
  * 
  * cpdef MutableFst epsnormalize(Fst ifst, bool eps_norm_output=False):             # <<<<<<<<<<<<<<
@@ -38958,6 +39374,9 @@ static char __pyx_doc_9pywrapfst_32epsnormalize[] = "\n  epsnormalize(ifst, eps_
 static PyObject *__pyx_pw_9pywrapfst_33epsnormalize(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   bool __pyx_v_eps_norm_output;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("epsnormalize (wrapper)", 0);
@@ -38988,7 +39407,7 @@ static PyObject *__pyx_pw_9pywrapfst_33epsnormalize(PyObject *__pyx_self, PyObje
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "epsnormalize") < 0)) __PYX_ERR(0, 3668, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "epsnormalize") < 0)) __PYX_ERR(0, 3700, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39001,20 +39420,20 @@ static PyObject *__pyx_pw_9pywrapfst_33epsnormalize(PyObject *__pyx_self, PyObje
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_eps_norm_output = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_eps_norm_output == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3668, __pyx_L3_error)
+      __pyx_v_eps_norm_output = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_eps_norm_output == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3700, __pyx_L3_error)
     } else {
       __pyx_v_eps_norm_output = ((bool)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("epsnormalize", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3668, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("epsnormalize", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3700, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.epsnormalize", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3668, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3700, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_32epsnormalize(__pyx_self, __pyx_v_ifst, __pyx_v_eps_norm_output);
 
   /* function exit code */
@@ -39031,11 +39450,14 @@ static PyObject *__pyx_pf_9pywrapfst_32epsnormalize(CYTHON_UNUSED PyObject *__py
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   struct __pyx_opt_args_9pywrapfst_epsnormalize __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("epsnormalize", 0);
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.eps_norm_output = __pyx_v_eps_norm_output;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_epsnormalize(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3668, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_epsnormalize(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3700, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -39052,7 +39474,7 @@ static PyObject *__pyx_pf_9pywrapfst_32epsnormalize(CYTHON_UNUSED PyObject *__py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3697
+/* "pywrapfst.pyx":3729
  * 
  * 
  * cpdef bool equal(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -39062,9 +39484,12 @@ static PyObject *__pyx_pf_9pywrapfst_32epsnormalize(CYTHON_UNUSED PyObject *__py
 
 static PyObject *__pyx_pw_9pywrapfst_35equal(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static bool __pyx_f_9pywrapfst_equal(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_equal *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__36;
+  float __pyx_v_delta = __pyx_k__38;
   bool __pyx_r;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("equal", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -39072,7 +39497,7 @@ static bool __pyx_f_9pywrapfst_equal(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_if
     }
   }
 
-  /* "pywrapfst.pyx":3715
+  /* "pywrapfst.pyx":3747
  *     True if the FSTs satisfy the above condition, else False.
  *   """
  *   return fst.Equal(deref(ifst1._fst), deref(ifst2._fst), delta)             # <<<<<<<<<<<<<<
@@ -39081,16 +39506,16 @@ static bool __pyx_f_9pywrapfst_equal(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_if
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3715, __pyx_L1_error)
+    __PYX_ERR(0, 3747, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3715, __pyx_L1_error)
+    __PYX_ERR(0, 3747, __pyx_L1_error)
   }
   __pyx_r = fst::script::Equal((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_delta);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3697
+  /* "pywrapfst.pyx":3729
  * 
  * 
  * cpdef bool equal(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -39114,6 +39539,9 @@ static PyObject *__pyx_pw_9pywrapfst_35equal(PyObject *__pyx_self, PyObject *__p
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1 = 0;
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2 = 0;
   float __pyx_v_delta;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("equal (wrapper)", 0);
@@ -39142,7 +39570,7 @@ static PyObject *__pyx_pw_9pywrapfst_35equal(PyObject *__pyx_self, PyObject *__p
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, 1); __PYX_ERR(0, 3697, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, 1); __PYX_ERR(0, 3729, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -39152,7 +39580,7 @@ static PyObject *__pyx_pw_9pywrapfst_35equal(PyObject *__pyx_self, PyObject *__p
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "equal") < 0)) __PYX_ERR(0, 3697, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "equal") < 0)) __PYX_ERR(0, 3729, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39167,21 +39595,21 @@ static PyObject *__pyx_pw_9pywrapfst_35equal(PyObject *__pyx_self, PyObject *__p
     __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst_Fst *)values[1]);
     if (values[2]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3697, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3729, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__36;
+      __pyx_v_delta = __pyx_k__38;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3697, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("equal", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3729, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.equal", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3697, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3697, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3729, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3729, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_34equal(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_delta);
 
   /* function exit code */
@@ -39199,12 +39627,15 @@ static PyObject *__pyx_pf_9pywrapfst_34equal(CYTHON_UNUSED PyObject *__pyx_self,
   bool __pyx_t_1;
   struct __pyx_opt_args_9pywrapfst_equal __pyx_t_2;
   PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("equal", 0);
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.delta = __pyx_v_delta;
   __pyx_t_1 = __pyx_f_9pywrapfst_equal(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2); 
-  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3697, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3729, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -39221,7 +39652,7 @@ static PyObject *__pyx_pf_9pywrapfst_34equal(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3718
+/* "pywrapfst.pyx":3750
  * 
  * 
  * cpdef bool equivalent(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -39231,9 +39662,12 @@ static PyObject *__pyx_pf_9pywrapfst_34equal(CYTHON_UNUSED PyObject *__pyx_self,
 
 static PyObject *__pyx_pw_9pywrapfst_37equivalent(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static bool __pyx_f_9pywrapfst_equivalent(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_equivalent *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__37;
+  float __pyx_v_delta = __pyx_k__39;
   bool __pyx_r;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("equivalent", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -39241,7 +39675,7 @@ static bool __pyx_f_9pywrapfst_equivalent(struct __pyx_obj_9pywrapfst_Fst *__pyx
     }
   }
 
-  /* "pywrapfst.pyx":3736
+  /* "pywrapfst.pyx":3768
  *     True if the FSTs satisfy the above condition, else False.
  *   """
  *   return fst.Equivalent(deref(ifst1._fst), deref(ifst2._fst), delta)             # <<<<<<<<<<<<<<
@@ -39250,16 +39684,16 @@ static bool __pyx_f_9pywrapfst_equivalent(struct __pyx_obj_9pywrapfst_Fst *__pyx
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3736, __pyx_L1_error)
+    __PYX_ERR(0, 3768, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3736, __pyx_L1_error)
+    __PYX_ERR(0, 3768, __pyx_L1_error)
   }
   __pyx_r = fst::script::Equivalent((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_delta);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3718
+  /* "pywrapfst.pyx":3750
  * 
  * 
  * cpdef bool equivalent(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -39283,6 +39717,9 @@ static PyObject *__pyx_pw_9pywrapfst_37equivalent(PyObject *__pyx_self, PyObject
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1 = 0;
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2 = 0;
   float __pyx_v_delta;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("equivalent (wrapper)", 0);
@@ -39311,7 +39748,7 @@ static PyObject *__pyx_pw_9pywrapfst_37equivalent(PyObject *__pyx_self, PyObject
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, 1); __PYX_ERR(0, 3718, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, 1); __PYX_ERR(0, 3750, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -39321,7 +39758,7 @@ static PyObject *__pyx_pw_9pywrapfst_37equivalent(PyObject *__pyx_self, PyObject
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "equivalent") < 0)) __PYX_ERR(0, 3718, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "equivalent") < 0)) __PYX_ERR(0, 3750, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39336,21 +39773,21 @@ static PyObject *__pyx_pw_9pywrapfst_37equivalent(PyObject *__pyx_self, PyObject
     __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst_Fst *)values[1]);
     if (values[2]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3718, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3750, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__37;
+      __pyx_v_delta = __pyx_k__39;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3718, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("equivalent", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3750, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.equivalent", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3718, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3718, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3750, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3750, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_36equivalent(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_delta);
 
   /* function exit code */
@@ -39368,12 +39805,15 @@ static PyObject *__pyx_pf_9pywrapfst_36equivalent(CYTHON_UNUSED PyObject *__pyx_
   bool __pyx_t_1;
   struct __pyx_opt_args_9pywrapfst_equivalent __pyx_t_2;
   PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("equivalent", 0);
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.delta = __pyx_v_delta;
   __pyx_t_1 = __pyx_f_9pywrapfst_equivalent(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2); 
-  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3718, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3750, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -39390,33 +39830,36 @@ static PyObject *__pyx_pf_9pywrapfst_36equivalent(CYTHON_UNUSED PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3739
+/* "pywrapfst.pyx":3771
  * 
  * 
  * cpdef MutableFst intersect(Fst ifst1,             # <<<<<<<<<<<<<<
  *                            Fst ifst2,
- *                            compose_filter=b"auto",
+ *                            compose_filter="auto",
  */
 
 static PyObject *__pyx_pw_9pywrapfst_39intersect(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_intersect(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_intersect *__pyx_optional_args) {
-  PyObject *__pyx_v_compose_filter = ((PyObject *)__pyx_n_b_auto);
+  PyObject *__pyx_v_compose_filter = ((PyObject *)__pyx_n_u_auto);
 
-  /* "pywrapfst.pyx":3742
+  /* "pywrapfst.pyx":3774
  *                            Fst ifst2,
- *                            compose_filter=b"auto",
+ *                            compose_filter="auto",
  *                            bool connect=True):             # <<<<<<<<<<<<<<
  *   """
  *   intersect(ifst1, ifst2, compose_filter="auto", connect=True)
  */
   bool __pyx_v_connect = ((bool)1);
-  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v_tfst;
-  std::unique_ptr<fst::ComposeOptions>  __pyx_v_opts;
+  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v__tfst;
+  std::unique_ptr<fst::ComposeOptions>  __pyx_v__opts;
   struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
   enum fst::ComposeFilter __pyx_t_2;
   PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("intersect", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -39427,75 +39870,75 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_intersect(stru
     }
   }
 
-  /* "pywrapfst.pyx":3765
+  /* "pywrapfst.pyx":3797
  *   """
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))             # <<<<<<<<<<<<<<
- *   cdef unique_ptr[fst.ComposeOptions] opts
- *   opts.reset(new fst.ComposeOptions(
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))             # <<<<<<<<<<<<<<
+ *   cdef unique_ptr[fst.ComposeOptions] _opts
+ *   _opts.reset(
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3765, __pyx_L1_error)
+    __PYX_ERR(0, 3797, __pyx_L1_error)
   }
-  __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst1->__pyx_vtab)->arc_type(__pyx_v_ifst1, 0)));
+  __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst1->__pyx_vtab)->arc_type(__pyx_v_ifst1, 0)));
 
-  /* "pywrapfst.pyx":3769
- *   opts.reset(new fst.ComposeOptions(
- *       connect,
- *       _get_compose_filter(tostring(compose_filter))))             # <<<<<<<<<<<<<<
- *   fst.Intersect(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
- *   return _init_MutableFst(tfst.release())
+  /* "pywrapfst.pyx":3801
+ *   _opts.reset(
+ *       new fst.ComposeOptions(connect,
+ *                             _get_compose_filter(tostring(compose_filter))))             # <<<<<<<<<<<<<<
+ *   fst.Intersect(deref(ifst1._fst), deref(ifst2._fst), _tfst.get(), deref(_opts))
+ *   return _init_MutableFst(_tfst.release())
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3769, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3769, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_compose_filter); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3801, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_compose_filter(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3801, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":3767
- *   tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
- *   cdef unique_ptr[fst.ComposeOptions] opts
- *   opts.reset(new fst.ComposeOptions(             # <<<<<<<<<<<<<<
- *       connect,
- *       _get_compose_filter(tostring(compose_filter))))
+  /* "pywrapfst.pyx":3799
+ *   _tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
+ *   cdef unique_ptr[fst.ComposeOptions] _opts
+ *   _opts.reset(             # <<<<<<<<<<<<<<
+ *       new fst.ComposeOptions(connect,
+ *                             _get_compose_filter(tostring(compose_filter))))
  */
-  __pyx_v_opts.reset(new fst::ComposeOptions(__pyx_v_connect, __pyx_t_2));
+  __pyx_v__opts.reset(new fst::ComposeOptions(__pyx_v_connect, __pyx_t_2));
 
-  /* "pywrapfst.pyx":3770
- *       connect,
- *       _get_compose_filter(tostring(compose_filter))))
- *   fst.Intersect(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
- *   return _init_MutableFst(tfst.release())
+  /* "pywrapfst.pyx":3802
+ *       new fst.ComposeOptions(connect,
+ *                             _get_compose_filter(tostring(compose_filter))))
+ *   fst.Intersect(deref(ifst1._fst), deref(ifst2._fst), _tfst.get(), deref(_opts))             # <<<<<<<<<<<<<<
+ *   return _init_MutableFst(_tfst.release())
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3770, __pyx_L1_error)
+    __PYX_ERR(0, 3802, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3770, __pyx_L1_error)
+    __PYX_ERR(0, 3802, __pyx_L1_error)
   }
-  fst::script::Intersect((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
+  fst::script::Intersect((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v__tfst.get(), (*__pyx_v__opts));
 
-  /* "pywrapfst.pyx":3771
- *       _get_compose_filter(tostring(compose_filter))))
- *   fst.Intersect(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
- *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3803
+ *                             _get_compose_filter(tostring(compose_filter))))
+ *   fst.Intersect(deref(ifst1._fst), deref(ifst2._fst), _tfst.get(), deref(_opts))
+ *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3771, __pyx_L1_error)
+  __pyx_t_3 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3803, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3739
+  /* "pywrapfst.pyx":3771
  * 
  * 
  * cpdef MutableFst intersect(Fst ifst1,             # <<<<<<<<<<<<<<
  *                            Fst ifst2,
- *                            compose_filter=b"auto",
+ *                            compose_filter="auto",
  */
 
   /* function exit code */
@@ -39517,13 +39960,16 @@ static PyObject *__pyx_pw_9pywrapfst_39intersect(PyObject *__pyx_self, PyObject
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2 = 0;
   PyObject *__pyx_v_compose_filter = 0;
   bool __pyx_v_connect;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("intersect (wrapper)", 0);
   {
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ifst1,&__pyx_n_s_ifst2,&__pyx_n_s_compose_filter,&__pyx_n_s_connect,0};
     PyObject* values[4] = {0,0,0,0};
-    values[2] = ((PyObject *)__pyx_n_b_auto);
+    values[2] = ((PyObject *)__pyx_n_u_auto);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -39548,7 +39994,7 @@ static PyObject *__pyx_pw_9pywrapfst_39intersect(PyObject *__pyx_self, PyObject
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 4, 1); __PYX_ERR(0, 3739, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 4, 1); __PYX_ERR(0, 3771, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -39564,7 +40010,7 @@ static PyObject *__pyx_pw_9pywrapfst_39intersect(PyObject *__pyx_self, PyObject
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "intersect") < 0)) __PYX_ERR(0, 3739, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "intersect") < 0)) __PYX_ERR(0, 3771, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39582,12 +40028,12 @@ static PyObject *__pyx_pw_9pywrapfst_39intersect(PyObject *__pyx_self, PyObject
     __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst_Fst *)values[1]);
     __pyx_v_compose_filter = values[2];
     if (values[3]) {
-      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3742, __pyx_L3_error)
+      __pyx_v_connect = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_connect == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3774, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3742
+      /* "pywrapfst.pyx":3774
  *                            Fst ifst2,
- *                            compose_filter=b"auto",
+ *                            compose_filter="auto",
  *                            bool connect=True):             # <<<<<<<<<<<<<<
  *   """
  *   intersect(ifst1, ifst2, compose_filter="auto", connect=True)
@@ -39597,22 +40043,22 @@ static PyObject *__pyx_pw_9pywrapfst_39intersect(PyObject *__pyx_self, PyObject
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3739, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3771, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.intersect", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3739, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3740, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3771, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3772, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_38intersect(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_compose_filter, __pyx_v_connect);
 
-  /* "pywrapfst.pyx":3739
+  /* "pywrapfst.pyx":3771
  * 
  * 
  * cpdef MutableFst intersect(Fst ifst1,             # <<<<<<<<<<<<<<
  *                            Fst ifst2,
- *                            compose_filter=b"auto",
+ *                            compose_filter="auto",
  */
 
   /* function exit code */
@@ -39629,12 +40075,15 @@ static PyObject *__pyx_pf_9pywrapfst_38intersect(CYTHON_UNUSED PyObject *__pyx_s
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   struct __pyx_opt_args_9pywrapfst_intersect __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("intersect", 0);
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 2;
   __pyx_t_2.compose_filter = __pyx_v_compose_filter;
   __pyx_t_2.connect = __pyx_v_connect;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_intersect(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3739, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_intersect(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3771, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -39651,7 +40100,7 @@ static PyObject *__pyx_pf_9pywrapfst_38intersect(CYTHON_UNUSED PyObject *__pyx_s
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3774
+/* "pywrapfst.pyx":3806
  * 
  * 
  * cpdef bool isomorphic(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -39661,9 +40110,12 @@ static PyObject *__pyx_pf_9pywrapfst_38intersect(CYTHON_UNUSED PyObject *__pyx_s
 
 static PyObject *__pyx_pw_9pywrapfst_41isomorphic(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static bool __pyx_f_9pywrapfst_isomorphic(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_isomorphic *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__38;
+  float __pyx_v_delta = __pyx_k__40;
   bool __pyx_r;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("isomorphic", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -39671,7 +40123,7 @@ static bool __pyx_f_9pywrapfst_isomorphic(struct __pyx_obj_9pywrapfst_Fst *__pyx
     }
   }
 
-  /* "pywrapfst.pyx":3795
+  /* "pywrapfst.pyx":3827
  *     True if the two transducers satisfy the above condition, else False.
  *   """
  *   return fst.Isomorphic(deref(ifst1._fst), deref(ifst2._fst), delta)             # <<<<<<<<<<<<<<
@@ -39680,16 +40132,16 @@ static bool __pyx_f_9pywrapfst_isomorphic(struct __pyx_obj_9pywrapfst_Fst *__pyx
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3795, __pyx_L1_error)
+    __PYX_ERR(0, 3827, __pyx_L1_error)
   }
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3795, __pyx_L1_error)
+    __PYX_ERR(0, 3827, __pyx_L1_error)
   }
   __pyx_r = fst::script::Isomorphic((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_delta);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3774
+  /* "pywrapfst.pyx":3806
  * 
  * 
  * cpdef bool isomorphic(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
@@ -39713,6 +40165,9 @@ static PyObject *__pyx_pw_9pywrapfst_41isomorphic(PyObject *__pyx_self, PyObject
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1 = 0;
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2 = 0;
   float __pyx_v_delta;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("isomorphic (wrapper)", 0);
@@ -39741,7 +40196,7 @@ static PyObject *__pyx_pw_9pywrapfst_41isomorphic(PyObject *__pyx_self, PyObject
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, 1); __PYX_ERR(0, 3774, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, 1); __PYX_ERR(0, 3806, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -39751,7 +40206,7 @@ static PyObject *__pyx_pw_9pywrapfst_41isomorphic(PyObject *__pyx_self, PyObject
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "isomorphic") < 0)) __PYX_ERR(0, 3774, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "isomorphic") < 0)) __PYX_ERR(0, 3806, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -39766,21 +40221,21 @@ static PyObject *__pyx_pw_9pywrapfst_41isomorphic(PyObject *__pyx_self, PyObject
     __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst_Fst *)values[1]);
     if (values[2]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3774, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3806, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__38;
+      __pyx_v_delta = __pyx_k__40;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3774, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("isomorphic", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3806, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.isomorphic", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3774, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3774, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3806, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3806, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_40isomorphic(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_delta);
 
   /* function exit code */
@@ -39798,12 +40253,15 @@ static PyObject *__pyx_pf_9pywrapfst_40isomorphic(CYTHON_UNUSED PyObject *__pyx_
   bool __pyx_t_1;
   struct __pyx_opt_args_9pywrapfst_isomorphic __pyx_t_2;
   PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("isomorphic", 0);
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.delta = __pyx_v_delta;
   __pyx_t_1 = __pyx_f_9pywrapfst_isomorphic(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2); 
-  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3774, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3806, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -39820,7 +40278,7 @@ static PyObject *__pyx_pf_9pywrapfst_40isomorphic(CYTHON_UNUSED PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3798
+/* "pywrapfst.pyx":3830
  * 
  * 
  * cpdef MutableFst prune(Fst ifst,             # <<<<<<<<<<<<<<
@@ -39830,10 +40288,10 @@ static PyObject *__pyx_pf_9pywrapfst_40isomorphic(CYTHON_UNUSED PyObject *__pyx_
 
 static PyObject *__pyx_pw_9pywrapfst_43prune(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_prune(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_prune *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__39;
-  int64 __pyx_v_nstate = __pyx_k__40;
+  float __pyx_v_delta = __pyx_k__41;
+  int64 __pyx_v_nstate = __pyx_k__42;
 
-  /* "pywrapfst.pyx":3801
+  /* "pywrapfst.pyx":3833
  *                        float delta=fst.kDelta,
  *                        int64 nstate=fst.kNoStateId,
  *                        weight=None):             # <<<<<<<<<<<<<<
@@ -39841,12 +40299,15 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_prune(struct _
  *   prune(ifst, delta=0.0009765625, nstate=NO_STATE_ID, weight=None)
  */
   PyObject *__pyx_v_weight = ((PyObject *)Py_None);
-  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v_tfst;
-  fst::script::WeightClass __pyx_v_wc;
+  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v__tfst;
+  fst::script::WeightClass __pyx_v__weight;
   struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   fst::script::WeightClass __pyx_t_1;
   PyObject *__pyx_t_2 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("prune", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -39860,61 +40321,69 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_prune(struct _
     }
   }
 
-  /* "pywrapfst.pyx":3823
+  /* "pywrapfst.pyx":3855
  *   """
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
- *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
- *   fst.Prune(deref(ifst._fst), tfst.get(), wc, nstate, delta)
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
+ *   cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(ifst.weight_type(),
+ *                                                           weight)
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3823, __pyx_L1_error)
+    __PYX_ERR(0, 3855, __pyx_L1_error)
   }
-  __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
+  __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":3824
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
- *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)             # <<<<<<<<<<<<<<
- *   fst.Prune(deref(ifst._fst), tfst.get(), wc, nstate, delta)
- *   return _init_MutableFst(tfst.release())
+  /* "pywrapfst.pyx":3856
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+ *   cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(ifst.weight_type(),             # <<<<<<<<<<<<<<
+ *                                                           weight)
+ *   fst.Prune(deref(ifst._fst), _tfst.get(), _weight, nstate, delta)
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 3824, __pyx_L1_error)
+    __PYX_ERR(0, 3856, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_Zero(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3824, __pyx_L1_error)
-  __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":3825
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
- *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
- *   fst.Prune(deref(ifst._fst), tfst.get(), wc, nstate, delta)             # <<<<<<<<<<<<<<
- *   return _init_MutableFst(tfst.release())
+  /* "pywrapfst.pyx":3857
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+ *   cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(ifst.weight_type(),
+ *                                                           weight)             # <<<<<<<<<<<<<<
+ *   fst.Prune(deref(ifst._fst), _tfst.get(), _weight, nstate, delta)
+ *   return _init_MutableFst(_tfst.release())
+ */
+  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_Zero(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3856, __pyx_L1_error)
+  __pyx_v__weight = __pyx_t_1;
+
+  /* "pywrapfst.pyx":3858
+ *   cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(ifst.weight_type(),
+ *                                                           weight)
+ *   fst.Prune(deref(ifst._fst), _tfst.get(), _weight, nstate, delta)             # <<<<<<<<<<<<<<
+ *   return _init_MutableFst(_tfst.release())
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3825, __pyx_L1_error)
+    __PYX_ERR(0, 3858, __pyx_L1_error)
   }
-  fst::script::Prune((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), __pyx_v_wc, __pyx_v_nstate, __pyx_v_delta);
+  fst::script::Prune((*__pyx_v_ifst->_fst), __pyx_v__tfst.get(), __pyx_v__weight, __pyx_v_nstate, __pyx_v_delta);
 
-  /* "pywrapfst.pyx":3826
- *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
- *   fst.Prune(deref(ifst._fst), tfst.get(), wc, nstate, delta)
- *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3859
+ *                                                           weight)
+ *   fst.Prune(deref(ifst._fst), _tfst.get(), _weight, nstate, delta)
+ *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3826, __pyx_L1_error)
+  __pyx_t_2 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3859, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_2);
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3798
+  /* "pywrapfst.pyx":3830
  * 
  * 
  * cpdef MutableFst prune(Fst ifst,             # <<<<<<<<<<<<<<
@@ -39941,6 +40410,9 @@ static PyObject *__pyx_pw_9pywrapfst_43prune(PyObject *__pyx_self, PyObject *__p
   float __pyx_v_delta;
   int64 __pyx_v_nstate;
   PyObject *__pyx_v_weight = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("prune (wrapper)", 0);
@@ -39948,7 +40420,7 @@ static PyObject *__pyx_pw_9pywrapfst_43prune(PyObject *__pyx_self, PyObject *__p
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ifst,&__pyx_n_s_delta,&__pyx_n_s_nstate,&__pyx_n_s_weight,0};
     PyObject* values[4] = {0,0,0,0};
 
-    /* "pywrapfst.pyx":3801
+    /* "pywrapfst.pyx":3833
  *                        float delta=fst.kDelta,
  *                        int64 nstate=fst.kNoStateId,
  *                        weight=None):             # <<<<<<<<<<<<<<
@@ -39996,7 +40468,7 @@ static PyObject *__pyx_pw_9pywrapfst_43prune(PyObject *__pyx_self, PyObject *__p
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "prune") < 0)) __PYX_ERR(0, 3798, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "prune") < 0)) __PYX_ERR(0, 3830, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -40013,29 +40485,29 @@ static PyObject *__pyx_pw_9pywrapfst_43prune(PyObject *__pyx_self, PyObject *__p
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3799, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3831, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__39;
+      __pyx_v_delta = __pyx_k__41;
     }
     if (values[2]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[2]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3800, __pyx_L3_error)
+      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[2]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3832, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__40;
+      __pyx_v_nstate = __pyx_k__42;
     }
     __pyx_v_weight = values[3];
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("prune", 0, 1, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3798, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("prune", 0, 1, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3830, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.prune", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3798, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3830, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_42prune(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nstate, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":3798
+  /* "pywrapfst.pyx":3830
  * 
  * 
  * cpdef MutableFst prune(Fst ifst,             # <<<<<<<<<<<<<<
@@ -40057,13 +40529,16 @@ static PyObject *__pyx_pf_9pywrapfst_42prune(CYTHON_UNUSED PyObject *__pyx_self,
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   struct __pyx_opt_args_9pywrapfst_prune __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("prune", 0);
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 3;
   __pyx_t_2.delta = __pyx_v_delta;
   __pyx_t_2.nstate = __pyx_v_nstate;
   __pyx_t_2.weight = __pyx_v_weight;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_prune(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3798, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_prune(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3830, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -40080,7 +40555,7 @@ static PyObject *__pyx_pf_9pywrapfst_42prune(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3829
+/* "pywrapfst.pyx":3862
  * 
  * 
  * cpdef MutableFst push(Fst ifst,             # <<<<<<<<<<<<<<
@@ -40090,9 +40565,9 @@ static PyObject *__pyx_pf_9pywrapfst_42prune(CYTHON_UNUSED PyObject *__pyx_self,
 
 static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_push(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_push *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__41;
+  float __pyx_v_delta = __pyx_k__43;
 
-  /* "pywrapfst.pyx":3831
+  /* "pywrapfst.pyx":3864
  * cpdef MutableFst push(Fst ifst,
  *                       float delta=fst.kDelta,
  *                       bool push_weights=False,             # <<<<<<<<<<<<<<
@@ -40101,7 +40576,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_push(struct __
  */
   bool __pyx_v_push_weights = ((bool)0);
 
-  /* "pywrapfst.pyx":3832
+  /* "pywrapfst.pyx":3865
  *                       float delta=fst.kDelta,
  *                       bool push_weights=False,
  *                       bool push_labels=False,             # <<<<<<<<<<<<<<
@@ -40110,7 +40585,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_push(struct __
  */
   bool __pyx_v_push_labels = ((bool)0);
 
-  /* "pywrapfst.pyx":3833
+  /* "pywrapfst.pyx":3866
  *                       bool push_weights=False,
  *                       bool push_labels=False,
  *                       bool remove_common_affix=False,             # <<<<<<<<<<<<<<
@@ -40119,7 +40594,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_push(struct __
  */
   bool __pyx_v_remove_common_affix = ((bool)0);
 
-  /* "pywrapfst.pyx":3834
+  /* "pywrapfst.pyx":3867
  *                       bool push_labels=False,
  *                       bool remove_common_affix=False,
  *                       bool remove_total_weight=False,             # <<<<<<<<<<<<<<
@@ -40128,7 +40603,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_push(struct __
  */
   bool __pyx_v_remove_total_weight = ((bool)0);
 
-  /* "pywrapfst.pyx":3835
+  /* "pywrapfst.pyx":3868
  *                       bool remove_common_affix=False,
  *                       bool remove_total_weight=False,
  *                       bool to_final=False):             # <<<<<<<<<<<<<<
@@ -40136,11 +40611,14 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_push(struct __
  *   push(ifst, delta=0.0009765625, push_weights=False, push_labels=False,
  */
   bool __pyx_v_to_final = ((bool)0);
-  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v_tfst;
+  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v__tfst;
   uint8 __pyx_v_flags;
   struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("push", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -40163,64 +40641,64 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_push(struct __
     }
   }
 
-  /* "pywrapfst.pyx":3872
+  /* "pywrapfst.pyx":3905
  *   """
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
  *   cdef uint8 flags = fst.GetPushFlags(push_weights,
  *                                       push_labels,
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3872, __pyx_L1_error)
+    __PYX_ERR(0, 3905, __pyx_L1_error)
   }
-  __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
+  __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":3873
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+  /* "pywrapfst.pyx":3906
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   cdef uint8 flags = fst.GetPushFlags(push_weights,             # <<<<<<<<<<<<<<
  *                                       push_labels,
  *                                       remove_common_affix,
  */
   __pyx_v_flags = fst::script::GetPushFlags(__pyx_v_push_weights, __pyx_v_push_labels, __pyx_v_remove_common_affix, __pyx_v_remove_total_weight);
 
-  /* "pywrapfst.pyx":3877
+  /* "pywrapfst.pyx":3910
  *                                       remove_common_affix,
  *                                       remove_total_weight)
  *   fst.Push(deref(ifst._fst),             # <<<<<<<<<<<<<<
- *            tfst.get(),
+ *            _tfst.get(),
  *            flags,
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3877, __pyx_L1_error)
+    __PYX_ERR(0, 3910, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3881
+  /* "pywrapfst.pyx":3914
  *            flags,
  *            fst.GetReweightType(to_final),
  *            delta)             # <<<<<<<<<<<<<<
- *   return _init_MutableFst(tfst.release())
+ *   return _init_MutableFst(_tfst.release())
  * 
  */
-  fst::script::Push((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), __pyx_v_flags, fst::script::GetReweightType(__pyx_v_to_final), __pyx_v_delta);
+  fst::script::Push((*__pyx_v_ifst->_fst), __pyx_v__tfst.get(), __pyx_v_flags, fst::script::GetReweightType(__pyx_v_to_final), __pyx_v_delta);
 
-  /* "pywrapfst.pyx":3882
+  /* "pywrapfst.pyx":3915
  *            fst.GetReweightType(to_final),
  *            delta)
- *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
+ *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3882, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3915, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3829
+  /* "pywrapfst.pyx":3862
  * 
  * 
  * cpdef MutableFst push(Fst ifst,             # <<<<<<<<<<<<<<
@@ -40250,6 +40728,9 @@ static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__py
   bool __pyx_v_remove_common_affix;
   bool __pyx_v_remove_total_weight;
   bool __pyx_v_to_final;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("push (wrapper)", 0);
@@ -40320,7 +40801,7 @@ static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__py
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "push") < 0)) __PYX_ERR(0, 3829, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "push") < 0)) __PYX_ERR(0, 3862, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -40343,15 +40824,15 @@ static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__py
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3830, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3863, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__41;
+      __pyx_v_delta = __pyx_k__43;
     }
     if (values[2]) {
-      __pyx_v_push_weights = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_push_weights == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3831, __pyx_L3_error)
+      __pyx_v_push_weights = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_push_weights == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3864, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3831
+      /* "pywrapfst.pyx":3864
  * cpdef MutableFst push(Fst ifst,
  *                       float delta=fst.kDelta,
  *                       bool push_weights=False,             # <<<<<<<<<<<<<<
@@ -40361,10 +40842,10 @@ static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__py
       __pyx_v_push_weights = ((bool)0);
     }
     if (values[3]) {
-      __pyx_v_push_labels = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_push_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3832, __pyx_L3_error)
+      __pyx_v_push_labels = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_push_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3865, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3832
+      /* "pywrapfst.pyx":3865
  *                       float delta=fst.kDelta,
  *                       bool push_weights=False,
  *                       bool push_labels=False,             # <<<<<<<<<<<<<<
@@ -40374,10 +40855,10 @@ static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__py
       __pyx_v_push_labels = ((bool)0);
     }
     if (values[4]) {
-      __pyx_v_remove_common_affix = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_remove_common_affix == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3833, __pyx_L3_error)
+      __pyx_v_remove_common_affix = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_remove_common_affix == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3866, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3833
+      /* "pywrapfst.pyx":3866
  *                       bool push_weights=False,
  *                       bool push_labels=False,
  *                       bool remove_common_affix=False,             # <<<<<<<<<<<<<<
@@ -40387,10 +40868,10 @@ static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__py
       __pyx_v_remove_common_affix = ((bool)0);
     }
     if (values[5]) {
-      __pyx_v_remove_total_weight = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_remove_total_weight == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3834, __pyx_L3_error)
+      __pyx_v_remove_total_weight = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_remove_total_weight == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3867, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3834
+      /* "pywrapfst.pyx":3867
  *                       bool push_labels=False,
  *                       bool remove_common_affix=False,
  *                       bool remove_total_weight=False,             # <<<<<<<<<<<<<<
@@ -40400,10 +40881,10 @@ static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__py
       __pyx_v_remove_total_weight = ((bool)0);
     }
     if (values[6]) {
-      __pyx_v_to_final = __Pyx_PyObject_IsTrue(values[6]); if (unlikely((__pyx_v_to_final == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3835, __pyx_L3_error)
+      __pyx_v_to_final = __Pyx_PyObject_IsTrue(values[6]); if (unlikely((__pyx_v_to_final == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3868, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3835
+      /* "pywrapfst.pyx":3868
  *                       bool remove_common_affix=False,
  *                       bool remove_total_weight=False,
  *                       bool to_final=False):             # <<<<<<<<<<<<<<
@@ -40415,16 +40896,16 @@ static PyObject *__pyx_pw_9pywrapfst_45push(PyObject *__pyx_self, PyObject *__py
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("push", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3829, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("push", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3862, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.push", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3829, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3862, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_44push(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_push_weights, __pyx_v_push_labels, __pyx_v_remove_common_affix, __pyx_v_remove_total_weight, __pyx_v_to_final);
 
-  /* "pywrapfst.pyx":3829
+  /* "pywrapfst.pyx":3862
  * 
  * 
  * cpdef MutableFst push(Fst ifst,             # <<<<<<<<<<<<<<
@@ -40446,6 +40927,9 @@ static PyObject *__pyx_pf_9pywrapfst_44push(CYTHON_UNUSED PyObject *__pyx_self,
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   struct __pyx_opt_args_9pywrapfst_push __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("push", 0);
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 6;
@@ -40455,7 +40939,7 @@ static PyObject *__pyx_pf_9pywrapfst_44push(CYTHON_UNUSED PyObject *__pyx_self,
   __pyx_t_2.remove_common_affix = __pyx_v_remove_common_affix;
   __pyx_t_2.remove_total_weight = __pyx_v_remove_total_weight;
   __pyx_t_2.to_final = __pyx_v_to_final;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_push(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3829, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_push(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3862, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -40472,7 +40956,7 @@ static PyObject *__pyx_pf_9pywrapfst_44push(CYTHON_UNUSED PyObject *__pyx_self,
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3885
+/* "pywrapfst.pyx":3918
  * 
  * 
  * cpdef bool randequivalent(Fst ifst1,             # <<<<<<<<<<<<<<
@@ -40483,17 +40967,20 @@ static PyObject *__pyx_pf_9pywrapfst_44push(CYTHON_UNUSED PyObject *__pyx_self,
 static PyObject *__pyx_pw_9pywrapfst_47randequivalent(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_randequivalent *__pyx_optional_args) {
   int32 __pyx_v_npath = ((int32)1);
-  float __pyx_v_delta = __pyx_k__42;
-  time_t __pyx_v_seed = ((time_t)0);
-  PyObject *__pyx_v_select = ((PyObject *)__pyx_n_b_uniform);
-  int32 __pyx_v_max_length = __pyx_k__43;
-  enum fst::script::RandArcSelection __pyx_v_ras;
-  std::unique_ptr<fst::RandGenOptions<enum fst::script::RandArcSelection> >  __pyx_v_opts;
+  float __pyx_v_delta = __pyx_k__44;
+  PyObject *__pyx_v_select = ((PyObject *)__pyx_n_u_uniform);
+  int32 __pyx_v_max_length = __pyx_k__45;
+  uint64 __pyx_v_seed = ((uint64)0);
+  enum fst::script::RandArcSelection __pyx_v__select;
+  std::unique_ptr<fst::RandGenOptions<enum fst::script::RandArcSelection> >  __pyx_v__opts;
   bool __pyx_r;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
   enum fst::script::RandArcSelection __pyx_t_2;
   int __pyx_t_3;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("randequivalent", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -40501,11 +40988,11 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst_Fst *_
       if (__pyx_optional_args->__pyx_n > 1) {
         __pyx_v_delta = __pyx_optional_args->delta;
         if (__pyx_optional_args->__pyx_n > 2) {
-          __pyx_v_seed = __pyx_optional_args->seed;
+          __pyx_v_select = __pyx_optional_args->select;
           if (__pyx_optional_args->__pyx_n > 3) {
-            __pyx_v_select = __pyx_optional_args->select;
+            __pyx_v_max_length = __pyx_optional_args->max_length;
             if (__pyx_optional_args->__pyx_n > 4) {
-              __pyx_v_max_length = __pyx_optional_args->max_length;
+              __pyx_v_seed = __pyx_optional_args->seed;
             }
           }
         }
@@ -40513,89 +41000,89 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst_Fst *_
     }
   }
 
-  /* "pywrapfst.pyx":3918
+  /* "pywrapfst.pyx":3951
  *     True if the two transducers satisfy the above condition, else False.
  *   """
- *   cdef fst.RandArcSelection ras = _get_rand_arc_selection(tostring(select))             # <<<<<<<<<<<<<<
- *   cdef unique_ptr[fst.RandGenOptions[fst.RandArcSelection]] opts
+ *   cdef fst.RandArcSelection _select = _get_rand_arc_selection(tostring(select))             # <<<<<<<<<<<<<<
+ *   cdef unique_ptr[fst.RandGenOptions[fst.RandArcSelection]] _opts
  *   # The three trailing options will be ignored by RandEquivalent.
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_select); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3918, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3918, __pyx_L1_error)
-  __pyx_v_ras = __pyx_t_2;
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_select); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3951, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3951, __pyx_L1_error)
+  __pyx_v__select = __pyx_t_2;
 
-  /* "pywrapfst.pyx":3921
- *   cdef unique_ptr[fst.RandGenOptions[fst.RandArcSelection]] opts
+  /* "pywrapfst.pyx":3954
+ *   cdef unique_ptr[fst.RandGenOptions[fst.RandArcSelection]] _opts
  *   # The three trailing options will be ignored by RandEquivalent.
- *   opts.reset(new fst.RandGenOptions[fst.RandArcSelection](ras,             # <<<<<<<<<<<<<<
- *                                                           max_length,
- *                                                           1,
+ *   _opts.reset(             # <<<<<<<<<<<<<<
+ *        new fst.RandGenOptions[fst.RandArcSelection](_select,
+ *                                                     max_length,
  */
-  __pyx_v_opts.reset(new fst::RandGenOptions<enum fst::script::RandArcSelection> (__pyx_v_ras, __pyx_v_max_length, 1, 0, 0));
+  __pyx_v__opts.reset(new fst::RandGenOptions<enum fst::script::RandArcSelection> (__pyx_v__select, __pyx_v_max_length, 1, 0, 0));
 
-  /* "pywrapfst.pyx":3926
- *                                                           False,
- *                                                           False))
+  /* "pywrapfst.pyx":3960
+ *                                                     False,
+ *                                                     False))
  *   if seed == 0:             # <<<<<<<<<<<<<<
- *     seed = time(NULL) + getpid()
+ *     seed = time(NULL)
  *   return fst.RandEquivalent(deref(ifst1._fst),
  */
   __pyx_t_3 = ((__pyx_v_seed == 0) != 0);
   if (__pyx_t_3) {
 
-    /* "pywrapfst.pyx":3927
- *                                                           False))
+    /* "pywrapfst.pyx":3961
+ *                                                     False))
  *   if seed == 0:
- *     seed = time(NULL) + getpid()             # <<<<<<<<<<<<<<
+ *     seed = time(NULL)             # <<<<<<<<<<<<<<
  *   return fst.RandEquivalent(deref(ifst1._fst),
  *                             deref(ifst2._fst),
  */
-    __pyx_v_seed = (time(NULL) + getpid());
+    __pyx_v_seed = time(NULL);
 
-    /* "pywrapfst.pyx":3926
- *                                                           False,
- *                                                           False))
+    /* "pywrapfst.pyx":3960
+ *                                                     False,
+ *                                                     False))
  *   if seed == 0:             # <<<<<<<<<<<<<<
- *     seed = time(NULL) + getpid()
+ *     seed = time(NULL)
  *   return fst.RandEquivalent(deref(ifst1._fst),
  */
   }
 
-  /* "pywrapfst.pyx":3928
+  /* "pywrapfst.pyx":3962
  *   if seed == 0:
- *     seed = time(NULL) + getpid()
+ *     seed = time(NULL)
  *   return fst.RandEquivalent(deref(ifst1._fst),             # <<<<<<<<<<<<<<
  *                             deref(ifst2._fst),
  *                             npath,
  */
   if (unlikely(((PyObject *)__pyx_v_ifst1) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3928, __pyx_L1_error)
+    __PYX_ERR(0, 3962, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3929
- *     seed = time(NULL) + getpid()
+  /* "pywrapfst.pyx":3963
+ *     seed = time(NULL)
  *   return fst.RandEquivalent(deref(ifst1._fst),
  *                             deref(ifst2._fst),             # <<<<<<<<<<<<<<
  *                             npath,
- *                             delta,
+ *                             deref(_opts),
  */
   if (unlikely(((PyObject *)__pyx_v_ifst2) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3929, __pyx_L1_error)
+    __PYX_ERR(0, 3963, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":3928
+  /* "pywrapfst.pyx":3962
  *   if seed == 0:
- *     seed = time(NULL) + getpid()
+ *     seed = time(NULL)
  *   return fst.RandEquivalent(deref(ifst1._fst),             # <<<<<<<<<<<<<<
  *                             deref(ifst2._fst),
  *                             npath,
  */
-  __pyx_r = fst::script::RandEquivalent((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_npath, __pyx_v_delta, __pyx_v_seed, (*__pyx_v_opts));
+  __pyx_r = fst::script::RandEquivalent((*__pyx_v_ifst1->_fst), (*__pyx_v_ifst2->_fst), __pyx_v_npath, (*__pyx_v__opts), __pyx_v_delta, __pyx_v_seed);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3885
+  /* "pywrapfst.pyx":3918
  * 
  * 
  * cpdef bool randequivalent(Fst ifst1,             # <<<<<<<<<<<<<<
@@ -40614,22 +41101,25 @@ static bool __pyx_f_9pywrapfst_randequivalent(struct __pyx_obj_9pywrapfst_Fst *_
 
 /* Python wrapper */
 static PyObject *__pyx_pw_9pywrapfst_47randequivalent(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_9pywrapfst_46randequivalent[] = "\n  randequivalent(ifst1, ifst2, npath=1, delta=0.0009765625, seed=0,\n                 select=\"uniform\", max_length=2147483647)\n\n  Are two acceptors stochastically equivalent?\n\n  This operation tests whether two FSTs are equivalent by randomly generating\n  paths alternatively in each of the two FSTs. For each randomly generated path,\n  the algorithm computes for each of the two FSTs the sum of the weights of all\n  the successful paths sharing the same input and output labels as the randomly\n  generated path and checks that these two values are within `delta`.\n\n  Args:\n    ifst1: The first input FST.\n    ifst2: The second input FST.\n    npath: The number of random paths to generate.\n    delta: Comparison/quantization delta.\n    seed: An optional seed value for random path generation; if zero, the\n        current time and process ID is used.\n    select: A string matching a known random arc selection type; one of:\n        \"uniform\", \"log_prob\", \"fast_log_prob\".\n    max_length: The maximum length of each random path.\n\n  Returns:\n    True if the two transducers satisfy the above condition, else False.\n  ";
+static char __pyx_doc_9pywrapfst_46randequivalent[] = "\n  randequivalent(ifst1, ifst2, npath=1, delta=0.0009765625, select=\"uniform\",\n                 max_length=2147483647, seed=0)\n\n  Are two acceptors stochastically equivalent?\n\n  This operation tests whether two FSTs are equivalent by randomly generating\n  paths alternatively in each of the two FSTs. For each randomly generated path,\n  the algorithm computes for each of the two FSTs the sum of the weights of all\n  the successful paths sharing the same input and output labels as the randomly\n  generated path and checks that these two values are within `delta`.\n\n  Args:\n    ifst1: The first input FST.\n    ifst2: The second input FST.\n    npath: The number of random paths to generate.\n    delta: Comparison/quantization delta.\n    seed: An optional seed value for random path generation; if zero, the\n        current time and process ID is used.\n    select: A string matching a known random arc selection type; one of:\n        \"uniform\", \"log_prob\", \"fast_log_prob\".\n    max_length: The maximum length of each random path.\n\n  Returns:\n    True if the two transducers satisfy the above condition, else False.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_47randequivalent(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1 = 0;
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2 = 0;
   int32 __pyx_v_npath;
   float __pyx_v_delta;
-  time_t __pyx_v_seed;
   PyObject *__pyx_v_select = 0;
   int32 __pyx_v_max_length;
+  uint64 __pyx_v_seed;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("randequivalent (wrapper)", 0);
   {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ifst1,&__pyx_n_s_ifst2,&__pyx_n_s_npath,&__pyx_n_s_delta,&__pyx_n_s_seed,&__pyx_n_s_select,&__pyx_n_s_max_length,0};
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ifst1,&__pyx_n_s_ifst2,&__pyx_n_s_npath,&__pyx_n_s_delta,&__pyx_n_s_select,&__pyx_n_s_max_length,&__pyx_n_s_seed,0};
     PyObject* values[7] = {0,0,0,0,0,0,0};
-    values[5] = ((PyObject *)__pyx_n_b_uniform);
+    values[4] = ((PyObject *)__pyx_n_u_uniform);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -40660,7 +41150,7 @@ static PyObject *__pyx_pw_9pywrapfst_47randequivalent(PyObject *__pyx_self, PyOb
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst2)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, 1); __PYX_ERR(0, 3885, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, 1); __PYX_ERR(0, 3918, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
@@ -40677,24 +41167,24 @@ static PyObject *__pyx_pw_9pywrapfst_47randequivalent(PyObject *__pyx_self, PyOb
         CYTHON_FALLTHROUGH;
         case  4:
         if (kw_args > 0) {
-          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_seed);
+          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_select);
           if (value) { values[4] = value; kw_args--; }
         }
         CYTHON_FALLTHROUGH;
         case  5:
         if (kw_args > 0) {
-          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_select);
+          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_max_length);
           if (value) { values[5] = value; kw_args--; }
         }
         CYTHON_FALLTHROUGH;
         case  6:
         if (kw_args > 0) {
-          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_max_length);
+          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_seed);
           if (value) { values[6] = value; kw_args--; }
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "randequivalent") < 0)) __PYX_ERR(0, 3885, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "randequivalent") < 0)) __PYX_ERR(0, 3918, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -40717,38 +41207,38 @@ static PyObject *__pyx_pw_9pywrapfst_47randequivalent(PyObject *__pyx_self, PyOb
     __pyx_v_ifst1 = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     __pyx_v_ifst2 = ((struct __pyx_obj_9pywrapfst_Fst *)values[1]);
     if (values[2]) {
-      __pyx_v_npath = __Pyx_PyInt_As_int32_t(values[2]); if (unlikely((__pyx_v_npath == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3887, __pyx_L3_error)
+      __pyx_v_npath = __Pyx_PyInt_As_int32_t(values[2]); if (unlikely((__pyx_v_npath == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3920, __pyx_L3_error)
     } else {
       __pyx_v_npath = ((int32)1);
     }
     if (values[3]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[3]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3888, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[3]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 3921, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__42;
+      __pyx_v_delta = __pyx_k__44;
     }
-    if (values[4]) {
-      __pyx_v_seed = __Pyx_PyInt_As_time_t(values[4]); if (unlikely((__pyx_v_seed == ((time_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3889, __pyx_L3_error)
+    __pyx_v_select = values[4];
+    if (values[5]) {
+      __pyx_v_max_length = __Pyx_PyInt_As_int32_t(values[5]); if (unlikely((__pyx_v_max_length == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3923, __pyx_L3_error)
     } else {
-      __pyx_v_seed = ((time_t)0);
+      __pyx_v_max_length = __pyx_k__45;
     }
-    __pyx_v_select = values[5];
     if (values[6]) {
-      __pyx_v_max_length = __Pyx_PyInt_As_int32_t(values[6]); if (unlikely((__pyx_v_max_length == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3891, __pyx_L3_error)
+      __pyx_v_seed = __Pyx_PyInt_As_uint64_t(values[6]); if (unlikely((__pyx_v_seed == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3924, __pyx_L3_error)
     } else {
-      __pyx_v_max_length = __pyx_k__43;
+      __pyx_v_seed = ((uint64)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3885, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("randequivalent", 0, 2, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3918, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.randequivalent", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3885, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3886, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_46randequivalent(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_npath, __pyx_v_delta, __pyx_v_seed, __pyx_v_select, __pyx_v_max_length);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst1), __pyx_ptype_9pywrapfst_Fst, 1, "ifst1", 0))) __PYX_ERR(0, 3918, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst2), __pyx_ptype_9pywrapfst_Fst, 1, "ifst2", 0))) __PYX_ERR(0, 3919, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_46randequivalent(__pyx_self, __pyx_v_ifst1, __pyx_v_ifst2, __pyx_v_npath, __pyx_v_delta, __pyx_v_select, __pyx_v_max_length, __pyx_v_seed);
 
   /* function exit code */
   goto __pyx_L0;
@@ -40759,22 +41249,25 @@ static PyObject *__pyx_pw_9pywrapfst_47randequivalent(PyObject *__pyx_self, PyOb
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_46randequivalent(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, int32 __pyx_v_npath, float __pyx_v_delta, time_t __pyx_v_seed, PyObject *__pyx_v_select, int32 __pyx_v_max_length) {
+static PyObject *__pyx_pf_9pywrapfst_46randequivalent(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst1, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst2, int32 __pyx_v_npath, float __pyx_v_delta, PyObject *__pyx_v_select, int32 __pyx_v_max_length, uint64 __pyx_v_seed) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   bool __pyx_t_1;
   struct __pyx_opt_args_9pywrapfst_randequivalent __pyx_t_2;
   PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("randequivalent", 0);
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 5;
   __pyx_t_2.npath = __pyx_v_npath;
   __pyx_t_2.delta = __pyx_v_delta;
-  __pyx_t_2.seed = __pyx_v_seed;
   __pyx_t_2.select = __pyx_v_select;
   __pyx_t_2.max_length = __pyx_v_max_length;
-  __pyx_t_1 = __pyx_f_9pywrapfst_randequivalent(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2); if (unlikely(__pyx_t_1 == ((bool)-1) && PyErr_Occurred())) __PYX_ERR(0, 3885, __pyx_L1_error)
-  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3885, __pyx_L1_error)
+  __pyx_t_2.seed = __pyx_v_seed;
+  __pyx_t_1 = __pyx_f_9pywrapfst_randequivalent(__pyx_v_ifst1, __pyx_v_ifst2, 0, &__pyx_t_2); if (unlikely(__pyx_t_1 == ((bool)-1) && PyErr_Occurred())) __PYX_ERR(0, 3918, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3918, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_r = __pyx_t_3;
   __pyx_t_3 = 0;
@@ -40791,61 +41284,64 @@ static PyObject *__pyx_pf_9pywrapfst_46randequivalent(CYTHON_UNUSED PyObject *__
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3936
+/* "pywrapfst.pyx":3970
  * 
  * 
  * cpdef MutableFst randgen(Fst ifst,             # <<<<<<<<<<<<<<
  *                          int32 npath=1,
- *                          time_t seed=0,
+ *                          select="uniform",
  */
 
 static PyObject *__pyx_pw_9pywrapfst_49randgen(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_randgen(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_randgen *__pyx_optional_args) {
   int32 __pyx_v_npath = ((int32)1);
-  time_t __pyx_v_seed = ((time_t)0);
-  PyObject *__pyx_v_select = ((PyObject *)__pyx_n_b_uniform);
-  int32 __pyx_v_max_length = __pyx_k__44;
+  PyObject *__pyx_v_select = ((PyObject *)__pyx_n_u_uniform);
+  int32 __pyx_v_max_length = __pyx_k__46;
 
-  /* "pywrapfst.pyx":3941
- *                          select=b"uniform",
+  /* "pywrapfst.pyx":3974
+ *                          select="uniform",
  *                          int32 max_length=INT32_MAX,
  *                          bool weighted=False,             # <<<<<<<<<<<<<<
- *                          bool remove_total_weight=False):
- *   """
+ *                          bool remove_total_weight=False,
+ *                          uint64 seed=0):
  */
   bool __pyx_v_weighted = ((bool)0);
 
-  /* "pywrapfst.pyx":3942
+  /* "pywrapfst.pyx":3975
  *                          int32 max_length=INT32_MAX,
  *                          bool weighted=False,
- *                          bool remove_total_weight=False):             # <<<<<<<<<<<<<<
+ *                          bool remove_total_weight=False,             # <<<<<<<<<<<<<<
+ *                          uint64 seed=0):
  *   """
- *   randgen(ifst, npath=1, seed=0, select="uniform", max_length=2147483647,
  */
   bool __pyx_v_remove_total_weight = ((bool)0);
-  enum fst::script::RandArcSelection __pyx_v_ras;
-  std::unique_ptr<fst::RandGenOptions<enum fst::script::RandArcSelection> >  __pyx_v_opts;
-  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v_tfst;
+  uint64 __pyx_v_seed = ((uint64)0);
+  enum fst::script::RandArcSelection __pyx_v__select;
+  std::unique_ptr<fst::RandGenOptions<enum fst::script::RandArcSelection> >  __pyx_v__opts;
+  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v__tfst;
   struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
   enum fst::script::RandArcSelection __pyx_t_2;
   int __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("randgen", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
       __pyx_v_npath = __pyx_optional_args->npath;
       if (__pyx_optional_args->__pyx_n > 1) {
-        __pyx_v_seed = __pyx_optional_args->seed;
+        __pyx_v_select = __pyx_optional_args->select;
         if (__pyx_optional_args->__pyx_n > 2) {
-          __pyx_v_select = __pyx_optional_args->select;
+          __pyx_v_max_length = __pyx_optional_args->max_length;
           if (__pyx_optional_args->__pyx_n > 3) {
-            __pyx_v_max_length = __pyx_optional_args->max_length;
+            __pyx_v_weighted = __pyx_optional_args->weighted;
             if (__pyx_optional_args->__pyx_n > 4) {
-              __pyx_v_weighted = __pyx_optional_args->weighted;
+              __pyx_v_remove_total_weight = __pyx_optional_args->remove_total_weight;
               if (__pyx_optional_args->__pyx_n > 5) {
-                __pyx_v_remove_total_weight = __pyx_optional_args->remove_total_weight;
+                __pyx_v_seed = __pyx_optional_args->seed;
               }
             }
           }
@@ -40854,100 +41350,100 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_randgen(struct
     }
   }
 
-  /* "pywrapfst.pyx":3972
+  /* "pywrapfst.pyx":4006
  *     An FST containing one or more random paths.
  *   """
- *   cdef fst.RandArcSelection ras = _get_rand_arc_selection(tostring(select))             # <<<<<<<<<<<<<<
- *   cdef unique_ptr[fst.RandGenOptions[fst.RandArcSelection]] opts
- *   opts.reset(new fst.RandGenOptions[fst.RandArcSelection](ras,
- */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_select); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3972, __pyx_L1_error)
-  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 3972, __pyx_L1_error)
-  __pyx_v_ras = __pyx_t_2;
-
-  /* "pywrapfst.pyx":3974
- *   cdef fst.RandArcSelection ras = _get_rand_arc_selection(tostring(select))
- *   cdef unique_ptr[fst.RandGenOptions[fst.RandArcSelection]] opts
- *   opts.reset(new fst.RandGenOptions[fst.RandArcSelection](ras,             # <<<<<<<<<<<<<<
- *                                                           max_length,
- *                                                           npath,
- */
-  __pyx_v_opts.reset(new fst::RandGenOptions<enum fst::script::RandArcSelection> (__pyx_v_ras, __pyx_v_max_length, __pyx_v_npath, __pyx_v_weighted, __pyx_v_remove_total_weight));
-
-  /* "pywrapfst.pyx":3980
- *                                                           remove_total_weight))
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
+ *   cdef fst.RandArcSelection _select = _get_rand_arc_selection(tostring(select))             # <<<<<<<<<<<<<<
+ *   cdef unique_ptr[fst.RandGenOptions[fst.RandArcSelection]] _opts
+ *   _opts.reset(
+ */
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_select); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4006, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst__get_rand_arc_selection(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4006, __pyx_L1_error)
+  __pyx_v__select = __pyx_t_2;
+
+  /* "pywrapfst.pyx":4008
+ *   cdef fst.RandArcSelection _select = _get_rand_arc_selection(tostring(select))
+ *   cdef unique_ptr[fst.RandGenOptions[fst.RandArcSelection]] _opts
+ *   _opts.reset(             # <<<<<<<<<<<<<<
+ *       new fst.RandGenOptions[fst.RandArcSelection](_select,
+ *                                                    max_length,
+ */
+  __pyx_v__opts.reset(new fst::RandGenOptions<enum fst::script::RandArcSelection> (__pyx_v__select, __pyx_v_max_length, __pyx_v_npath, __pyx_v_weighted, __pyx_v_remove_total_weight));
+
+  /* "pywrapfst.pyx":4015
+ *                                                    remove_total_weight))
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
  *   if seed == 0:
- *     seed = time(NULL) + getpid()
+ *     seed = time(NULL)
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 3980, __pyx_L1_error)
+    __PYX_ERR(0, 4015, __pyx_L1_error)
   }
-  __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
+  __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":3981
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+  /* "pywrapfst.pyx":4016
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   if seed == 0:             # <<<<<<<<<<<<<<
- *     seed = time(NULL) + getpid()
- *   fst.RandGen(deref(ifst._fst), tfst.get(), seed, deref(opts))
+ *     seed = time(NULL)
+ *   fst.RandGen(deref(ifst._fst), _tfst.get(), deref(_opts), seed)
  */
   __pyx_t_3 = ((__pyx_v_seed == 0) != 0);
   if (__pyx_t_3) {
 
-    /* "pywrapfst.pyx":3982
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+    /* "pywrapfst.pyx":4017
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   if seed == 0:
- *     seed = time(NULL) + getpid()             # <<<<<<<<<<<<<<
- *   fst.RandGen(deref(ifst._fst), tfst.get(), seed, deref(opts))
- *   return _init_MutableFst(tfst.release())
+ *     seed = time(NULL)             # <<<<<<<<<<<<<<
+ *   fst.RandGen(deref(ifst._fst), _tfst.get(), deref(_opts), seed)
+ *   return _init_MutableFst(_tfst.release())
  */
-    __pyx_v_seed = (time(NULL) + getpid());
+    __pyx_v_seed = time(NULL);
 
-    /* "pywrapfst.pyx":3981
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+    /* "pywrapfst.pyx":4016
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   if seed == 0:             # <<<<<<<<<<<<<<
- *     seed = time(NULL) + getpid()
- *   fst.RandGen(deref(ifst._fst), tfst.get(), seed, deref(opts))
+ *     seed = time(NULL)
+ *   fst.RandGen(deref(ifst._fst), _tfst.get(), deref(_opts), seed)
  */
   }
 
-  /* "pywrapfst.pyx":3983
+  /* "pywrapfst.pyx":4018
  *   if seed == 0:
- *     seed = time(NULL) + getpid()
- *   fst.RandGen(deref(ifst._fst), tfst.get(), seed, deref(opts))             # <<<<<<<<<<<<<<
- *   return _init_MutableFst(tfst.release())
+ *     seed = time(NULL)
+ *   fst.RandGen(deref(ifst._fst), _tfst.get(), deref(_opts), seed)             # <<<<<<<<<<<<<<
+ *   return _init_MutableFst(_tfst.release())
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 3983, __pyx_L1_error)
+    __PYX_ERR(0, 4018, __pyx_L1_error)
   }
-  fst::script::RandGen((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), __pyx_v_seed, (*__pyx_v_opts));
+  fst::script::RandGen((*__pyx_v_ifst->_fst), __pyx_v__tfst.get(), (*__pyx_v__opts), __pyx_v_seed);
 
-  /* "pywrapfst.pyx":3984
- *     seed = time(NULL) + getpid()
- *   fst.RandGen(deref(ifst._fst), tfst.get(), seed, deref(opts))
- *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":4019
+ *     seed = time(NULL)
+ *   fst.RandGen(deref(ifst._fst), _tfst.get(), deref(_opts), seed)
+ *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 3984, __pyx_L1_error)
+  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4019, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_4);
   __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3936
+  /* "pywrapfst.pyx":3970
  * 
  * 
  * cpdef MutableFst randgen(Fst ifst,             # <<<<<<<<<<<<<<
  *                          int32 npath=1,
- *                          time_t seed=0,
+ *                          select="uniform",
  */
 
   /* function exit code */
@@ -40967,18 +41463,21 @@ static char __pyx_doc_9pywrapfst_48randgen[] = "\n  randgen(ifst, npath=1, seed=
 static PyObject *__pyx_pw_9pywrapfst_49randgen(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   int32 __pyx_v_npath;
-  time_t __pyx_v_seed;
   PyObject *__pyx_v_select = 0;
   int32 __pyx_v_max_length;
   bool __pyx_v_weighted;
   bool __pyx_v_remove_total_weight;
+  uint64 __pyx_v_seed;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("randgen (wrapper)", 0);
   {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ifst,&__pyx_n_s_npath,&__pyx_n_s_seed,&__pyx_n_s_select,&__pyx_n_s_max_length,&__pyx_n_s_weighted,&__pyx_n_s_remove_total_weight,0};
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ifst,&__pyx_n_s_npath,&__pyx_n_s_select,&__pyx_n_s_max_length,&__pyx_n_s_weighted,&__pyx_n_s_remove_total_weight,&__pyx_n_s_seed,0};
     PyObject* values[7] = {0,0,0,0,0,0,0};
-    values[3] = ((PyObject *)__pyx_n_b_uniform);
+    values[2] = ((PyObject *)__pyx_n_u_uniform);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -41014,36 +41513,36 @@ static PyObject *__pyx_pw_9pywrapfst_49randgen(PyObject *__pyx_self, PyObject *_
         CYTHON_FALLTHROUGH;
         case  2:
         if (kw_args > 0) {
-          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_seed);
+          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_select);
           if (value) { values[2] = value; kw_args--; }
         }
         CYTHON_FALLTHROUGH;
         case  3:
         if (kw_args > 0) {
-          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_select);
+          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_max_length);
           if (value) { values[3] = value; kw_args--; }
         }
         CYTHON_FALLTHROUGH;
         case  4:
         if (kw_args > 0) {
-          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_max_length);
+          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_weighted);
           if (value) { values[4] = value; kw_args--; }
         }
         CYTHON_FALLTHROUGH;
         case  5:
         if (kw_args > 0) {
-          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_weighted);
+          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_remove_total_weight);
           if (value) { values[5] = value; kw_args--; }
         }
         CYTHON_FALLTHROUGH;
         case  6:
         if (kw_args > 0) {
-          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_remove_total_weight);
+          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_seed);
           if (value) { values[6] = value; kw_args--; }
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "randgen") < 0)) __PYX_ERR(0, 3936, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "randgen") < 0)) __PYX_ERR(0, 3970, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -41066,65 +41565,65 @@ static PyObject *__pyx_pw_9pywrapfst_49randgen(PyObject *__pyx_self, PyObject *_
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_npath = __Pyx_PyInt_As_int32_t(values[1]); if (unlikely((__pyx_v_npath == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3937, __pyx_L3_error)
+      __pyx_v_npath = __Pyx_PyInt_As_int32_t(values[1]); if (unlikely((__pyx_v_npath == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3971, __pyx_L3_error)
     } else {
       __pyx_v_npath = ((int32)1);
     }
-    if (values[2]) {
-      __pyx_v_seed = __Pyx_PyInt_As_time_t(values[2]); if (unlikely((__pyx_v_seed == ((time_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3938, __pyx_L3_error)
+    __pyx_v_select = values[2];
+    if (values[3]) {
+      __pyx_v_max_length = __Pyx_PyInt_As_int32_t(values[3]); if (unlikely((__pyx_v_max_length == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3973, __pyx_L3_error)
     } else {
-      __pyx_v_seed = ((time_t)0);
+      __pyx_v_max_length = __pyx_k__46;
     }
-    __pyx_v_select = values[3];
     if (values[4]) {
-      __pyx_v_max_length = __Pyx_PyInt_As_int32_t(values[4]); if (unlikely((__pyx_v_max_length == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3940, __pyx_L3_error)
-    } else {
-      __pyx_v_max_length = __pyx_k__44;
-    }
-    if (values[5]) {
-      __pyx_v_weighted = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_weighted == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3941, __pyx_L3_error)
+      __pyx_v_weighted = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_weighted == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3974, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3941
- *                          select=b"uniform",
+      /* "pywrapfst.pyx":3974
+ *                          select="uniform",
  *                          int32 max_length=INT32_MAX,
  *                          bool weighted=False,             # <<<<<<<<<<<<<<
- *                          bool remove_total_weight=False):
- *   """
+ *                          bool remove_total_weight=False,
+ *                          uint64 seed=0):
  */
       __pyx_v_weighted = ((bool)0);
     }
-    if (values[6]) {
-      __pyx_v_remove_total_weight = __Pyx_PyObject_IsTrue(values[6]); if (unlikely((__pyx_v_remove_total_weight == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3942, __pyx_L3_error)
+    if (values[5]) {
+      __pyx_v_remove_total_weight = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_remove_total_weight == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3975, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3942
+      /* "pywrapfst.pyx":3975
  *                          int32 max_length=INT32_MAX,
  *                          bool weighted=False,
- *                          bool remove_total_weight=False):             # <<<<<<<<<<<<<<
+ *                          bool remove_total_weight=False,             # <<<<<<<<<<<<<<
+ *                          uint64 seed=0):
  *   """
- *   randgen(ifst, npath=1, seed=0, select="uniform", max_length=2147483647,
  */
       __pyx_v_remove_total_weight = ((bool)0);
     }
+    if (values[6]) {
+      __pyx_v_seed = __Pyx_PyInt_As_uint64_t(values[6]); if (unlikely((__pyx_v_seed == ((uint64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3976, __pyx_L3_error)
+    } else {
+      __pyx_v_seed = ((uint64)0);
+    }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("randgen", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3936, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("randgen", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3970, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.randgen", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3936, __pyx_L1_error)
-  __pyx_r = __pyx_pf_9pywrapfst_48randgen(__pyx_self, __pyx_v_ifst, __pyx_v_npath, __pyx_v_seed, __pyx_v_select, __pyx_v_max_length, __pyx_v_weighted, __pyx_v_remove_total_weight);
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 3970, __pyx_L1_error)
+  __pyx_r = __pyx_pf_9pywrapfst_48randgen(__pyx_self, __pyx_v_ifst, __pyx_v_npath, __pyx_v_select, __pyx_v_max_length, __pyx_v_weighted, __pyx_v_remove_total_weight, __pyx_v_seed);
 
-  /* "pywrapfst.pyx":3936
+  /* "pywrapfst.pyx":3970
  * 
  * 
  * cpdef MutableFst randgen(Fst ifst,             # <<<<<<<<<<<<<<
  *                          int32 npath=1,
- *                          time_t seed=0,
+ *                          select="uniform",
  */
 
   /* function exit code */
@@ -41136,21 +41635,24 @@ static PyObject *__pyx_pw_9pywrapfst_49randgen(PyObject *__pyx_self, PyObject *_
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_48randgen(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, int32 __pyx_v_npath, time_t __pyx_v_seed, PyObject *__pyx_v_select, int32 __pyx_v_max_length, bool __pyx_v_weighted, bool __pyx_v_remove_total_weight) {
+static PyObject *__pyx_pf_9pywrapfst_48randgen(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, int32 __pyx_v_npath, PyObject *__pyx_v_select, int32 __pyx_v_max_length, bool __pyx_v_weighted, bool __pyx_v_remove_total_weight, uint64 __pyx_v_seed) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   struct __pyx_opt_args_9pywrapfst_randgen __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("randgen", 0);
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 6;
   __pyx_t_2.npath = __pyx_v_npath;
-  __pyx_t_2.seed = __pyx_v_seed;
   __pyx_t_2.select = __pyx_v_select;
   __pyx_t_2.max_length = __pyx_v_max_length;
   __pyx_t_2.remove_total_weight = __pyx_v_weighted;
   __pyx_t_2.weighted = __pyx_v_remove_total_weight;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_randgen(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3936, __pyx_L1_error)
+  __pyx_t_2.seed = __pyx_v_seed;
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_randgen(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3970, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -41167,35 +41669,35 @@ static PyObject *__pyx_pf_9pywrapfst_48randgen(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":3987
+/* "pywrapfst.pyx":4022
  * 
  * 
  * cpdef MutableFst replace(pairs,             # <<<<<<<<<<<<<<
- *                          call_arc_labeling=b"input",
- *                          return_arc_labeling=b"neither",
+ *                          call_arc_labeling="input",
+ *                          return_arc_labeling="neither",
  */
 
 static PyObject *__pyx_pw_9pywrapfst_51replace(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObject *__pyx_v_pairs, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_replace *__pyx_optional_args) {
-  PyObject *__pyx_v_call_arc_labeling = ((PyObject *)__pyx_n_b_input);
-  PyObject *__pyx_v_return_arc_labeling = ((PyObject *)__pyx_n_b_neither);
+  PyObject *__pyx_v_call_arc_labeling = ((PyObject *)__pyx_n_u_input);
+  PyObject *__pyx_v_return_arc_labeling = ((PyObject *)__pyx_n_u_neither);
 
-  /* "pywrapfst.pyx":3990
- *                          call_arc_labeling=b"input",
- *                          return_arc_labeling=b"neither",
+  /* "pywrapfst.pyx":4025
+ *                          call_arc_labeling="input",
+ *                          return_arc_labeling="neither",
  *                          bool epsilon_on_replace=False,             # <<<<<<<<<<<<<<
  *                          int64 return_label=0):
  *   """
  */
   bool __pyx_v_epsilon_on_replace = ((bool)0);
   int64 __pyx_v_return_label = ((int64)0);
+  int64 __pyx_v__label;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v__pfst = 0;
   std::vector<__pyx_t_10cpywrapfst_LabelFstClassPair>  __pyx_v__pairs;
-  int64 __pyx_v_label;
-  struct __pyx_obj_9pywrapfst_Fst *__pyx_v_pfst = 0;
-  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v_tfst;
-  enum fst::ReplaceLabelType __pyx_v_cal;
-  enum fst::ReplaceLabelType __pyx_v_ral;
-  std::unique_ptr<fst::script::ReplaceOptions>  __pyx_v_opts;
+  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v__tfst;
+  enum fst::ReplaceLabelType __pyx_v__cal;
+  enum fst::ReplaceLabelType __pyx_v__ral;
+  std::unique_ptr<fst::script::ReplaceOptions>  __pyx_v__opts;
   struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -41210,6 +41712,9 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
   __pyx_t_10cpywrapfst_LabelFstClassPair __pyx_t_10;
   std::string __pyx_t_11;
   enum fst::ReplaceLabelType __pyx_t_12;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("replace", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -41226,37 +41731,37 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
     }
   }
 
-  /* "pywrapfst.pyx":4031
- *   cdef int64 label
- *   cdef Fst pfst
- *   for (label, pfst) in pairs:             # <<<<<<<<<<<<<<
- *     _pairs.push_back(fst.LabelFstClassPair(label, pfst._fst.get()))
- *   cdef unique_ptr[fst.VectorFstClass] tfst
+  /* "pywrapfst.pyx":4066
+ *   cdef Fst _pfst
+ *   cdef vector[fst.LabelFstClassPair] _pairs
+ *   for (_label, _pfst) in pairs:             # <<<<<<<<<<<<<<
+ *       _pairs.push_back(fst.LabelFstClassPair(_label, _pfst._fst.get()))
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
  */
   if (likely(PyList_CheckExact(__pyx_v_pairs)) || PyTuple_CheckExact(__pyx_v_pairs)) {
     __pyx_t_1 = __pyx_v_pairs; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
     __pyx_t_3 = NULL;
   } else {
-    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_pairs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4031, __pyx_L1_error)
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_pairs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4066, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4031, __pyx_L1_error)
+    __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4066, __pyx_L1_error)
   }
   for (;;) {
     if (likely(!__pyx_t_3)) {
       if (likely(PyList_CheckExact(__pyx_t_1))) {
         if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 4031, __pyx_L1_error)
+        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 4066, __pyx_L1_error)
         #else
-        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4031, __pyx_L1_error)
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4066, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         #endif
       } else {
         if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 4031, __pyx_L1_error)
+        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 4066, __pyx_L1_error)
         #else
-        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4031, __pyx_L1_error)
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4066, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_4);
         #endif
       }
@@ -41266,7 +41771,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
         PyObject* exc_type = PyErr_Occurred();
         if (exc_type) {
           if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-          else __PYX_ERR(0, 4031, __pyx_L1_error)
+          else __PYX_ERR(0, 4066, __pyx_L1_error)
         }
         break;
       }
@@ -41278,7 +41783,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
       if (unlikely(size != 2)) {
         if (size > 2) __Pyx_RaiseTooManyValuesError(2);
         else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        __PYX_ERR(0, 4031, __pyx_L1_error)
+        __PYX_ERR(0, 4066, __pyx_L1_error)
       }
       #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
       if (likely(PyTuple_CheckExact(sequence))) {
@@ -41291,15 +41796,15 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
       __Pyx_INCREF(__pyx_t_5);
       __Pyx_INCREF(__pyx_t_6);
       #else
-      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4031, __pyx_L1_error)
+      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4066, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4031, __pyx_L1_error)
+      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4066, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_6);
       #endif
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     } else {
       Py_ssize_t index = -1;
-      __pyx_t_7 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4031, __pyx_L1_error)
+      __pyx_t_7 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4066, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __pyx_t_8 = Py_TYPE(__pyx_t_7)->tp_iternext;
@@ -41307,7 +41812,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
       __Pyx_GOTREF(__pyx_t_5);
       index = 1; __pyx_t_6 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_6)) goto __pyx_L5_unpacking_failed;
       __Pyx_GOTREF(__pyx_t_6);
-      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) __PYX_ERR(0, 4031, __pyx_L1_error)
+      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) __PYX_ERR(0, 4066, __pyx_L1_error)
       __pyx_t_8 = NULL;
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       goto __pyx_L6_unpacking_done;
@@ -41315,135 +41820,135 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
       __pyx_t_8 = NULL;
       if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      __PYX_ERR(0, 4031, __pyx_L1_error)
+      __PYX_ERR(0, 4066, __pyx_L1_error)
       __pyx_L6_unpacking_done:;
     }
-    __pyx_t_9 = __Pyx_PyInt_As_int64_t(__pyx_t_5); if (unlikely((__pyx_t_9 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4031, __pyx_L1_error)
+    __pyx_t_9 = __Pyx_PyInt_As_int64_t(__pyx_t_5); if (unlikely((__pyx_t_9 == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4066, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 4031, __pyx_L1_error)
-    __pyx_v_label = __pyx_t_9;
-    __Pyx_XDECREF_SET(__pyx_v_pfst, ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_6));
+    if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 4066, __pyx_L1_error)
+    __pyx_v__label = __pyx_t_9;
+    __Pyx_XDECREF_SET(__pyx_v__pfst, ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_6));
     __pyx_t_6 = 0;
 
-    /* "pywrapfst.pyx":4032
- *   cdef Fst pfst
- *   for (label, pfst) in pairs:
- *     _pairs.push_back(fst.LabelFstClassPair(label, pfst._fst.get()))             # <<<<<<<<<<<<<<
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(_pairs[0].second.ArcType()))
+    /* "pywrapfst.pyx":4067
+ *   cdef vector[fst.LabelFstClassPair] _pairs
+ *   for (_label, _pfst) in pairs:
+ *       _pairs.push_back(fst.LabelFstClassPair(_label, _pfst._fst.get()))             # <<<<<<<<<<<<<<
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(_pairs[0].second.ArcType()))
  */
-    if (unlikely(((PyObject *)__pyx_v_pfst) == Py_None)) {
+    if (unlikely(((PyObject *)__pyx_v__pfst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 4032, __pyx_L1_error)
+      __PYX_ERR(0, 4067, __pyx_L1_error)
     }
     try {
-      __pyx_t_10 = __pyx_t_10cpywrapfst_LabelFstClassPair(__pyx_v_label, __pyx_v_pfst->_fst.get());
+      __pyx_t_10 = __pyx_t_10cpywrapfst_LabelFstClassPair(__pyx_v__label, __pyx_v__pfst->_fst.get());
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 4032, __pyx_L1_error)
+      __PYX_ERR(0, 4067, __pyx_L1_error)
     }
     try {
       __pyx_v__pairs.push_back(__pyx_t_10);
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 4032, __pyx_L1_error)
+      __PYX_ERR(0, 4067, __pyx_L1_error)
     }
 
-    /* "pywrapfst.pyx":4031
- *   cdef int64 label
- *   cdef Fst pfst
- *   for (label, pfst) in pairs:             # <<<<<<<<<<<<<<
- *     _pairs.push_back(fst.LabelFstClassPair(label, pfst._fst.get()))
- *   cdef unique_ptr[fst.VectorFstClass] tfst
+    /* "pywrapfst.pyx":4066
+ *   cdef Fst _pfst
+ *   cdef vector[fst.LabelFstClassPair] _pairs
+ *   for (_label, _pfst) in pairs:             # <<<<<<<<<<<<<<
+ *       _pairs.push_back(fst.LabelFstClassPair(_label, _pfst._fst.get()))
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
  */
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":4034
- *     _pairs.push_back(fst.LabelFstClassPair(label, pfst._fst.get()))
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(_pairs[0].second.ArcType()))             # <<<<<<<<<<<<<<
- *   cdef fst.ReplaceLabelType cal = _get_replace_label_type(
+  /* "pywrapfst.pyx":4069
+ *       _pairs.push_back(fst.LabelFstClassPair(_label, _pfst._fst.get()))
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(_pairs[0].second.ArcType()))             # <<<<<<<<<<<<<<
+ *   cdef fst.ReplaceLabelType _cal = _get_replace_label_type(
  *       tostring(call_arc_labeling),
  */
-  __pyx_v_tfst.reset(new fst::script::VectorFstClass((__pyx_v__pairs[0]).second->ArcType()));
+  __pyx_v__tfst.reset(new fst::script::VectorFstClass((__pyx_v__pairs[0]).second->ArcType()));
 
-  /* "pywrapfst.pyx":4036
- *   tfst.reset(new fst.VectorFstClass(_pairs[0].second.ArcType()))
- *   cdef fst.ReplaceLabelType cal = _get_replace_label_type(
+  /* "pywrapfst.pyx":4071
+ *   _tfst.reset(new fst.VectorFstClass(_pairs[0].second.ArcType()))
+ *   cdef fst.ReplaceLabelType _cal = _get_replace_label_type(
  *       tostring(call_arc_labeling),             # <<<<<<<<<<<<<<
  *       epsilon_on_replace)
- *   cdef fst.ReplaceLabelType ral = _get_replace_label_type(
+ *   cdef fst.ReplaceLabelType _ral = _get_replace_label_type(
  */
-  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_call_arc_labeling); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4036, __pyx_L1_error)
+  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_call_arc_labeling); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4071, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4035
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(_pairs[0].second.ArcType()))
- *   cdef fst.ReplaceLabelType cal = _get_replace_label_type(             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":4070
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(_pairs[0].second.ArcType()))
+ *   cdef fst.ReplaceLabelType _cal = _get_replace_label_type(             # <<<<<<<<<<<<<<
  *       tostring(call_arc_labeling),
  *       epsilon_on_replace)
  */
-  __pyx_t_12 = __pyx_f_9pywrapfst__get_replace_label_type(__pyx_t_11, __pyx_v_epsilon_on_replace); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4035, __pyx_L1_error)
-  __pyx_v_cal = __pyx_t_12;
+  __pyx_t_12 = __pyx_f_9pywrapfst__get_replace_label_type(__pyx_t_11, __pyx_v_epsilon_on_replace); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4070, __pyx_L1_error)
+  __pyx_v__cal = __pyx_t_12;
 
-  /* "pywrapfst.pyx":4039
+  /* "pywrapfst.pyx":4074
  *       epsilon_on_replace)
- *   cdef fst.ReplaceLabelType ral = _get_replace_label_type(
+ *   cdef fst.ReplaceLabelType _ral = _get_replace_label_type(
  *       tostring(return_arc_labeling),             # <<<<<<<<<<<<<<
  *       epsilon_on_replace)
- *   cdef unique_ptr[fst.ReplaceOptions] opts
+ *   cdef unique_ptr[fst.ReplaceOptions] _opts
  */
-  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_return_arc_labeling); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4039, __pyx_L1_error)
+  __pyx_t_11 = __pyx_f_9pywrapfst_tostring(__pyx_v_return_arc_labeling); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4074, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4038
+  /* "pywrapfst.pyx":4073
  *       tostring(call_arc_labeling),
  *       epsilon_on_replace)
- *   cdef fst.ReplaceLabelType ral = _get_replace_label_type(             # <<<<<<<<<<<<<<
+ *   cdef fst.ReplaceLabelType _ral = _get_replace_label_type(             # <<<<<<<<<<<<<<
  *       tostring(return_arc_labeling),
  *       epsilon_on_replace)
  */
-  __pyx_t_12 = __pyx_f_9pywrapfst__get_replace_label_type(__pyx_t_11, __pyx_v_epsilon_on_replace); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4038, __pyx_L1_error)
-  __pyx_v_ral = __pyx_t_12;
+  __pyx_t_12 = __pyx_f_9pywrapfst__get_replace_label_type(__pyx_t_11, __pyx_v_epsilon_on_replace); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4073, __pyx_L1_error)
+  __pyx_v__ral = __pyx_t_12;
 
-  /* "pywrapfst.pyx":4042
+  /* "pywrapfst.pyx":4077
  *       epsilon_on_replace)
- *   cdef unique_ptr[fst.ReplaceOptions] opts
- *   opts.reset(new fst.ReplaceOptions(_pairs[0].first, cal, ral, return_label))             # <<<<<<<<<<<<<<
- *   fst.Replace(_pairs, tfst.get(), deref(opts))
- *   return _init_MutableFst(tfst.release())
+ *   cdef unique_ptr[fst.ReplaceOptions] _opts
+ *   _opts.reset(new fst.ReplaceOptions(_pairs[0].first, _cal, _ral, return_label))             # <<<<<<<<<<<<<<
+ *   fst.Replace(_pairs, _tfst.get(), deref(_opts))
+ *   return _init_MutableFst(_tfst.release())
  */
-  __pyx_v_opts.reset(new fst::script::ReplaceOptions((__pyx_v__pairs[0]).first, __pyx_v_cal, __pyx_v_ral, __pyx_v_return_label));
+  __pyx_v__opts.reset(new fst::script::ReplaceOptions((__pyx_v__pairs[0]).first, __pyx_v__cal, __pyx_v__ral, __pyx_v_return_label));
 
-  /* "pywrapfst.pyx":4043
- *   cdef unique_ptr[fst.ReplaceOptions] opts
- *   opts.reset(new fst.ReplaceOptions(_pairs[0].first, cal, ral, return_label))
- *   fst.Replace(_pairs, tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
- *   return _init_MutableFst(tfst.release())
+  /* "pywrapfst.pyx":4078
+ *   cdef unique_ptr[fst.ReplaceOptions] _opts
+ *   _opts.reset(new fst.ReplaceOptions(_pairs[0].first, _cal, _ral, return_label))
+ *   fst.Replace(_pairs, _tfst.get(), deref(_opts))             # <<<<<<<<<<<<<<
+ *   return _init_MutableFst(_tfst.release())
  * 
  */
-  fst::script::Replace(__pyx_v__pairs, __pyx_v_tfst.get(), (*__pyx_v_opts));
+  fst::script::Replace(__pyx_v__pairs, __pyx_v__tfst.get(), (*__pyx_v__opts));
 
-  /* "pywrapfst.pyx":4044
- *   opts.reset(new fst.ReplaceOptions(_pairs[0].first, cal, ral, return_label))
- *   fst.Replace(_pairs, tfst.get(), deref(opts))
- *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":4079
+ *   _opts.reset(new fst.ReplaceOptions(_pairs[0].first, _cal, _ral, return_label))
+ *   fst.Replace(_pairs, _tfst.get(), deref(_opts))
+ *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4044, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4079, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":3987
+  /* "pywrapfst.pyx":4022
  * 
  * 
  * cpdef MutableFst replace(pairs,             # <<<<<<<<<<<<<<
- *                          call_arc_labeling=b"input",
- *                          return_arc_labeling=b"neither",
+ *                          call_arc_labeling="input",
+ *                          return_arc_labeling="neither",
  */
 
   /* function exit code */
@@ -41456,7 +41961,7 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_replace(PyObje
   __Pyx_AddTraceback("pywrapfst.replace", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_pfst);
+  __Pyx_XDECREF((PyObject *)__pyx_v__pfst);
   __Pyx_XGIVEREF((PyObject *)__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
@@ -41471,14 +41976,17 @@ static PyObject *__pyx_pw_9pywrapfst_51replace(PyObject *__pyx_self, PyObject *_
   PyObject *__pyx_v_return_arc_labeling = 0;
   bool __pyx_v_epsilon_on_replace;
   int64 __pyx_v_return_label;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("replace (wrapper)", 0);
   {
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pairs,&__pyx_n_s_call_arc_labeling,&__pyx_n_s_return_arc_labeling,&__pyx_n_s_epsilon_on_replace,&__pyx_n_s_return_label,0};
     PyObject* values[5] = {0,0,0,0,0};
-    values[1] = ((PyObject *)__pyx_n_b_input);
-    values[2] = ((PyObject *)__pyx_n_b_neither);
+    values[1] = ((PyObject *)__pyx_n_u_input);
+    values[2] = ((PyObject *)__pyx_n_u_neither);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -41527,7 +42035,7 @@ static PyObject *__pyx_pw_9pywrapfst_51replace(PyObject *__pyx_self, PyObject *_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "replace") < 0)) __PYX_ERR(0, 3987, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "replace") < 0)) __PYX_ERR(0, 4022, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -41548,12 +42056,12 @@ static PyObject *__pyx_pw_9pywrapfst_51replace(PyObject *__pyx_self, PyObject *_
     __pyx_v_call_arc_labeling = values[1];
     __pyx_v_return_arc_labeling = values[2];
     if (values[3]) {
-      __pyx_v_epsilon_on_replace = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_epsilon_on_replace == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3990, __pyx_L3_error)
+      __pyx_v_epsilon_on_replace = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_epsilon_on_replace == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4025, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":3990
- *                          call_arc_labeling=b"input",
- *                          return_arc_labeling=b"neither",
+      /* "pywrapfst.pyx":4025
+ *                          call_arc_labeling="input",
+ *                          return_arc_labeling="neither",
  *                          bool epsilon_on_replace=False,             # <<<<<<<<<<<<<<
  *                          int64 return_label=0):
  *   """
@@ -41561,14 +42069,14 @@ static PyObject *__pyx_pw_9pywrapfst_51replace(PyObject *__pyx_self, PyObject *_
       __pyx_v_epsilon_on_replace = ((bool)0);
     }
     if (values[4]) {
-      __pyx_v_return_label = __Pyx_PyInt_As_int64_t(values[4]); if (unlikely((__pyx_v_return_label == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 3991, __pyx_L3_error)
+      __pyx_v_return_label = __Pyx_PyInt_As_int64_t(values[4]); if (unlikely((__pyx_v_return_label == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4026, __pyx_L3_error)
     } else {
       __pyx_v_return_label = ((int64)0);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("replace", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3987, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("replace", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4022, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.replace", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -41576,12 +42084,12 @@ static PyObject *__pyx_pw_9pywrapfst_51replace(PyObject *__pyx_self, PyObject *_
   __pyx_L4_argument_unpacking_done:;
   __pyx_r = __pyx_pf_9pywrapfst_50replace(__pyx_self, __pyx_v_pairs, __pyx_v_call_arc_labeling, __pyx_v_return_arc_labeling, __pyx_v_epsilon_on_replace, __pyx_v_return_label);
 
-  /* "pywrapfst.pyx":3987
+  /* "pywrapfst.pyx":4022
  * 
  * 
  * cpdef MutableFst replace(pairs,             # <<<<<<<<<<<<<<
- *                          call_arc_labeling=b"input",
- *                          return_arc_labeling=b"neither",
+ *                          call_arc_labeling="input",
+ *                          return_arc_labeling="neither",
  */
 
   /* function exit code */
@@ -41594,6 +42102,9 @@ static PyObject *__pyx_pf_9pywrapfst_50replace(CYTHON_UNUSED PyObject *__pyx_sel
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   struct __pyx_opt_args_9pywrapfst_replace __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("replace", 0);
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 4;
@@ -41601,7 +42112,7 @@ static PyObject *__pyx_pf_9pywrapfst_50replace(CYTHON_UNUSED PyObject *__pyx_sel
   __pyx_t_2.return_arc_labeling = __pyx_v_return_arc_labeling;
   __pyx_t_2.epsilon_on_replace = __pyx_v_epsilon_on_replace;
   __pyx_t_2.return_label = __pyx_v_return_label;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_replace(__pyx_v_pairs, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3987, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_replace(__pyx_v_pairs, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4022, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -41618,7 +42129,7 @@ static PyObject *__pyx_pf_9pywrapfst_50replace(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4047
+/* "pywrapfst.pyx":4082
  * 
  * 
  * cpdef MutableFst reverse(Fst ifst, bool require_superinitial=True):             # <<<<<<<<<<<<<<
@@ -41629,10 +42140,13 @@ static PyObject *__pyx_pf_9pywrapfst_50replace(CYTHON_UNUSED PyObject *__pyx_sel
 static PyObject *__pyx_pw_9pywrapfst_53reverse(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_reverse(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_reverse *__pyx_optional_args) {
   bool __pyx_v_require_superinitial = ((bool)1);
-  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v_tfst;
+  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v__tfst;
   struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reverse", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -41640,47 +42154,47 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_reverse(struct
     }
   }
 
-  /* "pywrapfst.pyx":4067
+  /* "pywrapfst.pyx":4102
  *   """
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
- *   fst.Reverse(deref(ifst._fst), tfst.get(), require_superinitial)
- *   return _init_MutableFst(tfst.release())
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
+ *   fst.Reverse(deref(ifst._fst), _tfst.get(), require_superinitial)
+ *   return _init_MutableFst(_tfst.release())
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 4067, __pyx_L1_error)
+    __PYX_ERR(0, 4102, __pyx_L1_error)
   }
-  __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
+  __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":4068
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
- *   fst.Reverse(deref(ifst._fst), tfst.get(), require_superinitial)             # <<<<<<<<<<<<<<
- *   return _init_MutableFst(tfst.release())
+  /* "pywrapfst.pyx":4103
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+ *   fst.Reverse(deref(ifst._fst), _tfst.get(), require_superinitial)             # <<<<<<<<<<<<<<
+ *   return _init_MutableFst(_tfst.release())
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 4068, __pyx_L1_error)
+    __PYX_ERR(0, 4103, __pyx_L1_error)
   }
-  fst::script::Reverse((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), __pyx_v_require_superinitial);
+  fst::script::Reverse((*__pyx_v_ifst->_fst), __pyx_v__tfst.get(), __pyx_v_require_superinitial);
 
-  /* "pywrapfst.pyx":4069
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
- *   fst.Reverse(deref(ifst._fst), tfst.get(), require_superinitial)
- *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":4104
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+ *   fst.Reverse(deref(ifst._fst), _tfst.get(), require_superinitial)
+ *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4069, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4104, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4047
+  /* "pywrapfst.pyx":4082
  * 
  * 
  * cpdef MutableFst reverse(Fst ifst, bool require_superinitial=True):             # <<<<<<<<<<<<<<
@@ -41705,6 +42219,9 @@ static char __pyx_doc_9pywrapfst_52reverse[] = "\n  reverse(ifst, require_superi
 static PyObject *__pyx_pw_9pywrapfst_53reverse(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   bool __pyx_v_require_superinitial;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("reverse (wrapper)", 0);
@@ -41735,7 +42252,7 @@ static PyObject *__pyx_pw_9pywrapfst_53reverse(PyObject *__pyx_self, PyObject *_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reverse") < 0)) __PYX_ERR(0, 4047, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "reverse") < 0)) __PYX_ERR(0, 4082, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -41748,20 +42265,20 @@ static PyObject *__pyx_pw_9pywrapfst_53reverse(PyObject *__pyx_self, PyObject *_
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_require_superinitial = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_require_superinitial == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4047, __pyx_L3_error)
+      __pyx_v_require_superinitial = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_require_superinitial == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4082, __pyx_L3_error)
     } else {
       __pyx_v_require_superinitial = ((bool)1);
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("reverse", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4047, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("reverse", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4082, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.reverse", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4047, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4082, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_52reverse(__pyx_self, __pyx_v_ifst, __pyx_v_require_superinitial);
 
   /* function exit code */
@@ -41778,11 +42295,14 @@ static PyObject *__pyx_pf_9pywrapfst_52reverse(CYTHON_UNUSED PyObject *__pyx_sel
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   struct __pyx_opt_args_9pywrapfst_reverse __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reverse", 0);
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.require_superinitial = __pyx_v_require_superinitial;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_reverse(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4047, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_reverse(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4082, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -41799,35 +42319,35 @@ static PyObject *__pyx_pf_9pywrapfst_52reverse(CYTHON_UNUSED PyObject *__pyx_sel
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4075
+/* "pywrapfst.pyx":4110
  * 
  * 
- * cdef vector[fst.WeightClass] *_shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
- *                                                 float delta=fst.kShortestDelta,
- *                                                 int64 nstate=fst.kNoStateId,
+ * cdef void _shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
+ *                             vector[fst.WeightClass] *distance,
+ *                             float delta=fst.kShortestDelta,
  */
 
-static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdistance(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, struct __pyx_opt_args_9pywrapfst__shortestdistance *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__45;
-  int64 __pyx_v_nstate = __pyx_k__46;
-  PyObject *__pyx_v_queue_type = ((PyObject *)__pyx_n_b_auto);
+static void __pyx_f_9pywrapfst__shortestdistance(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, std::vector<fst::script::WeightClass>  *__pyx_v_distance, struct __pyx_opt_args_9pywrapfst__shortestdistance *__pyx_optional_args) {
+  float __pyx_v_delta = __pyx_k__47;
+  int64 __pyx_v_nstate = __pyx_k__48;
+  PyObject *__pyx_v_queue_type = ((PyObject *)__pyx_n_u_auto);
 
-  /* "pywrapfst.pyx":4079
- *                                                 int64 nstate=fst.kNoStateId,
- *                                                 queue_type=b"auto",
- *                                                 bool reverse=False) except *:             # <<<<<<<<<<<<<<
- *   cdef unique_ptr[vector[fst.WeightClass]] distance
- *   distance.reset(new vector[fst.WeightClass]())
+  /* "pywrapfst.pyx":4115
+ *                             int64 nstate=fst.kNoStateId,
+ *                             queue_type="auto",
+ *                             bool reverse=False) except *:             # <<<<<<<<<<<<<<
+ *   cdef unique_ptr[fst.ShortestDistanceOptions] _opts
+ *   if reverse:
  */
   bool __pyx_v_reverse = ((bool)0);
-  std::unique_ptr<std::vector<fst::script::WeightClass> >  __pyx_v_distance;
-  std::unique_ptr<fst::script::ShortestDistanceOptions>  __pyx_v_opts;
-  std::vector<fst::script::WeightClass>  *__pyx_r;
+  std::unique_ptr<fst::script::ShortestDistanceOptions>  __pyx_v__opts;
   __Pyx_RefNannyDeclarations
-  std::vector<fst::script::WeightClass>  *__pyx_t_1;
-  int __pyx_t_2;
-  std::string __pyx_t_3;
-  enum fst::QueueType __pyx_t_4;
+  int __pyx_t_1;
+  std::string __pyx_t_2;
+  enum fst::QueueType __pyx_t_3;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_shortestdistance", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -41844,47 +42364,32 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
     }
   }
 
-  /* "pywrapfst.pyx":4081
- *                                                 bool reverse=False) except *:
- *   cdef unique_ptr[vector[fst.WeightClass]] distance
- *   distance.reset(new vector[fst.WeightClass]())             # <<<<<<<<<<<<<<
- *   # For scoping reasons, these have to be declared here even though they may
- *   # not be used in all cases.
- */
-  try {
-    __pyx_t_1 = new std::vector<fst::script::WeightClass> ();
-  } catch(...) {
-    __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 4081, __pyx_L1_error)
-  }
-  __pyx_v_distance.reset(__pyx_t_1);
-
-  /* "pywrapfst.pyx":4085
- *   # not be used in all cases.
- *   cdef unique_ptr[fst.ShortestDistanceOptions] opts
+  /* "pywrapfst.pyx":4117
+ *                             bool reverse=False) except *:
+ *   cdef unique_ptr[fst.ShortestDistanceOptions] _opts
  *   if reverse:             # <<<<<<<<<<<<<<
  *     # Only the simpler signature supports shortest distance to final states;
  *     # `nstate` and `queue_type` arguments are ignored.
  */
-  __pyx_t_2 = (__pyx_v_reverse != 0);
-  if (__pyx_t_2) {
+  __pyx_t_1 = (__pyx_v_reverse != 0);
+  if (__pyx_t_1) {
 
-    /* "pywrapfst.pyx":4088
+    /* "pywrapfst.pyx":4120
  *     # Only the simpler signature supports shortest distance to final states;
  *     # `nstate` and `queue_type` arguments are ignored.
- *     fst.ShortestDistance(deref(ifst._fst), distance.get(), True, delta)             # <<<<<<<<<<<<<<
+ *     fst.ShortestDistance(deref(ifst._fst), distance, True, delta)             # <<<<<<<<<<<<<<
  *   else:
- *     opts.reset(new fst.ShortestDistanceOptions(
+ *     _opts.reset(
  */
     if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 4088, __pyx_L1_error)
+      __PYX_ERR(0, 4120, __pyx_L1_error)
     }
-    fst::script::ShortestDistance((*__pyx_v_ifst->_fst), __pyx_v_distance.get(), 1, __pyx_v_delta);
+    fst::script::ShortestDistance((*__pyx_v_ifst->_fst), __pyx_v_distance, 1, __pyx_v_delta);
 
-    /* "pywrapfst.pyx":4085
- *   # not be used in all cases.
- *   cdef unique_ptr[fst.ShortestDistanceOptions] opts
+    /* "pywrapfst.pyx":4117
+ *                             bool reverse=False) except *:
+ *   cdef unique_ptr[fst.ShortestDistanceOptions] _opts
  *   if reverse:             # <<<<<<<<<<<<<<
  *     # Only the simpler signature supports shortest distance to final states;
  *     # `nstate` and `queue_type` arguments are ignored.
@@ -41892,77 +42397,66 @@ static std::vector<fst::script::WeightClass>  *__pyx_f_9pywrapfst__shortestdista
     goto __pyx_L3;
   }
 
-  /* "pywrapfst.pyx":4090
- *     fst.ShortestDistance(deref(ifst._fst), distance.get(), True, delta)
+  /* "pywrapfst.pyx":4122
+ *     fst.ShortestDistance(deref(ifst._fst), distance, True, delta)
  *   else:
- *     opts.reset(new fst.ShortestDistanceOptions(             # <<<<<<<<<<<<<<
- *         _get_queue_type(tostring(queue_type)),
- *         fst.ANY_ARC_FILTER,
+ *     _opts.reset(             # <<<<<<<<<<<<<<
+ *         new fst.ShortestDistanceOptions(_get_queue_type(tostring(queue_type)),
+ *                                         fst.ANY_ARC_FILTER,
  */
   /*else*/ {
 
-    /* "pywrapfst.pyx":4091
+    /* "pywrapfst.pyx":4123
  *   else:
- *     opts.reset(new fst.ShortestDistanceOptions(
- *         _get_queue_type(tostring(queue_type)),             # <<<<<<<<<<<<<<
- *         fst.ANY_ARC_FILTER,
- *         nstate,
+ *     _opts.reset(
+ *         new fst.ShortestDistanceOptions(_get_queue_type(tostring(queue_type)),             # <<<<<<<<<<<<<<
+ *                                         fst.ANY_ARC_FILTER,
+ *                                         nstate,
  */
-    __pyx_t_3 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4091, __pyx_L1_error)
-    __pyx_t_4 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4091, __pyx_L1_error)
+    __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4123, __pyx_L1_error)
+    __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4123, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4090
- *     fst.ShortestDistance(deref(ifst._fst), distance.get(), True, delta)
+    /* "pywrapfst.pyx":4122
+ *     fst.ShortestDistance(deref(ifst._fst), distance, True, delta)
  *   else:
- *     opts.reset(new fst.ShortestDistanceOptions(             # <<<<<<<<<<<<<<
- *         _get_queue_type(tostring(queue_type)),
- *         fst.ANY_ARC_FILTER,
+ *     _opts.reset(             # <<<<<<<<<<<<<<
+ *         new fst.ShortestDistanceOptions(_get_queue_type(tostring(queue_type)),
+ *                                         fst.ANY_ARC_FILTER,
  */
-    __pyx_v_opts.reset(new fst::script::ShortestDistanceOptions(__pyx_t_4, fst::script::ANY_ARC_FILTER, __pyx_v_nstate, __pyx_v_delta));
+    __pyx_v__opts.reset(new fst::script::ShortestDistanceOptions(__pyx_t_3, fst::script::ANY_ARC_FILTER, __pyx_v_nstate, __pyx_v_delta));
 
-    /* "pywrapfst.pyx":4095
- *         nstate,
- *         delta))
- *     fst.ShortestDistance(deref(ifst._fst), distance.get(), deref(opts))             # <<<<<<<<<<<<<<
- *   return distance.release()
+    /* "pywrapfst.pyx":4127
+ *                                         nstate,
+ *                                         delta))
+ *     fst.ShortestDistance(deref(ifst._fst), distance, deref(_opts))             # <<<<<<<<<<<<<<
+ * 
  * 
  */
     if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-      __PYX_ERR(0, 4095, __pyx_L1_error)
+      __PYX_ERR(0, 4127, __pyx_L1_error)
     }
-    fst::script::ShortestDistance((*__pyx_v_ifst->_fst), __pyx_v_distance.get(), (*__pyx_v_opts));
+    fst::script::ShortestDistance((*__pyx_v_ifst->_fst), __pyx_v_distance, (*__pyx_v__opts));
   }
   __pyx_L3:;
 
-  /* "pywrapfst.pyx":4096
- *         delta))
- *     fst.ShortestDistance(deref(ifst._fst), distance.get(), deref(opts))
- *   return distance.release()             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":4110
  * 
  * 
- */
-  __pyx_r = __pyx_v_distance.release();
-  goto __pyx_L0;
-
-  /* "pywrapfst.pyx":4075
- * 
- * 
- * cdef vector[fst.WeightClass] *_shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
- *                                                 float delta=fst.kShortestDelta,
- *                                                 int64 nstate=fst.kNoStateId,
+ * cdef void _shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
+ *                             vector[fst.WeightClass] *distance,
+ *                             float delta=fst.kShortestDelta,
  */
 
   /* function exit code */
+  goto __pyx_L0;
   __pyx_L1_error:;
   __Pyx_AddTraceback("pywrapfst._shortestdistance", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = 0;
   __pyx_L0:;
   __Pyx_RefNannyFinishContext();
-  return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4099
+/* "pywrapfst.pyx":4130
  * 
  * 
  * def shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
@@ -41980,13 +42474,16 @@ static PyObject *__pyx_pw_9pywrapfst_55shortestdistance(PyObject *__pyx_self, Py
   int64 __pyx_v_nstate;
   PyObject *__pyx_v_queue_type = 0;
   bool __pyx_v_reverse;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("shortestdistance (wrapper)", 0);
   {
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ifst,&__pyx_n_s_delta,&__pyx_n_s_nstate,&__pyx_n_s_queue_type,&__pyx_n_s_reverse,0};
     PyObject* values[5] = {0,0,0,0,0};
-    values[3] = ((PyObject *)__pyx_n_b_auto);
+    values[3] = ((PyObject *)__pyx_n_u_auto);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -42035,7 +42532,7 @@ static PyObject *__pyx_pw_9pywrapfst_55shortestdistance(PyObject *__pyx_self, Py
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "shortestdistance") < 0)) __PYX_ERR(0, 4099, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "shortestdistance") < 0)) __PYX_ERR(0, 4130, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -42054,23 +42551,23 @@ static PyObject *__pyx_pw_9pywrapfst_55shortestdistance(PyObject *__pyx_self, Py
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 4100, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 4131, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__47;
+      __pyx_v_delta = __pyx_k__49;
     }
     if (values[2]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[2]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4101, __pyx_L3_error)
+      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[2]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4132, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__48;
+      __pyx_v_nstate = __pyx_k__50;
     }
     __pyx_v_queue_type = values[3];
     if (values[4]) {
-      __pyx_v_reverse = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_reverse == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4103, __pyx_L3_error)
+      __pyx_v_reverse = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_reverse == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4134, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4103
+      /* "pywrapfst.pyx":4134
  *                      int64 nstate=fst.kNoStateId,
- *                      queue_type=b"auto",
+ *                      queue_type="auto",
  *                      bool reverse=False):             # <<<<<<<<<<<<<<
  *   """
  *   shortestdistance(ifst, delta=1e-6, nstate=NO_STATE_ID,
@@ -42080,16 +42577,16 @@ static PyObject *__pyx_pw_9pywrapfst_55shortestdistance(PyObject *__pyx_self, Py
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("shortestdistance", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4099, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("shortestdistance", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4130, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.shortestdistance", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4099, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4130, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_54shortestdistance(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nstate, __pyx_v_queue_type, __pyx_v_reverse);
 
-  /* "pywrapfst.pyx":4099
+  /* "pywrapfst.pyx":4130
  * 
  * 
  * def shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
@@ -42107,91 +42604,105 @@ static PyObject *__pyx_pw_9pywrapfst_55shortestdistance(PyObject *__pyx_self, Py
 }
 
 static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, float __pyx_v_delta, int64 __pyx_v_nstate, PyObject *__pyx_v_queue_type, bool __pyx_v_reverse) {
-  std::unique_ptr<std::vector<fst::script::WeightClass> >  __pyx_v_distance;
-  std::string __pyx_v_weight_type;
+  std::vector<fst::script::WeightClass>  __pyx_v__distance;
   fst::script::WeightClass __pyx_7genexpr__pyx_v_weight;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  std::vector<fst::script::WeightClass>  *__pyx_t_1;
-  struct __pyx_opt_args_9pywrapfst__shortestdistance __pyx_t_2;
-  PyObject *__pyx_t_3 = NULL;
-  std::vector<fst::script::WeightClass> ::iterator __pyx_t_4;
-  fst::script::WeightClass __pyx_t_5;
+  struct __pyx_opt_args_9pywrapfst__shortestdistance __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  std::vector<fst::script::WeightClass> ::iterator __pyx_t_3;
+  fst::script::WeightClass __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
   PyObject *__pyx_t_6 = NULL;
   PyObject *__pyx_t_7 = NULL;
-  PyObject *__pyx_t_8 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("shortestdistance", 0);
 
-  /* "pywrapfst.pyx":4131
+  /* "pywrapfst.pyx":4162
  *   """
- *   cdef unique_ptr[vector[fst.WeightClass]] distance
- *   distance.reset(_shortestdistance(ifst, delta, nstate, queue_type, reverse))             # <<<<<<<<<<<<<<
- *   cdef string weight_type = ifst.weight_type()
- *   return [Weight(weight_type, weight.ToString()) for weight in deref(distance)]
+ *   cdef vector[fst.WeightClass] _distance
+ *   _shortestdistance(ifst, addr(_distance), delta, nstate, queue_type, reverse)             # <<<<<<<<<<<<<<
+ *   return [Weight(ifst._fst.get().WeightType(), weight.ToString())
+ *           for weight in _distance]
  */
-  __pyx_t_2.__pyx_n = 4;
-  __pyx_t_2.delta = __pyx_v_delta;
-  __pyx_t_2.nstate = __pyx_v_nstate;
-  __pyx_t_2.queue_type = __pyx_v_queue_type;
-  __pyx_t_2.reverse = __pyx_v_reverse;
-  __pyx_t_1 = __pyx_f_9pywrapfst__shortestdistance(__pyx_v_ifst, &__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4131, __pyx_L1_error)
-  __pyx_v_distance.reset(__pyx_t_1);
+  __pyx_t_1.__pyx_n = 4;
+  __pyx_t_1.delta = __pyx_v_delta;
+  __pyx_t_1.nstate = __pyx_v_nstate;
+  __pyx_t_1.queue_type = __pyx_v_queue_type;
+  __pyx_t_1.reverse = __pyx_v_reverse;
+  __pyx_f_9pywrapfst__shortestdistance(__pyx_v_ifst, (&__pyx_v__distance), &__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4162, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4132
- *   cdef unique_ptr[vector[fst.WeightClass]] distance
- *   distance.reset(_shortestdistance(ifst, delta, nstate, queue_type, reverse))
- *   cdef string weight_type = ifst.weight_type()             # <<<<<<<<<<<<<<
- *   return [Weight(weight_type, weight.ToString()) for weight in deref(distance)]
+  /* "pywrapfst.pyx":4163
+ *   cdef vector[fst.WeightClass] _distance
+ *   _shortestdistance(ifst, addr(_distance), delta, nstate, queue_type, reverse)
+ *   return [Weight(ifst._fst.get().WeightType(), weight.ToString())             # <<<<<<<<<<<<<<
+ *           for weight in _distance]
  * 
  */
-  if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
-    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 4132, __pyx_L1_error)
-  }
-  __pyx_v_weight_type = ((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0);
+  __Pyx_XDECREF(__pyx_r);
+  { /* enter inner scope */
+    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4163, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":4133
- *   distance.reset(_shortestdistance(ifst, delta, nstate, queue_type, reverse))
- *   cdef string weight_type = ifst.weight_type()
- *   return [Weight(weight_type, weight.ToString()) for weight in deref(distance)]             # <<<<<<<<<<<<<<
+    /* "pywrapfst.pyx":4164
+ *   _shortestdistance(ifst, addr(_distance), delta, nstate, queue_type, reverse)
+ *   return [Weight(ifst._fst.get().WeightType(), weight.ToString())
+ *           for weight in _distance]             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __Pyx_XDECREF(__pyx_r);
-  { /* enter inner scope */
-    __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4133, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_1 = &(*__pyx_v_distance);
-    __pyx_t_4 = __pyx_t_1->begin();
+    __pyx_t_3 = __pyx_v__distance.begin();
     for (;;) {
-      if (!(__pyx_t_4 != __pyx_t_1->end())) break;
-      __pyx_t_5 = *__pyx_t_4;
-      ++__pyx_t_4;
-      __pyx_7genexpr__pyx_v_weight = __pyx_t_5;
-      __pyx_t_6 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_weight_type); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4133, __pyx_L1_error)
+      if (!(__pyx_t_3 != __pyx_v__distance.end())) break;
+      __pyx_t_4 = *__pyx_t_3;
+      ++__pyx_t_3;
+      __pyx_7genexpr__pyx_v_weight = __pyx_t_4;
+
+      /* "pywrapfst.pyx":4163
+ *   cdef vector[fst.WeightClass] _distance
+ *   _shortestdistance(ifst, addr(_distance), delta, nstate, queue_type, reverse)
+ *   return [Weight(ifst._fst.get().WeightType(), weight.ToString())             # <<<<<<<<<<<<<<
+ *           for weight in _distance]
+ * 
+ */
+      if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
+        PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
+        __PYX_ERR(0, 4163, __pyx_L1_error)
+      }
+      __pyx_t_5 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_ifst->_fst.get()->WeightType()); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4163, __pyx_L1_error)
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_6 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_7genexpr__pyx_v_weight.ToString()); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4163, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_6);
-      __pyx_t_7 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_7genexpr__pyx_v_weight.ToString()); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4133, __pyx_L1_error)
+      __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4163, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_7);
-      __pyx_t_8 = PyTuple_New(2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 4133, __pyx_L1_error)
-      __Pyx_GOTREF(__pyx_t_8);
+      __Pyx_GIVEREF(__pyx_t_5);
+      PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5);
       __Pyx_GIVEREF(__pyx_t_6);
-      PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6);
-      __Pyx_GIVEREF(__pyx_t_7);
-      PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_7);
+      PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_6);
+      __pyx_t_5 = 0;
       __pyx_t_6 = 0;
-      __pyx_t_7 = 0;
-      __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4133, __pyx_L1_error)
-      __Pyx_GOTREF(__pyx_t_7);
-      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      if (unlikely(__Pyx_ListComp_Append(__pyx_t_3, (PyObject*)__pyx_t_7))) __PYX_ERR(0, 4133, __pyx_L1_error)
+      __pyx_t_6 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_9pywrapfst_Weight), __pyx_t_7, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4163, __pyx_L1_error)
+      __Pyx_GOTREF(__pyx_t_6);
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_6))) __PYX_ERR(0, 4163, __pyx_L1_error)
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+      /* "pywrapfst.pyx":4164
+ *   _shortestdistance(ifst, addr(_distance), delta, nstate, queue_type, reverse)
+ *   return [Weight(ifst._fst.get().WeightType(), weight.ToString())
+ *           for weight in _distance]             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
     }
   } /* exit inner scope */
-  __pyx_r = __pyx_t_3;
-  __pyx_t_3 = 0;
+  __pyx_r = __pyx_t_2;
+  __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4099
+  /* "pywrapfst.pyx":4130
  * 
  * 
  * def shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
@@ -42201,10 +42712,10 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
   __Pyx_XDECREF(__pyx_t_7);
-  __Pyx_XDECREF(__pyx_t_8);
   __Pyx_AddTraceback("pywrapfst.shortestdistance", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -42213,7 +42724,7 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4136
+/* "pywrapfst.pyx":4167
  * 
  * 
  * cpdef MutableFst shortestpath(Fst ifst,             # <<<<<<<<<<<<<<
@@ -42223,37 +42734,40 @@ static PyObject *__pyx_pf_9pywrapfst_54shortestdistance(CYTHON_UNUSED PyObject *
 
 static PyObject *__pyx_pw_9pywrapfst_57shortestpath(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_shortestpath(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_shortestpath *__pyx_optional_args) {
-  float __pyx_v_delta = __pyx_k__49;
+  float __pyx_v_delta = __pyx_k__51;
   int32 __pyx_v_nshortest = ((int32)1);
-  int64 __pyx_v_nstate = __pyx_k__50;
-  PyObject *__pyx_v_queue_type = ((PyObject *)__pyx_n_b_auto);
+  int64 __pyx_v_nstate = __pyx_k__52;
+  PyObject *__pyx_v_queue_type = ((PyObject *)__pyx_n_u_auto);
 
-  /* "pywrapfst.pyx":4141
+  /* "pywrapfst.pyx":4172
  *                               int64 nstate=fst.kNoStateId,
- *                               queue_type=b"auto",
+ *                               queue_type="auto",
  *                               bool unique=False,             # <<<<<<<<<<<<<<
  *                               weight=None):
  *   """
  */
   bool __pyx_v_unique = ((bool)0);
 
-  /* "pywrapfst.pyx":4142
- *                               queue_type=b"auto",
+  /* "pywrapfst.pyx":4173
+ *                               queue_type="auto",
  *                               bool unique=False,
  *                               weight=None):             # <<<<<<<<<<<<<<
  *   """
  *   shortestpath(ifst, delta=1e-6, nshortest=1, nstate=NO_STATE_ID,
  */
   PyObject *__pyx_v_weight = ((PyObject *)Py_None);
-  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v_tfst;
-  fst::script::WeightClass __pyx_v_wc;
-  std::unique_ptr<fst::script::ShortestPathOptions>  __pyx_v_opts;
+  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v__tfst;
+  fst::script::WeightClass __pyx_v__weight;
+  std::unique_ptr<fst::script::ShortestPathOptions>  __pyx_v__opts;
   struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   fst::script::WeightClass __pyx_t_1;
   std::string __pyx_t_2;
   enum fst::QueueType __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("shortestpath", 0);
   if (__pyx_optional_args) {
     if (__pyx_optional_args->__pyx_n > 0) {
@@ -42276,80 +42790,88 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_shortestpath(s
     }
   }
 
-  /* "pywrapfst.pyx":4174
+  /* "pywrapfst.pyx":4205
  *   """
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
  *   # Threshold is set to semiring Zero (no pruning) if no weight is specified.
- *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
+ *   cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(ifst.weight_type(),
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 4174, __pyx_L1_error)
+    __PYX_ERR(0, 4205, __pyx_L1_error)
   }
-  __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
+  __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":4176
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+  /* "pywrapfst.pyx":4207
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
  *   # Threshold is set to semiring Zero (no pruning) if no weight is specified.
- *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)             # <<<<<<<<<<<<<<
- *   cdef unique_ptr[fst.ShortestPathOptions] opts
- *   opts.reset(new fst.ShortestPathOptions(_get_queue_type(tostring(queue_type)),
+ *   cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(ifst.weight_type(),             # <<<<<<<<<<<<<<
+ *                                                           weight)
+ *   cdef unique_ptr[fst.ShortestPathOptions] _opts
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "weight_type");
-    __PYX_ERR(0, 4176, __pyx_L1_error)
+    __PYX_ERR(0, 4207, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_Zero(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4176, __pyx_L1_error)
-  __pyx_v_wc = __pyx_t_1;
 
-  /* "pywrapfst.pyx":4178
- *   cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
- *   cdef unique_ptr[fst.ShortestPathOptions] opts
- *   opts.reset(new fst.ShortestPathOptions(_get_queue_type(tostring(queue_type)),             # <<<<<<<<<<<<<<
- *                                          nshortest,
- *                                          unique,
+  /* "pywrapfst.pyx":4208
+ *   # Threshold is set to semiring Zero (no pruning) if no weight is specified.
+ *   cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(ifst.weight_type(),
+ *                                                           weight)             # <<<<<<<<<<<<<<
+ *   cdef unique_ptr[fst.ShortestPathOptions] _opts
+ *   _opts.reset(
+ */
+  __pyx_t_1 = __pyx_f_9pywrapfst__get_WeightClass_or_Zero(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->weight_type(__pyx_v_ifst, 0), __pyx_v_weight); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4207, __pyx_L1_error)
+  __pyx_v__weight = __pyx_t_1;
+
+  /* "pywrapfst.pyx":4211
+ *   cdef unique_ptr[fst.ShortestPathOptions] _opts
+ *   _opts.reset(
+ *       new fst.ShortestPathOptions(_get_queue_type(tostring(queue_type)),             # <<<<<<<<<<<<<<
+ *                                   nshortest,
+ *                                   unique,
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4178, __pyx_L1_error)
-  __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4178, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_queue_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4211, __pyx_L1_error)
+  __pyx_t_3 = __pyx_f_9pywrapfst__get_queue_type(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4211, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4183
- *                                          delta,
- *                                          wc,
- *                                          nstate))             # <<<<<<<<<<<<<<
- *   fst.ShortestPath(deref(ifst._fst), tfst.get(), deref(opts))
- *   return _init_MutableFst(tfst.release())
+  /* "pywrapfst.pyx":4210
+ *                                                           weight)
+ *   cdef unique_ptr[fst.ShortestPathOptions] _opts
+ *   _opts.reset(             # <<<<<<<<<<<<<<
+ *       new fst.ShortestPathOptions(_get_queue_type(tostring(queue_type)),
+ *                                   nshortest,
  */
-  __pyx_v_opts.reset(new fst::script::ShortestPathOptions(__pyx_t_3, __pyx_v_nshortest, __pyx_v_unique, __pyx_v_delta, __pyx_v_wc, __pyx_v_nstate));
+  __pyx_v__opts.reset(new fst::script::ShortestPathOptions(__pyx_t_3, __pyx_v_nshortest, __pyx_v_unique, __pyx_v_delta, __pyx_v__weight, __pyx_v_nstate));
 
-  /* "pywrapfst.pyx":4184
- *                                          wc,
- *                                          nstate))
- *   fst.ShortestPath(deref(ifst._fst), tfst.get(), deref(opts))             # <<<<<<<<<<<<<<
- *   return _init_MutableFst(tfst.release())
+  /* "pywrapfst.pyx":4217
+ *                                   _weight,
+ *                                   nstate))
+ *   fst.ShortestPath(deref(ifst._fst), _tfst.get(), deref(_opts))             # <<<<<<<<<<<<<<
+ *   return _init_MutableFst(_tfst.release())
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 4184, __pyx_L1_error)
+    __PYX_ERR(0, 4217, __pyx_L1_error)
   }
-  fst::script::ShortestPath((*__pyx_v_ifst->_fst), __pyx_v_tfst.get(), (*__pyx_v_opts));
+  fst::script::ShortestPath((*__pyx_v_ifst->_fst), __pyx_v__tfst.get(), (*__pyx_v__opts));
 
-  /* "pywrapfst.pyx":4185
- *                                          nstate))
- *   fst.ShortestPath(deref(ifst._fst), tfst.get(), deref(opts))
- *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":4218
+ *                                   nstate))
+ *   fst.ShortestPath(deref(ifst._fst), _tfst.get(), deref(_opts))
+ *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4185, __pyx_L1_error)
+  __pyx_t_4 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4218, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_4);
   __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4136
+  /* "pywrapfst.pyx":4167
  * 
  * 
  * cpdef MutableFst shortestpath(Fst ifst,             # <<<<<<<<<<<<<<
@@ -42379,16 +42901,19 @@ static PyObject *__pyx_pw_9pywrapfst_57shortestpath(PyObject *__pyx_self, PyObje
   PyObject *__pyx_v_queue_type = 0;
   bool __pyx_v_unique;
   PyObject *__pyx_v_weight = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("shortestpath (wrapper)", 0);
   {
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_ifst,&__pyx_n_s_delta,&__pyx_n_s_nshortest,&__pyx_n_s_nstate,&__pyx_n_s_queue_type,&__pyx_n_s_unique,&__pyx_n_s_weight,0};
     PyObject* values[7] = {0,0,0,0,0,0,0};
-    values[4] = ((PyObject *)__pyx_n_b_auto);
+    values[4] = ((PyObject *)__pyx_n_u_auto);
 
-    /* "pywrapfst.pyx":4142
- *                               queue_type=b"auto",
+    /* "pywrapfst.pyx":4173
+ *                               queue_type="auto",
  *                               bool unique=False,
  *                               weight=None):             # <<<<<<<<<<<<<<
  *   """
@@ -42459,7 +42984,7 @@ static PyObject *__pyx_pw_9pywrapfst_57shortestpath(PyObject *__pyx_self, PyObje
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "shortestpath") < 0)) __PYX_ERR(0, 4136, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "shortestpath") < 0)) __PYX_ERR(0, 4167, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -42482,28 +43007,28 @@ static PyObject *__pyx_pw_9pywrapfst_57shortestpath(PyObject *__pyx_self, PyObje
     }
     __pyx_v_ifst = ((struct __pyx_obj_9pywrapfst_Fst *)values[0]);
     if (values[1]) {
-      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 4137, __pyx_L3_error)
+      __pyx_v_delta = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_delta == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 4168, __pyx_L3_error)
     } else {
-      __pyx_v_delta = __pyx_k__49;
+      __pyx_v_delta = __pyx_k__51;
     }
     if (values[2]) {
-      __pyx_v_nshortest = __Pyx_PyInt_As_int32_t(values[2]); if (unlikely((__pyx_v_nshortest == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4138, __pyx_L3_error)
+      __pyx_v_nshortest = __Pyx_PyInt_As_int32_t(values[2]); if (unlikely((__pyx_v_nshortest == ((int32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4169, __pyx_L3_error)
     } else {
       __pyx_v_nshortest = ((int32)1);
     }
     if (values[3]) {
-      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4139, __pyx_L3_error)
+      __pyx_v_nstate = __Pyx_PyInt_As_int64_t(values[3]); if (unlikely((__pyx_v_nstate == ((int64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4170, __pyx_L3_error)
     } else {
-      __pyx_v_nstate = __pyx_k__50;
+      __pyx_v_nstate = __pyx_k__52;
     }
     __pyx_v_queue_type = values[4];
     if (values[5]) {
-      __pyx_v_unique = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_unique == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4141, __pyx_L3_error)
+      __pyx_v_unique = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_unique == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4172, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4141
+      /* "pywrapfst.pyx":4172
  *                               int64 nstate=fst.kNoStateId,
- *                               queue_type=b"auto",
+ *                               queue_type="auto",
  *                               bool unique=False,             # <<<<<<<<<<<<<<
  *                               weight=None):
  *   """
@@ -42514,16 +43039,16 @@ static PyObject *__pyx_pw_9pywrapfst_57shortestpath(PyObject *__pyx_self, PyObje
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("shortestpath", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4136, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("shortestpath", 0, 1, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4167, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.shortestpath", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4136, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4167, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_56shortestpath(__pyx_self, __pyx_v_ifst, __pyx_v_delta, __pyx_v_nshortest, __pyx_v_nstate, __pyx_v_queue_type, __pyx_v_unique, __pyx_v_weight);
 
-  /* "pywrapfst.pyx":4136
+  /* "pywrapfst.pyx":4167
  * 
  * 
  * cpdef MutableFst shortestpath(Fst ifst,             # <<<<<<<<<<<<<<
@@ -42545,6 +43070,9 @@ static PyObject *__pyx_pf_9pywrapfst_56shortestpath(CYTHON_UNUSED PyObject *__py
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   struct __pyx_opt_args_9pywrapfst_shortestpath __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("shortestpath", 0);
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 6;
@@ -42554,7 +43082,7 @@ static PyObject *__pyx_pf_9pywrapfst_56shortestpath(CYTHON_UNUSED PyObject *__py
   __pyx_t_2.queue_type = __pyx_v_queue_type;
   __pyx_t_2.unique = __pyx_v_unique;
   __pyx_t_2.weight = __pyx_v_weight;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_shortestpath(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4136, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_shortestpath(__pyx_v_ifst, 0, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4167, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -42571,7 +43099,7 @@ static PyObject *__pyx_pf_9pywrapfst_56shortestpath(CYTHON_UNUSED PyObject *__py
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4188
+/* "pywrapfst.pyx":4221
  * 
  * 
  * cpdef Fst statemap(Fst ifst, map_type):             # <<<<<<<<<<<<<<
@@ -42585,9 +43113,12 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_statemap(struct __pyx
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   struct __pyx_opt_args_9pywrapfst__map __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("statemap", 0);
 
-  /* "pywrapfst.pyx":4211
+  /* "pywrapfst.pyx":4244
  *     FstArgError: Unknown map type.
  *   """
  *   return _map(ifst, fst.kDelta, map_type, 1., None)             # <<<<<<<<<<<<<<
@@ -42600,13 +43131,13 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_statemap(struct __pyx
   __pyx_t_2.map_type = __pyx_v_map_type;
   __pyx_t_2.power = 1.;
   __pyx_t_2.weight = Py_None;
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__map(__pyx_v_ifst, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4211, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__map(__pyx_v_ifst, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4244, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4188
+  /* "pywrapfst.pyx":4221
  * 
  * 
  * cpdef Fst statemap(Fst ifst, map_type):             # <<<<<<<<<<<<<<
@@ -42631,6 +43162,9 @@ static char __pyx_doc_9pywrapfst_58statemap[] = "\n  state_map(ifst, map_type)\n
 static PyObject *__pyx_pw_9pywrapfst_59statemap(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
   PyObject *__pyx_v_map_type = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("statemap (wrapper)", 0);
@@ -42657,11 +43191,11 @@ static PyObject *__pyx_pw_9pywrapfst_59statemap(PyObject *__pyx_self, PyObject *
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_map_type)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("statemap", 1, 2, 2, 1); __PYX_ERR(0, 4188, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("statemap", 1, 2, 2, 1); __PYX_ERR(0, 4221, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "statemap") < 0)) __PYX_ERR(0, 4188, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "statemap") < 0)) __PYX_ERR(0, 4221, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -42674,13 +43208,13 @@ static PyObject *__pyx_pw_9pywrapfst_59statemap(PyObject *__pyx_self, PyObject *
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("statemap", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4188, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("statemap", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4221, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.statemap", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4188, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4221, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_58statemap(__pyx_self, __pyx_v_ifst, __pyx_v_map_type);
 
   /* function exit code */
@@ -42696,9 +43230,12 @@ static PyObject *__pyx_pf_9pywrapfst_58statemap(CYTHON_UNUSED PyObject *__pyx_se
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("statemap", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_statemap(__pyx_v_ifst, __pyx_v_map_type, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4188, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_statemap(__pyx_v_ifst, __pyx_v_map_type, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4221, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -42715,7 +43252,7 @@ static PyObject *__pyx_pf_9pywrapfst_58statemap(CYTHON_UNUSED PyObject *__pyx_se
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4214
+/* "pywrapfst.pyx":4247
  * 
  * 
  * cpdef MutableFst synchronize(Fst ifst):             # <<<<<<<<<<<<<<
@@ -42725,53 +43262,56 @@ static PyObject *__pyx_pf_9pywrapfst_58statemap(CYTHON_UNUSED PyObject *__pyx_se
 
 static PyObject *__pyx_pw_9pywrapfst_61synchronize(PyObject *__pyx_self, PyObject *__pyx_v_ifst); /*proto*/
 static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_synchronize(struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst, CYTHON_UNUSED int __pyx_skip_dispatch) {
-  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v_tfst;
+  std::unique_ptr<fst::script::VectorFstClass>  __pyx_v__tfst;
   struct __pyx_obj_9pywrapfst_MutableFst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("synchronize", 0);
 
-  /* "pywrapfst.pyx":4234
+  /* "pywrapfst.pyx":4267
  *   """
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
- *   fst.Synchronize(deref(ifst._fst), tfst.get())
- *   return _init_MutableFst(tfst.release())
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))             # <<<<<<<<<<<<<<
+ *   fst.Synchronize(deref(ifst._fst), _tfst.get())
+ *   return _init_MutableFst(_tfst.release())
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "arc_type");
-    __PYX_ERR(0, 4234, __pyx_L1_error)
+    __PYX_ERR(0, 4267, __pyx_L1_error)
   }
-  __pyx_v_tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
+  __pyx_v__tfst.reset(new fst::script::VectorFstClass(((struct __pyx_vtabstruct_9pywrapfst_Fst *)__pyx_v_ifst->__pyx_vtab)->arc_type(__pyx_v_ifst, 0)));
 
-  /* "pywrapfst.pyx":4235
- *   cdef unique_ptr[fst.VectorFstClass] tfst
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
- *   fst.Synchronize(deref(ifst._fst), tfst.get())             # <<<<<<<<<<<<<<
- *   return _init_MutableFst(tfst.release())
+  /* "pywrapfst.pyx":4268
+ *   cdef unique_ptr[fst.VectorFstClass] _tfst
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+ *   fst.Synchronize(deref(ifst._fst), _tfst.get())             # <<<<<<<<<<<<<<
+ *   return _init_MutableFst(_tfst.release())
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 4235, __pyx_L1_error)
+    __PYX_ERR(0, 4268, __pyx_L1_error)
   }
-  fst::script::Synchronize((*__pyx_v_ifst->_fst), __pyx_v_tfst.get());
+  fst::script::Synchronize((*__pyx_v_ifst->_fst), __pyx_v__tfst.get());
 
-  /* "pywrapfst.pyx":4236
- *   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
- *   fst.Synchronize(deref(ifst._fst), tfst.get())
- *   return _init_MutableFst(tfst.release())             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":4269
+ *   _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+ *   fst.Synchronize(deref(ifst._fst), _tfst.get())
+ *   return _init_MutableFst(_tfst.release())             # <<<<<<<<<<<<<<
  * 
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4236, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_MutableFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4269, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_MutableFst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4214
+  /* "pywrapfst.pyx":4247
  * 
  * 
  * cpdef MutableFst synchronize(Fst ifst):             # <<<<<<<<<<<<<<
@@ -42794,10 +43334,13 @@ static struct __pyx_obj_9pywrapfst_MutableFst *__pyx_f_9pywrapfst_synchronize(st
 static PyObject *__pyx_pw_9pywrapfst_61synchronize(PyObject *__pyx_self, PyObject *__pyx_v_ifst); /*proto*/
 static char __pyx_doc_9pywrapfst_60synchronize[] = "\n  synchronize(ifst)\n\n  Constructively synchronizes an FST.\n\n  This operation synchronizes a transducer. The result will be an equivalent\n  FST that has the property that during the traversal of a path, the delay is\n  either zero or strictly increasing, where the delay is the difference between\n  the number of non-epsilon output labels and input labels along the path. For\n  the algorithm to terminate, the input transducer must have bounded delay,\n  i.e., the delay of every cycle must be zero.\n\n  Args:\n    ifst: The input FST.\n\n  Returns:\n    An equivalent synchronized FST.\n  ";
 static PyObject *__pyx_pw_9pywrapfst_61synchronize(PyObject *__pyx_self, PyObject *__pyx_v_ifst) {
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("synchronize (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4214, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4247, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_60synchronize(__pyx_self, ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_ifst));
 
   /* function exit code */
@@ -42813,9 +43356,12 @@ static PyObject *__pyx_pf_9pywrapfst_60synchronize(CYTHON_UNUSED PyObject *__pyx
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("synchronize", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_synchronize(__pyx_v_ifst, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4214, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_synchronize(__pyx_v_ifst, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4247, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -42832,19 +43378,19 @@ static PyObject *__pyx_pf_9pywrapfst_60synchronize(CYTHON_UNUSED PyObject *__pyx
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4293
+/* "pywrapfst.pyx":4326
  *   """
  * 
  *   def __cinit__(self,             # <<<<<<<<<<<<<<
- *                 string fst_type=b"vector",
- *                 string arc_type=b"standard",
+ *                 str fst_type="vector",
+ *                 str arc_type="standard",
  */
 
 /* Python wrapper */
 static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  std::string __pyx_v_fst_type;
-  std::string __pyx_v_arc_type;
+  PyObject *__pyx_v_fst_type = 0;
+  PyObject *__pyx_v_arc_type = 0;
   struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_isymbols = 0;
   struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_osymbols = 0;
   struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_ssymbols = 0;
@@ -42853,24 +43399,29 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
   bool __pyx_v_keep_osymbols;
   bool __pyx_v_keep_state_numbering;
   bool __pyx_v_allow_negative_labels;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
   {
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_fst_type,&__pyx_n_s_arc_type,&__pyx_n_s_isymbols,&__pyx_n_s_osymbols,&__pyx_n_s_ssymbols,&__pyx_n_s_acceptor,&__pyx_n_s_keep_isymbols,&__pyx_n_s_keep_osymbols,&__pyx_n_s_keep_state_numbering,&__pyx_n_s_allow_negative_labels,0};
     PyObject* values[10] = {0,0,0,0,0,0,0,0,0,0};
+    values[0] = ((PyObject*)__pyx_n_u_vector);
+    values[1] = ((PyObject*)__pyx_n_u_standard);
 
-    /* "pywrapfst.pyx":4296
- *                 string fst_type=b"vector",
- *                 string arc_type=b"standard",
+    /* "pywrapfst.pyx":4329
+ *                 str fst_type="vector",
+ *                 str arc_type="standard",
  *                 SymbolTable isymbols=None,             # <<<<<<<<<<<<<<
  *                 SymbolTable osymbols=None,
  *                 SymbolTable ssymbols=None,
  */
     values[2] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTable *)Py_None);
 
-    /* "pywrapfst.pyx":4297
- *                 string arc_type=b"standard",
+    /* "pywrapfst.pyx":4330
+ *                 str arc_type="standard",
  *                 SymbolTable isymbols=None,
  *                 SymbolTable osymbols=None,             # <<<<<<<<<<<<<<
  *                 SymbolTable ssymbols=None,
@@ -42878,7 +43429,7 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
  */
     values[3] = (PyObject *)((struct __pyx_obj_9pywrapfst_SymbolTable *)Py_None);
 
-    /* "pywrapfst.pyx":4298
+    /* "pywrapfst.pyx":4331
  *                 SymbolTable isymbols=None,
  *                 SymbolTable osymbols=None,
  *                 SymbolTable ssymbols=None,             # <<<<<<<<<<<<<<
@@ -42976,7 +43527,7 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 4293, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 4326, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -43004,24 +43555,16 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
         default: goto __pyx_L5_argtuple_error;
       }
     }
-    if (values[0]) {
-      __pyx_v_fst_type = __pyx_convert_string_from_py_std__in_string(values[0]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4294, __pyx_L3_error)
-    } else {
-      __pyx_v_fst_type = __pyx_k__51;
-    }
-    if (values[1]) {
-      __pyx_v_arc_type = __pyx_convert_string_from_py_std__in_string(values[1]); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4295, __pyx_L3_error)
-    } else {
-      __pyx_v_arc_type = __pyx_k__52;
-    }
+    __pyx_v_fst_type = ((PyObject*)values[0]);
+    __pyx_v_arc_type = ((PyObject*)values[1]);
     __pyx_v_isymbols = ((struct __pyx_obj_9pywrapfst_SymbolTable *)values[2]);
     __pyx_v_osymbols = ((struct __pyx_obj_9pywrapfst_SymbolTable *)values[3]);
     __pyx_v_ssymbols = ((struct __pyx_obj_9pywrapfst_SymbolTable *)values[4]);
     if (values[5]) {
-      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4299, __pyx_L3_error)
+      __pyx_v_acceptor = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_acceptor == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4332, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4299
+      /* "pywrapfst.pyx":4332
  *                 SymbolTable osymbols=None,
  *                 SymbolTable ssymbols=None,
  *                 bool acceptor=False,             # <<<<<<<<<<<<<<
@@ -43031,10 +43574,10 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
       __pyx_v_acceptor = ((bool)0);
     }
     if (values[6]) {
-      __pyx_v_keep_isymbols = __Pyx_PyObject_IsTrue(values[6]); if (unlikely((__pyx_v_keep_isymbols == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4300, __pyx_L3_error)
+      __pyx_v_keep_isymbols = __Pyx_PyObject_IsTrue(values[6]); if (unlikely((__pyx_v_keep_isymbols == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4333, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4300
+      /* "pywrapfst.pyx":4333
  *                 SymbolTable ssymbols=None,
  *                 bool acceptor=False,
  *                 bool keep_isymbols=False,             # <<<<<<<<<<<<<<
@@ -43044,10 +43587,10 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
       __pyx_v_keep_isymbols = ((bool)0);
     }
     if (values[7]) {
-      __pyx_v_keep_osymbols = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_keep_osymbols == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4301, __pyx_L3_error)
+      __pyx_v_keep_osymbols = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_keep_osymbols == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4334, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4301
+      /* "pywrapfst.pyx":4334
  *                 bool acceptor=False,
  *                 bool keep_isymbols=False,
  *                 bool keep_osymbols=False,             # <<<<<<<<<<<<<<
@@ -43057,10 +43600,10 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
       __pyx_v_keep_osymbols = ((bool)0);
     }
     if (values[8]) {
-      __pyx_v_keep_state_numbering = __Pyx_PyObject_IsTrue(values[8]); if (unlikely((__pyx_v_keep_state_numbering == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4302, __pyx_L3_error)
+      __pyx_v_keep_state_numbering = __Pyx_PyObject_IsTrue(values[8]); if (unlikely((__pyx_v_keep_state_numbering == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4335, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4302
+      /* "pywrapfst.pyx":4335
  *                 bool keep_isymbols=False,
  *                 bool keep_osymbols=False,
  *                 bool keep_state_numbering=False,             # <<<<<<<<<<<<<<
@@ -43070,10 +43613,10 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
       __pyx_v_keep_state_numbering = ((bool)0);
     }
     if (values[9]) {
-      __pyx_v_allow_negative_labels = __Pyx_PyObject_IsTrue(values[9]); if (unlikely((__pyx_v_allow_negative_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4303, __pyx_L3_error)
+      __pyx_v_allow_negative_labels = __Pyx_PyObject_IsTrue(values[9]); if (unlikely((__pyx_v_allow_negative_labels == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4336, __pyx_L3_error)
     } else {
 
-      /* "pywrapfst.pyx":4303
+      /* "pywrapfst.pyx":4336
  *                 bool keep_osymbols=False,
  *                 bool keep_state_numbering=False,
  *                 bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
@@ -43085,23 +43628,25 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 10, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4293, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 10, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4326, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.Compiler.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return -1;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "isymbols", 0))) __PYX_ERR(0, 4296, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 4297, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 4298, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fst_type), (&PyUnicode_Type), 1, "fst_type", 1))) __PYX_ERR(0, 4327, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_arc_type), (&PyUnicode_Type), 1, "arc_type", 1))) __PYX_ERR(0, 4328, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_isymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "isymbols", 0))) __PYX_ERR(0, 4329, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_osymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "osymbols", 0))) __PYX_ERR(0, 4330, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ssymbols), __pyx_ptype_9pywrapfst_SymbolTable, 1, "ssymbols", 0))) __PYX_ERR(0, 4331, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_8Compiler___cinit__(((struct __pyx_obj_9pywrapfst_Compiler *)__pyx_v_self), __pyx_v_fst_type, __pyx_v_arc_type, __pyx_v_isymbols, __pyx_v_osymbols, __pyx_v_ssymbols, __pyx_v_acceptor, __pyx_v_keep_isymbols, __pyx_v_keep_osymbols, __pyx_v_keep_state_numbering, __pyx_v_allow_negative_labels);
 
-  /* "pywrapfst.pyx":4293
+  /* "pywrapfst.pyx":4326
  *   """
  * 
  *   def __cinit__(self,             # <<<<<<<<<<<<<<
- *                 string fst_type=b"vector",
- *                 string arc_type=b"standard",
+ *                 str fst_type="vector",
+ *                 str arc_type="standard",
  */
 
   /* function exit code */
@@ -43113,17 +43658,19 @@ static int __pyx_pw_9pywrapfst_8Compiler_1__cinit__(PyObject *__pyx_v_self, PyOb
   return __pyx_r;
 }
 
-static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_Compiler *__pyx_v_self, std::string __pyx_v_fst_type, std::string __pyx_v_arc_type, struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_isymbols, struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_osymbols, struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_ssymbols, bool __pyx_v_acceptor, bool __pyx_v_keep_isymbols, bool __pyx_v_keep_osymbols, bool __pyx_v_keep_state_numbering, bool __pyx_v_allow_negative_labels) {
+static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_Compiler *__pyx_v_self, PyObject *__pyx_v_fst_type, PyObject *__pyx_v_arc_type, struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_isymbols, struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_osymbols, struct __pyx_obj_9pywrapfst_SymbolTable *__pyx_v_ssymbols, bool __pyx_v_acceptor, bool __pyx_v_keep_isymbols, bool __pyx_v_keep_osymbols, bool __pyx_v_keep_state_numbering, bool __pyx_v_allow_negative_labels) {
   int __pyx_r;
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  std::string __pyx_t_2;
+  std::string __pyx_t_1;
+  int __pyx_t_2;
   int __pyx_t_3;
-  int __pyx_t_4;
-  fst::SymbolTable const *__pyx_t_5;
+  fst::SymbolTable const *__pyx_t_4;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "pywrapfst.pyx":4304
+  /* "pywrapfst.pyx":4337
  *                 bool keep_state_numbering=False,
  *                 bool allow_negative_labels=False):
  *     self._sstrm.reset(new stringstream())             # <<<<<<<<<<<<<<
@@ -43132,45 +43679,39 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_sstrm");
-    __PYX_ERR(0, 4304, __pyx_L1_error)
+    __PYX_ERR(0, 4337, __pyx_L1_error)
   }
   __pyx_v_self->_sstrm.reset(new std::stringstream());
 
-  /* "pywrapfst.pyx":4305
+  /* "pywrapfst.pyx":4338
  *                 bool allow_negative_labels=False):
  *     self._sstrm.reset(new stringstream())
  *     self._fst_type = tostring(fst_type)             # <<<<<<<<<<<<<<
  *     self._arc_type = tostring(arc_type)
  *     self._isymbols = NULL
  */
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_fst_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4305, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4305, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_fst_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4338, __pyx_L1_error)
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst_type");
-    __PYX_ERR(0, 4305, __pyx_L1_error)
+    __PYX_ERR(0, 4338, __pyx_L1_error)
   }
-  __pyx_v_self->_fst_type = __pyx_t_2;
+  __pyx_v_self->_fst_type = __pyx_t_1;
 
-  /* "pywrapfst.pyx":4306
+  /* "pywrapfst.pyx":4339
  *     self._sstrm.reset(new stringstream())
  *     self._fst_type = tostring(fst_type)
  *     self._arc_type = tostring(arc_type)             # <<<<<<<<<<<<<<
  *     self._isymbols = NULL
  *     if isymbols is not None:
  */
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4306, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4306, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4339, __pyx_L1_error)
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc_type");
-    __PYX_ERR(0, 4306, __pyx_L1_error)
+    __PYX_ERR(0, 4339, __pyx_L1_error)
   }
-  __pyx_v_self->_arc_type = __pyx_t_2;
+  __pyx_v_self->_arc_type = __pyx_t_1;
 
-  /* "pywrapfst.pyx":4307
+  /* "pywrapfst.pyx":4340
  *     self._fst_type = tostring(fst_type)
  *     self._arc_type = tostring(arc_type)
  *     self._isymbols = NULL             # <<<<<<<<<<<<<<
@@ -43179,22 +43720,22 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_isymbols");
-    __PYX_ERR(0, 4307, __pyx_L1_error)
+    __PYX_ERR(0, 4340, __pyx_L1_error)
   }
   __pyx_v_self->_isymbols = NULL;
 
-  /* "pywrapfst.pyx":4308
+  /* "pywrapfst.pyx":4341
  *     self._arc_type = tostring(arc_type)
  *     self._isymbols = NULL
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
  *       self._isymbols = isymbols._raw_ptr_or_raise()
  *     self._osymbols = NULL
  */
-  __pyx_t_3 = (((PyObject *)__pyx_v_isymbols) != Py_None);
-  __pyx_t_4 = (__pyx_t_3 != 0);
-  if (__pyx_t_4) {
+  __pyx_t_2 = (((PyObject *)__pyx_v_isymbols) != Py_None);
+  __pyx_t_3 = (__pyx_t_2 != 0);
+  if (__pyx_t_3) {
 
-    /* "pywrapfst.pyx":4309
+    /* "pywrapfst.pyx":4342
  *     self._isymbols = NULL
  *     if isymbols is not None:
  *       self._isymbols = isymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -43203,16 +43744,16 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
     if (unlikely(((PyObject *)__pyx_v_isymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 4309, __pyx_L1_error)
+      __PYX_ERR(0, 4342, __pyx_L1_error)
     }
-    __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTable *)__pyx_v_isymbols->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base._raw_ptr_or_raise(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_isymbols)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4309, __pyx_L1_error)
+    __pyx_t_4 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTable *)__pyx_v_isymbols->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base._raw_ptr_or_raise(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_isymbols)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4342, __pyx_L1_error)
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_isymbols");
-      __PYX_ERR(0, 4309, __pyx_L1_error)
+      __PYX_ERR(0, 4342, __pyx_L1_error)
     }
-    __pyx_v_self->_isymbols = __pyx_t_5;
+    __pyx_v_self->_isymbols = __pyx_t_4;
 
-    /* "pywrapfst.pyx":4308
+    /* "pywrapfst.pyx":4341
  *     self._arc_type = tostring(arc_type)
  *     self._isymbols = NULL
  *     if isymbols is not None:             # <<<<<<<<<<<<<<
@@ -43221,7 +43762,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   }
 
-  /* "pywrapfst.pyx":4310
+  /* "pywrapfst.pyx":4343
  *     if isymbols is not None:
  *       self._isymbols = isymbols._raw_ptr_or_raise()
  *     self._osymbols = NULL             # <<<<<<<<<<<<<<
@@ -43230,22 +43771,22 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_osymbols");
-    __PYX_ERR(0, 4310, __pyx_L1_error)
+    __PYX_ERR(0, 4343, __pyx_L1_error)
   }
   __pyx_v_self->_osymbols = NULL;
 
-  /* "pywrapfst.pyx":4311
+  /* "pywrapfst.pyx":4344
  *       self._isymbols = isymbols._raw_ptr_or_raise()
  *     self._osymbols = NULL
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
  *       self._osymbols = osymbols._raw_ptr_or_raise()
  *     self._ssymbols = NULL
  */
-  __pyx_t_4 = (((PyObject *)__pyx_v_osymbols) != Py_None);
-  __pyx_t_3 = (__pyx_t_4 != 0);
-  if (__pyx_t_3) {
+  __pyx_t_3 = (((PyObject *)__pyx_v_osymbols) != Py_None);
+  __pyx_t_2 = (__pyx_t_3 != 0);
+  if (__pyx_t_2) {
 
-    /* "pywrapfst.pyx":4312
+    /* "pywrapfst.pyx":4345
  *     self._osymbols = NULL
  *     if osymbols is not None:
  *       self._osymbols = osymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -43254,16 +43795,16 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
     if (unlikely(((PyObject *)__pyx_v_osymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 4312, __pyx_L1_error)
+      __PYX_ERR(0, 4345, __pyx_L1_error)
     }
-    __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTable *)__pyx_v_osymbols->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base._raw_ptr_or_raise(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_osymbols)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4312, __pyx_L1_error)
+    __pyx_t_4 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTable *)__pyx_v_osymbols->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base._raw_ptr_or_raise(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_osymbols)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4345, __pyx_L1_error)
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_osymbols");
-      __PYX_ERR(0, 4312, __pyx_L1_error)
+      __PYX_ERR(0, 4345, __pyx_L1_error)
     }
-    __pyx_v_self->_osymbols = __pyx_t_5;
+    __pyx_v_self->_osymbols = __pyx_t_4;
 
-    /* "pywrapfst.pyx":4311
+    /* "pywrapfst.pyx":4344
  *       self._isymbols = isymbols._raw_ptr_or_raise()
  *     self._osymbols = NULL
  *     if osymbols is not None:             # <<<<<<<<<<<<<<
@@ -43272,7 +43813,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   }
 
-  /* "pywrapfst.pyx":4313
+  /* "pywrapfst.pyx":4346
  *     if osymbols is not None:
  *       self._osymbols = osymbols._raw_ptr_or_raise()
  *     self._ssymbols = NULL             # <<<<<<<<<<<<<<
@@ -43281,22 +43822,22 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_ssymbols");
-    __PYX_ERR(0, 4313, __pyx_L1_error)
+    __PYX_ERR(0, 4346, __pyx_L1_error)
   }
   __pyx_v_self->_ssymbols = NULL;
 
-  /* "pywrapfst.pyx":4314
+  /* "pywrapfst.pyx":4347
  *       self._osymbols = osymbols._raw_ptr_or_raise()
  *     self._ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
  *       self._ssymbols = ssymbols._raw_ptr_or_raise()
  *     self._acceptor = acceptor
  */
-  __pyx_t_3 = (((PyObject *)__pyx_v_ssymbols) != Py_None);
-  __pyx_t_4 = (__pyx_t_3 != 0);
-  if (__pyx_t_4) {
+  __pyx_t_2 = (((PyObject *)__pyx_v_ssymbols) != Py_None);
+  __pyx_t_3 = (__pyx_t_2 != 0);
+  if (__pyx_t_3) {
 
-    /* "pywrapfst.pyx":4315
+    /* "pywrapfst.pyx":4348
  *     self._ssymbols = NULL
  *     if ssymbols is not None:
  *       self._ssymbols = ssymbols._raw_ptr_or_raise()             # <<<<<<<<<<<<<<
@@ -43305,16 +43846,16 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
     if (unlikely(((PyObject *)__pyx_v_ssymbols) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_raw_ptr_or_raise");
-      __PYX_ERR(0, 4315, __pyx_L1_error)
+      __PYX_ERR(0, 4348, __pyx_L1_error)
     }
-    __pyx_t_5 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTable *)__pyx_v_ssymbols->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base._raw_ptr_or_raise(((struct __pyx_obj_9pywrapfst__SymbolTable *)__pyx_v_ssymbols)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4315, __pyx_L1_error)
+    __pyx_t_4 = ((struct __pyx_vtabstruct_9pywrapfst_SymbolTable *)__pyx_v_ssymbols->__pyx_base.__pyx_base.__pyx_vtab)->__pyx_base.__pyx_base._raw_ptr_or_raise(((struct __pyx_obj_9pywrapfst_SymbolTableView *)__pyx_v_ssymbols)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4348, __pyx_L1_error)
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_ssymbols");
-      __PYX_ERR(0, 4315, __pyx_L1_error)
+      __PYX_ERR(0, 4348, __pyx_L1_error)
     }
-    __pyx_v_self->_ssymbols = __pyx_t_5;
+    __pyx_v_self->_ssymbols = __pyx_t_4;
 
-    /* "pywrapfst.pyx":4314
+    /* "pywrapfst.pyx":4347
  *       self._osymbols = osymbols._raw_ptr_or_raise()
  *     self._ssymbols = NULL
  *     if ssymbols is not None:             # <<<<<<<<<<<<<<
@@ -43323,7 +43864,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   }
 
-  /* "pywrapfst.pyx":4316
+  /* "pywrapfst.pyx":4349
  *     if ssymbols is not None:
  *       self._ssymbols = ssymbols._raw_ptr_or_raise()
  *     self._acceptor = acceptor             # <<<<<<<<<<<<<<
@@ -43332,11 +43873,11 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_acceptor");
-    __PYX_ERR(0, 4316, __pyx_L1_error)
+    __PYX_ERR(0, 4349, __pyx_L1_error)
   }
   __pyx_v_self->_acceptor = __pyx_v_acceptor;
 
-  /* "pywrapfst.pyx":4317
+  /* "pywrapfst.pyx":4350
  *       self._ssymbols = ssymbols._raw_ptr_or_raise()
  *     self._acceptor = acceptor
  *     self._keep_isymbols = keep_isymbols             # <<<<<<<<<<<<<<
@@ -43345,11 +43886,11 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_isymbols");
-    __PYX_ERR(0, 4317, __pyx_L1_error)
+    __PYX_ERR(0, 4350, __pyx_L1_error)
   }
   __pyx_v_self->_keep_isymbols = __pyx_v_keep_isymbols;
 
-  /* "pywrapfst.pyx":4318
+  /* "pywrapfst.pyx":4351
  *     self._acceptor = acceptor
  *     self._keep_isymbols = keep_isymbols
  *     self._keep_osymbols = keep_osymbols             # <<<<<<<<<<<<<<
@@ -43358,11 +43899,11 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_osymbols");
-    __PYX_ERR(0, 4318, __pyx_L1_error)
+    __PYX_ERR(0, 4351, __pyx_L1_error)
   }
   __pyx_v_self->_keep_osymbols = __pyx_v_keep_osymbols;
 
-  /* "pywrapfst.pyx":4319
+  /* "pywrapfst.pyx":4352
  *     self._keep_isymbols = keep_isymbols
  *     self._keep_osymbols = keep_osymbols
  *     self._keep_state_numbering = keep_state_numbering             # <<<<<<<<<<<<<<
@@ -43371,11 +43912,11 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_state_numbering");
-    __PYX_ERR(0, 4319, __pyx_L1_error)
+    __PYX_ERR(0, 4352, __pyx_L1_error)
   }
   __pyx_v_self->_keep_state_numbering = __pyx_v_keep_state_numbering;
 
-  /* "pywrapfst.pyx":4320
+  /* "pywrapfst.pyx":4353
  *     self._keep_osymbols = keep_osymbols
  *     self._keep_state_numbering = keep_state_numbering
  *     self._allow_negative_labels = allow_negative_labels             # <<<<<<<<<<<<<<
@@ -43384,23 +43925,22 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_allow_negative_labels");
-    __PYX_ERR(0, 4320, __pyx_L1_error)
+    __PYX_ERR(0, 4353, __pyx_L1_error)
   }
   __pyx_v_self->_allow_negative_labels = __pyx_v_allow_negative_labels;
 
-  /* "pywrapfst.pyx":4293
+  /* "pywrapfst.pyx":4326
  *   """
  * 
  *   def __cinit__(self,             # <<<<<<<<<<<<<<
- *                 string fst_type=b"vector",
- *                 string arc_type=b"standard",
+ *                 str fst_type="vector",
+ *                 str arc_type="standard",
  */
 
   /* function exit code */
   __pyx_r = 0;
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
   __Pyx_AddTraceback("pywrapfst.Compiler.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = -1;
   __pyx_L0:;
@@ -43408,7 +43948,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4322
+/* "pywrapfst.pyx":4355
  *     self._allow_negative_labels = allow_negative_labels
  * 
  *   cpdef Fst compile(self):             # <<<<<<<<<<<<<<
@@ -43418,7 +43958,7 @@ static int __pyx_pf_9pywrapfst_8Compiler___cinit__(struct __pyx_obj_9pywrapfst_C
 
 static PyObject *__pyx_pw_9pywrapfst_8Compiler_3compile(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
 static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_8Compiler_compile(struct __pyx_obj_9pywrapfst_Compiler *__pyx_v_self, int __pyx_skip_dispatch) {
-  std::unique_ptr<fst::script::FstClass>  __pyx_v_tfst;
+  std::unique_ptr<fst::script::FstClass>  __pyx_v__tfst;
   struct __pyx_obj_9pywrapfst_Fst *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
@@ -43426,6 +43966,9 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_8Compiler_compile(str
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   int __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("compile", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -43436,7 +43979,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_8Compiler_compile(str
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_compile); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4322, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_compile); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4355, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_8Compiler_3compile)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -43453,10 +43996,10 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_8Compiler_compile(str
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4322, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4355, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 4322, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 4355, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -43475,178 +44018,178 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_8Compiler_compile(str
     #endif
   }
 
-  /* "pywrapfst.pyx":4337
+  /* "pywrapfst.pyx":4370
  *     """
- *     cdef unique_ptr[fst.FstClass] tfst
- *     tfst.reset(fst.CompileFstInternal(deref(self._sstrm),             # <<<<<<<<<<<<<<
- *                                       b"<pywrapfst>",
- *                                       self._fst_type,
+ *     cdef unique_ptr[fst.FstClass] _tfst
+ *     _tfst.reset(fst.CompileFstInternal(deref(self._sstrm),             # <<<<<<<<<<<<<<
+ *                                        b"<pywrapfst>",
+ *                                        self._fst_type,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_sstrm");
-    __PYX_ERR(0, 4337, __pyx_L1_error)
+    __PYX_ERR(0, 4370, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4339
- *     tfst.reset(fst.CompileFstInternal(deref(self._sstrm),
- *                                       b"<pywrapfst>",
- *                                       self._fst_type,             # <<<<<<<<<<<<<<
- *                                       self._arc_type,
- *                                       self._isymbols,
+  /* "pywrapfst.pyx":4372
+ *     _tfst.reset(fst.CompileFstInternal(deref(self._sstrm),
+ *                                        b"<pywrapfst>",
+ *                                        self._fst_type,             # <<<<<<<<<<<<<<
+ *                                        self._arc_type,
+ *                                        self._isymbols,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst_type");
-    __PYX_ERR(0, 4339, __pyx_L1_error)
+    __PYX_ERR(0, 4372, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4340
- *                                       b"<pywrapfst>",
- *                                       self._fst_type,
- *                                       self._arc_type,             # <<<<<<<<<<<<<<
- *                                       self._isymbols,
- *                                       self._osymbols,
+  /* "pywrapfst.pyx":4373
+ *                                        b"<pywrapfst>",
+ *                                        self._fst_type,
+ *                                        self._arc_type,             # <<<<<<<<<<<<<<
+ *                                        self._isymbols,
+ *                                        self._osymbols,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_arc_type");
-    __PYX_ERR(0, 4340, __pyx_L1_error)
+    __PYX_ERR(0, 4373, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4341
- *                                       self._fst_type,
- *                                       self._arc_type,
- *                                       self._isymbols,             # <<<<<<<<<<<<<<
- *                                       self._osymbols,
- *                                       self._ssymbols,
+  /* "pywrapfst.pyx":4374
+ *                                        self._fst_type,
+ *                                        self._arc_type,
+ *                                        self._isymbols,             # <<<<<<<<<<<<<<
+ *                                        self._osymbols,
+ *                                        self._ssymbols,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_isymbols");
-    __PYX_ERR(0, 4341, __pyx_L1_error)
+    __PYX_ERR(0, 4374, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4342
- *                                       self._arc_type,
- *                                       self._isymbols,
- *                                       self._osymbols,             # <<<<<<<<<<<<<<
- *                                       self._ssymbols,
- *                                       self._acceptor,
+  /* "pywrapfst.pyx":4375
+ *                                        self._arc_type,
+ *                                        self._isymbols,
+ *                                        self._osymbols,             # <<<<<<<<<<<<<<
+ *                                        self._ssymbols,
+ *                                        self._acceptor,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_osymbols");
-    __PYX_ERR(0, 4342, __pyx_L1_error)
+    __PYX_ERR(0, 4375, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4343
- *                                       self._isymbols,
- *                                       self._osymbols,
- *                                       self._ssymbols,             # <<<<<<<<<<<<<<
- *                                       self._acceptor,
- *                                       self._keep_isymbols,
+  /* "pywrapfst.pyx":4376
+ *                                        self._isymbols,
+ *                                        self._osymbols,
+ *                                        self._ssymbols,             # <<<<<<<<<<<<<<
+ *                                        self._acceptor,
+ *                                        self._keep_isymbols,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_ssymbols");
-    __PYX_ERR(0, 4343, __pyx_L1_error)
+    __PYX_ERR(0, 4376, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4344
- *                                       self._osymbols,
- *                                       self._ssymbols,
- *                                       self._acceptor,             # <<<<<<<<<<<<<<
- *                                       self._keep_isymbols,
- *                                       self._keep_osymbols,
+  /* "pywrapfst.pyx":4377
+ *                                        self._osymbols,
+ *                                        self._ssymbols,
+ *                                        self._acceptor,             # <<<<<<<<<<<<<<
+ *                                        self._keep_isymbols,
+ *                                        self._keep_osymbols,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_acceptor");
-    __PYX_ERR(0, 4344, __pyx_L1_error)
+    __PYX_ERR(0, 4377, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4345
- *                                       self._ssymbols,
- *                                       self._acceptor,
- *                                       self._keep_isymbols,             # <<<<<<<<<<<<<<
- *                                       self._keep_osymbols,
- *                                       self._keep_state_numbering,
+  /* "pywrapfst.pyx":4378
+ *                                        self._ssymbols,
+ *                                        self._acceptor,
+ *                                        self._keep_isymbols,             # <<<<<<<<<<<<<<
+ *                                        self._keep_osymbols,
+ *                                        self._keep_state_numbering,
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_isymbols");
-    __PYX_ERR(0, 4345, __pyx_L1_error)
+    __PYX_ERR(0, 4378, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4346
- *                                       self._acceptor,
- *                                       self._keep_isymbols,
- *                                       self._keep_osymbols,             # <<<<<<<<<<<<<<
- *                                       self._keep_state_numbering,
- *                                       self._allow_negative_labels))
+  /* "pywrapfst.pyx":4379
+ *                                        self._acceptor,
+ *                                        self._keep_isymbols,
+ *                                        self._keep_osymbols,             # <<<<<<<<<<<<<<
+ *                                        self._keep_state_numbering,
+ *                                        self._allow_negative_labels))
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_osymbols");
-    __PYX_ERR(0, 4346, __pyx_L1_error)
+    __PYX_ERR(0, 4379, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4347
- *                                       self._keep_isymbols,
- *                                       self._keep_osymbols,
- *                                       self._keep_state_numbering,             # <<<<<<<<<<<<<<
- *                                       self._allow_negative_labels))
+  /* "pywrapfst.pyx":4380
+ *                                        self._keep_isymbols,
+ *                                        self._keep_osymbols,
+ *                                        self._keep_state_numbering,             # <<<<<<<<<<<<<<
+ *                                        self._allow_negative_labels))
  *     self._sstrm.reset(new stringstream())
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_keep_state_numbering");
-    __PYX_ERR(0, 4347, __pyx_L1_error)
+    __PYX_ERR(0, 4380, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4348
- *                                       self._keep_osymbols,
- *                                       self._keep_state_numbering,
- *                                       self._allow_negative_labels))             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":4381
+ *                                        self._keep_osymbols,
+ *                                        self._keep_state_numbering,
+ *                                        self._allow_negative_labels))             # <<<<<<<<<<<<<<
  *     self._sstrm.reset(new stringstream())
- *     if tfst.get() == NULL:
+ *     if _tfst.get() == NULL:
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_allow_negative_labels");
-    __PYX_ERR(0, 4348, __pyx_L1_error)
+    __PYX_ERR(0, 4381, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4337
+  /* "pywrapfst.pyx":4370
  *     """
- *     cdef unique_ptr[fst.FstClass] tfst
- *     tfst.reset(fst.CompileFstInternal(deref(self._sstrm),             # <<<<<<<<<<<<<<
- *                                       b"<pywrapfst>",
- *                                       self._fst_type,
+ *     cdef unique_ptr[fst.FstClass] _tfst
+ *     _tfst.reset(fst.CompileFstInternal(deref(self._sstrm),             # <<<<<<<<<<<<<<
+ *                                        b"<pywrapfst>",
+ *                                        self._fst_type,
  */
-  __pyx_v_tfst.reset(fst::script::CompileFstInternal((*__pyx_v_self->_sstrm), __pyx_k_pywrapfst, __pyx_v_self->_fst_type, __pyx_v_self->_arc_type, __pyx_v_self->_isymbols, __pyx_v_self->_osymbols, __pyx_v_self->_ssymbols, __pyx_v_self->_acceptor, __pyx_v_self->_keep_isymbols, __pyx_v_self->_keep_osymbols, __pyx_v_self->_keep_state_numbering, __pyx_v_self->_allow_negative_labels));
+  __pyx_v__tfst.reset(fst::script::CompileFstInternal((*__pyx_v_self->_sstrm), __pyx_k_pywrapfst, __pyx_v_self->_fst_type, __pyx_v_self->_arc_type, __pyx_v_self->_isymbols, __pyx_v_self->_osymbols, __pyx_v_self->_ssymbols, __pyx_v_self->_acceptor, __pyx_v_self->_keep_isymbols, __pyx_v_self->_keep_osymbols, __pyx_v_self->_keep_state_numbering, __pyx_v_self->_allow_negative_labels));
 
-  /* "pywrapfst.pyx":4349
- *                                       self._keep_state_numbering,
- *                                       self._allow_negative_labels))
+  /* "pywrapfst.pyx":4382
+ *                                        self._keep_state_numbering,
+ *                                        self._allow_negative_labels))
  *     self._sstrm.reset(new stringstream())             # <<<<<<<<<<<<<<
- *     if tfst.get() == NULL:
+ *     if _tfst.get() == NULL:
  *       raise FstOpError("Compilation failed")
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_sstrm");
-    __PYX_ERR(0, 4349, __pyx_L1_error)
+    __PYX_ERR(0, 4382, __pyx_L1_error)
   }
   __pyx_v_self->_sstrm.reset(new std::stringstream());
 
-  /* "pywrapfst.pyx":4350
- *                                       self._allow_negative_labels))
+  /* "pywrapfst.pyx":4383
+ *                                        self._allow_negative_labels))
  *     self._sstrm.reset(new stringstream())
- *     if tfst.get() == NULL:             # <<<<<<<<<<<<<<
+ *     if _tfst.get() == NULL:             # <<<<<<<<<<<<<<
  *       raise FstOpError("Compilation failed")
- *     return _init_XFst(tfst.release())
+ *     return _init_XFst(_tfst.release())
  */
-  __pyx_t_5 = ((__pyx_v_tfst.get() == NULL) != 0);
+  __pyx_t_5 = ((__pyx_v__tfst.get() == NULL) != 0);
   if (unlikely(__pyx_t_5)) {
 
-    /* "pywrapfst.pyx":4351
+    /* "pywrapfst.pyx":4384
  *     self._sstrm.reset(new stringstream())
- *     if tfst.get() == NULL:
+ *     if _tfst.get() == NULL:
  *       raise FstOpError("Compilation failed")             # <<<<<<<<<<<<<<
- *     return _init_XFst(tfst.release())
+ *     return _init_XFst(_tfst.release())
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4351, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4384, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -43660,37 +44203,37 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_8Compiler_compile(str
     }
     __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_kp_u_Compilation_failed) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_Compilation_failed);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4351, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4384, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 4351, __pyx_L1_error)
+    __PYX_ERR(0, 4384, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4350
- *                                       self._allow_negative_labels))
+    /* "pywrapfst.pyx":4383
+ *                                        self._allow_negative_labels))
  *     self._sstrm.reset(new stringstream())
- *     if tfst.get() == NULL:             # <<<<<<<<<<<<<<
+ *     if _tfst.get() == NULL:             # <<<<<<<<<<<<<<
  *       raise FstOpError("Compilation failed")
- *     return _init_XFst(tfst.release())
+ *     return _init_XFst(_tfst.release())
  */
   }
 
-  /* "pywrapfst.pyx":4352
- *     if tfst.get() == NULL:
+  /* "pywrapfst.pyx":4385
+ *     if _tfst.get() == NULL:
  *       raise FstOpError("Compilation failed")
- *     return _init_XFst(tfst.release())             # <<<<<<<<<<<<<<
+ *     return _init_XFst(_tfst.release())             # <<<<<<<<<<<<<<
  * 
  *   cpdef void write(self, expression):
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v_tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4352, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(__pyx_v__tfst.release())); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4385, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4322
+  /* "pywrapfst.pyx":4355
  *     self._allow_negative_labels = allow_negative_labels
  * 
  *   cpdef Fst compile(self):             # <<<<<<<<<<<<<<
@@ -43730,9 +44273,12 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_2compile(struct __pyx_obj_9pywrap
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("compile", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_8Compiler_compile(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4322, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_8Compiler_compile(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4355, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -43749,8 +44295,8 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_2compile(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4354
- *     return _init_XFst(tfst.release())
+/* "pywrapfst.pyx":4387
+ *     return _init_XFst(_tfst.release())
  * 
  *   cpdef void write(self, expression):             # <<<<<<<<<<<<<<
  *     """
@@ -43759,7 +44305,7 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_2compile(struct __pyx_obj_9pywrap
 
 static PyObject *__pyx_pw_9pywrapfst_8Compiler_5write(PyObject *__pyx_v_self, PyObject *__pyx_v_expression); /*proto*/
 static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compiler *__pyx_v_self, PyObject *__pyx_v_expression, int __pyx_skip_dispatch) {
-  std::string __pyx_v_line;
+  std::string __pyx_v__line;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
@@ -43768,6 +44314,9 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
   std::string __pyx_t_5;
   int __pyx_t_6;
   int __pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -43778,7 +44327,7 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4354, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_write); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4387, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_8Compiler_5write)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -43794,7 +44343,7 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_expression) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_expression);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4354, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4387, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -43814,67 +44363,67 @@ static void __pyx_f_9pywrapfst_8Compiler_write(struct __pyx_obj_9pywrapfst_Compi
     #endif
   }
 
-  /* "pywrapfst.pyx":4370
+  /* "pywrapfst.pyx":4403
  *       expression: A string expression to add to compiler string buffer.
  *     """
- *     cdef string line = tostring(expression)             # <<<<<<<<<<<<<<
- *     if not line.empty() and line.back() != b'\n':
- *       line.append(b'\n')
+ *     cdef string _line = tostring(expression)             # <<<<<<<<<<<<<<
+ *     if not _line.empty() and _line.back() != b'\n':
+ *       _line.append(b'\n')
  */
-  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_expression); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4370, __pyx_L1_error)
-  __pyx_v_line = __pyx_t_5;
+  __pyx_t_5 = __pyx_f_9pywrapfst_tostring(__pyx_v_expression); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4403, __pyx_L1_error)
+  __pyx_v__line = __pyx_t_5;
 
-  /* "pywrapfst.pyx":4371
+  /* "pywrapfst.pyx":4404
  *     """
- *     cdef string line = tostring(expression)
- *     if not line.empty() and line.back() != b'\n':             # <<<<<<<<<<<<<<
- *       line.append(b'\n')
- *     deref(self._sstrm) << line
+ *     cdef string _line = tostring(expression)
+ *     if not _line.empty() and _line.back() != b'\n':             # <<<<<<<<<<<<<<
+ *       _line.append(b'\n')
+ *     deref(self._sstrm) << _line
  */
-  __pyx_t_7 = ((!(__pyx_v_line.empty() != 0)) != 0);
+  __pyx_t_7 = ((!(__pyx_v__line.empty() != 0)) != 0);
   if (__pyx_t_7) {
   } else {
     __pyx_t_6 = __pyx_t_7;
     goto __pyx_L4_bool_binop_done;
   }
-  __pyx_t_7 = ((__pyx_v_line.back() != '\n') != 0);
+  __pyx_t_7 = ((__pyx_v__line.back() != '\n') != 0);
   __pyx_t_6 = __pyx_t_7;
   __pyx_L4_bool_binop_done:;
   if (__pyx_t_6) {
 
-    /* "pywrapfst.pyx":4372
- *     cdef string line = tostring(expression)
- *     if not line.empty() and line.back() != b'\n':
- *       line.append(b'\n')             # <<<<<<<<<<<<<<
- *     deref(self._sstrm) << line
+    /* "pywrapfst.pyx":4405
+ *     cdef string _line = tostring(expression)
+ *     if not _line.empty() and _line.back() != b'\n':
+ *       _line.append(b'\n')             # <<<<<<<<<<<<<<
+ *     deref(self._sstrm) << _line
  * 
  */
-    (void)(__pyx_v_line.append(((char const *)"\n")));
+    (void)(__pyx_v__line.append(((char const *)"\n")));
 
-    /* "pywrapfst.pyx":4371
+    /* "pywrapfst.pyx":4404
  *     """
- *     cdef string line = tostring(expression)
- *     if not line.empty() and line.back() != b'\n':             # <<<<<<<<<<<<<<
- *       line.append(b'\n')
- *     deref(self._sstrm) << line
+ *     cdef string _line = tostring(expression)
+ *     if not _line.empty() and _line.back() != b'\n':             # <<<<<<<<<<<<<<
+ *       _line.append(b'\n')
+ *     deref(self._sstrm) << _line
  */
   }
 
-  /* "pywrapfst.pyx":4373
- *     if not line.empty() and line.back() != b'\n':
- *       line.append(b'\n')
- *     deref(self._sstrm) << line             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":4406
+ *     if not _line.empty() and _line.back() != b'\n':
+ *       _line.append(b'\n')
+ *     deref(self._sstrm) << _line             # <<<<<<<<<<<<<<
  * 
  * 
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_sstrm");
-    __PYX_ERR(0, 4373, __pyx_L1_error)
+    __PYX_ERR(0, 4406, __pyx_L1_error)
   }
-  (void)(((*__pyx_v_self->_sstrm) << __pyx_v_line));
+  (void)(((*__pyx_v_self->_sstrm) << __pyx_v__line));
 
-  /* "pywrapfst.pyx":4354
- *     return _init_XFst(tfst.release())
+  /* "pywrapfst.pyx":4387
+ *     return _init_XFst(_tfst.release())
  * 
  *   cpdef void write(self, expression):             # <<<<<<<<<<<<<<
  *     """
@@ -43911,9 +44460,12 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_4write(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("write", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_8Compiler_write(__pyx_v_self, __pyx_v_expression, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4354, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_8Compiler_write(__pyx_v_self, __pyx_v_expression, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4387, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -43953,6 +44505,9 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_6__reduce_cython__(CYTHON_UNUSED
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__reduce_cython__", 0);
 
   /* "(tree fragment)":2
@@ -44007,6 +44562,9 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_8__setstate_cython__(CYTHON_UNUSE
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__setstate_cython__", 0);
 
   /* "(tree fragment)":4
@@ -44037,12 +44595,12 @@ static PyObject *__pyx_pf_9pywrapfst_8Compiler_8__setstate_cython__(CYTHON_UNUSE
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4395
+/* "pywrapfst.pyx":4428
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
- *     raise FstDeletedConstructorError(
- *         "Cannot construct {}".format(self.__class__.__name__))
+ *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")
+ * 
  */
 
 /* Python wrapper */
@@ -44066,99 +44624,59 @@ static int __pyx_pf_9pywrapfst_9FarReader___init__(struct __pyx_obj_9pywrapfst_F
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":4396
- * 
- *   def __init__(self):
- *     raise FstDeletedConstructorError(             # <<<<<<<<<<<<<<
- *         "Cannot construct {}".format(self.__class__.__name__))
+  /* "pywrapfst.pyx":4429
  * 
- */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4396, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-
-  /* "pywrapfst.pyx":4397
  *   def __init__(self):
- *     raise FstDeletedConstructorError(
- *         "Cannot construct {}".format(self.__class__.__name__))             # <<<<<<<<<<<<<<
+ *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")             # <<<<<<<<<<<<<<
  * 
  *   def __repr__(self):
  */
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4397, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4397, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_name); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4397, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = NULL;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) {
-    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
-    if (likely(__pyx_t_5)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-      __Pyx_INCREF(__pyx_t_5);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_4, function);
-    }
-  }
-  __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4397, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = NULL;
-  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
-    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
-    if (likely(__pyx_t_4)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-      __Pyx_INCREF(__pyx_t_4);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_2, function);
-    }
-  }
-  __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4396, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4429, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4429, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_t_2, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4429, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Cannot_construct, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4429, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_NotImplementedError, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4429, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(0, 4396, __pyx_L1_error)
+  __PYX_ERR(0, 4429, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4395
+  /* "pywrapfst.pyx":4428
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
- *     raise FstDeletedConstructorError(
- *         "Cannot construct {}".format(self.__class__.__name__))
+ *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")
+ * 
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
   __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
   __Pyx_AddTraceback("pywrapfst.FarReader.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = -1;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4399
- *         "Cannot construct {}".format(self.__class__.__name__))
+/* "pywrapfst.pyx":4431
+ *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<{} FarReader at 0x{:x}>".format(self.far_type(), id(self))
+ *     return f"<{self.far_type()} FarReader at 0x{id(self):x}>"
  * 
  */
 
@@ -44179,101 +44697,80 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_2;
+  Py_UCS4 __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
-  int __pyx_t_6;
-  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":4400
+  /* "pywrapfst.pyx":4432
  * 
  *   def __repr__(self):
- *     return "<{} FarReader at 0x{:x}>".format(self.far_type(), id(self))             # <<<<<<<<<<<<<<
+ *     return f"<{self.far_type()} FarReader at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
  * 
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_FarReader_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4400, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4432, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 127;
+  __Pyx_INCREF(__pyx_kp_u__2);
+  __pyx_t_2 += 1;
+  __Pyx_GIVEREF(__pyx_kp_u__2);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u__2);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "far_type");
-    __PYX_ERR(0, 4400, __pyx_L1_error)
+    __PYX_ERR(0, 4432, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->far_type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4400, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4400, __pyx_L1_error)
+  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->far_type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4432, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = NULL;
-  __pyx_t_6 = 0;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
-    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2);
-    if (likely(__pyx_t_5)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-      __Pyx_INCREF(__pyx_t_5);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_2, function);
-      __pyx_t_6 = 1;
-    }
-  }
-  #if CYTHON_FAST_PYCALL
-  if (PyFunction_Check(__pyx_t_2)) {
-    PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4400, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  } else
-  #endif
-  #if CYTHON_FAST_PYCCALL
-  if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
-    PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4400, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  } else
-  #endif
-  {
-    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4400, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_7);
-    if (__pyx_t_5) {
-      __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL;
-    }
-    __Pyx_GIVEREF(__pyx_t_3);
-    PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_6, __pyx_t_3);
-    __Pyx_GIVEREF(__pyx_t_4);
-    PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_4);
-    __pyx_t_3 = 0;
-    __pyx_t_4 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4400, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  }
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_4);
+  __pyx_t_4 = 0;
+  __Pyx_INCREF(__pyx_kp_u_FarReader_at_0x);
+  __pyx_t_2 += 16;
+  __Pyx_GIVEREF(__pyx_kp_u_FarReader_at_0x);
+  PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_FarReader_at_0x);
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4432, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4432, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_t_5);
+  __pyx_t_5 = 0;
+  __Pyx_INCREF(__pyx_kp_u__3);
+  __pyx_t_2 += 1;
+  __Pyx_GIVEREF(__pyx_kp_u__3);
+  PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_kp_u__3);
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4432, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4399
- *         "Cannot construct {}".format(self.__class__.__name__))
+  /* "pywrapfst.pyx":4431
+ *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<{} FarReader at 0x{:x}>".format(self.far_type(), id(self))
+ *     return f"<{self.far_type()} FarReader at 0x{id(self):x}>"
  * 
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_AddTraceback("pywrapfst.FarReader.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -44282,7 +44779,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_2__repr__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4403
+/* "pywrapfst.pyx":4435
  * 
  *   @classmethod
  *   def open(cls, *sources):             # <<<<<<<<<<<<<<
@@ -44310,178 +44807,164 @@ static PyObject *__pyx_pw_9pywrapfst_9FarReader_5open(PyObject *__pyx_v_cls, PyO
 }
 
 static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_sources) {
-  std::vector<std::string>  __pyx_v_source_strings;
-  PyObject *__pyx_v_source = NULL;
-  std::unique_ptr<fst::script::FarReaderClass>  __pyx_v_tfar;
-  struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_result = 0;
+  std::vector<std::string>  __pyx_v__sources;
+  std::unique_ptr<fst::script::FarReaderClass>  __pyx_v__tfar;
+  struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_reader = 0;
+  PyObject *__pyx_8genexpr1__pyx_v_source = NULL;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  Py_ssize_t __pyx_t_2;
-  PyObject *__pyx_t_3 = NULL;
-  std::string __pyx_t_4;
-  int __pyx_t_5;
-  PyObject *__pyx_t_6 = NULL;
-  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  Py_ssize_t __pyx_t_3;
+  PyObject *__pyx_t_4 = NULL;
+  std::string __pyx_t_5;
+  std::vector<std::string>  __pyx_t_6;
+  int __pyx_t_7;
   PyObject *__pyx_t_8 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("open", 0);
 
-  /* "pywrapfst.pyx":4422
+  /* "pywrapfst.pyx":4453
+ *       FstIOError: Read failed.
  *     """
- *     cdef vector[string] source_strings
- *     for source in sources:             # <<<<<<<<<<<<<<
- *       source_strings.push_back(tostring(source))
- *     cdef unique_ptr[fst.FarReaderClass] tfar
- */
-  __pyx_t_1 = __pyx_v_sources; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
-  for (;;) {
-    if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
-    #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-    __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 4422, __pyx_L1_error)
-    #else
-    __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4422, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_3);
-    #endif
-    __Pyx_XDECREF_SET(__pyx_v_source, __pyx_t_3);
-    __pyx_t_3 = 0;
-
-    /* "pywrapfst.pyx":4423
- *     cdef vector[string] source_strings
- *     for source in sources:
- *       source_strings.push_back(tostring(source))             # <<<<<<<<<<<<<<
- *     cdef unique_ptr[fst.FarReaderClass] tfar
- *     tfar.reset(fst.FarReaderClass.Open(source_strings))
+ *     cdef vector[string] _sources = [path_tostring(source) for source in sources]             # <<<<<<<<<<<<<<
+ *     cdef unique_ptr[fst.FarReaderClass] _tfar
+ *     _tfar.reset(fst.FarReaderClass.Open(_sources))
  */
-    __pyx_t_4 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4423, __pyx_L1_error)
-    try {
-      __pyx_v_source_strings.push_back(__pyx_t_4);
-    } catch(...) {
-      __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 4423, __pyx_L1_error)
+  { /* enter inner scope */
+    __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4453, __pyx_L5_error)
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_2 = __pyx_v_sources; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
+    for (;;) {
+      if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
+      #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
+      __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_4); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 4453, __pyx_L5_error)
+      #else
+      __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4453, __pyx_L5_error)
+      __Pyx_GOTREF(__pyx_t_4);
+      #endif
+      __Pyx_XDECREF_SET(__pyx_8genexpr1__pyx_v_source, __pyx_t_4);
+      __pyx_t_4 = 0;
+      __pyx_t_5 = __pyx_f_9pywrapfst_path_tostring(__pyx_8genexpr1__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4453, __pyx_L5_error)
+      __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4453, __pyx_L5_error)
+      __Pyx_GOTREF(__pyx_t_4);
+      if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) __PYX_ERR(0, 4453, __pyx_L5_error)
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     }
-
-    /* "pywrapfst.pyx":4422
- *     """
- *     cdef vector[string] source_strings
- *     for source in sources:             # <<<<<<<<<<<<<<
- *       source_strings.push_back(tostring(source))
- *     cdef unique_ptr[fst.FarReaderClass] tfar
- */
-  }
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_XDECREF(__pyx_8genexpr1__pyx_v_source); __pyx_8genexpr1__pyx_v_source = 0;
+    goto __pyx_L8_exit_scope;
+    __pyx_L5_error:;
+    __Pyx_XDECREF(__pyx_8genexpr1__pyx_v_source); __pyx_8genexpr1__pyx_v_source = 0;
+    goto __pyx_L1_error;
+    __pyx_L8_exit_scope:;
 } /* exit inner scope */
+  __pyx_t_6 = __pyx_convert_vector_from_py_std_3a__3a_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4453, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_v__sources = __pyx_t_6;
 
-  /* "pywrapfst.pyx":4425
- *       source_strings.push_back(tostring(source))
- *     cdef unique_ptr[fst.FarReaderClass] tfar
- *     tfar.reset(fst.FarReaderClass.Open(source_strings))             # <<<<<<<<<<<<<<
- *     if tfar.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(sources))
+  /* "pywrapfst.pyx":4455
+ *     cdef vector[string] _sources = [path_tostring(source) for source in sources]
+ *     cdef unique_ptr[fst.FarReaderClass] _tfar
+ *     _tfar.reset(fst.FarReaderClass.Open(_sources))             # <<<<<<<<<<<<<<
+ *     if _tfar.get() == NULL:
+ *       raise FstIOError(f"Read failed: {sources!r}")
  */
-  __pyx_v_tfar.reset(fst::script::FarReaderClass::Open(__pyx_v_source_strings));
+  __pyx_v__tfar.reset(fst::script::FarReaderClass::Open(__pyx_v__sources));
 
-  /* "pywrapfst.pyx":4426
- *     cdef unique_ptr[fst.FarReaderClass] tfar
- *     tfar.reset(fst.FarReaderClass.Open(source_strings))
- *     if tfar.get() == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Read failed: {!r}".format(sources))
- *     cdef FarReader result = FarReader.__new__(FarReader)
+  /* "pywrapfst.pyx":4456
+ *     cdef unique_ptr[fst.FarReaderClass] _tfar
+ *     _tfar.reset(fst.FarReaderClass.Open(_sources))
+ *     if _tfar.get() == NULL:             # <<<<<<<<<<<<<<
+ *       raise FstIOError(f"Read failed: {sources!r}")
+ *     cdef FarReader reader = FarReader.__new__(FarReader)
  */
-  __pyx_t_5 = ((__pyx_v_tfar.get() == NULL) != 0);
-  if (unlikely(__pyx_t_5)) {
+  __pyx_t_7 = ((__pyx_v__tfar.get() == NULL) != 0);
+  if (unlikely(__pyx_t_7)) {
 
-    /* "pywrapfst.pyx":4427
- *     tfar.reset(fst.FarReaderClass.Open(source_strings))
- *     if tfar.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(sources))             # <<<<<<<<<<<<<<
- *     cdef FarReader result = FarReader.__new__(FarReader)
- *     result._reader.reset(tfar.release())
+    /* "pywrapfst.pyx":4457
+ *     _tfar.reset(fst.FarReaderClass.Open(_sources))
+ *     if _tfar.get() == NULL:
+ *       raise FstIOError(f"Read failed: {sources!r}")             # <<<<<<<<<<<<<<
+ *     cdef FarReader reader = FarReader.__new__(FarReader)
+ *     reader._reader.reset(_tfar.release())
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4427, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Read_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4427, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_7);
-    __pyx_t_8 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) {
-      __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7);
-      if (likely(__pyx_t_8)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
-        __Pyx_INCREF(__pyx_t_8);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_7, function);
-      }
-    }
-    __pyx_t_6 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_v_sources) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_sources);
-    __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
-    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4427, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_6);
-    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-    __pyx_t_7 = NULL;
-    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_3);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
-        __Pyx_INCREF(__pyx_t_7);
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4457, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_4 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_sources), __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4457, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_8 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Read_failed, __pyx_t_4); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 4457, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_8);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = NULL;
+    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
+      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
+      if (likely(__pyx_t_4)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+        __Pyx_INCREF(__pyx_t_4);
         __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_3, function);
+        __Pyx_DECREF_SET(__pyx_t_2, function);
       }
     }
-    __pyx_t_1 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_7, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_6);
-    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4427, __pyx_L1_error)
+    __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_8) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_8);
+    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4457, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 4427, __pyx_L1_error)
+    __PYX_ERR(0, 4457, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4426
- *     cdef unique_ptr[fst.FarReaderClass] tfar
- *     tfar.reset(fst.FarReaderClass.Open(source_strings))
- *     if tfar.get() == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Read failed: {!r}".format(sources))
- *     cdef FarReader result = FarReader.__new__(FarReader)
+    /* "pywrapfst.pyx":4456
+ *     cdef unique_ptr[fst.FarReaderClass] _tfar
+ *     _tfar.reset(fst.FarReaderClass.Open(_sources))
+ *     if _tfar.get() == NULL:             # <<<<<<<<<<<<<<
+ *       raise FstIOError(f"Read failed: {sources!r}")
+ *     cdef FarReader reader = FarReader.__new__(FarReader)
  */
   }
 
-  /* "pywrapfst.pyx":4428
- *     if tfar.get() == NULL:
- *       raise FstIOError("Read failed: {!r}".format(sources))
- *     cdef FarReader result = FarReader.__new__(FarReader)             # <<<<<<<<<<<<<<
- *     result._reader.reset(tfar.release())
- *     return result
+  /* "pywrapfst.pyx":4458
+ *     if _tfar.get() == NULL:
+ *       raise FstIOError(f"Read failed: {sources!r}")
+ *     cdef FarReader reader = FarReader.__new__(FarReader)             # <<<<<<<<<<<<<<
+ *     reader._reader.reset(_tfar.release())
+ *     return reader
  */
-  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_FarReader(((PyTypeObject *)__pyx_ptype_9pywrapfst_FarReader), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4428, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_tp_new_9pywrapfst_FarReader(((PyTypeObject *)__pyx_ptype_9pywrapfst_FarReader), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4458, __pyx_L1_error)
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_v_result = ((struct __pyx_obj_9pywrapfst_FarReader *)__pyx_t_1);
+  __pyx_v_reader = ((struct __pyx_obj_9pywrapfst_FarReader *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":4429
- *       raise FstIOError("Read failed: {!r}".format(sources))
- *     cdef FarReader result = FarReader.__new__(FarReader)
- *     result._reader.reset(tfar.release())             # <<<<<<<<<<<<<<
- *     return result
+  /* "pywrapfst.pyx":4459
+ *       raise FstIOError(f"Read failed: {sources!r}")
+ *     cdef FarReader reader = FarReader.__new__(FarReader)
+ *     reader._reader.reset(_tfar.release())             # <<<<<<<<<<<<<<
+ *     return reader
  * 
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v_reader) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4429, __pyx_L1_error)
+    __PYX_ERR(0, 4459, __pyx_L1_error)
   }
-  __pyx_v_result->_reader.reset(__pyx_v_tfar.release());
+  __pyx_v_reader->_reader.reset(__pyx_v__tfar.release());
 
-  /* "pywrapfst.pyx":4430
- *     cdef FarReader result = FarReader.__new__(FarReader)
- *     result._reader.reset(tfar.release())
- *     return result             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":4460
+ *     cdef FarReader reader = FarReader.__new__(FarReader)
+ *     reader._reader.reset(_tfar.release())
+ *     return reader             # <<<<<<<<<<<<<<
  * 
  *   cpdef string arc_type(self):
  */
   __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_result));
-  __pyx_r = ((PyObject *)__pyx_v_result);
+  __Pyx_INCREF(((PyObject *)__pyx_v_reader));
+  __pyx_r = ((PyObject *)__pyx_v_reader);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4403
+  /* "pywrapfst.pyx":4435
  * 
  *   @classmethod
  *   def open(cls, *sources):             # <<<<<<<<<<<<<<
@@ -44492,22 +44975,21 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_4open(CYTHON_UNUSED PyTypeObject
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_8);
   __Pyx_AddTraceback("pywrapfst.FarReader.open", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
-  __Pyx_XDECREF(__pyx_v_source);
-  __Pyx_XDECREF((PyObject *)__pyx_v_result);
+  __Pyx_XDECREF((PyObject *)__pyx_v_reader);
+  __Pyx_XDECREF(__pyx_8genexpr1__pyx_v_source);
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4432
- *     return result
+/* "pywrapfst.pyx":4462
+ *     return reader
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
  *     """
@@ -44523,6 +45005,9 @@ static std::string __pyx_f_9pywrapfst_9FarReader_arc_type(struct __pyx_obj_9pywr
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   std::string __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("arc_type", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -44533,7 +45018,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_arc_type(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4432, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4462, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_7arc_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -44549,10 +45034,10 @@ static std::string __pyx_f_9pywrapfst_9FarReader_arc_type(struct __pyx_obj_9pywr
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4432, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4462, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4432, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4462, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -44571,7 +45056,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_arc_type(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":4438
+  /* "pywrapfst.pyx":4468
  *     Returns a string indicating the arc type.
  *     """
  *     return self._reader.get().ArcType()             # <<<<<<<<<<<<<<
@@ -44580,13 +45065,13 @@ static std::string __pyx_f_9pywrapfst_9FarReader_arc_type(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4438, __pyx_L1_error)
+    __PYX_ERR(0, 4468, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4432
- *     return result
+  /* "pywrapfst.pyx":4462
+ *     return reader
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
  *     """
@@ -44624,9 +45109,12 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_6arc_type(struct __pyx_obj_9pywr
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("arc_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4432, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4462, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44643,7 +45131,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_6arc_type(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4440
+/* "pywrapfst.pyx":4470
  *     return self._reader.get().ArcType()
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -44660,6 +45148,9 @@ static bool __pyx_f_9pywrapfst_9FarReader_done(struct __pyx_obj_9pywrapfst_FarRe
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   bool __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("done", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -44670,7 +45161,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_done(struct __pyx_obj_9pywrapfst_FarRe
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4440, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_done); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4470, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_9done)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -44686,10 +45177,10 @@ static bool __pyx_f_9pywrapfst_9FarReader_done(struct __pyx_obj_9pywrapfst_FarRe
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4440, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4470, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4440, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4470, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -44708,7 +45199,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_done(struct __pyx_obj_9pywrapfst_FarRe
     #endif
   }
 
-  /* "pywrapfst.pyx":4449
+  /* "pywrapfst.pyx":4479
  *       True if the iterator is exhausted, False otherwise.
  *     """
  *     return self._reader.get().Done()             # <<<<<<<<<<<<<<
@@ -44717,12 +45208,12 @@ static bool __pyx_f_9pywrapfst_9FarReader_done(struct __pyx_obj_9pywrapfst_FarRe
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4449, __pyx_L1_error)
+    __PYX_ERR(0, 4479, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->Done();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4440
+  /* "pywrapfst.pyx":4470
  *     return self._reader.get().ArcType()
  * 
  *   cpdef bool done(self):             # <<<<<<<<<<<<<<
@@ -44761,9 +45252,12 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_8done(struct __pyx_obj_9pywrapfs
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("done", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_9FarReader_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4440, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_9FarReader_done(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4470, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44780,7 +45274,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_8done(struct __pyx_obj_9pywrapfs
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4451
+/* "pywrapfst.pyx":4481
  *     return self._reader.get().Done()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -44797,6 +45291,9 @@ static bool __pyx_f_9pywrapfst_9FarReader_error(struct __pyx_obj_9pywrapfst_FarR
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   bool __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("error", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -44807,7 +45304,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_error(struct __pyx_obj_9pywrapfst_FarR
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_error); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4451, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_error); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4481, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_11error)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -44823,10 +45320,10 @@ static bool __pyx_f_9pywrapfst_9FarReader_error(struct __pyx_obj_9pywrapfst_FarR
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4451, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4481, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4451, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4481, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -44845,7 +45342,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_error(struct __pyx_obj_9pywrapfst_FarR
     #endif
   }
 
-  /* "pywrapfst.pyx":4460
+  /* "pywrapfst.pyx":4490
  *       True if the FarReader is in an errorful state, False otherwise.
  *     """
  *     return self._reader.get().Error()             # <<<<<<<<<<<<<<
@@ -44854,12 +45351,12 @@ static bool __pyx_f_9pywrapfst_9FarReader_error(struct __pyx_obj_9pywrapfst_FarR
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4460, __pyx_L1_error)
+    __PYX_ERR(0, 4490, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->Error();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4451
+  /* "pywrapfst.pyx":4481
  *     return self._reader.get().Done()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -44898,9 +45395,12 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_10error(struct __pyx_obj_9pywrap
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("error", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_9FarReader_error(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4451, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_9FarReader_error(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4481, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -44917,7 +45417,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_10error(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4462
+/* "pywrapfst.pyx":4492
  *     return self._reader.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -44934,6 +45434,9 @@ static std::string __pyx_f_9pywrapfst_9FarReader_far_type(struct __pyx_obj_9pywr
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   std::string __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("far_type", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -44944,7 +45447,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_far_type(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_far_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4462, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_far_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4492, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_13far_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -44960,10 +45463,10 @@ static std::string __pyx_f_9pywrapfst_9FarReader_far_type(struct __pyx_obj_9pywr
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4462, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4492, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4462, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4492, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -44982,7 +45485,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_far_type(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":4463
+  /* "pywrapfst.pyx":4493
  * 
  *   cpdef string far_type(self):
  *     return fst.GetFarTypeString(self._reader.get().Type())             # <<<<<<<<<<<<<<
@@ -44991,12 +45494,12 @@ static std::string __pyx_f_9pywrapfst_9FarReader_far_type(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4463, __pyx_L1_error)
+    __PYX_ERR(0, 4493, __pyx_L1_error)
   }
   __pyx_r = fst::GetFarTypeString(__pyx_v_self->_reader.get()->Type());
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4462
+  /* "pywrapfst.pyx":4492
  *     return self._reader.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -45034,9 +45537,12 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_12far_type(struct __pyx_obj_9pyw
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("far_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_far_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4462, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_far_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4492, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45053,7 +45559,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_12far_type(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4465
+/* "pywrapfst.pyx":4495
  *     return fst.GetFarTypeString(self._reader.get().Type())
  * 
  *   cpdef bool find(self, key):             # <<<<<<<<<<<<<<
@@ -45071,6 +45577,9 @@ static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarRe
   PyObject *__pyx_t_4 = NULL;
   bool __pyx_t_5;
   std::string __pyx_t_6;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("find", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -45081,7 +45590,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarRe
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_find); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4465, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_find); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4495, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_15find)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -45097,10 +45606,10 @@ static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarRe
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_key) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_key);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4465, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4495, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4465, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4495, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -45119,7 +45628,7 @@ static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarRe
     #endif
   }
 
-  /* "pywrapfst.pyx":4478
+  /* "pywrapfst.pyx":4508
  *       True if the key was found, False otherwise.
  *     """
  *     return self._reader.get().Find(tostring(key))             # <<<<<<<<<<<<<<
@@ -45128,13 +45637,13 @@ static bool __pyx_f_9pywrapfst_9FarReader_find(struct __pyx_obj_9pywrapfst_FarRe
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4478, __pyx_L1_error)
+    __PYX_ERR(0, 4508, __pyx_L1_error)
   }
-  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4478, __pyx_L1_error)
+  __pyx_t_6 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4508, __pyx_L1_error)
   __pyx_r = __pyx_v_self->_reader.get()->Find(__pyx_t_6);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4465
+  /* "pywrapfst.pyx":4495
  *     return fst.GetFarTypeString(self._reader.get().Type())
  * 
  *   cpdef bool find(self, key):             # <<<<<<<<<<<<<<
@@ -45173,9 +45682,12 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_14find(struct __pyx_obj_9pywrapf
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("find", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_9FarReader_find(__pyx_v_self, __pyx_v_key, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4465, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_9FarReader_find(__pyx_v_self, __pyx_v_key, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4495, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45192,7 +45704,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_14find(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4480
+/* "pywrapfst.pyx":4510
  *     return self._reader.get().Find(tostring(key))
  * 
  *   cpdef Fst get_fst(self):             # <<<<<<<<<<<<<<
@@ -45208,6 +45720,9 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(st
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_fst", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -45218,7 +45733,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(st
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_fst); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4480, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_fst); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4510, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_17get_fst)) {
         __Pyx_XDECREF(((PyObject *)__pyx_r));
@@ -45235,10 +45750,10 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(st
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4480, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4510, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 4480, __pyx_L1_error)
+        if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_9pywrapfst_Fst))))) __PYX_ERR(0, 4510, __pyx_L1_error)
         __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_2);
         __pyx_t_2 = 0;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -45257,7 +45772,7 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(st
     #endif
   }
 
-  /* "pywrapfst.pyx":4489
+  /* "pywrapfst.pyx":4519
  *       A copy of the FST at the current position.
  *     """
  *     return _init_XFst(new fst.FstClass(deref(self._reader.get().GetFstClass())))             # <<<<<<<<<<<<<<
@@ -45267,15 +45782,15 @@ static struct __pyx_obj_9pywrapfst_Fst *__pyx_f_9pywrapfst_9FarReader_get_fst(st
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4489, __pyx_L1_error)
+    __PYX_ERR(0, 4519, __pyx_L1_error)
   }
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(new fst::script::FstClass((*__pyx_v_self->_reader.get()->GetFstClass())))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4489, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst__init_XFst(new fst::script::FstClass((*__pyx_v_self->_reader.get()->GetFstClass())))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4519, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4480
+  /* "pywrapfst.pyx":4510
  *     return self._reader.get().Find(tostring(key))
  * 
  *   cpdef Fst get_fst(self):             # <<<<<<<<<<<<<<
@@ -45315,9 +45830,12 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_16get_fst(struct __pyx_obj_9pywr
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_fst", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_9FarReader_get_fst(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4480, __pyx_L1_error)
+  __pyx_t_1 = ((PyObject *)__pyx_f_9pywrapfst_9FarReader_get_fst(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4510, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45334,7 +45852,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_16get_fst(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4491
+/* "pywrapfst.pyx":4521
  *     return _init_XFst(new fst.FstClass(deref(self._reader.get().GetFstClass())))
  * 
  *   cpdef string get_key(self):             # <<<<<<<<<<<<<<
@@ -45351,6 +45869,9 @@ static std::string __pyx_f_9pywrapfst_9FarReader_get_key(struct __pyx_obj_9pywra
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   std::string __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_key", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -45361,7 +45882,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_get_key(struct __pyx_obj_9pywra
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_key); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4491, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_key); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4521, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_19get_key)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -45377,10 +45898,10 @@ static std::string __pyx_f_9pywrapfst_9FarReader_get_key(struct __pyx_obj_9pywra
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4491, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4521, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4491, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4521, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -45399,7 +45920,7 @@ static std::string __pyx_f_9pywrapfst_9FarReader_get_key(struct __pyx_obj_9pywra
     #endif
   }
 
-  /* "pywrapfst.pyx":4500
+  /* "pywrapfst.pyx":4530
  *       The string key at the current position.
  *     """
  *     return self._reader.get().GetKey()             # <<<<<<<<<<<<<<
@@ -45408,12 +45929,12 @@ static std::string __pyx_f_9pywrapfst_9FarReader_get_key(struct __pyx_obj_9pywra
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4500, __pyx_L1_error)
+    __PYX_ERR(0, 4530, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_reader.get()->GetKey();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4491
+  /* "pywrapfst.pyx":4521
  *     return _init_XFst(new fst.FstClass(deref(self._reader.get().GetFstClass())))
  * 
  *   cpdef string get_key(self):             # <<<<<<<<<<<<<<
@@ -45452,9 +45973,12 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_18get_key(struct __pyx_obj_9pywr
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_key", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_get_key(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4491, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarReader_get_key(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4521, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45471,7 +45995,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_18get_key(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4502
+/* "pywrapfst.pyx":4532
  *     return self._reader.get().GetKey()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -45486,6 +46010,9 @@ static void __pyx_f_9pywrapfst_9FarReader_next(struct __pyx_obj_9pywrapfst_FarRe
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("next", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -45496,7 +46023,7 @@ static void __pyx_f_9pywrapfst_9FarReader_next(struct __pyx_obj_9pywrapfst_FarRe
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4502, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_next); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4532, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_21next)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -45512,7 +46039,7 @@ static void __pyx_f_9pywrapfst_9FarReader_next(struct __pyx_obj_9pywrapfst_FarRe
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4502, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4532, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -45532,7 +46059,7 @@ static void __pyx_f_9pywrapfst_9FarReader_next(struct __pyx_obj_9pywrapfst_FarRe
     #endif
   }
 
-  /* "pywrapfst.pyx":4508
+  /* "pywrapfst.pyx":4538
  *     Advances the iterator.
  *     """
  *     self._reader.get().Next()             # <<<<<<<<<<<<<<
@@ -45541,11 +46068,11 @@ static void __pyx_f_9pywrapfst_9FarReader_next(struct __pyx_obj_9pywrapfst_FarRe
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4508, __pyx_L1_error)
+    __PYX_ERR(0, 4538, __pyx_L1_error)
   }
   __pyx_v_self->_reader.get()->Next();
 
-  /* "pywrapfst.pyx":4502
+  /* "pywrapfst.pyx":4532
  *     return self._reader.get().GetKey()
  * 
  *   cpdef void next(self):             # <<<<<<<<<<<<<<
@@ -45583,9 +46110,12 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_20next(struct __pyx_obj_9pywrapf
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("next", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_9FarReader_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4502, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_9FarReader_next(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4532, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45602,7 +46132,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_20next(struct __pyx_obj_9pywrapf
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4510
+/* "pywrapfst.pyx":4540
  *     self._reader.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -45617,6 +46147,9 @@ static void __pyx_f_9pywrapfst_9FarReader_reset(struct __pyx_obj_9pywrapfst_FarR
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reset", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -45627,7 +46160,7 @@ static void __pyx_f_9pywrapfst_9FarReader_reset(struct __pyx_obj_9pywrapfst_FarR
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4510, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_reset); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4540, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarReader_23reset)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -45643,7 +46176,7 @@ static void __pyx_f_9pywrapfst_9FarReader_reset(struct __pyx_obj_9pywrapfst_FarR
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4510, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4540, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -45663,7 +46196,7 @@ static void __pyx_f_9pywrapfst_9FarReader_reset(struct __pyx_obj_9pywrapfst_FarR
     #endif
   }
 
-  /* "pywrapfst.pyx":4516
+  /* "pywrapfst.pyx":4546
  *     Resets the iterator to the initial position.
  *     """
  *     self._reader.get().Reset()             # <<<<<<<<<<<<<<
@@ -45672,11 +46205,11 @@ static void __pyx_f_9pywrapfst_9FarReader_reset(struct __pyx_obj_9pywrapfst_FarR
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4516, __pyx_L1_error)
+    __PYX_ERR(0, 4546, __pyx_L1_error)
   }
   __pyx_v_self->_reader.get()->Reset();
 
-  /* "pywrapfst.pyx":4510
+  /* "pywrapfst.pyx":4540
  *     self._reader.get().Next()
  * 
  *   cpdef void reset(self):             # <<<<<<<<<<<<<<
@@ -45714,9 +46247,12 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_22reset(struct __pyx_obj_9pywrap
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("reset", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_9FarReader_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4510, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(__pyx_f_9pywrapfst_9FarReader_reset(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4540, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -45733,7 +46269,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_22reset(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4518
+/* "pywrapfst.pyx":4548
  *     self._reader.get().Reset()
  * 
  *   def __getitem__(self, key):             # <<<<<<<<<<<<<<
@@ -45760,9 +46296,12 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
   std::string __pyx_t_1;
   int __pyx_t_2;
   PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__getitem__", 0);
 
-  /* "pywrapfst.pyx":4519
+  /* "pywrapfst.pyx":4549
  * 
  *   def __getitem__(self, key):
  *     if self._reader.get().Find(tostring(key)):             # <<<<<<<<<<<<<<
@@ -45771,13 +46310,13 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_reader");
-    __PYX_ERR(0, 4519, __pyx_L1_error)
+    __PYX_ERR(0, 4549, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4519, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4549, __pyx_L1_error)
   __pyx_t_2 = (__pyx_v_self->_reader.get()->Find(__pyx_t_1) != 0);
   if (likely(__pyx_t_2)) {
 
-    /* "pywrapfst.pyx":4520
+    /* "pywrapfst.pyx":4550
  *   def __getitem__(self, key):
  *     if self._reader.get().Find(tostring(key)):
  *       return self.get_fst()             # <<<<<<<<<<<<<<
@@ -45787,15 +46326,15 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
     __Pyx_XDECREF(__pyx_r);
     if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
       PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "get_fst");
-      __PYX_ERR(0, 4520, __pyx_L1_error)
+      __PYX_ERR(0, 4550, __pyx_L1_error)
     }
-    __pyx_t_3 = ((PyObject *)((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->get_fst(__pyx_v_self, 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4520, __pyx_L1_error)
+    __pyx_t_3 = ((PyObject *)((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->get_fst(__pyx_v_self, 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4550, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_r = __pyx_t_3;
     __pyx_t_3 = 0;
     goto __pyx_L0;
 
-    /* "pywrapfst.pyx":4519
+    /* "pywrapfst.pyx":4549
  * 
  *   def __getitem__(self, key):
  *     if self._reader.get().Find(tostring(key)):             # <<<<<<<<<<<<<<
@@ -45804,22 +46343,22 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
  */
   }
 
-  /* "pywrapfst.pyx":4522
+  /* "pywrapfst.pyx":4552
  *       return self.get_fst()
  *     else:
  *       raise KeyError(key)             # <<<<<<<<<<<<<<
  * 
- * 
+ *   def __next__(self):
  */
   /*else*/ {
-    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_KeyError, __pyx_v_key); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4522, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_KeyError, __pyx_v_key); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4552, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 4522, __pyx_L1_error)
+    __PYX_ERR(0, 4552, __pyx_L1_error)
   }
 
-  /* "pywrapfst.pyx":4518
+  /* "pywrapfst.pyx":4548
  *     self._reader.get().Reset()
  * 
  *   def __getitem__(self, key):             # <<<<<<<<<<<<<<
@@ -45838,6 +46377,211 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
   return __pyx_r;
 }
 
+/* "pywrapfst.pyx":4554
+ *       raise KeyError(key)
+ * 
+ *   def __next__(self):             # <<<<<<<<<<<<<<
+ *     if self.done():
+ *       raise StopIteration
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9pywrapfst_9FarReader_27__next__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_9FarReader_27__next__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__next__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_9pywrapfst_9FarReader_26__next__(((struct __pyx_obj_9pywrapfst_FarReader *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9pywrapfst_9FarReader_26__next__(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self) {
+  std::string __pyx_v__key;
+  struct __pyx_obj_9pywrapfst_Fst *__pyx_v__fst = 0;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__next__", 0);
+
+  /* "pywrapfst.pyx":4555
+ * 
+ *   def __next__(self):
+ *     if self.done():             # <<<<<<<<<<<<<<
+ *       raise StopIteration
+ *     cdef string _key = self.get_key()
+ */
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "done");
+    __PYX_ERR(0, 4555, __pyx_L1_error)
+  }
+  __pyx_t_1 = (((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->done(__pyx_v_self, 0) != 0);
+  if (unlikely(__pyx_t_1)) {
+
+    /* "pywrapfst.pyx":4556
+ *   def __next__(self):
+ *     if self.done():
+ *       raise StopIteration             # <<<<<<<<<<<<<<
+ *     cdef string _key = self.get_key()
+ *     cdef Fst _fst = self.get_fst()
+ */
+    __Pyx_Raise(__pyx_builtin_StopIteration, 0, 0, 0);
+    __PYX_ERR(0, 4556, __pyx_L1_error)
+
+    /* "pywrapfst.pyx":4555
+ * 
+ *   def __next__(self):
+ *     if self.done():             # <<<<<<<<<<<<<<
+ *       raise StopIteration
+ *     cdef string _key = self.get_key()
+ */
+  }
+
+  /* "pywrapfst.pyx":4557
+ *     if self.done():
+ *       raise StopIteration
+ *     cdef string _key = self.get_key()             # <<<<<<<<<<<<<<
+ *     cdef Fst _fst = self.get_fst()
+ *     self.next()
+ */
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "get_key");
+    __PYX_ERR(0, 4557, __pyx_L1_error)
+  }
+  __pyx_v__key = ((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->get_key(__pyx_v_self, 0);
+
+  /* "pywrapfst.pyx":4558
+ *       raise StopIteration
+ *     cdef string _key = self.get_key()
+ *     cdef Fst _fst = self.get_fst()             # <<<<<<<<<<<<<<
+ *     self.next()
+ *     return (_key, _fst)
+ */
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "get_fst");
+    __PYX_ERR(0, 4558, __pyx_L1_error)
+  }
+  __pyx_t_2 = ((PyObject *)((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->get_fst(__pyx_v_self, 0)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4558, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_v__fst = ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_t_2);
+  __pyx_t_2 = 0;
+
+  /* "pywrapfst.pyx":4559
+ *     cdef string _key = self.get_key()
+ *     cdef Fst _fst = self.get_fst()
+ *     self.next()             # <<<<<<<<<<<<<<
+ *     return (_key, _fst)
+ * 
+ */
+  if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "next");
+    __PYX_ERR(0, 4559, __pyx_L1_error)
+  }
+  ((struct __pyx_vtabstruct_9pywrapfst_FarReader *)__pyx_v_self->__pyx_vtab)->next(__pyx_v_self, 0);
+
+  /* "pywrapfst.pyx":4560
+ *     cdef Fst _fst = self.get_fst()
+ *     self.next()
+ *     return (_key, _fst)             # <<<<<<<<<<<<<<
+ * 
+ *   # This just registers this class as a possible iterator.
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_v__key); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4560, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4560, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __Pyx_INCREF(((PyObject *)__pyx_v__fst));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v__fst));
+  PyTuple_SET_ITEM(__pyx_t_3, 1, ((PyObject *)__pyx_v__fst));
+  __pyx_t_2 = 0;
+  __pyx_r = __pyx_t_3;
+  __pyx_t_3 = 0;
+  goto __pyx_L0;
+
+  /* "pywrapfst.pyx":4554
+ *       raise KeyError(key)
+ * 
+ *   def __next__(self):             # <<<<<<<<<<<<<<
+ *     if self.done():
+ *       raise StopIteration
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("pywrapfst.FarReader.__next__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v__fst);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pywrapfst.pyx":4563
+ * 
+ *   # This just registers this class as a possible iterator.
+ *   def __iter__(self):             # <<<<<<<<<<<<<<
+ *     return self
+ * 
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9pywrapfst_9FarReader_29__iter__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_9FarReader_29__iter__(PyObject *__pyx_v_self) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_9pywrapfst_9FarReader_28__iter__(((struct __pyx_obj_9pywrapfst_FarReader *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9pywrapfst_9FarReader_28__iter__(struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__iter__", 0);
+
+  /* "pywrapfst.pyx":4564
+ *   # This just registers this class as a possible iterator.
+ *   def __iter__(self):
+ *     return self             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self));
+  __pyx_r = ((PyObject *)__pyx_v_self);
+  goto __pyx_L0;
+
+  /* "pywrapfst.pyx":4563
+ * 
+ *   # This just registers this class as a possible iterator.
+ *   def __iter__(self):             # <<<<<<<<<<<<<<
+ *     return self
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
 /* "(tree fragment)":1
  * def __reduce_cython__(self):             # <<<<<<<<<<<<<<
  *     raise TypeError("self._reader cannot be converted to a Python object for pickling")
@@ -45845,22 +46589,25 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_24__getitem__(struct __pyx_obj_9
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_9FarReader_27__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_9FarReader_27__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+static PyObject *__pyx_pw_9pywrapfst_9FarReader_31__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_9FarReader_31__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_9FarReader_26__reduce_cython__(((struct __pyx_obj_9pywrapfst_FarReader *)__pyx_v_self));
+  __pyx_r = __pyx_pf_9pywrapfst_9FarReader_30__reduce_cython__(((struct __pyx_obj_9pywrapfst_FarReader *)__pyx_v_self));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_9FarReader_26__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self) {
+static PyObject *__pyx_pf_9pywrapfst_9FarReader_30__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__reduce_cython__", 0);
 
   /* "(tree fragment)":2
@@ -45899,22 +46646,25 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_26__reduce_cython__(CYTHON_UNUSE
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_9pywrapfst_9FarReader_29__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/
-static PyObject *__pyx_pw_9pywrapfst_9FarReader_29__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) {
+static PyObject *__pyx_pw_9pywrapfst_9FarReader_33__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/
+static PyObject *__pyx_pw_9pywrapfst_9FarReader_33__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_9pywrapfst_9FarReader_28__setstate_cython__(((struct __pyx_obj_9pywrapfst_FarReader *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state));
+  __pyx_r = __pyx_pf_9pywrapfst_9FarReader_32__setstate_cython__(((struct __pyx_obj_9pywrapfst_FarReader *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state));
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_9pywrapfst_9FarReader_28__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) {
+static PyObject *__pyx_pf_9pywrapfst_9FarReader_32__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_9pywrapfst_FarReader *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__setstate_cython__", 0);
 
   /* "(tree fragment)":4
@@ -45945,12 +46695,12 @@ static PyObject *__pyx_pf_9pywrapfst_9FarReader_28__setstate_cython__(CYTHON_UNU
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4545
+/* "pywrapfst.pyx":4587
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
- *     raise FstDeletedConstructorError(
- *         "Cannot construct {}".format(self.__class__.__name__))
+ *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")
+ * 
  */
 
 /* Python wrapper */
@@ -45974,99 +46724,59 @@ static int __pyx_pf_9pywrapfst_9FarWriter___init__(struct __pyx_obj_9pywrapfst_F
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "pywrapfst.pyx":4546
- * 
- *   def __init__(self):
- *     raise FstDeletedConstructorError(             # <<<<<<<<<<<<<<
- *         "Cannot construct {}".format(self.__class__.__name__))
+  /* "pywrapfst.pyx":4588
  * 
- */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstDeletedConstructorError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4546, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-
-  /* "pywrapfst.pyx":4547
  *   def __init__(self):
- *     raise FstDeletedConstructorError(
- *         "Cannot construct {}".format(self.__class__.__name__))             # <<<<<<<<<<<<<<
+ *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")             # <<<<<<<<<<<<<<
  * 
  *   def __repr__(self):
  */
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Cannot_construct, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4547, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4547, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_name); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4547, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = NULL;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) {
-    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
-    if (likely(__pyx_t_5)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
-      __Pyx_INCREF(__pyx_t_5);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_4, function);
-    }
-  }
-  __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6);
-  __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4547, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = NULL;
-  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
-    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
-    if (likely(__pyx_t_4)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-      __Pyx_INCREF(__pyx_t_4);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_2, function);
-    }
-  }
-  __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4546, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4588, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4588, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_t_2, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4588, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Cannot_construct, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4588, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_NotImplementedError, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4588, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(0, 4546, __pyx_L1_error)
+  __PYX_ERR(0, 4588, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4545
+  /* "pywrapfst.pyx":4587
  *   """
  * 
  *   def __init__(self):             # <<<<<<<<<<<<<<
- *     raise FstDeletedConstructorError(
- *         "Cannot construct {}".format(self.__class__.__name__))
+ *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")
+ * 
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
   __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
   __Pyx_AddTraceback("pywrapfst.FarWriter.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = -1;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4549
- *         "Cannot construct {}".format(self.__class__.__name__))
+/* "pywrapfst.pyx":4590
+ *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<{} FarWriter at 0x{:x}>".format(self.far_type(), id(self))
+ *     return f"<{self.far_type()} FarWriter at 0x{id(self):x}>"
  * 
  */
 
@@ -46087,101 +46797,80 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_2;
+  Py_UCS4 __pyx_t_3;
   PyObject *__pyx_t_4 = NULL;
   PyObject *__pyx_t_5 = NULL;
-  int __pyx_t_6;
-  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "pywrapfst.pyx":4550
+  /* "pywrapfst.pyx":4591
  * 
  *   def __repr__(self):
- *     return "<{} FarWriter at 0x{:x}>".format(self.far_type(), id(self))             # <<<<<<<<<<<<<<
+ *     return f"<{self.far_type()} FarWriter at 0x{id(self):x}>"             # <<<<<<<<<<<<<<
  * 
  *   @classmethod
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_FarWriter_at_0x_x, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4550, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4591, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = 0;
+  __pyx_t_3 = 127;
+  __Pyx_INCREF(__pyx_kp_u__2);
+  __pyx_t_2 += 1;
+  __Pyx_GIVEREF(__pyx_kp_u__2);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u__2);
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "far_type");
-    __PYX_ERR(0, 4550, __pyx_L1_error)
+    __PYX_ERR(0, 4591, __pyx_L1_error)
   }
-  __pyx_t_3 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_FarWriter *)__pyx_v_self->__pyx_vtab)->far_type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4550, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4550, __pyx_L1_error)
+  __pyx_t_4 = __pyx_convert_PyUnicode_string_to_py_std__in_string(((struct __pyx_vtabstruct_9pywrapfst_FarWriter *)__pyx_v_self->__pyx_vtab)->far_type(__pyx_v_self, 0)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4591, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = NULL;
-  __pyx_t_6 = 0;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
-    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2);
-    if (likely(__pyx_t_5)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-      __Pyx_INCREF(__pyx_t_5);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_2, function);
-      __pyx_t_6 = 1;
-    }
-  }
-  #if CYTHON_FAST_PYCALL
-  if (PyFunction_Check(__pyx_t_2)) {
-    PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4550, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  } else
-  #endif
-  #if CYTHON_FAST_PYCCALL
-  if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
-    PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_3, __pyx_t_4};
-    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4550, __pyx_L1_error)
-    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  } else
-  #endif
-  {
-    __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4550, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_7);
-    if (__pyx_t_5) {
-      __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL;
-    }
-    __Pyx_GIVEREF(__pyx_t_3);
-    PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_6, __pyx_t_3);
-    __Pyx_GIVEREF(__pyx_t_4);
-    PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_4);
-    __pyx_t_3 = 0;
-    __pyx_t_4 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4550, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  }
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_4);
+  __pyx_t_4 = 0;
+  __Pyx_INCREF(__pyx_kp_u_FarWriter_at_0x);
+  __pyx_t_2 += 16;
+  __Pyx_GIVEREF(__pyx_kp_u_FarWriter_at_0x);
+  PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_FarWriter_at_0x);
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_id, ((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4591, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_PyObject_Format(__pyx_t_4, __pyx_n_u_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4591, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
+  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_t_5);
+  __pyx_t_5 = 0;
+  __Pyx_INCREF(__pyx_kp_u__3);
+  __pyx_t_2 += 1;
+  __Pyx_GIVEREF(__pyx_kp_u__3);
+  PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_kp_u__3);
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4591, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4549
- *         "Cannot construct {}".format(self.__class__.__name__))
+  /* "pywrapfst.pyx":4590
+ *     raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")
  * 
  *   def __repr__(self):             # <<<<<<<<<<<<<<
- *     return "<{} FarWriter at 0x{:x}>".format(self.far_type(), id(self))
+ *     return f"<{self.far_type()} FarWriter at 0x{id(self):x}>"
  * 
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_7);
   __Pyx_AddTraceback("pywrapfst.FarWriter.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
@@ -46190,10 +46879,10 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_2__repr__(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4553
+/* "pywrapfst.pyx":4594
  * 
  *   @classmethod
- *   def create(cls, source, arc_type=b"standard", far_type=b"default"):             # <<<<<<<<<<<<<<
+ *   def create(cls, source, arc_type="standard", far_type="default"):             # <<<<<<<<<<<<<<
  *     """
  *     FarWriter.
  */
@@ -46205,14 +46894,17 @@ static PyObject *__pyx_pw_9pywrapfst_9FarWriter_5create(PyObject *__pyx_v_cls, P
   PyObject *__pyx_v_source = 0;
   PyObject *__pyx_v_arc_type = 0;
   PyObject *__pyx_v_far_type = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("create (wrapper)", 0);
   {
     static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_source,&__pyx_n_s_arc_type,&__pyx_n_s_far_type,0};
     PyObject* values[3] = {0,0,0};
-    values[1] = ((PyObject *)__pyx_n_b_standard);
-    values[2] = ((PyObject *)__pyx_n_b_default);
+    values[1] = ((PyObject *)__pyx_n_u_standard);
+    values[2] = ((PyObject *)__pyx_n_u_default);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -46245,7 +46937,7 @@ static PyObject *__pyx_pw_9pywrapfst_9FarWriter_5create(PyObject *__pyx_v_cls, P
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "create") < 0)) __PYX_ERR(0, 4553, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "create") < 0)) __PYX_ERR(0, 4594, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -46264,7 +46956,7 @@ static PyObject *__pyx_pw_9pywrapfst_9FarWriter_5create(PyObject *__pyx_v_cls, P
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("create", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4553, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("create", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4594, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.FarWriter.create", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -46278,81 +46970,87 @@ static PyObject *__pyx_pw_9pywrapfst_9FarWriter_5create(PyObject *__pyx_v_cls, P
 }
 
 static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObject *__pyx_v_cls, PyObject *__pyx_v_source, PyObject *__pyx_v_arc_type, PyObject *__pyx_v_far_type) {
-  enum fst::FarType __pyx_v_ft;
-  fst::script::FarWriterClass *__pyx_v_tfar;
-  struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_result = 0;
+  std::unique_ptr<fst::script::FarWriterClass>  __pyx_v__tfar;
+  struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_writer = 0;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   std::string __pyx_t_1;
   std::string __pyx_t_2;
-  int __pyx_t_3;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
+  std::string __pyx_t_3;
+  fst::FarType __pyx_t_4;
+  int __pyx_t_5;
   PyObject *__pyx_t_6 = NULL;
   PyObject *__pyx_t_7 = NULL;
   PyObject *__pyx_t_8 = NULL;
+  PyObject *__pyx_t_9 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("create", 0);
 
-  /* "pywrapfst.pyx":4574
- *       FstIOError: Read failed.
- *     """
- *     cdef fst.FarType ft = fst.GetFarType(tostring(far_type))             # <<<<<<<<<<<<<<
- *     cdef fst.FarWriterClass *tfar = fst.FarWriterClass.Create(
- *         tostring(source),
- */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_far_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4574, __pyx_L1_error)
-  __pyx_v_ft = fst::script::GetFarType(__pyx_t_1);
-
-  /* "pywrapfst.pyx":4576
- *     cdef fst.FarType ft = fst.GetFarType(tostring(far_type))
- *     cdef fst.FarWriterClass *tfar = fst.FarWriterClass.Create(
- *         tostring(source),             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":4617
+ *     cdef unique_ptr[fst.FarWriterClass] _tfar
+ *     _tfar.reset(fst.FarWriterClass.Create(
+ *         path_tostring(source),             # <<<<<<<<<<<<<<
  *         tostring(arc_type),
- *         ft)
+ *         _get_far_type(tostring(far_type))))
  */
-  __pyx_t_1 = __pyx_f_9pywrapfst_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4576, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_9pywrapfst_path_tostring(__pyx_v_source); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4617, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4577
- *     cdef fst.FarWriterClass *tfar = fst.FarWriterClass.Create(
- *         tostring(source),
+  /* "pywrapfst.pyx":4618
+ *     _tfar.reset(fst.FarWriterClass.Create(
+ *         path_tostring(source),
  *         tostring(arc_type),             # <<<<<<<<<<<<<<
- *         ft)
- *     if tfar == NULL:
+ *         _get_far_type(tostring(far_type))))
+ *     if _tfar.get() == NULL:
  */
-  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4577, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_9pywrapfst_tostring(__pyx_v_arc_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4618, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4575
+  /* "pywrapfst.pyx":4619
+ *         path_tostring(source),
+ *         tostring(arc_type),
+ *         _get_far_type(tostring(far_type))))             # <<<<<<<<<<<<<<
+ *     if _tfar.get() == NULL:
+ *       raise FstIOError(f"Open failed: {source!r}")
+ */
+  __pyx_t_3 = __pyx_f_9pywrapfst_tostring(__pyx_v_far_type); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4619, __pyx_L1_error)
+  __pyx_t_4 = __pyx_f_9pywrapfst__get_far_type(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4619, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":4616
  *     """
- *     cdef fst.FarType ft = fst.GetFarType(tostring(far_type))
- *     cdef fst.FarWriterClass *tfar = fst.FarWriterClass.Create(             # <<<<<<<<<<<<<<
- *         tostring(source),
+ *     cdef unique_ptr[fst.FarWriterClass] _tfar
+ *     _tfar.reset(fst.FarWriterClass.Create(             # <<<<<<<<<<<<<<
+ *         path_tostring(source),
  *         tostring(arc_type),
  */
-  __pyx_v_tfar = fst::script::FarWriterClass::Create(__pyx_t_1, __pyx_t_2, __pyx_v_ft);
+  __pyx_v__tfar.reset(fst::script::FarWriterClass::Create(__pyx_t_1, __pyx_t_2, __pyx_t_4));
 
-  /* "pywrapfst.pyx":4579
+  /* "pywrapfst.pyx":4620
  *         tostring(arc_type),
- *         ft)
- *     if tfar == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Open failed: {!r}".format(source))
- *     cdef FarWriter result = FarWriter.__new__(FarWriter)
+ *         _get_far_type(tostring(far_type))))
+ *     if _tfar.get() == NULL:             # <<<<<<<<<<<<<<
+ *       raise FstIOError(f"Open failed: {source!r}")
+ *     cdef FarWriter writer = FarWriter.__new__(FarWriter)
  */
-  __pyx_t_3 = ((__pyx_v_tfar == NULL) != 0);
-  if (unlikely(__pyx_t_3)) {
+  __pyx_t_5 = ((__pyx_v__tfar.get() == NULL) != 0);
+  if (unlikely(__pyx_t_5)) {
 
-    /* "pywrapfst.pyx":4580
- *         ft)
- *     if tfar == NULL:
- *       raise FstIOError("Open failed: {!r}".format(source))             # <<<<<<<<<<<<<<
- *     cdef FarWriter result = FarWriter.__new__(FarWriter)
- *     result._writer.reset(tfar)
+    /* "pywrapfst.pyx":4621
+ *         _get_far_type(tostring(far_type))))
+ *     if _tfar.get() == NULL:
+ *       raise FstIOError(f"Open failed: {source!r}")             # <<<<<<<<<<<<<<
+ *     cdef FarWriter writer = FarWriter.__new__(FarWriter)
+ *     writer._writer = move(_tfar)
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4580, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Open_failed_r, __pyx_n_s_format); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4580, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_FstIOError); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4621, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_8 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_source), __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 4621, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_8);
+    __pyx_t_9 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Open_failed, __pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 4621, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_9);
+    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
     __pyx_t_8 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) {
+    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_7))) {
       __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7);
       if (likely(__pyx_t_8)) {
         PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
@@ -46361,102 +47059,86 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
         __Pyx_DECREF_SET(__pyx_t_7, function);
       }
     }
-    __pyx_t_6 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_v_source) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_source);
+    __pyx_t_6 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_t_9) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_9);
     __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
-    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4580, __pyx_L1_error)
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4621, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-    __pyx_t_7 = NULL;
-    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
-      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
-      if (likely(__pyx_t_7)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
-        __Pyx_INCREF(__pyx_t_7);
-        __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_5, function);
-      }
-    }
-    __pyx_t_4 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_7, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6);
-    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __Pyx_Raise(__pyx_t_6, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4580, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_Raise(__pyx_t_4, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __PYX_ERR(0, 4580, __pyx_L1_error)
+    __PYX_ERR(0, 4621, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4579
+    /* "pywrapfst.pyx":4620
  *         tostring(arc_type),
- *         ft)
- *     if tfar == NULL:             # <<<<<<<<<<<<<<
- *       raise FstIOError("Open failed: {!r}".format(source))
- *     cdef FarWriter result = FarWriter.__new__(FarWriter)
+ *         _get_far_type(tostring(far_type))))
+ *     if _tfar.get() == NULL:             # <<<<<<<<<<<<<<
+ *       raise FstIOError(f"Open failed: {source!r}")
+ *     cdef FarWriter writer = FarWriter.__new__(FarWriter)
  */
   }
 
-  /* "pywrapfst.pyx":4581
- *     if tfar == NULL:
- *       raise FstIOError("Open failed: {!r}".format(source))
- *     cdef FarWriter result = FarWriter.__new__(FarWriter)             # <<<<<<<<<<<<<<
- *     result._writer.reset(tfar)
- *     return result
+  /* "pywrapfst.pyx":4622
+ *     if _tfar.get() == NULL:
+ *       raise FstIOError(f"Open failed: {source!r}")
+ *     cdef FarWriter writer = FarWriter.__new__(FarWriter)             # <<<<<<<<<<<<<<
+ *     writer._writer = move(_tfar)
+ *     return writer
  */
-  __pyx_t_4 = ((PyObject *)__pyx_tp_new_9pywrapfst_FarWriter(((PyTypeObject *)__pyx_ptype_9pywrapfst_FarWriter), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4581, __pyx_L1_error)
-  __Pyx_GOTREF(((PyObject *)__pyx_t_4));
-  __pyx_v_result = ((struct __pyx_obj_9pywrapfst_FarWriter *)__pyx_t_4);
-  __pyx_t_4 = 0;
+  __pyx_t_6 = ((PyObject *)__pyx_tp_new_9pywrapfst_FarWriter(((PyTypeObject *)__pyx_ptype_9pywrapfst_FarWriter), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4622, __pyx_L1_error)
+  __Pyx_GOTREF(((PyObject *)__pyx_t_6));
+  __pyx_v_writer = ((struct __pyx_obj_9pywrapfst_FarWriter *)__pyx_t_6);
+  __pyx_t_6 = 0;
 
-  /* "pywrapfst.pyx":4582
- *       raise FstIOError("Open failed: {!r}".format(source))
- *     cdef FarWriter result = FarWriter.__new__(FarWriter)
- *     result._writer.reset(tfar)             # <<<<<<<<<<<<<<
- *     return result
+  /* "pywrapfst.pyx":4623
+ *       raise FstIOError(f"Open failed: {source!r}")
+ *     cdef FarWriter writer = FarWriter.__new__(FarWriter)
+ *     writer._writer = move(_tfar)             # <<<<<<<<<<<<<<
+ *     return writer
  * 
  */
-  if (unlikely(((PyObject *)__pyx_v_result) == Py_None)) {
+  if (unlikely(((PyObject *)__pyx_v_writer) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4582, __pyx_L1_error)
+    __PYX_ERR(0, 4623, __pyx_L1_error)
   }
-  __pyx_v_result->_writer.reset(__pyx_v_tfar);
+  __pyx_v_writer->_writer = fst::move<std::unique_ptr<fst::script::FarWriterClass> >(__pyx_v__tfar);
 
-  /* "pywrapfst.pyx":4583
- *     cdef FarWriter result = FarWriter.__new__(FarWriter)
- *     result._writer.reset(tfar)
- *     return result             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":4624
+ *     cdef FarWriter writer = FarWriter.__new__(FarWriter)
+ *     writer._writer = move(_tfar)
+ *     return writer             # <<<<<<<<<<<<<<
  * 
  *   # NB: Invoking this method may be dangerous: calling any other method on the
  */
   __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_result));
-  __pyx_r = ((PyObject *)__pyx_v_result);
+  __Pyx_INCREF(((PyObject *)__pyx_v_writer));
+  __pyx_r = ((PyObject *)__pyx_v_writer);
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4553
+  /* "pywrapfst.pyx":4594
  * 
  *   @classmethod
- *   def create(cls, source, arc_type=b"standard", far_type=b"default"):             # <<<<<<<<<<<<<<
+ *   def create(cls, source, arc_type="standard", far_type="default"):             # <<<<<<<<<<<<<<
  *     """
  *     FarWriter.
  */
 
   /* function exit code */
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6);
   __Pyx_XDECREF(__pyx_t_7);
   __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_9);
   __Pyx_AddTraceback("pywrapfst.FarWriter.create", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_result);
+  __Pyx_XDECREF((PyObject *)__pyx_v_writer);
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4587
+/* "pywrapfst.pyx":4628
  *   # NB: Invoking this method may be dangerous: calling any other method on the
  *   # instance after this is invoked may result in a null dereference.
  *   cdef void close(self):             # <<<<<<<<<<<<<<
@@ -46466,9 +47148,12 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_4create(CYTHON_UNUSED PyTypeObje
 
 static void __pyx_f_9pywrapfst_9FarWriter_close(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self) {
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("close", 0);
 
-  /* "pywrapfst.pyx":4588
+  /* "pywrapfst.pyx":4629
  *   # instance after this is invoked may result in a null dereference.
  *   cdef void close(self):
  *     self._writer.reset()             # <<<<<<<<<<<<<<
@@ -46477,11 +47162,11 @@ static void __pyx_f_9pywrapfst_9FarWriter_close(struct __pyx_obj_9pywrapfst_FarW
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4588, __pyx_L1_error)
+    __PYX_ERR(0, 4629, __pyx_L1_error)
   }
   __pyx_v_self->_writer.reset();
 
-  /* "pywrapfst.pyx":4587
+  /* "pywrapfst.pyx":4628
  *   # NB: Invoking this method may be dangerous: calling any other method on the
  *   # instance after this is invoked may result in a null dereference.
  *   cdef void close(self):             # <<<<<<<<<<<<<<
@@ -46497,7 +47182,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_close(struct __pyx_obj_9pywrapfst_FarW
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pywrapfst.pyx":4590
+/* "pywrapfst.pyx":4631
  *     self._writer.reset()
  * 
  *   cpdef void add(self, key, Fst ifst) except *:             # <<<<<<<<<<<<<<
@@ -46516,6 +47201,9 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
   PyObject *__pyx_t_6 = NULL;
   std::string __pyx_t_7;
   int __pyx_t_8;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("add", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -46526,7 +47214,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4590, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_add); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4631, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarWriter_7add)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -46545,7 +47233,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
         #if CYTHON_FAST_PYCALL
         if (PyFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_v_key, ((PyObject *)__pyx_v_ifst)};
-          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4590, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4631, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
@@ -46553,13 +47241,13 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
         #if CYTHON_FAST_PYCCALL
         if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
           PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_v_key, ((PyObject *)__pyx_v_ifst)};
-          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4590, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4631, __pyx_L1_error)
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_GOTREF(__pyx_t_2);
         } else
         #endif
         {
-          __pyx_t_6 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4590, __pyx_L1_error)
+          __pyx_t_6 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4631, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_6);
           if (__pyx_t_4) {
             __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); __pyx_t_4 = NULL;
@@ -46570,7 +47258,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
           __Pyx_INCREF(((PyObject *)__pyx_v_ifst));
           __Pyx_GIVEREF(((PyObject *)__pyx_v_ifst));
           PyTuple_SET_ITEM(__pyx_t_6, 1+__pyx_t_5, ((PyObject *)__pyx_v_ifst));
-          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4590, __pyx_L1_error)
+          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4631, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_2);
           __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
         }
@@ -46592,7 +47280,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
     #endif
   }
 
-  /* "pywrapfst.pyx":4608
+  /* "pywrapfst.pyx":4649
  *     # Failure here results from passing an FST with a different arc type than
  *     # used by the FAR was initialized to use.
  *     if not self._writer.get().Add(tostring(key), deref(ifst._fst)):             # <<<<<<<<<<<<<<
@@ -46601,24 +47289,24 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4608, __pyx_L1_error)
+    __PYX_ERR(0, 4649, __pyx_L1_error)
   }
-  __pyx_t_7 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4608, __pyx_L1_error)
+  __pyx_t_7 = __pyx_f_9pywrapfst_tostring(__pyx_v_key); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4649, __pyx_L1_error)
   if (unlikely(((PyObject *)__pyx_v_ifst) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_fst");
-    __PYX_ERR(0, 4608, __pyx_L1_error)
+    __PYX_ERR(0, 4649, __pyx_L1_error)
   }
   __pyx_t_8 = ((!(__pyx_v_self->_writer.get()->Add(__pyx_t_7, (*__pyx_v_ifst->_fst)) != 0)) != 0);
   if (unlikely(__pyx_t_8)) {
 
-    /* "pywrapfst.pyx":4609
+    /* "pywrapfst.pyx":4650
  *     # used by the FAR was initialized to use.
  *     if not self._writer.get().Add(tostring(key), deref(ifst._fst)):
  *       raise FstOpError("Incompatible or invalid arc type")             # <<<<<<<<<<<<<<
  * 
  *   cpdef string arc_type(self):
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4609, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstOpError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4650, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_3 = NULL;
     if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
@@ -46632,14 +47320,14 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
     }
     __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_kp_u_Incompatible_or_invalid_arc_type) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_Incompatible_or_invalid_arc_type);
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4609, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4650, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __Pyx_Raise(__pyx_t_1, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __PYX_ERR(0, 4609, __pyx_L1_error)
+    __PYX_ERR(0, 4650, __pyx_L1_error)
 
-    /* "pywrapfst.pyx":4608
+    /* "pywrapfst.pyx":4649
  *     # Failure here results from passing an FST with a different arc type than
  *     # used by the FAR was initialized to use.
  *     if not self._writer.get().Add(tostring(key), deref(ifst._fst)):             # <<<<<<<<<<<<<<
@@ -46648,7 +47336,7 @@ static void __pyx_f_9pywrapfst_9FarWriter_add(struct __pyx_obj_9pywrapfst_FarWri
  */
   }
 
-  /* "pywrapfst.pyx":4590
+  /* "pywrapfst.pyx":4631
  *     self._writer.reset()
  * 
  *   cpdef void add(self, key, Fst ifst) except *:             # <<<<<<<<<<<<<<
@@ -46675,6 +47363,9 @@ static char __pyx_doc_9pywrapfst_9FarWriter_6add[] = "\n    add(self, key, ifst)
 static PyObject *__pyx_pw_9pywrapfst_9FarWriter_7add(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_key = 0;
   struct __pyx_obj_9pywrapfst_Fst *__pyx_v_ifst = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("add (wrapper)", 0);
@@ -46701,11 +47392,11 @@ static PyObject *__pyx_pw_9pywrapfst_9FarWriter_7add(PyObject *__pyx_v_self, PyO
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_ifst)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("add", 1, 2, 2, 1); __PYX_ERR(0, 4590, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("add", 1, 2, 2, 1); __PYX_ERR(0, 4631, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add") < 0)) __PYX_ERR(0, 4590, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add") < 0)) __PYX_ERR(0, 4631, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -46718,13 +47409,13 @@ static PyObject *__pyx_pw_9pywrapfst_9FarWriter_7add(PyObject *__pyx_v_self, PyO
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("add", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4590, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("add", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 4631, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("pywrapfst.FarWriter.add", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4590, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ifst), __pyx_ptype_9pywrapfst_Fst, 1, "ifst", 0))) __PYX_ERR(0, 4631, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_9FarWriter_6add(((struct __pyx_obj_9pywrapfst_FarWriter *)__pyx_v_self), __pyx_v_key, __pyx_v_ifst);
 
   /* function exit code */
@@ -46740,10 +47431,13 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_6add(struct __pyx_obj_9pywrapfst
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("add", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_f_9pywrapfst_9FarWriter_add(__pyx_v_self, __pyx_v_key, __pyx_v_ifst, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4590, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4590, __pyx_L1_error)
+  __pyx_f_9pywrapfst_9FarWriter_add(__pyx_v_self, __pyx_v_key, __pyx_v_ifst, 1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4631, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_void_to_None(NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4631, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -46760,7 +47454,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_6add(struct __pyx_obj_9pywrapfst
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4611
+/* "pywrapfst.pyx":4652
  *       raise FstOpError("Incompatible or invalid arc type")
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -46777,6 +47471,9 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_arc_type(struct __pyx_obj_9pywr
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   std::string __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("arc_type", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -46787,7 +47484,7 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_arc_type(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4611, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_arc_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4652, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarWriter_9arc_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -46803,10 +47500,10 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_arc_type(struct __pyx_obj_9pywr
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4611, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4652, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4611, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4652, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -46825,7 +47522,7 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_arc_type(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":4617
+  /* "pywrapfst.pyx":4658
  *     Returns a string indicating the arc type.
  *     """
  *     return self._writer.get().ArcType()             # <<<<<<<<<<<<<<
@@ -46834,12 +47531,12 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_arc_type(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4617, __pyx_L1_error)
+    __PYX_ERR(0, 4658, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_writer.get()->ArcType();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4611
+  /* "pywrapfst.pyx":4652
  *       raise FstOpError("Incompatible or invalid arc type")
  * 
  *   cpdef string arc_type(self):             # <<<<<<<<<<<<<<
@@ -46878,9 +47575,12 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_8arc_type(struct __pyx_obj_9pywr
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("arc_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarWriter_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4611, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarWriter_arc_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4652, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -46897,7 +47597,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_8arc_type(struct __pyx_obj_9pywr
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4619
+/* "pywrapfst.pyx":4660
  *     return self._writer.get().ArcType()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -46914,6 +47614,9 @@ static bool __pyx_f_9pywrapfst_9FarWriter_error(struct __pyx_obj_9pywrapfst_FarW
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   bool __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("error", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -46924,7 +47627,7 @@ static bool __pyx_f_9pywrapfst_9FarWriter_error(struct __pyx_obj_9pywrapfst_FarW
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_error); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4619, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_error); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4660, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarWriter_11error)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -46940,10 +47643,10 @@ static bool __pyx_f_9pywrapfst_9FarWriter_error(struct __pyx_obj_9pywrapfst_FarW
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4619, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4660, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4619, __pyx_L1_error)
+        __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 4660, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -46962,7 +47665,7 @@ static bool __pyx_f_9pywrapfst_9FarWriter_error(struct __pyx_obj_9pywrapfst_FarW
     #endif
   }
 
-  /* "pywrapfst.pyx":4628
+  /* "pywrapfst.pyx":4669
  *       True if the FarWriter is in an errorful state, False otherwise.
  *     """
  *     return self._writer.get().Error()             # <<<<<<<<<<<<<<
@@ -46971,12 +47674,12 @@ static bool __pyx_f_9pywrapfst_9FarWriter_error(struct __pyx_obj_9pywrapfst_FarW
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4628, __pyx_L1_error)
+    __PYX_ERR(0, 4669, __pyx_L1_error)
   }
   __pyx_r = __pyx_v_self->_writer.get()->Error();
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4619
+  /* "pywrapfst.pyx":4660
  *     return self._writer.get().ArcType()
  * 
  *   cpdef bool error(self):             # <<<<<<<<<<<<<<
@@ -47015,9 +47718,12 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_10error(struct __pyx_obj_9pywrap
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("error", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_9FarWriter_error(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4619, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_9pywrapfst_9FarWriter_error(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4660, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -47034,7 +47740,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_10error(struct __pyx_obj_9pywrap
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4630
+/* "pywrapfst.pyx":4671
  *     return self._writer.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -47051,6 +47757,9 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
   std::string __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("far_type", 0);
   /* Check if called by wrapper */
   if (unlikely(__pyx_skip_dispatch)) ;
@@ -47061,7 +47770,7 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
     if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) {
       PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self));
       #endif
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_far_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4630, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_far_type); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4671, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_9pywrapfst_9FarWriter_13far_type)) {
         __Pyx_INCREF(__pyx_t_1);
@@ -47077,10 +47786,10 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
         }
         __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
         __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4630, __pyx_L1_error)
+        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4671, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4630, __pyx_L1_error)
+        __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4671, __pyx_L1_error)
         __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
         __pyx_r = __pyx_t_5;
         __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -47099,7 +47808,7 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
     #endif
   }
 
-  /* "pywrapfst.pyx":4636
+  /* "pywrapfst.pyx":4677
  *     Returns a string indicating the FAR type.
  *     """
  *     return fst.GetFarTypeString(self._writer.get().Type())             # <<<<<<<<<<<<<<
@@ -47108,12 +47817,12 @@ static std::string __pyx_f_9pywrapfst_9FarWriter_far_type(struct __pyx_obj_9pywr
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "_writer");
-    __PYX_ERR(0, 4636, __pyx_L1_error)
+    __PYX_ERR(0, 4677, __pyx_L1_error)
   }
   __pyx_r = fst::GetFarTypeString(__pyx_v_self->_writer.get()->Type());
   goto __pyx_L0;
 
-  /* "pywrapfst.pyx":4630
+  /* "pywrapfst.pyx":4671
  *     return self._writer.get().Error()
  * 
  *   cpdef string far_type(self):             # <<<<<<<<<<<<<<
@@ -47152,9 +47861,12 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_12far_type(struct __pyx_obj_9pyw
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("far_type", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarWriter_far_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4630, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyUnicode_string_to_py_std__in_string(__pyx_f_9pywrapfst_9FarWriter_far_type(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4671, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -47171,7 +47883,7 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_12far_type(struct __pyx_obj_9pyw
   return __pyx_r;
 }
 
-/* "pywrapfst.pyx":4639
+/* "pywrapfst.pyx":4680
  * 
  *   # Dictionary-like assignment.
  *   def __setitem__(self, key, Fst fst):             # <<<<<<<<<<<<<<
@@ -47182,10 +47894,13 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_12far_type(struct __pyx_obj_9pyw
 /* Python wrapper */
 static int __pyx_pw_9pywrapfst_9FarWriter_15__setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_fst); /*proto*/
 static int __pyx_pw_9pywrapfst_9FarWriter_15__setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_fst) {
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fst), __pyx_ptype_9pywrapfst_Fst, 1, "fst", 0))) __PYX_ERR(0, 4639, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_fst), __pyx_ptype_9pywrapfst_Fst, 1, "fst", 0))) __PYX_ERR(0, 4680, __pyx_L1_error)
   __pyx_r = __pyx_pf_9pywrapfst_9FarWriter_14__setitem__(((struct __pyx_obj_9pywrapfst_FarWriter *)__pyx_v_self), ((PyObject *)__pyx_v_key), ((struct __pyx_obj_9pywrapfst_Fst *)__pyx_v_fst));
 
   /* function exit code */
@@ -47200,9 +47915,12 @@ static int __pyx_pw_9pywrapfst_9FarWriter_15__setitem__(PyObject *__pyx_v_self,
 static int __pyx_pf_9pywrapfst_9FarWriter_14__setitem__(struct __pyx_obj_9pywrapfst_FarWriter *__pyx_v_self, PyObject *__pyx_v_key, struct __pyx_obj_9pywrapfst_Fst *__pyx_v_fst) {
   int __pyx_r;
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__setitem__", 0);
 
-  /* "pywrapfst.pyx":4640
+  /* "pywrapfst.pyx":4681
  *   # Dictionary-like assignment.
  *   def __setitem__(self, key, Fst fst):
  *     self.add(key, fst)             # <<<<<<<<<<<<<<
@@ -47211,11 +47929,11 @@ static int __pyx_pf_9pywrapfst_9FarWriter_14__setitem__(struct __pyx_obj_9pywrap
  */
   if (unlikely(((PyObject *)__pyx_v_self) == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "add");
-    __PYX_ERR(0, 4640, __pyx_L1_error)
+    __PYX_ERR(0, 4681, __pyx_L1_error)
   }
-  ((struct __pyx_vtabstruct_9pywrapfst_FarWriter *)__pyx_v_self->__pyx_vtab)->add(__pyx_v_self, __pyx_v_key, __pyx_v_fst, 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4640, __pyx_L1_error)
+  ((struct __pyx_vtabstruct_9pywrapfst_FarWriter *)__pyx_v_self->__pyx_vtab)->add(__pyx_v_self, __pyx_v_key, __pyx_v_fst, 0); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4681, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4639
+  /* "pywrapfst.pyx":4680
  * 
  *   # Dictionary-like assignment.
  *   def __setitem__(self, key, Fst fst):             # <<<<<<<<<<<<<<
@@ -47257,6 +47975,9 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_16__reduce_cython__(CYTHON_UNUSE
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__reduce_cython__", 0);
 
   /* "(tree fragment)":2
@@ -47311,6 +48032,9 @@ static PyObject *__pyx_pf_9pywrapfst_9FarWriter_18__setstate_cython__(CYTHON_UNU
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__setstate_cython__", 0);
 
   /* "(tree fragment)":4
@@ -47355,6 +48079,9 @@ static std::string __pyx_convert_string_from_py_std__in_string(PyObject *__pyx_v
   std::string __pyx_r;
   __Pyx_RefNannyDeclarations
   char const *__pyx_t_1;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__pyx_convert_string_from_py_std__in_string", 0);
 
   /* "string.from_py":14
@@ -47415,6 +48142,9 @@ static CYTHON_INLINE PyObject *__pyx_convert_PyObject_string_to_py_std__in_strin
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__pyx_convert_PyObject_string_to_py_std__in_string", 0);
 
   /* "string.to_py":32
@@ -47462,6 +48192,9 @@ static CYTHON_INLINE PyObject *__pyx_convert_PyUnicode_string_to_py_std__in_stri
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__pyx_convert_PyUnicode_string_to_py_std__in_string", 0);
 
   /* "string.to_py":38
@@ -47509,6 +48242,9 @@ static CYTHON_INLINE PyObject *__pyx_convert_PyStr_string_to_py_std__in_string(s
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__pyx_convert_PyStr_string_to_py_std__in_string", 0);
 
   /* "string.to_py":44
@@ -47556,6 +48292,9 @@ static CYTHON_INLINE PyObject *__pyx_convert_PyBytes_string_to_py_std__in_string
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__pyx_convert_PyBytes_string_to_py_std__in_string", 0);
 
   /* "string.to_py":50
@@ -47603,6 +48342,9 @@ static CYTHON_INLINE PyObject *__pyx_convert_PyByteArray_string_to_py_std__in_st
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__pyx_convert_PyByteArray_string_to_py_std__in_string", 0);
 
   /* "string.to_py":56
@@ -47655,6 +48397,9 @@ static std::vector<int64>  __pyx_convert_vector_from_py_int64(PyObject *__pyx_v_
   PyObject *(*__pyx_t_3)(PyObject *);
   PyObject *__pyx_t_4 = NULL;
   int64 __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__pyx_convert_vector_from_py_int64", 0);
 
   /* "vector.from_py":47
@@ -47755,6 +48500,120 @@ static std::vector<int64>  __pyx_convert_vector_from_py_int64(PyObject *__pyx_v_
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
+
+static std::vector<std::string>  __pyx_convert_vector_from_py_std_3a__3a_string(PyObject *__pyx_v_o) {
+  std::vector<std::string>  __pyx_v_v;
+  PyObject *__pyx_v_item = NULL;
+  std::vector<std::string>  __pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  Py_ssize_t __pyx_t_2;
+  PyObject *(*__pyx_t_3)(PyObject *);
+  PyObject *__pyx_t_4 = NULL;
+  std::string __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__pyx_convert_vector_from_py_std_3a__3a_string", 0);
+
+  /* "vector.from_py":47
+ * cdef vector[X] __pyx_convert_vector_from_py_std_3a__3a_string(object o) except *:
+ *     cdef vector[X] v
+ *     for item in o:             # <<<<<<<<<<<<<<
+ *         v.push_back(<X>item)
+ *     return v
+ */
+  if (likely(PyList_CheckExact(__pyx_v_o)) || PyTuple_CheckExact(__pyx_v_o)) {
+    __pyx_t_1 = __pyx_v_o; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+    __pyx_t_3 = NULL;
+  } else {
+    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_o); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 47, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 47, __pyx_L1_error)
+  }
+  for (;;) {
+    if (likely(!__pyx_t_3)) {
+      if (likely(PyList_CheckExact(__pyx_t_1))) {
+        if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
+        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
+        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(1, 47, __pyx_L1_error)
+        #else
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 47, __pyx_L1_error)
+        __Pyx_GOTREF(__pyx_t_4);
+        #endif
+      } else {
+        if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
+        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(1, 47, __pyx_L1_error)
+        #else
+        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 47, __pyx_L1_error)
+        __Pyx_GOTREF(__pyx_t_4);
+        #endif
+      }
+    } else {
+      __pyx_t_4 = __pyx_t_3(__pyx_t_1);
+      if (unlikely(!__pyx_t_4)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else __PYX_ERR(1, 47, __pyx_L1_error)
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_4);
+    }
+    __Pyx_XDECREF_SET(__pyx_v_item, __pyx_t_4);
+    __pyx_t_4 = 0;
+
+    /* "vector.from_py":48
+ *     cdef vector[X] v
+ *     for item in o:
+ *         v.push_back(<X>item)             # <<<<<<<<<<<<<<
+ *     return v
+ * 
+ */
+    __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_v_item); if (unlikely(PyErr_Occurred())) __PYX_ERR(1, 48, __pyx_L1_error)
+    __pyx_v_v.push_back(((std::string)__pyx_t_5));
+
+    /* "vector.from_py":47
+ * cdef vector[X] __pyx_convert_vector_from_py_std_3a__3a_string(object o) except *:
+ *     cdef vector[X] v
+ *     for item in o:             # <<<<<<<<<<<<<<
+ *         v.push_back(<X>item)
+ *     return v
+ */
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "vector.from_py":49
+ *     for item in o:
+ *         v.push_back(<X>item)
+ *     return v             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __pyx_r = __pyx_v_v;
+  goto __pyx_L0;
+
+  /* "vector.from_py":45
+ * 
+ * @cname("__pyx_convert_vector_from_py_std_3a__3a_string")
+ * cdef vector[X] __pyx_convert_vector_from_py_std_3a__3a_string(object o) except *:             # <<<<<<<<<<<<<<
+ *     cdef vector[X] v
+ *     for item in o:
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("vector.from_py.__pyx_convert_vector_from_py_std_3a__3a_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_pretend_to_initialize(&__pyx_r);
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_item);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 static struct __pyx_vtabstruct_9pywrapfst_Weight __pyx_vtable_9pywrapfst_Weight;
 
 static PyObject *__pyx_tp_new_9pywrapfst_Weight(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
@@ -47940,10 +48799,10 @@ static PyTypeObject __pyx_type_9pywrapfst_Weight = {
   0, /*tp_print*/
   #endif
 };
-static struct __pyx_vtabstruct_9pywrapfst__SymbolTable __pyx_vtable_9pywrapfst__SymbolTable;
+static struct __pyx_vtabstruct_9pywrapfst_SymbolTableView __pyx_vtable_9pywrapfst_SymbolTableView;
 
-static PyObject *__pyx_tp_new_9pywrapfst__SymbolTable(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
-  struct __pyx_obj_9pywrapfst__SymbolTable *p;
+static PyObject *__pyx_tp_new_9pywrapfst_SymbolTableView(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+  struct __pyx_obj_9pywrapfst_SymbolTableView *p;
   PyObject *o;
   if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
     o = (*t->tp_alloc)(t, 0);
@@ -47951,12 +48810,12 @@ static PyObject *__pyx_tp_new_9pywrapfst__SymbolTable(PyTypeObject *t, CYTHON_UN
     o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
   }
   if (unlikely(!o)) return 0;
-  p = ((struct __pyx_obj_9pywrapfst__SymbolTable *)o);
-  p->__pyx_vtab = __pyx_vtabptr_9pywrapfst__SymbolTable;
+  p = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)o);
+  p->__pyx_vtab = __pyx_vtabptr_9pywrapfst_SymbolTableView;
   return o;
 }
 
-static void __pyx_tp_dealloc_9pywrapfst__SymbolTable(PyObject *o) {
+static void __pyx_tp_dealloc_9pywrapfst_SymbolTableView(PyObject *o) {
   #if CYTHON_USE_TP_FINALIZE
   if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
     if (PyObject_CallFinalizerFromDealloc(o)) return;
@@ -47965,42 +48824,29 @@ static void __pyx_tp_dealloc_9pywrapfst__SymbolTable(PyObject *o) {
   (*Py_TYPE(o)->tp_free)(o);
 }
 
-static PyMethodDef __pyx_methods_9pywrapfst__SymbolTable[] = {
-  {"__reduce__", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_5__reduce__, METH_NOARGS, 0},
-  {"available_key", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_7available_key, METH_NOARGS, __pyx_doc_9pywrapfst_12_SymbolTable_6available_key},
-  {"checksum", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_9checksum, METH_NOARGS, __pyx_doc_9pywrapfst_12_SymbolTable_8checksum},
-  {"copy", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_11copy, METH_NOARGS, __pyx_doc_9pywrapfst_12_SymbolTable_10copy},
-  {"find", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_13find, METH_O, __pyx_doc_9pywrapfst_12_SymbolTable_12find},
-  {"get_nth_key", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_15get_nth_key, METH_O, __pyx_doc_9pywrapfst_12_SymbolTable_14get_nth_key},
-  {"labeled_checksum", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_17labeled_checksum, METH_NOARGS, __pyx_doc_9pywrapfst_12_SymbolTable_16labeled_checksum},
-  {"member", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_19member, METH_O, __pyx_doc_9pywrapfst_12_SymbolTable_18member},
-  {"name", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_23name, METH_NOARGS, __pyx_doc_9pywrapfst_12_SymbolTable_22name},
-  {"num_symbols", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_25num_symbols, METH_NOARGS, __pyx_doc_9pywrapfst_12_SymbolTable_24num_symbols},
-  {"write", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_27write, METH_O, __pyx_doc_9pywrapfst_12_SymbolTable_26write},
-  {"write_text", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_29write_text, METH_O, __pyx_doc_9pywrapfst_12_SymbolTable_28write_text},
-  {"write_to_string", (PyCFunction)__pyx_pw_9pywrapfst_12_SymbolTable_31write_to_string, METH_NOARGS, __pyx_doc_9pywrapfst_12_SymbolTable_30write_to_string},
+static PyMethodDef __pyx_methods_9pywrapfst_SymbolTableView[] = {
+  {"__reduce__", (PyCFunction)__pyx_pw_9pywrapfst_15SymbolTableView_5__reduce__, METH_NOARGS, 0},
+  {"available_key", (PyCFunction)__pyx_pw_9pywrapfst_15SymbolTableView_7available_key, METH_NOARGS, __pyx_doc_9pywrapfst_15SymbolTableView_6available_key},
+  {"checksum", (PyCFunction)__pyx_pw_9pywrapfst_15SymbolTableView_9checksum, METH_NOARGS, __pyx_doc_9pywrapfst_15SymbolTableView_8checksum},
+  {"copy", (PyCFunction)__pyx_pw_9pywrapfst_15SymbolTableView_11copy, METH_NOARGS, __pyx_doc_9pywrapfst_15SymbolTableView_10copy},
+  {"find", (PyCFunction)__pyx_pw_9pywrapfst_15SymbolTableView_13find, METH_O, __pyx_doc_9pywrapfst_15SymbolTableView_12find},
+  {"get_nth_key", (PyCFunction)__pyx_pw_9pywrapfst_15SymbolTableView_15get_nth_key, METH_O, __pyx_doc_9pywrapfst_15SymbolTableView_14get_nth_key},
+  {"labeled_checksum", (PyCFunction)__pyx_pw_9pywrapfst_15SymbolTableView_17labeled_checksum, METH_NOARGS, __pyx_doc_9pywrapfst_15SymbolTableView_16labeled_checksum},
+  {"member", (PyCFunction)__pyx_pw_9pywrapfst_15SymbolTableView_19member, METH_O, __pyx_doc_9pywrapfst_15SymbolTableView_18member},
+  {"name", (PyCFunction)__pyx_pw_9pywrapfst_15SymbolTableView_21name, METH_NOARGS, __pyx_doc_9pywrapfst_15SymbolTableView_20name},
+  {"num_symbols", (PyCFunction)__pyx_pw_9pywrapfst_15SymbolTableView_23num_symbols, METH_NOARGS, __pyx_doc_9pywrapfst_15SymbolTableView_22num_symbols},
+  {"write", (PyCFunction)__pyx_pw_9pywrapfst_15SymbolTableView_25write, METH_O, __pyx_doc_9pywrapfst_15SymbolTableView_24write},
+  {"write_text", (PyCFunction)__pyx_pw_9pywrapfst_15SymbolTableView_27write_text, METH_O, __pyx_doc_9pywrapfst_15SymbolTableView_26write_text},
+  {"write_to_string", (PyCFunction)__pyx_pw_9pywrapfst_15SymbolTableView_29write_to_string, METH_NOARGS, __pyx_doc_9pywrapfst_15SymbolTableView_28write_to_string},
   {0, 0, 0, 0}
 };
 
-static PySequenceMethods __pyx_tp_as_sequence__SymbolTable = {
-  0, /*sq_length*/
-  0, /*sq_concat*/
-  0, /*sq_repeat*/
-  0, /*sq_item*/
-  0, /*sq_slice*/
-  0, /*sq_ass_item*/
-  0, /*sq_ass_slice*/
-  __pyx_pw_9pywrapfst_12_SymbolTable_21__contains__, /*sq_contains*/
-  0, /*sq_inplace_concat*/
-  0, /*sq_inplace_repeat*/
-};
-
-static PyTypeObject __pyx_type_9pywrapfst__SymbolTable = {
+static PyTypeObject __pyx_type_9pywrapfst_SymbolTableView = {
   PyVarObject_HEAD_INIT(0, 0)
-  "pywrapfst._SymbolTable", /*tp_name*/
-  sizeof(struct __pyx_obj_9pywrapfst__SymbolTable), /*tp_basicsize*/
+  "pywrapfst.SymbolTableView", /*tp_name*/
+  sizeof(struct __pyx_obj_9pywrapfst_SymbolTableView), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_9pywrapfst__SymbolTable, /*tp_dealloc*/
+  __pyx_tp_dealloc_9pywrapfst_SymbolTableView, /*tp_dealloc*/
   #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
   #endif
@@ -48017,7 +48863,7 @@ static PyTypeObject __pyx_type_9pywrapfst__SymbolTable = {
   #endif
   0, /*tp_repr*/
   0, /*tp_as_number*/
-  &__pyx_tp_as_sequence__SymbolTable, /*tp_as_sequence*/
+  0, /*tp_as_sequence*/
   0, /*tp_as_mapping*/
   0, /*tp_hash*/
   0, /*tp_call*/
@@ -48031,9 +48877,9 @@ static PyTypeObject __pyx_type_9pywrapfst__SymbolTable = {
   0, /*tp_clear*/
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
-  __pyx_pw_9pywrapfst_12_SymbolTable_3__iter__, /*tp_iter*/
+  __pyx_pw_9pywrapfst_15SymbolTableView_3__iter__, /*tp_iter*/
   0, /*tp_iternext*/
-  __pyx_methods_9pywrapfst__SymbolTable, /*tp_methods*/
+  __pyx_methods_9pywrapfst_SymbolTableView, /*tp_methods*/
   0, /*tp_members*/
   0, /*tp_getset*/
   0, /*tp_base*/
@@ -48041,9 +48887,9 @@ static PyTypeObject __pyx_type_9pywrapfst__SymbolTable = {
   0, /*tp_descr_get*/
   0, /*tp_descr_set*/
   0, /*tp_dictoffset*/
-  __pyx_pw_9pywrapfst_12_SymbolTable_1__init__, /*tp_init*/
+  __pyx_pw_9pywrapfst_15SymbolTableView_1__init__, /*tp_init*/
   0, /*tp_alloc*/
-  __pyx_tp_new_9pywrapfst__SymbolTable, /*tp_new*/
+  __pyx_tp_new_9pywrapfst_SymbolTableView, /*tp_new*/
   0, /*tp_free*/
   0, /*tp_is_gc*/
   0, /*tp_bases*/
@@ -48067,10 +48913,10 @@ static struct __pyx_vtabstruct_9pywrapfst__EncodeMapperSymbolTableView __pyx_vta
 
 static PyObject *__pyx_tp_new_9pywrapfst__EncodeMapperSymbolTableView(PyTypeObject *t, PyObject *a, PyObject *k) {
   struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *p;
-  PyObject *o = __pyx_tp_new_9pywrapfst__SymbolTable(t, a, k);
+  PyObject *o = __pyx_tp_new_9pywrapfst_SymbolTableView(t, a, k);
   if (unlikely(!o)) return 0;
   p = ((struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *)o);
-  p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_9pywrapfst__SymbolTable*)__pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTableView;
+  p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_9pywrapfst_SymbolTableView*)__pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTableView;
   new((void*)&(p->_mapper)) std::shared_ptr<fst::script::EncodeMapperClass> ();
   return o;
 }
@@ -48083,7 +48929,7 @@ static void __pyx_tp_dealloc_9pywrapfst__EncodeMapperSymbolTableView(PyObject *o
   }
   #endif
   __Pyx_call_destructor(p->_mapper);
-  __pyx_tp_dealloc_9pywrapfst__SymbolTable(o);
+  __pyx_tp_dealloc_9pywrapfst_SymbolTableView(o);
 }
 
 static PyMethodDef __pyx_methods_9pywrapfst__EncodeMapperSymbolTableView[] = {
@@ -48127,7 +48973,7 @@ static PyTypeObject __pyx_type_9pywrapfst__EncodeMapperSymbolTableView = {
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
   #if CYTHON_COMPILING_IN_PYPY
-  __pyx_pw_9pywrapfst_12_SymbolTable_3__iter__, /*tp_iter*/
+  __pyx_pw_9pywrapfst_15SymbolTableView_3__iter__, /*tp_iter*/
   #else
   0, /*tp_iter*/
   #endif
@@ -48141,7 +48987,7 @@ static PyTypeObject __pyx_type_9pywrapfst__EncodeMapperSymbolTableView = {
   0, /*tp_descr_set*/
   0, /*tp_dictoffset*/
   #if CYTHON_COMPILING_IN_PYPY
-  __pyx_pw_9pywrapfst_12_SymbolTable_1__init__, /*tp_init*/
+  __pyx_pw_9pywrapfst_15SymbolTableView_1__init__, /*tp_init*/
   #else
   0, /*tp_init*/
   #endif
@@ -48170,10 +49016,10 @@ static struct __pyx_vtabstruct_9pywrapfst__FstSymbolTableView __pyx_vtable_9pywr
 
 static PyObject *__pyx_tp_new_9pywrapfst__FstSymbolTableView(PyTypeObject *t, PyObject *a, PyObject *k) {
   struct __pyx_obj_9pywrapfst__FstSymbolTableView *p;
-  PyObject *o = __pyx_tp_new_9pywrapfst__SymbolTable(t, a, k);
+  PyObject *o = __pyx_tp_new_9pywrapfst_SymbolTableView(t, a, k);
   if (unlikely(!o)) return 0;
   p = ((struct __pyx_obj_9pywrapfst__FstSymbolTableView *)o);
-  p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_9pywrapfst__SymbolTable*)__pyx_vtabptr_9pywrapfst__FstSymbolTableView;
+  p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_9pywrapfst_SymbolTableView*)__pyx_vtabptr_9pywrapfst__FstSymbolTableView;
   new((void*)&(p->_fst)) std::shared_ptr<fst::script::FstClass> ();
   return o;
 }
@@ -48186,7 +49032,7 @@ static void __pyx_tp_dealloc_9pywrapfst__FstSymbolTableView(PyObject *o) {
   }
   #endif
   __Pyx_call_destructor(p->_fst);
-  __pyx_tp_dealloc_9pywrapfst__SymbolTable(o);
+  __pyx_tp_dealloc_9pywrapfst_SymbolTableView(o);
 }
 
 static PyMethodDef __pyx_methods_9pywrapfst__FstSymbolTableView[] = {
@@ -48230,7 +49076,7 @@ static PyTypeObject __pyx_type_9pywrapfst__FstSymbolTableView = {
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
   #if CYTHON_COMPILING_IN_PYPY
-  __pyx_pw_9pywrapfst_12_SymbolTable_3__iter__, /*tp_iter*/
+  __pyx_pw_9pywrapfst_15SymbolTableView_3__iter__, /*tp_iter*/
   #else
   0, /*tp_iter*/
   #endif
@@ -48244,7 +49090,7 @@ static PyTypeObject __pyx_type_9pywrapfst__FstSymbolTableView = {
   0, /*tp_descr_set*/
   0, /*tp_dictoffset*/
   #if CYTHON_COMPILING_IN_PYPY
-  __pyx_pw_9pywrapfst_12_SymbolTable_1__init__, /*tp_init*/
+  __pyx_pw_9pywrapfst_15SymbolTableView_1__init__, /*tp_init*/
   #else
   0, /*tp_init*/
   #endif
@@ -48273,10 +49119,10 @@ static struct __pyx_vtabstruct_9pywrapfst__MutableSymbolTable __pyx_vtable_9pywr
 
 static PyObject *__pyx_tp_new_9pywrapfst__MutableSymbolTable(PyTypeObject *t, PyObject *a, PyObject *k) {
   struct __pyx_obj_9pywrapfst__MutableSymbolTable *p;
-  PyObject *o = __pyx_tp_new_9pywrapfst__SymbolTable(t, a, k);
+  PyObject *o = __pyx_tp_new_9pywrapfst_SymbolTableView(t, a, k);
   if (unlikely(!o)) return 0;
   p = ((struct __pyx_obj_9pywrapfst__MutableSymbolTable *)o);
-  p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_9pywrapfst__SymbolTable*)__pyx_vtabptr_9pywrapfst__MutableSymbolTable;
+  p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_9pywrapfst_SymbolTableView*)__pyx_vtabptr_9pywrapfst__MutableSymbolTable;
   return o;
 }
 
@@ -48292,7 +49138,7 @@ static PyTypeObject __pyx_type_9pywrapfst__MutableSymbolTable = {
   "pywrapfst._MutableSymbolTable", /*tp_name*/
   sizeof(struct __pyx_obj_9pywrapfst__MutableSymbolTable), /*tp_basicsize*/
   0, /*tp_itemsize*/
-  __pyx_tp_dealloc_9pywrapfst__SymbolTable, /*tp_dealloc*/
+  __pyx_tp_dealloc_9pywrapfst_SymbolTableView, /*tp_dealloc*/
   #if PY_VERSION_HEX < 0x030800b4
   0, /*tp_print*/
   #endif
@@ -48324,7 +49170,7 @@ static PyTypeObject __pyx_type_9pywrapfst__MutableSymbolTable = {
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
   #if CYTHON_COMPILING_IN_PYPY
-  __pyx_pw_9pywrapfst_12_SymbolTable_3__iter__, /*tp_iter*/
+  __pyx_pw_9pywrapfst_15SymbolTableView_3__iter__, /*tp_iter*/
   #else
   0, /*tp_iter*/
   #endif
@@ -48338,7 +49184,7 @@ static PyTypeObject __pyx_type_9pywrapfst__MutableSymbolTable = {
   0, /*tp_descr_set*/
   0, /*tp_dictoffset*/
   #if CYTHON_COMPILING_IN_PYPY
-  __pyx_pw_9pywrapfst_12_SymbolTable_1__init__, /*tp_init*/
+  __pyx_pw_9pywrapfst_15SymbolTableView_1__init__, /*tp_init*/
   #else
   0, /*tp_init*/
   #endif
@@ -48370,7 +49216,7 @@ static PyObject *__pyx_tp_new_9pywrapfst__MutableFstSymbolTableView(PyTypeObject
   PyObject *o = __pyx_tp_new_9pywrapfst__MutableSymbolTable(t, a, k);
   if (unlikely(!o)) return 0;
   p = ((struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *)o);
-  p->__pyx_base.__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_9pywrapfst__SymbolTable*)__pyx_vtabptr_9pywrapfst__MutableFstSymbolTableView;
+  p->__pyx_base.__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_9pywrapfst_SymbolTableView*)__pyx_vtabptr_9pywrapfst__MutableFstSymbolTableView;
   new((void*)&(p->_mfst)) std::shared_ptr<fst::script::MutableFstClass> ();
   return o;
 }
@@ -48383,7 +49229,7 @@ static void __pyx_tp_dealloc_9pywrapfst__MutableFstSymbolTableView(PyObject *o)
   }
   #endif
   __Pyx_call_destructor(p->_mfst);
-  __pyx_tp_dealloc_9pywrapfst__SymbolTable(o);
+  __pyx_tp_dealloc_9pywrapfst_SymbolTableView(o);
 }
 
 static PyMethodDef __pyx_methods_9pywrapfst__MutableFstSymbolTableView[] = {
@@ -48427,7 +49273,7 @@ static PyTypeObject __pyx_type_9pywrapfst__MutableFstSymbolTableView = {
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
   #if CYTHON_COMPILING_IN_PYPY
-  __pyx_pw_9pywrapfst_12_SymbolTable_3__iter__, /*tp_iter*/
+  __pyx_pw_9pywrapfst_15SymbolTableView_3__iter__, /*tp_iter*/
   #else
   0, /*tp_iter*/
   #endif
@@ -48441,7 +49287,7 @@ static PyTypeObject __pyx_type_9pywrapfst__MutableFstSymbolTableView = {
   0, /*tp_descr_set*/
   0, /*tp_dictoffset*/
   #if CYTHON_COMPILING_IN_PYPY
-  __pyx_pw_9pywrapfst_12_SymbolTable_1__init__, /*tp_init*/
+  __pyx_pw_9pywrapfst_15SymbolTableView_1__init__, /*tp_init*/
   #else
   0, /*tp_init*/
   #endif
@@ -48473,7 +49319,7 @@ static PyObject *__pyx_tp_new_9pywrapfst_SymbolTable(PyTypeObject *t, PyObject *
   PyObject *o = __pyx_tp_new_9pywrapfst__MutableSymbolTable(t, a, k);
   if (unlikely(!o)) return 0;
   p = ((struct __pyx_obj_9pywrapfst_SymbolTable *)o);
-  p->__pyx_base.__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_9pywrapfst__SymbolTable*)__pyx_vtabptr_9pywrapfst_SymbolTable;
+  p->__pyx_base.__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_9pywrapfst_SymbolTableView*)__pyx_vtabptr_9pywrapfst_SymbolTable;
   new((void*)&(p->_smart_table)) std::unique_ptr<fst::SymbolTable> ();
   return o;
 }
@@ -48486,7 +49332,7 @@ static void __pyx_tp_dealloc_9pywrapfst_SymbolTable(PyObject *o) {
   }
   #endif
   __Pyx_call_destructor(p->_smart_table);
-  __pyx_tp_dealloc_9pywrapfst__SymbolTable(o);
+  __pyx_tp_dealloc_9pywrapfst_SymbolTableView(o);
 }
 
 static PyMethodDef __pyx_methods_9pywrapfst_SymbolTable[] = {
@@ -48533,7 +49379,7 @@ static PyTypeObject __pyx_type_9pywrapfst_SymbolTable = {
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
   #if CYTHON_COMPILING_IN_PYPY
-  __pyx_pw_9pywrapfst_12_SymbolTable_3__iter__, /*tp_iter*/
+  __pyx_pw_9pywrapfst_15SymbolTableView_3__iter__, /*tp_iter*/
   #else
   0, /*tp_iter*/
   #endif
@@ -48580,7 +49426,7 @@ static PyObject *__pyx_tp_new_9pywrapfst__SymbolTableIterator(PyTypeObject *t, C
   if (unlikely(!o)) return 0;
   p = ((struct __pyx_obj_9pywrapfst__SymbolTableIterator *)o);
   new((void*)&(p->_siter)) std::unique_ptr<fst::SymbolTable::iterator> ();
-  p->_table = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None); Py_INCREF(Py_None);
+  p->_table = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None); Py_INCREF(Py_None);
   return o;
 }
 
@@ -48610,7 +49456,7 @@ static int __pyx_tp_clear_9pywrapfst__SymbolTableIterator(PyObject *o) {
   PyObject* tmp;
   struct __pyx_obj_9pywrapfst__SymbolTableIterator *p = (struct __pyx_obj_9pywrapfst__SymbolTableIterator *)o;
   tmp = ((PyObject*)p->_table);
-  p->_table = ((struct __pyx_obj_9pywrapfst__SymbolTable *)Py_None); Py_INCREF(Py_None);
+  p->_table = ((struct __pyx_obj_9pywrapfst_SymbolTableView *)Py_None); Py_INCREF(Py_None);
   Py_XDECREF(tmp);
   return 0;
 }
@@ -48655,7 +49501,7 @@ static PyTypeObject __pyx_type_9pywrapfst__SymbolTableIterator = {
   0, /*tp_setattro*/
   0, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
-  "\n  _SymbolTableIterator(syms)\n\n  This class is used for iterating over a symbol table.\n  ", /*tp_doc*/
+  "\n  _SymbolTableIterator(symbols)\n\n  This class is used for iterating over a symbol table.\n  ", /*tp_doc*/
   __pyx_tp_traverse_9pywrapfst__SymbolTableIterator, /*tp_traverse*/
   __pyx_tp_clear_9pywrapfst__SymbolTableIterator, /*tp_clear*/
   0, /*tp_richcompare*/
@@ -48853,11 +49699,10 @@ static PyMethodDef __pyx_methods_9pywrapfst_Fst[] = {
   {"read_from_string", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_39read_from_string, METH_O, __pyx_doc_9pywrapfst_3Fst_38read_from_string},
   {"start", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_41start, METH_NOARGS, __pyx_doc_9pywrapfst_3Fst_40start},
   {"states", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_43states, METH_NOARGS, __pyx_doc_9pywrapfst_3Fst_42states},
-  {"text", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_3Fst_45text, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_3Fst_44text},
-  {"verify", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_47verify, METH_NOARGS, __pyx_doc_9pywrapfst_3Fst_46verify},
-  {"weight_type", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_49weight_type, METH_NOARGS, __pyx_doc_9pywrapfst_3Fst_48weight_type},
-  {"write", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_51write, METH_O, __pyx_doc_9pywrapfst_3Fst_50write},
-  {"write_to_string", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_53write_to_string, METH_NOARGS, __pyx_doc_9pywrapfst_3Fst_52write_to_string},
+  {"verify", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_45verify, METH_NOARGS, __pyx_doc_9pywrapfst_3Fst_44verify},
+  {"weight_type", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_47weight_type, METH_NOARGS, __pyx_doc_9pywrapfst_3Fst_46weight_type},
+  {"write", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_49write, METH_O, __pyx_doc_9pywrapfst_3Fst_48write},
+  {"write_to_string", (PyCFunction)__pyx_pw_9pywrapfst_3Fst_51write_to_string, METH_NOARGS, __pyx_doc_9pywrapfst_3Fst_50write_to_string},
   {0, 0, 0, 0}
 };
 
@@ -48970,7 +49815,7 @@ static PyMethodDef __pyx_methods_9pywrapfst_MutableFst[] = {
   {"mutable_input_symbols", (PyCFunction)__pyx_pw_9pywrapfst_10MutableFst_29mutable_input_symbols, METH_NOARGS, __pyx_doc_9pywrapfst_10MutableFst_28mutable_input_symbols},
   {"mutable_output_symbols", (PyCFunction)__pyx_pw_9pywrapfst_10MutableFst_31mutable_output_symbols, METH_NOARGS, __pyx_doc_9pywrapfst_10MutableFst_30mutable_output_symbols},
   {"num_states", (PyCFunction)__pyx_pw_9pywrapfst_10MutableFst_33num_states, METH_NOARGS, __pyx_doc_9pywrapfst_10MutableFst_32num_states},
-  {"project", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_10MutableFst_35project, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_10MutableFst_34project},
+  {"project", (PyCFunction)__pyx_pw_9pywrapfst_10MutableFst_35project, METH_O, __pyx_doc_9pywrapfst_10MutableFst_34project},
   {"prune", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_10MutableFst_37prune, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_10MutableFst_36prune},
   {"push", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_10MutableFst_39push, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_10MutableFst_38push},
   {"relabel_pairs", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_10MutableFst_41relabel_pairs, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_10MutableFst_40relabel_pairs},
@@ -49741,7 +50586,7 @@ static PyTypeObject __pyx_type_9pywrapfst_Compiler = {
   0, /*tp_setattro*/
   0, /*tp_as_buffer*/
   Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
-  "\n  Compiler(fst_type=\"vector\", arc_type=\"standard\", isymbols=None,\n           osymbols=None, ssymbols=None, acceptor=False, keep_isymbols=False,\n           keep_osymbols=False, keep_state_numbering=False,\n           allow_negative_labels=False)\n\n  Class used to compile FSTs from strings.\n\n  This class is used to compile FSTs specified using the AT&T FSM library\n  format described here:\n\n  http://web.eecs.umich.edu/~radev/NLP-fall2015/resources/fsm_archive/fsm.5.html\n\n  This is the same format used by the `fstcompile` executable.\n\n  Compiler options (symbol tables, etc.) are set at construction time.\n\n      compiler = fst.Compiler(isymbols=ascii_syms, osymbols=ascii_syms)\n\n  Once constructed, Compiler instances behave like a file handle opened for\n  writing:\n\n      # /ba+/\n      compiler.write(\"0 1 50 50\")\n      compiler.write(\"1 2 49 49\")\n      compiler.write(\"2 2 49 49\")\n      compiler.write(\"2\")\n\n  The `compile` method returns an actual FST instance:\n\n      sheep_machine = compiler.compile()\n\n  Compilation flushes the internal buffer, so the compiler instance can be\n  reused to compile new machines with the same symbol tables (etc.)\n\n  Args:\n    fst_type: A string indicating the container type for the compiled FST.\n    arc_type: A string indicating the arc type for the compiled FST.\n    isymbols: An optional SymbolTable used to label input symbols.\n    osymbols: An optional SymbolTable used to label output symbols.\n    ssymbols: An optional SymbolTable used to label states.\n    acceptor: Should the FST be rendered in acceptor format if possible?\n    keep_isymbols: Should the input symbol table be stored in the FST?\n    keep_osymbols: Should the output symbol table be stored in the FST?\n    keep_state_numbering: Should the state numbering be preserved?\n    allow_negative_labels: Should negative labels be allowed? (Not\n        recommended; may cause conflicts).\n  ", /*tp_doc*/
+  "\n  Compiler(fst_type=\"vector\", arc_type=\"standard\", isymbols=None,\n           osymbols=None, ssymbols=None, acceptor=False, keep_isymbols=False,\n           keep_osymbols=False, keep_state_numbering=False,\n           allow_negative_labels=False)\n\n  Class used to compile FSTs from strings.\n\n  This class is used to compile FSTs specified using the AT&T FSM library\n  format described here:\n\n  http://web.eecs.umich.edu/~radev/NLP-fall2015/resources/fsm_archive/fsm.5.html\n\n  This is the same format used by the `fstcompile` executable.\n\n  Compiler options (symbol tables, etc.) are set at construction time.\n\n      compiler = fst.Compiler(isymbols=ascii_symbols, osymbols=ascii_symbols)\n\n  Once constructed, Compiler instances behave like a file handle opened for\n  writing:\n\n      # /ba+/\n      compiler.write(\"0 1 50 50\")\n      compiler.write(\"1 2 49 49\")\n      compiler.write(\"2 2 49 49\")\n      compiler.write(\"2\")\n\n  The `compile` method returns an actual FST instance:\n\n      sheep_machine = compiler.compile()\n\n  Compilation flushes the internal buffer, so the compiler instance can be\n  reused to compile new machines with the same symbol tables (etc.)\n\n  Args:\n    fst_type: A string indicating the container type for the compiled FST.\n    arc_type: A string indicating the arc type for the compiled FST.\n    isymbols: An optional SymbolTable used to label input symbols.\n    osymbols: An optional SymbolTable used to label output symbols.\n    ssymbols: An optional SymbolTable used to label states.\n    acceptor: Should the FST be rendered in acceptor format if possible?\n    keep_isymbols: Should the input symbol table be stored in the FST?\n    keep_osymbols: Should the output symbol table be stored in the FST?\n    keep_state_numbering: Should the state numbering be preserved?\n    allow_negative_labels: Should negative labels be allowed? (Not\n        recommended; may cause conflicts).\n  ", /*tp_doc*/
   0, /*tp_traverse*/
   0, /*tp_clear*/
   0, /*tp_richcompare*/
@@ -49813,6 +50658,8 @@ static PyObject *__pyx_sq_item_9pywrapfst_FarReader(PyObject *o, Py_ssize_t i) {
   return r;
 }
 
+static PyObject *__pyx_specialmethod___pyx_pw_9pywrapfst_9FarReader_27__next__(PyObject *self, CYTHON_UNUSED PyObject *arg) {return __pyx_pw_9pywrapfst_9FarReader_27__next__(self);}
+
 static PyMethodDef __pyx_methods_9pywrapfst_FarReader[] = {
   {"open", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_9pywrapfst_9FarReader_5open, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9pywrapfst_9FarReader_4open},
   {"arc_type", (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_7arc_type, METH_NOARGS, __pyx_doc_9pywrapfst_9FarReader_6arc_type},
@@ -49824,8 +50671,9 @@ static PyMethodDef __pyx_methods_9pywrapfst_FarReader[] = {
   {"get_key", (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_19get_key, METH_NOARGS, __pyx_doc_9pywrapfst_9FarReader_18get_key},
   {"next", (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_21next, METH_NOARGS, __pyx_doc_9pywrapfst_9FarReader_20next},
   {"reset", (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_23reset, METH_NOARGS, __pyx_doc_9pywrapfst_9FarReader_22reset},
-  {"__reduce_cython__", (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_27__reduce_cython__, METH_NOARGS, 0},
-  {"__setstate_cython__", (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_29__setstate_cython__, METH_O, 0},
+  {"__next__", (PyCFunction)__pyx_specialmethod___pyx_pw_9pywrapfst_9FarReader_27__next__, METH_NOARGS|METH_COEXIST, 0},
+  {"__reduce_cython__", (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_31__reduce_cython__, METH_NOARGS, 0},
+  {"__setstate_cython__", (PyCFunction)__pyx_pw_9pywrapfst_9FarReader_33__setstate_cython__, METH_O, 0},
   {0, 0, 0, 0}
 };
 
@@ -49884,8 +50732,8 @@ static PyTypeObject __pyx_type_9pywrapfst_FarReader = {
   0, /*tp_clear*/
   0, /*tp_richcompare*/
   0, /*tp_weaklistoffset*/
-  0, /*tp_iter*/
-  0, /*tp_iternext*/
+  __pyx_pw_9pywrapfst_9FarReader_29__iter__, /*tp_iter*/
+  __pyx_pw_9pywrapfst_9FarReader_27__next__, /*tp_iternext*/
   __pyx_methods_9pywrapfst_FarReader, /*tp_methods*/
   0, /*tp_members*/
   0, /*tp_getset*/
@@ -50219,6 +51067,7 @@ static struct PyModuleDef __pyx_moduledef = {
 #endif
 
 static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_u_, __pyx_k_, sizeof(__pyx_k_), 0, 1, 0, 0},
   {&__pyx_n_s_ACCEPTOR, __pyx_k_ACCEPTOR, sizeof(__pyx_k_ACCEPTOR), 0, 0, 1, 1},
   {&__pyx_n_s_ACCESSIBLE, __pyx_k_ACCESSIBLE, sizeof(__pyx_k_ACCESSIBLE), 0, 0, 1, 1},
   {&__pyx_n_s_ACYCLIC, __pyx_k_ACYCLIC, sizeof(__pyx_k_ACYCLIC), 0, 0, 1, 1},
@@ -50235,22 +51084,24 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_ARC_WEIGHT_VALUE, __pyx_k_ARC_WEIGHT_VALUE, sizeof(__pyx_k_ARC_WEIGHT_VALUE), 0, 0, 1, 1},
   {&__pyx_n_s_Arc, __pyx_k_Arc, sizeof(__pyx_k_Arc), 0, 0, 1, 1},
   {&__pyx_n_s_ArcIterator, __pyx_k_ArcIterator, sizeof(__pyx_k_ArcIterator), 0, 0, 1, 1},
-  {&__pyx_kp_u_ArcIterator_at_0x_x, __pyx_k_ArcIterator_at_0x_x, sizeof(__pyx_k_ArcIterator_at_0x_x), 0, 1, 0, 0},
-  {&__pyx_kp_u_Arc_at_0x_x, __pyx_k_Arc_at_0x_x, sizeof(__pyx_k_Arc_at_0x_x), 0, 1, 0, 0},
+  {&__pyx_kp_u_ArcIterator_at_0x, __pyx_k_ArcIterator_at_0x, sizeof(__pyx_k_ArcIterator_at_0x), 0, 1, 0, 0},
+  {&__pyx_n_s_ArcMapType, __pyx_k_ArcMapType, sizeof(__pyx_k_ArcMapType), 0, 0, 1, 1},
+  {&__pyx_kp_u_Arc_at_0x, __pyx_k_Arc_at_0x, sizeof(__pyx_k_Arc_at_0x), 0, 1, 0, 0},
   {&__pyx_n_s_BINARY_PROPERTIES, __pyx_k_BINARY_PROPERTIES, sizeof(__pyx_k_BINARY_PROPERTIES), 0, 0, 1, 1},
   {&__pyx_n_s_COACCESSIBLE, __pyx_k_COACCESSIBLE, sizeof(__pyx_k_COACCESSIBLE), 0, 0, 1, 1},
   {&__pyx_n_s_COPY_PROPERTIES, __pyx_k_COPY_PROPERTIES, sizeof(__pyx_k_COPY_PROPERTIES), 0, 0, 1, 1},
   {&__pyx_n_s_CYCLIC, __pyx_k_CYCLIC, sizeof(__pyx_k_CYCLIC), 0, 0, 1, 1},
   {&__pyx_kp_u_Cannot_construct, __pyx_k_Cannot_construct, sizeof(__pyx_k_Cannot_construct), 0, 1, 0, 0},
-  {&__pyx_kp_u_Cannot_encode_as_string_r, __pyx_k_Cannot_encode_as_string_r, sizeof(__pyx_k_Cannot_encode_as_string_r), 0, 1, 0, 0},
   {&__pyx_kp_u_Cannot_topsort_cyclic_FST, __pyx_k_Cannot_topsort_cyclic_FST, sizeof(__pyx_k_Cannot_topsort_cyclic_FST), 0, 1, 0, 0},
   {&__pyx_kp_u_Compilation_failed, __pyx_k_Compilation_failed, sizeof(__pyx_k_Compilation_failed), 0, 1, 0, 0},
   {&__pyx_n_s_Compiler, __pyx_k_Compiler, sizeof(__pyx_k_Compiler), 0, 0, 1, 1},
-  {&__pyx_kp_u_Conversion_to_r_failed, __pyx_k_Conversion_to_r_failed, sizeof(__pyx_k_Conversion_to_r_failed), 0, 1, 0, 0},
+  {&__pyx_n_s_ComposeFilter, __pyx_k_ComposeFilter, sizeof(__pyx_k_ComposeFilter), 0, 0, 1, 1},
+  {&__pyx_kp_u_Conversion_to, __pyx_k_Conversion_to, sizeof(__pyx_k_Conversion_to), 0, 1, 0, 0},
   {&__pyx_n_s_DELETE_ARC_PROPERTIES, __pyx_k_DELETE_ARC_PROPERTIES, sizeof(__pyx_k_DELETE_ARC_PROPERTIES), 0, 0, 1, 1},
   {&__pyx_n_s_DELETE_STATE_PROPERTIES, __pyx_k_DELETE_STATE_PROPERTIES, sizeof(__pyx_k_DELETE_STATE_PROPERTIES), 0, 0, 1, 1},
-  {&__pyx_n_s_DeprecationWarning, __pyx_k_DeprecationWarning, sizeof(__pyx_k_DeprecationWarning), 0, 0, 1, 1},
+  {&__pyx_n_s_DeterminizeType, __pyx_k_DeterminizeType, sizeof(__pyx_k_DeterminizeType), 0, 0, 1, 1},
   {&__pyx_kp_u_Dot_rendering_failed_s, __pyx_k_Dot_rendering_failed_s, sizeof(__pyx_k_Dot_rendering_failed_s), 0, 1, 0, 0},
+  {&__pyx_n_s_DrawFloatFormat, __pyx_k_DrawFloatFormat, sizeof(__pyx_k_DrawFloatFormat), 0, 0, 1, 1},
   {&__pyx_n_s_ENCODE_FLAGS, __pyx_k_ENCODE_FLAGS, sizeof(__pyx_k_ENCODE_FLAGS), 0, 0, 1, 1},
   {&__pyx_n_s_ENCODE_LABELS, __pyx_k_ENCODE_LABELS, sizeof(__pyx_k_ENCODE_LABELS), 0, 0, 1, 1},
   {&__pyx_n_s_ENCODE_WEIGHTS, __pyx_k_ENCODE_WEIGHTS, sizeof(__pyx_k_ENCODE_WEIGHTS), 0, 0, 1, 1},
@@ -50260,23 +51111,24 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_EXTRINSIC_PROPERTIES, __pyx_k_EXTRINSIC_PROPERTIES, sizeof(__pyx_k_EXTRINSIC_PROPERTIES), 0, 0, 1, 1},
   {&__pyx_n_s_EncodeMapper, __pyx_k_EncodeMapper, sizeof(__pyx_k_EncodeMapper), 0, 0, 1, 1},
   {&__pyx_n_s_EncodeMapperSymbolTableView, __pyx_k_EncodeMapperSymbolTableView, sizeof(__pyx_k_EncodeMapperSymbolTableView), 0, 0, 1, 1},
-  {&__pyx_kp_u_EncodeMapper_at_0x_x, __pyx_k_EncodeMapper_at_0x_x, sizeof(__pyx_k_EncodeMapper_at_0x_x), 0, 1, 0, 0},
+  {&__pyx_kp_u_EncodeMapper_at_0x, __pyx_k_EncodeMapper_at_0x, sizeof(__pyx_k_EncodeMapper_at_0x), 0, 1, 0, 0},
+  {&__pyx_kp_u_Expected, __pyx_k_Expected, sizeof(__pyx_k_Expected), 0, 1, 0, 0},
   {&__pyx_n_s_FST_PROPERTIES, __pyx_k_FST_PROPERTIES, sizeof(__pyx_k_FST_PROPERTIES), 0, 0, 1, 1},
   {&__pyx_n_s_FarReader, __pyx_k_FarReader, sizeof(__pyx_k_FarReader), 0, 0, 1, 1},
-  {&__pyx_kp_u_FarReader_at_0x_x, __pyx_k_FarReader_at_0x_x, sizeof(__pyx_k_FarReader_at_0x_x), 0, 1, 0, 0},
+  {&__pyx_kp_u_FarReader_at_0x, __pyx_k_FarReader_at_0x, sizeof(__pyx_k_FarReader_at_0x), 0, 1, 0, 0},
+  {&__pyx_n_s_FarType, __pyx_k_FarType, sizeof(__pyx_k_FarType), 0, 0, 1, 1},
   {&__pyx_n_s_FarWriter, __pyx_k_FarWriter, sizeof(__pyx_k_FarWriter), 0, 0, 1, 1},
-  {&__pyx_kp_u_FarWriter_at_0x_x, __pyx_k_FarWriter_at_0x_x, sizeof(__pyx_k_FarWriter_at_0x_x), 0, 1, 0, 0},
+  {&__pyx_kp_u_FarWriter_at_0x, __pyx_k_FarWriter_at_0x, sizeof(__pyx_k_FarWriter_at_0x), 0, 1, 0, 0},
   {&__pyx_n_s_Fst, __pyx_k_Fst, sizeof(__pyx_k_Fst), 0, 0, 1, 1},
   {&__pyx_n_s_FstArgError, __pyx_k_FstArgError, sizeof(__pyx_k_FstArgError), 0, 0, 1, 1},
   {&__pyx_n_s_FstBadWeightError, __pyx_k_FstBadWeightError, sizeof(__pyx_k_FstBadWeightError), 0, 0, 1, 1},
-  {&__pyx_n_s_FstDeletedConstructorError, __pyx_k_FstDeletedConstructorError, sizeof(__pyx_k_FstDeletedConstructorError), 0, 0, 1, 1},
   {&__pyx_n_s_FstError, __pyx_k_FstError, sizeof(__pyx_k_FstError), 0, 0, 1, 1},
   {&__pyx_n_s_FstIOError, __pyx_k_FstIOError, sizeof(__pyx_k_FstIOError), 0, 0, 1, 1},
   {&__pyx_n_s_FstIndexError, __pyx_k_FstIndexError, sizeof(__pyx_k_FstIndexError), 0, 0, 1, 1},
   {&__pyx_n_s_FstOpError, __pyx_k_FstOpError, sizeof(__pyx_k_FstOpError), 0, 0, 1, 1},
   {&__pyx_n_s_FstSymbolTableView, __pyx_k_FstSymbolTableView, sizeof(__pyx_k_FstSymbolTableView), 0, 0, 1, 1},
-  {&__pyx_kp_u_Fst_SymbolTableView_r_at_0x_x, __pyx_k_Fst_SymbolTableView_r_at_0x_x, sizeof(__pyx_k_Fst_SymbolTableView_r_at_0x_x), 0, 1, 0, 0},
-  {&__pyx_kp_u_Fst_at_0x_x, __pyx_k_Fst_at_0x_x, sizeof(__pyx_k_Fst_at_0x_x), 0, 1, 0, 0},
+  {&__pyx_kp_u_Fst_SymbolTableView, __pyx_k_Fst_SymbolTableView, sizeof(__pyx_k_Fst_SymbolTableView), 0, 1, 0, 0},
+  {&__pyx_kp_u_Fst_at_0x, __pyx_k_Fst_at_0x, sizeof(__pyx_k_Fst_at_0x), 0, 1, 0, 0},
   {&__pyx_n_s_INITIAL_ACYCLIC, __pyx_k_INITIAL_ACYCLIC, sizeof(__pyx_k_INITIAL_ACYCLIC), 0, 0, 1, 1},
   {&__pyx_n_s_INITIAL_CYCLIC, __pyx_k_INITIAL_CYCLIC, sizeof(__pyx_k_INITIAL_CYCLIC), 0, 0, 1, 1},
   {&__pyx_n_s_INTRINSIC_PROPERTIES, __pyx_k_INTRINSIC_PROPERTIES, sizeof(__pyx_k_INTRINSIC_PROPERTIES), 0, 0, 1, 1},
@@ -50294,7 +51146,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_MUTABLE, __pyx_k_MUTABLE, sizeof(__pyx_k_MUTABLE), 0, 0, 1, 1},
   {&__pyx_n_s_MutableArcIterator, __pyx_k_MutableArcIterator, sizeof(__pyx_k_MutableArcIterator), 0, 0, 1, 1},
   {&__pyx_n_s_MutableArcIterator___iter, __pyx_k_MutableArcIterator___iter, sizeof(__pyx_k_MutableArcIterator___iter), 0, 0, 1, 1},
-  {&__pyx_kp_u_MutableArcIterator_at_0x_x, __pyx_k_MutableArcIterator_at_0x_x, sizeof(__pyx_k_MutableArcIterator_at_0x_x), 0, 1, 0, 0},
+  {&__pyx_kp_u_MutableArcIterator_at_0x, __pyx_k_MutableArcIterator_at_0x, sizeof(__pyx_k_MutableArcIterator_at_0x), 0, 1, 0, 0},
   {&__pyx_n_s_MutableFst, __pyx_k_MutableFst, sizeof(__pyx_k_MutableFst), 0, 0, 1, 1},
   {&__pyx_n_s_MutableFstSymbolTableView, __pyx_k_MutableFstSymbolTableView, sizeof(__pyx_k_MutableFstSymbolTableView), 0, 0, 1, 1},
   {&__pyx_n_s_MutableSymbolTable, __pyx_k_MutableSymbolTable, sizeof(__pyx_k_MutableSymbolTable), 0, 0, 1, 1},
@@ -50318,63 +51170,75 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_NoWeight, __pyx_k_NoWeight, sizeof(__pyx_k_NoWeight), 0, 0, 1, 1},
   {&__pyx_kp_u_No_new_SymbolTables_specified, __pyx_k_No_new_SymbolTables_specified, sizeof(__pyx_k_No_new_SymbolTables_specified), 0, 1, 0, 0},
   {&__pyx_kp_u_No_relabeling_pairs_specified, __pyx_k_No_relabeling_pairs_specified, sizeof(__pyx_k_No_relabeling_pairs_specified), 0, 1, 0, 0},
+  {&__pyx_n_s_NotImplementedError, __pyx_k_NotImplementedError, sizeof(__pyx_k_NotImplementedError), 0, 0, 1, 1},
   {&__pyx_n_s_Number, __pyx_k_Number, sizeof(__pyx_k_Number), 0, 0, 1, 1},
   {&__pyx_n_s_O_DETERMINISTIC, __pyx_k_O_DETERMINISTIC, sizeof(__pyx_k_O_DETERMINISTIC), 0, 0, 1, 1},
   {&__pyx_n_s_O_EPSILONS, __pyx_k_O_EPSILONS, sizeof(__pyx_k_O_EPSILONS), 0, 0, 1, 1},
   {&__pyx_n_s_O_LABEL_INVARIANT_PROPERTIES, __pyx_k_O_LABEL_INVARIANT_PROPERTIES, sizeof(__pyx_k_O_LABEL_INVARIANT_PROPERTIES), 0, 0, 1, 1},
   {&__pyx_n_s_O_LABEL_SORTED, __pyx_k_O_LABEL_SORTED, sizeof(__pyx_k_O_LABEL_SORTED), 0, 0, 1, 1},
   {&__pyx_n_s_One, __pyx_k_One, sizeof(__pyx_k_One), 0, 0, 1, 1},
-  {&__pyx_kp_u_Open_failed_r, __pyx_k_Open_failed_r, sizeof(__pyx_k_Open_failed_r), 0, 1, 0, 0},
+  {&__pyx_kp_u_Open_failed, __pyx_k_Open_failed, sizeof(__pyx_k_Open_failed), 0, 1, 0, 0},
   {&__pyx_kp_u_Operation_failed, __pyx_k_Operation_failed, sizeof(__pyx_k_Operation_failed), 0, 1, 0, 0},
   {&__pyx_n_s_PIPE, __pyx_k_PIPE, sizeof(__pyx_k_PIPE), 0, 0, 1, 1},
   {&__pyx_n_s_POS_TRINARY_PROPERTIES, __pyx_k_POS_TRINARY_PROPERTIES, sizeof(__pyx_k_POS_TRINARY_PROPERTIES), 0, 0, 1, 1},
   {&__pyx_n_s_Popen, __pyx_k_Popen, sizeof(__pyx_k_Popen), 0, 0, 1, 1},
+  {&__pyx_n_s_ProjectType, __pyx_k_ProjectType, sizeof(__pyx_k_ProjectType), 0, 0, 1, 1},
+  {&__pyx_n_s_QueueType, __pyx_k_QueueType, sizeof(__pyx_k_QueueType), 0, 0, 1, 1},
   {&__pyx_n_s_RM_SUPERFINAL_PROPERTIES, __pyx_k_RM_SUPERFINAL_PROPERTIES, sizeof(__pyx_k_RM_SUPERFINAL_PROPERTIES), 0, 0, 1, 1},
+  {&__pyx_n_s_RandArcSelection, __pyx_k_RandArcSelection, sizeof(__pyx_k_RandArcSelection), 0, 0, 1, 1},
   {&__pyx_kp_u_Read_failed, __pyx_k_Read_failed, sizeof(__pyx_k_Read_failed), 0, 1, 0, 0},
-  {&__pyx_kp_u_Read_failed_r, __pyx_k_Read_failed_r, sizeof(__pyx_k_Read_failed_r), 0, 1, 0, 0},
+  {&__pyx_kp_u_Read_from_FST_failed, __pyx_k_Read_from_FST_failed, sizeof(__pyx_k_Read_from_FST_failed), 0, 1, 0, 0},
+  {&__pyx_kp_u_Read_from_string_failed, __pyx_k_Read_from_string_failed, sizeof(__pyx_k_Read_from_string_failed), 0, 1, 0, 0},
+  {&__pyx_n_s_ReplaceLabelType, __pyx_k_ReplaceLabelType, sizeof(__pyx_k_ReplaceLabelType), 0, 0, 1, 1},
   {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1},
   {&__pyx_n_s_SET_ARC_PROPERTIES, __pyx_k_SET_ARC_PROPERTIES, sizeof(__pyx_k_SET_ARC_PROPERTIES), 0, 0, 1, 1},
   {&__pyx_n_s_SET_FINAL_PROPERTIES, __pyx_k_SET_FINAL_PROPERTIES, sizeof(__pyx_k_SET_FINAL_PROPERTIES), 0, 0, 1, 1},
   {&__pyx_n_s_SET_START_PROPERTIES, __pyx_k_SET_START_PROPERTIES, sizeof(__pyx_k_SET_START_PROPERTIES), 0, 0, 1, 1},
   {&__pyx_n_s_STATE_SORT_PROPERTIES, __pyx_k_STATE_SORT_PROPERTIES, sizeof(__pyx_k_STATE_SORT_PROPERTIES), 0, 0, 1, 1},
   {&__pyx_n_s_STRING, __pyx_k_STRING, sizeof(__pyx_k_STRING), 0, 0, 1, 1},
+  {&__pyx_n_s_SortType, __pyx_k_SortType, sizeof(__pyx_k_SortType), 0, 0, 1, 1},
   {&__pyx_n_s_StateIterator, __pyx_k_StateIterator, sizeof(__pyx_k_StateIterator), 0, 0, 1, 1},
-  {&__pyx_kp_u_StateIterator_at_0x_x, __pyx_k_StateIterator_at_0x_x, sizeof(__pyx_k_StateIterator_at_0x_x), 0, 1, 0, 0},
+  {&__pyx_kp_u_StateIterator_at_0x, __pyx_k_StateIterator_at_0x, sizeof(__pyx_k_StateIterator_at_0x), 0, 1, 0, 0},
+  {&__pyx_n_s_StateMapType, __pyx_k_StateMapType, sizeof(__pyx_k_StateMapType), 0, 0, 1, 1},
   {&__pyx_kp_u_State_index_out_of_range, __pyx_k_State_index_out_of_range, sizeof(__pyx_k_State_index_out_of_range), 0, 1, 0, 0},
   {&__pyx_n_s_StopIteration, __pyx_k_StopIteration, sizeof(__pyx_k_StopIteration), 0, 0, 1, 1},
-  {&__pyx_n_s_SymbolTable, __pyx_k_SymbolTable, sizeof(__pyx_k_SymbolTable), 0, 0, 1, 1},
+  {&__pyx_kp_u_SymbolTable, __pyx_k_SymbolTable, sizeof(__pyx_k_SymbolTable), 0, 1, 0, 0},
   {&__pyx_n_s_SymbolTableIterator, __pyx_k_SymbolTableIterator, sizeof(__pyx_k_SymbolTableIterator), 0, 0, 1, 1},
-  {&__pyx_kp_u_SymbolTableIterator_at_0x_x, __pyx_k_SymbolTableIterator_at_0x_x, sizeof(__pyx_k_SymbolTableIterator_at_0x_x), 0, 1, 0, 0},
+  {&__pyx_kp_u_SymbolTableIterator_at_0x, __pyx_k_SymbolTableIterator_at_0x, sizeof(__pyx_k_SymbolTableIterator_at_0x), 0, 1, 0, 0},
+  {&__pyx_n_s_SymbolTableView, __pyx_k_SymbolTableView, sizeof(__pyx_k_SymbolTableView), 0, 0, 1, 1},
   {&__pyx_n_s_SymbolTable_2, __pyx_k_SymbolTable_2, sizeof(__pyx_k_SymbolTable_2), 0, 0, 1, 1},
   {&__pyx_kp_u_SymbolTable_no_longer_exists, __pyx_k_SymbolTable_no_longer_exists, sizeof(__pyx_k_SymbolTable_no_longer_exists), 0, 1, 0, 0},
-  {&__pyx_kp_u_SymbolTable_r_at_0x_x, __pyx_k_SymbolTable_r_at_0x_x, sizeof(__pyx_k_SymbolTable_r_at_0x_x), 0, 1, 0, 0},
   {&__pyx_n_s_TOP_SORTED, __pyx_k_TOP_SORTED, sizeof(__pyx_k_TOP_SORTED), 0, 0, 1, 1},
   {&__pyx_n_s_TRINARY_PROPERTIES, __pyx_k_TRINARY_PROPERTIES, sizeof(__pyx_k_TRINARY_PROPERTIES), 0, 0, 1, 1},
   {&__pyx_kp_u_Tsvg, __pyx_k_Tsvg, sizeof(__pyx_k_Tsvg), 0, 1, 0, 0},
   {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1},
   {&__pyx_n_s_UNWEIGHTED, __pyx_k_UNWEIGHTED, sizeof(__pyx_k_UNWEIGHTED), 0, 0, 1, 1},
   {&__pyx_n_s_UNWEIGHTED_CYCLES, __pyx_k_UNWEIGHTED_CYCLES, sizeof(__pyx_k_UNWEIGHTED_CYCLES), 0, 0, 1, 1},
-  {&__pyx_kp_u_Unknown_arc_type_r, __pyx_k_Unknown_arc_type_r, sizeof(__pyx_k_Unknown_arc_type_r), 0, 1, 0, 0},
-  {&__pyx_kp_u_Unknown_compose_filter_type_r, __pyx_k_Unknown_compose_filter_type_r, sizeof(__pyx_k_Unknown_compose_filter_type_r), 0, 1, 0, 0},
-  {&__pyx_kp_u_Unknown_determinization_type_r, __pyx_k_Unknown_determinization_type_r, sizeof(__pyx_k_Unknown_determinization_type_r), 0, 1, 0, 0},
-  {&__pyx_kp_u_Unknown_map_type_r, __pyx_k_Unknown_map_type_r, sizeof(__pyx_k_Unknown_map_type_r), 0, 1, 0, 0},
-  {&__pyx_kp_u_Unknown_queue_type_r, __pyx_k_Unknown_queue_type_r, sizeof(__pyx_k_Unknown_queue_type_r), 0, 1, 0, 0},
+  {&__pyx_kp_u_Unknown_FAR_type, __pyx_k_Unknown_FAR_type, sizeof(__pyx_k_Unknown_FAR_type), 0, 1, 0, 0},
+  {&__pyx_kp_u_Unknown_arc_type, __pyx_k_Unknown_arc_type, sizeof(__pyx_k_Unknown_arc_type), 0, 1, 0, 0},
+  {&__pyx_kp_u_Unknown_compose_filter_type, __pyx_k_Unknown_compose_filter_type, sizeof(__pyx_k_Unknown_compose_filter_type), 0, 1, 0, 0},
+  {&__pyx_kp_u_Unknown_determinization_type, __pyx_k_Unknown_determinization_type, sizeof(__pyx_k_Unknown_determinization_type), 0, 1, 0, 0},
+  {&__pyx_kp_u_Unknown_map_type, __pyx_k_Unknown_map_type, sizeof(__pyx_k_Unknown_map_type), 0, 1, 0, 0},
+  {&__pyx_kp_u_Unknown_projection_type, __pyx_k_Unknown_projection_type, sizeof(__pyx_k_Unknown_projection_type), 0, 1, 0, 0},
+  {&__pyx_kp_u_Unknown_queue_type, __pyx_k_Unknown_queue_type, sizeof(__pyx_k_Unknown_queue_type), 0, 1, 0, 0},
   {&__pyx_kp_u_Unknown_random_arc_selection_typ, __pyx_k_Unknown_random_arc_selection_typ, sizeof(__pyx_k_Unknown_random_arc_selection_typ), 0, 1, 0, 0},
-  {&__pyx_kp_u_Unknown_replace_label_type_r, __pyx_k_Unknown_replace_label_type_r, sizeof(__pyx_k_Unknown_replace_label_type_r), 0, 1, 0, 0},
-  {&__pyx_kp_u_Unknown_sort_type_r, __pyx_k_Unknown_sort_type_r, sizeof(__pyx_k_Unknown_sort_type_r), 0, 1, 0, 0},
-  {&__pyx_kp_u_Use_print_instead, __pyx_k_Use_print_instead, sizeof(__pyx_k_Use_print_instead), 0, 1, 0, 0},
+  {&__pyx_kp_u_Unknown_replace_label_type, __pyx_k_Unknown_replace_label_type, sizeof(__pyx_k_Unknown_replace_label_type), 0, 1, 0, 0},
+  {&__pyx_kp_u_Unknown_sort_type, __pyx_k_Unknown_sort_type, sizeof(__pyx_k_Unknown_sort_type), 0, 1, 0, 0},
   {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
   {&__pyx_n_s_VectorFst, __pyx_k_VectorFst, sizeof(__pyx_k_VectorFst), 0, 0, 1, 1},
   {&__pyx_n_s_WEIGHTED, __pyx_k_WEIGHTED, sizeof(__pyx_k_WEIGHTED), 0, 0, 1, 1},
   {&__pyx_n_s_WEIGHTED_CYCLES, __pyx_k_WEIGHTED_CYCLES, sizeof(__pyx_k_WEIGHTED_CYCLES), 0, 0, 1, 1},
   {&__pyx_n_s_WEIGHT_INVARIANT_PROPERTIES, __pyx_k_WEIGHT_INVARIANT_PROPERTIES, sizeof(__pyx_k_WEIGHT_INVARIANT_PROPERTIES), 0, 0, 1, 1},
-  {&__pyx_n_s_Weight, __pyx_k_Weight, sizeof(__pyx_k_Weight), 0, 0, 1, 1},
-  {&__pyx_kp_u_Weight_at_0x_x, __pyx_k_Weight_at_0x_x, sizeof(__pyx_k_Weight_at_0x_x), 0, 1, 0, 0},
+  {&__pyx_kp_u_Weight, __pyx_k_Weight, sizeof(__pyx_k_Weight), 0, 1, 0, 0},
+  {&__pyx_n_s_WeightLike, __pyx_k_WeightLike, sizeof(__pyx_k_WeightLike), 0, 0, 1, 1},
+  {&__pyx_n_s_Weight_2, __pyx_k_Weight_2, sizeof(__pyx_k_Weight_2), 0, 0, 1, 1},
   {&__pyx_kp_u_Weight_type_not_found, __pyx_k_Weight_type_not_found, sizeof(__pyx_k_Weight_type_not_found), 0, 1, 0, 0},
-  {&__pyx_kp_u_Write_failed_r, __pyx_k_Write_failed_r, sizeof(__pyx_k_Write_failed_r), 0, 1, 0, 0},
+  {&__pyx_kp_u_Write_failed, __pyx_k_Write_failed, sizeof(__pyx_k_Write_failed), 0, 1, 0, 0},
   {&__pyx_kp_u_Write_to_string_failed, __pyx_k_Write_to_string_failed, sizeof(__pyx_k_Write_to_string_failed), 0, 1, 0, 0},
   {&__pyx_n_s_Zero, __pyx_k_Zero, sizeof(__pyx_k_Zero), 0, 0, 1, 1},
-  {&__pyx_kp_b__8, __pyx_k__8, sizeof(__pyx_k__8), 0, 0, 0, 0},
+  {&__pyx_kp_u__11, __pyx_k__11, sizeof(__pyx_k__11), 0, 1, 0, 0},
+  {&__pyx_kp_u__2, __pyx_k__2, sizeof(__pyx_k__2), 0, 1, 0, 0},
+  {&__pyx_kp_u__3, __pyx_k__3, sizeof(__pyx_k__3), 0, 1, 0, 0},
   {&__pyx_n_s_acceptor, __pyx_k_acceptor, sizeof(__pyx_k_acceptor), 0, 0, 1, 1},
   {&__pyx_n_s_add, __pyx_k_add, sizeof(__pyx_k_add), 0, 0, 1, 1},
   {&__pyx_n_s_add_state, __pyx_k_add_state, sizeof(__pyx_k_add_state), 0, 0, 1, 1},
@@ -50383,18 +51247,20 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_add_table, __pyx_k_add_table, sizeof(__pyx_k_add_table), 0, 0, 1, 1},
   {&__pyx_n_s_allow_negative_labels, __pyx_k_allow_negative_labels, sizeof(__pyx_k_allow_negative_labels), 0, 0, 1, 1},
   {&__pyx_n_s_allow_nondet, __pyx_k_allow_nondet, sizeof(__pyx_k_allow_nondet), 0, 0, 1, 1},
-  {&__pyx_n_u_always, __pyx_k_always, sizeof(__pyx_k_always), 0, 1, 0, 1},
   {&__pyx_n_s_arc, __pyx_k_arc, sizeof(__pyx_k_arc), 0, 0, 1, 1},
   {&__pyx_n_s_arc_type, __pyx_k_arc_type, sizeof(__pyx_k_arc_type), 0, 0, 1, 1},
   {&__pyx_n_s_arcs, __pyx_k_arcs, sizeof(__pyx_k_arcs), 0, 0, 1, 1},
   {&__pyx_n_s_args, __pyx_k_args, sizeof(__pyx_k_args), 0, 0, 1, 1},
+  {&__pyx_kp_u_at_0x, __pyx_k_at_0x, sizeof(__pyx_k_at_0x), 0, 1, 0, 0},
   {&__pyx_n_s_attach_new_isymbols, __pyx_k_attach_new_isymbols, sizeof(__pyx_k_attach_new_isymbols), 0, 0, 1, 1},
   {&__pyx_n_s_attach_new_osymbols, __pyx_k_attach_new_osymbols, sizeof(__pyx_k_attach_new_osymbols), 0, 0, 1, 1},
-  {&__pyx_n_b_auto, __pyx_k_auto, sizeof(__pyx_k_auto), 0, 0, 0, 1},
+  {&__pyx_n_u_auto, __pyx_k_auto, sizeof(__pyx_k_auto), 0, 1, 0, 1},
   {&__pyx_n_s_available_key, __pyx_k_available_key, sizeof(__pyx_k_available_key), 0, 0, 1, 1},
+  {&__pyx_kp_u_but_received, __pyx_k_but_received, sizeof(__pyx_k_but_received), 0, 1, 0, 0},
   {&__pyx_n_s_call_arc_labeling, __pyx_k_call_arc_labeling, sizeof(__pyx_k_call_arc_labeling), 0, 0, 1, 1},
   {&__pyx_n_s_checksum, __pyx_k_checksum, sizeof(__pyx_k_checksum), 0, 0, 1, 1},
   {&__pyx_n_s_class, __pyx_k_class, sizeof(__pyx_k_class), 0, 0, 1, 1},
+  {&__pyx_n_s_class_2, __pyx_k_class_2, sizeof(__pyx_k_class_2), 0, 0, 1, 1},
   {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1},
   {&__pyx_n_s_close, __pyx_k_close, sizeof(__pyx_k_close), 0, 0, 1, 1},
   {&__pyx_n_s_closure_plus, __pyx_k_closure_plus, sizeof(__pyx_k_closure_plus), 0, 0, 1, 1},
@@ -50403,10 +51269,10 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_compose_filter, __pyx_k_compose_filter, sizeof(__pyx_k_compose_filter), 0, 0, 1, 1},
   {&__pyx_n_s_connect, __pyx_k_connect, sizeof(__pyx_k_connect), 0, 0, 1, 1},
   {&__pyx_kp_u_const_EncodeMapper_SymbolTableV, __pyx_k_const_EncodeMapper_SymbolTableV, sizeof(__pyx_k_const_EncodeMapper_SymbolTableV), 0, 1, 0, 0},
-  {&__pyx_kp_u_const_Fst_SymbolTableView_r_at, __pyx_k_const_Fst_SymbolTableView_r_at, sizeof(__pyx_k_const_Fst_SymbolTableView_r_at), 0, 1, 0, 0},
+  {&__pyx_kp_u_const_Fst_SymbolTableView, __pyx_k_const_Fst_SymbolTableView, sizeof(__pyx_k_const_Fst_SymbolTableView), 0, 1, 0, 0},
   {&__pyx_n_s_copy, __pyx_k_copy, sizeof(__pyx_k_copy), 0, 0, 1, 1},
   {&__pyx_n_s_create, __pyx_k_create, sizeof(__pyx_k_create), 0, 0, 1, 1},
-  {&__pyx_n_b_default, __pyx_k_default, sizeof(__pyx_k_default), 0, 0, 0, 1},
+  {&__pyx_n_u_default, __pyx_k_default, sizeof(__pyx_k_default), 0, 1, 0, 1},
   {&__pyx_n_s_delta, __pyx_k_delta, sizeof(__pyx_k_delta), 0, 0, 1, 1},
   {&__pyx_n_s_det_type, __pyx_k_det_type, sizeof(__pyx_k_det_type), 0, 0, 1, 1},
   {&__pyx_n_s_distance, __pyx_k_distance, sizeof(__pyx_k_distance), 0, 0, 1, 1},
@@ -50415,37 +51281,37 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_done, __pyx_k_done, sizeof(__pyx_k_done), 0, 0, 1, 1},
   {&__pyx_n_u_dot, __pyx_k_dot, sizeof(__pyx_k_dot), 0, 1, 0, 1},
   {&__pyx_n_s_draw, __pyx_k_draw, sizeof(__pyx_k_draw), 0, 0, 1, 1},
-  {&__pyx_n_s_encode, __pyx_k_encode, sizeof(__pyx_k_encode), 0, 0, 1, 1},
   {&__pyx_n_s_encode_labels, __pyx_k_encode_labels, sizeof(__pyx_k_encode_labels), 0, 0, 1, 1},
   {&__pyx_n_s_encode_weights, __pyx_k_encode_weights, sizeof(__pyx_k_encode_weights), 0, 0, 1, 1},
   {&__pyx_n_s_eps_norm_output, __pyx_k_eps_norm_output, sizeof(__pyx_k_eps_norm_output), 0, 0, 1, 1},
   {&__pyx_n_s_epsilon_on_replace, __pyx_k_epsilon_on_replace, sizeof(__pyx_k_epsilon_on_replace), 0, 0, 1, 1},
   {&__pyx_n_s_error, __pyx_k_error, sizeof(__pyx_k_error), 0, 0, 1, 1},
+  {&__pyx_kp_u_failed, __pyx_k_failed, sizeof(__pyx_k_failed), 0, 1, 0, 0},
   {&__pyx_n_s_far_type, __pyx_k_far_type, sizeof(__pyx_k_far_type), 0, 0, 1, 1},
   {&__pyx_n_s_final, __pyx_k_final, sizeof(__pyx_k_final), 0, 0, 1, 1},
   {&__pyx_n_s_find, __pyx_k_find, sizeof(__pyx_k_find), 0, 0, 1, 1},
   {&__pyx_n_s_flags, __pyx_k_flags, sizeof(__pyx_k_flags), 0, 0, 1, 1},
   {&__pyx_n_s_float_format, __pyx_k_float_format, sizeof(__pyx_k_float_format), 0, 0, 1, 1},
   {&__pyx_n_s_fontsize, __pyx_k_fontsize, sizeof(__pyx_k_fontsize), 0, 0, 1, 1},
-  {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1},
+  {&__pyx_n_s_fspath, __pyx_k_fspath, sizeof(__pyx_k_fspath), 0, 0, 1, 1},
   {&__pyx_n_s_fst_type, __pyx_k_fst_type, sizeof(__pyx_k_fst_type), 0, 0, 1, 1},
-  {&__pyx_n_b_functional, __pyx_k_functional, sizeof(__pyx_k_functional), 0, 0, 0, 1},
-  {&__pyx_n_b_g, __pyx_k_g, sizeof(__pyx_k_g), 0, 0, 0, 1},
+  {&__pyx_n_u_functional, __pyx_k_functional, sizeof(__pyx_k_functional), 0, 1, 0, 1},
+  {&__pyx_n_u_g, __pyx_k_g, sizeof(__pyx_k_g), 0, 1, 0, 1},
   {&__pyx_n_s_get_fst, __pyx_k_get_fst, sizeof(__pyx_k_get_fst), 0, 0, 1, 1},
   {&__pyx_n_s_get_key, __pyx_k_get_key, sizeof(__pyx_k_get_key), 0, 0, 1, 1},
   {&__pyx_n_s_get_nth_key, __pyx_k_get_nth_key, sizeof(__pyx_k_get_nth_key), 0, 0, 1, 1},
   {&__pyx_n_s_getstate, __pyx_k_getstate, sizeof(__pyx_k_getstate), 0, 0, 1, 1},
   {&__pyx_n_s_height, __pyx_k_height, sizeof(__pyx_k_height), 0, 0, 1, 1},
   {&__pyx_n_s_id, __pyx_k_id, sizeof(__pyx_k_id), 0, 0, 1, 1},
-  {&__pyx_n_b_identity, __pyx_k_identity, sizeof(__pyx_k_identity), 0, 0, 0, 1},
+  {&__pyx_n_u_identity, __pyx_k_identity, sizeof(__pyx_k_identity), 0, 1, 0, 1},
   {&__pyx_n_s_ifst, __pyx_k_ifst, sizeof(__pyx_k_ifst), 0, 0, 1, 1},
   {&__pyx_n_s_ifst1, __pyx_k_ifst1, sizeof(__pyx_k_ifst1), 0, 0, 1, 1},
   {&__pyx_n_s_ifst2, __pyx_k_ifst2, sizeof(__pyx_k_ifst2), 0, 0, 1, 1},
-  {&__pyx_n_b_ilabel, __pyx_k_ilabel, sizeof(__pyx_k_ilabel), 0, 0, 0, 1},
   {&__pyx_n_s_ilabel, __pyx_k_ilabel, sizeof(__pyx_k_ilabel), 0, 0, 1, 1},
+  {&__pyx_n_u_ilabel, __pyx_k_ilabel, sizeof(__pyx_k_ilabel), 0, 1, 0, 1},
   {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
   {&__pyx_n_s_increment_subsequential_label, __pyx_k_increment_subsequential_label, sizeof(__pyx_k_increment_subsequential_label), 0, 0, 1, 1},
-  {&__pyx_n_b_input, __pyx_k_input, sizeof(__pyx_k_input), 0, 0, 0, 1},
+  {&__pyx_n_u_input, __pyx_k_input, sizeof(__pyx_k_input), 0, 1, 0, 1},
   {&__pyx_n_s_input_symbols, __pyx_k_input_symbols, sizeof(__pyx_k_input_symbols), 0, 0, 1, 1},
   {&__pyx_n_s_input_table, __pyx_k_input_table, sizeof(__pyx_k_input_table), 0, 0, 1, 1},
   {&__pyx_n_s_ipairs, __pyx_k_ipairs, sizeof(__pyx_k_ipairs), 0, 0, 1, 1},
@@ -50470,7 +51336,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_n, __pyx_k_n, sizeof(__pyx_k_n), 0, 0, 1, 1},
   {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1},
   {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1},
-  {&__pyx_n_b_neither, __pyx_k_neither, sizeof(__pyx_k_neither), 0, 0, 0, 1},
+  {&__pyx_n_u_neither, __pyx_k_neither, sizeof(__pyx_k_neither), 0, 1, 0, 1},
   {&__pyx_n_s_new_isymbols, __pyx_k_new_isymbols, sizeof(__pyx_k_new_isymbols), 0, 0, 1, 1},
   {&__pyx_n_s_new_osymbols, __pyx_k_new_osymbols, sizeof(__pyx_k_new_osymbols), 0, 0, 1, 1},
   {&__pyx_n_s_next, __pyx_k_next, sizeof(__pyx_k_next), 0, 0, 1, 1},
@@ -50491,6 +51357,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_old_osymbols, __pyx_k_old_osymbols, sizeof(__pyx_k_old_osymbols), 0, 0, 1, 1},
   {&__pyx_n_s_opairs, __pyx_k_opairs, sizeof(__pyx_k_opairs), 0, 0, 1, 1},
   {&__pyx_n_s_open, __pyx_k_open, sizeof(__pyx_k_open), 0, 0, 1, 1},
+  {&__pyx_n_s_os, __pyx_k_os, sizeof(__pyx_k_os), 0, 0, 1, 1},
   {&__pyx_n_s_osymbols, __pyx_k_osymbols, sizeof(__pyx_k_osymbols), 0, 0, 1, 1},
   {&__pyx_n_s_output_symbols, __pyx_k_output_symbols, sizeof(__pyx_k_output_symbols), 0, 0, 1, 1},
   {&__pyx_n_s_pairs, __pyx_k_pairs, sizeof(__pyx_k_pairs), 0, 0, 1, 1},
@@ -50502,12 +51369,12 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_precision, __pyx_k_precision, sizeof(__pyx_k_precision), 0, 0, 1, 1},
   {&__pyx_n_s_prepare, __pyx_k_prepare, sizeof(__pyx_k_prepare), 0, 0, 1, 1},
   {&__pyx_n_s_print, __pyx_k_print, sizeof(__pyx_k_print), 0, 0, 1, 1},
-  {&__pyx_n_s_project_output, __pyx_k_project_output, sizeof(__pyx_k_project_output), 0, 0, 1, 1},
   {&__pyx_n_s_properties, __pyx_k_properties, sizeof(__pyx_k_properties), 0, 0, 1, 1},
   {&__pyx_n_s_props, __pyx_k_props, sizeof(__pyx_k_props), 0, 0, 1, 1},
   {&__pyx_n_s_push_labels, __pyx_k_push_labels, sizeof(__pyx_k_push_labels), 0, 0, 1, 1},
   {&__pyx_n_s_push_weights, __pyx_k_push_weights, sizeof(__pyx_k_push_weights), 0, 0, 1, 1},
   {&__pyx_n_s_pywrapfst_2, __pyx_k_pywrapfst_2, sizeof(__pyx_k_pywrapfst_2), 0, 0, 1, 1},
+  {&__pyx_kp_s_pywrapfst_pyx, __pyx_k_pywrapfst_pyx, sizeof(__pyx_k_pywrapfst_pyx), 0, 0, 1, 0},
   {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1},
   {&__pyx_n_s_qualname, __pyx_k_qualname, sizeof(__pyx_k_qualname), 0, 0, 1, 1},
   {&__pyx_n_s_queue_type, __pyx_k_queue_type, sizeof(__pyx_k_queue_type), 0, 0, 1, 1},
@@ -50526,7 +51393,6 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_remove_total_weight, __pyx_k_remove_total_weight, sizeof(__pyx_k_remove_total_weight), 0, 0, 1, 1},
   {&__pyx_n_s_require_superinitial, __pyx_k_require_superinitial, sizeof(__pyx_k_require_superinitial), 0, 0, 1, 1},
   {&__pyx_n_s_reset, __pyx_k_reset, sizeof(__pyx_k_reset), 0, 0, 1, 1},
-  {&__pyx_n_s_result, __pyx_k_result, sizeof(__pyx_k_result), 0, 0, 1, 1},
   {&__pyx_n_s_return_arc_labeling, __pyx_k_return_arc_labeling, sizeof(__pyx_k_return_arc_labeling), 0, 0, 1, 1},
   {&__pyx_n_s_return_label, __pyx_k_return_label, sizeof(__pyx_k_return_label), 0, 0, 1, 1},
   {&__pyx_n_s_reverse, __pyx_k_reverse, sizeof(__pyx_k_reverse), 0, 0, 1, 1},
@@ -50550,13 +51416,10 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_setstate_cython, __pyx_k_setstate_cython, sizeof(__pyx_k_setstate_cython), 0, 0, 1, 1},
   {&__pyx_n_s_shortestdistance, __pyx_k_shortestdistance, sizeof(__pyx_k_shortestdistance), 0, 0, 1, 1},
   {&__pyx_n_s_show_weight_one, __pyx_k_show_weight_one, sizeof(__pyx_k_show_weight_one), 0, 0, 1, 1},
-  {&__pyx_n_s_simplefilter, __pyx_k_simplefilter, sizeof(__pyx_k_simplefilter), 0, 0, 1, 1},
   {&__pyx_n_s_sort_type, __pyx_k_sort_type, sizeof(__pyx_k_sort_type), 0, 0, 1, 1},
   {&__pyx_n_s_source, __pyx_k_source, sizeof(__pyx_k_source), 0, 0, 1, 1},
-  {&__pyx_kp_s_src_pywrapfst_pyx, __pyx_k_src_pywrapfst_pyx, sizeof(__pyx_k_src_pywrapfst_pyx), 0, 0, 1, 0},
   {&__pyx_n_s_ssymbols, __pyx_k_ssymbols, sizeof(__pyx_k_ssymbols), 0, 0, 1, 1},
-  {&__pyx_n_s_stacklevel, __pyx_k_stacklevel, sizeof(__pyx_k_stacklevel), 0, 0, 1, 1},
-  {&__pyx_n_b_standard, __pyx_k_standard, sizeof(__pyx_k_standard), 0, 0, 0, 1},
+  {&__pyx_n_u_standard, __pyx_k_standard, sizeof(__pyx_k_standard), 0, 1, 0, 1},
   {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1},
   {&__pyx_n_s_state, __pyx_k_state, sizeof(__pyx_k_state), 0, 0, 1, 1},
   {&__pyx_n_s_states, __pyx_k_states, sizeof(__pyx_k_states), 0, 0, 1, 1},
@@ -50566,50 +51429,62 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_subprocess, __pyx_k_subprocess, sizeof(__pyx_k_subprocess), 0, 0, 1, 1},
   {&__pyx_n_s_subsequential_label, __pyx_k_subsequential_label, sizeof(__pyx_k_subsequential_label), 0, 0, 1, 1},
   {&__pyx_n_s_symbol, __pyx_k_symbol, sizeof(__pyx_k_symbol), 0, 0, 1, 1},
-  {&__pyx_n_s_syms, __pyx_k_syms, sizeof(__pyx_k_syms), 0, 0, 1, 1},
+  {&__pyx_n_s_symbols, __pyx_k_symbols, sizeof(__pyx_k_symbols), 0, 0, 1, 1},
+  {&__pyx_n_s_sys, __pyx_k_sys, sizeof(__pyx_k_sys), 0, 0, 1, 1},
   {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},
   {&__pyx_n_s_test_2, __pyx_k_test_2, sizeof(__pyx_k_test_2), 0, 0, 1, 1},
-  {&__pyx_n_s_text, __pyx_k_text, sizeof(__pyx_k_text), 0, 0, 1, 1},
   {&__pyx_n_s_throw, __pyx_k_throw, sizeof(__pyx_k_throw), 0, 0, 1, 1},
   {&__pyx_n_s_times, __pyx_k_times, sizeof(__pyx_k_times), 0, 0, 1, 1},
   {&__pyx_n_s_title, __pyx_k_title, sizeof(__pyx_k_title), 0, 0, 1, 1},
   {&__pyx_n_s_to_final, __pyx_k_to_final, sizeof(__pyx_k_to_final), 0, 0, 1, 1},
   {&__pyx_n_s_to_string, __pyx_k_to_string, sizeof(__pyx_k_to_string), 0, 0, 1, 1},
   {&__pyx_n_s_type, __pyx_k_type, sizeof(__pyx_k_type), 0, 0, 1, 1},
-  {&__pyx_n_b_uniform, __pyx_k_uniform, sizeof(__pyx_k_uniform), 0, 0, 0, 1},
+  {&__pyx_n_s_typing, __pyx_k_typing, sizeof(__pyx_k_typing), 0, 0, 1, 1},
+  {&__pyx_kp_u_typing_Literal_alt_sequence_auto, __pyx_k_typing_Literal_alt_sequence_auto, sizeof(__pyx_k_typing_Literal_alt_sequence_auto), 0, 1, 0, 0},
+  {&__pyx_kp_u_typing_Literal_arc_sum_arc_uniqu, __pyx_k_typing_Literal_arc_sum_arc_uniqu, sizeof(__pyx_k_typing_Literal_arc_sum_arc_uniqu), 0, 1, 0, 0},
+  {&__pyx_kp_u_typing_Literal_auto_fifo_lifo_sh, __pyx_k_typing_Literal_auto_fifo_lifo_sh, sizeof(__pyx_k_typing_Literal_auto_fifo_lifo_sh), 0, 1, 0, 0},
+  {&__pyx_kp_u_typing_Literal_e_f_g, __pyx_k_typing_Literal_e_f_g, sizeof(__pyx_k_typing_Literal_e_f_g), 0, 1, 0, 0},
+  {&__pyx_kp_u_typing_Literal_fst_stlist_sttabl, __pyx_k_typing_Literal_fst_stlist_sttabl, sizeof(__pyx_k_typing_Literal_fst_stlist_sttabl), 0, 1, 0, 0},
+  {&__pyx_kp_u_typing_Literal_functional_nonfun, __pyx_k_typing_Literal_functional_nonfun, sizeof(__pyx_k_typing_Literal_functional_nonfun), 0, 1, 0, 0},
+  {&__pyx_kp_u_typing_Literal_identity_input_ep, __pyx_k_typing_Literal_identity_input_ep, sizeof(__pyx_k_typing_Literal_identity_input_ep), 0, 1, 0, 0},
+  {&__pyx_kp_u_typing_Literal_ilabel_olabel, __pyx_k_typing_Literal_ilabel_olabel, sizeof(__pyx_k_typing_Literal_ilabel_olabel), 0, 1, 0, 0},
+  {&__pyx_kp_u_typing_Literal_input_output, __pyx_k_typing_Literal_input_output, sizeof(__pyx_k_typing_Literal_input_output), 0, 1, 0, 0},
+  {&__pyx_kp_u_typing_Literal_neither_input_out, __pyx_k_typing_Literal_neither_input_out, sizeof(__pyx_k_typing_Literal_neither_input_out), 0, 1, 0, 0},
+  {&__pyx_kp_u_typing_Literal_uniform_log_prob, __pyx_k_typing_Literal_uniform_log_prob, sizeof(__pyx_k_typing_Literal_uniform_log_prob), 0, 1, 0, 0},
+  {&__pyx_kp_u_typing_Union_Weight_typing_Union, __pyx_k_typing_Union_Weight_typing_Union, sizeof(__pyx_k_typing_Union_Weight_typing_Union), 0, 1, 0, 0},
+  {&__pyx_n_u_uniform, __pyx_k_uniform, sizeof(__pyx_k_uniform), 0, 1, 0, 1},
   {&__pyx_n_s_unique, __pyx_k_unique, sizeof(__pyx_k_unique), 0, 0, 1, 1},
   {&__pyx_n_s_unknown_isymbol, __pyx_k_unknown_isymbol, sizeof(__pyx_k_unknown_isymbol), 0, 0, 1, 1},
   {&__pyx_n_s_unknown_osymbol, __pyx_k_unknown_osymbol, sizeof(__pyx_k_unknown_osymbol), 0, 0, 1, 1},
   {&__pyx_kp_u_unspecified, __pyx_k_unspecified, sizeof(__pyx_k_unspecified), 0, 1, 0, 0},
-  {&__pyx_n_u_utf8, __pyx_k_utf8, sizeof(__pyx_k_utf8), 0, 1, 0, 1},
   {&__pyx_n_s_value, __pyx_k_value, sizeof(__pyx_k_value), 0, 0, 1, 1},
-  {&__pyx_n_b_vector, __pyx_k_vector, sizeof(__pyx_k_vector), 0, 0, 0, 1},
+  {&__pyx_n_u_vector, __pyx_k_vector, sizeof(__pyx_k_vector), 0, 1, 0, 1},
   {&__pyx_n_s_verify, __pyx_k_verify, sizeof(__pyx_k_verify), 0, 0, 1, 1},
   {&__pyx_n_s_vertical, __pyx_k_vertical, sizeof(__pyx_k_vertical), 0, 0, 1, 1},
   {&__pyx_n_s_w, __pyx_k_w, sizeof(__pyx_k_w), 0, 0, 1, 1},
-  {&__pyx_n_s_warn, __pyx_k_warn, sizeof(__pyx_k_warn), 0, 0, 1, 1},
   {&__pyx_n_s_warning, __pyx_k_warning, sizeof(__pyx_k_warning), 0, 0, 1, 1},
-  {&__pyx_n_s_warnings, __pyx_k_warnings, sizeof(__pyx_k_warnings), 0, 0, 1, 1},
   {&__pyx_n_s_weight, __pyx_k_weight, sizeof(__pyx_k_weight), 0, 0, 1, 1},
+  {&__pyx_n_s_weight_2, __pyx_k_weight_2, sizeof(__pyx_k_weight_2), 0, 0, 1, 1},
   {&__pyx_n_s_weight_type, __pyx_k_weight_type, sizeof(__pyx_k_weight_type), 0, 0, 1, 1},
   {&__pyx_n_s_weighted, __pyx_k_weighted, sizeof(__pyx_k_weighted), 0, 0, 1, 1},
   {&__pyx_n_s_width, __pyx_k_width, sizeof(__pyx_k_width), 0, 0, 1, 1},
   {&__pyx_n_s_write, __pyx_k_write, sizeof(__pyx_k_write), 0, 0, 1, 1},
   {&__pyx_n_s_write_text, __pyx_k_write_text, sizeof(__pyx_k_write_text), 0, 0, 1, 1},
   {&__pyx_n_s_write_to_string, __pyx_k_write_to_string, sizeof(__pyx_k_write_to_string), 0, 0, 1, 1},
+  {&__pyx_n_u_x, __pyx_k_x, sizeof(__pyx_k_x), 0, 1, 0, 1},
   {0, 0, 0, 0, 0, 0, 0}
 };
 static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) {
-  __pyx_builtin_DeprecationWarning = __Pyx_GetBuiltinName(__pyx_n_s_DeprecationWarning); if (!__pyx_builtin_DeprecationWarning) __PYX_ERR(0, 106, __pyx_L1_error)
-  __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(0, 117, __pyx_L1_error)
-  __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(0, 127, __pyx_L1_error)
-  __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) __PYX_ERR(0, 132, __pyx_L1_error)
-  __pyx_builtin_IOError = __Pyx_GetBuiltinName(__pyx_n_s_IOError); if (!__pyx_builtin_IOError) __PYX_ERR(0, 137, __pyx_L1_error)
-  __pyx_builtin_staticmethod = __Pyx_GetBuiltinName(__pyx_n_s_staticmethod); if (!__pyx_builtin_staticmethod) __PYX_ERR(0, 1358, __pyx_L1_error)
-  __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) __PYX_ERR(0, 361, __pyx_L1_error)
-  __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(1, 2, __pyx_L1_error)
-  __pyx_builtin_StopIteration = __Pyx_GetBuiltinName(__pyx_n_s_StopIteration); if (!__pyx_builtin_StopIteration) __PYX_ERR(0, 1225, __pyx_L1_error)
-  __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) __PYX_ERR(0, 4522, __pyx_L1_error)
+  __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(0, 146, __pyx_L1_error)
+  __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) __PYX_ERR(0, 156, __pyx_L1_error)
+  __pyx_builtin_IOError = __Pyx_GetBuiltinName(__pyx_n_s_IOError); if (!__pyx_builtin_IOError) __PYX_ERR(0, 161, __pyx_L1_error)
+  __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(0, 166, __pyx_L1_error)
+  __pyx_builtin_staticmethod = __Pyx_GetBuiltinName(__pyx_n_s_staticmethod); if (!__pyx_builtin_staticmethod) __PYX_ERR(0, 1418, __pyx_L1_error)
+  __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(0, 195, __pyx_L1_error)
+  __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) __PYX_ERR(0, 424, __pyx_L1_error)
+  __pyx_builtin_NotImplementedError = __Pyx_GetBuiltinName(__pyx_n_s_NotImplementedError); if (!__pyx_builtin_NotImplementedError) __PYX_ERR(0, 745, __pyx_L1_error)
+  __pyx_builtin_StopIteration = __Pyx_GetBuiltinName(__pyx_n_s_StopIteration); if (!__pyx_builtin_StopIteration) __PYX_ERR(0, 1285, __pyx_L1_error)
+  __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) __PYX_ERR(0, 4552, __pyx_L1_error)
   return 0;
   __pyx_L1_error:;
   return -1;
@@ -50625,18 +51500,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._weight cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_s_self__weight_cannot_be_converted); if (unlikely(!__pyx_tuple_)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple_);
-  __Pyx_GIVEREF(__pyx_tuple_);
+  __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_s_self__weight_cannot_be_converted); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__4);
+  __Pyx_GIVEREF(__pyx_tuple__4);
 
   /* "(tree fragment)":4
  *     raise TypeError("self._weight cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._weight cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_s_self__weight_cannot_be_converted); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__2);
-  __Pyx_GIVEREF(__pyx_tuple__2);
+  __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_s_self__weight_cannot_be_converted); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__5);
+  __Pyx_GIVEREF(__pyx_tuple__5);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -50644,43 +51519,32 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._siter cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_s_self__siter_cannot_be_converted); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__4);
-  __Pyx_GIVEREF(__pyx_tuple__4);
+  __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_self__siter_cannot_be_converted); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__7);
+  __Pyx_GIVEREF(__pyx_tuple__7);
 
   /* "(tree fragment)":4
  *     raise TypeError("self._siter cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._siter cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_s_self__siter_cannot_be_converted); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__5);
-  __Pyx_GIVEREF(__pyx_tuple__5);
+  __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s_self__siter_cannot_be_converted); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__8);
+  __Pyx_GIVEREF(__pyx_tuple__8);
 
-  /* "pywrapfst.pyx":1516
+  /* "pywrapfst.pyx":1576
  *   @staticmethod
  *   cdef string _local_render_svg(const string &dot):
  *     proc = subprocess.Popen(("dot", "-Tsvg"),             # <<<<<<<<<<<<<<
  *                             stdin=subprocess.PIPE,
  *                             stdout=subprocess.PIPE)
  */
-  __pyx_tuple__6 = PyTuple_Pack(2, __pyx_n_u_dot, __pyx_kp_u_Tsvg); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(0, 1516, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__6);
-  __Pyx_GIVEREF(__pyx_tuple__6);
-  __pyx_tuple__7 = PyTuple_Pack(1, __pyx_tuple__6); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(0, 1516, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__7);
-  __Pyx_GIVEREF(__pyx_tuple__7);
-
-  /* "pywrapfst.pyx":1927
- *       A formatted string representing the machine.
- *     """
- *     warnings.warn("Use `print` instead", DeprecationWarning, stacklevel=2)             # <<<<<<<<<<<<<<
- *     return self.print(isymbols,
- *                       osymbols,
- */
-  __pyx_tuple__9 = PyTuple_Pack(2, __pyx_kp_u_Use_print_instead, __pyx_builtin_DeprecationWarning); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(0, 1927, __pyx_L1_error)
+  __pyx_tuple__9 = PyTuple_Pack(2, __pyx_n_u_dot, __pyx_kp_u_Tsvg); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(0, 1576, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__9);
   __Pyx_GIVEREF(__pyx_tuple__9);
+  __pyx_tuple__10 = PyTuple_Pack(1, __pyx_tuple__9); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(0, 1576, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__10);
+  __Pyx_GIVEREF(__pyx_tuple__10);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -50688,18 +51552,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._arc cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__22 = PyTuple_Pack(1, __pyx_kp_s_self__arc_cannot_be_converted_to); if (unlikely(!__pyx_tuple__22)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__22);
-  __Pyx_GIVEREF(__pyx_tuple__22);
+  __pyx_tuple__24 = PyTuple_Pack(1, __pyx_kp_s_self__arc_cannot_be_converted_to); if (unlikely(!__pyx_tuple__24)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__24);
+  __Pyx_GIVEREF(__pyx_tuple__24);
 
   /* "(tree fragment)":4
  *     raise TypeError("self._arc cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._arc cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__23 = PyTuple_Pack(1, __pyx_kp_s_self__arc_cannot_be_converted_to); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__23);
-  __Pyx_GIVEREF(__pyx_tuple__23);
+  __pyx_tuple__25 = PyTuple_Pack(1, __pyx_kp_s_self__arc_cannot_be_converted_to); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__25);
+  __Pyx_GIVEREF(__pyx_tuple__25);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -50707,18 +51571,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._aiter,self._fst cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__24 = PyTuple_Pack(1, __pyx_kp_s_self__aiter_self__fst_cannot_be); if (unlikely(!__pyx_tuple__24)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__24);
-  __Pyx_GIVEREF(__pyx_tuple__24);
+  __pyx_tuple__26 = PyTuple_Pack(1, __pyx_kp_s_self__aiter_self__fst_cannot_be); if (unlikely(!__pyx_tuple__26)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__26);
+  __Pyx_GIVEREF(__pyx_tuple__26);
 
   /* "(tree fragment)":4
  *     raise TypeError("self._aiter,self._fst cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._aiter,self._fst cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__25 = PyTuple_Pack(1, __pyx_kp_s_self__aiter_self__fst_cannot_be); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__25);
-  __Pyx_GIVEREF(__pyx_tuple__25);
+  __pyx_tuple__27 = PyTuple_Pack(1, __pyx_kp_s_self__aiter_self__fst_cannot_be); if (unlikely(!__pyx_tuple__27)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__27);
+  __Pyx_GIVEREF(__pyx_tuple__27);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -50726,18 +51590,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._aiter,self._mfst cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__26 = PyTuple_Pack(1, __pyx_kp_s_self__aiter_self__mfst_cannot_be); if (unlikely(!__pyx_tuple__26)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__26);
-  __Pyx_GIVEREF(__pyx_tuple__26);
+  __pyx_tuple__28 = PyTuple_Pack(1, __pyx_kp_s_self__aiter_self__mfst_cannot_be); if (unlikely(!__pyx_tuple__28)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__28);
+  __Pyx_GIVEREF(__pyx_tuple__28);
 
   /* "(tree fragment)":4
  *     raise TypeError("self._aiter,self._mfst cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._aiter,self._mfst cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__27 = PyTuple_Pack(1, __pyx_kp_s_self__aiter_self__mfst_cannot_be); if (unlikely(!__pyx_tuple__27)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__27);
-  __Pyx_GIVEREF(__pyx_tuple__27);
+  __pyx_tuple__29 = PyTuple_Pack(1, __pyx_kp_s_self__aiter_self__mfst_cannot_be); if (unlikely(!__pyx_tuple__29)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__29);
+  __Pyx_GIVEREF(__pyx_tuple__29);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -50745,18 +51609,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._fst,self._siter cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__28 = PyTuple_Pack(1, __pyx_kp_s_self__fst_self__siter_cannot_be); if (unlikely(!__pyx_tuple__28)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__28);
-  __Pyx_GIVEREF(__pyx_tuple__28);
+  __pyx_tuple__30 = PyTuple_Pack(1, __pyx_kp_s_self__fst_self__siter_cannot_be); if (unlikely(!__pyx_tuple__30)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__30);
+  __Pyx_GIVEREF(__pyx_tuple__30);
 
   /* "(tree fragment)":4
  *     raise TypeError("self._fst,self._siter cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self._fst,self._siter cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__29 = PyTuple_Pack(1, __pyx_kp_s_self__fst_self__siter_cannot_be); if (unlikely(!__pyx_tuple__29)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__29);
-  __Pyx_GIVEREF(__pyx_tuple__29);
+  __pyx_tuple__31 = PyTuple_Pack(1, __pyx_kp_s_self__fst_self__siter_cannot_be); if (unlikely(!__pyx_tuple__31)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__31);
+  __Pyx_GIVEREF(__pyx_tuple__31);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -50815,88 +51679,77 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__58);
   __Pyx_GIVEREF(__pyx_tuple__58);
 
-  /* "pywrapfst.pyx":106
- * import warnings
- * 
- * warnings.simplefilter("always", DeprecationWarning)             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __pyx_tuple__59 = PyTuple_Pack(2, __pyx_n_u_always, __pyx_builtin_DeprecationWarning); if (unlikely(!__pyx_tuple__59)) __PYX_ERR(0, 106, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__59);
-  __Pyx_GIVEREF(__pyx_tuple__59);
-
-  /* "pywrapfst.pyx":450
+  /* "pywrapfst.pyx":513
  * 
  * 
  * def plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
  *   """
  *   plus(lhs, rhs)
  */
-  __pyx_tuple__60 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_result); if (unlikely(!__pyx_tuple__60)) __PYX_ERR(0, 450, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__60);
-  __Pyx_GIVEREF(__pyx_tuple__60);
-  __pyx_codeobj__61 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__60, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_pywrapfst_pyx, __pyx_n_s_plus, 450, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__61)) __PYX_ERR(0, 450, __pyx_L1_error)
+  __pyx_tuple__59 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_weight_2); if (unlikely(!__pyx_tuple__59)) __PYX_ERR(0, 513, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__59);
+  __Pyx_GIVEREF(__pyx_tuple__59);
+  __pyx_codeobj__60 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__59, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_plus, 513, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__60)) __PYX_ERR(0, 513, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":482
+  /* "pywrapfst.pyx":545
  * 
  * 
  * def times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
  *   """
  *   times(lhs, rhs)
  */
-  __pyx_tuple__62 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_result); if (unlikely(!__pyx_tuple__62)) __PYX_ERR(0, 482, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__62);
-  __Pyx_GIVEREF(__pyx_tuple__62);
-  __pyx_codeobj__63 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__62, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_pywrapfst_pyx, __pyx_n_s_times, 482, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__63)) __PYX_ERR(0, 482, __pyx_L1_error)
+  __pyx_tuple__61 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_weight_2); if (unlikely(!__pyx_tuple__61)) __PYX_ERR(0, 545, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__61);
+  __Pyx_GIVEREF(__pyx_tuple__61);
+  __pyx_codeobj__62 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__61, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_times, 545, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__62)) __PYX_ERR(0, 545, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":514
+  /* "pywrapfst.pyx":577
  * 
  * 
  * def divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
  *   """
  *   divide(lhs, rhs)
  */
-  __pyx_tuple__64 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_result); if (unlikely(!__pyx_tuple__64)) __PYX_ERR(0, 514, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__64);
-  __Pyx_GIVEREF(__pyx_tuple__64);
-  __pyx_codeobj__65 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__64, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_pywrapfst_pyx, __pyx_n_s_divide, 514, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__65)) __PYX_ERR(0, 514, __pyx_L1_error)
+  __pyx_tuple__63 = PyTuple_Pack(3, __pyx_n_s_lhs, __pyx_n_s_rhs, __pyx_n_s_weight_2); if (unlikely(!__pyx_tuple__63)) __PYX_ERR(0, 577, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__63);
+  __Pyx_GIVEREF(__pyx_tuple__63);
+  __pyx_codeobj__64 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__63, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_divide, 577, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__64)) __PYX_ERR(0, 577, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":547
+  /* "pywrapfst.pyx":610
  * 
  * 
  * def power(Weight w, size_t n):             # <<<<<<<<<<<<<<
  *   """
  *   power(lhs, rhs)
  */
-  __pyx_tuple__66 = PyTuple_Pack(3, __pyx_n_s_w, __pyx_n_s_n, __pyx_n_s_result); if (unlikely(!__pyx_tuple__66)) __PYX_ERR(0, 547, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__66);
-  __Pyx_GIVEREF(__pyx_tuple__66);
-  __pyx_codeobj__67 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__66, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_pywrapfst_pyx, __pyx_n_s_power, 547, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__67)) __PYX_ERR(0, 547, __pyx_L1_error)
+  __pyx_tuple__65 = PyTuple_Pack(3, __pyx_n_s_w, __pyx_n_s_n, __pyx_n_s_weight_2); if (unlikely(!__pyx_tuple__65)) __PYX_ERR(0, 610, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__65);
+  __Pyx_GIVEREF(__pyx_tuple__65);
+  __pyx_codeobj__66 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__65, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_power, 610, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__66)) __PYX_ERR(0, 610, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":1359
+  /* "pywrapfst.pyx":1419
  * 
  *   @staticmethod
  *   def read_from_string(state):             # <<<<<<<<<<<<<<
  *     """
  *     read_from_string(state)
  */
-  __pyx_tuple__68 = PyTuple_Pack(1, __pyx_n_s_state); if (unlikely(!__pyx_tuple__68)) __PYX_ERR(0, 1359, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__68);
-  __Pyx_GIVEREF(__pyx_tuple__68);
-  __pyx_codeobj__69 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__68, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_pywrapfst_pyx, __pyx_n_s_read_from_string, 1359, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__69)) __PYX_ERR(0, 1359, __pyx_L1_error)
+  __pyx_tuple__67 = PyTuple_Pack(1, __pyx_n_s_state); if (unlikely(!__pyx_tuple__67)) __PYX_ERR(0, 1419, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__67);
+  __Pyx_GIVEREF(__pyx_tuple__67);
+  __pyx_codeobj__68 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__67, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_read_from_string, 1419, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__68)) __PYX_ERR(0, 1419, __pyx_L1_error)
 
-  /* "pywrapfst.pyx":4099
+  /* "pywrapfst.pyx":4130
  * 
  * 
  * def shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
  *                      float delta=fst.kShortestDelta,
  *                      int64 nstate=fst.kNoStateId,
  */
-  __pyx_tuple__70 = PyTuple_Pack(8, __pyx_n_s_ifst, __pyx_n_s_delta, __pyx_n_s_nstate, __pyx_n_s_queue_type, __pyx_n_s_reverse, __pyx_n_s_distance, __pyx_n_s_weight_type, __pyx_n_s_weight); if (unlikely(!__pyx_tuple__70)) __PYX_ERR(0, 4099, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__70);
-  __Pyx_GIVEREF(__pyx_tuple__70);
-  __pyx_codeobj__71 = (PyObject*)__Pyx_PyCode_New(5, 0, 8, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__70, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_pywrapfst_pyx, __pyx_n_s_shortestdistance, 4099, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__71)) __PYX_ERR(0, 4099, __pyx_L1_error)
+  __pyx_tuple__69 = PyTuple_Pack(7, __pyx_n_s_ifst, __pyx_n_s_delta, __pyx_n_s_nstate, __pyx_n_s_queue_type, __pyx_n_s_reverse, __pyx_n_s_distance, __pyx_n_s_weight); if (unlikely(!__pyx_tuple__69)) __PYX_ERR(0, 4130, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__69);
+  __Pyx_GIVEREF(__pyx_tuple__69);
+  __pyx_codeobj__70 = (PyObject*)__Pyx_PyCode_New(5, 0, 7, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__69, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_pywrapfst_pyx, __pyx_n_s_shortestdistance, 4130, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__70)) __PYX_ERR(0, 4130, __pyx_L1_error)
   __Pyx_RefNannyFinishContext();
   return 0;
   __pyx_L1_error:;
@@ -50906,7 +51759,6 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
 
 static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) {
   if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error);
-  __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) __PYX_ERR(0, 1, __pyx_L1_error)
   return 0;
   __pyx_L1_error:;
   return -1;
@@ -50938,10 +51790,14 @@ static int __Pyx_modinit_variable_export_code(void) {
 
 static int __Pyx_modinit_function_export_code(void) {
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0);
   /*--- Function export code ---*/
   if (__Pyx_ExportFunction("tostring", (void (*)(void))__pyx_f_9pywrapfst_tostring, "std::string (PyObject *)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("weight_tostring", (void (*)(void))__pyx_f_9pywrapfst_weight_tostring, "std::string (PyObject *)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_ExportFunction("path_tostring", (void (*)(void))__pyx_f_9pywrapfst_path_tostring, "std::string (PyObject *)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_get_compose_filter", (void (*)(void))__pyx_f_9pywrapfst__get_compose_filter, "enum fst::ComposeFilter (std::string const &)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_get_determinize_type", (void (*)(void))__pyx_f_9pywrapfst__get_determinize_type, "enum fst::DeterminizeType (std::string const &)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_get_queue_type", (void (*)(void))__pyx_f_9pywrapfst__get_queue_type, "enum fst::QueueType (std::string const &)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
@@ -50960,14 +51816,14 @@ static int __Pyx_modinit_function_export_code(void) {
   if (__Pyx_ExportFunction("_init_FstSymbolTableView", (void (*)(void))__pyx_f_9pywrapfst__init_FstSymbolTableView, "struct __pyx_obj_9pywrapfst__FstSymbolTableView *(std::shared_ptr<fst::script::FstClass> , bool)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_init_MutableFstSymbolTableView", (void (*)(void))__pyx_f_9pywrapfst__init_MutableFstSymbolTableView, "struct __pyx_obj_9pywrapfst__MutableFstSymbolTableView *(std::shared_ptr<fst::script::MutableFstClass> , bool)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_init_SymbolTable", (void (*)(void))__pyx_f_9pywrapfst__init_SymbolTable, "struct __pyx_obj_9pywrapfst_SymbolTable *(std::unique_ptr<fst::SymbolTable> )") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  if (__Pyx_ExportFunction("_read_SymbolTable_from_string", (void (*)(void))__pyx_f_9pywrapfst__read_SymbolTable_from_string, "struct __pyx_obj_9pywrapfst_SymbolTable *(PyObject *, int __pyx_skip_dispatch)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_ExportFunction("_read_SymbolTable_from_string", (void (*)(void))__pyx_f_9pywrapfst__read_SymbolTable_from_string, "struct __pyx_obj_9pywrapfst_SymbolTable *(std::string, int __pyx_skip_dispatch)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_init_EncodeMapper", (void (*)(void))__pyx_f_9pywrapfst__init_EncodeMapper, "struct __pyx_obj_9pywrapfst_EncodeMapper *(__pyx_t_9pywrapfst_EncodeMapperClass_ptr)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  if (__Pyx_ExportFunction("_read_EncodeMapper_from_string", (void (*)(void))__pyx_f_9pywrapfst__read_EncodeMapper_from_string, "struct __pyx_obj_9pywrapfst_EncodeMapper *(PyObject *, int __pyx_skip_dispatch)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_ExportFunction("_read_EncodeMapper_from_string", (void (*)(void))__pyx_f_9pywrapfst__read_EncodeMapper_from_string, "struct __pyx_obj_9pywrapfst_EncodeMapper *(std::string, int __pyx_skip_dispatch)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_init_Fst", (void (*)(void))__pyx_f_9pywrapfst__init_Fst, "struct __pyx_obj_9pywrapfst_Fst *(__pyx_t_9pywrapfst_FstClass_ptr)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_init_MutableFst", (void (*)(void))__pyx_f_9pywrapfst__init_MutableFst, "struct __pyx_obj_9pywrapfst_MutableFst *(__pyx_t_9pywrapfst_MutableFstClass_ptr)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_init_XFst", (void (*)(void))__pyx_f_9pywrapfst__init_XFst, "struct __pyx_obj_9pywrapfst_Fst *(__pyx_t_9pywrapfst_FstClass_ptr)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_read_Fst", (void (*)(void))__pyx_f_9pywrapfst__read_Fst, "struct __pyx_obj_9pywrapfst_Fst *(PyObject *, int __pyx_skip_dispatch)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  if (__Pyx_ExportFunction("_read_Fst_from_string", (void (*)(void))__pyx_f_9pywrapfst__read_Fst_from_string, "struct __pyx_obj_9pywrapfst_Fst *(PyObject *, int __pyx_skip_dispatch)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_ExportFunction("_read_Fst_from_string", (void (*)(void))__pyx_f_9pywrapfst__read_Fst_from_string, "struct __pyx_obj_9pywrapfst_Fst *(std::string, int __pyx_skip_dispatch)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_init_Arc", (void (*)(void))__pyx_f_9pywrapfst__init_Arc, "struct __pyx_obj_9pywrapfst_Arc *(fst::script::ArcClass const &)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("_map", (void (*)(void))__pyx_f_9pywrapfst__map, "struct __pyx_obj_9pywrapfst_Fst *(struct __pyx_obj_9pywrapfst_Fst *, struct __pyx_opt_args_9pywrapfst__map *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("arcmap", (void (*)(void))__pyx_f_9pywrapfst_arcmap, "struct __pyx_obj_9pywrapfst_Fst *(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_arcmap *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
@@ -50987,7 +51843,7 @@ static int __Pyx_modinit_function_export_code(void) {
   if (__Pyx_ExportFunction("randgen", (void (*)(void))__pyx_f_9pywrapfst_randgen, "struct __pyx_obj_9pywrapfst_MutableFst *(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_randgen *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("replace", (void (*)(void))__pyx_f_9pywrapfst_replace, "struct __pyx_obj_9pywrapfst_MutableFst *(PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_replace *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("reverse", (void (*)(void))__pyx_f_9pywrapfst_reverse, "struct __pyx_obj_9pywrapfst_MutableFst *(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_reverse *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  if (__Pyx_ExportFunction("_shortestdistance", (void (*)(void))__pyx_f_9pywrapfst__shortestdistance, "std::vector<fst::script::WeightClass>  *(struct __pyx_obj_9pywrapfst_Fst *, struct __pyx_opt_args_9pywrapfst__shortestdistance *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (__Pyx_ExportFunction("_shortestdistance", (void (*)(void))__pyx_f_9pywrapfst__shortestdistance, "void (struct __pyx_obj_9pywrapfst_Fst *, std::vector<fst::script::WeightClass>  *, struct __pyx_opt_args_9pywrapfst__shortestdistance *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("shortestpath", (void (*)(void))__pyx_f_9pywrapfst_shortestpath, "struct __pyx_obj_9pywrapfst_MutableFst *(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_shortestpath *__pyx_optional_args)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("statemap", (void (*)(void))__pyx_f_9pywrapfst_statemap, "struct __pyx_obj_9pywrapfst_Fst *(struct __pyx_obj_9pywrapfst_Fst *, PyObject *, int __pyx_skip_dispatch)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   if (__Pyx_ExportFunction("synchronize", (void (*)(void))__pyx_f_9pywrapfst_synchronize, "struct __pyx_obj_9pywrapfst_MutableFst *(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch)") < 0) __PYX_ERR(0, 1, __pyx_L1_error)
@@ -51000,6 +51856,9 @@ static int __Pyx_modinit_function_export_code(void) {
 
 static int __Pyx_modinit_type_init_code(void) {
   __Pyx_RefNannyDeclarations
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0);
   /*--- Type init code ---*/
   __pyx_vtabptr_9pywrapfst_Weight = &__pyx_vtable_9pywrapfst_Weight;
@@ -51008,126 +51867,126 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_Weight.to_string = (std::string (*)(struct __pyx_obj_9pywrapfst_Weight *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_6Weight_to_string;
   __pyx_vtable_9pywrapfst_Weight.type = (std::string (*)(struct __pyx_obj_9pywrapfst_Weight *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_6Weight_type;
   __pyx_vtable_9pywrapfst_Weight.member = (bool (*)(struct __pyx_obj_9pywrapfst_Weight *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_6Weight_member;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_Weight) < 0) __PYX_ERR(0, 339, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_Weight) < 0) __PYX_ERR(0, 403, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_Weight.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_Weight.tp_dictoffset && __pyx_type_9pywrapfst_Weight.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_Weight.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Weight.tp_dict, __pyx_vtabptr_9pywrapfst_Weight) < 0) __PYX_ERR(0, 339, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Weight, (PyObject *)&__pyx_type_9pywrapfst_Weight) < 0) __PYX_ERR(0, 339, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Weight) < 0) __PYX_ERR(0, 339, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Weight.tp_dict, __pyx_vtabptr_9pywrapfst_Weight) < 0) __PYX_ERR(0, 403, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Weight_2, (PyObject *)&__pyx_type_9pywrapfst_Weight) < 0) __PYX_ERR(0, 403, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Weight) < 0) __PYX_ERR(0, 403, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_Weight = &__pyx_type_9pywrapfst_Weight;
-  __pyx_vtabptr_9pywrapfst__SymbolTable = &__pyx_vtable_9pywrapfst__SymbolTable;
-  __pyx_vtable_9pywrapfst__SymbolTable._raw = (fst::SymbolTable const *(*)(struct __pyx_obj_9pywrapfst__SymbolTable *))__pyx_f_9pywrapfst_12_SymbolTable__raw;
-  __pyx_vtable_9pywrapfst__SymbolTable._raise_nonexistent = (void (*)(struct __pyx_obj_9pywrapfst__SymbolTable *))__pyx_f_9pywrapfst_12_SymbolTable__raise_nonexistent;
-  __pyx_vtable_9pywrapfst__SymbolTable._raw_ptr_or_raise = (fst::SymbolTable const *(*)(struct __pyx_obj_9pywrapfst__SymbolTable *))__pyx_f_9pywrapfst_12_SymbolTable__raw_ptr_or_raise;
-  __pyx_vtable_9pywrapfst__SymbolTable.available_key = (int64 (*)(struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_SymbolTable_available_key;
-  __pyx_vtable_9pywrapfst__SymbolTable.checksum = (PyObject *(*)(struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_SymbolTable_checksum;
-  __pyx_vtable_9pywrapfst__SymbolTable.copy = (struct __pyx_obj_9pywrapfst_SymbolTable *(*)(struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_SymbolTable_copy;
-  __pyx_vtable_9pywrapfst__SymbolTable.get_nth_key = (int64 (*)(struct __pyx_obj_9pywrapfst__SymbolTable *, Py_ssize_t, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_SymbolTable_get_nth_key;
-  __pyx_vtable_9pywrapfst__SymbolTable.labeled_checksum = (PyObject *(*)(struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_SymbolTable_labeled_checksum;
-  __pyx_vtable_9pywrapfst__SymbolTable.member = (bool (*)(struct __pyx_obj_9pywrapfst__SymbolTable *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_SymbolTable_member;
-  __pyx_vtable_9pywrapfst__SymbolTable.name = (std::string (*)(struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_SymbolTable_name;
-  __pyx_vtable_9pywrapfst__SymbolTable.num_symbols = (size_t (*)(struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_SymbolTable_num_symbols;
-  __pyx_vtable_9pywrapfst__SymbolTable.write = (void (*)(struct __pyx_obj_9pywrapfst__SymbolTable *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_SymbolTable_write;
-  __pyx_vtable_9pywrapfst__SymbolTable.write_text = (void (*)(struct __pyx_obj_9pywrapfst__SymbolTable *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_SymbolTable_write_text;
-  __pyx_vtable_9pywrapfst__SymbolTable.write_to_string = (PyObject *(*)(struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12_SymbolTable_write_to_string;
-  if (PyType_Ready(&__pyx_type_9pywrapfst__SymbolTable) < 0) __PYX_ERR(0, 669, __pyx_L1_error)
+  __pyx_vtabptr_9pywrapfst_SymbolTableView = &__pyx_vtable_9pywrapfst_SymbolTableView;
+  __pyx_vtable_9pywrapfst_SymbolTableView._raw = (fst::SymbolTable const *(*)(struct __pyx_obj_9pywrapfst_SymbolTableView *))__pyx_f_9pywrapfst_15SymbolTableView__raw;
+  __pyx_vtable_9pywrapfst_SymbolTableView._raise_nonexistent = (void (*)(struct __pyx_obj_9pywrapfst_SymbolTableView *))__pyx_f_9pywrapfst_15SymbolTableView__raise_nonexistent;
+  __pyx_vtable_9pywrapfst_SymbolTableView._raw_ptr_or_raise = (fst::SymbolTable const *(*)(struct __pyx_obj_9pywrapfst_SymbolTableView *))__pyx_f_9pywrapfst_15SymbolTableView__raw_ptr_or_raise;
+  __pyx_vtable_9pywrapfst_SymbolTableView.available_key = (int64 (*)(struct __pyx_obj_9pywrapfst_SymbolTableView *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_15SymbolTableView_available_key;
+  __pyx_vtable_9pywrapfst_SymbolTableView.checksum = (PyObject *(*)(struct __pyx_obj_9pywrapfst_SymbolTableView *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_15SymbolTableView_checksum;
+  __pyx_vtable_9pywrapfst_SymbolTableView.copy = (struct __pyx_obj_9pywrapfst_SymbolTable *(*)(struct __pyx_obj_9pywrapfst_SymbolTableView *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_15SymbolTableView_copy;
+  __pyx_vtable_9pywrapfst_SymbolTableView.get_nth_key = (int64 (*)(struct __pyx_obj_9pywrapfst_SymbolTableView *, Py_ssize_t, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_15SymbolTableView_get_nth_key;
+  __pyx_vtable_9pywrapfst_SymbolTableView.labeled_checksum = (PyObject *(*)(struct __pyx_obj_9pywrapfst_SymbolTableView *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_15SymbolTableView_labeled_checksum;
+  __pyx_vtable_9pywrapfst_SymbolTableView.member = (bool (*)(struct __pyx_obj_9pywrapfst_SymbolTableView *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_15SymbolTableView_member;
+  __pyx_vtable_9pywrapfst_SymbolTableView.name = (std::string (*)(struct __pyx_obj_9pywrapfst_SymbolTableView *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_15SymbolTableView_name;
+  __pyx_vtable_9pywrapfst_SymbolTableView.num_symbols = (size_t (*)(struct __pyx_obj_9pywrapfst_SymbolTableView *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_15SymbolTableView_num_symbols;
+  __pyx_vtable_9pywrapfst_SymbolTableView.write = (void (*)(struct __pyx_obj_9pywrapfst_SymbolTableView *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_15SymbolTableView_write;
+  __pyx_vtable_9pywrapfst_SymbolTableView.write_text = (void (*)(struct __pyx_obj_9pywrapfst_SymbolTableView *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_15SymbolTableView_write_text;
+  __pyx_vtable_9pywrapfst_SymbolTableView.write_to_string = (PyObject *(*)(struct __pyx_obj_9pywrapfst_SymbolTableView *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_15SymbolTableView_write_to_string;
+  if (PyType_Ready(&__pyx_type_9pywrapfst_SymbolTableView) < 0) __PYX_ERR(0, 730, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
-  __pyx_type_9pywrapfst__SymbolTable.tp_print = 0;
+  __pyx_type_9pywrapfst_SymbolTableView.tp_print = 0;
   #endif
-  if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__SymbolTable.tp_dictoffset && __pyx_type_9pywrapfst__SymbolTable.tp_getattro == PyObject_GenericGetAttr)) {
-    __pyx_type_9pywrapfst__SymbolTable.tp_getattro = __Pyx_PyObject_GenericGetAttr;
+  if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_SymbolTableView.tp_dictoffset && __pyx_type_9pywrapfst_SymbolTableView.tp_getattro == PyObject_GenericGetAttr)) {
+    __pyx_type_9pywrapfst_SymbolTableView.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__SymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__SymbolTable) < 0) __PYX_ERR(0, 669, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SymbolTable, (PyObject *)&__pyx_type_9pywrapfst__SymbolTable) < 0) __PYX_ERR(0, 669, __pyx_L1_error)
-  __pyx_ptype_9pywrapfst__SymbolTable = &__pyx_type_9pywrapfst__SymbolTable;
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_SymbolTableView.tp_dict, __pyx_vtabptr_9pywrapfst_SymbolTableView) < 0) __PYX_ERR(0, 730, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SymbolTableView, (PyObject *)&__pyx_type_9pywrapfst_SymbolTableView) < 0) __PYX_ERR(0, 730, __pyx_L1_error)
+  __pyx_ptype_9pywrapfst_SymbolTableView = &__pyx_type_9pywrapfst_SymbolTableView;
   __pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTableView = &__pyx_vtable_9pywrapfst__EncodeMapperSymbolTableView;
-  __pyx_vtable_9pywrapfst__EncodeMapperSymbolTableView.__pyx_base = *__pyx_vtabptr_9pywrapfst__SymbolTable;
-  __pyx_vtable_9pywrapfst__EncodeMapperSymbolTableView.__pyx_base._raw = (fst::SymbolTable const *(*)(struct __pyx_obj_9pywrapfst__SymbolTable *))__pyx_f_9pywrapfst_28_EncodeMapperSymbolTableView__raw;
-  __pyx_type_9pywrapfst__EncodeMapperSymbolTableView.tp_base = __pyx_ptype_9pywrapfst__SymbolTable;
-  if (PyType_Ready(&__pyx_type_9pywrapfst__EncodeMapperSymbolTableView) < 0) __PYX_ERR(0, 876, __pyx_L1_error)
+  __pyx_vtable_9pywrapfst__EncodeMapperSymbolTableView.__pyx_base = *__pyx_vtabptr_9pywrapfst_SymbolTableView;
+  __pyx_vtable_9pywrapfst__EncodeMapperSymbolTableView.__pyx_base._raw = (fst::SymbolTable const *(*)(struct __pyx_obj_9pywrapfst_SymbolTableView *))__pyx_f_9pywrapfst_28_EncodeMapperSymbolTableView__raw;
+  __pyx_type_9pywrapfst__EncodeMapperSymbolTableView.tp_base = __pyx_ptype_9pywrapfst_SymbolTableView;
+  if (PyType_Ready(&__pyx_type_9pywrapfst__EncodeMapperSymbolTableView) < 0) __PYX_ERR(0, 933, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst__EncodeMapperSymbolTableView.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__EncodeMapperSymbolTableView.tp_dictoffset && __pyx_type_9pywrapfst__EncodeMapperSymbolTableView.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst__EncodeMapperSymbolTableView.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__EncodeMapperSymbolTableView.tp_dict, __pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTableView) < 0) __PYX_ERR(0, 876, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_EncodeMapperSymbolTableView, (PyObject *)&__pyx_type_9pywrapfst__EncodeMapperSymbolTableView) < 0) __PYX_ERR(0, 876, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__EncodeMapperSymbolTableView.tp_dict, __pyx_vtabptr_9pywrapfst__EncodeMapperSymbolTableView) < 0) __PYX_ERR(0, 933, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_EncodeMapperSymbolTableView, (PyObject *)&__pyx_type_9pywrapfst__EncodeMapperSymbolTableView) < 0) __PYX_ERR(0, 933, __pyx_L1_error)
   __pyx_ptype_9pywrapfst__EncodeMapperSymbolTableView = &__pyx_type_9pywrapfst__EncodeMapperSymbolTableView;
   __pyx_vtabptr_9pywrapfst__FstSymbolTableView = &__pyx_vtable_9pywrapfst__FstSymbolTableView;
-  __pyx_vtable_9pywrapfst__FstSymbolTableView.__pyx_base = *__pyx_vtabptr_9pywrapfst__SymbolTable;
-  __pyx_vtable_9pywrapfst__FstSymbolTableView.__pyx_base._raw = (fst::SymbolTable const *(*)(struct __pyx_obj_9pywrapfst__SymbolTable *))__pyx_f_9pywrapfst_19_FstSymbolTableView__raw;
-  __pyx_type_9pywrapfst__FstSymbolTableView.tp_base = __pyx_ptype_9pywrapfst__SymbolTable;
-  if (PyType_Ready(&__pyx_type_9pywrapfst__FstSymbolTableView) < 0) __PYX_ERR(0, 900, __pyx_L1_error)
+  __pyx_vtable_9pywrapfst__FstSymbolTableView.__pyx_base = *__pyx_vtabptr_9pywrapfst_SymbolTableView;
+  __pyx_vtable_9pywrapfst__FstSymbolTableView.__pyx_base._raw = (fst::SymbolTable const *(*)(struct __pyx_obj_9pywrapfst_SymbolTableView *))__pyx_f_9pywrapfst_19_FstSymbolTableView__raw;
+  __pyx_type_9pywrapfst__FstSymbolTableView.tp_base = __pyx_ptype_9pywrapfst_SymbolTableView;
+  if (PyType_Ready(&__pyx_type_9pywrapfst__FstSymbolTableView) < 0) __PYX_ERR(0, 957, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst__FstSymbolTableView.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__FstSymbolTableView.tp_dictoffset && __pyx_type_9pywrapfst__FstSymbolTableView.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst__FstSymbolTableView.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__FstSymbolTableView.tp_dict, __pyx_vtabptr_9pywrapfst__FstSymbolTableView) < 0) __PYX_ERR(0, 900, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FstSymbolTableView, (PyObject *)&__pyx_type_9pywrapfst__FstSymbolTableView) < 0) __PYX_ERR(0, 900, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__FstSymbolTableView.tp_dict, __pyx_vtabptr_9pywrapfst__FstSymbolTableView) < 0) __PYX_ERR(0, 957, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FstSymbolTableView, (PyObject *)&__pyx_type_9pywrapfst__FstSymbolTableView) < 0) __PYX_ERR(0, 957, __pyx_L1_error)
   __pyx_ptype_9pywrapfst__FstSymbolTableView = &__pyx_type_9pywrapfst__FstSymbolTableView;
   __pyx_vtabptr_9pywrapfst__MutableSymbolTable = &__pyx_vtable_9pywrapfst__MutableSymbolTable;
-  __pyx_vtable_9pywrapfst__MutableSymbolTable.__pyx_base = *__pyx_vtabptr_9pywrapfst__SymbolTable;
-  __pyx_vtable_9pywrapfst__MutableSymbolTable.__pyx_base._raw = (fst::SymbolTable const *(*)(struct __pyx_obj_9pywrapfst__SymbolTable *))__pyx_f_9pywrapfst_19_MutableSymbolTable__raw;
+  __pyx_vtable_9pywrapfst__MutableSymbolTable.__pyx_base = *__pyx_vtabptr_9pywrapfst_SymbolTableView;
+  __pyx_vtable_9pywrapfst__MutableSymbolTable.__pyx_base._raw = (fst::SymbolTable const *(*)(struct __pyx_obj_9pywrapfst_SymbolTableView *))__pyx_f_9pywrapfst_19_MutableSymbolTable__raw;
   __pyx_vtable_9pywrapfst__MutableSymbolTable._mutable_raw = (fst::SymbolTable *(*)(struct __pyx_obj_9pywrapfst__MutableSymbolTable *))__pyx_f_9pywrapfst_19_MutableSymbolTable__mutable_raw;
   __pyx_vtable_9pywrapfst__MutableSymbolTable._mutable_raw_ptr_or_raise = (fst::SymbolTable *(*)(struct __pyx_obj_9pywrapfst__MutableSymbolTable *))__pyx_f_9pywrapfst_19_MutableSymbolTable__mutable_raw_ptr_or_raise;
   __pyx_vtable_9pywrapfst__MutableSymbolTable.add_symbol = (int64 (*)(struct __pyx_obj_9pywrapfst__MutableSymbolTable *, PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_19_MutableSymbolTable_add_symbol *__pyx_optional_args))__pyx_f_9pywrapfst_19_MutableSymbolTable_add_symbol;
-  __pyx_vtable_9pywrapfst__MutableSymbolTable.add_table = (void (*)(struct __pyx_obj_9pywrapfst__MutableSymbolTable *, struct __pyx_obj_9pywrapfst__SymbolTable *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19_MutableSymbolTable_add_table;
+  __pyx_vtable_9pywrapfst__MutableSymbolTable.add_table = (void (*)(struct __pyx_obj_9pywrapfst__MutableSymbolTable *, struct __pyx_obj_9pywrapfst_SymbolTableView *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19_MutableSymbolTable_add_table;
   __pyx_vtable_9pywrapfst__MutableSymbolTable.set_name = (void (*)(struct __pyx_obj_9pywrapfst__MutableSymbolTable *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_19_MutableSymbolTable_set_name;
-  __pyx_type_9pywrapfst__MutableSymbolTable.tp_base = __pyx_ptype_9pywrapfst__SymbolTable;
-  if (PyType_Ready(&__pyx_type_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 923, __pyx_L1_error)
+  __pyx_type_9pywrapfst__MutableSymbolTable.tp_base = __pyx_ptype_9pywrapfst_SymbolTableView;
+  if (PyType_Ready(&__pyx_type_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 980, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst__MutableSymbolTable.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__MutableSymbolTable.tp_dictoffset && __pyx_type_9pywrapfst__MutableSymbolTable.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst__MutableSymbolTable.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__MutableSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 923, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableSymbolTable, (PyObject *)&__pyx_type_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 923, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__MutableSymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 980, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableSymbolTable, (PyObject *)&__pyx_type_9pywrapfst__MutableSymbolTable) < 0) __PYX_ERR(0, 980, __pyx_L1_error)
   __pyx_ptype_9pywrapfst__MutableSymbolTable = &__pyx_type_9pywrapfst__MutableSymbolTable;
   __pyx_vtabptr_9pywrapfst__MutableFstSymbolTableView = &__pyx_vtable_9pywrapfst__MutableFstSymbolTableView;
   __pyx_vtable_9pywrapfst__MutableFstSymbolTableView.__pyx_base = *__pyx_vtabptr_9pywrapfst__MutableSymbolTable;
   __pyx_vtable_9pywrapfst__MutableFstSymbolTableView.__pyx_base._mutable_raw = (fst::SymbolTable *(*)(struct __pyx_obj_9pywrapfst__MutableSymbolTable *))__pyx_f_9pywrapfst_26_MutableFstSymbolTableView__mutable_raw;
   __pyx_type_9pywrapfst__MutableFstSymbolTableView.tp_base = __pyx_ptype_9pywrapfst__MutableSymbolTable;
-  if (PyType_Ready(&__pyx_type_9pywrapfst__MutableFstSymbolTableView) < 0) __PYX_ERR(0, 994, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__MutableFstSymbolTableView) < 0) __PYX_ERR(0, 1052, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst__MutableFstSymbolTableView.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__MutableFstSymbolTableView.tp_dictoffset && __pyx_type_9pywrapfst__MutableFstSymbolTableView.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst__MutableFstSymbolTableView.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__MutableFstSymbolTableView.tp_dict, __pyx_vtabptr_9pywrapfst__MutableFstSymbolTableView) < 0) __PYX_ERR(0, 994, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableFstSymbolTableView, (PyObject *)&__pyx_type_9pywrapfst__MutableFstSymbolTableView) < 0) __PYX_ERR(0, 994, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst__MutableFstSymbolTableView.tp_dict, __pyx_vtabptr_9pywrapfst__MutableFstSymbolTableView) < 0) __PYX_ERR(0, 1052, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableFstSymbolTableView, (PyObject *)&__pyx_type_9pywrapfst__MutableFstSymbolTableView) < 0) __PYX_ERR(0, 1052, __pyx_L1_error)
   __pyx_ptype_9pywrapfst__MutableFstSymbolTableView = &__pyx_type_9pywrapfst__MutableFstSymbolTableView;
   __pyx_vtabptr_9pywrapfst_SymbolTable = &__pyx_vtable_9pywrapfst_SymbolTable;
   __pyx_vtable_9pywrapfst_SymbolTable.__pyx_base = *__pyx_vtabptr_9pywrapfst__MutableSymbolTable;
   __pyx_vtable_9pywrapfst_SymbolTable.__pyx_base._mutable_raw = (fst::SymbolTable *(*)(struct __pyx_obj_9pywrapfst__MutableSymbolTable *))__pyx_f_9pywrapfst_11SymbolTable__mutable_raw;
   __pyx_type_9pywrapfst_SymbolTable.tp_base = __pyx_ptype_9pywrapfst__MutableSymbolTable;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 1009, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 1067, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_SymbolTable.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_SymbolTable.tp_dictoffset && __pyx_type_9pywrapfst_SymbolTable.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_SymbolTable.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_SymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 1009, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SymbolTable_2, (PyObject *)&__pyx_type_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 1009, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_SymbolTable.tp_dict, __pyx_vtabptr_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 1067, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SymbolTable_2, (PyObject *)&__pyx_type_9pywrapfst_SymbolTable) < 0) __PYX_ERR(0, 1067, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_SymbolTable = &__pyx_type_9pywrapfst_SymbolTable;
-  if (PyType_Ready(&__pyx_type_9pywrapfst__SymbolTableIterator) < 0) __PYX_ERR(0, 1203, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst__SymbolTableIterator) < 0) __PYX_ERR(0, 1263, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst__SymbolTableIterator.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst__SymbolTableIterator.tp_dictoffset && __pyx_type_9pywrapfst__SymbolTableIterator.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst__SymbolTableIterator.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SymbolTableIterator, (PyObject *)&__pyx_type_9pywrapfst__SymbolTableIterator) < 0) __PYX_ERR(0, 1203, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst__SymbolTableIterator) < 0) __PYX_ERR(0, 1203, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SymbolTableIterator, (PyObject *)&__pyx_type_9pywrapfst__SymbolTableIterator) < 0) __PYX_ERR(0, 1263, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst__SymbolTableIterator) < 0) __PYX_ERR(0, 1263, __pyx_L1_error)
   __pyx_ptype_9pywrapfst__SymbolTableIterator = &__pyx_type_9pywrapfst__SymbolTableIterator;
   __pyx_vtabptr_9pywrapfst_EncodeMapper = &__pyx_vtable_9pywrapfst_EncodeMapper;
   __pyx_vtable_9pywrapfst_EncodeMapper.arc_type = (std::string (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_arc_type;
@@ -51138,9 +51997,9 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_EncodeMapper.write_to_string = (PyObject *(*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_write_to_string;
   __pyx_vtable_9pywrapfst_EncodeMapper.input_symbols = (struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *(*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_input_symbols;
   __pyx_vtable_9pywrapfst_EncodeMapper.output_symbols = (struct __pyx_obj_9pywrapfst__EncodeMapperSymbolTableView *(*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_12EncodeMapper_output_symbols;
-  __pyx_vtable_9pywrapfst_EncodeMapper._set_input_symbols = (void (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, struct __pyx_obj_9pywrapfst__SymbolTable *))__pyx_f_9pywrapfst_12EncodeMapper__set_input_symbols;
-  __pyx_vtable_9pywrapfst_EncodeMapper._set_output_symbols = (void (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, struct __pyx_obj_9pywrapfst__SymbolTable *))__pyx_f_9pywrapfst_12EncodeMapper__set_output_symbols;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1235, __pyx_L1_error)
+  __pyx_vtable_9pywrapfst_EncodeMapper._set_input_symbols = (void (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, struct __pyx_obj_9pywrapfst_SymbolTableView *))__pyx_f_9pywrapfst_12EncodeMapper__set_input_symbols;
+  __pyx_vtable_9pywrapfst_EncodeMapper._set_output_symbols = (void (*)(struct __pyx_obj_9pywrapfst_EncodeMapper *, struct __pyx_obj_9pywrapfst_SymbolTableView *))__pyx_f_9pywrapfst_12EncodeMapper__set_output_symbols;
+  if (PyType_Ready(&__pyx_type_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1295, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_EncodeMapper.tp_print = 0;
   #endif
@@ -51149,7 +52008,7 @@ static int __Pyx_modinit_type_init_code(void) {
   }
   #if CYTHON_COMPILING_IN_CPYTHON
   {
-    PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_9pywrapfst_EncodeMapper, "__call__"); if (unlikely(!wrapper)) __PYX_ERR(0, 1235, __pyx_L1_error)
+    PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_9pywrapfst_EncodeMapper, "__call__"); if (unlikely(!wrapper)) __PYX_ERR(0, 1295, __pyx_L1_error)
     if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
       __pyx_wrapperbase_9pywrapfst_12EncodeMapper_4__call__ = *((PyWrapperDescrObject *)wrapper)->d_base;
       __pyx_wrapperbase_9pywrapfst_12EncodeMapper_4__call__.doc = __pyx_doc_9pywrapfst_12EncodeMapper_4__call__;
@@ -51157,8 +52016,8 @@ static int __Pyx_modinit_type_init_code(void) {
     }
   }
   #endif
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_EncodeMapper.tp_dict, __pyx_vtabptr_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1235, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_EncodeMapper, (PyObject *)&__pyx_type_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1235, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_EncodeMapper.tp_dict, __pyx_vtabptr_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1295, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_EncodeMapper, (PyObject *)&__pyx_type_9pywrapfst_EncodeMapper) < 0) __PYX_ERR(0, 1295, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_EncodeMapper = &__pyx_type_9pywrapfst_EncodeMapper;
   __pyx_vtabptr_9pywrapfst_Fst = &__pyx_vtable_9pywrapfst_Fst;
   __pyx_vtable_9pywrapfst_Fst._local_render_svg = (std::string (*)(std::string const &))__pyx_f_9pywrapfst_3Fst__local_render_svg;
@@ -51177,20 +52036,19 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_Fst.properties = (uint64 (*)(struct __pyx_obj_9pywrapfst_Fst *, uint64, bool, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_properties;
   __pyx_vtable_9pywrapfst_Fst.start = (int64 (*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_start;
   __pyx_vtable_9pywrapfst_Fst.states = (struct __pyx_obj_9pywrapfst_StateIterator *(*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_states;
-  __pyx_vtable_9pywrapfst_Fst.text = (std::string (*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch, struct __pyx_opt_args_9pywrapfst_3Fst_text *__pyx_optional_args))__pyx_f_9pywrapfst_3Fst_text;
   __pyx_vtable_9pywrapfst_Fst.verify = (bool (*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_verify;
   __pyx_vtable_9pywrapfst_Fst.weight_type = (std::string (*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_weight_type;
   __pyx_vtable_9pywrapfst_Fst.write = (void (*)(struct __pyx_obj_9pywrapfst_Fst *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_write;
   __pyx_vtable_9pywrapfst_Fst.write_to_string = (PyObject *(*)(struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Fst_write_to_string;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_Fst) < 0) __PYX_ERR(0, 1501, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_Fst) < 0) __PYX_ERR(0, 1561, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_Fst.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_Fst.tp_dictoffset && __pyx_type_9pywrapfst_Fst.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_Fst.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Fst.tp_dict, __pyx_vtabptr_9pywrapfst_Fst) < 0) __PYX_ERR(0, 1501, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Fst, (PyObject *)&__pyx_type_9pywrapfst_Fst) < 0) __PYX_ERR(0, 1501, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Fst.tp_dict, __pyx_vtabptr_9pywrapfst_Fst) < 0) __PYX_ERR(0, 1561, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Fst, (PyObject *)&__pyx_type_9pywrapfst_Fst) < 0) __PYX_ERR(0, 1561, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_Fst = &__pyx_type_9pywrapfst_Fst;
   __pyx_vtabptr_9pywrapfst_MutableFst = &__pyx_vtable_9pywrapfst_MutableFst;
   __pyx_vtable_9pywrapfst_MutableFst.__pyx_base = *__pyx_vtabptr_9pywrapfst_Fst;
@@ -51210,7 +52068,7 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_MutableFst._minimize = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__minimize *__pyx_optional_args))__pyx_f_9pywrapfst_10MutableFst__minimize;
   __pyx_vtable_9pywrapfst_MutableFst.mutable_arcs = (struct __pyx_obj_9pywrapfst_MutableArcIterator *(*)(struct __pyx_obj_9pywrapfst_MutableFst *, int64, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_10MutableFst_mutable_arcs;
   __pyx_vtable_9pywrapfst_MutableFst.num_states = (int64 (*)(struct __pyx_obj_9pywrapfst_MutableFst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_10MutableFst_num_states;
-  __pyx_vtable_9pywrapfst_MutableFst._project = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__project *__pyx_optional_args))__pyx_f_9pywrapfst_10MutableFst__project;
+  __pyx_vtable_9pywrapfst_MutableFst._project = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, PyObject *))__pyx_f_9pywrapfst_10MutableFst__project;
   __pyx_vtable_9pywrapfst_MutableFst._prune = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__prune *__pyx_optional_args))__pyx_f_9pywrapfst_10MutableFst__prune;
   __pyx_vtable_9pywrapfst_MutableFst._push = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__push *__pyx_optional_args))__pyx_f_9pywrapfst_10MutableFst__push;
   __pyx_vtable_9pywrapfst_MutableFst._relabel_pairs = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_opt_args_9pywrapfst_10MutableFst__relabel_pairs *__pyx_optional_args))__pyx_f_9pywrapfst_10MutableFst__relabel_pairs;
@@ -51222,45 +52080,45 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_MutableFst._set_final = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, int64, struct __pyx_opt_args_9pywrapfst_10MutableFst__set_final *__pyx_optional_args))__pyx_f_9pywrapfst_10MutableFst__set_final;
   __pyx_vtable_9pywrapfst_MutableFst._set_properties = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, uint64, uint64))__pyx_f_9pywrapfst_10MutableFst__set_properties;
   __pyx_vtable_9pywrapfst_MutableFst._set_start = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, int64))__pyx_f_9pywrapfst_10MutableFst__set_start;
-  __pyx_vtable_9pywrapfst_MutableFst._set_input_symbols = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_obj_9pywrapfst__SymbolTable *))__pyx_f_9pywrapfst_10MutableFst__set_input_symbols;
-  __pyx_vtable_9pywrapfst_MutableFst._set_output_symbols = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_obj_9pywrapfst__SymbolTable *))__pyx_f_9pywrapfst_10MutableFst__set_output_symbols;
+  __pyx_vtable_9pywrapfst_MutableFst._set_input_symbols = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_obj_9pywrapfst_SymbolTableView *))__pyx_f_9pywrapfst_10MutableFst__set_input_symbols;
+  __pyx_vtable_9pywrapfst_MutableFst._set_output_symbols = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *, struct __pyx_obj_9pywrapfst_SymbolTableView *))__pyx_f_9pywrapfst_10MutableFst__set_output_symbols;
   __pyx_vtable_9pywrapfst_MutableFst._topsort = (void (*)(struct __pyx_obj_9pywrapfst_MutableFst *))__pyx_f_9pywrapfst_10MutableFst__topsort;
   __pyx_type_9pywrapfst_MutableFst.tp_base = __pyx_ptype_9pywrapfst_Fst;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_MutableFst) < 0) __PYX_ERR(0, 1993, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_MutableFst) < 0) __PYX_ERR(0, 2026, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_MutableFst.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_MutableFst.tp_dictoffset && __pyx_type_9pywrapfst_MutableFst.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_MutableFst.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_MutableFst.tp_dict, __pyx_vtabptr_9pywrapfst_MutableFst) < 0) __PYX_ERR(0, 1993, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableFst, (PyObject *)&__pyx_type_9pywrapfst_MutableFst) < 0) __PYX_ERR(0, 1993, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_MutableFst.tp_dict, __pyx_vtabptr_9pywrapfst_MutableFst) < 0) __PYX_ERR(0, 2026, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableFst, (PyObject *)&__pyx_type_9pywrapfst_MutableFst) < 0) __PYX_ERR(0, 2026, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_MutableFst = &__pyx_type_9pywrapfst_MutableFst;
   __pyx_vtabptr_9pywrapfst_VectorFst = &__pyx_vtable_9pywrapfst_VectorFst;
   __pyx_vtable_9pywrapfst_VectorFst.__pyx_base = *__pyx_vtabptr_9pywrapfst_MutableFst;
   __pyx_type_9pywrapfst_VectorFst.tp_base = __pyx_ptype_9pywrapfst_MutableFst;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_VectorFst) < 0) __PYX_ERR(0, 2863, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_VectorFst) < 0) __PYX_ERR(0, 2891, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_VectorFst.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_VectorFst.tp_dictoffset && __pyx_type_9pywrapfst_VectorFst.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_VectorFst.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_VectorFst.tp_dict, __pyx_vtabptr_9pywrapfst_VectorFst) < 0) __PYX_ERR(0, 2863, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_VectorFst, (PyObject *)&__pyx_type_9pywrapfst_VectorFst) < 0) __PYX_ERR(0, 2863, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_VectorFst.tp_dict, __pyx_vtabptr_9pywrapfst_VectorFst) < 0) __PYX_ERR(0, 2891, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_VectorFst, (PyObject *)&__pyx_type_9pywrapfst_VectorFst) < 0) __PYX_ERR(0, 2891, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_VectorFst = &__pyx_type_9pywrapfst_VectorFst;
   __pyx_vtabptr_9pywrapfst_Arc = &__pyx_vtable_9pywrapfst_Arc;
   __pyx_vtable_9pywrapfst_Arc.copy = (struct __pyx_obj_9pywrapfst_Arc *(*)(struct __pyx_obj_9pywrapfst_Arc *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_3Arc_copy;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 3039, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 3068, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_Arc.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_Arc.tp_dictoffset && __pyx_type_9pywrapfst_Arc.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_Arc.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Arc.tp_dict, __pyx_vtabptr_9pywrapfst_Arc) < 0) __PYX_ERR(0, 3039, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Arc, (PyObject *)&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 3039, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 3039, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Arc.tp_dict, __pyx_vtabptr_9pywrapfst_Arc) < 0) __PYX_ERR(0, 3068, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Arc, (PyObject *)&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 3068, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Arc) < 0) __PYX_ERR(0, 3068, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_Arc = &__pyx_type_9pywrapfst_Arc;
   __pyx_vtabptr_9pywrapfst_ArcIterator = &__pyx_vtable_9pywrapfst_ArcIterator;
   __pyx_vtable_9pywrapfst_ArcIterator.done = (bool (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_done;
@@ -51271,16 +52129,16 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_ArcIterator.seek = (void (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, size_t, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_seek;
   __pyx_vtable_9pywrapfst_ArcIterator.set_flags = (void (*)(struct __pyx_obj_9pywrapfst_ArcIterator *, uint8, uint8, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_set_flags;
   __pyx_vtable_9pywrapfst_ArcIterator.value = (PyObject *(*)(struct __pyx_obj_9pywrapfst_ArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_11ArcIterator_value;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 3106, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 3135, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_ArcIterator.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_ArcIterator.tp_dictoffset && __pyx_type_9pywrapfst_ArcIterator.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_ArcIterator.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_ArcIterator.tp_dict, __pyx_vtabptr_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 3106, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_ArcIterator, (PyObject *)&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 3106, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 3106, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_ArcIterator.tp_dict, __pyx_vtabptr_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 3135, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_ArcIterator, (PyObject *)&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 3135, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_ArcIterator) < 0) __PYX_ERR(0, 3135, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_ArcIterator = &__pyx_type_9pywrapfst_ArcIterator;
   __pyx_vtabptr_9pywrapfst_MutableArcIterator = &__pyx_vtable_9pywrapfst_MutableArcIterator;
   __pyx_vtable_9pywrapfst_MutableArcIterator.done = (bool (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_done;
@@ -51292,46 +52150,46 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_MutableArcIterator.set_flags = (void (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, uint8, uint8, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_set_flags;
   __pyx_vtable_9pywrapfst_MutableArcIterator.set_value = (void (*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, struct __pyx_obj_9pywrapfst_Arc *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_set_value;
   __pyx_vtable_9pywrapfst_MutableArcIterator.value = (PyObject *(*)(struct __pyx_obj_9pywrapfst_MutableArcIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_18MutableArcIterator_value;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3217, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3246, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_MutableArcIterator.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_MutableArcIterator.tp_dictoffset && __pyx_type_9pywrapfst_MutableArcIterator.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_MutableArcIterator.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_MutableArcIterator.tp_dict, __pyx_vtabptr_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3217, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableArcIterator, (PyObject *)&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3217, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3217, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_MutableArcIterator.tp_dict, __pyx_vtabptr_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3246, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_MutableArcIterator, (PyObject *)&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3246, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_MutableArcIterator) < 0) __PYX_ERR(0, 3246, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_MutableArcIterator = &__pyx_type_9pywrapfst_MutableArcIterator;
   __pyx_vtabptr_9pywrapfst_StateIterator = &__pyx_vtable_9pywrapfst_StateIterator;
   __pyx_vtable_9pywrapfst_StateIterator.done = (bool (*)(struct __pyx_obj_9pywrapfst_StateIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_13StateIterator_done;
   __pyx_vtable_9pywrapfst_StateIterator.next = (void (*)(struct __pyx_obj_9pywrapfst_StateIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_13StateIterator_next;
   __pyx_vtable_9pywrapfst_StateIterator.reset = (void (*)(struct __pyx_obj_9pywrapfst_StateIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_13StateIterator_reset;
   __pyx_vtable_9pywrapfst_StateIterator.value = (int64 (*)(struct __pyx_obj_9pywrapfst_StateIterator *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_13StateIterator_value;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3337, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3366, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_StateIterator.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_StateIterator.tp_dictoffset && __pyx_type_9pywrapfst_StateIterator.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_StateIterator.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_StateIterator.tp_dict, __pyx_vtabptr_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3337, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_StateIterator, (PyObject *)&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3337, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3337, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_StateIterator.tp_dict, __pyx_vtabptr_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3366, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_StateIterator, (PyObject *)&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3366, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_StateIterator) < 0) __PYX_ERR(0, 3366, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_StateIterator = &__pyx_type_9pywrapfst_StateIterator;
   __pyx_vtabptr_9pywrapfst_Compiler = &__pyx_vtable_9pywrapfst_Compiler;
   __pyx_vtable_9pywrapfst_Compiler.compile = (struct __pyx_obj_9pywrapfst_Fst *(*)(struct __pyx_obj_9pywrapfst_Compiler *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_8Compiler_compile;
   __pyx_vtable_9pywrapfst_Compiler.write = (void (*)(struct __pyx_obj_9pywrapfst_Compiler *, PyObject *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_8Compiler_write;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4242, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4275, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_Compiler.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_Compiler.tp_dictoffset && __pyx_type_9pywrapfst_Compiler.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_Compiler.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Compiler.tp_dict, __pyx_vtabptr_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4242, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Compiler, (PyObject *)&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4242, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4242, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_Compiler.tp_dict, __pyx_vtabptr_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4275, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Compiler, (PyObject *)&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4275, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_Compiler) < 0) __PYX_ERR(0, 4275, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_Compiler = &__pyx_type_9pywrapfst_Compiler;
   __pyx_vtabptr_9pywrapfst_FarReader = &__pyx_vtable_9pywrapfst_FarReader;
   __pyx_vtable_9pywrapfst_FarReader.arc_type = (std::string (*)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarReader_arc_type;
@@ -51343,16 +52201,16 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_FarReader.get_key = (std::string (*)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarReader_get_key;
   __pyx_vtable_9pywrapfst_FarReader.next = (void (*)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarReader_next;
   __pyx_vtable_9pywrapfst_FarReader.reset = (void (*)(struct __pyx_obj_9pywrapfst_FarReader *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarReader_reset;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4379, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4412, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_FarReader.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_FarReader.tp_dictoffset && __pyx_type_9pywrapfst_FarReader.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_FarReader.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_FarReader.tp_dict, __pyx_vtabptr_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4379, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FarReader, (PyObject *)&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4379, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4379, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_FarReader.tp_dict, __pyx_vtabptr_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4412, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FarReader, (PyObject *)&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4412, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_FarReader) < 0) __PYX_ERR(0, 4412, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_FarReader = &__pyx_type_9pywrapfst_FarReader;
   __pyx_vtabptr_9pywrapfst_FarWriter = &__pyx_vtable_9pywrapfst_FarWriter;
   __pyx_vtable_9pywrapfst_FarWriter.arc_type = (std::string (*)(struct __pyx_obj_9pywrapfst_FarWriter *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarWriter_arc_type;
@@ -51360,18 +52218,18 @@ static int __Pyx_modinit_type_init_code(void) {
   __pyx_vtable_9pywrapfst_FarWriter.add = (void (*)(struct __pyx_obj_9pywrapfst_FarWriter *, PyObject *, struct __pyx_obj_9pywrapfst_Fst *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarWriter_add;
   __pyx_vtable_9pywrapfst_FarWriter.error = (bool (*)(struct __pyx_obj_9pywrapfst_FarWriter *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarWriter_error;
   __pyx_vtable_9pywrapfst_FarWriter.far_type = (std::string (*)(struct __pyx_obj_9pywrapfst_FarWriter *, int __pyx_skip_dispatch))__pyx_f_9pywrapfst_9FarWriter_far_type;
-  if (PyType_Ready(&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4525, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4567, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst_FarWriter.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_9pywrapfst_FarWriter.tp_dictoffset && __pyx_type_9pywrapfst_FarWriter.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_9pywrapfst_FarWriter.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_FarWriter.tp_dict, __pyx_vtabptr_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4525, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FarWriter, (PyObject *)&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4525, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4525, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_9pywrapfst_FarWriter.tp_dict, __pyx_vtabptr_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4567, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FarWriter, (PyObject *)&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4567, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_9pywrapfst_FarWriter) < 0) __PYX_ERR(0, 4567, __pyx_L1_error)
   __pyx_ptype_9pywrapfst_FarWriter = &__pyx_type_9pywrapfst_FarWriter;
-  if (PyType_Ready(&__pyx_type_9pywrapfst___pyx_scope_struct____iter__) < 0) __PYX_ERR(0, 3237, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_9pywrapfst___pyx_scope_struct____iter__) < 0) __PYX_ERR(0, 3266, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_9pywrapfst___pyx_scope_struct____iter__.tp_print = 0;
   #endif
@@ -51411,17 +52269,19 @@ static int __Pyx_modinit_function_import_code(void) {
 }
 
 
-#if PY_MAJOR_VERSION < 3
-#ifdef CYTHON_NO_PYINIT_EXPORT
-#define __Pyx_PyMODINIT_FUNC void
-#else
+#ifndef CYTHON_NO_PYINIT_EXPORT
 #define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC
+#elif PY_MAJOR_VERSION < 3
+#ifdef __cplusplus
+#define __Pyx_PyMODINIT_FUNC extern "C" void
+#else
+#define __Pyx_PyMODINIT_FUNC void
 #endif
 #else
-#ifdef CYTHON_NO_PYINIT_EXPORT
-#define __Pyx_PyMODINIT_FUNC PyObject *
+#ifdef __cplusplus
+#define __Pyx_PyMODINIT_FUNC extern "C" PyObject *
 #else
-#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC
+#define __Pyx_PyMODINIT_FUNC PyObject *
 #endif
 #endif
 
@@ -51506,7 +52366,9 @@ static CYTHON_SMALL_CODE int __pyx_pymod_exec_pywrapfst(PyObject *__pyx_pyinit_m
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
-  std::string __pyx_t_5;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   __Pyx_RefNannyDeclarations
   #if CYTHON_PEP489_MULTI_PHASE_INIT
   if (__pyx_m) {
@@ -51595,14 +52457,14 @@ if (!__Pyx_RefNanny) {
   }
   #endif
   /*--- Builtin init code ---*/
-  if (__Pyx_InitCachedBuiltins() < 0) goto __pyx_L1_error;
+  if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   /*--- Constants init code ---*/
-  if (__Pyx_InitCachedConstants() < 0) goto __pyx_L1_error;
+  if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   /*--- Global type/function init code ---*/
   (void)__Pyx_modinit_global_init_code();
   (void)__Pyx_modinit_variable_export_code();
-  if (unlikely(__Pyx_modinit_function_export_code() != 0)) goto __pyx_L1_error;
-  if (unlikely(__Pyx_modinit_type_init_code() != 0)) goto __pyx_L1_error;
+  if (unlikely(__Pyx_modinit_function_export_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error)
+  if (unlikely(__Pyx_modinit_type_init_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error)
   (void)__Pyx_modinit_type_import_code();
   (void)__Pyx_modinit_variable_import_code();
   (void)__Pyx_modinit_function_import_code();
@@ -51616,7 +52478,7 @@ if (!__Pyx_RefNanny) {
  * # Python imports.
  * import logging             # <<<<<<<<<<<<<<
  * import numbers
- * import subprocess
+ * import os
  */
   __pyx_t_1 = __Pyx_Import(__pyx_n_s_logging, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 99, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
@@ -51627,8 +52489,8 @@ if (!__Pyx_RefNanny) {
  * # Python imports.
  * import logging
  * import numbers             # <<<<<<<<<<<<<<
+ * import os
  * import subprocess
- * 
  */
   __pyx_t_1 = __Pyx_Import(__pyx_n_s_numbers, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 100, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
@@ -51638,78 +52500,193 @@ if (!__Pyx_RefNanny) {
   /* "pywrapfst.pyx":101
  * import logging
  * import numbers
- * import subprocess             # <<<<<<<<<<<<<<
- * 
- * # TODO(kbg): Used to handle the deprecation of `text`; remove on next release.
+ * import os             # <<<<<<<<<<<<<<
+ * import subprocess
+ * import sys
  */
-  __pyx_t_1 = __Pyx_Import(__pyx_n_s_subprocess, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 101, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_os, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 101, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_subprocess, __pyx_t_1) < 0) __PYX_ERR(0, 101, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_os, __pyx_t_1) < 0) __PYX_ERR(0, 101, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":104
- * 
- * # TODO(kbg): Used to handle the deprecation of `text`; remove on next release.
- * import warnings             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":102
+ * import numbers
+ * import os
+ * import subprocess             # <<<<<<<<<<<<<<
+ * import sys
  * 
- * warnings.simplefilter("always", DeprecationWarning)
  */
-  __pyx_t_1 = __Pyx_Import(__pyx_n_s_warnings, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 104, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_subprocess, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 102, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_warnings, __pyx_t_1) < 0) __PYX_ERR(0, 104, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_subprocess, __pyx_t_1) < 0) __PYX_ERR(0, 102, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":106
- * import warnings
- * 
- * warnings.simplefilter("always", DeprecationWarning)             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":103
+ * import os
+ * import subprocess
+ * import sys             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_warnings); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 106, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_sys, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 103, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_simplefilter); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 106, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_sys, __pyx_t_1) < 0) __PYX_ERR(0, 103, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__59, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 106, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":110
+ * # These defintions only ensure that these are defined to avoid attribute errors,
+ * # but don't actually contain the type definitions. Those are in _pywrapfst.pyi.
+ * import typing             # <<<<<<<<<<<<<<
+ * 
+ * ArcMapType = """typing.Literal["identity", "input_epsilon", "invert",
+ */
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_typing, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 110, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_typing, __pyx_t_1) < 0) __PYX_ERR(0, 110, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
   /* "pywrapfst.pyx":112
+ * import typing
+ * 
+ * ArcMapType = """typing.Literal["identity", "input_epsilon", "invert",             # <<<<<<<<<<<<<<
+ *                                "output_epsilon", "plus", "power", "quantize",
+ *                                "rmweight", "superfinal", "times", "to_log",
+ */
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ArcMapType, __pyx_kp_u_typing_Literal_identity_input_ep) < 0) __PYX_ERR(0, 112, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":117
+ *                                # NOTE: Both spellings of "to_std"
+ *                                "to_log64", "to_std", "to_standard"]"""
+ * ComposeFilter = """typing.Literal["alt_sequence", "auto", "match", "no_match",             # <<<<<<<<<<<<<<
+ *                            "null", "sequence", "trivial"]"""
+ * DeterminizeType = """typing.Literal["functional", "nonfunctional",
+ */
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ComposeFilter, __pyx_kp_u_typing_Literal_alt_sequence_auto) < 0) __PYX_ERR(0, 117, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":119
+ * ComposeFilter = """typing.Literal["alt_sequence", "auto", "match", "no_match",
+ *                            "null", "sequence", "trivial"]"""
+ * DeterminizeType = """typing.Literal["functional", "nonfunctional",             # <<<<<<<<<<<<<<
+ *                                     "disambiguate"]"""
+ * DrawFloatFormat = """typing.Literal["e", "f", "g"]"""
+ */
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_DeterminizeType, __pyx_kp_u_typing_Literal_functional_nonfun) < 0) __PYX_ERR(0, 119, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":121
+ * DeterminizeType = """typing.Literal["functional", "nonfunctional",
+ *                                     "disambiguate"]"""
+ * DrawFloatFormat = """typing.Literal["e", "f", "g"]"""             # <<<<<<<<<<<<<<
+ * FarType = """typing.Literal[
+ *   "fst",
+ */
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_DrawFloatFormat, __pyx_kp_u_typing_Literal_e_f_g) < 0) __PYX_ERR(0, 121, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":122
+ *                                     "disambiguate"]"""
+ * DrawFloatFormat = """typing.Literal["e", "f", "g"]"""
+ * FarType = """typing.Literal[             # <<<<<<<<<<<<<<
+ *   "fst",
+ *   "stlist",
+ */
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FarType, __pyx_kp_u_typing_Literal_fst_stlist_sttabl) < 0) __PYX_ERR(0, 122, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":128
+ *   "default"
+ * ]"""
+ * ProjectType = """typing.Literal["input", "output"]"""             # <<<<<<<<<<<<<<
+ * QueueType = """typing.Literal["auto", "fifo", "lifo", "shortest", "state",
+ *                               "top"]"""
+ */
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ProjectType, __pyx_kp_u_typing_Literal_input_output) < 0) __PYX_ERR(0, 128, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":129
+ * ]"""
+ * ProjectType = """typing.Literal["input", "output"]"""
+ * QueueType = """typing.Literal["auto", "fifo", "lifo", "shortest", "state",             # <<<<<<<<<<<<<<
+ *                               "top"]"""
+ * RandArcSelection = """typing.Literal["uniform", "log_prob", "fast_log_prob"]"""
+ */
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_QueueType, __pyx_kp_u_typing_Literal_auto_fifo_lifo_sh) < 0) __PYX_ERR(0, 129, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":131
+ * QueueType = """typing.Literal["auto", "fifo", "lifo", "shortest", "state",
+ *                               "top"]"""
+ * RandArcSelection = """typing.Literal["uniform", "log_prob", "fast_log_prob"]"""             # <<<<<<<<<<<<<<
+ * ReplaceLabelType = """typing.Literal["neither", "input", "output", "both"]"""
+ * SortType = """typing.Literal["ilabel", "olabel"]"""
+ */
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_RandArcSelection, __pyx_kp_u_typing_Literal_uniform_log_prob) < 0) __PYX_ERR(0, 131, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":132
+ *                               "top"]"""
+ * RandArcSelection = """typing.Literal["uniform", "log_prob", "fast_log_prob"]"""
+ * ReplaceLabelType = """typing.Literal["neither", "input", "output", "both"]"""             # <<<<<<<<<<<<<<
+ * SortType = """typing.Literal["ilabel", "olabel"]"""
+ * StateMapType = """typing.Literal["arc_sum", "arc_unique", "identity"]"""
+ */
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ReplaceLabelType, __pyx_kp_u_typing_Literal_neither_input_out) < 0) __PYX_ERR(0, 132, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":133
+ * RandArcSelection = """typing.Literal["uniform", "log_prob", "fast_log_prob"]"""
+ * ReplaceLabelType = """typing.Literal["neither", "input", "output", "both"]"""
+ * SortType = """typing.Literal["ilabel", "olabel"]"""             # <<<<<<<<<<<<<<
+ * StateMapType = """typing.Literal["arc_sum", "arc_unique", "identity"]"""
+ * 
+ */
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SortType, __pyx_kp_u_typing_Literal_ilabel_olabel) < 0) __PYX_ERR(0, 133, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":134
+ * ReplaceLabelType = """typing.Literal["neither", "input", "output", "both"]"""
+ * SortType = """typing.Literal["ilabel", "olabel"]"""
+ * StateMapType = """typing.Literal["arc_sum", "arc_unique", "identity"]"""             # <<<<<<<<<<<<<<
+ * 
+ * WeightLike = "typing.Union[Weight, typing.Union[str, int, float]]"
+ */
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_StateMapType, __pyx_kp_u_typing_Literal_arc_sum_arc_uniqu) < 0) __PYX_ERR(0, 134, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":136
+ * StateMapType = """typing.Literal["arc_sum", "arc_unique", "identity"]"""
+ * 
+ * WeightLike = "typing.Union[Weight, typing.Union[str, int, float]]"             # <<<<<<<<<<<<<<
+ * 
+ * ## Custom exceptions.
+ */
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WeightLike, __pyx_kp_u_typing_Union_Weight_typing_Union) < 0) __PYX_ERR(0, 136, __pyx_L1_error)
+
+  /* "pywrapfst.pyx":141
  * 
  * 
  * class FstError(Exception):             # <<<<<<<<<<<<<<
  * 
  *   pass
  */
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 112, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 141, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
   __Pyx_GIVEREF(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
   PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
-  __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 112, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 141, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_FstError, __pyx_n_s_FstError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 112, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_FstError, __pyx_n_s_FstError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 141, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_FstError, __pyx_t_1, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 112, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_FstError, __pyx_t_1, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 141, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstError, __pyx_t_4) < 0) __PYX_ERR(0, 112, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstError, __pyx_t_4) < 0) __PYX_ERR(0, 141, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":117
+  /* "pywrapfst.pyx":146
  * 
  * 
  * class FstArgError(FstError, ValueError):             # <<<<<<<<<<<<<<
  * 
  *   pass
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FstError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 117, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FstError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 146, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 117, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 146, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
@@ -51717,28 +52694,28 @@ if (!__Pyx_RefNanny) {
   __Pyx_GIVEREF(__pyx_builtin_ValueError);
   PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_builtin_ValueError);
   __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 117, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 146, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_FstArgError, __pyx_n_s_FstArgError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 117, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_FstArgError, __pyx_n_s_FstArgError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 146, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_FstArgError, __pyx_t_2, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 117, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_FstArgError, __pyx_t_2, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 146, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstArgError, __pyx_t_4) < 0) __PYX_ERR(0, 117, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstArgError, __pyx_t_4) < 0) __PYX_ERR(0, 146, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":122
+  /* "pywrapfst.pyx":151
  * 
  * 
  * class FstBadWeightError(FstError, ValueError):             # <<<<<<<<<<<<<<
  * 
  *   pass
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 122, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 151, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 122, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 151, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
@@ -51746,1787 +52723,1738 @@ if (!__Pyx_RefNanny) {
   __Pyx_GIVEREF(__pyx_builtin_ValueError);
   PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_builtin_ValueError);
   __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 122, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 151, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_FstBadWeightError, __pyx_n_s_FstBadWeightError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 122, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_FstBadWeightError, __pyx_n_s_FstBadWeightError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 151, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_FstBadWeightError, __pyx_t_1, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 122, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_FstBadWeightError, __pyx_t_1, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 151, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstBadWeightError, __pyx_t_4) < 0) __PYX_ERR(0, 122, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstBadWeightError, __pyx_t_4) < 0) __PYX_ERR(0, 151, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":127
+  /* "pywrapfst.pyx":156
  * 
  * 
- * class FstDeletedConstructorError(FstError, RuntimeError):             # <<<<<<<<<<<<<<
+ * class FstIndexError(FstError, IndexError):             # <<<<<<<<<<<<<<
  * 
  *   pass
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FstError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 127, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FstError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 156, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 127, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 156, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
-  __Pyx_INCREF(__pyx_builtin_RuntimeError);
-  __Pyx_GIVEREF(__pyx_builtin_RuntimeError);
-  PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_builtin_RuntimeError);
+  __Pyx_INCREF(__pyx_builtin_IndexError);
+  __Pyx_GIVEREF(__pyx_builtin_IndexError);
+  PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_builtin_IndexError);
   __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 127, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 156, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_FstDeletedConstructorError, __pyx_n_s_FstDeletedConstructorError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 127, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_FstIndexError, __pyx_n_s_FstIndexError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 156, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_FstDeletedConstructorError, __pyx_t_2, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 127, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_FstIndexError, __pyx_t_2, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 156, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstDeletedConstructorError, __pyx_t_4) < 0) __PYX_ERR(0, 127, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstIndexError, __pyx_t_4) < 0) __PYX_ERR(0, 156, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":132
+  /* "pywrapfst.pyx":161
  * 
  * 
- * class FstIndexError(FstError, IndexError):             # <<<<<<<<<<<<<<
+ * class FstIOError(FstError, IOError):             # <<<<<<<<<<<<<<
  * 
  *   pass
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 132, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 161, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 132, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 161, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
-  __Pyx_INCREF(__pyx_builtin_IndexError);
-  __Pyx_GIVEREF(__pyx_builtin_IndexError);
-  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_builtin_IndexError);
+  __Pyx_INCREF(__pyx_builtin_IOError);
+  __Pyx_GIVEREF(__pyx_builtin_IOError);
+  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_builtin_IOError);
   __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 132, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 161, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_FstIndexError, __pyx_n_s_FstIndexError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 132, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_FstIOError, __pyx_n_s_FstIOError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 161, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_FstIndexError, __pyx_t_1, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 132, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_FstIOError, __pyx_t_1, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 161, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstIndexError, __pyx_t_4) < 0) __PYX_ERR(0, 132, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstIOError, __pyx_t_4) < 0) __PYX_ERR(0, 161, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":137
+  /* "pywrapfst.pyx":166
  * 
  * 
- * class FstIOError(FstError, IOError):             # <<<<<<<<<<<<<<
+ * class FstOpError(FstError, RuntimeError):             # <<<<<<<<<<<<<<
  * 
  *   pass
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FstError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 137, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FstError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 166, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 137, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 166, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_1);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
-  __Pyx_INCREF(__pyx_builtin_IOError);
-  __Pyx_GIVEREF(__pyx_builtin_IOError);
-  PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_builtin_IOError);
+  __Pyx_INCREF(__pyx_builtin_RuntimeError);
+  __Pyx_GIVEREF(__pyx_builtin_RuntimeError);
+  PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_builtin_RuntimeError);
   __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 137, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 166, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_FstIOError, __pyx_n_s_FstIOError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 137, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_FstOpError, __pyx_n_s_FstOpError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 166, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_FstIOError, __pyx_t_2, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 137, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_FstOpError, __pyx_t_2, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 166, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstIOError, __pyx_t_4) < 0) __PYX_ERR(0, 137, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstOpError, __pyx_t_4) < 0) __PYX_ERR(0, 166, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":142
- * 
- * 
- * class FstOpError(FstError, RuntimeError):             # <<<<<<<<<<<<<<
- * 
- *   pass
- */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FstError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 142, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 142, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_2);
-  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
-  __Pyx_INCREF(__pyx_builtin_RuntimeError);
-  __Pyx_GIVEREF(__pyx_builtin_RuntimeError);
-  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_builtin_RuntimeError);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 142, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_FstOpError, __pyx_n_s_FstOpError, (PyObject *) NULL, __pyx_n_s_pywrapfst_2, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 142, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_FstOpError, __pyx_t_1, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 142, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FstOpError, __pyx_t_4) < 0) __PYX_ERR(0, 142, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
-  /* "pywrapfst.pyx":397
+  /* "pywrapfst.pyx":460
  * 
  *   @classmethod
  *   def Zero(cls, weight_type):             # <<<<<<<<<<<<<<
  *     """
  *     Weight.Zero(weight_type)
  */
-  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_Weight, __pyx_n_s_Zero); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 397, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_Weight, __pyx_n_s_Zero); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 460, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":396
+  /* "pywrapfst.pyx":459
  *   # C++ part out-of-class and then call it from within.
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def Zero(cls, weight_type):
  *     """
  */
-  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 396, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Weight->tp_dict, __pyx_n_s_Zero, __pyx_t_2) < 0) __PYX_ERR(0, 397, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 459, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Weight->tp_dict, __pyx_n_s_Zero, __pyx_t_1) < 0) __PYX_ERR(0, 460, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_Weight);
 
-  /* "pywrapfst.pyx":406
+  /* "pywrapfst.pyx":469
  * 
  *   @classmethod
  *   def One(cls, weight_type):             # <<<<<<<<<<<<<<
  *     """
  *     Weight.One(weight_type)
  */
-  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_Weight, __pyx_n_s_One); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 406, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_Weight, __pyx_n_s_One); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 469, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
 
-  /* "pywrapfst.pyx":405
+  /* "pywrapfst.pyx":468
  *     return _Zero(weight_type)
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def One(cls, weight_type):
  *     """
  */
-  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 405, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Weight->tp_dict, __pyx_n_s_One, __pyx_t_1) < 0) __PYX_ERR(0, 406, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 468, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Weight->tp_dict, __pyx_n_s_One, __pyx_t_2) < 0) __PYX_ERR(0, 469, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_Weight);
 
-  /* "pywrapfst.pyx":415
+  /* "pywrapfst.pyx":478
  * 
  *   @classmethod
  *   def NoWeight(cls, weight_type):             # <<<<<<<<<<<<<<
  *     """
  *     Weight.NoWeight(weight_type)
  */
-  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_Weight, __pyx_n_s_NoWeight); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 415, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_Weight, __pyx_n_s_NoWeight); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 478, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":414
+  /* "pywrapfst.pyx":477
  *     return _One(weight_type)
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def NoWeight(cls, weight_type):
  *     """
  */
-  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 414, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Weight->tp_dict, __pyx_n_s_NoWeight, __pyx_t_2) < 0) __PYX_ERR(0, 415, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 477, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Weight->tp_dict, __pyx_n_s_NoWeight, __pyx_t_1) < 0) __PYX_ERR(0, 478, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_Weight);
 
-  /* "pywrapfst.pyx":450
+  /* "pywrapfst.pyx":513
  * 
  * 
  * def plus(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
  *   """
  *   plus(lhs, rhs)
  */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_1plus, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 450, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_plus, __pyx_t_2) < 0) __PYX_ERR(0, 450, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_1plus, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 513, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_plus, __pyx_t_1) < 0) __PYX_ERR(0, 513, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":482
+  /* "pywrapfst.pyx":545
  * 
  * 
  * def times(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
  *   """
  *   times(lhs, rhs)
  */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_3times, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 482, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_times, __pyx_t_2) < 0) __PYX_ERR(0, 482, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_3times, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 545, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_times, __pyx_t_1) < 0) __PYX_ERR(0, 545, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":514
+  /* "pywrapfst.pyx":577
  * 
  * 
  * def divide(Weight lhs, Weight rhs):             # <<<<<<<<<<<<<<
  *   """
  *   divide(lhs, rhs)
  */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_5divide, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 514, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_divide, __pyx_t_2) < 0) __PYX_ERR(0, 514, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_5divide, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 577, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_divide, __pyx_t_1) < 0) __PYX_ERR(0, 577, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":547
+  /* "pywrapfst.pyx":610
  * 
  * 
  * def power(Weight w, size_t n):             # <<<<<<<<<<<<<<
  *   """
  *   power(lhs, rhs)
  */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_7power, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 547, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_power, __pyx_t_2) < 0) __PYX_ERR(0, 547, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_7power, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 610, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_power, __pyx_t_1) < 0) __PYX_ERR(0, 610, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pywrapfst.pyx":952
+  /* "pywrapfst.pyx":1009
  *     return mutable_raw
  * 
  *   cpdef int64 add_symbol(self, symbol, int64 key=fst.kNoSymbol) except *:             # <<<<<<<<<<<<<<
  *     """
  *     add_symbol(self, symbol, key=NO_SYMBOL)
  */
-  __pyx_k__3 = fst::kNoSymbol;
-  __pyx_k__3 = fst::kNoSymbol;
+  __pyx_k__6 = fst::kNoSymbol;
+  __pyx_k__6 = fst::kNoSymbol;
 
-  /* "pywrapfst.pyx":1036
+  /* "pywrapfst.pyx":1094
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
  *     """
  *     SymbolTable.read(source)
  */
-  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1036, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1094, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
 
-  /* "pywrapfst.pyx":1035
+  /* "pywrapfst.pyx":1093
  *     return self._smart_table.get()
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def read(cls, source):
  *     """
  */
-  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1035, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable->tp_dict, __pyx_n_s_read, __pyx_t_1) < 0) __PYX_ERR(0, 1036, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1093, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable->tp_dict, __pyx_n_s_read, __pyx_t_2) < 0) __PYX_ERR(0, 1094, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_SymbolTable);
 
-  /* "pywrapfst.pyx":1057
+  /* "pywrapfst.pyx":1115
  * 
  *   @classmethod
  *   def read_text(cls, source, bool allow_negative_labels=False):             # <<<<<<<<<<<<<<
  *     """
  *     SymbolTable.read_text(source)
  */
-  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read_text); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1057, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read_text); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1115, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":1056
- *     return _init_SymbolTable(move(syms))
+  /* "pywrapfst.pyx":1114
+ *     return _init_SymbolTable(move(_symbols))
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def read_text(cls, source, bool allow_negative_labels=False):
  *     """
  */
-  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1056, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable->tp_dict, __pyx_n_s_read_text, __pyx_t_2) < 0) __PYX_ERR(0, 1057, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1114, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable->tp_dict, __pyx_n_s_read_text, __pyx_t_1) < 0) __PYX_ERR(0, 1115, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_SymbolTable);
 
-  /* "pywrapfst.pyx":1082
+  /* "pywrapfst.pyx":1141
  * 
  *   @classmethod
  *   def read_fst(cls, source, bool input_table):             # <<<<<<<<<<<<<<
  *     """
  *     SymbolTable.read_fst(source, input_table)
  */
-  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read_fst); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1082, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_SymbolTable, __pyx_n_s_read_fst); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1141, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
 
-  /* "pywrapfst.pyx":1081
- *     return _init_SymbolTable(move(syms))
+  /* "pywrapfst.pyx":1140
+ *     return _init_SymbolTable(move(_symbols))
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def read_fst(cls, source, bool input_table):
  *     """
  */
-  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1081, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable->tp_dict, __pyx_n_s_read_fst, __pyx_t_1) < 0) __PYX_ERR(0, 1082, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1140, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_SymbolTable->tp_dict, __pyx_n_s_read_fst, __pyx_t_2) < 0) __PYX_ERR(0, 1141, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_SymbolTable);
 
-  /* "pywrapfst.pyx":1337
+  /* "pywrapfst.pyx":1397
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
  *     """
  *     EncodeMapper.read(source)
  */
-  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper, __pyx_n_s_read); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1337, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper, __pyx_n_s_read); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1397, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":1336
+  /* "pywrapfst.pyx":1396
  *     return self._mapper.get().Properties(mask)
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def read(cls, source):
  *     """
  */
-  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1336, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper->tp_dict, __pyx_n_s_read, __pyx_t_2) < 0) __PYX_ERR(0, 1337, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1396, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper->tp_dict, __pyx_n_s_read, __pyx_t_1) < 0) __PYX_ERR(0, 1397, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_EncodeMapper);
 
-  /* "pywrapfst.pyx":1359
+  /* "pywrapfst.pyx":1419
  * 
  *   @staticmethod
  *   def read_from_string(state):             # <<<<<<<<<<<<<<
  *     """
  *     read_from_string(state)
  */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_12EncodeMapper_19read_from_string, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1359, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper->tp_dict, __pyx_n_s_read_from_string, __pyx_t_2) < 0) __PYX_ERR(0, 1359, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_12EncodeMapper_19read_from_string, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1419, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper->tp_dict, __pyx_n_s_read_from_string, __pyx_t_1) < 0) __PYX_ERR(0, 1419, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_EncodeMapper);
 
-  /* "pywrapfst.pyx":1358
- *     return _init_EncodeMapper(mapper.release())
+  /* "pywrapfst.pyx":1418
+ *     return _init_EncodeMapper(_mapper.release())
  * 
  *   @staticmethod             # <<<<<<<<<<<<<<
  *   def read_from_string(state):
  *     """
  */
-  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper, __pyx_n_s_read_from_string); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1359, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_staticmethod, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1358, __pyx_L1_error)
+  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper, __pyx_n_s_read_from_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1419, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper->tp_dict, __pyx_n_s_read_from_string, __pyx_t_1) < 0) __PYX_ERR(0, 1359, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_staticmethod, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1418, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_EncodeMapper->tp_dict, __pyx_n_s_read_from_string, __pyx_t_2) < 0) __PYX_ERR(0, 1419, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_EncodeMapper);
 
-  /* "pywrapfst.pyx":1844
+  /* "pywrapfst.pyx":1915
  * 
  *   @classmethod
  *   def read(cls, source):             # <<<<<<<<<<<<<<
  *     """
  *     read(source)
  */
-  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_Fst, __pyx_n_s_read); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1844, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_Fst, __pyx_n_s_read); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1915, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":1843
+  /* "pywrapfst.pyx":1914
  *     return self._fst.get().Properties(mask, test)
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def read(cls, source):
  *     """
  */
-  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1843, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Fst->tp_dict, __pyx_n_s_read, __pyx_t_2) < 0) __PYX_ERR(0, 1844, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1914, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Fst->tp_dict, __pyx_n_s_read, __pyx_t_1) < 0) __PYX_ERR(0, 1915, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_Fst);
 
-  /* "pywrapfst.pyx":1862
+  /* "pywrapfst.pyx":1933
  * 
  *   @classmethod
  *   def read_from_string(cls, state):             # <<<<<<<<<<<<<<
  *     """
  *     read_from_string(state)
  */
-  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_Fst, __pyx_n_s_read_from_string); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1862, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_Fst, __pyx_n_s_read_from_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1933, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
 
-  /* "pywrapfst.pyx":1861
+  /* "pywrapfst.pyx":1932
  *     return _read_Fst(source)
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def read_from_string(cls, state):
  *     """
  */
-  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1861, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Fst->tp_dict, __pyx_n_s_read_from_string, __pyx_t_1) < 0) __PYX_ERR(0, 1862, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1932, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_Fst->tp_dict, __pyx_n_s_read_from_string, __pyx_t_2) < 0) __PYX_ERR(0, 1933, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_Fst);
 
-  /* "pywrapfst.pyx":2273
+  /* "pywrapfst.pyx":2306
  * 
  *   cdef void _minimize(self,
  *                       float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
  *                       bool allow_nondet=False) except *:
  *     # This runs in-place when the second argument is null.
  */
-  __pyx_k__10 = fst::kShortestDelta;
+  __pyx_k__12 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2279
+  /* "pywrapfst.pyx":2312
  *     self._check_mutating_imethod()
  * 
  *   def minimize(self, float delta=fst.kShortestDelta, bool allow_nondet=False):             # <<<<<<<<<<<<<<
  *     """
  *     minimize(self, delta=1e-6, allow_nondet=False)
  */
-  __pyx_k__11 = fst::kShortestDelta;
+  __pyx_k__13 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2375
+  /* "pywrapfst.pyx":2407
  * 
  *   cdef void _prune(self,
  *                    float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                    int64 nstate=fst.kNoStateId,
  *                    weight=None) except *:
  */
-  __pyx_k__12 = fst::kDelta;
+  __pyx_k__14 = fst::kDelta;
 
-  /* "pywrapfst.pyx":2376
+  /* "pywrapfst.pyx":2408
  *   cdef void _prune(self,
  *                    float delta=fst.kDelta,
  *                    int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                    weight=None) except *:
  *     # Threshold is set to semiring Zero (no pruning) if no weight is specified.
  */
-  __pyx_k__13 = fst::kNoStateId;
+  __pyx_k__15 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2385
+  /* "pywrapfst.pyx":2417
  * 
  *   def prune(self,
  *             float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *             int64 nstate=fst.kNoStateId,
  *             weight=None):
  */
-  __pyx_k__14 = fst::kDelta;
+  __pyx_k__16 = fst::kDelta;
 
-  /* "pywrapfst.pyx":2386
+  /* "pywrapfst.pyx":2418
  *   def prune(self,
  *             float delta=fst.kDelta,
  *             int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *             weight=None):
  *     """
  */
-  __pyx_k__15 = fst::kNoStateId;
+  __pyx_k__17 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2411
+  /* "pywrapfst.pyx":2443
  * 
  *   cdef void _push(self,
  *                   float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
  *                   bool remove_total_weight=False,
  *                   bool to_final=False):
  */
-  __pyx_k__16 = fst::kShortestDelta;
+  __pyx_k__18 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2418
+  /* "pywrapfst.pyx":2452
  * 
  *   def push(self,
  *            float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
  *            bool remove_total_weight=False,
  *            bool to_final=False):
  */
-  __pyx_k__17 = fst::kShortestDelta;
+  __pyx_k__19 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2656
+  /* "pywrapfst.pyx":2683
  *                        bool connect=True,
  *                        weight=None,
  *                        int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                        float delta=fst.kShortestDelta) except *:
- *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),
+ *     cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(self.weight_type(),
  */
-  __pyx_k__18 = fst::kNoStateId;
+  __pyx_k__20 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2657
+  /* "pywrapfst.pyx":2684
  *                        weight=None,
  *                        int64 nstate=fst.kNoStateId,
  *                        float delta=fst.kShortestDelta) except *:             # <<<<<<<<<<<<<<
- *     cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),
- *                                                        weight)
+ *     cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(self.weight_type(),
+ *                                                             weight)
  */
-  __pyx_k__19 = fst::kShortestDelta;
+  __pyx_k__21 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2673
+  /* "pywrapfst.pyx":2701
  *                 bool connect=True,
  *                 weight=None,
  *                 int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                 float delta=fst.kShortestDelta):
  *     """
  */
-  __pyx_k__20 = fst::kNoStateId;
+  __pyx_k__22 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":2674
+  /* "pywrapfst.pyx":2702
  *                 weight=None,
  *                 int64 nstate=fst.kNoStateId,
  *                 float delta=fst.kShortestDelta):             # <<<<<<<<<<<<<<
  *     """
  *     rmepsilon(self, queue_type="auto", connect=True, weight=None,
  */
-  __pyx_k__21 = fst::kShortestDelta;
+  __pyx_k__23 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":2948
+  /* "pywrapfst.pyx":2977
  * 
  * 
  * NO_LABEL = fst.kNoLabel             # <<<<<<<<<<<<<<
  * NO_STATE_ID = fst.kNoStateId
  * NO_SYMBOL = fst.kNoSymbol
  */
-  __pyx_t_1 = __Pyx_PyInt_From_int(fst::kNoLabel); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2948, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_LABEL, __pyx_t_1) < 0) __PYX_ERR(0, 2948, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_int(fst::kNoLabel); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2977, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_LABEL, __pyx_t_2) < 0) __PYX_ERR(0, 2977, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2949
+  /* "pywrapfst.pyx":2978
  * 
  * NO_LABEL = fst.kNoLabel
  * NO_STATE_ID = fst.kNoStateId             # <<<<<<<<<<<<<<
  * NO_SYMBOL = fst.kNoSymbol
  * 
  */
-  __pyx_t_1 = __Pyx_PyInt_From_int(fst::kNoStateId); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2949, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_STATE_ID, __pyx_t_1) < 0) __PYX_ERR(0, 2949, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_int(fst::kNoStateId); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2978, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_STATE_ID, __pyx_t_2) < 0) __PYX_ERR(0, 2978, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2950
+  /* "pywrapfst.pyx":2979
  * NO_LABEL = fst.kNoLabel
  * NO_STATE_ID = fst.kNoStateId
  * NO_SYMBOL = fst.kNoSymbol             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_1 = __Pyx_PyInt_From_int64_t(fst::kNoSymbol); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2950, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_SYMBOL, __pyx_t_1) < 0) __PYX_ERR(0, 2950, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_int64_t(fst::kNoSymbol); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2979, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_SYMBOL, __pyx_t_2) < 0) __PYX_ERR(0, 2979, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2956
+  /* "pywrapfst.pyx":2985
  * 
  * 
  * EXPANDED = fst.kExpanded             # <<<<<<<<<<<<<<
  * MUTABLE = fst.kMutable
  * ERROR = fst.kError
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kExpanded); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2956, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EXPANDED, __pyx_t_1) < 0) __PYX_ERR(0, 2956, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kExpanded); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2985, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EXPANDED, __pyx_t_2) < 0) __PYX_ERR(0, 2985, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2957
+  /* "pywrapfst.pyx":2986
  * 
  * EXPANDED = fst.kExpanded
  * MUTABLE = fst.kMutable             # <<<<<<<<<<<<<<
  * ERROR = fst.kError
  * ACCEPTOR = fst.kAcceptor
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kMutable); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2957, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_MUTABLE, __pyx_t_1) < 0) __PYX_ERR(0, 2957, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kMutable); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2986, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_MUTABLE, __pyx_t_2) < 0) __PYX_ERR(0, 2986, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2958
+  /* "pywrapfst.pyx":2987
  * EXPANDED = fst.kExpanded
  * MUTABLE = fst.kMutable
  * ERROR = fst.kError             # <<<<<<<<<<<<<<
  * ACCEPTOR = fst.kAcceptor
  * NOT_ACCEPTOR = fst.kNotAcceptor
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2958, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ERROR, __pyx_t_1) < 0) __PYX_ERR(0, 2958, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2987, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ERROR, __pyx_t_2) < 0) __PYX_ERR(0, 2987, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2959
+  /* "pywrapfst.pyx":2988
  * MUTABLE = fst.kMutable
  * ERROR = fst.kError
  * ACCEPTOR = fst.kAcceptor             # <<<<<<<<<<<<<<
  * NOT_ACCEPTOR = fst.kNotAcceptor
  * I_DETERMINISTIC = fst.kIDeterministic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAcceptor); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2959, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACCEPTOR, __pyx_t_1) < 0) __PYX_ERR(0, 2959, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kAcceptor); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2988, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACCEPTOR, __pyx_t_2) < 0) __PYX_ERR(0, 2988, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2960
+  /* "pywrapfst.pyx":2989
  * ERROR = fst.kError
  * ACCEPTOR = fst.kAcceptor
  * NOT_ACCEPTOR = fst.kNotAcceptor             # <<<<<<<<<<<<<<
  * I_DETERMINISTIC = fst.kIDeterministic
  * NON_I_DETERMINISTIC = fst.kNonIDeterministic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotAcceptor); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2960, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_ACCEPTOR, __pyx_t_1) < 0) __PYX_ERR(0, 2960, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNotAcceptor); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2989, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_ACCEPTOR, __pyx_t_2) < 0) __PYX_ERR(0, 2989, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2961
+  /* "pywrapfst.pyx":2990
  * ACCEPTOR = fst.kAcceptor
  * NOT_ACCEPTOR = fst.kNotAcceptor
  * I_DETERMINISTIC = fst.kIDeterministic             # <<<<<<<<<<<<<<
  * NON_I_DETERMINISTIC = fst.kNonIDeterministic
  * O_DETERMINISTIC = fst.kODeterministic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kIDeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2961, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_DETERMINISTIC, __pyx_t_1) < 0) __PYX_ERR(0, 2961, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kIDeterministic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2990, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_DETERMINISTIC, __pyx_t_2) < 0) __PYX_ERR(0, 2990, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2962
+  /* "pywrapfst.pyx":2991
  * NOT_ACCEPTOR = fst.kNotAcceptor
  * I_DETERMINISTIC = fst.kIDeterministic
  * NON_I_DETERMINISTIC = fst.kNonIDeterministic             # <<<<<<<<<<<<<<
  * O_DETERMINISTIC = fst.kODeterministic
  * NON_O_DETERMINISTIC = fst.kNonODeterministic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNonIDeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2962, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NON_I_DETERMINISTIC, __pyx_t_1) < 0) __PYX_ERR(0, 2962, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNonIDeterministic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2991, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NON_I_DETERMINISTIC, __pyx_t_2) < 0) __PYX_ERR(0, 2991, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2963
+  /* "pywrapfst.pyx":2992
  * I_DETERMINISTIC = fst.kIDeterministic
  * NON_I_DETERMINISTIC = fst.kNonIDeterministic
  * O_DETERMINISTIC = fst.kODeterministic             # <<<<<<<<<<<<<<
  * NON_O_DETERMINISTIC = fst.kNonODeterministic
  * EPSILONS = fst.kEpsilons
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kODeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2963, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_DETERMINISTIC, __pyx_t_1) < 0) __PYX_ERR(0, 2963, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kODeterministic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2992, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_DETERMINISTIC, __pyx_t_2) < 0) __PYX_ERR(0, 2992, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2964
+  /* "pywrapfst.pyx":2993
  * NON_I_DETERMINISTIC = fst.kNonIDeterministic
  * O_DETERMINISTIC = fst.kODeterministic
  * NON_O_DETERMINISTIC = fst.kNonODeterministic             # <<<<<<<<<<<<<<
  * EPSILONS = fst.kEpsilons
  * NO_EPSILONS = fst.kNoEpsilons
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNonODeterministic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2964, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NON_O_DETERMINISTIC, __pyx_t_1) < 0) __PYX_ERR(0, 2964, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNonODeterministic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2993, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NON_O_DETERMINISTIC, __pyx_t_2) < 0) __PYX_ERR(0, 2993, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2965
+  /* "pywrapfst.pyx":2994
  * O_DETERMINISTIC = fst.kODeterministic
  * NON_O_DETERMINISTIC = fst.kNonODeterministic
  * EPSILONS = fst.kEpsilons             # <<<<<<<<<<<<<<
  * NO_EPSILONS = fst.kNoEpsilons
  * I_EPSILONS = fst.kIEpsilons
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2965, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2965, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kEpsilons); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2994, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EPSILONS, __pyx_t_2) < 0) __PYX_ERR(0, 2994, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2966
+  /* "pywrapfst.pyx":2995
  * NON_O_DETERMINISTIC = fst.kNonODeterministic
  * EPSILONS = fst.kEpsilons
  * NO_EPSILONS = fst.kNoEpsilons             # <<<<<<<<<<<<<<
  * I_EPSILONS = fst.kIEpsilons
  * NO_I_EPSILONS = fst.kNoIEpsilons
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNoEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2966, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2966, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNoEpsilons); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2995, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_EPSILONS, __pyx_t_2) < 0) __PYX_ERR(0, 2995, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2967
+  /* "pywrapfst.pyx":2996
  * EPSILONS = fst.kEpsilons
  * NO_EPSILONS = fst.kNoEpsilons
  * I_EPSILONS = fst.kIEpsilons             # <<<<<<<<<<<<<<
  * NO_I_EPSILONS = fst.kNoIEpsilons
  * O_EPSILONS = fst.kOEpsilons
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kIEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2967, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2967, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kIEpsilons); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2996, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_EPSILONS, __pyx_t_2) < 0) __PYX_ERR(0, 2996, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2968
+  /* "pywrapfst.pyx":2997
  * NO_EPSILONS = fst.kNoEpsilons
  * I_EPSILONS = fst.kIEpsilons
  * NO_I_EPSILONS = fst.kNoIEpsilons             # <<<<<<<<<<<<<<
  * O_EPSILONS = fst.kOEpsilons
  * NO_O_EPSILONS = fst.kNoOEpsilons
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNoIEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2968, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_I_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2968, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNoIEpsilons); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2997, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_I_EPSILONS, __pyx_t_2) < 0) __PYX_ERR(0, 2997, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2969
+  /* "pywrapfst.pyx":2998
  * I_EPSILONS = fst.kIEpsilons
  * NO_I_EPSILONS = fst.kNoIEpsilons
  * O_EPSILONS = fst.kOEpsilons             # <<<<<<<<<<<<<<
  * NO_O_EPSILONS = fst.kNoOEpsilons
  * I_LABEL_SORTED = fst.kILabelSorted
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kOEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2969, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2969, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kOEpsilons); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2998, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_EPSILONS, __pyx_t_2) < 0) __PYX_ERR(0, 2998, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2970
+  /* "pywrapfst.pyx":2999
  * NO_I_EPSILONS = fst.kNoIEpsilons
  * O_EPSILONS = fst.kOEpsilons
  * NO_O_EPSILONS = fst.kNoOEpsilons             # <<<<<<<<<<<<<<
  * I_LABEL_SORTED = fst.kILabelSorted
  * NOT_I_LABEL_SORTED = fst.kNotILabelSorted
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNoOEpsilons); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2970, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_O_EPSILONS, __pyx_t_1) < 0) __PYX_ERR(0, 2970, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNoOEpsilons); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2999, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NO_O_EPSILONS, __pyx_t_2) < 0) __PYX_ERR(0, 2999, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2971
+  /* "pywrapfst.pyx":3000
  * O_EPSILONS = fst.kOEpsilons
  * NO_O_EPSILONS = fst.kNoOEpsilons
  * I_LABEL_SORTED = fst.kILabelSorted             # <<<<<<<<<<<<<<
  * NOT_I_LABEL_SORTED = fst.kNotILabelSorted
  * O_LABEL_SORTED = fst.kOLabelSorted
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kILabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2971, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_LABEL_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2971, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kILabelSorted); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3000, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_LABEL_SORTED, __pyx_t_2) < 0) __PYX_ERR(0, 3000, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2972
+  /* "pywrapfst.pyx":3001
  * NO_O_EPSILONS = fst.kNoOEpsilons
  * I_LABEL_SORTED = fst.kILabelSorted
  * NOT_I_LABEL_SORTED = fst.kNotILabelSorted             # <<<<<<<<<<<<<<
  * O_LABEL_SORTED = fst.kOLabelSorted
  * NOT_O_LABEL_SORTED = fst.kNotOLabelSorted
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotILabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2972, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_I_LABEL_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2972, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNotILabelSorted); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3001, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_I_LABEL_SORTED, __pyx_t_2) < 0) __PYX_ERR(0, 3001, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2973
+  /* "pywrapfst.pyx":3002
  * I_LABEL_SORTED = fst.kILabelSorted
  * NOT_I_LABEL_SORTED = fst.kNotILabelSorted
  * O_LABEL_SORTED = fst.kOLabelSorted             # <<<<<<<<<<<<<<
  * NOT_O_LABEL_SORTED = fst.kNotOLabelSorted
  * WEIGHTED = fst.kWeighted
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kOLabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2973, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_LABEL_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2973, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kOLabelSorted); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3002, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_LABEL_SORTED, __pyx_t_2) < 0) __PYX_ERR(0, 3002, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2974
+  /* "pywrapfst.pyx":3003
  * NOT_I_LABEL_SORTED = fst.kNotILabelSorted
  * O_LABEL_SORTED = fst.kOLabelSorted
  * NOT_O_LABEL_SORTED = fst.kNotOLabelSorted             # <<<<<<<<<<<<<<
  * WEIGHTED = fst.kWeighted
  * UNWEIGHTED = fst.kUnweighted
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotOLabelSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2974, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_O_LABEL_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2974, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNotOLabelSorted); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3003, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_O_LABEL_SORTED, __pyx_t_2) < 0) __PYX_ERR(0, 3003, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2975
+  /* "pywrapfst.pyx":3004
  * O_LABEL_SORTED = fst.kOLabelSorted
  * NOT_O_LABEL_SORTED = fst.kNotOLabelSorted
  * WEIGHTED = fst.kWeighted             # <<<<<<<<<<<<<<
  * UNWEIGHTED = fst.kUnweighted
  * CYCLIC = fst.kCyclic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kWeighted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2975, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WEIGHTED, __pyx_t_1) < 0) __PYX_ERR(0, 2975, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kWeighted); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3004, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WEIGHTED, __pyx_t_2) < 0) __PYX_ERR(0, 3004, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2976
+  /* "pywrapfst.pyx":3005
  * NOT_O_LABEL_SORTED = fst.kNotOLabelSorted
  * WEIGHTED = fst.kWeighted
  * UNWEIGHTED = fst.kUnweighted             # <<<<<<<<<<<<<<
  * CYCLIC = fst.kCyclic
  * ACYCLIC = fst.kAcyclic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kUnweighted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2976, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_UNWEIGHTED, __pyx_t_1) < 0) __PYX_ERR(0, 2976, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kUnweighted); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3005, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_UNWEIGHTED, __pyx_t_2) < 0) __PYX_ERR(0, 3005, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2977
+  /* "pywrapfst.pyx":3006
  * WEIGHTED = fst.kWeighted
  * UNWEIGHTED = fst.kUnweighted
  * CYCLIC = fst.kCyclic             # <<<<<<<<<<<<<<
  * ACYCLIC = fst.kAcyclic
  * INITIAL_CYCLIC = fst.kInitialCyclic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kCyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2977, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_CYCLIC, __pyx_t_1) < 0) __PYX_ERR(0, 2977, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kCyclic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3006, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_CYCLIC, __pyx_t_2) < 0) __PYX_ERR(0, 3006, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2978
+  /* "pywrapfst.pyx":3007
  * UNWEIGHTED = fst.kUnweighted
  * CYCLIC = fst.kCyclic
  * ACYCLIC = fst.kAcyclic             # <<<<<<<<<<<<<<
  * INITIAL_CYCLIC = fst.kInitialCyclic
  * INITIAL_ACYCLIC = fst.kInitialAcyclic
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAcyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2978, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACYCLIC, __pyx_t_1) < 0) __PYX_ERR(0, 2978, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kAcyclic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3007, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACYCLIC, __pyx_t_2) < 0) __PYX_ERR(0, 3007, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2979
+  /* "pywrapfst.pyx":3008
  * CYCLIC = fst.kCyclic
  * ACYCLIC = fst.kAcyclic
  * INITIAL_CYCLIC = fst.kInitialCyclic             # <<<<<<<<<<<<<<
  * INITIAL_ACYCLIC = fst.kInitialAcyclic
  * TOP_SORTED = fst.kTopSorted
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kInitialCyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2979, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_INITIAL_CYCLIC, __pyx_t_1) < 0) __PYX_ERR(0, 2979, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kInitialCyclic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3008, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_INITIAL_CYCLIC, __pyx_t_2) < 0) __PYX_ERR(0, 3008, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2980
+  /* "pywrapfst.pyx":3009
  * ACYCLIC = fst.kAcyclic
  * INITIAL_CYCLIC = fst.kInitialCyclic
  * INITIAL_ACYCLIC = fst.kInitialAcyclic             # <<<<<<<<<<<<<<
  * TOP_SORTED = fst.kTopSorted
  * NOT_TOP_SORTED = fst.kNotTopSorted
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kInitialAcyclic); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2980, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_INITIAL_ACYCLIC, __pyx_t_1) < 0) __PYX_ERR(0, 2980, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kInitialAcyclic); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3009, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_INITIAL_ACYCLIC, __pyx_t_2) < 0) __PYX_ERR(0, 3009, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2981
+  /* "pywrapfst.pyx":3010
  * INITIAL_CYCLIC = fst.kInitialCyclic
  * INITIAL_ACYCLIC = fst.kInitialAcyclic
  * TOP_SORTED = fst.kTopSorted             # <<<<<<<<<<<<<<
  * NOT_TOP_SORTED = fst.kNotTopSorted
  * ACCESSIBLE = fst.kAccessible
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kTopSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2981, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_TOP_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2981, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kTopSorted); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3010, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_TOP_SORTED, __pyx_t_2) < 0) __PYX_ERR(0, 3010, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2982
+  /* "pywrapfst.pyx":3011
  * INITIAL_ACYCLIC = fst.kInitialAcyclic
  * TOP_SORTED = fst.kTopSorted
  * NOT_TOP_SORTED = fst.kNotTopSorted             # <<<<<<<<<<<<<<
  * ACCESSIBLE = fst.kAccessible
  * NOT_ACCESSIBLE = fst.kNotAccessible
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotTopSorted); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2982, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_TOP_SORTED, __pyx_t_1) < 0) __PYX_ERR(0, 2982, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNotTopSorted); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3011, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_TOP_SORTED, __pyx_t_2) < 0) __PYX_ERR(0, 3011, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2983
+  /* "pywrapfst.pyx":3012
  * TOP_SORTED = fst.kTopSorted
  * NOT_TOP_SORTED = fst.kNotTopSorted
  * ACCESSIBLE = fst.kAccessible             # <<<<<<<<<<<<<<
  * NOT_ACCESSIBLE = fst.kNotAccessible
  * COACCESSIBLE = fst.kCoAccessible
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2983, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACCESSIBLE, __pyx_t_1) < 0) __PYX_ERR(0, 2983, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kAccessible); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3012, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ACCESSIBLE, __pyx_t_2) < 0) __PYX_ERR(0, 3012, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2984
+  /* "pywrapfst.pyx":3013
  * NOT_TOP_SORTED = fst.kNotTopSorted
  * ACCESSIBLE = fst.kAccessible
  * NOT_ACCESSIBLE = fst.kNotAccessible             # <<<<<<<<<<<<<<
  * COACCESSIBLE = fst.kCoAccessible
  * NOT_COACCESSIBLE = fst.kNotCoAccessible
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2984, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_ACCESSIBLE, __pyx_t_1) < 0) __PYX_ERR(0, 2984, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNotAccessible); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3013, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_ACCESSIBLE, __pyx_t_2) < 0) __PYX_ERR(0, 3013, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2985
+  /* "pywrapfst.pyx":3014
  * ACCESSIBLE = fst.kAccessible
  * NOT_ACCESSIBLE = fst.kNotAccessible
  * COACCESSIBLE = fst.kCoAccessible             # <<<<<<<<<<<<<<
  * NOT_COACCESSIBLE = fst.kNotCoAccessible
  * STRING = fst.kString
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kCoAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2985, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_COACCESSIBLE, __pyx_t_1) < 0) __PYX_ERR(0, 2985, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kCoAccessible); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3014, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_COACCESSIBLE, __pyx_t_2) < 0) __PYX_ERR(0, 3014, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2986
+  /* "pywrapfst.pyx":3015
  * NOT_ACCESSIBLE = fst.kNotAccessible
  * COACCESSIBLE = fst.kCoAccessible
  * NOT_COACCESSIBLE = fst.kNotCoAccessible             # <<<<<<<<<<<<<<
  * STRING = fst.kString
  * NOT_STRING = fst.kNotString
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotCoAccessible); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2986, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_COACCESSIBLE, __pyx_t_1) < 0) __PYX_ERR(0, 2986, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNotCoAccessible); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3015, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_COACCESSIBLE, __pyx_t_2) < 0) __PYX_ERR(0, 3015, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2987
+  /* "pywrapfst.pyx":3016
  * COACCESSIBLE = fst.kCoAccessible
  * NOT_COACCESSIBLE = fst.kNotCoAccessible
  * STRING = fst.kString             # <<<<<<<<<<<<<<
  * NOT_STRING = fst.kNotString
  * WEIGHTED_CYCLES = fst.kWeightedCycles
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kString); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2987, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_STRING, __pyx_t_1) < 0) __PYX_ERR(0, 2987, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kString); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3016, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_STRING, __pyx_t_2) < 0) __PYX_ERR(0, 3016, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2988
+  /* "pywrapfst.pyx":3017
  * NOT_COACCESSIBLE = fst.kNotCoAccessible
  * STRING = fst.kString
  * NOT_STRING = fst.kNotString             # <<<<<<<<<<<<<<
  * WEIGHTED_CYCLES = fst.kWeightedCycles
  * UNWEIGHTED_CYCLES = fst.kUnweightedCycles
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNotString); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2988, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_STRING, __pyx_t_1) < 0) __PYX_ERR(0, 2988, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNotString); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3017, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NOT_STRING, __pyx_t_2) < 0) __PYX_ERR(0, 3017, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2989
+  /* "pywrapfst.pyx":3018
  * STRING = fst.kString
  * NOT_STRING = fst.kNotString
  * WEIGHTED_CYCLES = fst.kWeightedCycles             # <<<<<<<<<<<<<<
  * UNWEIGHTED_CYCLES = fst.kUnweightedCycles
  * NULL_PROPERTIES = fst.kNullProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kWeightedCycles); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2989, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WEIGHTED_CYCLES, __pyx_t_1) < 0) __PYX_ERR(0, 2989, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kWeightedCycles); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3018, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WEIGHTED_CYCLES, __pyx_t_2) < 0) __PYX_ERR(0, 3018, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2990
+  /* "pywrapfst.pyx":3019
  * NOT_STRING = fst.kNotString
  * WEIGHTED_CYCLES = fst.kWeightedCycles
  * UNWEIGHTED_CYCLES = fst.kUnweightedCycles             # <<<<<<<<<<<<<<
  * NULL_PROPERTIES = fst.kNullProperties
  * COPY_PROPERTIES = fst.kCopyProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kUnweightedCycles); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2990, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_UNWEIGHTED_CYCLES, __pyx_t_1) < 0) __PYX_ERR(0, 2990, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kUnweightedCycles); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3019, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_UNWEIGHTED_CYCLES, __pyx_t_2) < 0) __PYX_ERR(0, 3019, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2991
+  /* "pywrapfst.pyx":3020
  * WEIGHTED_CYCLES = fst.kWeightedCycles
  * UNWEIGHTED_CYCLES = fst.kUnweightedCycles
  * NULL_PROPERTIES = fst.kNullProperties             # <<<<<<<<<<<<<<
  * COPY_PROPERTIES = fst.kCopyProperties
  * INTRINSIC_PROPERTIES = fst.kIntrinsicProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNullProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2991, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NULL_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2991, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNullProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3020, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NULL_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3020, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2992
+  /* "pywrapfst.pyx":3021
  * UNWEIGHTED_CYCLES = fst.kUnweightedCycles
  * NULL_PROPERTIES = fst.kNullProperties
  * COPY_PROPERTIES = fst.kCopyProperties             # <<<<<<<<<<<<<<
  * INTRINSIC_PROPERTIES = fst.kIntrinsicProperties
  * EXTRINSIC_PROPERTIES = fst.kExtrinsicProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kCopyProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2992, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_COPY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2992, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kCopyProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3021, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_COPY_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3021, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2993
+  /* "pywrapfst.pyx":3022
  * NULL_PROPERTIES = fst.kNullProperties
  * COPY_PROPERTIES = fst.kCopyProperties
  * INTRINSIC_PROPERTIES = fst.kIntrinsicProperties             # <<<<<<<<<<<<<<
  * EXTRINSIC_PROPERTIES = fst.kExtrinsicProperties
  * SET_START_PROPERTIES = fst.kSetStartProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kIntrinsicProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2993, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_INTRINSIC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2993, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kIntrinsicProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3022, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_INTRINSIC_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3022, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2994
+  /* "pywrapfst.pyx":3023
  * COPY_PROPERTIES = fst.kCopyProperties
  * INTRINSIC_PROPERTIES = fst.kIntrinsicProperties
  * EXTRINSIC_PROPERTIES = fst.kExtrinsicProperties             # <<<<<<<<<<<<<<
  * SET_START_PROPERTIES = fst.kSetStartProperties
  * SET_FINAL_PROPERTIES = fst.kSetFinalProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kExtrinsicProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2994, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EXTRINSIC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2994, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kExtrinsicProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3023, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_EXTRINSIC_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3023, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2995
+  /* "pywrapfst.pyx":3024
  * INTRINSIC_PROPERTIES = fst.kIntrinsicProperties
  * EXTRINSIC_PROPERTIES = fst.kExtrinsicProperties
  * SET_START_PROPERTIES = fst.kSetStartProperties             # <<<<<<<<<<<<<<
  * SET_FINAL_PROPERTIES = fst.kSetFinalProperties
  * ADD_STATE_PROPERTIES = fst.kAddStateProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kSetStartProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2995, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SET_START_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2995, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kSetStartProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3024, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SET_START_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3024, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2996
+  /* "pywrapfst.pyx":3025
  * EXTRINSIC_PROPERTIES = fst.kExtrinsicProperties
  * SET_START_PROPERTIES = fst.kSetStartProperties
  * SET_FINAL_PROPERTIES = fst.kSetFinalProperties             # <<<<<<<<<<<<<<
  * ADD_STATE_PROPERTIES = fst.kAddStateProperties
  * ADD_ARC_PROPERTIES = fst.kAddArcProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kSetFinalProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2996, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SET_FINAL_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2996, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kSetFinalProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3025, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SET_FINAL_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3025, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2997
+  /* "pywrapfst.pyx":3026
  * SET_START_PROPERTIES = fst.kSetStartProperties
  * SET_FINAL_PROPERTIES = fst.kSetFinalProperties
  * ADD_STATE_PROPERTIES = fst.kAddStateProperties             # <<<<<<<<<<<<<<
  * ADD_ARC_PROPERTIES = fst.kAddArcProperties
  * SET_ARC_PROPERTIES = fst.kSetArcProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAddStateProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2997, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ADD_STATE_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2997, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kAddStateProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3026, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ADD_STATE_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3026, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2998
+  /* "pywrapfst.pyx":3027
  * SET_FINAL_PROPERTIES = fst.kSetFinalProperties
  * ADD_STATE_PROPERTIES = fst.kAddStateProperties
  * ADD_ARC_PROPERTIES = fst.kAddArcProperties             # <<<<<<<<<<<<<<
  * SET_ARC_PROPERTIES = fst.kSetArcProperties
  * DELETE_STATE_PROPERTIES = fst.kDeleteStatesProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAddArcProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2998, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ADD_ARC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2998, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kAddArcProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3027, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ADD_ARC_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3027, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":2999
+  /* "pywrapfst.pyx":3028
  * ADD_STATE_PROPERTIES = fst.kAddStateProperties
  * ADD_ARC_PROPERTIES = fst.kAddArcProperties
  * SET_ARC_PROPERTIES = fst.kSetArcProperties             # <<<<<<<<<<<<<<
  * DELETE_STATE_PROPERTIES = fst.kDeleteStatesProperties
  * DELETE_ARC_PROPERTIES = fst.kDeleteArcsProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kSetArcProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2999, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SET_ARC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 2999, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kSetArcProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3028, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SET_ARC_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3028, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3000
+  /* "pywrapfst.pyx":3029
  * ADD_ARC_PROPERTIES = fst.kAddArcProperties
  * SET_ARC_PROPERTIES = fst.kSetArcProperties
  * DELETE_STATE_PROPERTIES = fst.kDeleteStatesProperties             # <<<<<<<<<<<<<<
  * DELETE_ARC_PROPERTIES = fst.kDeleteArcsProperties
  * STATE_SORT_PROPERTIES = fst.kStateSortProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kDeleteStatesProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3000, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_DELETE_STATE_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 3000, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kDeleteStatesProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3029, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_DELETE_STATE_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3029, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3001
+  /* "pywrapfst.pyx":3030
  * SET_ARC_PROPERTIES = fst.kSetArcProperties
  * DELETE_STATE_PROPERTIES = fst.kDeleteStatesProperties
  * DELETE_ARC_PROPERTIES = fst.kDeleteArcsProperties             # <<<<<<<<<<<<<<
  * STATE_SORT_PROPERTIES = fst.kStateSortProperties
  * ARC_SORT_PROPERTIES = fst.kArcSortProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kDeleteArcsProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3001, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_DELETE_ARC_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 3001, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kDeleteArcsProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3030, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_DELETE_ARC_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3030, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3002
+  /* "pywrapfst.pyx":3031
  * DELETE_STATE_PROPERTIES = fst.kDeleteStatesProperties
  * DELETE_ARC_PROPERTIES = fst.kDeleteArcsProperties
  * STATE_SORT_PROPERTIES = fst.kStateSortProperties             # <<<<<<<<<<<<<<
  * ARC_SORT_PROPERTIES = fst.kArcSortProperties
  * I_LABEL_INVARIANT_PROPERTIES = fst.kILabelInvariantProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kStateSortProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3002, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_STATE_SORT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 3002, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kStateSortProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3031, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_STATE_SORT_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3031, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3003
+  /* "pywrapfst.pyx":3032
  * DELETE_ARC_PROPERTIES = fst.kDeleteArcsProperties
  * STATE_SORT_PROPERTIES = fst.kStateSortProperties
  * ARC_SORT_PROPERTIES = fst.kArcSortProperties             # <<<<<<<<<<<<<<
  * I_LABEL_INVARIANT_PROPERTIES = fst.kILabelInvariantProperties
  * O_LABEL_INVARIANT_PROPERTIES = fst.kOLabelInvariantProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kArcSortProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3003, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_SORT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 3003, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kArcSortProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3032, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_SORT_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3032, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3004
+  /* "pywrapfst.pyx":3033
  * STATE_SORT_PROPERTIES = fst.kStateSortProperties
  * ARC_SORT_PROPERTIES = fst.kArcSortProperties
  * I_LABEL_INVARIANT_PROPERTIES = fst.kILabelInvariantProperties             # <<<<<<<<<<<<<<
  * O_LABEL_INVARIANT_PROPERTIES = fst.kOLabelInvariantProperties
  * WEIGHT_INVARIANT_PROPERTIES = fst.kWeightInvariantProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kILabelInvariantProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3004, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_LABEL_INVARIANT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 3004, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kILabelInvariantProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3033, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_I_LABEL_INVARIANT_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3033, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3005
+  /* "pywrapfst.pyx":3034
  * ARC_SORT_PROPERTIES = fst.kArcSortProperties
  * I_LABEL_INVARIANT_PROPERTIES = fst.kILabelInvariantProperties
  * O_LABEL_INVARIANT_PROPERTIES = fst.kOLabelInvariantProperties             # <<<<<<<<<<<<<<
  * WEIGHT_INVARIANT_PROPERTIES = fst.kWeightInvariantProperties
  * ADD_SUPERFINAL_PROPERTIES = fst.kAddSuperFinalProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kOLabelInvariantProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3005, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_LABEL_INVARIANT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 3005, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kOLabelInvariantProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3034, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_O_LABEL_INVARIANT_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3034, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3006
+  /* "pywrapfst.pyx":3035
  * I_LABEL_INVARIANT_PROPERTIES = fst.kILabelInvariantProperties
  * O_LABEL_INVARIANT_PROPERTIES = fst.kOLabelInvariantProperties
  * WEIGHT_INVARIANT_PROPERTIES = fst.kWeightInvariantProperties             # <<<<<<<<<<<<<<
  * ADD_SUPERFINAL_PROPERTIES = fst.kAddSuperFinalProperties
  * RM_SUPERFINAL_PROPERTIES = fst.kRmSuperFinalProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kWeightInvariantProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3006, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WEIGHT_INVARIANT_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 3006, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kWeightInvariantProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3035, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_WEIGHT_INVARIANT_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3035, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3007
+  /* "pywrapfst.pyx":3036
  * O_LABEL_INVARIANT_PROPERTIES = fst.kOLabelInvariantProperties
  * WEIGHT_INVARIANT_PROPERTIES = fst.kWeightInvariantProperties
  * ADD_SUPERFINAL_PROPERTIES = fst.kAddSuperFinalProperties             # <<<<<<<<<<<<<<
  * RM_SUPERFINAL_PROPERTIES = fst.kRmSuperFinalProperties
  * BINARY_PROPERTIES = fst.kBinaryProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kAddSuperFinalProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3007, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ADD_SUPERFINAL_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 3007, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kAddSuperFinalProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3036, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ADD_SUPERFINAL_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3036, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3008
+  /* "pywrapfst.pyx":3037
  * WEIGHT_INVARIANT_PROPERTIES = fst.kWeightInvariantProperties
  * ADD_SUPERFINAL_PROPERTIES = fst.kAddSuperFinalProperties
  * RM_SUPERFINAL_PROPERTIES = fst.kRmSuperFinalProperties             # <<<<<<<<<<<<<<
  * BINARY_PROPERTIES = fst.kBinaryProperties
  * TRINARY_PROPERTIES = fst.kTrinaryProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kRmSuperFinalProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3008, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_RM_SUPERFINAL_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 3008, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kRmSuperFinalProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3037, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_RM_SUPERFINAL_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3037, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3009
+  /* "pywrapfst.pyx":3038
  * ADD_SUPERFINAL_PROPERTIES = fst.kAddSuperFinalProperties
  * RM_SUPERFINAL_PROPERTIES = fst.kRmSuperFinalProperties
  * BINARY_PROPERTIES = fst.kBinaryProperties             # <<<<<<<<<<<<<<
  * TRINARY_PROPERTIES = fst.kTrinaryProperties
  * POS_TRINARY_PROPERTIES = fst.kPosTrinaryProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kBinaryProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3009, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_BINARY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 3009, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kBinaryProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3038, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_BINARY_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3038, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3010
+  /* "pywrapfst.pyx":3039
  * RM_SUPERFINAL_PROPERTIES = fst.kRmSuperFinalProperties
  * BINARY_PROPERTIES = fst.kBinaryProperties
  * TRINARY_PROPERTIES = fst.kTrinaryProperties             # <<<<<<<<<<<<<<
  * POS_TRINARY_PROPERTIES = fst.kPosTrinaryProperties
  * NEG_TRINARY_PROPERTIES = fst.kNegTrinaryProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kTrinaryProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3010, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_TRINARY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 3010, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kTrinaryProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3039, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_TRINARY_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3039, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3011
+  /* "pywrapfst.pyx":3040
  * BINARY_PROPERTIES = fst.kBinaryProperties
  * TRINARY_PROPERTIES = fst.kTrinaryProperties
  * POS_TRINARY_PROPERTIES = fst.kPosTrinaryProperties             # <<<<<<<<<<<<<<
  * NEG_TRINARY_PROPERTIES = fst.kNegTrinaryProperties
  * FST_PROPERTIES = fst.kFstProperties
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kPosTrinaryProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3011, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_POS_TRINARY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 3011, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kPosTrinaryProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3040, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_POS_TRINARY_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3040, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3012
+  /* "pywrapfst.pyx":3041
  * TRINARY_PROPERTIES = fst.kTrinaryProperties
  * POS_TRINARY_PROPERTIES = fst.kPosTrinaryProperties
  * NEG_TRINARY_PROPERTIES = fst.kNegTrinaryProperties             # <<<<<<<<<<<<<<
  * FST_PROPERTIES = fst.kFstProperties
  * 
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kNegTrinaryProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3012, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NEG_TRINARY_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 3012, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kNegTrinaryProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3041, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_NEG_TRINARY_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3041, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3013
+  /* "pywrapfst.pyx":3042
  * POS_TRINARY_PROPERTIES = fst.kPosTrinaryProperties
  * NEG_TRINARY_PROPERTIES = fst.kNegTrinaryProperties
  * FST_PROPERTIES = fst.kFstProperties             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint64_t(fst::kFstProperties); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3013, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FST_PROPERTIES, __pyx_t_1) < 0) __PYX_ERR(0, 3013, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(fst::kFstProperties); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3042, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FST_PROPERTIES, __pyx_t_2) < 0) __PYX_ERR(0, 3042, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3019
+  /* "pywrapfst.pyx":3048
  * 
  * 
  * ARC_I_LABEL_VALUE = fst.kArcILabelValue             # <<<<<<<<<<<<<<
  * ARC_O_LABEL_VALUE = fst.kArcOLabelValue
  * ARC_WEIGHT_VALUE = fst.kArcWeightValue
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(fst::kArcILabelValue); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3019, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_I_LABEL_VALUE, __pyx_t_1) < 0) __PYX_ERR(0, 3019, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kArcILabelValue); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3048, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_I_LABEL_VALUE, __pyx_t_2) < 0) __PYX_ERR(0, 3048, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3020
+  /* "pywrapfst.pyx":3049
  * 
  * ARC_I_LABEL_VALUE = fst.kArcILabelValue
  * ARC_O_LABEL_VALUE = fst.kArcOLabelValue             # <<<<<<<<<<<<<<
  * ARC_WEIGHT_VALUE = fst.kArcWeightValue
  * ARC_NEXT_STATE_VALUE = fst.kArcNextStateValue
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(fst::kArcOLabelValue); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3020, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_O_LABEL_VALUE, __pyx_t_1) < 0) __PYX_ERR(0, 3020, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kArcOLabelValue); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3049, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_O_LABEL_VALUE, __pyx_t_2) < 0) __PYX_ERR(0, 3049, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3021
+  /* "pywrapfst.pyx":3050
  * ARC_I_LABEL_VALUE = fst.kArcILabelValue
  * ARC_O_LABEL_VALUE = fst.kArcOLabelValue
  * ARC_WEIGHT_VALUE = fst.kArcWeightValue             # <<<<<<<<<<<<<<
  * ARC_NEXT_STATE_VALUE = fst.kArcNextStateValue
  * ARC_NO_CACHE = fst.kArcNoCache
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(fst::kArcWeightValue); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3021, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_WEIGHT_VALUE, __pyx_t_1) < 0) __PYX_ERR(0, 3021, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kArcWeightValue); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3050, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_WEIGHT_VALUE, __pyx_t_2) < 0) __PYX_ERR(0, 3050, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3022
+  /* "pywrapfst.pyx":3051
  * ARC_O_LABEL_VALUE = fst.kArcOLabelValue
  * ARC_WEIGHT_VALUE = fst.kArcWeightValue
  * ARC_NEXT_STATE_VALUE = fst.kArcNextStateValue             # <<<<<<<<<<<<<<
  * ARC_NO_CACHE = fst.kArcNoCache
  * ARC_VALUE_FLAGS = fst.kArcValueFlags
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(fst::kArcNextStateValue); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3022, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_NEXT_STATE_VALUE, __pyx_t_1) < 0) __PYX_ERR(0, 3022, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kArcNextStateValue); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3051, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_NEXT_STATE_VALUE, __pyx_t_2) < 0) __PYX_ERR(0, 3051, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3023
+  /* "pywrapfst.pyx":3052
  * ARC_WEIGHT_VALUE = fst.kArcWeightValue
  * ARC_NEXT_STATE_VALUE = fst.kArcNextStateValue
  * ARC_NO_CACHE = fst.kArcNoCache             # <<<<<<<<<<<<<<
  * ARC_VALUE_FLAGS = fst.kArcValueFlags
  * ARC_FLAGS = fst.kArcFlags
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(fst::kArcNoCache); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3023, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_NO_CACHE, __pyx_t_1) < 0) __PYX_ERR(0, 3023, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kArcNoCache); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3052, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_NO_CACHE, __pyx_t_2) < 0) __PYX_ERR(0, 3052, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3024
+  /* "pywrapfst.pyx":3053
  * ARC_NEXT_STATE_VALUE = fst.kArcNextStateValue
  * ARC_NO_CACHE = fst.kArcNoCache
  * ARC_VALUE_FLAGS = fst.kArcValueFlags             # <<<<<<<<<<<<<<
  * ARC_FLAGS = fst.kArcFlags
  * 
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(fst::kArcValueFlags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3024, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_VALUE_FLAGS, __pyx_t_1) < 0) __PYX_ERR(0, 3024, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kArcValueFlags); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3053, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_VALUE_FLAGS, __pyx_t_2) < 0) __PYX_ERR(0, 3053, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3025
+  /* "pywrapfst.pyx":3054
  * ARC_NO_CACHE = fst.kArcNoCache
  * ARC_VALUE_FLAGS = fst.kArcValueFlags
  * ARC_FLAGS = fst.kArcFlags             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(fst::kArcFlags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3025, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_FLAGS, __pyx_t_1) < 0) __PYX_ERR(0, 3025, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kArcFlags); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3054, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ARC_FLAGS, __pyx_t_2) < 0) __PYX_ERR(0, 3054, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3031
+  /* "pywrapfst.pyx":3060
  * 
  * 
  * ENCODE_LABELS = fst.kEncodeLabels             # <<<<<<<<<<<<<<
  * ENCODE_WEIGHTS = fst.kEncodeWeights
  * ENCODE_FLAGS = fst.kEncodeFlags
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(fst::kEncodeLabels); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3031, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ENCODE_LABELS, __pyx_t_1) < 0) __PYX_ERR(0, 3031, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kEncodeLabels); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3060, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ENCODE_LABELS, __pyx_t_2) < 0) __PYX_ERR(0, 3060, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3032
+  /* "pywrapfst.pyx":3061
  * 
  * ENCODE_LABELS = fst.kEncodeLabels
  * ENCODE_WEIGHTS = fst.kEncodeWeights             # <<<<<<<<<<<<<<
  * ENCODE_FLAGS = fst.kEncodeFlags
  * 
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(fst::kEncodeWeights); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3032, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ENCODE_WEIGHTS, __pyx_t_1) < 0) __PYX_ERR(0, 3032, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kEncodeWeights); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3061, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ENCODE_WEIGHTS, __pyx_t_2) < 0) __PYX_ERR(0, 3061, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3033
+  /* "pywrapfst.pyx":3062
  * ENCODE_LABELS = fst.kEncodeLabels
  * ENCODE_WEIGHTS = fst.kEncodeWeights
  * ENCODE_FLAGS = fst.kEncodeFlags             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_1 = __Pyx_PyInt_From_uint8_t(fst::kEncodeFlags); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3033, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ENCODE_FLAGS, __pyx_t_1) < 0) __PYX_ERR(0, 3033, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyInt_From_uint8_t(fst::kEncodeFlags); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3062, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ENCODE_FLAGS, __pyx_t_2) < 0) __PYX_ERR(0, 3062, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":3405
+  /* "pywrapfst.pyx":3434
  * 
  * cdef Fst _map(Fst ifst,
  *                float delta=fst.kDelta,             # <<<<<<<<<<<<<<
- *                map_type=b"identity",
+ *                map_type="identity",
  *                double power=1.,
  */
-  __pyx_k__30 = fst::kDelta;
+  __pyx_k__32 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3421
+  /* "pywrapfst.pyx":3450
  * 
  * cpdef Fst arcmap(Fst ifst,
  *                  float delta=fst.kDelta,             # <<<<<<<<<<<<<<
- *                  map_type=b"identity",
+ *                  map_type="identity",
  *                  double power=1.,
  */
-  __pyx_k__31 = fst::kDelta;
+  __pyx_k__33 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3420
+  /* "pywrapfst.pyx":3449
  * 
  * 
  * cpdef Fst arcmap(Fst ifst,             # <<<<<<<<<<<<<<
  *                  float delta=fst.kDelta,
- *                  map_type=b"identity",
+ *                  map_type="identity",
  */
-  __pyx_k__31 = fst::kDelta;
+  __pyx_k__33 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3531
+  /* "pywrapfst.pyx":3559
  * 
  * cpdef MutableFst determinize(Fst ifst,
  *                              float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
- *                              det_type=b"functional",
+ *                              det_type="functional",
  *                              int64 nstate=fst.kNoStateId,
  */
-  __pyx_k__32 = fst::kShortestDelta;
+  __pyx_k__34 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":3533
+  /* "pywrapfst.pyx":3561
  *                              float delta=fst.kShortestDelta,
- *                              det_type=b"functional",
+ *                              det_type="functional",
  *                              int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                              int64 subsequential_label=0,
  *                              weight=None,
  */
-  __pyx_k__33 = fst::kNoStateId;
+  __pyx_k__35 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3531
+  /* "pywrapfst.pyx":3559
  * 
  * cpdef MutableFst determinize(Fst ifst,
  *                              float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
- *                              det_type=b"functional",
+ *                              det_type="functional",
  *                              int64 nstate=fst.kNoStateId,
  */
-  __pyx_k__32 = fst::kShortestDelta;
+  __pyx_k__34 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":3533
+  /* "pywrapfst.pyx":3561
  *                              float delta=fst.kShortestDelta,
- *                              det_type=b"functional",
+ *                              det_type="functional",
  *                              int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                              int64 subsequential_label=0,
  *                              weight=None,
  */
-  __pyx_k__33 = fst::kNoStateId;
+  __pyx_k__35 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3627
+  /* "pywrapfst.pyx":3658
  * 
  * cpdef MutableFst disambiguate(Fst ifst,
  *                               float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                               int64 nstate=fst.kNoStateId,
  *                               int64 subsequential_label=0,
  */
-  __pyx_k__34 = fst::kDelta;
+  __pyx_k__36 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3628
+  /* "pywrapfst.pyx":3659
  * cpdef MutableFst disambiguate(Fst ifst,
  *                               float delta=fst.kDelta,
  *                               int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                               int64 subsequential_label=0,
  *                               weight=None):
  */
-  __pyx_k__35 = fst::kNoStateId;
+  __pyx_k__37 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3627
+  /* "pywrapfst.pyx":3658
  * 
  * cpdef MutableFst disambiguate(Fst ifst,
  *                               float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                               int64 nstate=fst.kNoStateId,
  *                               int64 subsequential_label=0,
  */
-  __pyx_k__34 = fst::kDelta;
+  __pyx_k__36 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3628
+  /* "pywrapfst.pyx":3659
  * cpdef MutableFst disambiguate(Fst ifst,
  *                               float delta=fst.kDelta,
  *                               int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                               int64 subsequential_label=0,
  *                               weight=None):
  */
-  __pyx_k__35 = fst::kNoStateId;
+  __pyx_k__37 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3697
+  /* "pywrapfst.pyx":3729
  * 
  * 
  * cpdef bool equal(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
  *   """
  *   equal(ifst1, ifst2, delta=0.0009765625)
  */
-  __pyx_k__36 = fst::kDelta;
-  __pyx_k__36 = fst::kDelta;
+  __pyx_k__38 = fst::kDelta;
+  __pyx_k__38 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3718
+  /* "pywrapfst.pyx":3750
  * 
  * 
  * cpdef bool equivalent(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
  *   """
  *   equivalent(ifst1, ifst2, delta=0.0009765625)
  */
-  __pyx_k__37 = fst::kDelta;
-  __pyx_k__37 = fst::kDelta;
+  __pyx_k__39 = fst::kDelta;
+  __pyx_k__39 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3774
+  /* "pywrapfst.pyx":3806
  * 
  * 
  * cpdef bool isomorphic(Fst ifst1, Fst ifst2, float delta=fst.kDelta):             # <<<<<<<<<<<<<<
  *   """
  *   isomorphic(ifst1, ifst2, delta=0.0009765625)
  */
-  __pyx_k__38 = fst::kDelta;
-  __pyx_k__38 = fst::kDelta;
+  __pyx_k__40 = fst::kDelta;
+  __pyx_k__40 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3799
+  /* "pywrapfst.pyx":3831
  * 
  * cpdef MutableFst prune(Fst ifst,
  *                        float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                        int64 nstate=fst.kNoStateId,
  *                        weight=None):
  */
-  __pyx_k__39 = fst::kDelta;
+  __pyx_k__41 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3800
+  /* "pywrapfst.pyx":3832
  * cpdef MutableFst prune(Fst ifst,
  *                        float delta=fst.kDelta,
  *                        int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                        weight=None):
  *   """
  */
-  __pyx_k__40 = fst::kNoStateId;
+  __pyx_k__42 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3799
+  /* "pywrapfst.pyx":3831
  * 
  * cpdef MutableFst prune(Fst ifst,
  *                        float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                        int64 nstate=fst.kNoStateId,
  *                        weight=None):
  */
-  __pyx_k__39 = fst::kDelta;
+  __pyx_k__41 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3800
+  /* "pywrapfst.pyx":3832
  * cpdef MutableFst prune(Fst ifst,
  *                        float delta=fst.kDelta,
  *                        int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
  *                        weight=None):
  *   """
  */
-  __pyx_k__40 = fst::kNoStateId;
+  __pyx_k__42 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":3830
+  /* "pywrapfst.pyx":3863
  * 
  * cpdef MutableFst push(Fst ifst,
  *                       float delta=fst.kDelta,             # <<<<<<<<<<<<<<
  *                       bool push_weights=False,
  *                       bool push_labels=False,
  */
-  __pyx_k__41 = fst::kDelta;
+  __pyx_k__43 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3829
+  /* "pywrapfst.pyx":3862
  * 
  * 
  * cpdef MutableFst push(Fst ifst,             # <<<<<<<<<<<<<<
  *                       float delta=fst.kDelta,
  *                       bool push_weights=False,
  */
-  __pyx_k__41 = fst::kDelta;
+  __pyx_k__43 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3888
+  /* "pywrapfst.pyx":3921
  *                           Fst ifst2,
  *                           int32 npath=1,
  *                           float delta=fst.kDelta,             # <<<<<<<<<<<<<<
- *                           time_t seed=0,
- *                           select=b"uniform",
+ *                           select="uniform",
+ *                           int32 max_length=INT32_MAX,
  */
-  __pyx_k__42 = fst::kDelta;
+  __pyx_k__44 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3891
- *                           time_t seed=0,
- *                           select=b"uniform",
- *                           int32 max_length=INT32_MAX) except *:             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3923
+ *                           float delta=fst.kDelta,
+ *                           select="uniform",
+ *                           int32 max_length=INT32_MAX,             # <<<<<<<<<<<<<<
+ *                           uint64 seed=0) except *:
  *   """
- *   randequivalent(ifst1, ifst2, npath=1, delta=0.0009765625, seed=0,
  */
-  __pyx_k__43 = INT32_MAX;
+  __pyx_k__45 = INT32_MAX;
 
-  /* "pywrapfst.pyx":3888
+  /* "pywrapfst.pyx":3921
  *                           Fst ifst2,
  *                           int32 npath=1,
  *                           float delta=fst.kDelta,             # <<<<<<<<<<<<<<
- *                           time_t seed=0,
- *                           select=b"uniform",
+ *                           select="uniform",
+ *                           int32 max_length=INT32_MAX,
  */
-  __pyx_k__42 = fst::kDelta;
+  __pyx_k__44 = fst::kDelta;
 
-  /* "pywrapfst.pyx":3891
- *                           time_t seed=0,
- *                           select=b"uniform",
- *                           int32 max_length=INT32_MAX) except *:             # <<<<<<<<<<<<<<
+  /* "pywrapfst.pyx":3923
+ *                           float delta=fst.kDelta,
+ *                           select="uniform",
+ *                           int32 max_length=INT32_MAX,             # <<<<<<<<<<<<<<
+ *                           uint64 seed=0) except *:
  *   """
- *   randequivalent(ifst1, ifst2, npath=1, delta=0.0009765625, seed=0,
  */
-  __pyx_k__43 = INT32_MAX;
+  __pyx_k__45 = INT32_MAX;
 
-  /* "pywrapfst.pyx":3940
- *                          time_t seed=0,
- *                          select=b"uniform",
+  /* "pywrapfst.pyx":3973
+ *                          int32 npath=1,
+ *                          select="uniform",
  *                          int32 max_length=INT32_MAX,             # <<<<<<<<<<<<<<
  *                          bool weighted=False,
- *                          bool remove_total_weight=False):
+ *                          bool remove_total_weight=False,
  */
-  __pyx_k__44 = INT32_MAX;
+  __pyx_k__46 = INT32_MAX;
 
-  /* "pywrapfst.pyx":3936
+  /* "pywrapfst.pyx":3970
  * 
  * 
  * cpdef MutableFst randgen(Fst ifst,             # <<<<<<<<<<<<<<
  *                          int32 npath=1,
- *                          time_t seed=0,
+ *                          select="uniform",
  */
-  __pyx_k__44 = INT32_MAX;
+  __pyx_k__46 = INT32_MAX;
 
-  /* "pywrapfst.pyx":4076
- * 
- * cdef vector[fst.WeightClass] *_shortestdistance(Fst ifst,
- *                                                 float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
- *                                                 int64 nstate=fst.kNoStateId,
- *                                                 queue_type=b"auto",
+  /* "pywrapfst.pyx":4112
+ * cdef void _shortestdistance(Fst ifst,
+ *                             vector[fst.WeightClass] *distance,
+ *                             float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
+ *                             int64 nstate=fst.kNoStateId,
+ *                             queue_type="auto",
  */
-  __pyx_k__45 = fst::kShortestDelta;
+  __pyx_k__47 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":4077
- * cdef vector[fst.WeightClass] *_shortestdistance(Fst ifst,
- *                                                 float delta=fst.kShortestDelta,
- *                                                 int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
- *                                                 queue_type=b"auto",
- *                                                 bool reverse=False) except *:
+  /* "pywrapfst.pyx":4113
+ *                             vector[fst.WeightClass] *distance,
+ *                             float delta=fst.kShortestDelta,
+ *                             int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
+ *                             queue_type="auto",
+ *                             bool reverse=False) except *:
  */
-  __pyx_k__46 = fst::kNoStateId;
+  __pyx_k__48 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":4100
+  /* "pywrapfst.pyx":4131
  * 
  * def shortestdistance(Fst ifst,
  *                      float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
  *                      int64 nstate=fst.kNoStateId,
- *                      queue_type=b"auto",
+ *                      queue_type="auto",
  */
-  __pyx_k__47 = fst::kShortestDelta;
+  __pyx_k__49 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":4101
+  /* "pywrapfst.pyx":4132
  * def shortestdistance(Fst ifst,
  *                      float delta=fst.kShortestDelta,
  *                      int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
- *                      queue_type=b"auto",
+ *                      queue_type="auto",
  *                      bool reverse=False):
  */
-  __pyx_k__48 = fst::kNoStateId;
+  __pyx_k__50 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":4099
+  /* "pywrapfst.pyx":4130
  * 
  * 
  * def shortestdistance(Fst ifst,             # <<<<<<<<<<<<<<
  *                      float delta=fst.kShortestDelta,
  *                      int64 nstate=fst.kNoStateId,
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_55shortestdistance, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4099, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_shortestdistance, __pyx_t_1) < 0) __PYX_ERR(0, 4099, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_9pywrapfst_55shortestdistance, NULL, __pyx_n_s_pywrapfst_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4130, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_shortestdistance, __pyx_t_2) < 0) __PYX_ERR(0, 4130, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pywrapfst.pyx":4137
+  /* "pywrapfst.pyx":4168
  * 
  * cpdef MutableFst shortestpath(Fst ifst,
  *                               float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
  *                               int32 nshortest=1,
  *                               int64 nstate=fst.kNoStateId,
  */
-  __pyx_k__49 = fst::kShortestDelta;
+  __pyx_k__51 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":4139
+  /* "pywrapfst.pyx":4170
  *                               float delta=fst.kShortestDelta,
  *                               int32 nshortest=1,
  *                               int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
- *                               queue_type=b"auto",
+ *                               queue_type="auto",
  *                               bool unique=False,
  */
-  __pyx_k__50 = fst::kNoStateId;
+  __pyx_k__52 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":4137
+  /* "pywrapfst.pyx":4168
  * 
  * cpdef MutableFst shortestpath(Fst ifst,
  *                               float delta=fst.kShortestDelta,             # <<<<<<<<<<<<<<
  *                               int32 nshortest=1,
  *                               int64 nstate=fst.kNoStateId,
  */
-  __pyx_k__49 = fst::kShortestDelta;
+  __pyx_k__51 = fst::kShortestDelta;
 
-  /* "pywrapfst.pyx":4139
+  /* "pywrapfst.pyx":4170
  *                               float delta=fst.kShortestDelta,
  *                               int32 nshortest=1,
  *                               int64 nstate=fst.kNoStateId,             # <<<<<<<<<<<<<<
- *                               queue_type=b"auto",
+ *                               queue_type="auto",
  *                               bool unique=False,
  */
-  __pyx_k__50 = fst::kNoStateId;
+  __pyx_k__52 = fst::kNoStateId;
 
-  /* "pywrapfst.pyx":4294
- * 
- *   def __cinit__(self,
- *                 string fst_type=b"vector",             # <<<<<<<<<<<<<<
- *                 string arc_type=b"standard",
- *                 SymbolTable isymbols=None,
- */
-  __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_n_b_vector); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4294, __pyx_L1_error)
-  __pyx_k__51 = __pyx_t_5;
-
-  /* "pywrapfst.pyx":4295
- *   def __cinit__(self,
- *                 string fst_type=b"vector",
- *                 string arc_type=b"standard",             # <<<<<<<<<<<<<<
- *                 SymbolTable isymbols=None,
- *                 SymbolTable osymbols=None,
- */
-  __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_n_b_standard); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 4295, __pyx_L1_error)
-  __pyx_k__52 = __pyx_t_5;
-
-  /* "pywrapfst.pyx":4403
+  /* "pywrapfst.pyx":4435
  * 
  *   @classmethod
  *   def open(cls, *sources):             # <<<<<<<<<<<<<<
  *     """
  *     FarReader.open(*sources)
  */
-  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_FarReader, __pyx_n_s_open); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4403, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_FarReader, __pyx_n_s_open); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4435, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
 
-  /* "pywrapfst.pyx":4402
- *     return "<{} FarReader at 0x{:x}>".format(self.far_type(), id(self))
+  /* "pywrapfst.pyx":4434
+ *     return f"<{self.far_type()} FarReader at 0x{id(self):x}>"
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
  *   def open(cls, *sources):
  *     """
  */
-  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4402, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_FarReader->tp_dict, __pyx_n_s_open, __pyx_t_2) < 0) __PYX_ERR(0, 4403, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4434, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_FarReader->tp_dict, __pyx_n_s_open, __pyx_t_1) < 0) __PYX_ERR(0, 4435, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_FarReader);
 
-  /* "pywrapfst.pyx":4553
+  /* "pywrapfst.pyx":4594
  * 
  *   @classmethod
- *   def create(cls, source, arc_type=b"standard", far_type=b"default"):             # <<<<<<<<<<<<<<
+ *   def create(cls, source, arc_type="standard", far_type="default"):             # <<<<<<<<<<<<<<
  *     """
  *     FarWriter.
  */
-  __Pyx_GetNameInClass(__pyx_t_2, (PyObject *)__pyx_ptype_9pywrapfst_FarWriter, __pyx_n_s_create); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4553, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_9pywrapfst_FarWriter, __pyx_n_s_create); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4594, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
 
-  /* "pywrapfst.pyx":4552
- *     return "<{} FarWriter at 0x{:x}>".format(self.far_type(), id(self))
+  /* "pywrapfst.pyx":4593
+ *     return f"<{self.far_type()} FarWriter at 0x{id(self):x}>"
  * 
  *   @classmethod             # <<<<<<<<<<<<<<
- *   def create(cls, source, arc_type=b"standard", far_type=b"default"):
+ *   def create(cls, source, arc_type="standard", far_type="default"):
  *     """
  */
-  __pyx_t_1 = __Pyx_Method_ClassMethod(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4552, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_FarWriter->tp_dict, __pyx_n_s_create, __pyx_t_1) < 0) __PYX_ERR(0, 4553, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4593, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_9pywrapfst_FarWriter->tp_dict, __pyx_n_s_create, __pyx_t_2) < 0) __PYX_ERR(0, 4594, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_9pywrapfst_FarWriter);
 
-  /* "pywrapfst.pyx":4644
+  /* "pywrapfst.pyx":4685
  * 
  * # Masks fst_error_fatal in-module.
  * fst.FLAGS_fst_error_fatal = False             # <<<<<<<<<<<<<<
@@ -53539,15 +54467,15 @@ if (!__Pyx_RefNanny) {
  * # Licensed under the Apache License, Version 2.0 (the "License");
  * # you may not use this file except in compliance with the License.
  */
-  __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test_2, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test_2, __pyx_t_2) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
   /* "vector.from_py":45
  * 
- * @cname("__pyx_convert_vector_from_py_int64")
- * cdef vector[X] __pyx_convert_vector_from_py_int64(object o) except *:             # <<<<<<<<<<<<<<
+ * @cname("__pyx_convert_vector_from_py_std_3a__3a_string")
+ * cdef vector[X] __pyx_convert_vector_from_py_std_3a__3a_string(object o) except *:             # <<<<<<<<<<<<<<
  *     cdef vector[X] v
  *     for item in o:
  */
@@ -53625,6 +54553,87 @@ static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
     return result;
 }
 
+/* PyObjectFormatAndDecref */
+static CYTHON_INLINE PyObject* __Pyx_PyObject_FormatSimpleAndDecref(PyObject* s, PyObject* f) {
+    if (unlikely(!s)) return NULL;
+    if (likely(PyUnicode_CheckExact(s))) return s;
+    #if PY_MAJOR_VERSION < 3
+    if (likely(PyString_CheckExact(s))) {
+        PyObject *result = PyUnicode_FromEncodedObject(s, NULL, "strict");
+        Py_DECREF(s);
+        return result;
+    }
+    #endif
+    return __Pyx_PyObject_FormatAndDecref(s, f);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyObject_FormatAndDecref(PyObject* s, PyObject* f) {
+    PyObject *result = PyObject_Format(s, f);
+    Py_DECREF(s);
+    return result;
+}
+
+/* JoinPyUnicode */
+static PyObject* __Pyx_PyUnicode_Join(PyObject* value_tuple, Py_ssize_t value_count, Py_ssize_t result_ulength,
+                                      CYTHON_UNUSED Py_UCS4 max_char) {
+#if CYTHON_USE_UNICODE_INTERNALS && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
+    PyObject *result_uval;
+    int result_ukind;
+    Py_ssize_t i, char_pos;
+    void *result_udata;
+#if CYTHON_PEP393_ENABLED
+    result_uval = PyUnicode_New(result_ulength, max_char);
+    if (unlikely(!result_uval)) return NULL;
+    result_ukind = (max_char <= 255) ? PyUnicode_1BYTE_KIND : (max_char <= 65535) ? PyUnicode_2BYTE_KIND : PyUnicode_4BYTE_KIND;
+    result_udata = PyUnicode_DATA(result_uval);
+#else
+    result_uval = PyUnicode_FromUnicode(NULL, result_ulength);
+    if (unlikely(!result_uval)) return NULL;
+    result_ukind = sizeof(Py_UNICODE);
+    result_udata = PyUnicode_AS_UNICODE(result_uval);
+#endif
+    char_pos = 0;
+    for (i=0; i < value_count; i++) {
+        int ukind;
+        Py_ssize_t ulength;
+        void *udata;
+        PyObject *uval = PyTuple_GET_ITEM(value_tuple, i);
+        if (unlikely(__Pyx_PyUnicode_READY(uval)))
+            goto bad;
+        ulength = __Pyx_PyUnicode_GET_LENGTH(uval);
+        if (unlikely(!ulength))
+            continue;
+        if (unlikely(char_pos + ulength < 0))
+            goto overflow;
+        ukind = __Pyx_PyUnicode_KIND(uval);
+        udata = __Pyx_PyUnicode_DATA(uval);
+        if (!CYTHON_PEP393_ENABLED || ukind == result_ukind) {
+            memcpy((char *)result_udata + char_pos * result_ukind, udata, (size_t) (ulength * result_ukind));
+        } else {
+            #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030300F0 || defined(_PyUnicode_FastCopyCharacters)
+            _PyUnicode_FastCopyCharacters(result_uval, char_pos, uval, 0, ulength);
+            #else
+            Py_ssize_t j;
+            for (j=0; j < ulength; j++) {
+                Py_UCS4 uchar = __Pyx_PyUnicode_READ(ukind, udata, j);
+                __Pyx_PyUnicode_WRITE(result_ukind, result_udata, char_pos+j, uchar);
+            }
+            #endif
+        }
+        char_pos += ulength;
+    }
+    return result_uval;
+overflow:
+    PyErr_SetString(PyExc_OverflowError, "join() result is too long for a Python string");
+bad:
+    Py_DECREF(result_uval);
+    return NULL;
+#else
+    result_ulength++;
+    value_count++;
+    return PyUnicode_Join(__pyx_empty_unicode, value_tuple);
+#endif
+}
+
 /* PyCFunctionFastCall */
 #if CYTHON_FAST_PYCCALL
 static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) {
@@ -53787,35 +54796,6 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg
 }
 #endif
 
-/* PyObjectCall2Args */
-static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) {
-    PyObject *args, *result = NULL;
-    #if CYTHON_FAST_PYCALL
-    if (PyFunction_Check(function)) {
-        PyObject *args[2] = {arg1, arg2};
-        return __Pyx_PyFunction_FastCall(function, args, 2);
-    }
-    #endif
-    #if CYTHON_FAST_PYCCALL
-    if (__Pyx_PyFastCFunction_Check(function)) {
-        PyObject *args[2] = {arg1, arg2};
-        return __Pyx_PyCFunction_FastCall(function, args, 2);
-    }
-    #endif
-    args = PyTuple_New(2);
-    if (unlikely(!args)) goto done;
-    Py_INCREF(arg1);
-    PyTuple_SET_ITEM(args, 0, arg1);
-    Py_INCREF(arg2);
-    PyTuple_SET_ITEM(args, 1, arg2);
-    Py_INCREF(function);
-    result = __Pyx_PyObject_Call(function, args, NULL);
-    Py_DECREF(args);
-    Py_DECREF(function);
-done:
-    return result;
-}
-
 /* PyObjectCallMethO */
 #if CYTHON_COMPILING_IN_CPYTHON
 static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) {
@@ -53876,67 +54856,6 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObjec
 }
 #endif
 
-/* PyDictVersioning */
-#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS
-static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) {
-    PyObject *dict = Py_TYPE(obj)->tp_dict;
-    return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0;
-}
-static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) {
-    PyObject **dictptr = NULL;
-    Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset;
-    if (offset) {
-#if CYTHON_COMPILING_IN_CPYTHON
-        dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj);
-#else
-        dictptr = _PyObject_GetDictPtr(obj);
-#endif
-    }
-    return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0;
-}
-static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) {
-    PyObject *dict = Py_TYPE(obj)->tp_dict;
-    if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict)))
-        return 0;
-    return obj_dict_version == __Pyx_get_object_dict_version(obj);
-}
-#endif
-
-/* GetModuleGlobalName */
-#if CYTHON_USE_DICT_VERSIONS
-static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value)
-#else
-static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name)
-#endif
-{
-    PyObject *result;
-#if !CYTHON_AVOID_BORROWED_REFS
-#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1
-    result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash);
-    __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version)
-    if (likely(result)) {
-        return __Pyx_NewRef(result);
-    } else if (unlikely(PyErr_Occurred())) {
-        return NULL;
-    }
-#else
-    result = PyDict_GetItem(__pyx_d, name);
-    __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version)
-    if (likely(result)) {
-        return __Pyx_NewRef(result);
-    }
-#endif
-#else
-    result = PyObject_GetItem(__pyx_d, name);
-    __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version)
-    if (likely(result)) {
-        return __Pyx_NewRef(result);
-    }
-    PyErr_Clear();
-#endif
-    return __Pyx_GetBuiltinName(name);
-}
-
 /* PyErrFetchRestore */
 #if CYTHON_FAST_THREAD_STATE
 static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) {
@@ -54120,6 +55039,132 @@ bad:
 }
 #endif
 
+/* PyDictVersioning */
+#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS
+static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) {
+    PyObject *dict = Py_TYPE(obj)->tp_dict;
+    return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0;
+}
+static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) {
+    PyObject **dictptr = NULL;
+    Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset;
+    if (offset) {
+#if CYTHON_COMPILING_IN_CPYTHON
+        dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj);
+#else
+        dictptr = _PyObject_GetDictPtr(obj);
+#endif
+    }
+    return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0;
+}
+static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) {
+    PyObject *dict = Py_TYPE(obj)->tp_dict;
+    if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict)))
+        return 0;
+    return obj_dict_version == __Pyx_get_object_dict_version(obj);
+}
+#endif
+
+/* GetModuleGlobalName */
+#if CYTHON_USE_DICT_VERSIONS
+static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value)
+#else
+static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name)
+#endif
+{
+    PyObject *result;
+#if !CYTHON_AVOID_BORROWED_REFS
+#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1
+    result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash);
+    __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version)
+    if (likely(result)) {
+        return __Pyx_NewRef(result);
+    } else if (unlikely(PyErr_Occurred())) {
+        return NULL;
+    }
+#else
+    result = PyDict_GetItem(__pyx_d, name);
+    __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version)
+    if (likely(result)) {
+        return __Pyx_NewRef(result);
+    }
+#endif
+#else
+    result = PyObject_GetItem(__pyx_d, name);
+    __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version)
+    if (likely(result)) {
+        return __Pyx_NewRef(result);
+    }
+    PyErr_Clear();
+#endif
+    return __Pyx_GetBuiltinName(name);
+}
+
+/* PyObjectCall2Args */
+static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) {
+    PyObject *args, *result = NULL;
+    #if CYTHON_FAST_PYCALL
+    if (PyFunction_Check(function)) {
+        PyObject *args[2] = {arg1, arg2};
+        return __Pyx_PyFunction_FastCall(function, args, 2);
+    }
+    #endif
+    #if CYTHON_FAST_PYCCALL
+    if (__Pyx_PyFastCFunction_Check(function)) {
+        PyObject *args[2] = {arg1, arg2};
+        return __Pyx_PyCFunction_FastCall(function, args, 2);
+    }
+    #endif
+    args = PyTuple_New(2);
+    if (unlikely(!args)) goto done;
+    Py_INCREF(arg1);
+    PyTuple_SET_ITEM(args, 0, arg1);
+    Py_INCREF(arg2);
+    PyTuple_SET_ITEM(args, 1, arg2);
+    Py_INCREF(function);
+    result = __Pyx_PyObject_Call(function, args, NULL);
+    Py_DECREF(args);
+    Py_DECREF(function);
+done:
+    return result;
+}
+
+/* PyObjectFormat */
+#if CYTHON_USE_UNICODE_WRITER
+static PyObject* __Pyx_PyObject_Format(PyObject* obj, PyObject* format_spec) {
+    int ret;
+    _PyUnicodeWriter writer;
+    if (likely(PyFloat_CheckExact(obj))) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x03040000
+        _PyUnicodeWriter_Init(&writer, 0);
+#else
+        _PyUnicodeWriter_Init(&writer);
+#endif
+        ret = _PyFloat_FormatAdvancedWriter(
+            &writer,
+            obj,
+            format_spec, 0, PyUnicode_GET_LENGTH(format_spec));
+    } else if (likely(PyLong_CheckExact(obj))) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x03040000
+        _PyUnicodeWriter_Init(&writer, 0);
+#else
+        _PyUnicodeWriter_Init(&writer);
+#endif
+        ret = _PyLong_FormatAdvancedWriter(
+            &writer,
+            obj,
+            format_spec, 0, PyUnicode_GET_LENGTH(format_spec));
+    } else {
+        return PyObject_Format(obj, format_spec);
+    }
+    if (unlikely(ret == -1)) {
+        _PyUnicodeWriter_Dealloc(&writer);
+        return NULL;
+    }
+    return _PyUnicodeWriter_Finish(&writer);
+}
+#endif
+
 /* RaiseArgTupleInvalid */
 static void __Pyx_RaiseArgtupleInvalid(
     const char* func_name,
@@ -54182,7 +55227,7 @@ static int __Pyx_ParseOptionalKeywords(
         }
         name = first_kw_arg;
         #if PY_MAJOR_VERSION < 3
-        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+        if (likely(PyString_Check(key))) {
             while (*name) {
                 if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
                         && _PyString_Eq(**name, key)) {
@@ -54209,7 +55254,7 @@ static int __Pyx_ParseOptionalKeywords(
             while (*name) {
                 int cmp = (**name == key) ? 0 :
                 #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
-                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 :
                 #endif
                     PyUnicode_Compare(**name, key);
                 if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
@@ -54225,7 +55270,7 @@ static int __Pyx_ParseOptionalKeywords(
                 while (argname != first_kw_arg) {
                     int cmp = (**argname == key) ? 0 :
                     #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
-                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                        (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 :
                     #endif
                         PyUnicode_Compare(**argname, key);
                     if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
@@ -54456,65 +55501,10 @@ static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject
 }
 #endif
 
-/* FastTypeChecks */
-#if CYTHON_COMPILING_IN_CPYTHON
-static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) {
-    while (a) {
-        a = a->tp_base;
-        if (a == b)
-            return 1;
-    }
-    return b == &PyBaseObject_Type;
-}
-static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) {
-    PyObject *mro;
-    if (a == b) return 1;
-    mro = a->tp_mro;
-    if (likely(mro)) {
-        Py_ssize_t i, n;
-        n = PyTuple_GET_SIZE(mro);
-        for (i = 0; i < n; i++) {
-            if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b)
-                return 1;
-        }
-        return 0;
-    }
-    return __Pyx_InBases(a, b);
-}
-#if PY_MAJOR_VERSION == 2
-static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) {
-    PyObject *exception, *value, *tb;
-    int res;
-    __Pyx_PyThreadState_declare
-    __Pyx_PyThreadState_assign
-    __Pyx_ErrFetch(&exception, &value, &tb);
-    res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0;
-    if (unlikely(res == -1)) {
-        PyErr_WriteUnraisable(err);
-        res = 0;
-    }
-    if (!res) {
-        res = PyObject_IsSubclass(err, exc_type2);
-        if (unlikely(res == -1)) {
-            PyErr_WriteUnraisable(err);
-            res = 0;
-        }
-    }
-    __Pyx_ErrRestore(exception, value, tb);
-    return res;
-}
-#else
-static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) {
-    int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0;
-    if (!res) {
-        res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2);
-    }
-    return res;
-}
-#endif
-static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) {
+/* PyErrExceptionMatches */
+#if CYTHON_FAST_THREAD_STATE
+static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) {
     Py_ssize_t i, n;
-    assert(PyExceptionClass_Check(exc_type));
     n = PyTuple_GET_SIZE(tuple);
 #if PY_MAJOR_VERSION >= 3
     for (i=0; i<n; i++) {
@@ -54522,37 +55512,17 @@ static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *
     }
 #endif
     for (i=0; i<n; i++) {
-        PyObject *t = PyTuple_GET_ITEM(tuple, i);
-        #if PY_MAJOR_VERSION < 3
-        if (likely(exc_type == t)) return 1;
-        #endif
-        if (likely(PyExceptionClass_Check(t))) {
-            if (__Pyx_inner_PyErr_GivenExceptionMatches2(exc_type, NULL, t)) return 1;
-        } else {
-        }
+        if (__Pyx_PyErr_GivenExceptionMatches(exc_type, PyTuple_GET_ITEM(tuple, i))) return 1;
     }
     return 0;
 }
-static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject* exc_type) {
-    if (likely(err == exc_type)) return 1;
-    if (likely(PyExceptionClass_Check(err))) {
-        if (likely(PyExceptionClass_Check(exc_type))) {
-            return __Pyx_inner_PyErr_GivenExceptionMatches2(err, NULL, exc_type);
-        } else if (likely(PyTuple_Check(exc_type))) {
-            return __Pyx_PyErr_GivenExceptionMatchesTuple(err, exc_type);
-        } else {
-        }
-    }
-    return PyErr_GivenExceptionMatches(err, exc_type);
-}
-static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *exc_type1, PyObject *exc_type2) {
-    assert(PyExceptionClass_Check(exc_type1));
-    assert(PyExceptionClass_Check(exc_type2));
-    if (likely(err == exc_type1 || err == exc_type2)) return 1;
-    if (likely(PyExceptionClass_Check(err))) {
-        return __Pyx_inner_PyErr_GivenExceptionMatches2(err, exc_type1, exc_type2);
-    }
-    return (PyErr_GivenExceptionMatches(err, exc_type1) || PyErr_GivenExceptionMatches(err, exc_type2));
+static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err) {
+    PyObject *exc_type = tstate->curexc_type;
+    if (exc_type == err) return 1;
+    if (unlikely(!exc_type)) return 0;
+    if (unlikely(PyTuple_Check(err)))
+        return __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err);
+    return __Pyx_PyErr_GivenExceptionMatches(exc_type, err);
 }
 #endif
 
@@ -54717,31 +55687,6 @@ static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
     return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
 }
 
-/* PyErrExceptionMatches */
-#if CYTHON_FAST_THREAD_STATE
-static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) {
-    Py_ssize_t i, n;
-    n = PyTuple_GET_SIZE(tuple);
-#if PY_MAJOR_VERSION >= 3
-    for (i=0; i<n; i++) {
-        if (exc_type == PyTuple_GET_ITEM(tuple, i)) return 1;
-    }
-#endif
-    for (i=0; i<n; i++) {
-        if (__Pyx_PyErr_GivenExceptionMatches(exc_type, PyTuple_GET_ITEM(tuple, i))) return 1;
-    }
-    return 0;
-}
-static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err) {
-    PyObject *exc_type = tstate->curexc_type;
-    if (exc_type == err) return 1;
-    if (unlikely(!exc_type)) return 0;
-    if (unlikely(PyTuple_Check(err)))
-        return __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err);
-    return __Pyx_PyErr_GivenExceptionMatches(exc_type, err);
-}
-#endif
-
 /* SwapException */
 #if CYTHON_FAST_THREAD_STATE
 static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) {
@@ -54905,6 +55850,28 @@ bad:
     return -1;
 }
 
+/* PyObjectGetAttrStrNoError */
+static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) {
+    __Pyx_PyThreadState_declare
+    __Pyx_PyThreadState_assign
+    if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError)))
+        __Pyx_PyErr_Clear();
+}
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) {
+    PyObject *result;
+#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1
+    PyTypeObject* tp = Py_TYPE(obj);
+    if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) {
+        return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1);
+    }
+#endif
+    result = __Pyx_PyObject_GetAttrStr(obj, attr_name);
+    if (unlikely(!result)) {
+        __Pyx_PyObject_GetAttrStr_ClearAttributeError();
+    }
+    return result;
+}
+
 /* SetupReduce */
 static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) {
   int ret;
@@ -54950,15 +55917,23 @@ static int __Pyx_setup_reduce(PyObject* type_obj) {
 #endif
         reduce = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce); if (unlikely(!reduce)) goto __PYX_BAD;
         if (reduce == object_reduce || __Pyx_setup_reduce_is_named(reduce, __pyx_n_s_reduce_cython)) {
-            reduce_cython = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce_cython); if (unlikely(!reduce_cython)) goto __PYX_BAD;
-            ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce, reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD;
-            ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD;
+            reduce_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_reduce_cython);
+            if (likely(reduce_cython)) {
+                ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce, reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD;
+                ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD;
+            } else if (reduce == object_reduce || PyErr_Occurred()) {
+                goto __PYX_BAD;
+            }
             setstate = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_setstate);
             if (!setstate) PyErr_Clear();
             if (!setstate || __Pyx_setup_reduce_is_named(setstate, __pyx_n_s_setstate_cython)) {
-                setstate_cython = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_setstate_cython); if (unlikely(!setstate_cython)) goto __PYX_BAD;
-                ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate, setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD;
-                ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD;
+                setstate_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_setstate_cython);
+                if (likely(setstate_cython)) {
+                    ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate, setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD;
+                    ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD;
+                } else if (!setstate || PyErr_Occurred()) {
+                    goto __PYX_BAD;
+                }
             }
             PyType_Modified((PyTypeObject*)type_obj);
         }
@@ -55011,7 +55986,7 @@ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
     {
         #if PY_MAJOR_VERSION >= 3
         if (level == -1) {
-            if (strchr(__Pyx_MODULE_NAME, '.')) {
+            if ((1) && (strchr(__Pyx_MODULE_NAME, '.'))) {
                 module = PyImport_ImportModuleLevelObject(
                     name, global_dict, empty_dict, list, 1);
                 if (!module) {
@@ -55162,6 +56137,7 @@ static PyObject* __Pyx_Method_ClassMethod(PyObject *method) {
 #if CYTHON_COMPILING_IN_PYSTON || CYTHON_COMPILING_IN_PYPY
     if (PyMethodDescr_Check(method))
 #else
+    #if PY_MAJOR_VERSION == 2
     static PyTypeObject *methoddescr_type = NULL;
     if (methoddescr_type == NULL) {
        PyObject *meth = PyObject_GetAttrString((PyObject*)&PyList_Type, "append");
@@ -55169,6 +56145,9 @@ static PyObject* __Pyx_Method_ClassMethod(PyObject *method) {
        methoddescr_type = Py_TYPE(meth);
        Py_DECREF(meth);
     }
+    #else
+    PyTypeObject *methoddescr_type = &PyMethodDescr_Type;
+    #endif
     if (__Pyx_TypeCheck(method, methoddescr_type))
 #endif
     {
@@ -55184,18 +56163,9 @@ static PyObject* __Pyx_Method_ClassMethod(PyObject *method) {
     else if (PyMethod_Check(method)) {
         return PyClassMethod_New(PyMethod_GET_FUNCTION(method));
     }
-    else if (PyCFunction_Check(method)) {
-        return PyClassMethod_New(method);
-    }
-#ifdef __Pyx_CyFunction_USED
-    else if (__Pyx_CyFunction_Check(method)) {
+    else {
         return PyClassMethod_New(method);
     }
-#endif
-    PyErr_SetString(PyExc_TypeError,
-                   "Class-level classmethod() can only be called on "
-                   "a method_descriptor or instance method.");
-    return NULL;
 }
 
 /* GetNameInClass */
@@ -55220,7 +56190,7 @@ static PyObject *__Pyx__GetNameInClass(PyObject *nmspace, PyObject *name) {
 
 /* CLineInTraceback */
 #ifndef CYTHON_CLINE_IN_TRACEBACK
-static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) {
+static int __Pyx_CLineForTraceback(CYTHON_NCP_UNUSED PyThreadState *tstate, int c_line) {
     PyObject *use_cline;
     PyObject *ptype, *pvalue, *ptraceback;
 #if CYTHON_COMPILING_IN_CPYTHON
@@ -55324,7 +56294,7 @@ static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
     if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
         int new_max = __pyx_code_cache.max_count + 64;
         entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
-            __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+            __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry));
         if (unlikely(!entries)) {
             return;
         }
@@ -56579,195 +57549,6 @@ raise_neg_overflow:
 }
 
 /* CIntFromPy */
-static CYTHON_INLINE time_t __Pyx_PyInt_As_time_t(PyObject *x) {
-    const time_t neg_one = (time_t) ((time_t) 0 - (time_t) 1), const_zero = (time_t) 0;
-    const int is_unsigned = neg_one > const_zero;
-#if PY_MAJOR_VERSION < 3
-    if (likely(PyInt_Check(x))) {
-        if (sizeof(time_t) < sizeof(long)) {
-            __PYX_VERIFY_RETURN_INT(time_t, long, PyInt_AS_LONG(x))
-        } else {
-            long val = PyInt_AS_LONG(x);
-            if (is_unsigned && unlikely(val < 0)) {
-                goto raise_neg_overflow;
-            }
-            return (time_t) val;
-        }
-    } else
-#endif
-    if (likely(PyLong_Check(x))) {
-        if (is_unsigned) {
-#if CYTHON_USE_PYLONG_INTERNALS
-            const digit* digits = ((PyLongObject*)x)->ob_digit;
-            switch (Py_SIZE(x)) {
-                case  0: return (time_t) 0;
-                case  1: __PYX_VERIFY_RETURN_INT(time_t, digit, digits[0])
-                case 2:
-                    if (8 * sizeof(time_t) > 1 * PyLong_SHIFT) {
-                        if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) {
-                            __PYX_VERIFY_RETURN_INT(time_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
-                        } else if (8 * sizeof(time_t) >= 2 * PyLong_SHIFT) {
-                            return (time_t) (((((time_t)digits[1]) << PyLong_SHIFT) | (time_t)digits[0]));
-                        }
-                    }
-                    break;
-                case 3:
-                    if (8 * sizeof(time_t) > 2 * PyLong_SHIFT) {
-                        if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) {
-                            __PYX_VERIFY_RETURN_INT(time_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
-                        } else if (8 * sizeof(time_t) >= 3 * PyLong_SHIFT) {
-                            return (time_t) (((((((time_t)digits[2]) << PyLong_SHIFT) | (time_t)digits[1]) << PyLong_SHIFT) | (time_t)digits[0]));
-                        }
-                    }
-                    break;
-                case 4:
-                    if (8 * sizeof(time_t) > 3 * PyLong_SHIFT) {
-                        if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) {
-                            __PYX_VERIFY_RETURN_INT(time_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
-                        } else if (8 * sizeof(time_t) >= 4 * PyLong_SHIFT) {
-                            return (time_t) (((((((((time_t)digits[3]) << PyLong_SHIFT) | (time_t)digits[2]) << PyLong_SHIFT) | (time_t)digits[1]) << PyLong_SHIFT) | (time_t)digits[0]));
-                        }
-                    }
-                    break;
-            }
-#endif
-#if CYTHON_COMPILING_IN_CPYTHON
-            if (unlikely(Py_SIZE(x) < 0)) {
-                goto raise_neg_overflow;
-            }
-#else
-            {
-                int result = PyObject_RichCompareBool(x, Py_False, Py_LT);
-                if (unlikely(result < 0))
-                    return (time_t) -1;
-                if (unlikely(result == 1))
-                    goto raise_neg_overflow;
-            }
-#endif
-            if (sizeof(time_t) <= sizeof(unsigned long)) {
-                __PYX_VERIFY_RETURN_INT_EXC(time_t, unsigned long, PyLong_AsUnsignedLong(x))
-#ifdef HAVE_LONG_LONG
-            } else if (sizeof(time_t) <= sizeof(unsigned PY_LONG_LONG)) {
-                __PYX_VERIFY_RETURN_INT_EXC(time_t, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x))
-#endif
-            }
-        } else {
-#if CYTHON_USE_PYLONG_INTERNALS
-            const digit* digits = ((PyLongObject*)x)->ob_digit;
-            switch (Py_SIZE(x)) {
-                case  0: return (time_t) 0;
-                case -1: __PYX_VERIFY_RETURN_INT(time_t, sdigit, (sdigit) (-(sdigit)digits[0]))
-                case  1: __PYX_VERIFY_RETURN_INT(time_t,  digit, +digits[0])
-                case -2:
-                    if (8 * sizeof(time_t) - 1 > 1 * PyLong_SHIFT) {
-                        if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) {
-                            __PYX_VERIFY_RETURN_INT(time_t, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
-                        } else if (8 * sizeof(time_t) - 1 > 2 * PyLong_SHIFT) {
-                            return (time_t) (((time_t)-1)*(((((time_t)digits[1]) << PyLong_SHIFT) | (time_t)digits[0])));
-                        }
-                    }
-                    break;
-                case 2:
-                    if (8 * sizeof(time_t) > 1 * PyLong_SHIFT) {
-                        if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) {
-                            __PYX_VERIFY_RETURN_INT(time_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
-                        } else if (8 * sizeof(time_t) - 1 > 2 * PyLong_SHIFT) {
-                            return (time_t) ((((((time_t)digits[1]) << PyLong_SHIFT) | (time_t)digits[0])));
-                        }
-                    }
-                    break;
-                case -3:
-                    if (8 * sizeof(time_t) - 1 > 2 * PyLong_SHIFT) {
-                        if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) {
-                            __PYX_VERIFY_RETURN_INT(time_t, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
-                        } else if (8 * sizeof(time_t) - 1 > 3 * PyLong_SHIFT) {
-                            return (time_t) (((time_t)-1)*(((((((time_t)digits[2]) << PyLong_SHIFT) | (time_t)digits[1]) << PyLong_SHIFT) | (time_t)digits[0])));
-                        }
-                    }
-                    break;
-                case 3:
-                    if (8 * sizeof(time_t) > 2 * PyLong_SHIFT) {
-                        if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) {
-                            __PYX_VERIFY_RETURN_INT(time_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
-                        } else if (8 * sizeof(time_t) - 1 > 3 * PyLong_SHIFT) {
-                            return (time_t) ((((((((time_t)digits[2]) << PyLong_SHIFT) | (time_t)digits[1]) << PyLong_SHIFT) | (time_t)digits[0])));
-                        }
-                    }
-                    break;
-                case -4:
-                    if (8 * sizeof(time_t) - 1 > 3 * PyLong_SHIFT) {
-                        if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) {
-                            __PYX_VERIFY_RETURN_INT(time_t, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
-                        } else if (8 * sizeof(time_t) - 1 > 4 * PyLong_SHIFT) {
-                            return (time_t) (((time_t)-1)*(((((((((time_t)digits[3]) << PyLong_SHIFT) | (time_t)digits[2]) << PyLong_SHIFT) | (time_t)digits[1]) << PyLong_SHIFT) | (time_t)digits[0])));
-                        }
-                    }
-                    break;
-                case 4:
-                    if (8 * sizeof(time_t) > 3 * PyLong_SHIFT) {
-                        if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) {
-                            __PYX_VERIFY_RETURN_INT(time_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
-                        } else if (8 * sizeof(time_t) - 1 > 4 * PyLong_SHIFT) {
-                            return (time_t) ((((((((((time_t)digits[3]) << PyLong_SHIFT) | (time_t)digits[2]) << PyLong_SHIFT) | (time_t)digits[1]) << PyLong_SHIFT) | (time_t)digits[0])));
-                        }
-                    }
-                    break;
-            }
-#endif
-            if (sizeof(time_t) <= sizeof(long)) {
-                __PYX_VERIFY_RETURN_INT_EXC(time_t, long, PyLong_AsLong(x))
-#ifdef HAVE_LONG_LONG
-            } else if (sizeof(time_t) <= sizeof(PY_LONG_LONG)) {
-                __PYX_VERIFY_RETURN_INT_EXC(time_t, PY_LONG_LONG, PyLong_AsLongLong(x))
-#endif
-            }
-        }
-        {
-#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
-            PyErr_SetString(PyExc_RuntimeError,
-                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
-#else
-            time_t val;
-            PyObject *v = __Pyx_PyNumber_IntOrLong(x);
- #if PY_MAJOR_VERSION < 3
-            if (likely(v) && !PyLong_Check(v)) {
-                PyObject *tmp = v;
-                v = PyNumber_Long(tmp);
-                Py_DECREF(tmp);
-            }
- #endif
-            if (likely(v)) {
-                int one = 1; int is_little = (int)*(unsigned char *)&one;
-                unsigned char *bytes = (unsigned char *)&val;
-                int ret = _PyLong_AsByteArray((PyLongObject *)v,
-                                              bytes, sizeof(val),
-                                              is_little, !is_unsigned);
-                Py_DECREF(v);
-                if (likely(!ret))
-                    return val;
-            }
-#endif
-            return (time_t) -1;
-        }
-    } else {
-        time_t val;
-        PyObject *tmp = __Pyx_PyNumber_IntOrLong(x);
-        if (!tmp) return (time_t) -1;
-        val = __Pyx_PyInt_As_time_t(tmp);
-        Py_DECREF(tmp);
-        return val;
-    }
-raise_overflow:
-    PyErr_SetString(PyExc_OverflowError,
-        "value too large to convert to time_t");
-    return (time_t) -1;
-raise_neg_overflow:
-    PyErr_SetString(PyExc_OverflowError,
-        "can't convert negative value to time_t");
-    return (time_t) -1;
-}
-
-/* CIntFromPy */
 static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {
     const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0;
     const int is_unsigned = neg_one > const_zero;
@@ -57145,6 +57926,106 @@ raise_neg_overflow:
     return (int) -1;
 }
 
+/* FastTypeChecks */
+#if CYTHON_COMPILING_IN_CPYTHON
+static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) {
+    while (a) {
+        a = a->tp_base;
+        if (a == b)
+            return 1;
+    }
+    return b == &PyBaseObject_Type;
+}
+static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) {
+    PyObject *mro;
+    if (a == b) return 1;
+    mro = a->tp_mro;
+    if (likely(mro)) {
+        Py_ssize_t i, n;
+        n = PyTuple_GET_SIZE(mro);
+        for (i = 0; i < n; i++) {
+            if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b)
+                return 1;
+        }
+        return 0;
+    }
+    return __Pyx_InBases(a, b);
+}
+#if PY_MAJOR_VERSION == 2
+static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) {
+    PyObject *exception, *value, *tb;
+    int res;
+    __Pyx_PyThreadState_declare
+    __Pyx_PyThreadState_assign
+    __Pyx_ErrFetch(&exception, &value, &tb);
+    res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0;
+    if (unlikely(res == -1)) {
+        PyErr_WriteUnraisable(err);
+        res = 0;
+    }
+    if (!res) {
+        res = PyObject_IsSubclass(err, exc_type2);
+        if (unlikely(res == -1)) {
+            PyErr_WriteUnraisable(err);
+            res = 0;
+        }
+    }
+    __Pyx_ErrRestore(exception, value, tb);
+    return res;
+}
+#else
+static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) {
+    int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0;
+    if (!res) {
+        res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2);
+    }
+    return res;
+}
+#endif
+static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) {
+    Py_ssize_t i, n;
+    assert(PyExceptionClass_Check(exc_type));
+    n = PyTuple_GET_SIZE(tuple);
+#if PY_MAJOR_VERSION >= 3
+    for (i=0; i<n; i++) {
+        if (exc_type == PyTuple_GET_ITEM(tuple, i)) return 1;
+    }
+#endif
+    for (i=0; i<n; i++) {
+        PyObject *t = PyTuple_GET_ITEM(tuple, i);
+        #if PY_MAJOR_VERSION < 3
+        if (likely(exc_type == t)) return 1;
+        #endif
+        if (likely(PyExceptionClass_Check(t))) {
+            if (__Pyx_inner_PyErr_GivenExceptionMatches2(exc_type, NULL, t)) return 1;
+        } else {
+        }
+    }
+    return 0;
+}
+static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject* exc_type) {
+    if (likely(err == exc_type)) return 1;
+    if (likely(PyExceptionClass_Check(err))) {
+        if (likely(PyExceptionClass_Check(exc_type))) {
+            return __Pyx_inner_PyErr_GivenExceptionMatches2(err, NULL, exc_type);
+        } else if (likely(PyTuple_Check(exc_type))) {
+            return __Pyx_PyErr_GivenExceptionMatchesTuple(err, exc_type);
+        } else {
+        }
+    }
+    return PyErr_GivenExceptionMatches(err, exc_type);
+}
+static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *exc_type1, PyObject *exc_type2) {
+    assert(PyExceptionClass_Check(exc_type1));
+    assert(PyExceptionClass_Check(exc_type2));
+    if (likely(err == exc_type1 || err == exc_type2)) return 1;
+    if (likely(PyExceptionClass_Check(err))) {
+        return __Pyx_inner_PyErr_GivenExceptionMatches2(err, exc_type1, exc_type2);
+    }
+    return (PyErr_GivenExceptionMatches(err, exc_type1) || PyErr_GivenExceptionMatches(err, exc_type2));
+}
+#endif
+
 /* FetchCommonType */
 static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) {
     PyObject* fake_module;
index a7e94f1..583436e 100644 (file)
@@ -3,9 +3,6 @@
 # finite-state transducer library.
 
 
-from libc.time cimport time
-from libc.time cimport time_t
-
 from libcpp cimport bool
 from libcpp.memory cimport shared_ptr
 from libcpp.memory cimport unique_ptr
@@ -13,14 +10,15 @@ from libcpp.string cimport string
 from libcpp.utility cimport pair
 from libcpp.vector cimport vector
 
-from cintegral_types cimport *
-
-cimport cpywrapfst as fst
-
+from cintegral_types cimport int32
+from cintegral_types cimport int64
+from cintegral_types cimport uint8
+from cintegral_types cimport uint64
 from cios cimport ostream
-from cios cimport ofstream
 from cios cimport stringstream
 
+cimport cpywrapfst as fst
+
 
 # Exportable helper functions.
 
@@ -29,6 +27,8 @@ cdef string tostring(data) except *
 
 cdef string weight_tostring(data) except *
 
+cdef string path_tostring(data) except *
+
 cdef fst.ComposeFilter _get_compose_filter(
     const string &compose_filter) except *
 
@@ -90,7 +90,7 @@ ctypedef fst.SymbolTable * SymbolTable_ptr
 ctypedef const fst.SymbolTable * const_SymbolTable_ptr
 
 
-cdef class _SymbolTable(object):
+cdef class SymbolTableView(object):
 
   cdef const fst.SymbolTable *_raw(self)
 
@@ -121,7 +121,7 @@ cdef class _SymbolTable(object):
   cpdef bytes write_to_string(self)
 
 
-cdef class _EncodeMapperSymbolTableView(_SymbolTable):
+cdef class _EncodeMapperSymbolTableView(SymbolTableView):
 
   # Indicates whether this view is of an input or output SymbolTable
   cdef bool _input_side
@@ -129,7 +129,7 @@ cdef class _EncodeMapperSymbolTableView(_SymbolTable):
   cdef shared_ptr[fst.EncodeMapperClass] _mapper
 
 
-cdef class _FstSymbolTableView(_SymbolTable):
+cdef class _FstSymbolTableView(SymbolTableView):
 
   # Indicates whether this view is of an input or output SymbolTable
   cdef bool _input_side
@@ -137,7 +137,7 @@ cdef class _FstSymbolTableView(_SymbolTable):
   cdef shared_ptr[fst.FstClass] _fst
 
 
-cdef class _MutableSymbolTable(_SymbolTable):
+cdef class _MutableSymbolTable(SymbolTableView):
 
   cdef fst.SymbolTable *_mutable_raw(self)
 
@@ -145,7 +145,7 @@ cdef class _MutableSymbolTable(_SymbolTable):
 
   cpdef int64 add_symbol(self, symbol, int64 key=?) except *
 
-  cpdef void add_table(self, _SymbolTable syms) except *
+  cpdef void add_table(self, SymbolTableView syms) except *
 
   cpdef void set_name(self, new_name) except *
 
@@ -178,12 +178,12 @@ cdef _MutableFstSymbolTableView _init_MutableFstSymbolTableView(
 cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] table)
 
 
-cpdef _SymbolTable _read_SymbolTable_from_string(state)
+cpdef SymbolTable _read_SymbolTable_from_string(string state)
 
 
 cdef class _SymbolTableIterator(object):
 
-  cdef _SymbolTable _table
+  cdef SymbolTableView _table
   cdef unique_ptr[fst.SymbolTableIterator] _siter
 
 
@@ -213,14 +213,14 @@ cdef class EncodeMapper(object):
 
   cpdef _EncodeMapperSymbolTableView output_symbols(self)
 
-  cdef void _set_input_symbols(self, _SymbolTable syms) except *
+  cdef void _set_input_symbols(self, SymbolTableView syms) except *
 
-  cdef void _set_output_symbols(self, _SymbolTable syms) except *
+  cdef void _set_output_symbols(self, SymbolTableView syms) except *
 
 
 cdef EncodeMapper _init_EncodeMapper(EncodeMapperClass_ptr mapper)
 
-cpdef EncodeMapper _read_EncodeMapper_from_string(state)
+cpdef EncodeMapper _read_EncodeMapper_from_string(string state)
 
 
 # Fst.
@@ -252,9 +252,9 @@ cdef class Fst(object):
 
   cpdef void draw(self,
                   source,
-                  _SymbolTable isymbols=?,
-                  _SymbolTable osymbols=?,
-                  _SymbolTable ssymbols=?,
+                  SymbolTableView isymbols=?,
+                  SymbolTableView osymbols=?,
+                  SymbolTableView ssymbols=?,
                   bool acceptor=?,
                   title=?,
                   double width=?,
@@ -283,9 +283,9 @@ cdef class Fst(object):
   cpdef _FstSymbolTableView output_symbols(self)
 
   cpdef string print(self,
-                    _SymbolTable isymbols=?,
-                    _SymbolTable osymbols=?,
-                    _SymbolTable ssymbols=?,
+                    SymbolTableView isymbols=?,
+                    SymbolTableView osymbols=?,
+                    SymbolTableView ssymbols=?,
                     bool acceptor=?,
                     bool show_weight_one=?,
                     missing_sym=?) except *
@@ -296,14 +296,6 @@ cdef class Fst(object):
 
   cpdef StateIterator states(self)
 
-  cpdef string text(self,
-                    _SymbolTable isymbols=?,
-                    _SymbolTable osymbols=?,
-                    _SymbolTable ssymbols=?,
-                    bool acceptor=?,
-                    bool show_weight_one=?,
-                    missing_sym=?) except *
-
   cpdef bool verify(self)
 
   cpdef string weight_type(self)
@@ -349,7 +341,7 @@ cdef class MutableFst(Fst):
 
   cpdef int64 num_states(self)
 
-  cdef void _project(self, bool project_output=?) except *
+  cdef void _project(self, project_type) except *
 
   cdef void _prune(self, float delta=?, int64 nstate=?, weight=?) except *
 
@@ -361,12 +353,12 @@ cdef class MutableFst(Fst):
   cdef void _relabel_pairs(self, ipairs=?, opairs=?) except *
 
   cdef void _relabel_tables(self,
-                            _SymbolTable old_isymbols=?,
-                            _SymbolTable new_isymbols=?,
+                            SymbolTableView old_isymbols=?,
+                            SymbolTableView new_isymbols=?,
                             unknown_isymbol=?,
                             bool attach_new_isymbols=?,
-                            _SymbolTable old_osymbols=?,
-                            _SymbolTable new_osymbols=?,
+                            SymbolTableView old_osymbols=?,
+                            SymbolTableView new_osymbols=?,
                             unknown_osymbol=?,
                             bool attach_new_osymbols=?) except *
 
@@ -389,9 +381,9 @@ cdef class MutableFst(Fst):
 
   cdef void _set_start(self, int64 state) except *
 
-  cdef void _set_input_symbols(self, _SymbolTable syms) except *
+  cdef void _set_input_symbols(self, SymbolTableView syms) except *
 
-  cdef void _set_output_symbols(self, _SymbolTable syms) except *
+  cdef void _set_output_symbols(self, SymbolTableView syms) except *
 
   cdef void _topsort(self)
 
@@ -412,7 +404,7 @@ cdef Fst _init_XFst(FstClass_ptr tfst)
 
 cpdef Fst _read_Fst(source)
 
-cpdef Fst _read_Fst_from_string(state)
+cpdef Fst _read_Fst_from_string(string state)
 
 
 # Iterators.
@@ -571,11 +563,12 @@ cpdef MutableFst replace(pairs,
 
 cpdef MutableFst reverse(Fst ifst, bool require_superinitial=?)
 
-cdef vector[fst.WeightClass] *_shortestdistance(Fst ifst,
-                                                float delta=?,
-                                                int64 nstate=?,
-                                                queue_type=?,
-                                                bool reverse=?) except *
+cdef void _shortestdistance(Fst ifst,
+                            vector[fst.WeightClass] *,
+                            float delta=?,
+                            int64 nstate=?,
+                            queue_type=?,
+                            bool reverse=?) except *
 
 cpdef MutableFst shortestpath(Fst ifst,
                               float delta=?,
index cfa5113..b9ec279 100644 (file)
@@ -32,7 +32,7 @@ normal `k` prefix.
 # * Custom exceptions
 # * General helpers
 # * Weight and helpers
-# * _SymbolTable, _EncodeMapperSymbolTableView, _FstSymbolTableView,
+# * SymbolTableView, _EncodeMapperSymbolTableView, _FstSymbolTableView,
 #   _MutableFstSymbolTableView, SymbolTable, and helpers
 # * _SymbolTableIterator
 # * EncodeMapper
@@ -69,7 +69,7 @@ from cython.operator cimport preincrement as inc   # ++foo
 # C imports.
 from libc.stdint cimport INT32_MAX
 from libc.stdint cimport SIZE_MAX
-from posix.unistd cimport getpid
+from libc.time cimport time
 
 # C++ imports.
 from libcpp cimport bool
@@ -84,12 +84,9 @@ from cutility cimport move
 # Python imports.
 import logging
 import numbers
+import os
 import subprocess
-
-# TODO(kbg): Used to handle the deprecation of `text`; remove on next release.
-import warnings
-
-warnings.simplefilter("always", DeprecationWarning)
+import sys
 
 # Google-only...
 # This only works, and is only needed, inside of Colab.
@@ -102,6 +99,41 @@ except ImportError:
 # ...Google-only.
 
 
+## Custom types.
+
+# These defintions only ensure that these are defined to avoid attribute errors,
+# but don't actually contain the type definitions. Those are in pywrapfst.pyi.
+import typing
+
+ArcMapType = """typing.Literal["identity", "input_epsilon", "invert",
+                               "output_epsilon", "plus", "power", "quantize",
+                               "rmweight", "superfinal", "times", "to_log",
+                               # NOTE: Both spellings of "to_std"
+                               "to_log64", "to_std", "to_standard"]"""
+ComposeFilter = """typing.Literal["alt_sequence", "auto", "match", "no_match",
+                           "null", "sequence", "trivial"]"""
+DeterminizeType = """typing.Literal["functional", "nonfunctional",
+                                    "disambiguate"]"""
+DrawFloatFormat = """typing.Literal["e", "f", "g"]"""
+FarType = """typing.Literal[
+  "fst",
+  "stlist",
+  "sttable",
+  # Google-only...
+  "sstable",
+  # ...Google-only.
+  "default"
+]"""
+ProjectType = """typing.Literal["input", "output"]"""
+QueueType = """typing.Literal["auto", "fifo", "lifo", "shortest", "state",
+                              "top"]"""
+RandArcSelection = """typing.Literal["uniform", "log_prob", "fast_log_prob"]"""
+ReplaceLabelType = """typing.Literal["neither", "input", "output", "both"]"""
+SortType = """typing.Literal["ilabel", "olabel"]"""
+StateMapType = """typing.Literal["arc_sum", "arc_unique", "identity"]"""
+
+WeightLike = "typing.Union[Weight, typing.Union[str, int, float]]"
+
 ## Custom exceptions.
 
 
@@ -120,11 +152,6 @@ class FstBadWeightError(FstError, ValueError):
   pass
 
 
-class FstDeletedConstructorError(FstError, RuntimeError):
-
-  pass
-
-
 class FstIndexError(FstError, IndexError):
 
   pass
@@ -146,7 +173,7 @@ class FstOpError(FstError, RuntimeError):
 cdef string tostring(data) except *:
   """Converts strings to bytestrings.
 
-  This function converts Python bytestrings and Unicode strings to bytestrings
+  This function converts Python Unicode strings to bytestrings
   encoded in UTF-8. It is used to process most Python string arguments before
   passing them to the lower-level library.
 
@@ -157,50 +184,70 @@ cdef string tostring(data) except *:
     A bytestring.
 
   Raises:
-    FstArgError: Cannot encode string.
-    UnicodeEncodeError.
+    TypeError: Cannot encode string.
 
   This function is not visible to Python users.
   """
-  # A Python bytestring can be implicitly cast to a C++ string.
-  if isinstance(data, bytes):
+  # A Python string can be implicitly cast to a C++ string.
+  if isinstance(data, str):
     return data
-  elif isinstance(data, unicode):
-    return data.encode("utf8")
-  raise FstArgError("Cannot encode as string: {!r}".format(data))
+  raise TypeError(f"Expected {str.__name__} but received "
+                  f"{type(data).__name__}: {data!r}")
 
 
 cdef string weight_tostring(data) except *:
   """Converts strings or numerics to bytestrings.
 
-  This function converts Python bytestrings, Unicode strings, and numerics
+  This function converts Python Unicode strings and numerics
   which can be cast to floats to bytestrings encoded in UTF-8. It is used to
   process Python string arguments so they can be used to construct Weight
   objects. In most cases, weights are underlyingly floating-point, but since
   not all weights are, they can only be constructed using a string.
 
   Args:
-    data: A Unicode string, bytestring, or type which can be converted to a
-      Python float.
+    data: A Unicode string or type which can be converted to a Python float.
 
   Returns:
     A bytestring.
 
   Raise:
-    FstArgError: Cannot encode string.
+    TypeError: Cannot encode string.
     ValueError: Invalid literal for float.
-    UnicodeEncodeError.
 
   This function is not visible to Python users.
   """
-  # A Python bytestring can be implicitly cast to a C++ string.
-  if isinstance(data, bytes):
+  # A Python string can be implicitly cast to a C++ string.
+  if isinstance(data, str):
     return data
-  elif isinstance(data, unicode):
-    return data.encode("utf8")
   elif isinstance(data, numbers.Number):
-    return str(data).encode("utf8")
-  raise FstArgError("Cannot encode as string: {!r}".format(data))
+    return str(data)
+  raise TypeError(f"Expected {str.__name__} but received "
+                  f"{type(data).__name__}: {data!r}")
+
+
+cdef string path_tostring(data) except *:
+  return tostring(os.fspath(data))
+
+
+cdef fst.FarType _get_far_type(const string &far_type) except *:
+  """Matches string with the appropriate FarType enum value.
+
+  Args:
+    far_type: A string indicating the FAR type; one of: "fst", "stlist",
+              "sttable", "sstable", "default".
+
+  Returns:
+    A FarType enum value.
+
+  Raises:
+    FstArgError: Unknown FAR type.
+
+  This function is not visible to Python users.
+  """
+  cdef fst.FarType _far_type
+  if not fst.GetFarType(far_type, addr(_far_type)):
+    raise FstArgError(f"Unknown FAR type: {far_type!r}")
+  return _far_type
 
 
 cdef fst.ComposeFilter _get_compose_filter(
@@ -224,11 +271,10 @@ cdef fst.ComposeFilter _get_compose_filter(
 
   This function is not visible to Python users.
   """
-  cdef fst.ComposeFilter compose_filter_enum
-  if not fst.GetComposeFilter(compose_filter, addr(compose_filter_enum)):
-    raise FstArgError("Unknown compose filter type: {!r}".format(
-        compose_filter))
-  return compose_filter_enum
+  cdef fst.ComposeFilter _compose_filter
+  if not fst.GetComposeFilter(compose_filter, addr(_compose_filter)):
+    raise FstArgError(f"Unknown compose filter type: {compose_filter!r}")
+  return _compose_filter
 
 
 cdef fst.DeterminizeType _get_determinize_type(const string &det_type) except *:
@@ -246,10 +292,31 @@ cdef fst.DeterminizeType _get_determinize_type(const string &det_type) except *:
 
   This function is not visible to Python users.
   """
-  cdef fst.DeterminizeType det_type_enum
-  if not fst.GetDeterminizeType(det_type, addr(det_type_enum)):
-    raise FstArgError("Unknown determinization type: {!r}".format(det_type))
-  return det_type_enum
+  cdef fst.DeterminizeType _det_type
+  if not fst.GetDeterminizeType(det_type, addr(_det_type)):
+    raise FstArgError(f"Unknown determinization type: {det_type!r}")
+  return _det_type
+
+
+cdef fst.ProjectType _get_project_type(const string &project_type) except *:
+  """Matches string with the appropriate ProjectType enum value.
+
+  Args:
+    project_type: A string matching a known projection type; one of:
+        "input", "output".
+
+  Returns:
+    A ProjectType enum value.
+
+  Raises:
+    FstArgError: Unknown projection type.
+
+  This function is not visible to Python users.
+  """
+  cdef fst.ProjectType _project_type
+  if not fst.GetProjectType(project_type, addr(_project_type)):
+    raise FstArgError(f"Unknown projection type: {project_type!r}")
+  return _project_type
 
 
 cdef fst.QueueType _get_queue_type(const string &queue_type) except *:
@@ -270,10 +337,10 @@ cdef fst.QueueType _get_queue_type(const string &queue_type) except *:
 
   This function is not visible to Python users.
   """
-  cdef fst.QueueType queue_type_enum
-  if not fst.GetQueueType(queue_type, addr(queue_type_enum)):
-    raise FstArgError("Unknown queue type: {!r}".format(queue_type))
-  return queue_type_enum
+  cdef fst.QueueType _queue_type
+  if not fst.GetQueueType(queue_type, addr(_queue_type)):
+    raise FstArgError(f"Unknown queue type: {queue_type!r}")
+  return _queue_type
 
 
 cdef fst.RandArcSelection _get_rand_arc_selection(
@@ -295,10 +362,10 @@ cdef fst.RandArcSelection _get_rand_arc_selection(
 
   This function is not visible to Python users.
   """
-  cdef fst.RandArcSelection select_enum
-  if not fst.GetRandArcSelection(select, addr(select_enum)):
-    raise FstArgError("Unknown random arc selection type: {!r}".format(select))
-  return select_enum
+  cdef fst.RandArcSelection _select
+  if not fst.GetRandArcSelection(select, addr(_select)):
+    raise FstArgError(f"Unknown random arc selection type: {select!r}")
+  return _select
 
 
 cdef fst.ReplaceLabelType _get_replace_label_type(
@@ -321,12 +388,12 @@ cdef fst.ReplaceLabelType _get_replace_label_type(
 
   This function is not visible to Python users.
   """
-  cdef fst.ReplaceLabelType replace_label_type_enum
-  if not fst.GetReplaceLabelType(replace_label_type, epsilon_on_replace,
-                                 addr(replace_label_type_enum)):
-    raise FstArgError("Unknown replace label type: {!r}".format(
-                      replace_label_type))
-  return replace_label_type_enum
+  cdef fst.ReplaceLabelType _replace_label_type
+  if not fst.GetReplaceLabelType(replace_label_type,
+                                 epsilon_on_replace,
+                                 addr(_replace_label_type)):
+    raise FstArgError(f"Unknown replace label type: {replace_label_type!r}")
+  return _replace_label_type
 
 
 ## Weight and helpers.
@@ -353,8 +420,7 @@ cdef class Weight:
   """
 
   def __repr__(self):
-    return "<{} Weight {} at 0x{:x}>".format(self.type(), self.to_string(),
-                                             id(self))
+    return f"<{self.type()} Weight {self.to_string()} at 0x{id(self):x}>"
 
   def __str__(self):
     return self.to_string()
@@ -382,9 +448,9 @@ cdef class Weight:
 
     Returns a copy of the Weight.
     """
-    cdef Weight result = Weight.__new__(Weight)
-    result._weight.reset(new fst.WeightClass(deref(self._weight)))
-    return result
+    cdef Weight _weight = Weight.__new__(Weight)
+    _weight._weight.reset(new fst.WeightClass(deref(self._weight)))
+    return _weight
 
   # To get around the inability to declare cdef class methods, we define the
   # C++ part out-of-class and then call it from within.
@@ -437,10 +503,10 @@ cdef class Weight:
 
 
 cdef Weight _plus(Weight lhs, Weight rhs):
-  cdef Weight result = Weight.__new__(Weight)
-  result._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),
-                                                    deref(rhs._weight))))
-  return result
+  cdef Weight _weight = Weight.__new__(Weight)
+  _weight._weight.reset(new fst.WeightClass(fst.Plus(deref(lhs._weight),
+                                                     deref(rhs._weight))))
+  return _weight
 
 
 def plus(Weight lhs, Weight rhs):
@@ -463,16 +529,16 @@ def plus(Weight lhs, Weight rhs):
     FstArgError: Weight type not found (or not in same semiring).
     FstBadWeightError: invalid weight.
   """
-  cdef Weight result = _plus(lhs, rhs)
-  result._check_weight()
-  return result
+  cdef Weight _weight = _plus(lhs, rhs)
+  _weight._check_weight()
+  return _weight
 
 
 cdef Weight _times(Weight lhs, Weight rhs):
-  cdef Weight result = Weight.__new__(Weight)
-  result._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),
-                                                     deref(rhs._weight))))
-  return result
+  cdef Weight _weight = Weight.__new__(Weight)
+  _weight._weight.reset(new fst.WeightClass(fst.Times(deref(lhs._weight),
+                                                      deref(rhs._weight))))
+  return _weight
 
 
 def times(Weight lhs, Weight rhs):
@@ -495,16 +561,16 @@ def times(Weight lhs, Weight rhs):
     FstArgError: Weight type not found (or not in same semiring).
     FstBadWeightError: Invalid weight.
   """
-  cdef Weight result = _times(lhs, rhs)
-  result._check_weight()
-  return result
+  cdef Weight _weight = _times(lhs, rhs)
+  _weight._check_weight()
+  return _weight
 
 
 cdef Weight _divide(Weight lhs, Weight rhs):
-  cdef Weight result = Weight.__new__(Weight)
-  result._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),
-                                                      deref(rhs._weight))))
-  return result
+  cdef Weight _weight = Weight.__new__(Weight)
+  _weight._weight.reset(new fst.WeightClass(fst.Divide(deref(lhs._weight),
+                                                       deref(rhs._weight))))
+  return _weight
 
 
 def divide(Weight lhs, Weight rhs):
@@ -529,15 +595,15 @@ def divide(Weight lhs, Weight rhs):
     FstArgError: Weight type not found (or not in same semiring).
     FstBadWeightError: Invalid weight.
   """
-  cdef Weight result = _divide(lhs, rhs)
-  result._check_weight()
-  return result
+  cdef Weight _weight = _divide(lhs, rhs)
+  _weight._check_weight()
+  return _weight
 
 
 cdef Weight _power(Weight w, size_t n):
-  cdef Weight result = Weight.__new__(Weight)
-  result._weight.reset(new fst.WeightClass(fst.Power(deref(w._weight), n)))
-  return result
+  cdef Weight _weight = Weight.__new__(Weight)
+  _weight._weight.reset(new fst.WeightClass(fst.Power(deref(w._weight), n)))
+  return _weight
 
 
 def power(Weight w, size_t n):
@@ -557,9 +623,9 @@ def power(Weight w, size_t n):
     FstArgError: Weight type not found (or not in same semiring).
     FstBadWeightError: Invalid weight.
   """
-  cdef Weight result = _power(w, n)
-  result._check_weight()
-  return result
+  cdef Weight _weight = _power(w, n)
+  _weight._check_weight()
+  return _weight
 
 
 cdef fst.WeightClass _get_WeightClass_or_Zero(const string &weight_type,
@@ -579,16 +645,16 @@ cdef fst.WeightClass _get_WeightClass_or_Zero(const string &weight_type,
 
   This function is not visible to Python users.
   """
-  cdef fst.WeightClass result
+  cdef fst.WeightClass _weight
   if weight is None:
-    result = fst.WeightClass.Zero(weight_type)
+    _weight = fst.WeightClass.Zero(weight_type)
   elif isinstance(weight, Weight):
-    result = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
+    _weight = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
   else:
-    result = fst.WeightClass(weight_type, weight_tostring(weight))
-    if not result.Member():
+    _weight = fst.WeightClass(weight_type, weight_tostring(weight))
+    if not _weight.Member():
       raise FstBadWeightError(weight_tostring(weight))
-  return result
+  return _weight
 
 
 cdef fst.WeightClass _get_WeightClass_or_One(const string &weight_type,
@@ -608,61 +674,59 @@ cdef fst.WeightClass _get_WeightClass_or_One(const string &weight_type,
 
   This function is not visible to Python users.
   """
-  cdef fst.WeightClass result
+  cdef fst.WeightClass _weight
   if weight is None:
-    result = fst.WeightClass.One(weight_type)
+    _weight = fst.WeightClass.One(weight_type)
   elif isinstance(weight, Weight):
-    result = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
+    _weight = deref(<fst.WeightClass *> (<Weight> weight)._weight.get())
   else:
-    result = fst.WeightClass(weight_type, weight_tostring(weight))
-    if not result.Member():
+    _weight = fst.WeightClass(weight_type, weight_tostring(weight))
+    if not _weight.Member():
       raise FstBadWeightError(weight_tostring(weight))
-  return result
+  return _weight
 
 
 cdef Weight _Zero(weight_type):
-  cdef Weight result = Weight.__new__(Weight)
-  result._weight.reset(new fst.WeightClass(fst.WeightClass.Zero(
-      tostring(weight_type))))
-  if result._weight.get().Type() == b"none":
+  cdef Weight _weight = Weight.__new__(Weight)
+  _weight._weight.reset(
+    new fst.WeightClass(fst.WeightClass.Zero(tostring(weight_type))))
+  if _weight._weight.get().Type() == b"none":
     raise FstArgError("Weight type not found")
-  return result
+  return _weight
 
 
 cdef Weight _One(weight_type):
-  cdef Weight result = Weight.__new__(Weight)
-  result._weight.reset(new fst.WeightClass(
-        fst.WeightClass.One(tostring(weight_type))))
-  if result._weight.get().Type() == b"none":
+  cdef Weight _weight = Weight.__new__(Weight)
+  _weight._weight.reset(
+    new fst.WeightClass(fst.WeightClass.One(tostring(weight_type))))
+  if _weight._weight.get().Type() == b"none":
     raise FstArgError("Weight type not found")
-  return result
+  return _weight
 
 
 cdef Weight _NoWeight(weight_type):
-  cdef Weight result = Weight.__new__(Weight)
-  result._weight.reset(new fst.WeightClass(
-        fst.WeightClass.NoWeight(tostring(weight_type))))
-  return result
+  cdef Weight _weight = Weight.__new__(Weight)
+  _weight._weight.reset(
+    new fst.WeightClass(fst.WeightClass.NoWeight(tostring(weight_type))))
+  return _weight
 
 
-# _SymbolTable, _MutableSymbolTable, _EncodeMapperSymbolTableView,
-# _FstSymbolTableView, _MutableFstSymbolTableView, SymbolTable, and helpers.
-#
 # SymbolTable hierarchy:
 #
-# _SymbolTable: abstract base class; has-a SymbolTable*
-# _EncodeMapperSymbolTableView(_SymbolTable): constant symbol table returned by
-#     EncodeMapper.input_symbols/output_symbols
-# _FstSymbolTableView(_SymbolTable): constant symbol table returned by
+# SymbolTableView: abstract base class; has-a SymbolTable*
+# _EncodeMapperSymbolTableView(SymbolTableView): constant symbol table returned
+#     by EncodeMapper.input_symbols/output_symbols
+# _FstSymbolTableView(SymbolTableView): constant symbol table returned by
 #     Fst.input_symbols/output_symbols
 #
-# _MutableSymbolTable(_SymbolTable): abstract base class adding mutation methods
+# _MutableSymbolTable(SymbolTableView): abstract base class adding mutation
+#     methods
 # _MutableFstSymbolTableView(_MutableSymbolTable): mutable symbol table
 #     returned by MutableFst.mutable_input_symbols/mutable_output_symbols
 # SymbolTable(_MutableSymbolTable): adds constructor
 
 
-cdef class _SymbolTable:
+cdef class SymbolTableView:
 
   """
   (No constructor.)
@@ -677,8 +741,7 @@ cdef class _SymbolTable:
   # Doing so will allow undefined behavior.
 
   def __init__(self):
-    raise FstDeletedConstructorError(
-        "Cannot construct {}".format(self.__class__.__name__))
+    raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")
 
   def __iter__(self):
     return _SymbolTableIterator(self)
@@ -702,10 +765,10 @@ cdef class _SymbolTable:
   # Internal API method that should be used when a const pointer to an
   # fst.SymbolTable is required.
   cdef const_SymbolTable_ptr _raw_ptr_or_raise(self) except *:
-    cdef const_SymbolTable_ptr raw = self._raw()
-    if raw == NULL:
+    cdef const_SymbolTable_ptr _raw = self._raw()
+    if _raw == NULL:
       self._raise_nonexistent()
-    return raw
+    return _raw
 
   cpdef int64 available_key(self) except *:
     """
@@ -748,11 +811,11 @@ cdef class _SymbolTable:
           the key is an integer, the associated symbol or an empty string if
           not found.
     """
-    cdef const_SymbolTable_ptr raw = self._raw_ptr_or_raise()
+    cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()
     try:
-      return raw.FindIndex(tostring(key))
-    except FstArgError:
-      return raw.FindSymbol(key)
+      return _raw.FindIndex(tostring(key))
+    except TypeError:
+      return _raw.FindSymbol(key)
 
   cpdef int64 get_nth_key(self, ssize_t pos) except *:
     """
@@ -792,14 +855,11 @@ cdef class _SymbolTable:
     Returns:
       Whether or not the key is present (as a string or a index) in the table.
     """
-    cdef const_SymbolTable_ptr raw = self._raw_ptr_or_raise()
+    cdef const_SymbolTable_ptr _raw = self._raw_ptr_or_raise()
     try:
-      return raw.MemberSymbol(tostring(key))
-    except FstArgError:
-      return raw.MemberIndex(key)
-
-  def __contains__(self, key):
-    return self.member(key)
+      return _raw.MemberSymbol(tostring(key))
+    except TypeError:
+      return _raw.MemberIndex(key)
 
   cpdef string name(self) except *:
     """
@@ -831,8 +891,8 @@ cdef class _SymbolTable:
     Raises:
       FstIOError: Write failed.
     """
-    if not self._raw_ptr_or_raise().Write(tostring(source)):
-      raise FstIOError("Write failed: {!r}".format(source))
+    if not self._raw_ptr_or_raise().Write(path_tostring(source)):
+      raise FstIOError(f"Write failed: {source!r}")
 
   cpdef void write_text(self, source) except *:
     """
@@ -848,8 +908,8 @@ cdef class _SymbolTable:
     Raises:
       FstIOError: Write failed.
     """
-    if not self._raw_ptr_or_raise().WriteText(tostring(source)):
-      raise FstIOError("Write failed: {!r}".format(source))
+    if not self._raw_ptr_or_raise().WriteText(path_tostring(source)):
+      raise FstIOError(f"Write failed: {source!r}")
 
   cpdef bytes write_to_string(self):
     """
@@ -863,13 +923,13 @@ cdef class _SymbolTable:
     Raises:
       FstIOError: Write to string failed.
     """
-    cdef stringstream sstrm
-    if not self._raw_ptr_or_raise().Write(sstrm):
+    cdef stringstream _sstrm
+    if not self._raw_ptr_or_raise().Write(_sstrm):
       raise FstIOError("Write to string failed")
-    return sstrm.str()
+    return _sstrm.str()
 
 
-cdef class _EncodeMapperSymbolTableView(_SymbolTable):
+cdef class _EncodeMapperSymbolTableView(SymbolTableView):
 
   """
   (No constructor.)
@@ -885,15 +945,15 @@ cdef class _EncodeMapperSymbolTableView(_SymbolTable):
   # Doing so will allow undefined behavior.
 
   def __repr__(self):
-    return "<const EncodeMapper SymbolTableView {!r} at 0x{:x}>".format(
-      self.name(), id(self))
+    return (f"<const EncodeMapper SymbolTableView {self.name()!r} "
+            f"at 0x{id(self):x}>")
 
   cdef const_SymbolTable_ptr _raw(self):
     return (self._mapper.get().InputSymbols() if self._input_side
             else self._mapper.get().OutputSymbols())
 
 
-cdef class _FstSymbolTableView(_SymbolTable):
+cdef class _FstSymbolTableView(SymbolTableView):
 
   """
   (No constructor.)
@@ -908,15 +968,15 @@ cdef class _FstSymbolTableView(_SymbolTable):
   # Doing so will allow undefined behavior.
 
   def __repr__(self):
-    return "<const Fst SymbolTableView {!r} at 0x{:x}>".format(self.name(),
-                                                               id(self))
+    return (f"<const Fst SymbolTableView {self.name()!r} "
+            f"at 0x{id(self):x}>")
 
   cdef const_SymbolTable_ptr _raw(self):
     return (self._fst.get().InputSymbols() if self._input_side
             else self._fst.get().OutputSymbols())
 
 
-cdef class _MutableSymbolTable(_SymbolTable):
+cdef class _MutableSymbolTable(SymbolTableView):
 
   """
   (No constructor.)
@@ -962,16 +1022,16 @@ cdef class _MutableSymbolTable(_SymbolTable):
     Returns:
       The integer key of the new symbol.
     """
+    cdef SymbolTable_ptr _mutable_raw = self._mutable_raw_ptr_or_raise()
     cdef string _symbol = tostring(symbol)
-    cdef SymbolTable_ptr mutable_raw = self._mutable_raw_ptr_or_raise()
     if key != fst.kNoSymbol:
-      return mutable_raw.AddSymbol(_symbol, key)
+      return _mutable_raw.AddSymbol(_symbol, key)
     else:
-      return mutable_raw.AddSymbol(_symbol)
+      return _mutable_raw.AddSymbol(_symbol)
 
-  cpdef void add_table(self, _SymbolTable syms) except *:
+  cpdef void add_table(self, SymbolTableView symbols) except *:
     """
-    add_table(self, syms)
+    add_table(self, symbols)
 
     Adds another SymbolTable to this table.
 
@@ -979,9 +1039,10 @@ cdef class _MutableSymbolTable(_SymbolTable):
     values will be offset by the current available key.
 
     Args:
-      syms: A SymbolTable to be merged with the current table.
+      symbols: A SymbolTable to be merged with the current table.
     """
-    self._mutable_raw_ptr_or_raise().AddTable(deref(syms._raw_ptr_or_raise()))
+    self._mutable_raw_ptr_or_raise().AddTable(
+        deref(symbols._raw_ptr_or_raise()))
 
   cpdef void set_name(self, new_name) except *:
     self._mutable_raw_ptr_or_raise().SetName(tostring(new_name))
@@ -995,7 +1056,7 @@ cdef class _MutableFstSymbolTableView(_MutableSymbolTable):
   """
 
   def __repr__(self):
-    return "<Fst SymbolTableView {!r} at 0x{:x}>".format(self.name(), id(self))
+    return f"<Fst SymbolTableView {self.name()!r} at 0x{id(self):x}>"
 
   cdef SymbolTable_ptr _mutable_raw(self):
     return (self._mfst.get().MutableInputSymbols() if self._input_side else
@@ -1020,7 +1081,7 @@ cdef class SymbolTable(_MutableSymbolTable):
   """
 
   def __repr__(self):
-    return "<SymbolTable {!r} at 0x{:x}>".format(self.name(), id(self))
+    return f"<SymbolTable {self.name()!r} at 0x{id(self):x}>"
 
   def __init__(self, name="<unspecified>"):
     self._smart_table.reset(new fst.SymbolTable(tostring(name)))
@@ -1043,11 +1104,11 @@ cdef class SymbolTable(_MutableSymbolTable):
     Returns:
       A new SymbolTable instance.
     """
-    cdef unique_ptr[fst.SymbolTable] syms
-    syms.reset(fst.SymbolTable.Read(tostring(source)))
-    if syms.get() == NULL:
-      raise FstIOError("Read failed: {!r}".format(source))
-    return _init_SymbolTable(move(syms))
+    cdef unique_ptr[fst.SymbolTable] _symbols
+    _symbols.reset(fst.SymbolTable.Read(path_tostring(source)))
+    if _symbols.get() == NULL:
+      raise FstIOError(f"Read failed: {source!r}")
+    return _init_SymbolTable(move(_symbols))
 
   @classmethod
   def read_text(cls, source, bool allow_negative_labels=False):
@@ -1066,13 +1127,14 @@ cdef class SymbolTable(_MutableSymbolTable):
     Returns:
       A new SymbolTable instance.
     """
-    cdef unique_ptr[fst.SymbolTableTextOptions] opts
-    opts.reset(new fst.SymbolTableTextOptions(allow_negative_labels))
-    cdef unique_ptr[fst.SymbolTable] syms
-    syms.reset(fst.SymbolTable.ReadText(tostring(source), deref(opts)))
-    if syms.get() == NULL:
-      raise FstIOError("Read failed: {!r}".format(source))
-    return _init_SymbolTable(move(syms))
+    cdef unique_ptr[fst.SymbolTableTextOptions] _opts
+    _opts.reset(new fst.SymbolTableTextOptions(allow_negative_labels))
+    cdef unique_ptr[fst.SymbolTable] _symbols
+    _symbols.reset(fst.SymbolTable.ReadText(path_tostring(source),
+                                            deref(_opts)))
+    if _symbols.get() == NULL:
+      raise FstIOError(f"Read failed: {source!r}")
+    return _init_SymbolTable(move(_symbols))
 
   @classmethod
   def read_fst(cls, source, bool input_table):
@@ -1095,77 +1157,78 @@ cdef class SymbolTable(_MutableSymbolTable):
     Raises:
       FstIOError: Read failed.
     """
-    cdef unique_ptr[fst.SymbolTable] syms
-    syms.reset(fst.FstReadSymbols(tostring(source), input_table))
-    if syms.get() == NULL:
-      raise FstIOError("Read failed: {!r}".format(source))
-    return _init_SymbolTable(move(syms))
+    cdef unique_ptr[fst.SymbolTable] _symbols
+    _symbols.reset(fst.FstReadSymbols(path_tostring(source), input_table))
+    if _symbols.get() == NULL:
+      raise FstIOError(f"Read from FST failed: {source!r}")
+    return _init_SymbolTable(move(_symbols))
 
 
 cdef _EncodeMapperSymbolTableView _init_EncodeMapperSymbolTableView(
     shared_ptr[fst.EncodeMapperClass] mapper, bool input_side):
-  cdef _EncodeMapperSymbolTableView result = (
+  cdef _EncodeMapperSymbolTableView _symbols = (
       _EncodeMapperSymbolTableView.__new__(_EncodeMapperSymbolTableView))
-  result._mapper = move(mapper)
-  result._input_side = input_side
-  return result
+  _symbols._mapper = move(mapper)
+  _symbols._input_side = input_side
+  return _symbols
 
 
 cdef _FstSymbolTableView _init_FstSymbolTableView(shared_ptr[fst.FstClass] ifst,
                                                   bool input_side):
-  cdef _FstSymbolTableView result = (
+  cdef _FstSymbolTableView _symbols = (
       _FstSymbolTableView.__new__(_FstSymbolTableView))
-  result._fst = move(ifst)
-  result._input_side = input_side
-  return result
+  _symbols._fst = move(ifst)
+  _symbols._input_side = input_side
+  return _symbols
 
 
 cdef _MutableFstSymbolTableView _init_MutableFstSymbolTableView(
                                     shared_ptr[fst.MutableFstClass] ifst,
                                     bool input_side):
-  cdef _MutableFstSymbolTableView result = (
+  cdef _MutableFstSymbolTableView _symbols = (
       _MutableFstSymbolTableView.__new__(_MutableFstSymbolTableView))
-  result._mfst = move(ifst)
-  result._input_side = input_side
-  return result
+  _symbols._mfst = move(ifst)
+  _symbols._input_side = input_side
+  return _symbols
 
 
-cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] table):
-  cdef SymbolTable result = SymbolTable.__new__(SymbolTable)
-  result._smart_table = move(table)
-  return result
+cdef SymbolTable _init_SymbolTable(unique_ptr[fst.SymbolTable] symbols):
+  cdef SymbolTable _symbols = SymbolTable.__new__(SymbolTable)
+  _symbols._smart_table = move(symbols)
+  return _symbols
 
 
-cpdef SymbolTable _read_SymbolTable_from_string(state):
-  cdef stringstream sstrm
-  sstrm << tostring(state)
-  cdef unique_ptr[fst.SymbolTable] syms
-  syms.reset(fst.SymbolTable.ReadStream(sstrm, b"<pywrapfst>"))
-  if syms.get() == NULL:
-    raise FstIOError("Read failed")
-  return _init_SymbolTable(move(syms))
+cpdef SymbolTable _read_SymbolTable_from_string(string state):
+  cdef stringstream _sstrm
+  _sstrm << state
+  cdef unique_ptr[fst.SymbolTable] _symbols
+  _symbols.reset(fst.SymbolTable.ReadStream(_sstrm, b"<pywrapfst>"))
+  if _symbols.get() == NULL:
+    raise FstIOError("Read from string failed")
+  return _init_SymbolTable(move(_symbols))
 
 
 # Constructive SymbolTable operations.
 
 
-cpdef SymbolTable compact_symbol_table(_SymbolTable syms):
+cpdef SymbolTable compact_symbol_table(SymbolTableView symbols):
   """
-  compact_symbol_table(syms)
+  compact_symbol_table(symbols)
 
   Constructively relabels a SymbolTable to make it a contiguous mapping.
 
   Args:
-    syms: Input SymbolTable.
+    symbols: Input SymbolTable.
 
   Returns:
     A new compacted SymbolTable.
   """
   return _init_SymbolTable(WrapUnique(fst.CompactSymbolTable(
-                                          deref(syms._raw_ptr_or_raise()))))
+                                          deref(symbols._raw_ptr_or_raise()))))
 
 
-cpdef SymbolTable merge_symbol_table(_SymbolTable lhs, _SymbolTable rhs):
+cpdef SymbolTable merge_symbol_table(SymbolTableView lhs,
+                                     SymbolTableView rhs):
   """
   merge_symbol_table(lhs, rhs)
 
@@ -1198,18 +1261,18 @@ cpdef SymbolTable merge_symbol_table(_SymbolTable lhs, _SymbolTable rhs):
 
 cdef class _SymbolTableIterator:
   """
-  _SymbolTableIterator(syms)
+  _SymbolTableIterator(symbols)
 
   This class is used for iterating over a symbol table.
   """
 
   def __repr__(self):
-    return "<_SymbolTableIterator at 0x{:x}>".format(id(self))
+    return f"<_SymbolTableIterator at 0x{id(self):x}>"
 
-  def __init__(self, _SymbolTable syms):
-    self._table = syms
-    self._siter.reset(new fst.SymbolTableIterator(
-                          self._table._raw_ptr_or_raise().begin()))
+  def __init__(self, SymbolTableView symbols):
+    self._table = symbols
+    self._siter.reset(
+        new fst.SymbolTableIterator(self._table._raw_ptr_or_raise().begin()))
 
   # This just registers this class as a possible iterator.
   def __iter__(self):
@@ -1219,10 +1282,10 @@ cdef class _SymbolTableIterator:
   def __next__(self):
     if self._table._raw_ptr_or_raise().end() == deref(self._siter):
       raise StopIteration
-    cdef int64 label = self._siter.get().Pair().Label()
-    cdef string symbol = self._siter.get().Pair().Symbol()
+    cdef int64 _label = self._siter.get().Pair().Label()
+    cdef string _symbol = self._siter.get().Pair().Symbol()
     inc(deref(self._siter))
-    return (label, symbol)
+    return (_label, _symbol)
 
 
 ## EncodeMapper.
@@ -1252,17 +1315,17 @@ cdef class EncodeMapper:
   """
 
   def __repr__(self):
-    return "<EncodeMapper at 0x{:x}>".format(id(self))
+    return f"<EncodeMapper at 0x{id(self):x}>"
 
   def __init__(self,
-               arc_type=b"standard",
+               arc_type="standard",
                bool encode_labels=False,
                bool encode_weights=False):
-    cdef uint8 flags = fst.GetEncodeFlags(encode_labels, encode_weights)
-    self._mapper.reset(new fst.EncodeMapperClass(tostring(arc_type), flags,
-                                                 fst.ENCODE))
-    if not self._mapper:
-      raise FstOpError("Unknown arc type: {!r}".format(arc_type))
+    cdef uint8 _flags = fst.GetEncodeFlags(encode_labels, encode_weights)
+    self._mapper.reset(
+        new fst.EncodeMapperClass(tostring(arc_type), _flags, fst.ENCODE))
+    if self._mapper.get() == NULL:
+      raise FstOpError(f"Unknown arc type: {arc_type!r}")
 
   # Python's equivalent to operator().
 
@@ -1345,11 +1408,11 @@ cdef class EncodeMapper:
     Returns:
       A new EncodeMapper instance.
     """
-    cdef unique_ptr[fst.EncodeMapperClass] mapper
-    mapper.reset(fst.EncodeMapperClass.Read(tostring(source)))
-    if mapper.get() == NULL:
-      raise FstIOError("Read failed: {!r}".format(source))
-    return _init_EncodeMapper(mapper.release())
+    cdef unique_ptr[fst.EncodeMapperClass] _mapper
+    _mapper.reset(fst.EncodeMapperClass.Read(path_tostring(source)))
+    if _mapper.get() == NULL:
+      raise FstIOError(f"Read failed: {source!r}")
+    return _init_EncodeMapper(_mapper.release())
 
   @staticmethod
   def read_from_string(state):
@@ -1382,8 +1445,8 @@ cdef class EncodeMapper:
       Raises:
         FstIOError: Write failed.
       """
-      if not self._mapper.get().Write(tostring(source)):
-        raise FstIOError("Write failed: {!r}".format(source))
+      if not self._mapper.get().Write(path_tostring(source)):
+        raise FstIOError(f"Write failed: {source!r}")
 
   cpdef bytes write_to_string(self):
       """
@@ -1397,10 +1460,10 @@ cdef class EncodeMapper:
       Raises:
         FstIOError: Write to string failed.
       """
-      cdef stringstream sstrm
-      if not self._mapper.get().WriteStream(sstrm, b"<pywrapfst>"):
+      cdef stringstream _sstrm
+      if not self._mapper.get().WriteStream(_sstrm, b"<pywrapfst>"):
         raise FstIOError("Write to string failed")
-      return sstrm.str()
+      return _sstrm.str()
 
   cpdef _EncodeMapperSymbolTableView input_symbols(self):
     """
@@ -1422,50 +1485,50 @@ cdef class EncodeMapper:
       return
     return _init_EncodeMapperSymbolTableView(self._mapper, input_side=False)
 
-  cdef void _set_input_symbols(self, _SymbolTable syms) except *:
-    if syms is None:
+  cdef void _set_input_symbols(self, SymbolTableView symbols) except *:
+    if symbols is None:
       self._mapper.get().SetInputSymbols(NULL)
       return
-    self._mapper.get().SetInputSymbols(syms._raw_ptr_or_raise())
+    self._mapper.get().SetInputSymbols(symbols._raw_ptr_or_raise())
 
-  def set_input_symbols(self, _SymbolTable syms):
+  def set_input_symbols(self, SymbolTableView symbols):
     """
-    set_input_symbols(self, syms)
+    set_input_symbols(self, symbols)
 
     Sets the mapper's input symbol table.
 
     Passing None as a value will delete the input symbol table.
 
     Args:
-      syms: A SymbolTable.
+      symbols: A SymbolTable.
 
     Returns:
       self.
     """
-    self._set_input_symbols(syms)
+    self._set_input_symbols(symbols)
     return self
 
-  cdef void _set_output_symbols(self, _SymbolTable syms) except *:
-    if syms is None:
+  cdef void _set_output_symbols(self, SymbolTableView symbols) except *:
+    if symbols is None:
       self._mapper.get().SetOutputSymbols(NULL)
       return
-    self._mapper.get().SetOutputSymbols(syms._raw_ptr_or_raise())
+    self._mapper.get().SetOutputSymbols(symbols._raw_ptr_or_raise())
 
-  def set_output_symbols(self, _SymbolTable syms):
+  def set_output_symbols(self, SymbolTableView symbols):
     """
-    set_output_symbols(self, syms)
+    set_output_symbols(self, symbols)
 
     Sets the mapper's output symbol table.
 
     Passing None as a value will delete the output symbol table.
 
     Args:
-      syms: A SymbolTable.
+      symbols: A SymbolTable.
 
     Returns:
       self.
     """
-    self._set_output_symbols(syms)
+    self._set_output_symbols(symbols)
     return self
 
 
@@ -1475,14 +1538,14 @@ cdef EncodeMapper _init_EncodeMapper(EncodeMapperClass_ptr mapper):
   return result
 
 
-cpdef EncodeMapper _read_EncodeMapper_from_string(state):
-  cdef stringstream sstrm
-  sstrm << tostring(state)
-  cdef unique_ptr[fst.EncodeMapperClass] mapper
-  mapper.reset(fst.EncodeMapperClass.ReadStream(sstrm, b"<pywrapfst>"))
-  if mapper.get() == NULL:
-    raise FstIOError("Read failed")
-  return _init_EncodeMapper(mapper.release())
+cpdef EncodeMapper _read_EncodeMapper_from_string(string state):
+  cdef stringstream _sstrm
+  _sstrm << state
+  cdef unique_ptr[fst.EncodeMapperClass] _mapper
+  _mapper.reset(fst.EncodeMapperClass.ReadStream(_sstrm, b"<pywrapfst>"))
+  if _mapper.get() == NULL:
+    raise FstIOError("Read from string failed")
+  return _init_EncodeMapper(_mapper.release())
 
 
 ## Fst and MutableFst.
@@ -1535,28 +1598,41 @@ cdef class Fst:
     publication-quality graphs should instead use the method `draw`, which
     exposes additional parameters.
     """
-    cdef stringstream sstrm
+    cdef stringstream _sstrm
     cdef bool acceptor = (self._fst.get().Properties(fst.kAcceptor, True) ==
                           fst.kAcceptor)
-    fst.Draw(deref(self._fst), self._fst.get().InputSymbols(),
-             self._fst.get().OutputSymbols(), NULL, acceptor, b"", 8.5, 11,
-             True, False, 0.4, 0.25, 14, 5, b"g", False, sstrm,
+    fst.Draw(deref(self._fst),
+             self._fst.get().InputSymbols(),
+             self._fst.get().OutputSymbols(),
+             NULL,
+             acceptor,
+             b"",
+             8.5,
+             11,
+             True,
+             False,
+             0.4,
+             0.25,
+             14,
+             5,
+             b"g",
+             False,
+             _sstrm,
              b"<pywrapfst>")
     # Google-only...
     try:
-      return Fst._server_render_svg(sstrm.str())
+      return Fst._server_render_svg(_sstrm.str())
     except Exception as e:
       frontend.DisplayToast("GraphViz server request failed: " + str(e))
       logging.error("Graphviz server requested failed: %s", e)
     # ...Google-only.
     try:
-      return Fst._local_render_svg(sstrm.str())
+      return Fst._local_render_svg(_sstrm.str())
     except Exception as e:
       logging.error("Dot rendering failed: %s", e)
 
   def __init__(self):
-    raise FstDeletedConstructorError(
-        "Cannot construct {}".format(self.__class__.__name__))
+    raise NotImplementedError(f"Cannot construct {self._class__.__name__}")
 
   # Registers the class for pickling; must be repeated in any subclass which
   # can't be derived by _init_XFst.
@@ -1565,7 +1641,7 @@ cdef class Fst:
     return (_read_Fst_from_string, (self.write_to_string(),))
 
   def __repr__(self):
-    return "<{} Fst at 0x{:x}>".format(self.fst_type(), id(self))
+    return f"<{self.fst_type()} Fst at 0x{id(self):x}>"
 
   def __str__(self):
     return self.print()
@@ -1602,11 +1678,11 @@ cdef class Fst:
 
   cpdef void draw(self,
                   source,
-                  _SymbolTable isymbols=None,
-                  _SymbolTable osymbols=None,
-                  _SymbolTable ssymbols=None,
+                  SymbolTableView isymbols=None,
+                  SymbolTableView osymbols=None,
+                  SymbolTableView ssymbols=None,
                   bool acceptor=False,
-                  title=b"",
+                  title="",
                   double width=8.5,
                   double height=11,
                   bool portrait=False,
@@ -1615,7 +1691,7 @@ cdef class Fst:
                   double nodesep=0.25,
                   int32 fontsize=14,
                   int32 precision=5,
-                  float_format=b"g",
+                  float_format="g",
                   bool show_weight_one=False) except *:
     """
     draw(self, source, isymbols=None, osymbols=None, ssymbols=None,
@@ -1648,9 +1724,9 @@ cdef class Fst:
       float_format: One of: 'e', 'f' or 'g'.
       show_weight_one: Should weights equivalent to semiring One be printed?
     """
-    cdef string source_string = tostring(source)
-    cdef unique_ptr[ostream] fstrm
-    fstrm.reset(new ofstream(source_string))
+    cdef string _source = path_tostring(source)
+    cdef unique_ptr[ostream] _fstrm
+    _fstrm.reset(new ofstream(_source))
     cdef const fst.SymbolTable *_isymbols = self._fst.get().InputSymbols()
     if isymbols is not None:
        _isymbols = isymbols._raw_ptr_or_raise()
@@ -1661,23 +1737,23 @@ cdef class Fst:
     if ssymbols is not None:
       _ssymbols = ssymbols._raw_ptr_or_raise()
     fst.Draw(deref(self._fst),
-        _isymbols,
-        _osymbols,
-        _ssymbols,
-        acceptor,
-        tostring(title),
-        width,
-        height,
-        portrait,
-        vertical,
-        ranksep,
-        nodesep,
-        fontsize,
-        precision,
-        tostring(float_format),
-        show_weight_one,
-        deref(fstrm),
-        source_string)
+             _isymbols,
+             _osymbols,
+             _ssymbols,
+             acceptor,
+             tostring(title),
+             width,
+             height,
+             portrait,
+             vertical,
+             ranksep,
+             nodesep,
+             fontsize,
+             precision,
+             tostring(float_format),
+             show_weight_one,
+             deref(_fstrm),
+             _source)
 
   cpdef Weight final(self, int64 state):
     """
@@ -1694,11 +1770,11 @@ cdef class Fst:
     Raises:
       FstIndexError: State index out of range.
     """
-    cdef Weight weight = Weight.__new__(Weight)
-    weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
-    if not weight.member():
+    cdef Weight _weight = Weight.__new__(Weight)
+    _weight._weight.reset(new fst.WeightClass(self._fst.get().Final(state)))
+    if not _weight.member():
       raise FstIndexError("State index out of range")
-    return weight
+    return _weight
 
   cpdef string fst_type(self):
     """
@@ -1714,8 +1790,7 @@ cdef class Fst:
 
     Returns the FST's input symbol table, or None if none is present.
     """
-    cdef const fst.SymbolTable *syms = self._fst.get().InputSymbols()
-    if syms == NULL:
+    if self._fst.get().InputSymbols() == NULL:
       return
     return _init_FstSymbolTableView(self._fst, input_side=True)
 
@@ -1734,10 +1809,10 @@ cdef class Fst:
     Raises:
       FstIndexError: State index out of range.
     """
-    cdef size_t result = self._fst.get().NumArcs(state)
-    if result == SIZE_MAX:
+    cdef size_t _result = self._fst.get().NumArcs(state)
+    if _result == SIZE_MAX:
       raise FstIndexError("State index out of range")
-    return result
+    return _result
 
   cpdef size_t num_input_epsilons(self, int64 state) except *:
     """
@@ -1754,10 +1829,10 @@ cdef class Fst:
     Raises:
       FstIndexError: State index out of range.
     """
-    cdef size_t result = self._fst.get().NumInputEpsilons(state)
-    if result == SIZE_MAX:
+    cdef size_t _result = self._fst.get().NumInputEpsilons(state)
+    if _result == SIZE_MAX:
       raise FstIndexError("State index out of range")
-    return result
+    return _result
 
   cpdef size_t num_output_epsilons(self, int64 state) except *:
     """
@@ -1774,10 +1849,10 @@ cdef class Fst:
     Raises:
       FstIndexError: State index out of range.
     """
-    cdef size_t result = self._fst.get().NumOutputEpsilons(state)
-    if result == SIZE_MAX:
+    cdef size_t _result = self._fst.get().NumOutputEpsilons(state)
+    if _result == SIZE_MAX:
       raise FstIndexError("State index out of range")
-    return result
+    return _result
 
   cpdef _FstSymbolTableView output_symbols(self):
     """
@@ -1785,15 +1860,14 @@ cdef class Fst:
 
     Returns the FST's output symbol table, or None if none is present.
     """
-    cdef const fst.SymbolTable *syms = self._fst.get().OutputSymbols()
-    if syms == NULL:
+    if self._fst.get().OutputSymbols() == NULL:
       return
     return _init_FstSymbolTableView(self._fst, input_side=False)
 
-  cpdef string print(self, _SymbolTable isymbols=None,
-      _SymbolTable osymbols=None, _SymbolTable ssymbols=None,
+  cpdef string print(self, SymbolTableView isymbols=None,
+      SymbolTableView osymbols=None, SymbolTableView ssymbols=None,
       bool acceptor=False, bool show_weight_one=False,
-      missing_sym=b"") except *:
+      missing_sym="") except *:
     """
     print(self, isymbols=None, osymbols=None, ssymbols=None, acceptor=False,
           show_weight_one=False, missing_sym="")
@@ -1825,9 +1899,9 @@ cdef class Fst:
     cdef const fst.SymbolTable *_ssymbols = NULL
     if ssymbols is not None:
       _ssymbols = ssymbols._raw_ptr_or_raise()
-    cdef stringstream sstrm
+    cdef stringstream _sstrm
     fst.Print(deref(self._fst),
-              sstrm,
+              _sstrm,
               b"<pywrapfst>",
               _isymbols,
               _osymbols,
@@ -1835,7 +1909,7 @@ cdef class Fst:
               acceptor,
               show_weight_one,
               tostring(missing_sym))
-    return sstrm.str()
+    return _sstrm.str()
 
   cpdef uint64 properties(self, uint64 mask, bool test):
     """
@@ -1912,44 +1986,6 @@ cdef class Fst:
     """
     return StateIterator(self)
 
-  # TODO(kbg): Deprecated; remove on next release.
-  cpdef string text(self,
-                    _SymbolTable isymbols=None,
-                    _SymbolTable osymbols=None,
-                    _SymbolTable ssymbols=None,
-                    bool acceptor=False,
-                    bool show_weight_one=False,
-                    missing_sym=b"") except *:
-    """
-    text(self, isymbols=None, osymbols=None, ssymbols=None, acceptor=False,
-          show_weight_one=False, missing_sym="")
-
-    Produces a human-readable string representation of the FST.
-
-    This method generates a human-readable string representation of the FST.
-    The caller may optionally specify SymbolTables used to label input labels,
-    output labels, or state labels, respectively.
-
-    Args:
-      isymbols: An optional symbol table used to label input symbols.
-      osymbols: An optional symbol table used to label output symbols.
-      ssymbols: An optional symbol table used to label states.
-      acceptor: Should the FST be rendered in acceptor format if possible?
-      show_weight_one: Should weights equivalent to semiring One be printed?
-      missing_symbol: The string to be printed when symbol table lookup fails.
-
-    Returns:
-      A formatted string representing the machine.
-    """
-    warnings.warn("Use `print` instead", DeprecationWarning, stacklevel=2)
-    return self.print(isymbols,
-                      osymbols,
-                      ssymbols,
-                      acceptor,
-                      show_weight_one,
-                      missing_sym)
-
-
   cpdef bool verify(self):
     """
     verify(self)
@@ -1986,8 +2022,8 @@ cdef class Fst:
     Raises:
       FstIOError: Write failed.
     """
-    if not self._fst.get().Write(tostring(source)):
-      raise FstIOError("Write failed: {!r}".format(source))
+    if not self._fst.get().Write(path_tostring(source)):
+      raise FstIOError(f"Write failed: {source!r}")
 
   cpdef bytes write_to_string(self):
     """
@@ -2001,10 +2037,10 @@ cdef class Fst:
     Raises:
       FstIOError: Write to string failed.
     """
-    cdef stringstream sstrm
-    if not self._fst.get().Write(sstrm, b"<pywrapfst>"):
+    cdef stringstream _sstrm
+    if not self._fst.get().Write(_sstrm, b"<pywrapfst>"):
       raise FstIOError("Write to string failed")
-    return sstrm.str()
+    return _sstrm.str()
 
 
 cdef class MutableFst(Fst):
@@ -2072,13 +2108,13 @@ cdef class MutableFst(Fst):
     """
     self._mfst.get().AddStates(n)
 
-  cdef void _arcsort(self, sort_type=b"ilabel") except *:
-    cdef fst.ArcSortType sort_type_enum
-    if not fst.GetArcSortType(tostring(sort_type), addr(sort_type_enum)):
-      raise FstArgError("Unknown sort type {!r}".format(sort_type))
-    fst.ArcSort(self._mfst.get(), sort_type_enum)
+  cdef void _arcsort(self, sort_type="ilabel") except *:
+    cdef fst.ArcSortType _sort_type
+    if not fst.GetArcSortType(tostring(sort_type), addr(_sort_type)):
+      raise FstArgError(f"Unknown sort type: {sort_type!r}")
+    fst.ArcSort(self._mfst.get(), _sort_type)
 
-  def arcsort(self, sort_type=b"ilabel"):
+  def arcsort(self, sort_type="ilabel"):
     """
     arcsort(self, sort_type="ilabel")
 
@@ -2342,8 +2378,7 @@ cdef class MutableFst(Fst):
 
     Returns the FST's (mutable) input symbol table, or None if none is present.
     """
-    cdef fst.SymbolTable *syms = self._mfst.get().MutableInputSymbols()
-    if syms == NULL:
+    if self._mfst.get().MutableInputSymbols() == NULL:
       return
     return _init_MutableFstSymbolTableView(self._mfst, input_side=True)
 
@@ -2353,8 +2388,7 @@ cdef class MutableFst(Fst):
 
     Returns the FST's (mutable) output symbol table, or None if none is present.
     """
-    cdef SymbolTable_ptr syms = self._mfst.get().MutableOutputSymbols()
-    if syms == NULL:
+    if self._mfst.get().MutableOutputSymbols() == NULL:
       return
     return _init_MutableFstSymbolTableView(self._mfst, input_side=False)
 
@@ -2366,12 +2400,12 @@ cdef class MutableFst(Fst):
     """
     return self._mfst.get().NumStates()
 
-  cdef void _project(self, bool project_output=False) except *:
-    fst.Project(self._mfst.get(), fst.GetProjectType(project_output))
+  cdef void _project(self, project_type) except *:
+    fst.Project(self._mfst.get(), _get_project_type(tostring(project_type)))
 
-  def project(self, bool project_output=False):
+  def project(self, project_type):
     """
-    project(self, project_output=False)
+    project(self, project_type)
 
     Converts the FST to an acceptor using input or output labels.
 
@@ -2380,12 +2414,13 @@ cdef class MutableFst(Fst):
     vice versa.
 
     Args:
-      project_output: Should the output labels be projected?
+      project_type: A string matching a known projection type; one of:
+          "input", "output".
 
     Returns:
       self.
     """
-    self._project(project_output)
+    self._project(project_type)
     return self
 
   cdef void _prune(self,
@@ -2393,9 +2428,9 @@ cdef class MutableFst(Fst):
                    int64 nstate=fst.kNoStateId,
                    weight=None) except *:
     # Threshold is set to semiring Zero (no pruning) if no weight is specified.
-    cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),
-                                                       weight)
-    fst.Prune(self._mfst.get(), wc, nstate, delta)
+    cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(self.weight_type(),
+                                                            weight)
+    fst.Prune(self._mfst.get(), _weight, nstate, delta)
     self._check_mutating_imethod()
 
   def prune(self,
@@ -2428,7 +2463,9 @@ cdef class MutableFst(Fst):
                   float delta=fst.kShortestDelta,
                   bool remove_total_weight=False,
                   bool to_final=False):
-    fst.Push(self._mfst.get(), fst.GetReweightType(to_final), delta,
+    fst.Push(self._mfst.get(),
+             fst.GetReweightType(to_final),
+             delta,
              remove_total_weight)
 
   def push(self,
@@ -2462,21 +2499,17 @@ cdef class MutableFst(Fst):
     return self
 
   cdef void _relabel_pairs(self, ipairs=None, opairs=None) except *:
-    cdef unique_ptr[vector[fst.LabelPair]] _ipairs
-    _ipairs.reset(new vector[fst.LabelPair]())
-    cdef unique_ptr[vector[fst.LabelPair]] _opairs
-    _opairs.reset(new vector[fst.LabelPair]())
-    cdef int64 before
-    cdef int64 after
+    cdef vector[fst.LabelPair] _ipairs
+    cdef vector[fst.LabelPair] _opairs
     if ipairs:
       for (before, after) in ipairs:
-        _ipairs.get().push_back(fst.LabelPair(before, after))
+        _ipairs.push_back(fst.LabelPair(before, after))
     if opairs:
       for (before, after) in opairs:
-        _opairs.get().push_back(fst.LabelPair(before, after))
-    if _ipairs.get().empty() and _opairs.get().empty():
+        _opairs.push_back(fst.LabelPair(before, after))
+    if _ipairs.empty() and _opairs.empty():
       raise FstArgError("No relabeling pairs specified")
-    fst.Relabel(self._mfst.get(), deref(_ipairs), deref(_opairs))
+    fst.Relabel(self._mfst.get(), _ipairs, _opairs)
     self._check_mutating_imethod()
 
   def relabel_pairs(self, ipairs=None, opairs=None):
@@ -2503,13 +2536,13 @@ cdef class MutableFst(Fst):
     return self
 
   cdef void _relabel_tables(self,
-                            _SymbolTable old_isymbols=None,
-                            _SymbolTable new_isymbols=None,
-                            unknown_isymbol=b"",
+                            SymbolTableView old_isymbols=None,
+                            SymbolTableView new_isymbols=None,
+                            unknown_isymbol="",
                             bool attach_new_isymbols=True,
-                            _SymbolTable old_osymbols=None,
-                            _SymbolTable new_osymbols=None,
-                            unknown_osymbol=b"",
+                            SymbolTableView old_osymbols=None,
+                            SymbolTableView new_osymbols=None,
+                            unknown_osymbol="",
                             bool attach_new_osymbols=True) except *:
     if new_isymbols is None and new_osymbols is None:
       raise FstArgError("No new SymbolTables specified")
@@ -2537,13 +2570,13 @@ cdef class MutableFst(Fst):
     self._check_mutating_imethod()
 
   def relabel_tables(self,
-                     _SymbolTable old_isymbols=None,
-                     _SymbolTable new_isymbols=None,
-                     unknown_isymbol=b"",
+                     SymbolTableView old_isymbols=None,
+                     SymbolTableView new_isymbols=None,
+                     unknown_isymbol="",
                      bool attach_new_isymbols=True,
-                     _SymbolTable old_osymbols=None,
-                     _SymbolTable new_osymbols=None,
-                     unknown_osymbol=b"",
+                     SymbolTableView old_osymbols=None,
+                     SymbolTableView new_osymbols=None,
+                     unknown_osymbol="",
                      bool attach_new_osymbols=True):
     """
     relabel_tables(self, old_isymbols=None, new_isymbols=None,
@@ -2631,14 +2664,11 @@ cdef class MutableFst(Fst):
     return self
 
   cdef void _reweight(self, potentials, bool to_final=False) except *:
-    cdef unique_ptr[vector[fst.WeightClass]] _potentials
-    _potentials.reset(new vector[fst.WeightClass]())
-    cdef string weight_type = self.weight_type()
+    cdef string _weight_type = self.weight_type()
+    cdef vector[fst.WeightClass] _potentials
     for weight in potentials:
-        _potentials.get().push_back(_get_WeightClass_or_One(self.weight_type(),
-                                                            weight))
-    fst.Reweight(self._mfst.get(), deref(_potentials),
-                 fst.GetReweightType(to_final))
+      _potentials.push_back(_get_WeightClass_or_One(_weight_type, weight))
+    fst.Reweight(self._mfst.get(), _potentials, fst.GetReweightType(to_final))
     self._check_mutating_imethod()
 
   def reweight(self, potentials, bool to_final=False):
@@ -2667,24 +2697,25 @@ cdef class MutableFst(Fst):
     return self
 
   cdef void _rmepsilon(self,
-                       queue_type=b"auto",
+                       queue_type="auto",
                        bool connect=True,
                        weight=None,
                        int64 nstate=fst.kNoStateId,
                        float delta=fst.kShortestDelta) except *:
-    cdef fst.WeightClass wc = _get_WeightClass_or_Zero(self.weight_type(),
-                                                       weight)
-    cdef unique_ptr[fst.RmEpsilonOptions] opts
-    opts.reset(new fst.RmEpsilonOptions(_get_queue_type(tostring(queue_type)),
-                                        connect,
-                                        wc,
-                                        nstate,
-                                        delta))
-    fst.RmEpsilon(self._mfst.get(), deref(opts))
+    cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(self.weight_type(),
+                                                            weight)
+    cdef unique_ptr[fst.RmEpsilonOptions] _opts
+    _opts.reset(
+        new fst.RmEpsilonOptions(_get_queue_type(tostring(queue_type)),
+                                 connect,
+                                 _weight,
+                                 nstate,
+                                 delta))
+    fst.RmEpsilon(self._mfst.get(), deref(_opts))
     self._check_mutating_imethod()
 
   def rmepsilon(self,
-                queue_type=b"auto",
+                queue_type="auto",
                 bool connect=True,
                 weight=None,
                 int64 nstate=fst.kNoStateId,
@@ -2716,9 +2747,9 @@ cdef class MutableFst(Fst):
   cdef void _set_final(self, int64 state, weight=None) except *:
     if not self._mfst.get().ValidStateId(state):
       raise FstIndexError("State index out of range")
-    cdef fst.WeightClass wc = _get_WeightClass_or_One(self.weight_type(),
-                                                      weight)
-    if not self._mfst.get().SetFinal(state, wc):
+    cdef fst.WeightClass _weight = _get_WeightClass_or_One(self.weight_type(),
+                                                          weight)
+    if not self._mfst.get().SetFinal(state, _weight):
       raise FstOpError("Incompatible or invalid weight")
     self._check_mutating_imethod()
 
@@ -2743,50 +2774,50 @@ cdef class MutableFst(Fst):
     self._set_final(state, weight)
     return self
 
-  cdef void _set_input_symbols(self, _SymbolTable syms) except *:
-    if syms is None:
+  cdef void _set_input_symbols(self, SymbolTableView symbols) except *:
+    if symbols is None:
       self._mfst.get().SetInputSymbols(NULL)
       return
-    self._mfst.get().SetInputSymbols(syms._raw_ptr_or_raise())
+    self._mfst.get().SetInputSymbols(symbols._raw_ptr_or_raise())
 
-  def set_input_symbols(self, _SymbolTable syms):
+  def set_input_symbols(self, SymbolTableView symbols):
     """
-    set_input_symbols(self, syms)
+    set_input_symbols(self, symbols)
 
     Sets the input symbol table.
 
     Passing None as a value will delete the input symbol table.
 
     Args:
-      syms: A SymbolTable.
+      symbols: A SymbolTable.
 
     Returns:
       self.
     """
-    self._set_input_symbols(syms)
+    self._set_input_symbols(symbols)
     return self
 
-  cdef void _set_output_symbols(self, _SymbolTable syms) except *:
-    if syms is None:
+  cdef void _set_output_symbols(self, SymbolTableView symbols) except *:
+    if symbols is None:
       self._mfst.get().SetOutputSymbols(NULL)
       return
-    self._mfst.get().SetOutputSymbols(syms._raw_ptr_or_raise())
+    self._mfst.get().SetOutputSymbols(symbols._raw_ptr_or_raise())
 
-  def set_output_symbols(self, _SymbolTable syms):
+  def set_output_symbols(self, SymbolTableView symbols):
     """
-    set_output_symbols(self, syms)
+    set_output_symbols(self, symbols)
 
     Sets the output symbol table.
 
     Passing None as a value will delete the output symbol table.
 
     Args:
-      syms: A SymbolTable.
+      symbols: A SymbolTable.
 
     Returns:
       self.
     """
-    self._set_output_symbols(syms)
+    self._set_output_symbols(symbols)
     return self
 
   cdef void _set_properties(self, uint64 props, uint64 mask):
@@ -2868,10 +2899,10 @@ cdef class MutableFst(Fst):
     Returns:
       self.
     """
+    cdef Fst _fst2
     cdef vector[const_FstClass_ptr] _fsts2
-    cdef Fst fst2
-    for fst2 in fsts2:
-      _fsts2.push_back(fst2._fst.get())
+    for _fst2 in fsts2:
+      _fsts2.push_back(_fst2._fst.get())
     fst.Union(self._mfst.get(), _fsts2)
     self._check_mutating_imethod()
     return self
@@ -2890,12 +2921,12 @@ cdef class VectorFst(MutableFst):
     FstOpError: Unknown arc type.
   """
 
-  def __init__(self, arc_type=b"standard"):
-    cdef unique_ptr[fst.MutableFstClass] tfst
-    tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
-    if tfst.get().Properties(fst.kError, True) == fst.kError:
-      raise FstOpError("Unknown arc type: {!r}".format(arc_type))
-    self._fst.reset(tfst.release())
+  def __init__(self, arc_type="standard"):
+    cdef unique_ptr[fst.MutableFstClass] _tfst
+    _tfst.reset(new fst.VectorFstClass(tostring(arc_type)))
+    if _tfst.get().Properties(fst.kError, True) == fst.kError:
+      raise FstOpError(f"Unknown arc type: {arc_type!r}")
+    self._fst.reset(_tfst.release())
     self._mfst = static_pointer_cast[fst.MutableFstClass,
                                      fst.FstClass](self._fst)
 
@@ -2919,19 +2950,20 @@ cdef class VectorFst(MutableFst):
 cdef Fst _init_Fst(FstClass_ptr tfst):
   if tfst.Properties(fst.kError, True) == fst.kError:
     raise FstOpError("Operation failed")
-  cdef Fst ofst = Fst.__new__(Fst)
-  ofst._fst.reset(tfst)
-  return ofst
+  cdef Fst _ofst = Fst.__new__(Fst)
+  _ofst._fst.reset(tfst)
+  return _ofst
 
 
 cdef MutableFst _init_MutableFst(MutableFstClass_ptr tfst):
   if tfst.Properties(fst.kError, True) == fst.kError:
     raise FstOpError("Operation failed")
-  cdef MutableFst ofst = MutableFst.__new__(MutableFst)
-  ofst._fst.reset(tfst)
+  cdef MutableFst _ofst = MutableFst.__new__(MutableFst)
+  _ofst._fst.reset(tfst)
   # Makes a copy of it as the derived type! Cool.
-  ofst._mfst = static_pointer_cast[fst.MutableFstClass, fst.FstClass](ofst._fst)
-  return ofst
+  _ofst._mfst = static_pointer_cast[fst.MutableFstClass,
+                                    fst.FstClass](_ofst._fst)
+  return _ofst
 
 
 cdef Fst _init_XFst(FstClass_ptr tfst):
@@ -2942,21 +2974,21 @@ cdef Fst _init_XFst(FstClass_ptr tfst):
 
 
 cpdef Fst _read_Fst(source):
-  cdef unique_ptr[fst.FstClass] tfst
-  tfst.reset(fst.FstClass.Read(tostring(source)))
-  if tfst.get() == NULL:
-    raise FstIOError("Read failed: {!r}".format(source))
-  return _init_XFst(tfst.release())
+  cdef unique_ptr[fst.FstClass] _tfst
+  _tfst.reset(fst.FstClass.Read(path_tostring(source)))
+  if _tfst.get() == NULL:
+    raise FstIOError(f"Read failed: {source!r}")
+  return _init_XFst(_tfst.release())
 
 
-cpdef Fst _read_Fst_from_string(state):
-  cdef stringstream sstrm
-  sstrm << tostring(state)
-  cdef unique_ptr[fst.FstClass] tfst
-  tfst.reset(fst.FstClass.ReadStream(sstrm, b"<pywrapfst>"))
-  if tfst.get() == NULL:
-    raise FstIOError("Read failed")
-  return _init_XFst(tfst.release())
+cpdef Fst _read_Fst_from_string(string state):
+  cdef stringstream _sstrm
+  _sstrm << state
+  cdef unique_ptr[fst.FstClass] _tfst
+  _tfst.reset(fst.FstClass.ReadStream(_sstrm, b"<pywrapfst>"))
+  if _tfst.get() == NULL:
+    raise FstIOError("Read from string failed")
+  return _init_XFst(_tfst.release())
 
 
 ## FST constants.
@@ -3070,11 +3102,11 @@ cdef class Arc:
   """
 
   def __repr__(self):
-    return "<Arc at 0x{:x}>".format(id(self))
+    return f"<Arc at 0x{id(self):x}>"
 
   def __init__(self, int64 ilabel, int64 olabel, weight, int64 nextstate):
-    cdef fst.WeightClass wc = _get_WeightClass_or_One(b"tropical", weight)
-    self._arc.reset(new fst.ArcClass(ilabel, olabel, wc, nextstate))
+    cdef fst.WeightClass _weight = _get_WeightClass_or_One(b"tropical", weight)
+    self._arc.reset(new fst.ArcClass(ilabel, olabel, _weight, nextstate))
 
   cpdef Arc copy(self):
     return Arc(self.ilabel, self.olabel, self.weight, self.nextstate)
@@ -3098,9 +3130,9 @@ cdef class Arc:
   property weight:
 
     def __get__(self):
-      cdef Weight weight = Weight.__new__(Weight)
-      weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))
-      return weight
+      cdef Weight _weight = Weight.__new__(Weight)
+      _weight._weight.reset(new fst.WeightClass(deref(self._arc).weight))
+      return _weight
 
     def __set__(self, weight):
       deref(self._arc).weight = _get_WeightClass_or_One(b"tropical", weight)
@@ -3115,9 +3147,9 @@ cdef class Arc:
 
 
 cdef Arc _init_Arc(const fst.ArcClass &arc):
-  cdef Weight weight = Weight.__new__(Weight)
-  weight._weight.reset(new fst.WeightClass(arc.weight))
-  return Arc(arc.ilabel, arc.olabel, weight, arc.nextstate)
+  cdef Weight _weight = Weight.__new__(Weight)
+  _weight._weight.reset(new fst.WeightClass(arc.weight))
+  return Arc(arc.ilabel, arc.olabel, _weight, arc.nextstate)
 
 
 cdef class ArcIterator:
@@ -3129,7 +3161,7 @@ cdef class ArcIterator:
   """
 
   def __repr__(self):
-    return "<ArcIterator at 0x{:x}>".format(id(self))
+    return f"<ArcIterator at 0x{id(self):x}>"
 
   def __init__(self, Fst ifst, int64 state):
     if not ifst._fst.get().ValidStateId(state):
@@ -3241,7 +3273,7 @@ cdef class MutableArcIterator:
   """
 
   def __repr__(self):
-    return "<MutableArcIterator at 0x{:x}>".format(id(self))
+    return f"<MutableArcIterator at 0x{id(self):x}>"
 
   def __init__(self, MutableFst ifst, int64 state):
     if not ifst._fst.get().ValidStateId(state):
@@ -3360,7 +3392,7 @@ cdef class StateIterator:
   """
 
   def __repr__(self):
-    return "<StateIterator at 0x{:x}>".format(id(self))
+    return f"<StateIterator at 0x{id(self):x}>"
 
   def __init__(self, Fst ifst):
     # Makes copy of the shared_ptr, potentially extending the FST's lifetime.
@@ -3420,23 +3452,23 @@ cdef class StateIterator:
 
 cdef Fst _map(Fst ifst,
                float delta=fst.kDelta,
-               map_type=b"identity",
+               map_type="identity",
                double power=1.,
                weight=None):
-  cdef fst.MapType map_type_enum
-  if not fst.GetMapType(tostring(map_type), addr(map_type_enum)):
-    raise FstArgError("Unknown map type: {!r}".format(map_type))
-  cdef fst.WeightClass wc
-  if map_type_enum == fst.TIMES_MAPPER:
-      wc = _get_WeightClass_or_One(ifst.weight_type(), weight)
+  cdef fst.MapType _map_type
+  if not fst.GetMapType(tostring(map_type), addr(_map_type)):
+    raise FstArgError(f"Unknown map type: {map_type!r}")
+  cdef fst.WeightClass _weight
+  if _map_type == fst.TIMES_MAPPER:
+      _weight = _get_WeightClass_or_One(ifst.weight_type(), weight)
   else:
-      wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
-  return _init_XFst(fst.Map(deref(ifst._fst), map_type_enum, delta, power, wc))
+      _weight = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
+  return _init_XFst(fst.Map(deref(ifst._fst), _map_type, delta, power, _weight))
 
 
 cpdef Fst arcmap(Fst ifst,
                  float delta=fst.kDelta,
-                 map_type=b"identity",
+                 map_type="identity",
                  double power=1.,
                  weight=None):
   """
@@ -3450,17 +3482,16 @@ cpdef Fst arcmap(Fst ifst,
     * identity: maps to self.
     * input_epsilon: replaces all input labels with epsilon.
     * invert: reciprocates all non-Zero weights.
-    * float_power: raises all weights to a floating-point power.
     * output_epsilon: replaces all output labels with epsilon.
     * quantize: quantizes weights.
     * plus: adds a constant to all weights.
-    * power: raises all weights to an integral power.
+    * power: raises all weights to a power.
     * rmweight: replaces all non-Zero weights with 1.
     * superfinal: redirects final states to a new superfinal state.
     * times: right-multiplies a constant by all weights.
     * to_log: converts weights to the log semiring.
     * to_log64: converts weights to the log64 semiring.
-    * to_standard: converts weights to the tropical ("standard") semiring.
+    * to_std: converts weights to the tropical semiring.
 
   Args:
     ifst: The input FST.
@@ -3468,7 +3499,7 @@ cpdef Fst arcmap(Fst ifst,
         `quantize`).
     map_type: A string matching a known mapping operation (see above).
     power: A positive scalar or integer power; ignored unless `map_type` is
-        `float_power` or `power` (in which case it defaults to 1).
+        `power` (in which case it defaults to 1).
     weight: A Weight or weight string passed to the arc-mapper; ignored unless
         `map_type` is `plus` (in which case it defaults to semiring Zero) or
         `times` (in which case it defaults to semiring One).
@@ -3484,7 +3515,7 @@ cpdef Fst arcmap(Fst ifst,
 
 cpdef MutableFst compose(Fst ifst1,
                          Fst ifst2,
-                         compose_filter=b"auto",
+                         compose_filter="auto",
                          bool connect=True):
   """
   compose(ifst1, ifst2, compose_filter="auto", connect=True)
@@ -3508,17 +3539,17 @@ cpdef MutableFst compose(Fst ifst1,
   Returns:
     An FST.
   """
-  cdef unique_ptr[fst.VectorFstClass] tfst
-  tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
-  cdef unique_ptr[fst.ComposeOptions] opts
-  opts.reset(new fst.ComposeOptions(
-      connect,
-      _get_compose_filter(tostring(compose_filter))))
-  fst.Compose(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
-  return _init_MutableFst(tfst.release())
+  cdef unique_ptr[fst.VectorFstClass] _tfst
+  _tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
+  cdef unique_ptr[fst.ComposeOptions] _opts
+  _opts.reset(
+      new fst.ComposeOptions(connect,
+                             _get_compose_filter(tostring(compose_filter))))
+  fst.Compose(deref(ifst1._fst), deref(ifst2._fst), _tfst.get(), deref(_opts))
+  return _init_MutableFst(_tfst.release())
 
 
-cpdef Fst convert(Fst ifst, fst_type=b""):
+cpdef Fst convert(Fst ifst, fst_type=""):
   """
   convert(ifst, fst_type="")
 
@@ -3535,18 +3566,18 @@ cpdef Fst convert(Fst ifst, fst_type=b""):
   Raises:
     FstOpError: Conversion failed.
   """
-  cdef string fst_type_string = tostring(fst_type)
-  cdef unique_ptr[fst.FstClass] tfst
-  tfst.reset(fst.Convert(deref(ifst._fst), fst_type_string))
+  cdef string _fst_type = tostring(fst_type)
+  cdef unique_ptr[fst.FstClass] _tfst
+  _tfst.reset(fst.Convert(deref(ifst._fst), _fst_type))
   # Script-land Convert returns a null pointer to signal failure.
-  if tfst.get() == NULL:
-    raise FstOpError("Conversion to {!r} failed".format(fst_type))
-  return _init_XFst(tfst.release())
+  if _tfst.get() == NULL:
+    raise FstOpError(f"Conversion to {fst_type!r} failed")
+  return _init_XFst(_tfst.release())
 
 
 cpdef MutableFst determinize(Fst ifst,
                              float delta=fst.kShortestDelta,
-                             det_type=b"functional",
+                             det_type="functional",
                              int64 nstate=fst.kNoStateId,
                              int64 subsequential_label=0,
                              weight=None,
@@ -3583,29 +3614,29 @@ cpdef MutableFst determinize(Fst ifst,
   Raises:
     FstArgError: Unknown determinization type.
   """
-  cdef unique_ptr[fst.VectorFstClass] tfst
-  tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+  cdef unique_ptr[fst.VectorFstClass] _tfst
+  _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
   # Threshold is set to semiring Zero (no pruning) if weight unspecified.
-  cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(),
-                                                     weight)
-  cdef fst.DeterminizeType determinize_type_enum
-  if not fst.GetDeterminizeType(tostring(det_type),
-                                addr(determinize_type_enum)):
-    raise FstArgError("Unknown determinization type: {!r}".format(det_type))
-  cdef unique_ptr[fst.DeterminizeOptions] opts
-  opts.reset(new fst.DeterminizeOptions(delta,
-                                        wc,
-                                        nstate,
-                                        subsequential_label,
-                                        determinize_type_enum,
-                                        increment_subsequential_label))
-  fst.Determinize(deref(ifst._fst), tfst.get(), deref(opts))
-  return _init_MutableFst(tfst.release())
+  cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(ifst.weight_type(),
+                                                          weight)
+  cdef fst.DeterminizeType _det_type
+  if not fst.GetDeterminizeType(tostring(det_type), addr(_det_type)):
+    raise FstArgError(f"Unknown determinization type: {det_type!r}")
+  cdef unique_ptr[fst.DeterminizeOptions] _opts
+  _opts.reset(
+      new fst.DeterminizeOptions(delta,
+                                 _weight,
+                                 nstate,
+                                 subsequential_label,
+                                 _det_type,
+                                 increment_subsequential_label))
+  fst.Determinize(deref(ifst._fst), _tfst.get(), deref(_opts))
+  return _init_MutableFst(_tfst.release())
 
 
 cpdef MutableFst difference(Fst ifst1,
                             Fst ifst2,
-                            compose_filter=b"auto",
+                            compose_filter="auto",
                             bool connect=True):
   """
   difference(ifst1, ifst2, compose_filter="auto", connect=True)
@@ -3630,14 +3661,17 @@ cpdef MutableFst difference(Fst ifst1,
   Returns:
     An FST representing the difference of the FSTs.
   """
-  cdef unique_ptr[fst.VectorFstClass] tfst
-  tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
-  cdef unique_ptr[fst.ComposeOptions] opts
-  opts.reset(new fst.ComposeOptions(
-      connect,
-      _get_compose_filter(tostring(compose_filter))))
-  fst.Difference(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
-  return _init_MutableFst(tfst.release())
+  cdef unique_ptr[fst.VectorFstClass] _tfst
+  _tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
+  cdef unique_ptr[fst.ComposeOptions] _opts
+  _opts.reset(
+      new fst.ComposeOptions(connect,
+                            _get_compose_filter(tostring(compose_filter))))
+  fst.Difference(deref(ifst1._fst),
+                 deref(ifst2._fst),
+                 _tfst.get(),
+                 deref(_opts))
+  return _init_MutableFst(_tfst.release())
 
 
 cpdef MutableFst disambiguate(Fst ifst,
@@ -3668,18 +3702,19 @@ cpdef MutableFst disambiguate(Fst ifst,
   Returns:
     An equivalent disambiguated FST.
   """
-  cdef unique_ptr[fst.VectorFstClass] tfst
-  tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+  cdef unique_ptr[fst.VectorFstClass] _tfst
+  _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
   # Threshold is set to semiring Zero (no pruning) if no weight is specified.
-  cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(),
+  cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(ifst.weight_type(),
                                                      weight)
-  cdef unique_ptr[fst.DisambiguateOptions] opts
-  opts.reset(new fst.DisambiguateOptions(delta,
-                                         wc,
-                                         nstate,
-                                         subsequential_label))
-  fst.Disambiguate(deref(ifst._fst), tfst.get(), deref(opts))
-  return _init_MutableFst(tfst.release())
+  cdef unique_ptr[fst.DisambiguateOptions] _opts
+  _opts.reset(
+      new fst.DisambiguateOptions(delta,
+                                  _weight,
+                                  nstate,
+                                  subsequential_label))
+  fst.Disambiguate(deref(ifst._fst), _tfst.get(), deref(_opts))
+  return _init_MutableFst(_tfst.release())
 
 
 cpdef MutableFst epsnormalize(Fst ifst, bool eps_norm_output=False):
@@ -3702,13 +3737,13 @@ cpdef MutableFst epsnormalize(Fst ifst, bool eps_norm_output=False):
   Returns:
     An equivalent epsilon-normalized FST.
   """
-  cdef unique_ptr[fst.VectorFstClass] tfst
-  tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+  cdef unique_ptr[fst.VectorFstClass] _tfst
+  _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
   fst.EpsNormalize(
       deref(ifst._fst),
-      tfst.get(),
+      _tfst.get(),
       fst.EPS_NORM_OUTPUT if eps_norm_output else fst.EPS_NORM_INPUT)
-  return _init_MutableFst(tfst.release())
+  return _init_MutableFst(_tfst.release())
 
 
 cpdef bool equal(Fst ifst1, Fst ifst2, float delta=fst.kDelta):
@@ -3755,7 +3790,7 @@ cpdef bool equivalent(Fst ifst1, Fst ifst2, float delta=fst.kDelta):
 
 cpdef MutableFst intersect(Fst ifst1,
                            Fst ifst2,
-                           compose_filter=b"auto",
+                           compose_filter="auto",
                            bool connect=True):
   """
   intersect(ifst1, ifst2, compose_filter="auto", connect=True)
@@ -3778,14 +3813,14 @@ cpdef MutableFst intersect(Fst ifst1,
   Returns:
     An intersected FST.
   """
-  cdef unique_ptr[fst.VectorFstClass] tfst
-  tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
-  cdef unique_ptr[fst.ComposeOptions] opts
-  opts.reset(new fst.ComposeOptions(
-      connect,
-      _get_compose_filter(tostring(compose_filter))))
-  fst.Intersect(deref(ifst1._fst), deref(ifst2._fst), tfst.get(), deref(opts))
-  return _init_MutableFst(tfst.release())
+  cdef unique_ptr[fst.VectorFstClass] _tfst
+  _tfst.reset(new fst.VectorFstClass(ifst1.arc_type()))
+  cdef unique_ptr[fst.ComposeOptions] _opts
+  _opts.reset(
+      new fst.ComposeOptions(connect,
+                            _get_compose_filter(tostring(compose_filter))))
+  fst.Intersect(deref(ifst1._fst), deref(ifst2._fst), _tfst.get(), deref(_opts))
+  return _init_MutableFst(_tfst.release())
 
 
 cpdef bool isomorphic(Fst ifst1, Fst ifst2, float delta=fst.kDelta):
@@ -3836,11 +3871,12 @@ cpdef MutableFst prune(Fst ifst,
   Returns:
     A pruned FST.
   """
-  cdef unique_ptr[fst.VectorFstClass] tfst
-  tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
-  cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
-  fst.Prune(deref(ifst._fst), tfst.get(), wc, nstate, delta)
-  return _init_MutableFst(tfst.release())
+  cdef unique_ptr[fst.VectorFstClass] _tfst
+  _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+  cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(ifst.weight_type(),
+                                                          weight)
+  fst.Prune(deref(ifst._fst), _tfst.get(), _weight, nstate, delta)
+  return _init_MutableFst(_tfst.release())
 
 
 cpdef MutableFst push(Fst ifst,
@@ -3885,26 +3921,25 @@ cpdef MutableFst push(Fst ifst,
   Returns:
     An equivalent pushed FST.
   """
-  cdef unique_ptr[fst.VectorFstClass] tfst
-  tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+  cdef unique_ptr[fst.VectorFstClass] _tfst
+  _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
   cdef uint8 flags = fst.GetPushFlags(push_weights,
                                       push_labels,
                                       remove_common_affix,
                                       remove_total_weight)
   fst.Push(deref(ifst._fst),
-           tfst.get(),
+           _tfst.get(),
            flags,
            fst.GetReweightType(to_final),
            delta)
-  return _init_MutableFst(tfst.release())
+  return _init_MutableFst(_tfst.release())
 
 
 cpdef bool randequivalent(Fst ifst1,
                           Fst ifst2,
                           int32 npath=1,
                           float delta=fst.kDelta,
-
-                          select=b"uniform",
+                          select="uniform",
                           int32 max_length=INT32_MAX,
                           uint64 seed=0) except *:
   """
@@ -3933,27 +3968,28 @@ cpdef bool randequivalent(Fst ifst1,
   Returns:
     True if the two transducers satisfy the above condition, else False.
   """
-  cdef fst.RandArcSelection ras = _get_rand_arc_selection(tostring(select))
-  cdef unique_ptr[fst.RandGenOptions[fst.RandArcSelection]] opts
+  cdef fst.RandArcSelection _select = _get_rand_arc_selection(tostring(select))
+  cdef unique_ptr[fst.RandGenOptions[fst.RandArcSelection]] _opts
   # The three trailing options will be ignored by RandEquivalent.
-  opts.reset(new fst.RandGenOptions[fst.RandArcSelection](ras,
-                                                          max_length,
-                                                          1,
-                                                          False,
-                                                          False))
+  _opts.reset(
+       new fst.RandGenOptions[fst.RandArcSelection](_select,
+                                                    max_length,
+                                                    1,
+                                                    False,
+                                                    False))
   if seed == 0:
-    seed = time(NULL) + getpid()
+    seed = time(NULL)
   return fst.RandEquivalent(deref(ifst1._fst),
                             deref(ifst2._fst),
                             npath,
-                            deref(opts),
+                            deref(_opts),
                             delta,
                             seed)
 
 
 cpdef MutableFst randgen(Fst ifst,
                          int32 npath=1,
-                         select=b"uniform",
+                         select="uniform",
                          int32 max_length=INT32_MAX,
                          bool weighted=False,
                          bool remove_total_weight=False,
@@ -3987,24 +4023,25 @@ cpdef MutableFst randgen(Fst ifst,
   Returns:
     An FST containing one or more random paths.
   """
-  cdef fst.RandArcSelection ras = _get_rand_arc_selection(tostring(select))
-  cdef unique_ptr[fst.RandGenOptions[fst.RandArcSelection]] opts
-  opts.reset(new fst.RandGenOptions[fst.RandArcSelection](ras,
-                                                          max_length,
-                                                          npath,
-                                                          weighted,
-                                                          remove_total_weight))
-  cdef unique_ptr[fst.VectorFstClass] tfst
-  tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+  cdef fst.RandArcSelection _select = _get_rand_arc_selection(tostring(select))
+  cdef unique_ptr[fst.RandGenOptions[fst.RandArcSelection]] _opts
+  _opts.reset(
+      new fst.RandGenOptions[fst.RandArcSelection](_select,
+                                                   max_length,
+                                                   npath,
+                                                   weighted,
+                                                   remove_total_weight))
+  cdef unique_ptr[fst.VectorFstClass] _tfst
+  _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
   if seed == 0:
-    seed = time(NULL) + getpid()
-  fst.RandGen(deref(ifst._fst), tfst.get(), deref(opts), seed)
-  return _init_MutableFst(tfst.release())
+    seed = time(NULL)
+  fst.RandGen(deref(ifst._fst), _tfst.get(), deref(_opts), seed)
+  return _init_MutableFst(_tfst.release())
 
 
 cpdef MutableFst replace(pairs,
-                         call_arc_labeling=b"input",
-                         return_arc_labeling=b"neither",
+                         call_arc_labeling="input",
+                         return_arc_labeling="neither",
                          bool epsilon_on_replace=False,
                          int64 return_label=0):
   """
@@ -4043,23 +4080,23 @@ cpdef MutableFst replace(pairs,
   Returns:
     An FST resulting from expanding the input RTN.
   """
+  cdef int64 _label
+  cdef Fst _pfst
   cdef vector[fst.LabelFstClassPair] _pairs
-  cdef int64 label
-  cdef Fst pfst
-  for (label, pfst) in pairs:
-    _pairs.push_back(fst.LabelFstClassPair(label, pfst._fst.get()))
-  cdef unique_ptr[fst.VectorFstClass] tfst
-  tfst.reset(new fst.VectorFstClass(_pairs[0].second.ArcType()))
-  cdef fst.ReplaceLabelType cal = _get_replace_label_type(
+  for (_label, _pfst) in pairs:
+      _pairs.push_back(fst.LabelFstClassPair(_label, _pfst._fst.get()))
+  cdef unique_ptr[fst.VectorFstClass] _tfst
+  _tfst.reset(new fst.VectorFstClass(_pairs[0].second.ArcType()))
+  cdef fst.ReplaceLabelType _cal = _get_replace_label_type(
       tostring(call_arc_labeling),
       epsilon_on_replace)
-  cdef fst.ReplaceLabelType ral = _get_replace_label_type(
+  cdef fst.ReplaceLabelType _ral = _get_replace_label_type(
       tostring(return_arc_labeling),
       epsilon_on_replace)
-  cdef unique_ptr[fst.ReplaceOptions] opts
-  opts.reset(new fst.ReplaceOptions(_pairs[0].first, cal, ral, return_label))
-  fst.Replace(_pairs, tfst.get(), deref(opts))
-  return _init_MutableFst(tfst.release())
+  cdef unique_ptr[fst.ReplaceOptions] _opts
+  _opts.reset(new fst.ReplaceOptions(_pairs[0].first, _cal, _ral, return_label))
+  fst.Replace(_pairs, _tfst.get(), deref(_opts))
+  return _init_MutableFst(_tfst.release())
 
 
 cpdef MutableFst reverse(Fst ifst, bool require_superinitial=True):
@@ -4081,43 +4118,39 @@ cpdef MutableFst reverse(Fst ifst, bool require_superinitial=True):
   Returns:
     A reversed FST.
   """
-  cdef unique_ptr[fst.VectorFstClass] tfst
-  tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
-  fst.Reverse(deref(ifst._fst), tfst.get(), require_superinitial)
-  return _init_MutableFst(tfst.release())
+  cdef unique_ptr[fst.VectorFstClass] _tfst
+  _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+  fst.Reverse(deref(ifst._fst), _tfst.get(), require_superinitial)
+  return _init_MutableFst(_tfst.release())
 
 
 # Pure C++ helper for shortestdistance.
 
 
-cdef vector[fst.WeightClass] *_shortestdistance(Fst ifst,
-                                                float delta=fst.kShortestDelta,
-                                                int64 nstate=fst.kNoStateId,
-                                                queue_type=b"auto",
-                                                bool reverse=False) except *:
-  cdef unique_ptr[vector[fst.WeightClass]] distance
-  distance.reset(new vector[fst.WeightClass]())
-  # For scoping reasons, these have to be declared here even though they may
-  # not be used in all cases.
-  cdef unique_ptr[fst.ShortestDistanceOptions] opts
+cdef void _shortestdistance(Fst ifst,
+                            vector[fst.WeightClass] *distance,
+                            float delta=fst.kShortestDelta,
+                            int64 nstate=fst.kNoStateId,
+                            queue_type="auto",
+                            bool reverse=False) except *:
+  cdef unique_ptr[fst.ShortestDistanceOptions] _opts
   if reverse:
     # Only the simpler signature supports shortest distance to final states;
     # `nstate` and `queue_type` arguments are ignored.
-    fst.ShortestDistance(deref(ifst._fst), distance.get(), True, delta)
+    fst.ShortestDistance(deref(ifst._fst), distance, True, delta)
   else:
-    opts.reset(new fst.ShortestDistanceOptions(
-        _get_queue_type(tostring(queue_type)),
-        fst.ANY_ARC_FILTER,
-        nstate,
-        delta))
-    fst.ShortestDistance(deref(ifst._fst), distance.get(), deref(opts))
-  return distance.release()
+    _opts.reset(
+        new fst.ShortestDistanceOptions(_get_queue_type(tostring(queue_type)),
+                                        fst.ANY_ARC_FILTER,
+                                        nstate,
+                                        delta))
+    fst.ShortestDistance(deref(ifst._fst), distance, deref(_opts))
 
 
 def shortestdistance(Fst ifst,
                      float delta=fst.kShortestDelta,
                      int64 nstate=fst.kNoStateId,
-                     queue_type=b"auto",
+                     queue_type="auto",
                      bool reverse=False):
   """
   shortestdistance(ifst, delta=1e-6, nstate=NO_STATE_ID,
@@ -4145,17 +4178,17 @@ def shortestdistance(Fst ifst,
   Returns:
     A list of Weight objects representing the shortest distance for each state.
   """
-  cdef unique_ptr[vector[fst.WeightClass]] distance
-  distance.reset(_shortestdistance(ifst, delta, nstate, queue_type, reverse))
-  cdef string weight_type = ifst.weight_type()
-  return [Weight(weight_type, weight.ToString()) for weight in deref(distance)]
+  cdef vector[fst.WeightClass] _distance
+  _shortestdistance(ifst, addr(_distance), delta, nstate, queue_type, reverse)
+  return [Weight(ifst._fst.get().WeightType(), weight.ToString())
+          for weight in _distance]
 
 
 cpdef MutableFst shortestpath(Fst ifst,
                               float delta=fst.kShortestDelta,
                               int32 nshortest=1,
                               int64 nstate=fst.kNoStateId,
-                              queue_type=b"auto",
+                              queue_type="auto",
                               bool unique=False,
                               weight=None):
   """
@@ -4188,19 +4221,21 @@ cpdef MutableFst shortestpath(Fst ifst,
   Returns:
     An FST containing the n-shortest paths.
   """
-  cdef unique_ptr[fst.VectorFstClass] tfst
-  tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+  cdef unique_ptr[fst.VectorFstClass] _tfst
+  _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
   # Threshold is set to semiring Zero (no pruning) if no weight is specified.
-  cdef fst.WeightClass wc = _get_WeightClass_or_Zero(ifst.weight_type(), weight)
-  cdef unique_ptr[fst.ShortestPathOptions] opts
-  opts.reset(new fst.ShortestPathOptions(_get_queue_type(tostring(queue_type)),
-                                         nshortest,
-                                         unique,
-                                         delta,
-                                         wc,
-                                         nstate))
-  fst.ShortestPath(deref(ifst._fst), tfst.get(), deref(opts))
-  return _init_MutableFst(tfst.release())
+  cdef fst.WeightClass _weight = _get_WeightClass_or_Zero(ifst.weight_type(),
+                                                          weight)
+  cdef unique_ptr[fst.ShortestPathOptions] _opts
+  _opts.reset(
+      new fst.ShortestPathOptions(_get_queue_type(tostring(queue_type)),
+                                  nshortest,
+                                  unique,
+                                  delta,
+                                  _weight,
+                                  nstate))
+  fst.ShortestPath(deref(ifst._fst), _tfst.get(), deref(_opts))
+  return _init_MutableFst(_tfst.release())
 
 
 cpdef Fst statemap(Fst ifst, map_type):
@@ -4248,10 +4283,10 @@ cpdef MutableFst synchronize(Fst ifst):
   Returns:
     An equivalent synchronized FST.
   """
-  cdef unique_ptr[fst.VectorFstClass] tfst
-  tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
-  fst.Synchronize(deref(ifst._fst), tfst.get())
-  return _init_MutableFst(tfst.release())
+  cdef unique_ptr[fst.VectorFstClass] _tfst
+  _tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
+  fst.Synchronize(deref(ifst._fst), _tfst.get())
+  return _init_MutableFst(_tfst.release())
 
 
 ## Compiler.
@@ -4276,7 +4311,7 @@ cdef class Compiler:
 
   Compiler options (symbol tables, etc.) are set at construction time.
 
-      compiler = fst.Compiler(isymbols=ascii_syms, osymbols=ascii_syms)
+      compiler = fst.Compiler(isymbols=ascii_symbols, osymbols=ascii_symbols)
 
   Once constructed, Compiler instances behave like a file handle opened for
   writing:
@@ -4309,8 +4344,8 @@ cdef class Compiler:
   """
 
   def __cinit__(self,
-                string fst_type=b"vector",
-                string arc_type=b"standard",
+                str fst_type="vector",
+                str arc_type="standard",
                 SymbolTable isymbols=None,
                 SymbolTable osymbols=None,
                 SymbolTable ssymbols=None,
@@ -4351,23 +4386,23 @@ cdef class Compiler:
     Raises:
       FstOpError: Compilation failed.
     """
-    cdef unique_ptr[fst.FstClass] tfst
-    tfst.reset(fst.CompileFstInternal(deref(self._sstrm),
-                                      b"<pywrapfst>",
-                                      self._fst_type,
-                                      self._arc_type,
-                                      self._isymbols,
-                                      self._osymbols,
-                                      self._ssymbols,
-                                      self._acceptor,
-                                      self._keep_isymbols,
-                                      self._keep_osymbols,
-                                      self._keep_state_numbering,
-                                      self._allow_negative_labels))
+    cdef unique_ptr[fst.FstClass] _tfst
+    _tfst.reset(fst.CompileFstInternal(deref(self._sstrm),
+                                       b"<pywrapfst>",
+                                       self._fst_type,
+                                       self._arc_type,
+                                       self._isymbols,
+                                       self._osymbols,
+                                       self._ssymbols,
+                                       self._acceptor,
+                                       self._keep_isymbols,
+                                       self._keep_osymbols,
+                                       self._keep_state_numbering,
+                                       self._allow_negative_labels))
     self._sstrm.reset(new stringstream())
-    if tfst.get() == NULL:
+    if _tfst.get() == NULL:
       raise FstOpError("Compilation failed")
-    return _init_XFst(tfst.release())
+    return _init_XFst(_tfst.release())
 
   cpdef void write(self, expression):
     """
@@ -4385,10 +4420,10 @@ cdef class Compiler:
     Args:
       expression: A string expression to add to compiler string buffer.
     """
-    cdef string line = tostring(expression)
-    if not line.empty() and line.back() != b'\n':
-      line.append(b'\n')
-    deref(self._sstrm) << line
+    cdef string _line = tostring(expression)
+    if not _line.empty() and _line.back() != b'\n':
+      _line.append(b'\n')
+    deref(self._sstrm) << _line
 
 
 ## FarReader and FarWriter.
@@ -4411,11 +4446,10 @@ cdef class FarReader:
   """
 
   def __init__(self):
-    raise FstDeletedConstructorError(
-        "Cannot construct {}".format(self.__class__.__name__))
+    raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")
 
   def __repr__(self):
-    return "<{} FarReader at 0x{:x}>".format(self.far_type(), id(self))
+    return f"<{self.far_type()} FarReader at 0x{id(self):x}>"
 
   @classmethod
   def open(cls, *sources):
@@ -4436,16 +4470,14 @@ cdef class FarReader:
     Raises:
       FstIOError: Read failed.
     """
-    cdef vector[string] source_strings
-    for source in sources:
-      source_strings.push_back(tostring(source))
-    cdef unique_ptr[fst.FarReaderClass] tfar
-    tfar.reset(fst.FarReaderClass.Open(source_strings))
-    if tfar.get() == NULL:
-      raise FstIOError("Read failed: {!r}".format(sources))
-    cdef FarReader result = FarReader.__new__(FarReader)
-    result._reader.reset(tfar.release())
-    return result
+    cdef vector[string] _sources = [path_tostring(source) for source in sources]
+    cdef unique_ptr[fst.FarReaderClass] _tfar
+    _tfar.reset(fst.FarReaderClass.Open(_sources))
+    if _tfar.get() == NULL:
+      raise FstIOError(f"Read failed: {sources!r}")
+    cdef FarReader reader = FarReader.__new__(FarReader)
+    reader._reader.reset(_tfar.release())
+    return reader
 
   cpdef string arc_type(self):
     """
@@ -4539,6 +4571,18 @@ cdef class FarReader:
     else:
       raise KeyError(key)
 
+  def __next__(self):
+    if self.done():
+      raise StopIteration
+    cdef string _key = self.get_key()
+    cdef Fst _fst = self.get_fst()
+    self.next()
+    return (_key, _fst)
+
+  # This just registers this class as a possible iterator.
+  def __iter__(self):
+    return self
+
 
 cdef class FarWriter:
 
@@ -4561,14 +4605,13 @@ cdef class FarWriter:
   """
 
   def __init__(self):
-    raise FstDeletedConstructorError(
-        "Cannot construct {}".format(self.__class__.__name__))
+    raise NotImplementedError(f"Cannot construct {self.__class__.__name__}")
 
   def __repr__(self):
-    return "<{} FarWriter at 0x{:x}>".format(self.far_type(), id(self))
+    return f"<{self.far_type()} FarWriter at 0x{id(self):x}>"
 
   @classmethod
-  def create(cls, source, arc_type=b"standard", far_type=b"default"):
+  def create(cls, source, arc_type="standard", far_type="default"):
     """
     FarWriter.
 
@@ -4589,16 +4632,16 @@ cdef class FarWriter:
     Raises:
       FstIOError: Read failed.
     """
-    cdef fst.FarType ft = fst.GetFarType(tostring(far_type))
-    cdef fst.FarWriterClass *tfar = fst.FarWriterClass.Create(
-        tostring(source),
+    cdef unique_ptr[fst.FarWriterClass] _tfar
+    _tfar.reset(fst.FarWriterClass.Create(
+        path_tostring(source),
         tostring(arc_type),
-        ft)
-    if tfar == NULL:
-      raise FstIOError("Open failed: {!r}".format(source))
-    cdef FarWriter result = FarWriter.__new__(FarWriter)
-    result._writer.reset(tfar)
-    return result
+        _get_far_type(tostring(far_type))))
+    if _tfar.get() == NULL:
+      raise FstIOError(f"Open failed: {source!r}")
+    cdef FarWriter writer = FarWriter.__new__(FarWriter)
+    writer._writer = move(_tfar)
+    return writer
 
   # NB: Invoking this method may be dangerous: calling any other method on the
   # instance after this is invoked may result in a null dereference.
index 25656d1..77b32d1 100644 (file)
@@ -15,7 +15,7 @@ libfst_LTLIBRARIES = phi-fst.la rho-fst.la sigma-fst.la
 lib_LTLIBRARIES = libfstspecial.la
 
 libfstspecial_la_SOURCES = phi-fst.cc rho-fst.cc sigma-fst.cc
-libfstspecial_la_LDFLAGS = -version-info 20:0:0
+libfstspecial_la_LDFLAGS = -version-info 21:0:0
 
 phi_fst_la_SOURCES = phi-fst.cc
 phi_fst_la_LDFLAGS = -avoid-version -module
index dc951e7..09c89fa 100644 (file)
@@ -388,7 +388,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include -I$(srcdir)/../../bin $(ICU_CPPFLAGS)
 libfst_LTLIBRARIES = phi-fst.la rho-fst.la sigma-fst.la
 lib_LTLIBRARIES = libfstspecial.la
 libfstspecial_la_SOURCES = phi-fst.cc rho-fst.cc sigma-fst.cc
-libfstspecial_la_LDFLAGS = -version-info 20:0:0
+libfstspecial_la_LDFLAGS = -version-info 21:0:0
 phi_fst_la_SOURCES = phi-fst.cc
 phi_fst_la_LDFLAGS = -avoid-version -module
 rho_fst_la_SOURCES = rho-fst.cc
index e13122a..2c00f0e 100644 (file)
@@ -9,7 +9,7 @@
 
 DEFINE_int64(phi_fst_phi_label, 0,
              "Label of transitions to be interpreted as phi ('failure') "
-              "transitions");
+             "transitions");
 DEFINE_bool(phi_fst_phi_loop, true,
             "When true, a phi self loop consumes a symbol");
 DEFINE_string(phi_fst_rewrite_mode, "auto",
index 1bdebd9..b68ca0c 100644 (file)
@@ -122,7 +122,7 @@ fst/state-table.h fst/statesort.h fst/string-weight.h fst/string.h \
 fst/symbol-table-ops.h fst/symbol-table.h fst/synchronize.h \
 fst/test-properties.h fst/topsort.h fst/tuple-weight.h fst/types.h \
 fst/union-find.h fst/union-weight.h fst/union.h fst/util.h fst/vector-fst.h \
-fst/verify.h fst/visit.h fst/weight.h \
+fst/verify.h fst/visit.h fst/windows_defs.inc fst/weight.h \
 $(compress_include_headers) \
 $(far_include_headers) \
 $(linear_include_headers) \
index 66140a3..bc9570e 100644 (file)
@@ -154,7 +154,7 @@ am__nobase_include_HEADERS_DIST = fst/accumulator.h fst/add-on.h \
        fst/symbol-table.h fst/synchronize.h fst/test-properties.h \
        fst/topsort.h fst/tuple-weight.h fst/types.h fst/union-find.h \
        fst/union-weight.h fst/union.h fst/util.h fst/vector-fst.h \
-       fst/verify.h fst/visit.h fst/weight.h \
+       fst/verify.h fst/visit.h fst/windows_defs.inc fst/weight.h \
        fst/extensions/compress/compress.h \
        fst/extensions/compress/compressscript.h \
        fst/extensions/compress/elias.h \
@@ -513,7 +513,7 @@ fst/state-table.h fst/statesort.h fst/string-weight.h fst/string.h \
 fst/symbol-table-ops.h fst/symbol-table.h fst/synchronize.h \
 fst/test-properties.h fst/topsort.h fst/tuple-weight.h fst/types.h \
 fst/union-find.h fst/union-weight.h fst/union.h fst/util.h fst/vector-fst.h \
-fst/verify.h fst/visit.h fst/weight.h \
+fst/verify.h fst/visit.h fst/windows_defs.inc fst/weight.h \
 $(compress_include_headers) \
 $(far_include_headers) \
 $(linear_include_headers) \
index 563245a..8fc6237 100644 (file)
@@ -22,6 +22,7 @@
 namespace fst {
 
 // This class accumulates arc weights using the semiring Plus().
+// Sum(w, aiter, begin, end) has time complexity O(begin - end).
 template <class A>
 class DefaultAccumulator {
  public:
@@ -56,6 +57,7 @@ class DefaultAccumulator {
 
 // This class accumulates arc weights using the log semiring Plus() assuming an
 // arc weight has a WeightConvert specialization to and from log64 weights.
+// Sum(w, aiter, begin, end) has time complexity O(begin - end).
 template <class A>
 class LogAccumulator {
  public:
@@ -194,6 +196,9 @@ class MutableFastLogAccumulatorData : public FastLogAccumulatorData {
 // arc weight has a WeightConvert specialization to and from log64 weights. The
 // member function Init(fst) has to be called to setup pre-computed weight
 // information.
+// Sum(w, aiter, begin, end) has time complexity O(arc_limit_) or O(arc_period_)
+// depending on whether the state has more than arc_limit_ arcs
+// Space complexity is O(CountStates(fst) + CountArcs(fst) / arc_period_).
 template <class A>
 class FastLogAccumulator {
  public:
@@ -457,7 +462,7 @@ class CacheLogAccumulatorData {
 // WeightConvert specialization to and from log64 weights. It is similar to the
 // FastLogAccumator. However here, the accumulated weights are pre-computed and
 // stored only for the states that are visited. The member function Init(fst)
-// has to be called to setup this accumulator.
+// has to be called to setup this accumulator.  Space complexity is O(gc_limit).
 template <class Arc>
 class CacheLogAccumulator {
  public:
@@ -553,9 +558,9 @@ class CacheLogAccumulator {
     auto pos = aiter->Position();
     if (weights_) {
       Extend(fst_->NumArcs(s_), aiter);
-      return std::lower_bound(weights_->begin() + pos + 1, weights_->end(),
-                              f, std::greater<double>()) -
-          weights_->begin() - 1;
+      return std::lower_bound(weights_->begin() + pos + 1, weights_->end(), f,
+                              std::greater<double>()) -
+             weights_->begin() - 1;
     } else {
       size_t n = 0;
       auto x = FloatLimits<double>::PosInfinity();
@@ -624,7 +629,6 @@ class CacheLogAccumulator {
     }
   }
 
-
   const WeightConvert<Weight, Log64Weight> to_log_weight_{};
   const WeightConvert<Log64Weight, Weight> to_weight_{};
   ssize_t arc_limit_;                    // Minimum # of arcs to cache a state.
index fc060ac..e70c41d 100644 (file)
@@ -43,10 +43,8 @@ namespace fst {
 template <typename Arc>
 class ArcArena {
  public:
-  explicit ArcArena(size_t block_size = 256,
-                    size_t max_retained_size = 1e6)
-      : block_size_(block_size),
-        max_retained_size_(max_retained_size) {
+  explicit ArcArena(size_t block_size = 256, size_t max_retained_size = 1e6)
+      : block_size_(block_size), max_retained_size_(max_retained_size) {
     blocks_.emplace_back(MakeSharedBlock(block_size_));
     first_block_size_ = block_size_;
     total_size_ = block_size_;
@@ -55,8 +53,10 @@ class ArcArena {
     next_ = arcs_;
   }
 
-  ArcArena(const ArcArena& copy)
-      : arcs_(copy.arcs_), next_(copy.next_), end_(copy.end_),
+  ArcArena(const ArcArena &copy)
+      : arcs_(copy.arcs_),
+        next_(copy.next_),
+        end_(copy.end_),
         block_size_(copy.block_size_),
         first_block_size_(copy.first_block_size_),
         total_size_(copy.total_size_),
@@ -70,7 +70,7 @@ class ArcArena {
     NewBlock(n);
   }
 
-  void PushArc(const Arcarc) {
+  void PushArc(const Arc &arc) {
     if (next_ == end_) {
       size_t length = next_ - arcs_;
       NewBlock(length * 2);
@@ -79,7 +79,7 @@ class ArcArena {
     ++next_;
   }
 
-  const ArcGetArcs() {
+  const Arc *GetArcs() {
     const auto *arcs = arcs_;
     arcs_ = next_;
     return arcs;
@@ -141,9 +141,6 @@ class ArcArenaStateStore {
   using Weight = typename Arc::Weight;
   using StateId = typename Arc::StateId;
 
-  ArcArenaStateStore() : arena_(64 * 1024) {
-  }
-
   class State {
    public:
     Weight Final() const { return final_weight_; }
@@ -158,7 +155,7 @@ class ArcArenaStateStore {
 
     const Arc *Arcs() const { return arcs_; }
 
-    intMutableRefCount() const { return nullptr; }
+    int *MutableRefCount() const { return nullptr; }
 
    private:
     State(Weight final_weight, int32 niepsilons, int32 noepsilons, int32 narcs,
@@ -180,7 +177,7 @@ class ArcArenaStateStore {
 
   template <class Expander>
   State *FindOrExpand(Expander &expander, StateId state_id) {  // NOLINT
-    auto it = cache_.insert(std::pair<StateId, State*>(state_id, nullptr));
+    auto it = cache_.insert(std::pair<StateId, State *>(state_id, nullptr));
     if (!it.second) return it.first->second;
     // Needs a new state.
     StateBuilder builder(&arena_);
index 47cd41b..3896f7e 100644 (file)
@@ -199,8 +199,8 @@ void ArcMap(const Fst<A> &ifst, MutableFst<B> *ofst, C *mapper) {
   }
   const auto final_action = mapper->FinalAction();
   if (ifst.Properties(kExpanded, false)) {
-    ofst->ReserveStates(
-        CountStates(ifst) + (final_action == MAP_NO_SUPERFINAL ? 0 : 1));
+    ofst->ReserveStates(CountStates(ifst) +
+                        (final_action == MAP_NO_SUPERFINAL ? 0 : 1));
   }
   // Adds all states.
   for (StateIterator<Fst<A>> siter(ifst); !siter.Done(); siter.Next()) {
@@ -526,20 +526,14 @@ class ArcMapFst : public ImplToFst<internal::ArcMapFstImpl<A, B, C>> {
   friend class ArcIterator<ArcMapFst<A, B, C>>;
   friend class StateIterator<ArcMapFst<A, B, C>>;
 
-  ArcMapFst(const Fst<A> &fst, const C &mapper, const ArcMapFstOptions &opts)
+  ArcMapFst(const Fst<A> &fst, const C &mapper,
+            const ArcMapFstOptions &opts = ArcMapFstOptions())
       : ImplToFst<Impl>(std::make_shared<Impl>(fst, mapper, opts)) {}
 
-  ArcMapFst(const Fst<A> &fst, C *mapper, const ArcMapFstOptions &opts)
+  ArcMapFst(const Fst<A> &fst, C *mapper,
+            const ArcMapFstOptions &opts = ArcMapFstOptions())
       : ImplToFst<Impl>(std::make_shared<Impl>(fst, mapper, opts)) {}
 
-  ArcMapFst(const Fst<A> &fst, const C &mapper)
-      : ImplToFst<Impl>(
-            std::make_shared<Impl>(fst, mapper, ArcMapFstOptions())) {}
-
-  ArcMapFst(const Fst<A> &fst, C *mapper)
-      : ImplToFst<Impl>(
-            std::make_shared<Impl>(fst, mapper, ArcMapFstOptions())) {}
-
   // See Fst<>::Copy() for doc.
   ArcMapFst(const ArcMapFst &fst, bool safe = false)
       : ImplToFst<Impl>(fst, safe) {}
@@ -739,7 +733,7 @@ class SuperFinalMapper {
   using FromArc = A;
   using ToArc = A;
   using Label = typename FromArc::Label;
-  using Weight = typename FromArc::Weight;;
+  using Weight = typename FromArc::Weight;
 
   // Arg allows setting super-final label.
   constexpr explicit SuperFinalMapper(Label final_label = 0)
@@ -770,8 +764,8 @@ class SuperFinalMapper {
     if (final_label_ == 0) {
       return props & kAddSuperFinalProperties;
     } else {
-      return props & kAddSuperFinalProperties &
-          kILabelInvariantProperties & kOLabelInvariantProperties;
+      return props & kAddSuperFinalProperties & kILabelInvariantProperties &
+             kOLabelInvariantProperties;
     }
   }
 
@@ -849,14 +843,14 @@ class ToGallicMapper {
     // Super-final arc.
     if (arc.nextstate == kNoStateId && arc.weight != AW::Zero()) {
       return ToArc(0, 0, GW(SW::One(), arc.weight), kNoStateId);
-    // Super-non-final arc.
+      // Super-non-final arc.
     } else if (arc.nextstate == kNoStateId) {
       return ToArc(0, 0, GW::Zero(), kNoStateId);
-    // Epsilon label.
+      // Epsilon label.
     } else if (arc.olabel == 0) {
       return ToArc(arc.ilabel, arc.ilabel, GW(SW::One(), arc.weight),
                    arc.nextstate);
-    // Regular label.
+      // Regular label.
     } else {
       return ToArc(arc.ilabel, arc.ilabel, GW(SW(arc.olabel), arc.weight),
                    arc.nextstate);
@@ -1214,10 +1208,10 @@ class RmWeightMapper {
   using ToWeight = typename ToArc::Weight;
 
   ToArc operator()(const FromArc &arc) const {
-    return ToArc(arc.ilabel, arc.olabel,
-                 arc.weight != FromWeight::Zero() ?
-                 ToWeight::One() : ToWeight::Zero(),
-                 arc.nextstate);
+    return ToArc(
+        arc.ilabel, arc.olabel,
+        arc.weight != FromWeight::Zero() ? ToWeight::One() : ToWeight::Zero(),
+        arc.nextstate);
   }
 
   constexpr MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
index d74c16a..59b868e 100644 (file)
@@ -18,6 +18,7 @@
 #include <fst/types.h>
 #include <fst/log.h>
 #include <fst/memory.h>
+#include <fst/windows_defs.inc>
 #include <unordered_set>
 
 namespace fst {
index d85c1c1..4ddccb5 100644 (file)
@@ -866,8 +866,9 @@ class CacheBaseImpl : public FstImpl<typename State::Arc> {
         max_expanded_state_id_(-1),
         cache_gc_(opts.gc),
         cache_limit_(opts.gc_limit),
-        cache_store_(opts.store ? opts.store : new CacheStore(CacheOptions(
-                                                   opts.gc, opts.gc_limit))),
+        cache_store_(
+            opts.store ? opts.store
+                       : new CacheStore(CacheOptions(opts.gc, opts.gc_limit))),
         new_cache_store_(!opts.store),
         own_cache_store_(opts.store ? opts.own_store : true) {}
 
@@ -897,7 +898,9 @@ class CacheBaseImpl : public FstImpl<typename State::Arc> {
     }
   }
 
-  ~CacheBaseImpl() override { if (own_cache_store_) delete cache_store_; }
+  ~CacheBaseImpl() override {
+    if (own_cache_store_) delete cache_store_;
+  }
 
   void SetStart(StateId s) {
     cache_start_ = s;
index df85739..9cb6fd5 100644 (file)
@@ -266,7 +266,7 @@ class CompactArcStore {
   Unsigned *states_ = nullptr;
   // Unowned pointer into compacts_region_.
   Element *compacts_ = nullptr;
-  size_t nstates_  = 0;
+  size_t nstates_ = 0;
   size_t ncompacts_ = 0;
   size_t narcs_ = 0;
   ssize_t start_ = kNoStateId;
@@ -711,8 +711,8 @@ class CompactArcState {
     s_ = s;
     range_ = compactor->CompactsRange(s);
     if (range_.second != 0 &&
-        compactor->ComputeArc(s, range_.first, kArcILabelValue).ilabel
-        == kNoLabel) {
+        compactor->ComputeArc(s, range_.first, kArcILabelValue).ilabel ==
+            kNoLabel) {
       has_final_ = true;
       ++range_.first;
       --range_.second;
@@ -792,8 +792,8 @@ class CompactArcState<ArcCompactor, U,
     }
     if (num_arcs_ > 0) {
       compacts_ = &(store->Compacts(offset));
-      if (arc_compactor_->Expand(s_, *compacts_, kArcILabelValue).ilabel
-          == kNoStateId) {
+      if (arc_compactor_->Expand(s_, *compacts_, kArcILabelValue).ilabel ==
+          kNoStateId) {
         ++compacts_;
         --num_arcs_;
         has_final_ = true;
@@ -840,17 +840,15 @@ class CompactFstImpl
   using FstImpl<Arc>::WriteHeader;
 
   using ImplBase = CacheBaseImpl<typename CacheStore::State, CacheStore>;
-  using ImplBase::PushArc;
   using ImplBase::HasArcs;
   using ImplBase::HasFinal;
   using ImplBase::HasStart;
+  using ImplBase::PushArc;
   using ImplBase::SetArcs;
   using ImplBase::SetFinal;
   using ImplBase::SetStart;
 
-  CompactFstImpl()
-      : ImplBase(CompactFstOptions()),
-        compactor_() {
+  CompactFstImpl() : ImplBase(CompactFstOptions()), compactor_() {
     SetType(Compactor::Type());
     SetProperties(kNullProperties | kStaticProperties);
   }
@@ -867,11 +865,12 @@ class CompactFstImpl
     SetInputSymbols(fst.InputSymbols());
     SetOutputSymbols(fst.OutputSymbols());
     if (compactor_->Error()) SetProperties(kError, kError);
-    uint64 copy_properties = fst.Properties(kMutable, false) ?
-        fst.Properties(kCopyProperties, true):
-        CheckProperties(fst,
-                        kCopyProperties & ~kWeightedCycles & ~kUnweightedCycles,
-                        kCopyProperties);
+    uint64 copy_properties =
+        fst.Properties(kMutable, false)
+            ? fst.Properties(kCopyProperties, true)
+            : CheckProperties(
+                  fst, kCopyProperties & ~kWeightedCycles & ~kUnweightedCycles,
+                  kCopyProperties);
     if ((copy_properties & kError) || !compactor_->IsCompatible(fst)) {
       FSTERROR() << "CompactFstImpl: Input Fst incompatible with compactor";
       SetProperties(kError, kError);
@@ -892,9 +891,9 @@ class CompactFstImpl
   // does so as well.
   CompactFstImpl(const CompactFstImpl &impl)
       : ImplBase(impl),
-        compactor_(impl.compactor_ == nullptr ?
-                   std::make_shared<Compactor>() :
-                   std::make_shared<Compactor>(*impl.compactor_)) {
+        compactor_(impl.compactor_ == nullptr
+                       ? std::make_shared<Compactor>()
+                       : std::make_shared<Compactor>(*impl.compactor_)) {
     SetType(impl.Type());
     SetProperties(impl.Properties());
     SetInputSymbols(impl.InputSymbols());
@@ -976,8 +975,8 @@ class CompactFstImpl
     if (hdr.Version() == kAlignedFileVersion) {
       hdr.SetFlags(hdr.GetFlags() | FstHeader::IS_ALIGNED);
     }
-    impl->compactor_ = std::shared_ptr<Compactor>(
-        Compactor::Read(strm, opts, hdr));
+    impl->compactor_ =
+        std::shared_ptr<Compactor>(Compactor::Read(strm, opts, hdr));
     if (!impl->compactor_) {
       return nullptr;
     }
@@ -1031,8 +1030,8 @@ class CompactFstImpl
  protected:
   template <class OtherArc, class OtherCompactor, class OtherCacheStore>
   explicit CompactFstImpl(
-    const CompactFstImpl<OtherArc, OtherCompactor, OtherCacheStore> &impl)
-    : compactor_(std::make_shared<Compactor>(*impl.GetCompactor())) {
+      const CompactFstImpl<OtherArc, OtherCompactor, OtherCacheStore> &impl)
+      : compactor_(std::make_shared<Compactor>(*impl.GetCompactor())) {
     SetType(impl.Type());
     SetProperties(impl.Properties());
     SetInputSymbols(impl.InputSymbols());
index d44e79c..00512a1 100644 (file)
@@ -113,6 +113,40 @@ std::unique_ptr<T> WrapUnique(T *ptr) {
   return std::unique_ptr<T>(ptr);
 }
 
+// Range utilities
+
+// A range adaptor for a pair of iterators.
+//
+// This just wraps two iterators into a range-compatible interface. Nothing
+// fancy at all.
+template <typename IteratorT>
+class iterator_range {
+ public:
+  using iterator = IteratorT;
+  using const_iterator = IteratorT;
+  using value_type = typename std::iterator_traits<IteratorT>::value_type;
+
+  iterator_range() : begin_iterator_(), end_iterator_() {}
+  iterator_range(IteratorT begin_iterator, IteratorT end_iterator)
+      : begin_iterator_(std::move(begin_iterator)),
+        end_iterator_(std::move(end_iterator)) {}
+
+  IteratorT begin() const { return begin_iterator_; }
+  IteratorT end() const { return end_iterator_; }
+
+ private:
+  IteratorT begin_iterator_, end_iterator_;
+};
+
+// Convenience function for iterating over sub-ranges.
+//
+// This provides a bit of syntactic sugar to make using sub-ranges
+// in for loops a bit easier. Analogous to std::make_pair().
+template <typename T>
+iterator_range<T> make_range(T x, T y) {
+  return iterator_range<T>(std::move(x), std::move(y));
+}
+
 // String munging.
 
 std::string StringJoin(const std::vector<std::string> &elements,
index 054b703..5065974 100644 (file)
@@ -266,8 +266,8 @@ inline void ComplementFst<Arc>::InitStateIterator(
 }
 
 template <class Arc>
-inline void ComplementFst<Arc>::InitArcIterator(StateId s,
-    ArcIteratorData<Arc> *data) const {
+inline void ComplementFst<Arc>::InitArcIterator(
+    StateId s, ArcIteratorData<Arc> *data) const {
   data->base = new ArcIterator<ComplementFst<Arc>>(*this, s);
 }
 
index 27700a0..52a9e82 100644 (file)
@@ -239,8 +239,8 @@ class SequenceComposeFilter {
 
   FilterState FilterArc(Arc *arc1, Arc *arc2) const {
     if (arc1->olabel == kNoLabel) {
-      return alleps1_ ? FilterState::NoState() : noeps1_ ? FilterState(0)
-                                                         : FilterState(1);
+      return alleps1_ ? FilterState::NoState()
+                      : noeps1_ ? FilterState(0) : FilterState(1);
     } else if (arc2->ilabel == kNoLabel) {
       return fs_ != FilterState(0) ? FilterState::NoState() : FilterState(0);
     } else {
@@ -263,8 +263,8 @@ class SequenceComposeFilter {
   StateId s1_;      // Current fst1_ state.
   StateId s2_;      // Current fst2_ state.
   FilterState fs_;  // Current filter state.
-  bool alleps1_;   // Only epsilons (and non-final) leaving s1_?
-  bool noeps1_;    // No epsilons leaving s1_?
+  bool alleps1_;    // Only epsilons (and non-final) leaving s1_?
+  bool noeps1_;     // No epsilons leaving s1_?
 };
 
 // This filter requires epsilons on FST2 to be read before epsilons on FST1.
@@ -318,8 +318,8 @@ class AltSequenceComposeFilter {
 
   FilterState FilterArc(Arc *arc1, Arc *arc2) const {
     if (arc2->ilabel == kNoLabel) {
-      return alleps2_ ? FilterState::NoState() : noeps2_ ? FilterState(0)
-                                                         : FilterState(1);
+      return alleps2_ ? FilterState::NoState()
+                      : noeps2_ ? FilterState(0) : FilterState(1);
     } else if (arc1->olabel == kNoLabel) {
       return fs_ == FilterState(1) ? FilterState::NoState() : FilterState(0);
     } else {
index 36dc586..4c68d00 100644 (file)
@@ -78,8 +78,8 @@ struct ComposeFstImplOptions : public CacheImplOptions<CacheStore> {
   M2 *matcher2;    // FST2 matcher.
   Filter *filter;  // Composition filter (see compose-filter.h).
   StateTable
-    *state_table;        // Composition state table (see compose-state-table.h).
-  bool own_state_table;   // ComposeFstImpl takes ownership of 'state_table'?
+      *state_table;      // Composition state table (see compose-state-table.h).
+  bool own_state_table;  // ComposeFstImpl takes ownership of 'state_table'?
   bool allow_noncommute;  // Allow non-commutative weights
 
   explicit ComposeFstImplOptions(const CacheOptions &opts,
@@ -138,9 +138,9 @@ class ComposeFstImplBase
   using FstImpl<Arc>::SetInputSymbols;
   using FstImpl<Arc>::SetOutputSymbols;
 
-  using CacheImpl::HasStart;
-  using CacheImpl::HasFinal;
   using CacheImpl::HasArcs;
+  using CacheImpl::HasFinal;
+  using CacheImpl::HasStart;
   using CacheImpl::SetFinal;
   using CacheImpl::SetStart;
 
@@ -321,8 +321,8 @@ class ComposeFstImpl
     if ((matcher1_->Type(false) == match_type) &&
         (matcher2_->Type(false) == match_type) &&
         (filter_->Properties(test_props) == test_props)) {
-      return new ComposeFstMatcher<
-        CacheStore, Filter, StateTable>(&fst, match_type);
+      return new ComposeFstMatcher<CacheStore, Filter, StateTable>(&fst,
+                                                                   match_type);
     }
     return nullptr;
   }
@@ -371,9 +371,9 @@ class ComposeFstImpl
   void AddArc(StateId s, const Arc &arc1, const Arc &arc2,
               const FilterState &f) {
     const StateTuple tuple(arc1.nextstate, arc2.nextstate, f);
-    CacheImpl::EmplaceArc(
-        s, arc1.ilabel, arc2.olabel, Times(arc1.weight, arc2.weight),
-        state_table_->FindState(tuple));
+    CacheImpl::EmplaceArc(s, arc1.ilabel, arc2.olabel,
+                          Times(arc1.weight, arc2.weight),
+                          state_table_->FindState(tuple));
   }
 
   StateId ComputeStart() override {
@@ -562,7 +562,8 @@ class ComposeFst
 
   friend class ArcIterator<ComposeFst<Arc, CacheStore>>;
   friend class StateIterator<ComposeFst<Arc, CacheStore>>;
-  template <class, class, class> friend class ComposeFstMatcher;
+  template <class, class, class>
+  friend class ComposeFstMatcher;
 
   // Compose specifying only caching options.
   ComposeFst(const Fst<Arc> &fst1, const Fst<Arc> &fst2,
@@ -797,9 +798,7 @@ class ComposeFstMatcher : public MatcherBase<typename CacheStore::Arc> {
 
   const Fst<Arc> &GetFst() const override { return fst_; }
 
-  uint64 Properties(uint64 inprops) const override {
-    return inprops;
-  }
+  uint64 Properties(uint64 inprops) const override { return inprops; }
 
   void SetState(StateId s) final {
     if (s_ == s) return;
@@ -845,14 +844,13 @@ class ComposeFstMatcher : public MatcherBase<typename CacheStore::Arc> {
 
  private:
   // Processes a match with the filter and creates resulting arc.
-  bool MatchArc(StateId s, Arc arc1,
-                Arc arc2) {  // FIXME(kbg): copy but not assignment.
-    const auto &fs = impl_->filter_->FilterArc(&arc1, &arc2);
+  bool MatchArc(StateId s, Arc *arc1, Arc *arc2) {
+    const auto &fs = impl_->filter_->FilterArc(arc1, arc2);
     if (fs == FilterState::NoState()) return false;
-    const StateTuple tuple(arc1.nextstate, arc2.nextstate, fs);
-    arc_.ilabel = arc1.ilabel;
-    arc_.olabel = arc2.olabel;
-    arc_.weight = Times(arc1.weight, arc2.weight);
+    const StateTuple tuple(arc1->nextstate, arc2->nextstate, fs);
+    arc_.ilabel = arc1->ilabel;
+    arc_.olabel = arc2->olabel;
+    arc_.weight = Times(arc1->weight, arc2->weight);
     arc_.nextstate = impl_->state_table_->FindState(tuple);
     return true;
   }
@@ -894,16 +892,17 @@ class ComposeFstMatcher : public MatcherBase<typename CacheStore::Arc> {
         // allowed by the filter (hence resulting in an arc x, z') return true.
         // Position 'matcherb' on the next potential match for y' before
         // returning.
-        const auto &arca = matchera->Value();
-        const auto &arcb = matcherb->Value();
+        auto arca = matchera->Value();
+        auto arcb = matcherb->Value();
         // Position 'matcherb' on the next potential match for y'.
         matcherb->Next();
         // Returns true If combining these two arcs is allowed by the filter
         // (hence resulting in an arc x, z'); otherwise consider next match
         // for y' on 'matcherb'.
-        if (MatchArc(s_, match_type_ == MATCH_INPUT ? arca : arcb,
-                     match_type_ == MATCH_INPUT ? arcb : arca)) {
-          return true;
+        if (match_type_ == MATCH_INPUT) {
+          return MatchArc(s_, &arca, &arcb);
+        } else {
+          return MatchArc(s_, &arcb, &arca);
         }
       }
     }
index 61642a5..610e468 100644 (file)
@@ -702,9 +702,9 @@ class DeterminizeFsaImpl : public DeterminizeFstImplBase<Arc> {
   // Adds an arc from state S to the destination state associated with state
   // tuple in det_arc as created by GetLabelMap.
   void AddArc(StateId s, DetArc &&det_arc) {
-    CacheImpl<Arc>::EmplaceArc(
-        s, det_arc.label, det_arc.label, std::move(det_arc.weight),
-        FindState(det_arc.dest_tuple));
+    CacheImpl<Arc>::EmplaceArc(s, det_arc.label, det_arc.label,
+                               std::move(det_arc.weight),
+                               FindState(det_arc.dest_tuple));
   }
 
   float delta_;                         // Quantization delta for weights.
index a7b18a6..72f6119 100644 (file)
@@ -124,7 +124,7 @@ void DfsVisit(const FST &fst, Visitor *visitor, ArcFilter filter,
     while (!state_stack.empty()) {
       auto *dfs_state = state_stack.top();
       const auto s = dfs_state->state_id;
-      if (s >= static_cast<typename FST::Arc::StateId>(state_color.size())) {
+      if (s >= static_cast<decltype(s)>(state_color.size())) {
         nstates = s + 1;
         state_color.resize(nstates, kDfsWhite);
       }
@@ -144,7 +144,8 @@ void DfsVisit(const FST &fst, Visitor *visitor, ArcFilter filter,
         continue;
       }
       const auto &arc = aiter.Value();
-      if (arc.nextstate >= state_color.size()) {
+      if (arc.nextstate >=
+          static_cast<decltype(arc.nextstate)>(state_color.size())) {
         nstates = arc.nextstate + 1;
         state_color.resize(nstates, kDfsWhite);
       }
index a413524..8b81b47 100644 (file)
@@ -268,7 +268,7 @@ class Disambiguator {
       // Ensures composition is between acceptors.
       const bool trans = ifst.Properties(kNotAcceptor, true);
       const auto *fsa =
-          trans ? new ProjectFst<Arc>(ifst, PROJECT_INPUT) : &ifst;
+          trans ? new ProjectFst<Arc>(ifst, ProjectType::INPUT) : &ifst;
       opts.state_table = new StateTable(*fsa, *fsa);
       const ComposeFst<Arc> cfst(*fsa, *fsa, opts);
       std::vector<bool> coaccess;
@@ -394,7 +394,8 @@ void Disambiguator<Arc>::PreDisambiguate(const ExpandedFst<Arc> &ifst,
                                                    AnyArcFilter<Arc>(),
                                                    &odistance);
       Prune(dfst, ofst, popts);
-      } else */ {
+      } else */
+    {
       *ofst = DeterminizeFst<Arc>(ifst, nopts);
       Prune(ofst, opts.weight_threshold, opts.state_threshold);
     }
index 6d94e87..dbca19b 100644 (file)
@@ -228,22 +228,22 @@ class EditFstData {
   // Returns the iterator of the map from external to internal state IDs
   // of edits_ for the specified external state IDs.
   typename std::unordered_map<StateId, StateId>::const_iterator
-      GetEditedIdMapIterator(StateId s) const {
+  GetEditedIdMapIterator(StateId s) const {
     return external_to_internal_ids_.find(s);
   }
 
-  typename std::unordered_map<StateId, StateId>::const_iterator
-      NotInEditedMap() const {
+  typename std::unordered_map<StateId, StateId>::const_iterator NotInEditedMap()
+      const {
     return external_to_internal_ids_.end();
   }
 
   typename std::unordered_map<StateId, Weight>::const_iterator
-      GetFinalWeightIterator(StateId s) const {
+  GetFinalWeightIterator(StateId s) const {
     return edited_final_weights_.find(s);
   }
 
   typename std::unordered_map<StateId, Weight>::const_iterator
-      NotInFinalWeightMap() const {
+  NotInFinalWeightMap() const {
     return edited_final_weights_.end();
   }
 
index f404543..e3b7481 100644 (file)
@@ -18,6 +18,7 @@
 #include <fst/arc-map.h>
 #include <fstream>
 #include <fst/rmfinalepsilon.h>
+#include <unordered_map>
 
 namespace fst {
 
index 708cfb4..98c4ed0 100644 (file)
@@ -45,8 +45,8 @@ template <class Arc, class WeightEqual>
 bool Equal(const Fst<Arc> &fst1, const Fst<Arc> &fst2, WeightEqual weight_equal,
            uint8 etype = kEqualFsts) {
   if ((etype & kEqualFstTypes) && (fst1.Type() != fst2.Type())) {
-    VLOG(1) << "Equal: Mismatched FST types (" << fst1.Type() << " != "
-            << fst2.Type() << ")";
+    VLOG(1) << "Equal: Mismatched FST types (" << fst1.Type()
+            << " != " << fst2.Type() << ")";
     return false;
   }
   if ((etype & kEqualCompatProperties) &&
@@ -67,8 +67,8 @@ bool Equal(const Fst<Arc> &fst1, const Fst<Arc> &fst2, WeightEqual weight_equal,
   }
   if (!(etype & kEqualFsts)) return true;
   if (fst1.Start() != fst2.Start()) {
-    VLOG(1) << "Equal: Mismatched start states (" << fst1.Start() << " != "
-            << fst2.Start() << ")";
+    VLOG(1) << "Equal: Mismatched start states (" << fst1.Start()
+            << " != " << fst2.Start() << ")";
     return false;
   }
   StateIterator<Fst<Arc>> siter1(fst1);
@@ -81,15 +81,14 @@ bool Equal(const Fst<Arc> &fst1, const Fst<Arc> &fst2, WeightEqual weight_equal,
     const auto s1 = siter1.Value();
     const auto s2 = siter2.Value();
     if (s1 != s2) {
-      VLOG(1) << "Equal: Mismatched states (" << s1 << "!= "
-              << s2 << ")";
+      VLOG(1) << "Equal: Mismatched states (" << s1 << "!= " << s2 << ")";
       return false;
     }
     const auto &final1 = fst1.Final(s1);
     const auto &final2 = fst2.Final(s2);
     if (!weight_equal(final1, final2)) {
-      VLOG(1) << "Equal: Mismatched final weights at state " << s1
-              << " (" << final1 << " != " << final2 << ")";
+      VLOG(1) << "Equal: Mismatched final weights at state " << s1 << " ("
+              << final1 << " != " << final2 << ")";
       return false;
     }
     ArcIterator<Fst<Arc>> aiter1(fst1, s1);
@@ -103,23 +102,22 @@ bool Equal(const Fst<Arc> &fst1, const Fst<Arc> &fst2, WeightEqual weight_equal,
       const auto &arc2 = aiter2.Value();
       if (arc1.ilabel != arc2.ilabel) {
         VLOG(1) << "Equal: Mismatched arc input labels at state " << s1
-                << ", arc " << a << " (" << arc1.ilabel << " != "
-                << arc2.ilabel << ")";
+                << ", arc " << a << " (" << arc1.ilabel << " != " << arc2.ilabel
+                << ")";
         return false;
       } else if (arc1.olabel != arc2.olabel) {
         VLOG(1) << "Equal: Mismatched arc output labels at state " << s1
-                << ", arc " << a << " (" << arc1.olabel << " != "
-                << arc2.olabel << ")";
+                << ", arc " << a << " (" << arc1.olabel << " != " << arc2.olabel
+                << ")";
         return false;
       } else if (!weight_equal(arc1.weight, arc2.weight)) {
-        VLOG(1) << "Equal: Mismatched arc weights at state " << s1
-                << ", arc " << a << " (" << arc1.weight << " != "
-                << arc2.weight << ")";
+        VLOG(1) << "Equal: Mismatched arc weights at state " << s1 << ", arc "
+                << a << " (" << arc1.weight << " != " << arc2.weight << ")";
         return false;
       } else if (arc1.nextstate != arc2.nextstate) {
-        VLOG(1) << "Equal: Mismatched next state at state " << s1
-                << ", arc " << a << " (" << arc1.nextstate << " != "
-                << arc2.nextstate << ")";
+        VLOG(1) << "Equal: Mismatched next state at state " << s1 << ", arc "
+                << a << " (" << arc1.nextstate << " != " << arc2.nextstate
+                << ")";
         return false;
       }
       aiter1.Next();
@@ -127,21 +125,20 @@ bool Equal(const Fst<Arc> &fst1, const Fst<Arc> &fst2, WeightEqual weight_equal,
     }
     // Sanity checks: should never fail.
     if (fst1.NumArcs(s1) != fst2.NumArcs(s2)) {
-      FSTERROR() << "Equal: Inconsistent arc counts at state " << s1
-                 << " (" << fst1.NumArcs(s1) << " != "
-                 << fst2.NumArcs(s2) << ")";
+      FSTERROR() << "Equal: Inconsistent arc counts at state " << s1 << " ("
+                 << fst1.NumArcs(s1) << " != " << fst2.NumArcs(s2) << ")";
       return false;
     }
     if (fst1.NumInputEpsilons(s1) != fst2.NumInputEpsilons(s2)) {
       FSTERROR() << "Equal: Inconsistent input epsilon counts at state " << s1
-                 << " (" << fst1.NumInputEpsilons(s1) << " != "
-                 << fst2.NumInputEpsilons(s2) << ")";
+                 << " (" << fst1.NumInputEpsilons(s1)
+                 << " != " << fst2.NumInputEpsilons(s2) << ")";
       return false;
     }
     if (fst1.NumOutputEpsilons(s1) != fst2.NumOutputEpsilons(s2)) {
       FSTERROR() << "Equal: Inconsistent output epsilon counts at state " << s1
-                 << " (" << fst1.NumOutputEpsilons(s1) << " != "
-                 << fst2.NumOutputEpsilons(s2) << ")";
+                 << " (" << fst1.NumOutputEpsilons(s1)
+                 << " != " << fst2.NumOutputEpsilons(s2) << ")";
     }
     siter1.Next();
     siter2.Next();
index 996d404..434c4b7 100644 (file)
@@ -166,7 +166,7 @@ class HashExpanderCache {
 
   template <class Expander>
   State *FindOrExpand(Expander &expander, StateId state_id) {  // NOLINT
-    auto it = cache_.insert(std::pair<StateId, State*>(state_id, nullptr));
+    auto it = cache_.insert(std::pair<StateId, State *>(state_id, nullptr));
     if (!it.second) return it.first->second;
     auto *state = new State;
     it.first->second = state;
index fb22c5c..b989b3e 100644 (file)
@@ -1,18 +1,23 @@
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
 //
-// Expectation semiring as described by Jason Eisner:
-// See: doi=10.1.1.22.9398
+// Expectation semiring, as described in:
+//
+//   Eisner, J. 2002. Parameter estimation for probabilistic finite-state
+//   transducers. In Proceedings of the 40th Annual Meeting of the
+//   Association for Computational Linguistics, pages 1-8.
+//
 // Multiplex semiring operations and identities:
+//
 //    One: <One, Zero>
 //    Zero: <Zero, Zero>
-//    Plus: <a1, b1> + <a2, b2> = < (a1 + a2) , (b1 + b2) >
-//    Times: <a1, b1> * <a2, b2> = < (a1 * a2) , [(a1 * b2) + (a2 * b1)] >
-//    Division: Undefined (currently)
+//    Plus: <a1, b1> + <a2, b2> = <(a1 + a2), (b1 + b2)>
+//    Times: <a1, b1> + <a2, b2> = <(a1 * a2), [(a1 * b2) + (a2 * b1)]>
+//    Division: Undefined.
 //
-// Usually used to store the pair <probability, random_variable> so that
-// ShortestDistance[Fst<ArcTpl<ExpectationWeight<P, V>>>]
-//    == < PosteriorProbability, Expected_Value[V] >
+// It is commonly used to store a probability, random variable pair so that
+// the shortest distance gives the posterior probability and the associated
+// expected value.
 
 #ifndef FST_EXPECTATION_WEIGHT_H_
 #define FST_EXPECTATION_WEIGHT_H_
 
 namespace fst {
 
-// X1 is usually a probability weight like LogWeight.
-// X2 is usually a random variable or vector (see SignedLogWeight or
+// W1 is usually a probability weight like LogWeight.
+// W2 is usually a random variable or vector (see SignedLogWeight or
 // SparsePowerWeight).
 //
-// If X1 is distinct from X2, it is required that there is an external product
-// between X1 and X2 and if both semriring are commutative, or left or right
-// semirings, then result must have those properties.
-template <class X1, class X2>
-class ExpectationWeight : public PairWeight<X1, X2> {
+// If W1 is distinct from W2, it is required that there is an external product
+// between W1 and W2 and if both semriring are commutative, or left or right
+// semirings, then the result must have those properties.
+template <class W1, class W2>
+class ExpectationWeight : public PairWeight<W1, W2> {
  public:
-  using PairWeight<X1, X2>::Value1;
-  using PairWeight<X1, X2>::Value2;
+  using PairWeight<W1, W2>::Value1;
+  using PairWeight<W1, W2>::Value2;
 
-  using PairWeight<X1, X2>::Reverse;
-  using PairWeight<X1, X2>::Quantize;
-  using PairWeight<X1, X2>::Member;
+  using PairWeight<W1, W2>::Reverse;
+  using PairWeight<W1, W2>::Quantize;
+  using PairWeight<W1, W2>::Member;
 
   using ReverseWeight =
-      ExpectationWeight<typename X1::ReverseWeight, typename X2::ReverseWeight>;
+      ExpectationWeight<typename W1::ReverseWeight, typename W2::ReverseWeight>;
 
-  ExpectationWeight() : PairWeight<X1, X2>(Zero()) {}
+  ExpectationWeight() : PairWeight<W1, W2>(Zero()) {}
 
-  explicit ExpectationWeight(const PairWeight<X1, X2> &weight)
-      : PairWeight<X1, X2>(weight) {}
+  explicit ExpectationWeight(const PairWeight<W1, W2> &weight)
+      : PairWeight<W1, W2>(weight) {}
 
-  ExpectationWeight(const X1 &x1, const X2 &x2) : PairWeight<X1, X2>(x1, x2) {}
+  ExpectationWeight(const W1 &w1, const W2 &w2) : PairWeight<W1, W2>(w1, w2) {}
 
   static const ExpectationWeight &Zero() {
-    static const ExpectationWeight zero(X1::Zero(), X2::Zero());
+    static const ExpectationWeight zero(W1::Zero(), W2::Zero());
     return zero;
   }
 
   static const ExpectationWeight &One() {
-    static const ExpectationWeight one(X1::One(), X2::Zero());
+    static const ExpectationWeight one(W1::One(), W2::Zero());
     return one;
   }
 
   static const ExpectationWeight &NoWeight() {
-    static const ExpectationWeight no_weight(X1::NoWeight(), X2::NoWeight());
+    static const ExpectationWeight no_weight(W1::NoWeight(), W2::NoWeight());
     return no_weight;
   }
 
   static const std::string &Type() {
     static const std::string *const type =
-        new std::string("expectation_" + X1::Type() + "_" + X2::Type());
+        new std::string("expectation_" + W1::Type() + "_" + W2::Type());
     return *type;
   }
 
-  PairWeight<X1, X2> Quantize(float delta = kDelta) const {
-    return ExpectationWeight(PairWeight<X1, X2>::Quantize(delta));
+  ExpectationWeight Quantize(float delta = kDelta) const {
+    return ExpectationWeight(PairWeight<W1, W2>::Quantize(delta));
   }
 
   ReverseWeight Reverse() const {
-    return ReverseWeight(PairWeight<X1, X2>::Reverse());
+    return ReverseWeight(PairWeight<W1, W2>::Reverse());
   }
 
-  bool Member() const { return PairWeight<X1, X2>::Member(); }
+  bool Member() const { return PairWeight<W1, W2>::Member(); }
 
   static constexpr uint64 Properties() {
-    return X1::Properties() & X2::Properties() &
+    return W1::Properties() & W2::Properties() &
            (kLeftSemiring | kRightSemiring | kCommutative | kIdempotent);
   }
 };
 
-template <class X1, class X2>
-inline ExpectationWeight<X1, X2> Plus(const ExpectationWeight<X1, X2> &w1,
-                                      const ExpectationWeight<X1, X2> &w2) {
-  return ExpectationWeight<X1, X2>(Plus(w1.Value1(), w2.Value1()),
+template <class W1, class W2>
+inline ExpectationWeight<W1, W2> Plus(const ExpectationWeight<W1, W2> &w1,
+                                      const ExpectationWeight<W1, W2> &w2) {
+  return ExpectationWeight<W1, W2>(Plus(w1.Value1(), w2.Value1()),
                                    Plus(w1.Value2(), w2.Value2()));
 }
 
-template <class X1, class X2>
-inline ExpectationWeight<X1, X2> Times(const ExpectationWeight<X1, X2> &w1,
-                                       const ExpectationWeight<X1, X2> &w2) {
-  return ExpectationWeight<X1, X2>(
+template <class W1, class W2>
+inline ExpectationWeight<W1, W2> Times(const ExpectationWeight<W1, W2> &w1,
+                                       const ExpectationWeight<W1, W2> &w2) {
+  return ExpectationWeight<W1, W2>(
       Times(w1.Value1(), w2.Value1()),
       Plus(Times(w1.Value1(), w2.Value2()), Times(w1.Value2(), w2.Value1())));
 }
 
-template <class X1, class X2>
-inline ExpectationWeight<X1, X2> Divide(const ExpectationWeight<X1, X2> &w1,
-                                        const ExpectationWeight<X1, X2> &w2,
+template <class W1, class W2>
+inline ExpectationWeight<W1, W2> Divide(const ExpectationWeight<W1, W2> &w1,
+                                        const ExpectationWeight<W1, W2> &w2,
                                         DivideType typ = DIVIDE_ANY) {
   FSTERROR() << "ExpectationWeight::Divide: Not implemented";
-  return ExpectationWeight<X1, X2>::NoWeight();
+  return ExpectationWeight<W1, W2>::NoWeight();
 }
 
-// Specialization for enpectation weight
-template <class X1, class X2>
-class Adder<ExpectationWeight<X1, X2>> {
+// Specialization for enpectation weight.
+template <class W1, class W2>
+class Adder<ExpectationWeight<W1, W2>> {
  public:
-  using Weight = ExpectationWeight<X1, X2>;
+  using Weight = ExpectationWeight<W1, W2>;
 
-  Adder() {}
+  Adder() = default;
 
-  explicit Adder(Weight w)
-      : adder1_(w.Value1()),
-        adder2_(w.Value2()) {}
+  explicit Adder(Weight w) : adder1_(w.Value1()), adder2_(w.Value2()) {}
 
   Weight Add(const Weight &w) {
     adder1_.Add(w.Value1());
@@ -140,24 +143,27 @@ class Adder<ExpectationWeight<X1, X2>> {
   }
 
  private:
-  Adder<X1> adder1_;
-  Adder<X2> adder2_;
+  Adder<W1> adder1_;
+  Adder<W2> adder2_;
 };
 
-
 // This function object generates weights by calling the underlying generators
 // for the template weight types, like all other pair weight types. This is
 // intended primarily for testing.
-template <class X1, class X2>
-class WeightGenerate<ExpectationWeight<X1, X2>>
-    : public WeightGenerate<PairWeight<X1, X2>> {
+template <class W1, class W2>
+class WeightGenerate<ExpectationWeight<W1, W2>> {
  public:
-  using Weight = ExpectationWeight<X1, X2>;
-  using Generate = WeightGenerate<PairWeight<X1, X2>>;
+  using Weight = ExpectationWeight<W1, W2>;
+  using Generate = WeightGenerate<PairWeight<W1, W2>>;
+
+  explicit WeightGenerate(uint64 seed = std::random_device()(),
+                          bool allow_zero = true)
+      : generate_(seed, allow_zero) {}
 
-  explicit WeightGenerate(bool allow_zero = true) : Generate(allow_zero) {}
+  Weight operator()() const { return Weight(generate_()); }
 
-  Weight operator()() const { return Weight(Generate::operator()()); }
+ private:
+  const Generate generate_;
 };
 
 }  // namespace fst
index a0c99b8..c54e8a6 100644 (file)
@@ -32,10 +32,8 @@ class StringReader {
   using Label = typename Arc::Label;
   using Weight = typename Arc::Weight;
 
-  enum EntryType { LINE = 1, FILE = 2 };
-
   StringReader(std::istream &istrm, const std::string &source,
-               EntryType entry_type, StringTokenType token_type,
+               FarEntryType entry_type, TokenType token_type,
                bool allow_negative_labels, const SymbolTable *syms = nullptr,
                Label unknown_label = kNoStateId)
       : nline_(0),
@@ -57,13 +55,13 @@ class StringReader {
       done_ = true;
       return;
     }
-    if (entry_type_ == LINE) {
-      getline(istrm_, content_);
+    if (entry_type_ == FarEntryType::LINE) {
+      std::getline(istrm_, content_);
       ++nline_;
     } else {
       content_.clear();
       std::string line;
-      while (getline(istrm_, line)) {
+      while (std::getline(istrm_, line)) {
         ++nline_;
         content_.append(line);
         content_.append("\n");
@@ -107,8 +105,8 @@ class StringReader {
   size_t nline_;
   std::istream &istrm_;
   std::string source_;
-  EntryType entry_type_;
-  StringTokenType token_type_;
+  FarEntryType entry_type_;
+  TokenType token_type_;
   const SymbolTable *symbols_;
   bool done_;
   StringCompiler<Arc> compiler_;
@@ -126,32 +124,12 @@ template <class Arc>
 void FarCompileStrings(const std::vector<std::string> &in_sources,
                        const std::string &out_source,
                        const std::string &fst_type, const FarType &far_type,
-                       int32 generate_keys, FarEntryType fet, FarTokenType tt,
-                       const std::string &symbols_source,
+                       int32 generate_keys, FarEntryType entry_type,
+                       TokenType token_type, const std::string &symbols_source,
                        const std::string &unknown_symbol, bool keep_symbols,
                        bool initial_symbols, bool allow_negative_labels,
                        const std::string &key_prefix,
                        const std::string &key_suffix) {
-  typename StringReader<Arc>::EntryType entry_type;
-  if (fet == FET_LINE) {
-    entry_type = StringReader<Arc>::LINE;
-  } else if (fet == FET_FILE) {
-    entry_type = StringReader<Arc>::FILE;
-  } else {
-    FSTERROR() << "FarCompileStrings: Unknown entry type";
-    return;
-  }
-  StringTokenType token_type;
-  if (tt == FTT_SYMBOL) {
-    token_type = StringTokenType::SYMBOL;
-  } else if (tt == FTT_BYTE) {
-    token_type = StringTokenType::BYTE;
-  } else if (tt == FTT_UTF8) {
-    token_type = StringTokenType::UTF8;
-  } else {
-    FSTERROR() << "FarCompileStrings: Unknown token type";
-    return;
-  }
   bool compact;
   if (fst_type.empty() || (fst_type == "vector")) {
     compact = false;
@@ -192,7 +170,7 @@ void FarCompileStrings(const std::vector<std::string> &in_sources,
       return;
     }
     const int key_size = generate_keys ? generate_keys
-                                       : (entry_type == StringReader<Arc>::FILE
+                                       : (entry_type == FarEntryType::FILE
                                               ? 1
                                               : KeySize(in_source.c_str()));
     if (key_size == 0) {
@@ -223,17 +201,19 @@ void FarCompileStrings(const std::vector<std::string> &in_sources,
       }
       if (initial_symbols) keep_syms = false;
       if (!fst) {
-        FSTERROR() << "FarCompileStrings: Compiling string number " << n
-                   << " in file " << in_source << " failed with token_type = "
-                   << (tt == FTT_BYTE
-                           ? "byte"
-                           : (tt == FTT_UTF8
-                                  ? "utf8"
-                                  : (tt == FTT_SYMBOL ? "symbol" : "unknown")))
-                   << " and entry_type = "
-                   << (fet == FET_LINE
-                           ? "line"
-                           : (fet == FET_FILE ? "file" : "unknown"));
+        FSTERROR()
+            << "FarCompileStrings: Compiling string number " << n << " in file "
+            << in_source << " failed with token_type = "
+            << (token_type == TokenType::BYTE
+                    ? "byte"
+                    : (token_type == TokenType::UTF8
+                           ? "utf8"
+                           : (token_type == TokenType::SYMBOL ? "symbol"
+                                                              : "unknown")))
+            << " and entry_type = "
+            << (entry_type == FarEntryType::LINE
+                    ? "line"
+                    : (entry_type == FarEntryType::FILE ? "file" : "unknown"));
         return;
       }
       std::ostringstream keybuf;
@@ -247,7 +227,7 @@ void FarCompileStrings(const std::vector<std::string> &in_sources,
         auto *source = new char[in_source.size() + 1];
         strcpy(source, in_source.c_str());  // NOLINT
         key = basename(source);
-        if (entry_type != StringReader<Arc>::FILE) {
+        if (entry_type != FarEntryType::FILE) {
           key += "-";
           key += keybuf.str();
         }
index 269563a..9fd13bf 100644 (file)
@@ -17,7 +17,6 @@
 namespace fst {
 namespace script {
 
-
 // FarReader API.
 
 // Virtual interface implemented by each concrete FarReaderImpl<A>.
@@ -76,7 +75,6 @@ class FarReaderClassImpl : public FarReaderImplBase {
   mutable std::unique_ptr<FstClass> fstc_;
 };
 
-
 class FarReaderClass;
 
 using OpenFarReaderClassArgs =
@@ -159,13 +157,12 @@ class FarWriterImplBase {
   virtual ~FarWriterImplBase() {}
 };
 
-
 // Templated implementation.
 template <class Arc>
 class FarWriterClassImpl : public FarWriterImplBase {
  public:
   explicit FarWriterClassImpl(const std::string &source,
-                              FarType type = FAR_DEFAULT)
+                              FarType type = FarType::DEFAULT)
       : impl_(FarWriter<Arc>::Create(source, type)) {}
 
   bool Add(const std::string &key, const FstClass &fst) final {
@@ -192,7 +189,6 @@ class FarWriterClassImpl : public FarWriterImplBase {
   std::unique_ptr<FarWriter<Arc>> impl_;
 };
 
-
 class FarWriterClass;
 
 using CreateFarWriterClassInnerArgs = std::pair<const std::string &, FarType>;
@@ -205,7 +201,7 @@ class FarWriterClass {
  public:
   static FarWriterClass *Create(const std::string &source,
                                 const std::string &arc_type,
-                                FarType type = FAR_DEFAULT);
+                                FarType type = FarType::DEFAULT);
 
   bool Add(const std::string &key, const FstClass &fst) {
     return impl_->Add(key, fst);
index f3958ef..d409b44 100644 (file)
@@ -18,9 +18,7 @@
 
 namespace fst {
 
-enum FarEntryType { FET_LINE, FET_FILE };
-
-enum FarTokenType { FTT_SYMBOL, FTT_BYTE, FTT_UTF8 };
+enum class FarEntryType { LINE, FILE };
 
 inline bool IsFst(const std::string &source) {
   std::ifstream strm(source, std::ios_base::in | std::ios_base::binary);
@@ -68,11 +66,11 @@ class FarHeader {
   std::string arctype_;
 };
 
-enum FarType {
-  FAR_DEFAULT = 0,
-  FAR_STTABLE = 1,
-  FAR_STLIST = 2,
-  FAR_FST = 3,
+enum class FarType {
+  DEFAULT = 0,
+  STTABLE = 1,
+  STLIST = 2,
+  FST = 3,
 };
 
 // This class creates an archive of FSTs.
@@ -83,7 +81,7 @@ class FarWriter {
 
   // Creates a new (empty) FST archive; returns null on error.
   static FarWriter *Create(const std::string &source,
-                           FarType type = FAR_DEFAULT);
+                           FarType type = FarType::DEFAULT);
 
   // Adds an FST to the end of an archive. Keys must be non-empty and
   // in lexicographic order. FSTs must have a suitable write method.
@@ -165,7 +163,7 @@ class STTableFarWriter : public FarWriter<A> {
     writer_->Add(key, fst);
   }
 
-  FarType Type() const final { return FAR_STTABLE; }
+  FarType Type() const final { return FarType::STTABLE; }
 
   bool Error() const final { return writer_->Error(); }
 
@@ -190,7 +188,7 @@ class STListFarWriter : public FarWriter<A> {
     writer_->Add(key, fst);
   }
 
-  FarType Type() const final { return FAR_STLIST; }
+  FarType Type() const final { return FarType::STLIST; }
 
   bool Error() const final { return writer_->Error(); }
 
@@ -223,7 +221,7 @@ class FstFarWriter final : public FarWriter<A> {
     }
   }
 
-  FarType Type() const final { return FAR_FST; }
+  FarType Type() const final { return FarType::FST; }
 
   bool Error() const final { return error_; }
 
@@ -239,13 +237,13 @@ template <class Arc>
 FarWriter<Arc> *FarWriter<Arc>::Create(const std::string &source,
                                        FarType type) {
   switch (type) {
-    case FAR_DEFAULT:
+    case FarType::DEFAULT:
       if (source.empty()) return STListFarWriter<Arc>::Create(source);
-    case FAR_STTABLE:
+    case FarType::STTABLE:
       return STTableFarWriter<Arc>::Create(source);
-    case FAR_STLIST:
+    case FarType::STLIST:
       return STListFarWriter<Arc>::Create(source);
-    case FAR_FST:
+    case FarType::FST:
       return FstFarWriter<Arc>::Create(source);
     default:
       LOG(ERROR) << "FarWriter::Create: Unknown FAR type";
@@ -291,7 +289,7 @@ class STTableFarReader : public FarReader<A> {
 
   const Fst<Arc> *GetFst() const final { return reader_->GetEntry(); }
 
-  FarType Type() const final { return FAR_STTABLE; }
+  FarType Type() const final { return FarType::STTABLE; }
 
   bool Error() const final { return reader_->Error(); }
 
@@ -331,7 +329,7 @@ class STListFarReader : public FarReader<A> {
 
   const Fst<Arc> *GetFst() const final { return reader_->GetEntry(); }
 
-  FarType Type() const final { return FAR_STLIST; }
+  FarType Type() const final { return FarType::STLIST; }
 
   bool Error() const final { return reader_->Error(); }
 
@@ -421,7 +419,7 @@ class FstFarReader final : public FarReader<A> {
 
   const Fst<Arc> *GetFst() const final { return fst_.get(); }
 
-  FarType Type() const final { return FAR_FST; }
+  FarType Type() const final { return FarType::FST; }
 
   bool Error() const final { return error_; }
 
index da91e79..fb7124f 100644 (file)
@@ -36,7 +36,7 @@ struct FarCompileStringsArgs {
   const FarType &far_type;
   const int32 generate_keys;
   const FarEntryType fet;
-  const FarTokenType tt;
+  const TokenType tt;
   const std::string &symbols_source;
   const std::string &unknown_symbol;
   const bool keep_symbols;
@@ -48,7 +48,7 @@ struct FarCompileStringsArgs {
   FarCompileStringsArgs(const std::vector<std::string> &in_sources,
                         const std::string &out_source,
                         const std::string &fst_type, const FarType &far_type,
-                        int32 generate_keys, FarEntryType fet, FarTokenType tt,
+                        int32 generate_keys, FarEntryType fet, TokenType tt,
                         const std::string &symbols_source,
                         const std::string &unknown_symbol, bool keep_symbols,
                         bool initial_symbols, bool allow_negative_labels,
@@ -83,7 +83,7 @@ void FarCompileStrings(const std::vector<std::string> &in_sources,
                        const std::string &out_source,
                        const std::string &arc_type, const std::string &fst_type,
                        const FarType &far_type, int32 generate_keys,
-                       FarEntryType fet, FarTokenType tt,
+                       FarEntryType fet, TokenType tt,
                        const std::string &symbols_source,
                        const std::string &unknown_symbol, bool keep_symbols,
                        bool initial_symbols, bool allow_negative_labels,
@@ -213,7 +213,7 @@ bool FarIsomorphic(const std::string &source1, const std::string &source2,
 struct FarPrintStringsArgs {
   const std::vector<std::string> &isources;
   const FarEntryType entry_type;
-  const FarTokenType token_type;
+  const TokenType token_type;
   const std::string &begin_key;
   const std::string &end_key;
   const bool print_key;
@@ -225,8 +225,7 @@ struct FarPrintStringsArgs {
   const std::string &source_suffix;
 
   FarPrintStringsArgs(const std::vector<std::string> &isources,
-                      const FarEntryType entry_type,
-                      const FarTokenType token_type,
+                      const FarEntryType entry_type, const TokenType token_type,
                       const std::string &begin_key, const std::string &end_key,
                       const bool print_key, const bool print_weight,
                       const std::string &symbols_source,
@@ -258,10 +257,9 @@ void FarPrintStrings(FarPrintStringsArgs *args) {
 
 void FarPrintStrings(const std::vector<std::string> &isources,
                      const std::string &arc_type, const FarEntryType entry_type,
-                     const FarTokenType token_type,
-                     const std::string &begin_key, const std::string &end_key,
-                     const bool print_key, const bool print_weight,
-                     const std::string &symbols_source,
+                     const TokenType token_type, const std::string &begin_key,
+                     const std::string &end_key, const bool print_key,
+                     const bool print_weight, const std::string &symbols_source,
                      const bool initial_symbols, const int32 generate_sources,
                      const std::string &source_prefix,
                      const std::string &source_suffix);
index f5dcc82..e15a584 100644 (file)
@@ -9,21 +9,20 @@
 
 #include <fst/flags.h>
 #include <fst/extensions/far/far.h>
+#include <fst/string.h>
 
 namespace fst {
 namespace script {
 
-FarType GetFarType(const std::string &str);
+bool GetFarType(const std::string &str, FarType *far_type);
 
 bool GetFarEntryType(const std::string &str, FarEntryType *entry_type);
 
-bool GetFarTokenType(const std::string &str, FarTokenType *token_type);
-
 void ExpandArgs(int argc, char **argv, int *argcp, char ***argvp);
 
 }  // namespace script
 
-std::string GetFarTypeString(FarType type);
+std::string GetFarTypeString(FarType far_type);
 
 }  // namespace fst
 
index a20cc13..95fd133 100644 (file)
@@ -22,23 +22,12 @@ namespace fst {
 
 template <class Arc>
 void FarPrintStrings(const std::vector<std::string> &isources,
-                     FarEntryType entry_type, FarTokenType far_token_type,
+                     FarEntryType entry_type, TokenType token_type,
                      const std::string &begin_key, const std::string &end_key,
                      bool print_key, bool print_weight,
                      const std::string &symbols_source, bool initial_symbols,
                      int32 generate_sources, const std::string &source_prefix,
                      const std::string &source_suffix) {
-  StringTokenType token_type;
-  if (far_token_type == FTT_SYMBOL) {
-    token_type = StringTokenType::SYMBOL;
-  } else if (far_token_type == FTT_BYTE) {
-    token_type = StringTokenType::BYTE;
-  } else if (far_token_type == FTT_UTF8) {
-    token_type = StringTokenType::UTF8;
-  } else {
-    FSTERROR() << "FarPrintStrings: Unknown token type";
-    return;
-  }
   std::unique_ptr<const SymbolTable> syms;
   if (!symbols_source.empty()) {
     // TODO(kbg): Allow negative flag?
@@ -65,21 +54,23 @@ void FarPrintStrings(const std::vector<std::string> &isources,
     }
     okey = key;
     const auto *fst = far_reader->GetFst();
-    if (i == 1 && initial_symbols && !syms && fst->InputSymbols())
+    if (i == 1 && initial_symbols && !syms && fst->InputSymbols()) {
       syms.reset(fst->InputSymbols()->Copy());
+    }
     std::string str;
     VLOG(2) << "Handling key: " << key;
-    StringPrinter<Arc> string_printer(
-        token_type, syms ? syms.get() : fst->InputSymbols(),
-        /*eps_sym_print_type=*/EpsilonSymbolPrintType::SYMBOLS_INCL_EPS);
-    string_printer(*fst, &str);
-    if (entry_type == FET_LINE) {
+    const StringPrinter<Arc> printer(token_type,
+                                     syms ? syms.get() : fst->InputSymbols(),
+                                     /*omit_epsilon=*/false);
+    printer(*fst, &str);
+    if (entry_type == FarEntryType::LINE) {
       if (print_key) std::cout << key << FLAGS_far_field_separator[0];
       std::cout << str;
-      if (print_weight)
+      if (print_weight) {
         std::cout << FLAGS_far_field_separator[0] << ShortestDistance(*fst);
+      }
       std::cout << std::endl;
-    } else if (entry_type == FET_FILE) {
+    } else if (entry_type == FarEntryType::FILE) {
       std::stringstream sstrm;
       if (generate_sources) {
         sstrm.fill('0');
@@ -96,7 +87,7 @@ void FarPrintStrings(const std::vector<std::string> &isources,
         return;
       }
       ostrm << str;
-      if (token_type == StringTokenType::SYMBOL) ostrm << "\n";
+      if (token_type == TokenType::SYMBOL) ostrm << "\n";
     }
   }
 }
index ef17f79..01c45c4 100644 (file)
@@ -213,7 +213,7 @@ class STTableReader {
 
     bool operator()(size_t i, size_t j) const {
       return (*keys)[i] > (*keys)[j];
-    };
+    }
 
    private:
     const std::vector<std::string> *keys;
@@ -290,8 +290,8 @@ class STTableReader {
   std::vector<std::string> sources_;           // Corresponding file names.
   std::vector<std::vector<int64>> positions_;  // Index of positions.
   std::vector<std::string> keys_;  // Lowest unread key for each stream.
-  std::vector<int64> heap_;   // Heap containing ID of streams with unread keys.
-  int64 current_;             // ID of current stream to be read.
+  std::vector<int64> heap_;  // Heap containing ID of streams with unread keys.
+  int64 current_;            // ID of current stream to be read.
   std::unique_ptr<Compare> compare_;  // Functor comparing stream IDs.
   mutable std::unique_ptr<T> entry_;  // The currently read entry.
   bool error_;
index 1d4613f..ed0f8cb 100644 (file)
@@ -698,17 +698,15 @@ bool FeatureGroupBuilder<A>::AddWeight(const std::vector<Label> &input,
     LOG(WARNING) << "\tOutput: " << JoinLabels(output, fsyms_);
     return false;
   }
-  if (num_input_start > 0 &&
-      input.size() - future_size_ - num_input_start <
-          output.size() - num_output_start) {
+  if (num_input_start > 0 && input.size() - future_size_ - num_input_start <
+                                 output.size() - num_output_start) {
     LOG(WARNING) << "Ignored: matching start-of-sentence with actual output!";
     LOG(WARNING) << "\tInput: " << JoinLabels(input, fsyms_);
     LOG(WARNING) << "\tOutput: " << JoinLabels(output, osyms_);
     return false;
   }
-  if (num_output_start > 0 &&
-      input.size() - future_size_ - num_input_start >
-          output.size() - num_output_start) {
+  if (num_output_start > 0 && input.size() - future_size_ - num_input_start >
+                                  output.size() - num_output_start) {
     LOG(WARNING) << "Ignored: matching start-of-sentence with actual input!";
     LOG(WARNING) << "\tInput: " << JoinLabels(input, fsyms_);
     LOG(WARNING) << "\tOutput: " << JoinLabels(output, osyms_);
index 22cc2e1..2ba7508 100644 (file)
@@ -334,8 +334,8 @@ inline void LinearTaggerFstImpl<A>::ExpandArcs(StateId s,
                        next_stub_));
   } else {
     std::pair<typename std::vector<typename A::Label>::const_iterator,
-              typename std::vector<typename A::Label>::const_iterator> range =
-        data_->PossibleOutputLabels(obs_ilabel);
+              typename std::vector<typename A::Label>::const_iterator>
+        range = data_->PossibleOutputLabels(obs_ilabel);
     for (typename std::vector<typename A::Label>::const_iterator it =
              range.first;
          it != range.second; ++it)
@@ -360,8 +360,8 @@ inline void LinearTaggerFstImpl<A>::AppendArcs(StateId /*s*/,
         MakeArc(state, ilabel, LinearFstData<A>::kStartOfSentence, next_stub_));
   } else {
     std::pair<typename std::vector<typename A::Label>::const_iterator,
-              typename std::vector<typename A::Label>::const_iterator> range =
-        data_->PossibleOutputLabels(obs_ilabel);
+              typename std::vector<typename A::Label>::const_iterator>
+        range = data_->PossibleOutputLabels(obs_ilabel);
     for (typename std::vector<typename A::Label>::const_iterator it =
              range.first;
          it != range.second; ++it)
@@ -389,10 +389,12 @@ void LinearTaggerFstImpl<A>::Expand(StateId s) {
 
   // Non-epsilon input when we haven't flushed
   if (delay_ == 0 ||
-      *(BufferEnd(state_stub_) - 1) != LinearFstData<A>::kEndOfSentence)
+      *(BufferEnd(state_stub_) - 1) != LinearFstData<A>::kEndOfSentence) {
     for (Label ilabel = data_->MinInputLabel();
-         ilabel <= data_->MaxInputLabel(); ++ilabel)
+         ilabel <= data_->MaxInputLabel(); ++ilabel) {
       ExpandArcs(s, state_stub_, ilabel, &next_stub_);
+    }
+  }
 
   SetArcs(s);
 }
index ca40e4f..2fb6ac0 100644 (file)
@@ -49,7 +49,7 @@ void LogLinearApply(const Fst<A> &ifst, const Fst<A> &lfst, MutableFst<A> *ofst,
     Compose(ifst, lfst, &unnormalized_ofst);
     {
       VectorFst<A> tropical_ifsa(unnormalized_ofst);
-      Project(&tropical_ifsa, PROJECT_INPUT);
+      Project(&tropical_ifsa, ProjectType::INPUT);
       {
         VectorFst<B> minimal_log_ifsa;
         {
index b5ddb3a..1fc4a61 100644 (file)
@@ -140,9 +140,8 @@ class NestedTrieTopology {
   const_iterator end() const { return const_iterator(this, NumNodes()); }
 
  private:
-  std::vector<NextMap *>
-      nodes_;  // Use pointers to avoid copying the maps when the
-               // vector grows
+  std::vector<NextMap *> nodes_;  // Use pointers to avoid copying the maps when
+                                  // the vector grows
 };
 
 template <class L, class H>
@@ -234,8 +233,8 @@ inline std::ostream &NestedTrieTopology<L, H>::Write(
 }
 
 template <class L, class H>
-inline typename NestedTrieTopology<L, H>::const_iterator
-    &NestedTrieTopology<L, H>::const_iterator::operator++() {
+inline typename NestedTrieTopology<L, H>::const_iterator &
+NestedTrieTopology<L, H>::const_iterator::operator++() {
   ++cur_edge_;
   if (cur_edge_ == ptr_->nodes_[cur_node_]->end()) {
     ++cur_node_;
@@ -247,8 +246,8 @@ inline typename NestedTrieTopology<L, H>::const_iterator
 }
 
 template <class L, class H>
-inline typename NestedTrieTopology<L, H>::const_iterator
-    &NestedTrieTopology<L, H>::const_iterator::operator++(int) {  // NOLINT
+inline typename NestedTrieTopology<L, H>::const_iterator &
+NestedTrieTopology<L, H>::const_iterator::operator++(int) {  // NOLINT
   const_iterator save(*this);
   ++(*this);
   return save;
index 47714e3..4bb4cb7 100644 (file)
@@ -155,9 +155,9 @@ class MPdtParenFilter {
 // the MPDT as the first composition argument.
 template <class Arc, bool left_pdt = true>
 class MPdtComposeFstOptions
-    : public ComposeFstOptions<Arc, ParenMatcher<Fst<Arc>>,
-                               MPdtParenFilter<AltSequenceComposeFilter<
-                                   ParenMatcher<Fst<Arc>> >> > {
+    : public ComposeFstOptions<
+          Arc, ParenMatcher<Fst<Arc>>,
+          MPdtParenFilter<AltSequenceComposeFilter<ParenMatcher<Fst<Arc>>>>> {
  public:
   using Label = typename Arc::Label;
   using MPdtMatcher = ParenMatcher<Fst<Arc>>;
@@ -185,7 +185,7 @@ template <class Arc>
 class MPdtComposeFstOptions<Arc, false>
     : public ComposeFstOptions<
           Arc, ParenMatcher<Fst<Arc>>,
-          MPdtParenFilter<SequenceComposeFilter<ParenMatcher<Fst<Arc>> >> > {
+          MPdtParenFilter<SequenceComposeFilter<ParenMatcher<Fst<Arc>>>>> {
  public:
   using Label = typename Arc::Label;
   using MPdtMatcher = ParenMatcher<Fst<Arc>>;
index b7b0cb3..341ee7b 100644 (file)
@@ -119,10 +119,9 @@ class MPdtExpandFstImpl : public CacheImpl<Arc> {
     if (!HasFinal(s)) {
       const auto &tuple = state_table_->Tuple(s);
       const auto weight = fst_->Final(tuple.state_id);
-      SetFinal(s,
-               (weight != Weight::Zero() && tuple.stack_id == 0)
-                   ? weight
-                   : Weight::Zero());
+      SetFinal(s, (weight != Weight::Zero() && tuple.stack_id == 0)
+                      ? weight
+                      : Weight::Zero());
     }
     return CacheImpl<Arc>::Final(s);
   }
@@ -300,11 +299,12 @@ struct MPdtExpandOptions {
 // The expansion enforces the parenthesis constraints. The MPDT must be
 // expandable as an FST.
 template <class Arc>
-void Expand(const Fst<Arc> &ifst,
-            const std::vector<
-            std::pair<typename Arc::Label, typename Arc::Label>> &parens,
-            const std::vector<typename Arc::Label> &assignments,
-            MutableFst<Arc> *ofst, const MPdtExpandOptions &opts) {
+void Expand(
+    const Fst<Arc> &ifst,
+    const std::vector<std::pair<typename Arc::Label, typename Arc::Label>>
+        &parens,
+    const std::vector<typename Arc::Label> &assignments, MutableFst<Arc> *ofst,
+    const MPdtExpandOptions &opts) {
   MPdtExpandFstOptions<Arc> eopts;
   eopts.gc_limit = 0;
   eopts.keep_parentheses = opts.keep_parentheses;
@@ -321,12 +321,12 @@ void Expand(const Fst<Arc> &ifst,
 // The expansion enforces the parenthesis constraints. The MPDT must be
 // expandable as an FST.
 template <class Arc>
-void Expand(const Fst<Arc> &ifst,
-            const std::vector<std::pair<typename Arc::Label,
-            typename Arc::Label>> &parens,
-            const std::vector<typename Arc::Label> &assignments,
-            MutableFst<Arc> *ofst, bool connect = true,
-            bool keep_parentheses = false) {
+void Expand(
+    const Fst<Arc> &ifst,
+    const std::vector<std::pair<typename Arc::Label, typename Arc::Label>>
+        &parens,
+    const std::vector<typename Arc::Label> &assignments, MutableFst<Arc> *ofst,
+    bool connect = true, bool keep_parentheses = false) {
   const MPdtExpandOptions opts(connect, keep_parentheses);
   Expand(ifst, parens, assignments, ofst, opts);
 }
index 49172fc..b887c1e 100644 (file)
@@ -12,6 +12,7 @@
 #include <fst/types.h>
 #include <fst/extensions/mpdt/mpdt.h>
 #include <fst/fst.h>
+#include <unordered_set>
 
 namespace fst {
 
@@ -124,23 +125,19 @@ MPdtInfo<Arc, nlevels>::MPdtInfo(
         const auto level = paren_levels[arc.ilabel];
         if (arc.ilabel == open_paren) {
           ++nopen_parens_[level];
-          if (!paren_set.count(open_paren)) {
+          if (paren_set.insert(open_paren).second) {
             ++nuniq_open_parens_[level];
-            paren_set.insert(open_paren);
           }
-          if (!open_paren_state_set.count(arc.nextstate)) {
+          if (open_paren_state_set.insert(arc.nextstate).second) {
             ++nopen_paren_states_[level];
-            open_paren_state_set.insert(arc.nextstate);
           }
         } else {
           ++nclose_parens_[level];
-          if (!paren_set.count(close_paren)) {
+          if (paren_set.insert(close_paren).second) {
             ++nuniq_close_parens_[level];
-            paren_set.insert(close_paren);
           }
-          if (!close_paren_state_set.count(s)) {
+          if (close_paren_state_set.insert(s).second) {
             ++nclose_paren_states_[level];
-            close_paren_state_set.insert(s);
           }
         }
       }
index 76b6575..9e4549f 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <fst/compat.h>
 #include <fst/extensions/pdt/pdt.h>
+#include <unordered_map>
 
 namespace fst {
 
@@ -202,7 +203,7 @@ class MPdtStack {
   Label max_paren_;
   // Stores level of each paren.
   std::unordered_map<Label, Label> paren_levels_;
-  std::vector<std::pair<Label, Label>> parens_;  // As in pdt.h.
+  std::vector<std::pair<Label, Label>> parens_;   // As in pdt.h.
   std::unordered_map<Label, size_t> paren_map_;  // As in pdt.h.
   // Maps between internal paren_id and external paren_id.
   std::unordered_map<KeyPair<Level>, size_t, KeyPairHasher<Level>>
index dec023e..74f1e7e 100644 (file)
@@ -9,25 +9,68 @@
 
 #include <fst/compat.h>
 #include <fst/types.h>
+#include <fst/log.h>
 
 // This class is a bitstring storage class with an index that allows
-// seeking to the Nth set or clear bit in time O(Log(N)) where N is
-// the length of the bit vector.  In addition, it allows counting set or
-// clear bits over ranges in constant time.
+// seeking to the Nth set or clear bit in time O(Log(N)) (or
+// O(log(1/density) if the relevant select index is enabled) where N is the
+// length of the bit vector, and density is the block density of zeros/ones
+// (for Select0/Select1 respectively).  The block density is for block i is
+// B / span_i, where B is the block size in bits (512); and span_i is
+// Select(B * (i + 1)) - Select(B * i), the range of the bitstring that
+// select index block i indexes.  That is, B 0 (or 1) bits occur over
+// span_i bits of the bit string.
 //
-// This is accomplished by maintaining an "secondary" index of limited
-// size in bits that maintains a running count of the number of bits set
-// in each block of bitmap data.  A block is defined as the number of
-// uint64 values that can fit in the secondary index before an overflow
-// occurs.
+// To turn this into the "standard"constant time select, there would need
+// to be a span size threshold.  Block spanning more than this would need
+// to have the position of each bit explicitly recorded.  8k is a typical
+// value for this threshold, but I saw no spans larger than ~6k.
 //
-// To handle overflows, a "primary" index containing a running count of
-// bits set in each block is created using the type uint32.  Therefore,
+// In addition, this class allows counting set or clear bits over ranges in
+// constant time.
+//
+// This is accomplished by maintaining an index of the running popcounts
+// of the bitstring.  The index is divided into blocks that cover the
+// size of a cache line (8 64-bit words).  Each entry has one absolute count
+// of all the 1s that appear before the block and 7 relative counts since the
+// beginning of the block.
+//
+// The bitstring itself is stored as uint64s:
+// uint64 *bits_;
+//
+// The rank index looks like
+// struct RankIndexEntry {
+//   uint32 absolute_ones_count();
+//   uint32 relative_ones_count_1();
+//   ...
+//   uint32 relative_ones_count_7();
+// };
+// vector<RankIndexEntry> rank_index_;
+//
+// Where rank_index_[i].absolute_ones_count() == Rank1(512 * i), and
+// for k in 1 .. 7:
+// rank_index_[i].relative_ones_count_k() ==
+//     Rank1(512 * i + 64 * k) - Rank1(512 * i).
+//
+// This index is queried directly for Rank0 and Rank1 and binary searched
+// for Select0 and Select1.  If configured in the constructor or via
+// BuildIndex, additional indices for Select0 and Select1 can be built
+// to reduce these operations to O(log(1/density)) as explained above.
+//
+// The select indexes are stored as
+// vector<uint32> select_0_index_;
+// where
+// select_0_index_[i] == Select0(512 * i).
+// Similarly for select_1_index_.
+//
+// To save space, the absolute counts are stored as uint32.  Therefore,
 // only bitstrings with < 2**32 ones are supported.
 //
-// For each 64 bits of input there are 16 bits of secondary index and
-// 32/kSecondaryBlockSize == 32/1023 bits of primary index,
-// for a 25.05% space overhead.
+// For each 64 bytes of input (8 8-byte words) there are 12 bytes of index
+// (4 bytes for the absolute count and 2 * 4 bytes for the relative counts)
+// for a 18.75% space overhead.
+//
+// The select indices have 6.25% overhead together.
 
 namespace fst {
 
@@ -38,16 +81,20 @@ class BitmapIndex {
   }
 
   BitmapIndex() = default;
-  BitmapIndex(BitmapIndex &&) = default;
-  BitmapIndex &operator=(BitmapIndex &&) = default;
+  BitmapIndex(BitmapIndex&&) = default;
+  BitmapIndex& operator=(BitmapIndex&&) = default;
 
   // Convenience constructor to avoid a separate BuildIndex call.
-  BitmapIndex(const uint64 *bits, std::size_t num_bits) {
-    BuildIndex(bits, num_bits);
+  BitmapIndex(const uint64* bits, std::size_t num_bits,
+              bool enable_select_0_index = false,
+              bool enable_select_1_index = false) {
+    BuildIndex(bits, num_bits, enable_select_0_index, enable_select_1_index);
   }
 
-  bool Get(size_t index) const {
-    return (bits_[index >> kStorageLogBitSize] &
+  bool Get(size_t index) const { return Get(bits_, index); }
+
+  static bool Get(const uint64* bits, size_t index) {
+    return (bits[index >> kStorageLogBitSize] &
             (kOne << (index & kStorageBlockMask))) != 0;
   }
 
@@ -64,20 +111,19 @@ class BitmapIndex {
   size_t ArraySize() const { return StorageSize(num_bits_); }
 
   // Number of bytes used to store the bit vector.
-  size_t ArrayBytes() const {
-    return ArraySize() * sizeof(bits_[0]);
-  }
+  size_t ArrayBytes() const { return ArraySize() * sizeof(bits_[0]); }
 
-  // Number of bytes used to store the primary and secondary indices.
+  // Number of bytes used to store the rank index.
   size_t IndexBytes() const {
-    return (primary_index_.size() * sizeof(primary_index_[0]) +
-            secondary_index_.size() * sizeof(secondary_index_[0]));
+    return (rank_index_.size() * sizeof(rank_index_[0]) +
+            select_0_index_.size() * sizeof(select_0_index_[0]) +
+            select_1_index_.size() * sizeof(select_1_index_[0]));
   }
 
   // Returns the number of one bits in the bitmap
   size_t GetOnesCount() const {
-    // Empty bitmaps still have a non-empty primary index.
-    return primary_index_.back();
+    // We keep an extra entry with the total count.
+    return rank_index_.back().absolute_ones_count();
   }
 
   // Returns the number of one bits in positions 0 to limit - 1.
@@ -95,7 +141,7 @@ class BitmapIndex {
   size_t Rank0(size_t end) const { return end - Rank1(end); }
 
   // Returns the number of zero bits in the range start to end - 1.
-  // REQUIRES: limit <= Bits()
+  // REQUIRES: start <= limit <= Bits()
   size_t GetZeroesCountInRange(size_t start, size_t end) const {
     return end - start - GetOnesCountInRange(start, end);
   }
@@ -104,6 +150,8 @@ class BitmapIndex {
   // is set.  0 <= begin <= end <= Bits() is required.
   //
   bool TestRange(size_t start, size_t end) const {
+    // Rank1 will DCHECK the other requirements.
+    DCHECK_LE(start, end);
     return Rank1(end) > Rank1(start);
   }
 
@@ -122,77 +170,160 @@ class BitmapIndex {
   // Rebuilds from index for the associated Bitmap, should be called
   // whenever changes have been made to the Bitmap or else behavior
   // of the indexed bitmap methods will be undefined.
-  void BuildIndex(const uint64* bits, size_t num_bits);
-
-  // the secondary index accumulates counts until it can possibly overflow
-  // this constant computes the number of uint64 units that can fit into
-  // units the size of uint16.
-  static const uint64 kOne = 1;
-  static const uint32 kStorageBitSize = 64;
-  static const uint32 kStorageLogBitSize = 6;
-  // Number of secondary index entries per primary index entry.
-  static const uint32 kSecondaryBlockSize =
-      ((1 << 16) - 1) >> kStorageLogBitSize;
+  void BuildIndex(const uint64* bits, size_t num_bits,
+                  bool enable_select_0_index = false,
+                  bool enable_select_1_index = false);
+
+  static constexpr uint64 kOne = 1;
+  static constexpr uint32 kStorageBitSize = 64;
+  static constexpr uint32 kStorageLogBitSize = 6;
 
  private:
-  static const uint32 kStorageBlockMask = kStorageBitSize - 1;
-
-  // returns, from the index, the count of ones up to array_index
-  size_t get_index_ones_count(size_t array_index) const;
-
-  // because the indexes, both primary and secondary, contain a running
-  // count of the population of one bits contained in [0,i), there is
-  // no reason to have an element in the zeroth position as this value would
-  // necessarily be zero.  (The bits are indexed in a zero based way.)  Thus
-  // we don't store the 0th element in either index for non-empty bitmaps.
-  // For empty bitmaps, the 0 is stored for the primary index, but not the
-  // secondary index.  Both of the following functions, if greater than 0,
-  // must be decremented by one before retrieving the value from the
-  // corresponding array.
-  // returns the 1 + the block that contains the bitindex in question
-  // the inverted version works the same but looks for zeros using an inverted
-  // view of the index
-  size_t find_primary_block(size_t bit_index) const;
-
-  size_t find_inverted_primary_block(size_t bit_index) const;
-
-  // similarly, the secondary index (which resets its count to zero at
-  // the end of every kSecondaryBlockSize entries) does not store the element
-  // at 0.  Note that the rem_bit_index parameter is the number of bits
-  // within the secondary block, after the bits accounted for by the primary
-  // block have been removed (i.e. the remaining bits)  And, because we
-  // reset to zero with each new block, there is no need to store those
-  // actual zeros.
-  // returns 1 + the secondary block that contains the bitindex in question
-  size_t find_secondary_block(size_t block, size_t rem_bit_index) const;
-
-  size_t find_inverted_secondary_block(size_t block,
-                                       size_t rem_bit_index) const;
-
-  // We create a primary index based upon the number of secondary index
-  // blocks.  The primary index uses fields wide enough to accomodate any
-  // index of the bitarray so cannot overflow
-  // The primary index is the actual running
-  // count of one bits set for all blocks (and, thus, all uint64s).
-  size_t primary_index_size() const {
-    // Special-case empty bitmaps to still store the 0 in the primary index.
-    if (ArraySize() == 0) return 1;
-    return (ArraySize() + kSecondaryBlockSize - 1) / kSecondaryBlockSize;
+  static constexpr uint32 kUnitsPerRankIndexEntry = 8;
+  static constexpr uint32 kBitsPerRankIndexEntry =
+      kUnitsPerRankIndexEntry * kStorageBitSize;
+  static constexpr uint32 kStorageBlockMask = kStorageBitSize - 1;
+
+  // TODO(jrosenstock): benchmark different values here.
+  // It's reasonable that these are the same since density is typically around
+  // 1/2.
+  static constexpr uint32 kBitsPerSelect0Block = 512;
+  static constexpr uint32 kBitsPerSelect1Block = 512;
+
+  // If this many or fewer RankIndexEntry blocks need to be searched by
+  // FindRankIndexEntry use a linear search instead of a binary search.
+  // FindInvertedRankIndexEntry always uses binary search, since linear
+  // search never showed improvements on benchmarks.  The value of 8 was
+  // faster than smaller values on benchmarks, but I do not feel comfortable
+  // raising it because there are very few times a higher value would
+  // make a difference.  Thus, whether a higher value helps or hurts is harder
+  // to measure.  TODO(jrosenstock): Try to measure with low bit density.
+  static constexpr uint32 kMaxLinearSearchBlocks = 8;
+
+  // A RankIndexEntry covers a block of 8 64-bit words (one cache line on
+  // x86_64 and ARM).  It consists of an absolute count of all the 1s that
+  // appear before this block, and 7 relative counts for the 1s within
+  // the block.  relative_ones_count_k = popcount(block[0:k]).
+  // The relative counts are stored in bitfields.
+  // A RankIndexEntry takes 12 bytes, for 12/64 = 18.75% overhead.
+  // See also documentation at the top of the file.
+  class RankIndexEntry {
+   public:
+    RankIndexEntry()
+        : absolute_ones_count_(0),
+          relative_ones_count_1_(0),
+          relative_ones_count_2_(0),
+          relative_ones_count_3_(0),
+          relative_ones_count_4_(0),
+          relative_ones_count_5_(0),
+          relative_ones_count_6_(0),
+          relative_ones_count_7_(0) {}
+
+    uint32 absolute_ones_count() const { return absolute_ones_count_; }
+    uint32 relative_ones_count_1() const { return relative_ones_count_1_; }
+    uint32 relative_ones_count_2() const { return relative_ones_count_2_; }
+    uint32 relative_ones_count_3() const { return relative_ones_count_3_; }
+    uint32 relative_ones_count_4() const { return relative_ones_count_4_; }
+    uint32 relative_ones_count_5() const { return relative_ones_count_5_; }
+    uint32 relative_ones_count_6() const { return relative_ones_count_6_; }
+    uint32 relative_ones_count_7() const { return relative_ones_count_7_; }
+
+    void set_absolute_ones_count(uint32 v) { absolute_ones_count_ = v; }
+    void set_relative_ones_count_1(uint32 v) {
+      DCHECK_LE(v, kStorageBitSize);
+      relative_ones_count_1_ = v;
+    }
+    void set_relative_ones_count_2(uint32 v) {
+      DCHECK_LE(v, 2 * kStorageBitSize);
+      relative_ones_count_2_ = v;
+    }
+    void set_relative_ones_count_3(uint32 v) {
+      DCHECK_LE(v, 3 * kStorageBitSize);
+      relative_ones_count_3_ = v;
+    }
+    void set_relative_ones_count_4(uint32 v) {
+      DCHECK_LE(v, 4 * kStorageBitSize);
+      relative_ones_count_4_ = v;
+    }
+    void set_relative_ones_count_5(uint32 v) {
+      DCHECK_LE(v, 5 * kStorageBitSize);
+      relative_ones_count_5_ = v;
+    }
+    void set_relative_ones_count_6(uint32 v) {
+      DCHECK_LE(v, 6 * kStorageBitSize);
+      relative_ones_count_6_ = v;
+    }
+    void set_relative_ones_count_7(uint32 v) {
+      DCHECK_LE(v, 7 * kStorageBitSize);
+      relative_ones_count_7_ = v;
+    }
+
+   private:
+    // Popcount of 1s before this block.
+    // rank_index_[i].absolute_ones_count() == Rank1(512 * i).
+    uint32 absolute_ones_count_;
+
+    // Popcount of 1s since the beginning of the block.
+    // rank_index_[i].relative_ones_count_k() ==
+    //     Rank1(512 * i + 64 * k) - Rank1(512 * i).
+    //
+    // Bitfield widths are set based on the maximum value these relative
+    // counts can have: relative_ones_count_1 stores values up to 64,
+    // so must be 7 bits; relative_ones_count_7 stores values up to
+    // 7 * 64 == 448, so needs 9 bits.
+    //
+    // All fields could just be 9 bits and still fit
+    // in an int64, but by using these values (which are also the minimum
+    // required width), no field spans 2 int32s, which may be helpful on
+    // 32-bit architectures.
+    unsigned int relative_ones_count_1_ : 7;
+    unsigned int relative_ones_count_2_ : 8;
+    unsigned int relative_ones_count_3_ : 8;
+    unsigned int relative_ones_count_4_ : 9;
+    unsigned int relative_ones_count_5_ : 9;
+    unsigned int relative_ones_count_6_ : 9;
+    unsigned int relative_ones_count_7_ : 9;
+  };
+  static_assert(sizeof(RankIndexEntry) == 4 + 8,
+                "RankIndexEntry should be 12 bytes.");
+
+  // Returns, from the index, the count of ones up to array_index.
+  uint32 GetIndexOnesCount(size_t array_index) const;
+
+  // Finds the entry in the rank index for the block containing the
+  // bit_index-th 1 bit.
+  const RankIndexEntry& FindRankIndexEntry(size_t bit_index) const;
+
+  // Finds the entry in the rank index for the block containing the
+  // bit_index-th 0 bit.
+  const RankIndexEntry& FindInvertedRankIndexEntry(size_t bit_index) const;
+
+  // We create a combined primary and secondary index, with one extra entry
+  // to hold the total number of bits.
+  size_t rank_index_size() const {
+    return (ArraySize() + kUnitsPerRankIndexEntry - 1) /
+               kUnitsPerRankIndexEntry +
+           1;
   }
 
   const uint64* bits_ = nullptr;
   size_t num_bits_ = 0;
 
-  // The primary index contains the running popcount of all blocks
-  // which means the nth value contains the popcounts of uint64 elements
-  // [0,n*kSecondaryBlockSize], however, the 0th element is omitted for
-  // non-empty bitmaps.
-  std::vector<uint32> primary_index_;
-  // The secondary index contains the running popcount of the associated
-  // bitmap.  It is the same length (in units of uint16) as the
-  // bitmap's map is in units of uint64s, namely ArraySize() ==
-  // StorageSize(num_bits_).
-  std::vector<uint16> secondary_index_;
+  std::vector<RankIndexEntry> rank_index_;
+
+  // Index of positions for Select0
+  // select_0_index_[i] == Select0(kBitsPerSelect0Block * i).
+  // Empty means there is no index, otherwise, we always add an extra entry
+  // with num_bits_.  Overhead is 4 bytes / 64 bytes of zeros,
+  // so 4/64 times the density of zeros.  This is 6.25% * zeros_density.
+  std::vector<uint32> select_0_index_;
+
+  // Index of positions for Select1
+  // select_1_index_[i] == Select1(kBitsPerSelect1Block * i).
+  // Empty means there is no index, otherwise, we always add an extra entry
+  // with num_bits_.  Overhead is 4 bytes / 64 bytes of ones,
+  // so 4/64 times the density of ones.  This is 6.25% * ones_density.
+  std::vector<uint32> select_1_index_;
 };
 
 }  // end namespace fst
index 710605e..13a842e 100644 (file)
@@ -244,15 +244,15 @@ class NGramFstImpl : public FstImpl<A> {
   StateId Transition(const std::vector<Label> &context, Label future) const;
 
   // Properties always true for this Fst class.
-  static const uint64 kStaticProperties =
+  static constexpr uint64 kStaticProperties =
       kAcceptor | kIDeterministic | kODeterministic | kEpsilons | kIEpsilons |
       kOEpsilons | kILabelSorted | kOLabelSorted | kWeighted | kCyclic |
       kInitialAcyclic | kNotTopSorted | kAccessible | kCoAccessible |
       kNotString | kExpanded;
   // Current file format version.
-  static const int kFileVersion = 4;
+  static constexpr int kFileVersion = 4;
   // Minimum file format version supported.
-  static const int kMinFileVersion = 4;
+  static constexpr int kMinFileVersion = 4;
 
   std::unique_ptr<MappedFile> data_region_;
   const char *data_ = nullptr;
@@ -272,8 +272,12 @@ class NGramFstImpl : public FstImpl<A> {
   const Weight *backoff_ = nullptr;
   const Weight *final_probs_ = nullptr;
   const Weight *future_probs_ = nullptr;
+  // Uses all operations.
   BitmapIndex context_index_;
+  // Uses Select0 and Rank1.
   BitmapIndex future_index_;
+  // Uses Get and Rank1.  This wastes space if there are no or few final
+  // states, but it's also small.  TODO(jrosenstock): Look at EliasFanoArray.
   BitmapIndex final_index_;
 };
 
@@ -731,8 +735,12 @@ inline void NGramFstImpl<A>::Init(const char *data, bool owned,
   offset += num_final_ * sizeof(*final_probs_);
   future_probs_ = reinterpret_cast<const Weight *>(data_ + offset);
 
-  context_index_.BuildIndex(context_, context_bits);
-  future_index_.BuildIndex(future_, future_bits);
+  context_index_.BuildIndex(context_, context_bits,
+                            /*enable_select_0_index=*/true,
+                            /*enable_select_1_index=*/true);
+  future_index_.BuildIndex(future_, future_bits,
+                           /*enable_select_0_index=*/true,
+                           /*enable_select_1_index=*/false);
   final_index_.BuildIndex(final_, num_states_);
 
   select_root_ = context_index_.Select0s(0);
index e46610b..a86ea51 100644 (file)
@@ -7,6 +7,7 @@
 #include <cstdint>
 
 #include <fst/types.h>
+#include <fst/log.h>
 
 #if defined(__BMI2__)  // Intel Bit Manipulation Instruction Set 2
 // PDEP requires BMI2; this is present starting with Haswell.
 
 namespace fst {
 // Returns the position (0-63) of the r-th 1 bit in v.
-// 1 <= r <= CountOnes(v) <= 64.  Therefore, v must not be 0.
+// 0 <= r < CountOnes(v) <= 64.  Therefore, v must not be 0.
 inline uint32 nth_bit(uint64 v, uint32 r) {
+  DCHECK_NE(v, 0);
+  DCHECK_LE(0, r);
+  DCHECK_LT(r, __builtin_popcountll(v));
+
   // PDEP example from https://stackoverflow.com/a/27453505
-  return __builtin_ctzll(_pdep_u64(uint64{1} << (r - 1), v));
+  return __builtin_ctzll(_pdep_u64(uint64{1} << r, v));
 }
 }  // namespace fst
 
@@ -27,7 +32,7 @@ inline uint32 nth_bit(uint64 v, uint32 r) {
 
 namespace fst {
 // Returns the position (0-63) of the r-th 1 bit in v.
-// 1 <= r <= CountOnes(v) <= 64.  Therefore, v must not be 0.
+// 0 <= r < CountOnes(v) <= 64.  Therefore, v must not be 0.
 uint32 nth_bit(uint64 v, uint32 r);
 }  // namespace fst
 
@@ -36,12 +41,12 @@ uint32 nth_bit(uint64 v, uint32 r);
 
 namespace fst {
 namespace internal {
-extern const uint64 kPrefixSumOverflow[65];
+extern const uint64 kPrefixSumOverflow[64];
 extern const uint8 kSelectInByte[2048];
 }  // namespace internal
 
 // Returns the position (0-63) of the r-th 1 bit in v.
-// 1 <= r <= CountOnes(v) <= 64.  Therefore, v must not be 0.
+// 0 <= r < CountOnes(v) <= 64.  Therefore, v must not be 0.
 //
 // This version is based on the paper "Broadword Implementation of
 // Rank/Select Queries" by Sebastiano Vigna, p. 5, Algorithm 2, with
@@ -52,6 +57,10 @@ inline uint32 nth_bit(const uint64 v, const uint32 r) {
   constexpr uint64 kOnesStep8 = 0x0101010101010101;
   constexpr uint64 kMSBsStep8 = 0x80 * kOnesStep8;
 
+  DCHECK_NE(v, 0);
+  DCHECK_LE(0, r);
+  DCHECK_LT(r, __builtin_popcountll(v));
+
   uint64 s = v;
   s = s - ((s >> 1) & (0x5 * kOnesStep4));
   s = (s & (0x3 * kOnesStep4)) + ((s >> 2) & (0x3 * kOnesStep4));
@@ -62,9 +71,9 @@ inline uint32 nth_bit(const uint64 v, const uint32 r) {
   // That is, byte i contains the popcounts of bytes <= i.
   uint64 byte_sums = s * kOnesStep8;
 
-  // kPrefixSumOverflow[r] == (0x80 - r) * kOnesStep8, so the high bit is
-  // still set if byte_sums - r >= 0, or byte_sums >= r.  The first one set
-  // is in the byte with the sum larger than or equal to r (since r is 1-based),
+  // kPrefixSumOverflow[r] == (0x7F - r) * kOnesStep8, so the high bit is
+  // still set if byte_sums - r > 0, or byte_sums > r.  The first one set
+  // is in the byte with the sum larger than r (since r is 0-based),
   // so this is the byte we need.
   const uint64 b = (byte_sums + internal::kPrefixSumOverflow[r]) & kMSBsStep8;
   // The first bit set is the high bit in the byte, so
@@ -75,8 +84,7 @@ inline uint32 nth_bit(const uint64 v, const uint32 r) {
   // The top byte contains the whole-word popcount; we never need that.
   byte_sums <<= 8;
   // Paper uses reinterpret_cast<uint8 *>; use shift/mask instead.
-  // Adjust for fact that r is 1-based.
-  const int rank_in_byte = r - 1 - (byte_sums >> shift) & 0xFF;
+  const int rank_in_byte = r - (byte_sums >> shift) & 0xFF;
   return shift +
          internal::kSelectInByte[(rank_in_byte << 8) + ((v >> shift) & 0xFF)];
 }
index 525d613..b68bc3f 100644 (file)
@@ -454,11 +454,12 @@ struct PdtComposeOptions {
 // interpreted as a PDT, the parens must balance on a path (see PdtExpand()).
 // The open-close parenthesis label pairs are passed using the parens argument.
 template <class Arc>
-void Compose(const Fst<Arc> &ifst1,
-             const std::vector<
-                 std::pair<typename Arc::Label, typename Arc::Label>> &parens,
-             const Fst<Arc> &ifst2, MutableFst<Arc> *ofst,
-             const PdtComposeOptions &opts = PdtComposeOptions()) {
+void Compose(
+    const Fst<Arc> &ifst1,
+    const std::vector<std::pair<typename Arc::Label, typename Arc::Label>>
+        &parens,
+    const Fst<Arc> &ifst2, MutableFst<Arc> *ofst,
+    const PdtComposeOptions &opts = PdtComposeOptions()) {
   bool expand = opts.filter_type != PAREN_FILTER;
   bool keep_parens = opts.filter_type != EXPAND_FILTER;
   PdtComposeFstOptions<Arc, true> copts(ifst1, parens, ifst2, expand,
@@ -474,11 +475,12 @@ void Compose(const Fst<Arc> &ifst1,
 // interpreted as a PDT, the parens must balance on a path (see ExpandFst()).
 // The open-close parenthesis label pairs are passed using the parens argument.
 template <class Arc>
-void Compose(const Fst<Arc> &ifst1, const Fst<Arc> &ifst2,
-             const std::vector<
-                 std::pair<typename Arc::Label, typename Arc::Label>> &parens,
-             MutableFst<Arc> *ofst,
-             const PdtComposeOptions &opts = PdtComposeOptions()) {
+void Compose(
+    const Fst<Arc> &ifst1, const Fst<Arc> &ifst2,
+    const std::vector<std::pair<typename Arc::Label, typename Arc::Label>>
+        &parens,
+    MutableFst<Arc> *ofst,
+    const PdtComposeOptions &opts = PdtComposeOptions()) {
   bool expand = opts.filter_type != PAREN_FILTER;
   bool keep_parens = opts.filter_type != EXPAND_FILTER;
   PdtComposeFstOptions<Arc, false> copts(ifst1, ifst2, parens, expand,
index 9e179ee..8887155 100644 (file)
@@ -20,6 +20,7 @@
 #include <fst/queue.h>
 #include <fst/state-table.h>
 #include <fst/test-properties.h>
+#include <unordered_map>
 
 namespace fst {
 
@@ -920,10 +921,11 @@ void Expand(
 // pairs are passed using the parents argument. Expansion enforces the
 // parenthesis constraints. The PDT must be expandable as an FST.
 template <class Arc>
-void Expand(const Fst<Arc> &ifst,
+void Expand(
+    const Fst<Arc> &ifst,
     const std::vector<std::pair<typename Arc::Label, typename Arc::Label>>
-    &parens, MutableFst<Arc> *ofst, bool connect = true,
-    bool keep_parentheses = false) {
+        &parens,
+    MutableFst<Arc> *ofst, bool connect = true, bool keep_parentheses = false) {
   const PdtExpandOptions<Arc> opts(connect, keep_parentheses);
   Expand(ifst, parens, ofst, opts);
 }
index 1c566f9..159450e 100644 (file)
@@ -13,6 +13,8 @@
 #include <fst/types.h>
 #include <fst/extensions/pdt/pdt.h>
 #include <fst/fst.h>
+#include <unordered_map>
+#include <unordered_set>
 
 namespace fst {
 
@@ -94,23 +96,19 @@ PdtInfo<Arc>::PdtInfo(
         const auto close_paren = parens[it->second].second;
         if (arc.ilabel == open_paren) {
           ++nopen_parens_;
-          if (!paren_set.count(open_paren)) {
+          if (paren_set.insert(open_paren).second) {
             ++nuniq_open_parens_;
-            paren_set.insert(open_paren);
           }
-          if (!open_paren_state_set.count(arc.nextstate)) {
+          if (open_paren_state_set.insert(arc.nextstate).second) {
             ++nopen_paren_states_;
-            open_paren_state_set.insert(arc.nextstate);
           }
         } else {
           ++nclose_parens_;
-          if (!paren_set.count(close_paren)) {
+          if (paren_set.insert(close_paren).second) {
             ++nuniq_close_parens_;
-            paren_set.insert(close_paren);
           }
-          if (!close_paren_state_set.count(s)) {
+          if (close_paren_state_set.insert(s).second) {
             ++nclose_paren_states_;
-            close_paren_state_set.insert(s);
           }
         }
       }
index 0347848..c4543de 100644 (file)
@@ -9,7 +9,7 @@
 #include <algorithm>
 #include <set>
 #include <unordered_map>
-#include <unordered_set>
+#include <vector>
 
 #include <fst/log.h>
 
@@ -17,6 +17,8 @@
 #include <fst/extensions/pdt/pdt.h>
 #include <fst/dfs-visit.h>
 #include <fst/fst.h>
+#include <unordered_map>
+#include <unordered_set>
 
 
 namespace fst {
@@ -306,10 +308,11 @@ class PdtBalanceData {
   using OpenParenSet = std::unordered_set<State, StateHash>;
 
   // Maps from open paren destination state to parenthesis ID.
-  using OpenParenMap = std::unordered_multimap<StateId, Label>;
+  using OpenParenMap = std::unordered_map<StateId, std::vector<Label>>;
 
   // Maps from open paren state to source states of matching close parens
-  using CloseParenMap = std::unordered_multimap<State, StateId, StateHash>;
+  using CloseParenMap =
+      std::unordered_map<State, std::vector<StateId>, StateHash>;
 
   // Maps from open paren state to close source set ID.
   using CloseSourceMap = std::unordered_map<State, ssize_t, StateHash>;
@@ -326,9 +329,8 @@ class PdtBalanceData {
   // Adds an open parenthesis with destination state open_dest.
   void OpenInsert(Label paren_id, StateId open_dest) {
     const State key(paren_id, open_dest);
-    if (!open_paren_set_.count(key)) {
-      open_paren_set_.insert(key);
-      open_paren_map_.emplace(open_dest, paren_id);
+    if (open_paren_set_.insert(key).second) {
+      open_paren_map_[open_dest].push_back(paren_id);
     }
   }
 
@@ -338,7 +340,7 @@ class PdtBalanceData {
   void CloseInsert(Label paren_id, StateId open_dest, StateId close_source) {
     const State key(paren_id, open_dest);
     if (open_paren_set_.count(key)) {
-      close_paren_map_.emplace(key, close_source);
+      close_paren_map_[key].push_back(close_source);
     }
   }
 
@@ -359,25 +361,24 @@ class PdtBalanceData {
   // parentheses entering state open_dest) are finished. Must be called before
   // Find(open_dest).
   void FinishInsert(StateId open_dest) {
-    std::vector<StateId> close_sources;
-    for (auto oit = open_paren_map_.find(open_dest);
-         oit != open_paren_map_.end() && oit->first == open_dest;) {
-      const auto paren_id = oit->second;
-      close_sources.clear();
-      const State key(paren_id, open_dest);
-      open_paren_set_.erase(open_paren_set_.find(key));
-      for (auto cit = close_paren_map_.find(key);
-           cit != close_paren_map_.end() && cit->first == key;) {
-        close_sources.push_back(cit->second);
-        close_paren_map_.erase(cit++);
-      }
-      std::sort(close_sources.begin(), close_sources.end());
-      auto unique_end = std::unique(close_sources.begin(), close_sources.end());
-      close_sources.resize(unique_end - close_sources.begin());
-      if (!close_sources.empty()) {
-        close_source_map_[key] = close_source_sets_.FindId(close_sources);
+    const auto open_parens = open_paren_map_.find(open_dest);
+    if (open_parens != open_paren_map_.end()) {
+      for (const Label paren_id : open_parens->second) {
+        const State key(paren_id, open_dest);
+        open_paren_set_.erase(key);
+        const auto close_paren_it = close_paren_map_.find(key);
+        CHECK(close_paren_it != close_paren_map_.end());
+        std::vector<StateId> &close_sources = close_paren_it->second;
+        std::sort(close_sources.begin(), close_sources.end());
+        auto unique_end =
+            std::unique(close_sources.begin(), close_sources.end());
+        close_sources.resize(unique_end - close_sources.begin());
+        if (!close_sources.empty()) {
+          close_source_map_[key] = close_source_sets_.FindId(close_sources);
+        }
+        close_paren_map_.erase(close_paren_it);
       }
-      open_paren_map_.erase(oit++);
+      open_paren_map_.erase(open_parens);
     }
   }
 
index 3ed8710..a05da1d 100644 (file)
@@ -16,6 +16,7 @@
 #include <fst/replace-util.h>
 #include <fst/replace.h>
 #include <fst/symbol-table-ops.h>
+#include <unordered_map>
 
 namespace fst {
 namespace internal {
@@ -99,11 +100,12 @@ class PdtParser {
       std::unordered_map<ParenKey, size_t, internal::ReplaceParenHash<StateId>>;
 
   PdtParser(const std::vector<LabelFstPair> &fst_array,
-            const PdtReplaceOptions<Arc> &opts) :
-      root_(opts.root), start_paren_labels_(opts.start_paren_labels),
-      left_paren_prefix_(std::move(opts.left_paren_prefix)),
-      right_paren_prefix_(std::move(opts.right_paren_prefix)),
-      error_(false) {
+            const PdtReplaceOptions<Arc> &opts)
+      : root_(opts.root),
+        start_paren_labels_(opts.start_paren_labels),
+        left_paren_prefix_(std::move(opts.left_paren_prefix)),
+        right_paren_prefix_(std::move(opts.right_paren_prefix)),
+        error_(false) {
     for (size_t i = 0; i < fst_array.size(); ++i) {
       if (!CompatSymbols(fst_array[0].second->InputSymbols(),
                          fst_array[i].second->InputSymbols())) {
@@ -199,12 +201,10 @@ class PdtParser {
   // the parenthesis that would carry the non-terminal arc weight and the other
   // parenthesis is omitted (appropriate for the strongly-regular case).
   void AddParensToFst(
-      const std::vector<LabelPair> &parens,
-      const ParenMap &paren_map,
+      const std::vector<LabelPair> &parens, const ParenMap &paren_map,
       const std::vector<StateId> &open_dest,
       const std::vector<std::vector<StateWeightPair>> &close_src,
-      const std::vector<bool> &close_non_term_weight,
-      MutableFst<Arc> *ofst);
+      const std::vector<bool> &close_non_term_weight, MutableFst<Arc> *ofst);
 
   // Ensures that parentheses arcs are added to the symbol table.
   void AddParensToSymbolTables(const std::vector<LabelPair> &parens,
@@ -281,18 +281,15 @@ void PdtParser<Arc>::CreateFst(
       }
     }
   }
-  if (start_paren_labels_ == kNoLabel)
-    start_paren_labels_ = max_label + 1;
+  if (start_paren_labels_ == kNoLabel) start_paren_labels_ = max_label + 1;
 }
 
 template <class Arc>
 void PdtParser<Arc>::AddParensToFst(
-    const std::vector<LabelPair> &parens,
-    const ParenMap &paren_map,
+    const std::vector<LabelPair> &parens, const ParenMap &paren_map,
     const std::vector<StateId> &open_dest,
     const std::vector<std::vector<StateWeightPair>> &close_src,
-    const std::vector<bool> &close_non_term_weight,
-    MutableFst<Arc> *ofst) {
+    const std::vector<bool> &close_non_term_weight, MutableFst<Arc> *ofst) {
   StateId dead_state = kNoStateId;
   using MIter = MutableArcIterator<MutableFst<Arc>>;
   for (StateIterator<Fst<Arc>> siter(*ofst); !siter.Done(); siter.Next()) {
@@ -404,8 +401,8 @@ class PdtLeftParser final : public PdtParser<Arc> {
   using PdtParser<Arc>::Root;
 
   PdtLeftParser(const std::vector<LabelFstPair> &fst_array,
-                const PdtReplaceOptions<Arc> &opts) :
-      PdtParser<Arc>(fst_array, opts) { }
+                const PdtReplaceOptions<Arc> &opts)
+      : PdtParser<Arc>(fst_array, opts) {}
 
   void GetParser(MutableFst<Arc> *ofst,
                  std::vector<LabelPair> *parens) override;
@@ -418,9 +415,8 @@ class PdtLeftParser final : public PdtParser<Arc> {
 };
 
 template <class Arc>
-void PdtLeftParser<Arc>::GetParser(
-    MutableFst<Arc> *ofst,
-    std::vector<LabelPair> *parens) {
+void PdtLeftParser<Arc>::GetParser(MutableFst<Arc> *ofst,
+                                   std::vector<LabelPair> *parens) {
   ofst->DeleteStates();
   parens->clear();
   const auto &fst_array = FstArray();
@@ -451,9 +447,8 @@ void PdtLeftParser<Arc>::GetParser(
 }
 
 template <class Arc>
-size_t PdtLeftParser<Arc>::AssignParenIds(
-    const Fst<Arc> &ofst,
-    ParenMap *paren_map) const {
+size_t PdtLeftParser<Arc>::AssignParenIds(const Fst<Arc> &ofst,
+                                          ParenMap *paren_map) const {
   // Number of distinct parenthesis pairs per FST.
   std::vector<size_t> nparens(FstArray().size(), 0);
   // Number of distinct parenthesis pairs overall.
@@ -508,9 +503,9 @@ class PdtLeftSRParser final : public PdtParser<Arc> {
   using PdtParser<Arc>::Root;
 
   PdtLeftSRParser(const std::vector<LabelFstPair> &fst_array,
-                  const PdtReplaceOptions<Arc> &opts) :
-      PdtParser<Arc>(fst_array, opts),
-      replace_util_(fst_array, ReplaceUtilOptions(opts.root)) { }
+                  const PdtReplaceOptions<Arc> &opts)
+      PdtParser<Arc>(fst_array, opts),
+        replace_util_(fst_array, ReplaceUtilOptions(opts.root)) {}
 
   void GetParser(MutableFst<Arc> *ofst,
                  std::vector<LabelPair> *parens) override;
@@ -569,8 +564,7 @@ class PdtLeftSRParser final : public PdtParser<Arc> {
  private:
   // Merges initial (final) states of in a left- (right-) linear dependency SCC
   // after dealing with the non-terminal arc and final weights.
-  void ProcSCCs(MutableFst<Arc> *ofst,
-                std::vector<StateId> *open_dest,
+  void ProcSCCs(MutableFst<Arc> *ofst, std::vector<StateId> *open_dest,
                 std::vector<std::vector<StateWeightPair>> *close_src,
                 std::vector<bool> *close_non_term_weight) const;
 
@@ -605,9 +599,8 @@ class PdtLeftSRParser final : public PdtParser<Arc> {
 };
 
 template <class Arc>
-void PdtLeftSRParser<Arc>::GetParser(
-    MutableFst<Arc> *ofst,
-    std::vector<LabelPair> *parens) {
+void PdtLeftSRParser<Arc>::GetParser(MutableFst<Arc> *ofst,
+                                     std::vector<LabelPair> *parens) {
   ofst->DeleteStates();
   parens->clear();
   const auto &fst_array = FstArray();
@@ -640,8 +633,7 @@ void PdtLeftSRParser<Arc>::GetParser(
 
 template <class Arc>
 void PdtLeftSRParser<Arc>::ProcSCCs(
-    MutableFst<Arc> *ofst,
-    std::vector<StateId> *open_dest,
+    MutableFst<Arc> *ofst, std::vector<StateId> *open_dest,
     std::vector<std::vector<StateWeightPair>> *close_src,
     std::vector<bool> *close_non_term_weight) const {
   const auto &fst_array = FstArray();
@@ -664,8 +656,7 @@ void PdtLeftSRParser<Arc>::ProcSCCs(
           ofst->AddArc(rs, arc);
         }
         ofst->DeleteArcs(os);
-        if (os == ofst->Start())
-          ofst->SetStart(rs);
+        if (os == ofst->Start()) ofst->SetStart(rs);
         (*open_dest)[fst_id] = rs;
       }
     }
@@ -728,9 +719,8 @@ void PdtLeftSRParser<Arc>::GetNonTermDests() const {
 }
 
 template <class Arc>
-size_t PdtLeftSRParser<Arc>::AssignParenIds(
-    const Fst<Arc> &ofst,
-    ParenMap *paren_map) const {
+size_t PdtLeftSRParser<Arc>::AssignParenIds(const Fst<Arc> &ofst,
+                                            ParenMap *paren_map) const {
   const auto &fst_array = FstArray();
   // Number of distinct parenthesis pairs per FST.
   std::vector<size_t> nparens(fst_array.size(), 0);
@@ -790,18 +780,16 @@ void Replace(
     std::vector<std::pair<typename Arc::Label, typename Arc::Label>> *parens,
     const PdtReplaceOptions<Arc> &opts) {
   switch (opts.type) {
-    case PDT_LEFT_PARSER:
-      {
-        PdtLeftParser<Arc> pr(ifst_array, opts);
-        pr.GetParser(ofst, parens);
-        return;
-      }
-    case PDT_LEFT_SR_PARSER:
-      {
-        PdtLeftSRParser<Arc> pr(ifst_array, opts);
-        pr.GetParser(ofst, parens);
-        return;
-      }
+    case PDT_LEFT_PARSER: {
+      PdtLeftParser<Arc> pr(ifst_array, opts);
+      pr.GetParser(ofst, parens);
+      return;
+    }
+    case PDT_LEFT_SR_PARSER: {
+      PdtLeftSRParser<Arc> pr(ifst_array, opts);
+      pr.GetParser(ofst, parens);
+      return;
+    }
     default:
       FSTERROR() << "Replace: Unknown PDT parser type: " << opts.type;
       ofst->DeleteStates();
index 3bd44e2..900a408 100644 (file)
@@ -16,10 +16,11 @@ namespace fst {
 
 // Reverses a pushdown transducer (PDT) encoded as an FST.
 template <class Arc, class RevArc>
-void Reverse(const Fst<Arc> &ifst,
-             const std::vector<
-                 std::pair<typename Arc::Label, typename Arc::Label>> &parens,
-             MutableFst<RevArc> *ofst) {
+void Reverse(
+    const Fst<Arc> &ifst,
+    const std::vector<std::pair<typename Arc::Label, typename Arc::Label>>
+        &parens,
+    MutableFst<RevArc> *ofst) {
   using Label = typename Arc::Label;
   // Reverses FST component.
   Reverse(ifst, ofst);
index a73bd3c..73e8525 100644 (file)
@@ -16,6 +16,7 @@
 #include <fst/extensions/pdt/paren.h>
 #include <fst/extensions/pdt/pdt.h>
 #include <fst/shortest-path.h>
+#include <unordered_map>
 
 namespace fst {
 
index 14fcd76..006d36b 100644 (file)
@@ -91,7 +91,8 @@ class PhiFstMatcher : public PhiMatcher<M> {
   enum : uint8 { kFlags = flags };
 
   // This makes a copy of the FST.
-  PhiFstMatcher(const FST &fst, MatchType match_type,
+  PhiFstMatcher(
+      const FST &fst, MatchType match_type,
       std::shared_ptr<MatcherData> data = std::make_shared<MatcherData>())
       : PhiMatcher<M>(fst, match_type,
                       PhiLabel(match_type, data ? data->PhiLabel()
@@ -101,7 +102,8 @@ class PhiFstMatcher : public PhiMatcher<M> {
         data_(data) {}
 
   // This doesn't copy the FST.
-  PhiFstMatcher(const FST *fst, MatchType match_type,
+  PhiFstMatcher(
+      const FST *fst, MatchType match_type,
       std::shared_ptr<MatcherData> data = std::make_shared<MatcherData>())
       : PhiMatcher<M>(fst, match_type,
                       PhiLabel(match_type, data ? data->PhiLabel()
index 94c8676..afb7fca 100644 (file)
@@ -29,7 +29,7 @@ class RhoFstMatcherData {
       : rho_label_(data.rho_label_), rewrite_mode_(data.rewrite_mode_) {}
 
   static RhoFstMatcherData<Label> *Read(std::istream &istrm,
-                                    const FstReadOptions &read) {
+                                        const FstReadOptions &read) {
     auto *data = new RhoFstMatcherData<Label>();
     ReadType(istrm, &data->rho_label_);
     int32 rewrite_mode;
index 7ca51dd..b2333da 100644 (file)
@@ -21,15 +21,15 @@ template <class Label>
 class SigmaFstMatcherData {
  public:
   explicit SigmaFstMatcherData(Label sigma_label = FLAGS_sigma_fst_sigma_label,
-      MatcherRewriteMode rewrite_mode =
-                          RewriteMode(FLAGS_sigma_fst_rewrite_mode))
+                               MatcherRewriteMode rewrite_mode =
+                                   RewriteMode(FLAGS_sigma_fst_rewrite_mode))
       : sigma_label_(sigma_label), rewrite_mode_(rewrite_mode) {}
 
   SigmaFstMatcherData(const SigmaFstMatcherData &data)
       : sigma_label_(data.sigma_label_), rewrite_mode_(data.rewrite_mode_) {}
 
   static SigmaFstMatcherData<Label> *Read(std::istream &istrm,
-                                      const FstReadOptions &read) {
+                                          const FstReadOptions &read) {
     auto *data = new SigmaFstMatcherData<Label>();
     ReadType(istrm, &data->sigma_label_);
     int32 rewrite_mode;
index 1e54094..700fdee 100644 (file)
@@ -9,9 +9,9 @@
 #include <algorithm>
 #include <climits>
 #include <cmath>
-#include <cstdlib>
 #include <cstring>
 #include <limits>
+#include <random>
 #include <sstream>
 #include <string>
 #include <type_traits>
@@ -76,11 +76,12 @@ class FloatWeightTpl {
   void SetValue(const T &f) { value_ = f; }
 
   static constexpr const char *GetPrecisionString() {
-    return sizeof(T) == 4 ? ""
-        : sizeof(T) == 1 ? "8"
-        : sizeof(T) == 2 ? "16"
-        : sizeof(T) == 8 ? "64"
-        : "unknown";
+    return sizeof(T) == 4
+               ? ""
+               : sizeof(T) == 1
+                     ? "8"
+                     : sizeof(T) == 2 ? "16"
+                                      : sizeof(T) == 8 ? "64" : "unknown";
   }
 
  private:
@@ -248,7 +249,7 @@ template <class T>
 constexpr TropicalWeightTpl<T> Plus(const TropicalWeightTpl<T> &w1,
                                     const TropicalWeightTpl<T> &w2) {
   return (!w1.Member() || !w2.Member()) ? TropicalWeightTpl<T>::NoWeight()
-      : w1.Value() < w2.Value() ? w1 : w2;
+                                        : w1.Value() < w2.Value() ? w1 : w2;
 }
 
 // See comment at operator==(FloatWeightTpl<float>, FloatWeightTpl<float>)
@@ -372,14 +373,14 @@ constexpr TropicalWeightTpl<double> Divide(const TropicalWeightTpl<double> &w1,
 // of Power<T, V> is made conditionally available only to that template
 // specialization.
 
-template <class T, class V,
-          bool Enable = !std::is_same<V, size_t>::value,
+template <class T, class V, bool Enable = !std::is_same<V, size_t>::value,
           typename std::enable_if<Enable>::type * = nullptr>
 constexpr TropicalWeightTpl<T> Power(const TropicalWeightTpl<T> &w, V n) {
   using Weight = TropicalWeightTpl<T>;
-  return (!w.Member() || n != n) ? Weight::NoWeight()
-      : (n == 0 || w == Weight::One()) ? Weight::One()
-      : Weight(w.Value() * n);
+  return (!w.Member() || n != n)
+             ? Weight::NoWeight()
+             : (n == 0 || w == Weight::One()) ? Weight::One()
+                                              : Weight(w.Value() * n);
 }
 
 // Specializes the library-wide template to use the above implementation; rules
@@ -397,7 +398,6 @@ constexpr TropicalWeightTpl<double> Power<TropicalWeightTpl<double>>(
   return Power<double, size_t, true>(weight, n);
 }
 
-
 // Log semiring: (log(e^-x + e^-y), +, inf, 0).
 template <class T>
 class LogWeightTpl : public FloatWeightTpl<T> {
@@ -556,14 +556,14 @@ constexpr LogWeightTpl<double> Divide(const LogWeightTpl<double> &w1,
 
 // The comments for Power<>(Tropical...) above apply here unchanged.
 
-template <class T, class V,
-          bool Enable = !std::is_same<V, size_t>::value,
+template <class T, class V, bool Enable = !std::is_same<V, size_t>::value,
           typename std::enable_if<Enable>::type * = nullptr>
 constexpr LogWeightTpl<T> Power(const LogWeightTpl<T> &w, V n) {
   using Weight = LogWeightTpl<T>;
-  return (!w.Member() || n != n) ? Weight::NoWeight()
-      : (n == 0 || w == Weight::One()) ? Weight::One()
-      : Weight(w.Value() * n);
+  return (!w.Member() || n != n)
+             ? Weight::NoWeight()
+             : (n == 0 || w == Weight::One()) ? Weight::One()
+                                              : Weight(w.Value() * n);
 }
 
 // Specializes the library-wide template to use the above implementation; rules
@@ -587,9 +587,7 @@ class Adder<LogWeightTpl<T>> {
  public:
   using Weight = LogWeightTpl<T>;
 
-  explicit Adder(Weight w = Weight::Zero())
-      : sum_(w.Value()),
-        c_(0.0) { }
+  explicit Adder(Weight w = Weight::Zero()) : sum_(w.Value()), c_(0.0) {}
 
   Weight Add(const Weight &w) {
     using Limits = FloatLimits<T>;
@@ -616,7 +614,7 @@ class Adder<LogWeightTpl<T>> {
 
  private:
   double sum_;
-  double c_;   // Kahan compensation.
+  double c_;  // Kahan compensation.
 };
 
 // Real semiring: (+, *, 0, 1).
@@ -705,7 +703,7 @@ inline RealWeightTpl<double> Plus(const RealWeightTpl<double> &w1,
 
 template <class T>
 inline RealWeightTpl<T> Minus(const RealWeightTpl<T> &w1,
-                             const RealWeightTpl<T> &w2) {
+                              const RealWeightTpl<T> &w2) {
   // The comments for Divide(Tropical...) above apply here unchanged.
   const T f1 = w1.Value();
   const T f2 = w2.Value();
@@ -713,12 +711,12 @@ inline RealWeightTpl<T> Minus(const RealWeightTpl<T> &w1,
 }
 
 inline RealWeightTpl<float> Minus(const RealWeightTpl<float> &w1,
-                                 const RealWeightTpl<float> &w2) {
+                                  const RealWeightTpl<float> &w2) {
   return Minus<float>(w1, w2);
 }
 
 inline RealWeightTpl<double> Minus(const RealWeightTpl<double> &w1,
-                                  const RealWeightTpl<double> &w2) {
+                                   const RealWeightTpl<double> &w2) {
   return Minus<double>(w1, w2);
 }
 
@@ -741,8 +739,8 @@ constexpr RealWeightTpl<double> Times(const RealWeightTpl<double> &w1,
 
 template <class T>
 constexpr RealWeightTpl<T> Divide(const RealWeightTpl<T> &w1,
-                                 const RealWeightTpl<T> &w2,
-                                 DivideType typ = DIVIDE_ANY) {
+                                  const RealWeightTpl<T> &w2,
+                                  DivideType typ = DIVIDE_ANY) {
   using Weight = RealWeightTpl<T>;
   return w2.Member() ? Weight(w1.Value() / w2.Value()) : Weight::NoWeight();
 }
@@ -761,14 +759,14 @@ constexpr RealWeightTpl<double> Divide(const RealWeightTpl<double> &w1,
 
 // The comments for Power<>(Tropical...) above apply here unchanged.
 
-template <class T, class V,
-          bool Enable = !std::is_same<V, size_t>::value,
+template <class T, class V, bool Enable = !std::is_same<V, size_t>::value,
           typename std::enable_if<Enable>::type * = nullptr>
 constexpr RealWeightTpl<T> Power(const RealWeightTpl<T> &w, V n) {
   using Weight = RealWeightTpl<T>;
-  return (!w.Member() || n != n) ? Weight::NoWeight()
-      : (n == 0 || w == Weight::One()) ? Weight::One()
-      : Weight(pow(w.Value(), n));
+  return (!w.Member() || n != n)
+             ? Weight::NoWeight()
+             : (n == 0 || w == Weight::One()) ? Weight::One()
+                                              : Weight(pow(w.Value(), n));
 }
 
 // Specializes the library-wide template to use the above implementation; rules
@@ -792,9 +790,7 @@ class Adder<RealWeightTpl<T>> {
  public:
   using Weight = RealWeightTpl<T>;
 
-  explicit Adder(Weight w = Weight::Zero())
-      : sum_(w.Value()),
-        c_(0.0) { }
+  explicit Adder(Weight w = Weight::Zero()) : sum_(w.Value()), c_(0.0) {}
 
   Weight Add(const Weight &w) {
     using Limits = FloatLimits<T>;
@@ -818,7 +814,7 @@ class Adder<RealWeightTpl<T>> {
 
  private:
   double sum_;
-  double c_;   // Kahan compensation.
+  double c_;  // Kahan compensation.
 };
 
 // MinMax semiring: (min, max, inf, -inf).
@@ -851,8 +847,8 @@ class MinMaxWeightTpl : public FloatWeightTpl<T> {
 
   MinMaxWeightTpl<T> Quantize(float delta = kDelta) const {
     // If one of infinities, or a NaN.
-    if (!Member() ||
-        Value() == Limits::NegInfinity() || Value() == Limits::PosInfinity()) {
+    if (!Member() || Value() == Limits::NegInfinity() ||
+        Value() == Limits::PosInfinity()) {
       return *this;
     } else {
       return MinMaxWeightTpl<T>(std::floor(Value() / delta + 0.5F) * delta);
@@ -872,9 +868,9 @@ using MinMaxWeight = MinMaxWeightTpl<float>;
 // Min.
 template <class T>
 constexpr MinMaxWeightTpl<T> Plus(const MinMaxWeightTpl<T> &w1,
-                               const MinMaxWeightTpl<T> &w2) {
+                                  const MinMaxWeightTpl<T> &w2) {
   return (!w1.Member() || !w2.Member()) ? MinMaxWeightTpl<T>::NoWeight()
-      : w1.Value() < w2.Value() ? w1 : w2;
+                                        : w1.Value() < w2.Value() ? w1 : w2;
 }
 
 constexpr MinMaxWeightTpl<float> Plus(const MinMaxWeightTpl<float> &w1,
@@ -892,7 +888,7 @@ template <class T>
 constexpr MinMaxWeightTpl<T> Times(const MinMaxWeightTpl<T> &w1,
                                    const MinMaxWeightTpl<T> &w2) {
   return (!w1.Member() || !w2.Member()) ? MinMaxWeightTpl<T>::NoWeight()
-      : w1.Value() >= w2.Value() ? w1 : w2;
+                                        : w1.Value() >= w2.Value() ? w1 : w2;
 }
 
 constexpr MinMaxWeightTpl<float> Times(const MinMaxWeightTpl<float> &w1,
@@ -950,16 +946,12 @@ struct WeightConvert<TropicalWeight, LogWeight> {
 
 template <>
 struct WeightConvert<RealWeight, LogWeight> {
-  LogWeight operator()(const RealWeight &w) const {
-    return -log(w.Value());
-  }
+  LogWeight operator()(const RealWeight &w) const { return -log(w.Value()); }
 };
 
 template <>
 struct WeightConvert<Real64Weight, LogWeight> {
-  LogWeight operator()(const Real64Weight &w) const {
-    return -log(w.Value());
-  }
+  LogWeight operator()(const Real64Weight &w) const { return -log(w.Value()); }
 };
 
 template <>
@@ -979,9 +971,7 @@ struct WeightConvert<TropicalWeight, Log64Weight> {
 
 template <>
 struct WeightConvert<RealWeight, Log64Weight> {
-  Log64Weight operator()(const RealWeight &w) const {
-    return -log(w.Value());
-  }
+  Log64Weight operator()(const RealWeight &w) const { return -log(w.Value()); }
 };
 
 template <>
@@ -1001,16 +991,12 @@ struct WeightConvert<LogWeight, Log64Weight> {
 // Converts to real.
 template <>
 struct WeightConvert<LogWeight, RealWeight> {
-  RealWeight operator()(const LogWeight &w) const {
-    return exp(-w.Value());
-  }
+  RealWeight operator()(const LogWeight &w) const { return exp(-w.Value()); }
 };
 
 template <>
 struct WeightConvert<Log64Weight, RealWeight> {
-  RealWeight operator()(const Log64Weight &w) const {
-    return exp(-w.Value());
-  }
+  RealWeight operator()(const Log64Weight &w) const { return exp(-w.Value()); }
 };
 
 template <>
@@ -1023,9 +1009,7 @@ struct WeightConvert<Real64Weight, RealWeight> {
 // Converts to real64
 template <>
 struct WeightConvert<LogWeight, Real64Weight> {
-  Real64Weight operator()(const LogWeight &w) const {
-    return exp(-w.Value());
-  }
+  Real64Weight operator()(const LogWeight &w) const { return exp(-w.Value()); }
 };
 
 template <>
@@ -1042,29 +1026,30 @@ struct WeightConvert<RealWeight, Real64Weight> {
   }
 };
 
-
 // This function object returns random integers chosen from [0,
-// num_random_weights). The boolean 'allow_zero' determines whether Zero() and
+// num_random_weights). The allow_zero argument determines whether Zero() and
 // zero divisors should be returned in the random weight generation. This is
 // intended primary for testing.
 template <class Weight>
 class FloatWeightGenerate {
  public:
   explicit FloatWeightGenerate(
-      bool allow_zero = true,
+      uint64 seed = std::random_device()(), bool allow_zero = true,
       const size_t num_random_weights = kNumRandomWeights)
-      : allow_zero_(allow_zero), num_random_weights_(num_random_weights) {}
+      : rand_(seed),
+        allow_zero_(allow_zero),
+        num_random_weights_(num_random_weights) {}
 
   Weight operator()() const {
-    const int n = rand() % (num_random_weights_ + allow_zero_);  // NOLINT
-    if (allow_zero_ && n == num_random_weights_) return Weight::Zero();
-    return Weight(n);
+    const int sample = std::uniform_int_distribution<>(
+        0, num_random_weights_ + allow_zero_ - 1)(rand_);
+    if (allow_zero_ && sample == num_random_weights_) return Weight::Zero();
+    return Weight(sample);
   }
 
  private:
-  // Permits Zero() and zero divisors.
+  mutable std::mt19937_64 rand_;
   const bool allow_zero_;
-  // Number of alternative random weights.
   const size_t num_random_weights_;
 };
 
@@ -1075,9 +1060,10 @@ class WeightGenerate<TropicalWeightTpl<T>>
   using Weight = TropicalWeightTpl<T>;
   using Generate = FloatWeightGenerate<Weight>;
 
-  explicit WeightGenerate(bool allow_zero = true,
+  explicit WeightGenerate(uint64 seed = std::random_device()(),
+                          bool allow_zero = true,
                           size_t num_random_weights = kNumRandomWeights)
-      : Generate(allow_zero, num_random_weights) {}
+      : Generate(seed, allow_zero, num_random_weights) {}
 
   Weight operator()() const { return Weight(Generate::operator()()); }
 };
@@ -1089,9 +1075,10 @@ class WeightGenerate<LogWeightTpl<T>>
   using Weight = LogWeightTpl<T>;
   using Generate = FloatWeightGenerate<Weight>;
 
-  explicit WeightGenerate(bool allow_zero = true,
+  explicit WeightGenerate(uint64 seed = std::random_device()(),
+                          bool allow_zero = true,
                           size_t num_random_weights = kNumRandomWeights)
-      : Generate(allow_zero, num_random_weights) {}
+      : Generate(seed, allow_zero, num_random_weights) {}
 
   Weight operator()() const { return Weight(Generate::operator()()); }
 };
@@ -1103,9 +1090,10 @@ class WeightGenerate<RealWeightTpl<T>>
   using Weight = RealWeightTpl<T>;
   using Generate = FloatWeightGenerate<Weight>;
 
-  explicit WeightGenerate(bool allow_zero = true,
+  explicit WeightGenerate(uint64 seed = std::random_device()(),
+                          bool allow_zero = true,
                           size_t num_random_weights = kNumRandomWeights)
-      : Generate(allow_zero, num_random_weights) {}
+      : Generate(seed, allow_zero, num_random_weights) {}
 
   Weight operator()() const { return Weight(Generate::operator()()); }
 };
@@ -1119,27 +1107,28 @@ class WeightGenerate<MinMaxWeightTpl<T>> {
  public:
   using Weight = MinMaxWeightTpl<T>;
 
-  explicit WeightGenerate(bool allow_zero = true,
+  explicit WeightGenerate(uint64 seed = std::random_device()(),
+                          bool allow_zero = true,
                           size_t num_random_weights = kNumRandomWeights)
-      : allow_zero_(allow_zero), num_random_weights_(num_random_weights) {}
+      : rand_(seed),
+        allow_zero_(allow_zero),
+        num_random_weights_(num_random_weights) {}
 
   Weight operator()() const {
-    const int n = (rand() %  // NOLINT
-                   (2 * num_random_weights_ + allow_zero_)) -
-                  num_random_weights_;
-    if (allow_zero_ && n == num_random_weights_) {
+    const int sample = std::uniform_int_distribution<>(
+        -num_random_weights_, num_random_weights_ + allow_zero_)(rand_);
+    if (allow_zero_ && sample == 0) {
       return Weight::Zero();
-    } else if (n == -num_random_weights_) {
+    } else if (sample == -num_random_weights_) {
       return Weight::One();
     } else {
-      return Weight(n);
+      return Weight(sample);
     }
   }
 
  private:
-  // Permits Zero() and zero divisors.
+  mutable std::mt19937_64 rand_;
   const bool allow_zero_;
-  // Number of alternative random weights.
   const size_t num_random_weights_;
 };
 
index 14f8994..5ef194b 100644 (file)
@@ -11,6 +11,7 @@
 #include <memory>  // for allocator<>
 
 #include <fst/types.h>
+#include <fst/windows_defs.inc>
 
 namespace fst {
 
index 8a41795..94f28c4 100644 (file)
@@ -115,8 +115,13 @@ class FstHeader {
     IS_ALIGNED = 0x4,    // Memory-aligned (where appropriate).
   };
 
-  FstHeader() : version_(0), flags_(0), properties_(0), start_(-1),
-      numstates_(0), numarcs_(0) {}
+  FstHeader()
+      : version_(0),
+        flags_(0),
+        properties_(0),
+        start_(-1),
+        numstates_(0),
+        numarcs_(0) {}
 
   const std::string &FstType() const { return fsttype_; }
 
@@ -766,8 +771,8 @@ class FstImpl {
   // Writes header and symbols to output stream. If opts.header is false, skips
   // writing header. If opts.[io]symbols is false, skips writing those symbols.
   // This method is needed for implementations that implement Write methods.
-  void WriteHeader(std::ostream &strm, const FstWriteOptions &opts,
-                   int version, FstHeader *hdr) const {
+  void WriteHeader(std::ostream &strm, const FstWriteOptions &opts, int version,
+                   FstHeader *hdr) const {
     if (opts.write_header) {
       hdr->SetFstType(type_);
       hdr->SetArcType(Arc::Type());
@@ -863,8 +868,8 @@ template <class Arc>
 inline FstImpl<Arc>::FstImpl(FstImpl<Arc> &&) noexcept = default;
 
 template <class Arc>
-inline FstImpl<Arc> &FstImpl<Arc>::operator=(
-    FstImpl<Arc> &&) noexcept = default;
+inline FstImpl<Arc> &FstImpl<Arc>::operator=(FstImpl<Arc> &&) noexcept =
+    default;
 
 template <class Arc>
 bool FstImpl<Arc>::ReadHeader(std::istream &strm, const FstReadOptions &opts,
@@ -875,27 +880,22 @@ bool FstImpl<Arc>::ReadHeader(std::istream &strm, const FstReadOptions &opts,
     return false;
   }
   VLOG(2) << "FstImpl::ReadHeader: source: " << opts.source
-          << ", fst_type: " << hdr->FstType()
-          << ", arc_type: " << Arc::Type()
-          << ", version: " << hdr->Version()
-          << ", flags: " << hdr->GetFlags();
+          << ", fst_type: " << hdr->FstType() << ", arc_type: " << Arc::Type()
+          << ", version: " << hdr->Version() << ", flags: " << hdr->GetFlags();
   if (hdr->FstType() != type_) {
-    LOG(ERROR) << "FstImpl::ReadHeader: FST not of type " << type_
-               << ", found " << hdr->FstType()
-               << ": " << opts.source;
+    LOG(ERROR) << "FstImpl::ReadHeader: FST not of type " << type_ << ", found "
+               << hdr->FstType() << ": " << opts.source;
     return false;
   }
   if (hdr->ArcType() != Arc::Type()) {
     LOG(ERROR) << "FstImpl::ReadHeader: Arc not of type " << Arc::Type()
-               << ", found " << hdr->ArcType()
-               << ": " << opts.source;
+               << ", found " << hdr->ArcType() << ": " << opts.source;
     return false;
   }
   if (hdr->Version() < min_version) {
-    LOG(ERROR) << "FstImpl::ReadHeader: Obsolete " << type_
-               << " FST version " << hdr->Version()
-               << ", min_version=" << min_version
-               << ": " << opts.source;
+    LOG(ERROR) << "FstImpl::ReadHeader: Obsolete " << type_ << " FST version "
+               << hdr->Version() << ", min_version=" << min_version << ": "
+               << opts.source;
     return false;
   }
   properties_.store(hdr->Properties(), std::memory_order_relaxed);
@@ -1039,8 +1039,8 @@ class ImplToFst : public FST {
 template <class IFST, class OFST>
 void Cast(const IFST &ifst, OFST *ofst) {
   using OImpl = typename OFST::Impl;
-  ofst->impl_ = std::shared_ptr<OImpl>(ifst.impl_,
-      reinterpret_cast<OImpl *>(ifst.impl_.get()));
+  ofst->impl_ = std::shared_ptr<OImpl>(
+      ifst.impl_, reinterpret_cast<OImpl *>(ifst.impl_.get()));
 }
 
 // FST serialization.
index 041a4bb..40aa7df 100644 (file)
@@ -68,7 +68,7 @@ class Heap {
   // Returns the least value.
   Value Pop() {
     Value top = values_.front();
-    Swap(0, size_-1);
+    Swap(0, size_ - 1);
     size_--;
     Heapify(0);
     return top;
index b81a1e6..e94cd61 100644 (file)
@@ -26,9 +26,7 @@ struct InvertMapper {
     return ToArc(arc.olabel, arc.ilabel, arc.weight, arc.nextstate);
   }
 
-  constexpr MapFinalAction FinalAction() const {
-     return MAP_NO_SUPERFINAL;
-  }
+  constexpr MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
 
   constexpr MapSymbolsAction InputSymbolsAction() const {
     return MAP_CLEAR_SYMBOLS;
@@ -38,9 +36,7 @@ struct InvertMapper {
     return MAP_CLEAR_SYMBOLS;
   }
 
-  uint64 Properties(uint64 props) const {
-    return InvertProperties(props);
-  }
+  uint64 Properties(uint64 props) const { return InvertProperties(props); }
 };
 
 // Inverts the transduction corresponding to an FST by exchanging the
index c97206d..923c006 100644 (file)
@@ -129,19 +129,25 @@ class Isomorphism {
 
   std::unique_ptr<Fst<Arc>> fst1_;
   std::unique_ptr<Fst<Arc>> fst2_;
-  float delta_;                          // Weight equality delta.
-  std::vector<Arc> arcs1_;               // For sorting arcs on FST1.
-  std::vector<Arc> arcs2_;               // For sorting arcs on FST2.
-  std::vector<StateId> state_pairs_;     // Maintains state correspondences.
+  float delta_;                       // Weight equality delta.
+  std::vector<Arc> arcs1_;            // For sorting arcs on FST1.
+  std::vector<Arc> arcs2_;            // For sorting arcs on FST2.
+  std::vector<StateId> state_pairs_;  // Maintains state correspondences.
   std::queue<std::pair<StateId, StateId>> queue_;  // Queue of state pairs.
-  bool error_;                           // Error flag.
-  bool nondet_;                          // Nondeterminism detected.
+  bool error_;                                     // Error flag.
+  bool nondet_;                                    // Nondeterminism detected.
   ArcCompare comp_;
 };
 
 template <class Arc>
 bool Isomorphism<Arc>::IsIsomorphicState(StateId s1, StateId s2) {
-  if (!ApproxEqual(fst1_->Final(s1), fst2_->Final(s2), delta_)) return false;
+  if (!ApproxEqual(fst1_->Final(s1), fst2_->Final(s2), delta_)) {
+    VLOG(1) << "Isomorphic: Final weights not equal to within delta="
+            << delta_ << ": "  //
+            << "fst1.Final(" << s1 << ") = " << fst1_->Final(s1) << ", "
+            << "fst2.Final(" << s2 << ") = " << fst2_->Final(s2);
+    return false;
+  }
   const auto narcs1 = fst1_->NumArcs(s1);
   const auto narcs2 = fst2_->NumArcs(s2);
   if (narcs1 != narcs2) {
@@ -167,34 +173,34 @@ bool Isomorphism<Arc>::IsIsomorphicState(StateId s1, StateId s2) {
     const auto &arc2 = arcs2_[i];
     if (arc1.ilabel != arc2.ilabel) {
       VLOG(1) << "Isomorphic: ilabels not equal. "
-              << "arc1: *" << arc1.ilabel << "* " << arc1.olabel
-              << " " << arc1.weight << " " << arc1.nextstate
-              << "arc2: *" << arc2.ilabel << "* " << arc2.olabel
-              << " " << arc2.weight << " " << arc2.nextstate;
+              << "arc1: *" << arc1.ilabel << "* " << arc1.olabel << " "
+              << arc1.weight << " " << arc1.nextstate << "arc2: *"
+              << arc2.ilabel << "* " << arc2.olabel << " " << arc2.weight << " "
+              << arc2.nextstate;
       return false;
     }
     if (arc1.olabel != arc2.olabel) {
       VLOG(1) << "Isomorphic: olabels not equal. "
-              << "arc1: " << arc1.ilabel << " *" << arc1.olabel
-              << "* " << arc1.weight << " " << arc1.nextstate
-              << "arc2: " << arc2.ilabel << " *" << arc2.olabel
-              << "* " << arc2.weight << " " << arc2.nextstate;
+              << "arc1: " << arc1.ilabel << " *" << arc1.olabel << "* "
+              << arc1.weight << " " << arc1.nextstate << "arc2: " << arc2.ilabel
+              << " *" << arc2.olabel << "* " << arc2.weight << " "
+              << arc2.nextstate;
       return false;
     }
     if (!ApproxEqual(arc1.weight, arc2.weight, delta_)) {
       VLOG(1) << "Isomorphic: weights not ApproxEqual. "
-              << "arc1: " << arc1.ilabel << " " << arc1.olabel
-              << " *" << arc1.weight << "* " << arc1.nextstate
-              << "arc2: " << arc2.ilabel << " " << arc2.olabel
-              << " *" << arc2.weight << "* " << arc2.nextstate;
+              << "arc1: " << arc1.ilabel << " " << arc1.olabel << " *"
+              << arc1.weight << "* " << arc1.nextstate
+              << "arc2: " << arc2.ilabel << " " << arc2.olabel << " *"
+              << arc2.weight << "* " << arc2.nextstate;
       return false;
     }
     if (!PairState(arc1.nextstate, arc2.nextstate)) {
       VLOG(1) << "Isomorphic: nextstates could not be paired. "
-              << "arc1: " << arc1.ilabel << " " << arc1.olabel
-              << " " << arc1.weight << " *" << arc1.nextstate
-              << "* arc2: " << arc2.ilabel << " " << arc2.olabel
-              << " " << arc2.weight << " *" << arc2.nextstate << "*";
+              << "arc1: " << arc1.ilabel << " " << arc1.olabel << " "
+              << arc1.weight << " *" << arc1.nextstate
+              << "* arc2: " << arc2.ilabel << " " << arc2.olabel << " "
+              << arc2.weight << " *" << arc2.nextstate << "*";
       return false;
     }
     if (i > 0) {  // Checks for non-determinism.
@@ -206,10 +212,10 @@ bool Isomorphism<Arc>::IsIsomorphicState(StateId s1, StateId s2) {
         // states of nondeterministic transitions.
         VLOG(1) << "Isomorphic: Detected non-determinism as an unweighted "
                 << "automaton; deferring error. "
-                << "arc1: " << arc1.ilabel << " " << arc1.olabel
-                << " " << arc1.weight << " " << arc1.nextstate
-                << "arc2: " << arc2.ilabel << " " << arc2.olabel
-                << " " << arc2.weight << " " << arc2.nextstate;
+                << "arc1: " << arc1.ilabel << " " << arc1.olabel << " "
+                << arc1.weight << " " << arc1.nextstate
+                << "arc2: " << arc2.ilabel << " " << arc2.olabel << " "
+                << arc2.weight << " " << arc2.nextstate;
         nondet_ = true;
       }
     }
index 7a8770f..963fa04 100644 (file)
@@ -51,7 +51,14 @@ class LabelReachableData {
 
   int NumIntervalSets() const { return interval_sets_.size(); }
 
-  std::unordered_map<Label, Label> *Label2Index() {
+  std::unordered_map<Label, Label> *MutableLabel2Index() {
+    if (!have_relabel_data_) {
+      FSTERROR() << "LabelReachableData: No relabeling data";
+    }
+    return &label2index_;
+  }
+
+  const std::unordered_map<Label, Label> *Label2Index() const {
     if (!have_relabel_data_) {
       FSTERROR() << "LabelReachableData: No relabeling data";
     }
@@ -479,7 +486,7 @@ class LabelReachable {
     auto &interval_sets = *data_->MutableIntervalSets();
     interval_sets = state_reachable.IntervalSets();
     interval_sets.resize(ins);
-    auto &label2index = *data_->Label2Index();
+    auto &label2index = *data_->MutableLabel2Index();
     for (const auto &kv : label2state_) {
       Label i = state2index[kv.second];
       label2index[kv.first] = i;
index 4b229d4..9ccd562 100644 (file)
@@ -13,7 +13,7 @@
 #ifndef FST_LEXICOGRAPHIC_WEIGHT_H_
 #define FST_LEXICOGRAPHIC_WEIGHT_H_
 
-#include <cstdlib>
+#include <random>
 #include <string>
 
 #include <fst/types.h>
@@ -145,27 +145,30 @@ class WeightGenerate<LexicographicWeight<W1, W2>> {
   using Generate1 = WeightGenerate<W1>;
   using Generate2 = WeightGenerate<W2>;
 
-  explicit WeightGenerate(bool allow_zero = true,
+  explicit WeightGenerate(uint64 seed = std::random_device()(),
+                          bool allow_zero = true,
                           size_t num_random_weights = kNumRandomWeights)
-      : generator1_(false, num_random_weights),
-        generator2_(false, num_random_weights), allow_zero_(allow_zero),
-        num_random_weights_(num_random_weights) {}
+      : rand_(seed),
+        allow_zero_(allow_zero),
+        num_random_weights_(num_random_weights),
+        generator1_(seed, false, num_random_weights),
+        generator2_(seed, false, num_random_weights) {}
 
   Weight operator()() const {
     if (allow_zero_) {
-      const int n = rand() % (num_random_weights_ + 1);  // NOLINT
-      if (n == num_random_weights_) return Weight(W1::Zero(), W2::Zero());
+      const int sample =
+          std::uniform_int_distribution<>(0, num_random_weights_)(rand_);
+      if (sample == num_random_weights_) return Weight(W1::Zero(), W2::Zero());
     }
     return Weight(generator1_(), generator2_());
   }
 
  private:
-  const Generate1 generator1_;
-  const Generate2 generator2_;
-  // Permits Zero() and zero divisors.
+  mutable std::mt19937_64 rand_;
   const bool allow_zero_;
-  // The number of alternative random weights.
   const size_t num_random_weights_;
+  const Generate1 generator1_;
+  const Generate2 generator2_;
 };
 
 }  // namespace fst
index cebeb75..6780343 100644 (file)
@@ -439,8 +439,7 @@ class PushLabelsComposeFilter {
     }
     const auto &fs1 = filter_.FilterArc(arc1, arc2);
     if (fs1 == FilterState1::NoState()) return FilterState::NoState();
-    if (!LookAheadArc())
-      return FilterState(fs1, FilterState2(kNoLabel));
+    if (!LookAheadArc()) return FilterState(fs1, FilterState2(kNoLabel));
     return LookAheadOutput() ? PushLabelFilterArc(arc1, arc2, fs1)
                              : PushLabelFilterArc(arc2, arc1, fs1);
   }
index c2aa62c..99570e3 100644 (file)
@@ -232,9 +232,8 @@ class TrivialLookAheadMatcher
 
 // Look-ahead of one transition. Template argument flags accepts flags to
 // control behavior.
-template <class M,
-          uint32 flags = kLookAheadNonEpsilons | kLookAheadEpsilons |
-                         kLookAheadWeight | kLookAheadPrefix>
+template <class M, uint32 flags = kLookAheadNonEpsilons | kLookAheadEpsilons |
+                                  kLookAheadWeight | kLookAheadPrefix>
 class ArcLookAheadMatcher : public LookAheadMatcherBase<typename M::FST::Arc> {
  public:
   using FST = typename M::FST;
@@ -254,18 +253,16 @@ class ArcLookAheadMatcher : public LookAheadMatcherBase<typename M::FST::Arc> {
   enum : uint32 { kFlags = flags };
 
   // This makes a copy of the FST.
-  ArcLookAheadMatcher(
-      const FST &fst, MatchType match_type,
-      std::shared_ptr<MatcherData> data = nullptr)
+  ArcLookAheadMatcher(const FST &fst, MatchType match_type,
+                      std::shared_ptr<MatcherData> data = nullptr)
       : matcher_(fst, match_type),
         fst_(matcher_.GetFst()),
         lfst_(nullptr),
         state_(kNoStateId) {}
 
   // This doesn't copy the FST.
-  ArcLookAheadMatcher(
-      const FST *fst, MatchType match_type,
-      std::shared_ptr<MatcherData> data = nullptr)
+  ArcLookAheadMatcher(const FST *fst, MatchType match_type,
+                      std::shared_ptr<MatcherData> data = nullptr)
       : matcher_(fst, match_type),
         fst_(matcher_.GetFst()),
         lfst_(nullptr),
@@ -438,13 +435,16 @@ class LabelLookAheadMatcher
   using LookAheadMatcherBase<Arc>::LookAheadPrefix;
   using LookAheadMatcherBase<Arc>::SetLookAheadPrefix;
 
+  static_assert(!(flags & kInputLookAheadMatcher) !=
+                    !(flags & kOutputLookAheadMatcher),
+                "Must include precisely one of kInputLookAheadMatcher and "
+                "kOutputLookAheadMatcher");
   enum : uint32 { kFlags = flags };
 
   // This makes a copy of the FST.
-  LabelLookAheadMatcher(
-      const FST &fst, MatchType match_type,
-      std::shared_ptr<MatcherData> data = nullptr,
-      Accumulator *accumulator = nullptr)
+  LabelLookAheadMatcher(const FST &fst, MatchType match_type,
+                        std::shared_ptr<MatcherData> data = nullptr,
+                        Accumulator *accumulator = nullptr)
       : matcher_(fst, match_type),
         lfst_(nullptr),
         state_(kNoStateId),
@@ -453,10 +453,9 @@ class LabelLookAheadMatcher
   }
 
   // This doesn't copy the FST.
-  LabelLookAheadMatcher(
-      const FST *fst, MatchType match_type,
-      std::shared_ptr<MatcherData> data = nullptr,
-      Accumulator *accumulator = nullptr)
+  LabelLookAheadMatcher(const FST *fst, MatchType match_type,
+                        std::shared_ptr<MatcherData> data = nullptr,
+                        Accumulator *accumulator = nullptr)
       : matcher_(fst, match_type),
         lfst_(nullptr),
         state_(kNoStateId),
@@ -531,8 +530,7 @@ class LabelLookAheadMatcher
   }
 
   std::shared_ptr<MatcherData> GetSharedData() const {
-    return label_reachable_ ? label_reachable_->GetSharedData()
-                            : nullptr;
+    return label_reachable_ ? label_reachable_->GetSharedData() : nullptr;
   }
   // Checks if there is a matching (possibly super-final) transition at
   // (state_, s).
@@ -576,12 +574,7 @@ class LabelLookAheadMatcher
 
  private:
   void Init(const FST &fst, MatchType match_type,
-            std::shared_ptr<MatcherData> data,
-            Accumulator *accumulator) {
-    if (!(kFlags & (kInputLookAheadMatcher | kOutputLookAheadMatcher))) {
-      FSTERROR() << "LabelLookaheadMatcher: Bad matcher flags: " << kFlags;
-      error_ = true;
-    }
+            std::shared_ptr<MatcherData> data, Accumulator *accumulator) {
     const bool reach_input = match_type == MATCH_INPUT;
     if (data) {
       if (reach_input == data->ReachInput()) {
@@ -757,8 +750,7 @@ class LookAheadMatcher {
 
   // This doesn't copy the FST.
   LookAheadMatcher(const FST *fst, MatchType match_type)
-      : base_(fst->InitMatcher(match_type)),
-        lookahead_(false) {
+      : base_(fst->InitMatcher(match_type)), lookahead_(false) {
     if (!base_) base_ = fst::make_unique<SortedMatcher<FST>>(fst, match_type);
   }
 
@@ -790,9 +782,7 @@ class LookAheadMatcher {
 
   ssize_t Priority(StateId s) { return base_->Priority(s); }
 
-  const FST &GetFst() const {
-    return static_cast<const FST &>(base_->GetFst());
-  }
+  const FST &GetFst() const { return static_cast<const FST &>(base_->GetFst()); }
 
   uint64 Properties(uint64 props) const { return base_->Properties(props); }
 
index c81e6e8..8f70700 100644 (file)
@@ -4,11 +4,15 @@
 #ifndef FST_MAPPED_FILE_H_
 #define FST_MAPPED_FILE_H_
 
+#ifdef _WIN32
+#include <windows.h>
+#include <fst/compat.h>
+#endif
+
 #include <cstddef>
 #include <istream>
 #include <string>
 
-#include <fst/compat.h>
 #include <fst/flags.h>
 
 namespace fst {
@@ -25,6 +29,9 @@ struct MemoryRegion {
   void *mmap;
   size_t size;
   size_t offset;
+#ifdef _WIN32
+  HANDLE file_mapping;
+#endif
 };
 
 class MappedFile {
index b0eef87..e1104a0 100644 (file)
@@ -281,8 +281,8 @@ class SortedMatcher : public MatcherBase<typename F::Arc> {
     if (current_loop_) return false;
     if (aiter_->Done()) return true;
     if (!exact_match_) return false;
-    aiter_->SetFlags(match_type_ == MATCH_INPUT ?
-        kArcILabelValue : kArcOLabelValue,
+    aiter_->SetFlags(
+        match_type_ == MATCH_INPUT ? kArcILabelValue : kArcOLabelValue,
         kArcValueFlags);
     return GetLabel() != match_label_;
   }
@@ -301,13 +301,9 @@ class SortedMatcher : public MatcherBase<typename F::Arc> {
     }
   }
 
-  Weight Final(StateId s) const final {
-    return MatcherBase<Arc>::Final(s);
-  }
+  Weight Final(StateId s) const final { return MatcherBase<Arc>::Final(s); }
 
-  ssize_t Priority(StateId s) final {
-    return MatcherBase<Arc>::Priority(s);
-  }
+  ssize_t Priority(StateId s) final { return MatcherBase<Arc>::Priority(s); }
 
   const FST &GetFst() const override { return fst_; }
 
@@ -327,18 +323,18 @@ class SortedMatcher : public MatcherBase<typename F::Arc> {
   bool LinearSearch();
   bool Search();
 
-  std::unique_ptr<const FST> owned_fst_;   // FST ptr if owned.
-  const FST &fst_;           // FST for matching.
-  StateId state_;            // Matcher state.
-  ArcIterator<FST> *aiter_;  // Iterator for current state.
-  MatchType match_type_;     // Type of match to perform.
-  Label binary_label_;       // Least label for binary search.
-  Label match_label_;        // Current label to be matched.
-  size_t narcs_;             // Current state arc count.
-  Arc loop_;                 // For non-consuming symbols.
-  bool current_loop_;        // Current arc is the implicit loop.
-  bool exact_match_;         // Exact match or lower bound?
-  bool error_;               // Error encountered?
+  std::unique_ptr<const FST> owned_fst_;  // FST ptr if owned.
+  const FST &fst_;                        // FST for matching.
+  StateId state_;                         // Matcher state.
+  ArcIterator<FST> *aiter_;               // Iterator for current state.
+  MatchType match_type_;                  // Type of match to perform.
+  Label binary_label_;                    // Least label for binary search.
+  Label match_label_;                     // Current label to be matched.
+  size_t narcs_;                          // Current state arc count.
+  Arc loop_;                              // For non-consuming symbols.
+  bool current_loop_;                     // Current arc is the implicit loop.
+  bool exact_match_;                      // Exact match or lower bound?
+  bool error_;                            // Error encountered?
   MemoryPool<ArcIterator<FST>> aiter_pool_;  // Pool of arc iterators.
 };
 
@@ -390,9 +386,9 @@ inline bool SortedMatcher<FST>::LinearSearch() {
 // bound.
 template <class FST>
 inline bool SortedMatcher<FST>::Search() {
-  aiter_->SetFlags(match_type_ == MATCH_INPUT ?
-                   kArcILabelValue : kArcOLabelValue,
-                   kArcValueFlags);
+  aiter_->SetFlags(
+      match_type_ == MATCH_INPUT ? kArcILabelValue : kArcOLabelValue,
+      kArcValueFlags);
   if (match_label_ >= binary_label_) {
     return BinarySearch();
   } else {
@@ -452,8 +448,8 @@ class HashMatcher : public MatcherBase<typename F::Arc> {
         match_type_(matcher.match_type_),
         loop_(matcher.loop_),
         error_(matcher.error_),
-        state_table_(
-            safe ? std::make_shared<StateTable>() : matcher.state_table_) {}
+        state_table_(safe ? std::make_shared<StateTable>()
+                          : matcher.state_table_) {}
 
   HashMatcher *Copy(bool safe = false) const override {
     return new HashMatcher(*this, safe);
@@ -511,12 +507,12 @@ class HashMatcher : public MatcherBase<typename F::Arc> {
   using StateTable = std::unordered_map<StateId, std::unique_ptr<LabelTable>>;
 
   std::unique_ptr<const FST> owned_fst_;  // ptr to FST if owned.
-  const FST &fst_;     // FST for matching.
-  StateId state_;      // Matcher state.
+  const FST &fst_;                        // FST for matching.
+  StateId state_;                         // Matcher state.
   MatchType match_type_;
-  Arc loop_;            // The implicit loop itself.
-  bool current_loop_;   // Is the current arc the implicit loop?
-  bool error_;          // Error encountered?
+  Arc loop_;           // The implicit loop itself.
+  bool current_loop_;  // Is the current arc the implicit loop?
+  bool error_;         // Error encountered?
   std::unique_ptr<ArcIterator<FST>> aiter_;
   std::shared_ptr<StateTable> state_table_;  // Table from state to label table.
   LabelTable *label_table_;  // Pointer to current state's label table.
@@ -537,7 +533,7 @@ void HashMatcher<FST>::SetState(typename FST::Arc::StateId s) {
   }
   // Attempts to insert a new label table.
   auto it_and_success = state_table_->emplace(
-    state_, std::unique_ptr<LabelTable>(new LabelTable()));
+      state_, std::unique_ptr<LabelTable>(new LabelTable()));
   // Sets instance's pointer to the label table for this state.
   label_table_ = it_and_success.first->second.get();
   // If it already exists, no additional work is done and we simply return.
@@ -627,8 +623,7 @@ class PhiMatcher : public MatcherBase<typename M::Arc> {
              MatcherRewriteMode rewrite_mode = MATCHER_REWRITE_AUTO,
              M *matcher = nullptr)
       : PhiMatcher(*fst, match_type, phi_label, phi_loop, rewrite_mode,
-                   matcher ? matcher : new M(fst, match_type)) { }
-
+                   matcher ? matcher : new M(fst, match_type)) {}
 
   // This makes a copy of the FST.
   PhiMatcher(const PhiMatcher &matcher, bool safe = false)
@@ -890,7 +885,7 @@ class RhoMatcher : public MatcherBase<typename M::Arc> {
              MatcherRewriteMode rewrite_mode = MATCHER_REWRITE_AUTO,
              M *matcher = nullptr)
       : RhoMatcher(*fst, match_type, rho_label, rewrite_mode,
-                   matcher ? matcher : new M(fst, match_type)) { }
+                   matcher ? matcher : new M(fst, match_type)) {}
 
   // This makes a copy of the FST.
   RhoMatcher(const RhoMatcher &matcher, bool safe = false)
@@ -1004,9 +999,8 @@ inline uint64 RhoMatcher<M>::Properties(uint64 inprops) const {
              ~(kODeterministic | kNonODeterministic | kString | kILabelSorted |
                kNotILabelSorted | kOLabelSorted | kNotOLabelSorted);
     } else {
-      return outprops &
-             ~(kODeterministic | kAcceptor | kString | kILabelSorted |
-               kNotILabelSorted);
+      return outprops & ~(kODeterministic | kAcceptor | kString |
+                          kILabelSorted | kNotILabelSorted);
     }
   } else if (match_type_ == MATCH_OUTPUT) {
     if (rewrite_both_) {
@@ -1014,9 +1008,8 @@ inline uint64 RhoMatcher<M>::Properties(uint64 inprops) const {
              ~(kIDeterministic | kNonIDeterministic | kString | kILabelSorted |
                kNotILabelSorted | kOLabelSorted | kNotOLabelSorted);
     } else {
-      return outprops &
-             ~(kIDeterministic | kAcceptor | kString | kOLabelSorted |
-               kNotOLabelSorted);
+      return outprops & ~(kIDeterministic | kAcceptor | kString |
+                          kOLabelSorted | kNotOLabelSorted);
     }
   } else {
     // Shouldn't ever get here.
@@ -1080,9 +1073,9 @@ class SigmaMatcher : public MatcherBase<typename M::Arc> {
   SigmaMatcher(const FST *fst, MatchType match_type,
                Label sigma_label = kNoLabel,
                MatcherRewriteMode rewrite_mode = MATCHER_REWRITE_AUTO,
-             M *matcher = nullptr)
+               M *matcher = nullptr)
       : SigmaMatcher(*fst, match_type, sigma_label, rewrite_mode,
-                     matcher ? matcher : new M(fst, match_type)) { }
+                     matcher ? matcher : new M(fst, match_type)) {}
 
   // This makes a copy of the FST.
   SigmaMatcher(const SigmaMatcher &matcher, bool safe = false)
@@ -1198,20 +1191,17 @@ inline uint64 SigmaMatcher<M>::Properties(uint64 inprops) const {
   if (match_type_ == MATCH_NONE) {
     return outprops;
   } else if (rewrite_both_) {
-    return outprops &
-           ~(kIDeterministic | kNonIDeterministic | kODeterministic |
-             kNonODeterministic | kILabelSorted | kNotILabelSorted |
-             kOLabelSorted | kNotOLabelSorted | kString);
+    return outprops & ~(kIDeterministic | kNonIDeterministic | kODeterministic |
+                        kNonODeterministic | kILabelSorted | kNotILabelSorted |
+                        kOLabelSorted | kNotOLabelSorted | kString);
   } else if (match_type_ == MATCH_INPUT) {
-    return outprops &
-           ~(kIDeterministic | kNonIDeterministic | kODeterministic |
-             kNonODeterministic | kILabelSorted | kNotILabelSorted | kString |
-             kAcceptor);
+    return outprops & ~(kIDeterministic | kNonIDeterministic | kODeterministic |
+                        kNonODeterministic | kILabelSorted | kNotILabelSorted |
+                        kString | kAcceptor);
   } else if (match_type_ == MATCH_OUTPUT) {
-    return outprops &
-           ~(kIDeterministic | kNonIDeterministic | kODeterministic |
-             kNonODeterministic | kOLabelSorted | kNotOLabelSorted | kString |
-             kAcceptor);
+    return outprops & ~(kIDeterministic | kNonIDeterministic | kODeterministic |
+                        kNonODeterministic | kOLabelSorted | kNotOLabelSorted |
+                        kString | kAcceptor);
   } else {
     // Shouldn't ever get here.
     FSTERROR() << "SigmaMatcher: Bad match type: " << match_type_;
@@ -1518,8 +1508,7 @@ class Matcher {
 
   // This makes a copy of the FST.
   Matcher(const FST &fst, MatchType match_type)
-      : owned_fst_(fst.Copy()),
-        base_(owned_fst_->InitMatcher(match_type)) {
+      : owned_fst_(fst.Copy()), base_(owned_fst_->InitMatcher(match_type)) {
     if (!base_)
       base_ =
           fst::make_unique<SortedMatcher<FST>>(owned_fst_.get(), match_type);
@@ -1533,15 +1522,12 @@ class Matcher {
 
   // This makes a copy of the FST.
   Matcher(const Matcher &matcher, bool safe = false)
-      : base_(matcher.base_->Copy(safe)) { }
+      : base_(matcher.base_->Copy(safe)) {}
 
   // Takes ownership of the provided matcher.
-  explicit Matcher(MatcherBase<Arc> *base_matcher)
-      : base_(base_matcher) { }
+  explicit Matcher(MatcherBase<Arc> *base_matcher) : base_(base_matcher) {}
 
-  Matcher *Copy(bool safe = false) const {
-    return new Matcher(*this, safe);
-  }
+  Matcher *Copy(bool safe = false) const { return new Matcher(*this, safe); }
 
   MatchType Type(bool test) const { return base_->Type(test); }
 
@@ -1555,9 +1541,7 @@ class Matcher {
 
   void Next() { base_->Next(); }
 
-  const FST &GetFst() const {
-    return static_cast<const FST &>(base_->GetFst());
-  }
+  const FST &GetFst() const { return static_cast<const FST &>(base_->GetFst()); }
 
   uint64 Properties(uint64 props) const { return base_->Properties(props); }
 
index 552ca6c..08a7281 100644 (file)
@@ -70,7 +70,7 @@ class MemoryArenaImpl : public MemoryArenaBase {
 
  private:
   const size_t block_size_;  // Default block size in bytes.
-  size_t block_pos_;   // Current position in block in bytes.
+  size_t block_pos_;         // Current position in block in bytes.
   std::list<std::unique_ptr<char[]>> blocks_;  // List of allocated blocks.
 };
 
index 1f2e963..5b71282 100644 (file)
@@ -7,7 +7,7 @@
 #ifndef FST_PAIR_WEIGHT_H_
 #define FST_PAIR_WEIGHT_H_
 
-#include <climits>
+#include <random>
 #include <stack>
 #include <string>
 #include <utility>
@@ -140,14 +140,15 @@ class WeightGenerate<PairWeight<W1, W2>> {
   using Generate1 = WeightGenerate<W1>;
   using Generate2 = WeightGenerate<W2>;
 
-  explicit WeightGenerate(bool allow_zero = true)
-      : generate1_(allow_zero), generate2_(allow_zero) {}
+  explicit WeightGenerate(uint64 seed = std::random_device()(),
+                          bool allow_zero = true)
+      : generate1_(seed, allow_zero), generate2_(seed, allow_zero) {}
 
   Weight operator()() const { return Weight(generate1_(), generate2_()); }
 
  private:
-  Generate1 generate1_;
-  Generate2 generate2_;
+  const Generate1 generate1_;
+  const Generate2 generate2_;
 };
 
 }  // namespace fst
index 15fb9e9..1884bfe 100644 (file)
@@ -60,8 +60,9 @@ class ProjectPowerWeightMapper {
   explicit ProjectPowerWeightMapper(
       Index from_index = 0, Index to_index = 0,
       const ComponentWeight &default_weight = ComponentWeight::Zero())
-    : from_index_(from_index), to_index_(to_index),
-      default_weight_(default_weight) {}
+      : from_index_(from_index),
+        to_index_(to_index),
+        default_weight_(default_weight) {}
 
   PowerWeightT operator()(const PowerWeightT &w) const {
     return PowerWeightT(to_index_, w.Value(from_index_), default_weight_);
index 0af03ad..e1f9a3f 100644 (file)
@@ -6,6 +6,7 @@
 #ifndef FST_POWER_WEIGHT_H_
 #define FST_POWER_WEIGHT_H_
 
+#include <random>
 #include <string>
 
 #include <fst/types.h>
@@ -153,7 +154,9 @@ class WeightGenerate<PowerWeight<W, n>> {
   using Weight = PowerWeight<W, n>;
   using Generate = WeightGenerate<W>;
 
-  explicit WeightGenerate(bool allow_zero = true) : generate_(allow_zero) {}
+  explicit WeightGenerate(uint64 seed = std::random_device()(),
+                          bool allow_zero = true)
+      : generate_(seed, allow_zero) {}
 
   Weight operator()() const {
     Weight result;
@@ -162,7 +165,7 @@ class WeightGenerate<PowerWeight<W, n>> {
   }
 
  private:
-  Generate generate_;
+  const Generate generate_;
 };
 
 }  // namespace fst
index 329a927..fab1657 100644 (file)
@@ -6,6 +6,7 @@
 #ifndef FST_PRODUCT_WEIGHT_H_
 #define FST_PRODUCT_WEIGHT_H_
 
+#include <random>
 #include <string>
 #include <utility>
 
@@ -97,9 +98,7 @@ class Adder<ProductWeight<W1, W2>> {
 
   Adder() {}
 
-  explicit Adder(Weight w)
-      : adder1_(w.Value1()),
-        adder2_(w.Value2()) {}
+  explicit Adder(Weight w) : adder1_(w.Value1()), adder2_(w.Value2()) {}
 
   Weight Add(const Weight &w) {
     adder1_.Add(w.Value1());
@@ -119,20 +118,23 @@ class Adder<ProductWeight<W1, W2>> {
   Adder<W2> adder2_;
 };
 
-
 // This function object generates weights by calling the underlying generators
 // for the template weight types, like all other pair weight types. This is
 // intended primarily for testing.
 template <class W1, class W2>
-class WeightGenerate<ProductWeight<W1, W2>> :
-    public WeightGenerate<PairWeight<W1, W2>> {
+class WeightGenerate<ProductWeight<W1, W2>> {
  public:
   using Weight = ProductWeight<W1, W2>;
   using Generate = WeightGenerate<PairWeight<W1, W2>>;
 
-  explicit WeightGenerate(bool allow_zero = true) : Generate(allow_zero) {}
+  explicit WeightGenerate(uint64 seed = std::random_device()(),
+                          bool allow_zero = true)
+      : generate_(seed, allow_zero) {}
+
+  Weight operator()() const { return Weight(generate_()); }
 
-  Weight operator()() const { return Weight(Generate::operator()()); }
+ private:
+  const Generate generate_;
 };
 
 }  // namespace fst
index 6c519ab..ae96322 100644 (file)
 #include <fst/arc-map.h>
 #include <fst/mutable-fst.h>
 
-
 namespace fst {
 
 // This specifies whether to project on input or output.
-enum ProjectType { PROJECT_INPUT = 1, PROJECT_OUTPUT = 2 };
+enum class ProjectType { INPUT = 1, OUTPUT = 2 };
+OPENFST_DEPRECATED("Use `ProjectType::INPUT` instead.")
+static constexpr ProjectType PROJECT_INPUT = ProjectType::INPUT;
+OPENFST_DEPRECATED("Use `ProjectType::OUTPUT` instead.")
+static constexpr ProjectType PROJECT_OUTPUT = ProjectType::OUTPUT;
 
 // Mapper to implement projection per arc.
 template <class A>
@@ -28,26 +31,25 @@ class ProjectMapper {
       : project_type_(project_type) {}
 
   ToArc operator()(const FromArc &arc) const {
-    const auto label = project_type_ == PROJECT_INPUT ? arc.ilabel : arc.olabel;
+    const auto label =
+        project_type_ == ProjectType::INPUT ? arc.ilabel : arc.olabel;
     return ToArc(label, label, arc.weight, arc.nextstate);
   }
 
-  constexpr MapFinalAction FinalAction() const {
-    return MAP_NO_SUPERFINAL;
-  }
+  constexpr MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }
 
   constexpr MapSymbolsAction InputSymbolsAction() const {
-    return project_type_ == PROJECT_INPUT ? MAP_COPY_SYMBOLS
-                                          : MAP_CLEAR_SYMBOLS;
+    return project_type_ == ProjectType::INPUT ? MAP_COPY_SYMBOLS
+                                               : MAP_CLEAR_SYMBOLS;
   }
 
   constexpr MapSymbolsAction OutputSymbolsAction() const {
-    return project_type_ == PROJECT_OUTPUT ? MAP_COPY_SYMBOLS
-                                           : MAP_CLEAR_SYMBOLS;
+    return project_type_ == ProjectType::OUTPUT ? MAP_COPY_SYMBOLS
+                                                : MAP_CLEAR_SYMBOLS;
   }
 
   constexpr uint64 Properties(uint64 props) const {
-    return ProjectProperties(props, project_type_ == PROJECT_INPUT);
+    return ProjectProperties(props, project_type_ == ProjectType::INPUT);
   }
 
  private:
@@ -68,10 +70,10 @@ inline void Project(const Fst<Arc> &ifst, MutableFst<Arc> *ofst,
                     ProjectType project_type) {
   ArcMap(ifst, ofst, ProjectMapper<Arc>(project_type));
   switch (project_type) {
-    case PROJECT_INPUT:
+    case ProjectType::INPUT:
       ofst->SetOutputSymbols(ifst.InputSymbols());
       return;
-    case PROJECT_OUTPUT:
+    case ProjectType::OUTPUT:
       ofst->SetInputSymbols(ifst.OutputSymbols());
       return;
   }
@@ -82,10 +84,10 @@ template <class Arc>
 inline void Project(MutableFst<Arc> *fst, ProjectType project_type) {
   ArcMap(fst, ProjectMapper<Arc>(project_type));
   switch (project_type) {
-    case PROJECT_INPUT:
+    case ProjectType::INPUT:
       fst->SetOutputSymbols(fst->InputSymbols());
       return;
-    case PROJECT_OUTPUT:
+    case ProjectType::OUTPUT:
       fst->SetInputSymbols(fst->OutputSymbols());
       return;
   }
@@ -112,10 +114,10 @@ class ProjectFst : public ArcMapFst<A, A, ProjectMapper<A>> {
 
   ProjectFst(const Fst<A> &fst, ProjectType project_type)
       : ArcMapFst<A, A, ProjectMapper<A>>(fst, ProjectMapper<A>(project_type)) {
-    if (project_type == PROJECT_INPUT) {
+    if (project_type == ProjectType::INPUT) {
       GetMutableImpl()->SetOutputSymbols(fst.InputSymbols());
     }
-    if (project_type == PROJECT_OUTPUT) {
+    if (project_type == ProjectType::OUTPUT) {
       GetMutableImpl()->SetInputSymbols(fst.OutputSymbols());
     }
   }
index a44b149..1f0ec1d 100644 (file)
@@ -299,12 +299,12 @@ constexpr uint64 kTrinaryProperties = 0x0000ffffffff0000ULL;
 // COMPUTED PROPERTIES
 
 // 1st bit of trinary properties.
-constexpr uint64 kPosTrinaryProperties = kTrinaryProperties &
-    0x5555555555555555ULL;
+constexpr uint64 kPosTrinaryProperties =
+    kTrinaryProperties & 0x5555555555555555ULL;
 
 // 2nd bit of trinary properties.
-constexpr uint64 kNegTrinaryProperties = kTrinaryProperties &
-    0xaaaaaaaaaaaaaaaaULL;
+constexpr uint64 kNegTrinaryProperties =
+    kTrinaryProperties & 0xaaaaaaaaaaaaaaaaULL;
 
 // All properties.
 constexpr uint64 kFstProperties = kBinaryProperties | kTrinaryProperties;
@@ -423,8 +423,8 @@ uint64 SetFinalProperties(uint64 inprops, const Weight &old_weight,
 /// \param prev_arc the previously-added (or "last") arc of state s, or nullptr
 //                  if s currently has no arcs.
 template <typename Arc>
-uint64 AddArcProperties(uint64 inprops, typename Arc::StateId s,
-                        const Arc &arc, const Arc *prev_arc) {
+uint64 AddArcProperties(uint64 inprops, typename Arc::StateId s, const Arc &arc,
+                        const Arc *prev_arc) {
   using Weight = typename Arc::Weight;
   auto outprops = inprops;
   if (arc.ilabel != arc.olabel) {
index e2e821c..387bca2 100644 (file)
@@ -123,9 +123,9 @@ void Prune(MutableFst<Arc> *fst, const PruneOptions<Arc, ArcFilter> &opts =
   dead.push_back(fst->AddState());
   NaturalLess<Weight> less;
   auto s = fst->Start();
-  const auto limit = opts.threshold_initial ?
-      Times(opts.weight_threshold, (*fdistance)[s]) :
-      Times((*fdistance)[s], opts.weight_threshold);
+  const auto limit = opts.threshold_initial
+                         ? Times(opts.weight_threshold, (*fdistance)[s])
+                         : Times((*fdistance)[s], opts.weight_threshold);
   StateId num_visited = 0;
 
   if (!less(limit, (*fdistance)[s])) {
@@ -145,9 +145,10 @@ void Prune(MutableFst<Arc> *fst, const PruneOptions<Arc, ArcFilter> &opts =
          aiter.Next()) {
       auto arc = aiter.Value();  // Copy intended.
       if (!opts.filter(arc)) continue;
-      const auto weight = Times(Times(idistance[s], arc.weight),
-                                arc.nextstate < fdistance->size() ?
-                                (*fdistance)[arc.nextstate] : Weight::Zero());
+      const auto weight =
+          Times(Times(idistance[s], arc.weight),
+                arc.nextstate < fdistance->size() ? (*fdistance)[arc.nextstate]
+                                                  : Weight::Zero());
       if (less(limit, weight)) {
         arc.nextstate = dead[0];
         aiter.SetValue(arc);
@@ -247,9 +248,9 @@ void Prune(
   std::vector<size_t> enqueued;
   std::vector<bool> visited;
   auto s = ifst.Start();
-  const auto limit = opts.threshold_initial ?
-      Times(opts.weight_threshold, (*fdistance)[s]) :
-      Times((*fdistance)[s], opts.weight_threshold);
+  const auto limit = opts.threshold_initial
+                         ? Times(opts.weight_threshold, (*fdistance)[s])
+                         : Times((*fdistance)[s], opts.weight_threshold);
   while (copy.size() <= s) copy.push_back(kNoStateId);
   copy[s] = ofst->AddState();
   ofst->SetStart(copy[s]);
@@ -271,9 +272,10 @@ void Prune(
     for (ArcIterator<Fst<Arc>> aiter(ifst, s); !aiter.Done(); aiter.Next()) {
       const auto &arc = aiter.Value();
       if (!opts.filter(arc)) continue;
-      const auto weight = Times(Times(idistance[s], arc.weight),
-                                arc.nextstate < fdistance->size() ?
-                                (*fdistance)[arc.nextstate] : Weight::Zero());
+      const auto weight =
+          Times(Times(idistance[s], arc.weight),
+                arc.nextstate < fdistance->size() ? (*fdistance)[arc.nextstate]
+                                                  : Weight::Zero());
       if (less(limit, weight)) continue;
       if ((opts.state_threshold != kNoStateId) &&
           (ofst->NumStates() >= opts.state_threshold)) {
index ad80e13..429b5e6 100644 (file)
@@ -65,28 +65,27 @@ void RemoveWeight(MutableFst<Arc> *fst, const typename Arc::Weight &weight,
   }
 }
 
-// Pushes the weights in FST in the direction defined by TYPE. If pushing
-// towards the initial state, the sum of the weight of the outgoing transitions
-// and final weight at a non-initial state is equal to One() in the resulting
-// machine. If pushing towards the final state, the same property holds on the
-// reverse machine.
+// Pushes the weights in FST in the requested direction. If pushing towards the
+// initial state, the sum of the weight of the outgoing transitions and final
+// weight at a non-initial state is equal to One() in the resulting machine. If
+// pushing towards the final state, the same property holds on the reverse
+// machine.
 //
 // Weight needs to be left distributive when pushing towards the initial state
 // and right distributive when pushing towards the final states.
 template <class Arc>
-void Push(MutableFst<Arc> *fst, ReweightType type, float delta = kShortestDelta,
-          bool remove_total_weight = false) {
+void Push(MutableFst<Arc> *fst, ReweightType type = REWEIGHT_TO_INITIAL,
+          float delta = kShortestDelta, bool remove_total_weight = false) {
   using Weight = typename Arc::Weight;
   std::vector<Weight> distance;
-  ShortestDistance(*fst, &distance, type == REWEIGHT_TO_INITIAL, delta);
-  auto total_weight = Weight::One();
+  const bool reverse = type == REWEIGHT_TO_INITIAL;
+  ShortestDistance(*fst, &distance, reverse, delta);
   if (remove_total_weight) {
-    total_weight =
-        ComputeTotalWeight(*fst, distance, type == REWEIGHT_TO_INITIAL);
-  }
-  Reweight(fst, distance, type);
-  if (remove_total_weight) {
-    RemoveWeight(fst, total_weight, type == REWEIGHT_TO_FINAL);
+    const auto total_weight = ComputeTotalWeight(*fst, distance, reverse);
+    Reweight(fst, distance, type);
+    RemoveWeight(fst, total_weight, !reverse);
+  } else {
+    Reweight(fst, distance, type);
   }
 }
 
index 4326965..05e978b 100644 (file)
@@ -783,7 +783,7 @@ class NaturalAStarEstimate {
   NaturalAStarEstimate(const std::vector<Weight> &beta) : beta_(beta) {}
 
   const Weight &operator()(StateId s) const {
-     return (s < beta_.size()) ? beta_[s] : kZero;
+    return (s < beta_.size()) ? beta_[s] : kZero;
   }
 
  private:
@@ -825,7 +825,8 @@ class AStarWeightCompare {
 
 // A* queue discipline templated on StateId, Weight, and Estimate.
 template <typename S, typename Weight, typename Estimate>
-class NaturalAStarQueue : public ShortestFirstQueue<
+class NaturalAStarQueue
+    : public ShortestFirstQueue<
           S, AStarWeightCompare<S, NaturalLess<Weight>, Estimate>> {
  public:
   using StateId = S;
index 8fd41e9..55d45d6 100644 (file)
@@ -63,8 +63,8 @@ bool RandEquivalent(const Fst<Arc> &fst1, const Fst<Arc> &fst2, int32 npath,
     RandGen(fst, &path, opts);
     VectorFst<Arc> ipath(path);
     VectorFst<Arc> opath(path);
-    Project(&ipath, PROJECT_INPUT);
-    Project(&opath, PROJECT_OUTPUT);
+    Project(&ipath, ProjectType::INPUT);
+    Project(&opath, ProjectType::OUTPUT);
     VectorFst<Arc> cfst1, pfst1;
     Compose(ipath, sfst1, &cfst1);
     ArcSort(&cfst1, ocomp);
index cdad394..2fe1af5 100644 (file)
@@ -138,8 +138,8 @@ class FastLogProbArcSelector : public LogProbArcSelector<Arc> {
   // Constructs a selector with a non-deterministic seed.
   FastLogProbArcSelector() : LogProbArcSelector<Arc>() {}
   // Constructs a selector with a given seed.
-  explicit FastLogProbArcSelector(uint64 seed) : LogProbArcSelector<Arc>(
-      seed) {}
+  explicit FastLogProbArcSelector(uint64 seed)
+      : LogProbArcSelector<Arc>(seed) {}
 
   size_t operator()(const Fst<Arc> &fst, StateId s,
                     CacheLogAccumulator<Arc> *accumulator) const {
@@ -149,8 +149,8 @@ class FastLogProbArcSelector : public LogProbArcSelector<Arc> {
     const double sum =
         ToLogWeight(accumulator->Sum(fst.Final(s), &aiter, 0, fst.NumArcs(s)))
             .Value();
-    const double r = -log(std::uniform_real_distribution<>(0, 1)(
-        MutableRand()));
+    const double r =
+        -log(std::uniform_real_distribution<>(0, 1)(MutableRand()));
     Weight w = from_log_weight_(r + sum);
     aiter.Reset();
     return accumulator->LowerBound(w, &aiter);
index 8dc41fd..24bac15 100644 (file)
@@ -78,8 +78,7 @@ class FstRegisterer : public GenericRegisterer<FstRegister<typename FST::Arc>> {
                                                           BuildEntry()) {}
 
  private:
-  static Fst<Arc> *ReadGeneric(
-      std::istream &strm, const FstReadOptions &opts) {
+  static Fst<Arc> *ReadGeneric(std::istream &strm, const FstReadOptions &opts) {
     static_assert(std::is_base_of<Fst<Arc>, FST>::value,
                   "FST class does not inherit from Fst<Arc>");
     return FST::Read(strm, opts);
index 50c2a3a..b7a99d6 100644 (file)
@@ -165,14 +165,11 @@ void Relabel(MutableFst<Arc> *fst, const SymbolTable *old_isymbols,
              const SymbolTable *new_isymbols, bool attach_new_isymbols,
              const SymbolTable *old_osymbols, const SymbolTable *new_osymbols,
              bool attach_new_osymbols) {
-  Relabel(fst,
-          old_isymbols, new_isymbols, "" /* no unknown isymbol */,
-          attach_new_isymbols,
-          old_osymbols, new_osymbols, "" /* no unknown ioymbol */,
-          attach_new_osymbols);
+  Relabel(fst, old_isymbols, new_isymbols, "" /* no unknown isymbol */,
+          attach_new_isymbols, old_osymbols, new_osymbols,
+          "" /* no unknown ioymbol */, attach_new_osymbols);
 }
 
-
 // Relabels either the input labels or output labels. The old to
 // new labels are specified using symbol tables. Any label associations not
 // specified are assumed to be identity mapping.
@@ -234,12 +231,10 @@ class RelabelFstImpl : public CacheImpl<Arc> {
     SetType("relabel");
   }
 
-  RelabelFstImpl(const Fst<Arc> &fst,
-                 const SymbolTable *old_isymbols,
+  RelabelFstImpl(const Fst<Arc> &fst, const SymbolTable *old_isymbols,
                  const SymbolTable *new_isymbols,
                  const SymbolTable *old_osymbols,
-                 const SymbolTable *new_osymbols,
-                 const RelabelFstOptions &opts)
+                 const SymbolTable *new_osymbols, const RelabelFstOptions &opts)
       : CacheImpl<Arc>(opts),
         fst_(fst.Copy()),
         relabel_input_(false),
@@ -434,7 +429,7 @@ class StateIterator<RelabelFst<Arc>> : public StateIteratorBase<Arc> {
   }
 
  private:
-  const internal::RelabelFstImpl<Arc>impl_;
+  const internal::RelabelFstImpl<Arc> *impl_;
   StateIterator<Fst<Arc>> siter_;
   StateId s_;
 
index 8572fb4..ed83f53 100644 (file)
@@ -58,9 +58,8 @@ struct ReplaceUtilOptions {
 
   // For backwards compatibility.
   ReplaceUtilOptions(int64 root, bool epsilon_replace_arc)
-      : ReplaceUtilOptions(root,
-                           epsilon_replace_arc ? REPLACE_LABEL_NEITHER
-                                               : REPLACE_LABEL_INPUT) {}
+      : ReplaceUtilOptions(root, epsilon_replace_arc ? REPLACE_LABEL_NEITHER
+                                                     : REPLACE_LABEL_INPUT) {}
 };
 
 // Every non-terminal on a path appears as the first label on that path in every
@@ -344,8 +343,7 @@ void ReplaceUtil<Arc>::GetDependencies(bool stats) const {
         ++stats_[ilabel].nstates;
         if (ifst->Final(s) != Weight::Zero()) ++stats_[ilabel].nfinal;
       }
-      for (ArcIterator<Fst<Arc>> aiter(*ifst, s); !aiter.Done();
-           aiter.Next()) {
+      for (ArcIterator<Fst<Arc>> aiter(*ifst, s); !aiter.Done(); aiter.Next()) {
         if (have_stats_) ++stats_[ilabel].narcs;
         const auto &arc = aiter.Value();
         auto it = nonterminal_hash_.find(arc.olabel);
@@ -583,8 +581,8 @@ void ReplaceUtil<Arc>::GetSCCProperties() const {
   if (!(depprops_ & kCyclic)) return;  // No cyclic dependencies.
   // Checks for self-loops in the dependency graph.
   for (StateId scc = 0; scc < depscc_.size(); ++scc) {
-    for (ArcIterator<Fst<Arc> > aiter(depfst_, scc);
-         !aiter.Done(); aiter.Next()) {
+    for (ArcIterator<Fst<Arc>> aiter(depfst_, scc); !aiter.Done();
+         aiter.Next()) {
       const auto &arc = aiter.Value();
       if (arc.nextstate == scc) {  // SCC has a self loop.
         depsccprops_[scc] |= kReplaceSCCNonTrivial;
index 401ad52..747931f 100644 (file)
@@ -121,7 +121,7 @@ class ReplaceFstStateFingerprint {
 template <typename S, typename P>
 class ReplaceHash {
  public:
-  size_t operator()(const ReplaceStateTuple<S, P>t) const {
+  size_t operator()(const ReplaceStateTuple<S, P> &t) const {
     static constexpr size_t prime0 = 7853;
     static constexpr size_t prime1 = 7867;
     return t.prefix_id + t.fst_id * prime0 + t.fst_state * prime1;
@@ -253,7 +253,7 @@ class VectorHashReplaceStateTable {
     return prefix_table_.FindId(prefix);
   }
 
-  const StackPrefixGetStackPrefix(PrefixId id) const {
+  const StackPrefix &GetStackPrefix(PrefixId id) const {
     return prefix_table_.FindEntry(id);
   }
 
@@ -373,7 +373,6 @@ struct ReplaceFstOptions : CacheImplOptions<CacheStore> {
         call_output_label(epsilon_replace_arc ? 0 : kNoLabel) {}
 };
 
-
 // Forward declaration.
 template <class Arc, class StateTable, class CacheStore>
 class ReplaceFstMatcher;
@@ -474,10 +473,10 @@ class ReplaceFstImpl
   using FstImpl<Arc>::InputSymbols;
   using FstImpl<Arc>::OutputSymbols;
 
-  using CacheImpl::PushArc;
   using CacheImpl::HasArcs;
   using CacheImpl::HasFinal;
   using CacheImpl::HasStart;
+  using CacheImpl::PushArc;
   using CacheImpl::SetArcs;
   using CacheImpl::SetFinal;
   using CacheImpl::SetStart;
@@ -994,8 +993,8 @@ class ReplaceFst
     if ((GetImpl()->ArcIteratorFlags() & kArcNoCache) &&
         ((match_type == MATCH_INPUT && Properties(kILabelSorted, false)) ||
          (match_type == MATCH_OUTPUT && Properties(kOLabelSorted, false)))) {
-      return new ReplaceFstMatcher<Arc, StateTable, CacheStore>
-          (this, match_type);
+      return new ReplaceFstMatcher<Arc, StateTable, CacheStore>(this,
+                                                                match_type);
     } else {
       VLOG(2) << "Not using replace matcher";
       return nullptr;
index 649e368..0bbe29b 100644 (file)
@@ -61,7 +61,7 @@ void Reverse(const Fst<FromArc> &ifst, MutableFst<ToArc> *ofst,
       std::vector<StateId> scc;
       SccVisitor<FromArc> scc_visitor(&scc, nullptr, nullptr, &dfs_iprops);
       DfsVisit(ifst, &scc_visitor);
-      if (count(scc.begin(), scc.end(), scc[ostart]) > 1) {
+      if (std::count(scc.begin(), scc.end(), scc[ostart]) > 1) {
         ostart = kNoStateId;
       } else {
         for (ArcIterator<Fst<FromArc>> aiter(ifst, ostart); !aiter.Done();
index 229f50b..a9addd5 100644 (file)
@@ -140,7 +140,9 @@ void RmEpsilonState<Arc, Queue>::Expand(typename Arc::StateId source) {
   while (!eps_queue_.empty()) {
     const auto state = eps_queue_.top();
     eps_queue_.pop();
-    while (visited_.size() <= state) visited_.push_back(false);
+    if (static_cast<decltype(state)>(visited_.size()) <= state) {
+      visited_.resize(state + 1, false);
+    }
     if (visited_[state]) continue;
     visited_[state] = true;
     visited_states_.push_front(state);
@@ -149,7 +151,10 @@ void RmEpsilonState<Arc, Queue>::Expand(typename Arc::StateId source) {
       auto arc = aiter.Value();
       arc.weight = Times((*distance_)[state], arc.weight);
       if (eps_filter_(arc)) {
-        while (visited_.size() <= arc.nextstate) visited_.push_back(false);
+        if (static_cast<decltype(arc.nextstate)>(visited_.size()) <=
+            arc.nextstate) {
+          visited_.resize(arc.nextstate + 1, false);
+        }
         if (!visited_[arc.nextstate]) eps_queue_.push(arc.nextstate);
       } else {
         const Element element(arc.ilabel, arc.olabel, arc.nextstate);
index 551266d..7febb0d 100644 (file)
@@ -15,7 +15,9 @@ namespace script {
 struct ArcClass {
   template <class Arc>
   explicit ArcClass(const Arc &arc)
-      : ilabel(arc.ilabel), olabel(arc.olabel), weight(arc.weight),
+      : ilabel(arc.ilabel),
+        olabel(arc.olabel),
+        weight(arc.weight),
         nextstate(arc.nextstate) {}
 
   ArcClass(int64 ilabel, int64 olabel, const WeightClass &weight,
index 97dc608..8f6859d 100644 (file)
@@ -122,8 +122,7 @@ class MutableArcIteratorImplBase : public ArcIteratorImplBase {
 
 // Templated implementation.
 template <class Arc>
-class MutableArcIteratorClassImpl
-    : public MutableArcIteratorImplBase {
+class MutableArcIteratorClassImpl : public MutableArcIteratorImplBase {
  public:
   explicit MutableArcIteratorClassImpl(MutableFst<Arc> *fst, int64 s)
       : aiter_(fst, s) {}
index 3e56fe5..85c3876 100644 (file)
 namespace fst {
 namespace script {
 
-enum ArcSortType {
-  ILABEL_SORT,
-  OLABEL_SORT
-};
+enum ArcSortType { ILABEL_SORT, OLABEL_SORT };
 
 using ArcSortArgs = std::pair<MutableFstClass *, ArcSortType>;
 
index 42ea82f..18ab237 100644 (file)
@@ -43,8 +43,8 @@ class FstCompiler {
     std::unique_ptr<SymbolTable> misyms(isyms ? isyms->Copy() : nullptr);
     std::unique_ptr<SymbolTable> mosyms(osyms ? osyms->Copy() : nullptr);
     std::unique_ptr<SymbolTable> mssyms(ssyms ? ssyms->Copy() : nullptr);
-    Init(istrm, source, misyms.get(), mosyms.get(), mssyms.get(), accep,
-         ikeep, okeep, nkeep, allow_negative_labels, false);
+    Init(istrm, source, misyms.get(), mosyms.get(), mssyms.get(), accep, ikeep,
+         okeep, nkeep, allow_negative_labels, false);
   }
 
   FstCompiler(std::istream &istrm, const std::string &source,  // NOLINT
@@ -75,8 +75,7 @@ class FstCompiler {
       ++nline_;
       std::vector<char *> col;
       SplitString(line, separator.c_str(), &col, true);
-      if (col.empty() || col[0][0] == '\0')
-        continue;
+      if (col.empty() || col[0][0] == '\0') continue;
       if (col.size() > 5 || (col.size() > 4 && accep) ||
           (col.size() == 3 && !accep)) {
         FSTERROR() << "FstCompiler: Bad number of columns, source = " << source_
@@ -153,7 +152,7 @@ class FstCompiler {
     } else {
       char *p;
       n = strtoll(s, &p, 10);
-      if (p < s + strlen(s) || (!allow_negative && n < 0)) {
+      if (*p != '\0' || (!allow_negative && n < 0)) {
         FSTERROR() << "FstCompiler: Bad " << name << " integer = \"" << s
                    << "\", source = " << source_ << ", line = " << nline_;
         fst_.SetProperties(kError, kError);
@@ -203,7 +202,7 @@ class FstCompiler {
   SymbolTable *osyms_;  // olabel symbol table (not owned).
   SymbolTable *ssyms_;  // slabel symbol table (not owned).
   std::unordered_map<StateId, StateId> states_;  // State ID map.
-  StateId nstates_;                              // Number of seen states.
+  StateId nstates_;                               // Number of seen states.
   bool keep_state_numbering_;
   bool allow_negative_labels_;  // Not recommended; may cause conflicts.
   bool add_symbols_;            // Add to symbol tables on-the fly.
index 183a629..90fcfd4 100644 (file)
@@ -34,8 +34,8 @@ struct DeterminizeOptions {
         increment_subsequential_label(increment_subsequential_label) {}
 };
 
-using DeterminizeArgs = std::tuple<const FstClass &, MutableFstClass *,
-                                   const DeterminizeOptions &>;
+using DeterminizeArgs =
+    std::tuple<const FstClass &, MutableFstClass *, const DeterminizeOptions &>;
 
 template <class Arc>
 void Determinize(DeterminizeArgs *args) {
@@ -44,8 +44,9 @@ void Determinize(DeterminizeArgs *args) {
   MutableFst<Arc> *ofst = std::get<1>(*args)->GetMutableFst<Arc>();
   const auto &opts = std::get<2>(*args);
   const auto weight_threshold = *opts.weight_threshold.GetWeight<Weight>();
-  const fst::DeterminizeOptions<Arc> detargs(opts.delta, weight_threshold,
-      opts.state_threshold, opts.subsequential_label, opts.det_type,
+  const fst::DeterminizeOptions<Arc> detargs(
+      opts.delta, weight_threshold, opts.state_threshold,
+      opts.subsequential_label, opts.det_type,
       opts.increment_subsequential_label);
   Determinize(ifst, ofst, detargs);
 }
index 5f892a9..936295c 100644 (file)
@@ -30,7 +30,7 @@ struct DisambiguateOptions {
 };
 
 using DisambiguateArgs = std::tuple<const FstClass &, MutableFstClass *,
-                                     const DisambiguateOptions &>;
+                                    const DisambiguateOptions &>;
 
 template <class Arc>
 void Disambiguate(DisambiguateArgs *args) {
index 7c039f9..a463bc7 100644 (file)
@@ -91,12 +91,12 @@ class FstDrawer {
   }
 
  private:
-  void SetStreamState(std::ostreamstrm) const {
+  void SetStreamState(std::ostream *strm) const {
     strm->precision(precision_);
     if (float_format_ == "e")
-        strm->setf(std::ios_base::scientific, std::ios_base::floatfield);
+      strm->setf(std::ios_base::scientific, std::ios_base::floatfield);
     if (float_format_ == "f")
-        strm->setf(std::ios_base::fixed, std::ios_base::floatfield);
+      strm->setf(std::ios_base::fixed, std::ios_base::floatfield);
     // O.w. defaults to "g" per standard lib.
   }
 
@@ -145,7 +145,9 @@ class FstDrawer {
   }
 
   template <class T>
-  void Print(T t) const { *ostrm_ << t; }
+  void Print(T t) const {
+    *ostrm_ << t;
+  }
 
   template <class T>
   std::string ToString(T t) const {
index 66f111a..19686cf 100644 (file)
@@ -65,9 +65,10 @@ template <class Arc>
 void Draw(DrawArgs *args) {
   const Fst<Arc> &fst = *args->fst.GetFst<Arc>();
   FstDrawer<Arc> fstdrawer(fst, args->isyms, args->osyms, args->ssyms,
-      args->accep, args->title, args->width, args->height, args->portrait,
-      args->vertical, args->ranksep, args->nodesep, args->fontsize,
-      args->precision, args->float_format, args->show_weight_one);
+                           args->accep, args->title, args->width, args->height,
+                           args->portrait, args->vertical, args->ranksep,
+                           args->nodesep, args->fontsize, args->precision,
+                           args->float_format, args->show_weight_one);
   fstdrawer.Draw(args->ostrm, args->dest);
 }
 
index 86bc4d9..6648de2 100644 (file)
@@ -12,8 +12,8 @@
 namespace fst {
 namespace script {
 
-using EpsNormalizeArgs = std::tuple<const FstClass &, MutableFstClass *,
-                                    EpsNormalizeType>;
+using EpsNormalizeArgs =
+    std::tuple<const FstClass &, MutableFstClass *, EpsNormalizeType>;
 
 template <class Arc>
 void EpsNormalize(EpsNormalizeArgs *args) {
index f3d4f88..d88fb04 100644 (file)
@@ -13,8 +13,8 @@
 namespace fst {
 namespace script {
 
-using EquivalentInnerArgs = std::tuple<const FstClass &, const FstClass &,
-                                       float>;
+using EquivalentInnerArgs =
+    std::tuple<const FstClass &, const FstClass &, float>;
 
 using EquivalentArgs = WithReturnValue<bool, EquivalentInnerArgs>;
 
index 294d015..b5f5141 100644 (file)
@@ -27,6 +27,6 @@ class StateIteratorClass;
 class WeightClass;
 
 }  // namespace script
-}  // namespace fst;
+}  // namespace fst
 
 #endif  // FST_SCRIPT_FSTSCRIPT_DECL_H_
index 052c7fd..d2ad515 100644 (file)
@@ -104,8 +104,7 @@ class AllFstOperationsRegisterer {
     REGISTER_FST_OPERATION(EpsNormalize, Arc, EpsNormalizeArgs);
     REGISTER_FST_OPERATION(Equal, Arc, EqualArgs);
     REGISTER_FST_OPERATION(Equivalent, Arc, EquivalentArgs);
-    REGISTER_FST_OPERATION(InitArcIteratorClass, Arc,
-                           InitArcIteratorClassArgs);
+    REGISTER_FST_OPERATION(InitArcIteratorClass, Arc, InitArcIteratorClassArgs);
     REGISTER_FST_OPERATION(InitMutableArcIteratorClass, Arc,
                            InitMutableArcIteratorClassArgs);
     REGISTER_FST_OPERATION(InitStateIteratorClass, Arc,
@@ -135,6 +134,7 @@ class AllFstOperationsRegisterer {
     REGISTER_FST_OPERATION(RmEpsilon, Arc, RmEpsilonArgs);
     REGISTER_FST_OPERATION(ShortestDistance, Arc, ShortestDistanceArgs1);
     REGISTER_FST_OPERATION(ShortestDistance, Arc, ShortestDistanceArgs2);
+    REGISTER_FST_OPERATION(ShortestDistance, Arc, ShortestDistanceArgs3);
     REGISTER_FST_OPERATION(ShortestPath, Arc, ShortestPathArgs);
     REGISTER_FST_OPERATION(Synchronize, Arc, SynchronizeArgs);
     REGISTER_FST_OPERATION(TopSort, Arc, TopSortArgs);
index 0b35d08..dcee33e 100644 (file)
@@ -19,6 +19,7 @@
 #include <fst/push.h>            // For kPushWeights (etc.).
 #include <fst/queue.h>           // For QueueType.
 #include <fst/rational.h>        // For ClosureType.
+#include <fst/string.h>          // For TokenType.
 #include <fst/script/arcsort.h>      // For ArcSortType.
 #include <fst/script/map.h>          // For MapType.
 #include <fst/script/script-impl.h>  // For RandArcSelection.
@@ -47,14 +48,11 @@ inline EpsNormalizeType GetEpsNormalizeType(bool eps_norm_output) {
 
 bool GetMapType(const std::string &str, MapType *map_type);
 
-inline ProjectType GetProjectType(bool project_output) {
-  return project_output ? PROJECT_OUTPUT : PROJECT_INPUT;
-}
+bool GetProjectType(const std::string &str, ProjectType *project_type);
 
 inline uint8 GetPushFlags(bool push_weights, bool push_labels,
                           bool remove_total_weight, bool remove_common_affix) {
-  return ((push_weights ? kPushWeights : 0) |
-          (push_labels ? kPushLabels : 0) |
+  return ((push_weights ? kPushWeights : 0) | (push_labels ? kPushLabels : 0) |
           (remove_total_weight ? kPushRemoveTotalWeight : 0) |
           (remove_common_affix ? kPushRemoveCommonAffix : 0));
 }
@@ -70,6 +68,8 @@ inline ReweightType GetReweightType(bool to_final) {
   return to_final ? REWEIGHT_TO_FINAL : REWEIGHT_TO_INITIAL;
 }
 
+bool GetTokenType(const std::string &str, TokenType *token_type);
+
 }  // namespace script
 }  // namespace fst
 
index 7e82601..3dba049 100644 (file)
@@ -13,8 +13,8 @@
 namespace fst {
 namespace script {
 
-using IsomorphicInnerArgs = std::tuple<const FstClass &, const FstClass &,
-                                       float>;
+using IsomorphicInnerArgs =
+    std::tuple<const FstClass &, const FstClass &, float>;
 
 using IsomorphicArgs = WithReturnValue<bool, IsomorphicInnerArgs>;
 
index 15ea67c..9445a17 100644 (file)
 namespace fst {
 namespace script {
 
-using MinimizeArgs = std::tuple<MutableFstClass *, MutableFstClass *, float,
-                                bool>;
+using MinimizeArgs =
+    std::tuple<MutableFstClass *, MutableFstClass *, float, bool>;
 
 template <class Arc>
 void Minimize(MinimizeArgs *args) {
   MutableFst<Arc> *ofst1 = std::get<0>(*args)->GetMutableFst<Arc>();
-  MutableFst<Arc> *ofst2 = std::get<1>(*args) ?
-                            std::get<1>(*args)->GetMutableFst<Arc>() :
-                            nullptr;
+  MutableFst<Arc> *ofst2 =
+      std::get<1>(*args) ? std::get<1>(*args)->GetMutableFst<Arc>() : nullptr;
   Minimize(ofst1, ofst2, std::get<2>(*args), std::get<3>(*args));
 }
 
index 59cb7d7..90594eb 100644 (file)
@@ -27,9 +27,8 @@ class FstPrinter {
   using Weight = typename Arc::Weight;
 
   explicit FstPrinter(const Fst<Arc> &fst, const SymbolTable *isyms,
-                      const SymbolTable *osyms,
-                      const SymbolTable *ssyms, bool accept,
-                      bool show_weight_one,
+                      const SymbolTable *osyms, const SymbolTable *ssyms,
+                      bool accept, bool show_weight_one,
                       const std::string &field_separator,
                       const std::string &missing_symbol = "")
       : fst_(fst),
index e812fc6..a9587d8 100644 (file)
@@ -26,8 +26,8 @@ void Prune(PruneArgs1 *args) {
   Prune(ifst, ofst, weight_threshold, std::get<3>(*args), std::get<4>(*args));
 }
 
-using PruneArgs2 = std::tuple<MutableFstClass *, const WeightClass &, int64,
-                               float>;
+using PruneArgs2 =
+    std::tuple<MutableFstClass *, const WeightClass &, int64, float>;
 
 template <class Arc>
 void Prune(PruneArgs2 *args) {
@@ -39,8 +39,7 @@ void Prune(PruneArgs2 *args) {
 
 void Prune(const FstClass &ifst, MutableFstClass *ofst,
            const WeightClass &weight_threshold,
-           int64 state_threshold = kNoStateId,
-           float delta = kDelta);
+           int64 state_threshold = kNoStateId, float delta = kDelta);
 
 void Prune(MutableFstClass *fst, const WeightClass &weight_threshold,
            int64 state_threshold = kNoStateId, float delta = kDelta);
index 63a91a7..3138b28 100644 (file)
@@ -21,8 +21,8 @@ void Push(PushArgs1 *args) {
   Push(fst, std::get<1>(*args), std::get<2>(*args), std::get<3>(*args));
 }
 
-using PushArgs2 = std::tuple<const FstClass &, MutableFstClass *, uint8,
-                             ReweightType, float>;
+using PushArgs2 =
+    std::tuple<const FstClass &, MutableFstClass *, uint8, ReweightType, float>;
 
 template <class Arc>
 void Push(PushArgs2 *args) {
@@ -42,7 +42,7 @@ void Push(PushArgs2 *args) {
   }
 }
 
-void Push(MutableFstClass *fst, ReweightType rew_type,
+void Push(MutableFstClass *fst, ReweightType type = REWEIGHT_TO_INITIAL,
           float delta = kShortestDelta, bool remove_total_weight = false);
 
 void Push(const FstClass &ifst, MutableFstClass *ofst, uint8 flags,
index b30611e..1276abf 100644 (file)
@@ -21,8 +21,8 @@ struct ReplaceOptions {
   const ReplaceLabelType return_label_type;  // How to label return arc.
   const int64 return_label;                  // Specifies return arc label.
 
-  explicit ReplaceOptions(int64 root,
-      ReplaceLabelType call_label_type = REPLACE_LABEL_INPUT,
+  explicit ReplaceOptions(
+      int64 root, ReplaceLabelType call_label_type = REPLACE_LABEL_INPUT,
       ReplaceLabelType return_label_type = REPLACE_LABEL_NEITHER,
       int64 return_label = 0)
       : root(root),
@@ -57,7 +57,7 @@ void Replace(ReplaceArgs *args) {
     ofst->SetProperties(kError, kError);
     return;
   }
-  typed_opts.gc = true;     // Caching options to speed up batch copy.
+  typed_opts.gc = true;  // Caching options to speed up batch copy.
   typed_opts.gc_limit = 0;
   *ofst = rfst;
 }
index 4374360..dfd9f6d 100644 (file)
@@ -160,8 +160,8 @@ struct Operation {
 template <class OpReg>
 void Apply(const std::string &op_name, const std::string &arc_type,
            typename OpReg::ArgPack *args) {
-  const auto op = OpReg::Register::GetRegister()->GetOperation(op_name,
-                                                               arc_type);
+  const auto op =
+      OpReg::Register::GetRegister()->GetOperation(op_name, arc_type);
   if (!op) {
     FSTERROR() << op_name << ": No operation found on arc type " << arc_type;
     return;
index 05f6db1..da2f45f 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <fst/queue.h>
 #include <fst/shortest-distance.h>
+#include <fst/script/arg-packs.h>
 #include <fst/script/fst-class.h>
 #include <fst/script/prune.h>
 #include <fst/script/script-impl.h>
@@ -201,6 +202,17 @@ void ShortestDistance(ShortestDistanceArgs2 *args) {
   internal::CopyWeights(typed_distance, std::get<1>(*args));
 }
 
+using ShortestDistanceInnerArgs3 = std::tuple<const FstClass &, double>;
+
+using ShortestDistanceArgs3 =
+    WithReturnValue<WeightClass, ShortestDistanceInnerArgs3>;
+
+template <class Arc>
+void ShortestDistance(ShortestDistanceArgs3 *args) {
+  const Fst<Arc> &fst = *std::get<0>(args->args).GetFst<Arc>();
+  args->retval = WeightClass(ShortestDistance(fst, std::get<1>(args->args)));
+}
+
 void ShortestDistance(const FstClass &fst, std::vector<WeightClass> *distance,
                       const ShortestDistanceOptions &opts);
 
@@ -208,6 +220,9 @@ void ShortestDistance(const FstClass &ifst, std::vector<WeightClass> *distance,
                       bool reverse = false,
                       double delta = fst::kShortestDelta);
 
+WeightClass ShortestDistance(const FstClass &ifst,
+                             double delta = fst::kShortestDelta);
+
 }  // namespace script
 }  // namespace fst
 
index 531fa23..002052c 100644 (file)
@@ -73,9 +73,8 @@ void ShortestPath(const Fst<Arc> &ifst, MutableFst<Arc> *ofst,
       return;
     }
     case SHORTEST_FIRST_QUEUE: {
-      ShortestPath<Arc, NaturalShortestFirstQueue<StateId, Weight>>(ifst, ofst,
-                                                                    &distance,
-                                                                    opts);
+      ShortestPath<Arc, NaturalShortestFirstQueue<StateId, Weight>>(
+          ifst, ofst, &distance, opts);
       return;
     }
     case STATE_ORDER_QUEUE: {
@@ -87,8 +86,7 @@ void ShortestPath(const Fst<Arc> &ifst, MutableFst<Arc> *ofst,
       return;
     }
     default: {
-      FSTERROR() << "ShortestPath: Unknown queue type: "
-                 << opts.queue_type;
+      FSTERROR() << "ShortestPath: Unknown queue type: " << opts.queue_type;
       ofst->SetProperties(kError, kError);
       return;
     }
index 8ca2ace..8ecdcfe 100644 (file)
@@ -84,7 +84,7 @@ class WeightClassImpl : public WeightImplBase {
   }
 
   WeightClassImpl<W> &PowerEq(size_t n) final {
-    weight_ = Power<W>(weight_, n);
+    weight_ = Power(weight_, n);
     return *this;
   }
 
@@ -94,7 +94,6 @@ class WeightClassImpl : public WeightImplBase {
   W weight_;
 };
 
-
 class WeightClass {
  public:
   WeightClass() = default;
@@ -117,8 +116,8 @@ class WeightClass {
     return *this;
   }
 
-  static constexpr char __ZERO__[] = "__ZERO__";  // NOLINT
-  static constexpr char __ONE__[] = "__ONE__";    // NOLINT
+  static constexpr char __ZERO__[] = "__ZERO__";          // NOLINT
+  static constexpr char __ONE__[] = "__ONE__";            // NOLINT
   static constexpr char __NOWEIGHT__[] = "__NOWEIGHT__";  // NOLINT
 
   static WeightClass Zero(const std::string &weight_type);
@@ -130,7 +129,7 @@ class WeightClass {
   template <class W>
   const W *GetWeight() const {
     if (W::Type() != impl_->Type()) {
-       return nullptr;
+      return nullptr;
     } else {
       auto *typed_impl = static_cast<WeightClassImpl<W> *>(impl_.get());
       return typed_impl->GetImpl();
index cdba0d0..dcf958a 100644 (file)
@@ -9,8 +9,8 @@
 #define FST_SET_WEIGHT_H_
 
 #include <algorithm>
-#include <cstdlib>
 #include <list>
+#include <random>
 #include <string>
 #include <vector>
 
@@ -35,19 +35,21 @@ constexpr char kSetSeparator = '_';  // Label separator in sets.
 // treats all non-Zero() elements as equivalent (with Zero() ==
 // UnivSet()), useful for algorithms that don't really depend on the
 // detailed sets.
-enum SetType { SET_INTERSECT_UNION = 0,
-               SET_UNION_INTERSECT = 1,
-               SET_INTERSECT_UNION_RESTRICT = 2,
-               SET_BOOLEAN = 3 };
+enum SetType {
+  SET_INTERSECT_UNION = 0,
+  SET_UNION_INTERSECT = 1,
+  SET_INTERSECT_UNION_RESTRICT = 2,
+  SET_BOOLEAN = 3
+};
 
 template <class>
 class SetWeightIterator;
 
 // Set semiring of integral labels.
-template <typename Label_, SetType S = SET_INTERSECT_UNION>
+template <typename L, SetType S = SET_INTERSECT_UNION>
 class SetWeight {
  public:
-  using Label = Label_;
+  using Label = L;
   using ReverseWeight = SetWeight<Label, S>;
   using Iterator = SetWeightIterator<SetWeight>;
   friend class SetWeightIterator<SetWeight>;
@@ -69,11 +71,13 @@ class SetWeight {
 
   template <SetType S2>
   explicit SetWeight(const SetWeight<Label, S2> &w)
-    : first_(w.first_), rest_(w.rest_) {}
+      : first_(w.first_), rest_(w.rest_) {}
 
   template <SetType S2>
   explicit SetWeight(SetWeight<Label, S2> &&w)
-    : first_(w.first_), rest_(std::move(w.rest_)) { w.Clear(); }
+      : first_(w.first_), rest_(std::move(w.rest_)) {
+    w.Clear();
+  }
 
   template <SetType S2>
   SetWeight &operator=(const SetWeight<Label, S2> &w) {
@@ -223,7 +227,6 @@ class SetWeightIterator {
   typename decltype(Weight::rest_)::const_iterator iter_;
 };
 
-
 // SetWeight member functions follow that require SetWeightIterator
 
 template <typename Label, SetType S>
@@ -313,8 +316,7 @@ inline bool operator!=(const SetWeight<Label, S> &w1,
 
 template <typename Label, SetType S>
 inline bool ApproxEqual(const SetWeight<Label, S> &w1,
-                        const SetWeight<Label, S> &w2,
-                        float delta = kDelta) {
+                        const SetWeight<Label, S> &w2, float delta = kDelta) {
   return w1 == w2;
 }
 
@@ -363,9 +365,8 @@ inline std::istream &operator>>(std::istream &strm,
 }
 
 template <typename Label, SetType S>
-inline SetWeight<Label, S> Union(
-    const SetWeight<Label, S> &w1,
-    const SetWeight<Label, S> &w2) {
+inline SetWeight<Label, S> Union(const SetWeight<Label, S> &w1,
+                                 const SetWeight<Label, S> &w2) {
   using Weight = SetWeight<Label, S>;
   using Iterator = typename SetWeight<Label, S>::Iterator;
   if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
@@ -397,9 +398,8 @@ inline SetWeight<Label, S> Union(
 }
 
 template <typename Label, SetType S>
-inline SetWeight<Label, S> Intersect(
-    const SetWeight<Label, S> &w1,
-    const SetWeight<Label, S> &w2) {
+inline SetWeight<Label, S> Intersect(const SetWeight<Label, S> &w1,
+                                     const SetWeight<Label, S> &w2) {
   using Weight = SetWeight<Label, S>;
   using Iterator = typename SetWeight<Label, S>::Iterator;
   if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
@@ -427,9 +427,8 @@ inline SetWeight<Label, S> Intersect(
 }
 
 template <typename Label, SetType S>
-inline SetWeight<Label, S> Difference(
-    const SetWeight<Label, S> &w1,
-    const SetWeight<Label, S> &w2) {
+inline SetWeight<Label, S> Difference(const SetWeight<Label, S> &w1,
+                                      const SetWeight<Label, S> &w2) {
   using Weight = SetWeight<Label, S>;
   using Iterator = typename SetWeight<Label, S>::Iterator;
   if (!w1.Member() || !w2.Member()) return Weight::NoWeight();
@@ -458,9 +457,8 @@ inline SetWeight<Label, S> Difference(
 
 // Default: Plus = Intersect.
 template <typename Label, SetType S>
-inline SetWeight<Label, S> Plus(
-    const SetWeight<Label, S> &w1,
-    const SetWeight<Label, S> &w2) {
+inline SetWeight<Label, S> Plus(const SetWeight<Label, S> &w1,
+                                const SetWeight<Label, S> &w2) {
   return Intersect(w1, w2);
 }
 
@@ -506,9 +504,8 @@ inline SetWeight<Label, SET_BOOLEAN> Plus(
 
 // Default: Times = Union.
 template <typename Label, SetType S>
-inline SetWeight<Label, S> Times(
-    const SetWeight<Label, S> &w1,
-    const SetWeight<Label, S> &w2) {
+inline SetWeight<Label, S> Times(const SetWeight<Label, S> &w1,
+                                 const SetWeight<Label, S> &w2) {
   return Union(w1, w2);
 }
 
@@ -585,7 +582,8 @@ class WeightGenerate<SetWeight<Label, S>> {
  public:
   using Weight = SetWeight<Label, S>;
 
-  explicit WeightGenerate(bool allow_zero = true,
+  explicit WeightGenerate(uint64 seed = std::random_device()(),
+                          bool allow_zero = true,
                           size_t alphabet_size = kNumRandomWeights,
                           size_t max_set_length = kNumRandomWeights)
       : allow_zero_(allow_zero),
@@ -593,11 +591,14 @@ class WeightGenerate<SetWeight<Label, S>> {
         max_set_length_(max_set_length) {}
 
   Weight operator()() const {
-    const size_t n = rand() % (max_set_length_ + allow_zero_);  // NOLINT
+    const int n = std::uniform_int_distribution<>(
+        0, max_set_length_ + allow_zero_ - 1)(rand_);
     if (allow_zero_ && n == max_set_length_) return Weight::Zero();
     std::vector<Label> labels;
-    for (size_t i = 0; i < n; ++i) {
-      labels.push_back(rand() % alphabet_size_ + 1);  // NOLINT
+    labels.reserve(n);
+    for (int i = 0; i < n; ++i) {
+      labels.push_back(
+          std::uniform_int_distribution<>(0, alphabet_size_)(rand_));
     }
     std::sort(labels.begin(), labels.end());
     const auto labels_end = std::unique(labels.begin(), labels.end());
@@ -606,11 +607,9 @@ class WeightGenerate<SetWeight<Label, S>> {
   }
 
  private:
-  // Permits Zero() and zero divisors.
+  mutable std::mt19937_64 rand_;
   const bool allow_zero_;
-  // Alphabet size for random weights.
   const size_t alphabet_size_;
-  // Number of alternative random weights.
   const size_t max_set_length_;
 };
 
index 0037402..fa7b594 100644 (file)
@@ -44,8 +44,7 @@ struct ShortestDistanceOptions {
 
   ShortestDistanceOptions(Queue *state_queue, ArcFilter arc_filter,
                           StateId source = kNoStateId,
-                          float delta = kShortestDelta,
-                          bool first_path = false)
+                          float delta = kShortestDelta, bool first_path = false)
       : state_queue(state_queue),
         arc_filter(arc_filter),
         source(source),
@@ -117,7 +116,7 @@ class ShortestDistanceState {
   std::vector<Weight> *distance_;
   Queue *state_queue_;
   ArcFilter arc_filter_;
-  WeightEqual weight_equal_;           // Determines when relaxation stops.
+  WeightEqual weight_equal_;  // Determines when relaxation stops.
   const bool first_path_;
   const bool retain_;  // Retain and reuse information across calls.
 
@@ -133,8 +132,8 @@ class ShortestDistanceState {
 // Compute the shortest distance; if source is kNoStateId, uses the initial
 // state of the FST.
 template <class Arc, class Queue, class ArcFilter, class WeightEqual>
-    void ShortestDistanceState<Arc, Queue, ArcFilter,
-                               WeightEqual>::ShortestDistance(StateId source) {
+void ShortestDistanceState<Arc, Queue, ArcFilter,
+                           WeightEqual>::ShortestDistance(StateId source) {
   if (fst_.Start() == kNoStateId) {
     if (fst_.Properties(kError, false)) error_ = true;
     return;
index 6a7e449..a7ebd4c 100644 (file)
@@ -150,7 +150,7 @@ class FirstPathSelect<S, W, NaturalAStarQueue<S, W, Estimate>> {
   using Queue = NaturalAStarQueue<S, W, Estimate>;
 
   FirstPathSelect(const Queue &state_queue)
-    : estimate_(state_queue.GetCompare().GetEstimate()) {}
+      : estimate_(state_queue.GetCompare().GetEstimate()) {}
 
   bool operator()(S s, W d, W f) const {
     return f == Plus(Times(d, estimate_(s)), f);
index debf8bf..ed0f585 100644 (file)
@@ -11,7 +11,7 @@
 #ifndef FST_SIGNED_LOG_WEIGHT_H_
 #define FST_SIGNED_LOG_WEIGHT_H_
 
-#include <cstdlib>
+#include <random>
 
 #include <fst/types.h>
 
@@ -24,52 +24,52 @@ namespace fst {
 template <class T>
 class SignedLogWeightTpl : public PairWeight<TropicalWeight, LogWeightTpl<T>> {
  public:
-  using X1 = TropicalWeight;
-  using X2 = LogWeightTpl<T>;
+  using W1 = TropicalWeight;
+  using W2 = LogWeightTpl<T>;
   using ReverseWeight = SignedLogWeightTpl;
 
-  using PairWeight<X1, X2>::Value1;
-  using PairWeight<X1, X2>::Value2;
+  using PairWeight<W1, W2>::Value1;
+  using PairWeight<W1, W2>::Value2;
 
-  SignedLogWeightTpl() noexcept : PairWeight<X1, X2>() {}
+  SignedLogWeightTpl() noexcept : PairWeight<W1, W2>() {}
 
-  explicit SignedLogWeightTpl(const PairWeight<X1, X2> &w)
-      : PairWeight<X1, X2>(w) {}
+  explicit SignedLogWeightTpl(const PairWeight<W1, W2> &weight)
+      : PairWeight<W1, W2>(weight) {}
 
-  SignedLogWeightTpl(const X1 &x1, const X2 &x2) : PairWeight<X1, X2>(x1, x2) {}
+  SignedLogWeightTpl(const W1 &w1, const W2 &w2) : PairWeight<W1, W2>(w1, w2) {}
 
   static const SignedLogWeightTpl &Zero() {
-    static const SignedLogWeightTpl zero(X1(1.0), X2::Zero());
+    static const SignedLogWeightTpl zero(W1(1.0), W2::Zero());
     return zero;
   }
 
   static const SignedLogWeightTpl &One() {
-    static const SignedLogWeightTpl one(X1(1.0), X2::One());
+    static const SignedLogWeightTpl one(W1(1.0), W2::One());
     return one;
   }
 
   static const SignedLogWeightTpl &NoWeight() {
-    static const SignedLogWeightTpl no_weight(X1(1.0), X2::NoWeight());
+    static const SignedLogWeightTpl no_weight(W1(1.0), W2::NoWeight());
     return no_weight;
   }
 
   static const std::string &Type() {
     static const std::string *const type =
-        new std::string("signed_log_" + X1::Type() + "_" + X2::Type());
+        new std::string("signed_log_" + W1::Type() + "_" + W2::Type());
     return *type;
   }
 
   bool IsPositive() const { return Value1().Value() > 0; }
 
   SignedLogWeightTpl Quantize(float delta = kDelta) const {
-    return SignedLogWeightTpl(PairWeight<X1, X2>::Quantize(delta));
+    return SignedLogWeightTpl(PairWeight<W1, W2>::Quantize(delta));
   }
 
   ReverseWeight Reverse() const {
-    return SignedLogWeightTpl(PairWeight<X1, X2>::Reverse());
+    return SignedLogWeightTpl(PairWeight<W1, W2>::Reverse());
   }
 
-  bool Member() const { return PairWeight<X1, X2>::Member(); }
+  bool Member() const { return PairWeight<W1, W2>::Member(); }
 
   // Neither idempotent nor path.
   static constexpr uint64 Properties() {
@@ -78,7 +78,7 @@ class SignedLogWeightTpl : public PairWeight<TropicalWeight, LogWeightTpl<T>> {
 
   size_t Hash() const {
     size_t h1;
-    if (Value2() == X2::Zero() || IsPositive()) {
+    if (Value2() == W2::Zero() || IsPositive()) {
       h1 = TropicalWeight(1.0).Hash();
     } else {
       h1 = TropicalWeight(-1.0).Hash();
@@ -93,8 +93,8 @@ class SignedLogWeightTpl : public PairWeight<TropicalWeight, LogWeightTpl<T>> {
 template <class T>
 inline SignedLogWeightTpl<T> Plus(const SignedLogWeightTpl<T> &w1,
                                   const SignedLogWeightTpl<T> &w2) {
-  using X1 = TropicalWeight;
-  using X2 = LogWeightTpl<T>;
+  using W1 = TropicalWeight;
+  using W2 = LogWeightTpl<T>;
   if (!w1.Member() || !w2.Member()) return SignedLogWeightTpl<T>::NoWeight();
   const auto s1 = w1.IsPositive();
   const auto s2 = w2.IsPositive();
@@ -107,25 +107,25 @@ inline SignedLogWeightTpl<T> Plus(const SignedLogWeightTpl<T> &w1,
     return w1;
   } else if (f1 == f2) {
     if (equal) {
-      return SignedLogWeightTpl<T>(X1(w1.Value1()), X2(f2 - M_LN2));
+      return SignedLogWeightTpl<T>(W1(w1.Value1()), W2(f2 - M_LN2));
     } else {
       return SignedLogWeightTpl<T>::Zero();
     }
   } else if (f1 > f2) {
     if (equal) {
-      return SignedLogWeightTpl<T>(X1(w1.Value1()),
-                                   X2(f2 - internal::LogPosExp(f1 - f2)));
+      return SignedLogWeightTpl<T>(W1(w1.Value1()),
+                                   W2(f2 - internal::LogPosExp(f1 - f2)));
     } else {
-      return SignedLogWeightTpl<T>(X1(w2.Value1()),
-                                   X2((f2 - internal::LogNegExp(f1 - f2))));
+      return SignedLogWeightTpl<T>(W1(w2.Value1()),
+                                   W2((f2 - internal::LogNegExp(f1 - f2))));
     }
   } else {
     if (equal) {
-      return SignedLogWeightTpl<T>(X1(w2.Value1()),
-                                   X2((f1 - internal::LogPosExp(f2 - f1))));
+      return SignedLogWeightTpl<T>(W1(w2.Value1()),
+                                   W2((f1 - internal::LogPosExp(f2 - f1))));
     } else {
-      return SignedLogWeightTpl<T>(X1(w1.Value1()),
-                                   X2((f1 - internal::LogNegExp(f2 - f1))));
+      return SignedLogWeightTpl<T>(W1(w1.Value1()),
+                                   W2((f1 - internal::LogNegExp(f2 - f1))));
     }
   }
 }
@@ -140,16 +140,16 @@ inline SignedLogWeightTpl<T> Minus(const SignedLogWeightTpl<T> &w1,
 template <class T>
 inline SignedLogWeightTpl<T> Times(const SignedLogWeightTpl<T> &w1,
                                    const SignedLogWeightTpl<T> &w2) {
-  using X2 = LogWeightTpl<T>;
+  using W2 = LogWeightTpl<T>;
   if (!w1.Member() || !w2.Member()) return SignedLogWeightTpl<T>::NoWeight();
   const auto s1 = w1.IsPositive();
   const auto s2 = w2.IsPositive();
   const auto f1 = w1.Value2().Value();
   const auto f2 = w2.Value2().Value();
   if (s1 == s2) {
-    return SignedLogWeightTpl<T>(TropicalWeight(1.0), X2(f1 + f2));
+    return SignedLogWeightTpl<T>(TropicalWeight(1.0), W2(f1 + f2));
   } else {
-    return SignedLogWeightTpl<T>(TropicalWeight(-1.0), X2(f1 + f2));
+    return SignedLogWeightTpl<T>(TropicalWeight(-1.0), W2(f1 + f2));
   }
 }
 
@@ -157,7 +157,7 @@ template <class T>
 inline SignedLogWeightTpl<T> Divide(const SignedLogWeightTpl<T> &w1,
                                     const SignedLogWeightTpl<T> &w2,
                                     DivideType typ = DIVIDE_ANY) {
-  using X2 = LogWeightTpl<T>;
+  using W2 = LogWeightTpl<T>;
   if (!w1.Member() || !w2.Member()) return SignedLogWeightTpl<T>::NoWeight();
   const auto s1 = w1.IsPositive();
   const auto s2 = w2.IsPositive();
@@ -165,38 +165,37 @@ inline SignedLogWeightTpl<T> Divide(const SignedLogWeightTpl<T> &w1,
   const auto f2 = w2.Value2().Value();
   if (f2 == FloatLimits<T>::PosInfinity()) {
     return SignedLogWeightTpl<T>(TropicalWeight(1.0),
-                                 X2(FloatLimits<T>::NumberBad()));
+                                 W2(FloatLimits<T>::NumberBad()));
   } else if (f1 == FloatLimits<T>::PosInfinity()) {
     return SignedLogWeightTpl<T>(TropicalWeight(1.0),
-                                 X2(FloatLimits<T>::PosInfinity()));
+                                 W2(FloatLimits<T>::PosInfinity()));
   } else if (s1 == s2) {
-    return SignedLogWeightTpl<T>(TropicalWeight(1.0), X2(f1 - f2));
+    return SignedLogWeightTpl<T>(TropicalWeight(1.0), W2(f1 - f2));
   } else {
-    return SignedLogWeightTpl<T>(TropicalWeight(-1.0), X2(f1 - f2));
+    return SignedLogWeightTpl<T>(TropicalWeight(-1.0), W2(f1 - f2));
   }
 }
 
 template <class T>
 inline bool ApproxEqual(const SignedLogWeightTpl<T> &w1,
                         const SignedLogWeightTpl<T> &w2, float delta = kDelta) {
-  using X2 = LogWeightTpl<T>;
+  using W2 = LogWeightTpl<T>;
   if (w1.IsPositive() == w2.IsPositive()) {
     return ApproxEqual(w1.Value2(), w2.Value2(), delta);
   } else {
-    return ApproxEqual(w1.Value2(), X2::Zero(), delta)
-        && ApproxEqual(w2.Value2(), X2::Zero(), delta);
+    return ApproxEqual(w1.Value2(), W2::Zero(), delta) &&
+           ApproxEqual(w2.Value2(), W2::Zero(), delta);
   }
 }
 
 template <class T>
 inline bool operator==(const SignedLogWeightTpl<T> &w1,
                        const SignedLogWeightTpl<T> &w2) {
-  using X2 = LogWeightTpl<T>;
+  using W2 = LogWeightTpl<T>;
   if (w1.IsPositive() == w2.IsPositive()) {
     return w1.Value2() == w2.Value2();
   } else {
-    return w1.Value2() == X2::Zero()
-        && w2.Value2() == X2::Zero();
+    return w1.Value2() == W2::Zero() && w2.Value2() == W2::Zero();
   }
 }
 
@@ -215,8 +214,8 @@ using SignedLog64Weight = SignedLogWeightTpl<double>;
 template <class W1, class W2>
 bool SignedLogConvertCheck(W1 weight) {
   if (weight.Value1().Value() < 0.0) {
-    FSTERROR() << "WeightConvert: Can't convert weight " << weight
-               << " from " << W1::Type() << " to " << W2::Type();
+    FSTERROR() << "WeightConvert: Can't convert weight " << weight << " from "
+               << W1::Type() << " to " << W2::Type();
     return false;
   }
   return true;
@@ -227,13 +226,11 @@ template <class T>
 class Adder<SignedLogWeightTpl<T>> {
  public:
   using Weight = SignedLogWeightTpl<T>;
-  using X1 = TropicalWeight;
-  using X2 = LogWeightTpl<T>;
+  using W1 = TropicalWeight;
+  using W2 = LogWeightTpl<T>;
 
   explicit Adder(Weight w = Weight::Zero())
-      : ssum_(w.IsPositive()),
-        sum_(w.Value2().Value()),
-        c_(0.0) { }
+      : ssum_(w.IsPositive()), sum_(w.Value2().Value()), c_(0.0) {}
 
   Weight Add(const Weight &w) {
     const auto sw = w.IsPositive();
@@ -271,7 +268,7 @@ class Adder<SignedLogWeightTpl<T>> {
     return Sum();
   }
 
-  Weight Sum() const { return Weight(X1(ssum_ ? 1.0 : -1.0), X2(sum_)); }
+  Weight Sum() const { return Weight(W1(ssum_ ? 1.0 : -1.0), W2(sum_)); }
 
   void Reset(Weight w = Weight::Zero()) {
     ssum_ = w.IsPositive();
@@ -352,16 +349,14 @@ struct WeightConvert<SignedLog64Weight, Log64Weight> {
 template <>
 struct WeightConvert<SignedLogWeight, RealWeight> {
   RealWeight operator()(const SignedLogWeight &weight) const {
-    return RealWeight(weight.Value1().Value() *
-                      exp(-weight.Value2().Value()));
+    return RealWeight(weight.Value1().Value() * exp(-weight.Value2().Value()));
   }
 };
 
 template <>
 struct WeightConvert<SignedLog64Weight, RealWeight> {
   RealWeight operator()(const SignedLog64Weight &weight) const {
-    return RealWeight(weight.Value1().Value() *
-                      exp(-weight.Value2().Value()));
+    return RealWeight(weight.Value1().Value() * exp(-weight.Value2().Value()));
   }
 };
 
@@ -479,27 +474,31 @@ template <class T>
 class WeightGenerate<SignedLogWeightTpl<T>> {
  public:
   using Weight = SignedLogWeightTpl<T>;
-  using X1 = typename Weight::X1;
-  using X2 = typename Weight::X2;
+  using W1 = typename Weight::W1;
+  using W2 = typename Weight::W2;
 
-  explicit WeightGenerate(bool allow_zero = true,
+  explicit WeightGenerate(uint64 seed = std::random_device()(),
+                          bool allow_zero = true,
                           size_t num_random_weights = kNumRandomWeights)
-    : allow_zero_(allow_zero), num_random_weights_(num_random_weights) {}
+      : rand_(seed),
+        allow_zero_(allow_zero),
+        num_random_weights_(num_random_weights) {}
 
   Weight operator()() const {
-    static const X1 negative_one(-1.0);
-    static const X1 positive_one(+1.0);
-    const int m = rand() % 2;                                    // NOLINT
-    const int n = rand() % (num_random_weights_ + allow_zero_);  // NOLINT
-    return Weight((m == 0) ? negative_one : positive_one,
-                  (allow_zero_ && n == num_random_weights_) ?
-                   X2::Zero() : X2(n));
+    static constexpr W1 negative(-1.0);
+    static constexpr W1 positive(+1.0);
+    const bool sign = std::bernoulli_distribution(.5)(rand_);
+    const int sample = std::uniform_int_distribution<>(
+        0, num_random_weights_ + allow_zero_ - 1)(rand_);
+    if (allow_zero_ && sample == num_random_weights_) {
+      return Weight(sign ? positive : negative, W2::Zero());
+    }
+    return Weight(sign ? positive : negative, W2(sample));
   }
 
  private:
-  // Permits Zero() and zero divisors.
+  mutable std::mt19937_64 rand_;
   const bool allow_zero_;
-  // Number of alternative random weights.
   const size_t num_random_weights_;
 };
 
index d7e17ee..a70bd78 100644 (file)
@@ -7,7 +7,7 @@
 #ifndef FST_SPARSE_POWER_WEIGHT_H_
 #define FST_SPARSE_POWER_WEIGHT_H_
 
-#include <climits>
+#include <random>
 #include <string>
 
 #include <fst/types.h>
@@ -39,12 +39,10 @@ class SparsePowerWeight : public SparseTupleWeight<W, K> {
 
   SparsePowerWeight() {}
 
-  explicit SparsePowerWeight(const Base &weight)
-      : Base(weight) {}
+  explicit SparsePowerWeight(const Base &weight) : Base(weight) {}
 
   template <class Iterator>
-  SparsePowerWeight(Iterator begin, Iterator end)
-      : Base(begin, end) {}
+  SparsePowerWeight(Iterator begin, Iterator end) : Base(begin, end) {}
 
   // Initialize component `key` to `weight`, with `default_weight` for all
   // other components.
@@ -63,8 +61,7 @@ class SparsePowerWeight : public SparseTupleWeight<W, K> {
   }
 
   static const SparsePowerWeight &NoWeight() {
-    static const SparsePowerWeight no_weight(
-        Base::NoWeight());
+    static const SparsePowerWeight no_weight(Base::NoWeight());
     return no_weight;
   }
 
@@ -90,15 +87,12 @@ class SparsePowerWeight : public SparseTupleWeight<W, K> {
     return SparsePowerWeight(Base::Quantize(delta));
   }
 
-  ReverseWeight Reverse() const {
-    return ReverseWeight(Base::Reverse());
-  }
+  ReverseWeight Reverse() const { return ReverseWeight(Base::Reverse()); }
 };
 
 template <class W, class K, class M>
 inline SparsePowerWeight<W, K> SparsePowerWeightMap(
-    const SparsePowerWeight<W, K> &w1,
-    const SparsePowerWeight<W, K> &w2,
+    const SparsePowerWeight<W, K> &w1, const SparsePowerWeight<W, K> &w2,
     const M &operator_mapper) {
   SparsePowerWeight<W, K> result;
   SparseTupleWeightMap(&result, w1, w2, operator_mapper);
@@ -190,9 +184,9 @@ class WeightGenerate<SparsePowerWeight<W, K>> {
   using Weight = SparsePowerWeight<W, K>;
   using Generate = WeightGenerate<W>;
 
-  explicit WeightGenerate(bool allow_zero = true,
-                          size_t sparse_power_rank = 3)
-      : generate_(allow_zero), sparse_power_rank_(sparse_power_rank) {}
+  explicit WeightGenerate(uint64 seed = std::random_device()(),
+                          bool allow_zero = true, size_t sparse_power_rank = 3)
+      : generate_(seed, allow_zero), sparse_power_rank_(sparse_power_rank) {}
 
   Weight operator()() const {
     Weight weight;
index a00d1e1..e9dc20a 100644 (file)
@@ -261,8 +261,8 @@ class StateMapFstImpl : public CacheImpl<B> {
   void InitStateIterator(StateIteratorData<B> *datb) const {
     StateIteratorData<A> data;
     fst_->InitStateIterator(&data);
-    datb->base = data.base ? new StateMapStateIteratorBase<A, B>(data.base)
-        : nullptr;
+    datb->base =
+        data.base ? new StateMapStateIteratorBase<A, B>(data.base) : nullptr;
     datb->nstates = data.nstates;
   }
 
index 75b9a5e..29f5e40 100644 (file)
@@ -6,8 +6,8 @@
 #ifndef FST_STRING_WEIGHT_H_
 #define FST_STRING_WEIGHT_H_
 
-#include <cstdlib>
 #include <list>
+#include <random>
 #include <string>
 #include <vector>
 
@@ -42,10 +42,10 @@ template <class>
 class StringWeightReverseIterator;
 
 // String semiring: (longest_common_prefix/suffix, ., Infinity, Epsilon)
-template <typename Label_, StringType S = STRING_LEFT>
+template <typename L, StringType S = STRING_LEFT>
 class StringWeight {
  public:
-  using Label = Label_;
+  using Label = L;
   using ReverseWeight = StringWeight<Label, ReverseStringType(S)>;
   using Iterator = StringWeightIterator<StringWeight>;
   using ReverseIterator = StringWeightReverseIterator<StringWeight>;
@@ -496,30 +496,32 @@ class WeightGenerate<StringWeight<Label, S>> {
  public:
   using Weight = StringWeight<Label, S>;
 
-  explicit WeightGenerate(bool allow_zero = true,
+  explicit WeightGenerate(uint64 seed = std::random_device()(),
+                          bool allow_zero = true,
                           size_t alphabet_size = kNumRandomWeights,
                           size_t max_string_length = kNumRandomWeights)
-      : allow_zero_(allow_zero),
+      : rand_(seed),
+        allow_zero_(allow_zero),
         alphabet_size_(alphabet_size),
         max_string_length_(max_string_length) {}
 
   Weight operator()() const {
-    size_t n = rand() % (max_string_length_ + allow_zero_);  // NOLINT
+    const int n = std::uniform_int_distribution<>(
+        0, max_string_length_ + allow_zero_)(rand_);
     if (allow_zero_ && n == max_string_length_) return Weight::Zero();
     std::vector<Label> labels;
     labels.reserve(n);
-    for (size_t i = 0; i < n; ++i) {
-      labels.push_back(rand() % alphabet_size_ + 1);  // NOLINT
+    for (int i = 0; i < n; ++i) {
+      labels.push_back(
+          std::uniform_int_distribution<>(1, alphabet_size_)(rand_));
     }
     return Weight(labels.begin(), labels.end());
   }
 
  private:
-  // Permits Zero() and zero divisors.
+  mutable std::mt19937_64 rand_;
   const bool allow_zero_;
-  // Alphabet size for random weights.
   const size_t alphabet_size_;
-  // Number of alternative random weights.
   const size_t max_string_length_;
 };
 
@@ -651,7 +653,9 @@ class WeightGenerate<GallicWeight<Label, W, G>>
   using Generate = WeightGenerate<
       ProductWeight<StringWeight<Label, GallicStringType(G)>, W>>;
 
-  explicit WeightGenerate(bool allow_zero = true) : generate_(allow_zero) {}
+  explicit WeightGenerate(uint64 seed = std::random_device()(),
+                          bool allow_zero = true)
+      : generate_(seed, allow_zero) {}
 
   Weight operator()() const { return Weight(generate_()); }
 
@@ -795,7 +799,9 @@ class WeightGenerate<GallicWeight<Label, W, GALLIC>>
       WeightGenerate<UnionWeight<GallicWeight<Label, W, GALLIC_RESTRICT>,
                                  GallicUnionWeightOptions<Label, W>>>;
 
-  explicit WeightGenerate(bool allow_zero = true) : generate_(allow_zero) {}
+  explicit WeightGenerate(uint64 seed = std::random_device()(),
+                          bool allow_zero = true)
+      : generate_(seed, allow_zero) {}
 
   Weight operator()() const { return Weight(generate_()); }
 
index 0680fe1..c850daf 100644 (file)
 #include <fst/symbol-table.h>
 #include <fst/util.h>
 
-
 DECLARE_string(fst_field_separator);
 
 namespace fst {
 
-enum StringTokenType { SYMBOL = 1, BYTE = 2, UTF8 = 3 };
+enum class TokenType : uint8 { SYMBOL = 1, BYTE = 2, UTF8 = 3 };
 
-enum EpsilonSymbolPrintType { NONEPS_SYMBOLS = 1, SYMBOLS_INCL_EPS = 2 };
+OPENFST_DEPRECATED("Use `TokenType::SYMBOL` instead.")
+static constexpr TokenType SYMBOL = TokenType::SYMBOL;
+OPENFST_DEPRECATED("Use `TokenType::BYTE` instead.")
+static constexpr TokenType BYTE = TokenType::BYTE;
+OPENFST_DEPRECATED("Use `TokenType::UTF8` instead.")
+static constexpr TokenType UTF8 = TokenType::UTF8;
 
 namespace internal {
 
@@ -50,7 +54,7 @@ bool ConvertSymbolToLabel(const char *str, const SymbolTable *syms,
   } else {
     char *p;
     n = strtoll(str, &p, 10);
-    if (p < str + strlen(str) || (!allow_negative && n < 0)) {
+    if (*p != '\0' || (!allow_negative && n < 0)) {
       LOG(ERROR) << "ConvertSymbolToLabel: Bad label integer "
                  << "= \"" << str << "\"";
       return false;
@@ -61,23 +65,27 @@ bool ConvertSymbolToLabel(const char *str, const SymbolTable *syms,
 }
 
 template <class Label>
-bool ConvertStringToLabels(const std::string &str, StringTokenType token_type,
+bool ConvertStringToLabels(const std::string &str, TokenType token_type,
                            const SymbolTable *syms, Label unknown_label,
                            bool allow_negative, std::vector<Label> *labels,
                            const std::string &sep = FLAGS_fst_field_separator) {
   labels->clear();
-  if (token_type == StringTokenType::BYTE) {
+  if (token_type == TokenType::BYTE) {
     labels->reserve(str.size());
     return ByteStringToLabels(str, labels);
-  } else if (token_type == StringTokenType::UTF8) {
+  } else if (token_type == TokenType::UTF8) {
     return UTF8StringToLabels(str, labels);
   } else {
-    std::unique_ptr<char[]> c_str(new char[str.size() + 1]);
-    str.copy(c_str.get(), str.size());
-    c_str[str.size()] = 0;
+    // SplitString modifies its input, so make a copy.
+    // TODO(jrosenstock): Investigate minimal fst::string_view and/or
+    // SplitString returning vector<string_view> if available and
+    // vector<string> otherwise.
+    std::string str_copy = str;
     std::vector<char *> vec;
     const std::string separator = "\n" + sep;
-    SplitString(c_str.get(), separator.c_str(), &vec, true);
+    // This really wants to be data, but non-const data() requires C++17.
+    // str[str.size()] has been guaranteed to be '\0' since C++11,
+    SplitString(&str_copy[0], separator.c_str(), &vec, true);
     for (const char *c : vec) {
       Label label;
       if (!ConvertSymbolToLabel(c, syms, unknown_label, allow_negative,
@@ -91,21 +99,17 @@ bool ConvertStringToLabels(const std::string &str, StringTokenType token_type,
 }
 
 // The last character of 'sep' is used as a separator between symbols.
-// Additionally, epsilon symbols will be printed only if the epsilon symbol
-// print type is set to SYMBOLS_INCL_EPS, and will be ignored (default) if set
-// to NONEPS_SYMBOLS.
+// Additionally, epsilon symbols will be printed only if omit_epsilon
+// is false.
 template <class Label>
 bool LabelsToSymbolString(const std::vector<Label> &labels, std::string *str,
                           const SymbolTable &syms,
                           const std::string &sep = FLAGS_fst_field_separator,
-                          EpsilonSymbolPrintType eps_sym_print_type =
-                              EpsilonSymbolPrintType::NONEPS_SYMBOLS) {
+                          bool omit_epsilon = true) {
   std::stringstream ostrm;
   std::string delim = "";
   for (auto label : labels) {
-    // Don't include epsilon labels in output if in NONEPS_SYMBOLS mode.
-    if (!label && eps_sym_print_type == EpsilonSymbolPrintType::NONEPS_SYMBOLS)
-      continue;
+    if (omit_epsilon && !label) continue;
     ostrm << delim;
     const std::string &symbol = syms.Find(label);
     if (symbol.empty()) {
@@ -122,20 +126,16 @@ bool LabelsToSymbolString(const std::vector<Label> &labels, std::string *str,
 }
 
 // The last character of 'sep' is used as a separator between symbols.
-// Additionally, epsilon symbols will be printed only if the epsilon symbol
-// print type is set to SYMBOLS_INCL_EPS, and will be ignored (default) if set
-// to NONEPS_SYMBOLS.
+// Additionally, epsilon symbols will be printed only if omit_epsilon
+// is false.
 template <class Label>
 bool LabelsToNumericString(const std::vector<Label> &labels, std::string *str,
                            const std::string &sep = FLAGS_fst_field_separator,
-                           EpsilonSymbolPrintType eps_sym_print_type =
-                               EpsilonSymbolPrintType::NONEPS_SYMBOLS) {
+                           bool omit_epsilon = true) {
   std::stringstream ostrm;
   std::string delim = "";
   for (auto label : labels) {
-    // Don't include epsilon labels in output if in NONEPS_SYMBOLS mode.
-    if (!label && eps_sym_print_type == EpsilonSymbolPrintType::NONEPS_SYMBOLS)
-      continue;
+    if (omit_epsilon && !label) continue;
     ostrm << delim;
     ostrm << label;
     delim = std::string(1, sep.back());
@@ -154,7 +154,7 @@ class StringCompiler {
   using StateId = typename Arc::StateId;
   using Weight = typename Arc::Weight;
 
-  explicit StringCompiler(StringTokenType token_type = BYTE,
+  explicit StringCompiler(TokenType token_type = TokenType::BYTE,
                           const SymbolTable *syms = nullptr,
                           Label unknown_label = kNoLabel,
                           bool allow_negative = false)
@@ -233,7 +233,7 @@ class StringCompiler {
         std::make_shared<Compactor>(compacts.begin(), compacts.end()));
   }
 
-  const StringTokenType token_type_;
+  const TokenType token_type_;
   const SymbolTable *syms_;    // Symbol table (used when token type is symbol).
   const Label unknown_label_;  // Label for token missing from symbol table.
   const bool allow_negative_;  // Negative labels allowed?
@@ -285,28 +285,26 @@ bool StringFstToOutputLabels(const Fst<Arc> &fst,
 
 // Converts a list of symbols to a string. If the token type is SYMBOL, the last
 // character of sep is used to separate textual symbols. Additionally, if the
-// token type is SYMBOL, then epsilon symbols will be printed only if the
-// epsilon symbol print type is set to SYMBOLS_INCL_EPS, and will be ignored
-// (default) if set to NONEPS_SYMBOLS. Returns true on success.
+// token type is SYMBOL, epsilon symbols will be printed only if omit_epsilon
+// is false. Returns true on success.
 template <class Label>
 bool LabelsToString(const std::vector<Label> &labels, std::string *str,
-                    StringTokenType ttype = BYTE,
+                    TokenType ttype = TokenType::BYTE,
                     const SymbolTable *syms = nullptr,
                     const std::string &sep = FLAGS_fst_field_separator,
-                    EpsilonSymbolPrintType eps_sym_print_type =
-                        EpsilonSymbolPrintType::NONEPS_SYMBOLS) {
+                    bool omit_epsilon = true) {
   switch (ttype) {
-    case StringTokenType::BYTE: {
+    case TokenType::BYTE: {
       return LabelsToByteString(labels, str);
     }
-    case StringTokenType::UTF8: {
+    case TokenType::UTF8: {
       return LabelsToUTF8String(labels, str);
     }
-    case StringTokenType::SYMBOL: {
+    case TokenType::SYMBOL: {
       return syms ? internal::LabelsToSymbolString(labels, str, *syms, sep,
-                                                   eps_sym_print_type)
+                                                   omit_epsilon)
                   : internal::LabelsToNumericString(labels, str, sep,
-                                                    eps_sym_print_type);
+                                                    omit_epsilon);
     }
   }
   return false;
@@ -318,30 +316,24 @@ class StringPrinter {
  public:
   using Label = typename Arc::Label;
 
-  explicit StringPrinter(StringTokenType token_type = BYTE,
+  explicit StringPrinter(TokenType token_type = TokenType::BYTE,
                          const SymbolTable *syms = nullptr,
-                         EpsilonSymbolPrintType eps_sym_print_type =
-                             EpsilonSymbolPrintType::NONEPS_SYMBOLS)
-      : token_type_(token_type),
-        syms_(syms),
-        eps_sym_print_type_(eps_sym_print_type) {}
+                         bool omit_epsilon = true)
+      : token_type_(token_type), syms_(syms), omit_epsilon_(omit_epsilon) {}
 
   // Converts the FST into a string. With SYMBOL token type, the last character
   // of sep is used as a separator between symbols. Returns true on success.
   bool operator()(const Fst<Arc> &fst, std::string *str,
                   const std::string &sep = FLAGS_fst_field_separator) const {
     std::vector<Label> labels;
-    return (StringFstToOutputLabels(fst, &labels) &&
-            LabelsToString(labels, str, token_type_, syms_, sep,
-                           eps_sym_print_type_));
+    return StringFstToOutputLabels(fst, &labels) &&
+           LabelsToString(labels, str, token_type_, syms_, sep, omit_epsilon_);
   }
 
  private:
-  const StringTokenType token_type_;
+  const TokenType token_type_;
   const SymbolTable *syms_;
-  const EpsilonSymbolPrintType
-      eps_sym_print_type_;  // Whether to print epsilons in
-                            // StringTokenType::SYMBOL mode.
+  const bool omit_epsilon_;
 
   StringPrinter(const StringPrinter &) = delete;
   StringPrinter &operator=(const StringPrinter &) = delete;
index a0eef84..8de7f08 100644 (file)
@@ -22,6 +22,7 @@
 #include <fst/types.h>
 #include <fst/log.h>
 #include <fstream>
+#include <fst/windows_defs.inc>
 #include <map>
 #include <functional>
 
@@ -222,7 +223,7 @@ class SymbolTableImpl final : public MutableSymbolTableImpl {
       std::istream &strm, const std::string &name,
       const SymbolTableTextOptions &opts = SymbolTableTextOptions());
 
-  static SymbolTableImplRead(std::istream &strm,
+  static SymbolTableImpl *Read(std::istream &strm,
                                const SymbolTableReadOptions &opts);
 
   bool Write(std::ostream &strm) const override;
@@ -240,8 +241,11 @@ class SymbolTableImpl final : public MutableSymbolTableImpl {
   }
 
   int64 GetNthKey(ssize_t pos) const override {
-    if (pos < 0 || pos >= symbols_.Size()) return kNoSymbol;
-    if (pos < dense_key_limit_) return pos;
+    if (pos < 0 || static_cast<size_t>(pos) >= symbols_.Size()) {
+      return kNoSymbol;
+    } else if (pos < dense_key_limit_) {
+      return pos;
+    }
     return Find(symbols_.GetSymbol(pos));
   }
 
@@ -340,7 +344,7 @@ class SymbolTable {
 
     iterator &operator++() {
       ++pos_;
-      if (pos_ < nsymbols_) iter_item_.SetPosition(pos_);
+      if (static_cast<size_t>(pos_) < nsymbols_) iter_item_.SetPosition(pos_);
       return *this;
     }
 
@@ -394,7 +398,7 @@ class SymbolTable {
 
   // WARNING: Reading via symbol table read options should not be used. This is
   // a temporary work-around.
-  static SymbolTableRead(std::istream &strm,
+  static SymbolTable *Read(std::istream &strm,
                            const SymbolTableReadOptions &opts) {
     std::shared_ptr<internal::SymbolTableImpl> impl(
         internal::SymbolTableImpl::Read(strm, opts));
@@ -573,7 +577,8 @@ class OPENFST_DEPRECATED(
 // TODO(allauzen): consider adding options to allow for some form of implicit
 // identity relabeling.
 template <class Label>
-SymbolTable *RelabelSymbolTable(const SymbolTable *table,
+SymbolTable *RelabelSymbolTable(
+    const SymbolTable *table,
     const std::vector<std::pair<Label, Label>> &pairs) {
   auto *new_table = new SymbolTable(
       table->Name().empty() ? std::string()
index 251c5cf..8f77b96 100644 (file)
@@ -329,9 +329,8 @@ class SynchronizeFst : public ImplToFst<internal::SynchronizeFstImpl<A>> {
   friend class ArcIterator<SynchronizeFst<A>>;
   friend class StateIterator<SynchronizeFst<A>>;
 
-  explicit SynchronizeFst(
-      const Fst<A> &fst,
-      const SynchronizeFstOptions &opts = SynchronizeFstOptions())
+  explicit SynchronizeFst(const Fst<A> &fst, const SynchronizeFstOptions &opts =
+                                                 SynchronizeFstOptions())
       : ImplToFst<Impl>(std::make_shared<Impl>(fst, opts)) {}
 
   // See Fst<>::Copy() for doc.
index 9b8049b..bf663f7 100644 (file)
@@ -6,6 +6,10 @@
 #ifndef FST_TEST_ALGO_TEST_H_
 #define FST_TEST_ALGO_TEST_H_
 
+#include <memory>
+#include <random>
+#include <utility>
+
 #include <fst/types.h>
 #include <fst/log.h>
 #include <fst/fstlib.h>
@@ -76,13 +80,14 @@ class WeightedTester {
   using StateId = typename Arc::StateId;
   using Weight = typename Arc::Weight;
 
-  WeightedTester(time_t seed, const Fst<Arc> &zero_fst, const Fst<Arc> &one_fst,
-                 const Fst<Arc> &univ_fst, WeightGenerator *weight_generator)
+  WeightedTester(uint64 seed, const Fst<Arc> &zero_fst, const Fst<Arc> &one_fst,
+                 const Fst<Arc> &univ_fst, WeightGenerator weight_generator)
       : seed_(seed),
+        rand_(seed),
         zero_fst_(zero_fst),
         one_fst_(one_fst),
         univ_fst_(univ_fst),
-        weight_generator_(weight_generator) {}
+        generate_(std::move(weight_generator)) {}
 
   void Test(const Fst<Arc> &T1, const Fst<Arc> &T2, const Fst<Arc> &T3) {
     TestRational(T1, T2, T3);
@@ -317,8 +322,8 @@ class WeightedTester {
     {
       VLOG(1) << "Check destructive and delayed projection are equivalent.";
       VectorFst<Arc> P1(T);
-      Project(&P1, PROJECT_INPUT);
-      ProjectFst<Arc> P2(T, PROJECT_INPUT);
+      Project(&P1, ProjectType::INPUT);
+      ProjectFst<Arc> P2(T, ProjectType::INPUT);
       CHECK(Equiv(P1, P2));
     }
 
@@ -334,9 +339,9 @@ class WeightedTester {
       VLOG(1) << "Check Pi_1(T) = Pi_2(T^-1) (destructive).";
       VectorFst<Arc> P1(T);
       VectorFst<Arc> I1(T);
-      Project(&P1, PROJECT_INPUT);
+      Project(&P1, ProjectType::INPUT);
       Invert(&I1);
-      Project(&I1, PROJECT_OUTPUT);
+      Project(&I1, ProjectType::OUTPUT);
       CHECK(Equiv(P1, I1));
     }
 
@@ -344,25 +349,25 @@ class WeightedTester {
       VLOG(1) << "Check Pi_2(T) = Pi_1(T^-1) (destructive).";
       VectorFst<Arc> P1(T);
       VectorFst<Arc> I1(T);
-      Project(&P1, PROJECT_OUTPUT);
+      Project(&P1, ProjectType::OUTPUT);
       Invert(&I1);
-      Project(&I1, PROJECT_INPUT);
+      Project(&I1, ProjectType::INPUT);
       CHECK(Equiv(P1, I1));
     }
 
     {
       VLOG(1) << "Check Pi_1(T) = Pi_2(T^-1) (delayed).";
-      ProjectFst<Arc> P1(T, PROJECT_INPUT);
+      ProjectFst<Arc> P1(T, ProjectType::INPUT);
       InvertFst<Arc> I1(T);
-      ProjectFst<Arc> P2(I1, PROJECT_OUTPUT);
+      ProjectFst<Arc> P2(I1, ProjectType::OUTPUT);
       CHECK(Equiv(P1, P2));
     }
 
     {
       VLOG(1) << "Check Pi_2(T) = Pi_1(T^-1) (delayed).";
-      ProjectFst<Arc> P1(T, PROJECT_OUTPUT);
+      ProjectFst<Arc> P1(T, ProjectType::OUTPUT);
       InvertFst<Arc> I1(T);
-      ProjectFst<Arc> P2(I1, PROJECT_INPUT);
+      ProjectFst<Arc> P2(I1, ProjectType::INPUT);
       CHECK(Equiv(P1, P2));
     }
 
@@ -374,7 +379,9 @@ class WeightedTester {
       for (size_t i = 0; i < kNumLabels; ++i) labelset[i] = i;
       for (size_t i = 0; i < kNumLabels; ++i) {
         using std::swap;
-        swap(labelset[i], labelset[rand() % kNumLabels]);
+        const auto index =
+            std::uniform_int_distribution<>(0, kNumLabels - 1)(rand_);
+        swap(labelset[i], labelset[index]);
       }
 
       std::vector<std::pair<Label, Label>> ipairs1(kNumLabels);
@@ -405,9 +412,13 @@ class WeightedTester {
     {
       VLOG(1) << "Check encoding/decoding (destructive).";
       VectorFst<Arc> D(T);
-      uint32 encode_props = 0;
-      if (rand() % 2) encode_props |= kEncodeLabels;
-      if (rand() % 2) encode_props |= kEncodeWeights;
+      uint8 encode_props = 0;
+      if (std::bernoulli_distribution(.5)(rand_)) {
+        encode_props |= kEncodeLabels;
+      }
+      if (std::bernoulli_distribution(.5)(rand_)) {
+        encode_props |= kEncodeWeights;
+      }
       EncodeMapper<Arc> encoder(encode_props, ENCODE);
       Encode(&D, &encoder);
       Decode(&D, encoder);
@@ -416,9 +427,13 @@ class WeightedTester {
 
     {
       VLOG(1) << "Check encoding/decoding (delayed).";
-      uint32 encode_props = 0;
-      if (rand() % 2) encode_props |= kEncodeLabels;
-      if (rand() % 2) encode_props |= kEncodeWeights;
+      uint8 encode_props = 0;
+      if (std::bernoulli_distribution(.5)(rand_)) {
+        encode_props |= kEncodeLabels;
+      }
+      if (std::bernoulli_distribution(.5)(rand_)) {
+        encode_props |= kEncodeWeights;
+      }
       EncodeMapper<Arc> encoder(encode_props, ENCODE);
       EncodeFst<Arc> E(T, &encoder);
       VectorFst<Arc> Encoded(E);
@@ -497,9 +512,9 @@ class WeightedTester {
     VectorFst<Arc> A1(S1);
     VectorFst<Arc> A2(S2);
     VectorFst<Arc> A3(S3);
-    Project(&A1, PROJECT_OUTPUT);
-    Project(&A2, PROJECT_INPUT);
-    Project(&A3, PROJECT_INPUT);
+    Project(&A1, ProjectType::OUTPUT);
+    Project(&A2, ProjectType::INPUT);
+    Project(&A3, ProjectType::INPUT);
 
     {
       VLOG(1) << "Check intersection is commutative.";
@@ -605,7 +620,7 @@ class WeightedTester {
     uint64 wprops = Weight::Properties();
 
     VectorFst<Arc> A(T);
-    Project(&A, PROJECT_INPUT);
+    Project(&A, ProjectType::INPUT);
     {
       VLOG(1) << "Check connected FST is equivalent to its input.";
       VectorFst<Arc> C1(T);
@@ -669,7 +684,7 @@ class WeightedTester {
       if ((wprops & (kPath | kCommutative)) == (kPath | kCommutative)) {
         VLOG(1) << "Check pruning in determinization";
         VectorFst<Arc> P;
-        Weight threshold = (*weight_generator_)();
+        const Weight threshold = generate_();
         DeterminizeOptions<Arc> opts;
         opts.weight_threshold = threshold;
         Determinize(A, &P, opts);
@@ -740,7 +755,7 @@ class WeightedTester {
       if ((wprops & (kPath | kCommutative)) == (kPath | kCommutative)) {
         VLOG(1)  << "Check pruning in disambiguation";
         VectorFst<Arc> P;
-        Weight threshold = (*weight_generator_)();
+        const Weight threshold = generate_();
         DisambiguateOptions<Arc> opts;
         opts.weight_threshold = threshold;
         Disambiguate(R, &P, opts);
@@ -755,8 +770,9 @@ class WeightedTester {
       std::vector<Weight> potential;
       VectorFst<Arc> RI(T);
       VectorFst<Arc> RF(T);
-      while (potential.size() < RI.NumStates())
-        potential.push_back((*weight_generator_)());
+      while (potential.size() < RI.NumStates()) {
+        potential.push_back(generate_());
+      }
 
       Reweight(&RI, potential, REWEIGHT_TO_INITIAL);
       CHECK(Equiv(T, RI));
@@ -801,30 +817,30 @@ class WeightedTester {
       VLOG(1) << "Check pruning algorithm";
       {
         VLOG(1) << "Check equiv. of constructive and destructive algorithms";
-        Weight thresold = (*weight_generator_)();
+        const Weight threshold = generate_();
         VectorFst<Arc> P1(T);
-        Prune(&P1, thresold);
+        Prune(&P1, threshold);
         VectorFst<Arc> P2;
-        Prune(T, &P2, thresold);
+        Prune(T, &P2, threshold);
         CHECK(Equiv(P1, P2));
       }
 
       {
         VLOG(1) << "Check prune(reverse) equiv reverse(prune)";
-        Weight thresold = (*weight_generator_)();
+        const Weight threshold = generate_();
         VectorFst<ReverseArc<Arc>> R;
         VectorFst<Arc> P1(T);
         VectorFst<Arc> P2;
-        Prune(&P1, thresold);
+        Prune(&P1, threshold);
         Reverse(T, &R);
-        Prune(&R, thresold.Reverse());
+        Prune(&R, threshold.Reverse());
         Reverse(R, &P2);
         CHECK(Equiv(P1, P2));
       }
       {
         VLOG(1) << "Check: ShortestDistance(A - prune(A))"
                 << " > ShortestDistance(A) times Threshold";
-        Weight threshold = (*weight_generator_)();
+        const Weight threshold = generate_();
         VectorFst<Arc> P;
         Prune(A, &P, threshold);
         CHECK(PruneEquiv(A, P, threshold));
@@ -842,7 +858,7 @@ class WeightedTester {
     uint64 wprops = Weight::Properties();
 
     VectorFst<Arc> A(T);
-    Project(&A, PROJECT_INPUT);
+    Project(&A, ProjectType::INPUT);
 
     if ((wprops & (kPath | kRightSemiring)) == (kPath | kRightSemiring)) {
       VLOG(1) << "Check 1-best weight.";
@@ -856,12 +872,12 @@ class WeightedTester {
     if ((wprops & (kPath | kSemiring)) == (kPath | kSemiring)) {
       VLOG(1) << "Check n-best weights";
       VectorFst<Arc> R(A);
-      RmEpsilon(&R, /*connect=*/ true, Arc::Weight::Zero(), kNoStateId,
-                kDelta);
-      int nshortest = rand() % kNumRandomShortestPaths + 2;
+      RmEpsilon(&R, /*connect=*/true, Arc::Weight::Zero(), kNoStateId, kDelta);
+      const int nshortest = std::uniform_int_distribution<>(
+          0, kNumRandomShortestPaths + 1)(rand_);
       VectorFst<Arc> paths;
-      ShortestPath(R, &paths, nshortest, /*unique=*/ true,
-                   /*first_path=*/ false, Weight::Zero(), kNumShortestStates,
+      ShortestPath(R, &paths, nshortest, /*unique=*/true,
+                   /*first_path=*/false, Weight::Zero(), kNumShortestStates,
                    kDelta);
       std::vector<Weight> distance;
       ShortestDistance(paths, &distance, true, kDelta);
@@ -897,12 +913,12 @@ class WeightedTester {
 
     // Ensures seed used once per instantiation.
     static const UniformArcSelector<A> uniform_selector(seed_);
-    RandGenOptions<UniformArcSelector<A>> opts(uniform_selector,
-                                               kRandomPathLength);
+    const RandGenOptions<UniformArcSelector<A>> opts(uniform_selector,
+                                                     kRandomPathLength);
     return RandEquivalent(fst1, fst2, kNumRandomPaths, opts, kTestDelta, seed_);
   }
 
-  // Tests FSA is unambiguous
+  // Tests FSA is unambiguous.
   bool Unambiguous(const Fst<Arc> &fst) {
     VectorFst<StdArc> sfst, dfst;
     VectorFst<LogArc> lfst1, lfst2;
@@ -920,8 +936,8 @@ class WeightedTester {
   bool MinRelated(const Fst<A> &fst1, const Fst<A> &fst2) {
     // Same domain
     VectorFst<Arc> P1(fst1), P2(fst2);
-    Project(&P1, PROJECT_INPUT);
-    Project(&P2, PROJECT_INPUT);
+    Project(&P1, ProjectType::INPUT);
+    Project(&P2, ProjectType::INPUT);
     if (!Equiv(P1, P2)) {
       LOG(ERROR) << "Inputs not equivalent";
       return false;
@@ -929,8 +945,8 @@ class WeightedTester {
 
     // Ensures seed used once per instantiation.
     static const UniformArcSelector<A> uniform_selector(seed_);
-    RandGenOptions<UniformArcSelector<A>> opts(uniform_selector,
-                                               kRandomPathLength);
+    const RandGenOptions<UniformArcSelector<A>> opts(uniform_selector,
+                                                     kRandomPathLength);
 
     VectorFst<Arc> path, paths1, paths2;
     for (ssize_t n = 0; n < kNumRandomPaths; ++n) {
@@ -949,8 +965,7 @@ class WeightedTester {
     return true;
   }
 
-  // Tests ShortestDistance(A - P) >=
-  // ShortestDistance(A) times Threshold.
+  // Tests ShortestDistance(A - P) >= ShortestDistance(A) times Threshold.
   template <class A>
   bool PruneEquiv(const Fst<A> &fst, const Fst<A> &pfst, Weight threshold) {
     VLOG(1) << "Check FSTs for sanity (including property bits).";
@@ -959,13 +974,15 @@ class WeightedTester {
 
     DifferenceFst<Arc> D(fst, DeterminizeFst<Arc>(RmEpsilonFst<Arc>(
                                   MakeArcMapFst(pfst, RmWeightMapper<Arc>()))));
-    Weight sum1 = Times(ShortestDistance(fst), threshold);
-    Weight sum2 = ShortestDistance(D);
+    const Weight sum1 = Times(ShortestDistance(fst), threshold);
+    const Weight sum2 = ShortestDistance(D);
     return ApproxEqual(Plus(sum1, sum2), sum1, kTestDelta);
   }
 
   // Random seed.
-  int seed_;
+  uint64 seed_;
+  // Random state (for randomness in this class).
+  std::mt19937_64 rand_;
   // FST with no states
   VectorFst<Arc> zero_fst_;
   // FST with one state that accepts epsilon.
@@ -973,7 +990,7 @@ class WeightedTester {
   // FST with one state that accepts all strings.
   VectorFst<Arc> univ_fst_;
   // Generates weights used in testing.
-  WeightGenerator *weight_generator_;
+  WeightGenerator generate_;
   // Maximum random path length.
   static const int kRandomPathLength;
   // Number of random paths to explore.
@@ -1011,7 +1028,7 @@ template <class Arc>
 class UnweightedTester {
  public:
   UnweightedTester(const Fst<Arc> &zero_fsa, const Fst<Arc> &one_fsa,
-                   const Fst<Arc> &univ_fsa) {}
+                   const Fst<Arc> &univ_fsa, uint64 seed) {}
 
   void Test(const Fst<Arc> &A1, const Fst<Arc> &A2, const Fst<Arc> &A3) {}
 };
@@ -1028,8 +1045,11 @@ class UnweightedTester<StdArc> {
   using Weight = Arc::Weight;
 
   UnweightedTester(const Fst<Arc> &zero_fsa, const Fst<Arc> &one_fsa,
-                   const Fst<Arc> &univ_fsa)
-      : zero_fsa_(zero_fsa), one_fsa_(one_fsa), univ_fsa_(univ_fsa) {}
+                   const Fst<Arc> &univ_fsa, uint64 seed)
+      : zero_fsa_(zero_fsa),
+        one_fsa_(one_fsa),
+        univ_fsa_(univ_fsa),
+        rand_(seed) {}
 
   void Test(const Fst<Arc> &A1, const Fst<Arc> &A2, const Fst<Arc> &A3) {
     TestRational(A1, A2, A3);
@@ -1038,7 +1058,7 @@ class UnweightedTester<StdArc> {
   }
 
  private:
-  // Tests rational operations with identities
+  // Tests rational operations with identities.
   void TestRational(const Fst<Arc> &A1, const Fst<Arc> &A2,
                     const Fst<Arc> &A3) {
     {
@@ -1061,7 +1081,7 @@ class UnweightedTester<StdArc> {
     {
       VLOG(1) << "Check if A^n c A* (destructive).";
       VectorFst<Arc> C(one_fsa_);
-      int n = rand() % 5;
+      const int n = std::uniform_int_distribution<>(0, 4)(rand_);
       for (int i = 0; i < n; ++i) Concat(&C, A1);
 
       VectorFst<Arc> S(A1);
@@ -1071,7 +1091,7 @@ class UnweightedTester<StdArc> {
 
     {
       VLOG(1) << "Check if A^n c A* (delayed).";
-      int n = rand() % 5;
+      const int n = std::uniform_int_distribution<>(0, 4)(rand_);
       Fst<Arc> *C = new VectorFst<Arc>(one_fsa_);
       for (int i = 0; i < n; ++i) {
         ConcatFst<Arc> *F = new ConcatFst<Arc>(*C, A1);
@@ -1157,7 +1177,7 @@ class UnweightedTester<StdArc> {
     }
   }
 
-  // Tests optimization operations
+  // Tests optimization operations.
   void TestOptimize(const Fst<Arc> &A) {
     {
       VLOG(1) << "Check determinized FSA is equivalent to its input.";
@@ -1186,7 +1206,7 @@ class UnweightedTester<StdArc> {
         n = M.NumStates();
       }
 
-      if (n) {  // Skip test if A is the empty machine
+      if (n) {  // Skips test if A is the empty machine.
         VLOG(1) << "Check that Hopcroft's and Revuz's algorithms lead to the"
                 << " same number of states as Brozozowski's algorithm";
         VectorFst<Arc> R;
@@ -1198,7 +1218,7 @@ class UnweightedTester<StdArc> {
         DeterminizeFst<Arc> DRD(RD);
         VectorFst<Arc> M(DRD);
         CHECK_EQ(n + 1, M.NumStates());  // Accounts for the epsilon transition
-                                         // to the initial state
+                                         // to the initial state.
       }
     }
   }
@@ -1234,7 +1254,7 @@ class UnweightedTester<StdArc> {
     Connect(&ufsa);
     bool equiv2 = ufsa.NumStates() == 0;
 
-    // Check two equivalence tests match
+    // Checks both equivalence tests match.
     CHECK((equiv1 && equiv2) || (!equiv1 && !equiv2));
 
     return equiv1;
@@ -1259,7 +1279,7 @@ class UnweightedTester<StdArc> {
     return Equivalent(dfa1, dfa2);
   }
 
-  // Returns complement Fsa
+  // Returns complement FSA.
   void Complement(const Fst<Arc> &ifsa, MutableFst<Arc> *ofsa) {
     RmEpsilonFst<Arc> rfsa(ifsa);
     DeterminizeFst<Arc> dfa(rfsa);
@@ -1267,14 +1287,14 @@ class UnweightedTester<StdArc> {
     *ofsa = cfsa;
   }
 
-  // FSA with no states
+  // FSA with no states.
   VectorFst<Arc> zero_fsa_;
-
   // FSA with one state that accepts epsilon.
   VectorFst<Arc> one_fsa_;
-
   // FSA with one state that accepts all strings.
   VectorFst<Arc> univ_fsa_;
+  // Random state.
+  std::mt19937_64 rand_;
 };
 
 // This class tests a variety of identities and properties that must
@@ -1288,34 +1308,28 @@ class AlgoTester {
   using StateId = typename Arc::StateId;
   using Weight = typename Arc::Weight;
 
-  AlgoTester(WeightGenerator generator, int seed)
-      : weight_generator_(generator) {
+  AlgoTester(WeightGenerator generator, uint64 seed)
+      : generate_(std::move(generator)), rand_(seed) {
     one_fst_.AddState();
     one_fst_.SetStart(0);
-    one_fst_.SetFinal(0, Weight::One());
+    one_fst_.SetFinal(0);
 
     univ_fst_.AddState();
     univ_fst_.SetStart(0);
-    univ_fst_.SetFinal(0, Weight::One());
-    for (int i = 0; i < kNumRandomLabels; ++i)
-      univ_fst_.AddArc(0, Arc(i, i, Weight::One(), 0));
-
-    weighted_tester_ = new WeightedTester<Arc, WeightGenerator>(
-        seed, zero_fst_, one_fst_, univ_fst_, &weight_generator_);
+    univ_fst_.SetFinal(0);
+    for (int i = 0; i < kNumRandomLabels; ++i) univ_fst_.EmplaceArc(0, i, i, 0);
 
-    unweighted_tester_ =
-        new UnweightedTester<Arc>(zero_fst_, one_fst_, univ_fst_);
-  }
+    weighted_tester_.reset(new WeightedTester<Arc, WeightGenerator>(
+        seed, zero_fst_, one_fst_, univ_fst_, generate_));
 
-  ~AlgoTester() {
-    delete weighted_tester_;
-    delete unweighted_tester_;
+    unweighted_tester_.reset(
+        new UnweightedTester<Arc>(zero_fst_, one_fst_, univ_fst_, seed));
   }
 
   void MakeRandFst(MutableFst<Arc> *fst) {
     RandFst<Arc, WeightGenerator>(kNumRandomStates, kNumRandomArcs,
-                                  kNumRandomLabels, kAcyclicProb,
-                                  &weight_generator_, fst);
+                                  kNumRandomLabels, kAcyclicProb, generate_,
+                                  rand_(), fst);
   }
 
   void Test() {
@@ -1334,9 +1348,9 @@ class AlgoTester {
       VectorFst<Arc> A1(T1);
       VectorFst<Arc> A2(T2);
       VectorFst<Arc> A3(T3);
-      Project(&A1, PROJECT_OUTPUT);
-      Project(&A2, PROJECT_INPUT);
-      Project(&A3, PROJECT_INPUT);
+      Project(&A1, ProjectType::OUTPUT);
+      Project(&A2, ProjectType::INPUT);
+      Project(&A3, ProjectType::INPUT);
       ArcMap(&A1, rm_weight_mapper_);
       ArcMap(&A2, rm_weight_mapper_);
       ArcMap(&A3, rm_weight_mapper_);
@@ -1346,41 +1360,31 @@ class AlgoTester {
 
  private:
   // Generates weights used in testing.
-  WeightGenerator weight_generator_;
-
+  WeightGenerator generate_;
+  // Random state used to seed RandFst.
+  std::mt19937_64 rand_;
   // FST with no states
   VectorFst<Arc> zero_fst_;
-
   // FST with one state that accepts epsilon.
   VectorFst<Arc> one_fst_;
-
   // FST with one state that accepts all strings.
   VectorFst<Arc> univ_fst_;
-
   // Tests weighted FSTs
-  WeightedTester<Arc, WeightGenerator> *weighted_tester_;
-
+  std::unique_ptr<WeightedTester<Arc, WeightGenerator>> weighted_tester_;
   // Tests unweighted FSTs
-  UnweightedTester<Arc> *unweighted_tester_;
-
+  std::unique_ptr<UnweightedTester<Arc>> unweighted_tester_;
   // Mapper to remove weights from an Fst
   RmWeightMapper<Arc> rm_weight_mapper_;
-
   // Maximum number of states in random test Fst.
   static const int kNumRandomStates;
-
   // Maximum number of arcs in random test Fst.
   static const int kNumRandomArcs;
-
   // Number of alternative random labels.
   static const int kNumRandomLabels;
-
   // Probability to force an acyclic Fst
   static const float kAcyclicProb;
-
   // Maximum random path length.
   static const int kRandomPathLength;
-
   // Number of random paths to explore.
   static const int kNumRandomPaths;
 
index 5c0cda6..34553a9 100644 (file)
@@ -1,6 +1,9 @@
 #ifndef FST_TEST_RAND_FST_H_
 #define FST_TEST_RAND_FST_H_
 
+#include <random>
+
+#include <fst/types.h>
 #include <fst/log.h>
 #include <fst/mutable-fst.h>
 #include <fst/verify.h>
 namespace fst {
 
 // Generates a random FST.
-template <class Arc, class WeightGenerator>
+template <class Arc, class Generate>
 void RandFst(const int num_random_states, const int num_random_arcs,
              const int num_random_labels, const float acyclic_prob,
-             WeightGenerator *weight_generator, MutableFst<Arc> *fst) {
+             Generate generate, uint64 seed, MutableFst<Arc> *fst) {
   using Label = typename Arc::Label;
   using StateId = typename Arc::StateId;
   using Weight = typename Arc::Weight;
@@ -25,32 +28,39 @@ void RandFst(const int num_random_states, const int num_random_arcs,
     NUM_DIRECTIONS = 3
   };
 
+  std::mt19937_64 rand(seed);
+  const StateId ns =
+      std::uniform_int_distribution<>(0, num_random_states - 1)(rand);
+  std::uniform_int_distribution<size_t> arc_dist(0, num_random_arcs - 1);
+  std::uniform_int_distribution<Label> label_dist(0, num_random_labels - 1);
+  std::uniform_int_distribution<StateId> ns_dist(0, ns - 1);
+
   ArcDirection arc_direction = ANY_DIRECTION;
-  if (rand() / (RAND_MAX + 1.0) < acyclic_prob)
-    arc_direction = rand() % 2 ? FORWARD_DIRECTION : REVERSE_DIRECTION;
+  if (!std::bernoulli_distribution(acyclic_prob)(rand)) {
+    arc_direction = std::bernoulli_distribution(.5)(rand) ? FORWARD_DIRECTION
+                                                          : REVERSE_DIRECTION;
+  }
 
   fst->DeleteStates();
-  StateId ns = rand() % num_random_states;
 
   if (ns == 0) return;
-  for (StateId s = 0; s < ns; ++s) fst->AddState();
+  fst->AddStates(ns);
 
-  StateId start = rand() % ns;
+  const StateId start = ns_dist(rand);
   fst->SetStart(start);
 
-  size_t na = rand() % num_random_arcs;
+  const size_t na = arc_dist(rand);
   for (size_t n = 0; n < na; ++n) {
-    StateId s = rand() % ns;
+    StateId s = ns_dist(rand);
     Arc arc;
-    arc.ilabel = rand() % num_random_labels;
-    arc.olabel = rand() % num_random_labels;
-    arc.weight = (*weight_generator)();
-    arc.nextstate = rand() % ns;
-
+    arc.ilabel = label_dist(rand);
+    arc.olabel = label_dist(rand);
+    arc.weight = generate();
+    arc.nextstate = ns_dist(rand);
     if ((arc_direction == FORWARD_DIRECTION ||
          arc_direction == REVERSE_DIRECTION) &&
         s == arc.nextstate) {
-      continue;  // skips self-loops
+      continue;  // Skips self-loops.
     }
 
     if ((arc_direction == FORWARD_DIRECTION && s > arc.nextstate) ||
@@ -63,22 +73,21 @@ void RandFst(const int num_random_states, const int num_random_arcs,
     fst->AddArc(s, arc);
   }
 
-  StateId nf = rand() % (ns + 1);
+  const StateId nf = std::uniform_int_distribution<>(0, ns)(rand);
   for (StateId n = 0; n < nf; ++n) {
-    StateId s = rand() % ns;
-    Weight final = (*weight_generator)();
-    fst->SetFinal(s, final);
+    const StateId s = ns_dist(rand);
+    fst->SetFinal(s, generate());
   }
   VLOG(1) << "Check FST for sanity (including property bits).";
   CHECK(Verify(*fst));
 
   // Get/compute all properties.
-  uint64 props = fst->Properties(kFstProperties, true);
+  const uint64 props = fst->Properties(kFstProperties, true);
 
   // Select random set of properties to be unknown.
   uint64 mask = 0;
   for (int n = 0; n < 8; ++n) {
-    mask |= rand() & 0xff;
+    mask |= std::uniform_int_distribution<>(0, 0xff)(rand);
     mask <<= 8;
   }
   mask &= ~kTrinaryProperties;
index ee39f48..d0dd9e5 100644 (file)
@@ -72,8 +72,7 @@ class TupleWeight {
   }
 
   bool Member() const {
-    return std::all_of(values_.begin(), values_.end(),
-                       std::mem_fn(&W::Member));
+    return std::all_of(values_.begin(), values_.end(), std::mem_fn(&W::Member));
   }
 
   size_t Hash() const {
index e05a03f..6426dcb 100644 (file)
@@ -3,14 +3,14 @@
 //
 // Union weight set and associated semiring operation definitions.
 //
-// TODO(riley): add in normalizer functor
+// TODO(riley): add in normalizer functor.
 
 #ifndef FST_UNION_WEIGHT_H_
 #define FST_UNION_WEIGHT_H_
 
-#include <cstdlib>
 #include <iostream>
 #include <list>
+#include <random>
 #include <sstream>
 #include <string>
 #include <utility>
@@ -478,16 +478,20 @@ class WeightGenerate<UnionWeight<W, O>> {
   using Weight = UnionWeight<W, O>;
   using Generate = WeightGenerate<W>;
 
-  explicit WeightGenerate(bool allow_zero = true,
+  explicit WeightGenerate(uint64 seed = std::random_device()(),
+                          bool allow_zero = true,
                           size_t num_random_weights = kNumRandomWeights)
-      : generate_(false), allow_zero_(allow_zero),
-        num_random_weights_(num_random_weights) {}
+      : rand_(seed),
+        allow_zero_(allow_zero),
+        num_random_weights_(num_random_weights),
+        generate_(seed, false) {}
 
   Weight operator()() const {
-    const int n = rand() % (num_random_weights_ + 1);  // NOLINT
-    if (allow_zero_ && n == num_random_weights_) {
+    const int sample = std::uniform_int_distribution<>(
+        0, num_random_weights_ + allow_zero_ - 1)(rand_);
+    if (allow_zero_ && sample == num_random_weights_) {
       return Weight::Zero();
-    } else if (n % 2 == 0) {
+    } else if (std::bernoulli_distribution(.5)(rand_)) {
       return Weight(generate_());
     } else {
       return Plus(Weight(generate_()), Weight(generate_()));
@@ -495,11 +499,10 @@ class WeightGenerate<UnionWeight<W, O>> {
   }
 
  private:
-  Generate generate_;
-  // Permits Zero() and zero divisors.
-  bool allow_zero_;
-  // The number of alternative random weights.
+  mutable std::mt19937_64 rand_;
+  const bool allow_zero_;
   const size_t num_random_weights_;
+  const Generate generate_;
 };
 
 }  // namespace fst
index 5ea9c35..e18fd90 100644 (file)
@@ -44,16 +44,16 @@ namespace fst {
 
 // Generic case.
 template <class T,
-    typename std::enable_if<std::is_class<T>::value, T>::type* = nullptr>
+          typename std::enable_if<std::is_class<T>::value, T>::type * = nullptr>
 inline std::istream &ReadType(std::istream &strm, T *t) {
   return t->Read(strm);
 }
 
 // Numeric (boolean, integral, floating-point) case.
-template <class T,
-    typename std::enable_if<std::is_arithmetic<T>::value, T>::type* = nullptr>
+template <class T, typename std::enable_if<std::is_arithmetic<T>::value,
+                                           T>::type * = nullptr>
 inline std::istream &ReadType(std::istream &strm, T *t) {
-  return strm.read(reinterpret_cast<char *>(t), sizeof(T)); \
+  return strm.read(reinterpret_cast<char *>(t), sizeof(T));
 }
 
 // String case.
@@ -158,15 +158,15 @@ std::istream &ReadType(std::istream &strm, std::unordered_map<T...> *c) {
 
 // Generic case.
 template <class T,
-    typename std::enable_if<std::is_class<T>::value, T>::type* = nullptr>
+          typename std::enable_if<std::is_class<T>::value, T>::type * = nullptr>
 inline std::ostream &WriteType(std::ostream &strm, const T t) {
   t.Write(strm);
   return strm;
 }
 
 // Numeric (boolean, integral, floating-point) case.
-template <class T,
-    typename std::enable_if<std::is_arithmetic<T>::value, T>::type* = nullptr>
+template <class T, typename std::enable_if<std::is_arithmetic<T>::value,
+                                           T>::type * = nullptr>
 inline std::ostream &WriteType(std::ostream &strm, const T t) {
   return strm.write(reinterpret_cast<const char *>(&t), sizeof(T));
 }
index 75774af..c818798 100644 (file)
@@ -93,7 +93,7 @@ class VectorState {
   }
 
   template <class... T>
-  void EmplaceArc(T&&... ctor_args) {
+  void EmplaceArc(T &&... ctor_args) {
     arcs_.emplace_back(std::forward<T>(ctor_args)...);
     IncrementNumEpsilons(arcs_.back());
   }
@@ -230,7 +230,7 @@ class VectorFstBaseImpl : public FstImpl<typename S::Arc> {
   }
 
   template <class... T>
-  void EmplaceArc(StateId state, T&&... ctor_args) {
+  void EmplaceArc(StateId state, T &&... ctor_args) {
     states_[state]->EmplaceArc(std::forward<T>(ctor_args)...);
   }
 
@@ -386,7 +386,7 @@ class VectorFstImpl : public VectorFstBaseImpl<S> {
   }
 
   template <class... T>
-  void EmplaceArc(StateId state, T&&... ctor_args) {
+  void EmplaceArc(StateId state, T &&... ctor_args) {
     BaseImpl::EmplaceArc(state, std::forward<T>(ctor_args)...);
     UpdatePropertiesAfterAddArc(state);
   }
@@ -420,9 +420,8 @@ class VectorFstImpl : public VectorFstBaseImpl<S> {
     const size_t num_arcs{vstate->NumArcs()};
     if (num_arcs) {
       const auto &arc = vstate->GetArc(num_arcs - 1);
-      const auto *parc = (num_arcs < 2)
-                         ? nullptr
-                         : &(vstate->GetArc(num_arcs - 2));
+      const auto *parc =
+          (num_arcs < 2) ? nullptr : &(vstate->GetArc(num_arcs - 2));
       SetProperties(AddArcProperties(Properties(), state, arc, parc));
     }
   }
@@ -550,7 +549,7 @@ class VectorFst : public ImplToMutableFst<internal::VectorFstImpl<S>> {
   }
 
   template <class... T>
-  void EmplaceArc(StateId state, T&&... ctor_args) {
+  void EmplaceArc(StateId state, T &&... ctor_args) {
     MutateCheck();
     GetMutableImpl()->EmplaceArc(state, std::forward<T>(ctor_args)...);
   }
index c665804..7d0ebcd 100644 (file)
@@ -272,8 +272,10 @@ class PartialCopyVisitor : public CopyVisitor<A> {
 
   PartialCopyVisitor(MutableFst<Arc> *ofst, StateId maxvisit,
                      bool copy_grey = true, bool copy_black = true)
-      : CopyVisitor<A>(ofst), maxvisit_(maxvisit),
-        copy_grey_(copy_grey), copy_black_(copy_black) {}
+      : CopyVisitor<A>(ofst),
+        maxvisit_(maxvisit),
+        copy_grey_(copy_grey),
+        copy_black_(copy_black) {}
 
   void InitVisit(const Fst<A> &ifst) {
     CopyVisitor<A>::InitVisit(ifst);
index 81e8301..418848a 100644 (file)
@@ -133,8 +133,8 @@ constexpr size_t kNumRandomWeights = 5;
 // Weight property boolean constants needed for SFINAE.
 
 template <class W>
-using IsIdempotent = std::integral_constant<bool,
-    (W::Properties() & kIdempotent) != 0>;
+using IsIdempotent =
+    std::integral_constant<bool, (W::Properties() & kIdempotent) != 0>;
 
 template <class W>
 using IsPath = std::integral_constant<bool, (W::Properties() & kPath) != 0>;
@@ -233,8 +233,8 @@ class Adder {
 template <class W1, class W2>
 struct WeightConvert {
   W2 operator()(W1 w1) const {
-    FSTERROR() << "WeightConvert: Can't convert weight from \"" << W1::Type()
-               << "\" to \"" << W2::Type();
+    FSTERROR() << "WeightConvert: Can't convert weight from " << W1::Type()
+               << " to " << W2::Type();
     return W2::NoWeight();
   }
 };
@@ -246,6 +246,21 @@ struct WeightConvert<W, W> {
 };
 
 // General random weight generator: raises error.
+//
+// The standard interface is roughly:
+//
+// class WeightGenerate<MyWeight> {
+//  public:
+//   explicit WeightGenerate(uint64 seed = std::random_device()(),
+//                           bool allow_zero = true,
+//                           ...);
+//
+//   MyWeight operator()() const;
+// };
+//
+// Many weight generators also take trailing constructor arguments specifying
+// the number of random (unique) weights, the length of weights (e.g., for
+// string-based weights), etc. with sensible defaults
 template <class W>
 struct WeightGenerate {
   W operator()() const {
diff --git a/src/include/fst/windows_defs.inc b/src/include/fst/windows_defs.inc
new file mode 100644 (file)
index 0000000..4b222dd
--- /dev/null
@@ -0,0 +1,6 @@
+// Aggregator file for common things that need to be defined when building
+// for Windows.
+#ifdef _WIN32
+#include <basetsd.h>
+using ssize_t = SSIZE_T;
+#endif
\ No newline at end of file
index ec40722..4a1a1e9 100644 (file)
@@ -4,5 +4,5 @@ lib_LTLIBRARIES = libfst.la
 libfst_la_SOURCES = compat.cc encode.cc flags.cc fst.cc fst-types.cc \
                     mapped-file.cc properties.cc symbol-table.cc \
                     symbol-table-ops.cc weight.cc util.cc
-libfst_la_LDFLAGS = -version-info 20:0:0
+libfst_la_LDFLAGS = -version-info 21:0:0
 libfst_la_LIBADD = $(DL_LIBS)
index b3d51f7..5be7d36 100644 (file)
@@ -355,7 +355,7 @@ libfst_la_SOURCES = compat.cc encode.cc flags.cc fst.cc fst-types.cc \
                     mapped-file.cc properties.cc symbol-table.cc \
                     symbol-table-ops.cc weight.cc util.cc
 
-libfst_la_LDFLAGS = -version-info 20:0:0
+libfst_la_LDFLAGS = -version-info 21:0:0
 libfst_la_LIBADD = $(DL_LIBS)
 all: all-am
 
index 9702b84..f9441f6 100644 (file)
@@ -48,8 +48,8 @@ bool IsFstHeader(std::istream &strm, const std::string &) {
   int32 magic_number = 0;
   ReadType(strm, &magic_number);
   if (magic_number != kFstMagicNumber) {
-      LOG(WARNING) << "Magic number not matched. Got: " << magic_number;
-      match = false;
+    LOG(WARNING) << "Magic number not matched. Got: " << magic_number;
+    match = false;
   }
   strm.seekg(pos);
   return match;
@@ -64,10 +64,10 @@ bool FstHeader::Read(std::istream &strm, const std::string &source,
   int32 magic_number = 0;
   ReadType(strm, &magic_number);
   if (magic_number != kFstMagicNumber) {
-      LOG(ERROR) << "FstHeader::Read: Bad FST header: " << source
-          << ". Magic number not matched. Got: " << magic_number;
-      if (rewind) strm.seekg(pos);
-      return false;
+    LOG(ERROR) << "FstHeader::Read: Bad FST header: " << source
+               << ". Magic number not matched. Got: " << magic_number;
+    if (rewind) strm.seekg(pos);
+    return false;
   }
   ReadType(strm, &fsttype_);
   ReadType(strm, &arctype_);
index 97e2c3f..adaa8b3 100644 (file)
@@ -5,28 +5,50 @@
 #include <fst/mapped-file.h>
 
 #include <fcntl.h>
-#include <sys/mman.h>
 #include <sys/types.h>
+
+#ifdef _WIN32
+#include <io.h>         // for _get_osfhandle, _open
+#include <memoryapi.h>  // for CreateFileMapping, UnmapViewOfFile
+#include <windows.h>
+#else
+#include <sys/mman.h>
 #include <unistd.h>
+#endif  // _WIN32
 
 #include <algorithm>
 #include <cerrno>
+#include <cstring>
 #include <ios>
+#include <limits>
 #include <memory>
 
 #include <fst/log.h>
 
 namespace fst {
 
+#ifdef _WIN32
+namespace {
+static constexpr DWORD DWORD_MAX = std::numeric_limits<DWORD>::max();
+}  // namespace
+#endif  // _WIN32
+
 MappedFile::MappedFile(const MemoryRegion &region) : region_(region) {}
 
 MappedFile::~MappedFile() {
   if (region_.size != 0) {
     if (region_.mmap) {
       VLOG(2) << "munmap'ed " << region_.size << " bytes at " << region_.mmap;
+#ifdef _WIN32
+      if (UnmapViewOfFile(region_.mmap) != 0) {
+        LOG(ERROR) << "Failed to unmap region: " << GetLastError();
+      }
+      CloseHandle(region_.file_mapping);
+#else
       if (munmap(region_.mmap, region_.size) != 0) {
         LOG(ERROR) << "Failed to unmap region: " << strerror(errno);
       }
+#endif
     } else {
       if (region_.data) {
         operator delete(static_cast<char *>(region_.data) - region_.offset);
@@ -42,8 +64,12 @@ MappedFile *MappedFile::Map(std::istream *istrm, bool memorymap,
           << source << "\""
           << " size: " << size << " offset: " << spos;
   if (memorymap && spos >= 0 && spos % kArchAlignment == 0) {
-    const size_t pos = spos;
+    const size_t pos = static_cast<size_t>(spos);
+#ifdef _WIN32
+    const int fd = _open(source.c_str(), _O_RDONLY);
+#else
     const int fd = open(source.c_str(), O_RDONLY);
+#endif
     if (fd != -1) {
       std::unique_ptr<MappedFile> mmf(MapFromFileDescriptor(fd, pos, size));
       if (close(fd) == 0 && mmf != nullptr) {
@@ -83,20 +109,62 @@ MappedFile *MappedFile::Map(std::istream *istrm, bool memorymap,
 }
 
 MappedFile *MappedFile::MapFromFileDescriptor(int fd, size_t pos, size_t size) {
+#ifdef _WIN32
+  SYSTEM_INFO sysInfo;
+  GetSystemInfo(&sysInfo);
+  const DWORD pagesize = sysInfo.dwPageSize;
+#else
   const int pagesize = sysconf(_SC_PAGESIZE);
-  const off_t offset = pos % pagesize;
-  const off_t upsize = size + offset;
-  void *map = mmap(nullptr, upsize, PROT_READ, MAP_SHARED, fd, pos - offset);
+#endif  // _WIN32
+
+  const size_t offset = pos % pagesize;
+  const size_t offset_pos = pos - offset;
+  const size_t upsize = size + offset;
+
+#ifdef _WIN32
+  if (fd == -1) {
+    LOG(ERROR) << "Invalid file descriptor fd=" << fd;
+    return nullptr;
+  }
+  HANDLE file = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
+  if (file == INVALID_HANDLE_VALUE) {
+    LOG(ERROR) << "Invalid file descriptor fd=" << fd;
+    return nullptr;
+  }
+  HANDLE file_mapping = CreateFileMappingA(file, nullptr, PAGE_READONLY,
+                                           upsize >> (8 * sizeof(DWORD)),
+                                           upsize & DWORD_MAX, nullptr);
+  if (file_mapping == INVALID_HANDLE_VALUE) {
+    LOG(ERROR) << "Can't create mapping for fd=" << fd << " size=" << upsize
+               << ": " << GetLastError();
+    return nullptr;
+  }
+
+  void *map = MapViewOfFile(file_mapping, FILE_MAP_READ,
+                            offset_pos >> (8 * sizeof(DWORD)),
+                            offset_pos & DWORD_MAX, upsize);
+  if (!map) {
+    LOG(ERROR) << "mmap failed for fd=" << fd << " size=" << upsize
+               << " offset=" << offset_pos << ": " << GetLastError();
+    CloseHandle(file_mapping);
+    return nullptr;
+  }
+#else
+  void *map = mmap(nullptr, upsize, PROT_READ, MAP_SHARED, fd, offset_pos);
   if (map == MAP_FAILED) {
     LOG(ERROR) << "mmap failed for fd=" << fd << " size=" << upsize
-               << " offset=" << (pos - offset);
+               << " offset=" << offset_pos;
     return nullptr;
   }
+#endif
   MemoryRegion region;
   region.mmap = map;
   region.size = upsize;
   region.data = static_cast<void *>(static_cast<char *>(map) + offset);
   region.offset = offset;
+#ifdef _WIN32
+  region.file_mapping = file_mapping;
+#endif  // _WIN32
   return new MappedFile(region);
 }
 
index ecc1616..97dcaab 100644 (file)
@@ -32,10 +32,11 @@ uint64 ClosureProperties(uint64 inprops, bool, bool delayed) {
   if (!delayed || inprops & kAccessible) {
     outprops |= (kNotAcceptor | kNonIDeterministic | kNonODeterministic |
                  kNotILabelSorted | kNotOLabelSorted | kWeighted |
-                 kWeightedCycles | kNotAccessible | kNotCoAccessible) & inprops;
+                 kWeightedCycles | kNotAccessible | kNotCoAccessible) &
+                inprops;
     if ((inprops & kWeighted) && (inprops & kAccessible) &&
         (inprops & kCoAccessible)) {
-        outprops |= kWeightedCycles;
+      outprops |= kWeightedCycles;
     }
   }
   return outprops;
@@ -180,10 +181,10 @@ uint64 InvertProperties(uint64 inprops) {
 uint64 ProjectProperties(uint64 inprops, bool project_input) {
   auto outprops = kAcceptor;
   outprops |= (kExpanded | kMutable | kError | kWeighted | kUnweighted |
-               kWeightedCycles | kUnweightedCycles |
-               kCyclic | kAcyclic | kInitialCyclic | kInitialAcyclic |
-               kTopSorted | kNotTopSorted | kAccessible | kNotAccessible |
-               kCoAccessible | kNotCoAccessible | kString | kNotString) &
+               kWeightedCycles | kUnweightedCycles | kCyclic | kAcyclic |
+               kInitialCyclic | kInitialAcyclic | kTopSorted | kNotTopSorted |
+               kAccessible | kNotAccessible | kCoAccessible | kNotCoAccessible |
+               kString | kNotString) &
               inprops;
   if (project_input) {
     outprops |= (kIDeterministic | kNonIDeterministic | kIEpsilons |
@@ -255,7 +256,8 @@ uint64 ReplaceProperties(const std::vector<uint64>& inprops, size_t root,
       if (replace_transducer) props |= kNotAcceptor & inprop;
       props |= (kNonIDeterministic | kNonODeterministic | kEpsilons |
                 kIEpsilons | kOEpsilons | kWeighted | kWeightedCycles |
-                kCyclic | kNotTopSorted | kNotString) & inprop;
+                kCyclic | kNotTopSorted | kNotString) &
+               inprop;
       if (!(inprop & kString)) string = false;
     }
     outprops |= props;
@@ -363,8 +365,8 @@ uint64 SynchronizeProperties(uint64 inprops) {
                    kUnweighted | kUnweightedCycles) &
                   inprops;
   if (inprops & kAccessible) {
-    outprops |= (kCyclic | kNotCoAccessible | kWeighted | kWeightedCycles) &
-        inprops;
+    outprops |=
+        (kCyclic | kNotCoAccessible | kWeighted | kWeightedCycles) & inprops;
   }
   return outprops;
 }
index b7c7b13..378252a 100644 (file)
@@ -83,9 +83,7 @@ void DenseSymbolMap::RemoveSymbol(size_t idx) {
   Rehash(buckets_.size());
 }
 
-void DenseSymbolMap::ShrinkToFit() {
-  symbols_.shrink_to_fit();
-}
+void DenseSymbolMap::ShrinkToFit() { symbols_.shrink_to_fit(); }
 
 void MutableSymbolTableImpl::AddTable(const SymbolTable &table) {
   for (const auto &item : table) {
@@ -125,10 +123,10 @@ SymbolTableImpl *SymbolTableImpl::ReadText(std::istream &strm,
   std::unique_ptr<SymbolTableImpl> impl(new SymbolTableImpl(source));
   int64 nline = 0;
   char line[kLineLen];
+  const auto separator = opts.fst_field_separator + "\n";
   while (!strm.getline(line, kLineLen).fail()) {
     ++nline;
     std::vector<char *> col;
-    const auto separator = opts.fst_field_separator + "\n";
     SplitString(line, separator.c_str(), &col, true);
     if (col.empty()) continue;  // Empty line.
     if (col.size() != 2) {
@@ -142,7 +140,7 @@ SymbolTableImpl *SymbolTableImpl::ReadText(std::istream &strm,
     const char *value = col[1];
     char *p;
     const auto key = strtoll(value, &p, 10);
-    if (p < value + strlen(value) || (!opts.allow_negative_labels && key < 0) ||
+    if (*p != '\0' || (!opts.allow_negative_labels && key < 0) ||
         key == kNoSymbol) {
       LOG(ERROR) << "SymbolTable::ReadText: Bad non-negative integer \""
                  << value << "\", "
@@ -325,9 +323,7 @@ bool SymbolTableImpl::Write(std::ostream &strm) const {
   return true;
 }
 
-void SymbolTableImpl::ShrinkToFit() {
-  symbols_.ShrinkToFit();
-}
+void SymbolTableImpl::ShrinkToFit() { symbols_.ShrinkToFit(); }
 
 }  // namespace internal
 
index ea53976..30265d5 100644 (file)
@@ -13,5 +13,5 @@ shortest-distance.cc shortest-path.cc stateiterator-class.cc synchronize.cc \
 text-io.cc topsort.cc union.cc weight-class.cc verify.cc
 
 libfstscript_la_LIBADD = ../lib/libfst.la -lm $(DL_LIBS)
-libfstscript_la_LDFLAGS = -version-info 20:0:0
+libfstscript_la_LDFLAGS = -version-info 21:0:0
 endif
index e2c3102..86336ec 100644 (file)
@@ -407,7 +407,7 @@ AM_CPPFLAGS = -I$(srcdir)/../include $(ICU_CPPFLAGS)
 @HAVE_SCRIPT_TRUE@text-io.cc topsort.cc union.cc weight-class.cc verify.cc
 
 @HAVE_SCRIPT_TRUE@libfstscript_la_LIBADD = ../lib/libfst.la -lm $(DL_LIBS)
-@HAVE_SCRIPT_TRUE@libfstscript_la_LDFLAGS = -version-info 20:0:0
+@HAVE_SCRIPT_TRUE@libfstscript_la_LDFLAGS = -version-info 21:0:0
 all: all-am
 
 .SUFFIXES:
index f3ef2ab..3ccb8a3 100644 (file)
@@ -15,8 +15,8 @@ ArcIteratorClass::ArcIteratorClass(const FstClass &fst, int64 s)
                                              fst.ArcType(), &args);
 }
 
-MutableArcIteratorClass::MutableArcIteratorClass(MutableFstClass *fst,
-                                                 int64 s) : impl_(nullptr) {
+MutableArcIteratorClass::MutableArcIteratorClass(MutableFstClass *fst, int64 s)
+    : impl_(nullptr) {
   InitMutableArcIteratorClassArgs args(fst, s, this);
   Apply<Operation<InitMutableArcIteratorClassArgs>>(
       "InitMutableArcIteratorClass", fst->ArcType(), &args);
index 8c07c52..5c012b9 100644 (file)
@@ -88,6 +88,17 @@ bool GetMapType(const std::string &str, MapType *map_type) {
   return true;
 }
 
+bool GetProjectType(const std::string &str, ProjectType *project_type) {
+  if (str == "input") {
+    *project_type = ProjectType::INPUT;
+  } else if (str == "output") {
+    *project_type = ProjectType::OUTPUT;
+  } else {
+    return false;
+  }
+  return true;
+}
+
 bool GetRandArcSelection(const std::string &str, RandArcSelection *ras) {
   if (str == "uniform") {
     *ras = UNIFORM_ARC_SELECTOR;
@@ -136,5 +147,18 @@ bool GetReplaceLabelType(const std::string &str, bool epsilon_on_replace,
   return true;
 }
 
+bool GetTokenType(const std::string &str, TokenType *token_type) {
+  if (str == "byte") {
+    *token_type = TokenType::BYTE;
+  } else if (str == "utf8") {
+    *token_type = TokenType::UTF8;
+  } else if (str == "symbol") {
+    *token_type = TokenType::SYMBOL;
+  } else {
+    return false;
+  }
+  return true;
+}
+
 }  // namespace script
 }  // namespace fst
index 8bba946..80d4858 100644 (file)
@@ -8,7 +8,6 @@
 namespace fst {
 namespace script {
 
-
 void Project(MutableFstClass *ofst, ProjectType project_type) {
   ProjectArgs args(ofst, project_type);
   Apply<Operation<ProjectArgs>>("Project", ofst->ArcType(), &args);
index cf90938..70cc150 100644 (file)
@@ -9,8 +9,8 @@ namespace fst {
 namespace script {
 
 void Prune(const FstClass &ifst, MutableFstClass *ofst,
-           const WeightClass &weight_threshold,
-           int64 state_threshold, float delta) {
+           const WeightClass &weight_threshold, int64 state_threshold,
+           float delta) {
   if (!internal::ArcTypesMatch(ifst, *ofst, "Prune") ||
       !ofst->WeightTypesMatch(weight_threshold, "Prune")) {
     ofst->SetProperties(kError, kError);
index 548580f..f27ad9a 100644 (file)
@@ -14,8 +14,8 @@ void Relabel(MutableFstClass *ofst, const SymbolTable *old_isyms,
              const SymbolTable *old_osyms, const SymbolTable *relabel_osyms,
              const std::string &unknown_osymbol, bool attach_new_osyms) {
   RelabelArgs1 args(ofst, old_isyms, relabel_isyms, unknown_isymbol,
-                    attach_new_isyms, old_osyms, relabel_osyms,
-                    unknown_osymbol, attach_new_osyms);
+                    attach_new_isyms, old_osyms, relabel_osyms, unknown_osymbol,
+                    attach_new_osyms);
   Apply<Operation<RelabelArgs1>>("Relabel", ofst->ArcType(), &args);
 }
 
index 567ff51..f958037 100644 (file)
@@ -15,15 +15,24 @@ void ShortestDistance(const FstClass &fst, std::vector<WeightClass> *distance,
                                           &args);
 }
 
-void ShortestDistance(const FstClass &ifst, std::vector<WeightClass> *distance,
+void ShortestDistance(const FstClass &fst, std::vector<WeightClass> *distance,
                       bool reverse, double delta) {
-  ShortestDistanceArgs2 args(ifst, distance, reverse, delta);
-  Apply<Operation<ShortestDistanceArgs2>>("ShortestDistance", ifst.ArcType(),
+  ShortestDistanceArgs2 args(fst, distance, reverse, delta);
+  Apply<Operation<ShortestDistanceArgs2>>("ShortestDistance", fst.ArcType(),
+                                          &args);
+}
+
+WeightClass ShortestDistance(const FstClass &fst, double delta) {
+  ShortestDistanceInnerArgs3 iargs(fst, delta);
+  ShortestDistanceArgs3 args(iargs);
+  Apply<Operation<ShortestDistanceArgs3>>("ShortestDistance", fst.ArcType(),
                                           &args);
+  return args.retval;
 }
 
 REGISTER_FST_OPERATION_3ARCS(ShortestDistance, ShortestDistanceArgs1);
 REGISTER_FST_OPERATION_3ARCS(ShortestDistance, ShortestDistanceArgs2);
+REGISTER_FST_OPERATION_3ARCS(ShortestDistance, ShortestDistanceArgs3);
 
 }  // namespace script
 }  // namespace fst
index a490557..b71b7af 100644 (file)
@@ -11,6 +11,7 @@
 #include <fst/log.h>
 #include <fstream>
 #include <fst/util.h>
+#include <fst/windows_defs.inc>
 
 namespace fst {
 namespace script {
index 014b826..ed04731 100644 (file)
@@ -5,7 +5,7 @@
 
 #include <fst/test/algo_test.h>
 
-#include <cstdlib>
+#include <random>
 #include <vector>
 
 #include <fst/flags.h>
 // DEFINEs determine which semirings are tested; these are controlled by
 // the `defines` attributes of the associated build rules.
 
-DEFINE_int32(seed, -1, "random seed");
+DEFINE_uint64(seed, 403, "random seed");
 DEFINE_int32(repeat, 25, "number of test repetitions");
 
-using fst::AlgoTester;
-using fst::ArcTpl;
-using fst::GallicArc;
-using fst::GallicWeight;
-using fst::LexicographicArc;
-using fst::LexicographicWeight;
-using fst::LogArc;
-using fst::LogWeight;
-using fst::MinMaxArc;
-using fst::MinMaxWeight;
-using fst::PowerWeight;
-using fst::STRING_LEFT;
-using fst::STRING_RIGHT;
-using fst::StdArc;
-using fst::StringArc;
-using fst::StringWeight;
-using fst::TropicalWeight;
-using fst::WeightGenerate;
+namespace {
+
+using ::fst::AlgoTester;
+using ::fst::ArcTpl;
+using ::fst::GallicArc;
+using ::fst::GallicWeight;
+using ::fst::LexicographicArc;
+using ::fst::LexicographicWeight;
+using ::fst::LogArc;
+using ::fst::LogWeight;
+using ::fst::MinMaxArc;
+using ::fst::MinMaxWeight;
+using ::fst::PowerWeight;
+using ::fst::StdArc;
+using ::fst::STRING_LEFT;
+using ::fst::STRING_RIGHT;
+using ::fst::StringArc;
+using ::fst::TropicalWeight;
+using ::fst::WeightGenerate;
+
+}  // namespace
 
 int main(int argc, char **argv) {
   FLAGS_fst_verify_properties = true;
@@ -42,51 +45,52 @@ int main(int argc, char **argv) {
 
   static const int kCacheGcLimit = 20;
 
-  srand(FLAGS_seed);
   LOG(INFO) << "Seed = " << FLAGS_seed;
 
-  FLAGS_fst_default_cache_gc = rand() % 2;
-  FLAGS_fst_default_cache_gc_limit = rand() % kCacheGcLimit;
+  std::mt19937_64 rand(FLAGS_seed);
+
+  FLAGS_fst_default_cache_gc = std::bernoulli_distribution(.5)(rand);
+  FLAGS_fst_default_cache_gc_limit =
+      std::uniform_int_distribution<>(0, kCacheGcLimit)(rand);
   VLOG(1) << "default_cache_gc:" << FLAGS_fst_default_cache_gc;
   VLOG(1) << "default_cache_gc_limit:" << FLAGS_fst_default_cache_gc_limit;
 
 #ifdef TEST_TROPICAL
   using TropicalWeightGenerate = WeightGenerate<TropicalWeight>;
-  TropicalWeightGenerate tropical_generator(false);
-  AlgoTester<StdArc, TropicalWeightGenerate> tropical_tester(
-      tropical_generator, FLAGS_seed);
+  TropicalWeightGenerate tropical_generator(FLAGS_seed, false);
+  AlgoTester<StdArc, TropicalWeightGenerate> tropical_tester(tropical_generator,
+                                                             FLAGS_seed);
   tropical_tester.Test();
 #endif  // TEST_TROPICAL
 
 #ifdef TEST_LOG
   using LogWeightGenerate = WeightGenerate<LogWeight>;
-  LogWeightGenerate log_generator(false);
+  LogWeightGenerate log_generator(FLAGS_seed, false);
   AlgoTester<LogArc, LogWeightGenerate> log_tester(log_generator, FLAGS_seed);
   log_tester.Test();
 #endif  // TEST_LOG
 
 #ifdef TEST_MINMAX
   using MinMaxWeightGenerate = WeightGenerate<MinMaxWeight>;
-  MinMaxWeightGenerate minmax_generator(false);
+  MinMaxWeightGenerate minmax_generator(FLAGS_seed, false);
   AlgoTester<MinMaxArc, MinMaxWeightGenerate> minmax_tester(minmax_generator,
-                                                             FLAGS_seed);
+                                                            FLAGS_seed);
   minmax_tester.Test();
 #endif
 
 #ifdef TEST_LEFT_STRING
   using StringWeightGenerate = WeightGenerate<StringWeight<int, STRING_LEFT>>;
-  StringWeightGenerate left_string_generator(false);
+  StringWeightGenerate left_string_generator(FLAGS_seed, false);
   AlgoTester<StringArc<>, StringWeightGenerate> left_string_tester(
       left_string_generator, FLAGS_seed);
   left_string_tester.Test();
 #endif  // TEST_LEFT_STRING
 
 #ifdef TEST_RIGHT_STRING
-  using StringWeightGenerate =
-      WeightGenerate<StringWeight<int, STRING_RIGHT>>;
-  StringWeightGenerate right_string_generator(false);
-  AlgoTester<StringArc<STRING_RIGHT>, StringWeightGenerate>
-      right_string_tester(right_string_generator, FLAGS_seed);
+  using StringWeightGenerate = WeightGenerate<StringWeight<int, STRING_RIGHT>>;
+  StringWeightGenerate right_string_generator(FLAGS_seed, false);
+  AlgoTester<StringArc<STRING_RIGHT>, StringWeightGenerate> right_string_tester(
+      right_string_generator, FLAGS_seed);
   right_string_tester.Test();
 #endif  // TEST_RIGHT_STRING
 
@@ -94,7 +98,7 @@ int main(int argc, char **argv) {
   using StdGallicArc = GallicArc<StdArc>;
   using TropicalGallicWeightGenerate =
       WeightGenerate<GallicWeight<int, TropicalWeight>>;
-  TropicalGallicWeightGenerate tropical_gallic_generator(false);
+  TropicalGallicWeightGenerate tropical_gallic_generator(FLAGS_seed, false);
   AlgoTester<StdGallicArc, TropicalGallicWeightGenerate> gallic_tester(
       tropical_gallic_generator, FLAGS_seed);
   gallic_tester.Test();
@@ -105,7 +109,8 @@ int main(int argc, char **argv) {
       LexicographicArc<TropicalWeight, TropicalWeight>;
   using TropicalLexicographicWeightGenerate =
       WeightGenerate<LexicographicWeight<TropicalWeight, TropicalWeight>>;
-  TropicalLexicographicWeightGenerate lexicographic_generator(false);
+  TropicalLexicographicWeightGenerate lexicographic_generator(FLAGS_seed,
+                                                              false);
   AlgoTester<TropicalLexicographicArc, TropicalLexicographicWeightGenerate>
       lexicographic_tester(lexicographic_generator, FLAGS_seed);
   lexicographic_tester.Test();
@@ -115,13 +120,11 @@ int main(int argc, char **argv) {
   using TropicalCubeWeight = PowerWeight<TropicalWeight, 3>;
   using TropicalCubeArc = ArcTpl<TropicalCubeWeight>;
   using TropicalCubeWeightGenerate = WeightGenerate<TropicalCubeWeight>;
-  TropicalCubeWeightGenerate tropical_cube_generator(false);
+  TropicalCubeWeightGenerate tropical_cube_generator(FLAGS_seed, false);
   AlgoTester<TropicalCubeArc, TropicalCubeWeightGenerate> tropical_cube_tester(
       tropical_cube_generator, FLAGS_seed);
   tropical_cube_tester.Test();
 #endif  // TEST_POWER
 
-  std::cout << "PASS" << std::endl;
-
   return 0;
 }
index adc87d7..0b93afe 100644 (file)
@@ -3,9 +3,6 @@
 //
 // Regression test for FST weights.
 
-#include <cstdlib>
-#include <ctime>
-
 #include <fst/flags.h>
 #include <fst/log.h>
 #include <fst/expectation-weight.h>
@@ -20,7 +17,7 @@
 #include <fst/union-weight.h>
 #include <fst/test/weight-tester.h>
 
-DEFINE_int32(seed, -1, "random seed");
+DEFINE_uint64(seed, 403, "random seed");
 DEFINE_int32(repeat, 10000, "number of test repetitions");
 
 namespace {
@@ -32,23 +29,23 @@ using fst::GallicWeight;
 using fst::LexicographicWeight;
 using fst::LogWeight;
 using fst::LogWeightTpl;
-using fst::RealWeight;
-using fst::RealWeightTpl;
 using fst::MinMaxWeight;
 using fst::MinMaxWeightTpl;
 using fst::NaturalLess;
 using fst::PowerWeight;
 using fst::ProductWeight;
-using fst::SetWeight;
+using fst::RealWeight;
+using fst::RealWeightTpl;
+using fst::SET_BOOLEAN;
 using fst::SET_INTERSECT_UNION;
 using fst::SET_UNION_INTERSECT;
-using fst::SET_BOOLEAN;
+using fst::SetWeight;
 using fst::SignedLogWeight;
 using fst::SignedLogWeightTpl;
 using fst::SparsePowerWeight;
-using fst::StringWeight;
 using fst::STRING_LEFT;
 using fst::STRING_RIGHT;
+using fst::StringWeight;
 using fst::TropicalWeight;
 using fst::TropicalWeightTpl;
 using fst::UnionWeight;
@@ -57,33 +54,33 @@ using fst::WeightGenerate;
 using fst::WeightTester;
 
 template <class T>
-void TestTemplatedWeights(int repeat) {
+void TestTemplatedWeights(uint64 seed, int repeat) {
   using TropicalWeightGenerate = WeightGenerate<TropicalWeightTpl<T>>;
-  TropicalWeightGenerate tropical_generate;
+  TropicalWeightGenerate tropical_generate(seed);
   WeightTester<TropicalWeightTpl<T>, TropicalWeightGenerate> tropical_tester(
       tropical_generate);
   tropical_tester.Test(repeat);
 
   using LogWeightGenerate = WeightGenerate<LogWeightTpl<T>>;
-  LogWeightGenerate log_generate;
+  LogWeightGenerate log_generate(seed);
   WeightTester<LogWeightTpl<T>, LogWeightGenerate> log_tester(log_generate);
   log_tester.Test(repeat);
 
   using RealWeightGenerate = WeightGenerate<RealWeightTpl<T>>;
-  RealWeightGenerate real_generate;
+  RealWeightGenerate real_generate(seed);
   WeightTester<RealWeightTpl<T>, RealWeightGenerate> real_tester(real_generate);
   real_tester.Test(repeat);
 
   using MinMaxWeightGenerate = WeightGenerate<MinMaxWeightTpl<T>>;
-  MinMaxWeightGenerate minmax_generate(true);
+  MinMaxWeightGenerate minmax_generate(seed, true);
   WeightTester<MinMaxWeightTpl<T>, MinMaxWeightGenerate> minmax_tester(
       minmax_generate);
   minmax_tester.Test(repeat);
 
   using SignedLogWeightGenerate = WeightGenerate<SignedLogWeightTpl<T>>;
-  SignedLogWeightGenerate signedlog_generate;
-  WeightTester<SignedLogWeightTpl<T>, SignedLogWeightGenerate>
-      signedlog_tester(signedlog_generate);
+  SignedLogWeightGenerate signedlog_generate(seed, true);
+  WeightTester<SignedLogWeightTpl<T>, SignedLogWeightGenerate> signedlog_tester(
+      signedlog_generate);
   signedlog_tester.Test(repeat);
 }
 
@@ -104,7 +101,7 @@ void TestSignedAdder(int n) {
   Adder<Weight> adder;
   const Weight minus_one = Minus(Weight::Zero(), Weight::One());
   for (int i = 0; i < n; ++i) {
-    if (i < n/4 || i > 3*n/4) {
+    if (i < n / 4 || i > 3 * n / 4) {
       sum = Plus(sum, Weight::One());
       adder.Add(Weight::One());
     } else {
@@ -287,14 +284,11 @@ int main(int argc, char **argv) {
   std::set_new_handler(FailedNewHandler);
   SET_FLAGS(argv[0], &argc, &argv, true);
 
-  LOG(INFO) << "Seed = " << FLAGS_seed;
-  srand(FLAGS_seed);
-
-  TestTemplatedWeights<float>(FLAGS_repeat);
-  TestTemplatedWeights<double>(FLAGS_repeat);
+  TestTemplatedWeights<float>(FLAGS_seed, FLAGS_repeat);
+  TestTemplatedWeights<double>(FLAGS_seed, FLAGS_repeat);
   FLAGS_fst_weight_parentheses = "()";
-  TestTemplatedWeights<float>(FLAGS_repeat);
-  TestTemplatedWeights<double>(FLAGS_repeat);
+  TestTemplatedWeights<float>(FLAGS_seed, FLAGS_repeat);
+  TestTemplatedWeights<double>(FLAGS_seed, FLAGS_repeat);
   FLAGS_fst_weight_parentheses = "";
 
   // Makes sure type names for templated weights are consistent.
@@ -322,14 +316,14 @@ int main(int argc, char **argv) {
 
   using LeftStringWeight = StringWeight<int>;
   using LeftStringWeightGenerate = WeightGenerate<LeftStringWeight>;
-  LeftStringWeightGenerate left_string_generate;
+  LeftStringWeightGenerate left_string_generate(FLAGS_seed);
   WeightTester<LeftStringWeight, LeftStringWeightGenerate> left_string_tester(
       left_string_generate);
   left_string_tester.Test(FLAGS_repeat);
 
   using RightStringWeight = StringWeight<int, STRING_RIGHT>;
   using RightStringWeightGenerate = WeightGenerate<RightStringWeight>;
-  RightStringWeightGenerate right_string_generate;
+  RightStringWeightGenerate right_string_generate(FLAGS_seed);
   WeightTester<RightStringWeight, RightStringWeightGenerate>
       right_string_tester(right_string_generate);
   right_string_tester.Test(FLAGS_repeat);
@@ -339,16 +333,14 @@ int main(int argc, char **argv) {
 
   using IUSetWeight = SetWeight<int, SET_INTERSECT_UNION>;
   using IUSetWeightGenerate = WeightGenerate<IUSetWeight>;
-  IUSetWeightGenerate iu_set_generate;
-  WeightTester<IUSetWeight, IUSetWeightGenerate>
-      iu_set_tester(iu_set_generate);
+  IUSetWeightGenerate iu_set_generate(FLAGS_seed);
+  WeightTester<IUSetWeight, IUSetWeightGenerate> iu_set_tester(iu_set_generate);
   iu_set_tester.Test(FLAGS_repeat);
 
   using UISetWeight = SetWeight<int, SET_UNION_INTERSECT>;
   using UISetWeightGenerate = WeightGenerate<UISetWeight>;
-  UISetWeightGenerate ui_set_generate;
-  WeightTester<UISetWeight, UISetWeightGenerate>
-      ui_set_tester(ui_set_generate);
+  UISetWeightGenerate ui_set_generate(FLAGS_seed);
+  WeightTester<UISetWeight, UISetWeightGenerate> ui_set_tester(ui_set_generate);
   ui_set_tester.Test(FLAGS_repeat);
 
   // SET_INTERSECT_UNION_RESTRICT not tested since it requires equal sets,
@@ -356,9 +348,9 @@ int main(int argc, char **argv) {
 
   using BoolSetWeight = SetWeight<int, SET_BOOLEAN>;
   using BoolSetWeightGenerate = WeightGenerate<BoolSetWeight>;
-  BoolSetWeightGenerate bool_set_generate;
-  WeightTester<BoolSetWeight, BoolSetWeightGenerate>
-      bool_set_tester(bool_set_generate);
+  BoolSetWeightGenerate bool_set_generate(FLAGS_seed);
+  WeightTester<BoolSetWeight, BoolSetWeightGenerate> bool_set_tester(
+      bool_set_generate);
   bool_set_tester.Test(FLAGS_repeat);
 
   TestWeightConversion<IUSetWeight, UISetWeight>(iu_set_generate());
@@ -381,20 +373,21 @@ int main(int argc, char **argv) {
 
   using TropicalGallicWeight = GallicWeight<int, TropicalWeight>;
   using TropicalGallicWeightGenerate = WeightGenerate<TropicalGallicWeight>;
-  TropicalGallicWeightGenerate tropical_gallic_generate(true);
+  TropicalGallicWeightGenerate tropical_gallic_generate(FLAGS_seed, true);
   WeightTester<TropicalGallicWeight, TropicalGallicWeightGenerate>
       tropical_gallic_tester(tropical_gallic_generate);
 
   using TropicalGenGallicWeight = GallicWeight<int, TropicalWeight, GALLIC>;
   using TropicalGenGallicWeightGenerate =
       WeightGenerate<TropicalGenGallicWeight>;
-  TropicalGenGallicWeightGenerate tropical_gen_gallic_generate(false);
+  TropicalGenGallicWeightGenerate tropical_gen_gallic_generate(FLAGS_seed,
+                                                               false);
   WeightTester<TropicalGenGallicWeight, TropicalGenGallicWeightGenerate>
       tropical_gen_gallic_tester(tropical_gen_gallic_generate);
 
   using TropicalProductWeight = ProductWeight<TropicalWeight, TropicalWeight>;
   using TropicalProductWeightGenerate = WeightGenerate<TropicalProductWeight>;
-  TropicalProductWeightGenerate tropical_product_generate;
+  TropicalProductWeightGenerate tropical_product_generate(FLAGS_seed);
   WeightTester<TropicalProductWeight, TropicalProductWeightGenerate>
       tropical_product_tester(tropical_product_generate);
 
@@ -402,14 +395,14 @@ int main(int argc, char **argv) {
       LexicographicWeight<TropicalWeight, TropicalWeight>;
   using TropicalLexicographicWeightGenerate =
       WeightGenerate<TropicalLexicographicWeight>;
-  TropicalLexicographicWeightGenerate tropical_lexicographic_generate;
-  WeightTester<TropicalLexicographicWeight,
-               TropicalLexicographicWeightGenerate>
+  TropicalLexicographicWeightGenerate tropical_lexicographic_generate(
+      FLAGS_seed);
+  WeightTester<TropicalLexicographicWeight, TropicalLexicographicWeightGenerate>
       tropical_lexicographic_tester(tropical_lexicographic_generate);
 
   using TropicalCubeWeight = PowerWeight<TropicalWeight, 3>;
   using TropicalCubeWeightGenerate = WeightGenerate<TropicalCubeWeight>;
-  TropicalCubeWeightGenerate tropical_cube_generate;
+  TropicalCubeWeightGenerate tropical_cube_generate(FLAGS_seed);
   WeightTester<TropicalCubeWeight, TropicalCubeWeightGenerate>
       tropical_cube_tester(tropical_cube_generate);
 
@@ -417,7 +410,7 @@ int main(int argc, char **argv) {
       ProductWeight<TropicalProductWeight, TropicalWeight>;
   using FirstNestedProductWeightGenerate =
       WeightGenerate<FirstNestedProductWeight>;
-  FirstNestedProductWeightGenerate first_nested_product_generate;
+  FirstNestedProductWeightGenerate first_nested_product_generate(FLAGS_seed);
   WeightTester<FirstNestedProductWeight, FirstNestedProductWeightGenerate>
       first_nested_product_tester(first_nested_product_generate);
 
@@ -425,14 +418,14 @@ int main(int argc, char **argv) {
       ProductWeight<TropicalWeight, TropicalProductWeight>;
   using SecondNestedProductWeightGenerate =
       WeightGenerate<SecondNestedProductWeight>;
-  SecondNestedProductWeightGenerate second_nested_product_generate;
+  SecondNestedProductWeightGenerate second_nested_product_generate(FLAGS_seed);
   WeightTester<SecondNestedProductWeight, SecondNestedProductWeightGenerate>
       second_nested_product_tester(second_nested_product_generate);
 
   using NestedProductCubeWeight = PowerWeight<FirstNestedProductWeight, 3>;
   using NestedProductCubeWeightGenerate =
       WeightGenerate<NestedProductCubeWeight>;
-  NestedProductCubeWeightGenerate nested_product_cube_generate;
+  NestedProductCubeWeightGenerate nested_product_cube_generate(FLAGS_seed);
   WeightTester<NestedProductCubeWeight, NestedProductCubeWeightGenerate>
       nested_product_cube_tester(nested_product_cube_generate);
 
@@ -440,21 +433,22 @@ int main(int argc, char **argv) {
       SparsePowerWeight<NestedProductCubeWeight, size_t>;
   using SparseNestedProductCubeWeightGenerate =
       WeightGenerate<SparseNestedProductCubeWeight>;
-  SparseNestedProductCubeWeightGenerate sparse_nested_product_cube_generate;
+  SparseNestedProductCubeWeightGenerate sparse_nested_product_cube_generate(
+      FLAGS_seed);
   WeightTester<SparseNestedProductCubeWeight,
                SparseNestedProductCubeWeightGenerate>
       sparse_nested_product_cube_tester(sparse_nested_product_cube_generate);
 
   using LogSparsePowerWeight = SparsePowerWeight<LogWeight, size_t>;
   using LogSparsePowerWeightGenerate = WeightGenerate<LogSparsePowerWeight>;
-  LogSparsePowerWeightGenerate log_sparse_power_generate;
+  LogSparsePowerWeightGenerate log_sparse_power_generate(FLAGS_seed);
   WeightTester<LogSparsePowerWeight, LogSparsePowerWeightGenerate>
       log_sparse_power_tester(log_sparse_power_generate);
 
   using LogLogExpectationWeight = ExpectationWeight<LogWeight, LogWeight>;
   using LogLogExpectationWeightGenerate =
       WeightGenerate<LogLogExpectationWeight>;
-  LogLogExpectationWeightGenerate log_log_expectation_generate;
+  LogLogExpectationWeightGenerate log_log_expectation_generate(FLAGS_seed);
   WeightTester<LogLogExpectationWeight, LogLogExpectationWeightGenerate>
       log_log_expectation_tester(log_log_expectation_generate);
 
@@ -462,7 +456,8 @@ int main(int argc, char **argv) {
       ExpectationWeight<LogWeight, LogSparsePowerWeight>;
   using LogLogSparseExpectationWeightGenerate =
       WeightGenerate<LogLogSparseExpectationWeight>;
-  LogLogSparseExpectationWeightGenerate log_log_sparse_expectation_generate;
+  LogLogSparseExpectationWeightGenerate log_log_sparse_expectation_generate(
+      FLAGS_seed);
   WeightTester<LogLogSparseExpectationWeight,
                LogLogSparseExpectationWeightGenerate>
       log_log_sparse_expectation_tester(log_log_sparse_expectation_generate);
@@ -482,7 +477,7 @@ int main(int argc, char **argv) {
 
   using TropicalUnionWeight = UnionWeight<TropicalWeight, UnionWeightOptions>;
   using TropicalUnionWeightGenerate = WeightGenerate<TropicalUnionWeight>;
-  TropicalUnionWeightGenerate tropical_union_generate;
+  TropicalUnionWeightGenerate tropical_union_generate(FLAGS_seed);
   WeightTester<TropicalUnionWeight, TropicalUnionWeightGenerate>
       tropical_union_tester(tropical_union_generate);
 
@@ -529,7 +524,5 @@ int main(int argc, char **argv) {
 
   TestFloatEqualityIsReflexive();
 
-  std::cout << "PASS" << std::endl;
-
   return 0;
 }